1pub mod schema;
45pub mod storage;
46
47pub use storage::{
48 OmegaStore, StorageError, Result,
49 StoredMemory, StoredSkill, StoredArchitecture,
50 StoredIntelligence, StoredVector, StoredReflexionEpisode,
51 StoredCausalEdge, DatabaseStatistics,
52};
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use chrono::Utc;
58
59 fn create_test_store() -> OmegaStore {
60 OmegaStore::new_in_memory().expect("Failed to create test store")
61 }
62
63 #[test]
64 fn test_store_and_retrieve_memory() {
65 let store = create_test_store();
66 let now = Utc::now().timestamp();
67
68 let memory = StoredMemory {
69 id: "mem-test-001".to_string(),
70 content: "Test memory content".to_string(),
71 tier: 2,
72 importance: 0.85,
73 embedding_blob: Some(vec![1, 2, 3, 4]),
74 created_at: now,
75 last_accessed: now,
76 };
77
78 store.store_memory(&memory).unwrap();
79 let retrieved = store.get_memory("mem-test-001").unwrap();
80
81 assert_eq!(retrieved.id, "mem-test-001");
82 assert_eq!(retrieved.content, "Test memory content");
83 assert_eq!(retrieved.tier, 2);
84 assert_eq!(retrieved.importance, 0.85);
85 assert_eq!(retrieved.embedding_blob, Some(vec![1, 2, 3, 4]));
86 }
87
88 #[test]
89 fn test_query_memories_by_tier() {
90 let store = create_test_store();
91 let now = Utc::now().timestamp();
92
93 for i in 0..5 {
95 let memory = StoredMemory {
96 id: format!("mem-tier-{}", i),
97 content: format!("Memory {}", i),
98 tier: if i < 3 { 1 } else { 2 },
99 importance: 0.5 + (i as f64 * 0.1),
100 embedding_blob: None,
101 created_at: now,
102 last_accessed: now,
103 };
104 store.store_memory(&memory).unwrap();
105 }
106
107 let tier1_memories = store.query_memories_by_tier(1).unwrap();
108 assert_eq!(tier1_memories.len(), 3);
109
110 let tier2_memories = store.query_memories_by_tier(2).unwrap();
111 assert_eq!(tier2_memories.len(), 2);
112
113 assert!(tier1_memories[0].importance >= tier1_memories[1].importance);
115 }
116
117 #[test]
118 fn test_update_memory_access() {
119 let store = create_test_store();
120 let now = Utc::now().timestamp();
121
122 let memory = StoredMemory {
123 id: "mem-access-001".to_string(),
124 content: "Access test".to_string(),
125 tier: 1,
126 importance: 0.7,
127 embedding_blob: None,
128 created_at: now,
129 last_accessed: now,
130 };
131
132 store.store_memory(&memory).unwrap();
133
134 let new_access_time = now + 1000;
135 store.update_memory_access("mem-access-001", new_access_time).unwrap();
136
137 let retrieved = store.get_memory("mem-access-001").unwrap();
138 assert_eq!(retrieved.last_accessed, new_access_time);
139 }
140
141 #[test]
142 fn test_store_and_retrieve_skill() {
143 let store = create_test_store();
144 let now = Utc::now().timestamp();
145
146 let skill = StoredSkill {
147 id: "skill-001".to_string(),
148 name: "code_review".to_string(),
149 description: "Perform code review with best practices".to_string(),
150 trigger_pattern: "review.*code".to_string(),
151 success_count: 5,
152 last_used: Some(now),
153 created_at: now,
154 };
155
156 store.store_skill(&skill).unwrap();
157 let retrieved = store.get_skill("skill-001").unwrap();
158
159 assert_eq!(retrieved.name, "code_review");
160 assert_eq!(retrieved.success_count, 5);
161 }
162
163 #[test]
164 fn test_get_skills_by_pattern() {
165 let store = create_test_store();
166 let now = Utc::now().timestamp();
167
168 let skills = vec![
169 StoredSkill {
170 id: "skill-code-1".to_string(),
171 name: "code_analysis".to_string(),
172 description: "Analyze code quality".to_string(),
173 trigger_pattern: "analyze_code".to_string(),
174 success_count: 10,
175 last_used: Some(now),
176 created_at: now,
177 },
178 StoredSkill {
179 id: "skill-code-2".to_string(),
180 name: "code_generation".to_string(),
181 description: "Generate code from spec".to_string(),
182 trigger_pattern: "generate_code".to_string(),
183 success_count: 7,
184 last_used: Some(now),
185 created_at: now,
186 },
187 StoredSkill {
188 id: "skill-test-1".to_string(),
189 name: "test_writing".to_string(),
190 description: "Write unit tests".to_string(),
191 trigger_pattern: "write_tests".to_string(),
192 success_count: 3,
193 last_used: Some(now),
194 created_at: now,
195 },
196 ];
197
198 for skill in &skills {
199 store.store_skill(skill).unwrap();
200 }
201
202 let code_skills = store.get_skills_by_pattern("code").unwrap();
203 assert_eq!(code_skills.len(), 2);
204
205 assert_eq!(code_skills[0].success_count, 10);
207 assert_eq!(code_skills[1].success_count, 7);
208 }
209
210 #[test]
211 fn test_increment_skill_success() {
212 let store = create_test_store();
213 let now = Utc::now().timestamp();
214
215 let skill = StoredSkill {
216 id: "skill-inc-001".to_string(),
217 name: "test_skill".to_string(),
218 description: "Test".to_string(),
219 trigger_pattern: "test".to_string(),
220 success_count: 5,
221 last_used: None,
222 created_at: now,
223 };
224
225 store.store_skill(&skill).unwrap();
226
227 let new_time = now + 500;
228 store.increment_skill_success("skill-inc-001", new_time).unwrap();
229
230 let retrieved = store.get_skill("skill-inc-001").unwrap();
231 assert_eq!(retrieved.success_count, 6);
232 assert_eq!(retrieved.last_used, Some(new_time));
233 }
234
235 #[test]
236 fn test_store_and_retrieve_architecture() {
237 let store = create_test_store();
238 let now = Utc::now().timestamp();
239
240 let arch = StoredArchitecture {
241 id: "arch-001".to_string(),
242 name: "HybridTransformer".to_string(),
243 paradigm: "neural".to_string(),
244 substrate: "pytorch".to_string(),
245 fitness_json: r#"{"accuracy": 0.95, "speed": 0.8}"#.to_string(),
246 lineage_json: r#"{"parent": null, "generation": 1}"#.to_string(),
247 created_at: now,
248 };
249
250 store.store_architecture(&arch).unwrap();
251 let retrieved = store.get_architecture("arch-001").unwrap();
252
253 assert_eq!(retrieved.name, "HybridTransformer");
254 assert_eq!(retrieved.paradigm, "neural");
255 }
256
257 #[test]
258 fn test_get_architectures_by_paradigm() {
259 let store = create_test_store();
260 let now = Utc::now().timestamp();
261
262 let archs = vec![
263 StoredArchitecture {
264 id: "arch-neural-1".to_string(),
265 name: "Transformer".to_string(),
266 paradigm: "neural".to_string(),
267 substrate: "pytorch".to_string(),
268 fitness_json: "{}".to_string(),
269 lineage_json: "{}".to_string(),
270 created_at: now,
271 },
272 StoredArchitecture {
273 id: "arch-neural-2".to_string(),
274 name: "CNN".to_string(),
275 paradigm: "neural".to_string(),
276 substrate: "tensorflow".to_string(),
277 fitness_json: "{}".to_string(),
278 lineage_json: "{}".to_string(),
279 created_at: now + 100,
280 },
281 StoredArchitecture {
282 id: "arch-symbolic-1".to_string(),
283 name: "LogicNet".to_string(),
284 paradigm: "symbolic".to_string(),
285 substrate: "prolog".to_string(),
286 fitness_json: "{}".to_string(),
287 lineage_json: "{}".to_string(),
288 created_at: now + 200,
289 },
290 ];
291
292 for arch in &archs {
293 store.store_architecture(arch).unwrap();
294 }
295
296 let neural_archs = store.get_architectures_by_paradigm("neural").unwrap();
297 assert_eq!(neural_archs.len(), 2);
298
299 assert_eq!(neural_archs[0].name, "CNN");
301 assert_eq!(neural_archs[1].name, "Transformer");
302 }
303
304 #[test]
305 fn test_store_and_retrieve_intelligence() {
306 let store = create_test_store();
307 let now = Utc::now().timestamp();
308
309 let arch = StoredArchitecture {
311 id: "arch-intel-001".to_string(),
312 name: "TestArch".to_string(),
313 paradigm: "hybrid".to_string(),
314 substrate: "rust".to_string(),
315 fitness_json: "{}".to_string(),
316 lineage_json: "{}".to_string(),
317 created_at: now,
318 };
319 store.store_architecture(&arch).unwrap();
320
321 let intel = StoredIntelligence {
322 id: "intel-001".to_string(),
323 name: "Alpha".to_string(),
324 arch_id: "arch-intel-001".to_string(),
325 maturity: 0.75,
326 capabilities_json: r#"["reasoning", "learning"]"#.to_string(),
327 memories_json: r#"["mem-001", "mem-002"]"#.to_string(),
328 state_json: r#"{"active": true}"#.to_string(),
329 created_at: now,
330 updated_at: now,
331 };
332
333 store.store_intelligence(&intel).unwrap();
334 let retrieved = store.get_intelligence("intel-001").unwrap();
335
336 assert_eq!(retrieved.name, "Alpha");
337 assert_eq!(retrieved.maturity, 0.75);
338 assert_eq!(retrieved.arch_id, "arch-intel-001");
339 }
340
341 #[test]
342 fn test_get_intelligences_by_arch() {
343 let store = create_test_store();
344 let now = Utc::now().timestamp();
345
346 let arch = StoredArchitecture {
348 id: "arch-multi-001".to_string(),
349 name: "MultiArch".to_string(),
350 paradigm: "neural".to_string(),
351 substrate: "pytorch".to_string(),
352 fitness_json: "{}".to_string(),
353 lineage_json: "{}".to_string(),
354 created_at: now,
355 };
356 store.store_architecture(&arch).unwrap();
357
358 for i in 0..3 {
360 let intel = StoredIntelligence {
361 id: format!("intel-multi-{}", i),
362 name: format!("Intel-{}", i),
363 arch_id: "arch-multi-001".to_string(),
364 maturity: 0.5 + (i as f64 * 0.2),
365 capabilities_json: "[]".to_string(),
366 memories_json: "[]".to_string(),
367 state_json: "{}".to_string(),
368 created_at: now,
369 updated_at: now,
370 };
371 store.store_intelligence(&intel).unwrap();
372 }
373
374 let intels = store.get_intelligences_by_arch("arch-multi-001").unwrap();
375 assert_eq!(intels.len(), 3);
376
377 assert!(intels[0].maturity >= intels[1].maturity);
379 assert!(intels[1].maturity >= intels[2].maturity);
380 }
381
382 #[test]
383 fn test_store_and_retrieve_vector() {
384 let store = create_test_store();
385 let now = Utc::now().timestamp();
386
387 let memory = StoredMemory {
389 id: "mem-vec-001".to_string(),
390 content: "Vector test".to_string(),
391 tier: 1,
392 importance: 0.8,
393 embedding_blob: None,
394 created_at: now,
395 last_accessed: now,
396 };
397 store.store_memory(&memory).unwrap();
398
399 let vector = StoredVector {
401 id: "vec-001".to_string(),
402 memory_id: "mem-vec-001".to_string(),
403 dimensions: 768,
404 data_blob: vec![0u8; 768 * 4], };
406
407 store.store_vector(&vector).unwrap();
408 let retrieved = store.get_vector_by_memory("mem-vec-001").unwrap();
409
410 assert_eq!(retrieved.dimensions, 768);
411 assert_eq!(retrieved.data_blob.len(), 768 * 4);
412 }
413
414 #[test]
415 fn test_store_and_retrieve_reflexion() {
416 let store = create_test_store();
417 let now = Utc::now().timestamp();
418
419 let memory = StoredMemory {
421 id: "mem-reflex-001".to_string(),
422 content: "Reflexion test".to_string(),
423 tier: 1,
424 importance: 0.9,
425 embedding_blob: None,
426 created_at: now,
427 last_accessed: now,
428 };
429 store.store_memory(&memory).unwrap();
430
431 let episode = StoredReflexionEpisode {
433 id: "reflex-001".to_string(),
434 memory_id: "mem-reflex-001".to_string(),
435 trigger: "code_error".to_string(),
436 context: "Syntax error in function".to_string(),
437 action: "Fixed missing semicolon".to_string(),
438 outcome: "Code compiled successfully".to_string(),
439 created_at: now,
440 };
441
442 store.store_reflexion(&episode).unwrap();
443 let episodes = store.get_reflexions_by_memory("mem-reflex-001").unwrap();
444
445 assert_eq!(episodes.len(), 1);
446 assert_eq!(episodes[0].trigger, "code_error");
447 assert_eq!(episodes[0].outcome, "Code compiled successfully");
448 }
449
450 #[test]
451 fn test_store_and_retrieve_causal_edge() {
452 let store = create_test_store();
453 let now = Utc::now().timestamp();
454
455 let mem1 = StoredMemory {
457 id: "mem-cause-001".to_string(),
458 content: "Cause".to_string(),
459 tier: 1,
460 importance: 0.8,
461 embedding_blob: None,
462 created_at: now,
463 last_accessed: now,
464 };
465 let mem2 = StoredMemory {
466 id: "mem-effect-001".to_string(),
467 content: "Effect".to_string(),
468 tier: 1,
469 importance: 0.7,
470 embedding_blob: None,
471 created_at: now,
472 last_accessed: now,
473 };
474 store.store_memory(&mem1).unwrap();
475 store.store_memory(&mem2).unwrap();
476
477 let edge = StoredCausalEdge {
479 id: "edge-001".to_string(),
480 from_memory: "mem-cause-001".to_string(),
481 to_memory: "mem-effect-001".to_string(),
482 weight: 0.9,
483 edge_type: "causal".to_string(),
484 created_at: now,
485 };
486
487 store.store_causal_edge(&edge).unwrap();
488 let edges = store.get_causal_edges_from("mem-cause-001").unwrap();
489
490 assert_eq!(edges.len(), 1);
491 assert_eq!(edges[0].to_memory, "mem-effect-001");
492 assert_eq!(edges[0].weight, 0.9);
493 }
494
495 #[test]
496 fn test_database_statistics() {
497 let store = create_test_store();
498 let now = Utc::now().timestamp();
499
500 let memory = StoredMemory {
502 id: "mem-stats-001".to_string(),
503 content: "Stats test".to_string(),
504 tier: 1,
505 importance: 0.5,
506 embedding_blob: None,
507 created_at: now,
508 last_accessed: now,
509 };
510 store.store_memory(&memory).unwrap();
511
512 let skill = StoredSkill {
513 id: "skill-stats-001".to_string(),
514 name: "test".to_string(),
515 description: "test".to_string(),
516 trigger_pattern: "test".to_string(),
517 success_count: 0,
518 last_used: None,
519 created_at: now,
520 };
521 store.store_skill(&skill).unwrap();
522
523 let stats = store.get_statistics().unwrap();
524 assert_eq!(stats.memory_count, 1);
525 assert_eq!(stats.skill_count, 1);
526 assert_eq!(stats.architecture_count, 0);
527 assert_eq!(stats.intelligence_count, 0);
528 assert_eq!(stats.causal_edge_count, 0);
529 }
530
531 #[test]
532 fn test_backup() {
533 use tempfile::NamedTempFile;
534
535 let store = create_test_store();
536 let now = Utc::now().timestamp();
537
538 let memory = StoredMemory {
540 id: "mem-backup-001".to_string(),
541 content: "Backup test".to_string(),
542 tier: 1,
543 importance: 0.8,
544 embedding_blob: None,
545 created_at: now,
546 last_accessed: now,
547 };
548 store.store_memory(&memory).unwrap();
549
550 let backup_file = NamedTempFile::new().unwrap();
552 let backup_path = backup_file.path().to_str().unwrap();
553 store.backup(backup_path).unwrap();
554
555 let backup_store = OmegaStore::new(backup_path).unwrap();
557 let retrieved = backup_store.get_memory("mem-backup-001").unwrap();
558 assert_eq!(retrieved.content, "Backup test");
559 }
560
561 #[test]
562 fn test_not_found_errors() {
563 let store = create_test_store();
564
565 let result = store.get_memory("nonexistent");
567 assert!(result.is_err());
568 assert!(matches!(result.unwrap_err(), StorageError::NotFound(_)));
569
570 let result = store.get_skill("nonexistent");
572 assert!(result.is_err());
573 assert!(matches!(result.unwrap_err(), StorageError::NotFound(_)));
574
575 let result = store.get_architecture("nonexistent");
577 assert!(result.is_err());
578 assert!(matches!(result.unwrap_err(), StorageError::NotFound(_)));
579
580 let result = store.get_intelligence("nonexistent");
582 assert!(result.is_err());
583 assert!(matches!(result.unwrap_err(), StorageError::NotFound(_)));
584 }
585}