lc_agents/hooks/approval.rs
1// lc-agents/src/hooks/approval.rs
2//! ApprovalHook — blocks tool calls until the user approves them.
3//!
4//! Implements human-in-the-loop by requiring explicit approval before
5//! each tool call. Useful for dangerous or expensive operations.
6
7use async_trait::async_trait;
8
9use super::{AgentHook, ToolCallAction, ToolCallContext};
10
11/// A hook that requires user approval before each tool call.
12///
13/// When `on_before_tool_call` is invoked, it always returns `ToolCallAction::Reject`
14/// with a message indicating approval is needed. In a real application, this
15/// would block on user input (e.g., via a channel or callback).
16///
17/// # Example
18///
19/// ```rust,ignore
20/// use lc_agents::hooks::ApprovalHook;
21///
22/// let hook = ApprovalHook::new();
23/// let executor = AgentExecutor::new(agent, tools).hook(hook);
24/// ```
25pub struct ApprovalHook {
26 /// If true, automatically approve all tool calls (useful for testing).
27 auto_approve: bool,
28}
29
30impl ApprovalHook {
31 /// Creates a new ApprovalHook that requires manual approval.
32 pub fn new() -> Self {
33 Self {
34 auto_approve: false,
35 }
36 }
37
38 /// Creates an ApprovalHook that automatically approves all tool calls.
39 pub fn auto_approve() -> Self {
40 Self { auto_approve: true }
41 }
42
43 /// Sets the auto-approve mode.
44 pub fn with_auto_approve(mut self, auto_approve: bool) -> Self {
45 self.auto_approve = auto_approve;
46 self
47 }
48}
49
50impl Default for ApprovalHook {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56#[async_trait]
57impl AgentHook for ApprovalHook {
58 fn on_before_tool_call(&self, ctx: &mut ToolCallContext) -> ToolCallAction {
59 if self.auto_approve {
60 ToolCallAction::Continue
61 } else {
62 ToolCallAction::Reject {
63 reason: format!(
64 "Tool call '{}' requires manual approval. Arguments: {}",
65 ctx.name, ctx.arguments
66 ),
67 }
68 }
69 }
70}