everruns_core/tool_hooks.rs
1//! Neutral contracts for capability-contributed per-tool execution hooks.
2
3use crate::tool_context::ToolContext;
4use async_trait::async_trait;
5use everruns_provider::tool_types::{ToolCall, ToolDefinition, ToolResult};
6
7/// Decision returned by a [`PreToolUseHook`] before a tool is dispatched.
8#[derive(Debug, Clone)]
9pub enum PreToolUseDecision {
10 /// Continue with the possibly transformed call.
11 Continue(ToolCall),
12 /// Block this call without affecting sibling calls in the batch.
13 Block {
14 /// Call that was blocked.
15 tool_call: ToolCall,
16 /// Error text recorded for the model and audit stream.
17 reason: String,
18 /// Optional message for a user-facing runtime.
19 user_message: Option<String>,
20 },
21}
22
23/// Capability hook invoked before each individual tool execution.
24#[async_trait]
25pub trait PreToolUseHook: Send + Sync {
26 /// Transform or block a tool call before dispatch.
27 async fn before_exec(
28 &self,
29 tool_call: ToolCall,
30 tool_def: &ToolDefinition,
31 context: &ToolContext,
32 ) -> PreToolUseDecision;
33}
34
35/// Ordering for capability-contributed post-tool hooks.
36#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
37pub enum PostToolExecHookPriority {
38 /// Inspect or block output before normal mutating hooks.
39 Guardrail = 0,
40 /// Default ordering for transformation and observability hooks.
41 Normal = 100,
42}
43
44/// Capability hook invoked after each individual tool execution.
45#[async_trait]
46pub trait PostToolExecHook: Send + Sync {
47 /// Ordering within the capability-contributed hook phase.
48 fn priority(&self) -> PostToolExecHookPriority {
49 PostToolExecHookPriority::Normal
50 }
51
52 /// Inspect or transform one tool result before engine event emission.
53 async fn after_exec(
54 &self,
55 tool_call: &ToolCall,
56 tool_def: &ToolDefinition,
57 result: &mut ToolResult,
58 context: &ToolContext,
59 );
60}