1use crate::{
4 ApiAddRequest, ApiSearchRequest, AuditEvent, AuditListOptions, ForgetMemoryRequest,
5 ForgetMemoryResponse, GetMemoryRequest, GetMemoryResponse, GraphDirection, GraphNeighbor,
6 GraphNeighborsRequest, GraphNeighborsResponse, GraphPath, GraphPathRequest, GraphPathResponse,
7 GraphPathsRequest, GraphPathsResponse, MemoryEdge, MemoryNode, MemoryResponse, SearchResponse,
8 UpdateMemoryRequest, UpdateMemoryResponse,
9};
10use async_trait::async_trait;
11use std::collections::HashMap;
12
13#[derive(Debug, Clone)]
15pub struct VecSearchHit {
16 pub id: String,
17 pub score: f64,
18}
19
20#[async_trait]
22pub trait GraphStore: Send + Sync {
23 async fn add_node(
25 &self,
26 id: &str,
27 memory: &str,
28 metadata: &HashMap<String, serde_json::Value>,
29 user_name: Option<&str>,
30 ) -> Result<(), GraphStoreError>;
31
32 async fn add_nodes_batch(
34 &self,
35 nodes: &[MemoryNode],
36 user_name: Option<&str>,
37 ) -> Result<(), GraphStoreError>;
38
39 async fn add_edges_batch(
41 &self,
42 edges: &[MemoryEdge],
43 user_name: Option<&str>,
44 ) -> Result<(), GraphStoreError>;
45
46 async fn get_node(
48 &self,
49 id: &str,
50 include_embedding: bool,
51 ) -> Result<Option<MemoryNode>, GraphStoreError>;
52
53 async fn get_nodes(
55 &self,
56 ids: &[String],
57 include_embedding: bool,
58 ) -> Result<Vec<MemoryNode>, GraphStoreError>;
59
60 async fn get_neighbors(
62 &self,
63 id: &str,
64 relation: Option<&str>,
65 direction: GraphDirection,
66 limit: usize,
67 include_embedding: bool,
68 user_name: Option<&str>,
69 ) -> Result<Vec<GraphNeighbor>, GraphStoreError>;
70
71 async fn shortest_path(
73 &self,
74 source_id: &str,
75 target_id: &str,
76 relation: Option<&str>,
77 direction: GraphDirection,
78 max_depth: usize,
79 include_deleted: bool,
80 user_name: Option<&str>,
81 ) -> Result<Option<GraphPath>, GraphStoreError>;
82
83 async fn find_paths(
85 &self,
86 source_id: &str,
87 target_id: &str,
88 relation: Option<&str>,
89 direction: GraphDirection,
90 max_depth: usize,
91 top_k: usize,
92 include_deleted: bool,
93 user_name: Option<&str>,
94 ) -> Result<Vec<GraphPath>, GraphStoreError>;
95
96 async fn search_by_embedding(
98 &self,
99 vector: &[f32],
100 top_k: usize,
101 user_name: Option<&str>,
102 ) -> Result<Vec<VecSearchHit>, GraphStoreError>;
103
104 async fn get_all_memory_items(
106 &self,
107 scope: &str,
108 user_name: &str,
109 include_embedding: bool,
110 ) -> Result<Vec<MemoryNode>, GraphStoreError>;
111
112 async fn update_node(
114 &self,
115 id: &str,
116 fields: &HashMap<String, serde_json::Value>,
117 user_name: Option<&str>,
118 ) -> Result<(), GraphStoreError>;
119
120 async fn delete_node(&self, id: &str, user_name: Option<&str>) -> Result<(), GraphStoreError>;
123
124 async fn delete_edges_by_node(
126 &self,
127 id: &str,
128 user_name: Option<&str>,
129 ) -> Result<usize, GraphStoreError>;
130}
131
132#[async_trait]
134pub trait VecStore: Send + Sync {
135 async fn add(
137 &self,
138 items: &[VecStoreItem],
139 collection: Option<&str>,
140 ) -> Result<(), VecStoreError>;
141
142 async fn search(
144 &self,
145 query_vector: &[f32],
146 top_k: usize,
147 filter: Option<&HashMap<String, serde_json::Value>>,
148 collection: Option<&str>,
149 ) -> Result<Vec<VecSearchHit>, VecStoreError>;
150
151 async fn get_by_ids(
153 &self,
154 ids: &[String],
155 collection: Option<&str>,
156 ) -> Result<Vec<VecStoreItem>, VecStoreError>;
157
158 async fn delete(&self, ids: &[String], collection: Option<&str>) -> Result<(), VecStoreError>;
160
161 async fn upsert(
163 &self,
164 items: &[VecStoreItem],
165 collection: Option<&str>,
166 ) -> Result<(), VecStoreError>;
167}
168
169#[derive(Clone, Debug)]
171pub struct VecStoreItem {
172 pub id: String,
173 pub vector: Vec<f32>,
174 pub payload: HashMap<String, serde_json::Value>,
175}
176
177#[async_trait]
179pub trait Embedder: Send + Sync {
180 async fn embed(&self, text: &str) -> Result<Vec<f32>, EmbedderError> {
182 let v = self.embed_batch(&[text.to_string()]).await?;
183 v.into_iter().next().ok_or(EmbedderError::EmptyResponse)
184 }
185
186 async fn embed_batch(&self, texts: &[String]) -> Result<Vec<Vec<f32>>, EmbedderError>;
188}
189
190#[async_trait]
192pub trait MemCube: Send + Sync {
193 async fn add_memories(&self, req: &ApiAddRequest) -> Result<MemoryResponse, MemCubeError>;
195
196 async fn search_memories(&self, req: &ApiSearchRequest)
198 -> Result<SearchResponse, MemCubeError>;
199
200 async fn update_memory(
202 &self,
203 req: &UpdateMemoryRequest,
204 ) -> Result<UpdateMemoryResponse, MemCubeError>;
205
206 async fn forget_memory(
208 &self,
209 req: &ForgetMemoryRequest,
210 ) -> Result<ForgetMemoryResponse, MemCubeError>;
211
212 async fn get_memory(&self, req: &GetMemoryRequest) -> Result<GetMemoryResponse, MemCubeError>;
214
215 async fn graph_neighbors(
217 &self,
218 req: &GraphNeighborsRequest,
219 ) -> Result<GraphNeighborsResponse, MemCubeError>;
220
221 async fn graph_path(&self, req: &GraphPathRequest) -> Result<GraphPathResponse, MemCubeError>;
223
224 async fn graph_paths(
226 &self,
227 req: &GraphPathsRequest,
228 ) -> Result<GraphPathsResponse, MemCubeError>;
229}
230
231#[derive(Debug, thiserror::Error)]
232pub enum GraphStoreError {
233 #[error("graph store error: {0}")]
234 Other(String),
235}
236
237#[derive(Debug, thiserror::Error)]
238pub enum VecStoreError {
239 #[error("vector store error: {0}")]
240 Other(String),
241}
242
243#[derive(Debug, thiserror::Error)]
244pub enum EmbedderError {
245 #[error("embedder error: {0}")]
246 Other(String),
247 #[error("empty response")]
248 EmptyResponse,
249}
250
251#[async_trait]
253pub trait AuditStore: Send + Sync {
254 async fn append(&self, event: AuditEvent) -> Result<(), AuditStoreError>;
256
257 async fn list(&self, opts: &AuditListOptions) -> Result<Vec<AuditEvent>, AuditStoreError>;
259}
260
261#[derive(Debug, thiserror::Error)]
262pub enum AuditStoreError {
263 #[error("audit store error: {0}")]
264 Other(String),
265}
266
267#[derive(Debug, thiserror::Error)]
268pub enum MemCubeError {
269 #[error("mem cube error: {0}")]
270 Other(String),
271 #[error("bad request: {0}")]
272 BadRequest(String),
273 #[error("not found: {0}")]
274 NotFound(String),
275 #[error("embedder: {0}")]
276 Embedder(#[from] EmbedderError),
277 #[error("graph: {0}")]
278 Graph(#[from] GraphStoreError),
279 #[error("vector: {0}")]
280 Vec(#[from] VecStoreError),
281}