Skip to main content

mag/memory_core/
traits.rs

1use anyhow::Result;
2use async_trait::async_trait;
3
4use super::domain::{
5    BackupInfo, CheckpointInput, GraphNode, ListResult, MemoryInput, MemoryUpdate, Relationship,
6    SearchOptions, SearchResult, SemanticResult,
7};
8
9/// Trait for ingesting raw content into the memory system.
10#[async_trait]
11pub trait Ingestor: Send + Sync {
12    /// Ingests the provided content and returns a processed string.
13    async fn ingest(&self, content: &str) -> Result<String>;
14}
15
16/// Trait for processing ingested content (e.g., summarization, embedding).
17#[async_trait]
18pub trait Processor: Send + Sync {
19    /// Processes the input string and returns a refined result.
20    async fn process(&self, input: &str) -> Result<String>;
21}
22
23/// Trait for storing processed memory data.
24#[async_trait]
25pub trait Storage: Send + Sync {
26    async fn store(&self, id: &str, data: &str, input: &MemoryInput) -> Result<()>;
27}
28
29/// Trait for retrieving stored memory data.
30#[async_trait]
31pub trait Retriever: Send + Sync {
32    /// Retrieves the data associated with the given ID.
33    async fn retrieve(&self, id: &str) -> Result<String>;
34}
35
36/// Trait for searching stored memory data.
37#[async_trait]
38pub trait Searcher: Send + Sync {
39    /// Searches for memories matching the query string.
40    async fn search(
41        &self,
42        query: &str,
43        limit: usize,
44        opts: &SearchOptions,
45    ) -> Result<Vec<SearchResult>>;
46}
47
48#[async_trait]
49pub trait Recents: Send + Sync {
50    async fn recent(&self, limit: usize, opts: &SearchOptions) -> Result<Vec<SearchResult>>;
51}
52
53#[async_trait]
54pub trait SemanticSearcher: Send + Sync {
55    async fn semantic_search(
56        &self,
57        query: &str,
58        limit: usize,
59        opts: &SearchOptions,
60    ) -> Result<Vec<SemanticResult>>;
61}
62
63#[async_trait]
64pub trait GraphTraverser: Send + Sync {
65    async fn traverse(
66        &self,
67        start_id: &str,
68        max_hops: usize,
69        min_weight: f64,
70        edge_types: Option<&[String]>,
71    ) -> Result<Vec<GraphNode>>;
72}
73
74#[async_trait]
75pub trait SimilarFinder: Send + Sync {
76    async fn find_similar(&self, memory_id: &str, limit: usize) -> Result<Vec<SemanticResult>>;
77}
78
79#[async_trait]
80pub trait PhraseSearcher: Send + Sync {
81    async fn phrase_search(
82        &self,
83        phrase: &str,
84        limit: usize,
85        opts: &SearchOptions,
86    ) -> Result<Vec<SearchResult>>;
87}
88
89#[async_trait]
90pub trait AdvancedSearcher: Send + Sync {
91    async fn advanced_search(
92        &self,
93        query: &str,
94        limit: usize,
95        opts: &SearchOptions,
96    ) -> Result<Vec<SemanticResult>>;
97}
98
99/// Trait for deleting stored memories.
100#[async_trait]
101pub trait Deleter: Send + Sync {
102    /// Deletes the memory with the given ID. Returns `true` if a row was removed.
103    async fn delete(&self, id: &str) -> Result<bool>;
104}
105
106/// Trait for updating stored memory content and tags.
107#[async_trait]
108pub trait Updater: Send + Sync {
109    /// Updates an existing memory. At least one of content, tags, importance, or metadata must be provided.
110    async fn update(&self, id: &str, input: &MemoryUpdate) -> Result<()>;
111}
112
113/// Trait for querying memories by tag.
114#[async_trait]
115pub trait Tagger: Send + Sync {
116    /// Returns memories whose tags contain **all** of the supplied tags.
117    async fn get_by_tags(
118        &self,
119        tags: &[String],
120        limit: usize,
121        opts: &SearchOptions,
122    ) -> Result<Vec<SearchResult>>;
123}
124
125/// Trait for paginated listing of memories.
126#[async_trait]
127pub trait Lister: Send + Sync {
128    /// Lists memories with pagination, returning the page and total count.
129    async fn list(&self, offset: usize, limit: usize, opts: &SearchOptions) -> Result<ListResult>;
130}
131
132/// Trait for querying relationships of a memory.
133#[async_trait]
134pub trait RelationshipQuerier: Send + Sync {
135    /// Returns all relationships where `memory_id` is either source or target.
136    async fn get_relationships(&self, memory_id: &str) -> Result<Vec<Relationship>>;
137}
138
139#[async_trait]
140pub trait VersionChainQuerier: Send + Sync {
141    /// Returns the full version chain for a memory, ordered by created_at ascending.
142    /// Includes the memory itself and all versions in its chain.
143    async fn get_version_chain(&self, memory_id: &str) -> Result<Vec<SearchResult>>;
144
145    /// Manually supersede an old memory with a new one.
146    /// Creates SUPERSEDES relationship and sets superseded_by_id on the old memory.
147    #[allow(dead_code)]
148    async fn supersede_memory(&self, old_id: &str, new_id: &str) -> Result<()>;
149}
150
151#[async_trait]
152pub trait FeedbackRecorder: Send + Sync {
153    async fn record_feedback(
154        &self,
155        memory_id: &str,
156        rating: &str,
157        reason: Option<&str>,
158    ) -> Result<serde_json::Value>;
159}
160
161#[async_trait]
162pub trait ExpirationSweeper: Send + Sync {
163    async fn sweep_expired(&self) -> Result<usize>;
164}
165
166#[async_trait]
167pub trait ProfileManager: Send + Sync {
168    async fn get_profile(&self) -> Result<serde_json::Value>;
169    async fn set_profile(&self, updates: &serde_json::Value) -> Result<()>;
170}
171
172#[async_trait]
173pub trait CheckpointManager: Send + Sync {
174    async fn save_checkpoint(&self, input: CheckpointInput) -> Result<String>;
175    async fn resume_task(
176        &self,
177        query: &str,
178        project: Option<&str>,
179        limit: usize,
180    ) -> Result<Vec<serde_json::Value>>;
181}
182
183#[async_trait]
184pub trait ReminderManager: Send + Sync {
185    async fn create_reminder(
186        &self,
187        text: &str,
188        duration_str: &str,
189        context: Option<&str>,
190        session_id: Option<&str>,
191        project: Option<&str>,
192    ) -> Result<serde_json::Value>;
193    async fn list_reminders(&self, status: Option<&str>) -> Result<Vec<serde_json::Value>>;
194    async fn dismiss_reminder(&self, reminder_id: &str) -> Result<serde_json::Value>;
195}
196
197#[async_trait]
198pub trait LessonQuerier: Send + Sync {
199    async fn query_lessons(
200        &self,
201        task: Option<&str>,
202        project: Option<&str>,
203        exclude_session: Option<&str>,
204        agent_type: Option<&str>,
205        limit: usize,
206    ) -> Result<Vec<serde_json::Value>>;
207}
208
209/// Maintenance operations for memory store housekeeping.
210#[async_trait]
211pub trait MaintenanceManager: Send + Sync {
212    /// Check database health: size, integrity, node count vs limits.
213    async fn check_health(
214        &self,
215        warn_mb: f64,
216        critical_mb: f64,
217        max_nodes: i64,
218    ) -> Result<serde_json::Value>;
219    /// Prune zero-access memories older than `prune_days` and cap session summaries.
220    async fn consolidate(&self, prune_days: i64, max_summaries: i64) -> Result<serde_json::Value>;
221    /// Merge near-duplicate memories of a given event type using Jaccard similarity.
222    async fn compact(
223        &self,
224        event_type: &str,
225        similarity_threshold: f64,
226        min_cluster_size: usize,
227        dry_run: bool,
228    ) -> Result<serde_json::Value>;
229    /// Delete all memories (and their relationships) for a given session.
230    async fn clear_session(&self, session_id: &str) -> Result<usize>;
231    /// Auto-compact: sweep all event types that have dedup thresholds,
232    /// using embedding cosine similarity. Triggered when memory count
233    /// exceeds `count_threshold`. Returns summary of compacted clusters.
234    async fn auto_compact(
235        &self,
236        count_threshold: usize,
237        dry_run: bool,
238    ) -> Result<serde_json::Value>;
239}
240
241/// Session startup briefing provider.
242#[async_trait]
243pub trait WelcomeProvider: Send + Sync {
244    /// Generate a welcome briefing with recent activity, profile, and pending reminders.
245    async fn welcome(
246        &self,
247        session_id: Option<&str>,
248        project: Option<&str>,
249    ) -> Result<serde_json::Value>;
250}
251
252/// Manages database backup, rotation, and restore.
253#[async_trait]
254pub trait BackupManager: Send + Sync {
255    /// Create a binary backup of the database file, returning backup metadata.
256    async fn create_backup(&self) -> Result<BackupInfo>;
257    /// Rotate backups, keeping only the `max_count` most recent. Returns the number removed.
258    async fn rotate_backups(&self, max_count: usize) -> Result<usize>;
259    /// List available backups with path and size.
260    async fn list_backups(&self) -> Result<Vec<BackupInfo>>;
261    /// Restore from a backup file. Creates a safety backup of the current DB first.
262    async fn restore_backup(&self, backup_path: &std::path::Path) -> Result<()>;
263    /// Run automatic startup backup if needed (>24h since last). Returns backup path if created.
264    async fn maybe_startup_backup(&self) -> Result<Option<BackupInfo>>;
265}
266
267/// Extended statistics beyond basic counts.
268#[async_trait]
269pub trait StatsProvider: Send + Sync {
270    /// Per-event-type memory counts.
271    async fn type_stats(&self) -> Result<serde_json::Value>;
272    /// Per-session memory counts (top 20).
273    async fn session_stats(&self) -> Result<serde_json::Value>;
274    /// Activity digest for a given period.
275    async fn weekly_digest(&self, days: i64) -> Result<serde_json::Value>;
276    /// Access rate analysis: zero-access %, top-accessed, by-type breakdown.
277    async fn access_rate_stats(&self) -> Result<serde_json::Value>;
278}