1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Clone, Debug, Default)]
6pub struct MemoryScope {
7 pub tenant_id: Option<String>,
8 pub session_ids: Option<Vec<String>>,
9 pub tiers: Option<Vec<String>>,
10 pub from_utc: Option<DateTime<Utc>>,
11 pub to_utc: Option<DateTime<Utc>>,
12}
13
14#[derive(Clone, Copy, Debug, Default)]
15pub struct MemoryAvecState {
16 pub stability: f32,
17 pub friction: f32,
18 pub logic: f32,
19 pub autonomy: f32,
20}
21
22#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
23pub enum MemoryFallbackPolicy {
24 Never,
25 #[default]
26 OnEmpty,
27 Always,
28}
29
30#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
31pub enum MemoryStrictnessMode {
32 Precision,
33 #[default]
34 Balanced,
35 Recall,
36}
37
38#[derive(Clone, Debug, Default)]
39pub struct MemoryMetricRange {
40 pub min: Option<f32>,
41 pub max: Option<f32>,
42}
43
44#[derive(Clone, Debug, Default)]
45pub struct MemoryFilter {
46 pub has_embedding: Option<bool>,
47 pub embedding_model: Option<String>,
48 pub psi: Option<MemoryMetricRange>,
49 pub rho: Option<MemoryMetricRange>,
50 pub kappa: Option<MemoryMetricRange>,
51 pub text_contains: Option<String>,
52 pub tags_contains: Option<Vec<String>>,
53 pub has_tag: Option<String>,
54 pub indexed_tags: Option<Vec<String>>,
55 pub tag_prefix: Option<String>,
56 pub has_semantic_links: Option<bool>,
57 pub link_rel: Option<String>,
58 pub link_target: Option<String>,
59 pub links_to_ref: Option<String>,
60}
61
62#[derive(Clone, Debug, Default, Serialize, Deserialize)]
63pub struct MemorySemanticLink {
64 pub rel: String,
65 pub target: String,
66 pub confidence: Option<f32>,
67}
68
69#[derive(Clone, Debug)]
70pub struct MemoryRecallRequest {
71 pub scope: MemoryScope,
72 pub filter: MemoryFilter,
73 pub current_avec: Option<MemoryAvecState>,
74 pub query_text: Option<String>,
75 pub limit: usize,
76 pub alpha: f32,
77 pub beta: f32,
78 pub gamma: f32,
79 pub fallback_policy: MemoryFallbackPolicy,
80 pub strictness: MemoryStrictnessMode,
81 pub include_explain: bool,
82}
83
84impl Default for MemoryRecallRequest {
85 fn default() -> Self {
86 Self {
87 scope: MemoryScope::default(),
88 filter: MemoryFilter::default(),
89 current_avec: None,
90 query_text: None,
91 limit: 20,
92 alpha: 0.7,
93 beta: 0.3,
94 gamma: 0.0,
95 fallback_policy: MemoryFallbackPolicy::OnEmpty,
96 strictness: MemoryStrictnessMode::Balanced,
97 include_explain: false,
98 }
99 }
100}
101
102#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
103pub enum MemorySortField {
104 #[default]
105 Timestamp,
106 UpdatedAt,
107 Psi,
108 Rho,
109 Kappa,
110}
111
112#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
113pub enum MemorySortDirection {
114 Asc,
115 #[default]
116 Desc,
117}
118
119#[derive(Clone, Debug)]
120pub struct MemoryFindRequest {
121 pub scope: MemoryScope,
122 pub filter: MemoryFilter,
123 pub limit: usize,
124 pub cursor: Option<String>,
125 pub sort_field: MemorySortField,
126 pub sort_direction: MemorySortDirection,
127}
128
129impl Default for MemoryFindRequest {
130 fn default() -> Self {
131 Self {
132 scope: MemoryScope::default(),
133 filter: MemoryFilter::default(),
134 limit: 50,
135 cursor: None,
136 sort_field: MemorySortField::Timestamp,
137 sort_direction: MemorySortDirection::Desc,
138 }
139 }
140}
141
142#[derive(Clone, Debug, Default)]
143pub struct MemoryNode {
144 pub raw: String,
145 pub session_id: String,
146 pub tier: String,
147 pub timestamp: DateTime<Utc>,
148 pub compression_depth: i32,
149 pub parent_node_id: Option<String>,
150 pub sync_key: String,
151 pub context_summary: Option<String>,
152 pub semantic_tags: Option<Vec<String>>,
153 pub semantic_links: Option<Vec<MemorySemanticLink>>,
154 pub embedding_model: Option<String>,
155 pub embedding_dimensions: Option<usize>,
156 pub embedded_at: Option<DateTime<Utc>>,
157 pub rho: f32,
158 pub kappa: f32,
159 pub psi: f32,
160 pub user_avec: MemoryAvecState,
161 pub model_avec: MemoryAvecState,
162 pub compression_avec: Option<MemoryAvecState>,
163 pub updated_at: DateTime<Utc>,
164}
165
166#[derive(Clone, Debug, Default)]
167pub struct MemoryFindResponse {
168 pub retrieved: usize,
169 pub has_more: bool,
170 pub next_cursor: Option<String>,
171 pub nodes: Vec<MemoryNode>,
172 pub node_sync_keys: Vec<String>,
173}
174
175#[derive(Clone, Debug, Default)]
176pub struct MemoryRecallResponse {
177 pub retrieved: usize,
178 pub next_cursor: Option<String>,
179 pub has_more: bool,
180 pub retrieval_path: Option<String>,
181 pub fallback_triggered: bool,
182 pub fallback_reason: Option<String>,
183 pub nodes: Vec<MemoryNode>,
184 pub node_sync_keys: Vec<String>,
185}
186
187#[derive(Clone, Debug)]
188pub struct MemoryStoreRequest {
189 pub session_id: String,
190 pub raw_node: String,
191}
192
193#[derive(Clone, Debug, Default)]
194pub struct MemoryStoreResponse {
195 pub node_id: String,
196 pub psi: f32,
197 pub valid: bool,
198 pub validation_error: Option<String>,
199}
200
201#[derive(Clone, Debug, Default)]
202pub struct MemoryAggregateRequest {
203 pub scope: MemoryScope,
204 pub max_groups: usize,
205 pub max_nodes: usize,
206}
207
208#[derive(Clone, Debug, Default)]
209pub struct MemoryAggregateResponse {
210 pub total_groups: usize,
211 pub scanned_nodes: usize,
212}
213
214#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
215pub enum MemoryTransformOperation {
216 #[default]
217 EmbedBackfill,
218 ReindexEmbeddings,
219 EmbedTagBackfill,
220 ReindexTagEmbeddings,
221}
222
223#[derive(Clone, Debug)]
224pub struct MemoryTransformRequest {
225 pub scope: MemoryScope,
226 pub filter: MemoryFilter,
227 pub operation: MemoryTransformOperation,
228 pub dry_run: bool,
229 pub batch_size: usize,
230 pub max_nodes: usize,
231 pub provider_id: Option<String>,
232 pub model: Option<String>,
233}
234
235impl Default for MemoryTransformRequest {
236 fn default() -> Self {
237 Self {
238 scope: MemoryScope::default(),
239 filter: MemoryFilter::default(),
240 operation: MemoryTransformOperation::EmbedBackfill,
241 dry_run: true,
242 batch_size: 100,
243 max_nodes: 5000,
244 provider_id: None,
245 model: None,
246 }
247 }
248}
249
250#[derive(Clone, Debug, Default)]
251pub struct MemoryTransformResponse {
252 pub scanned: usize,
253 pub selected: usize,
254 pub updated: usize,
255 pub skipped: usize,
256 pub failed: usize,
257 pub duplicate: usize,
258 pub failures: Vec<String>,
259}
260
261#[derive(Clone, Debug, Default)]
262pub struct MemoryRollupRequest {
263 pub scope: MemoryScope,
264 pub max_days: usize,
265 pub max_nodes: usize,
266}
267
268#[derive(Clone, Debug, Default)]
269pub struct MemoryRollupResponse {
270 pub total_groups: usize,
271 pub scanned_nodes: usize,
272}
273
274#[derive(Clone, Debug, Default)]
275pub struct MemorySchemaResponse {
276 pub schema_version: String,
277 pub sort_fields: Vec<String>,
278 pub filter_fields: Vec<String>,
279 pub group_by_fields: Vec<String>,
280 pub fallback_policies: Vec<String>,
281 pub strictness_modes: Vec<String>,
282 pub transform_operations: Vec<String>,
283 pub evict_operations: Vec<String>,
284}
285
286#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
287pub enum MemoryEvictMode {
288 #[default]
289 BySyncKeys,
290 ByNodeIds,
291 ByFilter,
292 PurgeSession,
293}
294
295#[derive(Clone, Debug, Default, Serialize, Deserialize)]
296pub struct MemoryInboundReferencesPreview {
297 pub child_parent_links: Vec<String>,
298 pub incoming_semantic_refs: Vec<String>,
299}
300
301#[derive(Clone, Debug, Default, Serialize, Deserialize)]
302pub struct MemoryEvictRecord {
303 pub node_id: String,
304 pub sync_key: String,
305 pub status: String,
306 pub reason: Option<String>,
307 pub inbound_references: Option<MemoryInboundReferencesPreview>,
308}
309
310#[derive(Clone, Debug)]
311pub struct MemoryEvictRequest {
312 pub mode: MemoryEvictMode,
313 pub scope: MemoryScope,
314 pub filter: MemoryFilter,
315 pub sync_keys: Option<Vec<String>>,
316 pub node_ids: Option<Vec<String>>,
317 pub dry_run: bool,
318 pub force: bool,
319 pub max_nodes: usize,
320 pub include_calibration: bool,
321 pub include_checkpoints: bool,
322}
323
324impl Default for MemoryEvictRequest {
325 fn default() -> Self {
326 Self {
327 mode: MemoryEvictMode::BySyncKeys,
328 scope: MemoryScope::default(),
329 filter: MemoryFilter::default(),
330 sync_keys: None,
331 node_ids: None,
332 dry_run: true,
333 force: false,
334 max_nodes: 5000,
335 include_calibration: false,
336 include_checkpoints: false,
337 }
338 }
339}
340
341#[derive(Clone, Debug, Default)]
342pub struct MemoryEvictResponse {
343 pub dry_run: bool,
344 pub deleted: usize,
345 pub blocked: usize,
346 pub not_found: usize,
347 pub skipped: usize,
348 pub would_delete: Vec<String>,
349 pub calibrations_deleted: usize,
350 pub checkpoints_deleted: usize,
351 pub records: Vec<MemoryEvictRecord>,
352}
353
354#[derive(Clone, Debug)]
355pub struct MemoryGraphRequest {
356 pub scope: MemoryScope,
357 pub filter: MemoryFilter,
358 pub include_lineage: bool,
359 pub include_semantic: bool,
360 pub include_session_topology: bool,
361 pub rel: Option<String>,
362 pub target_prefix: Option<String>,
363 pub limit: usize,
364}
365
366impl Default for MemoryGraphRequest {
367 fn default() -> Self {
368 Self {
369 scope: MemoryScope::default(),
370 filter: MemoryFilter::default(),
371 include_lineage: true,
372 include_semantic: true,
373 include_session_topology: true,
374 rel: None,
375 target_prefix: None,
376 limit: 200,
377 }
378 }
379}
380
381#[derive(Clone, Debug, Default)]
382pub struct MemoryGraphResponse {
383 pub sessions: Vec<Value>,
384 pub nodes: Vec<Value>,
385 pub edges: Vec<Value>,
386 pub retrieved: usize,
387}