Expand description
The graph control plane: submit and inspect graph documents, start graph runs, and project a graph run’s per-node progress.
§A graph run is an ordinary run with a richer log
This module adds no new durability story. A graph run’s log opens with
GraphRunStarted instead of RunStarted, and its nodes narrate the walk
with NodeEntered/NodeExited/BranchTaken/…, but every model call, tool
call, suspension, and completion inside it is recorded through the exact
same RunCtx machinery an agent run uses. So the
pure-read endpoints (GET /v1/runs/{id},
/replay, /events) and even
POST /v1/runs/{id}/resume work on a graph run with
their existing code: they fold or drive the log, and a graph run is just a
log. The one place resume needs help is re-driving: the log carries only the
graph’s hash, so resume looks the document back up here and drives it with
the engine rather than the built-in loop. See drive_resume.
§Strict at submit, honest at resolution
POST /v1/graphs validates a document all at once (collect-all,
node/edge-precise) and refuses the whole thing with 400 invalid_graph on
any error: the strict-at-submit posture a control document earns. Starting
a run then resolves what the document references against the server’s live
inventory, synchronously, before the run is spawned: every agent node’s
hash must be a registered agent (built through the same
AgentFactory an agent run uses), and every tool
node’s tool must be present in the server’s ToolRegistry. A missing
reference is a synchronous 404 naming the node, not a background failure,
so an operator learns at submit that a run cannot proceed rather than
watching it stall.
§Tool resolution: the existing registry, nothing new
A graph tool node resolves through the server’s ToolRegistry: the
SAME seam a client-driven tool step dispatches through. No new
tool-registration surface exists for graphs. salvor serve wires that
registry EMPTY, so on a stock server every tool node is a precise
unknown_tool refusal until a host registers the tool it names; a test (or
a future aarg serve) injects a registry holding its tools.
Functions§
- drive_
resume - Drives a parked or crashed GRAPH run further, for
crate::runs::resume’s graph branch. The resume handler has already read the log and classified the run, and hands a graph run’s input here UNCHECKED (see [refuse_nonconforming_approval] for why the check belongs on this side). This resolves the graph document (by the hash the log records) and its references, vets the input against the gate or tool suspension the run is parked at, then spawns the engine over it. Returns the same202 drivingbody the agent-run resume path returns. - fork
POST /v1/runs/{id}/fork: fork a graph run from a node boundary into a NEW run, refusing (or recording an acknowledgement for) the writes the re-walked segment would re-fire.- forks
GET /v1/runs/{id}/forks: the forks of a run, as a DERIVED index.- get
GET /v1/graphs/{hash}: the stored document, under its hash.404 unknown_graphwhen nothing is stored under the hash.- is_
graph_ run - Whether a log is a graph run: its first event is
GraphRunStarted. - list
GET /v1/graphs: one entry per stored graph, each with its hash and a shape summary (node/edge counts, entry and terminal node ids), following the enriched-runs precedent.- projection
GET /v1/runs/{id}/graph: the graph run’s per-node projection, for the canvas.404 unknown_runwhen the id has no history;409 not_a_graph_runwhen the run is an ordinary agent run (its log has noGraphRunStartedhead), mirroring the existing 409 error shape.- start_
run POST /v1/graph-runs: start a run of a stored graph, and return its id at once (the same fire-and-return shapePOST /v1/runsuses).- submit
POST /v1/graphs: submit (and strictly validate) a graph document.- validate_
only POST /v1/graphs/validate: validate a document without storing it.