stasis/infrastructure/memory/
locus_memory_mapping.rs1use locus_core_rs::domain::models::{SemanticLink, SttpNode};
2use locus_sdk::prelude::{
3 FallbackPolicy, MemoryFilter as LocusFilter, MemoryScope as LocusScope, MemoryScoring,
4 MemorySortField as LocusSortField, SortDirection as LocusSortDirection, StrictnessMode,
5};
6use locus_sdk::domain::memory::MetricRange as LocusMetricRange;
7
8use crate::ports::outbound::memory::memory_models::{
9 MemoryAvecState, MemoryFallbackPolicy, MemoryFilter, MemoryMetricRange, MemoryNode,
10 MemoryScope, MemorySemanticLink, MemorySortDirection, MemorySortField, MemoryStrictnessMode,
11};
12
13pub fn map_scope(scope: &MemoryScope) -> LocusScope {
14 LocusScope {
15 tenant_id: scope.tenant_id.clone(),
16 session_ids: scope.session_ids.clone(),
17 tiers: scope.tiers.clone(),
18 from_utc: scope.from_utc,
19 to_utc: scope.to_utc,
20 }
21}
22
23pub fn map_filter(value: &MemoryFilter) -> LocusFilter {
24 LocusFilter {
25 has_embedding: value.has_embedding,
26 embedding_model: value.embedding_model.clone(),
27 psi: value.psi.as_ref().map(map_metric_range),
28 rho: value.rho.as_ref().map(map_metric_range),
29 kappa: value.kappa.as_ref().map(map_metric_range),
30 text_contains: value.text_contains.clone(),
31 tags_contains: value.tags_contains.clone(),
32 has_tag: value.has_tag.clone(),
33 indexed_tags: value.indexed_tags.clone(),
34 tag_prefix: value.tag_prefix.clone(),
35 has_semantic_links: value.has_semantic_links,
36 link_rel: value.link_rel.clone(),
37 link_target: value.link_target.clone(),
38 links_to_ref: value.links_to_ref.clone(),
39 }
40}
41
42pub fn map_scoring(
43 alpha: f32,
44 beta: f32,
45 gamma: f32,
46 fallback_policy: MemoryFallbackPolicy,
47 strictness: MemoryStrictnessMode,
48) -> MemoryScoring {
49 MemoryScoring {
50 alpha,
51 beta,
52 gamma,
53 fallback_policy: map_fallback(fallback_policy),
54 strictness: map_strictness(strictness),
55 ..Default::default()
56 }
57}
58
59pub fn map_node(node: &SttpNode) -> MemoryNode {
60 MemoryNode {
61 raw: node.raw.clone(),
62 session_id: node.session_id.clone(),
63 tier: node.tier.clone(),
64 timestamp: node.timestamp,
65 compression_depth: node.compression_depth,
66 parent_node_id: node.parent_node_id.clone(),
67 sync_key: node.sync_key.clone(),
68 context_summary: node.context_summary.clone(),
69 semantic_tags: node.semantic_tags.clone(),
70 semantic_links: node
71 .semantic_links
72 .as_ref()
73 .map(|links| links.iter().map(map_semantic_link).collect()),
74 embedding_model: node.embedding_model.clone(),
75 embedding_dimensions: node.embedding_dimensions,
76 embedded_at: node.embedded_at,
77 rho: node.rho,
78 kappa: node.kappa,
79 psi: node.psi,
80 user_avec: map_avec(&node.user_avec),
81 model_avec: map_avec(&node.model_avec),
82 compression_avec: node.compression_avec.as_ref().map(map_avec),
83 updated_at: node.updated_at,
84 }
85}
86
87fn map_semantic_link(link: &SemanticLink) -> MemorySemanticLink {
88 MemorySemanticLink {
89 rel: link.rel.clone(),
90 target: link.target.clone(),
91 confidence: link.confidence,
92 }
93}
94
95fn map_avec(avec: &locus_core_rs::domain::models::AvecState) -> MemoryAvecState {
96 MemoryAvecState {
97 stability: avec.stability,
98 friction: avec.friction,
99 logic: avec.logic,
100 autonomy: avec.autonomy,
101 }
102}
103
104pub fn map_fallback(value: MemoryFallbackPolicy) -> FallbackPolicy {
105 match value {
106 MemoryFallbackPolicy::Never => FallbackPolicy::Never,
107 MemoryFallbackPolicy::OnEmpty => FallbackPolicy::OnEmpty,
108 MemoryFallbackPolicy::Always => FallbackPolicy::Always,
109 }
110}
111
112pub fn map_strictness(value: MemoryStrictnessMode) -> StrictnessMode {
113 match value {
114 MemoryStrictnessMode::Precision => StrictnessMode::Precision,
115 MemoryStrictnessMode::Balanced => StrictnessMode::Balanced,
116 MemoryStrictnessMode::Recall => StrictnessMode::Recall,
117 }
118}
119
120fn map_metric_range(value: &MemoryMetricRange) -> LocusMetricRange {
121 LocusMetricRange {
122 min: value.min,
123 max: value.max,
124 }
125}
126
127pub fn map_sort_field(value: MemorySortField) -> LocusSortField {
128 match value {
129 MemorySortField::Timestamp => LocusSortField::Timestamp,
130 MemorySortField::UpdatedAt => LocusSortField::UpdatedAt,
131 MemorySortField::Psi => LocusSortField::Psi,
132 MemorySortField::Rho => LocusSortField::Rho,
133 MemorySortField::Kappa => LocusSortField::Kappa,
134 }
135}
136
137pub fn map_sort_direction(value: MemorySortDirection) -> LocusSortDirection {
138 match value {
139 MemorySortDirection::Asc => LocusSortDirection::Asc,
140 MemorySortDirection::Desc => LocusSortDirection::Desc,
141 }
142}