Skip to main content

stasis/ports/outbound/memory/
memory_models.rs

1use chrono::{DateTime, Utc};
2
3#[derive(Clone, Debug, Default)]
4pub struct MemoryScope {
5    pub session_ids: Option<Vec<String>>,
6    pub tiers: Option<Vec<String>>,
7    pub from_utc: Option<DateTime<Utc>>,
8    pub to_utc: Option<DateTime<Utc>>,
9}
10
11#[derive(Clone, Copy, Debug, Default)]
12pub struct MemoryAvecState {
13    pub stability: f32,
14    pub friction: f32,
15    pub logic: f32,
16    pub autonomy: f32,
17}
18
19#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
20pub enum MemoryFallbackPolicy {
21    Never,
22    #[default]
23    OnEmpty,
24    Always,
25}
26
27#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
28pub enum MemoryStrictnessMode {
29    Precision,
30    #[default]
31    Balanced,
32    Recall,
33}
34
35#[derive(Clone, Debug)]
36pub struct MemoryRecallRequest {
37    pub scope: MemoryScope,
38    pub current_avec: Option<MemoryAvecState>,
39    pub query_text: Option<String>,
40    pub limit: usize,
41    pub alpha: f32,
42    pub beta: f32,
43    pub fallback_policy: MemoryFallbackPolicy,
44    pub strictness: MemoryStrictnessMode,
45    pub include_explain: bool,
46}
47
48impl Default for MemoryRecallRequest {
49    fn default() -> Self {
50        Self {
51            scope: MemoryScope::default(),
52            current_avec: None,
53            query_text: None,
54            limit: 20,
55            alpha: 0.7,
56            beta: 0.3,
57            fallback_policy: MemoryFallbackPolicy::OnEmpty,
58            strictness: MemoryStrictnessMode::Balanced,
59            include_explain: false,
60        }
61    }
62}
63
64#[derive(Clone, Debug, Default)]
65pub struct MemoryMetricRange {
66    pub min: Option<f32>,
67    pub max: Option<f32>,
68}
69
70#[derive(Clone, Debug, Default)]
71pub struct MemoryFilter {
72    pub has_embedding: Option<bool>,
73    pub embedding_model: Option<String>,
74    pub psi: Option<MemoryMetricRange>,
75    pub rho: Option<MemoryMetricRange>,
76    pub kappa: Option<MemoryMetricRange>,
77    pub text_contains: Option<String>,
78}
79
80#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
81pub enum MemorySortField {
82    #[default]
83    Timestamp,
84    UpdatedAt,
85    Psi,
86    Rho,
87    Kappa,
88}
89
90#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
91pub enum MemorySortDirection {
92    Asc,
93    #[default]
94    Desc,
95}
96
97#[derive(Clone, Debug)]
98pub struct MemoryFindRequest {
99    pub scope: MemoryScope,
100    pub filter: MemoryFilter,
101    pub limit: usize,
102    pub cursor: Option<String>,
103    pub sort_field: MemorySortField,
104    pub sort_direction: MemorySortDirection,
105}
106
107impl Default for MemoryFindRequest {
108    fn default() -> Self {
109        Self {
110            scope: MemoryScope::default(),
111            filter: MemoryFilter::default(),
112            limit: 50,
113            cursor: None,
114            sort_field: MemorySortField::Timestamp,
115            sort_direction: MemorySortDirection::Desc,
116        }
117    }
118}
119
120#[derive(Clone, Debug, Default)]
121pub struct MemoryFindResponse {
122    pub retrieved: usize,
123    pub has_more: bool,
124    pub next_cursor: Option<String>,
125    pub node_sync_keys: Vec<String>,
126}
127
128#[derive(Clone, Debug, Default)]
129pub struct MemoryRecallResponse {
130    pub retrieved: usize,
131    pub next_cursor: Option<String>,
132    pub has_more: bool,
133    pub retrieval_path: Option<String>,
134    pub fallback_triggered: bool,
135    pub fallback_reason: Option<String>,
136    pub node_sync_keys: Vec<String>,
137}
138
139#[derive(Clone, Debug)]
140pub struct MemoryStoreRequest {
141    pub session_id: String,
142    pub raw_node: String,
143}
144
145#[derive(Clone, Debug, Default)]
146pub struct MemoryStoreResponse {
147    pub node_id: String,
148    pub psi: f32,
149    pub valid: bool,
150    pub validation_error: Option<String>,
151}
152
153#[derive(Clone, Debug, Default)]
154pub struct MemoryAggregateRequest {
155    pub scope: MemoryScope,
156    pub max_groups: usize,
157    pub max_nodes: usize,
158}
159
160#[derive(Clone, Debug, Default)]
161pub struct MemoryAggregateResponse {
162    pub total_groups: usize,
163    pub scanned_nodes: usize,
164}
165
166#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
167pub enum MemoryTransformOperation {
168    #[default]
169    EmbedBackfill,
170    ReindexEmbeddings,
171}
172
173#[derive(Clone, Debug)]
174pub struct MemoryTransformRequest {
175    pub scope: MemoryScope,
176    pub operation: MemoryTransformOperation,
177    pub dry_run: bool,
178    pub batch_size: usize,
179    pub max_nodes: usize,
180    pub provider_id: Option<String>,
181    pub model: Option<String>,
182}
183
184impl Default for MemoryTransformRequest {
185    fn default() -> Self {
186        Self {
187            scope: MemoryScope::default(),
188            operation: MemoryTransformOperation::EmbedBackfill,
189            dry_run: true,
190            batch_size: 100,
191            max_nodes: 5000,
192            provider_id: None,
193            model: None,
194        }
195    }
196}
197
198#[derive(Clone, Debug, Default)]
199pub struct MemoryTransformResponse {
200    pub scanned: usize,
201    pub selected: usize,
202    pub updated: usize,
203    pub skipped: usize,
204    pub failed: usize,
205    pub duplicate: usize,
206    pub failures: Vec<String>,
207}
208
209#[derive(Clone, Debug, Default)]
210pub struct MemoryRollupRequest {
211    pub scope: MemoryScope,
212    pub max_days: usize,
213    pub max_nodes: usize,
214}
215
216#[derive(Clone, Debug, Default)]
217pub struct MemoryRollupResponse {
218    pub total_groups: usize,
219    pub scanned_nodes: usize,
220}
221
222#[derive(Clone, Debug, Default)]
223pub struct MemorySchemaResponse {
224    pub schema_version: String,
225    pub sort_fields: Vec<String>,
226    pub filter_fields: Vec<String>,
227    pub group_by_fields: Vec<String>,
228    pub fallback_policies: Vec<String>,
229    pub strictness_modes: Vec<String>,
230    pub transform_operations: Vec<String>,
231}