Skip to content

Commit 8ba8253

Browse files
authored
fix: preserve cron telegram topic delivery after timeout (#72317)
1 parent ffa84cd commit 8ba8253

3 files changed

Lines changed: 48 additions & 0 deletions

File tree

src/cron/isolated-agent.direct-delivery-core-channels.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,18 @@ describe("runCronIsolatedAgentTurn telegram forum-topic direct delivery", () =>
363363
});
364364
});
365365

366+
it("preserves explicit supergroup topic targets for cron announce delivery", async () => {
367+
await expectTelegramAnnounceDelivery({
368+
to: "-1003774691294:topic:47",
369+
payloads: [{ text: "topic 47 completion" }],
370+
expected: {
371+
chatId: "-1003774691294",
372+
text: "topic 47 completion",
373+
messageThreadId: 47,
374+
},
375+
});
376+
});
377+
366378
it("delivers only the final assistant-visible text to forum-topic telegram targets", async () => {
367379
await expectTelegramAnnounceDelivery({
368380
to: "123:topic:42",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export function createCronPromptExecutor(params: {
143143
cliSessionId,
144144
skillsSnapshot: params.skillsSnapshot,
145145
messageChannel: params.messageChannel,
146+
abortSignal: params.abortSignal,
146147
bootstrapPromptWarningSignaturesSeen,
147148
bootstrapPromptWarningSignature,
148149
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)