From 14c25cbbf56124f38235cb79a3424754c84f7dc3 Mon Sep 17 00:00:00 2001 From: cpkt9762 Date: Mon, 6 Apr 2026 12:44:12 +0800 Subject: [PATCH] feat(background-task): make taskCleanupDelayMs configurable TASK_CLEANUP_DELAY_MS is the delay between a task reaching a terminal state (completed/cancelled/errored) and its removal from the in-memory task store. It is currently a hard-coded 10 minute constant, which is too short for long-running background workflows: users routinely hit 'task not found' on background_output lookups when they inspect results more than ~10 minutes after completion. taskTtlMs (landed in #2825) already exposes the non-terminal task TTL on BackgroundTaskConfigSchema. This PR mirrors that pattern for the terminal-state cleanup delay: - Add taskCleanupDelayMs: z.number().min(60000).optional() to BackgroundTaskConfigSchema with JSDoc matching taskTtlMs's style. - BackgroundManager.scheduleCompletionRemoval() reads this.config?.taskCleanupDelayMs ?? TASK_CLEANUP_DELAY_MS, preserving the existing 10 min default for unconfigured users. - Regenerate assets/oh-my-opencode.schema.json. Default: 600000 ms (10 min, unchanged from current hard-coded value). Minimum: 60000 ms (1 min). bun run typecheck: clean. bun test src/features/background-agent: 411/411 pass. --- assets/oh-my-opencode.schema.json | 4 ++++ src/config/schema/background-task.ts | 2 ++ src/features/background-agent/manager.ts | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/assets/oh-my-opencode.schema.json b/assets/oh-my-opencode.schema.json index 607988931..26354a494 100644 --- a/assets/oh-my-opencode.schema.json +++ b/assets/oh-my-opencode.schema.json @@ -5687,6 +5687,10 @@ "type": "number", "minimum": 10000 }, + "taskCleanupDelayMs": { + "type": "number", + "minimum": 60000 + }, "syncPollTimeoutMs": { "type": "number", "minimum": 60000 diff --git a/src/config/schema/background-task.ts b/src/config/schema/background-task.ts index 44d16b505..0884381c9 100644 --- a/src/config/schema/background-task.ts +++ b/src/config/schema/background-task.ts @@ -20,6 +20,8 @@ export const BackgroundTaskConfigSchema = z.object({ taskTtlMs: z.number().min(300000).optional(), /** Timeout for tasks whose session has completely disappeared from the status registry (default: 60000 = 1 minute, minimum: 10000 = 10 seconds). When a session is gone (likely crashed), this shorter timeout is used instead of the normal stale timeout. */ sessionGoneTimeoutMs: z.number().min(10000).optional(), + /** Delay before removing completed/cancelled/errored tasks from memory in milliseconds (default: 600000 = 10 minutes, minimum: 60000 = 1 minute). */ + taskCleanupDelayMs: z.number().min(60000).optional(), syncPollTimeoutMs: z.number().min(60000).optional(), /** Maximum tool calls per subagent task before circuit breaker triggers (default: 200, minimum: 10). Prevents runaway loops from burning unlimited tokens. */ maxToolCalls: z.number().int().min(10).optional(), diff --git a/src/features/background-agent/manager.ts b/src/features/background-agent/manager.ts index bd8ff2477..8bc7f01bb 100644 --- a/src/features/background-agent/manager.ts +++ b/src/features/background-agent/manager.ts @@ -1510,7 +1510,7 @@ export class BackgroundManager { SessionCategoryRegistry.remove(task.sessionID) } log("[background-agent] Removed completed task from memory:", taskId) - }, TASK_CLEANUP_DELAY_MS) + }, this.config?.taskCleanupDelayMs ?? TASK_CLEANUP_DELAY_MS) this.completionTimers.set(taskId, timer) }