Skip to main content

lean_ctx/core/triage/
fusion.rs

1use super::{ProfileHypothesis, profile::TaskProfileLocal};
2
3#[derive(Debug, Clone, Copy, Default)]
4pub struct FusionEngine;
5
6#[derive(Debug, Clone, Copy, Default)]
7pub struct RuntimeSignals {
8    pub files_count: usize,
9    pub modules_affected: usize,
10    pub has_compiler_errors: bool,
11    pub context_cached_ratio: f32,
12}
13
14impl FusionEngine {
15    pub fn fuse(hypotheses: &[ProfileHypothesis], signals: &RuntimeSignals) -> TaskProfileLocal {
16        let mut profile = hypotheses
17            .iter()
18            .max_by_key(|h| h.confidence_milli)
19            .map_or_else(TaskProfileLocal::default, |h| h.profile.clone());
20        if signals.files_count > 8 || signals.modules_affected > 3 {
21            profile.complexity = "high".into();
22        }
23        profile
24    }
25}
26pub fn fuse(hypotheses: &[ProfileHypothesis], signals: &RuntimeSignals) -> TaskProfileLocal {
27    FusionEngine::fuse(hypotheses, signals)
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use crate::core::triage::TriageBackendLocal;
34    fn h(c: u16, complexity: &str) -> ProfileHypothesis {
35        ProfileHypothesis {
36            profile: TaskProfileLocal {
37                complexity: complexity.into(),
38                confidence_milli: c,
39                ..Default::default()
40            },
41            confidence_milli: c,
42            backend: TriageBackendLocal::Rules,
43        }
44    }
45    #[test]
46    fn empty_uses_default() {
47        assert_eq!(
48            fuse(&[], &RuntimeSignals::default()),
49            TaskProfileLocal::default()
50        );
51    }
52    #[test]
53    fn highest_confidence_wins() {
54        assert_eq!(
55            fuse(
56                &[h(400, "low"), h(900, "medium")],
57                &RuntimeSignals::default()
58            )
59            .complexity,
60            "medium"
61        );
62    }
63    #[test]
64    fn files_or_modules_raise_complexity() {
65        for signals in [
66            RuntimeSignals {
67                files_count: 9,
68                ..Default::default()
69            },
70            RuntimeSignals {
71                modules_affected: 4,
72                ..Default::default()
73            },
74        ] {
75            assert_eq!(fuse(&[h(900, "low")], &signals).complexity, "high");
76        }
77    }
78}