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 <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
5b34a98e0a
commit
498fda11a0
@ -1,6 +1,6 @@
|
|||||||
import type { BackgroundTask } from "./types"
|
import type { BackgroundTask } from "./types"
|
||||||
|
|
||||||
export type BackgroundTaskNotificationStatus = "COMPLETED" | "CANCELLED"
|
export type BackgroundTaskNotificationStatus = "COMPLETED" | "CANCELLED" | "INTERRUPTED"
|
||||||
|
|
||||||
export function buildBackgroundTaskNotificationText(input: {
|
export function buildBackgroundTaskNotificationText(input: {
|
||||||
task: BackgroundTask
|
task: BackgroundTask
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export function buildBackgroundTaskNotificationText(args: {
|
|||||||
}): string {
|
}): string {
|
||||||
const { task, duration, allComplete, remainingCount, completedTasks } = args
|
const { task, duration, allComplete, remainingCount, completedTasks } = args
|
||||||
const statusText =
|
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}` : ""
|
const errorInfo = task.error ? `\n**Error:** ${task.error}` : ""
|
||||||
|
|
||||||
if (allComplete) {
|
if (allComplete) {
|
||||||
|
|||||||
@ -92,7 +92,7 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client:
|
|||||||
return await formatTaskResult(task, 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)
|
return formatTaskStatus(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,9 +113,9 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client:
|
|||||||
return await formatTaskResult(currentTask, client)
|
return await formatTaskResult(currentTask, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTask.status === "error" || currentTask.status === "cancelled") {
|
if (currentTask.status === "error" || currentTask.status === "cancelled" || currentTask.status === "interrupt") {
|
||||||
return formatTaskStatus(currentTask)
|
return formatTaskStatus(currentTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalTask = manager.getTask(args.task_id)
|
const finalTask = manager.getTask(args.task_id)
|
||||||
|
|||||||
@ -93,10 +93,10 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client:
|
|||||||
return await formatTaskResult(task, client)
|
return await formatTaskResult(task, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error or cancelled: return status immediately
|
// Error or cancelled: return status immediately
|
||||||
if (task.status === "error" || task.status === "cancelled") {
|
if (task.status === "error" || task.status === "cancelled" || task.status === "interrupt") {
|
||||||
return formatTaskStatus(task)
|
return formatTaskStatus(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-blocking and still running: return status
|
// Non-blocking and still running: return status
|
||||||
if (!shouldBlock) {
|
if (!shouldBlock) {
|
||||||
@ -118,9 +118,9 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client:
|
|||||||
return await formatTaskResult(currentTask, client)
|
return await formatTaskResult(currentTask, client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentTask.status === "error" || currentTask.status === "cancelled") {
|
if (currentTask.status === "error" || currentTask.status === "cancelled" || currentTask.status === "interrupt") {
|
||||||
return formatTaskStatus(currentTask)
|
return formatTaskStatus(currentTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout exceeded: return current status
|
// Timeout exceeded: return current status
|
||||||
|
|||||||
@ -38,20 +38,24 @@ ${truncated}
|
|||||||
\`\`\``
|
\`\`\``
|
||||||
}
|
}
|
||||||
|
|
||||||
let statusNote = ""
|
let statusNote = ""
|
||||||
if (task.status === "pending") {
|
if (task.status === "pending") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Queued**: Task is waiting for a concurrency slot to become available.`
|
> **Queued**: Task is waiting for a concurrency slot to become available.`
|
||||||
} else if (task.status === "running") {
|
} else if (task.status === "running") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Note**: No need to wait explicitly - the system will notify you when this task completes.`
|
> **Note**: No need to wait explicitly - the system will notify you when this task completes.`
|
||||||
} else if (task.status === "error") {
|
} else if (task.status === "error") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Failed**: The task encountered an error. Check the last message for details.`
|
> **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"
|
const durationLabel = task.status === "pending" ? "Queued for" : "Duration"
|
||||||
|
|
||||||
|
|||||||
@ -32,20 +32,24 @@ ${truncated}
|
|||||||
\`\`\``
|
\`\`\``
|
||||||
}
|
}
|
||||||
|
|
||||||
let statusNote = ""
|
let statusNote = ""
|
||||||
if (task.status === "pending") {
|
if (task.status === "pending") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Queued**: Task is waiting for a concurrency slot to become available.`
|
> **Queued**: Task is waiting for a concurrency slot to become available.`
|
||||||
} else if (task.status === "running") {
|
} else if (task.status === "running") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Note**: No need to wait explicitly - the system will notify you when this task completes.`
|
> **Note**: No need to wait explicitly - the system will notify you when this task completes.`
|
||||||
} else if (task.status === "error") {
|
} else if (task.status === "error") {
|
||||||
statusNote = `
|
statusNote = `
|
||||||
|
|
||||||
> **Failed**: The task encountered an error. Check the last message for details.`
|
> **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"
|
const durationLabel = task.status === "pending" ? "Queued for" : "Duration"
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user