Sub-agents
A lead agent can hand work to other agents in two ways. By the end of this page you will have run both, found every child’s trace from the lead’s, and put a person in front of a delegation.Every output on this page is what the code printed when it was run with
gpt-5.4-mini. The model’s wording, the tasks it writes for its children, and
whether it calls them one after the other or together, will differ on your run.A fixed team
Each agent insub_agents becomes a delegate_<name> tool on the lead. The
lead’s model decides when to call it and what to ask.
- The lead’s model called
delegate_researcher, then passed what it learned todelegate_coder. Adelegate_<name>tool takes the parameters of the child’srun():query(the task, required), and optionaltagsandprovenance, which are recorded on the child’s trace. - Each child ran as a whole agent run of its own — its own tools, its own
trace — with the lead’s
session_idand a newrun_id. get_trace_familyreturned the lead’s trace and both children’s, each child naming its parent inparent_trace_id. The lead’s trajectory also nests each child’s trajectory under the call that started it (call["subagent"]["child_trajectory"]).
Workers spawned on demand
Withenable_subagents, the lead gets a spawn_subagents tool and writes the
workers itself:
spawn_subagents call, each wrote its
file (workspace/files/kyoto_tips.txt and lisbon_tips.txt), and the lead
read them before answering. The model sends the tool a subagents list — one
item for one worker, up to 15 for parallel work:
/workspace/ in output_path means
the agent’s workspace files folder.
Worker profiles: the right model for each worker
A worker that only searches does not need your strongest model, and one that only reviews should not write. List the kinds of worker the lead may start inworker_profiles, and the lead picks one for each worker, by its description:
spawn_subagents takes a
profile for each worker, and its description lists each profile with its
model, effort, steps and tools. A worker with no profile, or one not listed,
starts nothing, and the lead is told the names. Without profiles, workers are
as described below.
A profile only narrows: a tool or MCP server the lead does not have is refused
when the lead initializes, and a worker never gets an allow rule its lead does
not have. Every worker spends the lead’s budgets,
whatever its model. Each spawn records the profile, model and effort the
worker ran with, and the
subagent.spawn request names the profile, so a
policy can, for example, ask before any builder starts. A runnable example
is cookbook/getting_started/agent_with_worker_profiles.py.
How it works
What a spawned worker gets. A worker, namedsubagent_<name>, inherits
(unless its profile says otherwise) the lead’s model, MCP servers, your local tools, and its whole agent_config
— workspace files, skills, the sandbox, context management and tool offloading
— with these changes: at most 50 steps, no spawn_subagents of its own,
and workspace files, context management and offloading always on. Its system
instruction is its role, its task, and the file to write. Output goes to files,
not the lead’s context, so it survives the lead’s context being trimmed.
What enable_subagents changes on the lead. It turns workspace files,
context management and tool offloading
on — keeping any budget, threshold and strategy you set — because the lead
reads its workers’ files and must not run out of context doing it.
Time. A delegate_<name> call is a tool call: it is bounded by
tool_call_timeout (180 seconds by default). spawn_subagents is not: a
worker is bounded by its own step cap and the run’s deadline, and by
subagent_timeout if you set it.
Evidence. Every child’s trace is linked to the lead’s: find them with
get_trace_family(trace_id=...) or get_trace_family(run_id=...), or read
them nested in the lead’s trajectory. The lead’s trace records
subagent_spawn, subagent_result and subagent_error events.
Governance
When the lead has governance on, every delegation is asubagent.spawn
request, decided by the lead’s policy. The development profiles
(interactive-dev) ask for it, so the run pauses before any child starts:
- A governed agent only delegates to governed children. A child with no
governance_configis governed by default (permissive-dev); a child that turns governance off ({"enabled": False}) is refused — its tools would run under no policy. The child is governed by its own policy, so configure it for the child’s tools. - Spawned workers run under the lead’s policy plus one rule: they cannot spawn workers of their own; a worker’s profile may add deny and ask rules. What they spend counts against the lead’s budgets: one ledger for the lead and all its workers.
- A child’s ask pauses the lead. The child’s pending approvals appear on
the lead’s run — each naming the child’s call, its arguments, and the
child’s run (
delegated_run_id) — and the lead’s run goes toawaiting_approval. A decision on the lead’s approval (resolve_approval, orPOST /runs/{run_id}/approvals/{approval_id}) is forwarded to the child’s, and when the lead resumes, the child’s run resumes where it stopped rather than starting over. - An ask on the delegation itself, as above, pauses the lead the same way, before any child runs.
subagent.spawn.
Options
Everything else is in the agent settings and
OmniCoreAgent references.
When things go wrong
Delegation refused: agent 'translator' is not governed. A governed agent can only delegate to agents with governance enabled.
Delegation refused: agent 'translator' is not governed. A governed agent can only delegate to agents with governance enabled.
The lead has governance on and the child turned it off
(
"governance_config": {"enabled": False}). The call fails with this as
its error, and the run carries on — in our run the model simply
translated the sentence itself. Leave the child’s governance on: drop
{"enabled": False}, or give it a profile or policy of its own.ValueError: sub_agents must be a list of agents, e.g. sub_agents=[researcher]
ValueError: sub_agents must be a list of agents, e.g. sub_agents=[researcher]
sub_agents takes a list, even for one child: sub_agents=[researcher].ValueError: subagent_timeout must be between 2 and 86400, got 1
ValueError: subagent_timeout must be between 2 and 86400, got 1
subagent_timeout is in seconds, from 2 to 86,400 — or None for no limit
beyond the workers’ own.The lead's run is awaiting_approval and no tool of yours was called
The lead's run is awaiting_approval and no tool of yours was called
The profile asks before
subagent.spawn (both delegate_<name> and
spawn_subagents), or a child hit an ask. Approve as above, or allow the
capability in your policy; permissive-dev allows it outright.A worker's output is missing
A worker's output is missing
A worker must write its
output_path. When it did not, the lead is told
Subagent '<name>' did not create the requested output: <path>. Give the
worker a task it can finish within 50 steps, with the tools it inherits.Next
Context engineering
What keeps the lead and its workers inside their context.
Durable runs
Approvals, pauses and resumes — for delegated runs too.
Observability
Trajectories with every child run nested in.
Security model
What a policy decides, for sub-agents and everything else.