[PR #6045] feat(task): implement fire-and-forget TaskTool with background execution #11713

Closed
opened 2026-02-16 18:16:39 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/6045

State: closed
Merged: No


Summary

Implements Phase 4 of the Background Task Runner plan: Makes TaskTool truly fire-and-forget by returning immediately after enqueueing work to SessionRunner, while maintaining live progress updates in the parent tool part metadata.

PR Stack

This PR is part of a stacked PR series. Please review and merge in order.

PR Branch Description Status
#5996 feat/async-subagent-1-runner SessionRunner abstraction 🔵 Open
#6036 feat/async-subagent-2-background Background job runner with queue and lifecycle events 🔵 Open
#6041 feat/async-subagent-3-centralize Centralize async session work through SessionRunner 🔵 Open
This PR pr4-fire-and-forget-tasktool Fire-and-forget TaskTool 🆕 New

Base: This PR is stacked on top of #6041

Changes

src/tool/tool.ts

  • Add toolPartID?: string to Tool.Context type for post-return metadata updates

src/session/prompt.ts

  • Pass toolPartID when invoking tool.execute() so tools can update their own part after returning

src/tool/task.ts

  • Fire-and-forget execution: Return immediately after enqueueing work to SessionRunner
  • Live progress updates: Subscribe to child session PartUpdated events and update parent tool part metadata via Storage.read + Session.updatePart
  • Final status propagation: Update parent metadata with job status (completed, failed, canceled, timed_out) when background job ends
  • Proper cleanup: Subscribe to all job lifecycle events and clean up listeners/abort handlers
  • Error handling: Log enqueue failures and perform cleanup; log storage read errors with context
  • Accurate tracing: Use ctx.callID (actual tool call ID) instead of ctx.messageID

Behavior Change

Before: TaskTool blocked until child session completed, then returned the full result.

After: TaskTool returns immediately with "Task started in background." and the child session runs asynchronously. Progress is streamed to the parent tool part metadata. Users can click to navigate to the subagent session.

Testing

  • All 30 SessionRunner tests pass
  • Type checker passes (only pre-existing TUI errors remain)

Related

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/6045 **State:** closed **Merged:** No --- ## Summary Implements Phase 4 of the Background Task Runner plan: Makes TaskTool truly fire-and-forget by returning immediately after enqueueing work to SessionRunner, while maintaining live progress updates in the parent tool part metadata. ## PR Stack > **This PR is part of a stacked PR series. Please review and merge in order.** | PR | Branch | Description | Status | |---|---|---|---| | #5996 | `feat/async-subagent-1-runner` | SessionRunner abstraction | 🔵 Open | | #6036 | `feat/async-subagent-2-background` | Background job runner with queue and lifecycle events | 🔵 Open | | #6041 | `feat/async-subagent-3-centralize` | Centralize async session work through SessionRunner | 🔵 Open | | **This PR** | `pr4-fire-and-forget-tasktool` | **Fire-and-forget TaskTool** | 🆕 New | **Base:** This PR is stacked on top of #6041 ## Changes ### `src/tool/tool.ts` - Add `toolPartID?: string` to `Tool.Context` type for post-return metadata updates ### `src/session/prompt.ts` - Pass `toolPartID` when invoking `tool.execute()` so tools can update their own part after returning ### `src/tool/task.ts` - **Fire-and-forget execution**: Return immediately after enqueueing work to SessionRunner - **Live progress updates**: Subscribe to child session `PartUpdated` events and update parent tool part metadata via `Storage.read` + `Session.updatePart` - **Final status propagation**: Update parent metadata with job status (`completed`, `failed`, `canceled`, `timed_out`) when background job ends - **Proper cleanup**: Subscribe to all job lifecycle events and clean up listeners/abort handlers - **Error handling**: Log enqueue failures and perform cleanup; log storage read errors with context - **Accurate tracing**: Use `ctx.callID` (actual tool call ID) instead of `ctx.messageID` ## Behavior Change **Before:** TaskTool blocked until child session completed, then returned the full result. **After:** TaskTool returns immediately with `"Task started in background."` and the child session runs asynchronously. Progress is streamed to the parent tool part metadata. Users can click to navigate to the subagent session. ## Testing - All 30 SessionRunner tests pass - Type checker passes (only pre-existing TUI errors remain) ## Related - Depends on: #6041, #6036, #5996 - Plan document: `~/Desktop/plan.md` (Phase 4)
yindo added the pull-request label 2026-02-16 18:16:39 -05:00
yindo closed this issue 2026-02-16 18:16:39 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#11713