ollie/prompts/tools-subagent.md

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."]}
]}]