Skip to main content

walrus_daemon/hook/
mod.rs

1//! Stateful Hook implementation for the daemon.
2//!
3//! [`DaemonHook`] composes memory, skill, and MCP sub-hooks.
4//! `on_build_agent` delegates to skills and memory; `on_register_tools`
5//! delegates to memory and MCP sub-hooks in sequence.
6
7use crate::hook::skill::SkillHandler;
8use mcp::McpHandler;
9use memory::InMemory;
10use wcore::{AgentConfig, AgentEvent, Hook, ToolRegistry};
11
12pub mod mcp;
13pub mod skill;
14
15/// Stateful Hook implementation for the daemon.
16///
17/// Composes memory, skill, and MCP sub-hooks. Each sub-hook
18/// self-registers its tools via `on_register_tools`.
19pub struct DaemonHook {
20    pub memory: InMemory,
21    pub skills: SkillHandler,
22    pub mcp: McpHandler,
23}
24
25impl DaemonHook {
26    /// Create a new DaemonHook with the given backends.
27    pub fn new(memory: InMemory, skills: SkillHandler, mcp: McpHandler) -> Self {
28        Self {
29            memory,
30            skills,
31            mcp,
32        }
33    }
34}
35
36impl Hook for DaemonHook {
37    fn on_build_agent(&self, config: AgentConfig) -> AgentConfig {
38        let config = self.skills.on_build_agent(config);
39        self.memory.on_build_agent(config)
40    }
41
42    async fn on_register_tools(&self, tools: &mut ToolRegistry) {
43        self.memory.on_register_tools(tools).await;
44        self.mcp.on_register_tools(tools).await
45    }
46
47    fn on_event(&self, agent: &str, event: &AgentEvent) {
48        match event {
49            AgentEvent::TextDelta(text) => {
50                tracing::trace!(%agent, text_len = text.len(), "agent text delta");
51            }
52            AgentEvent::ToolCallsStart(calls) => {
53                tracing::debug!(%agent, count = calls.len(), "agent tool calls started");
54            }
55            AgentEvent::ToolResult { call_id, .. } => {
56                tracing::debug!(%agent, %call_id, "agent tool result");
57            }
58            AgentEvent::ToolCallsComplete => {
59                tracing::debug!(%agent, "agent tool calls complete");
60            }
61            AgentEvent::Done(response) => {
62                tracing::info!(
63                    %agent,
64                    iterations = response.iterations,
65                    stop_reason = ?response.stop_reason,
66                    "agent run complete"
67                );
68            }
69        }
70    }
71}