-
Notifications
You must be signed in to change notification settings - Fork 5
EN Course 10 Sub Agent Runtime
SubAgent is not just another output-producing tool. It starts a restricted child agent runtime that reuses the same major layers as the parent:
child session
-> agent loop
-> prompt builder
-> transport
-> tools
-> store/events/stats
The restriction is intentional: nested delegation is limited so a child runtime does not recursively fan out without control.
The tool starts a child agent session:
tool_sub_agent() {
local prompt="$1" description="$2" fork="${3:-false}" sub_session_id child_dir parent_dir
sub_session_id="sub_$(util_new_session_id)"
parent_dir="$(dirname "$CONV_FILE")"
child_dir="$(dirname "$parent_dir")/$sub_session_id"
# child loop runs in the background and reports result back through the input FIFO
}There are two modes:
- default: a fresh child session with its own conversation
- fork: copy selected parent context into the child session before running
Fork mode is useful when the child needs the parent’s working context. Default mode is better for independent investigation.
The child does not return as a normal synchronous tool result. It sends a structured result back to the parent input queue:
AGENT_RESULT <session_id> <status> <text> <in> <out> <cache_read> <cache_creation> <requests>
The parent records a sub_agent_result event and starts another model turn so the assistant can interpret the child result.
This is why SubAgent sits late in the course: it combines session store, prompt construction, transport, tools, display events, and stats into a second runtime instance.
parent tool call
-> child launched (background)
-> parent continues
-> child finishes and emits AGENT_RESULT
-> parent appends sub_agent_result event
-> parent triggers next model turn
This separation explains why results arrive later and why the model must match messages by session_id.
Typical statuses include success and failed. On failure:
- result text can be partial or empty
- token counters may still be present
- parent should not assume retries happened
Handling rule: treat child output as an external async signal, then decide whether to continue, retry, or decompose the task differently.
Runtime Parity closes the course by showing how the same boundaries are kept across Bash, C, Go, and Rust.