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