| name | subagents |
| description | Use when multiple independent subtasks can run in parallel, when a research or exploration task is large enough to keep separate rather than do inline (doing it inline fills the conversation with intermediate steps you'll carry through to the end), or when you need a specialized agent type (explore for deep search, shell for system commands). Any task with a clear deliverable and no dependency on the current thread is a good candidate to delegate. |
Subagent Dispatch Skill
Use call_subagent to delegate tasks to other agents, and wait_for_subagents to collect results from background runs.
When To Use
Delegate when at least one is true:
- The task is large enough to benefit from an isolated execution context
- Multiple independent tasks can run in parallel
- You need a specialized agent type (read-only explore, shell-heavy work)
Do not delegate when:
- The task is small and can be done directly
- The work requires constant access to the current conversation state
- Multiple sub-agents would write to the same file with no merge plan
- You cannot summarize the full context into a self-contained prompt
Depth limit: sub-agents cannot call call_subagent. Only the root agent may dispatch.
Tool: call_subagent
from sdk.tool import tool
result = tool.call("call_subagent", {
"agent_name": str,
"agent_id": str,
"prompt": str,
"model_id": str,
"background": bool,
})
agent_name
Maps to a .agent filename under agents/. Built-in types:
magic: general-purpose, full tool access (web, files, code). Use for complex multi-step tasks.
explore: read-only. Searches files, reads code, answers structural questions. Cannot modify anything.
shell: shell command specialist. Runs scripts, installs deps, performs system operations.
search: web research specialist. Searches the web and reads pages to gather external information. Cannot modify local files.
Other .agent files (e.g. data-analyst) can also be used by name.
agent_id
Human-readable session identity, e.g. market-research-phase1.
- Same
agent_id → resume the existing conversation (same chat history)
- Different
agent_id → fresh start with empty history
- Name by responsibility, not by sequence:
ppt-outline, shell-install-ffmpeg — not task1, worker-a
prompt
The sub-agent has no access to the parent's conversation history. The prompt must be fully self-contained. Include:
- The exact task
- Expected output format
- Relevant file paths or object identifiers
- Constraints (e.g. read-only, specific file to write)
- Success criteria
Bad:
Find out what competitors are doing and summarize.
Good:
Search the web for the top 3 competitors of [product category] that have launched or updated in the past 12 months.
For each, return: product name, target users, main differentiator, and source URL.
Focus on product launch articles, review sites, and tech media. Do not modify files.
background
False (default): run synchronously, block until the sub-agent finishes, return result immediately.
True: dispatch as a background task and return immediately. Must follow with wait_for_subagents to collect the result.
Use background=True for all parallel workloads. Sequential call_subagent(..., background=True) calls result in concurrent execution regardless of whether the model supports parallel tool calls.
Tool: wait_for_subagents
from sdk.tool import tool
result = tool.call("wait_for_subagents", {
"agent_ids": ["id-a", "id-b"],
"timeout": 30,
})
Awaits all listed agents together. result.content uses this format per agent:
[i/total] agent_type/session_id: status
Result:
```final output```
status values: done, error, interrupted, running, not_found, ambiguous
Result: appears only when status is done — contains the sub-agent's final output
- When status is
running (timed out), Result: is replaced by Last message: — this is the last assistant message the sub-agent produced before the timeout, useful for gauging progress
wait_for_subagents is idempotent — if status is still running, call it again or decide to stop waiting
result.data["results"]: structured list for programmatic access, fields: agent_id, agent_name, status, result, error, last_activity
Output Target
Decide where results go before dispatching. If the output target is missing from the prompt, the sub-agent will guess — and will usually create a file or object it shouldn't.
Three patterns:
Shared container (canvas, slides): pass the same container identifier (e.g. project path) to every sub-agent; tell each one which section it owns. Do not let sub-agents create or choose their own container.
Single file (report, document): assign the full file to one agent, or have parallel agents draft their sections independently then designate one merge agent to write the final file.
Independent outputs (one file per topic, one canvas per theme): each agent gets its own target; no coordination needed.
Never let multiple sub-agents write to the same file concurrently.
Reporting Results to the User
Sub-agents may include output file paths in their results. When reporting to the user, convert those paths to [@file_path:path] format — the frontend renders them as clickable links.
Example: Research report is ready: [@file_path:reports/market-research.md]
Sync Example
from sdk.tool import tool
result = tool.call("call_subagent", {
"agent_name": "explore",
"agent_id": "find-product-positioning-doc",
"prompt": """Find the single workspace document that is most useful for answering: "What is this project, who is it for, and what does it provide?"
Check workspace folders that are likely to contain project briefs, product analysis, requirements, launch materials, or internal planning before searching elsewhere.
Return:
1. the file path
2. a 3-5 bullet summary
3. one related file worth reading next
Do not modify files.""",
"background": False,
})
print(result.content)
Parallel Example
Dispatch first (sequential calls, concurrent execution):
from sdk.tool import tool
def dispatch(agent_id, prompt):
tool.call("call_subagent", {
"agent_name": "search",
"agent_id": agent_id,
"prompt": prompt,
"background": True,
})
dispatch("research-competitors", """Search the web for the top 3-5 competitors in this product space.
For each, return: product name, target users, main differentiator, and source URL.
Focus on product launches, review sites, and tech media from the past 12 months.""")
dispatch("research-market-signals", """Search the web for recent market signals in this product space.
Return:
1. notable user needs or pain points (with source URLs)
2. recurring themes across articles or community discussions
3. any emerging trends worth tracking""")
Then wait:
result = tool.call("wait_for_subagents", {
"agent_ids": ["research-competitors", "research-market-signals"],
"timeout": 60,
})
print(result.content)
Checklist
Before dispatching:
- Is delegation actually necessary?
- Does the prompt contain all required context (no reference to parent conversation)?
- Is
agent_id stable, human-readable, and unique to this task branch?
- Is the output target explicit and conflict-free?
- If
background=True, is there a matching wait_for_subagents?