rpi-agent
The provider-agnostic agent runtime: the agent loop, the AgentTool trait,
events, hooks, queues and cancellation. This is the layer you embed when you
want to build your own agent rather than use the rpi CLI.
Install
[]
= "0.3"
= "0.3"
= { = "1", = ["rt-multi-thread", "macros"] }
For built-in file and shell tools, add
rpi-tools. For durable sessions and
compaction, add rpi-harness.
Design
The only LLM boundary is StreamFn, which returns an
AssistantMessageEventStream synchronously. Everything else in the loop speaks
AgentMessage and never touches a provider wire format, so a provider, a test
double and a recorded transcript are interchangeable.
The invariants that the loop guarantees:
- Tools may finish in any order, but tool results are emitted in the order the calls appeared, so the transcript stays valid for the next request.
- A
MessageEndis emitted exactly once per assistant message, including when a late streaming update arrives after the run already settled. - Truncated or failed tool calls never leave a dangling call without a result.
Quick start
Deterministic, offline, no API key — the faux provider scripts one text reply:
use Arc;
use AgentBuilder;
use ;
use Provider;
async
A runnable version of this lives in
examples/minimal
(cargo run -p minimal), and a version that drives the real filesystem through
the built-in tools lives in
examples/tools.
Defining a tool
Tools implement AgentTool. A tool owns the provider-facing schema, a display
label, and the execution function; parameters are validated against that schema
before execute is called:
use Arc;
use async_trait;
use ;
use Tool;
use CancellationToken;
execute receives a CancellationToken for cancellation and an on_update
callback for partial results. Calls to on_update after the run has settled are
dropped by the loop, so a tool never has to track settlement itself. Returning
Err(AgentError) turns into an error tool result, not a failed run.
For real implementations, wrap the JSON Schema derivation with schemars and
start from rpi-tools, which contains
complete examples of a filesystem tool and a streaming shell tool.
Observing a run
agent.subscribe() returns a broadcast receiver of AgentEvent covering the
run (AgentStart/AgentEnd), each assistant message
(MessageStart/MessageUpdate/MessageEnd), and each tool
(ToolStart/ToolUpdate/ToolEnd). Cancellation goes through AbortHandle.
Related crates
| Crate | Role |
|---|---|
rpi-ai |
Provider-agnostic message and streaming types |
rpi-tools |
read/write/edit/bash and friends |
rpi-harness |
Sessions, JSONL persistence, compaction |
rpi-cli |
The rpi terminal agent built on all of the above |
Documentation
- Crate docs: https://docs.rs/rpi-agent
- Architecture: docs/architecture.md
- Project structure guide: docs/agent-project.md