5.7 KiB
subagent_spawn
Spawn an independent subagent session. The subagent receives the prompt and runs asynchronously — subagent_spawn returns immediately with the session path. Use prompt files for coordination and completion signaling.
Trigger condition: a task decomposes into independent subtasks each requiring multi-step reasoning or multiple tool calls; you are processing N items with the same operation; a subtask is better handled by a different agent (model, backend, or prompt); or the current agent's identity would work against the quality of a subtask — in which case, delegate to an agent whose identity is aligned with it. In the last case, your job is to gather the necessary material and write a clear, scoped prompt for the specialized agent, not to do the work yourself.
Example: a coding agent asked to write documentation should not write the docs directly — its prompt is oriented toward brevity and minimal additions, which is antagonistic to good documentation. Instead, extract the relevant context from the codebase, identify the target audience and scope, and spawn a docs agent with a well-formed prompt.
Calling convention:
execute_code: steps=[{tool: "subagent_spawn", args: ["-name", "NAME", "-agent", "A", "-cwd", "/path", "prompt text here"]}]
| Flag | Default | Description |
|---|---|---|
-name NAME |
auto | Session name; predictable IDs let you build a roster before agents start |
-agent A |
server default | Agent config name |
-backend B |
server default | Backend override |
-model M |
server default | Model override |
-cwd DIR |
pwd |
Working directory for each subagent |
Prompt is all remaining arguments after flags.
Returns: session path (e.g. ~/mnt/ollie/s/my-session).
Constraints:
- Subagents do not share memory with the parent session. Pass any necessary context explicitly in the prompt.
- The parent does not wait for subagents to finish. Subagents signal completion by writing to the parent's prompt file.
Coordination
A subagent is a full agent, not an extension of the parent. It runs the same system prompt and has the same capabilities. What it lacks is situational awareness — it does not know who spawned it, what the larger goal is, or who else it may be coordinating with. Several of these are established by convention and need not be spelled out manually.
Spawner is injected automatically: subagent_spawn prepends
[parent_session_id=...] and [session_id=...] headers to every prompt.
The child always knows its own ID and who spawned it without the calling
agent needing to reference $OLLIE_SESSION_ID.
Role is implicit in the agent config. -agent reviewer means the child
is a code reviewer; the agent.json describes what that means. No additional
role description is needed unless the task scope differs from the agent's
general mandate.
Shared task should be included explicitly: the beads issue ID or todo entry tracking the overall work. This is the one field the parent must always provide.
Peers are known at spawn time. The parent creates the full roster and
assigns -name to each subagent, so every peer ID is known before any agent
starts. Pass the complete roster (name → task mapping) in each seeding prompt
so agents can communicate directly without discovery. Names must be globally
unique (they become directories under s/). Note: duplicate session names
fail silently due to 9P client limitations.
Rendezvous is implicit. Every session has a prompt file at
s/{sid}/prompt. Writing to another session's prompt file always works:
if the session is running, the write appends to its FIFO and the agent sees
it on its next idle; if the session is idle, it sits in the prompt file until
the session resumes. The caller never needs to check peer state — always write
to prompt.
Completion signal: when a subagent finishes, it writes its result to
s/{parent-sid}/prompt. The parent receives it as a new turn, whether it is
currently idle or busy (in which case it queues). This is a direct async
callback — not a polled condition.
Example coordination prompt:
You are the test-writer subagent.
Roster:
myparent-impl — writing pkg/auth/middleware.go
myparent-test-writer (you) — writing pkg/auth/middleware_test.go
Shared task: beads issue #42 ("add auth middleware").
When impl's file exists, write tests and run them.
When done, write your result to the parent's prompt file.
Note: the child receives [parent_session_id=...] and [session_id=...]
headers automatically — it knows its own name and the parent's address
without the calling agent encoding them.
Parallel spawn
To spawn multiple subagents simultaneously, use a {parallel: [...]} stage.
Each entry is an independent subagent_spawn call with its own prompt and
-name. All agents start at the same time with the full roster. The tool
auto-injects [parent_session_id=...] and [session_id=...] into each
prompt, so the calling agent does not need to reference $OLLIE_SESSION_ID:
execute_code: steps=[{parallel: [
{tool: "subagent_spawn", args: ["-name", "myparent-impl", "-agent", "coding", "You are impl. Roster: myparent-impl (you) — write middleware, myparent-test-writer — write tests. Task: beads #42. Write pkg/auth/middleware.go. When done, notify test-writer by writing to s/myparent-test-writer/prompt, then write your result to the parent's prompt."]},
{tool: "subagent_spawn", args: ["-name", "myparent-test-writer", "-agent", "qa", "You are test-writer. Roster: myparent-impl — write middleware, myparent-test-writer (you) — write tests. Task: beads #42. Wait for notification from impl, then write and run tests. When done, write your result to the parent's prompt."]}
]}]