Skip to main content

agentic_evolve_core/crystallization/
confidence.rs

1//! ConfidenceCalculator — calculates pattern confidence from execution data.
2
3use crate::types::skill::SuccessfulExecution;
4
5/// Calculates confidence score for a pattern based on execution evidence.
6#[derive(Debug)]
7pub struct ConfidenceCalculator {
8    pub test_weight: f64,
9    pub execution_time_weight: f64,
10    pub code_complexity_weight: f64,
11}
12
13impl ConfidenceCalculator {
14    pub fn new() -> Self {
15        Self {
16            test_weight: 0.5,
17            execution_time_weight: 0.2,
18            code_complexity_weight: 0.3,
19        }
20    }
21
22    pub fn calculate(&self, execution: &SuccessfulExecution) -> f64 {
23        let test_score = self.test_score(execution);
24        let time_score = self.time_score(execution);
25        let complexity_score = self.complexity_score(&execution.code);
26
27        let raw = test_score * self.test_weight
28            + time_score * self.execution_time_weight
29            + complexity_score * self.code_complexity_weight;
30
31        raw.clamp(0.0, 1.0)
32    }
33
34    fn test_score(&self, execution: &SuccessfulExecution) -> f64 {
35        if execution.test_results.is_empty() {
36            return 0.5; // No tests = moderate confidence
37        }
38        let passed = execution.test_results.iter().filter(|t| t.passed).count();
39        passed as f64 / execution.test_results.len() as f64
40    }
41
42    fn time_score(&self, execution: &SuccessfulExecution) -> f64 {
43        // Faster execution = higher confidence (reasonable thresholds)
44        match execution.execution_time_ms {
45            0..=100 => 1.0,
46            101..=500 => 0.9,
47            501..=1000 => 0.8,
48            1001..=5000 => 0.6,
49            _ => 0.4,
50        }
51    }
52
53    fn complexity_score(&self, code: &str) -> f64 {
54        let lines = code.lines().count();
55        let nesting = max_nesting_depth(code);
56
57        // Sweet spot: moderate complexity
58        let line_score = match lines {
59            0..=5 => 0.9,
60            6..=50 => 1.0,
61            51..=200 => 0.8,
62            _ => 0.6,
63        };
64
65        let nesting_score = match nesting {
66            0..=2 => 1.0,
67            3..=4 => 0.8,
68            5..=6 => 0.6,
69            _ => 0.4,
70        };
71
72        (line_score + nesting_score) / 2.0
73    }
74}
75
76impl Default for ConfidenceCalculator {
77    fn default() -> Self {
78        Self::new()
79    }
80}
81
82fn max_nesting_depth(code: &str) -> usize {
83    let mut max_depth = 0;
84    let mut current: usize = 0;
85    for ch in code.chars() {
86        match ch {
87            '{' | '(' | '[' => {
88                current += 1;
89                max_depth = max_depth.max(current);
90            }
91            '}' | ')' | ']' => {
92                current = current.saturating_sub(1);
93            }
94            _ => {}
95        }
96    }
97    max_depth
98}