a3s_code_core/durable_memory/
policy.rs1use super::invalid;
2use a3s_memory::repository::{DurableMemoryKind, MemoryRepositoryError, MAX_QUERY_LIMIT};
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8#[non_exhaustive]
9pub enum DurableMemoryMode {
10 ShadowCandidates,
12 ActiveRecall,
14}
15
16#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
18#[serde(rename_all = "camelCase")]
19pub struct DurableMemoryRecallPolicy {
20 max_results: usize,
21 min_lexical_score: f32,
22 max_related_lookups: usize,
23}
24
25impl DurableMemoryRecallPolicy {
26 pub fn try_new(
27 max_results: usize,
28 min_lexical_score: f32,
29 ) -> Result<Self, MemoryRepositoryError> {
30 if !(1..=MAX_QUERY_LIMIT).contains(&max_results) {
31 return Err(invalid(
32 "recallPolicy.maxResults",
33 format!("must be between 1 and {MAX_QUERY_LIMIT}"),
34 ));
35 }
36 if !min_lexical_score.is_finite() || !(0.0..=1.0).contains(&min_lexical_score) {
37 return Err(invalid(
38 "recallPolicy.minLexicalScore",
39 "must be finite and between 0 and 1",
40 ));
41 }
42 Ok(Self {
43 max_results,
44 min_lexical_score,
45 max_related_lookups: 0,
46 })
47 }
48
49 pub fn try_with_related_lookups(
52 mut self,
53 max_related_lookups: usize,
54 ) -> Result<Self, MemoryRepositoryError> {
55 if max_related_lookups > MAX_QUERY_LIMIT {
56 return Err(invalid(
57 "recallPolicy.maxRelatedLookups",
58 format!("must not exceed {MAX_QUERY_LIMIT}"),
59 ));
60 }
61 self.max_related_lookups = max_related_lookups;
62 Ok(self)
63 }
64
65 pub fn max_results(self) -> usize {
66 self.max_results
67 }
68
69 pub fn min_lexical_score(self) -> f32 {
70 self.min_lexical_score
71 }
72
73 pub fn max_related_lookups(self) -> usize {
74 self.max_related_lookups
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
80#[serde(rename_all = "snake_case")]
81#[non_exhaustive]
82pub enum DurableMemoryRecallChannel {
83 Lexical,
84 Semantic,
85 Hybrid,
86 Related,
87}
88
89#[derive(Debug, Clone, PartialEq, Serialize)]
91#[serde(rename_all = "camelCase")]
92#[non_exhaustive]
93pub struct DurableMemoryRecallHit {
94 pub node_id: String,
95 pub node_revision: u64,
96 pub kind: DurableMemoryKind,
97 pub content: String,
98 pub score: f32,
99 pub channel: DurableMemoryRecallChannel,
100 pub related_from: Option<String>,
101}
102
103#[derive(Debug, Clone, PartialEq, Serialize)]
106#[serde(rename_all = "camelCase")]
107#[non_exhaustive]
108pub struct DurableMemoryRecallPreview {
109 pub hits: Vec<DurableMemoryRecallHit>,
110}