From da251c9b30c26299deb421af5265821d96ea91d9 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 2 May 2026 03:01:03 +0900 Subject: [PATCH] refactor(background-agent): normalize task ID field naming Rename BackgroundTask and attempt ID fields to camelCase across background-agent consumers while moving BackgroundManager construction to a single config object. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/create-managers.ts | 28 +- .../background-agent/attempt-lifecycle.ts | 36 +- ...kground-task-notification-template.test.ts | 32 +- .../background-task-notification-template.ts | 14 +- .../cancel-task-cleanup.test.ts | 40 +- .../default-message-staleness-timeout.test.ts | 6 +- .../fallback-retry-handler.test.ts | 36 +- .../fallback-retry-handler.ts | 10 +- .../manager-circuit-breaker.test.ts | 70 +- .../manager-session-permission.test.ts | 12 +- .../manager-shutdown-global-cleanup.test.ts | 16 +- .../background-agent/manager.polling.test.ts | 16 +- src/features/background-agent/manager.test.ts | 1325 ++++++++--------- src/features/background-agent/manager.ts | 363 ++--- .../session-idle-event-handler.test.ts | 28 +- src/features/background-agent/spawner.test.ts | 88 +- src/features/background-agent/spawner.ts | 34 +- src/features/background-agent/state.ts | 22 +- .../task-completion-cleanup.test.ts | 32 +- .../task-history-cleanup.test.ts | 10 +- .../background-agent/task-poller.test.ts | 34 +- src/features/background-agent/task-poller.ts | 2 +- src/features/background-agent/types.ts | 24 +- .../wait-for-task-session.test.ts | 4 +- .../background-agent/wait-for-task-session.ts | 10 +- .../task-message-analyzer.ts | 2 +- .../unstable-agent-babysitter-hook.ts | 2 +- .../create-background-cancel.ts | 4 +- .../create-background-output.blocking.test.ts | 6 +- .../create-background-output.metadata.test.ts | 6 +- .../create-background-output.ts | 4 +- .../create-background-output.undo.test.ts | 6 +- .../create-background-task.test.ts | 24 +- .../background-task/create-background-task.ts | 8 +- .../background-task/full-session-format.ts | 6 +- .../task-result-format.test.ts | 6 +- .../background-task/task-result-format.ts | 16 +- .../background-task/task-status-format.ts | 2 +- src/tools/background-task/tools.test.ts | 12 +- .../background-agent-executor.ts | 8 +- .../call-omo-agent/background-executor.ts | 8 +- .../background-continuation.test.ts | 4 +- .../delegate-task/background-continuation.ts | 6 +- .../delegate-task/background-task.test.ts | 54 +- src/tools/delegate-task/background-task.ts | 10 +- .../delegate-task/metadata-await.test.ts | 2 +- .../metadata-model-unification.test.ts | 18 +- .../metadata-task-id-consistency.test.ts | 16 +- .../delegate-task/oracle-gap-closure.test.ts | 6 +- .../delegate-task/sync-poll-timeout.test.ts | 4 +- .../delegate-task/sync-result-fetcher.test.ts | 2 +- src/tools/delegate-task/tools.test.ts | 56 +- .../unstable-agent-cleanup.test.ts | 8 +- .../unstable-agent-permission.test.ts | 4 +- .../delegate-task/unstable-agent-task.test.ts | 12 +- .../delegate-task/unstable-agent-task.ts | 8 +- .../unstable-agent-timeout.test.ts | 4 +- 57 files changed, 1299 insertions(+), 1327 deletions(-) diff --git a/src/create-managers.ts b/src/create-managers.ts index 602cc8502..c4fcc9837 100644 --- a/src/create-managers.ts +++ b/src/create-managers.ts @@ -68,12 +68,11 @@ export function createManagers(args: { }, }) - const backgroundManager = new deps.BackgroundManagerClass( - ctx, - pluginConfig.background_task, - { - tmuxConfig, - onSubagentSessionCreated: async (event: SubagentSessionCreatedEvent) => { + const backgroundManager = new deps.BackgroundManagerClass({ + pluginContext: ctx, + config: pluginConfig.background_task, + tmuxConfig, + onSubagentSessionCreated: async (event: SubagentSessionCreatedEvent) => { log("[create-managers] onSubagentSessionCreated callback received", { sessionID: event.sessionID, parentID: event.parentID, @@ -104,16 +103,15 @@ export function createManagers(args: { } log("[create-managers] onSubagentSessionCreated callback completed") - }, - onShutdown: async () => { - await tmuxSessionManager.cleanup().catch((error) => { - log("[create-managers] tmux cleanup error during shutdown:", error) - }) - }, - enableParentSessionNotifications: backgroundNotificationHookEnabled, - modelFallbackControllerAccessor, }, - ) + onShutdown: async () => { + await tmuxSessionManager.cleanup().catch((error) => { + log("[create-managers] tmux cleanup error during shutdown:", error) + }) + }, + enableParentSessionNotifications: backgroundNotificationHookEnabled, + modelFallbackControllerAccessor, + }) deps.initTaskToastManagerFn(ctx.client) diff --git a/src/features/background-agent/attempt-lifecycle.ts b/src/features/background-agent/attempt-lifecycle.ts index 428e60b9c..cc43c28be 100644 --- a/src/features/background-agent/attempt-lifecycle.ts +++ b/src/features/background-agent/attempt-lifecycle.ts @@ -3,28 +3,28 @@ import type { BackgroundTask, BackgroundTaskAttempt, BackgroundTaskStatus } from type TerminalAttemptStatus = Extract -function toAttemptModel(model: DelegatedModelConfig | undefined): Pick { +function toAttemptModel(model: DelegatedModelConfig | undefined): Pick { return { - providerID: model?.providerID, - modelID: model?.modelID, + providerId: model?.providerID, + modelId: model?.modelID, variant: model?.variant, } } function toTaskModel(attempt: BackgroundTaskAttempt): DelegatedModelConfig | undefined { - if (!attempt.providerID || !attempt.modelID) { + if (!attempt.providerId || !attempt.modelId) { return undefined } return { - providerID: attempt.providerID, - modelID: attempt.modelID, + providerID: attempt.providerId, + modelID: attempt.modelId, ...(attempt.variant ? { variant: attempt.variant } : {}), } } function getAttemptIndex(task: BackgroundTask, attemptID: string): number { - return task.attempts?.findIndex((attempt) => attempt.attemptID === attemptID) ?? -1 + return task.attempts?.findIndex((attempt) => attempt.attemptId === attemptID) ?? -1 } function getAttempt(task: BackgroundTask, attemptID: string): BackgroundTaskAttempt | undefined { @@ -54,9 +54,9 @@ export function ensureCurrentAttempt( } const attempt: BackgroundTaskAttempt = { - attemptID: `att_${crypto.randomUUID().slice(0, 8)}`, + attemptId: `att_${crypto.randomUUID().slice(0, 8)}`, attemptNumber: (task.attempts?.length ?? 0) + 1, - sessionID: task.sessionID, + sessionId: task.sessionId, ...toAttemptModel(model), status: task.status, error: task.error, @@ -65,7 +65,7 @@ export function ensureCurrentAttempt( } task.attempts = [...(task.attempts ?? []), attempt] - task.currentAttemptID = attempt.attemptID + task.currentAttemptID = attempt.attemptId return attempt } @@ -76,7 +76,7 @@ export function projectTaskFromCurrentAttempt(task: BackgroundTask): BackgroundT } task.status = currentAttempt.status - task.sessionID = currentAttempt.sessionID + task.sessionId = currentAttempt.sessionId task.startedAt = currentAttempt.startedAt task.completedAt = currentAttempt.completedAt task.error = currentAttempt.error @@ -87,16 +87,16 @@ export function projectTaskFromCurrentAttempt(task: BackgroundTask): BackgroundT export function startAttempt(task: BackgroundTask, model: DelegatedModelConfig | undefined): BackgroundTaskAttempt { const attempt: BackgroundTaskAttempt = { - attemptID: `att_${crypto.randomUUID().slice(0, 8)}`, + attemptId: `att_${crypto.randomUUID().slice(0, 8)}`, attemptNumber: (task.attempts?.length ?? 0) + 1, ...toAttemptModel(model), status: "pending", } task.attempts = [...(task.attempts ?? []), attempt] - task.currentAttemptID = attempt.attemptID + task.currentAttemptID = attempt.attemptId task.status = "pending" - task.sessionID = undefined + task.sessionId = undefined task.startedAt = undefined task.completedAt = undefined task.error = undefined @@ -121,13 +121,13 @@ export function bindAttemptSession( return undefined } - attempt.sessionID = sessionID + attempt.sessionId = sessionID attempt.status = "running" attempt.startedAt = new Date() attempt.completedAt = undefined attempt.error = undefined - attempt.providerID = model?.providerID ?? attempt.providerID - attempt.modelID = model?.modelID ?? attempt.modelID + attempt.providerId = model?.providerID ?? attempt.providerId + attempt.modelId = model?.modelID ?? attempt.modelId attempt.variant = model?.variant ?? attempt.variant return getCurrentAttempt(projectTaskFromCurrentAttempt(task)) @@ -170,5 +170,5 @@ export function scheduleRetryAttempt( } export function findAttemptBySession(task: BackgroundTask, sessionID: string): BackgroundTaskAttempt | undefined { - return task.attempts?.find((attempt) => attempt.sessionID === sessionID) + return task.attempts?.find((attempt) => attempt.sessionId === sessionID) } diff --git a/src/features/background-agent/background-task-notification-template.test.ts b/src/features/background-agent/background-task-notification-template.test.ts index 183975080..7001aef12 100644 --- a/src/features/background-agent/background-task-notification-template.test.ts +++ b/src/features/background-agent/background-task-notification-template.test.ts @@ -164,20 +164,20 @@ Use \`background_output(task_id="")\` to retrieve each result. status: "completed", attempts: [ { - attemptID: "att-1", + attemptId: "att-1", attemptNumber: 1, - sessionID: "ses-primary", - providerID: "genai-proxy-openai", - modelID: "gpt-5.4-mini", + sessionId: "ses-primary", + providerId: "genai-proxy-openai", + modelId: "gpt-5.4-mini", status: "error", error: "Forbidden: Selected provider is forbidden", }, { - attemptID: "att-2", + attemptId: "att-2", attemptNumber: 2, - sessionID: "ses-fallback", - providerID: "anthropic", - modelID: "claude-haiku-4.5", + sessionId: "ses-fallback", + providerId: "anthropic", + modelId: "claude-haiku-4.5", status: "completed", }, ], @@ -193,20 +193,20 @@ Use \`background_output(task_id="")\` to retrieve each result. status: "completed", attempts: [ { - attemptID: "att-1", + attemptId: "att-1", attemptNumber: 1, - sessionID: "ses-primary", - providerID: "genai-proxy-openai", - modelID: "gpt-5.4-mini", + sessionId: "ses-primary", + providerId: "genai-proxy-openai", + modelId: "gpt-5.4-mini", status: "error", error: "Forbidden: Selected provider is forbidden", }, { - attemptID: "att-2", + attemptId: "att-2", attemptNumber: 2, - sessionID: "ses-fallback", - providerID: "anthropic", - modelID: "claude-haiku-4.5", + sessionId: "ses-fallback", + providerId: "anthropic", + modelId: "claude-haiku-4.5", status: "completed", }, ], diff --git a/src/features/background-agent/background-task-notification-template.ts b/src/features/background-agent/background-task-notification-template.ts index c3472c4a0..7c71cd4e7 100644 --- a/src/features/background-agent/background-task-notification-template.ts +++ b/src/features/background-agent/background-task-notification-template.ts @@ -11,16 +11,16 @@ export interface BackgroundTaskNotificationTask { } function formatAttemptModel(attempt: BackgroundTaskAttempt): string { - if (attempt.providerID && attempt.modelID) { - return `${attempt.providerID}/${attempt.modelID}` + if (attempt.providerId && attempt.modelId) { + return `${attempt.providerId}/${attempt.modelId}` } - if (attempt.modelID) { - return attempt.modelID + if (attempt.modelId) { + return attempt.modelId } - if (attempt.providerID) { - return attempt.providerID + if (attempt.providerId) { + return attempt.providerId } return "unknown-model" @@ -34,7 +34,7 @@ function formatAttemptTimeline(task: BackgroundTaskNotificationTask): string { const lines = task.attempts .map((attempt) => { const attemptLines = [ - ` - Attempt ${attempt.attemptNumber} — ${attempt.status.toUpperCase()} — ${formatAttemptModel(attempt)} — ${attempt.sessionID ?? "unknown"}`, + ` - Attempt ${attempt.attemptNumber} — ${attempt.status.toUpperCase()} — ${formatAttemptModel(attempt)} — ${attempt.sessionId ?? "unknown"}`, ] if (attempt.status !== "completed" && attempt.error) { diff --git a/src/features/background-agent/cancel-task-cleanup.test.ts b/src/features/background-agent/cancel-task-cleanup.test.ts index 1994e22a9..d8e43f95b 100644 --- a/src/features/background-agent/cancel-task-cleanup.test.ts +++ b/src/features/background-agent/cancel-task-cleanup.test.ts @@ -22,24 +22,24 @@ function createBackgroundManager(config?: { defaultConcurrency?: number }): Back Reflect.set(client.session, "prompt", async () => ({ data: { info: {}, parts: [] } })) Reflect.set(client.session, "promptAsync", async () => ({ data: undefined })) - const manager = new BackgroundManager({ + const manager = new BackgroundManager({ pluginContext: { $: {} as PluginInput["$"], client, directory, project: {} as PluginInput["project"], serverUrl: new URL("http://localhost"), worktree: directory, - }, config) + }, config: config }) managersToShutdown.push(manager) return manager } -function createMockTask(overrides: Partial & { id: string; parentSessionID: string }): BackgroundTask { +function createMockTask(overrides: Partial & { id: string; parentSessionId: string }): BackgroundTask { return { id: overrides.id, - sessionID: overrides.sessionID, - parentSessionID: overrides.parentSessionID, - parentMessageID: overrides.parentMessageID ?? "parent-message-id", + sessionId: overrides.sessionId, + parentSessionId: overrides.parentSessionId, + parentMessageId: overrides.parentMessageId ?? "parent-message-id", description: overrides.description ?? "test task", prompt: overrides.prompt ?? "test prompt", agent: overrides.agent ?? "test-agent", @@ -90,12 +90,12 @@ describe("BackgroundManager.cancelTask cleanup", () => { const manager = createBackgroundManager() const task = createMockTask({ id: "task-skip-notification-cleanup", - parentSessionID: "parent-session-skip-notification-cleanup", - sessionID: "session-skip-notification-cleanup", + parentSessionId: "parent-session-skip-notification-cleanup", + sessionId: "session-skip-notification-cleanup", }) getTaskMap(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) // when const cancelled = await manager.cancelTask(task.id, { @@ -105,7 +105,7 @@ describe("BackgroundManager.cancelTask cleanup", () => { // then expect(cancelled).toBe(true) - expect(getPendingByParent(manager).get(task.parentSessionID)).toBeUndefined() + expect(getPendingByParent(manager).get(task.parentSessionId)).toBeUndefined() runScheduledCleanup(manager, task.id) expect(manager.getTask(task.id)).toBeUndefined() }) @@ -115,12 +115,12 @@ describe("BackgroundManager.cancelTask cleanup", () => { const manager = createBackgroundManager() const task = createMockTask({ id: "task-notify-cleanup", - parentSessionID: "parent-session-notify-cleanup", - sessionID: "session-notify-cleanup", + parentSessionId: "parent-session-notify-cleanup", + sessionId: "session-notify-cleanup", }) getTaskMap(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) // when const cancelled = await manager.cancelTask(task.id, { @@ -143,13 +143,13 @@ describe("BackgroundManager.cancelTask cleanup", () => { const runningTask = createMockTask({ id: "task-running-before-cancel", - parentSessionID: "parent-session-concurrency-cleanup", - sessionID: "session-running-before-cancel", + parentSessionId: "parent-session-concurrency-cleanup", + sessionId: "session-running-before-cancel", concurrencyKey, }) const pendingTask = createMockTask({ id: "task-pending-after-cancel", - parentSessionID: runningTask.parentSessionID, + parentSessionId: runningTask.parentSessionId, status: "pending", startedAt: undefined, queuedAt: new Date(), @@ -159,20 +159,20 @@ describe("BackgroundManager.cancelTask cleanup", () => { agent: pendingTask.agent, description: pendingTask.description, model: pendingTask.model, - parentMessageID: pendingTask.parentMessageID, - parentSessionID: pendingTask.parentSessionID, + parentMessageId: pendingTask.parentMessageId, + parentSessionId: pendingTask.parentSessionId, prompt: pendingTask.prompt, } getTaskMap(manager).set(runningTask.id, runningTask) getTaskMap(manager).set(pendingTask.id, pendingTask) - getPendingByParent(manager).set(runningTask.parentSessionID, new Set([runningTask.id, pendingTask.id])) + getPendingByParent(manager).set(runningTask.parentSessionId, new Set([runningTask.id, pendingTask.id])) getQueuesByKey(manager).set(concurrencyKey, [{ input: queuedInput, task: pendingTask }]) Reflect.set(manager, "startTask", async ({ task }: { task: BackgroundTask; input: LaunchInput }) => { task.status = "running" task.startedAt = new Date() - task.sessionID = "session-started-after-cancel" + task.sessionId = "session-started-after-cancel" task.concurrencyKey = concurrencyKey task.concurrencyGroup = concurrencyKey }) diff --git a/src/features/background-agent/default-message-staleness-timeout.test.ts b/src/features/background-agent/default-message-staleness-timeout.test.ts index d8b4e6671..73c8e6d54 100644 --- a/src/features/background-agent/default-message-staleness-timeout.test.ts +++ b/src/features/background-agent/default-message-staleness-timeout.test.ts @@ -8,9 +8,9 @@ import type { BackgroundTask } from "./types" function createRunningTask(startedAt: Date): BackgroundTask { return { id: "task-1", - sessionID: "ses-1", - parentSessionID: "parent-ses-1", - parentMessageID: "msg-1", + sessionId: "ses-1", + parentSessionId: "parent-ses-1", + parentMessageId: "msg-1", description: "test", prompt: "test", agent: "explore", diff --git a/src/features/background-agent/fallback-retry-handler.test.ts b/src/features/background-agent/fallback-retry-handler.test.ts index 6456f1d09..a9c4f0cd1 100644 --- a/src/features/background-agent/fallback-retry-handler.test.ts +++ b/src/features/background-agent/fallback-retry-handler.test.ts @@ -69,8 +69,8 @@ function createMockTask(overrides: Partial = {}): BackgroundTask prompt: "test prompt", agent: "sisyphus-junior", status: "error", - parentSessionID: "parent-session-1", - parentMessageID: "parent-message-1", + parentSessionId: "parent-session-1", + parentMessageId: "parent-message-1", fallbackChain: [ { model: "fallback-model-1", providers: ["provider-a"], variant: undefined }, { model: "fallback-model-2", providers: ["provider-b"], variant: undefined }, @@ -174,13 +174,13 @@ describe("tryFallbackRetry", () => { test("clears sessionID and startedAt", async () => { const args = createDefaultArgs({ - sessionID: "old-session", + sessionId: "old-session", startedAt: new Date(), }) await tryFallbackRetry(args) - expect(args.task.sessionID).toBeUndefined() + expect(args.task.sessionId).toBeUndefined() expect(args.task.startedAt).toBeUndefined() }) @@ -217,7 +217,7 @@ describe("tryFallbackRetry", () => { }) test("aborts existing session", async () => { - const args = createDefaultArgs({ sessionID: "session-to-abort" }) + const args = createDefaultArgs({ sessionId: "session-to-abort" }) await tryFallbackRetry(args) @@ -227,7 +227,7 @@ describe("tryFallbackRetry", () => { }) test("waits for session abort before resolving", async () => { - const args = createDefaultArgs({ sessionID: "session-to-abort" }) + const args = createDefaultArgs({ sessionId: "session-to-abort" }) const deferred = createDeferredPromise() args.abortMock.mockImplementationOnce(() => deferred.promise) @@ -263,15 +263,15 @@ describe("tryFallbackRetry", () => { test("finalizes the failed attempt, creates a new pending attempt, and enqueues its explicit attemptID", async () => { const args = createDefaultArgs({ status: "running", - sessionID: "session-attempt-1", + sessionId: "session-attempt-1", startedAt: new Date("2026-04-27T00:00:00.000Z"), attempts: [ { - attemptID: "attempt-1", + attemptId: "attempt-1", attemptNumber: 1, - sessionID: "session-attempt-1", - providerID: "provider-a", - modelID: "original-model", + sessionId: "session-attempt-1", + providerId: "provider-a", + modelId: "original-model", status: "running", startedAt: new Date("2026-04-27T00:00:00.000Z"), }, @@ -283,8 +283,8 @@ describe("tryFallbackRetry", () => { expect(args.task.attempts).toHaveLength(2) expect(args.task.attempts?.[0]).toMatchObject({ - attemptID: "attempt-1", - sessionID: "session-attempt-1", + attemptId: "attempt-1", + sessionId: "session-attempt-1", status: "error", error: "model overloaded", }) @@ -293,11 +293,11 @@ describe("tryFallbackRetry", () => { const nextAttempt = args.task.attempts?.[1] expect(nextAttempt).toBeDefined() expect(nextAttempt?.attemptNumber).toBe(2) - expect(nextAttempt?.providerID).toBe("provider-a") - expect(nextAttempt?.modelID).toBe("fallback-model-1") + expect(nextAttempt?.providerId).toBe("provider-a") + expect(nextAttempt?.modelId).toBe("fallback-model-1") expect(nextAttempt?.status).toBe("pending") - expect(args.task.currentAttemptID).toBe(nextAttempt?.attemptID) + expect(args.task.currentAttemptID).toBe(nextAttempt?.attemptId) expect(args.task.status).toBe("pending") expect(args.task.model).toEqual({ providerID: "provider-a", @@ -308,7 +308,7 @@ describe("tryFallbackRetry", () => { const key = `${args.task.model!.providerID}/${args.task.model!.modelID}` const queue = args.queuesByKey.get(key) expect(queue).toBeDefined() - expect((queue?.[0] as QueueItem & { attemptID?: string })?.attemptID).toBe(nextAttempt?.attemptID) + expect((queue?.[0] as QueueItem & { attemptID?: string })?.attemptID).toBe(nextAttempt?.attemptId) }) }) @@ -363,7 +363,7 @@ describe("tryFallbackRetry", () => { describe("#given task without session", () => { test("skips session abort", async () => { - const args = createDefaultArgs({ sessionID: undefined }) + const args = createDefaultArgs({ sessionId: undefined }) await tryFallbackRetry(args) diff --git a/src/features/background-agent/fallback-retry-handler.ts b/src/features/background-agent/fallback-retry-handler.ts index 52fb2ab5a..f5f31a6ad 100644 --- a/src/features/background-agent/fallback-retry-handler.ts +++ b/src/features/background-agent/fallback-retry-handler.ts @@ -124,7 +124,7 @@ export async function tryFallbackRetry(args: { idleDeferralTimers.delete(task.id) } - const previousSessionID = task.sessionID + const previousSessionID = task.sessionId const previousModel = task.model const transformedModelId = transformModelForProvider(providerID, nextFallback.model) @@ -134,7 +134,7 @@ export async function tryFallbackRetry(args: { variant: nextFallback.variant, } task.attemptCount = selectedAttemptCount - const failedAttemptID = ensureCurrentAttempt(task, previousModel).attemptID + const failedAttemptID = ensureCurrentAttempt(task, previousModel).attemptId const nextAttempt = failedAttemptID ? scheduleRetryAttempt(task, failedAttemptID, nextModel, errorInfo.message) : undefined @@ -165,8 +165,8 @@ export async function tryFallbackRetry(args: { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, parentTools: task.parentTools, @@ -180,7 +180,7 @@ export async function tryFallbackRetry(args: { await abortWithTimeout(client, previousSessionID).catch(() => {}) } - queue.push({ task, input: retryInput, attemptID: nextAttempt.attemptID }) + queue.push({ task, input: retryInput, attemptID: nextAttempt.attemptId }) queuesByKey.set(key, queue) processKey(key) return true diff --git a/src/features/background-agent/manager-circuit-breaker.test.ts b/src/features/background-agent/manager-circuit-breaker.test.ts index 9a8734fb1..aa307bd03 100644 --- a/src/features/background-agent/manager-circuit-breaker.test.ts +++ b/src/features/background-agent/manager-circuit-breaker.test.ts @@ -16,14 +16,14 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager { }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, config) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: config }) const testManager = manager as unknown as { - enqueueNotificationForParent: (sessionID: string, fn: () => Promise) => Promise + enqueueNotificationForParent: (sessionId: string, fn: () => Promise) => Promise notifyParentSession: (task: BackgroundTask) => Promise tasks: Map } - testManager.enqueueNotificationForParent = async (_sessionID, fn) => { + testManager.enqueueNotificationForParent = async (_sessionId: sessionID, fn) => { await fn() } testManager.notifyParentSession = async () => {} @@ -49,9 +49,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-loop-1", - sessionID: "session-loop-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-loop-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Looping task", prompt: "loop", agent: "explore", @@ -67,7 +67,7 @@ describe("BackgroundManager circuit breaker", () => { for (let i = 0; i < 20; i++) { manager.handleEvent({ type: "message.part.updated", - properties: { sessionID: task.sessionID, type: "tool", tool: "read" }, + properties: { sessionID: task.sessionId, type: "tool", tool: "read" }, }) } @@ -87,9 +87,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-diverse-1", - sessionID: "session-diverse-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-diverse-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Healthy task", prompt: "work", agent: "explore", @@ -116,7 +116,7 @@ describe("BackgroundManager circuit breaker", () => { ]) { manager.handleEvent({ type: "message.part.updated", - properties: { sessionID: task.sessionID, type: "tool", tool: toolName }, + properties: { sessionID: task.sessionId, type: "tool", tool: toolName }, }) } @@ -137,9 +137,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-cap-1", - sessionID: "session-cap-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-cap-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Backstop task", prompt: "work", agent: "explore", @@ -155,7 +155,7 @@ describe("BackgroundManager circuit breaker", () => { for (let i = 0; i < 3; i++) { manager.handleEvent({ type: "message.part.updated", - properties: { sessionID: task.sessionID, type: "tool", tool: "read" }, + properties: { sessionID: task.sessionId, type: "tool", tool: "read" }, }) } @@ -176,9 +176,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-dedupe-1", - sessionID: "session-dedupe-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-dedupe-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Dedupe task", prompt: "work", agent: "explore", @@ -197,7 +197,7 @@ describe("BackgroundManager circuit breaker", () => { properties: { part: { id: "tool-1", - sessionID: task.sessionID, + sessionID: task.sessionId, type: "tool", tool: "bash", state: { status: "running" }, @@ -223,9 +223,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-diff-files-1", - sessionID: "session-diff-files-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-diff-files-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Reading different files", prompt: "work", agent: "explore", @@ -243,7 +243,7 @@ describe("BackgroundManager circuit breaker", () => { type: "message.part.updated", properties: { part: { - sessionID: task.sessionID, + sessionID: task.sessionId, type: "tool", tool: "read", state: { status: "running", input: { filePath: `/src/file-${i}.ts` } }, @@ -268,9 +268,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-same-file-1", - sessionID: "session-same-file-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-same-file-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Reading same file repeatedly", prompt: "work", agent: "explore", @@ -288,7 +288,7 @@ describe("BackgroundManager circuit breaker", () => { type: "message.part.updated", properties: { part: { - sessionID: task.sessionID, + sessionID: task.sessionId, type: "tool", tool: "read", state: { status: "running", input: { filePath: "/src/same.ts" } }, @@ -315,9 +315,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-disabled-1", - sessionID: "session-disabled-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-disabled-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Disabled circuit breaker task", prompt: "work", agent: "explore", @@ -334,7 +334,7 @@ describe("BackgroundManager circuit breaker", () => { manager.handleEvent({ type: "message.part.updated", properties: { - sessionID: task.sessionID, + sessionID: task.sessionId, type: "tool", tool: "read", }, @@ -358,9 +358,9 @@ describe("BackgroundManager circuit breaker", () => { }) const task: BackgroundTask = { id: "task-cap-disabled-1", - sessionID: "session-cap-disabled-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-cap-disabled-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Backstop task with disabled circuit breaker", prompt: "work", agent: "explore", @@ -376,7 +376,7 @@ describe("BackgroundManager circuit breaker", () => { for (const toolName of ["read", "grep", "edit"]) { manager.handleEvent({ type: "message.part.updated", - properties: { sessionID: task.sessionID, type: "tool", tool: toolName }, + properties: { sessionID: task.sessionId, type: "tool", tool: toolName }, }) } diff --git a/src/features/background-agent/manager-session-permission.test.ts b/src/features/background-agent/manager-session-permission.test.ts index 83c5139be..a9f4a1756 100644 --- a/src/features/background-agent/manager-session-permission.test.ts +++ b/src/features/background-agent/manager-session-permission.test.ts @@ -21,15 +21,15 @@ describe("BackgroundManager session permission", () => { }, } const directory = tmpdir() - const manager = new BackgroundManager({ client, directory } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory } as unknown as PluginInput }) // when await manager.launch({ description: "Test task", prompt: "Do something", agent: "explore", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) await new Promise((resolve) => setTimeout(resolve, 50)) manager.shutdown() @@ -62,15 +62,15 @@ describe("BackgroundManager session permission", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) // when await manager.launch({ description: "Test task", prompt: "Do something", agent: "explore", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", sessionPermission: [ { permission: "question", action: "deny", pattern: "*" }, ], diff --git a/src/features/background-agent/manager-shutdown-global-cleanup.test.ts b/src/features/background-agent/manager-shutdown-global-cleanup.test.ts index ef0be8dcf..f3b436983 100644 --- a/src/features/background-agent/manager-shutdown-global-cleanup.test.ts +++ b/src/features/background-agent/manager-shutdown-global-cleanup.test.ts @@ -20,10 +20,10 @@ function createDeferredPromise(): { } } -function createTask(overrides: Partial & { id: string; sessionID: string }): BackgroundTask { +function createTask(overrides: Partial & { id: string; sessionId: string }): BackgroundTask { return { - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", description: "test task", prompt: "test prompt", agent: "explore", @@ -34,7 +34,7 @@ function createTask(overrides: Partial & { id: string; sessionID } function createBackgroundManager(): BackgroundManager { - return new BackgroundManager({ + return new BackgroundManager({ pluginContext: { client: { session: { abort: async () => ({}), @@ -47,7 +47,7 @@ function createBackgroundManager(): BackgroundManager { worktree: tmpdir(), serverUrl: new URL("https://example.com"), $: {} as never, - } as never) + } as never }) } describe("BackgroundManager shutdown global cleanup", () => { @@ -74,14 +74,14 @@ describe("BackgroundManager shutdown global cleanup", () => { "task-running-shutdown-cleanup", createTask({ id: "task-running-shutdown-cleanup", - sessionID: runningSessionID, + sessionId: runningSessionID, }), ], [ "task-completed-shutdown-cleanup", createTask({ id: "task-completed-shutdown-cleanup", - sessionID: completedSessionID, + sessionId: completedSessionID, status: "completed", completedAt: new Date(), }), @@ -119,7 +119,7 @@ describe("BackgroundManager shutdown global cleanup", () => { "task-running-await-shutdown", createTask({ id: "task-running-await-shutdown", - sessionID: runningSessionID, + sessionId: runningSessionID, }), ], ]) diff --git a/src/features/background-agent/manager.polling.test.ts b/src/features/background-agent/manager.polling.test.ts index 6b3a38f9c..3bcceaf13 100644 --- a/src/features/background-agent/manager.polling.test.ts +++ b/src/features/background-agent/manager.polling.test.ts @@ -18,7 +18,7 @@ function createManagerWithStatus(statusImpl: () => Promise<{ data: Record { @@ -56,12 +56,12 @@ describe("BackgroundManager polling overlap", () => { }) -function createRunningTask(sessionID: string): BackgroundTask { +function createRunningTask(sessionId: string): BackgroundTask { return { - id: `bg_test_${sessionID}`, - sessionID, - parentSessionID: "parent-session", - parentMessageID: "parent-msg", + id: `bg_test_${sessionId}`, + sessionId, + parentSessionId: "parent-session", + parentMessageId: "parent-msg", description: "test task", prompt: "test", agent: "explore", @@ -98,9 +98,7 @@ function createManagerWithClient(clientOverrides: Record = {}): }, } return new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - undefined, - { enableParentSessionNotifications: false }, + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: undefined, enableParentSessionNotifications: false }, ) } diff --git a/src/features/background-agent/manager.test.ts b/src/features/background-agent/manager.test.ts index 5c099d5f1..f7aae5b46 100644 --- a/src/features/background-agent/manager.test.ts +++ b/src/features/background-agent/manager.test.ts @@ -40,33 +40,33 @@ class MockBackgroundManager { return this.tasks.get(id) } - findBySession(sessionID: string): BackgroundTask | undefined { + findBySession(sessionId: string): BackgroundTask | undefined { for (const task of this.tasks.values()) { - if (task.sessionID === sessionID) { + if (task.sessionId === sessionId) { return task } } return undefined } - getTasksByParentSession(sessionID: string): BackgroundTask[] { + getTasksByParentSession(sessionId: string): BackgroundTask[] { const result: BackgroundTask[] = [] for (const task of this.tasks.values()) { - if (task.parentSessionID === sessionID) { + if (task.parentSessionId === sessionId) { result.push(task) } } return result } - getAllDescendantTasks(sessionID: string): BackgroundTask[] { + getAllDescendantTasks(sessionId: string): BackgroundTask[] { const result: BackgroundTask[] = [] - const directChildren = this.getTasksByParentSession(sessionID) + const directChildren = this.getTasksByParentSession(sessionId) for (const child of directChildren) { result.push(child) - if (child.sessionID) { - const descendants = this.getAllDescendantTasks(child.sessionID) + if (child.sessionId) { + const descendants = this.getAllDescendantTasks(child.sessionId) result.push(...descendants) } } @@ -75,22 +75,22 @@ class MockBackgroundManager { } markForNotification(task: BackgroundTask): void { - const queue = this.notifications.get(task.parentSessionID) ?? [] + const queue = this.notifications.get(task.parentSessionId) ?? [] queue.push(task) - this.notifications.set(task.parentSessionID, queue) + this.notifications.set(task.parentSessionId, queue) } - getPendingNotifications(sessionID: string): BackgroundTask[] { - return this.notifications.get(sessionID) ?? [] + getPendingNotifications(sessionId: string): BackgroundTask[] { + return this.notifications.get(sessionId) ?? [] } private clearNotificationsForTask(taskId: string): void { - for (const [sessionID, tasks] of this.notifications.entries()) { + for (const [sessionId, tasks] of this.notifications.entries()) { const filtered = tasks.filter((t) => t.id !== taskId) if (filtered.length === 0) { - this.notifications.delete(sessionID) + this.notifications.delete(sessionId) } else { - this.notifications.set(sessionID, filtered) + this.notifications.set(sessionId, filtered) } } } @@ -110,9 +110,9 @@ class MockBackgroundManager { } } - for (const [sessionID, notifications] of this.notifications.entries()) { + for (const [sessionId, notifications] of this.notifications.entries()) { if (notifications.length === 0) { - this.notifications.delete(sessionID) + this.notifications.delete(sessionId) continue } const validNotifications = notifications.filter((task) => { @@ -123,9 +123,9 @@ class MockBackgroundManager { const removed = notifications.length - validNotifications.length prunedNotifications += removed if (validNotifications.length === 0) { - this.notifications.delete(sessionID) + this.notifications.delete(sessionId) } else if (validNotifications.length !== notifications.length) { - this.notifications.set(sessionID, validNotifications) + this.notifications.set(sessionId, validNotifications) } } @@ -159,8 +159,8 @@ class MockBackgroundManager { existingTask.status = "running" existingTask.completedAt = undefined existingTask.error = undefined - existingTask.parentSessionID = input.parentSessionID - existingTask.parentMessageID = input.parentMessageID + existingTask.parentSessionId = input.parentSessionId + existingTask.parentMessageId = input.parentMessageId existingTask.parentModel = input.parentModel existingTask.progress = { @@ -172,9 +172,9 @@ class MockBackgroundManager { } } -function createMockTask(overrides: Partial & { id: string; parentSessionID: string; sessionID?: string }): BackgroundTask { +function createMockTask(overrides: Partial & { id: string; parentSessionId: string; sessionId?: string }): BackgroundTask { return { - parentMessageID: "mock-message-id", + parentMessageId: "mock-message-id", description: "test task", prompt: "test prompt", agent: "test-agent", @@ -192,7 +192,7 @@ function createBackgroundManager(): BackgroundManager { abort: async () => ({}), }, } - return new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + return new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) } function createBackgroundManagerWithOptions(options: unknown): BackgroundManager { @@ -204,9 +204,7 @@ function createBackgroundManagerWithOptions(options: unknown): BackgroundManager }, } return new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - undefined, - options as ConstructorParameters[2], + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: undefined, ...options as ConstructorParameters[2] }, ) } @@ -292,8 +290,8 @@ describe("BackgroundManager session.error fallback hydration", () => { const fallbackChain = [ { model: "fallback-model-1", providers: ["provider-a"], variant: undefined }, ] - const getSessionFallbackChain = mock((sessionID: string) => - sessionID === "child-session" ? fallbackChain : undefined, + const getSessionFallbackChain = mock((sessionId: string) => + sessionId === "child-session" ? fallbackChain : undefined, ) const manager = createBackgroundManagerWithOptions({ modelFallbackControllerAccessor: { @@ -302,8 +300,8 @@ describe("BackgroundManager session.error fallback hydration", () => { }) const task = createMockTask({ id: "task-sync-fallback", - sessionID: "child-session", - parentSessionID: "parent-session", + sessionId: "child-session", + parentSessionId: "parent-session", fallbackChain: undefined, }) let capturedFallbackChain: BackgroundTask["fallbackChain"] @@ -356,7 +354,7 @@ describe("BackgroundManager prompt rejection fallback routing", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) ;(manager as unknown as { reserveSubagentSpawn: () => Promise<{ @@ -386,8 +384,8 @@ describe("BackgroundManager prompt rejection fallback routing", () => { description: "background retry test", prompt: "say hi", agent: "sisyphus-junior", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "genai-proxy-openai", modelID: "gpt-5.4-mini" }, fallbackChain: [{ model: "claude-haiku-4-5", providers: ["anthropic"] }], }) @@ -418,13 +416,13 @@ describe("BackgroundManager prompt rejection fallback routing", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "bg_resume_retry", - sessionID: "ses_resume_retry", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + sessionId: "ses_resume_retry", + parentSessionId: "parent-session", + parentMessageId: "parent-message", description: "resume retry test", prompt: "say hi", agent: "sisyphus-junior", @@ -450,8 +448,8 @@ describe("BackgroundManager prompt rejection fallback routing", () => { await manager.resume({ sessionId: "ses_resume_retry", prompt: "continue", - parentSessionID: "parent-session", - parentMessageID: "parent-message-2", + parentSessionId: "parent-session", + parentMessageId: "parent-message-2", }) await flushBackgroundNotifications() @@ -475,20 +473,20 @@ describe("BackgroundManager retry observability", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task = createMockTask({ id: "bg_retry_observable", - parentSessionID: "parent-session", + parentSessionId: "parent-session", fallbackChain: [{ model: "claude-haiku-4-5", providers: ["anthropic"] }], attemptCount: 0, status: "running", attempts: [ { - attemptID: "att_retry_visibility", + attemptId: "att_retry_visibility", attemptNumber: 1, - sessionID: "ses_retry_visibility", - providerID: "genai-proxy-openai", - modelID: "gpt-5.4-mini", + sessionId: "ses_retry_visibility", + providerId: "genai-proxy-openai", + modelId: "gpt-5.4-mini", status: "running", }, ], @@ -497,7 +495,7 @@ describe("BackgroundManager retry observability", () => { getTaskMap(manager).set(task.id, task) const queuePendingNotification = mock(() => {}) ;(manager as unknown as { - queuePendingNotification: (sessionID: string | undefined, notification: string) => void + queuePendingNotification: (sessionId: string | undefined, notification: string) => void }).queuePendingNotification = queuePendingNotification //#when @@ -528,13 +526,13 @@ describe("BackgroundManager retry observability", () => { promptAsync: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) ;(manager as unknown as { - queuePendingNotification: (sessionID: string | undefined, notification: string) => void + queuePendingNotification: (sessionId: string | undefined, notification: string) => void }).queuePendingNotification = queuePendingNotification const task = createMockTask({ id: "bg_retry_ready", - parentSessionID: "parent-session", + parentSessionId: "parent-session", status: "pending", attemptCount: 1, queuedAt: new Date(), @@ -546,19 +544,19 @@ describe("BackgroundManager retry observability", () => { }, attempts: [ { - attemptID: "att_retry_failed", + attemptId: "att_retry_failed", attemptNumber: 1, - sessionID: "ses_retry_visibility", - providerID: "genai-proxy-openai", - modelID: "gpt-5.4-mini", + sessionId: "ses_retry_visibility", + providerId: "genai-proxy-openai", + modelId: "gpt-5.4-mini", status: "error", error: "Forbidden: Selected provider is forbidden", }, { - attemptID: "att_retry_ready", + attemptId: "att_retry_ready", attemptNumber: 2, - providerID: "anthropic", - modelID: "claude-haiku-4.5", + providerId: "anthropic", + modelId: "claude-haiku-4.5", status: "pending", }, ], @@ -569,8 +567,8 @@ describe("BackgroundManager retry observability", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: task.model, fallbackChain: task.fallbackChain, category: task.category, @@ -583,7 +581,7 @@ describe("BackgroundManager retry observability", () => { const item: RetryReadyQueueItem = { task, input: taskInput, - attemptID: task.currentAttemptID ?? "att_retry_ready", + attemptId: task.currentAttemptID ?? "att_retry_ready", } //#when @@ -616,13 +614,13 @@ describe("BackgroundManager retry observability", () => { promptAsync: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: managerDirectory } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: managerDirectory } as unknown as PluginInput }) ;(manager as unknown as { - queuePendingNotification: (sessionID: string | undefined, notification: string) => void + queuePendingNotification: (sessionId: string | undefined, notification: string) => void }).queuePendingNotification = queuePendingNotification const task = createMockTask({ id: "bg_retry_ready_parent_dir", - parentSessionID: "parent-session", + parentSessionId: "parent-session", status: "pending", attemptCount: 1, queuedAt: new Date(), @@ -632,19 +630,19 @@ describe("BackgroundManager retry observability", () => { }, attempts: [ { - attemptID: "att_retry_failed_parent_dir", + attemptId: "att_retry_failed_parent_dir", attemptNumber: 1, - sessionID: "ses_retry_failed_parent_dir", - providerID: "genai-proxy-openai", - modelID: "gpt-5.4-mini", + sessionId: "ses_retry_failed_parent_dir", + providerId: "genai-proxy-openai", + modelId: "gpt-5.4-mini", status: "error", error: "Forbidden: Selected provider is forbidden", }, { - attemptID: "att_retry_ready_parent_dir", + attemptId: "att_retry_ready_parent_dir", attemptNumber: 2, - providerID: "anthropic", - modelID: "claude-haiku-4.5", + providerId: "anthropic", + modelId: "claude-haiku-4.5", status: "pending", }, ], @@ -655,8 +653,8 @@ describe("BackgroundManager retry observability", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: task.model, fallbackChain: task.fallbackChain, category: task.category, @@ -712,8 +710,8 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // given const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID: "session-a", + sessionId: "session-b", + parentSessionId: "session-a", }) manager.addTask(taskB) @@ -730,13 +728,13 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // Session A -> Task B -> Task C const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID: "session-a", + sessionId: "session-b", + parentSessionId: "session-a", }) const taskC = createMockTask({ id: "task-c", - sessionID: "session-c", - parentSessionID: "session-b", + sessionId: "session-c", + parentSessionId: "session-b", }) manager.addTask(taskB) manager.addTask(taskC) @@ -755,18 +753,18 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // Session A -> Task B -> Task C -> Task D const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID: "session-a", + sessionId: "session-b", + parentSessionId: "session-a", }) const taskC = createMockTask({ id: "task-c", - sessionID: "session-c", - parentSessionID: "session-b", + sessionId: "session-c", + parentSessionId: "session-b", }) const taskD = createMockTask({ id: "task-d", - sessionID: "session-d", - parentSessionID: "session-c", + sessionId: "session-d", + parentSessionId: "session-c", }) manager.addTask(taskB) manager.addTask(taskC) @@ -788,23 +786,23 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // -> Task B2 -> Task C2 const taskB1 = createMockTask({ id: "task-b1", - sessionID: "session-b1", - parentSessionID: "session-a", + sessionId: "session-b1", + parentSessionId: "session-a", }) const taskB2 = createMockTask({ id: "task-b2", - sessionID: "session-b2", - parentSessionID: "session-a", + sessionId: "session-b2", + parentSessionId: "session-a", }) const taskC1 = createMockTask({ id: "task-c1", - sessionID: "session-c1", - parentSessionID: "session-b1", + sessionId: "session-c1", + parentSessionId: "session-b1", }) const taskC2 = createMockTask({ id: "task-c2", - sessionID: "session-c2", - parentSessionID: "session-b2", + sessionId: "session-c2", + parentSessionId: "session-b2", }) manager.addTask(taskB1) manager.addTask(taskB2) @@ -828,13 +826,13 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // Session X -> Task Y (unrelated) const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID: "session-a", + sessionId: "session-b", + parentSessionId: "session-a", }) const taskY = createMockTask({ id: "task-y", - sessionID: "session-y", - parentSessionID: "session-x", + sessionId: "session-y", + parentSessionId: "session-x", }) manager.addTask(taskB) manager.addTask(taskY) @@ -853,13 +851,13 @@ describe("BackgroundManager.getAllDescendantTasks", () => { // Session A -> Task B -> Task C const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID: "session-a", + sessionId: "session-b", + parentSessionId: "session-a", }) const taskC = createMockTask({ id: "task-c", - sessionID: "session-c", - parentSessionID: "session-b", + sessionId: "session-c", + parentSessionId: "session-b", }) manager.addTask(taskB) manager.addTask(taskC) @@ -953,8 +951,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications", () => { // given const task = createMockTask({ id: "task-fresh", - sessionID: "session-fresh", - parentSessionID: "session-parent", + sessionId: "session-fresh", + parentSessionId: "session-parent", startedAt: new Date(), }) manager.addTask(task) @@ -972,8 +970,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications", () => { const staleDate = new Date(Date.now() - 31 * 60 * 1000) const task = createMockTask({ id: "task-stale", - sessionID: "session-stale", - parentSessionID: "session-parent", + sessionId: "session-stale", + parentSessionId: "session-parent", startedAt: staleDate, }) manager.addTask(task) @@ -991,8 +989,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications", () => { const staleDate = new Date(Date.now() - 31 * 60 * 1000) const task = createMockTask({ id: "task-stale", - sessionID: "session-stale", - parentSessionID: "session-parent", + sessionId: "session-stale", + parentSessionId: "session-parent", startedAt: staleDate, }) manager.markForNotification(task) @@ -1010,8 +1008,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications", () => { const staleDate = new Date(Date.now() - 31 * 60 * 1000) const task = createMockTask({ id: "task-stale", - sessionID: "session-stale", - parentSessionID: "session-parent", + sessionId: "session-stale", + parentSessionId: "session-parent", startedAt: staleDate, }) manager.addTask(task) @@ -1030,14 +1028,14 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications", () => { const staleDate = new Date(Date.now() - 31 * 60 * 1000) const staleTask = createMockTask({ id: "task-stale", - sessionID: "session-stale", - parentSessionID: "session-parent", + sessionId: "session-stale", + parentSessionId: "session-parent", startedAt: staleDate, }) const freshTask = createMockTask({ id: "task-fresh", - sessionID: "session-fresh", - parentSessionID: "session-parent", + sessionId: "session-fresh", + parentSessionId: "session-parent", startedAt: new Date(), }) manager.addTask(staleTask) @@ -1067,8 +1065,8 @@ describe("BackgroundManager.resume", () => { expect(() => manager.resume({ sessionId: "non-existent", prompt: "continue", - parentSessionID: "session-new", - parentMessageID: "msg-new", + parentSessionId: "session-new", + parentMessageId: "msg-new", })).toThrow("Task not found for session: non-existent") }) @@ -1076,8 +1074,8 @@ describe("BackgroundManager.resume", () => { // given const completedTask = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID: "session-parent", + sessionId: "session-a", + parentSessionId: "session-parent", status: "completed", }) completedTask.completedAt = new Date() @@ -1088,24 +1086,24 @@ describe("BackgroundManager.resume", () => { const result = manager.resume({ sessionId: "session-a", prompt: "continue the work", - parentSessionID: "session-new-parent", - parentMessageID: "msg-new", + parentSessionId: "session-new-parent", + parentMessageId: "msg-new", }) // then expect(result.status).toBe("running") expect(result.completedAt).toBeUndefined() expect(result.error).toBeUndefined() - expect(result.parentSessionID).toBe("session-new-parent") - expect(result.parentMessageID).toBe("msg-new") + expect(result.parentSessionId).toBe("session-new-parent") + expect(result.parentMessageId).toBe("msg-new") }) test("should preserve task identity while updating parent context", () => { // given const existingTask = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID: "old-parent", + sessionId: "session-a", + parentSessionId: "old-parent", description: "original description", agent: "explore", status: "completed", @@ -1116,14 +1114,14 @@ describe("BackgroundManager.resume", () => { const result = manager.resume({ sessionId: "session-a", prompt: "new prompt", - parentSessionID: "new-parent", - parentMessageID: "new-msg", + parentSessionId: "new-parent", + parentMessageId: "new-msg", parentModel: { providerID: "anthropic", modelID: "claude-opus" }, }) // then expect(result.id).toBe("task-a") - expect(result.sessionID).toBe("session-a") + expect(result.sessionId).toBe("session-a") expect(result.description).toBe("original description") expect(result.agent).toBe("explore") expect(result.parentModel).toEqual({ providerID: "anthropic", modelID: "claude-opus" }) @@ -1133,8 +1131,8 @@ describe("BackgroundManager.resume", () => { // given const task = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID: "session-parent", + sessionId: "session-a", + parentSessionId: "session-parent", status: "completed", }) manager.addTask(task) @@ -1143,8 +1141,8 @@ describe("BackgroundManager.resume", () => { manager.resume({ sessionId: "session-a", prompt: "continue with additional context", - parentSessionID: "session-new", - parentMessageID: "msg-new", + parentSessionId: "session-new", + parentMessageId: "msg-new", }) // then @@ -1159,8 +1157,8 @@ describe("BackgroundManager.resume", () => { // given const taskWithProgress = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID: "session-parent", + sessionId: "session-a", + parentSessionId: "session-parent", status: "completed", }) taskWithProgress.progress = { @@ -1174,8 +1172,8 @@ describe("BackgroundManager.resume", () => { const result = manager.resume({ sessionId: "session-a", prompt: "continue", - parentSessionID: "session-new", - parentMessageID: "msg-new", + parentSessionId: "session-new", + parentMessageId: "msg-new", }) // then @@ -1186,8 +1184,8 @@ describe("BackgroundManager.resume", () => { // given const runningTask = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID: "session-parent", + sessionId: "session-a", + parentSessionId: "session-parent", status: "running", }) manager.addTask(runningTask) @@ -1196,12 +1194,12 @@ describe("BackgroundManager.resume", () => { const result = manager.resume({ sessionId: "session-a", prompt: "resume should be ignored", - parentSessionID: "new-parent", - parentMessageID: "new-msg", + parentSessionId: "new-parent", + parentMessageId: "new-msg", }) // then - expect(result.parentSessionID).toBe("session-parent") + expect(result.parentSessionId).toBe("session-parent") expect(manager.resumeCalls).toHaveLength(0) }) }) @@ -1213,8 +1211,8 @@ describe("LaunchInput.skillContent", () => { description: "test", prompt: "test prompt", agent: "explore", - parentSessionID: "parent-session", - parentMessageID: "parent-msg", + parentSessionId: "parent-session", + parentMessageId: "parent-msg", } // when / then @@ -1227,8 +1225,8 @@ describe("LaunchInput.skillContent", () => { description: "test", prompt: "test prompt", agent: "explore", - parentSessionID: "parent-session", - parentMessageID: "parent-msg", + parentSessionId: "parent-session", + parentMessageId: "parent-msg", skillContent: "You are a playwright expert", } @@ -1272,12 +1270,12 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () => }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-skip-compaction", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task with compaction at tail", prompt: "test", agent: "explore", @@ -1303,9 +1301,9 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () => // given const task: BackgroundTask = { id: "task-1", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task with dynamic lookup", prompt: "test", agent: "explore", @@ -1332,9 +1330,9 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () => // given const task: BackgroundTask = { id: "task-2", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task fallback agent", prompt: "test", agent: "explore", @@ -1358,9 +1356,9 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () => // given - model missing modelID const task: BackgroundTask = { id: "task-3", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task incomplete model", prompt: "test", agent: "explore", @@ -1387,9 +1385,9 @@ describe("BackgroundManager.notifyParentSession - dynamic message lookup", () => // given - no message found (messageDir lookup failed) const task: BackgroundTask = { id: "task-4", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task no message", prompt: "test", agent: "explore", @@ -1429,12 +1427,12 @@ describe("BackgroundManager.notifyParentSession - aborted parent", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-aborted-parent", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task aborted parent", prompt: "test", agent: "explore", @@ -1471,12 +1469,12 @@ describe("BackgroundManager.notifyParentSession - aborted parent", () => { messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-aborted-prompt", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task aborted prompt", prompt: "test", agent: "explore", @@ -1511,12 +1509,12 @@ describe("BackgroundManager.notifyParentSession - aborted parent", () => { messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-aborted-idle-queue", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task idle queue", prompt: "test", agent: "explore", @@ -1568,15 +1566,13 @@ describe("BackgroundManager.notifyParentSession - notifications toggle", () => { }, } const manager = new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - undefined, - { enableParentSessionNotifications: false }, + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: undefined, enableParentSessionNotifications: false }, ) const task: BackgroundTask = { id: "task-no-parent-notification", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task notifications disabled", prompt: "test", agent: "explore", @@ -1623,12 +1619,12 @@ describe("BackgroundManager.notifyParentSession - variant propagation", () => { }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-parent-variant-wins", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task with mismatched variant", prompt: "test", agent: "explore", @@ -1664,12 +1660,12 @@ describe("BackgroundManager.notifyParentSession - variant propagation", () => { messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-no-variant", - sessionID: "session-child", - parentSessionID: "session-parent", - parentMessageID: "msg-parent", + sessionId: "session-child", + parentSessionId: "session-parent", + parentMessageId: "msg-parent", description: "task without variant", prompt: "test", agent: "explore", @@ -1759,9 +1755,9 @@ describe("BackgroundManager.tryCompleteTask", () => { const task: BackgroundTask = { id: "task-1", - sessionID: "session-1", - parentSessionID: "session-parent", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "session-parent", + parentMessageId: "msg-1", description: "test task", prompt: "test", agent: "explore", @@ -1788,9 +1784,9 @@ describe("BackgroundManager.tryCompleteTask", () => { const task: BackgroundTask = { id: "task-1", - sessionID: "session-1", - parentSessionID: "session-parent", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "session-parent", + parentMessageId: "msg-1", description: "test task", prompt: "test", agent: "explore", @@ -1824,14 +1820,14 @@ describe("BackgroundManager.tryCompleteTask", () => { }, } manager.shutdown() - manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-1", - sessionID: "session-1", - parentSessionID: "session-parent", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "session-parent", + parentMessageId: "msg-1", description: "test task", prompt: "test", agent: "explore", @@ -1859,13 +1855,13 @@ describe("BackgroundManager.tryCompleteTask", () => { }, } manager.shutdown() - manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-pending-cleanup", - sessionID: "session-pending-cleanup", - parentSessionID: "parent-pending-cleanup", - parentMessageID: "msg-1", + sessionId: "session-pending-cleanup", + parentSessionId: "parent-pending-cleanup", + parentMessageId: "msg-1", description: "pending cleanup task", prompt: "test", agent: "explore", @@ -1873,14 +1869,14 @@ describe("BackgroundManager.tryCompleteTask", () => { startedAt: new Date(), } getTaskMap(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) // when await tryCompleteTaskForTest(manager, task) // then expect(task.status).toBe("completed") - expect(getPendingByParent(manager).get(task.parentSessionID)).toBeUndefined() + expect(getPendingByParent(manager).get(task.parentSessionId)).toBeUndefined() }) test("should remove toast tracking before notifying completed task", async () => { @@ -1889,9 +1885,9 @@ describe("BackgroundManager.tryCompleteTask", () => { const task: BackgroundTask = { id: "task-toast-complete", - sessionID: "session-toast-complete", - parentSessionID: "parent-toast-complete", - parentMessageID: "msg-1", + sessionId: "session-toast-complete", + parentSessionId: "parent-toast-complete", + parentMessageId: "msg-1", description: "toast completion task", prompt: "test", agent: "explore", @@ -1917,8 +1913,8 @@ describe("BackgroundManager.tryCompleteTask", () => { const task = createMockTask({ id: "task-process-key-concurrency", - sessionID: "session-process-key-concurrency", - parentSessionID: "parent-process-key-concurrency", + sessionId: "session-process-key-concurrency", + parentSessionId: "parent-process-key-concurrency", status: "pending", agent: "explore", }) @@ -1926,8 +1922,8 @@ describe("BackgroundManager.tryCompleteTask", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: { providerID: "anthropic", modelID: "claude-opus-4.7" }, } getTaskMap(manager).set(task.id, task) @@ -1952,19 +1948,19 @@ describe("BackgroundManager.tryCompleteTask", () => { const task = createMockTask({ id: "task-zombie-session", - sessionID: "session-zombie-placeholder", - parentSessionID: "parent-zombie", + sessionId: "session-zombie-placeholder", + parentSessionId: "parent-zombie", status: "pending", agent: "explore", }) - delete (task as Partial).sessionID + delete (task as Partial).sessionId const input = { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: { providerID: "anthropic", modelID: "claude-opus-4.7" }, } getTaskMap(manager).set(task.id, task) @@ -1972,7 +1968,7 @@ describe("BackgroundManager.tryCompleteTask", () => { ;(manager as unknown as { startTask: (item: { task: BackgroundTask; input: typeof input }) => Promise }).startTask = async (item) => { item.task.status = "running" - item.task.sessionID = "ses_zombie_child" + item.task.sessionId = "ses_zombie_child" item.task.startedAt = new Date() item.task.concurrencyKey = concurrencyKey throw new Error("crash between session creation and prompt send") @@ -1994,8 +1990,8 @@ describe("BackgroundManager.tryCompleteTask", () => { const task = createMockTask({ id: "task-process-key-interrupt", - sessionID: "session-process-key-interrupt", - parentSessionID: "parent-process-key-interrupt", + sessionId: "session-process-key-interrupt", + parentSessionId: "parent-process-key-interrupt", status: "interrupt", agent: "explore", }) @@ -2003,8 +1999,8 @@ describe("BackgroundManager.tryCompleteTask", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: { providerID: "anthropic", modelID: "claude-opus-4.7" }, } getTaskMap(manager).set(task.id, task) @@ -2069,18 +2065,18 @@ describe("BackgroundManager.tryCompleteTask", () => { } manager.shutdown() - manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const parentSessionID = "parent-session" const taskA = createMockTask({ id: "task-a", - sessionID: "session-a", - parentSessionID, + sessionId: "session-a", + parentSessionId: parentSessionID, }) const taskB = createMockTask({ id: "task-b", - sessionID: "session-b", - parentSessionID, + sessionId: "session-b", + parentSessionId: parentSessionID, }) getTaskMap(manager).set(taskA.id, taskA) @@ -2129,8 +2125,8 @@ describe("BackgroundManager.trackTask", () => { // given const input = { taskId: "task-1", - sessionID: "session-1", - parentSessionID: "parent-session", + sessionId: "session-1", + parentSessionId: "parent-session", description: "external task", agent: "task", concurrencyKey: "external-key", @@ -2164,8 +2160,8 @@ describe("BackgroundManager.resume concurrency key", () => { // given const task = await manager.trackTask({ taskId: "task-1", - sessionID: "session-1", - parentSessionID: "parent-session", + sessionId: "session-1", + parentSessionId: "parent-session", description: "external task", agent: "task", concurrencyKey: "external-key", @@ -2177,8 +2173,8 @@ describe("BackgroundManager.resume concurrency key", () => { await manager.resume({ sessionId: "session-1", prompt: "resume", - parentSessionID: "parent-session-2", - parentMessageID: "msg-2", + parentSessionId: "parent-session-2", + parentMessageId: "msg-2", }) // then @@ -2206,7 +2202,7 @@ describe("BackgroundManager.resume model persistence", () => { abort: async () => ({}), }, } - manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) }) @@ -2221,9 +2217,9 @@ describe("BackgroundManager.resume model persistence", () => { // given - task with model from category config const taskWithModel: BackgroundTask = { id: "task-with-model", - sessionID: "session-1", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "task with model override", prompt: "original prompt", agent: "explore", @@ -2239,8 +2235,8 @@ describe("BackgroundManager.resume model persistence", () => { await manager.resume({ sessionId: "session-1", prompt: "continue the work", - parentSessionID: "parent-session-2", - parentMessageID: "msg-2", + parentSessionId: "parent-session-2", + parentMessageId: "msg-2", }) // then @@ -2253,9 +2249,9 @@ describe("BackgroundManager.resume model persistence", () => { // given - task resumed after fallback promotion const taskWithAdvancedModel: BackgroundTask = { id: "task-with-advanced-model", - sessionID: "session-advanced", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-advanced", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "task with advanced model settings", prompt: "original prompt", agent: "explore", @@ -2280,8 +2276,8 @@ describe("BackgroundManager.resume model persistence", () => { await manager.resume({ sessionId: "session-advanced", prompt: "continue the work", - parentSessionID: "parent-session-2", - parentMessageID: "msg-2", + parentSessionId: "parent-session-2", + parentMessageId: "msg-2", }) // then @@ -2307,9 +2303,9 @@ describe("BackgroundManager.resume model persistence", () => { // given - task without model (default behavior) const taskWithoutModel: BackgroundTask = { id: "task-no-model", - sessionID: "session-2", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-2", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "task without model", prompt: "original prompt", agent: "explore", @@ -2324,8 +2320,8 @@ describe("BackgroundManager.resume model persistence", () => { await manager.resume({ sessionId: "session-2", prompt: "continue the work", - parentSessionID: "parent-session-2", - parentMessageID: "msg-2", + parentSessionId: "parent-session-2", + parentMessageId: "msg-2", }) // then @@ -2410,7 +2406,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { beforeEach(() => { // given mockClient = createMockClient() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput }) }) afterEach(() => { @@ -2424,8 +2420,8 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2438,7 +2434,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { expect(task.agent).toBe("test-agent") expect(task.queuedAt).toBeInstanceOf(Date) expect(task.startedAt).toBeUndefined() - expect(task.sessionID).toBeUndefined() + expect(task.sessionId).toBeUndefined() }) test("should initialize attempt state for a newly launched task", async () => { @@ -2447,8 +2443,8 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "openai", modelID: "gpt-5.4-mini", @@ -2461,12 +2457,12 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // then expect(task.attempts).toHaveLength(1) - expect(task.currentAttemptID).toBe(task.attempts?.[0]?.attemptID) + expect(task.currentAttemptID).toBe(task.attempts?.[0]?.attemptId) expect(task.attempts?.[0]).toEqual({ - attemptID: task.currentAttemptID, + attemptId: task.currentAttemptID, attemptNumber: 1, - providerID: "openai", - modelID: "gpt-5.4-mini", + providerId: "openai", + modelId: "gpt-5.4-mini", variant: "medium", status: "pending", }) @@ -2475,21 +2471,21 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { expect(task.model).toEqual(input.model) expect(task.queuedAt).toBeInstanceOf(Date) expect(task.startedAt).toBeUndefined() - expect(task.sessionID).toBeUndefined() + expect(task.sessionId).toBeUndefined() }) test("should return immediately even with concurrency limit", async () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2537,22 +2533,22 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, } manager.shutdown() - manager = new BackgroundManager({ client: customClient, directory: tmpdir() } as unknown as PluginInput) + manager = new BackgroundManager({ pluginContext: { client: customClient, directory: tmpdir() } as unknown as PluginInput }) const launchInputWithModel = { description: "Test task with model", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "anthropic", modelID: "claude-opus-4.7" }, } const launchInputWithoutModel = { description: "Test task without model", prompt: "Do something else", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2575,14 +2571,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 2 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2628,16 +2624,16 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, } manager.shutdown() - manager = new BackgroundManager({ client: customClient, directory: tmpdir() } as unknown as PluginInput, { + manager = new BackgroundManager({ pluginContext: { client: customClient, directory: tmpdir() } as unknown as PluginInput, config: { defaultConcurrency: 5, - }) + } }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2653,14 +2649,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 5 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2671,22 +2667,22 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { const updatedTask = manager.getTask(task.id) expect(updatedTask?.status).toBe("running") expect(updatedTask?.startedAt).toBeInstanceOf(Date) - expect(updatedTask?.sessionID).toBeDefined() - expect(updatedTask?.sessionID).toBeTruthy() + expect(updatedTask?.sessionId).toBeDefined() + expect(updatedTask?.sessionId).toBeTruthy() }) test("should set startedAt when transitioning to running", async () => { // given const config = { defaultConcurrency: 5 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -2707,30 +2703,29 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-depth-2": { directory: "/test/dir", parentID: "session-depth-1" }, "session-depth-1": { directory: "/test/dir", parentID: "session-root" }, "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, - { maxDepth: 3 }, + } as unknown as PluginInput, config: { maxDepth: 3 } }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-depth-2", - parentMessageID: "parent-message", + parentSessionId: "session-depth-2", + parentMessageId: "parent-message", } // when const task = await manager.launch(input) // then - expect(task.rootSessionID).toBe("session-root") + expect(task.rootSessionId).toBe("session-root") expect(task.spawnDepth).toBe(3) }) @@ -2738,7 +2733,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-depth-3": { directory: "/test/dir", parentID: "session-depth-2" }, "session-depth-2": { directory: "/test/dir", parentID: "session-depth-1" }, @@ -2746,16 +2741,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, - { maxDepth: 3 }, + } as unknown as PluginInput, config: { maxDepth: 3 } }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-depth-3", - parentMessageID: "parent-message", + parentSessionId: "session-depth-3", + parentMessageId: "parent-message", } // when @@ -2769,20 +2763,20 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } await manager.launch(input) @@ -2798,12 +2792,12 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) await manager.reserveSubagentSpawn("session-root") @@ -2822,7 +2816,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain( { "session-root": { directory: "/test/dir" }, @@ -2830,15 +2824,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { { sessionLookupError: new Error("session lookup failed") } ), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } // when @@ -2852,21 +2846,20 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, - { defaultConcurrency: 1 }, + } as unknown as PluginInput, config: { defaultConcurrency: 1 } }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } await manager.launch(input) @@ -2888,7 +2881,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { let createAttempts = 0 manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: { session: { create: async () => { @@ -2909,15 +2902,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, }, directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } await manager.launch(input) @@ -2936,20 +2929,20 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { const concurrencyKey = "test-agent" const task = createMockTask({ id: "task-single-reservation-rollback", - sessionID: "session-single-reservation-rollback", - parentSessionID: "session-root", + sessionId: "session-single-reservation-rollback", + parentSessionId: "session-root", status: "pending", agent: "test-agent", - rootSessionID: "session-root", + rootSessionId: "session-root", }) - delete (task as Partial).sessionID + delete (task as Partial).sessionId const input = { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, } getTaskMap(manager).set(task.id, task) @@ -2988,7 +2981,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: { session: { create: async () => { @@ -3018,16 +3011,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, }, directory: tmpdir(), - } as unknown as PluginInput, - { defaultConcurrency: 1 } + } as unknown as PluginInput, config: { defaultConcurrency: 1 } } ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const firstTask = await manager.launch(input) @@ -3051,7 +3043,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { expect(createCallCount).toBe(2) expect(manager.getTask(firstTask.id)?.status).toBe("cancelled") expect(manager.getTask(secondTask.id)?.status).toBe("running") - expect(manager.getTask(secondTask.id)?.sessionID).toBe(secondSessionID) + expect(manager.getTask(secondTask.id)?.sessionId).toBe(secondSessionID) }) test("should keep sibling launch running when concurrent launches share a parent and the first is cancelled during session creation", async () => { @@ -3071,7 +3063,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: { session: { create: async () => { @@ -3101,16 +3093,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, }, directory: tmpdir(), - } as unknown as PluginInput, - { defaultConcurrency: 1 } + } as unknown as PluginInput, config: { defaultConcurrency: 1 } } ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3136,7 +3127,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { expect(createCallCount).toBe(2) expect(manager.getTask(firstTask.id)?.status).toBe("cancelled") expect(manager.getTask(secondTask.id)?.status).toBe("running") - expect(manager.getTask(secondTask.id)?.sessionID).toBe(secondSessionID) + expect(manager.getTask(secondTask.id)?.sessionId).toBe(secondSessionID) }) test("should keep task cancelled and abort the session when cancellation wins during session creation", async () => { @@ -3156,7 +3147,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: { session: { create: async () => { @@ -3182,16 +3173,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, }, directory: tmpdir(), - } as unknown as PluginInput, - { defaultConcurrency: 1 } + } as unknown as PluginInput, config: { defaultConcurrency: 1 } } ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const task = await manager.launch(input) @@ -3214,7 +3204,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { const updatedTask = manager.getTask(task.id) expect(cancelled).toBe(true) expect(updatedTask?.status).toBe("cancelled") - expect(updatedTask?.sessionID).toBeUndefined() + expect(updatedTask?.sessionId).toBeUndefined() expect(promptAsyncSessionIDs).not.toContain(createdSessionID) expect(abortCalls).toEqual([createdSessionID]) expect(getConcurrencyManager(manager).getCount("test-agent")).toBe(0) @@ -3238,7 +3228,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: { session: { create: async () => ({ data: { id: createdSessionID } }), @@ -3259,12 +3249,9 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { }, }, directory: tmpdir(), - } as unknown as PluginInput, - { + } as unknown as PluginInput, config: { defaultConcurrency: 1, - }, - { - tmuxConfig: { + }, tmuxConfig: { enabled: true, layout: "main-vertical", main_pane_size: 60, @@ -3283,16 +3270,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { source: "test", abortSession: false, }) - }, - } + }, } ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const task = await manager.launch(input) @@ -3308,7 +3294,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // then const updatedTask = manager.getTask(task.id) expect(updatedTask?.status).toBe("cancelled") - expect(updatedTask?.sessionID).toBeUndefined() + expect(updatedTask?.sessionId).toBeUndefined() expect(promptAsyncSessionIDs).not.toContain(createdSessionID) expect(abortCalls).toEqual([createdSessionID]) expect(getConcurrencyManager(manager).getCount("test-agent")).toBe(0) @@ -3327,12 +3313,12 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { test("allows relaunch after task completes", async () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) stubNotifyParentSession(manager) @@ -3340,15 +3326,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } const task = await manager.launch(input) const internalTask = getTaskMap(manager).get(task.id)! internalTask.status = "running" - internalTask.sessionID = "child-session-complete" - internalTask.rootSessionID = "session-root" + internalTask.sessionId = "child-session-complete" + internalTask.rootSessionId = "session-root" // Complete via internal method (session.status events go through the poller, not handleEvent) await tryCompleteTaskForTest(manager, internalTask) @@ -3359,26 +3345,26 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { test("allows relaunch after running task is cancelled", async () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } const task = await manager.launch(input) const internalTask = getTaskMap(manager).get(task.id)! internalTask.status = "running" - internalTask.sessionID = "child-session-cancel" + internalTask.sessionId = "child-session-cancel" await manager.cancelTask(task.id) @@ -3388,30 +3374,30 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { test("allows relaunch after task errors", async () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } const task = await manager.launch(input) const internalTask = getTaskMap(manager).get(task.id)! internalTask.status = "running" - internalTask.sessionID = "child-session-error" + internalTask.sessionId = "child-session-error" manager.handleEvent({ type: "session.error", - properties: { sessionID: internalTask.sessionID, info: { id: internalTask.sessionID } }, + properties: { sessionID: internalTask.sessionId, info: { id: internalTask.sessionId } }, }) await new Promise((resolve) => setTimeout(resolve, 100)) @@ -3421,20 +3407,20 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { test("allows repeated relaunch after pending tasks are cancelled", async () => { manager.shutdown() manager = new BackgroundManager( - { + { pluginContext: { client: createMockClientWithSessionChain({ "session-root": { directory: "/test/dir" }, }), directory: tmpdir(), - } as unknown as PluginInput, + } as unknown as PluginInput }, ) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "session-root", - parentMessageID: "parent-message", + parentSessionId: "session-root", + parentMessageId: "parent-message", } const task1 = await manager.launch(input) @@ -3453,14 +3439,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const task1 = await manager.launch(input) @@ -3481,14 +3467,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 5 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const task = await manager.launch(input) @@ -3507,14 +3493,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const task1 = await manager.launch(input) @@ -3548,15 +3534,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { const task = createMockTask({ id: "task-cancel-running", - sessionID: "session-cancel-running", - parentSessionID: "parent-cancel", + sessionId: "session-cancel-running", + parentSessionId: "parent-cancel", status: "running", concurrencyKey, }) getTaskMap(manager).set(task.id, task) const pendingByParent = getPendingByParent(manager) - pendingByParent.set(task.parentSessionID, new Set([task.id])) + pendingByParent.set(task.parentSessionId, new Set([task.id])) // when const cancelled = await manager.cancelTask(task.id, { source: "test" }) @@ -3569,7 +3555,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { expect(updatedTask?.concurrencyKey).toBeUndefined() expect(concurrencyManager.getCount(concurrencyKey)).toBe(0) - const pendingSet = pendingByParent.get(task.parentSessionID) + const pendingSet = pendingByParent.get(task.parentSessionId) expect(pendingSet?.has(task.id) ?? false).toBe(false) }) @@ -3579,8 +3565,8 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { const manager = createBackgroundManager() const task = createMockTask({ id: "task-cancel-skip-notification", - sessionID: "session-cancel-skip-notification", - parentSessionID: "parent-cancel-skip-notification", + sessionId: "session-cancel-skip-notification", + parentSessionId: "parent-cancel-skip-notification", status: "running", }) getTaskMap(manager).set(task.id, task) @@ -3605,22 +3591,22 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input1 = { description: "Task 1", prompt: "Do something", agent: "agent-a", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const input2 = { description: "Task 2", prompt: "Do something else", agent: "agent-b", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3640,14 +3626,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3667,15 +3653,15 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input1 = { description: "Task 1", prompt: "Do something", agent: "test-agent", model: { providerID: "anthropic", modelID: "claude-opus-4.7" }, - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const input2 = { @@ -3683,8 +3669,8 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { prompt: "Do something else", agent: "test-agent", model: { providerID: "openai", modelID: "gpt-5.4" }, - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3706,14 +3692,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } await manager.launch(input) @@ -3737,14 +3723,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 5 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3765,14 +3751,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 1 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } await manager.launch(input) @@ -3805,14 +3791,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => { // given const config = { defaultConcurrency: 5 } manager.shutdown() - manager = new BackgroundManager({ client: mockClient, directory: tmpdir() } as unknown as PluginInput, config) + manager = new BackgroundManager({ pluginContext: { client: mockClient, directory: tmpdir() } as unknown as PluginInput, config: config }) const input = { description: "Test task", prompt: "Do something", agent: "test-agent", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } // when @@ -3863,13 +3849,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) const task: BackgroundTask = { id: "task-1", - sessionID: "session-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Test task", prompt: "Test", agent: "test-agent", @@ -3896,13 +3882,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) const task: BackgroundTask = { id: "task-2", - sessionID: "session-2", - parentSessionID: "parent-2", - parentMessageID: "msg-2", + sessionId: "session-2", + parentSessionId: "parent-2", + parentMessageId: "msg-2", description: "Test task", prompt: "Test", agent: "test-agent", @@ -3929,14 +3915,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-3", - sessionID: "session-3", - parentSessionID: "parent-3", - parentMessageID: "msg-3", + sessionId: "session-3", + parentSessionId: "parent-3", + parentMessageId: "msg-3", description: "Stale task", prompt: "Test", agent: "test-agent", @@ -3966,14 +3952,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 60_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 60_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-4", - sessionID: "session-4", - parentSessionID: "parent-4", - parentMessageID: "msg-4", + sessionId: "session-4", + parentSessionId: "parent-4", + parentMessageId: "msg-4", description: "Custom timeout task", prompt: "Test", agent: "test-agent", @@ -4001,14 +3987,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-5", - sessionID: "session-5", - parentSessionID: "parent-5", - parentMessageID: "msg-5", + sessionId: "session-5", + parentSessionId: "parent-5", + parentMessageId: "msg-5", description: "Concurrency test", prompt: "Test", agent: "test-agent", @@ -4037,14 +4023,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task1: BackgroundTask = { id: "task-6", - sessionID: "session-6", - parentSessionID: "parent-6", - parentMessageID: "msg-6", + sessionId: "session-6", + parentSessionId: "parent-6", + parentMessageId: "msg-6", description: "Stale 1", prompt: "Test", agent: "test-agent", @@ -4058,9 +4044,9 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { const task2: BackgroundTask = { id: "task-7", - sessionID: "session-7", - parentSessionID: "parent-7", - parentMessageID: "msg-7", + sessionId: "session-7", + parentSessionId: "parent-7", + parentMessageId: "msg-7", description: "Stale 2", prompt: "Test", agent: "test-agent", @@ -4089,14 +4075,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-8", - sessionID: "session-8", - parentSessionID: "parent-8", - parentMessageID: "msg-8", + sessionId: "session-8", + parentSessionId: "parent-8", + parentMessageId: "msg-8", description: "Default timeout", prompt: "Test", agent: "test-agent", @@ -4127,13 +4113,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) const task: BackgroundTask = { id: "task-running-session", - sessionID: "session-running", - parentSessionID: "parent-rs", - parentMessageID: "msg-rs", + sessionId: "session-running", + parentSessionId: "parent-rs", + parentMessageId: "msg-rs", description: "Task with running session", prompt: "Test", agent: "test-agent", @@ -4166,14 +4152,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-idle-session", - sessionID: "session-idle", - parentSessionID: "parent-is", - parentMessageID: "msg-is", + sessionId: "session-idle", + parentSessionId: "parent-is", + parentMessageId: "msg-is", description: "Task with idle session", prompt: "Test", agent: "test-agent", @@ -4204,13 +4190,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) const task: BackgroundTask = { id: "task-long-running", - sessionID: "session-long", - parentSessionID: "parent-lr", - parentMessageID: "msg-lr", + sessionId: "session-long", + parentSessionId: "parent-lr", + parentMessageId: "msg-lr", description: "Long running task", prompt: "Test", agent: "test-agent", @@ -4240,13 +4226,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { messageStalenessTimeoutMs: 600_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { messageStalenessTimeoutMs: 600_000 } }) const task: BackgroundTask = { id: "task-running-no-progress", - sessionID: "session-rnp", - parentSessionID: "parent-rnp", - parentMessageID: "msg-rnp", + sessionId: "session-rnp", + parentSessionId: "parent-rnp", + parentMessageId: "msg-rnp", description: "Running no progress", prompt: "Test", agent: "test-agent", @@ -4278,14 +4264,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { messageStalenessTimeoutMs: 600_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { messageStalenessTimeoutMs: 600_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-no-update", - sessionID: "session-no-update", - parentSessionID: "parent-nu", - parentMessageID: "msg-nu", + sessionId: "session-no-update", + parentSessionId: "parent-nu", + parentMessageId: "msg-nu", description: "No update task", prompt: "Test", agent: "test-agent", @@ -4314,13 +4300,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { messageStalenessTimeoutMs: 600_000, sessionGoneTimeoutMs: 600_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { messageStalenessTimeoutMs: 600_000, sessionGoneTimeoutMs: 600_000 } }) const task: BackgroundTask = { id: "task-fresh-no-update", - sessionID: "session-fresh", - parentSessionID: "parent-fn", - parentMessageID: "msg-fn", + sessionId: "session-fresh", + parentSessionId: "parent-fn", + parentMessageId: "msg-fn", description: "Fresh no-update task", prompt: "Test", agent: "test-agent", @@ -4353,13 +4339,13 @@ describe("BackgroundManager.shutdown session abort", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task1: BackgroundTask = { id: "task-1", - sessionID: "session-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Running task 1", prompt: "Test", agent: "test-agent", @@ -4368,9 +4354,9 @@ describe("BackgroundManager.shutdown session abort", () => { } const task2: BackgroundTask = { id: "task-2", - sessionID: "session-2", - parentSessionID: "parent-2", - parentMessageID: "msg-2", + sessionId: "session-2", + parentSessionId: "parent-2", + parentMessageId: "msg-2", description: "Running task 2", prompt: "Test", agent: "test-agent", @@ -4403,13 +4389,13 @@ describe("BackgroundManager.shutdown session abort", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const completedTask: BackgroundTask = { id: "task-completed", - sessionID: "session-completed", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-completed", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Completed task", prompt: "Test", agent: "test-agent", @@ -4419,9 +4405,9 @@ describe("BackgroundManager.shutdown session abort", () => { } const cancelledTask: BackgroundTask = { id: "task-cancelled", - sessionID: "session-cancelled", - parentSessionID: "parent-2", - parentMessageID: "msg-2", + sessionId: "session-cancelled", + parentSessionId: "parent-2", + parentMessageId: "msg-2", description: "Cancelled task", prompt: "Test", agent: "test-agent", @@ -4431,8 +4417,8 @@ describe("BackgroundManager.shutdown session abort", () => { } const pendingTask: BackgroundTask = { id: "task-pending", - parentSessionID: "parent-3", - parentMessageID: "msg-3", + parentSessionId: "parent-3", + parentMessageId: "msg-3", description: "Pending task", prompt: "Test", agent: "test-agent", @@ -4462,13 +4448,9 @@ describe("BackgroundManager.shutdown session abort", () => { }, } const manager = new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - undefined, - { - onShutdown: () => { + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: undefined, onShutdown: () => { shutdownCalled = true - }, - } + }, } ) // when @@ -4488,13 +4470,9 @@ describe("BackgroundManager.shutdown session abort", () => { }, } const manager = new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - undefined, - { - onShutdown: () => { + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: undefined, onShutdown: () => { throw new Error("cleanup failed") - }, - } + }, } ) // when / #then @@ -4509,28 +4487,28 @@ describe("BackgroundManager.handleEvent - session.deleted cascade", () => { const parentSessionID = "session-parent" const childTask = createMockTask({ id: "task-child", - sessionID: "session-child", - parentSessionID, + sessionId: "session-child", + parentSessionId: parentSessionID, status: "running", }) const siblingTask = createMockTask({ id: "task-sibling", - sessionID: "session-sibling", - parentSessionID, + sessionId: "session-sibling", + parentSessionId: parentSessionID, status: "running", }) const grandchildTask = createMockTask({ id: "task-grandchild", - sessionID: "session-grandchild", - parentSessionID: "session-child", + sessionId: "session-grandchild", + parentSessionId: "session-child", status: "pending", startedAt: undefined, queuedAt: new Date(), }) const unrelatedTask = createMockTask({ id: "task-unrelated", - sessionID: "session-unrelated", - parentSessionID: "other-parent", + sessionId: "session-unrelated", + parentSessionId: "other-parent", status: "running", }) @@ -4579,14 +4557,14 @@ describe("BackgroundManager.handleEvent - session.deleted cascade", () => { const parentSessionID = "session-parent-toast" const childTask = createMockTask({ id: "task-child-toast", - sessionID: "session-child-toast", - parentSessionID, + sessionId: "session-child-toast", + parentSessionId: parentSessionID, status: "running", }) const grandchildTask = createMockTask({ id: "task-grandchild-toast", - sessionID: "session-grandchild-toast", - parentSessionID: "session-child-toast", + sessionId: "session-grandchild-toast", + parentSessionId: "session-child-toast", status: "pending", startedAt: undefined, queuedAt: new Date(), @@ -4648,16 +4626,16 @@ describe("BackgroundManager.handleEvent - session.error", () => { const createRetryTask = (manager: BackgroundManager, input: { id: string - sessionID: string + sessionId: string description: string concurrencyKey?: string fallbackChain?: typeof defaultRetryFallbackChain }) => { const task = createMockTask({ id: input.id, - sessionID: input.sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-retry", + sessionId: input.sessionId, + parentSessionId: "parent-session", + parentMessageId: "msg-retry", description: input.description, agent: "sisyphus", status: "running", @@ -4680,22 +4658,22 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_error_1" const task = createMockTask({ id: "task-session-error", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "task that errors", agent: "explore", status: "running", concurrencyKey, }) getTaskMap(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) //#when manager.handleEvent({ type: "session.error", properties: { - sessionID, + sessionID: sessionID, error: { name: "UnknownError", data: { message: "Model not found: kimi-for-coding/k2p5." }, @@ -4711,7 +4689,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { expect(task.completedAt).toBeInstanceOf(Date) expect(concurrencyManager.getCount(concurrencyKey)).toBe(0) expect(getTaskMap(manager).has(task.id)).toBe(true) - expect(getPendingByParent(manager).get(task.parentSessionID)).toBeUndefined() + expect(getPendingByParent(manager).get(task.parentSessionId)).toBeUndefined() expect(getCompletionTimers(manager).has(task.id)).toBe(true) manager.shutdown() @@ -4724,8 +4702,8 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_error_toast" const task = createMockTask({ id: "task-session-error-toast", - sessionID, - parentSessionID: "parent-session", + sessionId: sessionID, + parentSessionId: "parent-session", status: "running", }) getTaskMap(manager).set(task.id, task) @@ -4734,7 +4712,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { manager.handleEvent({ type: "session.error", properties: { - sessionID, + sessionID: sessionID, error: { name: "UnknownError", message: "boom" }, }, }) @@ -4755,9 +4733,9 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_error_ignored" const task = createMockTask({ id: "task-non-running", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "task already done", agent: "explore", status: "completed", @@ -4770,7 +4748,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { manager.handleEvent({ type: "session.error", properties: { - sessionID, + sessionID: sessionID, error: { name: "UnknownError", message: "should not matter" }, }, }) @@ -4815,7 +4793,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_error_retry" const task = createRetryTask(manager, { id: "task-session-error-retry", - sessionID, + sessionId: sessionID, description: "task that should retry", concurrencyKey, fallbackChain: [ @@ -4828,7 +4806,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { manager.handleEvent({ type: "session.error", properties: { - sessionID, + sessionID: sessionID, error: { name: "UnknownError", data: { @@ -4861,7 +4839,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_status_retry" const task = createRetryTask(manager, { id: "task-status-retry", - sessionID, + sessionId: sessionID, description: "task that should retry on status", }) @@ -4869,7 +4847,7 @@ describe("BackgroundManager.handleEvent - session.error", () => { manager.handleEvent({ type: "session.status", properties: { - sessionID, + sessionID: sessionID, status: { type: "retry", message: "Provider is overloaded", @@ -4897,14 +4875,14 @@ describe("BackgroundManager.handleEvent - session.error", () => { const sessionID = "ses_message_updated_retry" const task = createRetryTask(manager, { id: "task-message-updated-retry", - sessionID, + sessionId: sessionID, description: "task that should retry on message.updated", }) //#when const messageInfo = { id: "msg_errored", - sessionID, + sessionID: sessionID, role: "assistant", error: { name: "UnknownError", @@ -4946,15 +4924,14 @@ describe("BackgroundManager queue processing - error tasks are skipped", () => { }, } const manager = new BackgroundManager( - { client, directory: tmpdir() } as unknown as PluginInput, - { defaultConcurrency: 1 } + { pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { defaultConcurrency: 1 } } ) const key = "test-key" const task: BackgroundTask = { id: "task-error-queued", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "queued error task", prompt: "test", agent: "test-agent", @@ -4966,8 +4943,8 @@ describe("BackgroundManager queue processing - error tasks are skipped", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, } let startCalled = false @@ -4996,8 +4973,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications - removes pruned tas const queuedAt = new Date(Date.now() - 31 * 60 * 1000) const task: BackgroundTask = { id: "task-stale-pending", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "stale pending", prompt: "test", agent: "test-agent", @@ -5010,8 +4987,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications - removes pruned tas description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, } getTaskMap(manager).set(task.id, task) @@ -5032,8 +5009,8 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications - removes pruned tas const manager = createBackgroundManager() const staleTask = createMockTask({ id: "task-stale-toast", - sessionID: "session-stale-toast", - parentSessionID: "parent-session", + sessionId: "session-stale-toast", + parentSessionId: "parent-session", status: "running", startedAt: new Date(Date.now() - 31 * 60 * 1000), }) @@ -5068,16 +5045,16 @@ describe("BackgroundManager.pruneStaleTasksAndNotifications - removes pruned tas messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const staleTask = createMockTask({ id: "task-stale-notify-cleanup", - sessionID: "session-stale-notify-cleanup", - parentSessionID: "parent-stale-notify-cleanup", + sessionId: "session-stale-notify-cleanup", + parentSessionId: "parent-stale-notify-cleanup", status: "running", startedAt: new Date(Date.now() - 31 * 60 * 1000), }) getTaskMap(manager).set(staleTask.id, staleTask) - getPendingByParent(manager).set(staleTask.parentSessionID, new Set([staleTask.id])) + getPendingByParent(manager).set(staleTask.parentSessionId, new Set([staleTask.id])) //#when pruneStaleTasksAndNotificationsForTest(manager) @@ -5131,12 +5108,12 @@ describe("BackgroundManager.completionTimers - Memory Leak Fix", () => { messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const taskA: BackgroundTask = { id: "task-timer-a", - sessionID: "session-timer-a", - parentSessionID: "parent-session", - parentMessageID: "msg-a", + sessionId: "session-timer-a", + parentSessionId: "parent-session", + parentMessageId: "msg-a", description: "Task A", prompt: "test", agent: "explore", @@ -5146,9 +5123,9 @@ describe("BackgroundManager.completionTimers - Memory Leak Fix", () => { } const taskB: BackgroundTask = { id: "task-timer-b", - sessionID: "session-timer-b", - parentSessionID: "parent-session", - parentMessageID: "msg-b", + sessionId: "session-timer-b", + parentSessionId: "parent-session", + parentMessageId: "msg-b", description: "Task B", prompt: "test", agent: "explore", @@ -5204,9 +5181,9 @@ describe("BackgroundManager.completionTimers - Memory Leak Fix", () => { const manager = createBackgroundManager() const task: BackgroundTask = { id: "task-timer-4", - sessionID: "session-timer-4", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-timer-4", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "Test task", prompt: "test", agent: "explore", @@ -5276,15 +5253,15 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => { }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const remainingMs = 1200 const task: BackgroundTask = { id: "task-early-idle", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "early idle task", prompt: "test", agent: "explore", @@ -5333,14 +5310,14 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => { }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-late-idle", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "late idle task", prompt: "test", agent: "explore", @@ -5387,15 +5364,15 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => { }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const remainingMs = 120 const task: BackgroundTask = { id: "task-deferred-noop", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "deferred noop task", prompt: "test", agent: "explore", @@ -5437,14 +5414,14 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const oldUpdate = new Date(Date.now() - 300_000) const task: BackgroundTask = { id: "task-text-1", - sessionID: "session-text-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-text-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Thinking task", prompt: "Think deeply", agent: "oracle", @@ -5477,14 +5454,14 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const oldUpdate = new Date(Date.now() - 300_000) const task: BackgroundTask = { id: "task-thinking-1", - sessionID: "session-thinking-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-thinking-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Reasoning task", prompt: "Reason about architecture", agent: "oracle", @@ -5517,13 +5494,13 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-init-1", - sessionID: "session-init-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-init-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "New task", prompt: "Start thinking", agent: "oracle", @@ -5553,14 +5530,14 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-alive-1", - sessionID: "session-alive-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-alive-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Long thinking task", prompt: "Deep reasoning", agent: "oracle", @@ -5593,14 +5570,14 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 }) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: { staleTimeoutMs: 180_000 } }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-delta-1", - sessionID: "session-delta-1", - parentSessionID: "parent-1", - parentMessageID: "msg-1", + sessionId: "session-delta-1", + parentSessionId: "parent-1", + parentMessageId: "msg-1", description: "Reasoning task with delta events", prompt: "Extended thinking", agent: "oracle", @@ -5651,14 +5628,14 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) const task: BackgroundTask = { id: "task-output-cached-idle", - sessionID, - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: sessionID, + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "idle cached output task", prompt: "test", agent: "explore", @@ -5669,7 +5646,7 @@ describe("BackgroundManager.handleEvent - non-tool event lastUpdate", () => { manager.handleEvent({ type: "message.part.updated", - properties: { sessionID, type: "text" }, + properties: { sessionID: sessionID, type: "text" }, }) //#when - session.idle fires after output event was already observed @@ -5695,13 +5672,13 @@ describe("BackgroundManager regression fixes - resume and aborted notification", abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-resume-timer-regression", - sessionID: "session-resume-timer-regression", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-resume-timer-regression", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "resume timer regression", prompt: "test", agent: "explore", @@ -5723,8 +5700,8 @@ describe("BackgroundManager regression fixes - resume and aborted notification", await manager.resume({ sessionId: "session-resume-timer-regression", prompt: "resume task", - parentSessionID: "parent-session-2", - parentMessageID: "msg-2", + parentSessionId: "parent-session-2", + parentMessageId: "msg-2", }) await new Promise((resolve) => setTimeout(resolve, 60)) @@ -5749,12 +5726,12 @@ describe("BackgroundManager regression fixes - resume and aborted notification", messages: async () => ({ data: [] }), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-aborted-cleanup-regression", - sessionID: "session-aborted-cleanup-regression", - parentSessionID: "parent-session", - parentMessageID: "msg-1", + sessionId: "session-aborted-cleanup-regression", + parentSessionId: "parent-session", + parentMessageId: "msg-1", description: "aborted prompt cleanup regression", prompt: "test", agent: "explore", @@ -5763,7 +5740,7 @@ describe("BackgroundManager regression fixes - resume and aborted notification", completedAt: new Date(), } getTaskMap(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) //#when await (manager as unknown as { notifyParentSession: (task: BackgroundTask) => Promise }).notifyParentSession(task) @@ -5789,7 +5766,7 @@ describe("BackgroundManager - tool permission spread order", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-1", status: "pending", @@ -5797,15 +5774,15 @@ describe("BackgroundManager - tool permission spread order", () => { description: "test task", prompt: "test prompt", agent: "explore", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", } const input: import("./types").LaunchInput = { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, } //#when @@ -5835,7 +5812,7 @@ describe("BackgroundManager - tool permission spread order", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-explicit-model", status: "pending", @@ -5843,16 +5820,16 @@ describe("BackgroundManager - tool permission spread order", () => { description: "test task", prompt: "test prompt", agent: "sisyphus-junior", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "openai", modelID: "gpt-5.4", variant: "medium" }, } const input: import("./types").LaunchInput = { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: task.model, } @@ -5881,12 +5858,12 @@ describe("BackgroundManager - tool permission spread order", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-2", - sessionID: "session-2", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + sessionId: "session-2", + parentSessionId: "parent-session", + parentMessageId: "parent-message", description: "resume task", prompt: "resume prompt", agent: "explore", @@ -5900,8 +5877,8 @@ describe("BackgroundManager - tool permission spread order", () => { await manager.resume({ sessionId: "session-2", prompt: "continue", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", }) //#then @@ -5926,12 +5903,12 @@ describe("BackgroundManager - tool permission spread order", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-explicit-model-resume", - sessionID: "session-3", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + sessionId: "session-3", + parentSessionId: "parent-session", + parentMessageId: "parent-message", description: "resume task", prompt: "resume prompt", agent: "explore", @@ -5946,8 +5923,8 @@ describe("BackgroundManager - tool permission spread order", () => { await manager.resume({ sessionId: "session-3", prompt: "continue", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", }) //#then @@ -5982,8 +5959,8 @@ describe("BackgroundManager.launch - attempt state initialization", () => { description: "attempt state test", prompt: "do something", agent: "explore", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "anthropic", modelID: "claude-haiku-4.5" }, }) @@ -5996,15 +5973,15 @@ describe("BackgroundManager.launch - attempt state initialization", () => { const firstAttempt = stored?.attempts?.[0] expect(firstAttempt?.attemptNumber).toBe(1) expect(firstAttempt?.status).toBe("pending") - expect(firstAttempt?.providerID).toBe("anthropic") - expect(firstAttempt?.modelID).toBe("claude-haiku-4.5") + expect(firstAttempt?.providerId).toBe("anthropic") + expect(firstAttempt?.modelId).toBe("claude-haiku-4.5") expect(stored?.currentAttemptID).toBeDefined() - expect(stored?.currentAttemptID).toBe(firstAttempt?.attemptID) + expect(stored?.currentAttemptID).toBe(firstAttempt?.attemptId) expect(stored?.status).toBeDefined() expect(stored?.model).toBeDefined() - expect(stored?.parentSessionID).toBe("parent-session") + expect(stored?.parentSessionId).toBe("parent-session") manager.shutdown() }) @@ -6021,7 +5998,7 @@ describe("BackgroundManager attempt lifecycle bindings", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) const task: BackgroundTask = { id: "task-attempt-binding", status: "pending", @@ -6029,26 +6006,26 @@ describe("BackgroundManager attempt lifecycle bindings", () => { description: "retry binding task", prompt: "continue", agent: "sisyphus-junior", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "anthropic", modelID: "claude-haiku-4.5", variant: "max" }, attempts: [ { - attemptID: "attempt-1", + attemptId: "attempt-1", attemptNumber: 1, - sessionID: "session-attempt-1", - providerID: "openai", - modelID: "gpt-5.4-mini", + sessionId: "session-attempt-1", + providerId: "openai", + modelId: "gpt-5.4-mini", status: "error", error: "first attempt failed", startedAt: new Date("2026-04-27T00:00:00.000Z"), completedAt: new Date("2026-04-27T00:00:05.000Z"), }, { - attemptID: "attempt-2", + attemptId: "attempt-2", attemptNumber: 2, - providerID: "anthropic", - modelID: "claude-haiku-4.5", + providerId: "anthropic", + modelId: "claude-haiku-4.5", variant: "max", status: "pending", }, @@ -6060,8 +6037,8 @@ describe("BackgroundManager attempt lifecycle bindings", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: task.model, } @@ -6071,17 +6048,17 @@ describe("BackgroundManager attempt lifecycle bindings", () => { }).startTask({ task, input, attemptID: "attempt-2" }) //#then - const activeAttempt = task.attempts?.find((attempt) => attempt.attemptID === "attempt-2") + const activeAttempt = task.attempts?.find((attempt) => attempt.attemptId === "attempt-2") expect(activeAttempt).toBeDefined() - expect(activeAttempt?.sessionID).toBe("session-attempt-2") + expect(activeAttempt?.sessionId).toBe("session-attempt-2") expect(activeAttempt?.status).toBe("running") expect(activeAttempt?.startedAt).toBeInstanceOf(Date) expect(task.currentAttemptID).toBe("attempt-2") - expect(task.sessionID).toBe("session-attempt-2") + expect(task.sessionId).toBe("session-attempt-2") expect(task.status).toBe("running") expect(task.attempts?.[0]).toMatchObject({ - attemptID: "attempt-1", - sessionID: "session-attempt-1", + attemptId: "attempt-1", + sessionId: "session-attempt-1", status: "error", error: "first attempt failed", }) @@ -6097,31 +6074,31 @@ describe("BackgroundManager attempt lifecycle bindings", () => { status: "running", queuedAt: new Date("2026-04-27T00:00:00.000Z"), startedAt: new Date("2026-04-27T00:00:10.000Z"), - sessionID: "session-attempt-2", + sessionId: "session-attempt-2", description: "ignore stale retry events", prompt: "continue", agent: "explore", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "anthropic", modelID: "claude-haiku-4.5" }, attempts: [ { - attemptID: "attempt-1", + attemptId: "attempt-1", attemptNumber: 1, - sessionID: "session-attempt-1", - providerID: "openai", - modelID: "gpt-5.4-mini", + sessionId: "session-attempt-1", + providerId: "openai", + modelId: "gpt-5.4-mini", status: "error", error: "first attempt failed", startedAt: new Date("2026-04-27T00:00:00.000Z"), completedAt: new Date("2026-04-27T00:00:05.000Z"), }, { - attemptID: "attempt-2", + attemptId: "attempt-2", attemptNumber: 2, - sessionID: "session-attempt-2", - providerID: "anthropic", - modelID: "claude-haiku-4.5", + sessionId: "session-attempt-2", + providerId: "anthropic", + modelId: "claude-haiku-4.5", status: "running", startedAt: new Date("2026-04-27T00:00:10.000Z"), }, @@ -6135,7 +6112,7 @@ describe("BackgroundManager attempt lifecycle bindings", () => { manager.handleEvent({ type: "session.error", properties: { - sessionID: "session-attempt-1", + sessionId: "session-attempt-1", error: { name: "UnknownError", message: "late event from old session" }, }, }) @@ -6144,17 +6121,17 @@ describe("BackgroundManager attempt lifecycle bindings", () => { //#then expect(resolvedTask?.id).toBe(task.id) expect(task.currentAttemptID).toBe("attempt-2") - expect(task.sessionID).toBe("session-attempt-2") + expect(task.sessionId).toBe("session-attempt-2") expect(task.status).toBe("running") expect(task.error).toBeUndefined() expect(task.attempts?.[0]).toMatchObject({ - attemptID: "attempt-1", + attemptId: "attempt-1", status: "error", error: "first attempt failed", }) expect(task.attempts?.[1]).toMatchObject({ - attemptID: "attempt-2", - sessionID: "session-attempt-2", + attemptId: "attempt-2", + sessionId: "session-attempt-2", status: "running", }) @@ -6178,7 +6155,7 @@ describe("BackgroundManager attempt lifecycle bindings", () => { }, }, } - const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput) + const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) stubNotifyParentSession(manager) ;(manager as unknown as { tryFallbackRetry: (task: BackgroundTask, errorInfo: { name?: string; message?: string }, source: string) => Promise @@ -6190,15 +6167,15 @@ describe("BackgroundManager attempt lifecycle bindings", () => { description: "ignore stale prompt errors", prompt: "continue", agent: "sisyphus-junior", - parentSessionID: "parent-session", - parentMessageID: "parent-message", + parentSessionId: "parent-session", + parentMessageId: "parent-message", model: { providerID: "openai", modelID: "gpt-5.4-mini" }, attempts: [ { - attemptID: "attempt-1", + attemptId: "attempt-1", attemptNumber: 1, - providerID: "openai", - modelID: "gpt-5.4-mini", + providerId: "openai", + modelId: "gpt-5.4-mini", status: "pending", }, ], @@ -6209,8 +6186,8 @@ describe("BackgroundManager attempt lifecycle bindings", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, model: task.model, } @@ -6220,9 +6197,9 @@ describe("BackgroundManager attempt lifecycle bindings", () => { task.attempts = [ { - attemptID: "attempt-1", + attemptId: "attempt-1", attemptNumber: 1, - sessionID: "session-attempt-1", + sessionId: "session-attempt-1", providerID: "openai", modelID: "gpt-5.4-mini", status: "error", @@ -6231,9 +6208,9 @@ describe("BackgroundManager attempt lifecycle bindings", () => { completedAt: new Date("2026-04-27T00:00:05.000Z"), }, { - attemptID: "attempt-2", + attemptId: "attempt-2", attemptNumber: 2, - sessionID: "session-attempt-2", + sessionId: "session-attempt-2", providerID: "anthropic", modelID: "claude-haiku-4.5", status: "running", @@ -6241,7 +6218,7 @@ describe("BackgroundManager attempt lifecycle bindings", () => { }, ] task.currentAttemptID = "attempt-2" - task.sessionID = "session-attempt-2" + task.sessionId = "session-attempt-2" task.status = "running" task.error = undefined @@ -6251,18 +6228,18 @@ describe("BackgroundManager attempt lifecycle bindings", () => { //#then expect(task.currentAttemptID).toBe("attempt-2") - expect(task.sessionID).toBe("session-attempt-2") + expect(task.sessionId).toBe("session-attempt-2") expect(task.status).toBe("running") expect(task.error).toBeUndefined() expect(task.attempts?.[0]).toMatchObject({ - attemptID: "attempt-1", + attemptId: "attempt-1", status: "error", error: "first attempt failed", }) expect(task.attempts?.[1]).toMatchObject({ - attemptID: "attempt-2", + attemptId: "attempt-2", status: "running", - sessionID: "session-attempt-2", + sessionId: "session-attempt-2", }) expect(abortCalls).toEqual([]) diff --git a/src/features/background-agent/manager.ts b/src/features/background-agent/manager.ts index 2df90e917..9442c23d9 100644 --- a/src/features/background-agent/manager.ts +++ b/src/features/background-agent/manager.ts @@ -129,12 +129,12 @@ interface Todo { id: string } -function formatAttemptModelSummary(attempt: Pick | undefined): string | undefined { - if (!attempt?.providerID || !attempt.modelID) { +function formatAttemptModelSummary(attempt: Pick | undefined): string | undefined { + if (!attempt?.providerId || !attempt.modelId) { return undefined } - return `${attempt.providerID}/${attempt.modelID}` + return `${attempt.providerId}/${attempt.modelId}` } function getPreviousAttempt(task: BackgroundTask, attemptID: string | undefined): BackgroundTaskAttempt | undefined { @@ -142,7 +142,7 @@ function getPreviousAttempt(task: BackgroundTask, attemptID: string | undefined) return undefined } - const attemptIndex = task.attempts.findIndex((attempt) => attempt.attemptID === attemptID) + const attemptIndex = task.attempts.findIndex((attempt) => attempt.attemptId === attemptID) if (attemptIndex <= 0) { return undefined } @@ -173,6 +173,16 @@ export type OnSubagentSessionCreated = (event: SubagentSessionCreatedEvent) => P const MAX_TASK_REMOVAL_RESCHEDULES = 6 +export interface BackgroundManagerConfig { + pluginContext: PluginInput + config?: BackgroundTaskConfig + tmuxConfig?: TmuxConfig + onSubagentSessionCreated?: OnSubagentSessionCreated + onShutdown?: () => void | Promise + enableParentSessionNotifications?: boolean + modelFallbackControllerAccessor?: ModelFallbackControllerAccessor +} + export class BackgroundManager { @@ -207,26 +217,17 @@ export class BackgroundManager { readonly taskHistory = new TaskHistory() private cachedCircuitBreakerSettings?: CircuitBreakerSettings - constructor( - ctx: PluginInput, - config?: BackgroundTaskConfig, - options?: { - tmuxConfig?: TmuxConfig - onSubagentSessionCreated?: OnSubagentSessionCreated - onShutdown?: () => void | Promise - enableParentSessionNotifications?: boolean - modelFallbackControllerAccessor?: ModelFallbackControllerAccessor - } - ) { + constructor(config: BackgroundManagerConfig) { + const { pluginContext, ...options } = config this.tasks = new Map() this.tasksByParentSession = new Map() this.notifications = new Map() this.pendingNotifications = new Map() this.pendingByParent = new Map() - this.client = ctx.client - this.directory = ctx.directory - this.concurrencyManager = new ConcurrencyManager(config) - this.config = config + this.client = pluginContext.client + this.directory = pluginContext.directory + this.concurrencyManager = new ConcurrencyManager(options.config) + this.config = options.config this.tmuxEnabled = options?.tmuxConfig?.enabled ?? false this.onSubagentSessionCreated = options?.onSubagentSessionCreated this.onShutdown = options?.onShutdown @@ -317,36 +318,36 @@ export class BackgroundManager { return } - if (!task.rootSessionID) { + if (!task.rootSessionId) { return } - this.unregisterRootDescendant(task.rootSessionID) + this.unregisterRootDescendant(task.rootSessionId) } private addTask(task: BackgroundTask): void { this.tasks.set(task.id, task) - if (!task.parentSessionID) { + if (!task.parentSessionId) { return } - const taskIDs = this.tasksByParentSession.get(task.parentSessionID) ?? new Set() + const taskIDs = this.tasksByParentSession.get(task.parentSessionId) ?? new Set() taskIDs.add(task.id) - this.tasksByParentSession.set(task.parentSessionID, taskIDs) + this.tasksByParentSession.set(task.parentSessionId, taskIDs) } private removeTask(task: BackgroundTask): void { this.tasks.delete(task.id) - this.removeTaskFromParentIndex(task.id, task.parentSessionID) + this.removeTaskFromParentIndex(task.id, task.parentSessionId) } private updateTaskParent(task: BackgroundTask, parentSessionID: string): void { - if (task.parentSessionID === parentSessionID) { + if (task.parentSessionId === parentSessionID) { return } - this.removeTaskFromParentIndex(task.id, task.parentSessionID) - task.parentSessionID = parentSessionID + this.removeTaskFromParentIndex(task.id, task.parentSessionId) + task.parentSessionId = parentSessionID const taskIDs = this.tasksByParentSession.get(parentSessionID) ?? new Set() taskIDs.add(task.id) this.tasksByParentSession.set(parentSessionID, taskIDs) @@ -373,18 +374,18 @@ export class BackgroundManager { agent: input.agent, model: input.model, description: input.description, - parentSessionID: input.parentSessionID, + parentSessionID: input.parentSessionId, }) if (!input.agent || input.agent.trim() === "") { throw new Error("Agent parameter is required") } - const spawnReservation = await this.reserveSubagentSpawn(input.parentSessionID) + const spawnReservation = await this.reserveSubagentSpawn(input.parentSessionId) try { log("[background-agent] spawn guard passed", { - parentSessionID: input.parentSessionID, + parentSessionID: input.parentSessionId, rootSessionID: spawnReservation.spawnContext.rootSessionID, childDepth: spawnReservation.spawnContext.childDepth, descendantCount: spawnReservation.descendantCount, @@ -395,15 +396,15 @@ export class BackgroundManager { id: `bg_${crypto.randomUUID().slice(0, 8)}`, status: "pending", queuedAt: new Date(), - rootSessionID: spawnReservation.spawnContext.rootSessionID, + rootSessionId: spawnReservation.spawnContext.rootSessionID, // Do NOT set startedAt - will be set when running // Do NOT set sessionID - will be set when running description: input.description, prompt: input.prompt, agent: input.agent, spawnDepth: spawnReservation.spawnContext.childDepth, - parentSessionID: input.parentSessionID, - parentMessageID: input.parentMessageID, + parentSessionId: input.parentSessionId, + parentMessageId: input.parentMessageId, parentModel: input.parentModel, parentAgent: input.parentAgent, parentTools: input.parentTools, @@ -415,19 +416,19 @@ export class BackgroundManager { const firstAttempt = startAttempt(task, input.model) this.addTask(task) - this.taskHistory.record(input.parentSessionID, { id: task.id, agent: input.agent, description: input.description, status: "pending", category: input.category }) + this.taskHistory.record(input.parentSessionId, { id: task.id, agent: input.agent, description: input.description, status: "pending", category: input.category }) // Track for batched notifications immediately (pending state) - if (input.parentSessionID) { - const pending = this.pendingByParent.get(input.parentSessionID) ?? new Set() + if (input.parentSessionId) { + const pending = this.pendingByParent.get(input.parentSessionId) ?? new Set() pending.add(task.id) - this.pendingByParent.set(input.parentSessionID, pending) + this.pendingByParent.set(input.parentSessionId, pending) } // Add to queue const key = this.getConcurrencyKeyFromInput(input) const queue = this.queuesByKey.get(key) ?? [] - queue.push({ task, input, attemptID: firstAttempt.attemptID }) + queue.push({ task, input, attemptID: firstAttempt.attemptId }) this.queuesByKey.set(key, queue) log("[background-agent] Task queued:", { taskId: task.id, key, queueLength: queue.length }) @@ -506,12 +507,12 @@ export class BackgroundManager { removeTaskToastTracking(item.task.id) // Abort the orphaned session if one was created before the error - if (item.task.sessionID) { - await this.abortSessionWithLogging(item.task.sessionID, "startTask error cleanup") + if (item.task.sessionId) { + await this.abortSessionWithLogging(item.task.sessionId, "startTask error cleanup") } this.markForNotification(item.task) - this.enqueueNotificationForParent(item.task.parentSessionID, () => this.notifyParentSession(item.task)).catch(err => { + this.enqueueNotificationForParent(item.task.parentSessionId, () => this.notifyParentSession(item.task)).catch(err => { log("[background-agent] Failed to notify on startTask error:", err) }) } @@ -523,7 +524,7 @@ export class BackgroundManager { private async startTask(item: QueueItem): Promise { const { task, input } = item - const attemptID = item.attemptID ?? ensureCurrentAttempt(task, input.model).attemptID + const attemptID = item.attemptID ?? ensureCurrentAttempt(task, input.model).attemptId log("[background-agent] Starting task:", { taskId: task.id, @@ -534,7 +535,7 @@ export class BackgroundManager { const concurrencyKey = this.getConcurrencyKeyFromInput(input) const parentSession = await this.client.session.get({ - path: { id: input.parentSessionID }, + path: { id: input.parentSessionId }, query: { directory: this.directory }, }).catch((err) => { log(`[background-agent] Failed to get parent session: ${err}`) @@ -545,7 +546,7 @@ export class BackgroundManager { const createResult = await this.client.session.create({ body: { - parentID: input.parentSessionID, + parentID: input.parentSessionId, title: `${input.description} (@${input.agent} subagent)`, ...(input.sessionPermission ? { permission: input.sessionPermission } : {}), } as Record, @@ -578,14 +579,14 @@ export class BackgroundManager { tmuxEnabled: this.tmuxEnabled, isInsideTmux: isInsideTmux(), sessionID, - parentID: input.parentSessionID, + parentID: input.parentSessionId, }) if (this.onSubagentSessionCreated && this.tmuxEnabled && isInsideTmux()) { log("[background-agent] Invoking tmux callback NOW", { sessionID }) await this.onSubagentSessionCreated({ sessionID, - parentID: input.parentSessionID, + parentID: input.parentSessionId, title: input.description, }).catch((err) => { log("[background-agent] Failed to spawn tmux pane:", err) @@ -599,8 +600,8 @@ export class BackgroundManager { if (this.tasks.get(task.id)?.status === "cancelled") { await this.abortSessionWithLogging(sessionID, "cancelled during tmux setup") subagentSessions.delete(sessionID) - if (task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } this.concurrencyManager.release(concurrencyKey) return @@ -610,8 +611,8 @@ export class BackgroundManager { if (!boundAttempt) { await this.abortSessionWithLogging(sessionID, "stale attempt binding cleanup") subagentSessions.delete(sessionID) - if (task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } this.concurrencyManager.release(concurrencyKey) return @@ -627,8 +628,8 @@ export class BackgroundManager { if (task.retryNotification) { const attemptNumber = boundAttempt.attemptNumber const retrySessionUrl = buildLocalSessionUrl(parentDirectory, sessionID) - const previousAttempt = getPreviousAttempt(task, boundAttempt.attemptID) - const failedSessionID = previousAttempt?.sessionID ?? task.retryNotification.previousSessionID + const previousAttempt = getPreviousAttempt(task, boundAttempt.attemptId) + const failedSessionID = previousAttempt?.sessionId ?? task.retryNotification.previousSessionID const failedSessionLine = failedSessionID ? `\n- Failed session: \`${failedSessionID}\`` : "" @@ -642,7 +643,7 @@ export class BackgroundManager { : "" const retryModel = formatAttemptModelSummary(boundAttempt) ?? task.retryNotification.nextModel this.queuePendingNotification( - task.parentSessionID, + task.parentSessionId, ` [BACKGROUND TASK RETRY SESSION READY] **ID:** \`${task.id}\` @@ -657,7 +658,7 @@ The fallback retry session is now created and can be inspected directly. task.retryNotification = undefined } - this.taskHistory.record(input.parentSessionID, { id: task.id, sessionID, agent: input.agent, description: input.description, status: "running", category: input.category, startedAt: task.startedAt }) + this.taskHistory.record(input.parentSessionId, { id: task.id, sessionID, agent: input.agent, description: input.description, status: "running", category: input.category, startedAt: task.startedAt }) this.startPolling() log("[background-agent] Launching task:", { taskId: task.id, sessionID, agent: input.agent }) @@ -764,8 +765,8 @@ The fallback retry session is now created and can be inspected directly. existingTask.error = terminalError existingTask.completedAt = new Date() } - if (existingTask.rootSessionID) { - this.unregisterRootDescendant(existingTask.rootSessionID) + if (existingTask.rootSessionId) { + this.unregisterRootDescendant(existingTask.rootSessionId) } if (existingTask.concurrencyKey) { this.concurrencyManager.release(existingTask.concurrencyKey) @@ -779,7 +780,7 @@ The fallback retry session is now created and can be inspected directly. await this.abortSessionWithLogging(sessionID, "launch error cleanup") this.markForNotification(existingTask) - this.enqueueNotificationForParent(existingTask.parentSessionID, () => this.notifyParentSession(existingTask)).catch(err => { + this.enqueueNotificationForParent(existingTask.parentSessionId, () => this.notifyParentSession(existingTask)).catch(err => { log("[background-agent] Failed to notify on error:", err) }) } @@ -795,7 +796,7 @@ The fallback retry session is now created and can be inspected directly. if (!taskIDs) { const result: BackgroundTask[] = [] for (const task of this.tasks.values()) { - if (task.parentSessionID === sessionID) { + if (task.parentSessionId === sessionID) { result.push(task) } } @@ -818,8 +819,8 @@ The fallback retry session is now created and can be inspected directly. for (const child of directChildren) { result.push(child) - if (child.sessionID) { - const descendants = this.getAllDescendantTasks(child.sessionID) + if (child.sessionId) { + const descendants = this.getAllDescendantTasks(child.sessionId) result.push(...descendants) } } @@ -829,7 +830,7 @@ The fallback retry session is now created and can be inspected directly. findBySession(sessionID: string): BackgroundTask | undefined { for (const task of this.tasks.values()) { - if (task.sessionID === sessionID) { + if (task.sessionId === sessionID) { return task } if (findAttemptBySession(task, sessionID)) { @@ -850,14 +851,14 @@ The fallback retry session is now created and can be inspected directly. return { task, attemptID: undefined, - isCurrent: task.sessionID === sessionID, + isCurrent: task.sessionId === sessionID, } } return { task, - attemptID: attempt.attemptID, - isCurrent: task.currentAttemptID === attempt.attemptID, + attemptID: attempt.attemptId, + isCurrent: task.currentAttemptID === attempt.attemptId, } } @@ -874,8 +875,8 @@ The fallback retry session is now created and can be inspected directly. */ async trackTask(input: { taskId: string - sessionID: string - parentSessionID: string + sessionId: string + parentSessionId: string description: string agent?: string parentAgent?: string @@ -885,10 +886,10 @@ The fallback retry session is now created and can be inspected directly. if (existingTask) { // P2 fix: Clean up old parent's pending set BEFORE changing parent // Otherwise cleanupPendingByParent would use the new parent ID - const parentChanged = input.parentSessionID !== existingTask.parentSessionID + const parentChanged = input.parentSessionId !== existingTask.parentSessionId if (parentChanged) { this.cleanupPendingByParent(existingTask) // Clean from OLD parent - this.updateTaskParent(existingTask, input.parentSessionID) + this.updateTaskParent(existingTask, input.parentSessionId) } if (input.parentAgent !== undefined) { existingTask.parentAgent = input.parentAgent @@ -897,22 +898,22 @@ The fallback retry session is now created and can be inspected directly. existingTask.concurrencyGroup = input.concurrencyKey ?? existingTask.agent } - if (existingTask.sessionID) { - subagentSessions.add(existingTask.sessionID) + if (existingTask.sessionId) { + subagentSessions.add(existingTask.sessionId) } this.startPolling() // Track for batched notifications if task is pending or running if (existingTask.status === "pending" || existingTask.status === "running") { - const pending = this.pendingByParent.get(input.parentSessionID) ?? new Set() + const pending = this.pendingByParent.get(input.parentSessionId) ?? new Set() pending.add(existingTask.id) - this.pendingByParent.set(input.parentSessionID, pending) + this.pendingByParent.set(input.parentSessionId, pending) } else if (!parentChanged) { // Only clean up if parent didn't change (already cleaned above if it did) this.cleanupPendingByParent(existingTask) } - log("[background-agent] External task already registered:", { taskId: existingTask.id, sessionID: existingTask.sessionID, status: existingTask.status }) + log("[background-agent] External task already registered:", { taskId: existingTask.id, sessionID: existingTask.sessionId, status: existingTask.status }) return existingTask } @@ -926,9 +927,9 @@ The fallback retry session is now created and can be inspected directly. const task: BackgroundTask = { id: input.taskId, - sessionID: input.sessionID, - parentSessionID: input.parentSessionID, - parentMessageID: "", + sessionId: input.sessionId, + parentSessionId: input.parentSessionId, + parentMessageId: "", description: input.description, prompt: "", agent: input.agent || "task", @@ -944,17 +945,17 @@ The fallback retry session is now created and can be inspected directly. } this.addTask(task) - subagentSessions.add(input.sessionID) + subagentSessions.add(input.sessionId) this.startPolling() - this.taskHistory.record(input.parentSessionID, { id: task.id, sessionID: input.sessionID, agent: input.agent || "task", description: input.description, status: "running", startedAt: task.startedAt }) + this.taskHistory.record(input.parentSessionId, { id: task.id, sessionID: input.sessionId, agent: input.agent || "task", description: input.description, status: "running", startedAt: task.startedAt }) - if (input.parentSessionID) { - const pending = this.pendingByParent.get(input.parentSessionID) ?? new Set() + if (input.parentSessionId) { + const pending = this.pendingByParent.get(input.parentSessionId) ?? new Set() pending.add(task.id) - this.pendingByParent.set(input.parentSessionID, pending) + this.pendingByParent.set(input.parentSessionId, pending) } - log("[background-agent] Registered external task:", { taskId: task.id, sessionID: input.sessionID }) + log("[background-agent] Registered external task:", { taskId: task.id, sessionID: input.sessionId }) return task } @@ -965,14 +966,14 @@ The fallback retry session is now created and can be inspected directly. throw new Error(`Task not found for session: ${input.sessionId}`) } - if (!existingTask.sessionID) { + if (!existingTask.sessionId) { throw new Error(`Task has no sessionID: ${existingTask.id}`) } if (existingTask.status === "running") { log("[background-agent] Resume skipped - task already running:", { taskId: existingTask.id, - sessionID: existingTask.sessionID, + sessionID: existingTask.sessionId, }) return existingTask } @@ -993,8 +994,8 @@ The fallback retry session is now created and can be inspected directly. existingTask.status = "running" existingTask.completedAt = undefined existingTask.error = undefined - this.updateTaskParent(existingTask, input.parentSessionID) - existingTask.parentMessageID = input.parentMessageID + this.updateTaskParent(existingTask, input.parentSessionId) + existingTask.parentMessageId = input.parentMessageId existingTask.parentModel = input.parentModel existingTask.parentAgent = input.parentAgent if (input.parentTools) { @@ -1012,14 +1013,14 @@ The fallback retry session is now created and can be inspected directly. } this.startPolling() - if (existingTask.sessionID) { - subagentSessions.add(existingTask.sessionID) + if (existingTask.sessionId) { + subagentSessions.add(existingTask.sessionId) } - if (input.parentSessionID) { - const pending = this.pendingByParent.get(input.parentSessionID) ?? new Set() + if (input.parentSessionId) { + const pending = this.pendingByParent.get(input.parentSessionId) ?? new Set() pending.add(existingTask.id) - this.pendingByParent.set(input.parentSessionID, pending) + this.pendingByParent.set(input.parentSessionId, pending) } const toastManager = getTaskToastManager() @@ -1032,10 +1033,10 @@ The fallback retry session is now created and can be inspected directly. }) } - log("[background-agent] Resuming task:", { taskId: existingTask.id, sessionID: existingTask.sessionID }) + log("[background-agent] Resuming task:", { taskId: existingTask.id, sessionID: existingTask.sessionId }) log("[background-agent] Resuming task - calling prompt (fire-and-forget) with:", { - sessionID: existingTask.sessionID, + sessionID: existingTask.sessionId, agent: existingTask.agent, model: existingTask.model, promptLength: input.prompt.length, @@ -1052,11 +1053,11 @@ The fallback retry session is now created and can be inspected directly. const resumeVariant = existingTask.model?.variant if (existingTask.model) { - applySessionPromptParams(existingTask.sessionID!, existingTask.model) + applySessionPromptParams(existingTask.sessionId!, existingTask.model) } this.client.session.promptAsync({ - path: { id: existingTask.sessionID }, + path: { id: existingTask.sessionId }, body: { agent: existingTask.agent, ...(resumeModel ? { model: resumeModel } : {}), @@ -1068,7 +1069,7 @@ The fallback retry session is now created and can be inspected directly. question: false, ...getAgentToolRestrictions(existingTask.agent), } - setSessionTools(existingTask.sessionID!, tools) + setSessionTools(existingTask.sessionId!, tools) return tools })(), parts: [createInternalAgentTextPart(input.prompt)], @@ -1087,8 +1088,8 @@ The fallback retry session is now created and can be inspected directly. const errorMessage = errorInfo.message ?? (error instanceof Error ? error.message : String(error)) existingTask.error = errorMessage existingTask.completedAt = new Date() - if (existingTask.rootSessionID) { - this.unregisterRootDescendant(existingTask.rootSessionID) + if (existingTask.rootSessionId) { + this.unregisterRootDescendant(existingTask.rootSessionId) } // Release concurrency on error to prevent slot leaks @@ -1101,12 +1102,12 @@ The fallback retry session is now created and can be inspected directly. // Abort the session to prevent infinite polling hang // Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT) - if (existingTask.sessionID) { - await this.abortSessionWithLogging(existingTask.sessionID, "resume error cleanup") + if (existingTask.sessionId) { + await this.abortSessionWithLogging(existingTask.sessionId, "resume error cleanup") } this.markForNotification(existingTask) - this.enqueueNotificationForParent(existingTask.parentSessionID, () => this.notifyParentSession(existingTask)).catch(err => { + this.enqueueNotificationForParent(existingTask.parentSessionId, () => this.notifyParentSession(existingTask)).catch(err => { log("[background-agent] Failed to notify on resume error:", err) }) }) @@ -1386,25 +1387,25 @@ The fallback retry session is now created and can be inspected directly. const deletedSessionIDs = new Set([sessionID]) for (const task of tasksToCancel.values()) { - if (task.sessionID) { - deletedSessionIDs.add(task.sessionID) + if (task.sessionId) { + deletedSessionIDs.add(task.sessionId) } } for (const task of tasksToCancel.values()) { - parentSessionsToClear.add(task.parentSessionID) + parentSessionsToClear.add(task.parentSessionId) if (task.status === "running" || task.status === "pending") { void this.cancelTask(task.id, { source: "session.deleted", reason: "Session deleted", }).then(() => { - if (deletedSessionIDs.has(task.parentSessionID)) { - this.pendingNotifications.delete(task.parentSessionID) + if (deletedSessionIDs.has(task.parentSessionId)) { + this.pendingNotifications.delete(task.parentSessionId) } }).catch(err => { - if (deletedSessionIDs.has(task.parentSessionID)) { - this.pendingNotifications.delete(task.parentSessionID) + if (deletedSessionIDs.has(task.parentSessionId)) { + this.pendingNotifications.delete(task.parentSessionId) } log("[background-agent] Failed to cancel task on session.deleted:", { taskId: task.id, error: err }) }) @@ -1449,8 +1450,8 @@ The fallback retry session is now created and can be inspected directly. }): Promise { const { task, errorInfo, errorMessage, errorName } = args - if (!task.fallbackChain && task.sessionID) { - const sessionFallbackChain = this.modelFallbackControllerAccessor?.getSessionFallbackChain(task.sessionID) + if (!task.fallbackChain && task.sessionId) { + const sessionFallbackChain = this.modelFallbackControllerAccessor?.getSessionFallbackChain(task.sessionId) if (sessionFallbackChain?.length) { task.fallbackChain = sessionFallbackChain } @@ -1490,10 +1491,10 @@ The fallback retry session is now created and can be inspected directly. task.error = errorMsg task.completedAt = new Date() } - if (task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } - this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) + this.taskHistory.record(task.parentSessionId, { id: task.id, sessionID: task.sessionId, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) @@ -1519,12 +1520,12 @@ The fallback retry session is now created and can be inspected directly. toastManager.removeTask(task.id) } this.scheduleTaskRemoval(task.id) - if (task.sessionID) { - SessionCategoryRegistry.remove(task.sessionID) + if (task.sessionId) { + SessionCategoryRegistry.remove(task.sessionId) } this.markForNotification(task) - this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)).catch(err => { + this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch(err => { log("[background-agent] Error in notifyParentSession for errored task:", { taskId: task.id, error: err }) }) } @@ -1534,7 +1535,7 @@ The fallback retry session is now created and can be inspected directly. errorInfo: { name?: string; message?: string }, source: string, ): Promise { - const previousSessionID = task.sessionID + const previousSessionID = task.sessionId const result = tryFallbackRetry({ task, errorInfo, @@ -1546,15 +1547,15 @@ The fallback retry session is now created and can be inspected directly. processKey: (key: string) => this.processKey(key), onRetrying: ({ task, source }) => { const currentAttempt = getCurrentAttempt(task) - const previousAttempt = getPreviousAttempt(task, currentAttempt?.attemptID) + const previousAttempt = getPreviousAttempt(task, currentAttempt?.attemptId) const sourceText = source ? ` via ${source}` : "" - const failedSessionLine = previousAttempt?.sessionID ? `\n- Failed session: \`${previousAttempt.sessionID}\`` : "" + const failedSessionLine = previousAttempt?.sessionId ? `\n- Failed session: \`${previousAttempt.sessionId}\`` : "" const failedModel = formatAttemptModelSummary(previousAttempt) const failedModelLine = failedModel ? `\n- Failed model: \`${failedModel}\`` : "" const failedErrorLine = previousAttempt?.error ? `\n- Error: ${previousAttempt.error}` : "" const nextModel = formatAttemptModelSummary(currentAttempt) this.queuePendingNotification( - task.parentSessionID, + task.parentSessionId, ` [BACKGROUND TASK RETRYING] **ID:** \`${task.id}\` @@ -1576,9 +1577,9 @@ The task was re-queued on a fallback model after a retryable failure. } markForNotification(task: BackgroundTask): void { - const queue = this.notifications.get(task.parentSessionID) ?? [] + const queue = this.notifications.get(task.parentSessionId) ?? [] queue.push(task) - this.notifications.set(task.parentSessionID, queue) + this.notifications.set(task.parentSessionId, queue) } getPendingNotifications(sessionID: string): BackgroundTask[] { @@ -1695,12 +1696,12 @@ The task was re-queued on a fallback model after a retryable failure. * Cleans up the parent entry if no pending tasks remain. */ private cleanupPendingByParent(task: BackgroundTask): void { - if (!task.parentSessionID) return - const pending = this.pendingByParent.get(task.parentSessionID) + if (!task.parentSessionId) return + const pending = this.pendingByParent.get(task.parentSessionId) if (pending) { pending.delete(task.id) if (pending.size === 0) { - this.pendingByParent.delete(task.parentSessionID) + this.pendingByParent.delete(task.parentSessionId) } } } @@ -1724,8 +1725,8 @@ The task was re-queued on a fallback model after a retryable failure. const task = this.tasks.get(taskId) if (!task) return - if (task.parentSessionID) { - const siblings = this.getTasksByParentSession(task.parentSessionID) + if (task.parentSessionId) { + const siblings = this.getTasksByParentSession(task.parentSessionId) const runningOrPendingSiblings = siblings.filter( sibling => sibling.id !== taskId && (sibling.status === "running" || sibling.status === "pending"), ) @@ -1739,10 +1740,10 @@ The task was re-queued on a fallback model after a retryable failure. this.clearNotificationsForTask(taskId) this.removeTask(task) - this.clearTaskHistoryWhenParentTasksGone(task.parentSessionID) - if (task.sessionID) { - subagentSessions.delete(task.sessionID) - SessionCategoryRegistry.remove(task.sessionID) + this.clearTaskHistoryWhenParentTasksGone(task.parentSessionId) + if (task.sessionId) { + subagentSessions.delete(task.sessionId) + SessionCategoryRegistry.remove(task.sessionId) } log("[background-agent] Removed completed task from memory:", taskId) }, TASK_CLEANUP_DELAY_MS) @@ -1791,10 +1792,10 @@ The task was re-queued on a fallback model after a retryable failure. task.error = reason } } - if (wasRunning && task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (wasRunning && task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } - this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "cancelled", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) + this.taskHistory.record(task.parentSessionId, { id: task.id, sessionID: task.sessionId, agent: task.agent, description: task.description, status: "cancelled", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) @@ -1813,11 +1814,11 @@ The task was re-queued on a fallback model after a retryable failure. this.idleDeferralTimers.delete(task.id) } - if (abortSession && task.sessionID) { + if (abortSession && task.sessionId) { // Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT) - await this.abortSessionWithLogging(task.sessionID, `task cancellation (${source})`) + await this.abortSessionWithLogging(task.sessionId, `task cancellation (${source})`) - SessionCategoryRegistry.remove(task.sessionID) + SessionCategoryRegistry.remove(task.sessionId) } removeTaskToastTracking(task.id) @@ -1832,7 +1833,7 @@ The task was re-queued on a fallback model after a retryable failure. this.markForNotification(task) try { - await this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)) + await this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)) log(`[background-agent] Task cancelled via ${source}:`, task.id) } catch (err) { log("[background-agent] Error in notifyParentSession for cancelled task:", { taskId: task.id, error: err }) @@ -1911,10 +1912,10 @@ The task was re-queued on a fallback model after a retryable failure. task.status = "completed" task.completedAt = new Date() } - this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "completed", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) + this.taskHistory.record(task.parentSessionId, { id: task.id, sessionID: task.sessionId, agent: task.agent, description: task.description, status: "completed", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) - if (task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } removeTaskToastTracking(task.id) @@ -1933,15 +1934,15 @@ The task was re-queued on a fallback model after a retryable failure. this.idleDeferralTimers.delete(task.id) } - if (task.sessionID) { + if (task.sessionId) { // Awaited to prevent dangling promise during subagent teardown (Bun/WebKit SIGABRT) - await this.abortSessionWithLogging(task.sessionID, `task completion (${source})`) + await this.abortSessionWithLogging(task.sessionId, `task completion (${source})`) - SessionCategoryRegistry.remove(task.sessionID) + SessionCategoryRegistry.remove(task.sessionId) } try { - await this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)) + await this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)) log(`[background-agent] Task completed via ${source}:`, task.id) } catch (err) { log("[background-agent] Error in notifyParentSession:", { taskId: task.id, error: err }) @@ -1966,10 +1967,10 @@ The task was re-queued on a fallback model after a retryable failure. }) } - if (!this.completedTaskSummaries.has(task.parentSessionID)) { - this.completedTaskSummaries.set(task.parentSessionID, []) + if (!this.completedTaskSummaries.has(task.parentSessionId)) { + this.completedTaskSummaries.set(task.parentSessionId, []) } - this.completedTaskSummaries.get(task.parentSessionID)!.push({ + this.completedTaskSummaries.get(task.parentSessionId)!.push({ id: task.id, description: task.description, status: task.status, @@ -1978,7 +1979,7 @@ The task was re-queued on a fallback model after a retryable failure. }) // Update pending tracking and check if all tasks complete - const pendingSet = this.pendingByParent.get(task.parentSessionID) + const pendingSet = this.pendingByParent.get(task.parentSessionId) let allComplete = false let remainingCount = 0 if (pendingSet) { @@ -1986,21 +1987,21 @@ The task was re-queued on a fallback model after a retryable failure. remainingCount = pendingSet.size allComplete = remainingCount === 0 if (allComplete) { - this.pendingByParent.delete(task.parentSessionID) + this.pendingByParent.delete(task.parentSessionId) } } else { remainingCount = Array.from(this.tasks.values()) - .filter(t => t.parentSessionID === task.parentSessionID && t.id !== task.id && (t.status === "running" || t.status === "pending")) + .filter(t => t.parentSessionId === task.parentSessionId && t.id !== task.id && (t.status === "running" || t.status === "pending")) .length allComplete = remainingCount === 0 } const completedTasks = allComplete - ? (this.completedTaskSummaries.get(task.parentSessionID) ?? [{ id: task.id, description: task.description, status: task.status, error: task.error, attempts: cloneAttempts(task) }]) + ? (this.completedTaskSummaries.get(task.parentSessionId) ?? [{ id: task.id, description: task.description, status: task.status, error: task.error, attempts: cloneAttempts(task) }]) : [] if (allComplete) { - this.completedTaskSummaries.delete(task.parentSessionID) + this.completedTaskSummaries.delete(task.parentSessionId) } const statusText = task.status === "completed" @@ -2026,7 +2027,7 @@ The task was re-queued on a fallback model after a retryable failure. if (this.enableParentSessionNotifications) { try { - const messagesResp = await this.client.session.messages({ path: { id: task.parentSessionID } }) + const messagesResp = await this.client.session.messages({ path: { id: task.parentSessionId } }) const messages = normalizeSDKResponse(messagesResp, [] as Array<{ info?: { agent?: string @@ -2038,7 +2039,7 @@ The task was re-queued on a fallback model after a retryable failure. }>) promptContext = resolvePromptContextFromSessionMessages( messages, - task.parentSessionID, + task.parentSessionId, ) const normalizedTools = isRecord(promptContext?.tools) ? normalizePromptTools(promptContext.tools) @@ -2055,12 +2056,12 @@ The task was re-queued on a fallback model after a retryable failure. if (isAbortedSessionError(error)) { log("[background-agent] Parent session aborted while loading messages; using messageDir fallback:", { taskId: task.id, - parentSessionID: task.parentSessionID, + parentSessionID: task.parentSessionId, }) } - const messageDir = join(MESSAGE_STORAGE, task.parentSessionID) + const messageDir = join(MESSAGE_STORAGE, task.parentSessionId) const currentMessage = messageDir - ? findNearestMessageExcludingCompaction(messageDir, task.parentSessionID) + ? findNearestMessageExcludingCompaction(messageDir, task.parentSessionId) : null agent = currentMessage?.agent ?? task.parentAgent model = currentMessage?.model?.providerID && currentMessage?.model?.modelID @@ -2069,7 +2070,7 @@ The task was re-queued on a fallback model after a retryable failure. tools = normalizePromptTools(currentMessage?.tools) ?? tools } - const resolvedTools = resolveInheritedPromptTools(task.parentSessionID, tools) + const resolvedTools = resolveInheritedPromptTools(task.parentSessionId, tools) log("[background-agent] notifyParentSession context:", { taskId: task.id, @@ -2084,7 +2085,7 @@ The task was re-queued on a fallback model after a retryable failure. try { await this.client.session.promptAsync({ - path: { id: task.parentSessionID }, + path: { id: task.parentSessionId }, body: { noReply: !shouldReply, ...(agent !== undefined ? { agent } : {}), @@ -2104,9 +2105,9 @@ The task was re-queued on a fallback model after a retryable failure. if (isAbortedSessionError(error)) { log("[background-agent] Parent session aborted while sending notification; continuing cleanup:", { taskId: task.id, - parentSessionID: task.parentSessionID, + parentSessionID: task.parentSessionId, }) - this.queuePendingNotification(task.parentSessionID, notification) + this.queuePendingNotification(task.parentSessionId, notification) } else { log("[background-agent] Failed to send notification:", error) } @@ -2114,7 +2115,7 @@ The task was re-queued on a fallback model after a retryable failure. } else { log("[background-agent] Parent session notifications disabled, skipping prompt injection:", { taskId: task.id, - parentSessionID: task.parentSessionID, + parentSessionID: task.parentSessionId, }) } @@ -2141,10 +2142,10 @@ The task was re-queued on a fallback model after a retryable failure. task.status = "error" task.error = errorMessage task.completedAt = new Date() - if (!wasPending && task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (!wasPending && task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } - this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) + this.taskHistory.record(task.parentSessionId, { id: task.id, sessionID: task.sessionId, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) task.concurrencyKey = undefined @@ -2177,7 +2178,7 @@ The task was re-queued on a fallback model after a retryable failure. } this.cleanupPendingByParent(task) this.markForNotification(task) - this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)).catch(err => { + this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch(err => { log("[background-agent] Error in notifyParentSession for stale-pruned task:", { taskId: task.id, error: err }) }) }, @@ -2193,7 +2194,7 @@ The task was re-queued on a fallback model after a retryable failure. directory: this.directory, config: this.config, concurrencyManager: this.concurrencyManager, - notifyParentSession: (task) => this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)), + notifyParentSession: (task) => this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)), sessionStatuses: allStatuses, }) } @@ -2210,10 +2211,10 @@ The task was re-queued on a fallback model after a retryable failure. task.error = errorMessage task.completedAt = new Date() } - if (task.rootSessionID) { - this.unregisterRootDescendant(task.rootSessionID) + if (task.rootSessionId) { + this.unregisterRootDescendant(task.rootSessionId) } - this.taskHistory.record(task.parentSessionID, { id: task.id, sessionID: task.sessionID, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) + this.taskHistory.record(task.parentSessionId, { id: task.id, sessionID: task.sessionId, agent: task.agent, description: task.description, status: "error", category: task.category, startedAt: task.startedAt, completedAt: task.completedAt }) if (task.concurrencyKey) { this.concurrencyManager.release(task.concurrencyKey) task.concurrencyKey = undefined @@ -2234,12 +2235,12 @@ The task was re-queued on a fallback model after a retryable failure. this.clearNotificationsForTask(task.id) removeTaskToastTracking(task.id) this.scheduleTaskRemoval(task.id) - if (task.sessionID) { - SessionCategoryRegistry.remove(task.sessionID) + if (task.sessionId) { + SessionCategoryRegistry.remove(task.sessionId) } this.markForNotification(task) - this.enqueueNotificationForParent(task.parentSessionID, () => this.notifyParentSession(task)).catch(err => { + this.enqueueNotificationForParent(task.parentSessionId, () => this.notifyParentSession(task)).catch(err => { log("[background-agent] Error in notifyParentSession for crashed task:", { taskId: task.id, error: err }) }) } @@ -2258,7 +2259,7 @@ The task was re-queued on a fallback model after a retryable failure. for (const task of this.tasks.values()) { if (task.status !== "running") continue - const sessionID = task.sessionID + const sessionID = task.sessionId if (!sessionID) continue try { @@ -2360,14 +2361,14 @@ The task was re-queued on a fallback model after a retryable failure. // Abort all running sessions to prevent zombie processes (#1240) for (const task of this.tasks.values()) { - if (task.sessionID) { - trackedSessionIDs.add(task.sessionID) + if (task.sessionId) { + trackedSessionIDs.add(task.sessionId) } - if (task.status === "running" && task.sessionID) { + if (task.status === "running" && task.sessionId) { abortRequests.push({ - sessionID: task.sessionID, - promise: abortWithTimeout(this.client, task.sessionID), + sessionID: task.sessionId, + promise: abortWithTimeout(this.client, task.sessionId), }) } } diff --git a/src/features/background-agent/session-idle-event-handler.test.ts b/src/features/background-agent/session-idle-event-handler.test.ts index 1e2efafbc..d0dd04bde 100644 --- a/src/features/background-agent/session-idle-event-handler.test.ts +++ b/src/features/background-agent/session-idle-event-handler.test.ts @@ -7,9 +7,9 @@ import { MIN_IDLE_TIME_MS } from "./constants" function createRunningTask(overrides: Partial = {}): BackgroundTask { return { id: "task-1", - sessionID: "ses-idle-1", - parentSessionID: "parent-ses-1", - parentMessageID: "msg-1", + sessionId: "ses-idle-1", + parentSessionId: "parent-ses-1", + parentMessageId: "msg-1", description: "test idle handler", prompt: "test", agent: "explore", @@ -91,7 +91,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(true), @@ -113,7 +113,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(true), @@ -141,7 +141,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers, validateSessionHasOutput: () => Promise.resolve(true), @@ -175,7 +175,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers, validateSessionHasOutput: () => Promise.resolve(true), @@ -206,7 +206,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers, validateSessionHasOutput: () => Promise.resolve(true), @@ -217,7 +217,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#then - wait for deferred timer await new Promise((resolve) => setTimeout(resolve, remainingMs + 50)) - expect(emitIdleEvent).toHaveBeenCalledWith(task.sessionID) + expect(emitIdleEvent).toHaveBeenCalledWith(task.sessionId) expect(idleDeferralTimers.has(task.id)).toBe(false) } finally { Date.now = realDateNow @@ -233,7 +233,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(true), @@ -254,7 +254,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(false), @@ -275,7 +275,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(true), @@ -296,7 +296,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: async () => { @@ -320,7 +320,7 @@ describe("handleSessionIdleBackgroundEvent", () => { //#when handleSessionIdleBackgroundEvent({ - properties: { sessionID: task.sessionID! }, + properties: { sessionID: task.sessionId! }, findBySession: () => task, idleDeferralTimers: new Map(), validateSessionHasOutput: () => Promise.resolve(true), diff --git a/src/features/background-agent/spawner.test.ts b/src/features/background-agent/spawner.test.ts index 9be6ed1fc..8a228866e 100644 --- a/src/features/background-agent/spawner.test.ts +++ b/src/features/background-agent/spawner.test.ts @@ -37,8 +37,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: "Implement feature", prompt: "Please implement the break-even analysis", agent: "Sisyphus-Junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -47,8 +47,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -109,8 +109,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: "Implement feature", prompt: "Do work", agent: "Sisyphus-Junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -119,8 +119,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, }, } @@ -162,8 +162,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: "Implement feature", prompt: "Do work", agent: "Sisyphus-Junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -172,8 +172,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, }, } @@ -221,8 +221,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: "Test task", prompt: "Do work", agent: "Sisyphus-Junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -231,8 +231,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -284,8 +284,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: "Test task", prompt: "Do work", agent: "Custom-Agent", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -294,8 +294,8 @@ describe("background-agent spawner agent-not-found fallback", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -353,8 +353,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Test task", prompt: "Do the thing", agent: "oracle", - parentSessionID: "parent-1", - parentMessageID: "message-1", + parentSessionId: "parent-1", + parentMessageId: "message-1", model: { providerID: "openai", modelID: "gpt-5.4", @@ -371,8 +371,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Test task", prompt: "Do the thing", agent: "oracle", - parentSessionID: "parent-1", - parentMessageID: "message-1", + parentSessionId: "parent-1", + parentMessageId: "message-1", model: task.model, } @@ -427,8 +427,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Test task", prompt: "Do work", agent: "sisyphus-junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", model: { providerID: "openai", modelID: "gpt-5.4", variant: "medium" }, }) @@ -438,8 +438,8 @@ describe("background-agent spawner fallback model promotion", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -486,8 +486,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Test task", prompt: "Do work", agent: "sisyphus-junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -496,8 +496,8 @@ describe("background-agent spawner fallback model promotion", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -542,8 +542,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Test task", prompt: "Do work", agent: "\u200Bsisyphus-junior", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -552,8 +552,8 @@ describe("background-agent spawner fallback model promotion", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -596,8 +596,8 @@ describe("background-agent spawner fallback model promotion", () => { description: "Legacy ZWSP", prompt: "Do work", agent: "\u200B\u200BHephaestus - Deep Agent", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -606,8 +606,8 @@ describe("background-agent spawner fallback model promotion", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, parentModel: task.parentModel, parentAgent: task.parentAgent, model: task.model, @@ -665,8 +665,8 @@ describe("background-agent spawner tmux callback ordering", () => { description: "Blocking tmux test", prompt: "Do work", agent: "general", - parentSessionID: "ses_parent", - parentMessageID: "msg_parent", + parentSessionId: "ses_parent", + parentMessageId: "msg_parent", }) const item = { @@ -675,8 +675,8 @@ describe("background-agent spawner tmux callback ordering", () => { description: task.description, prompt: task.prompt, agent: task.agent, - parentSessionID: task.parentSessionID, - parentMessageID: task.parentMessageID, + parentSessionId: task.parentSessionId, + parentMessageId: task.parentMessageId, }, } diff --git a/src/features/background-agent/spawner.ts b/src/features/background-agent/spawner.ts index ab6aaa2f1..2cb3edc35 100644 --- a/src/features/background-agent/spawner.ts +++ b/src/features/background-agent/spawner.ts @@ -58,8 +58,8 @@ export function createTask(input: LaunchInput): BackgroundTask { description: input.description, prompt: input.prompt, agent: input.agent, - parentSessionID: input.parentSessionID, - parentMessageID: input.parentMessageID, + parentSessionId: input.parentSessionId, + parentMessageId: input.parentMessageId, parentModel: input.parentModel, parentAgent: input.parentAgent, model: input.model, @@ -84,7 +84,7 @@ export async function startTask( : input.agent const parentSession = await client.session.get({ - path: { id: input.parentSessionID }, + path: { id: input.parentSessionId }, query: { directory }, }).catch((err) => { log(`[background-agent] Failed to get parent session: ${err}`) @@ -95,7 +95,7 @@ export async function startTask( const createResult = await client.session.create({ body: { - parentID: input.parentSessionID, + parentID: input.parentSessionId, ...(input.sessionPermission ? { permission: input.sessionPermission } : {}), } as Record, query: { @@ -116,7 +116,7 @@ export async function startTask( task.status = "running" task.startedAt = new Date() - task.sessionID = sessionID + task.sessionId = sessionID task.progress = { toolCalls: 0, lastUpdate: new Date(), @@ -199,14 +199,14 @@ export async function startTask( tmuxEnabled, isInsideTmux: isInsideTmux(), sessionID, - parentID: input.parentSessionID, + parentID: input.parentSessionId, }) if (onSubagentSessionCreated && tmuxEnabled && isInsideTmux()) { log("[background-agent] Invoking tmux callback (fire-and-forget)", { sessionID }) void onSubagentSessionCreated({ sessionID, - parentID: input.parentSessionID, + parentID: input.parentSessionId, title: input.description, }).catch((err) => { log("[background-agent] Failed to spawn tmux pane:", err) @@ -223,14 +223,14 @@ export async function resumeTask( ): Promise { const { client, concurrencyManager, onTaskError } = ctx - if (!task.sessionID) { + if (!task.sessionId) { throw new Error(`Task has no sessionID: ${task.id}`) } if (task.status === "running") { log("[background-agent] Resume skipped - task already running:", { taskId: task.id, - sessionID: task.sessionID, + sessionID: task.sessionId, }) return } @@ -243,8 +243,8 @@ export async function resumeTask( task.status = "running" task.completedAt = undefined task.error = undefined - task.parentSessionID = input.parentSessionID - task.parentMessageID = input.parentMessageID + task.parentSessionId = input.parentSessionId + task.parentMessageId = input.parentMessageId task.parentModel = input.parentModel task.parentAgent = input.parentAgent task.startedAt = new Date() @@ -254,7 +254,7 @@ export async function resumeTask( lastUpdate: new Date(), } - subagentSessions.add(task.sessionID) + subagentSessions.add(task.sessionId) const toastManager = getTaskToastManager() if (toastManager) { @@ -266,10 +266,10 @@ export async function resumeTask( }) } - log("[background-agent] Resuming task:", { taskId: task.id, sessionID: task.sessionID }) + log("[background-agent] Resuming task:", { taskId: task.id, sessionID: task.sessionId }) log("[background-agent] Resuming task - calling prompt (fire-and-forget) with:", { - sessionID: task.sessionID, + sessionID: task.sessionId, agent: task.agent, model: task.model, promptLength: input.prompt.length, @@ -283,7 +283,7 @@ export async function resumeTask( : undefined const resumeVariant = task.model?.variant - applySessionPromptParams(task.sessionID, task.model) + applySessionPromptParams(task.sessionId, task.model) const resumeBody = { agent: task.agent, @@ -299,7 +299,7 @@ export async function resumeTask( } client.session.promptAsync({ - path: { id: task.sessionID }, + path: { id: task.sessionId }, body: resumeBody, }).catch(async (error) => { if (isAgentNotFoundError(error) && task.agent !== FALLBACK_AGENT) { @@ -310,7 +310,7 @@ export async function resumeTask( }) try { await promptWithModelSuggestionRetry(client, { - path: { id: task.sessionID! }, + path: { id: task.sessionId! }, body: buildFallbackBody(resumeBody, FALLBACK_AGENT), }) task.agent = FALLBACK_AGENT diff --git a/src/features/background-agent/state.ts b/src/features/background-agent/state.ts index 074ece38d..df668f82e 100644 --- a/src/features/background-agent/state.ts +++ b/src/features/background-agent/state.ts @@ -14,7 +14,7 @@ export class TaskStateManager { } findBySession(sessionID: string): BackgroundTask | undefined { for (const task of this.tasks.values()) { - if (task.sessionID === sessionID) { + if (task.sessionId === sessionID) { return task } } @@ -23,7 +23,7 @@ export class TaskStateManager { getTasksByParentSession(sessionID: string): BackgroundTask[] { const result: BackgroundTask[] = [] for (const task of this.tasks.values()) { - if (task.parentSessionID === sessionID) { + if (task.parentSessionId === sessionID) { result.push(task) } } @@ -36,8 +36,8 @@ export class TaskStateManager { for (const child of directChildren) { result.push(child) - if (child.sessionID) { - const descendants = this.getAllDescendantTasks(child.sessionID) + if (child.sessionId) { + const descendants = this.getAllDescendantTasks(child.sessionId) result.push(...descendants) } } @@ -79,8 +79,8 @@ export class TaskStateManager { removeTask(taskId: string): void { const task = this.tasks.get(taskId) - if (task?.sessionID) { - subagentSessions.delete(task.sessionID) + if (task?.sessionId) { + subagentSessions.delete(task.sessionId) } this.tasks.delete(taskId) } @@ -92,20 +92,20 @@ export class TaskStateManager { } cleanupPendingByParent(task: BackgroundTask): void { - if (!task.parentSessionID) return - const pending = this.pendingByParent.get(task.parentSessionID) + if (!task.parentSessionId) return + const pending = this.pendingByParent.get(task.parentSessionId) if (pending) { pending.delete(task.id) if (pending.size === 0) { - this.pendingByParent.delete(task.parentSessionID) + this.pendingByParent.delete(task.parentSessionId) } } } markForNotification(task: BackgroundTask): void { - const queue = this.notifications.get(task.parentSessionID) ?? [] + const queue = this.notifications.get(task.parentSessionId) ?? [] queue.push(task) - this.notifications.set(task.parentSessionID, queue) + this.notifications.set(task.parentSessionId, queue) } getPendingNotifications(sessionID: string): BackgroundTask[] { diff --git a/src/features/background-agent/task-completion-cleanup.test.ts b/src/features/background-agent/task-completion-cleanup.test.ts index 419faf296..b15a84af4 100644 --- a/src/features/background-agent/task-completion-cleanup.test.ts +++ b/src/features/background-agent/task-completion-cleanup.test.ts @@ -29,13 +29,13 @@ afterEach(() => { fakeTimers = undefined }) -function createTask(overrides: Partial & { id: string; parentSessionID: string }): BackgroundTask { +function createTask(overrides: Partial & { id: string; parentSessionId: string }): BackgroundTask { const id = overrides.id - const parentSessionID = overrides.parentSessionID - const { id: _ignoredID, parentSessionID: _ignoredParentSessionID, ...rest } = overrides + const parentSessionID = overrides.parentSessionId + const { id: _ignoredID, parentSessionId: _ignoredParentSessionID, ...rest } = overrides return { - parentMessageID: overrides.parentMessageID ?? "parent-message-id", + parentMessageId: overrides.parentMessageId ?? "parent-message-id", description: overrides.description ?? overrides.id, prompt: overrides.prompt ?? `Prompt for ${overrides.id}`, agent: overrides.agent ?? "test-agent", @@ -43,7 +43,7 @@ function createTask(overrides: Partial & { id: string; parentSes startedAt: overrides.startedAt ?? new Date("2026-03-11T00:00:00.000Z"), ...rest, id, - parentSessionID, + parentSessionId: parentSessionID, } } @@ -74,9 +74,7 @@ function createManager(enableParentSessionNotifications: boolean): { } const manager = new BackgroundManager( - ctx, - undefined, - { enableParentSessionNotifications } + { pluginContext: ctx, config: undefined, enableParentSessionNotifications } ) Reflect.set(manager, "client", client) @@ -162,13 +160,13 @@ describe("BackgroundManager.notifyParentSession cleanup scheduling", () => { const { manager } = createManager(false) managerUnderTest = manager fakeTimers = installFakeTimers() - const taskA = createTask({ id: "task-a", parentSessionID: "parent-1", description: "task A", status: "completed", completedAt: new Date() }) - const taskB = createTask({ id: "task-b", parentSessionID: "parent-1", description: "task B", status: "running" }) - const taskC = createTask({ id: "task-c", parentSessionID: "parent-1", description: "task C", status: "pending" }) + const taskA = createTask({ id: "task-a", parentSessionId: "parent-1", description: "task A", status: "completed", completedAt: new Date() }) + const taskB = createTask({ id: "task-b", parentSessionId: "parent-1", description: "task B", status: "running" }) + const taskC = createTask({ id: "task-c", parentSessionId: "parent-1", description: "task C", status: "pending" }) getTasks(manager).set(taskA.id, taskA) getTasks(manager).set(taskB.id, taskB) getTasks(manager).set(taskC.id, taskC) - getPendingByParent(manager).set(taskA.parentSessionID, new Set([taskA.id, taskB.id, taskC.id])) + getPendingByParent(manager).set(taskA.parentSessionId, new Set([taskA.id, taskB.id, taskC.id])) // when await notifyParentSessionForTest(manager, taskA) @@ -204,11 +202,11 @@ describe("BackgroundManager.notifyParentSession cleanup scheduling", () => { const { manager, promptAsyncCalls } = createManager(true) managerUnderTest = manager fakeTimers = installFakeTimers() - const taskA = createTask({ id: "task-a", parentSessionID: "parent-1", description: "task A", status: "completed", completedAt: new Date("2026-03-11T00:01:00.000Z") }) - const taskB = createTask({ id: "task-b", parentSessionID: "parent-1", description: "task B", status: "running" }) + const taskA = createTask({ id: "task-a", parentSessionId: "parent-1", description: "task A", status: "completed", completedAt: new Date("2026-03-11T00:01:00.000Z") }) + const taskB = createTask({ id: "task-b", parentSessionId: "parent-1", description: "task B", status: "running" }) getTasks(manager).set(taskA.id, taskA) getTasks(manager).set(taskB.id, taskB) - getPendingByParent(manager).set(taskA.parentSessionID, new Set([taskA.id, taskB.id])) + getPendingByParent(manager).set(taskA.parentSessionId, new Set([taskA.id, taskB.id])) await notifyParentSessionForTest(manager, taskA) taskB.status = "completed" @@ -242,9 +240,9 @@ describe("BackgroundManager.notifyParentSession cleanup scheduling", () => { const { manager } = createManager(false) managerUnderTest = manager fakeTimers = installFakeTimers() - const task = createTask({ id: "task-a", parentSessionID: "parent-1", description: "task A", status: "completed", completedAt: new Date("2026-03-11T00:01:00.000Z") }) + const task = createTask({ id: "task-a", parentSessionId: "parent-1", description: "task A", status: "completed", completedAt: new Date("2026-03-11T00:01:00.000Z") }) getTasks(manager).set(task.id, task) - getPendingByParent(manager).set(task.parentSessionID, new Set([task.id])) + getPendingByParent(manager).set(task.parentSessionId, new Set([task.id])) await notifyParentSessionForTest(manager, task) const cleanupTimer = getRequiredTimer(manager, task.id) diff --git a/src/features/background-agent/task-history-cleanup.test.ts b/src/features/background-agent/task-history-cleanup.test.ts index f9dd72c56..4ae464762 100644 --- a/src/features/background-agent/task-history-cleanup.test.ts +++ b/src/features/background-agent/task-history-cleanup.test.ts @@ -29,20 +29,20 @@ function createManager(): BackgroundManager { $: {} as PluginInput["$"], } - const manager = new BackgroundManager(ctx) + const manager = new BackgroundManager({ pluginContext: ctx }) Reflect.set(manager, "client", client) return manager } -function createTask(overrides: Partial & { id: string; parentSessionID: string }): BackgroundTask { +function createTask(overrides: Partial & { id: string; parentSessionId: string }): BackgroundTask { const { id, parentSessionID, ...rest } = overrides return { ...rest, id, parentSessionID, - parentMessageID: rest.parentMessageID ?? "parent-message-id", + parentMessageId: rest.parentMessageId ?? "parent-message-id", description: rest.description ?? id, prompt: rest.prompt ?? `Prompt for ${id}`, agent: rest.agent ?? "test-agent", @@ -118,12 +118,12 @@ describe("task history cleanup", () => { managerUnderTest = manager const staleTask = createTask({ id: "task-stale", - parentSessionID: "parent-1", + parentSessionId: "parent-1", startedAt: new Date(Date.now() - 31 * 60 * 1000), }) const liveTask = createTask({ id: "task-live", - parentSessionID: "parent-2", + parentSessionId: "parent-2", startedAt: new Date(), }) diff --git a/src/features/background-agent/task-poller.test.ts b/src/features/background-agent/task-poller.test.ts index 532fd6e57..f3ccffbda 100644 --- a/src/features/background-agent/task-poller.test.ts +++ b/src/features/background-agent/task-poller.test.ts @@ -33,9 +33,9 @@ describe("checkAndInterruptStaleTasks", () => { function createRunningTask(overrides: Partial = {}): BackgroundTask { return { id: "task-1", - sessionID: "ses-1", - parentSessionID: "parent-ses-1", - parentMessageID: "msg-1", + sessionId: "ses-1", + parentSessionId: "parent-ses-1", + parentMessageId: "msg-1", description: "test", prompt: "test", agent: "explore", @@ -745,8 +745,8 @@ describe("pruneStaleTasksAndNotifications", () => { function createTerminalTask(overrides: Partial = {}): BackgroundTask { return { id: "terminal-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "terminal", prompt: "terminal", agent: "explore", @@ -762,8 +762,8 @@ describe("pruneStaleTasksAndNotifications", () => { const tasks = new Map() const oldTask: BackgroundTask = { id: "old-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "old", prompt: "old", agent: "explore", @@ -791,8 +791,8 @@ describe("pruneStaleTasksAndNotifications", () => { const tasks = new Map() const activeTask: BackgroundTask = { id: "active-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "active", prompt: "active", agent: "oracle", @@ -824,8 +824,8 @@ describe("pruneStaleTasksAndNotifications", () => { const tasks = new Map() const staleTask: BackgroundTask = { id: "stale-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "stale", prompt: "stale", agent: "oracle", @@ -857,8 +857,8 @@ describe("pruneStaleTasksAndNotifications", () => { const tasks = new Map() const task: BackgroundTask = { id: "custom-ttl-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "custom", prompt: "custom", agent: "explore", @@ -887,8 +887,8 @@ describe("pruneStaleTasksAndNotifications", () => { const tasks = new Map() const task: BackgroundTask = { id: "within-ttl-task", - parentSessionID: "parent", - parentMessageID: "msg", + parentSessionId: "parent", + parentMessageId: "msg", description: "within", prompt: "within", agent: "explore", @@ -944,7 +944,7 @@ describe("pruneStaleTasksAndNotifications", () => { //#given const task = createTerminalTask() const tasks = new Map([[task.id, task]]) - const notifications = new Map([[task.parentSessionID, [task]]]) + const notifications = new Map([[task.parentSessionId, [task]]]) const pruned: string[] = [] //#when @@ -957,6 +957,6 @@ describe("pruneStaleTasksAndNotifications", () => { //#then expect(pruned).toEqual([]) expect(tasks.has(task.id)).toBe(true) - expect(notifications.has(task.parentSessionID)).toBe(false) + expect(notifications.has(task.parentSessionId)).toBe(false) }) }) diff --git a/src/features/background-agent/task-poller.ts b/src/features/background-agent/task-poller.ts index 73cb2ac4e..729e2a8f4 100644 --- a/src/features/background-agent/task-poller.ts +++ b/src/features/background-agent/task-poller.ts @@ -131,7 +131,7 @@ export async function checkAndInterruptStaleTasks(args: { if (task.status !== "running") continue const startedAt = task.startedAt - const sessionID = task.sessionID + const sessionID = task.sessionId if (!startedAt || !sessionID) continue const sessionStatus = sessionStatuses?.[sessionID]?.type diff --git a/src/features/background-agent/types.ts b/src/features/background-agent/types.ts index 030fdc014..7d480975b 100644 --- a/src/features/background-agent/types.ts +++ b/src/features/background-agent/types.ts @@ -29,11 +29,11 @@ export interface TaskProgress { export type BackgroundTaskAttemptStatus = BackgroundTaskStatus export interface BackgroundTaskAttempt { - attemptID: string + attemptId: string attemptNumber: number - sessionID?: string - providerID?: string - modelID?: string + sessionId?: string + providerId?: string + modelId?: string variant?: string status: BackgroundTaskAttemptStatus error?: string @@ -43,10 +43,10 @@ export interface BackgroundTaskAttempt { export interface BackgroundTask { id: string - sessionID?: string - rootSessionID?: string - parentSessionID: string - parentMessageID: string + sessionId?: string + rootSessionId?: string + parentSessionId: string + parentMessageId: string description: string prompt: string agent: string @@ -101,8 +101,8 @@ export interface LaunchInput { description: string prompt: string agent: string - parentSessionID: string - parentMessageID: string + parentSessionId: string + parentMessageId: string parentModel?: { providerID: string; modelID: string } parentAgent?: string parentTools?: Record @@ -119,8 +119,8 @@ export interface LaunchInput { export interface ResumeInput { sessionId: string prompt: string - parentSessionID: string - parentMessageID: string + parentSessionId: string + parentMessageId: string parentModel?: { providerID: string; modelID: string } parentAgent?: string parentTools?: Record diff --git a/src/features/background-agent/wait-for-task-session.test.ts b/src/features/background-agent/wait-for-task-session.test.ts index 812d9f700..7ccd97e8c 100644 --- a/src/features/background-agent/wait-for-task-session.test.ts +++ b/src/features/background-agent/wait-for-task-session.test.ts @@ -23,7 +23,7 @@ function createManager(responses: TaskSnapshot[]) { describe("waitForTaskSessionID", () => { test("#given task already has a session id #when waiting #then it returns immediately", async () => { // given - const manager = createManager([{ sessionID: "ses_ready_123", status: "running" }]) + const manager = createManager([{ sessionId: "ses_ready_123", status: "running" }]) // when const sessionID = await waitForTaskSessionID(manager, "bg_ready") @@ -37,7 +37,7 @@ describe("waitForTaskSessionID", () => { const manager = createManager([ { status: "running" }, { status: "running" }, - { sessionID: "ses_late_123", status: "running" }, + { sessionId: "ses_late_123", status: "running" }, ]) // when diff --git a/src/features/background-agent/wait-for-task-session.ts b/src/features/background-agent/wait-for-task-session.ts index eb5fe49d8..992772c71 100644 --- a/src/features/background-agent/wait-for-task-session.ts +++ b/src/features/background-agent/wait-for-task-session.ts @@ -5,7 +5,7 @@ type SessionWaitTerminalStatus = Extract = {}): BackgroundTask { return { id: "task-1", - sessionID: "ses-1", - parentSessionID: "main-1", - parentMessageID: "msg-1", + sessionId: "ses-1", + parentSessionId: "main-1", + parentMessageId: "msg-1", description: "background task", prompt: "do work", agent: "test-agent", diff --git a/src/tools/background-task/create-background-output.metadata.test.ts b/src/tools/background-task/create-background-output.metadata.test.ts index 7b031abee..d763b961a 100644 --- a/src/tools/background-task/create-background-output.metadata.test.ts +++ b/src/tools/background-task/create-background-output.metadata.test.ts @@ -20,9 +20,9 @@ describe("createBackgroundOutput metadata", () => { const task: BackgroundTask = { id: "task-1", - sessionID: undefined, - parentSessionID: "main-1", - parentMessageID: "msg-1", + sessionId: undefined, + parentSessionId: "main-1", + parentMessageId: "msg-1", description: "background task", prompt: "do work", agent: "test-agent", diff --git a/src/tools/background-task/create-background-output.ts b/src/tools/background-task/create-background-output.ts index 56634b191..e4ea3f8ca 100644 --- a/src/tools/background-task/create-background-output.ts +++ b/src/tools/background-task/create-background-output.ts @@ -70,7 +70,7 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: agent: task.agent, category: task.category, description: task.description, - ...(task.sessionID ? { sessionId: task.sessionID, taskId: task.sessionID } : {}), + ...(task.sessionId ? { sessionId: task.sessionId, taskId: task.sessionId } : {}), } as Record, } await publishToolMetadata(ctx, meta) @@ -129,7 +129,7 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: } if (resolvedTask.status === "completed") { - recordBackgroundOutputConsumption(ctx.sessionID, ctx.messageID, resolvedTask.sessionID) + recordBackgroundOutputConsumption(ctx.sessionID, ctx.messageID, resolvedTask.sessionId) return await formatTaskResult(resolvedTask, client) } diff --git a/src/tools/background-task/create-background-output.undo.test.ts b/src/tools/background-task/create-background-output.undo.test.ts index c060cf473..04dc5f534 100644 --- a/src/tools/background-task/create-background-output.undo.test.ts +++ b/src/tools/background-task/create-background-output.undo.test.ts @@ -32,9 +32,9 @@ const baseContext = { function createTask(overrides: Partial = {}): BackgroundTask { return { id: "task-1", - sessionID: taskSessionID, - parentSessionID, - parentMessageID: "msg-parent", + sessionId: taskSessionID, + parentSessionId: parentSessionID, + parentMessageId: "msg-parent", description: "background task", prompt: "do work", agent: "test-agent", diff --git a/src/tools/background-task/create-background-task.test.ts b/src/tools/background-task/create-background-task.test.ts index a7c108ca6..a7b588ff6 100644 --- a/src/tools/background-task/create-background-task.test.ts +++ b/src/tools/background-task/create-background-task.test.ts @@ -8,13 +8,13 @@ import { createBackgroundTask } from "./create-background-task" describe("createBackgroundTask", () => { const launchMock = mock(async (): Promise<{ id: string - sessionID: string | null + sessionId: string | null description: string agent: string status: string }> => ({ id: "test-task-id", - sessionID: null, + sessionId: null, description: "Test task", agent: "test-agent", status: "pending", @@ -55,14 +55,14 @@ describe("createBackgroundTask", () => { //#given launchMock.mockResolvedValueOnce({ id: "test-task-id", - sessionID: null, + sessionId: null, description: "Test task", agent: "test-agent", status: "pending", }) getTaskMock.mockReturnValueOnce({ id: "test-task-id", - sessionID: null, + sessionId: null, description: "Test task", agent: "test-agent", status: "interrupt", @@ -81,7 +81,7 @@ describe("createBackgroundTask", () => { const abortController = new AbortController() launchMock.mockResolvedValueOnce({ id: "test-task-id", - sessionID: null, + sessionId: null, description: "Test task", agent: "test-agent", status: "pending", @@ -90,7 +90,7 @@ describe("createBackgroundTask", () => { abortController.abort() return { id: "test-task-id", - sessionID: null, + sessionId: null, description: "Test task", agent: "test-agent", status: "pending", @@ -114,15 +114,15 @@ describe("createBackgroundTask", () => { const firstAbortController = new AbortController() const secondAbortController = new AbortController() const states = new Map([ - ["task-1", { reads: 0, abortOnFirstRead: true, sessionID: "ses-1" }], - ["task-2", { reads: 0, abortOnFirstRead: false, sessionID: "ses-2" }], + ["task-1", { reads: 0, abortOnFirstRead: true, sessionId: "ses-1" }], + ["task-2", { reads: 0, abortOnFirstRead: false, sessionId: "ses-2" }], ]) let launchCount = 0 launchMock.mockImplementation(async () => { launchCount += 1 return launchCount === 1 - ? { id: "task-1", sessionID: null, description: "Task 1", agent: "test-agent", status: "pending" } - : { id: "task-2", sessionID: null, description: "Task 2", agent: "test-agent", status: "pending" } + ? { id: "task-1", sessionId: null, description: "Task 1", agent: "test-agent", status: "pending" } + : { id: "task-2", sessionId: null, description: "Task 2", agent: "test-agent", status: "pending" } }) getTaskMock.mockImplementation((taskID: string) => { const state = states.get(taskID) @@ -132,8 +132,8 @@ describe("createBackgroundTask", () => { firstAbortController.abort() } return state.reads >= 2 - ? { id: taskID, sessionID: state.sessionID, description: "Task", agent: "test-agent", status: "pending" } - : { id: taskID, sessionID: null, description: "Task", agent: "test-agent", status: "pending" } + ? { id: taskID, sessionId: state.sessionId, description: "Task", agent: "test-agent", status: "pending" } + : { id: taskID, sessionId: null, description: "Task", agent: "test-agent", status: "pending" } }) //#when diff --git a/src/tools/background-task/create-background-task.ts b/src/tools/background-task/create-background-task.ts index cd892e6a3..dbda87948 100644 --- a/src/tools/background-task/create-background-task.ts +++ b/src/tools/background-task/create-background-task.ts @@ -69,8 +69,8 @@ export function createBackgroundTask( description: args.description, prompt: args.prompt, agent: args.agent.trim(), - parentSessionID: ctx.sessionID, - parentMessageID: ctx.messageID, + parentSessionId: ctx.sessionID, + parentMessageId: ctx.messageID, parentModel, parentAgent, }) @@ -78,13 +78,13 @@ export function createBackgroundTask( const WAIT_FOR_SESSION_INTERVAL_MS = 50 const WAIT_FOR_SESSION_TIMEOUT_MS = 30000 const waitStart = Date.now() - let sessionId = task.sessionID + let sessionId = task.sessionId while (!sessionId && Date.now() - waitStart < WAIT_FOR_SESSION_TIMEOUT_MS) { const updated = manager.getTask(task.id) if (updated?.status === "error" || updated?.status === "cancelled" || updated?.status === "interrupt") { return `Task ${`entered error state`}\.\n\nTask ID: ${task.id}` } - sessionId = updated?.sessionID + sessionId = updated?.sessionId if (sessionId) { break } diff --git a/src/tools/background-task/full-session-format.ts b/src/tools/background-task/full-session-format.ts index 9b50a09fb..fae77299c 100644 --- a/src/tools/background-task/full-session-format.ts +++ b/src/tools/background-task/full-session-format.ts @@ -41,12 +41,12 @@ export async function formatFullSession( thinkingMaxChars?: number } ): Promise { - if (!task.sessionID) { + if (!task.sessionId) { return formatTaskStatus(task) } const messagesResult: BackgroundOutputMessagesResult = await client.session.messages({ - path: { id: task.sessionID }, + path: { id: task.sessionId }, }) const errorMessage = getErrorMessage(messagesResult) @@ -107,7 +107,7 @@ export async function formatFullSession( lines.push(`Task ID: ${task.id}`) lines.push(`Description: ${task.description}`) lines.push(`Status: ${task.status}`) - lines.push(`Session ID: ${task.sessionID}`) + lines.push(`Session ID: ${task.sessionId}`) lines.push(`Total messages: ${normalizedMessages.length}`) lines.push(`Returned: ${visibleMessages.length}`) lines.push(`Has more: ${hasMore ? "true" : "false"}`) diff --git a/src/tools/background-task/task-result-format.test.ts b/src/tools/background-task/task-result-format.test.ts index aa34b94e2..ccc091c94 100644 --- a/src/tools/background-task/task-result-format.test.ts +++ b/src/tools/background-task/task-result-format.test.ts @@ -7,9 +7,9 @@ import { formatTaskResult } from "./task-result-format" function createTask(overrides: Partial = {}): BackgroundTask { return { id: "task-1", - sessionID: "ses-1", - parentSessionID: "main-1", - parentMessageID: "msg-1", + sessionId: "ses-1", + parentSessionId: "main-1", + parentMessageId: "msg-1", description: "background task", prompt: "do work", agent: "test-agent", diff --git a/src/tools/background-task/task-result-format.ts b/src/tools/background-task/task-result-format.ts index c71469703..9c1eae348 100644 --- a/src/tools/background-task/task-result-format.ts +++ b/src/tools/background-task/task-result-format.ts @@ -10,12 +10,12 @@ function getTimeString(value: unknown): string { } export async function formatTaskResult(task: BackgroundTask, client: BackgroundOutputClient): Promise { - if (!task.sessionID) { + if (!task.sessionId) { return `Error: Task has no sessionID` } const messagesResult: BackgroundOutputMessagesResult = await client.session.messages({ - path: { id: task.sessionID }, + path: { id: task.sessionId }, }) const errorMessage = getErrorMessage(messagesResult) @@ -30,7 +30,7 @@ export async function formatTaskResult(task: BackgroundTask, client: BackgroundO Task ID: ${task.id} Description: ${task.description} Duration: ${formatDuration(task.startedAt ?? new Date(), task.completedAt)} -Session ID: ${task.sessionID} +Session ID: ${task.sessionId} --- @@ -44,7 +44,7 @@ Session ID: ${task.sessionID} Task ID: ${task.id} Description: ${task.description} Duration: ${formatDuration(task.startedAt ?? new Date(), task.completedAt)} -Session ID: ${task.sessionID} +Session ID: ${task.sessionId} --- @@ -67,14 +67,14 @@ Session ID: ${task.sessionID} Task ID: ${task.id} Description: ${task.description} Duration: ${formatDuration(task.startedAt ?? new Date(), task.completedAt)} -Session ID: ${task.sessionID} +Session ID: ${task.sessionId} --- Session error: ${sessionError}` } - const newMessages = consumeNewMessages(task.sessionID, sortedMessages) + const newMessages = consumeNewMessages(task.sessionId, sortedMessages) if (newMessages.length === 0) { const duration = formatDuration(task.startedAt ?? new Date(), task.completedAt) return `Task Result @@ -82,7 +82,7 @@ Session error: ${sessionError}` Task ID: ${task.id} Description: ${task.description} Duration: ${duration} -Session ID: ${task.sessionID} +Session ID: ${task.sessionId} --- @@ -123,7 +123,7 @@ Session ID: ${task.sessionID} Task ID: ${task.id} Description: ${task.description} Duration: ${duration} -Session ID: ${task.sessionID} +Session ID: ${task.sessionId} --- diff --git a/src/tools/background-task/task-status-format.ts b/src/tools/background-task/task-status-format.ts index 12c742ad8..d62b42ec5 100644 --- a/src/tools/background-task/task-status-format.ts +++ b/src/tools/background-task/task-status-format.ts @@ -62,7 +62,7 @@ ${truncated} | Agent | ${task.agent} | | Status | **${task.status}** | | ${durationLabel} | ${duration} | -| Session ID | \`${task.sessionID}\` |${progressSection} +| Session ID | \`${task.sessionId}\` |${progressSection} ${statusNote} ## Original Prompt diff --git a/src/tools/background-task/tools.test.ts b/src/tools/background-task/tools.test.ts index 78d5987c4..12404bf72 100644 --- a/src/tools/background-task/tools.test.ts +++ b/src/tools/background-task/tools.test.ts @@ -41,9 +41,9 @@ function createMockClient(messagesBySession: Record = {}): BackgroundTask { return { id: "task-1", - sessionID: "ses-1", - parentSessionID: "main-1", - parentMessageID: "msg-1", + sessionId: "ses-1", + parentSessionId: "main-1", + parentMessageId: "msg-1", description: "background task", prompt: "do work", agent: "test-agent", @@ -345,7 +345,7 @@ describe("background_output blocking", () => { test("block=true keeps legacy task result output when full_session is not provided", async () => { // #given a task that transitions running → completed after 2 polls let pollCount = 0 - const task = createTask({ status: "running", sessionID: "ses-blocking-default" }) + const task = createTask({ status: "running", sessionId: "ses-blocking-default" }) const manager: BackgroundOutputManager = { getTask: (id: string) => { if (id !== task.id) return undefined @@ -435,8 +435,8 @@ describe("background_cancel", () => { test("preserves original status in cancellation table", async () => { // #given - const taskA = createTask({ id: "task-a", status: "running", sessionID: "ses-a", description: "running task" }) - const taskB = createTask({ id: "task-b", status: "pending", sessionID: undefined, description: "pending task" }) + const taskA = createTask({ id: "task-a", status: "running", sessionId: "ses-a", description: "running task" }) + const taskB = createTask({ id: "task-b", status: "pending", sessionId: undefined, description: "pending task" }) const manager = { getTask: () => undefined, getAllDescendantTasks: () => [taskA, taskB], diff --git a/src/tools/call-omo-agent/background-agent-executor.ts b/src/tools/call-omo-agent/background-agent-executor.ts index 7318d958c..23cfbfc0d 100644 --- a/src/tools/call-omo-agent/background-agent-executor.ts +++ b/src/tools/call-omo-agent/background-agent-executor.ts @@ -40,8 +40,8 @@ export async function executeBackgroundAgent( description: args.description, prompt: args.prompt, agent: args.subagent_type, - parentSessionID: toolContext.sessionID, - parentMessageID: toolContext.messageID, + parentSessionId: toolContext.sessionID, + parentMessageId: toolContext.messageID, parentAgent, parentTools: getSessionTools(toolContext.sessionID), }) @@ -50,13 +50,13 @@ export async function executeBackgroundAgent( const waitTimeoutMs = 30_000 const waitIntervalMs = 50 - let sessionId = task.sessionID + let sessionId = task.sessionId while (!sessionId && Date.now() - waitStart < waitTimeoutMs) { const updated = manager.getTask(task.id) if (updated?.status === "error" || updated?.status === "cancelled" || updated?.status === "interrupt") { return `Task failed to start (status: ${updated.status}).\n\nTask ID: ${task.id}` } - sessionId = updated?.sessionID + sessionId = updated?.sessionId if (sessionId) { break } diff --git a/src/tools/call-omo-agent/background-executor.ts b/src/tools/call-omo-agent/background-executor.ts index d76133c0b..0483abc64 100644 --- a/src/tools/call-omo-agent/background-executor.ts +++ b/src/tools/call-omo-agent/background-executor.ts @@ -48,8 +48,8 @@ export async function executeBackground( description: args.description, prompt: args.prompt, agent: args.subagent_type, - parentSessionID: toolContext.sessionID, - parentMessageID: toolContext.messageID, + parentSessionId: toolContext.sessionID, + parentMessageId: toolContext.messageID, parentAgent, parentTools: getSessionTools(toolContext.sessionID), model, @@ -59,13 +59,13 @@ export async function executeBackground( const WAIT_FOR_SESSION_INTERVAL_MS = 50 const WAIT_FOR_SESSION_TIMEOUT_MS = 30000 const waitStart = Date.now() - let sessionId = task.sessionID + let sessionId = task.sessionId while (!sessionId && Date.now() - waitStart < WAIT_FOR_SESSION_TIMEOUT_MS) { const updated = manager.getTask(task.id) if (updated?.status === "error" || updated?.status === "cancelled" || updated?.status === "interrupt") { return `Task failed to start (status: ${updated.status}).\n\nTask ID: ${task.id}` } - sessionId = updated?.sessionID + sessionId = updated?.sessionId if (sessionId) { break } diff --git a/src/tools/delegate-task/background-continuation.test.ts b/src/tools/delegate-task/background-continuation.test.ts index 2b0e768c9..bbb03a414 100644 --- a/src/tools/delegate-task/background-continuation.test.ts +++ b/src/tools/delegate-task/background-continuation.test.ts @@ -9,7 +9,7 @@ describe("executeBackgroundContinuation - subagent metadata", () => { description: "oracle consultation", agent: "oracle", status: "running", - sessionID: "ses_resumed_123", + sessionId: "ses_resumed_123", }), } @@ -55,7 +55,7 @@ describe("executeBackgroundContinuation - subagent metadata", () => { description: "unknown task", agent: undefined, status: "running", - sessionID: "ses_resumed_456", + sessionId: "ses_resumed_456", }), } diff --git a/src/tools/delegate-task/background-continuation.ts b/src/tools/delegate-task/background-continuation.ts index 1d0aa94f6..890a87ebf 100644 --- a/src/tools/delegate-task/background-continuation.ts +++ b/src/tools/delegate-task/background-continuation.ts @@ -29,13 +29,13 @@ export async function executeBackgroundContinuation( const task = await manager.resume({ sessionId: taskID, prompt: effectivePrompt, - parentSessionID: parentContext.sessionID, - parentMessageID: parentContext.messageID, + parentSessionId: parentContext.sessionID, + parentMessageId: parentContext.messageID, parentModel: parentContext.model, parentAgent: parentContext.agent, parentTools: getSessionTools(parentContext.sessionID), }) - const sessionId = task.sessionID + const sessionId = task.sessionId const backgroundTaskId = task.id const resolvedModel = resolveMetadataModel(task.model, parentContext.model) diff --git a/src/tools/delegate-task/background-task.test.ts b/src/tools/delegate-task/background-task.test.ts index ea4e159a3..659090e1f 100644 --- a/src/tools/delegate-task/background-task.test.ts +++ b/src/tools/delegate-task/background-task.test.ts @@ -29,7 +29,7 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_unresolved", - sessionID: undefined, + sessionId: undefined, description: "Unresolved session", agent: "explore", status: "running", @@ -72,12 +72,12 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_resolved", - sessionID: "ses_sub_123", + sessionId: "ses_sub_123", description: "Resolved session", agent: "explore", status: "running", }), - getTask: () => ({ sessionID: "ses_sub_123" }), + getTask: () => ({ sessionId: "ses_sub_123" }), } const result = await executeBackgroundTask( @@ -121,14 +121,14 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_late", - sessionID: undefined, + sessionId: undefined, description: "Late session", agent: "explore", status: "running", }), getTask: () => { reads += 1 - return reads >= 2 ? { sessionID: "ses_late_123" } : undefined + return reads >= 2 ? { sessionId: "ses_late_123" } : undefined }, } @@ -171,13 +171,13 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => launchCalls.push(input) return { id: "bg_permission", - sessionID: "ses_permission_123", + sessionId: "ses_permission_123", description: "Permission session", agent: "explore", status: "running", } }, - getTask: () => ({ sessionID: "ses_permission_123" }), + getTask: () => ({ sessionId: "ses_permission_123" }), } //#when @@ -217,13 +217,13 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => launchCalls.push(input) return { id: "bg_clean_agent", - sessionID: "ses_clean_agent", + sessionId: "ses_clean_agent", description: "Clean agent", agent: "sisyphus-junior", status: "running", } }, - getTask: () => ({ sessionID: "ses_clean_agent" }), + getTask: () => ({ sessionId: "ses_clean_agent" }), } //#when @@ -260,14 +260,14 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_abort_after_launch", - sessionID: undefined, + sessionId: undefined, description: "Abort after launch", agent: "explore", status: "pending", }), getTask: () => { abortController.abort() - return { sessionID: undefined, status: "pending" } + return { sessionId: undefined, status: "pending" } }, } @@ -309,7 +309,7 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_abort_category", - sessionID: undefined, + sessionId: undefined, description: "Abort category", agent: "explore", status: "pending", @@ -317,8 +317,8 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => getTask: () => { reads += 1 return reads >= 2 - ? { sessionID: "ses_abort_category", status: "running" } - : { sessionID: undefined, status: "pending" } + ? { sessionId: "ses_abort_category", status: "running" } + : { sessionId: undefined, status: "pending" } }, } @@ -359,12 +359,12 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_abort_terminal", - sessionID: undefined, + sessionId: undefined, description: "Abort terminal", agent: "explore", status: "pending", }), - getTask: () => ({ sessionID: undefined, status: "interrupt" }), + getTask: () => ({ sessionId: undefined, status: "interrupt" }), } //#when @@ -401,7 +401,7 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const manager = { launch: async () => ({ id: "bg_crash_before_prompt", - sessionID: undefined, + sessionId: undefined, description: "Crash before prompt", agent: "explore", status: "pending", @@ -409,9 +409,9 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => getTask: () => { reads += 1 if (reads >= 2) { - return { sessionID: "ses_orphan", status: "error", error: "crash between session creation and prompt send" } + return { sessionId: "ses_orphan", status: "error", error: "crash between session creation and prompt send" } } - return { sessionID: undefined, status: "pending" } + return { sessionId: undefined, status: "pending" } }, } @@ -447,16 +447,16 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => const firstAbortController = new AbortController() const secondAbortController = new AbortController() const states = new Map([ - ["bg_first", { reads: 0, abortOnFirstRead: true, sessionID: "ses_first" }], - ["bg_second", { reads: 0, abortOnFirstRead: false, sessionID: "ses_second" }], + ["bg_first", { reads: 0, abortOnFirstRead: true, sessionId: "ses_first" }], + ["bg_second", { reads: 0, abortOnFirstRead: false, sessionId: "ses_second" }], ]) let launchCount = 0 const manager = { launch: async () => { launchCount += 1 return launchCount === 1 - ? { id: "bg_first", sessionID: undefined, description: "First", agent: "explore", status: "pending" } - : { id: "bg_second", sessionID: undefined, description: "Second", agent: "explore", status: "pending" } + ? { id: "bg_first", sessionId: undefined, description: "First", agent: "explore", status: "pending" } + : { id: "bg_second", sessionId: undefined, description: "Second", agent: "explore", status: "pending" } }, getTask: (taskID: string) => { const state = states.get(taskID) @@ -466,8 +466,8 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => firstAbortController.abort() } return state.reads >= 2 - ? { sessionID: state.sessionID, status: "running" } - : { sessionID: undefined, status: "pending" } + ? { sessionId: state.sessionId, status: "running" } + : { sessionId: undefined, status: "pending" } }, } @@ -531,13 +531,13 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => launchCalls.push(input) return { id: "bg_legacy_zwsp", - sessionID: "ses_legacy_zwsp", + sessionId: "ses_legacy_zwsp", description: "Legacy ZWSP", agent: "Hephaestus - Deep Agent", status: "running", } }, - getTask: () => ({ sessionID: "ses_legacy_zwsp" }), + getTask: () => ({ sessionId: "ses_legacy_zwsp" }), } //#when diff --git a/src/tools/delegate-task/background-task.ts b/src/tools/delegate-task/background-task.ts index e4ec2db38..8de84bf68 100644 --- a/src/tools/delegate-task/background-task.ts +++ b/src/tools/delegate-task/background-task.ts @@ -48,7 +48,7 @@ function continueSessionSetup(args: { return } - const sessionId = updated.sessionID + const sessionId = updated.sessionId if (!sessionId) { continue } @@ -81,7 +81,7 @@ async function waitForBackgroundSessionStart(args: { return undefined } - sessionId = updated?.sessionID + sessionId = updated?.sessionId if (sessionId) { return sessionId } @@ -117,8 +117,8 @@ export async function executeBackgroundTask( description: args.description, prompt: effectivePrompt, agent: normalizedAgent, - parentSessionID: parentContext.sessionID, - parentMessageID: parentContext.messageID, + parentSessionId: parentContext.sessionID, + parentMessageId: parentContext.messageID, parentModel: parentContext.model, parentAgent: parentContext.agent, parentTools: getSessionTools(parentContext.sessionID), @@ -137,7 +137,7 @@ export async function executeBackgroundTask( const timing = getTimingConfig() let sessionId = await waitForBackgroundSessionStart({ taskId: task.id, - initialSessionId: task.sessionID, + initialSessionId: task.sessionId, manager, timing, abortSignal: ctx.abort, diff --git a/src/tools/delegate-task/metadata-await.test.ts b/src/tools/delegate-task/metadata-await.test.ts index 733970d88..6592457c5 100644 --- a/src/tools/delegate-task/metadata-await.test.ts +++ b/src/tools/delegate-task/metadata-await.test.ts @@ -36,7 +36,7 @@ describe("task tool metadata awaiting", () => { prompt: "Do something", agent: "explore", status: "pending", - sessionID: "ses_child", + sessionId: "ses_child", }), getTask: () => undefined, }, diff --git a/src/tools/delegate-task/metadata-model-unification.test.ts b/src/tools/delegate-task/metadata-model-unification.test.ts index 5e913b5e7..3a64022ab 100644 --- a/src/tools/delegate-task/metadata-model-unification.test.ts +++ b/src/tools/delegate-task/metadata-model-unification.test.ts @@ -67,7 +67,7 @@ describe("metadata model unification", () => { manager: { launch: async () => ({ id: "bg_1", description: "test", agent: "explore", - status: "pending", sessionID: "ses_bg", model: MODEL, + status: "pending", sessionId: "ses_bg", model: MODEL, }), getTask: () => undefined, }, @@ -88,7 +88,7 @@ describe("metadata model unification", () => { const launchedTask = { id: "bg_unstable", description: "test", agent: "explore", - status: "completed", sessionID: "ses_unstable", model: MODEL, + status: "completed", sessionId: "ses_unstable", model: MODEL, } await executeUnstableAgentTask( args, ctx, @@ -130,7 +130,7 @@ describe("metadata model unification", () => { manager: { resume: async () => ({ id: "bg_2", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed", model: MODEL, + status: "running", sessionId: "ses_resumed", model: MODEL, }), }, } as any, parentContext) @@ -210,7 +210,7 @@ describe("metadata model unification", () => { manager: { launch: async () => ({ id: "bg_1", description: "test", agent: "explore", - status: "pending", sessionID: "ses_bg", + status: "pending", sessionId: "ses_bg", }), getTask: () => undefined, }, @@ -231,7 +231,7 @@ describe("metadata model unification", () => { const launchedTask = { id: "bg_unstable", description: "test", agent: "explore", - status: "completed", sessionID: "ses_unstable", + status: "completed", sessionId: "ses_unstable", } await executeUnstableAgentTask( @@ -274,7 +274,7 @@ describe("metadata model unification", () => { manager: { resume: async () => ({ id: "bg_2", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed", + status: "running", sessionId: "ses_resumed", }), }, } as any, parentContext) @@ -385,7 +385,7 @@ describe("metadata model unification", () => { manager: { launch: async () => ({ id: "bg_variant", description: "test", agent: "explore", - status: "pending", sessionID: "ses_bg_variant", model: MODEL_WITH_VARIANT, + status: "pending", sessionId: "ses_bg_variant", model: MODEL_WITH_VARIANT, }), getTask: () => undefined, }, @@ -406,7 +406,7 @@ describe("metadata model unification", () => { const launchedTask = { id: "bg_unstable_variant", description: "test", agent: "explore", - status: "completed", sessionID: "ses_unstable_variant", model: MODEL_WITH_VARIANT, + status: "completed", sessionId: "ses_unstable_variant", model: MODEL_WITH_VARIANT, } await executeUnstableAgentTask( @@ -449,7 +449,7 @@ describe("metadata model unification", () => { manager: { resume: async () => ({ id: "bg_resume_variant", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed_variant", model: MODEL_WITH_VARIANT, + status: "running", sessionId: "ses_resumed_variant", model: MODEL_WITH_VARIANT, }), }, } as any, parentContext) diff --git a/src/tools/delegate-task/metadata-task-id-consistency.test.ts b/src/tools/delegate-task/metadata-task-id-consistency.test.ts index 1f0d985d5..69f3f5508 100644 --- a/src/tools/delegate-task/metadata-task-id-consistency.test.ts +++ b/src/tools/delegate-task/metadata-task-id-consistency.test.ts @@ -68,7 +68,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { manager: { launch: async () => ({ id: "bg_abc123", description: "test", agent: "explore", - status: "pending", sessionID: "ses_xyz789", + status: "pending", sessionId: "ses_xyz789", }), getTask: () => undefined, }, @@ -93,7 +93,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { const launchedTask = { id: "bg_unstable_abc", description: "test", agent: "explore", - status: "completed", sessionID: "ses_unstable_xyz", + status: "completed", sessionId: "ses_unstable_xyz", } await executeUnstableAgentTask( @@ -140,7 +140,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { manager: { resume: async () => ({ id: "bg_resumed_y", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed_x", model: MODEL, + status: "running", sessionId: "ses_resumed_x", model: MODEL, }), }, } as any, parentContext) @@ -164,7 +164,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { manager: { resume: async () => ({ id: "bg_resumed_y", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed_x", model: MODEL, category: "deep", + status: "running", sessionId: "ses_resumed_x", model: MODEL, category: "deep", }), }, } as any, parentContext) @@ -191,7 +191,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { manager: { resume: async () => ({ id: "bg_resumed_y", description: "continue", agent: "explore", - status: "running", sessionID: "ses_resumed_x", model: MODEL, + status: "running", sessionId: "ses_resumed_x", model: MODEL, }), }, } as any, parentContext) @@ -372,7 +372,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { manager: { launch: async () => ({ id: "bg_abc123", description: "test", agent: "Sisyphus-Junior", - status: "pending", sessionID: "ses_xyz789", + status: "pending", sessionId: "ses_xyz789", }), getTask: () => undefined, }, @@ -397,7 +397,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { const launchedTask = { id: "bg_unstable_abc", description: "test", agent: "Sisyphus-Junior", - status: "completed", sessionID: "ses_unstable_xyz", + status: "completed", sessionId: "ses_unstable_xyz", } await executeUnstableAgentTask( @@ -436,7 +436,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => { const manager = { getTask: (id: string) => ({ id, - sessionID: "ses_bg_session", + sessionId: "ses_bg_session", agent: "explore", category: "deep", description: "test", diff --git a/src/tools/delegate-task/oracle-gap-closure.test.ts b/src/tools/delegate-task/oracle-gap-closure.test.ts index eb8c3fe1c..57d67965a 100644 --- a/src/tools/delegate-task/oracle-gap-closure.test.ts +++ b/src/tools/delegate-task/oracle-gap-closure.test.ts @@ -131,7 +131,7 @@ describe("delegate-task Oracle gap closure", () => { description: "existing", agent: "explore", status: "running", - sessionID: "ses_bg_category", + sessionId: "ses_bg_category", category: "deep", model: MODEL, }), @@ -163,7 +163,7 @@ describe("delegate-task Oracle gap closure", () => { description: "old desc", agent: "explore", status: "running", - sessionID: "ses_bg_title", + sessionId: "ses_bg_title", model: MODEL, }), }, @@ -221,7 +221,7 @@ describe("delegate-task Oracle gap closure", () => { description: "existing", agent: "explore", status: "running", - sessionID: "ses_bg_skills", + sessionId: "ses_bg_skills", model: MODEL, } }, diff --git a/src/tools/delegate-task/sync-poll-timeout.test.ts b/src/tools/delegate-task/sync-poll-timeout.test.ts index d5381840c..4f5e1afa5 100644 --- a/src/tools/delegate-task/sync-poll-timeout.test.ts +++ b/src/tools/delegate-task/sync-poll-timeout.test.ts @@ -161,8 +161,8 @@ describe("syncPollTimeoutMs threading", () => { } const mockManager = { - launch: async () => ({ id: "task_001", sessionID: "ses_unstable", status: "running" }), - getTask: () => ({ id: "task_001", sessionID: "ses_unstable", status: "running" }), + launch: async () => ({ id: "task_001", sessionId: "ses_unstable", status: "running" }), + getTask: () => ({ id: "task_001", sessionId: "ses_unstable", status: "running" }), } const result = await executeUnstableAgentTask( diff --git a/src/tools/delegate-task/sync-result-fetcher.test.ts b/src/tools/delegate-task/sync-result-fetcher.test.ts index 436b9044e..82a41f3f6 100644 --- a/src/tools/delegate-task/sync-result-fetcher.test.ts +++ b/src/tools/delegate-task/sync-result-fetcher.test.ts @@ -141,4 +141,4 @@ describe("fetchSyncResult", () => { expect(result.ok).toBe(false) expect(result.error).toContain("No assistant response found") }) -}) \ No newline at end of file +}) diff --git a/src/tools/delegate-task/tools.test.ts b/src/tools/delegate-task/tools.test.ts index 070566292..2abd75a71 100644 --- a/src/tools/delegate-task/tools.test.ts +++ b/src/tools/delegate-task/tools.test.ts @@ -578,7 +578,7 @@ describe("sisyphus-task", () => { // given a mock client with no model in config const { createDelegateTask } = require("./tools") - const mockManager = { launch: async () => ({ id: "task-123", status: "pending", description: "Test task", agent: "sisyphus-junior", sessionID: "test-session" }) } + const mockManager = { launch: async () => ({ id: "task-123", status: "pending", description: "Test task", agent: "sisyphus-junior", sessionId: "test-session" }) } const mockClient = { app: { agents: async () => ({ data: [] }) }, config: { get: async () => ({}) }, // No model configured @@ -687,7 +687,7 @@ describe("sisyphus-task", () => { const task = { id: "bg_1", status: "pending", description: "Test task", agent: "explore" } tasks.set(task.id, task) setTimeout(() => { - tasks.set(task.id, { ...task, status: "running", sessionID: "ses_child" }) + tasks.set(task.id, { ...task, status: "running", sessionId: "ses_child" }) }, 20) return task }, @@ -1363,7 +1363,7 @@ describe("sisyphus-task", () => { test("#given task_id without run_in_background #when executing #then throws required parameter error", async () => { // given const { createDelegateTask } = require("./tools") - const mockManager = { resume: async () => ({ id: "task-1", sessionID: "ses_1", status: "running" }) } + const mockManager = { resume: async () => ({ id: "task-1", sessionId: "ses_1", status: "running" }) } const mockClient = { app: { agents: async () => ({ data: [] }) }, config: { get: async () => ({ data: { model: SYSTEM_DEFAULT_MODEL } }) }, @@ -1596,7 +1596,7 @@ describe("sisyphus-task", () => { launchCalled = true return { id: "bg_explicit_true", - sessionID: "ses_bg_explicit_true", + sessionId: "ses_bg_explicit_true", description: "Explicit true", agent: "Sisyphus-Junior", status: "running", @@ -1639,8 +1639,8 @@ describe("sisyphus-task", () => { const firstAbortController = new AbortController() const secondAbortController = new AbortController() const taskStates = new Map([ - ["bg_tool_first", { reads: 0, abortOnFirstRead: true, sessionID: "ses_tool_first" }], - ["bg_tool_second", { reads: 0, abortOnFirstRead: false, sessionID: "ses_tool_second" }], + ["bg_tool_first", { reads: 0, abortOnFirstRead: true, sessionId: "ses_tool_first" }], + ["bg_tool_second", { reads: 0, abortOnFirstRead: false, sessionId: "ses_tool_second" }], ]) let launchCount = 0 const mockManager = { @@ -1649,14 +1649,14 @@ describe("sisyphus-task", () => { return launchCount === 1 ? { id: "bg_tool_first", - sessionID: undefined, + sessionId: undefined, description: "Tool first", agent: "Sisyphus-Junior", status: "running", } : { id: "bg_tool_second", - sessionID: undefined, + sessionId: undefined, description: "Tool second", agent: "Sisyphus-Junior", status: "running", @@ -1670,8 +1670,8 @@ describe("sisyphus-task", () => { firstAbortController.abort() } return state.reads >= 2 - ? { sessionID: state.sessionID, status: "running" } - : { sessionID: undefined, status: "pending" } + ? { sessionId: state.sessionId, status: "running" } + : { sessionId: undefined, status: "pending" } }, } const mockClient = { @@ -1728,7 +1728,7 @@ describe("sisyphus-task", () => { const mockTask = { id: "task-123", - sessionID: "ses_continue_test", + sessionId: "ses_continue_test", description: "Continued task", agent: "explore", status: "running", @@ -1890,7 +1890,7 @@ describe("sisyphus-task", () => { } const tool = createDelegateTask({ - manager: { resume: async () => ({ id: "task-var", sessionID: "ses_var_test", description: "Variant test", agent: "sisyphus-junior", status: "running" }) }, + manager: { resume: async () => ({ id: "task-var", sessionId: "ses_var_test", description: "Variant test", agent: "sisyphus-junior", status: "running" }) }, client: mockClient, }) @@ -1927,7 +1927,7 @@ describe("sisyphus-task", () => { const mockTask = { id: "task-456", - sessionID: "ses_bg_continue", + sessionId: "ses_bg_continue", description: "Background continued task", agent: "explore", status: "running", @@ -2223,7 +2223,7 @@ describe("sisyphus-task", () => { const launchedTask = { id: "task-unstable", - sessionID: "ses_unstable_gemini", + sessionId: "ses_unstable_gemini", description: "Unstable gemini task", agent: "sisyphus-junior", status: "running", @@ -2294,7 +2294,7 @@ describe("sisyphus-task", () => { launchCalled = true return { id: "task-normal-bg", - sessionID: "ses_normal_bg", + sessionId: "ses_normal_bg", description: "Normal background task", agent: "sisyphus-junior", status: "running", @@ -2350,7 +2350,7 @@ describe("sisyphus-task", () => { const launchedTask = { id: "task-unstable-minimax", - sessionID: "ses_unstable_minimax", + sessionId: "ses_unstable_minimax", description: "Unstable minimax task", agent: "sisyphus-junior", status: "running", @@ -2424,7 +2424,7 @@ describe("sisyphus-task", () => { const mockManager = { launch: async () => { launchCalled = true - return { id: "should-not-be-called", sessionID: "x", description: "x", agent: "x", status: "running" } + return { id: "should-not-be-called", sessionId: "x", description: "x", agent: "x", status: "running" } }, } @@ -2486,7 +2486,7 @@ describe("sisyphus-task", () => { const launchedTask = { id: "task-artistry", - sessionID: "ses_artistry_gemini", + sessionId: "ses_artistry_gemini", description: "Artistry gemini task", agent: "sisyphus-junior", status: "running", @@ -2569,7 +2569,7 @@ describe("sisyphus-task", () => { const mockManager = { launch: async () => { launchCalled = true - return { id: "should-not-be-called", sessionID: "x", description: "x", agent: "x", status: "running" } + return { id: "should-not-be-called", sessionId: "x", description: "x", agent: "x", status: "running" } }, } @@ -2630,7 +2630,7 @@ describe("sisyphus-task", () => { const launchedTask = { id: "task-custom-unstable", - sessionID: "ses_custom_unstable", + sessionId: "ses_custom_unstable", description: "Custom unstable task", agent: "sisyphus-junior", status: "running", @@ -2711,7 +2711,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-fallback", - sessionID: "ses_fallback_test", + sessionId: "ses_fallback_test", description: "Fallback test task", agent: "sisyphus-junior", status: "running", @@ -2775,7 +2775,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-ui-model", - sessionID: "ses_ui_model_test", + sessionId: "ses_ui_model_test", description: "UI model inheritance test", agent: "sisyphus-junior", status: "running", @@ -2839,7 +2839,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-override", - sessionID: "ses_override_test", + sessionId: "ses_override_test", description: "Override precedence test", agent: "sisyphus-junior", status: "running", @@ -2900,7 +2900,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-category-precedence", - sessionID: "ses_category_precedence_test", + sessionId: "ses_category_precedence_test", description: "Category precedence test", agent: "sisyphus-junior", status: "running", @@ -2965,7 +2965,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-1295-quick", - sessionID: "ses_1295_quick", + sessionId: "ses_1295_quick", description: "Issue 1295 regression", agent: "sisyphus-junior", status: "running", @@ -3027,7 +3027,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-1295-custom", - sessionID: "ses_1295_custom", + sessionId: "ses_1295_custom", description: "Issue 1295 custom category", agent: "sisyphus-junior", status: "running", @@ -3737,7 +3737,7 @@ describe("sisyphus-task", () => { launchInput = input return { id: "task-explore", - sessionID: "ses_explore_model", + sessionId: "ses_explore_model", description: "Explore task", agent: "explore", status: "running", @@ -4369,7 +4369,7 @@ describe("sisyphus-task", () => { const mockManager = { launch: async () => ({ id: "bg_meta_test", - sessionID: "ses_bg_metadata", + sessionId: "ses_bg_metadata", description: "Background metadata test", agent: "sisyphus-junior", status: "running", diff --git a/src/tools/delegate-task/unstable-agent-cleanup.test.ts b/src/tools/delegate-task/unstable-agent-cleanup.test.ts index 3647351e0..c7ffb9edb 100644 --- a/src/tools/delegate-task/unstable-agent-cleanup.test.ts +++ b/src/tools/delegate-task/unstable-agent-cleanup.test.ts @@ -59,8 +59,8 @@ describe("executeUnstableAgentTask cleanup", () => { const cancelCalls: Array<{ taskId: string; options?: Record }> = [] const mockManager = { - launch: async () => ({ id: "bg_abort_monitoring", sessionID: "ses_abort_monitoring", status: "running" }), - getTask: () => ({ id: "bg_abort_monitoring", sessionID: "ses_abort_monitoring", status: "running" }), + launch: async () => ({ id: "bg_abort_monitoring", sessionId: "ses_abort_monitoring", status: "running" }), + getTask: () => ({ id: "bg_abort_monitoring", sessionId: "ses_abort_monitoring", status: "running" }), cancelTask: async (taskId: string, options?: Record) => { cancelCalls.push({ taskId, options }) return true @@ -99,8 +99,8 @@ describe("executeUnstableAgentTask cleanup", () => { const cancelCalls: Array<{ taskId: string; options?: Record }> = [] const mockManager = { - launch: async () => ({ id: "bg_timeout_cleanup", sessionID: "ses_timeout_cleanup", status: "running" }), - getTask: () => ({ id: "bg_timeout_cleanup", sessionID: "ses_timeout_cleanup", status: "running" }), + launch: async () => ({ id: "bg_timeout_cleanup", sessionId: "ses_timeout_cleanup", status: "running" }), + getTask: () => ({ id: "bg_timeout_cleanup", sessionId: "ses_timeout_cleanup", status: "running" }), cancelTask: async (taskId: string, options?: Record) => { cancelCalls.push({ taskId, options }) return true diff --git a/src/tools/delegate-task/unstable-agent-permission.test.ts b/src/tools/delegate-task/unstable-agent-permission.test.ts index 190eddcf2..50b96bad6 100644 --- a/src/tools/delegate-task/unstable-agent-permission.test.ts +++ b/src/tools/delegate-task/unstable-agent-permission.test.ts @@ -11,7 +11,7 @@ describe("executeUnstableAgentTask session permission", () => { launchCalls.push(input) return { id: "bg_unstable_permission", - sessionID: "ses_unstable_permission", + sessionId: "ses_unstable_permission", description: "test task", agent: "sisyphus-junior", status: "running", @@ -19,7 +19,7 @@ describe("executeUnstableAgentTask session permission", () => { }, getTask: () => ({ id: "bg_unstable_permission", - sessionID: "ses_unstable_permission", + sessionId: "ses_unstable_permission", status: "interrupt", description: "test task", agent: "sisyphus-junior", diff --git a/src/tools/delegate-task/unstable-agent-task.test.ts b/src/tools/delegate-task/unstable-agent-task.test.ts index de5de8408..b52499980 100644 --- a/src/tools/delegate-task/unstable-agent-task.test.ts +++ b/src/tools/delegate-task/unstable-agent-task.test.ts @@ -25,7 +25,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { //#given - a background task that gets interrupted on first poll check const taskState = { id: "bg_test_interrupt", - sessionID: "ses_test_interrupt", + sessionId: "ses_test_interrupt", status: "interrupt" as string, description: "test interrupted task", prompt: "test prompt", @@ -42,7 +42,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { const mockClient = { session: { - status: async () => ({ data: { [taskState.sessionID!]: { type: "idle" } } }), + status: async () => ({ data: { [taskState.sessionId!]: { type: "idle" } } }), messages: async () => ({ data: [] }), }, } @@ -92,7 +92,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { //#given - a background task that is already errored when poll checks const taskState = { id: "bg_test_error", - sessionID: "ses_test_error", + sessionId: "ses_test_error", status: "error" as string, description: "test error task", prompt: "test prompt", @@ -109,7 +109,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { const mockClient = { session: { - status: async () => ({ data: { [taskState.sessionID!]: { type: "idle" } } }), + status: async () => ({ data: { [taskState.sessionId!]: { type: "idle" } } }), messages: async () => ({ data: [] }), }, } @@ -159,7 +159,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { //#given - a background task that is already cancelled when poll checks const taskState = { id: "bg_test_cancel", - sessionID: "ses_test_cancel", + sessionId: "ses_test_cancel", status: "cancelled" as string, description: "test cancelled task", prompt: "test prompt", @@ -176,7 +176,7 @@ describe("executeUnstableAgentTask - interrupt detection", () => { const mockClient = { session: { - status: async () => ({ data: { [taskState.sessionID!]: { type: "idle" } } }), + status: async () => ({ data: { [taskState.sessionId!]: { type: "idle" } } }), messages: async () => ({ data: [] }), }, } diff --git a/src/tools/delegate-task/unstable-agent-task.ts b/src/tools/delegate-task/unstable-agent-task.ts index f81eb9971..f6eff2a8a 100644 --- a/src/tools/delegate-task/unstable-agent-task.ts +++ b/src/tools/delegate-task/unstable-agent-task.ts @@ -33,8 +33,8 @@ export async function executeUnstableAgentTask( description: args.description, prompt: effectivePrompt, agent: agentToUse, - parentSessionID: parentContext.sessionID, - parentMessageID: parentContext.messageID, + parentSessionId: parentContext.sessionID, + parentMessageId: parentContext.messageID, parentModel: parentContext.model, parentAgent: parentContext.agent, parentTools: getSessionTools(parentContext.sessionID), @@ -48,7 +48,7 @@ export async function executeUnstableAgentTask( const timing = getTimingConfig() const waitStart = Date.now() - let sessionID = task.sessionID + let sessionID = task.sessionId while (!sessionID && Date.now() - waitStart < timing.WAIT_FOR_SESSION_TIMEOUT_MS) { if (ctx.abort?.aborted) { cleanupReason = "Parent aborted while waiting for unstable task session start" @@ -56,7 +56,7 @@ export async function executeUnstableAgentTask( } await new Promise(resolve => setTimeout(resolve, timing.WAIT_FOR_SESSION_INTERVAL_MS)) const updated = manager.getTask(task.id) - sessionID = updated?.sessionID + sessionID = updated?.sessionId } if (!sessionID) { cleanupReason = "Unstable task session start timed out before session became available" diff --git a/src/tools/delegate-task/unstable-agent-timeout.test.ts b/src/tools/delegate-task/unstable-agent-timeout.test.ts index 30bdc1fe2..f1f063262 100644 --- a/src/tools/delegate-task/unstable-agent-timeout.test.ts +++ b/src/tools/delegate-task/unstable-agent-timeout.test.ts @@ -22,8 +22,8 @@ describe("executeUnstableAgentTask timeout handling", () => { const { executeUnstableAgentTask } = require("./unstable-agent-task") const mockManager = { - launch: async () => ({ id: "task_001", sessionID: "ses_timeout", status: "running" }), - getTask: () => ({ id: "task_001", sessionID: "ses_timeout", status: "running" }), + launch: async () => ({ id: "task_001", sessionId: "ses_timeout", status: "running" }), + getTask: () => ({ id: "task_001", sessionId: "ses_timeout", status: "running" }), } const mockClient = {