1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
//! Lifecycle Hooks System for Agent Execution Control
//!
//! This module provides a powerful hooks system for intercepting, monitoring, and controlling
//! agent behavior at critical lifecycle points. Hooks enable you to implement security gates,
//! audit logging, input validation, output filtering, and dynamic behavior modification without
//! modifying the core agent logic.
//!
//! # Overview
//!
//! The hooks system operates on an event-driven model with three key interception points:
//!
//! 1. **PreToolUse**: Fired before any tool is executed, allowing you to:
//! - Block dangerous operations (security gates)
//! - Modify tool inputs (parameter injection, sanitization)
//! - Log tool usage for auditing
//! - Implement rate limiting or quotas
//!
//! 2. **PostToolUse**: Fired after tool execution completes, allowing you to:
//! - Audit tool results
//! - Filter or redact sensitive information in outputs
//! - Collect metrics and telemetry
//! - Validate tool behavior
//!
//! 3. **UserPromptSubmit**: Fired before processing user input, allowing you to:
//! - Filter inappropriate content
//! - Modify prompts (add context, instructions)
//! - Implement content moderation
//! - Track user interactions
//!
//! # Execution Model
//!
//! Hooks follow a **sequential "first non-None wins"** execution model:
//! - Hooks are executed in the order they were registered
//! - Each hook can return `None` (pass-through) or `Some(HookDecision)` (take control)
//! - The **first hook** that returns `Some(HookDecision)` determines the outcome
//! - Subsequent hooks are **not executed** after a decision is made
//! - If all hooks return `None`, execution continues normally
//!
//! This model ensures predictable behavior and allows you to create hook chains where
//! earlier hooks can implement critical security checks that later hooks cannot override.
//!
//! # Common Use Cases
//!
//! ## Security Gate (Block Dangerous Operations)
//!
//! ```rust,no_run
//! use open_agent::{Hooks, PreToolUseEvent, HookDecision};
//!
//! let hooks = Hooks::new().add_pre_tool_use(|event| async move {
//! // Block file deletion in production
//! if event.tool_name == "delete_file" {
//! return Some(HookDecision::block("File deletion not allowed"));
//! }
//! None // Allow other operations
//! });
//! ```
//!
//! ## Audit Logging
//!
//! ```rust,no_run
//! use open_agent::{Hooks, PostToolUseEvent, HookDecision};
//!
//! let hooks = Hooks::new().add_post_tool_use(|event| async move {
//! // Log all tool executions for compliance
//! println!("Tool '{}' executed with result: {:?}",
//! event.tool_name, event.tool_result);
//! None // Don't interfere with execution
//! });
//! ```
//!
//! ## Input Modification (Parameter Injection)
//!
//! ```rust,no_run
//! use open_agent::{Hooks, PreToolUseEvent, HookDecision};
//! use serde_json::json;
//!
//! let hooks = Hooks::new().add_pre_tool_use(|event| async move {
//! if event.tool_name == "query_database" {
//! // Inject security context into all database queries
//! let mut input = event.tool_input.clone();
//! input["user_id"] = json!("current_user_123");
//! return Some(HookDecision::modify_input(input, "Injected user context"));
//! }
//! None
//! });
//! ```
//!
//! ## Content Moderation
//!
//! ```rust,no_run
//! use open_agent::{Hooks, UserPromptSubmitEvent, HookDecision};
//!
//! let hooks = Hooks::new().add_user_prompt_submit(|event| async move {
//! if event.prompt.contains("inappropriate_content") {
//! return Some(HookDecision::block("Content policy violation"));
//! }
//! None
//! });
//! ```
//!
//! ## Dynamic Prompt Enhancement
//!
//! ```ignore
//! use open_agent::{Hooks, UserPromptSubmitEvent, HookDecision};
//!
//! let hooks = Hooks::new().add_user_prompt_submit(|event| async move {
//! // Add context to user prompts
//! let enhanced = format!(
//! "{}\n\nAdditional Context: Current time is {}",
//! event.prompt,
//! chrono::Utc::now()
//! );
//! Some(HookDecision::modify_prompt(enhanced, "Added timestamp context"))
//! });
//! ```
//!
//! # Thread Safety and Async
//!
//! All hooks are async functions wrapped in `Arc` to enable:
//! - **Thread-safe sharing** across multiple agent instances
//! - **Async operations** like database queries, API calls, or file I/O
//! - **Zero-cost cloning** when passing hooks between threads
//!
//! Hooks can safely perform I/O operations, make network requests, or access shared state
//! as long as that state is thread-safe (e.g., wrapped in `Arc<Mutex<T>>`).
//!
//! # Error Handling
//!
//! If a hook panics or returns an error, the entire agent operation will be aborted.
//! Design your hooks to be robust and handle errors gracefully within the hook itself:
//!
//! ```rust,no_run
//! use open_agent::{Hooks, PreToolUseEvent, HookDecision};
//!
//! let hooks = Hooks::new().add_pre_tool_use(|event| async move {
//! match risky_validation(&event).await {
//! Ok(is_valid) => {
//! if !is_valid {
//! Some(HookDecision::block("Validation failed"))
//! } else {
//! None
//! }
//! }
//! Err(e) => {
//! eprintln!("Hook validation error: {}", e);
//! // Fail safe: block on errors
//! Some(HookDecision::block(format!("Validation error: {}", e)))
//! }
//! }
//! });
//!
//! async fn risky_validation(_event: &PreToolUseEvent) -> Result<bool, String> {
//! // Your validation logic here
//! Ok(true)
//! }
//! ```
use Value;
use Future;
use Pin;
use Arc;
include!;
include!;
include!;
include!;