fix(background-agent): skip terminal tasks during stale pruning
Prevent TTL pruning from deleting terminal tasks before delayed notification cleanup runs. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -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 { checkAndInterruptStaleTasks, pruneStaleTasksAndNotifications } from "./task-poller"
|
||||||
import type { BackgroundTask } from "./types"
|
import type { BackgroundTask } from "./types"
|
||||||
@@ -447,4 +448,38 @@ describe("pruneStaleTasksAndNotifications", () => {
|
|||||||
//#then
|
//#then
|
||||||
expect(pruned).toContain("old-task")
|
expect(pruned).toContain("old-task")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should skip terminal tasks even when they exceeded TTL", () => {
|
||||||
|
//#given
|
||||||
|
const tasks = new Map<string, BackgroundTask>()
|
||||||
|
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<string, BackgroundTask[]>(),
|
||||||
|
onTaskPruned: (taskId) => pruned.push(taskId),
|
||||||
|
})
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(pruned).toEqual([])
|
||||||
|
expect(Array.from(tasks.keys())).toEqual(terminalStatuses)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ import {
|
|||||||
} from "./constants"
|
} from "./constants"
|
||||||
import { removeTaskToastTracking } from "./remove-task-toast-tracking"
|
import { removeTaskToastTracking } from "./remove-task-toast-tracking"
|
||||||
|
|
||||||
|
const TERMINAL_TASK_STATUSES = new Set<BackgroundTask["status"]>([
|
||||||
|
"completed",
|
||||||
|
"error",
|
||||||
|
"cancelled",
|
||||||
|
"interrupt",
|
||||||
|
])
|
||||||
|
|
||||||
export function pruneStaleTasksAndNotifications(args: {
|
export function pruneStaleTasksAndNotifications(args: {
|
||||||
tasks: Map<string, BackgroundTask>
|
tasks: Map<string, BackgroundTask>
|
||||||
notifications: Map<string, BackgroundTask[]>
|
notifications: Map<string, BackgroundTask[]>
|
||||||
@@ -22,6 +29,8 @@ export function pruneStaleTasksAndNotifications(args: {
|
|||||||
const now = Date.now()
|
const now = Date.now()
|
||||||
|
|
||||||
for (const [taskId, task] of tasks.entries()) {
|
for (const [taskId, task] of tasks.entries()) {
|
||||||
|
if (TERMINAL_TASK_STATUSES.has(task.status)) continue
|
||||||
|
|
||||||
const timestamp = task.status === "pending"
|
const timestamp = task.status === "pending"
|
||||||
? task.queuedAt?.getTime()
|
? task.queuedAt?.getTime()
|
||||||
: task.startedAt?.getTime()
|
: task.startedAt?.getTime()
|
||||||
|
|||||||
Reference in New Issue
Block a user