Skip to main content

tinyagents/
lib.rs

1//! # TinyAgents — a recursive language-model (RLM) harness for Rust
2//!
3//! TinyAgents is a typed, durable runtime where **language models call models,
4//! agents call agents, and graphs run graphs** — and where a model can author,
5//! compile, and run the very workflow it is standing inside, all as inspectable,
6//! checkpointed, policy-checked Rust.
7//!
8//! The "recursive" framing is the through-line of the whole crate, not a
9//! footnote. It is architected around the execution model described in
10//! "Recursive Language Models" (Alex L. Zhang, Tim Kraska, Omar Khattab, MIT
11//! CSAIL, 2025; <https://arxiv.org/abs/2512.24601>): rather than stuffing
12//! everything into one context window, a model treats long context as an
13//! external *environment* it interacts with through a REPL — examining,
14//! decomposing, and recursively calling sub-models over snippets. TinyAgents
15//! brings that idea to Rust as a production-shaped harness (sub-model /
16//! sub-agent / sub-graph calls as functions, persistent session values, depth
17//! tracking, and trajectory/event logging). It is *inspired by and architected
18//! around* the RLM execution model, not a reimplementation of the paper's
19//! benchmarks.
20//!
21//! ## The five surfaces
22//!
23//! 1. **Harness** ([`harness`]) — provider-neutral model calls, typed tools,
24//!    middleware, structured output, streaming, usage/cost, retry/limits, cache,
25//!    memory/embeddings, sub-agents, steering, and a testkit.
26//! 2. **Graph runtime** ([`graph`]) — LangGraph-style durable typed state
27//!    graphs: [`START`]/[`END`], nodes, conditional routing, [`Command`]s,
28//!    fan-out, reducers/channels, [`Checkpoint`]s, [`Interrupt`]s, subgraphs,
29//!    streaming, and topology export.
30//! 3. **Registry** ([`registry`]) — a named capability catalog (models, tools,
31//!    agents, graphs, stores, middleware, policy) that `.rag`/`.ragsh` bind by
32//!    name.
33//! 4. **Expressive language `.rag`** ([`language`]) — a declarative,
34//!    side-effect-free blueprint format that compiles (lexer → parser →
35//!    compiler) into the same graph/harness runtime; the safe boundary for
36//!    agent-authored plans.
37//! 5. **REPL language `.ragsh`** ([`repl`]) — imperative, capability-bound
38//!    interactive orchestration; the RLM/CodeAct loop surface.
39//!
40//! ## The recursion story
41//!
42//! Both `.rag` and `.ragsh` lower into the *same* [`graph`] + [`harness`] types
43//! as hand-written Rust — a language whose programs are the runtime that
44//! interprets them. A harness agent can be exposed *as a tool* to another agent
45//! ([`SubAgent`], [`SubAgentTool`], [`SubAgentSession`]), so orchestration is
46//! just a model calling a model; the runtime tracks parent/child run lineage and
47//! enforces a recursion cap ([`TinyAgentsError::SubAgentDepth`]). At the deepest
48//! level a model can emit a `.rag` blueprint that compiles through the same
49//! registry-bound path as a human-authored file and runs on the same runtime the
50//! model is already executing in (see `examples/openai_self_blueprint.rs`).
51//!
52//! ## Provider features
53//!
54//! The default build is offline and deterministic ([`harness::providers::MockModel`]).
55//! Hosted and local providers (OpenAI plus the OpenAI-compatible endpoints for
56//! Anthropic, Ollama, DeepSeek, Groq, xAI, OpenRouter, Together, and Mistral)
57//! live behind the `openai` Cargo feature.
58//!
59//! ## Crate-root re-exports
60//!
61//! For discoverability the most-used types from each surface are re-exported at
62//! the crate root, grouped below by surface ([`error`], [`registry`],
63//! [`language`], [`harness`], and [`graph`]).
64
65pub mod error;
66pub mod graph;
67pub mod harness;
68pub mod language;
69pub mod registry;
70pub mod repl;
71
72// --- Error: the crate-wide error type and `Result` alias ---
73pub use error::{Result, TinyAgentsError};
74
75// --- Registry: named capability catalog (.rag/.ragsh binding by name) ---
76pub use registry::{CapabilityRegistry, ComponentId, ComponentKind, ComponentMetadata};
77
78// --- Language: registry → blueprint binding façade ---
79// The strict, registry-backed entry points the REPL and orchestrators use to
80// turn `.rag`/`.ragsh` source into validated blueprints. `compile_source` runs
81// parse -> compile -> registry-bind in one call.
82pub use language::compiler::{
83    CapabilityResolver, bind_capabilities, bind_capabilities_with_registry, compile, compile_source,
84};
85pub use language::types::Blueprint;
86
87// --- Harness: embeddings + retrieval ---
88pub use harness::embeddings::{
89    EmbeddingModel, InMemoryVectorStore, MockEmbeddingModel, Retriever, ScoredDoc, VectorStore,
90    cosine_similarity,
91};
92
93// --- Harness: first-class sub-agents (agent-calling-agent composition) ---
94pub use harness::subagent::{SubAgent, SubAgentSession, SubAgentTool};
95
96// --- Harness: orchestrator → sub-agent steering ---
97pub use harness::steering::{
98    SteeringCommand, SteeringCommandKind, SteeringHandle, SteeringOutcome, SteeringPolicy,
99};
100
101// --- Cooperative run cancellation ---
102pub use harness::cancel::CancellationToken;
103
104// --- Harness: durable observability (journals, status stores, sinks) ---
105pub use harness::observability::{
106    AgentObservation, FanOutSink, HarnessEventJournal, HarnessStatusStore, InMemoryEventJournal,
107    InMemoryStatusStore, JournalSink, JsonlSink, RedactingSink, StoreEventJournal,
108};
109
110// --- Graph: durable execution model (LangGraph-style) ---
111// Re-exported with explicit names so the durable API is discoverable at the
112// crate root. The `harness::stream::StreamMode` and `graph::stream::StreamMode`
113// types intentionally stay behind their module paths to avoid a name clash.
114#[cfg(feature = "sqlite")]
115pub use graph::SqliteCheckpointer;
116pub use graph::{
117    Checkpoint, CheckpointConfig, CheckpointMetadata, CheckpointSource, CheckpointTuple,
118    Checkpointer, ChildRun, ChildRunSink, ClosureReducer, ClosureStateReducer, Command,
119    CompiledGraph, DurabilityMode, END, FileCheckpointer, ForkId, GraphBuilder, GraphDefaults,
120    GraphEvent, GraphExecution, GraphRunStatus, InMemoryCheckpointer, Interrupt, NodeContext,
121    NodeResult, RecursionFrame, RecursionPolicy, RecursionStack, Reducer, ResumeTarget, Route,
122    RouteTarget, RunTree, START, StateReducer, StateSnapshot,
123};
124
125// --- Graph: sub-agent nodes (delegate a graph step to a registered agent) ---
126pub use graph::{
127    HarnessAgent, HarnessSubAgent, SubAgentBudget, SubAgentInput, SubAgentNode, SubAgentOutput,
128    SubAgentPolicy, subagent_node,
129};
130
131// --- Graph: channel-per-field state model (additive; see state-channels.md) ---
132// An opt-in alternative to the monolithic State + StateReducer path: state is
133// split into independently-merged named channels.
134pub use graph::{
135    Barrier, BinaryAggregate, Channel, ChannelSet, ChannelState, ChannelUpdate, Delta, Ephemeral,
136    LastValue, Messages, NamedBarrier, Topic, Untracked,
137};
138
139// --- Graph: durable observability (journals, status stores, journaling sink) ---
140// Names are graph-prefixed so they never collide with the harness observability
141// re-exports above.
142pub use graph::{
143    GraphEventJournal, GraphObservation, GraphStatusStore, InMemoryGraphEventJournal,
144    InMemoryGraphStatusStore, JournalGraphSink, StoreGraphEventJournal,
145};
146
147// --- Graph: export / visualization ---
148// Topology types are surfaced at the crate root; the `to_json`/`to_mermaid`
149// free functions stay behind `graph::export::` to avoid generic-name clashes.
150pub use graph::{
151    ChannelInfo, ConditionalEdgeInfo, EdgeInfo, GraphPolicySummary, GraphTopology, NodeInfo,
152    NodePolicySummary, RouteInfo, ValidationReport, WaitingEdgeInfo,
153};