omega_runtime/
config.rs

1//! Runtime configuration for the Omega system
2
3use crate::error::{ConfigError, ConfigResult};
4use serde::{Deserialize, Serialize};
5use std::path::Path;
6
7/// Configuration for the AgentDB subsystem
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct AgentDBConfig {
10    /// Maximum number of concurrent agents
11    pub max_agents: usize,
12    /// Agent pruning threshold
13    pub prune_threshold: usize,
14    /// Enable agent persistence
15    pub enable_persistence: bool,
16    /// Persistence directory
17    pub persistence_dir: Option<String>,
18}
19
20impl Default for AgentDBConfig {
21    fn default() -> Self {
22        Self {
23            max_agents: 10000,
24            prune_threshold: 8000,
25            enable_persistence: true,
26            persistence_dir: Some("data/agentdb".to_string()),
27        }
28    }
29}
30
31/// Configuration for the Memory subsystem
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct MemoryConfig {
34    /// Working memory capacity (in items)
35    pub working_capacity: usize,
36    /// Short-term memory capacity
37    pub short_term_capacity: usize,
38    /// Long-term memory capacity
39    pub long_term_capacity: usize,
40    /// Consolidation interval (in seconds)
41    pub consolidation_interval: u64,
42    /// Enable compression
43    pub enable_compression: bool,
44    /// Memory persistence directory
45    pub persistence_dir: Option<String>,
46}
47
48impl Default for MemoryConfig {
49    fn default() -> Self {
50        Self {
51            working_capacity: 1000,
52            short_term_capacity: 10000,
53            long_term_capacity: 1000000,
54            consolidation_interval: 300, // 5 minutes
55            enable_compression: true,
56            persistence_dir: Some("data/memory".to_string()),
57        }
58    }
59}
60
61/// Configuration for the Loops subsystem
62#[derive(Debug, Clone, Serialize, Deserialize)]
63pub struct LoopsConfig {
64    /// Enable conscious loop
65    pub enable_conscious: bool,
66    /// Conscious loop interval (ms)
67    pub conscious_interval: u64,
68    /// Enable subconscious loop
69    pub enable_subconscious: bool,
70    /// Subconscious loop interval (ms)
71    pub subconscious_interval: u64,
72    /// Enable meta loop
73    pub enable_meta: bool,
74    /// Meta loop interval (ms)
75    pub meta_interval: u64,
76    /// Enable unconscious loop
77    pub enable_unconscious: bool,
78    /// Unconscious loop interval (ms)
79    pub unconscious_interval: u64,
80}
81
82impl Default for LoopsConfig {
83    fn default() -> Self {
84        Self {
85            enable_conscious: true,
86            conscious_interval: 100,
87            enable_subconscious: true,
88            subconscious_interval: 500,
89            enable_meta: true,
90            meta_interval: 1000,
91            enable_unconscious: true,
92            unconscious_interval: 5000,
93        }
94    }
95}
96
97/// Configuration for the Meta-SONA subsystem
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct MetaSONAConfig {
100    /// Population size for evolution
101    pub population_size: usize,
102    /// Number of generations
103    pub generations: usize,
104    /// Mutation rate (0.0 to 1.0)
105    pub mutation_rate: f64,
106    /// Crossover rate (0.0 to 1.0)
107    pub crossover_rate: f64,
108    /// Enable neural architecture search
109    pub enable_nas: bool,
110    /// Enable self-modification
111    pub enable_self_modification: bool,
112    /// Intelligence cache size
113    pub cache_size: usize,
114}
115
116impl Default for MetaSONAConfig {
117    fn default() -> Self {
118        Self {
119            population_size: 100,
120            generations: 50,
121            mutation_rate: 0.1,
122            crossover_rate: 0.7,
123            enable_nas: true,
124            enable_self_modification: true,
125            cache_size: 1000,
126        }
127    }
128}
129
130/// Main configuration for the Omega Runtime
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct OmegaConfig {
133    /// AgentDB configuration
134    pub agentdb: AgentDBConfig,
135    /// Memory configuration
136    pub memory: MemoryConfig,
137    /// Loops configuration
138    pub loops: LoopsConfig,
139    /// Meta-SONA configuration
140    pub meta_sona: MetaSONAConfig,
141    /// Enable event logging
142    pub enable_event_logging: bool,
143    /// Enable metrics collection
144    pub enable_metrics: bool,
145    /// Runtime data directory
146    pub data_dir: String,
147}
148
149impl Default for OmegaConfig {
150    fn default() -> Self {
151        Self {
152            agentdb: AgentDBConfig::default(),
153            memory: MemoryConfig::default(),
154            loops: LoopsConfig::default(),
155            meta_sona: MetaSONAConfig::default(),
156            enable_event_logging: true,
157            enable_metrics: true,
158            data_dir: "data/omega".to_string(),
159        }
160    }
161}
162
163impl OmegaConfig {
164    /// Create configuration from a file
165    pub fn from_file(path: &Path) -> ConfigResult<Self> {
166        let content = std::fs::read_to_string(path)
167            .map_err(|e| ConfigError::FileNotFound(format!("{}: {}", path.display(), e)))?;
168
169        let config: OmegaConfig = serde_json::from_str(&content)
170            .map_err(|e| ConfigError::Parse(format!("Failed to parse config: {}", e)))?;
171
172        config.validate()?;
173        Ok(config)
174    }
175
176    /// Save configuration to a file
177    pub fn to_file(&self, path: &Path) -> ConfigResult<()> {
178        let content = serde_json::to_string_pretty(self)?;
179        std::fs::write(path, content)?;
180        Ok(())
181    }
182
183    /// Validate the configuration
184    pub fn validate(&self) -> ConfigResult<()> {
185        // Validate AgentDB config
186        if self.agentdb.max_agents == 0 {
187            return Err(ConfigError::Validation(
188                "max_agents must be greater than 0".to_string(),
189            ));
190        }
191        if self.agentdb.prune_threshold >= self.agentdb.max_agents {
192            return Err(ConfigError::Validation(
193                "prune_threshold must be less than max_agents".to_string(),
194            ));
195        }
196
197        // Validate Memory config
198        if self.memory.working_capacity == 0 {
199            return Err(ConfigError::Validation(
200                "working_capacity must be greater than 0".to_string(),
201            ));
202        }
203        if self.memory.consolidation_interval == 0 {
204            return Err(ConfigError::Validation(
205                "consolidation_interval must be greater than 0".to_string(),
206            ));
207        }
208
209        // Validate Loops config
210        if self.loops.conscious_interval == 0 {
211            return Err(ConfigError::Validation(
212                "conscious_interval must be greater than 0".to_string(),
213            ));
214        }
215
216        // Validate Meta-SONA config
217        if self.meta_sona.population_size == 0 {
218            return Err(ConfigError::Validation(
219                "population_size must be greater than 0".to_string(),
220            ));
221        }
222        if !(0.0..=1.0).contains(&self.meta_sona.mutation_rate) {
223            return Err(ConfigError::Validation(
224                "mutation_rate must be between 0.0 and 1.0".to_string(),
225            ));
226        }
227        if !(0.0..=1.0).contains(&self.meta_sona.crossover_rate) {
228            return Err(ConfigError::Validation(
229                "crossover_rate must be between 0.0 and 1.0".to_string(),
230            ));
231        }
232
233        Ok(())
234    }
235
236    /// Create a minimal configuration for testing
237    pub fn minimal() -> Self {
238        Self {
239            agentdb: AgentDBConfig {
240                max_agents: 100,
241                prune_threshold: 80,
242                enable_persistence: false,
243                persistence_dir: None,
244            },
245            memory: MemoryConfig {
246                working_capacity: 100,
247                short_term_capacity: 1000,
248                long_term_capacity: 10000,
249                consolidation_interval: 60,
250                enable_compression: false,
251                persistence_dir: None,
252            },
253            loops: LoopsConfig {
254                enable_conscious: true,
255                conscious_interval: 1000,
256                enable_subconscious: false,
257                subconscious_interval: 5000,
258                enable_meta: false,
259                meta_interval: 10000,
260                enable_unconscious: false,
261                unconscious_interval: 30000,
262            },
263            meta_sona: MetaSONAConfig {
264                population_size: 10,
265                generations: 5,
266                mutation_rate: 0.1,
267                crossover_rate: 0.7,
268                enable_nas: false,
269                enable_self_modification: false,
270                cache_size: 100,
271            },
272            enable_event_logging: false,
273            enable_metrics: false,
274            data_dir: "test_data".to_string(),
275        }
276    }
277}
278
279#[cfg(test)]
280mod tests {
281    use super::*;
282
283    #[test]
284    fn test_default_config_is_valid() {
285        let config = OmegaConfig::default();
286        assert!(config.validate().is_ok());
287    }
288
289    #[test]
290    fn test_minimal_config_is_valid() {
291        let config = OmegaConfig::minimal();
292        assert!(config.validate().is_ok());
293    }
294
295    #[test]
296    fn test_invalid_max_agents() {
297        let mut config = OmegaConfig::default();
298        config.agentdb.max_agents = 0;
299        assert!(config.validate().is_err());
300    }
301
302    #[test]
303    fn test_invalid_prune_threshold() {
304        let mut config = OmegaConfig::default();
305        config.agentdb.prune_threshold = config.agentdb.max_agents + 1;
306        assert!(config.validate().is_err());
307    }
308
309    #[test]
310    fn test_invalid_mutation_rate() {
311        let mut config = OmegaConfig::default();
312        config.meta_sona.mutation_rate = 1.5;
313        assert!(config.validate().is_err());
314    }
315
316    #[test]
317    fn test_serialization() {
318        let config = OmegaConfig::default();
319        let json = serde_json::to_string(&config).unwrap();
320        let deserialized: OmegaConfig = serde_json::from_str(&json).unwrap();
321        assert!(deserialized.validate().is_ok());
322    }
323}