Skip to main content

lean_ctx/core/context_kernel/
adaptive_hook.rs

1//! Adapts kernel compression advice from observed context-read bounces.
2
3use super::adaptive_bridge::KernelCompressionAdvice;
4
5/// Compression guidance derived from bounce-tracker observations.
6#[derive(Debug, Clone, Copy, serde::Serialize)]
7pub struct CompressionAdvice {
8    /// Whether compression should be reduced.
9    pub should_reduce: bool,
10    /// Bounce rate used to produce the advice.
11    pub bounce_rate: f64,
12    /// Kernel recommendation for the observed bounce rate.
13    pub advice: KernelCompressionAdvice,
14}
15
16impl CompressionAdvice {
17    fn maintain() -> Self {
18        Self {
19            should_reduce: false,
20            bounce_rate: 0.0,
21            advice: KernelCompressionAdvice::Maintain,
22        }
23    }
24
25    fn from_rate(bounce_rate: f64) -> Self {
26        let advice = super::adaptive_bridge::compression_advice(bounce_rate);
27        Self {
28            should_reduce: advice == KernelCompressionAdvice::Reduce,
29            bounce_rate,
30            advice,
31        }
32    }
33}
34
35/// Updates the adaptive bridge from the process-wide bounce tracker.
36pub fn update_from_bounce_tracker() {
37    if !super::kernel_config::is_enabled() {
38        return;
39    }
40    let tracker = crate::core::bounce_tracker::global()
41        .lock()
42        .unwrap_or_else(std::sync::PoisonError::into_inner);
43    let total_bounces = tracker.total_bounces();
44    let _total_wasted_tokens = tracker.total_wasted_tokens();
45    let denominator = total_bounces.saturating_add(100).max(1);
46    let rate = total_bounces as f64 / denominator as f64;
47    drop(tracker);
48    super::adaptive_bridge::update_bounce_signal(rate);
49}
50
51/// Returns adaptive compression guidance for a path's extension.
52#[must_use]
53pub fn advice_for_path(path: &str) -> CompressionAdvice {
54    if !super::kernel_config::is_enabled() {
55        return CompressionAdvice::maintain();
56    }
57    let tracker = crate::core::bounce_tracker::global()
58        .lock()
59        .unwrap_or_else(std::sync::PoisonError::into_inner);
60    tracker
61        .bounce_rate_for_extension(path)
62        .map_or_else(CompressionAdvice::maintain, CompressionAdvice::from_rate)
63}
64
65/// Returns adaptive compression guidance for the latest global bounce signal.
66#[must_use]
67pub fn global_advice() -> CompressionAdvice {
68    CompressionAdvice::from_rate(super::adaptive_bridge::current_bounce_rate())
69}
70
71/// Clears adaptive compression signal state.
72pub fn reset() {
73    super::adaptive_bridge::reset();
74}
75
76#[cfg(test)]
77mod tests {
78    use super::{advice_for_path, update_from_bounce_tracker};
79    use crate::core::context_kernel::{adaptive_bridge, kernel_config};
80
81    fn setup() -> std::sync::MutexGuard<'static, ()> {
82        let guard = kernel_config::KERNEL_TEST_LOCK
83            .lock()
84            .unwrap_or_else(std::sync::PoisonError::into_inner);
85        kernel_config::reset_features();
86        adaptive_bridge::reset();
87        let mut tracker = crate::core::bounce_tracker::global()
88            .lock()
89            .unwrap_or_else(std::sync::PoisonError::into_inner);
90        *tracker = crate::core::bounce_tracker::BounceTracker::new();
91        drop(tracker);
92        guard
93    }
94
95    #[test]
96    fn update_feeds_bridge() {
97        let _guard = setup();
98        crate::core::bounce_tracker::global()
99            .lock()
100            .unwrap_or_else(std::sync::PoisonError::into_inner)
101            .record_expansion(None, 20);
102        update_from_bounce_tracker();
103        assert!(adaptive_bridge::current_bounce_rate() > 0.0);
104    }
105
106    #[test]
107    fn advice_for_unknown_path() {
108        let _guard = setup();
109        assert_eq!(
110            advice_for_path("unknown.rs").advice,
111            adaptive_bridge::KernelCompressionAdvice::Maintain
112        );
113    }
114
115    #[test]
116    fn disabled_kernel_noop() {
117        let _guard = setup();
118        let mut features = kernel_config::features();
119        features.enabled = false;
120        kernel_config::update_features(features);
121        update_from_bounce_tracker();
122        assert_eq!(
123            advice_for_path("disabled.rs").advice,
124            adaptive_bridge::KernelCompressionAdvice::Maintain
125        );
126    }
127}