agent-works
Batteries-included Agent toolbox built on agent-base.
agent-works adds production-ready capabilities on top of the agent-base runtime kernel: loop guards for model misbehavior, MCP multi-server management, Skills with progressive disclosure, a Focus module for structured LLM extraction, multi-agent orchestration with fork_history, and a CLI REPL loop — all behind feature flags. Pick what you need.
Relationship with agent-base
agent-base Pure runtime kernel (~12 deps, trait interfaces only)
↑
agent-works Batteries-included toolbox (wraps agent-base + enhancements)
- Use
agent-basealone when you only need the runtime (LLM + tools + middleware). - Use
agent-workswhen you want MCP, Skills, Focus, multi-agent, and CLI — and still get everything from agent-base through re-exports. - Switching from
agent-basetoagent-worksis a one-line import change.
Installation
[]
= { = "0.1.7", = ["full"] }
Or pick specific features:
= { = "0.1.7", = ["mcp", "skill"] }
Feature Flags
| Feature | Description | Extra deps |
|---|---|---|
mcp |
McpHUb — multi-server MCP with HTTP + stdio transport |
— |
skill |
Skill trait + LazySkillPrompter / FullDetailPrompter + SkillDetailTool + SkillLoader |
— |
prompt_skill |
PromptSkill — skill definitions from prompt files |
serde_yaml |
yaml_skill |
YamlSkill — skill definitions from YAML files |
serde_yaml |
hot-reload |
Hot-reload skill definitions on file change | notify, prompt_skill |
cli |
CliRepl (generic REPL loop) + CliEventPrinter (terminal event output) |
— |
full |
All of the above | — |
All types from agent-base are re-exported (AgentBuilder, AgentRuntime, Tool, Middleware, ...), so you only need to depend on agent-works.
Quick Start
Skills
Skills package tools + descriptions into reusable units with progressive disclosure:
use Arc;
use ;
use ;
use async_trait;
use ;
// 1. Define tools
;
// 2. Pack into a Skill
;
// 3. Build with agent-works AgentBuilder
let runtime = new
.system_prompt
.register_skill // auto-registers tools, injects prompt, adds detail tool
.build?;
The builder automatically:
- Registers skill tools and detects name conflicts
- Injects skill brief descriptions into the system prompt (via
LazySkillPrompter) - Registers
SkillDetailToolfor on-demand detailed prompt loading
Focus — Structured LLM Extraction
Focus provides a clean API for extracting structured data from LLM responses:
use Arc;
use Duration;
use Focus;
use Deserialize;
let focus = new;
let output = focus
.
.await?;
println!;
Multi-Agent with fork_history
Spawn child agents that inherit conversation context:
use ;
let mut runtime = new;
// Spawn a child agent with full parent history
let child_id = runtime
.spawn_child_with_history
.await?;
// Send a message and collect the result
let events = runtime.send_input.await?;
AgentHandle provides a higher-level wrapper for agent lifecycle management:
use AgentHandle;
let handle = spawn?;
handle.send.await?;
// Events stream from handle.events()
MCP Multi-Server
use *;
let mut hub = new;
hub.add_server;
hub.connect_all.await?;
// Discover tools from all servers
let all_tools = hub.discover_all.await?;
// Register into the agent runtime
let mut tools = runtime.tools_mut;
hub.register_all;
CLI REPL
use ;
// Default (stdout)
let mut printer = new;
// Or capture output for testing
let mut printer = with_writer;
let mut repl = new;
// Register custom shell commands
repl.register_shell_command;
repl.run.await?;
Tool Enforcement
The ToolEnforcementMiddleware (inherited from agent-base) nudges the LLM to actually call tools instead of just describing what it would do:
use ToolEnforcementMiddleware;
use ToolEnforcementConfig;
let runtime = new
.register_tool
.middleware
.build?;
Guard — Loop Protection
Guards protect the agent loop from model misbehavior (reasoning-only responses, empty responses, incomplete answers). Without a guard the runtime still works; with one it's smarter.
use ;
// No guard — NoopGuard injected automatically, no intervention
let runtime = new.build?;
// DefaultGuard with defaults — handles reasoning_only, empty_response, text_only
let runtime = new
.guard
.build?;
// DefaultGuard with LLM judge — verifies task completion on text-only responses
let config = DefaultGuardConfig ;
let runtime = new
.guard
.build?;
Custom guards implement the ReactLoopGuard trait:
use ;
;
Examples
# Guard system — DefaultGuard, NoopGuard, custom guards
# Skills with progressive disclosure
# MCP multi-server connection
# CLI REPL + event printer
Module Structure
src/
├── lib.rs # Re-exports agent-base + feature-gated modules
├── builder.rs # AgentBuilder wrapper with skill integration
├── handle.rs # AgentHandle — high-level agent lifecycle
├── guard/ # DefaultGuard + ReactLoopGuard trait
├── mcp/ # McpHUb + McpClient (HTTP + stdio transport)
├── skill/ # Skill trait + prompter strategies + detail tool
├── focus/ # Focus — structured LLM extraction
├── multi_agent/ # MultiAgentRuntime + fork_history support
└── cli/ # CliRepl + CliEventPrinter<W>
License
MIT