Skip to main content

el_core/
config.rs

1//! Per-session configuration (immutable for the life of a session — ADR-001).
2
3use crate::value_objects::{DeviceTarget, ModelFormat, SafetyMode, SpeculationMode};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct SessionConfig {
7    pub format: ModelFormat,
8    pub device: DeviceTarget,
9    pub safety: SafetyMode,
10    pub speculation: SpeculationMode,
11    /// Apply LLMLingua-2 prompt compression before prefill (degradable).
12    pub compress: bool,
13    pub max_tokens: u32,
14    /// Hard cap for the static memory plan (ADR-003). Default 1 GiB.
15    pub memory_budget_bytes: u64,
16    /// Opt-in LAN relay (ADR-004). **Defaults to `false` — air-gapped.**
17    pub hybrid_mode: bool,
18}
19
20impl Default for SessionConfig {
21    fn default() -> Self {
22        Self {
23            format: ModelFormat::Gguf,
24            device: DeviceTarget::Auto,
25            safety: SafetyMode::Lightweight,
26            speculation: SpeculationMode::Off, // safe default off (ADR-002)
27            compress: true,
28            max_tokens: 512,
29            memory_budget_bytes: 1024 * 1024 * 1024, // 1 GiB cap (ADR-003)
30            hybrid_mode: false,                      // air-gapped by default (ADR-004)
31        }
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn defaults_are_air_gapped_and_conservative() {
41        let c = SessionConfig::default();
42        assert!(!c.hybrid_mode, "must be air-gapped by default (ADR-004)");
43        assert_eq!(
44            c.speculation,
45            SpeculationMode::Off,
46            "speculation off by default"
47        );
48    }
49}