rig-compose
Composable agent kernel: stateless skills, transport-agnostic tools, registry-driven agents, signal-routing coordinator. Companion crate for rig.
Overview
rig-compose is a domain-neutral composition layer for Rig-shaped agent systems. It provides the kernel traits and data structures for stateless skills, side-effectful tools, shared registries, generic agents, deterministic signal routing, workflows, in-process agent delegation, and optional YAML manifest loading.
The crate does not call an LLM itself and does not depend on rig-core; instead it defines the small tool and skill surfaces that companion crates such as rig-mcp and rig-resources plug into.
Why it exists
Rig supplies provider-agnostic model, embedding, vector-store, and tool traits. rig-compose fills a different gap: it organizes domain skills and tools into repeatable agent workflows without forcing those workflows to know whether a tool is local, delegated to another in-process agent, or surfaced through MCP.
This keeps downstream systems from reimplementing the same coordination pieces: Skill, Tool, ToolRegistry, SkillRegistry, GenericAgent, CoordinatorAgent, DelegateTool, and the budget guards used to meter finite work.
Status
- Crate version:
0.1.2. - Rust edition: 2024.
- MSRV: 1.88.
- Runtime stance: runtime-agnostic library;
tokiois used only as a dev-dependency for tests and examples. - Current Unreleased work adds the
budgetmodule, drop-safeTokenReservationrefunds, andKernelError::ToolNotApplicablefor soft tool failures.
Feature flags
| Feature | Default | Enables | Checked by just check |
|---|---|---|---|
| none | yes | Core agent, skill, tool, registry, workflow, delegate, coordinator, context, instruction, and budget APIs. | cargo clippy --all-targets, cargo test --all-targets |
manifest |
no | YAML-backed portable agent manifest types and materialization helpers from src/manifest.rs. Pulls serde_yaml. |
cargo clippy --all-targets --features manifest, cargo test --all-targets --features manifest, docs and examples with all features |
Key Types
- src/skill.rs:
Skill,SkillId, andSkillOutcome. Skills are stateless and decide whether they apply to anInvestigationContext. - src/tool.rs:
Tool,ToolSchema,ToolName, andLocalTool. Tools are the side-effectful async boundary. - src/registry.rs:
ToolRegistry,SkillRegistry, andKernelError. Registries hold shared tools and skills;ToolRegistry::scopedproduces per-agent tool views. - src/agent.rs:
Agent,AgentId,AgentStepResult,GenericAgent, andGenericAgentBuilder. Generic agents run registered skill chains over mutable investigation context. - src/context.rs:
InvestigationContext,Signal,Evidence, andNextAction. This is the shared state that skills read and enrich. - src/delegate.rs:
DelegateExecutor,DelegateRegistry,DelegateTool,DelegateName, andInProcessAgentDelegate. This is the model-driven agent-to-agent delegation path. - src/coordinator.rs:
CoordinatorAgent,CoordinatorBuilder, andRoutingRule. This is deterministic first-match routing for fixed topologies. - src/budget.rs:
BudgetGuard,TokenBudget,AtomicBudget,AtomicTokenBudget,TokenReservation,TokenRefund, andBudgetError. These meter rows, dispatch slots, and prompt-token reservations. - src/workflow.rs:
Workflow, the async workflow composition trait. - src/instructions.rs:
Instructions, a serializable instruction bundle with examples, response schema, and metadata. - src/manifest.rs:
AgentManifest,ModelSpec,ToolSpec,DelegateSpec, and materialization helpers, gated behindmanifest.
The crate-level architecture rule is simple: Skill is pure decision logic, Tool is the side-effect boundary, registries own lookup, and agents compose registered pieces without hard-coding concrete implementations.
Integration With Rig
rig-compose does not pin rig-core in Cargo.toml. It is intentionally Rig-shaped rather than Rig-bound: other crates can adapt Rig tools, MCP tools, local closures, or in-process delegates into the same Tool and Skill flow.
The main companion integration points are:
rig-mcpimplements remote MCP access by adapting MCP endpoints intorig_compose::Toolvalues.rig-resourcesprovides reusable skills and tools that implementrig-composetraits.- Downstream systems such as Azrael can use
BudgetGuardandTokenBudgetto enforce compute budgets around agent dispatch and LLM token use.
Usage
The minimal runnable example is examples/basic_agent.rs. It registers one stateless skill, builds a GenericAgent, and runs that agent against an InvestigationContext.
use Arc;
use async_trait;
use ;
;
# async
The budget behavior is covered by the unit tests in src/budget.rs, including reservation reconciliation and drop-time refunds.
Validation
Canonical validation is just check.
That recipe runs formatter checks, clippy and tests for default features and manifest, rustdoc with -D warnings -D rustdoc::broken_intra_doc_links, and cargo build --examples --all-features.
Gotchas
DelegateToolandCoordinatorAgentsolve different routing problems. UseDelegateToolwhen the model should decide whether to call another agent; useCoordinatorAgentfor fixed host-driven signal routing.KernelError::ToolNotApplicableis a soft failure for tools that cannot apply to the current context. Callers may treat it as a no-op, asrig-resourcesdoes for missing graph entities.TokenReservationrefunds its estimate on drop unlessAtomicTokenBudget::record_usagedisarms it. Keep the handle alive until actual usage is recorded.- The library is runtime-agnostic. Do not add runtime dependencies to
[dependencies]; tests and examples usetokiofrom[dev-dependencies].
Ecosystem
These companion crates are maintained as separate repositories. Together they form a small stack around the upstream Rig project: rig-compose provides the kernel surface, rig-resources contributes reusable skills and tools, rig-mcp moves tools across MCP, rig-memvid connects Rig agents to persistent .mv2 memory, and rig-ballista reserves the metadata-catalog seam for future query-engine integration.
flowchart TD
rig["rig / rig-core"]
compose["rig-compose 0.1.x"]
resources["rig-resources 0.1.x"]
mcp["rig-mcp 0.1.x"]
memvid["rig-memvid 0.1.x"]
ballista["rig-ballista 0.1.x"]
compose -. "Rig-shaped kernel; no direct rig-core dep" .-> rig
resources -- "rig-compose = 0.1; features: security, graph, full" --> compose
mcp -- "rig-compose = 0.1; rmcp stdio bridge" --> compose
memvid -- "rig-core = 0.36.0; features: lex, vec, api_embed, temporal, encryption" --> rig
ballista -. "planned rig-compose catalog integration; no direct dep today" .-> compose
Pinned Rig-facing dependencies from the current manifests:
| Crate | Direct Rig-facing dependency | Notes |
|---|---|---|
rig-compose |
none | Defines a Rig-shaped kernel surface without depending on rig-core. |
rig-resources |
rig-compose = 0.1 |
Uses a sibling path during local workspace development. |
rig-mcp |
rig-compose = 0.1 |
Uses a sibling path during local workspace development. |
rig-memvid |
rig-core = 0.36.0 |
Implements Rig vector-store and prompt-hook flows over Memvid. |
rig-ballista |
none today | Ballista/Iceberg/DataFusion dependencies remain planned and commented out. |
The concrete multi-crate workflow tested today is the MCP loopback path: a rig_compose::ToolRegistry is exposed through rig_mcp::LoopbackTransport, remote schemas are wrapped as rig_mcp::McpTool, and the wrapped tools are registered back into another ToolRegistry. That proves a local rig-compose tool and an MCP-adapted tool are indistinguishable to callers. The backing test is mcp_tool_indistinguishable_from_local in rig-mcp/src/transport.rs.
License
Licensed under either Apache-2.0 or MIT, at your option.