1pub mod backend;
2pub mod chunker;
3pub mod config;
4pub mod embeddings;
5pub mod episodic;
6pub mod markdown;
7pub mod none;
8pub mod sqlite;
9pub mod traits;
10pub mod vector;
11
12pub use backend::{classify_memory_backend, default_memory_backend_key, MemoryBackendKind};
13pub use chunker::{chunk_markdown, Chunk};
14pub use embeddings::{
15 create_embedding_provider, EmbeddingProvider, NoopEmbedding, OpenAiEmbedding,
16};
17pub use episodic::{
18 EpisodicMemoryConfig, EpisodicMemoryConfigBuilder, EpisodicMemoryStore, SessionSnapshotConfig,
19};
20pub use markdown::MarkdownMemory;
21pub use none::NoneMemory;
22pub use sqlite::SqliteMemory;
23pub use traits::{Memory, MemoryCategory, MemoryEntry};
24pub use vector::{bytes_to_vec, cosine_similarity, hybrid_merge, vec_to_bytes, ScoredResult};
25
26use std::path::Path;
27
28pub fn create_memory(backend: &str, workspace_dir: &Path) -> anyhow::Result<Box<dyn Memory>> {
29 match classify_memory_backend(backend) {
30 MemoryBackendKind::Sqlite => Ok(Box::new(SqliteMemory::new(workspace_dir)?)),
31 MemoryBackendKind::Markdown => Ok(Box::new(MarkdownMemory::new(workspace_dir))),
32 MemoryBackendKind::None => Ok(Box::new(NoneMemory::new())),
33 MemoryBackendKind::Unknown => {
34 tracing::warn!(
35 "Unknown memory backend '{}', falling back to markdown",
36 backend
37 );
38 Ok(Box::new(MarkdownMemory::new(workspace_dir)))
39 }
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn factory_sqlite() {
49 let tmp = tempfile::TempDir::new().unwrap();
50 let mem = create_memory("sqlite", tmp.path()).unwrap();
51 assert_eq!(mem.name(), "sqlite");
52 }
53
54 #[test]
55 fn factory_markdown() {
56 let tmp = tempfile::TempDir::new().unwrap();
57 let mem = create_memory("markdown", tmp.path()).unwrap();
58 assert_eq!(mem.name(), "markdown");
59 }
60
61 #[test]
62 fn factory_none() {
63 let tmp = tempfile::TempDir::new().unwrap();
64 let mem = create_memory("none", tmp.path()).unwrap();
65 assert_eq!(mem.name(), "none");
66 }
67
68 #[test]
69 fn factory_unknown_falls_back_to_markdown() {
70 let tmp = tempfile::TempDir::new().unwrap();
71 let mem = create_memory("redis", tmp.path()).unwrap();
72 assert_eq!(mem.name(), "markdown");
73 }
74}