Skip to main content

HookHandler

Trait HookHandler 

pub trait HookHandler: Send + Sync {
Show 21 methods // Required method fn name(&self) -> &str; // Provided methods fn priority(&self) -> i32 { ... } fn on_gateway_start<'life0, 'life1, 'async_trait>( &'life0 self, _host: &'life1 str, _port: u16, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait { ... } fn on_gateway_stop<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn on_session_start<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _session_id: &'life1 str, _channel: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn on_session_end<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _session_id: &'life1 str, _channel: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn on_llm_input<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _messages: &'life1 [ChatMessage], _model: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn on_llm_output<'life0, 'life1, 'async_trait>( &'life0 self, _response: &'life1 ChatResponse, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait { ... } fn on_after_tool_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _tool: &'life1 str, _result: &'life2 ToolResult, _duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn on_after_tool_call_with_context<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, tool: &'life2 str, result: &'life3 ToolResult, duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait { ... } fn on_after_tool_call_with_context_and_args<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, context: &'life1 ToolCallHookContext, tool: &'life2 str, _args: &'life3 Value, result: &'life4 ToolResult, duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait { ... } fn on_tool_call_abandoned<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, _tool: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn on_message_sent<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _channel: &'life1 str, _recipient: &'life2 str, _content: &'life3 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait { ... } fn on_heartbeat_tick<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn before_model_resolve<'life0, 'async_trait>( &'life0 self, model_provider: String, model: String, ) -> Pin<Box<dyn Future<Output = HookResult<(String, String)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn before_prompt_build<'life0, 'async_trait>( &'life0 self, prompt: String, ) -> Pin<Box<dyn Future<Output = HookResult<String>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn before_llm_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _messages: &'life1 mut Vec<ChatMessage>, _model: &'life2 mut String, ) -> Pin<Box<dyn Future<Output = HookResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn before_tool_call<'life0, 'async_trait>( &'life0 self, name: String, args: Value, ) -> Pin<Box<dyn Future<Output = HookResult<(String, Value)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn before_tool_call_with_context<'life0, 'life1, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, name: String, args: Value, ) -> Pin<Box<dyn Future<Output = HookResult<(String, Value)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait { ... } fn on_message_received<'life0, 'async_trait>( &'life0 self, message: ChannelMessage, ) -> Pin<Box<dyn Future<Output = HookResult<ChannelMessage>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... } fn on_message_sending<'life0, 'async_trait>( &'life0 self, channel: String, recipient: String, content: String, ) -> Pin<Box<dyn Future<Output = HookResult<(String, String, String)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait { ... }
}
Expand description

Trait for hook handlers. All methods have default no-op implementations. Implement only the events you care about.

Required Methods§

Source

fn name(&self) -> &str

Provided Methods§

Source

fn priority(&self) -> i32

Source

fn on_gateway_start<'life0, 'life1, 'async_trait>( &'life0 self, _host: &'life1 str, _port: u16, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source

fn on_gateway_stop<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn on_session_start<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _session_id: &'life1 str, _channel: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn on_session_end<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _session_id: &'life1 str, _channel: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn on_llm_input<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _messages: &'life1 [ChatMessage], _model: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn on_llm_output<'life0, 'life1, 'async_trait>( &'life0 self, _response: &'life1 ChatResponse, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Source

fn on_after_tool_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _tool: &'life1 str, _result: &'life2 ToolResult, _duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn on_after_tool_call_with_context<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, tool: &'life2 str, result: &'life3 ToolResult, duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Observe tool completion with explicit correlation context.

When context.is_correlated() is false, handlers must not use its phase-local identity to pair callbacks or retain attributed state.

Source

fn on_after_tool_call_with_context_and_args<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, context: &'life1 ToolCallHookContext, tool: &'life2 str, _args: &'life3 Value, result: &'life4 ToolResult, duration: Duration, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Observe tool completion with explicit correlation context and the arguments that were actually dispatched.

Runners that know the final prepared arguments dispatch this variant instead of HookHandler::on_after_tool_call_with_context; the default delegates there, dropping the arguments. Handlers that audit arguments should override this variant so their export reflects what was dispatched — and so they never need to retain arguments between the before and after phases.

Source

fn on_tool_call_abandoned<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, _tool: &'life2 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Observe that a tool-call context will never reach its after phase.

Fired exactly once per correlated context whose before phase ran, when the call cannot complete: the before hook chain cancelled it, approval denied or replaced it, duplicate suppression skipped it, or execution failed or was interrupted before post-execution handling. Abandonment is NOT execution completion — handlers must never synthesize a tool result from it.

Best-effort by nature: the runner dispatches abandonment on every awaited non-completion path, but a turn future dropped outright (an outer timeout, outer cancellation, or hard task abort) cannot run any async callback, abandonment included. Handlers must therefore avoid retaining safety-critical state between the before and after phases in the first place, and treat abandonment as a best-effort release signal rather than a guarantee.

Source

fn on_message_sent<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _channel: &'life1 str, _recipient: &'life2 str, _content: &'life3 str, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Source

fn on_heartbeat_tick<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn before_model_resolve<'life0, 'async_trait>( &'life0 self, model_provider: String, model: String, ) -> Pin<Box<dyn Future<Output = HookResult<(String, String)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn before_prompt_build<'life0, 'async_trait>( &'life0 self, prompt: String, ) -> Pin<Box<dyn Future<Output = HookResult<String>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn before_llm_call<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _messages: &'life1 mut Vec<ChatMessage>, _model: &'life2 mut String, ) -> Pin<Box<dyn Future<Output = HookResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Source

fn before_tool_call<'life0, 'async_trait>( &'life0 self, name: String, args: Value, ) -> Pin<Box<dyn Future<Output = HookResult<(String, Value)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn before_tool_call_with_context<'life0, 'life1, 'async_trait>( &'life0 self, _context: &'life1 ToolCallHookContext, name: String, args: Value, ) -> Pin<Box<dyn Future<Output = HookResult<(String, Value)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Inspect or modify a tool call with explicit correlation context.

When context.is_correlated() is false, handlers must not retain state that assumes the after phase will receive the same identity.

Source

fn on_message_received<'life0, 'async_trait>( &'life0 self, message: ChannelMessage, ) -> Pin<Box<dyn Future<Output = HookResult<ChannelMessage>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Source

fn on_message_sending<'life0, 'async_trait>( &'life0 self, channel: String, recipient: String, content: String, ) -> Pin<Box<dyn Future<Output = HookResult<(String, String, String)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§