e0a5f57793
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as a monorepo subdirectory under desktop/. Source only — node_modules, dist, Cargo target and the upstream .git history are excluded. desktop/ keeps its own independent Cargo workspace (desktop/src-tauri with crates/*); it is not part of the backend boosapi crate, so a `cargo check` at the metapi root still compiles only the backend. Build the desktop app from desktop/src-tauri per desktop/README.md. Note: app icons are still placeholder assets pending the final BoosAPI logo. The updater signing keys live outside the repo and are not included.
11 KiB
11 KiB
Open Agent SDK (Rust)
A lightweight, open-source Rust SDK for building AI agents. Run the full agent loop in-process — no CLI or subprocess required. Deploy anywhere: cloud, serverless, Docker, CI/CD.
Also available in TypeScript and Go.
Features
- Multi-Provider — Supports both Anthropic Messages API and OpenAI Chat Completions API, with auto-detection by model name
- Agent Loop — Streaming agentic loop with tool execution, multi-turn conversations, and cost tracking
- 25+ Built-in Tools — Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearch, Agent (subagents), AskUser, Tasks, Teams, Plans, Worktrees, Todos, Cron, LSP, Config, MCP Resources, ToolSearch
- Session Persistence — Save, load, fork, and resume conversations across sessions
- MCP Support — Connect to MCP servers via stdio, HTTP, and SSE transports
- Permission System — Configurable tool approval with allow/deny rules and filesystem path validation
- Hook System — 20+ hook events: PreToolUse, PostToolUse, SessionStart/End, SubagentStart/Stop, TaskCreated/Completed, FileChanged, PreCompact/PostCompact, and more
- Extended Thinking — Support for extended thinking with budget tokens
- Cost Tracking — Per-model token usage and pricing for Anthropic, OpenAI, and DeepSeek models
- Custom Tools — Implement the
Tooltrait to add your own tools - Auto-Compaction — Multi-tier context compression (micro-compact, LLM summarization, image stripping)
- Sandbox Config — Network and filesystem restrictions for tool execution
- File State Cache — LRU cache for file state tracking and staleness detection
Quick Start
[dependencies]
open-agent-sdk = "0.1.0"
tokio = { version = "1", features = ["full"] }
use open_agent_sdk::{Agent, AgentOptions, SDKMessage};
use open_agent_sdk::types;
#[tokio::main]
async fn main() {
let mut agent = Agent::new(AgentOptions::default()).await.unwrap();
// Streaming
let (mut rx, handle) = agent.query("What files are in this directory?").await;
while let Some(event) = rx.recv().await {
match event {
SDKMessage::Assistant { message, .. } => {
print!("{}", types::extract_text(&message));
}
SDKMessage::Result { text, cost_usd, .. } => {
println!("\nDone (${:.4})", cost_usd);
}
_ => {}
}
}
handle.await.unwrap();
// Or use the blocking API
let result = agent.prompt("Count lines in Cargo.toml").await.unwrap();
println!("{}", result.text);
agent.close().await;
}
Examples
| # | Example | Description |
|---|---|---|
| 01 | Simple Query | Streaming query with tool calls |
| 02 | Multi-Tool | Glob + Bash multi-tool orchestration |
| 03 | Multi-Turn | Multi-turn conversation with session persistence |
| 04 | Prompt API | Blocking prompt() for one-shot queries |
| 05 | Custom System Prompt | Custom system prompt for code review |
| 06 | MCP Server | MCP server integration (stdio transport) |
| 07 | Custom Tools | Define and use custom tools |
| 08 | One-shot Query | Quick one-shot agent query |
| 09 | Subagents | Specialized subagent with restricted tools |
| 10 | Permissions | Read-only agent with allowed tools |
| 11 | Web Chat | Web-based chat UI with streaming |
Run any example:
export CODEANY_BASE_URL=https://openrouter.ai/api
export CODEANY_API_KEY=your-api-key
export CODEANY_MODEL=anthropic/claude-sonnet-4
cargo run --example 01-simple-query
For the web chat UI:
cargo run --example web-chat
# Open http://localhost:8082
Custom Tools
Implement the Tool trait:
use async_trait::async_trait;
use open_agent_sdk::*;
use serde_json::{json, Value};
use std::collections::HashMap;
use std::sync::Arc;
struct MyTool;
#[async_trait]
impl Tool for MyTool {
fn name(&self) -> &str { "MyTool" }
fn description(&self) -> &str { "Does something useful" }
fn input_schema(&self) -> ToolInputSchema {
ToolInputSchema {
schema_type: "object".to_string(),
properties: HashMap::from([(
"input".to_string(),
json!({"type": "string", "description": "The input"}),
)]),
required: vec!["input".to_string()],
additional_properties: Some(false),
}
}
fn is_read_only(&self, _: &Value) -> bool { true }
async fn call(&self, input: Value, _ctx: &ToolUseContext) -> Result<ToolResult, ToolError> {
Ok(ToolResult::text("result"))
}
}
// Use it
let agent = Agent::new(AgentOptions {
custom_tools: vec![Arc::new(MyTool)],
..Default::default()
}).await.unwrap();
Session Persistence
use open_agent_sdk::session::*;
// Save current session
save_session(&session_data).await.unwrap();
// List all sessions
let sessions = list_sessions().await.unwrap();
// Resume a session
let data = load_session("session-id").await.unwrap();
// Fork a session
let new_id = fork_session("session-id").await.unwrap();
MCP Servers
use open_agent_sdk::types::McpServerConfig;
let agent = Agent::new(AgentOptions {
mcp_servers: HashMap::from([(
"filesystem".to_string(),
McpServerConfig::Stdio {
command: "npx".to_string(),
args: vec!["-y".to_string(), "@modelcontextprotocol/server-filesystem".to_string(), "/tmp".to_string()],
env: HashMap::new(),
},
)]),
..Default::default()
}).await.unwrap();
Built-in Tools
| Tool | Description | Read-Only |
|---|---|---|
| Bash | Execute shell commands | No |
| Read | Read files with line numbers | Yes |
| Write | Create/overwrite files | No |
| Edit | String replacement in files | No |
| Glob | File pattern matching | Yes |
| Grep | Regex search (ripgrep) | Yes |
| NotebookEdit | Edit Jupyter notebook cells | No |
| WebFetch | Fetch URL content | Yes |
| WebSearch | Web search (pluggable) | Yes |
| AskUserQuestion | Interactive user prompts | No |
| SendMessage | Inter-agent messaging | No |
| TeamCreate/Delete | Multi-agent team management | No |
| EnterPlanMode/ExitPlanMode | Structured planning mode | No |
| EnterWorktree/ExitWorktree | Git worktree isolation | No |
| TodoWrite | Session todo list | No |
| TaskCreate/Get/List/Update/Stop/Output | Task tracking (6 tools) | Mixed |
| CronCreate/Delete/List | Scheduled task management | Mixed |
| Config | Session configuration | Mixed |
| LSP | Language Server Protocol operations | Yes |
| ListMcpResources/ReadMcpResource | MCP resource access | Yes |
| ToolSearch | Discover available tools | Yes |
Multi-Provider Support
The SDK automatically detects which API format to use based on the model name:
| Models | API Format | Auto-detected |
|---|---|---|
| Claude (sonnet, opus, haiku) | Anthropic Messages | Yes |
| GPT-4o, O1, O3, O4 | OpenAI Chat Completions | Yes |
| DeepSeek, Qwen, Mistral | OpenAI Chat Completions | Yes |
| LLaMA, Gemma, Gemini, Yi, GLM | OpenAI Chat Completions | Yes |
Override with CODEANY_API_TYPE=openai-completions or CODEANY_API_TYPE=anthropic-messages.
Works with any OpenAI-compatible endpoint (OpenRouter, vLLM, Ollama, LiteLLM, etc.):
export CODEANY_BASE_URL=https://openrouter.ai/api
export CODEANY_API_KEY=your-key
export CODEANY_MODEL=anthropic/claude-sonnet-4
cargo run --example 01-simple-query
Architecture
open-agent-sdk-rust/
├── src/
│ ├── agent/ # Agent loop, query engine, options
│ ├── api/ # Multi-provider API abstraction
│ │ ├── provider.rs # LLMProvider trait + auto-detection
│ │ ├── anthropic.rs# Anthropic Messages API (SSE streaming)
│ │ └── openai.rs # OpenAI Chat Completions API (SSE streaming)
│ ├── types/ # Core types: Message, Tool, ContentBlock, MCP, Sandbox
│ ├── tools/ # 25+ built-in tool implementations + registry + executor
│ ├── mcp/ # MCP client (stdio, HTTP, SSE) + tool wrapping
│ ├── permissions/ # Permission rules, filesystem validation
│ ├── hooks/ # 20+ hook events with pre/post tool-use lifecycle
│ ├── costtracker/ # Token usage and cost tracking (Anthropic, OpenAI, DeepSeek)
│ ├── context/ # System/user context injection (git status, AGENT.md)
│ ├── session/ # Session persistence (save, load, fork, resume)
│ └── utils/ # Token estimation, retry, messages, compaction, file cache
├── tests/ # Comprehensive test suite (116 tests)
└── examples/ # 11 runnable examples + web chat UI
Configuration
Environment variables:
| Variable | Description |
|---|---|
CODEANY_API_KEY |
API key (required) |
CODEANY_MODEL |
Default model (default: sonnet-4-6) |
CODEANY_BASE_URL |
API base URL override |
CODEANY_API_TYPE |
Force API format: anthropic-messages or openai-completions |
CODEANY_CUSTOM_HEADERS |
Custom headers (comma-separated key:value) |
API_TIMEOUT_MS |
API request timeout in ms |
HTTPS_PROXY / HTTP_PROXY |
Proxy URL |
Links
- Website: codeany.ai
- TypeScript SDK: github.com/codeany-ai/open-agent-sdk-typescript
- Go SDK: github.com/codeany-ai/open-agent-sdk-go
- Issues: github.com/codeany-ai/open-agent-sdk-rust/issues
License
MIT