ri-agent-graph
Graph-based agent orchestration for Rust — a LangGraph-inspired execution engine with 8 node types, parallel fan-out/fan-in, SQLite checkpointing, interrupt/resume, retry policies, event streaming, and HMAC-SHA256 cryptographic receipts.
If you're building AI agents, multi-step LLM workflows, or agent councils in Rust — this is the runtime. Define your workflow as a graph, execute it with deterministic state flowing through nodes, and get cryptographic receipts proving what happened.
What it gives you
- 8 node types —
llm,router,join,parallel,passthrough,state_transform,subgraph,human_approval— compose any agent topology - Parallel fan-out/fan-in with
JoinSet-backed real concurrency and 5 join modes:collect_array,merge_objects,first_non_null,all_success,quorum - SQLite checkpointing — atomic transactions, crash recovery, checkpoint mismatch detection, step-level state snapshots
- Interrupt/resume — pause at any node, inspect state, inject new input, resume from exact checkpoint
- HMAC-SHA256 receipts —
GraphExecutionReceiptV1with step-level digests, budget counters, and trace IDs - Event streaming —
StreamExtover node lifecycle, token output, and state snapshots - Retry policies — per-node configurable backoff, max retries, predicate filters
- stack-ids integration —
TraceCtx,AttemptId,TrialIdat every layer for distributed tracing
Prerequisites
- Rust 1.75+ (rustup.rs)
- SQLite —
rusqlitebundles SQLite via thebundledfeature; no system library required. Disable withdefault-features = false
Installation
Or in Cargo.toml:
[]
= "0.2"
Feature flags
| Flag | Default | Description |
|---|---|---|
checkpointing |
✅ on | SQLite persistence via rusqlite (bundled) |
# Without checkpointing
= { = "0.2", = false }
Quick start
use *;
async
Core concepts
Graph & state model
| Type | Role |
|---|---|
AgentGraph<S> |
Immutable graph: nodes + edges + reducers. Built via builder, validated at .build() |
AgentState |
Thread-safe key-value state (serde_json::Value) flowing through execution |
GraphExecutor<S> |
Runtime engine. Wraps a graph and optional checkpoint store. Drives the superstep loop |
Superstep execution loop
Dispatch → Execute → Checkpoint → Advance → Repeat
│ │ │ │
│ JoinSet for SQLite END sentinel
│ fan-out nodes atomic tx or max_iterations
│
Router resolves edges
to target frontier
Node types
| Node | Purpose | Example |
|---|---|---|
llm |
Invoke an LLM via Payload trait. Response merged by reducer. |
Text generation, classification |
router |
Conditional branching. Evaluates predicate → selects next edges. | Route based on LLM output |
parallel |
Fan-out dispatch. Concurrent branches via JoinSet. |
Multi-agent brainstorming |
join |
Fan-in sync. Waits for all branches, merges with join mode. | Collect parallel results |
passthrough |
No-op pass. Fan-out distribution point. | Bridge coordinator → workers |
state_transform |
10 ops: set, copy, delete, increment, append, merge, merge_object, select, compare, format |
Format state between nodes |
subgraph |
Compose another graph as a node. | Reusable multi-step workflows |
human_approval |
HITL gate. Emits InterruptError, resumes via checkpoint. |
Pause for operator review |
Router example
let graph = builder
.add_node
.add_node
.add_node
.add_edge
.add_router
.add_edge
.add_edge
.build?;
Parallel fan-out with join
let graph = builder
.add_node
.add_node
.add_node
.add_node
.add_node
.add_edge
.add_edge
.add_edge
.add_edge
.add_edge
.add_edge
.build?;
State management
state.set.await?;
state.set.await?;
let name: String = state.get.await?;
let maybe: = state.get_opt.await?;
let keys: = state.keys.await;
state.remove.await?;
// Snapshot & restore
let snap = state.snapshot.await;
state.restore.await?;
// State limits
let graph = builder
.with_state_limits
.build?;
Reducers
When parallel branches write the same key, reducers resolve conflicts:
new
.append_to // Concatenate arrays
.merge_into // Deep-merge objects
.with // Numeric addition
.with
.with_fn;
Checkpointing & interrupt/resume
use SqliteCheckpointStore;
let store = open.await?;
let executor = new.with_checkpoint_store;
match executor.execute_with_interrupt.await
Retry policies
use RetryPolicy;
let graph = builder
.add_node
.with_retry_policy
.build?;
Event streaming
use StreamExt;
let mut stream = executor.execute_stream.await?;
while let Some = stream.next.await
Execution receipts
Every run produces a GraphExecutionReceiptV1:
Error handling
Ecosystem
| Crate | Description | Version |
|---|---|---|
| ri-agent-graph | Core engine (this crate) | v0.2.2 |
| agent-graph-mcp | MCP server — 25 typed tools | v0.2.4 |
| stack-ids | Trace/identity primitives | v0.1.3 |
| llm-pipeline | Reusable LLM node payloads | v0.2.0 |
Comparison
| Feature | ri-agent-graph | LangGraph (Python) |
|---|---|---|
| Language | Rust | Python |
| Type safety | ✅ Compile-time | ❌ Runtime |
| Parallel fan-out | ✅ JoinSet native |
✅ asyncio |
| Checkpointing | ✅ SQLite bundled | ✅ Postgres/SQLite |
| Cryptographic receipts | ✅ HMAC-SHA256 | ❌ |
| Retry policies | ✅ Per-node, predicate | ✅ Per-node |
| Event streaming | ✅ StreamExt |
✅ |
| MCP protocol server | ✅ Built-in | ❌ |
| Zero-copy state | ✅ serde_json::Value |
❌ Python dict |
Claim boundaries
- Graph execution semantics only — this crate does not include LLM provider clients, prompt templating, or response parsing. Those belong in
llm-pipelineor your application. - Receipts prove structural execution — they carry digests of the local execution trace. They do not prove an external model call occurred.
- Interrupt/resume is deterministic local — supports linear
passthrough/state_transformchains. Does not resume across LLM calls or network I/O. - Parallelism is best-effort — unordered parallel writes to the same key are rejected without an explicit
Reducer.
Verification
Roadmap
- Typed state extractors (derive macro for
StateExtract) - Graph visualization (Mermaid/DOT export)
- Streaming LLM token passthrough
- Distributed checkpoint backends (PostgreSQL, S3)
- Subgraph composition with state isolation
- WebAssembly target
Contributing
PRs welcome. See the ri-agent-graph repo for source and issues.
License
MIT — see LICENSE-MIT.
Built by RecursiveIntell — an applied R&D studio building local-first AI infrastructure.