Skip to main content

Module protocol

Module protocol 

Source
Expand description

The supervisor↔subagent control protocol.

A minimal JSON-RPC sibling — not literal MCP (no initialize handshake) — carried length-framed (4-byte prefix, crate::json::frame) over the child’s stdio pipes, so payloads that contain newlines (instructions, context seeds, distilled results) survive. Two directions: ControlMsg flows down (supervisor→child), AgentMsg flows up.

The control reader inside the child runs on a thread separate from the agentic loop, so Ping/Pong liveness survives a long in-flight tool or model call: if the reader shared the loop’s thread, a slow model call would read as a hung child and the supervisor would reap a healthy process. This module is just the wire types; the spawn mechanics are supervisor/spawn.rs, the child side subagent/control.rs.

Structs§

IntelActive
Which endpoint is serving the child’s intelligence, for AgentMsg::IntelHealth. The bounded structural identity ONLY — the list index and the transport scheme (unix/vsock/https) — never the URL, cid, host, or any credential, matching what the agentd://intelligence resource redacts. An index plus a scheme is enough to tell operators which configured endpoint is live without putting an address into logs or events.
IntelConfig
Limits
SeedMessage
A single seed message — a minimal {role, content} pair. Roles mirror the loop’s: system | user | assistant | tool.
SpawnPayload
Everything a subagent needs to run, minted by the supervisor. The child takes none of these fields from its own request — depth in particular is derived by the supervisor from the caller’s handle, so a child cannot claim a shallower depth to buy itself more levels of delegation.
SwapIntel
The intelligence config the child rebuilds its client from on a hot-swap: the endpoint-list URI, the default endpoint-1 credential, the model, and the swap policy — exactly the parts IntelConfig carries plus the policy. Boxed in ControlMsg to keep the enum small, as SpawnPayload is.
Telemetry
The correlation block stamped into the child’s logs, so every line a subtree emits can be joined back to the run and to its position in the tree.
TurnResult
A finished turn. messages is the transcript DELTA — only the assistant and tool messages appended during this turn, in order — which the supervisor concatenates onto the context it already holds. Sending a delta rather than the whole transcript keeps the frame bounded as a conversation grows.
TurnSpec
The turn worker’s input: everything the child needs to run exactly one turn — the system prompt, the context slice, the tool definitions and which of them round-trip to the supervisor, the output schema, and the knobs. The worker holds no state of its own between turns; whatever it needs is here.

Enums§

AgentMsg
ControlMsg
Role
The child’s role: which driver the child process runs after spawn.
TurnKind
What kind of turn a Role::Turn worker runs.

Constants§

ALLOWED_TOOLS_ROLE
The reserved SeedMessage::role that carries a child’s tool allow-listsubagent.run’s tools: narrowing, which is how scope narrows monotonically down the tree. Minted by the supervisor with SpawnPayload::narrow_tools, enforced by the child in crate::agentloop::runner::Session::prepare, which filters its assembled catalogue AND its dispatch against it.
SUBAGENT_ENV
The environment variable the supervisor sets on the child so its main takes the subagent path instead of re-parsing CLI config.

Functions§

parse_allowed_tools
Parse an allow-list marker’s body (a JSON array of registry patterns: *, an exact name, prefix*). An unreadable body narrows to NOTHING rather than to everything — a grant that cannot be read is not a grant (fail closed).