fix(#2825): secondary agents no longer pruned after 30 min of total runtime

TTL (pruneStaleTasksAndNotifications) now resets on last activity:
- Uses task.progress.lastUpdate as TTL anchor for running tasks
  (was always using startedAt, causing 30-min hard deadline)
- Added taskTtlMs config option for user-adjustable TTL
- Error message shows actual TTL duration, not hardcoded '30 minutes'
- 3 new tests for the new behavior
This commit is contained in:
YeonGyu-Kim
2026-03-27 16:06:38 +09:00
parent 3b4420bc23
commit c41e59e9ab
5 changed files with 144 additions and 5 deletions
+11 -5
View File
@@ -27,8 +27,10 @@ export function pruneStaleTasksAndNotifications(args: {
tasks: Map<string, BackgroundTask>
notifications: Map<string, BackgroundTask[]>
onTaskPruned: (taskId: string, task: BackgroundTask, errorMessage: string) => void
taskTtlMs?: number
}): void {
const { tasks, notifications, onTaskPruned } = args
const effectiveTtl = args.taskTtlMs ?? TASK_TTL_MS
const now = Date.now()
const tasksWithPendingNotifications = new Set<string>()
@@ -53,18 +55,22 @@ export function pruneStaleTasksAndNotifications(args: {
continue
}
const lastActivity = task.status === "running" && task.progress?.lastUpdate
? task.progress.lastUpdate.getTime()
: undefined
const timestamp = task.status === "pending"
? task.queuedAt?.getTime()
: task.startedAt?.getTime()
: (lastActivity ?? task.startedAt?.getTime())
if (!timestamp) continue
const age = now - timestamp
if (age <= TASK_TTL_MS) continue
if (age <= effectiveTtl) continue
const ttlMinutes = Math.round(effectiveTtl / 60000)
const errorMessage = task.status === "pending"
? "Task timed out while queued (30 minutes)"
: "Task timed out after 30 minutes"
? `Task timed out while queued (${ttlMinutes} minutes)`
: `Task timed out after ${ttlMinutes} minutes of inactivity`
onTaskPruned(taskId, task, errorMessage)
}
@@ -78,7 +84,7 @@ export function pruneStaleTasksAndNotifications(args: {
const validNotifications = queued.filter((task) => {
if (!task.startedAt) return false
const age = now - task.startedAt.getTime()
return age <= TASK_TTL_MS
return age <= effectiveTtl
})
if (validNotifications.length === 0) {