fix(background-agent): treat non-active session statuses as terminal to prevent parent session hang

Previously, pollRunningTasks() and checkAndInterruptStaleTasks() treated
any non-"idle" session status as "still running", which caused tasks with
terminal statuses like "interrupted" to be skipped indefinitely — both
for completion detection AND stale timeout. This made the parent session
hang forever waiting for an ALL COMPLETE notification that never came.

Extract isActiveSessionStatus() and isTerminalSessionStatus() that
classify session statuses explicitly. Only known active statuses
("busy", "retry", "running") protect tasks from completion/stale checks.
Known terminal statuses ("interrupted") trigger immediate completion.
Unknown statuses fall through to the standard idle/gone path with output
validation as a conservative default.

Introduced by: a0c93816 (2026-02-14), dc370f7f (2026-03-08)
This commit is contained in:
YeonGyu-Kim
2026-03-18 13:56:11 +09:00
parent 57757a345d
commit 952bd5338d
6 changed files with 202 additions and 9 deletions
+2 -1
View File
@@ -14,6 +14,7 @@ import {
} from "./constants"
import { removeTaskToastTracking } from "./remove-task-toast-tracking"
import { isActiveSessionStatus } from "./session-status-classifier"
const TERMINAL_TASK_STATUSES = new Set<BackgroundTask["status"]>([
"completed",
"error",
@@ -120,7 +121,7 @@ export async function checkAndInterruptStaleTasks(args: {
if (!startedAt || !sessionID) continue
const sessionStatus = sessionStatuses?.[sessionID]?.type
const sessionIsRunning = sessionStatus !== undefined && sessionStatus !== "idle"
const sessionIsRunning = sessionStatus !== undefined && isActiveSessionStatus(sessionStatus)
const runtime = now - startedAt.getTime()
if (!task.progress?.lastUpdate) {