{"id":47733043,"url":"https://github.com/danielkov/agentkit","last_synced_at":"2026-05-04T00:02:48.531Z","repository":{"id":347006388,"uuid":"1184432997","full_name":"danielkov/agentkit","owner":"danielkov","description":"Rust toolkit for building LLM agent applications, e.g.: coding agents, assistant CLIs and multi-agent tools.","archived":false,"fork":false,"pushed_at":"2026-04-17T23:19:44.000Z","size":2856,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T01:29:19.873Z","etag":null,"topics":["ai","ai-agents","ai-agents-framework","llm-tools"],"latest_commit_sha":null,"homepage":"https://danielkov.github.io/agentkit/","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/danielkov.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-03-17T15:26:49.000Z","updated_at":"2026-04-17T23:19:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/danielkov/agentkit","commit_stats":null,"previous_names":["danielkov/agentkit"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/danielkov/agentkit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Fagentkit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Fagentkit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Fagentkit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Fagentkit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielkov","download_url":"https://codeload.github.com/danielkov/agentkit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielkov%2Fagentkit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32585045,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ai","ai-agents","ai-agents-framework","llm-tools"],"created_at":"2026-04-02T22:00:15.669Z","updated_at":"2026-05-04T00:02:48.525Z","avatar_url":"https://github.com/danielkov.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentkit\n\n`agentkit` is a Rust toolkit for building LLM agent applications such as coding agents, assistant CLIs, and multi-agent tools.\n\nThe project is intentionally split into small crates behind feature flags so hosts can pull in only the pieces they need.\n\n## Current status\n\n`agentkit` is past the design-only stage. The repo currently includes working implementations for:\n\n- normalized transcript, content-part, and delta types with fluent builders\n- a runtime-agnostic loop driver with blocking approval interrupts plus cooperative yields for end-of-turn input and between-tool-round interjection\n- federated tool sources behind a single `ToolSource` trait — frozen `ToolRegistry`s, dynamic catalogs, and MCP-backed sources compose by registration order, with collision policies and live `ToolCatalogChanged` events\n- trait-based tools, permissions, and approval handoff\n- a `TranscriptObserver` channel for loss-free transcript reconstruction (persistence, replication, audit) alongside the operational `LoopObserver` event stream\n- built-in filesystem, shell, and skills tools\n- context loading for `AGENTS.md` and skills directories\n- MCP integration on top of [`rmcp`](https://crates.io/crates/rmcp): stdio + Streamable HTTP transports, discovery, tool/resource/prompt adapters, auth replay, lifecycle management (connect / disconnect / refresh), pluggable sampling/elicitation/roots responders, and a broadcast subscription for server-pushed progress, logging, resource updates, list-changed, and cancellation events\n- reporting observers\n- compaction triggers, strategy pipelines, and backend-driven semantic compaction\n- async task management with foreground/background scheduling, routing policies, detach-after-timeout, and notification of background-tool completion through the loop event stream\n- optional turn cancellation with resumable sessions\n- prompt caching with automatic and explicit strategies, retention hints, and cache keys\n- a generic completions adapter base for building provider crates\n- provider adapters for OpenRouter, OpenAI, Anthropic, Cerebras, Ollama, vLLM, Groq, and Mistral\n\nThe repo also ships multiple examples that exercise these pieces end to end.\n\n## Crates\n\n- `agentkit-core`\n  - transcript, parts, deltas, IDs, usage, and cancellation primitives\n- `agentkit-capabilities`\n  - lower-level invocable/resource/prompt abstraction\n- `agentkit-tools-core`\n  - tools, registry, executor, permissions, approvals, auth requests\n- `agentkit-loop`\n  - model session abstraction, driver, interrupts, tool roundtrips\n- `agentkit-context`\n  - `AGENTS.md` and skills loading\n- `agentkit-mcp`\n  - MCP integration built on `rmcp`: stdio + Streamable HTTP transports, discovery, lifecycle, auth + replay, tool/resource/prompt adapters, sampling/elicitation/roots responders, and a server-event broadcast\n- `agentkit-reporting`\n  - loop observers and reporting adapters\n- `agentkit-compaction`\n  - compaction triggers, strategies, pipelines, backend hooks\n- `agentkit-task-manager`\n  - task scheduling for tool execution: foreground, background, and detach-after-timeout routing\n- `agentkit-tool-fs`\n  - filesystem tools\n- `agentkit-tool-shell`\n  - shell execution tool\n- `agentkit-tool-skills`\n  - progressive skill discovery and activation\n- `agentkit-http`\n  - HTTP transport abstraction (`HttpClient`, `Http`, `HttpRequestBuilder`) with a default reqwest-backed implementation and an optional `reqwest-middleware` adapter\n- `agentkit-adapter-completions`\n  - generic chat completions adapter base for building provider crates\n- `agentkit-provider-openrouter`\n  - OpenRouter adapter\n- `agentkit-provider-openai`\n  - OpenAI adapter\n- `agentkit-provider-anthropic`\n  - Anthropic Messages API adapter with streaming, prompt caching, extended thinking, and server-side tools (web search, web fetch, code execution)\n- `agentkit-provider-cerebras`\n  - Cerebras Inference API adapter with streaming, reasoning, strict JSON schema, compression (msgpack/gzip), predicted outputs, service tiers, and Files + Batch API\n- `agentkit-provider-ollama`\n  - Ollama adapter\n- `agentkit-provider-vllm`\n  - vLLM adapter\n- `agentkit-provider-groq`\n  - Groq adapter\n- `agentkit-provider-mistral`\n  - Mistral adapter\n- `agentkit`\n  - umbrella crate with feature-gated re-exports\n\n## Built-in tools today\n\nFilesystem:\n\n- `fs_read_file`\n  - supports optional `from` / `to` line ranges\n- `fs_write_file`\n- `fs_replace_in_file`\n- `fs_move`\n- `fs_delete`\n- `fs_list_directory`\n- `fs_create_directory`\n\nShell:\n\n- `shell_exec`\n\nThe filesystem crate also supports session-scoped read-before-write enforcement through `FileSystemToolResources` and `FileSystemToolPolicy`.\n\n## Quick start\n\n1. Set your OpenRouter API key and model — either through environment variables or directly in code via `OpenRouterConfig::new(api_key, model)`.\n2. Run one of the examples.\n\nExample commands:\n\n```bash\ncargo run -p openrouter-chat -- \"hello\"\n```\n\n```bash\ncargo run -p openrouter-coding-agent -- \\\n  \"Use fs_read_file on ./Cargo.toml and return only the workspace member count as an integer.\"\n```\n\n```bash\ncargo run -p openrouter-agent-cli -- --mcp-mock \\\n  \"Return only the secret from the MCP tool.\"\n```\n\n## Example progression\n\n- `openrouter-chat`\n  - minimal chat loop\n  - now supports `Ctrl-C` turn cancellation\n- `openrouter-coding-agent`\n  - one-shot coding-oriented prompt runner with filesystem tools\n- `openrouter-context-agent`\n  - context loading from `AGENTS.md` and skills\n- `openrouter-mcp-tool`\n  - MCP tool discovery and invocation\n- `openrouter-subagent-tool`\n  - custom tool that runs a nested agent\n- `openrouter-compaction-agent`\n  - structural, semantic, and hybrid compaction\n  - semantic compaction uses a nested agent as the backend\n- `openrouter-parallel-agent`\n  - async task manager with foreground fs tools and detach-after-timeout shell tools\n  - `TaskManagerHandle` event stream printed to stderr\n- `openrouter-agent-cli`\n  - combined example using context, tools, shell, MCP, compaction, and reporting\n- `anthropic-chat`\n  - streaming REPL against Anthropic's Messages API, with server tools\n    (`--web-search`, `--web-fetch`, `--code-exec`), extended thinking\n    (`--thinking`), and a streaming / buffered toggle (`--streaming` /\n    `--no-streaming`)\n- `cerebras-chat`\n  - interactive REPL against Cerebras `/v1/chat/completions`; CLI flags\n    cover every `CerebrasConfig` knob (sampling, reasoning, response\n    format, compression, service tier, predicted outputs, local tools)\n    and slash commands (`/show`, `/usage`, `/ratelimit`, `/headers`,\n    `/models`, `/reset`) surface runtime state\n- `cerebras-batch`\n  - one-shot CLI over the Cerebras Files + Batch APIs: `files upload|list|get|content|delete`,\n    `batches create|submit|list|get|cancel|wait`, and `run` to submit → wait → dump outputs\n\n## Examples\n\n### Minimal chat\n\nBuild an agent with a provider adapter and an opening user turn, then drive the loop:\n\n```rust\nuse agentkit_core::{Item, ItemKind};\nuse agentkit_loop::{\n    Agent, LoopInterrupt, LoopStep, PromptCacheRequest, PromptCacheRetention, SessionConfig,\n};\nuse agentkit_provider_openrouter::{OpenRouterAdapter, OpenRouterConfig};\n\nlet adapter = OpenRouterAdapter::new(\n    OpenRouterConfig::new(\"sk-or-v1-...\", \"openrouter/auto\")\n        .with_temperature(0.0),\n)?;\n\nlet agent = Agent::builder()\n    .model(adapter)\n    // Optional — preload a prior transcript (system prompt or resumed\n    // session) and the next user turn. Both default to empty.\n    .input(vec![Item::text(ItemKind::User, \"Hello!\")])\n    .build()?;\n\nlet mut driver = agent\n    .start(SessionConfig::new(\"chat\").with_cache(\n        PromptCacheRequest::automatic().with_retention(PromptCacheRetention::Short),\n    ))\n    .await?;\n\n// First next() dispatches the model directly because we preloaded input.\nmatch driver.next().await? {\n    LoopStep::Finished(result) =\u003e { /* render result.items */ }\n    LoopStep::Interrupt(LoopInterrupt::ApprovalRequest(pending)) =\u003e {\n        /* blocking: approve or deny via the PendingApproval handle */\n    }\n    LoopStep::Interrupt(LoopInterrupt::AwaitingInput(req)) =\u003e {\n        /* cooperative: req.submit(\u0026mut driver, more_items)? then call next() */\n    }\n    LoopStep::Interrupt(LoopInterrupt::AfterToolResult(_)) =\u003e { /* call next() to resume */ }\n}\n```\n\n`AgentBuilder::transcript` preloads the prior transcript as passive starting state — typically `[system_item]` for a fresh session, or a transcript loaded from disk when resuming. `AgentBuilder::input` preloads the next user turn into the driver's pending-input queue: when non-empty, the first `next()` dispatches the model directly; when left empty (the default for turn-based loops), the first `next()` yields `AwaitingInput` and every user turn flows through the `InputRequest` / `ToolRoundInfo` handles surfaced on the cooperative interrupts. There is no out-of-turn `submit_input` entry point.\n\n### Tools and permissions\n\nRegister filesystem tools with a path-scoped permission policy. Tool sources federate — call `add_tool_source` once per source (registry, MCP catalog reader, skill watcher, …) and the agent walks them in registration order:\n\n```rust\nuse agentkit_core::MetadataMap;\nuse agentkit_loop::Agent;\nuse agentkit_tools_core::{\n    CompositePermissionChecker, PathPolicy, PermissionCode, PermissionDecision, PermissionDenial,\n};\n\nlet permissions = CompositePermissionChecker::new(PermissionDecision::Deny(PermissionDenial {\n    code: PermissionCode::UnknownRequest,\n    message: \"not allowed by policy\".into(),\n    metadata: MetadataMap::new(),\n}))\n.with_policy(\n    PathPolicy::new()\n        .allow_root(std::env::current_dir()?)\n        .require_approval_outside_allowed(false),\n);\n\nlet agent = Agent::builder()\n    .model(adapter)\n    .add_tool_source(agentkit_tool_fs::registry())\n    .permissions(permissions)\n    .build()?;\n```\n\n### Reporting\n\nCompose multiple observers to log output, track usage, and record transcripts:\n\n```rust\nuse agentkit_reporting::{CompositeReporter, JsonlReporter, StdoutReporter, UsageReporter};\n\nlet reporter = CompositeReporter::new()\n    .with_observer(StdoutReporter::new(std::io::stderr()).with_usage(false))\n    .with_observer(JsonlReporter::new(Vec::new()))\n    .with_observer(UsageReporter::new());\n\nlet agent = Agent::builder()\n    .model(adapter)\n    .observer(reporter)\n    .build()?;\n```\n\n### Compaction\n\nConfigure structural compaction that drops reasoning and failed tool results, then keeps the most recent items:\n\n```rust\nuse agentkit_compaction::{\n    CompactionConfig, CompactionPipeline, DropFailedToolResultsStrategy,\n    DropReasoningStrategy, ItemCountTrigger, KeepRecentStrategy,\n};\nuse agentkit_core::ItemKind;\n\nlet compaction = CompactionConfig::new(\n    ItemCountTrigger::new(10),\n    CompactionPipeline::new()\n        .with_strategy(DropReasoningStrategy::new())\n        .with_strategy(DropFailedToolResultsStrategy::new())\n        .with_strategy(\n            KeepRecentStrategy::new(8)\n                .preserve_kind(ItemKind::System)\n                .preserve_kind(ItemKind::Context),\n        ),\n);\n\nlet agent = Agent::builder()\n    .model(adapter)\n    .compaction(compaction)\n    .build()?;\n```\n\n### Async task management\n\nRoute shell commands to background execution with automatic detach-after-timeout:\n\n```rust\nuse agentkit_task_manager::{AsyncTaskManager, RoutingDecision};\nuse std::time::Duration;\n\nlet task_manager = AsyncTaskManager::new().routing(|req: \u0026agentkit_tools_core::ToolRequest| {\n    if req.tool_name.0 == \"shell_exec\" {\n        RoutingDecision::ForegroundThenDetachAfter(Duration::from_secs(5))\n    } else {\n        RoutingDecision::Foreground\n    }\n});\n\nlet agent = Agent::builder()\n    .model(adapter)\n    .add_tool_source(tools)\n    .task_manager(task_manager)\n    .build()?;\n```\n\n## Feature flags\n\nThe umbrella crate re-exports subcrates behind feature flags.\n\nDefault flags:\n\n- `core`\n- `capabilities`\n- `tools`\n- `task-manager`\n- `loop`\n- `reporting`\n\nOptional flags:\n\n- `compaction`\n- `context`\n- `mcp`\n- `adapter-completions`\n- `provider-openrouter`\n- `provider-openai`\n- `provider-anthropic`\n- `provider-cerebras`\n- `provider-ollama`\n- `provider-vllm`\n- `provider-groq`\n- `provider-mistral`\n- `tool-fs`\n- `tool-shell`\n- `tool-skills`\n\nMore detail is in [docs/feature-flags.md](./docs/feature-flags.md).\n\n## Docs\n\n- [docs/getting-started.md](./docs/getting-started.md)\n- [docs/architecture.md](./docs/architecture.md)\n- [docs/core.md](./docs/core.md)\n- [docs/tools.md](./docs/tools.md)\n- [docs/loop.md](./docs/loop.md)\n- [docs/permissions.md](./docs/permissions.md)\n- [docs/capabilities.md](./docs/capabilities.md)\n- [docs/context.md](./docs/context.md)\n- [docs/mcp.md](./docs/mcp.md)\n- [docs/compaction.md](./docs/compaction.md)\n- [docs/reporting.md](./docs/reporting.md)\n- [docs/feature-flags.md](./docs/feature-flags.md)\n- [docs/README.md](./docs/README.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielkov%2Fagentkit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielkov%2Fagentkit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielkov%2Fagentkit/lists"}