walrus_runtime/hook.rs
1//! Hook trait — stateful runtime backend.
2//!
3//! Hook is the single abstraction that Runtime delegates all backend concerns
4//! to: model access, tool dispatch, prompt enrichment, and event observation.
5//! Implementations own the concrete backends (model provider, memory, MCP,
6//! tool registry, skill registry).
7
8use anyhow::Result;
9use std::future::Future;
10use wcore::AgentConfig;
11use wcore::AgentEvent;
12use wcore::model::{Model, Tool};
13
14/// Stateful runtime backend.
15///
16/// Owns the model provider, tool registry, skill registry, MCP bridge, and
17/// any other backend state. Runtime holds `Arc<H>` and delegates through
18/// these methods.
19pub trait Hook: Send + Sync {
20 /// The model provider for this hook.
21 type Model: Model + Send + Sync;
22
23 /// Access the model provider.
24 fn model(&self) -> &Self::Model;
25
26 /// Return tool schemas available to the named agent.
27 fn tools(&self, agent: &str) -> Vec<Tool>;
28
29 /// Dispatch tool calls for the named agent.
30 ///
31 /// Each entry in `calls` is `(method_name, params_json)`. Returns one
32 /// result per call in the same order.
33 fn dispatch(
34 &self,
35 agent: &str,
36 calls: &[(&str, &str)],
37 ) -> impl Future<Output = Vec<Result<String>>> + Send;
38
39 /// Build an enriched system prompt for the given agent config.
40 ///
41 /// Default implementation returns the config's system prompt unchanged.
42 /// Override to inject skills, MCP context, or other prompt augmentation.
43 fn enrich_prompt(&self, config: &AgentConfig) -> String {
44 config.system_prompt.clone()
45 }
46
47 /// Called when an agent emits an event during execution.
48 ///
49 /// Default is a no-op.
50 fn on_event(&self, _event: &AgentEvent) {}
51}
52
53impl Hook for () {
54 type Model = ();
55
56 fn model(&self) -> &() {
57 &()
58 }
59
60 fn tools(&self, _agent: &str) -> Vec<Tool> {
61 vec![]
62 }
63
64 fn dispatch(
65 &self,
66 _agent: &str,
67 calls: &[(&str, &str)],
68 ) -> impl Future<Output = Vec<Result<String>>> + Send {
69 let len = calls.len();
70 async move { (0..len).map(|_| Ok(String::new())).collect() }
71 }
72}