diff --git a/src/features/background-agent/task-poller.test.ts b/src/features/background-agent/task-poller.test.ts index d411cb240..12d733803 100644 --- a/src/features/background-agent/task-poller.test.ts +++ b/src/features/background-agent/task-poller.test.ts @@ -422,4 +422,38 @@ describe("pruneStaleTasksAndNotifications", () => { //#then expect(pruned).toContain("old-task") }) + + it("should skip terminal tasks even when they exceeded TTL", () => { + //#given + const tasks = new Map() + const oldStartedAt = new Date(Date.now() - 31 * 60 * 1000) + const terminalStatuses: BackgroundTask["status"][] = ["completed", "error", "cancelled", "interrupt"] + + for (const status of terminalStatuses) { + tasks.set(status, { + id: status, + parentSessionID: "parent", + parentMessageID: "msg", + description: status, + prompt: status, + agent: "explore", + status, + startedAt: oldStartedAt, + completedAt: new Date(), + }) + } + + const pruned: string[] = [] + + //#when + pruneStaleTasksAndNotifications({ + tasks, + notifications: new Map(), + onTaskPruned: (taskId) => pruned.push(taskId), + }) + + //#then + expect(pruned).toEqual([]) + expect(Array.from(tasks.keys())).toEqual(terminalStatuses) + }) }) diff --git a/src/features/background-agent/task-poller.ts b/src/features/background-agent/task-poller.ts index eca83bc66..37bebd798 100644 --- a/src/features/background-agent/task-poller.ts +++ b/src/features/background-agent/task-poller.ts @@ -12,6 +12,13 @@ import { TASK_TTL_MS, } from "./constants" +const TERMINAL_TASK_STATUSES = new Set([ + "completed", + "error", + "cancelled", + "interrupt", +]) + export function pruneStaleTasksAndNotifications(args: { tasks: Map notifications: Map @@ -21,6 +28,8 @@ export function pruneStaleTasksAndNotifications(args: { const now = Date.now() for (const [taskId, task] of tasks.entries()) { + if (TERMINAL_TASK_STATUSES.has(task.status)) continue + const timestamp = task.status === "pending" ? task.queuedAt?.getTime() : task.startedAt?.getTime()