From 247940bf02c52c305a87d08fadac5b3e7f3789bb Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 9 Feb 2026 11:15:22 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20address=20Cubic=20background-agent=20iss?= =?UTF-8?q?ues=20=E2=80=94=20task=20status=20filter,=20array=20response=20?= =?UTF-8?q?handling,=20error=20mapping,=20concurrency=20key,=20duration=20?= =?UTF-8?q?fallback,=20output=20validation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/background-agent/notification-builder.ts | 3 ++- src/features/background-agent/parent-session-notifier.ts | 2 +- src/features/background-agent/poll-running-tasks.ts | 5 ++++- src/features/background-agent/session-output-validator.ts | 3 ++- src/features/background-agent/task-queries.ts | 2 +- src/features/background-agent/task-resumer.ts | 6 +++++- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/features/background-agent/notification-builder.ts b/src/features/background-agent/notification-builder.ts index e16d2b4e5..66e9c5a87 100644 --- a/src/features/background-agent/notification-builder.ts +++ b/src/features/background-agent/notification-builder.ts @@ -8,7 +8,8 @@ export function buildBackgroundTaskNotificationText(args: { completedTasks: BackgroundTask[] }): string { const { task, duration, allComplete, remainingCount, completedTasks } = args - const statusText = task.status === "completed" ? "COMPLETED" : "CANCELLED" + const statusText = + task.status === "completed" ? "COMPLETED" : task.status === "error" ? "ERROR" : "CANCELLED" const errorInfo = task.error ? `\n**Error:** ${task.error}` : "" if (allComplete) { diff --git a/src/features/background-agent/parent-session-notifier.ts b/src/features/background-agent/parent-session-notifier.ts index 9d4c1ac08..2c2ff05ae 100644 --- a/src/features/background-agent/parent-session-notifier.ts +++ b/src/features/background-agent/parent-session-notifier.ts @@ -13,7 +13,7 @@ export async function notifyParentSession( ): Promise { const { client, state } = ctx - const duration = formatDuration(task.startedAt ?? new Date(), task.completedAt) + const duration = formatDuration(task.startedAt ?? task.completedAt ?? new Date(), task.completedAt) log("[background-agent] notifyParentSession called for task:", task.id) const toastManager = getTaskToastManager() diff --git a/src/features/background-agent/poll-running-tasks.ts b/src/features/background-agent/poll-running-tasks.ts index 688bba6f8..6c5a4461d 100644 --- a/src/features/background-agent/poll-running-tasks.ts +++ b/src/features/background-agent/poll-running-tasks.ts @@ -94,7 +94,10 @@ export async function pollRunningTasks(args: { continue } - const messages = asSessionMessages((messagesResult as { data?: unknown }).data) + const messagesPayload = Array.isArray(messagesResult) + ? messagesResult + : (messagesResult as { data?: unknown }).data + const messages = asSessionMessages(messagesPayload) const assistantMsgs = messages.filter((m) => m.info?.role === "assistant") let toolCalls = 0 diff --git a/src/features/background-agent/session-output-validator.ts b/src/features/background-agent/session-output-validator.ts index 136bcc41c..8e14a21c8 100644 --- a/src/features/background-agent/session-output-validator.ts +++ b/src/features/background-agent/session-output-validator.ts @@ -55,7 +55,8 @@ export async function validateSessionHasOutput( path: { id: sessionID }, }) - const messagesRaw = "data" in response ? response.data : [] + const messagesRaw = + isObject(response) && "data" in response ? (response as { data?: unknown }).data : response const messages = Array.isArray(messagesRaw) ? messagesRaw : [] const hasAssistantOrToolMessage = messages.some((message) => { diff --git a/src/features/background-agent/task-queries.ts b/src/features/background-agent/task-queries.ts index d53c6f901..641f0e41d 100644 --- a/src/features/background-agent/task-queries.ts +++ b/src/features/background-agent/task-queries.ts @@ -45,7 +45,7 @@ export function getRunningTasks(tasks: Iterable): BackgroundTask } export function getCompletedTasks(tasks: Iterable): BackgroundTask[] { - return Array.from(tasks).filter((t) => t.status !== "running") + return Array.from(tasks).filter((t) => t.status === "completed") } export function hasRunningTasks(tasks: Iterable): boolean { diff --git a/src/features/background-agent/task-resumer.ts b/src/features/background-agent/task-resumer.ts index e09b12768..632081c3a 100644 --- a/src/features/background-agent/task-resumer.ts +++ b/src/features/background-agent/task-resumer.ts @@ -48,7 +48,11 @@ export async function resumeBackgroundTask(args: { return existingTask } - const concurrencyKey = existingTask.concurrencyGroup ?? existingTask.agent + const concurrencyKey = + existingTask.concurrencyGroup ?? + (existingTask.model + ? `${existingTask.model.providerID}/${existingTask.model.modelID}` + : existingTask.agent) await concurrencyManager.acquire(concurrencyKey) existingTask.concurrencyKey = concurrencyKey existingTask.concurrencyGroup = concurrencyKey