Skip to content

Commit 518224c

Browse files
committed
fix: abort cli cron runs on timeout
1 parent 8252908 commit 518224c

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

src/cron/isolated-agent/run-executor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ export function createCronPromptExecutor(params: {
142142
cliSessionId,
143143
skillsSnapshot: params.skillsSnapshot,
144144
messageChannel: params.messageChannel,
145+
abortSignal: params.abortSignal,
145146
bootstrapPromptWarningSignaturesSeen,
146147
bootstrapPromptWarningSignature,
147148
senderIsOwner: true,

src/cron/isolated-agent/run.skill-filter.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
} from "./run.suite-helpers.js";
77
import {
88
buildWorkspaceSkillSnapshotMock,
9+
dispatchCronDeliveryMock,
910
getCliSessionIdMock,
1011
isCliProviderMock,
1112
lookupContextTokensMock,
@@ -257,6 +258,40 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
257258
});
258259

259260
describe("CLI session handoff (issue #29774)", () => {
261+
it("passes the cron abort signal to CLI runs and drops late CLI results", async () => {
262+
const abortController = new AbortController();
263+
let markCliStarted!: () => void;
264+
const cliStarted = new Promise<void>((resolve) => {
265+
markCliStarted = resolve;
266+
});
267+
268+
isCliProviderMock.mockReturnValue(true);
269+
runCliAgentMock.mockImplementationOnce(async (params: { abortSignal?: AbortSignal }) => {
270+
expect(params.abortSignal).toBe(abortController.signal);
271+
markCliStarted();
272+
await new Promise<void>((resolve) => {
273+
params.abortSignal?.addEventListener("abort", () => resolve(), { once: true });
274+
});
275+
return {
276+
payloads: [{ text: "late cli output" }],
277+
meta: { agentMeta: { sessionId: "late-cli-session", usage: { input: 5, output: 10 } } },
278+
};
279+
});
280+
mockCliFallbackInvocation();
281+
282+
const runPromise = runCronIsolatedAgentTurn(
283+
makeSkillParams({ abortSignal: abortController.signal }),
284+
);
285+
await cliStarted;
286+
abortController.abort("cron: job execution timed out");
287+
288+
const result = await runPromise;
289+
290+
expect(result.status).toBe("error");
291+
expect(result.error).toBe("cron: job execution timed out");
292+
expect(dispatchCronDeliveryMock).not.toHaveBeenCalled();
293+
});
294+
260295
it("does not pass stored cliSessionId on fresh isolated runs (isNewSession=true)", async () => {
261296
// Simulate a persisted CLI session ID from a previous run.
262297
getCliSessionIdMock.mockReturnValue("prev-cli-session-abc");

0 commit comments

Comments
 (0)