From 498fda11a0e4d49e345860a5c373db5e33ab9e43 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 9 Feb 2026 18:26:16 +0900 Subject: [PATCH] feat(background-agent): handle "interrupt" in notifications, output, and formatting Update notification systems to display INTERRUPTED status. Add interrupt handling to background_output tool (terminal status). Add interrupt-specific status note to formatTaskStatus. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../background-task-notification-template.ts | 2 +- .../background-agent/notification-builder.ts | 2 +- .../create-background-output.ts | 8 ++++---- .../modules/background-output.ts | 14 ++++++------- .../background-task/modules/formatters.ts | 20 +++++++++++-------- .../background-task/task-status-format.ts | 20 +++++++++++-------- 6 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/features/background-agent/background-task-notification-template.ts b/src/features/background-agent/background-task-notification-template.ts index c3234decc..da17cda14 100644 --- a/src/features/background-agent/background-task-notification-template.ts +++ b/src/features/background-agent/background-task-notification-template.ts @@ -1,6 +1,6 @@ import type { BackgroundTask } from "./types" -export type BackgroundTaskNotificationStatus = "COMPLETED" | "CANCELLED" +export type BackgroundTaskNotificationStatus = "COMPLETED" | "CANCELLED" | "INTERRUPTED" export function buildBackgroundTaskNotificationText(input: { task: BackgroundTask diff --git a/src/features/background-agent/notification-builder.ts b/src/features/background-agent/notification-builder.ts index 66e9c5a87..f5bffa651 100644 --- a/src/features/background-agent/notification-builder.ts +++ b/src/features/background-agent/notification-builder.ts @@ -9,7 +9,7 @@ export function buildBackgroundTaskNotificationText(args: { }): string { const { task, duration, allComplete, remainingCount, completedTasks } = args const statusText = - task.status === "completed" ? "COMPLETED" : task.status === "error" ? "ERROR" : "CANCELLED" + task.status === "completed" ? "COMPLETED" : task.status === "interrupt" ? "INTERRUPTED" : task.status === "error" ? "ERROR" : "CANCELLED" const errorInfo = task.error ? `\n**Error:** ${task.error}` : "" if (allComplete) { diff --git a/src/tools/background-task/create-background-output.ts b/src/tools/background-task/create-background-output.ts index 0999aa274..aaca3cb16 100644 --- a/src/tools/background-task/create-background-output.ts +++ b/src/tools/background-task/create-background-output.ts @@ -92,7 +92,7 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: return await formatTaskResult(task, client) } - if (task.status === "error" || task.status === "cancelled") { + if (task.status === "error" || task.status === "cancelled" || task.status === "interrupt") { return formatTaskStatus(task) } @@ -113,9 +113,9 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: return await formatTaskResult(currentTask, client) } - if (currentTask.status === "error" || currentTask.status === "cancelled") { - return formatTaskStatus(currentTask) - } + if (currentTask.status === "error" || currentTask.status === "cancelled" || currentTask.status === "interrupt") { + return formatTaskStatus(currentTask) + } } const finalTask = manager.getTask(args.task_id) diff --git a/src/tools/background-task/modules/background-output.ts b/src/tools/background-task/modules/background-output.ts index d86c4be63..70f522843 100644 --- a/src/tools/background-task/modules/background-output.ts +++ b/src/tools/background-task/modules/background-output.ts @@ -93,10 +93,10 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: return await formatTaskResult(task, client) } - // Error or cancelled: return status immediately - if (task.status === "error" || task.status === "cancelled") { - return formatTaskStatus(task) - } + // Error or cancelled: return status immediately + if (task.status === "error" || task.status === "cancelled" || task.status === "interrupt") { + return formatTaskStatus(task) + } // Non-blocking and still running: return status if (!shouldBlock) { @@ -118,9 +118,9 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client: return await formatTaskResult(currentTask, client) } - if (currentTask.status === "error" || currentTask.status === "cancelled") { - return formatTaskStatus(currentTask) - } + if (currentTask.status === "error" || currentTask.status === "cancelled" || currentTask.status === "interrupt") { + return formatTaskStatus(currentTask) + } } // Timeout exceeded: return current status diff --git a/src/tools/background-task/modules/formatters.ts b/src/tools/background-task/modules/formatters.ts index b569e88bc..aa17e7d9e 100644 --- a/src/tools/background-task/modules/formatters.ts +++ b/src/tools/background-task/modules/formatters.ts @@ -38,20 +38,24 @@ ${truncated} \`\`\`` } - let statusNote = "" - if (task.status === "pending") { - statusNote = ` + let statusNote = "" + if (task.status === "pending") { + statusNote = ` > **Queued**: Task is waiting for a concurrency slot to become available.` - } else if (task.status === "running") { - statusNote = ` + } else if (task.status === "running") { + statusNote = ` > **Note**: No need to wait explicitly - the system will notify you when this task completes.` - } else if (task.status === "error") { - statusNote = ` + } else if (task.status === "error") { + statusNote = ` > **Failed**: The task encountered an error. Check the last message for details.` - } + } else if (task.status === "interrupt") { + statusNote = ` + +> **Interrupted**: The task was interrupted by a prompt error. The session may contain partial results.` + } const durationLabel = task.status === "pending" ? "Queued for" : "Duration" diff --git a/src/tools/background-task/task-status-format.ts b/src/tools/background-task/task-status-format.ts index 8dd89132a..12c742ad8 100644 --- a/src/tools/background-task/task-status-format.ts +++ b/src/tools/background-task/task-status-format.ts @@ -32,20 +32,24 @@ ${truncated} \`\`\`` } - let statusNote = "" - if (task.status === "pending") { - statusNote = ` + let statusNote = "" + if (task.status === "pending") { + statusNote = ` > **Queued**: Task is waiting for a concurrency slot to become available.` - } else if (task.status === "running") { - statusNote = ` + } else if (task.status === "running") { + statusNote = ` > **Note**: No need to wait explicitly - the system will notify you when this task completes.` - } else if (task.status === "error") { - statusNote = ` + } else if (task.status === "error") { + statusNote = ` > **Failed**: The task encountered an error. Check the last message for details.` - } + } else if (task.status === "interrupt") { + statusNote = ` + +> **Interrupted**: The task was interrupted by a prompt error. The session may contain partial results.` + } const durationLabel = task.status === "pending" ? "Queued for" : "Duration"