lean_ctx/core/triage/
fusion.rs1use 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}