1use async_trait::async_trait;
4use serde_json::Value;
5
6#[derive(Debug, Clone)]
8pub struct MemoryEntry {
9 pub key: String,
10 pub value: String,
11 pub metadata: Option<Value>,
12 pub created_at: chrono::DateTime<chrono::Utc>,
13}
14
15#[derive(Debug, Clone)]
17pub struct EmbeddingEntry {
18 pub namespace: String,
19 pub key: String,
20 pub vector: Vec<f32>,
21 pub text: String,
22 pub created_at: chrono::DateTime<chrono::Utc>,
23}
24
25#[derive(Debug, Clone)]
27pub struct FileIndex {
28 pub path: String,
29 pub hash: String,
30 pub last_indexed: chrono::DateTime<chrono::Utc>,
31}
32
33#[derive(Debug, Clone)]
35pub struct Chunk {
36 pub file_path: String,
37 pub start_line: u32,
38 pub end_line: u32,
39 pub content: String,
40 pub embedding: Option<Vec<f32>>,
41 pub created_at: chrono::DateTime<chrono::Utc>,
42}
43
44#[derive(Debug, Clone)]
45pub struct ConversationSearchHit {
46 pub chat_id: String,
47 pub role: String,
48 pub content: String,
49 pub created_at: chrono::DateTime<chrono::Utc>,
50}
51
52#[async_trait]
54pub trait MemoryBackend: Send + Sync {
55 fn as_any(&self) -> &dyn std::any::Any;
57
58 async fn store(
60 &self,
61 namespace: &str,
62 key: &str,
63 value: &str,
64 metadata: Option<Value>,
65 ) -> anyhow::Result<()>;
66
67 async fn recall(&self, namespace: &str, key: &str) -> anyhow::Result<Option<MemoryEntry>>;
69
70 async fn search(
72 &self,
73 namespace: &str,
74 query: &str,
75 limit: usize,
76 ) -> anyhow::Result<Vec<MemoryEntry>>;
77
78 async fn forget(&self, namespace: &str, key: &str) -> anyhow::Result<()>;
80
81 async fn list(&self, namespace: &str) -> anyhow::Result<Vec<MemoryEntry>>;
83
84 async fn store_conversation(
86 &self,
87 chat_id: &str,
88 sender_id: &str,
89 role: &str,
90 content: &str,
91 ) -> anyhow::Result<()>;
92
93 async fn store_conversation_batch(
95 &self,
96 entries: &[(&str, &str, &str, &str)],
97 ) -> anyhow::Result<()> {
98 for (chat_id, sender_id, role, content) in entries {
99 self.store_conversation(chat_id, sender_id, role, content)
100 .await?;
101 }
102 Ok(())
103 }
104
105 async fn get_conversation_history(
107 &self,
108 chat_id: &str,
109 limit: usize,
110 ) -> anyhow::Result<Vec<(String, String)>>;
111
112 async fn clear_conversation(&self, chat_id: &str) -> anyhow::Result<()> {
117 let _ = chat_id;
118 anyhow::bail!("clearing a conversation is unsupported by this memory backend")
119 }
120
121 async fn search_conversations(
122 &self,
123 query: &str,
124 limit: usize,
125 chat_id: Option<&str>,
126 ) -> anyhow::Result<Vec<ConversationSearchHit>> {
127 let _ = (query, limit, chat_id);
128 Ok(Vec::new())
129 }
130
131 async fn get_sticker_cache(&self, sticker_id: &str) -> anyhow::Result<Option<String>>;
133
134 async fn store_sticker_cache(
136 &self,
137 sticker_id: &str,
138 file_id: &str,
139 description: &str,
140 ) -> anyhow::Result<()>;
141
142 async fn store_embedding(
150 &self,
151 namespace: &str,
152 key: &str,
153 vector: &[f32],
154 text: &str,
155 model: &str,
156 ) -> anyhow::Result<()> {
157 let _ = (namespace, key, vector, text, model);
158 Ok(())
159 }
160
161 async fn search_embeddings(
167 &self,
168 namespace: &str,
169 query_vector: &[f32],
170 limit: usize,
171 ) -> anyhow::Result<Vec<EmbeddingEntry>> {
172 let _ = (namespace, query_vector, limit);
173 Ok(Vec::new())
174 }
175
176 async fn store_file_index(&self, path: &str, hash: &str) -> anyhow::Result<()> {
180 let _ = (path, hash);
181 Ok(())
182 }
183
184 async fn get_file_index(&self, path: &str) -> anyhow::Result<Option<FileIndex>> {
186 let _ = path;
187 Ok(None)
188 }
189
190 async fn store_chunk(
194 &self,
195 file_path: &str,
196 start_line: u32,
197 end_line: u32,
198 content: &str,
199 embedding: Option<&[f32]>,
200 ) -> anyhow::Result<()> {
201 let _ = (file_path, start_line, end_line, content, embedding);
202 Ok(())
203 }
204
205 async fn get_chunks_for_file(&self, file_path: &str) -> anyhow::Result<Vec<Chunk>> {
207 let _ = file_path;
208 Ok(Vec::new())
209 }
210
211 async fn delete_chunks_for_file(&self, file_path: &str) -> anyhow::Result<()> {
213 let _ = file_path;
214 Ok(())
215 }
216}