# agentkit
Feature-gated umbrella crate for assembling agent applications from the workspace crates.
By default this crate re-exports the core runtime pieces:
- `core` -- shared types: `Item`, `Part`, `SessionId`, `Usage`, cancellation primitives
- `capabilities` -- capability traits: `Invocable`, `CapabilityProvider`, `PermissionChecker`
- `tools` -- tool abstractions: `Tool`, `ToolRegistry`, `ToolSpec`, permission types
- `loop` -- agent loop orchestration: `Agent`, `AgentBuilder`, `LoopDriver`, `LoopStep`
- `reporting` -- loop observers: `StdoutReporter`, `JsonlReporter`, `UsageReporter`, `CompositeReporter`
Additional integrations are available behind optional Cargo features:
| `compaction` | `agentkit-compaction` | Transcript compaction triggers, strategies, and pipelines |
| `context` | `agentkit-context` | `AGENTS.md` discovery and loading |
| `mcp` | `agentkit-mcp` | Model Context Protocol server connections |
| `provider-openrouter` | `agentkit-provider-openrouter` | OpenRouter `ModelAdapter` implementation |
| `tool-fs` | `agentkit-tool-fs` | Filesystem tools (read, write, edit, move, delete, list, mkdir) |
| `tool-shell` | `agentkit-tool-shell` | Shell execution tool (`shell.exec`) |
| `tool-skills` | `agentkit-tool-skills` | Progressive Agent Skills discovery and activation |
## Quick start
Add agentkit with the features you need:
```toml
[dependencies]
agentkit = { version = "0.2", features = ["provider-openrouter", "tool-fs", "tool-shell"] }
tokio = { version = "1", features = ["full"] }
```
## Examples
### Minimal agent with OpenRouter
```rust,no_run
use agentkit::core::{Item, ItemKind};
use agentkit::loop_::{
Agent, LoopStep, PromptCacheRequest, PromptCacheRetention, SessionConfig,
};
use agentkit::provider_openrouter::{OpenRouterAdapter, OpenRouterConfig};
use agentkit::reporting::StdoutReporter;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = OpenRouterConfig::from_env()?;
let adapter = OpenRouterAdapter::new(config)?;
let agent = Agent::builder()
.model(adapter)
.observer(StdoutReporter::new(std::io::stdout()))
.build()?;
let mut driver = agent
.start(
SessionConfig::new("demo").with_cache(
PromptCacheRequest::automatic().with_retention(PromptCacheRetention::Short),
),
)
.await?;
// Submit a user message and drive the loop to completion.
driver.submit_input(vec![Item::text(
ItemKind::User,
"What is the capital of France?",
)])?;
loop {
match driver.next().await? {
LoopStep::Finished(result) => {
println!("Turn finished: {:?}", result.finish_reason);
break;
}
LoopStep::Interrupt(interrupt) => match interrupt {
agentkit::loop_::LoopInterrupt::ApprovalRequest(req) => {
// Auto-approve for this demo; a real app would prompt the user.
driver.resolve_approval(req.id, true)?;
}
agentkit::loop_::LoopInterrupt::AuthRequest(req) => {
eprintln!("Auth required: {}", req.provider);
break;
}
agentkit::loop_::LoopInterrupt::AwaitingInput(_) => {
// Feed the next user message and continue the loop.
break;
}
},
}
}
Ok(())
}
```
### Agent with filesystem and shell tools
```rust,no_run
use agentkit::loop_::{Agent, PromptCacheRequest, PromptCacheRetention, SessionConfig};
use agentkit::reporting::{CompositeReporter, StdoutReporter, UsageReporter};
use agentkit::provider_openrouter::{OpenRouterAdapter, OpenRouterConfig};
use agentkit::tools::ToolRegistry;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let adapter = OpenRouterAdapter::new(OpenRouterConfig::from_env()?)?;
// Build a tool registry with filesystem and shell tools.
let mut tools = agentkit::tool_fs::registry();
for tool in agentkit::tool_shell::registry().tools() {
tools.register_arc(tool);
}
let agent = Agent::builder()
.model(adapter)
.tools(tools)
.observer(StdoutReporter::new(std::io::stdout()))
.build()?;
let _driver = agent
.start(
SessionConfig::new("coding-agent").with_cache(
PromptCacheRequest::automatic().with_retention(PromptCacheRetention::Short),
),
)
.await?;
Ok(())
}
```
### Default features only (no provider)
When writing a custom `ModelAdapter`, only the default features are needed:
```rust,ignore
use agentkit::core::{Item, SessionId};
use agentkit::loop_::{Agent, ModelAdapter, SessionConfig};
use agentkit::tools::ToolRegistry;
use agentkit::reporting::StdoutReporter;
// Implement ModelAdapter for your own backend, then:
// let agent = Agent::builder().model(my_adapter).build()?;
```