Skip to main content

remem/memory/service/
types.rs

1#[derive(Debug, Clone, Default)]
2pub struct SearchRequest {
3    pub query: Option<String>,
4    pub project: Option<String>,
5    pub memory_type: Option<String>,
6    pub limit: i64,
7    pub offset: i64,
8    pub include_stale: bool,
9    pub include_suppressed: bool,
10    pub branch: Option<String>,
11    pub multi_hop: bool,
12    pub explain: bool,
13}
14
15#[derive(Debug, Clone)]
16pub struct SearchRoutingPolicy {
17    pub plan_hash: String,
18    pub policy_version: String,
19    pub rerank_enabled: bool,
20    pub rerank_candidate_pool: u32,
21    pub rerank_output_k: u32,
22    pub use_multi_hop: bool,
23    pub raw_fallback_enabled: bool,
24    pub weights: SearchRoutingWeights,
25}
26
27#[derive(Debug, Clone, Copy)]
28pub struct SearchRoutingWeights {
29    pub fts: f64,
30    pub vector: f64,
31    pub entity: f64,
32    pub graph: f64,
33    pub temporal: f64,
34    pub fact: f64,
35    pub like_fallback: f64,
36    pub usage: f64,
37}
38
39impl SearchRoutingPolicy {
40    pub fn from_retrieval_plan(plan: &crate::retrieval_router::RetrievalPlan) -> Self {
41        let weight = |channel| channel_weight(plan, channel);
42        let temporal = weight(crate::retrieval_router::RetrievalChannel::Temporal);
43        Self {
44            plan_hash: plan.plan_hash.clone(),
45            policy_version: plan.policy_version.clone(),
46            rerank_enabled: plan.rerank_policy.enabled,
47            rerank_candidate_pool: plan.rerank_policy.candidate_pool,
48            rerank_output_k: plan.rerank_policy.output_k,
49            use_multi_hop: channel_enabled(
50                plan,
51                crate::retrieval_router::RetrievalChannel::GraphExpansion,
52            ),
53            raw_fallback_enabled: plan.abstention_policy.mode
54                != crate::retrieval_router::AbstentionMode::OnLowEvidence,
55            weights: SearchRoutingWeights {
56                fts: weight(crate::retrieval_router::RetrievalChannel::CanonicalFts),
57                vector: weight(crate::retrieval_router::RetrievalChannel::CanonicalVector),
58                entity: weight(crate::retrieval_router::RetrievalChannel::EntityGraph),
59                graph: weight(crate::retrieval_router::RetrievalChannel::GraphExpansion),
60                temporal,
61                // Structured fact lookup is the production implementation of
62                // the router's temporal/fact evidence lane.
63                fact: temporal,
64                // LIKE is retained only as the canonical FTS degradation path.
65                like_fallback: if channel_enabled(
66                    plan,
67                    crate::retrieval_router::RetrievalChannel::CanonicalFts,
68                ) {
69                    0.25
70                } else {
71                    0.0
72                },
73                // Usage ranking is not a GH-934 retrieval-router channel; keep
74                // routed execution bounded to channels represented in the plan.
75                usage: 0.0,
76            },
77        }
78    }
79}
80
81fn channel_enabled(
82    plan: &crate::retrieval_router::RetrievalPlan,
83    channel: crate::retrieval_router::RetrievalChannel,
84) -> bool {
85    plan.channel_plans
86        .iter()
87        .any(|plan| plan.channel == channel && plan.enabled)
88}
89
90fn channel_weight(
91    plan: &crate::retrieval_router::RetrievalPlan,
92    channel: crate::retrieval_router::RetrievalChannel,
93) -> f64 {
94    plan.channel_plans
95        .iter()
96        .find(|plan| plan.channel == channel && plan.enabled)
97        .map(|plan| plan.weight)
98        .unwrap_or(0.0)
99}
100
101/// Canonical default for `include_stale` across every adapter (MCP, REST, CLI).
102///
103/// Default search returns only current curated memories. Callers that need
104/// stale or archived history must opt in explicitly.
105pub fn default_include_stale() -> bool {
106    false
107}
108
109/// Canonical default for `include_suppressed` across every adapter.
110pub fn default_include_suppressed() -> bool {
111    false
112}
113
114#[derive(Debug, Clone)]
115pub struct MultiHopMeta {
116    pub hops: u8,
117    pub entities_discovered: Vec<String>,
118}
119
120#[derive(Debug, Clone)]
121pub struct SearchResultSet {
122    pub memories: Vec<crate::memory::Memory>,
123    pub multi_hop: Option<MultiHopMeta>,
124    pub has_more: bool,
125    pub explain: Option<crate::retrieval::search::SearchExplain>,
126    /// Raw archive hits attached as fallback when curated memories are sparse.
127    pub raw_hits: Vec<crate::memory::raw_archive::RawMessage>,
128    /// Error from the raw archive fallback path. Curated results remain usable.
129    pub raw_error: Option<String>,
130}
131
132#[derive(Debug, Clone)]
133pub(crate) struct SearchResultSetWithExplainDetails {
134    pub result: SearchResultSet,
135    pub explain_details: Option<crate::retrieval::search::SearchExplainDetails>,
136}
137
138#[derive(Debug, Clone, Default)]
139pub struct SaveMemoryRequest {
140    pub text: String,
141    pub title: Option<String>,
142    pub project: Option<String>,
143    pub session_id: Option<String>,
144    pub host: Option<String>,
145    pub topic_key: Option<String>,
146    pub memory_type: Option<String>,
147    pub files: Option<Vec<String>>,
148    pub scope: Option<String>,
149    pub created_at_epoch: Option<i64>,
150    pub branch: Option<String>,
151    pub local_path: Option<String>,
152    pub local_copy_enabled: Option<bool>,
153    pub claim_enabled: Option<bool>,
154    pub claim_source: Option<String>,
155    pub acknowledge_pattern: Option<String>,
156    /// Optional caller-supplied retry identity. Reuse with changed activation
157    /// input fails closed; omission preserves compatibility with one-shot saves.
158    pub idempotency_key: Option<String>,
159}
160
161#[derive(Debug, Clone)]
162pub struct LocalCopyResult {
163    pub status: String,
164    pub path: Option<String>,
165    pub reason: Option<String>,
166}
167
168#[derive(Debug, Clone)]
169pub struct SaveMemoryNextStep {
170    pub tool: String,
171    pub ids: Vec<i64>,
172    pub source: String,
173    pub reason: String,
174}
175
176#[derive(Debug, Clone)]
177pub struct SaveMemoryResult {
178    pub id: i64,
179    pub status: String,
180    pub memory_type: String,
181    pub project: String,
182    pub scope: String,
183    pub topic_key: Option<String>,
184    pub branch: Option<String>,
185    pub operation: String,
186    pub created_at_epoch: i64,
187    pub reference_time_epoch: i64,
188    pub updated_at_epoch: i64,
189    /// Compatibility alias: true when the request supplied `topic_key`.
190    /// It does not mean the durable row was updated; use `operation` for that.
191    pub upserted: bool,
192    pub local_copy: LocalCopyResult,
193    pub local_status: String,
194    pub local_path: Option<String>,
195    pub claim_status: String,
196    pub claim_id: Option<i64>,
197    pub claim_error: Option<String>,
198    pub next_step: SaveMemoryNextStep,
199}