1pub mod chunker;
2pub mod config;
3pub mod embeddings;
4pub mod hooks;
5pub mod profile;
6pub mod search;
7pub mod store;
8pub mod tools;
9pub mod types;
10
11use anyhow::Result;
12use std::sync::Arc;
13
14pub use chunker::TextChunker;
15pub use config::MemoryConfig;
16pub use embeddings::{EmbeddingProvider, MockEmbeddingProvider, OpenAIEmbeddingProvider};
17pub use hooks::{MemoryCaptureHook, MemoryRecallHook};
18pub use profile::UserProfile;
19pub use search::HybridSearcher;
20pub use store::MemoryStore;
21pub use tools::MemoryTools;
22
23pub struct MemorySystem {
24 pub store: Arc<MemoryStore>,
25 pub embedder: Arc<dyn EmbeddingProvider>,
26 pub searcher: Arc<HybridSearcher>,
27 pub profile: Arc<UserProfile>,
28 pub recall_hook: MemoryRecallHook,
29 pub capture_hook: MemoryCaptureHook,
30 pub config: MemoryConfig,
31}
32
33impl MemorySystem {
34 pub fn new(config: &MemoryConfig, embedder: Arc<dyn EmbeddingProvider>) -> Result<Self> {
35 let store = Arc::new(MemoryStore::new(config)?);
36
37 if let Err(e) = store.cleanup(&config.container_tag, config.retention_days, config.max_memories) {
39 tracing::warn!("memory cleanup failed during initialization: {}", e);
40 }
41
42 let searcher = Arc::new(HybridSearcher::new(store.clone(), embedder.clone(), config));
43 let profile = Arc::new(UserProfile::new(store.clone()));
44
45 let recall_hook = MemoryRecallHook::new(searcher.clone(), profile.clone(), config.clone());
46 let capture_hook = MemoryCaptureHook::new(
47 store.clone(),
48 embedder.clone(),
49 profile.clone(),
50 config.clone(),
51 );
52
53 Ok(Self {
54 store,
55 embedder,
56 searcher,
57 profile,
58 recall_hook,
59 capture_hook,
60 config: config.clone(),
61 })
62 }
63
64 pub fn new_in_memory(
65 config: &MemoryConfig,
66 embedder: Arc<dyn EmbeddingProvider>,
67 ) -> Result<Self> {
68 let store = Arc::new(MemoryStore::new_in_memory(config.embedding_dimension)?);
69 let searcher = Arc::new(HybridSearcher::new(store.clone(), embedder.clone(), config));
70 let profile = Arc::new(UserProfile::new(store.clone()));
71
72 let recall_hook = MemoryRecallHook::new(searcher.clone(), profile.clone(), config.clone());
73 let capture_hook = MemoryCaptureHook::new(
74 store.clone(),
75 embedder.clone(),
76 profile.clone(),
77 config.clone(),
78 );
79
80 Ok(Self {
81 store,
82 embedder,
83 searcher,
84 profile,
85 recall_hook,
86 capture_hook,
87 config: config.clone(),
88 })
89 }
90
91 pub fn tools(&self) -> MemoryTools {
92 MemoryTools::new(
93 self.store.clone(),
94 self.searcher.clone(),
95 self.embedder.clone(),
96 self.profile.clone(),
97 self.config.clone(),
98 )
99 }
100}