Skip to main content

lean_ctx/core/ocla/builtin/
config_tuner.rs

1//! BuiltinConfigTuner — proposes configuration adjustments.
2//!
3//! Wraps `core/config/mod.rs` tuning logic behind the OCLA trait. Generates
4//! deterministic proposal refs and signals whether the change requires user
5//! approval before application.
6
7use crate::core::adaptive_mode_policy::AdaptiveModePolicyStore;
8use crate::core::ocla::traits::{ConfigTuner, OclaService};
9use crate::core::ocla::types::{
10    ConfigProposal, ConfigTuningRequest, OclaCapability, OclaCapabilityKind, OclaResult,
11};
12
13pub struct BuiltinConfigTuner {
14    require_approval: bool,
15}
16
17impl BuiltinConfigTuner {
18    pub fn new() -> Self {
19        Self {
20            require_approval: true,
21        }
22    }
23
24    pub fn auto_apply() -> Self {
25        Self {
26            require_approval: false,
27        }
28    }
29
30    pub fn tune(&self, request: ConfigTuningRequest) -> OclaResult<ConfigProposal> {
31        let policy = AdaptiveModePolicyStore::load();
32        self.tune_with_policy(request, &policy)
33    }
34
35    #[allow(clippy::unnecessary_wraps, clippy::needless_pass_by_value)]
36    fn tune_with_policy(
37        &self,
38        request: ConfigTuningRequest,
39        policy: &AdaptiveModePolicyStore,
40    ) -> OclaResult<ConfigProposal> {
41        let intent =
42            (!request.objective_ref.trim().is_empty()).then_some(request.objective_ref.as_str());
43        let tuned_mode = policy.choose_auto_mode(intent, &request.config_ref);
44        let proposal_ref = format!(
45            "proposal:{}->{}:{}",
46            request.config_ref, tuned_mode, request.context.request_id
47        );
48        let rollback_ref = format!("rollback:{}", request.config_ref);
49
50        Ok(ConfigProposal {
51            proposal_ref,
52            rollback_ref,
53            requires_approval: self.require_approval,
54        })
55    }
56}
57
58impl Default for BuiltinConfigTuner {
59    fn default() -> Self {
60        Self::new()
61    }
62}
63
64impl OclaService for BuiltinConfigTuner {
65    fn capability(&self) -> OclaCapability {
66        OclaCapability::available(OclaCapabilityKind::ConfigTuner)
67    }
68}
69
70impl ConfigTuner for BuiltinConfigTuner {
71    fn propose_tuning(&self, request: ConfigTuningRequest) -> OclaResult<ConfigProposal> {
72        self.tune(request)
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79    use crate::core::ocla::types::OclaRequestContext;
80
81    fn tuning_req(config: &str) -> ConfigTuningRequest {
82        ConfigTuningRequest {
83            context: OclaRequestContext {
84                request_id: "r1".into(),
85                session_id: "s1".into(),
86                agent_id: "agent-test".into(),
87                content_ref: "ref:test".into(),
88                tenant_id: None,
89                trace_id: "tr-unit".into(),
90            },
91            config_ref: config.into(),
92            objective_ref: "minimize_tokens".into(),
93        }
94    }
95
96    #[test]
97    fn default_requires_approval() {
98        let tuner = BuiltinConfigTuner::new();
99        let proposal = tuner
100            .tune_with_policy(
101                tuning_req("aggressive"),
102                &AdaptiveModePolicyStore::default(),
103            )
104            .unwrap();
105        assert!(proposal.requires_approval);
106        assert!(proposal.proposal_ref.contains("aggressive->aggressive"));
107    }
108
109    #[test]
110    fn auto_apply_mode() {
111        let tuner = BuiltinConfigTuner::auto_apply();
112        let proposal = tuner
113            .tune_with_policy(tuning_req("mode"), &AdaptiveModePolicyStore::default())
114            .unwrap();
115        assert!(!proposal.requires_approval);
116    }
117
118    #[test]
119    fn tune_uses_penalty_for_predicted_mode() {
120        let tuner = BuiltinConfigTuner::new();
121        let mut policy = AdaptiveModePolicyStore::default();
122        policy.global.modes.insert(
123            "aggressive".to_string(),
124            crate::core::adaptive_mode_policy::ModePenalty {
125                ema_badness: 1.0,
126                samples: 1,
127                last_ts: Some("t".to_string()),
128            },
129        );
130
131        let proposal = tuner
132            .tune_with_policy(tuning_req("aggressive"), &policy)
133            .unwrap();
134
135        assert!(!proposal.proposal_ref.contains("aggressive->aggressive"));
136        assert!(proposal.proposal_ref.starts_with("proposal:aggressive->"));
137    }
138
139    #[test]
140    fn tune_honors_intent_specific_policy() {
141        let tuner = BuiltinConfigTuner::new();
142        let mut policy = AdaptiveModePolicyStore::default();
143        let intent = "minimize_tokens".to_string();
144        policy
145            .by_intent
146            .entry(intent.clone())
147            .or_default()
148            .modes
149            .insert(
150                "aggressive".to_string(),
151                crate::core::adaptive_mode_policy::ModePenalty {
152                    ema_badness: 1.0,
153                    samples: 1,
154                    last_ts: Some("t".to_string()),
155                },
156            );
157
158        let proposal = tuner
159            .tune_with_policy(tuning_req("aggressive"), &policy)
160            .unwrap();
161
162        assert!(!proposal.proposal_ref.contains("aggressive->aggressive"));
163    }
164
165    #[test]
166    fn registry_with_builtins_proposes_the_same_tuning() {
167        use crate::core::ocla::registry::OclaRegistry;
168
169        let direct = BuiltinConfigTuner::new()
170            .tune(tuning_req("aggressive"))
171            .unwrap();
172        let via_registry = OclaRegistry::with_builtins()
173            .config_tuner
174            .propose_tuning(tuning_req("aggressive"))
175            .unwrap();
176
177        assert_eq!(via_registry, direct);
178    }
179}