Expand description
The agentd 2.0 runtime (RFC 0026): the supervisor’s event loop over durable state, the turn workers it spawns, and the lifecycle policy. Built beside the 1.x mode drivers and selected by a v2 configuration document; the 1.x drivers are removed at the P5 cut-over.
Startup (RFC 0026 §8): parse+validate config → connect MCP servers
(contained failures) → connect the store or refuse → restore → build the
registry (validate overrides) → discover skills → resolve the instruction
→ load workflows → arm start nodes (once fires unless a live run was
restored) → re-spawn pending subagents → proc.ready → the loop.
Re-exports§
pub use reactor::Runtime;
Modules§
- activity
- Live activity (RFC 0032 §17): what each working unit is doing right now, for the display clients’ working row.
- artifacts
- Artifacts (RFC 0028 §3
artifact.*, RFC 0025 §3.3artifact): named pieces of content produced by turns and steps, store-backed, delivered on A2A tasks (P5) and referenced by large step outputs ({"$artifact": id}, P4). Content is stored inline (JSON or text) up to a cap; the record carries{name, mime, size, sha256, content, created_by, sensitive}. - audit
- The audit stream (plan §3.11, RFC 0025 §3.3
audit): an append-only record of who did what — every A2A call, every principal-driven tool/command, config reloads, restores, store conflicts, and kills. Each event is{ts, principal, role, action, target, outcome, request_id, trace, instance}, emitted to the configured sinks:log(a closed-vocabularyauditlog line) and/orstore(a durable, append-onlyKind::Auditrecord, ULID-keyed — never CAS’d, never listed, so it cannot be rewritten). Audit is security telemetry: it answers “why did the agent do that, and on whose authority?”. - children
- The runtime’s flat child tree (RFC 0026 §2, D3): every turn worker and
subagent is a direct child of the supervisor, spawned through the 1.x
machinery (
supervisor::spawn+ the reaper + PDEATHSIG + process groups), tracked here with its purpose, liveness and cancellation, and torn down by the kill ladder on drain. - events
- The runtime’s event vocabulary (RFC 0026 §3): everything the loop reacts to arrives here — child frames, reaped children, executor results, timers, signals, and the durable inbox events (A2A messages, start-node firings, signals) that are written ahead before being acted on.
- goal
- The self-correcting goal watchdog (RFC 0026). A supervisor-level periodic
check — it never blocks the agent loop — of whether the configured
goalis achieved, or the agent is stuck (no progress acrossstuck_afterchecks): - http_
node - The
httpworkflow node (RFC 0027): make an outbound REST call from a workflow —GET/POST/PUT/PATCH/DELETEwithheaders,query, and ajson/bodypayload — and observe{status, ok, headers, body, json}. This is also how a workflow emits a webhook (aPOSTto a URL). It runs on an executor thread over the one SSRF-guarded HTTP client (RFC 0012); the URL and body are already template-rendered (render_spec) against the run’s data. - human
- Human-in-the-loop (RFC 0032 §16): the
ask_humaninternal tool and the workflowhumannode, wired to the interface. - nested
- Nested bodies (RFC 0027 §5–§7):
foreach/batch(dynamic fan-out over an array, batches with bounded parallelism and rate pacing, per-batch durable progress, positional collection,on_error: continueslots),iterate(a bounded structured loop withwhile/until/max_iterations),parallel(static branches, fan-in object),race(first branch to finish wins, the rest are cancelled) andsubgraph(an inline sub-DAG). Body steps are ordinary steps executed under a scope: their run-record ids are<parent>[<index>].<step>(elements / iterations),<parent>{<branch>}.<step>(branches) or<parent>.<step>(subgraph); templates inside a body seeitem,index,batch,iteration,branchandsteps.<sibling>resolved within the scope. The parent step’swaitrecord carries the durable progress. - reactor
- The runtime state + event loop (RFC 0026 §3, §8): one single-threaded
reactor over child frames, reaped children, executor results, timers, the
durable inbox and signals; state mutation happens only here (single
writer); every mutation is followed by a checkpoint decision (RFC 0025 §5).
The other
runtime::*modules addimpl Runtimeblocks for turns, tools, steps and subagents; this file owns construction, the loop, lifecycle and the status view. - reload
- Hot reload of the v2 configuration (RFC 0030 §6, RFC 0017 semantics):
SIGHUP or
lifecycle.watch_configre-merges the files and re-validates; the restart-only paths must be unchanged (elserestart_required, the running configuration stays); the reloadable partition applies at the loop’s quiesce boundary — the flat tree makes most of it trivial: every turn worker is spawned fresh from the live settings, so a new intelligence endpoint, model, instruction, budget, tool override or workflow definition takes effect for the next unit of work. Live runs keep the definition they started with (pinned by hash). - starts
- Start nodes as the triggers (RFC 0027 §4, plan §3.6.6): beyond
onceandmanual, the long-lived start kinds fire runs while the instance lives —loop(re-run on completion,interval/until/max_iterations/backoff),schedule(cron /every,catch_up),subscribe(an MCP resource update, notify-then-read,debounce/coalesce/filter,claim/shardfor exactly-one-owner in a cluster),signal(a named signal),event(an internal lifecycle event), anda2a(a principal’s message routed here — P5). Start-node state (last fired, iteration, missed, next deadline, debounce) is durable in the manifest. - steps
- Runs and steps (RFC 0027 §6–§7, RFC 0026 §3): arming start nodes,
turning start events into durable runs, scheduling ready steps every tick,
executing the P3 step kinds (data steps in-loop, MCP calls on executor
threads,
agent/thinkin turn workers,sleepon durable timers,finishclosing the run), retries +on_errorrouting, and theworkflow.*tools. - subagents
- The subagent registry (RFC 0026 §6, RFC 0028 §3
subagent.*): flat children spawned from the one chokepoint (caps: depth/breadth/total/rate), recorded durably assubagent/<handle>(payload, mode, status, result), withsync(the caller waits),async(a handle;subagent.await),detached(fire and forget) andwarm(stays alive;subagent.send). - timers
- The durable timer wheel (RFC 0025 §3.3
timer, RFC 0026 §3): absolute deadlines owned by a step, a tool request, a start node or the lifecycle; armed through the store, fired by the loop’s tick (fire), re-armed from the restored records at startup (past deadlines fire immediately). - tools
- Internal tool execution (RFC 0028 §3): the runtime is the single place
internal tools run — for a turn worker’s
ToolRequest(answered withToolResult), for a workflow step (tool/memory.*/ … kinds) and for A2A commands (P5). Arguments are validated against the contract’s input schema before dispatch and results against the output schema after (schema failure ⇒ a tool error, never a panic). Some tools are deferred (sleep,subagent.run sync,subagent.await,await,think,context.compact,workflow.run wait,workflow.wait): the request is parked inpendingand answered when its wait resolves. Mapped tools (overrides) run on an executor thread against the runtime’s own MCP connection. - turns
- Turn dispatch (RFC 0026 §3.2): building a turn worker’s input (system
prompt, context slice, tool definitions by grant, skills, memory hints),
budget admission at dispatch, spawning the worker, and folding
TurnDoneback into the durable state (context delta, replies,finish, compaction). - waits
- Orchestration steps (RFC 0027 §5 integration / intelligence / control):
wait(on a resource update, a CEL condition, a signal, a run, a subagent, a conversation message, or a deadline),join(fan-in of runs/subagents),workflow(a child run:sync | async | detached,cascade),workflow.signal/workflow.wait/workflow.cancel,subagent,human(through theask_humancontract),mcp.resource(read | list | prompt | complete),a2a.delegate(the 1.x A2A client), thethinkpresets (classify | extract | summarize | judge | route), and stepcache(memoized outputs by input hash). Waits suspend the step durably (StepState.wait) and are resolved by the loop’s tick. - worker
- The turn worker (RFC 0026 §2, §3.2): a child process (
Role::Turn) that runs ONE turn over the context slice the supervisor handed it — a root / conversation turn, a boundedagentstep, or a structuredthink— and reports the transcript delta, the usage and the outcome (TurnDone).
Functions§
- capabilities
- A static capability document for
--capabilities(RFC 0015 §5.2): describes the configured 2.0 surface with no side effects — it does not connect to MCP servers, read secrets, or start the loop. It reflects the configuration (what the agent is set up to do), not live state. - run
- Run the 2.0 runtime for a loaded v2 configuration. Returns the exit code.