1use std::collections::HashMap;
4use std::path::Path;
5
6use agentic_evolve_core::collective::{
7 DecayManager, PromotionEngine, SuccessTracker, UsageTracker,
8};
9use agentic_evolve_core::composition::PatternComposer;
10use agentic_evolve_core::crystallization::PatternExtractor;
11use agentic_evolve_core::matching::CompositeMatcher;
12use agentic_evolve_core::optimization::{CacheManager, PatternOptimizer};
13use agentic_evolve_core::storage::{PatternIndex, PatternStore, PatternVersioner};
14use agentic_evolve_core::types::match_result::{MatchContext, MatchResult};
15use agentic_evolve_core::types::pattern::{FunctionSignature, Language, Pattern, PatternVariable};
16use agentic_evolve_core::types::skill::SuccessfulExecution;
17use agentic_evolve_core::EvolveResult;
18
19pub struct SessionManager {
21 store: PatternStore,
22 index: PatternIndex,
23 versioner: PatternVersioner,
24 matcher: CompositeMatcher,
25 extractor: PatternExtractor,
26 composer: PatternComposer,
27 usage_tracker: UsageTracker,
28 success_tracker: SuccessTracker,
29 decay_manager: DecayManager,
30 promotion_engine: PromotionEngine,
31 optimizer: PatternOptimizer,
32 cache: CacheManager,
33}
34
35impl SessionManager {
36 pub fn new(data_dir: &str) -> EvolveResult<Self> {
38 let path = Path::new(data_dir);
39 let store = PatternStore::with_data_dir(path)?;
40
41 let mut index = PatternIndex::new();
42 for pattern in store.list() {
43 index.add(pattern);
44 }
45
46 Ok(Self {
47 store,
48 index,
49 versioner: PatternVersioner::new(),
50 matcher: CompositeMatcher::new(),
51 extractor: PatternExtractor::new(),
52 composer: PatternComposer::new(),
53 usage_tracker: UsageTracker::new(),
54 success_tracker: SuccessTracker::new(),
55 decay_manager: DecayManager::default(),
56 promotion_engine: PromotionEngine::default(),
57 optimizer: PatternOptimizer::new(),
58 cache: CacheManager::default(),
59 })
60 }
61
62 #[allow(clippy::too_many_arguments)]
66 pub fn store_pattern(
67 &mut self,
68 name: &str,
69 domain: &str,
70 language: Language,
71 signature: FunctionSignature,
72 template: &str,
73 variables: Vec<PatternVariable>,
74 confidence: f64,
75 tags: Vec<String>,
76 ) -> EvolveResult<Pattern> {
77 let mut pattern = Pattern::new(
78 name, domain, language, signature, template, variables, confidence,
79 );
80 pattern.tags = tags;
81 self.store.save(&pattern)?;
82 self.index.add(&pattern);
83 self.versioner
84 .record_version(&pattern, "Initial creation")?;
85 Ok(pattern)
86 }
87
88 pub fn get_pattern(&self, id: &str) -> EvolveResult<&Pattern> {
90 self.store.get(id)
91 }
92
93 pub fn search_patterns(&self, query: &str) -> Vec<&Pattern> {
95 self.store.search(query)
96 }
97
98 pub fn list_patterns(&self) -> Vec<&Pattern> {
100 self.store.list()
101 }
102
103 pub fn delete_pattern(&mut self, id: &str) -> EvolveResult<Pattern> {
105 let pattern = self.store.delete(id)?;
106 self.index.remove(&pattern);
107 self.cache.invalidate_pattern(id);
108 Ok(pattern)
109 }
110
111 pub fn match_signature(
115 &self,
116 signature: &FunctionSignature,
117 context: &MatchContext,
118 limit: usize,
119 ) -> EvolveResult<Vec<MatchResult>> {
120 let patterns: Vec<&Pattern> = self.store.list();
121 self.matcher
122 .find_matches(signature, &patterns, context, limit)
123 }
124
125 pub fn match_context(
127 &self,
128 signature: &FunctionSignature,
129 context: &MatchContext,
130 limit: usize,
131 ) -> EvolveResult<Vec<MatchResult>> {
132 let patterns: Vec<&Pattern> = self.store.list();
133 self.matcher
134 .find_matches(signature, &patterns, context, limit)
135 }
136
137 pub fn crystallize(&mut self, execution: &SuccessfulExecution) -> EvolveResult<Vec<Pattern>> {
141 let patterns = self.extractor.extract(execution)?;
142 let mut stored = Vec::new();
143 for pattern in patterns {
144 self.store.save(&pattern)?;
145 self.index.add(&pattern);
146 self.versioner
147 .record_version(&pattern, "Crystallized from successful execution")?;
148 stored.push(pattern);
149 }
150 Ok(stored)
151 }
152
153 pub fn compose(
157 &self,
158 pattern_ids: &[String],
159 bindings: &HashMap<String, String>,
160 ) -> EvolveResult<agentic_evolve_core::composition::composer::CompositionResult> {
161 let mut patterns = Vec::new();
162 for id in pattern_ids {
163 patterns.push(self.store.get(id)?);
164 }
165 self.composer.compose(&patterns, bindings, None)
166 }
167
168 pub fn coverage(&self, signatures: &[FunctionSignature], threshold: f64) -> CoverageReport {
172 let all_patterns: Vec<&Pattern> = self.store.list();
173 let context = MatchContext::new();
174 let mut matched = 0;
175 let mut details = Vec::new();
176
177 for sig in signatures {
178 let results = self.matcher.find_matches(sig, &all_patterns, &context, 1);
179 let best_score = results
180 .as_ref()
181 .ok()
182 .and_then(|r| r.first())
183 .map(|r| r.score.combined)
184 .unwrap_or(0.0);
185 let covered = best_score >= threshold;
186 if covered {
187 matched += 1;
188 }
189 details.push(CoverageDetail {
190 function_name: sig.name.clone(),
191 best_match_score: best_score,
192 covered,
193 });
194 }
195
196 let total = signatures.len();
197 CoverageReport {
198 total,
199 covered: matched,
200 coverage: if total == 0 {
201 1.0
202 } else {
203 matched as f64 / total as f64
204 },
205 details,
206 }
207 }
208
209 pub fn confidence(&self, pattern_id: &str) -> EvolveResult<ConfidenceReport> {
213 let pattern = self.store.get(pattern_id)?;
214 let usage_rate = self.usage_tracker.success_rate(pattern_id);
215 let success_rate = self.success_tracker.success_rate(pattern_id);
216 let promotion = self.promotion_engine.evaluate(pattern);
217
218 Ok(ConfidenceReport {
219 pattern_id: pattern_id.to_string(),
220 base_confidence: pattern.confidence,
221 usage_success_rate: usage_rate,
222 tracker_success_rate: success_rate,
223 promotion_decision: format!("{promotion:?}"),
224 usage_count: pattern.usage_count,
225 success_count: pattern.success_count,
226 })
227 }
228
229 pub fn update_usage(
233 &mut self,
234 pattern_id: &str,
235 domain: &str,
236 success: bool,
237 ) -> EvolveResult<()> {
238 let pattern = self.store.get_mut(pattern_id)?;
239 pattern.record_use(success);
240 self.decay_manager.apply_usage_boost(pattern, success);
241
242 let pattern_clone = pattern.clone();
244 self.store.save(&pattern_clone)?;
245
246 self.usage_tracker.record_use(pattern_id, domain, success);
247 self.success_tracker.record(pattern_id, success);
248 self.cache.invalidate_pattern(pattern_id);
249 Ok(())
250 }
251
252 pub fn optimize(&mut self) -> EvolveResult<OptimizationSummary> {
256 let patterns: Vec<&Pattern> = self.store.list();
257 let report = self.optimizer.optimize_report(&patterns);
258 let decay_report = self.decay_manager.decay_report(&patterns);
259
260 let ids: Vec<String> = self
262 .store
263 .list()
264 .iter()
265 .map(|p| p.id.as_str().to_string())
266 .collect();
267 let mut decayed = 0;
268 for id in &ids {
269 if let Ok(pattern) = self.store.get_mut(id) {
270 let old = pattern.confidence;
271 self.decay_manager.apply_decay(pattern);
272 if (old - pattern.confidence).abs() > f64::EPSILON {
273 decayed += 1;
274 }
275 }
276 }
277
278 let mut promoted = 0;
280 let mut demoted = 0;
281 for id in &ids {
282 if let Ok(pattern) = self.store.get_mut(id) {
283 let decision = self.promotion_engine.apply_promotion(pattern);
284 match decision {
285 agentic_evolve_core::collective::promotion::PromotionDecision::Promote => {
286 promoted += 1
287 }
288 agentic_evolve_core::collective::promotion::PromotionDecision::Demote => {
289 demoted += 1
290 }
291 _ => {}
292 }
293 }
294 }
295
296 self.cache.clear();
297
298 Ok(OptimizationSummary {
299 patterns_total: report.patterns_before,
300 duplicates_found: report.duplicates_removed,
301 prunable: report.pruned,
302 decay_healthy: decay_report.healthy,
303 decay_decaying: decay_report.decaying,
304 decay_critical: decay_report.critical,
305 patterns_decayed: decayed,
306 patterns_promoted: promoted,
307 patterns_demoted: demoted,
308 cache_cleared: true,
309 })
310 }
311
312 pub fn get_body(
314 &self,
315 signature: &FunctionSignature,
316 context: &MatchContext,
317 ) -> EvolveResult<Option<(String, String, f64)>> {
318 let patterns: Vec<&Pattern> = self.store.list();
319 let results = self
320 .matcher
321 .find_matches(signature, &patterns, context, 1)?;
322 match results.into_iter().next() {
323 Some(result) => Ok(Some((
324 result.pattern.template.clone(),
325 result.pattern_id.as_str().to_string(),
326 result.score.combined,
327 ))),
328 None => Ok(None),
329 }
330 }
331
332 pub fn pattern_count(&self) -> usize {
334 self.store.count()
335 }
336}
337
338#[derive(Debug, Clone, serde::Serialize)]
340pub struct CoverageReport {
341 pub total: usize,
342 pub covered: usize,
343 pub coverage: f64,
344 pub details: Vec<CoverageDetail>,
345}
346
347#[derive(Debug, Clone, serde::Serialize)]
349pub struct CoverageDetail {
350 pub function_name: String,
351 pub best_match_score: f64,
352 pub covered: bool,
353}
354
355#[derive(Debug, Clone, serde::Serialize)]
357pub struct ConfidenceReport {
358 pub pattern_id: String,
359 pub base_confidence: f64,
360 pub usage_success_rate: f64,
361 pub tracker_success_rate: f64,
362 pub promotion_decision: String,
363 pub usage_count: u64,
364 pub success_count: u64,
365}
366
367#[derive(Debug, Clone, serde::Serialize)]
369pub struct OptimizationSummary {
370 pub patterns_total: usize,
371 pub duplicates_found: usize,
372 pub prunable: usize,
373 pub decay_healthy: usize,
374 pub decay_decaying: usize,
375 pub decay_critical: usize,
376 pub patterns_decayed: usize,
377 pub patterns_promoted: usize,
378 pub patterns_demoted: usize,
379 pub cache_cleared: bool,
380}