aether_core/
config.rs

1//! # Aether Configuration
2//! 
3//! Central configuration management for the Aether framework.
4//! Supports loading from environment variables, files, and programmatic defaults.
5
6use std::env;
7
8/// Global configuration for the Aether engine.
9/// 
10/// # Example
11/// ```rust
12/// use aether_core::AetherConfig;
13/// 
14/// // Load from environment
15/// let config = AetherConfig::from_env();
16/// 
17/// // Or customize
18/// let config = AetherConfig::default()
19///     .with_toon(true)
20///     .with_healing(true);
21/// ```
22#[derive(Debug, Clone)]
23pub struct AetherConfig {
24    /// Enable TOON (Token-Oriented Object Notation) for context compression.
25    /// Reduces token usage by 30-60% for structured data.
26    /// Default: false, Env: AETHER_TOON=true
27    pub toon_enabled: bool,
28
29    /// Enable Self-Healing mode (automatic validation and retry on errors).
30    /// Default: false, Env: AETHER_HEALING=true
31    pub healing_enabled: bool,
32
33    /// Enable Semantic Cache (reduces API costs for similar prompts).
34    /// Default: false, Env: AETHER_CACHE=true
35    pub cache_enabled: bool,
36
37    /// Enable parallel slot generation.
38    /// Default: true, Env: AETHER_PARALLEL=false
39    pub parallel: bool,
40
41    /// Maximum retries for failed generations.
42    /// Default: 2, Env: AETHER_MAX_RETRIES=3
43    pub max_retries: u32,
44
45    /// Auto-enable TOON when context exceeds this character count.
46    /// If None, TOON is only enabled manually.
47    /// Default: Some(2000), Env: AETHER_TOON_THRESHOLD=2000
48    pub auto_toon_threshold: Option<usize>,
49
50    /// Cache similarity threshold (0.0 - 1.0).
51    /// Higher values require more similar prompts to hit the cache.
52    /// Default: 0.90, Env: AETHER_CACHE_THRESHOLD=0.90
53    pub cache_threshold: f32,
54}
55
56impl Default for AetherConfig {
57    fn default() -> Self {
58        Self {
59            toon_enabled: false,
60            healing_enabled: false,
61            cache_enabled: false,
62            parallel: true,
63            max_retries: 2,
64            auto_toon_threshold: Some(2000),
65            cache_threshold: 0.90,
66        }
67    }
68}
69
70impl AetherConfig {
71    /// Create a new config from environment variables.
72    /// Falls back to defaults for missing variables.
73    pub fn from_env() -> Self {
74        let mut config = Self::default();
75
76        if let Ok(v) = env::var("AETHER_TOON") {
77            config.toon_enabled = v.to_lowercase() == "true" || v == "1";
78        }
79        if let Ok(v) = env::var("AETHER_HEALING") {
80            config.healing_enabled = v.to_lowercase() == "true" || v == "1";
81        }
82        if let Ok(v) = env::var("AETHER_CACHE") {
83            config.cache_enabled = v.to_lowercase() == "true" || v == "1";
84        }
85        if let Ok(v) = env::var("AETHER_PARALLEL") {
86            config.parallel = v.to_lowercase() != "false" && v != "0";
87        }
88        if let Ok(v) = env::var("AETHER_MAX_RETRIES") {
89            if let Ok(n) = v.parse() {
90                config.max_retries = n;
91            }
92        }
93        if let Ok(v) = env::var("AETHER_TOON_THRESHOLD") {
94            if let Ok(n) = v.parse() {
95                config.auto_toon_threshold = Some(n);
96            }
97        }
98        if let Ok(v) = env::var("AETHER_CACHE_THRESHOLD") {
99            if let Ok(n) = v.parse() {
100                config.cache_threshold = n;
101            }
102        }
103
104        config
105    }
106
107    /// Builder: Enable or disable TOON protocol.
108    pub fn with_toon(mut self, enabled: bool) -> Self {
109        self.toon_enabled = enabled;
110        self
111    }
112
113    /// Builder: Enable or disable Self-Healing.
114    pub fn with_healing(mut self, enabled: bool) -> Self {
115        self.healing_enabled = enabled;
116        self
117    }
118
119    /// Builder: Enable or disable Semantic Cache.
120    pub fn with_cache(mut self, enabled: bool) -> Self {
121        self.cache_enabled = enabled;
122        self
123    }
124
125    /// Builder: Enable or disable parallel generation.
126    pub fn with_parallel(mut self, enabled: bool) -> Self {
127        self.parallel = enabled;
128        self
129    }
130
131    /// Builder: Set maximum retries.
132    pub fn with_max_retries(mut self, retries: u32) -> Self {
133        self.max_retries = retries;
134        self
135    }
136
137    /// Builder: Set auto TOON threshold.
138    pub fn with_auto_toon_threshold(mut self, threshold: Option<usize>) -> Self {
139        self.auto_toon_threshold = threshold;
140        self
141    }
142
143    /// Check if TOON should be used for a given context length.
144    pub fn should_use_toon(&self, context_length: usize) -> bool {
145        if self.toon_enabled {
146            return true;
147        }
148        if let Some(threshold) = self.auto_toon_threshold {
149            return context_length >= threshold;
150        }
151        false
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158
159    #[test]
160    fn test_default_config() {
161        let config = AetherConfig::default();
162        assert!(!config.toon_enabled);
163        assert!(!config.healing_enabled);
164        assert!(config.parallel);
165        assert_eq!(config.max_retries, 2);
166    }
167
168    #[test]
169    fn test_builder_pattern() {
170        let config = AetherConfig::default()
171            .with_toon(true)
172            .with_healing(true)
173            .with_max_retries(5);
174
175        assert!(config.toon_enabled);
176        assert!(config.healing_enabled);
177        assert_eq!(config.max_retries, 5);
178    }
179
180    #[test]
181    fn test_auto_toon() {
182        let config = AetherConfig::default();
183        assert!(!config.should_use_toon(1000)); // Below threshold
184        assert!(config.should_use_toon(3000));  // Above threshold
185    }
186}