AgentBuilder & Capabilities
AgentBuilder is a composition layer that assembles an AgentLoop from pluggable capabilities. Each capability (Use* class) installs tools, hooks, drivers, or compilers into the builder. The result is a configured AgentLoop ready for execution.
Why AgentBuilder
AgentLoop is a stateless execution engine with sensible defaults. You can use it directly for simple agents. But as you add guards, custom tools, hooks, and compilers, manual setup becomes verbose and error-prone.
AgentBuilder solves this by letting you compose features as independent, reusable modules:
Core API
AgentBuilder exposes two interfaces:
CanComposeAgentLoop (user-facing):
CanConfigureAgent (capability-facing):
Writing a Capability
ImplementCanProvideAgentCapability with capabilityName() and configure():
What a Capability Can Do
A capability receives aCanConfigureAgent instance and returns a modified copy. The five configuration surfaces are:
| Surface | Method | Typical Use |
|---|---|---|
| Tools | withTools() | Add tool instances to the agent |
| Hooks | withHooks() | Register lifecycle hooks (guards, logging, state transforms) |
| Driver | withToolUseDriver() | Replace or wrap the tool-use driver |
| Compiler | withContextCompiler() | Replace or wrap the message compiler |
| Deferred tools | withDeferredTools() | Register tools resolved at build() time |
Adding Tools
The most common pattern — merge new tools into the existing set:Adding Hooks
Register a hook with trigger types and priority:Deferred Tools
Some tools need access to the final driver or event bus, which aren’t available untilbuild() runs. Use CanProvideDeferredTools to defer tool creation:
UseSubagents uses this pattern — the SpawnSubagentTool needs the parent’s driver and event bus, which are only finalized at build time.
Multi-Concern Capabilities
A single capability can install multiple components. For example, a capability might add a tool, register a persistence hook, and set a response format — all in oneconfigure() call:
Capability Names
capabilityName() returns a unique string identifier (e.g., 'use_bash'). This is used by the AgentCapabilityRegistry and agent templates to reference capabilities by name. See Agent Templates for how definitions reference capabilities.
Built-in Capabilities
Core Primitives
| Capability | Purpose |
|---|---|
UseGuards | Step, token, time, and finish-reason guards |
UseLLMConfig | LLM provider preset and retry policy |
UseContextConfig | System prompt and response format |
UseDriver | Custom driver implementation |
UseTools | Individual tool instances |
UseHook | Single hook with trigger and priority |
UseContextCompiler | Custom message compiler |
UseContextCompilerDecorator | Wrap the existing compiler |
UseDriverDecorator | Wrap the existing driver |
UseToolFactory | Deferred tool creation (runs at build() time) |
Domain Capabilities
| Capability | What It Installs |
|---|---|
UseBash | Bash command execution tool (with sandbox policy) |
UseFileTools | File read/write/edit tools (scoped to a base directory) |
UseSubagents | Subagent spawning tool with depth control |
UseStructuredOutputs | Schema-based data extraction tool + persistence hook |
UseSummarization | Message-to-buffer and buffer summarization hooks |
UseSelfCritique | Self-critique loop hook |
UseSkills | Skill injection for subagents |
UseTaskPlanning | Task planning tool |
UseMetadataTools | Metadata read/write tools |
UseToolRegistry | Dynamic tool registration |
Capability Examples
Minimal agent (no tools)
File system agent with guards
Agent with custom hook
Custom context compiler
Build Resolution Order
Whenbuild() is called, components are resolved in order:
- Compiler - configured compiler channel
- Driver - configured driver channel, then compiler/events are rebound
- Tools - configured tools merged with deferred tool providers (resolved with tools+driver+events context)
- Interceptor - derived from configured hooks (
HookStack), or pass-through when no hooks
UseSubagents).
Hook Priority Convention
| Range | Purpose |
|---|---|
| 200+ | Guards (steps, tokens, time) |
| 100 | Context preparation, security checks |
| 0 | Default (business logic) |
| -50 | Persistence, logging |
| -200 | Deferred processing (summarization, buffer management) |
Events and Logging
Pass a parent event handler toAgentBuilder::base() for event propagation:
Immutability
withCapability() returns a new builder instance. This means you can safely branch from a base configuration:
Builder Internals
AgentBuilder is a thin facade. The actual assembly happens in AgentConfigurator, an internal class that accumulates configuration and resolves it into an AgentLoop.
capability.configure(configurator) call returns a new AgentConfigurator with the applied changes. When all capabilities are installed, toAgentLoop() runs the resolution pipeline and produces the final AgentLoop.
See Also
- Agent Templates — define agents as data files and reference capabilities by name
- Subagents — task delegation via
UseSubagents