{"repo": "cablehead/yoagent", "files": {"README.md": {"9f5ac2e9d721001a6a4c8cf214ffe1b9ce30ea75": {"t": 1785747167.3771167, "n": 10641, "h": "a552f8d921705b07", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Real-time event streaming — `prompt()` spawns the loop concurrently and returns events immediately; `prompt_with_sender()` accepts a caller-provided channel for custom consumption\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Integrations**\n- OpenAPI tool adapter — auto-generate tools from any OpenAPI 3.0 spec (`features = [\"openapi\"]`)\n- MCP (Model Context Protocol) — connect to MCP tool servers via stdio or HTTP\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.6\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n# With a local server (LM Studio, Ollama, llama.cpp, vLLM):\ncargo run --example cli -- --api-url http://localhost:1234/v1 --model my-model\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "2ade197767b168a1435853843ef19a4208950bc6": {"t": 1785770869.321935, "n": 10641, "h": "a552f8d921705b07", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Real-time event streaming — `prompt()` spawns the loop concurrently and returns events immediately; `prompt_with_sender()` accepts a caller-provided channel for custom consumption\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Integrations**\n- OpenAPI tool adapter — auto-generate tools from any OpenAPI 3.0 spec (`features = [\"openapi\"]`)\n- MCP (Model Context Protocol) — connect to MCP tool servers via stdio or HTTP\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.6\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n# With a local server (LM Studio, Ollama, llama.cpp, vLLM):\ncargo run --example cli -- --api-url http://localhost:1234/v1 --model my-model\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "60aa25a285029ab8c9c23d10ab6ce3639a6f940e": {"t": 1785770870.8556898, "n": 10574, "h": "5d249fe932963021", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Real-time event streaming — `prompt_with_sender()` lets callers consume events on a separate task as they arrive\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Integrations**\n- OpenAPI tool adapter — auto-generate tools from any OpenAPI 3.0 spec (`features = [\"openapi\"]`)\n- MCP (Model Context Protocol) — connect to MCP tool servers via stdio or HTTP\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.6\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n# With a local server (LM Studio, Ollama, llama.cpp, vLLM):\ncargo run --example cli -- --api-url http://localhost:1234/v1 --model my-model\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "f8acdbc3b505775fa16b24653785c1e3b4590421": {"t": 1785770872.3164704, "n": 10459, "h": "ded8aae74b32e5ad", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Integrations**\n- OpenAPI tool adapter — auto-generate tools from any OpenAPI 3.0 spec (`features = [\"openapi\"]`)\n- MCP (Model Context Protocol) — connect to MCP tool servers via stdio or HTTP\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.5\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n# With a local server (LM Studio, Ollama, llama.cpp, vLLM):\ncargo run --example cli -- --api-url http://localhost:1234/v1 --model my-model\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "84e67f770273fe5e050020985902f991baa99627": {"t": 1785770873.7197492, "n": 10264, "h": "fc7314394a70932f", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.5\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n# With a local server (LM Studio, Ollama, llama.cpp, vLLM):\ncargo run --example cli -- --api-url http://localhost:1234/v1 --model my-model\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "da672d8f25e3b9519b07633b2b2831beb9ea55fd": {"t": 1785770876.1257613, "n": 10125, "h": "d73a3bd9185d62cc", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.5\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~250-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "b8323d9b71705e66737a7518d7c7d561e185446e": {"t": 1785770877.605599, "n": 10125, "h": "1411629c34623e81", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.5\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── sub_agent.rs # SubAgentTool — delegate tasks to child agent loops\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "36a1154a026fa3f83bdb8d4959065b3c977b4063": {"t": 1785770879.0869777, "n": 10044, "h": "270d918e6506683d", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Sub-agents via `SubAgentTool` — delegate tasks to child agent loops with their own tools and system prompts\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Multimodal support — `Content::Image` flows through tool results across all providers\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- State persistence — `save_messages()` / `restore_messages()` for pause/resume workflows\n- Lifecycle callbacks — `before_turn`, `after_turn`, `on_error` for observability and control\n- Full serde support — all core types implement `Serialize`/`Deserialize`/`PartialEq`\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.2\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "4e327a784433d65466737927e03f395670aea29c": {"t": 1785770881.3331797, "n": 9576, "h": "c6ea7e47ac507608", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Install\n\n```bash\ncargo add yoagent tokio --features tokio/full\n```\n\nOr add to `Cargo.toml`:\n\n```toml\n[dependencies]\nyoagent = \"0.2\"\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "7cc5104ca20fce05ea92bdd4d08f2466b94944ad": {"t": 1785770882.7727878, "n": 9548, "h": "71308eea9284a173", "c": "
\n\n\n \"yoagent\"\n\n\ncrates.io · Docs · GitHub · DeepWiki · Issues · Releases\n\n[![][crates-shield]][crates-link]\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black&style=flat-square&logo=rust&color=orange\n[crates-link]: https://crates.io/crates/yoagent\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "a9a5e96573d057e01c12001060d945c5044cdf99": {"t": 1785770884.5437799, "n": 9292, "h": "b6b9988af341abd1", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Context overflow detection across all major providers (Anthropic, OpenAI, Google, Bedrock, xAI, Groq, OpenRouter, llama.cpp, and more)\n- `ContextTracker` — hybrid real-usage + estimation for accurate token tracking\n- Tiered compaction: truncate tool outputs → summarize old turns → drop middle\n- Execution limits (max turns, max tokens, timeout)\n- Building blocks for LLM-based summarization (`replace_messages()`, `compact_messages()`)\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "004ee3a99b45e79f1f1c120d1b9c51b58baa2e41": {"t": 1785770885.8853378, "n": 9039, "h": "2aa2f694c597e82d", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Skills ([AgentSkills](https://agentskills.io) compatible)\n\nSkills extend the agent with domain expertise. A skill is a directory with a `SKILL.md`:\n\n```\nskills/\n└── git/\n ├── SKILL.md # YAML frontmatter + instructions\n └── scripts/ # Optional resources\n```\n\n```rust\nuse yoagent::SkillSet;\n\nlet skills = SkillSet::load(&[\"./skills\"])?;\n\nlet agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a coding assistant.\")\n .with_skills(skills) // Injects skill index into system prompt\n .with_tools(tools);\n```\n\nThe agent sees a compact index of available skills. When a task matches, it reads the full SKILL.md using the `read_file` tool — no special infrastructure needed. Skills are cross-compatible with Claude Code, Codex CLI, Gemini CLI, Cursor, and other AgentSkills-compatible agents.\n\nSee [docs/concepts/skills.md](docs/concepts/skills.md) for the full guide.\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n# With skills:\nANTHROPIC_API_KEY=sk-... cargo run --example cli -- --skills ./skills\n```\n\nA ~230-line interactive coding agent with all built-in tools, skills support, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n skills: 3 loaded\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "0976f37bd11d9ea5bef54cbbf649cf812cb62b6b": {"t": 1785770887.7925918, "n": 8008, "h": "7ab55d339a520060", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n- [AgentSkills](https://agentskills.io)-compatible skills — load skill directories, inject into system prompt, agent activates on demand\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n```\n\nA ~200-line interactive coding agent with all built-in tools, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "59c033d0ae963307aea95ff5b7e68c316475d5b6": {"t": 1785770889.1422887, "n": 7871, "h": "813b269a2b404d21", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n### Interactive CLI (mini coding agent)\n\n```bash\nANTHROPIC_API_KEY=sk-... cargo run --example cli\n```\n\nA ~200-line interactive coding agent with all built-in tools, streaming output, and colored tool feedback. Like a baby Claude Code.\n\n```\n yoagent cli — mini coding agent\n Type /quit to exit, /clear to reset\n\n model: claude-sonnet-4-20250514\n cwd: /home/user/my-project\n\n> find all TODO comments in src/\n\n ▶ search 'TODO' ✓\n\nFound 3 TODOs:\n src/main.rs:42: // TODO: handle edge case\n src/lib.rs:15: // TODO: add tests\n src/utils.rs:8: // TODO: optimize this\n\n tokens: 1250 in / 89 out\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "6add390a640fbbd73d4b66670e52874e597c06d1": {"t": 1785770891.3409607, "n": 7267, "h": "9a843e7baa770be0", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Automatic retry with exponential backoff and jitter for rate limits and network errors\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "1a87ba1f6a4a03c6b22e9a39ff06ea65c7ca40cd": {"t": 1785770892.5325785, "n": 7178, "h": "432527c2d2903aec", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Streaming tool output — tools emit real-time progress via `on_update` callback\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "f600510afc7f2733c33d7f8f93555d5e9ccd2d97": {"t": 1785770894.176676, "n": 7097, "h": "897ab09e3444560c", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Parallel tool execution by default — sequential and batched strategies also available\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "2c59afd2f296ea0a5011da0bd97251a7c258adbb": {"t": 1785770895.539099, "n": 7009, "h": "27d4f34762528099", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "a7a1d30d6e79965247f0b9159f8f7f520062219f": {"t": 1785770896.7630544, "n": 7009, "h": "c495894144fabe12", "c": "
\n\n\n \"yoagent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyoagent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyoagent = { git = \"https://github.com/yologdev/yoagent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yoagent::agent::Agent;\nuse yoagent::provider::AnthropicProvider;\nuse yoagent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yoagent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyoagent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yoagent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yoagent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yoagent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yoagent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yoagent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yoagent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n"}, "0c872f7681b55c451b04017cfa320e1f6ee9b72a": {"t": 1785770898.1206787, "n": 7030, "h": "f52f2c03640d69c8", "c": "
\n\n\n \"yo-agent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyo-agent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyo-agent = { git = \"https://github.com/yologdev/yo-agent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yo_agent::agent::Agent;\nuse yo_agent::provider::AnthropicProvider;\nuse yo_agent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yo_agent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyo-agent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yo-agent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yo-agent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yo-agent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yo-agent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yo-agent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yo-agent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yo-agent/commits/main\n"}, "1175fc17d07cbc419dc678782ae1aa3d4d7d4254": {"t": 1785770900.096325, "n": 7030, "h": "7846d2b94412c988", "c": "
\n\n\n \"yo-agent\"\n\n\nDocs · GitHub · DeepWiki · Issues · Releases\n\n[![][ci-shield]][ci-link]\n[![][license-shield]][license-link]\n[![][docs-shield]][docs-link]\n[![][last-commit-shield]][last-commit-link]\n\n
\n\n---\n\n## Overview\n\nyo-agent is a simple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nPrompt → LLM Stream → Tool Execution → Loop if tool calls → Done\n```\n\nEverything is observable via events. Supports 7 API protocols covering 20+ LLM providers out of the box.\n\n## Features\n\n**Agent Loop**\n- Stateful agent with steering (interrupt mid-run) and follow-up (queue work after completion)\n- Full event stream: `AgentStart` → `TurnStart` → `MessageUpdate` (deltas) → `ToolExecution` → `TurnEnd` → `AgentEnd`\n- Custom message types via `AgentMessage::Extension` — app-specific messages that don't pollute LLM context\n\n**Multi-Provider**\n- 7 API protocols, 20+ providers through a modular registry\n- One OpenAI-compatible implementation covers OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, and more\n- Per-provider quirk flags (`OpenAiCompat`) handle auth, reasoning format, and tool handling differences\n\n**Built-in Tools**\n- `bash` — Shell execution with timeout, output truncation, command deny patterns\n- `read_file` / `write_file` — File I/O with line numbers, path restrictions, auto-mkdir\n- `edit_file` — Surgical search/replace with fuzzy match error hints\n- `list_files` — Directory exploration via `find`\n- `search` — Pattern search via ripgrep/grep with context lines\n\n**Context Management**\n- Token estimation and smart truncation (keep first + last, drop middle)\n- Execution limits (max turns, max tokens, timeout)\n- Configurable context transforms and LLM message conversion\n\n---\n\n## Quick Start\n\n### Add to Cargo.toml\n\n```toml\n[dependencies]\nyo-agent = { git = \"https://github.com/yologdev/yo-agent.git\" }\ntokio = { version = \"1\", features = [\"full\"] }\n```\n\n### Basic Usage\n\n```rust\nuse yo_agent::agent::Agent;\nuse yo_agent::provider::AnthropicProvider;\nuse yo_agent::types::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"What is Rust's ownership model?\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate {\n delta: StreamDelta::Text { delta }, ..\n } => print!(\"{}\", delta),\n AgentEvent::AgentEnd { .. } => break,\n _ => {}\n }\n }\n}\n```\n\n
\nOpenAI-compatible provider example\n\n```rust\nuse yo_agent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Use any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Or Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n
\n\n---\n\n## Providers\n\n| Protocol | Providers |\n|----------|-----------|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags for differences in auth, reasoning format, tool handling, and more. Adding a new compatible provider is just a `ModelConfig` with the right `base_url`.\n\n---\n\n## Architecture\n\n```\nyo-agent/\n├── src/\n│ ├── types.rs # Message, AgentMessage, AgentEvent, AgentTool trait\n│ ├── agent_loop.rs # Core loop (agent_loop + agent_loop_continue)\n│ ├── agent.rs # Stateful Agent with steering/follow-up queues\n│ ├── context.rs # Token estimation, smart truncation, execution limits\n│ ├── tools/\n│ │ ├── bash.rs # Shell execution (timeout, deny patterns, confirm_fn)\n│ │ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ │ ├── edit.rs # Search/replace editing with fuzzy match hints\n│ │ ├── list.rs # Directory listing via find\n│ │ └── search.rs # Pattern search via ripgrep/grep\n│ └── provider/\n│ ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n│ ├── model.rs # ModelConfig, ApiProtocol, OpenAiCompat\n│ ├── registry.rs # ProviderRegistry — dispatch by protocol\n│ ├── anthropic.rs # Anthropic Messages API\n│ ├── openai_compat.rs # OpenAI Chat Completions (15+ providers)\n│ ├── openai_responses.rs # OpenAI Responses API\n│ ├── azure_openai.rs # Azure OpenAI\n│ ├── google.rs # Google Generative AI (Gemini)\n│ ├── google_vertex.rs # Google Vertex AI\n│ ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n│ ├── sse.rs # Shared SSE parsing utility\n│ └── mock.rs # Mock provider for testing\n├── docs/ # mdBook documentation\n├── examples/ # Usage examples\n└── tests/ # Integration tests\n```\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Links\n\n- [Documentation](https://yologdev.github.io/yo-agent/) — Full reference\n- [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent) — Original inspiration (TypeScript)\n\n\n[ci-shield]: https://img.shields.io/github/actions/workflow/status/yologdev/yo-agent/ci.yml?labelColor=black&style=flat-square&logo=github&label=CI\n[ci-link]: https://github.com/yologdev/yo-agent/actions/workflows/ci.yml\n[license-shield]: https://img.shields.io/badge/license-MIT-white?labelColor=black&style=flat-square\n[license-link]: https://github.com/yologdev/yo-agent/blob/main/LICENSE\n[docs-shield]: https://img.shields.io/badge/docs-mdBook-blue?labelColor=black&style=flat-square\n[docs-link]: https://yologdev.github.io/yo-agent/\n[last-commit-shield]: https://img.shields.io/github/last-commit/yologdev/yo-agent?color=c4f042&labelColor=black&style=flat-square\n[last-commit-link]: https://github.com/yologdev/yo-agent/commits/main\n"}, "455abf72d823890e27a892973c41e4eda6b18589": {"t": 1785770902.3500643, "n": 6368, "h": "b82c2e980384be66", "c": "# yo-agent 🦀\n\nSimple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\n## Philosophy\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nprompt → LLM stream → tool execution → loop if tool calls → done\n```\n\nEverything is observable via events. Custom message types let apps add UI-only messages without polluting the LLM context.\n\n## Quick Start\n\n```rust\nuse yo_agent::agent::Agent;\nuse yo_agent::provider::AnthropicProvider;\nuse yo_agent::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"Hello!\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate { delta: StreamDelta::Text { delta }, .. } => {\n print!(\"{}\", delta);\n }\n _ => {}\n }\n }\n}\n```\n\n## Architecture\n\n```\nsrc/\n├── types.rs # Core types: Message, AgentMessage, AgentEvent, AgentTool trait\n├── agent_loop.rs # The core loop (agent_loop + agent_loop_continue)\n├── agent.rs # Stateful Agent with steering/follow-up queues\n├── context.rs # Context management, token estimation, smart truncation\n├── tools/\n│ ├── bash.rs # Shell execution (timeout, output truncation, deny patterns)\n│ ├── file.rs # Read/write files (line numbers, path restrictions)\n│ ├── edit.rs # Surgical search/replace editing\n│ ├── list.rs # Directory listing via find\n│ └── search.rs # Pattern search via ripgrep/grep\n└── provider/\n ├── traits.rs # StreamProvider trait, StreamEvent, ProviderError\n ├── model.rs # ModelConfig, ApiProtocol, CostConfig, OpenAiCompat\n ├── registry.rs # ProviderRegistry — dispatch by API protocol\n ├── anthropic.rs # Anthropic Messages API (Claude)\n ├── openai_compat.rs # OpenAI Chat Completions (OpenAI, xAI, Groq, Mistral, etc.)\n ├── openai_responses.rs # OpenAI Responses API\n ├── azure_openai.rs # Azure OpenAI\n ├── google.rs # Google Generative AI (Gemini)\n ├── google_vertex.rs # Google Vertex AI\n ├── bedrock.rs # Amazon Bedrock (ConverseStream)\n ├── sse.rs # Shared SSE parsing utility\n └── mock.rs # Mock provider for testing\n```\n\n## Providers\n\nyo-agent supports **7 API protocols** covering **20+ providers** through a modular registry:\n\n| Protocol | Providers |\n|---|---|\n| Anthropic Messages | Anthropic (Claude) |\n| OpenAI Completions | OpenAI, xAI, Groq, Cerebras, OpenRouter, Mistral, MiniMax, HuggingFace, Kimi, DeepSeek |\n| OpenAI Responses | OpenAI (newer API) |\n| Azure OpenAI | Azure OpenAI |\n| Google Generative AI | Google Gemini |\n| Google Vertex | Google Vertex AI |\n| Bedrock ConverseStream | Amazon Bedrock |\n\nOpenAI-compatible providers share one implementation with per-provider quirk flags (`OpenAiCompat`) for differences in auth, reasoning format, tool handling, etc.\n\n```rust\nuse yo_agent::provider::{ModelConfig, ApiProtocol, ProviderRegistry};\n\n// Anthropic\nlet model = ModelConfig::anthropic(\"claude-sonnet-4-20250514\");\n\n// Any OpenAI-compatible provider\nlet model = ModelConfig::openai_compat(\"groq\", \"llama-3.3-70b\", \"https://api.groq.com/openai/v1\");\n\n// Google Gemini\nlet model = ModelConfig::google(\"gemini-2.5-pro\");\n\n// Registry dispatches to the right provider\nlet registry = ProviderRegistry::default();\n```\n\n## Key Concepts\n\n### AgentMessage vs Message\n\n`Message` is what LLMs understand (user/assistant/toolResult). `AgentMessage` wraps this and adds an `Extension` variant for app-specific messages (UI notifications, artifacts, etc.) that live in conversation history but aren't sent to the model.\n\n### Event Flow\n\n```\nagent_loop(\"Hello\")\n├─ AgentStart\n├─ TurnStart\n├─ MessageStart (user prompt)\n├─ MessageEnd (user prompt)\n├─ MessageStart (assistant)\n├─ MessageUpdate (streaming deltas)\n├─ MessageEnd (assistant complete)\n├─ TurnEnd\n└─ AgentEnd\n```\n\n### Steering & Follow-up\n\n- **Steering**: Interrupt the agent mid-tool-execution. Remaining tools are skipped.\n- **Follow-up**: Queue work for after the agent finishes its current task.\n\n```rust\n// While agent is running tools\nagent.steer(AgentMessage::Llm(Message::user(\"Stop! Do this instead.\")));\n\n// After agent finishes\nagent.follow_up(AgentMessage::Llm(Message::user(\"Also summarize the result.\")));\n```\n\n## Tools\n\nImplement the `AgentTool` trait:\n\n```rust\nuse yo_agent::*;\n\nstruct ReadFile;\n\n#[async_trait::async_trait]\nimpl AgentTool for ReadFile {\n fn name(&self) -> &str { \"read_file\" }\n fn label(&self) -> &str { \"Read File\" }\n fn description(&self) -> &str { \"Read a file's contents\" }\n fn parameters_schema(&self) -> serde_json::Value {\n serde_json::json!({\n \"type\": \"object\",\n \"properties\": {\n \"path\": {\"type\": \"string\", \"description\": \"File path\"}\n },\n \"required\": [\"path\"]\n })\n }\n async fn execute(\n &self,\n _id: &str,\n params: serde_json::Value,\n _cancel: tokio_util::sync::CancellationToken,\n ) -> Result {\n let path = params[\"path\"].as_str().ok_or(ToolError::InvalidArgs(\"missing path\".into()))?;\n let content = tokio::fs::read_to_string(path).await\n .map_err(|e| ToolError::Failed(e.to_string()))?;\n Ok(ToolResult {\n content: vec![Content::Text { text: content }],\n details: serde_json::Value::Null,\n })\n }\n}\n```\n\n## Testing\n\nUses `MockProvider` for tests — no API keys needed:\n\n```rust\nuse yo_agent::provider::mock::*;\nuse yo_agent::provider::MockProvider;\n\nlet provider = MockProvider::new(vec![\n MockResponse::ToolCalls(vec![MockToolCall {\n name: \"read_file\".into(),\n arguments: serde_json::json!({\"path\": \"test.txt\"}),\n }]),\n MockResponse::Text(\"File contents: hello\".into()),\n]);\n\nlet mut agent = Agent::new(provider)\n .with_system_prompt(\"test\")\n .with_model(\"mock\")\n .with_api_key(\"test\");\n```\n\n## License\n\nMIT\n"}, "8890186ec2d0686bc49352717d45a3f5e827dd99": {"t": 1785770904.536032, "n": 4211, "h": "bae6c4b457ba978a", "c": "# yo-agent 🦀\n\nSimple, effective agent loop with tool execution and event streaming in Rust. Inspired by [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\n## Philosophy\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nprompt → LLM stream → tool execution → loop if tool calls → done\n```\n\nEverything is observable via events. Custom message types let apps add UI-only messages without polluting the LLM context.\n\n## Quick Start\n\n```rust\nuse yo_agent::agent::Agent;\nuse yo_agent::provider::AnthropicProvider;\nuse yo_agent::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"Hello!\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate { delta: StreamDelta::Text { delta }, .. } => {\n print!(\"{}\", delta);\n }\n _ => {}\n }\n }\n}\n```\n\n## Architecture\n\n```\nsrc/\n├── types.rs # Core types: Message, AgentMessage, AgentEvent, AgentTool trait\n├── agent_loop.rs # The core loop (agent_loop + agent_loop_continue)\n├── agent.rs # Stateful Agent with steering/follow-up queues\n└── provider/\n ├── traits.rs # StreamProvider trait\n ├── anthropic.rs # Anthropic Claude (streaming)\n └── mock.rs # Mock provider for testing\n```\n\n## Key Concepts\n\n### AgentMessage vs Message\n\n`Message` is what LLMs understand (user/assistant/toolResult). `AgentMessage` wraps this and adds an `Extension` variant for app-specific messages (UI notifications, artifacts, etc.) that live in conversation history but aren't sent to the model.\n\n### Event Flow\n\n```\nagent_loop(\"Hello\")\n├─ AgentStart\n├─ TurnStart\n├─ MessageStart (user prompt)\n├─ MessageEnd (user prompt)\n├─ MessageStart (assistant)\n├─ MessageUpdate (streaming deltas)\n├─ MessageEnd (assistant complete)\n├─ TurnEnd\n└─ AgentEnd\n```\n\n### Steering & Follow-up\n\n- **Steering**: Interrupt the agent mid-tool-execution. Remaining tools are skipped.\n- **Follow-up**: Queue work for after the agent finishes its current task.\n\n```rust\n// While agent is running tools\nagent.steer(AgentMessage::Llm(Message::user(\"Stop! Do this instead.\")));\n\n// After agent finishes\nagent.follow_up(AgentMessage::Llm(Message::user(\"Also summarize the result.\")));\n```\n\n## Tools\n\nImplement the `AgentTool` trait:\n\n```rust\nuse yo_agent::*;\n\nstruct ReadFile;\n\n#[async_trait::async_trait]\nimpl AgentTool for ReadFile {\n fn name(&self) -> &str { \"read_file\" }\n fn label(&self) -> &str { \"Read File\" }\n fn description(&self) -> &str { \"Read a file's contents\" }\n fn parameters_schema(&self) -> serde_json::Value {\n serde_json::json!({\n \"type\": \"object\",\n \"properties\": {\n \"path\": {\"type\": \"string\", \"description\": \"File path\"}\n },\n \"required\": [\"path\"]\n })\n }\n async fn execute(\n &self,\n _id: &str,\n params: serde_json::Value,\n _cancel: tokio_util::sync::CancellationToken,\n ) -> Result {\n let path = params[\"path\"].as_str().ok_or(ToolError::InvalidArgs(\"missing path\".into()))?;\n let content = tokio::fs::read_to_string(path).await\n .map_err(|e| ToolError::Failed(e.to_string()))?;\n Ok(ToolResult {\n content: vec![Content::Text { text: content }],\n details: serde_json::Value::Null,\n })\n }\n}\n```\n\n## Testing\n\nUses `MockProvider` for tests — no API keys needed:\n\n```rust\nuse yo_agent::provider::mock::*;\nuse yo_agent::provider::MockProvider;\n\nlet provider = MockProvider::new(vec![\n MockResponse::ToolCalls(vec![MockToolCall {\n name: \"read_file\".into(),\n arguments: serde_json::json!({\"path\": \"test.txt\"}),\n }]),\n MockResponse::Text(\"File contents: hello\".into()),\n]);\n\nlet mut agent = Agent::new(provider)\n .with_system_prompt(\"test\")\n .with_model(\"mock\")\n .with_api_key(\"test\");\n```\n\n## License\n\nMIT\n"}, "728277a2e3c1dc943783d9fbf04e5190e3512766": {"t": 1785770906.226541, "n": 4204, "h": "f43a85200f90150b", "c": "# yo-agent 🦀\n\nSimple, effective agent loop with tool execution and event streaming. Rust port of [pi-agent-core](https://github.com/badlogic/pi-mono/tree/main/packages/agent).\n\n## Philosophy\n\nThe loop is the product. No over-engineered planning/reflection/RAG layers — just:\n\n```\nprompt → LLM stream → tool execution → loop if tool calls → done\n```\n\nEverything is observable via events. Custom message types let apps add UI-only messages without polluting the LLM context.\n\n## Quick Start\n\n```rust\nuse yo_agent::agent::Agent;\nuse yo_agent::provider::AnthropicProvider;\nuse yo_agent::*;\n\n#[tokio::main]\nasync fn main() {\n let mut agent = Agent::new(AnthropicProvider)\n .with_system_prompt(\"You are a helpful assistant.\")\n .with_model(\"claude-sonnet-4-20250514\")\n .with_api_key(std::env::var(\"ANTHROPIC_API_KEY\").unwrap());\n\n let mut rx = agent.prompt(\"Hello!\").await;\n\n while let Some(event) = rx.recv().await {\n match event {\n AgentEvent::MessageUpdate { delta: StreamDelta::Text { delta }, .. } => {\n print!(\"{}\", delta);\n }\n _ => {}\n }\n }\n}\n```\n\n## Architecture\n\n```\nsrc/\n├── types.rs # Core types: Message, AgentMessage, AgentEvent, AgentTool trait\n├── agent_loop.rs # The core loop (agent_loop + agent_loop_continue)\n├── agent.rs # Stateful Agent with steering/follow-up queues\n└── provider/\n ├── traits.rs # StreamProvider trait\n ├── anthropic.rs # Anthropic Claude (streaming)\n └── mock.rs # Mock provider for testing\n```\n\n## Key Concepts\n\n### AgentMessage vs Message\n\n`Message` is what LLMs understand (user/assistant/toolResult). `AgentMessage` wraps this and adds an `Extension` variant for app-specific messages (UI notifications, artifacts, etc.) that live in conversation history but aren't sent to the model.\n\n### Event Flow\n\n```\nagent_loop(\"Hello\")\n├─ AgentStart\n├─ TurnStart\n├─ MessageStart (user prompt)\n├─ MessageEnd (user prompt)\n├─ MessageStart (assistant)\n├─ MessageUpdate (streaming deltas)\n├─ MessageEnd (assistant complete)\n├─ TurnEnd\n└─ AgentEnd\n```\n\n### Steering & Follow-up\n\n- **Steering**: Interrupt the agent mid-tool-execution. Remaining tools are skipped.\n- **Follow-up**: Queue work for after the agent finishes its current task.\n\n```rust\n// While agent is running tools\nagent.steer(AgentMessage::Llm(Message::user(\"Stop! Do this instead.\")));\n\n// After agent finishes\nagent.follow_up(AgentMessage::Llm(Message::user(\"Also summarize the result.\")));\n```\n\n## Tools\n\nImplement the `AgentTool` trait:\n\n```rust\nuse yo_agent::*;\n\nstruct ReadFile;\n\n#[async_trait::async_trait]\nimpl AgentTool for ReadFile {\n fn name(&self) -> &str { \"read_file\" }\n fn label(&self) -> &str { \"Read File\" }\n fn description(&self) -> &str { \"Read a file's contents\" }\n fn parameters_schema(&self) -> serde_json::Value {\n serde_json::json!({\n \"type\": \"object\",\n \"properties\": {\n \"path\": {\"type\": \"string\", \"description\": \"File path\"}\n },\n \"required\": [\"path\"]\n })\n }\n async fn execute(\n &self,\n _id: &str,\n params: serde_json::Value,\n _cancel: tokio_util::sync::CancellationToken,\n ) -> Result {\n let path = params[\"path\"].as_str().ok_or(ToolError::InvalidArgs(\"missing path\".into()))?;\n let content = tokio::fs::read_to_string(path).await\n .map_err(|e| ToolError::Failed(e.to_string()))?;\n Ok(ToolResult {\n content: vec![Content::Text { text: content }],\n details: serde_json::Value::Null,\n })\n }\n}\n```\n\n## Testing\n\nUses `MockProvider` for tests — no API keys needed:\n\n```rust\nuse yo_agent::provider::mock::*;\nuse yo_agent::provider::MockProvider;\n\nlet provider = MockProvider::new(vec![\n MockResponse::ToolCalls(vec![MockToolCall {\n name: \"read_file\".into(),\n arguments: serde_json::json!({\"path\": \"test.txt\"}),\n }]),\n MockResponse::Text(\"File contents: hello\".into()),\n]);\n\nlet mut agent = Agent::new(provider)\n .with_system_prompt(\"test\")\n .with_model(\"mock\")\n .with_api_key(\"test\");\n```\n\n## License\n\nMIT\n"}}}}