omega_runtime/
events.rs

1//! Event system for the Omega Runtime
2
3use std::sync::Arc;
4use std::time::Duration;
5use uuid::Uuid;
6use serde::{Deserialize, Serialize};
7
8/// Types of cognitive loops
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10pub enum LoopType {
11    Conscious,
12    Subconscious,
13    Meta,
14    Unconscious,
15}
16
17/// Memory tier levels
18#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
19pub enum MemoryTier {
20    Working,
21    ShortTerm,
22    LongTerm,
23}
24
25/// Intelligence identifier
26pub type IntelligenceId = Uuid;
27
28/// Architecture identifier
29pub type ArchitectureId = Uuid;
30
31/// Events emitted by the Omega Runtime
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub enum OmegaEvent {
34    // Lifecycle events
35    SystemStarted {
36        timestamp: chrono::DateTime<chrono::Utc>,
37    },
38    SystemShutdown {
39        timestamp: chrono::DateTime<chrono::Utc>,
40    },
41    SystemPaused {
42        timestamp: chrono::DateTime<chrono::Utc>,
43    },
44    SystemResumed {
45        timestamp: chrono::DateTime<chrono::Utc>,
46    },
47
48    // Loop events
49    LoopCycleStarted {
50        loop_type: LoopType,
51        cycle_id: Uuid,
52        timestamp: chrono::DateTime<chrono::Utc>,
53    },
54    LoopCycleCompleted {
55        loop_type: LoopType,
56        cycle_id: Uuid,
57        duration: Duration,
58        timestamp: chrono::DateTime<chrono::Utc>,
59    },
60    LoopError {
61        loop_type: LoopType,
62        error: String,
63        timestamp: chrono::DateTime<chrono::Utc>,
64    },
65
66    // Memory events
67    MemoryStored {
68        tier: MemoryTier,
69        id: Uuid,
70        size_bytes: usize,
71        timestamp: chrono::DateTime<chrono::Utc>,
72    },
73    MemoryRetrieved {
74        tier: MemoryTier,
75        id: Uuid,
76        timestamp: chrono::DateTime<chrono::Utc>,
77    },
78    MemoryConsolidated {
79        from_tier: MemoryTier,
80        to_tier: MemoryTier,
81        count: usize,
82        timestamp: chrono::DateTime<chrono::Utc>,
83    },
84    MemoryEvicted {
85        tier: MemoryTier,
86        id: Uuid,
87        timestamp: chrono::DateTime<chrono::Utc>,
88    },
89
90    // Intelligence events
91    IntelligenceCreated {
92        id: IntelligenceId,
93        architecture_id: ArchitectureId,
94        timestamp: chrono::DateTime<chrono::Utc>,
95    },
96    IntelligenceEvolved {
97        id: IntelligenceId,
98        generation: usize,
99        fitness: f64,
100        timestamp: chrono::DateTime<chrono::Utc>,
101    },
102
103    // Architecture events
104    ArchitectureCreated {
105        id: ArchitectureId,
106        timestamp: chrono::DateTime<chrono::Utc>,
107    },
108    ArchitectureEvolved {
109        id: ArchitectureId,
110        fitness: f64,
111        timestamp: chrono::DateTime<chrono::Utc>,
112    },
113    ArchitectureMutated {
114        id: ArchitectureId,
115        timestamp: chrono::DateTime<chrono::Utc>,
116    },
117
118    // AgentDB events
119    AgentCreated {
120        agent_id: Uuid,
121        agent_type: String,
122        timestamp: chrono::DateTime<chrono::Utc>,
123    },
124    AgentDestroyed {
125        agent_id: Uuid,
126        timestamp: chrono::DateTime<chrono::Utc>,
127    },
128    AgentsPruned {
129        count: usize,
130        timestamp: chrono::DateTime<chrono::Utc>,
131    },
132
133    // Error events
134    Error {
135        component: String,
136        error: String,
137        timestamp: chrono::DateTime<chrono::Utc>,
138    },
139
140    // Metrics events
141    MetricsCollected {
142        component: String,
143        metrics: serde_json::Value,
144        timestamp: chrono::DateTime<chrono::Utc>,
145    },
146}
147
148impl OmegaEvent {
149    /// Get the event type as a string
150    pub fn event_type(&self) -> &'static str {
151        match self {
152            OmegaEvent::SystemStarted { .. } => "system.started",
153            OmegaEvent::SystemShutdown { .. } => "system.shutdown",
154            OmegaEvent::SystemPaused { .. } => "system.paused",
155            OmegaEvent::SystemResumed { .. } => "system.resumed",
156            OmegaEvent::LoopCycleStarted { .. } => "loop.cycle.started",
157            OmegaEvent::LoopCycleCompleted { .. } => "loop.cycle.completed",
158            OmegaEvent::LoopError { .. } => "loop.error",
159            OmegaEvent::MemoryStored { .. } => "memory.stored",
160            OmegaEvent::MemoryRetrieved { .. } => "memory.retrieved",
161            OmegaEvent::MemoryConsolidated { .. } => "memory.consolidated",
162            OmegaEvent::MemoryEvicted { .. } => "memory.evicted",
163            OmegaEvent::IntelligenceCreated { .. } => "intelligence.created",
164            OmegaEvent::IntelligenceEvolved { .. } => "intelligence.evolved",
165            OmegaEvent::ArchitectureCreated { .. } => "architecture.created",
166            OmegaEvent::ArchitectureEvolved { .. } => "architecture.evolved",
167            OmegaEvent::ArchitectureMutated { .. } => "architecture.mutated",
168            OmegaEvent::AgentCreated { .. } => "agent.created",
169            OmegaEvent::AgentDestroyed { .. } => "agent.destroyed",
170            OmegaEvent::AgentsPruned { .. } => "agents.pruned",
171            OmegaEvent::Error { .. } => "error",
172            OmegaEvent::MetricsCollected { .. } => "metrics.collected",
173        }
174    }
175
176    /// Get the timestamp of the event
177    pub fn timestamp(&self) -> chrono::DateTime<chrono::Utc> {
178        match self {
179            OmegaEvent::SystemStarted { timestamp } => *timestamp,
180            OmegaEvent::SystemShutdown { timestamp } => *timestamp,
181            OmegaEvent::SystemPaused { timestamp } => *timestamp,
182            OmegaEvent::SystemResumed { timestamp } => *timestamp,
183            OmegaEvent::LoopCycleStarted { timestamp, .. } => *timestamp,
184            OmegaEvent::LoopCycleCompleted { timestamp, .. } => *timestamp,
185            OmegaEvent::LoopError { timestamp, .. } => *timestamp,
186            OmegaEvent::MemoryStored { timestamp, .. } => *timestamp,
187            OmegaEvent::MemoryRetrieved { timestamp, .. } => *timestamp,
188            OmegaEvent::MemoryConsolidated { timestamp, .. } => *timestamp,
189            OmegaEvent::MemoryEvicted { timestamp, .. } => *timestamp,
190            OmegaEvent::IntelligenceCreated { timestamp, .. } => *timestamp,
191            OmegaEvent::IntelligenceEvolved { timestamp, .. } => *timestamp,
192            OmegaEvent::ArchitectureCreated { timestamp, .. } => *timestamp,
193            OmegaEvent::ArchitectureEvolved { timestamp, .. } => *timestamp,
194            OmegaEvent::ArchitectureMutated { timestamp, .. } => *timestamp,
195            OmegaEvent::AgentCreated { timestamp, .. } => *timestamp,
196            OmegaEvent::AgentDestroyed { timestamp, .. } => *timestamp,
197            OmegaEvent::AgentsPruned { timestamp, .. } => *timestamp,
198            OmegaEvent::Error { timestamp, .. } => *timestamp,
199            OmegaEvent::MetricsCollected { timestamp, .. } => *timestamp,
200        }
201    }
202}
203
204/// Event handler function type
205pub type EventHandler = Arc<dyn Fn(&OmegaEvent) + Send + Sync>;
206
207/// Event bus for distributing events to handlers
208pub struct EventBus {
209    handlers: Vec<EventHandler>,
210    buffer: Vec<OmegaEvent>,
211    max_buffer_size: usize,
212}
213
214impl EventBus {
215    /// Create a new event bus
216    pub fn new() -> Self {
217        Self {
218            handlers: Vec::new(),
219            buffer: Vec::new(),
220            max_buffer_size: 1000,
221        }
222    }
223
224    /// Create a new event bus with a custom buffer size
225    pub fn with_buffer_size(max_buffer_size: usize) -> Self {
226        Self {
227            handlers: Vec::new(),
228            buffer: Vec::new(),
229            max_buffer_size,
230        }
231    }
232
233    /// Register an event handler
234    pub fn on(&mut self, handler: EventHandler) {
235        self.handlers.push(handler);
236    }
237
238    /// Emit an event to all registered handlers
239    pub fn emit(&mut self, event: OmegaEvent) {
240        // Store in buffer
241        if self.buffer.len() >= self.max_buffer_size {
242            self.buffer.remove(0); // Remove oldest event
243        }
244        self.buffer.push(event.clone());
245
246        // Notify all handlers
247        for handler in &self.handlers {
248            handler(&event);
249        }
250    }
251
252    /// Get the event history buffer
253    pub fn history(&self) -> &[OmegaEvent] {
254        &self.buffer
255    }
256
257    /// Clear the event history buffer
258    pub fn clear_history(&mut self) {
259        self.buffer.clear();
260    }
261
262    /// Get the number of registered handlers
263    pub fn handler_count(&self) -> usize {
264        self.handlers.len()
265    }
266
267    /// Filter events by type
268    pub fn filter_by_type(&self, event_type: &str) -> Vec<&OmegaEvent> {
269        self.buffer
270            .iter()
271            .filter(|e| e.event_type() == event_type)
272            .collect()
273    }
274}
275
276impl Default for EventBus {
277    fn default() -> Self {
278        Self::new()
279    }
280}
281
282#[cfg(test)]
283mod tests {
284    use super::*;
285    use std::sync::atomic::{AtomicUsize, Ordering};
286
287    #[test]
288    fn test_event_bus_creation() {
289        let bus = EventBus::new();
290        assert_eq!(bus.handler_count(), 0);
291        assert_eq!(bus.history().len(), 0);
292    }
293
294    #[test]
295    fn test_event_emission() {
296        let mut bus = EventBus::new();
297        let counter = Arc::new(AtomicUsize::new(0));
298        let counter_clone = counter.clone();
299
300        bus.on(Arc::new(move |_| {
301            counter_clone.fetch_add(1, Ordering::SeqCst);
302        }));
303
304        bus.emit(OmegaEvent::SystemStarted {
305            timestamp: chrono::Utc::now(),
306        });
307
308        assert_eq!(counter.load(Ordering::SeqCst), 1);
309        assert_eq!(bus.history().len(), 1);
310    }
311
312    #[test]
313    fn test_event_buffer_overflow() {
314        let mut bus = EventBus::with_buffer_size(2);
315
316        bus.emit(OmegaEvent::SystemStarted {
317            timestamp: chrono::Utc::now(),
318        });
319        bus.emit(OmegaEvent::SystemPaused {
320            timestamp: chrono::Utc::now(),
321        });
322        bus.emit(OmegaEvent::SystemResumed {
323            timestamp: chrono::Utc::now(),
324        });
325
326        assert_eq!(bus.history().len(), 2);
327    }
328
329    #[test]
330    fn test_event_type_filtering() {
331        let mut bus = EventBus::new();
332
333        bus.emit(OmegaEvent::SystemStarted {
334            timestamp: chrono::Utc::now(),
335        });
336        bus.emit(OmegaEvent::SystemPaused {
337            timestamp: chrono::Utc::now(),
338        });
339        bus.emit(OmegaEvent::SystemStarted {
340            timestamp: chrono::Utc::now(),
341        });
342
343        let started_events = bus.filter_by_type("system.started");
344        assert_eq!(started_events.len(), 2);
345    }
346
347    #[test]
348    fn test_multiple_handlers() {
349        let mut bus = EventBus::new();
350        let counter1 = Arc::new(AtomicUsize::new(0));
351        let counter2 = Arc::new(AtomicUsize::new(0));
352
353        let c1 = counter1.clone();
354        let c2 = counter2.clone();
355
356        bus.on(Arc::new(move |_| {
357            c1.fetch_add(1, Ordering::SeqCst);
358        }));
359        bus.on(Arc::new(move |_| {
360            c2.fetch_add(1, Ordering::SeqCst);
361        }));
362
363        bus.emit(OmegaEvent::SystemStarted {
364            timestamp: chrono::Utc::now(),
365        });
366
367        assert_eq!(counter1.load(Ordering::SeqCst), 1);
368        assert_eq!(counter2.load(Ordering::SeqCst), 1);
369    }
370}