{"id":50999908,"url":"https://github.com/cablehead/yoagent","last_synced_at":"2026-06-20T13:30:54.310Z","repository":{"id":348833485,"uuid":"1200051632","full_name":"cablehead/yoagent","owner":"cablehead","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-03T20:04:04.000Z","size":945,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T21:31:44.815Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cablehead.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T01:40:46.000Z","updated_at":"2026-05-04T06:54:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cablehead/yoagent","commit_stats":null,"previous_names":["cablehead/yoagent"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cablehead/yoagent","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cablehead%2Fyoagent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cablehead%2Fyoagent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cablehead%2Fyoagent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cablehead%2Fyoagent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cablehead","download_url":"https://codeload.github.com/cablehead/yoagent/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cablehead%2Fyoagent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34572423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-20T13:30:51.918Z","updated_at":"2026-06-20T13:30:54.299Z","avatar_url":"https://github.com/cablehead.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cpicture\u003e\n  \u003cimg alt=\"yoagent\" src=\"docs/images/banner.png\" width=\"100%\" height=\"auto\"\u003e\n\u003c/picture\u003e\n\n\u003ca href=\"https://crates.io/crates/yoagent\"\u003ecrates.io\u003c/a\u003e · \u003ca href=\"https://yologdev.github.io/yoagent/\"\u003eDocs\u003c/a\u003e · \u003ca href=\"https://github.com/yologdev/yoagent\"\u003eGitHub\u003c/a\u003e · \u003ca href=\"https://deepwiki.com/yologdev/yoagent\"\u003eDeepWiki\u003c/a\u003e · \u003ca href=\"https://github.com/yologdev/yoagent/issues\"\u003eIssues\u003c/a\u003e · \u003ca href=\"https://github.com/yologdev/yoagent/releases\"\u003eReleases\u003c/a\u003e\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\u003c/div\u003e\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            } =\u003e print!(\"{}\", delta),\n            AgentEvent::AgentEnd { .. } =\u003e break,\n            _ =\u003e {}\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(\u0026[\"./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\u003e 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\u003cdetails\u003e\n\u003csummary\u003eOpenAI-compatible provider example\u003c/summary\u003e\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\u003c/details\u003e\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\u003c!-- Badge link definitions --\u003e\n[crates-shield]: https://img.shields.io/crates/v/yoagent?labelColor=black\u0026style=flat-square\u0026logo=rust\u0026color=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\u0026style=flat-square\u0026logo=github\u0026label=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\u0026style=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\u0026style=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\u0026labelColor=black\u0026style=flat-square\n[last-commit-link]: https://github.com/yologdev/yoagent/commits/main\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcablehead%2Fyoagent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcablehead%2Fyoagent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcablehead%2Fyoagent/lists"}