1pub 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#[derive(Debug, Clone, Serialize, Deserialize)]
24pub enum MemoryContent {
25 Sensory(Vec<u8>),
27 Text(String),
29 Structured(serde_json::Value),
31 Embedding(Vec<f32>),
33 MultiModal {
35 text: Option<String>,
36 embedding: Vec<f32>,
37 metadata: serde_json::Value,
38 },
39}
40
41#[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(), MemoryTier::Semantic => 1.0, _ => 1.0, }
98 }
99}
100
101#[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
123pub 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 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 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 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 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 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 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 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 pub async fn auto_consolidate(&self) -> Result<(), MemoryError> {
217 self.consolidator.auto_consolidate().await
218 }
219
220 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}