Hooks
The Hook trait — compose agent behaviors by registering tools, enriching configs, and observing events.
Hooks let you inject behavior into the agent lifecycle without modifying agents directly. They're the primary extension point in OpenWalrus — both in-process hooks and external extensions implement the same lifecycle callbacks.
The Hook trait
trait Hook: Send + Sync {
fn on_build_agent(&self, config: AgentConfig) -> AgentConfig;
fn on_register_tools(&self, registry: &mut ToolRegistry);
fn on_event(&self, agent: &str, event: &AgentEvent);
fn on_compact(&self, prompt: &mut String);
}All methods have default no-op implementations. You only override what you need.
| Method | When it runs | What it does |
|---|---|---|
on_build_agent | Agent is created | Enrich config, inject system prompt extensions |
on_register_tools | Runtime is constructed | Add tool schemas to the registry |
on_event | Every agent event | Observe text deltas, tool calls, completions |
on_compact | Context compaction | Enrich the compaction prompt |
In-process hooks
The daemon composes several hooks into DaemonHook:
| Hook | Tools registered | Purpose |
|---|---|---|
SkillHandler | search_skill, load_skill | Skill discovery |
McpHandler | search_mcp, call_mcp_tool | MCP integration |
OsHook | read, write, edit, bash | Filesystem and shell |
TaskRegistry | delegate, collect | Context isolation |
External extensions
Memory, search, and other capabilities run as external extensions. They communicate over protobuf and implement the same lifecycle callbacks (BuildAgent, BeforeRun, Compact, EventObserver, AfterRun, Infer, AfterCompact) via the Walrus Extension Protocol.
| Service | Tools | Capabilities |
|---|---|---|
| Search | web_search | Tools |
Third-party extensions use the same protocol as official ones — the daemon treats all extensions equally.
DaemonHook composition
DaemonHook is the central composition point. It holds in-process hooks plus the service registry for external extensions:
| Field | Type | Description |
|---|---|---|
skills | SkillHandler | Skill registry and loader |
mcp | McpHandler | MCP server bridge |
tasks | Arc<Mutex<TaskRegistry>> | Agent delegation registry |
downloads | Arc<Mutex<DownloadRegistry>> | Hub download tracker |
permissions | PermissionConfig | Per-tool permission rules |
scopes | BTreeMap | Per-agent tool whitelists |
registry | Option<ServiceRegistry> | External extension handles |
Tool dispatch
When an agent invokes a tool, DaemonHook::dispatch_tool routes it:
- Permission check — resolves Allow/Ask/Deny
- Scope check — verifies the tool is in the agent's whitelist
- Route by name — dispatches to the correct handler:
| Tools | Handler |
|---|---|
read, write, edit, bash | OS (in-process) |
search_skill, load_skill | Skills (in-process) |
search_mcp, call_mcp_tool | MCP (in-process) |
delegate, collect | Tasks (in-process) |
| Tools registered by extensions | ServiceRegistry (external) |
| Unknown tools | Forwarded to MCP bridge (fallback) |
What's next
- Agents — how agents are configured and scoped
- Built-in tools — OsHook details
- Tasks — context isolation via delegate and collect
- Extensions — external extension architecture