A provider-agnostic AI SDK for Rust
中文 · English
| Version | 0.2.0 |
| Stars | |
| Forks | |
| License | AGPL-3.0-or-later |
- Unified multi-provider API — one interface for DeepSeek / Qwen / OpenAI / Anthropic Claude / Google Gemini
- Streaming + tool calling together — text streams in real time while the tool loop runs automatically; no trade-off needed
- Native protocol engines — Anthropic and Gemini have dedicated engines, not OpenAI-compat wrappers
| Provider | Engine | Streaming | Tool Calling |
|---|---|---|---|
| DeepSeek / Qwen / OpenAI | OpenAI-compat | ✅ | ✅ |
| Anthropic (Claude) | Native | ✅ | ✅ |
| Google Gemini | Native | ✅ | ✅ |
[dependencies]
arc-ai = "0.2"Chat
use arc_ai::{ArcClient, Message};
let client = ArcClient::deepseek("sk-..."); // switch provider here only
let msgs = vec![Message::user("Explain Rust ownership.")];
let resp = client.chat("deepseek-chat", &msgs).await?;
println!("{}", resp.text);Stream
let mut stream = client.stream("gpt-4o", &msgs).await?;
while let Some(StreamPart::TextDelta(t)) = stream.next().await { print!("{t}"); }Tool calling (streaming + auto loop)
let tool = Tool::simple("get_weather", "Get weather", &[("city", "City")], |args| async move {
Ok(json!({ "temp": "32C", "condition": "sunny" }))
});
let req = Request::builder(client.provider().chat_model("claude-3-5-sonnet-20241022"))
.messages(vec![Message::user("Weather in Beijing?")])
.tools(vec![tool]).max_steps(5).build();
let mut s = sdk::stream_text(req).await?; // text streams → tool runs → more textcargo test # 37 passed
cargo clippy # zero warnings