Reagent
Reagent is a Rust library for building and running AI agents that interact with LLMs. It abstracts away provider-specific details (currently supports Ollama and OpenRouter), provides a consistent API for prompting, structured outputs, and tool use, and allows you to define fully custom invocation flows.
You can add the library to your project by pulling from crates:
or directly from github:
[]
= { = "https://github.com/VakeDomen/Reagent" }
Notes
- Reagent is experimental and provider support may change.
- Not all provider features are unified;
Features
-
Multiple providers: Ollama (default) and OpenRouter (experimental)
-
Structured output via JSON Schema (manual or via
schemars) -
Tooling:
- Define tools with input schemas
- Register async executors for tool calls
- Integrate MCP (Model Context Protocol) servers as tools
-
Flows:
- Default flows for common patterns
- Custom flows and closures
- Prebuilt flows for quick prototyping
-
Prompt templates with runtime or dynamic data sources
-
Notifications: subscribe to agent events like token streaming, tool calls, errors, etc.
Quick Start
use Error;
use AgentBuilder;
async
Building Agents
The AgentBuilder uses a builder pattern. Only model is required; everything else has defaults.
let agent = default
.set_model
.set_system_prompt
.set_temperature
.set_num_ctx
.build
.await?;
Providers
By default, Reagent assumes an Ollama instance running locally.
let agent = default
.set_model
.set_provider
.set_base_url
.build
.await?;
To use OpenRouter:
let agent = default
.set_model
.set_provider
.set_api_key
.build
.await?;
Note: some providers require provider-specific response format settings.
Structured Output
You can ask the model to return JSON that matches a schema.
Manual schema:
let agent = default
.set_model
.set_response_format
.build
.await?;
From struct via schemars:
let agent = default
.set_model
.
.build
.await?;
To get parsed output directly:
let resp: Weather = agent.invoke_flow_structured_output.await?;
Tools
Tools let the model call custom functions. Define an executor closure, wrap it in a ToolBuilder, and register it with the agent.
async ;
let tool = new
.function_name
.add_required_property
.executor_fn
.build?;
let agent = default
.set_model
.add_tool
.add_mcp_server
.add_mcp_server
.add_mcp_server
.build
.await?;
Flows
Flows control how the agent is invoked.
- Default flow: prompt -> LLM -> (maybe tool call -> LLM) -> result
- Prebuilt flows: e.g.,
reply,reply_without_tools,call_tools,plan_and_execute - Custom flow functions:
async
let agent = default
.set_model
.set_flow
.build
.await?;
Templates
Define prompts with placeholders:
let template = simple;
let agent = default
.set_model
.set_template
.build
.await?;
let prompt_data = from;
let resp = agent.invoke_flow_with_template.await?;
Pass a HashMap of values to invoke_flow_with_template.
You can also provide a TemplateDataSource that injects dynamic values at invocation time.
Notifications & Streaming
You can receive events from the agent using build_with_notification:
let = default
.set_model
.set_stream
.build_with_notification
.await?;
Prebuilds
For quick experiments, StatelessPrebuild and StatefullPrebuild offer presets some simple flow patterns. Stateful versions keep conversation history; stateless ones reset each call.
Examples:
let agent = reply
.set_model
.build
.await?;
let agent = call_tools
.set_model
.build
.await?;
License
MIT