diff --git a/src/features/background-agent/task-poller.test.ts b/src/features/background-agent/task-poller.test.ts index 521a85904..6da3ffb0e 100644 --- a/src/features/background-agent/task-poller.test.ts +++ b/src/features/background-agent/task-poller.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect, mock } from "bun:test" +declare const require: (name: string) => any +const { describe, it, expect, mock } = require("bun:test") import { checkAndInterruptStaleTasks, pruneStaleTasksAndNotifications } from "./task-poller" import type { BackgroundTask } from "./types" @@ -447,4 +448,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 c27cd4874..bc4f049a4 100644 --- a/src/features/background-agent/task-poller.ts +++ b/src/features/background-agent/task-poller.ts @@ -13,6 +13,13 @@ import { } from "./constants" import { removeTaskToastTracking } from "./remove-task-toast-tracking" +const TERMINAL_TASK_STATUSES = new Set([ + "completed", + "error", + "cancelled", + "interrupt", +]) + export function pruneStaleTasksAndNotifications(args: { tasks: Map notifications: Map @@ -22,6 +29,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()