From aaa54858a3866641844b6048b0e0ced083e1d6b3 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 12 Mar 2026 01:14:35 +0900 Subject: [PATCH] fix(background-agent): extend default no-progress stale timeout to 30 minutes Give never-updated background tasks a longer default window and keep the default-threshold regression coverage aligned with that behavior. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/features/background-agent/constants.ts | 2 +- .../default-message-staleness-timeout.test.ts | 60 +++++++++++++++++++ .../background-agent/task-poller.test.ts | 6 +- 3 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/features/background-agent/default-message-staleness-timeout.test.ts diff --git a/src/features/background-agent/constants.ts b/src/features/background-agent/constants.ts index cd3f3cf46..bfd4b7ee2 100644 --- a/src/features/background-agent/constants.ts +++ b/src/features/background-agent/constants.ts @@ -4,7 +4,7 @@ import type { BackgroundTask, LaunchInput } from "./types" export const TASK_TTL_MS = 30 * 60 * 1000 export const MIN_STABILITY_TIME_MS = 10 * 1000 export const DEFAULT_STALE_TIMEOUT_MS = 180_000 -export const DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 600_000 +export const DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS = 1_800_000 export const MIN_RUNTIME_BEFORE_STALE_MS = 30_000 export const MIN_IDLE_TIME_MS = 5000 export const POLLING_INTERVAL_MS = 3000 diff --git a/src/features/background-agent/default-message-staleness-timeout.test.ts b/src/features/background-agent/default-message-staleness-timeout.test.ts new file mode 100644 index 000000000..b13bf191a --- /dev/null +++ b/src/features/background-agent/default-message-staleness-timeout.test.ts @@ -0,0 +1,60 @@ +declare const require: (name: string) => any +const { describe, expect, test, mock } = require("bun:test") + +import { DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS } from "./constants" +import { checkAndInterruptStaleTasks } from "./task-poller" +import type { BackgroundTask } from "./types" + +function createRunningTask(startedAt: Date): BackgroundTask { + return { + id: "task-1", + sessionID: "ses-1", + parentSessionID: "parent-ses-1", + parentMessageID: "msg-1", + description: "test", + prompt: "test", + agent: "explore", + status: "running", + startedAt, + progress: undefined, + } +} + +describe("DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS", () => { + test("uses a 30 minute default", () => { + // #given + const expectedTimeout = 30 * 60 * 1000 + + // #when + const timeout = DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS + + // #then + expect(timeout).toBe(expectedTimeout) + }) + + test("does not interrupt a never-updated task after 15 minutes when config is omitted", async () => { + // #given + const task = createRunningTask(new Date(Date.now() - 15 * 60 * 1000)) + const client = { + session: { + abort: mock(() => Promise.resolve()), + }, + } + const concurrencyManager = { + release: mock(() => {}), + } + const notifyParentSession = mock(() => Promise.resolve()) + + // #when + await checkAndInterruptStaleTasks({ + tasks: [task], + client: client as never, + config: undefined, + concurrencyManager: concurrencyManager as never, + notifyParentSession, + }) + + // #then + expect(task.status).toBe("running") + }) +}) diff --git a/src/features/background-agent/task-poller.test.ts b/src/features/background-agent/task-poller.test.ts index 6716ec694..b71e27d8f 100644 --- a/src/features/background-agent/task-poller.test.ts +++ b/src/features/background-agent/task-poller.test.ts @@ -117,13 +117,13 @@ describe("checkAndInterruptStaleTasks", () => { }) it("should use DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS when messageStalenessTimeoutMs is not configured", async () => { - //#given — task started 15 minutes ago, no config for messageStalenessTimeoutMs + //#given — task started 35 minutes ago, no config for messageStalenessTimeoutMs const task = createRunningTask({ - startedAt: new Date(Date.now() - 15 * 60 * 1000), + startedAt: new Date(Date.now() - 35 * 60 * 1000), progress: undefined, }) - //#when — default is 10 minutes (600_000ms) + //#when — default is 30 minutes (1_800_000ms) await checkAndInterruptStaleTasks({ tasks: [task], client: mockClient as never,