omega_memory/
lib.rs

1//! # Omega Memory - 12-Tier Cosmic Memory System
2//!
3//! Implements hierarchical memory spanning from instant (milliseconds)
4//! to omega (universe-scale) timescales.
5
6pub mod tiers;
7pub mod individual;
8pub mod species;
9pub mod cosmic;
10pub mod query;
11pub mod consolidation;
12
13use chrono::{DateTime, Utc};
14use serde::{Deserialize, Serialize};
15use std::sync::Arc;
16use tokio::sync::RwLock;
17
18pub use tiers::MemoryTier;
19pub use query::{Query, QueryBuilder};
20pub use consolidation::MemoryConsolidator;
21
22/// Memory content types
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub enum MemoryContent {
25    /// Raw sensory data
26    Sensory(Vec<u8>),
27    /// Text-based memory
28    Text(String),
29    /// Structured data
30    Structured(serde_json::Value),
31    /// Embedding vector
32    Embedding(Vec<f32>),
33    /// Multi-modal memory
34    MultiModal {
35        text: Option<String>,
36        embedding: Vec<f32>,
37        metadata: serde_json::Value,
38    },
39}
40
41/// Core memory structure
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct Memory {
44    pub id: String,
45    pub tier: MemoryTier,
46    pub content: MemoryContent,
47    pub embedding: Vec<f32>,
48    pub importance: f64,
49    pub created_at: DateTime<Utc>,
50    pub accessed_at: DateTime<Utc>,
51    pub access_count: u64,
52    pub metadata: serde_json::Value,
53}
54
55impl Memory {
56    pub fn new(
57        tier: MemoryTier,
58        content: MemoryContent,
59        embedding: Vec<f32>,
60        importance: f64,
61    ) -> Self {
62        let now = Utc::now();
63        Self {
64            id: uuid::Uuid::new_v4().to_string(),
65            tier,
66            content,
67            embedding,
68            importance,
69            created_at: now,
70            accessed_at: now,
71            access_count: 0,
72            metadata: serde_json::Value::Object(Default::default()),
73        }
74    }
75
76    pub fn touch(&mut self) {
77        self.accessed_at = Utc::now();
78        self.access_count += 1;
79    }
80
81    pub fn relevance_score(&self) -> f64 {
82        let time_decay = self.time_decay_factor();
83        let access_boost = (self.access_count as f64).ln_1p() * 0.1;
84        self.importance * time_decay + access_boost
85    }
86
87    fn time_decay_factor(&self) -> f64 {
88        let age = Utc::now().signed_duration_since(self.accessed_at);
89        let hours = age.num_hours() as f64;
90
91        match self.tier {
92            MemoryTier::Instant => (-hours / 0.01).exp(),
93            MemoryTier::Session => (-hours / 24.0).exp(),
94            MemoryTier::Episodic => (-hours / 168.0).exp(), // 1 week
95            MemoryTier::Semantic => 1.0, // No decay for semantic
96            _ => 1.0, // Higher tiers don't decay
97        }
98    }
99}
100
101/// Memory errors
102#[derive(Debug, thiserror::Error)]
103pub enum MemoryError {
104    #[error("Storage error: {0}")]
105    Storage(String),
106
107    #[error("Query error: {0}")]
108    Query(String),
109
110    #[error("Consolidation error: {0}")]
111    Consolidation(String),
112
113    #[error("AgentDB error: {0}")]
114    AgentDB(String),
115
116    #[error("Serialization error: {0}")]
117    Serialization(#[from] serde_json::Error),
118
119    #[error("IO error: {0}")]
120    Io(#[from] std::io::Error),
121}
122
123/// Main Cosmic Memory system integrating all tiers
124pub struct CosmicMemory {
125    individual: Arc<RwLock<individual::IndividualMemory>>,
126    species: Arc<RwLock<species::SpeciesMemory>>,
127    cosmic_scale: Arc<RwLock<cosmic::CosmicScaleMemory>>,
128    consolidator: Arc<MemoryConsolidator>,
129}
130
131impl CosmicMemory {
132    pub async fn new() -> Result<Self, MemoryError> {
133        let individual = Arc::new(RwLock::new(individual::IndividualMemory::new().await?));
134        let species = Arc::new(RwLock::new(species::SpeciesMemory::new().await?));
135        let cosmic_scale = Arc::new(RwLock::new(cosmic::CosmicScaleMemory::new().await?));
136
137        let consolidator = Arc::new(MemoryConsolidator::new(
138            individual.clone(),
139            species.clone(),
140            cosmic_scale.clone(),
141        ));
142
143        Ok(Self {
144            individual,
145            species,
146            cosmic_scale,
147            consolidator,
148        })
149    }
150
151    /// Store a memory in the appropriate tier
152    pub async fn store(&self, memory: Memory) -> Result<String, MemoryError> {
153        let id = memory.id.clone();
154
155        match memory.tier {
156            MemoryTier::Instant | MemoryTier::Session | MemoryTier::Episodic | MemoryTier::Semantic => {
157                self.individual.write().await.store(memory).await?;
158            }
159            MemoryTier::Collective | MemoryTier::Evolutionary | MemoryTier::Architectural | MemoryTier::Substrate => {
160                self.species.write().await.store(memory).await?;
161            }
162            MemoryTier::Civilizational | MemoryTier::Temporal | MemoryTier::Physical | MemoryTier::Omega => {
163                self.cosmic_scale.write().await.store(memory).await?;
164            }
165        }
166
167        Ok(id)
168    }
169
170    /// Recall memories matching the query across specified tiers
171    pub async fn recall(
172        &self,
173        query: &Query,
174        tiers: &[MemoryTier],
175    ) -> Result<Vec<Memory>, MemoryError> {
176        let mut results = Vec::new();
177
178        // Query individual tiers (1-4)
179        if tiers.iter().any(|t| matches!(t, MemoryTier::Instant | MemoryTier::Session | MemoryTier::Episodic | MemoryTier::Semantic)) {
180            let individual_results = self.individual.read().await.recall(query, tiers).await?;
181            results.extend(individual_results);
182        }
183
184        // Query species tiers (5-8)
185        if tiers.iter().any(|t| matches!(t, MemoryTier::Collective | MemoryTier::Evolutionary | MemoryTier::Architectural | MemoryTier::Substrate)) {
186            let species_results = self.species.read().await.recall(query, tiers).await?;
187            results.extend(species_results);
188        }
189
190        // Query cosmic tiers (9-12)
191        if tiers.iter().any(|t| matches!(t, MemoryTier::Civilizational | MemoryTier::Temporal | MemoryTier::Physical | MemoryTier::Omega)) {
192            let cosmic_results = self.cosmic_scale.read().await.recall(query, tiers).await?;
193            results.extend(cosmic_results);
194        }
195
196        // Sort by relevance
197        results.sort_by(|a, b| {
198            b.relevance_score()
199                .partial_cmp(&a.relevance_score())
200                .unwrap_or(std::cmp::Ordering::Equal)
201        });
202
203        Ok(results)
204    }
205
206    /// Consolidate memories from one tier to another
207    pub async fn consolidate(
208        &self,
209        from_tier: MemoryTier,
210        to_tier: MemoryTier,
211    ) -> Result<(), MemoryError> {
212        self.consolidator.consolidate(from_tier, to_tier).await
213    }
214
215    /// Run automatic consolidation based on importance and age
216    pub async fn auto_consolidate(&self) -> Result<(), MemoryError> {
217        self.consolidator.auto_consolidate().await
218    }
219
220    /// Get statistics about memory usage across all tiers
221    pub async fn stats(&self) -> MemoryStats {
222        let individual_stats = self.individual.read().await.stats().await;
223        let species_stats = self.species.read().await.stats().await;
224        let cosmic_stats = self.cosmic_scale.read().await.stats().await;
225
226        MemoryStats {
227            individual: individual_stats.clone(),
228            species: species_stats.clone(),
229            cosmic: cosmic_stats.clone(),
230            total_memories: individual_stats.total + species_stats.total + cosmic_stats.total,
231        }
232    }
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct MemoryStats {
237    pub individual: individual::IndividualMemoryStats,
238    pub species: species::SpeciesMemoryStats,
239    pub cosmic: cosmic::CosmicMemoryStats,
240    pub total_memories: usize,
241}
242
243#[cfg(test)]
244mod tests {
245    use super::*;
246
247    #[tokio::test]
248    async fn test_memory_creation() {
249        let memory = Memory::new(
250            MemoryTier::Session,
251            MemoryContent::Text("test".to_string()),
252            vec![0.1, 0.2, 0.3],
253            0.5,
254        );
255
256        assert_eq!(memory.tier, MemoryTier::Session);
257        assert_eq!(memory.importance, 0.5);
258        assert_eq!(memory.access_count, 0);
259    }
260
261    #[tokio::test]
262    async fn test_cosmic_memory_init() {
263        let result = CosmicMemory::new().await;
264        assert!(result.is_ok());
265    }
266}