chat-rs
A multi-provider LLM framework for Rust. Build type-safe chat clients with tool calling, structured output, streaming, and embeddings — swap providers with a single line change.
Features
- Multi-provider — Gemini, Claude, OpenAI, and Router today, more coming (see Roadmap)
- Router — route requests across multiple providers with fallback and custom strategies (keyword, embedding, capability-based)
- Type-safe builder — compile-time enforcement of valid configurations via type-state pattern
- Tool calling — define tools with
#[tool], the framework handles the call loop automatically - Structured output — deserialize model responses directly into your Rust types via
schemars - Streaming — real-time token-by-token output with tool call support
- Embeddings — generate vector embeddings through the same unified API
- Retry & callbacks — configurable retry strategies with before/after hooks
- Native tools — provider-specific features like Google Search, code execution, web search
Quick Start
Add to your Cargo.toml:
[]
= { = "0.0.10", = ["openai"] }
= { = "1", = ["macros", "rt-multi-thread"] }
use ;
async
Set your API key via environment variable (OPENAI_API_KEY, GEMINI_API_KEY, or CLAUDE_API_KEY), or pass it explicitly with .with_api_key().
Providers
Enable providers via feature flags:
# Pick one or more
= { = "0.0.10", = ["gemini"] }
= { = "0.0.10", = ["claude"] }
= { = "0.0.10", = ["openai"] }
= { = "0.0.10", = ["router", "gemini", "claude"] }
= { = "0.0.10", = ["gemini", "claude", "openai", "stream"] }
| Provider | Feature | API Key Env Var | Builder |
|---|---|---|---|
| Google Gemini | gemini |
GEMINI_API_KEY |
GeminiBuilder |
| Anthropic Claude | claude |
CLAUDE_API_KEY |
ClaudeBuilder |
| OpenAI | openai |
OPENAI_API_KEY |
OpenAIBuilder |
| Router | router |
— | RouterBuilder |
Swapping providers is a one-line change — replace the builder, everything else stays the same:
// Gemini
let client = new
.with_model
.build;
// Claude
let client = new
.with_model
.build;
// OpenAI
let client = new
.with_model
.build;
// Same from here on
let mut chat = new.with_model.build;
Tool Calling
Define tools with the #[tool] macro from tools-rs and register them with collect_tools(). The framework automatically loops through tool calls until the model is done.
use ;
use ;
/// Looks up the current weather for a given city.
async
async
Structured Output
Deserialize model responses directly into typed Rust structs. Your type must derive JsonSchema and Deserialize.
use JsonSchema;
use Deserialize;
let mut chat = new
.
.with_model
.build;
let response = chat.complete.await?;
println!;
Streaming
Enable the stream feature flag:
= { = "0.0.10", = ["gemini", "stream"] }
use StreamEvent;
use StreamExt;
let mut chat = new
.with_model
.build;
let mut stream = chat.stream.await?;
while let Some = stream.next.await
Embeddings
let client = new
.with_model
.with_embeddings
.build;
let mut chat = new
.with_model
.with_embeddings
.build;
let response = chat.embed.await?;
println!;
Native Tools
Provider-specific capabilities beyond standard tool calling:
// Gemini: Google Search, Code Execution, Google Maps
let client = new
.with_model
.with_google_search
.with_code_execution
.build;
// OpenAI: Web Search
let client = new
.with_model
.with_web_search
.build;
OpenAI-Compatible Endpoints
Use local or proxy servers that implement the OpenAI Responses API:
let client = new
.with_model
.with_custom_url
.with_api_key
.build;
Note: The custom endpoint must support the Responses API format (
POST /responses), not the Chat Completions API.
Router
Route requests across multiple providers with automatic fallback on retryable errors. Add a custom RoutingStrategy to control provider selection based on keywords, embeddings, capabilities, or any logic you need.
use ;
let gemini = new
.with_model
.build;
let claude = new
.with_model
.build;
let router = new
.add_provider
.add_provider
// .with_strategy(my_strategy) // optional custom routing
.build;
let mut chat = new.with_model.build;
let mut msgs = from_user;
let res = chat.complete.await?;
Without a custom strategy, the router tries providers in order and falls back on retryable errors (rate limits, network issues). Non-retryable errors are returned immediately.
Note: The router currently supports completions only — streaming and embeddings are not yet available.
Architecture
chat-rs (root) ← Re-exports + feature flags
├── core/ ← Traits, types, Chat engine, builder
├── providers/
│ ├── gemini/ ← Google Gemini provider
│ ├── claude/ ← Anthropic Claude provider
│ ├── openai/ ← OpenAI Responses API provider
│ └── router/ ← Multi-provider router
└── examples/
├── gemini/ ← Gemini examples
├── claude/ ← Claude examples
├── openai/ ← OpenAI examples
└── router/ ← Router strategy examples
See core/AGENTS.md and providers/AGENTS.md for detailed architecture documentation.
Examples
Run examples with the appropriate feature flags:
# Gemini
# Claude
# OpenAI
# Router
# Retry strategies
Minimum Supported Rust Version
Rust 1.94 or later (edition 2024).
License
MIT