vtcode_core/tools/
optimized_registry.rs1use anyhow::Result;
4use hashbrown::HashMap;
5use parking_lot::RwLock;
6use serde_json::Value;
7use std::sync::Arc;
8use tokio::sync::Semaphore;
9
10use crate::tools::registry::ToolExecutionRecord;
11
12#[derive(Clone)]
14pub struct CachedToolMetadata {
15 pub name: String,
16 pub description: String,
17 pub parameters: Value,
18 pub is_cached: bool,
19 pub avg_execution_time_ms: u64,
20}
21
22pub struct OptimizedToolRegistry {
24 tool_metadata: Arc<RwLock<HashMap<String, Arc<CachedToolMetadata>>>>,
26
27 execution_semaphore: Arc<Semaphore>,
29
30 hot_cache: Arc<RwLock<lru::LruCache<String, Arc<CachedToolMetadata>>>>,
34
35 execution_stats: Arc<RwLock<Vec<ToolExecutionRecord>>>,
37}
38
39const HOT_CACHE_CAPACITY: usize = 16;
41
42impl OptimizedToolRegistry {
43 pub fn new(max_concurrent_tools: usize) -> Self {
44 Self {
45 tool_metadata: Arc::new(RwLock::new(HashMap::with_capacity(64))),
46 execution_semaphore: Arc::new(Semaphore::new(max_concurrent_tools)),
47 hot_cache: Arc::new(RwLock::new(lru::LruCache::new(
48 std::num::NonZeroUsize::new(HOT_CACHE_CAPACITY).unwrap_or(std::num::NonZeroUsize::MIN),
49 ))),
50 execution_stats: Arc::new(RwLock::new(Vec::with_capacity(1024))),
51 }
52 }
53
54 pub fn get_tool_metadata(&self, tool_name: &str) -> Option<Arc<CachedToolMetadata>> {
56 if let Some(metadata) = self.hot_cache.write().get(tool_name) {
59 return Some(Arc::clone(metadata));
60 }
61
62 let metadata = self.tool_metadata.read().get(tool_name).cloned()?;
64
65 self.promote_to_hot_cache(tool_name, &metadata);
67
68 Some(metadata)
69 }
70
71 pub fn register_tool(&self, metadata: CachedToolMetadata) {
73 let tool_name = metadata.name.clone();
74 let metadata_arc = Arc::new(metadata);
75
76 self.tool_metadata.write().insert(tool_name, metadata_arc);
77 }
78
79 pub async fn execute_tool_optimized(&self, tool_name: &str, _args: Value) -> Result<Value> {
81 let _permit = self.execution_semaphore.acquire().await?;
83
84 let start_time = std::time::Instant::now();
85
86 let result = self.execute_tool_impl(tool_name, _args).await;
88
89 let execution_time = start_time.elapsed();
90
91 self.record_execution_stats(tool_name, execution_time, result.is_ok());
93
94 result
95 }
96
97 fn promote_to_hot_cache(&self, tool_name: &str, metadata: &Arc<CachedToolMetadata>) {
101 self.hot_cache.write().push(tool_name.to_string(), Arc::clone(metadata));
102 }
103
104 fn record_execution_stats(&self, tool_name: &str, execution_time: std::time::Duration, success: bool) {
106 let record = ToolExecutionRecord {
107 tool_name: tool_name.to_string(),
108 requested_name: String::new(), is_mcp: false,
110 mcp_provider: None,
111 args: Value::Null,
112 result: if success {
113 Ok(Value::Null)
114 } else {
115 Err("Error".to_string())
116 },
117 timestamp: std::time::SystemTime::now(),
118 success,
119 context: crate::tools::registry::HarnessContextSnapshot::new("optimized".to_string(), None),
120 timeout_category: None,
121 base_timeout_ms: None,
122 adaptive_timeout_ms: None,
123 effective_timeout_ms: Some(execution_time.as_millis() as u64),
124 circuit_breaker: false,
125 attempt: 1,
126 retry_after_ms: None,
127 circuit_breaker_state: None,
128 };
129
130 let mut stats = self.execution_stats.write();
131 if stats.len() >= 1024 {
133 stats.drain(..128); }
135 stats.push(record);
136 }
137
138 async fn execute_tool_impl(&self, _tool_name: &str, _args: Value) -> Result<Value> {
140 Ok(Value::String("success".to_string()))
142 }
143
144 pub fn get_stats_snapshot(&self) -> Vec<ToolExecutionRecord> {
146 self.execution_stats.read().clone()
147 }
148
149 pub fn clear_hot_cache(&self) {
151 self.hot_cache.write().clear();
152 }
153}