Add background agent task tools for concurrent sub-agent dispatch (#863)#1908
Add background agent task tools for concurrent sub-agent dispatch (#863)#1908dgageot merged 1 commit intodocker:mainfrom
Conversation
dgageot
left a comment
There was a problem hiding this comment.
LGTM in general! Sorry, I left a few nit-picky comments. Feel free to ignore.
One of the things that could be better is that most of the code lives in the runtime package that we wish would be simpler. Do you think most of it could be extracted?
pkg/runtime/background_agent.go
Outdated
|
|
||
| // agent task status constants — mirrors backgroundJob in shell.go | ||
| const ( | ||
| agentTaskRunning int32 = iota |
There was a problem hiding this comment.
We should maybe introduce a type for the enum rather than int32?
I'll take care of all those and will refactor the background agent into a builtin task. It is similar to shell but has a dependency on some of the stream interfaces so I can work out an injectable interface for that to segregate the code more. |
2613048 to
37c1ce2
Compare
…cker#863) Add four tools mirroring the existing shell background job pattern, enabling orchestrating agents to dispatch sub-agent tasks concurrently: - run_background_agent: fire-and-forget dispatch, returns task ID - list_background_agents: show all tasks with status and runtime - view_background_agent: inspect live output or final result - stop_background_agent: cancel a running task Tools are registered for any agent with sub_agents configured. The handler and task tracking live in pkg/tools/builtin/agent/, following the same self-contained pattern as the shell tool. A Runner interface abstracts the runtime dependency, with LocalRuntime implementing it via thin delegation methods matching the existing tool handler pattern. Key design decisions: - Session-scoped agent identity (session.WithAgentName) eliminates the shared currentAgent race for concurrent background tasks - ToolsApproved=true for background sessions (no user to approve) - Resource caps: 20 concurrent, 100 total, 10MB output buffer per task - Typed taskStatus enum with google/uuid for task IDs - CAS-based status transitions with result written before CAS to prevent data race with concurrent readers - RunAgent drains the event channel on early error/cancellation to prevent RunStream goroutine from blocking Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
37c1ce2 to
097de4e
Compare
Summary
Implements concurrent sub-agent orchestration from #863 by adding four background agent tools that mirror the existing shell background job pattern:
run_background_agent— dispatch a named sub-agent task asynchronously, returns a task ID immediatelylist_background_agents— show all tasks with status and runtimeview_background_agent— inspect live buffered output or final result by task IDstop_background_agent— cancel a running taskTools are registered automatically for any agent that has
sub_agentsconfigured, alongside the existingtransfer_tasktool.Architecture
Handler and task tracking live in
pkg/tools/builtin/agent/, following the same self-contained pattern as the shell tool inbuiltin/shell.go. ARunnerinterface abstracts the runtime dependency:LocalRuntimeimplementsRunnerand registers the handlers via thin delegation methods, matching the existing pattern used byhandleTaskTransfer,handleHandoff, etc.Key design decisions
session.WithAgentNamepins each background session to its target agent, soRunStreamresolves configuration from the session rather than the sharedcurrentAgentfield. This eliminates the race between concurrent background tasks.view_background_agent, matching the UX of shell background jobsToolsApproved=truefor background sessions — no user present to answer approval prompts; documented with a TODO for per-session permission scopingtaskStatus int32withiota,google/uuidfor task IDsTest plan
pkg/tools/builtin/agent/with race detectorgo build ./...,go vet ./...clean🤖 Generated with Claude Code