diff --git a/src/agents/omo.ts b/src/agents/omo.ts index 122825f..b4b93fc 100644 --- a/src/agents/omo.ts +++ b/src/agents/omo.ts @@ -844,6 +844,7 @@ You are allowed to be proactive, but balance this with user expectations: - **Stop when you have enough** - don't over-explore - **Evidence for everything** - no evidence = not complete - **Background pattern** - fire agents, continue working, collect with background_output +- **Cleanup before answering** - When ready to deliver your final answer, cancel ALL running background tasks with \`background_cancel(all=true)\` first, then respond. This conserves resources and ensures clean workflow completion. - Complete accepted tasks fully - don't stop halfway through implementation - But if you discover the task is larger or more complex than initially apparent, communicate this and confirm direction before investing significant effort diff --git a/src/tools/background-task/constants.ts b/src/tools/background-task/constants.ts index 756ad24..5e9b8f2 100644 --- a/src/tools/background-task/constants.ts +++ b/src/tools/background-task/constants.ts @@ -25,9 +25,12 @@ Arguments: The system automatically notifies when background tasks complete. You typically don't need block=true.` -export const BACKGROUND_CANCEL_DESCRIPTION = `Cancel a running background task. +export const BACKGROUND_CANCEL_DESCRIPTION = `Cancel running background task(s). Only works for tasks with status "running". Aborts the background session and marks the task as cancelled. Arguments: -- taskId: Required task ID to cancel.` +- taskId: Task ID to cancel (optional if all=true) +- all: Set to true to cancel ALL running background tasks at once (default: false) + +**Cleanup Before Answer**: When you have gathered sufficient information and are ready to provide your final answer to the user, use \`all=true\` to cancel ALL running background tasks first, then deliver your response. This conserves resources and ensures clean workflow completion.` diff --git a/src/tools/background-task/tools.ts b/src/tools/background-task/tools.ts index 98eba74..4a33bd4 100644 --- a/src/tools/background-task/tools.ts +++ b/src/tools/background-task/tools.ts @@ -263,11 +263,42 @@ export function createBackgroundCancel(manager: BackgroundManager, client: Openc return tool({ description: BACKGROUND_CANCEL_DESCRIPTION, args: { - taskId: tool.schema.string().describe("Task ID to cancel"), + taskId: tool.schema.string().optional().describe("Task ID to cancel (required if all=false)"), + all: tool.schema.boolean().optional().describe("Cancel all running background tasks (default: false)"), }, - async execute(args: BackgroundCancelArgs) { + async execute(args: BackgroundCancelArgs, toolContext) { try { - const task = manager.getTask(args.taskId) + const cancelAll = args.all === true + + if (!cancelAll && !args.taskId) { + return `❌ Invalid arguments: Either provide a taskId or set all=true to cancel all running tasks.` + } + + if (cancelAll) { + const tasks = manager.getTasksByParentSession(toolContext.sessionID) + const runningTasks = tasks.filter(t => t.status === "running") + + if (runningTasks.length === 0) { + return `✅ No running background tasks to cancel.` + } + + const results: string[] = [] + for (const task of runningTasks) { + client.session.abort({ + path: { id: task.sessionID }, + }).catch(() => {}) + + task.status = "cancelled" + task.completedAt = new Date() + results.push(`- ${task.id}: ${task.description}`) + } + + return `✅ Cancelled ${runningTasks.length} background task(s): + +${results.join("\n")}` + } + + const task = manager.getTask(args.taskId!) if (!task) { return `❌ Task not found: ${args.taskId}` } diff --git a/src/tools/background-task/types.ts b/src/tools/background-task/types.ts index 3b346ee..1b6cf87 100644 --- a/src/tools/background-task/types.ts +++ b/src/tools/background-task/types.ts @@ -11,5 +11,6 @@ export interface BackgroundOutputArgs { } export interface BackgroundCancelArgs { - taskId: string + taskId?: string + all?: boolean }