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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
//! Execution context for coordinating agent optimization components
//!
//! This module provides the ExecutionContext struct that integrates all optimization
//! components (LoopDetector, ContextOptimizer, AutonomousExecutor,
//! AgentBehaviorAnalyzer) into a cohesive framework for autonomous agent execution.
use std::sync::Arc;
use tokio::sync::RwLock;
use super::context_optimizer::ContextOptimizer;
use super::loop_detector::LoopDetector;
use crate::exec::agent_optimization::AgentBehaviorAnalyzer;
use crate::tools::autonomous_executor::AutonomousExecutor;
/// Execution context that coordinates all optimization components
///
/// This struct provides a unified interface for managing agent execution with
/// integrated loop detection, context optimization, autonomous execution policy,
/// and behavior analysis.
#[derive(Clone)]
pub struct ExecutionContext {
/// Loop detector for identifying repetitive tool calls
pub loop_detector: Arc<RwLock<LoopDetector>>,
/// Context optimizer for managing output curation and compaction
pub context_optimizer: Arc<RwLock<ContextOptimizer>>,
/// Autonomous executor for determining execution policy
pub autonomous_executor: Arc<AutonomousExecutor>,
/// Behavior analyzer for tracking patterns and recommendations
pub behavior_analyzer: Arc<RwLock<AgentBehaviorAnalyzer>>,
}
impl ExecutionContext {
/// Create a new execution context with all optimization components
///
/// # Arguments
///
/// * `loop_detector` - Loop detector instance
/// * `context_optimizer` - Context optimizer instance
/// * `autonomous_executor` - Autonomous executor instance
/// * `behavior_analyzer` - Behavior analyzer instance
pub fn new(
loop_detector: Arc<RwLock<LoopDetector>>,
context_optimizer: Arc<RwLock<ContextOptimizer>>,
autonomous_executor: Arc<AutonomousExecutor>,
behavior_analyzer: Arc<RwLock<AgentBehaviorAnalyzer>>,
) -> Self {
Self {
loop_detector,
context_optimizer,
autonomous_executor,
behavior_analyzer,
}
}
/// Check if loop detection should block execution
///
/// # Arguments
///
/// * `tool_name` - Name of the tool being called
///
/// # Returns
///
/// Returns true if the tool should be blocked due to loop detection
pub async fn should_block_for_loop(&self, tool_name: &str) -> bool {
let detector = self.loop_detector.read().await;
detector.is_hard_limit_exceeded(tool_name)
}
/// Record a tool call for loop detection
///
/// # Arguments
///
/// * `tool_name` - Name of the tool being called
/// * `args` - Tool arguments as JSON value
///
/// # Returns
///
/// Returns Some(warning_message) if a loop is detected, None otherwise
pub async fn record_tool_call(
&self,
tool_name: &str,
args: &serde_json::Value,
) -> Option<String> {
let mut detector = self.loop_detector.write().await;
detector.record_call(tool_name, args)
}
/// Reset loop detection for a specific tool after successful progress
///
/// # Arguments
///
/// * `tool_name` - Name of the tool to reset
pub async fn reset_tool_loop_detection(&self, tool_name: &str) {
let mut detector = self.loop_detector.write().await;
detector.reset_tool(tool_name);
}
/// Get tool execution success rate from behavior analyzer
///
/// # Arguments
///
/// * `tool_name` - Name of the tool
///
/// # Returns
///
/// Returns the success rate as a ratio (0.0-1.0)
/// Note: This is calculated from recorded usage and failure data
pub async fn get_tool_success_rate(&self, tool_name: &str) -> f64 {
let analyzer = self.behavior_analyzer.read().await;
analyzer.tool_success_rate(tool_name)
}
/// Record tool execution result in behavior analyzer
///
/// # Arguments
///
/// * `tool_name` - Name of the tool
/// * `success` - Whether the execution was successful
pub async fn record_tool_execution(&self, tool_name: &str, success: bool) {
let mut analyzer = self.behavior_analyzer.write().await;
if success {
analyzer.record_tool_usage(tool_name);
} else {
analyzer.record_tool_failure(tool_name, "execution_failed");
}
}
/// Check if a warning should be shown for a tool based on failure rate
///
/// # Arguments
///
/// * `tool_name` - Name of the tool
///
/// # Returns
///
/// Returns Some(warning_message) if a warning should be shown, None otherwise
pub async fn should_warn_for_tool(&self, tool_name: &str) -> Option<String> {
let analyzer = self.behavior_analyzer.read().await;
analyzer.should_warn(tool_name)
}
/// Get recovery action for a known error pattern
///
/// # Arguments
///
/// * `error_type` - Type of error encountered
///
/// # Returns
///
/// Returns Some(recovery_action) if a known pattern exists, None otherwise
pub async fn get_recovery_action(&self, error_type: &str) -> Option<String> {
let analyzer = self.behavior_analyzer.read().await;
analyzer.get_recovery_action(error_type)
}
/// Generate a comprehensive status report
///
/// # Returns
///
/// Returns a formatted string with status information from all components
pub async fn generate_status_report(&self) -> String {
let mut report = String::new();
report.push_str("=== Execution Context Status ===\n\n");
// Loop detection status
let detector = self.loop_detector.read().await;
report.push_str(&format!(
"Loop Detection: {} tools tracked\n",
detector.get_tracked_tool_count()
));
report
}
}
impl Default for ExecutionContext {
fn default() -> Self {
Self::new(
Arc::new(RwLock::new(LoopDetector::new())),
Arc::new(RwLock::new(ContextOptimizer::new())),
Arc::new(AutonomousExecutor::new()),
Arc::new(RwLock::new(AgentBehaviorAnalyzer::new())),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_loop_detection_integration() {
let context = ExecutionContext::default();
let tool_name = "test_tool";
// Keep this integration assertion focused on context wiring rather than
// default threshold policy. Raise the per-tool threshold for this test.
context
.loop_detector
.write()
.await
.set_tool_limit(tool_name, 4);
// First few calls should not trigger warning
let args_1 = serde_json::json!({"param": "value-1"});
let args_2 = serde_json::json!({"param": "value-2"});
let args_3 = serde_json::json!({"param": "value-3"});
assert!(context.record_tool_call(tool_name, &args_1).await.is_none());
assert!(context.record_tool_call(tool_name, &args_2).await.is_none());
assert!(context.record_tool_call(tool_name, &args_3).await.is_none());
// Should not be blocked yet
assert!(!context.should_block_for_loop(tool_name).await);
// Reset should clear the counter
context.reset_tool_loop_detection(tool_name).await;
assert!(context.record_tool_call(tool_name, &args_1).await.is_none());
}
#[tokio::test]
async fn test_behavior_tracking() {
let context = ExecutionContext::default();
let tool_name = "test_tool";
// Record some executions
context.record_tool_execution(tool_name, true).await;
context.record_tool_execution(tool_name, true).await;
context.record_tool_execution(tool_name, false).await;
// Success rate currently derives from the analyzer's failure-rate model:
// one observed failure yields a 0.5 estimated success rate.
let success_rate = context.get_tool_success_rate(tool_name).await;
assert!((success_rate - 0.5).abs() < f64::EPSILON);
}
#[tokio::test]
async fn test_status_report_generation() {
let context = ExecutionContext::default();
let report = context.generate_status_report().await;
// Report should contain key sections
assert!(report.contains("Execution Context Status"));
assert!(report.contains("Loop Detection"));
}
}