agent-base
A lightweight Agent Runtime Kernel for building AI agents in Rust.
agent-base provides the minimal orchestration layer needed to build custom AI agents — LLM integration, tool dispatch, multi-turn conversation, approval flows, event streaming, and error recovery — all with zero business assumptions.
Installation
[]
= "0.2.1"
Design Principles
- Clear semantics —
RunOutcomeexplicitly distinguishesCompletedfromFailed; events capture the process, the return value captures the final result. - Simple state model — Runtime memory is the source of truth for live sessions;
SessionStoreis an optional persistence adapter. - Conservative by default — On tool failure, the runtime stops by default (
StopOnError) rather than guessing how to recover. - Strategy injection — All variable behaviors are injected via traits (
ToolErrorRecovery,ToolPolicy,ApprovalHandler,Middleware), not hardcoded.
Features
- LLM Abstraction —
LlmClienttrait with built-in OpenAI and Anthropic implementations;StreamClienttrait for provider-decoupled streaming - LLM Retry — Configurable retry with exponential backoff via
RetryConfig - Tool System —
Tooltrait +ToolRegistryfor registration and dispatch; configurabletool_timeout - Approval Flow —
ApprovalHandlertrait withAllowOnce/AllowAlways/Denydecisions + cancellation support - Error Recovery —
ToolErrorRecoverytrait; defaults toStopOnError, opt-inRetryOnError+ custom retry prompts - Event Streaming — Structured
RuntimeEventstream with configurableEventBuscapacity - Multi-turn Sessions —
AgentSessionmanages message history;SessionStorefor optional persistence;max_sessions/max_turns_per_sessionlimits - SQLite Session Store —
SqliteSessionStorebehindsqlite-sessionfeature flag for persistent session storage - Context Management — Configurable
ContextWindowManagerfor token budget control;max_message_tokenscap - Middleware — Hooks at
on_user_message,on_pre_llm, andon_post_llmfor extensions - Ephemeral Messages — Messages can be marked ephemeral; visible to LLM during the current turn, automatically cleaned from memory after turn ends, excluded from persistence
- Custom Messages —
ChatMessage::Customvariant withconvert_to_llmcallback for domain-specific message types - Plan Checklist — Built-in
UpdatePlanToolfor multi-step task tracking withPlanItem/PlanStepStatus - Checkpoints — Structured
CheckpointData/CheckpointStepevents enable replay, debugging, and resume - Tool Enforcement —
ToolEnforcementMiddlewarenudges the LLM to call tools instead of just describing actions - Turn Tool Limit —
TurnToolLimitMiddlewarecaps tool calls per turn - Circuit Breaker —
ConsecutiveFailureRecoverystops the run after N consecutive failures - Thinking / Reasoning — Per-model thinking budget and effort level configuration
- Response Format — Structured output via
ResponseFormat(JSON Schema / JSON Object) - Session ID Generator — Pluggable
SessionIdGeneratorfor custom ID strategies - Tool Output Truncation — Configurable
max_tool_output_charswith structuredTruncationInfo - Tool Partial Results —
ToolContext::emit_partial_result()for streaming intermediate output during long-running tool execution - Truncation Guard — Automatically detects truncated tool calls when LLM hits the token limit, forcing re-issue with complete arguments
- Message Queue —
MessageQueuewith steering/follow-up queues and configurableQueueModefor ordered or one-at-a-time draining
Feature Flags
| Flag | Description | Default |
|---|---|---|
sqlite-session |
Enable SqliteSessionStore for SQLite-backed session persistence |
off |
telemetry |
Enable OpenTelemetry integration for distributed tracing | off |
[]
= { = "0.2.1", = ["sqlite-session"] }
Quick Start
1. Define a Tool
Any capability you want your agent to have is expressed as a Tool:
use ;
use async_trait;
use ;
;
2. Build the Agent
use Arc;
use ;
async
The callback approach gives you full control over event handling. For simpler cases, run_turn_collect returns (Vec<RuntimeEvent>, RunOutcome) directly.
3. Handle Tool Errors
By default, tool failures stop the run. For self-healing agents (e.g. code agents that retry compilation), inject RetryOnError:
use RetryOnError;
let runtime = new
.register_tool
.error_recovery // ← retry on failure
.build?;
4. Add Approval for Sensitive Tools
use ;
use CancellationToken;
;
;
let runtime = new
.register_tool
.tool_policy
.approval_handler
.build?;
Examples
# Configure API key
# Edit .env with your OPENAI_API_KEY or ANTHROPIC_API_KEY
# Interactive REPL
# Full quickstart demo (tools + approval + middleware)
# SubAgent demo
# Middleware demo
# Approval & policy demo
# Tool context demo
# Thinking / reasoning test
What agent-base Does NOT Do
- Built-in SSH, filesystem, or database tools
- Workflow DAG or multi-agent orchestration engine
- Memory or RAG (Retrieval-Augmented Generation) framework
- Terminal UI or built-in approval dialog
- Production-grade persistence or transaction system
Business-specific tools and strategies belong in upper layers (e.g. phi-agent, agent-works, phi-tools).
Typical Layering
phi-agent / agent-works / ... ← Framework / Enhanced toolkits
└── agent-base ← Lightweight Runtime Kernel
v1 Semantics
| Convention | Meaning |
|---|---|
run_turn → callback FnMut(RuntimeEvent) |
Process events as they arrive; run_turn_collect batches them |
RunOutcome |
Completed / Failed / MaxTurnsExceeded / Cancelled |
RuntimeEvent::RunFinished |
Process ended — final status is in the run_turn return value |
Tool failure → defaults to StopOnError |
Inject RetryOnError for self-healing agents |
SubAgent → defaults to Ephemeral |
Use with_persistent() for shared context |
| Session → memory is source of truth | SessionStore is an optional persistence adapter |
Contributors
Acknowledgments
This project draws inspiration from the OpenAI Codex CLI project — particularly its approach to tool orchestration and task planning.
Stability
This project is in early development (v0.2.1). The core abstractions are settling but not yet frozen. Expect minor API changes as the ecosystem evolves.
License
MIT