rust-agentai
Library Listed
AgentAI is a Rust library designed to simplify the creation of AI agents.
- Downloads
- 205
- Dependents
- 2
- Stars
- 176
- Forks
- 25
- Contributors
- 3
- Commits
- 84
- Latest release
- 0.5.0 ·
About

AgentAI
AgentAI is a Rust library designed to simplify the creation of AI agents. It leverages the GenAI library to interface with a wide range of popular Large Language Models (LLMs), making it versatile and powerful. Written in Rust, AgentAI benefits from strong static typing and robust error handling, ensuring reliable and maintainable code. Whether you're developing simple or complex AI agents, AgentAI provides a streamlined and efficient development process.
Warning
This library is under heavy development. The interface may change at any time without notice.
Read the full README
Features
- Connect to any major LLM provider: Support for OpenAI, Anthropic, Gemini, Ollama, and other OpenAI-compatible APIs.
- Choose the right model for the job: Flexibly select the best-suited model for each step in your agent's workflow.
- Build custom tools with ease: A simple interface for creating and managing your own tools using the
ToolBox. - MCP Server Support, local and remote: Use tools from any Model Context Protocol server, whether you start it locally over stdio or connect to a running or hosted server over Streamable HTTP (with optional bearer token). Built on the official MCP Rust SDK.
- Structured Output: No need to parse raw text from model, just provide structure, and AI agent will provide response in defined format.
- Streaming: Show the answer as the model writes it, together with the tool calls the agent makes. The stream is
Send + 'static, ready for spawned tasks and server-sent events. - Images for vision models: Send text and images together in a
Prompt, by URL or from bytes. Plain text prompts work as before. - Image generation and editing: The
agentai-imagecrate gives the agent tools to draw and edit images (OpenAI and compatible APIs). Tools can return images to the model withToolOutput. - You own the conversation: An agent is shareable configuration. You keep the history, decide what to store, trim or persist, and get token usage and the stop reason from every run.
What's New
0.5.0 - Image generation, images in tool results
- Image generation and editing: the new
agentai-imagecrate hasImageGeneratorto make and edit images from your code:ImageGenerator::new("openai::gpt-image-1")?takes the provider from the model name and the key fromOPENAI_API_KEY; OpenAI-compatible servers work withOPENAI_BASE_URLor a base URL set in code, and OpenRouter models withopenrouter::<model>.provider::list_modelslists the image models a server offers. - Agents that draw:
GenerateImageToolBoxgives the agentgenerate_imageandedit_image. The model gets the image itself, or only its metadata as JSON to save tokens.ReadMediaToolBoxlets the model read any stored file by its ID. - Media storage:
MediaReadandMediaSave(inagentai-core) store images and other files under an ID; implement them for your blob store or directory, or useMemoryStorage. - Tools can return images: a tool returns a
ToolOutputwith text andMediaparts, for example a chart or a screenshot. For now every provider gets the images in a user message right after the tool results; a later release puts them in the tool result itself for Anthropic, Gemini, OpenAI Responses, Bedrock and Ollama.#[toolbox]methods returnToolResult<ToolOutput>for that; methods that return text stay as they are. - Tools see the call:
ToolBox::call_toolgets theToolCallwith itsid, the same id as in the tool result and the agent events, so a tool can tell parallel calls apart or report progress for one call. A#[toolbox]method gets it through a&ToolCallparameter, which the model does not see. - Fewer argument errors with local models: when a model sends an array or object argument as a JSON
string (
"tags": "[\"a\"]"),#[toolbox]tools now parse it instead of failing. Turn it off withparse_json_strings = falseon#[toolbox]or#[tool]. - TLS backend switches: pick
rustls-ring(the new default),rustls-aws-lcornative-tls, andsystem-proxy(on by default). The default build no longer compiles theaws-lc-sysC library. If you build your owngenai::Clientorreqwest::Client, calltls::install_crypto_providerfirst. - Internal: the new
agentai-corecrate holds the shared types (Message,Prompt,Media, still available fromagentaiunder the same paths) and the HTTP client abstraction used byagentai-image, so it can later run on other HTTP stacks, such as WebAssembly.
Breaking changes: ToolBox::call_tool takes a &ToolCall and returns ToolResult<ToolOutput>, and ToolResponse::content and
the content of tool result events are no longer a String. With default-features = false you must enable a
TLS feature, or HTTPS requests fail. Read the
CHANGELOG and the
migration guide
before upgrading.
0.3.0 - Streaming, conversation history in your hands, run details
- Streaming:
Agent::run_streamtakes the same configuration asAgent::run, and awaiting it returns a stream ofAgentEvents: text and reasoning as the model writes them, each tool call and its result, and finally the result of the run. Runs with tool calls and structured output stream too. The stream isSend + 'static, so you can spawn it or return it from a web handler. - You manage the history: the agent no longer keeps the conversation. Pass your history with
.with_history(&history)and add the run'snew_messagesto it when you want to continue:history.extend(result.new_messages). Store, trim, persist or reset it however you like:Messagehas its own stable JSON format. A failed or cancelled run never changes your history, and the system prompt is not part of it: the agent sends it with every request. - One agent, many conversations: the model and toolbox now belong to the agent
(
Agent::with_model,Agent::with_toolbox), and running takes&self, so one agent can be cloned cheaply and shared between tasks. Change the model, toolbox, iteration limit or options for a single run with thewith_*methods ofAgentRequestor a reusableRunOptions. - Run details: awaiting a run returns a
AgentResultwith the answer, token usage summed over all model calls, the stop reason, the model's reasoning and the number of model calls. An answer cut off by the token limit is reported asAgentError::MaxTokensinstead of a confusing parse error.
Breaking changes: agent.run(model, prompt, toolbox) is replaced by
agent.run(prompt).with_history(&history).await, which returns an AgentResult instead of the bare answer;
the model and toolbox are set with Agent::with_model and Agent::with_toolbox (or per run), and the agent
no longer remembers earlier runs. Agent::new_with_provider takes a Provider, and Agent::new_with_client
is removed. Follow the migration guide to upgrade from 0.2.0: it shows each change with before and
after code.
0.2.0 - Agent providers, remote MCP and configuration
- Creating agents:
Agent::new_with_providerbinds an agent to any genai provider with an explicit API key, for example the native OpenRouter adapter, which needs no base URL:Agent::new_with_provider(AdapterKind::OpenRouter, None, &api_key, system)?.Agent::newandAgent::new_with_urlnow returnResult, and the agent reports typed errors (AgentError). Tool errors are either recoverable (sent back to the model, which can try again) or fatal (they stop the run). - Remote MCP servers, not only stdio:
McpToolBoxnow connects to MCP servers over Streamable HTTP, so agents can use running and hosted servers, including ones that need a bearer token (McpToolBox::new_http,McpToolBox::new_http_with_bearer). Starting a local server over stdio (McpToolBox::new) works as before. MCP support is now built onrmcp, the official MCP Rust SDK. - Agent configuration:
Agent::with_max_iterationsandAgent::with_chat_optionsset the loop limit and the model options (temperature, max tokens, tool choice, reasoning effort, ...). - Strict tools:
#[tool(strict)]marks a tool as strict, so providers that support it make the model's arguments match the parameter schema exactly. - Dependencies: genai 0.7 (re-exported as
agentai::genai; tool calls are no longer lost when a model also returns text), schemars 1, reqwest 0.13, syn 3, Rust edition 2024 and MSRV 1.88.
Breaking changes: Agent::new, Agent::new_with_url and Agent::run return AgentError instead of
anyhow errors, ToolError variants are renamed and split, Tool is built with Tool::new, and answer
and tool parameter types need schemars 1.x. Read the
CHANGELOG before upgrading: it lists
every breaking change and how to migrate.
0.1.5 - ToolBox
This release introduces the ToolBox, a new feature providing an easy-to-use interface for supplying tools to AI agents.
Future Plans
We are continuously working to improve AgentAI. These are the next features we plan; the linked issues have the details:
- Agent Memory: control what the agent remembers between runs, such as persistence, record limits and context management.
- User input during a run: let an agent ask the user for more information or confirmation before it continues.
Installation
To add the AgentAI crate to your project, run the following command in your project's root directory:
cargo add agentai
This command adds the crate and its dependencies to your project.
Feature Flags
Usage
Here is a basic example of how to create an AI agent using AgentAI:
use agentai::{Agent, Message, AgentResult};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let agent = Agent::new("gpt-4o", "You are a useful assistant")?;
// The conversation history is yours
let mut history: Vec<Message> = Vec::new();
let result: AgentResult<String> = agent.run("Why is the sky blue?").with_history(&history).await?;
println!("Answer: {}", result.answer);
// Keep the question and the answer to continue the conversation
history.extend(result.new_messages);
Ok(())
}
Models that support images take a Prompt with text and images, by URL or from bytes:
use agentai::{Agent, AgentResult, Prompt};
let prompt = Prompt::text("Which of these logos is brighter?")
.with_image_url("https://example.com/logo.png")
.with_image_bytes("image/png", &png);
let result: AgentResult<String> = agent.run(prompt).await?;
To show the answer while it is written, use run_stream with the same configuration and
write the stream to the console, a file or any other std::io::Write:
use agentai::{Agent, AgentResult};
let result: AgentResult<String> = agent
.run_stream("Why is the sky blue?")
.await?
.print_to(std::io::stdout())
.await?;
For your own handling, read the [AgentEvent]s of the stream:
use agentai::{Agent, AgentEvent};
use futures_util::StreamExt;
let mut stream = agent.run_stream::<String>("Why is the sky blue?").await?;
while let Some(event) = stream.next().await {
match event? {
AgentEvent::TextDelta(text) => print!("{text}"),
AgentEvent::Finished(result) => println!("\n{} tokens", result.usage.total_tokens),
_ => {}
}
}
Error handling
A run returns an [AgentError] that you can match on. Provider failures that may
succeed on a second try report it with [AgentError::is_transient]. Your history is not
changed by a failed run, so you can simply try again:
use agentai::{Agent, AgentError};
match agent.run::<String>("Why is the sky blue?").await {
Ok(result) => println!("Answer: {}", result.answer),
Err(err) if err.is_transient() => println!("Try again later: {err}"),
Err(AgentError::InvalidAnswer { raw, .. }) => println!("Unexpected answer: {raw}"),
Err(err) => println!("Failed: {err}"),
}
Tools report failures with ToolError. Recoverable errors
(NotFound, InvalidArguments, Failed) are sent to the model as the tool result and the
run continues. Fatal errors (Configuration, Fatal) stop the run with
[AgentError::Tool]. ToolError::is_recoverable
tells the two groups apart.
Examples
For more examples, check out the examples directory. To run an example, use the following command, replacing <example_name> with the name of the example file (without the .rs extension):
cargo run --example <example_name>
For instance, to run the simple example:
cargo run --example simple
Documentation
Full documentation is available on docs.rs.
Contributing
Contributions are welcome! Please see our CONTRIBUTING.md for more details.
License
This project is licensed under the MIT License. See the LICENSE file for details.
Acknowledgements
Special thanks to the creators of the GenAI library for providing a robust framework for interfacing with various LLMs.
Compatibility
- Runs on
- GPU support unknown
What shows it
- no dependency or feature matches a backend row
- Native code
- None found
- No native code found
- Python bindings
- No Python binding crate found
- License
- MIT
Compare with similar projects
Order: strongest tier first, then most downloads, then name, with unmeasured values last. A library counts downloads over 30 days. An app counts binary downloads per release. An app with none counts its crate downloads over 30 days. ML Rust runs this catalogue, so its closest project always gets a row.
| Project | Downloads | Dependents | Stars | Latest release | Runs on (GPU) | Native code | License |
|---|---|---|---|---|---|---|---|
|
AgentAI is a Rust library designed to simplify the creation of AI agents. |
205 downloads over 30 days | 2 | 176 | 0.5.0 | GPU support unknown | No native code found | MIT |
|
the runtime your coding agents live on |
150,430 binary downloads per release | Not applicable | 49,455 | Not measured | Not measured | Apache-2.0 | |
|
rust-mcp-schema Featured
Type-safe implementation of the Model Context Protocol in Rust, designed to reduce errors and accelerate development with powerful utilities. |
107,187 downloads over 30 days | 19 | 79 | 2.0.0 | GPU support unknown | No native code found | MIT |
|
rust-mcp-sdk Featured
An asynchronous SDK and framework for building MCP-Servers and MCP-Clients, leveraging the rust-mcp-schema for type safe MCP Schema Objects. |
29,764 downloads over 30 days | 51 | 199 | 2.0.0 | GPU support unknown | No native code found | MIT |
|
Zero overhead. Zero compromise. 100% Rust. The fastest, smallest AI assistant. |
11,173 binary downloads per release | Not applicable | 33,286 | 0.8.7 | GPU support unknown | Binds native code: aardvark-sys, ring, libsqlite3-sys, tree-sitter, tree-sitter-language and 3 more | Apache-2.0 OR MIT |
|
chidori Listed
The agent framework where every run is durable, replayable, and resumable by default. Plain async TypeScript agents on an embedded pure-Rust JS engine. Python bindings |
257 downloads over 30 days | 0 | 1,372 | 3.8.1 | GPU support unknown | Binds native code: aws-lc-rs, aws-lc-sys, lcms2-sys, libffi-sys, libsqlite3-sys and 4 more | Apache-2.0 |
|
An open protocol that gives AI agents a secure, sandboxed place to run code and use tools — with lean context usage. AXP works alongside MCP |
Not measured | Not applicable | 3 | Not measured | Not measured | Not measured | Apache-2.0 |
Why ListedNo archive, New or Featured rule places it, so it is Listed.
What it lacks for Featured
- It has 0 active dependents and 0 new dependents in 365 days. Featured needs 11 active dependents or 9 new dependents in 365 days. The repository route reads 176 stars, 25 forks and 3 contributors. It needs 4,539 stars, 434 forks and 79 contributors together.
What else the check found
- The last activity is on 4 Nov 2026, 5 days ago. The rules expect an update within 365 days. Dormancy rule
Exact rules: Listed, Featured library. The check on applied thresholds version 9.
Every rule outcome, as the check records it
expected-interval: version 0.5.0 base 140, raised to the 365-day floor: E = 365 daysdormancy: last activity 2026-11-04, 5 days ago, E = 365: activefeatured: not featured: active_users 0 < 11 and new_adopters 0 < 9 and repository route stars 176 (needs 4539), forks 25 (needs 434), contributors 3 (needs 79)listed: listed: no archive, new or featured rule applies
Crates2 crates
- agentai Primary
- agentai-macros
Measurements and sources
Each signal row shows the raw value, its source and the fetch date. The Sources list gathers every distinct source on this page. Movement needs more history.
Sources6 sources
- Description: the crates.io description
- crates.io database dump, fetched
- RustSec advisory database, fetched
- GitHub repository, fetched
- crates.io package, fetched
- GitHub contributors, fetched
Adoption0 active dependents, 0 new dependents in 365 days1 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Active dependents | 0 | crates.io database dump | Yes | |
| New dependents (365 days) | 0 | crates.io database dump | Yes | |
| Peak active dependents | 0 | crates.io database dump | Yes | |
| Active dependents as a share of the peak | 1 | crates.io database dump | Yes | |
| Binary downloads per release | Not measured | Yes |
MaintenanceLatest human commit: 5 days ago3 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Latest human commit | 2026-11-04 | GitHub repository | Yes | |
| Latest release | 2026-11-04 | crates.io database dump | Yes | |
| First release | 2024-12-27 | crates.io database dump | Yes | |
| Latest version | 0.5.0 | crates.io database dump | Yes | |
| Days the oldest outside issue waits for a reply | 0 | GitHub repository | Yes | |
| Maintainer replies over 365 days | 16 | GitHub repository | Yes | |
| Repository archived | false | GitHub repository | Yes | |
| Repository gone | false | GitHub repository | Yes | |
| Release commit or manifest in the repo | true | crates.io package | Yes | |
| Published docs | true | crates.io database dump | Yes | |
| Latest release fails cargo check | Not measured | Yes | ||
| Build check date | Not measured | Yes | ||
| Build check toolchain | Not measured | Yes |
SecurityUnpatched vulnerabilities: none
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Unpatched vulnerabilities past the grace window | none | RustSec advisory database | Yes | |
| RustSec unmaintained advisory | none | RustSec advisory database | Yes | |
| Deprecation notice | none | crates.io database dump | Yes | |
| Deprecated requirement | none | crates.io database dump | Yes |
Distribution12 releases, 205 downloads over 30 days5 not measured
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| Releases | 12 | crates.io database dump | Yes | |
| Downloads over 30 days | 205 | crates.io database dump | Yes | |
| Binary downloads over the last 3 releases | Not measured | Yes | ||
| Homebrew installs on request over 365 days | Not measured | Yes | ||
| Repology repository families | Not measured | Yes | ||
| Docker pull growth over 90 days | Not measured | Yes | ||
| Docker pulls at the growth baseline | Not measured | Yes | ||
| Every version a prerelease | false | crates.io database dump | Yes | |
| Every version 0.0.x | false | crates.io database dump | Yes | |
| Every version yanked | false | crates.io database dump | Yes | |
| Crate deleted from crates.io | false | crates.io database dump | Yes |
Repository176 stars, 25 forks, 3 contributors, 84 commits. Stars alone never qualify a project.
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| GitHub stars | 176 | GitHub repository | Yes — one part of the repository route | |
| GitHub forks | 25 | GitHub repository | Yes — one part of the repository route | |
| Contributors with a GitHub account | 3 | GitHub contributors | Yes — one part of the repository route | |
| Commits on the default branch | 84 | GitHub repository | No | |
| Repository's main crate left out of the entry | none | crates.io database dump | Yes |
Facts that never count
| Signal | Value | Source | Fetched | Counts |
|---|---|---|---|---|
| License | MIT | crates.io database dump | No | |
| Runs on, from listed crates and their direct dependencies | GPU support unknown | crates.io database dump | No | |
| What shows each backend | no dependency or feature matches a backend row | crates.io database dump | No | |
| Native code, from listed crates and their dependencies | No native code found | crates.io database dump | No | |
| Python bindings, from direct dependencies of listed crates | No Python binding crate found | crates.io database dump | No | |
| Crates that depend on a listed crate directly | 2 | crates.io database dump | No |
Corrections and review history
No correction applies to this entry.
Judgments
A judgment enters only through an approved issue and a merged pull request.
No judgment applies to this entry.