oxios_memory/memory/backend.rs
1//! Memory backend abstraction — the strategy pattern for storage.
2//!
3//! `MemoryBackend` unifies the JSON file-based path and the SQLite backend
4//! behind a single trait. `MemoryManager` delegates all CRUD to whichever
5//! backend is active, eliminating `#[cfg]` branching in business logic.
6//!
7//! The JSON path is implemented by `MemoryManager` itself (via `state_store`).
8//! The SQLite path is implemented by `SqliteMemoryStore`.
9
10use anyhow::Result;
11
12use crate::memory::types::{MemoryEntry, MemoryTier, MemoryType};
13
14/// Storage backend strategy for memory CRUD.
15///
16/// Implementors provide the core read/write operations. The trait is
17/// dyn-compatible (no generics) so `MemoryManager` can hold
18/// `Option<Arc<dyn MemoryBackend>>`.
19#[async_trait::async_trait]
20pub trait MemoryBackend: Send + Sync {
21 /// Store a memory entry. Returns the entry ID.
22 async fn remember(&self, entry: &MemoryEntry) -> Result<String>;
23
24 /// Retrieve a single memory by ID and type.
25 fn get(&self, id: &str, memory_type: MemoryType) -> Result<Option<MemoryEntry>>;
26
27 /// Retrieve a single memory by ID (searches all types).
28 fn get_by_id(&self, id: &str) -> Result<Option<MemoryEntry>>;
29
30 /// Delete a memory entry. Returns true if it existed.
31 fn forget(&self, id: &str, memory_type: MemoryType) -> Result<bool>;
32
33 /// List memories of a given type, most recent first.
34 fn list(&self, memory_type: MemoryType, limit: usize) -> Result<Vec<MemoryEntry>>;
35
36 /// Search memories by query (semantic + keyword hybrid).
37 async fn search(
38 &self,
39 query: &str,
40 memory_type: Option<MemoryType>,
41 limit: usize,
42 ) -> Result<Vec<MemoryEntry>>;
43
44 /// Recall relevant memories for a query.
45 async fn recall(&self, query: &str, max_recall: usize) -> Result<Vec<MemoryEntry>>;
46
47 /// Recall with Flash Attention re-ranking.
48 async fn recall_with_rerank(&self, query: &str, max_recall: usize) -> Result<Vec<MemoryEntry>>;
49
50 /// Blend recalled memories into the system prompt.
51 fn blend_into_prompt(&self, memories: &[MemoryEntry], system_prompt: &str) -> String;
52
53 /// Check if a memory entry with identical content already exists.
54 async fn is_duplicate(&self, content: &str) -> bool;
55
56 /// Store a memory entry only if no duplicate content exists.
57 async fn remember_unique(&self, entry: &MemoryEntry) -> Result<Option<String>>;
58
59 /// List memories by tier.
60 fn list_by_tier(&self, tier: MemoryTier, limit: usize) -> Result<Vec<MemoryEntry>>;
61}