Skip to main content

mnemara_core/
config.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
4pub enum EmbeddingProviderKind {
5    #[default]
6    Disabled,
7    DeterministicLocal,
8}
9
10#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
11pub enum RecallScoringProfile {
12    #[default]
13    Balanced,
14    LexicalFirst,
15    ImportanceFirst,
16}
17
18#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
19pub enum RecallScorerKind {
20    #[default]
21    Profile,
22    Curated,
23}
24
25#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
26pub enum RecallPlanningProfile {
27    #[default]
28    FastPath,
29    ContinuityAware,
30}
31
32#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
33pub enum RecallPolicyProfile {
34    #[default]
35    General,
36    Support,
37    Research,
38    Assistant,
39    AutonomousAgent,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
43pub struct EngineTuningInfo {
44    pub recall_scorer_kind: RecallScorerKind,
45    pub recall_scoring_profile: RecallScoringProfile,
46    pub recall_planning_profile: RecallPlanningProfile,
47    pub recall_policy_profile: RecallPolicyProfile,
48    pub embedding_provider_kind: EmbeddingProviderKind,
49    pub embedding_dimensions: usize,
50    pub graph_expansion_max_hops: u8,
51    pub compaction_summarize_after_record_count: usize,
52    pub compaction_cold_archive_after_days: u32,
53    pub compaction_cold_archive_importance_threshold_per_mille: u16,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
57pub struct EngineConfig {
58    pub node_id: String,
59    pub default_tenant: String,
60    pub max_batch_size: usize,
61    pub retention: RetentionPolicy,
62    pub compaction: CompactionPolicy,
63    pub ingestion: IngestionPolicy,
64    pub recall_scorer_kind: RecallScorerKind,
65    pub recall_scoring_profile: RecallScoringProfile,
66    pub recall_planning_profile: RecallPlanningProfile,
67    pub recall_policy_profile: RecallPolicyProfile,
68    pub embedding_provider_kind: EmbeddingProviderKind,
69    pub embedding_dimensions: usize,
70    pub graph_expansion_max_hops: u8,
71    pub explain_recall: bool,
72}
73
74impl Default for EngineConfig {
75    fn default() -> Self {
76        Self {
77            node_id: "local-node".to_string(),
78            default_tenant: "default".to_string(),
79            max_batch_size: 256,
80            retention: RetentionPolicy::default(),
81            compaction: CompactionPolicy::default(),
82            ingestion: IngestionPolicy::default(),
83            recall_scorer_kind: RecallScorerKind::default(),
84            recall_scoring_profile: RecallScoringProfile::default(),
85            recall_planning_profile: RecallPlanningProfile::default(),
86            recall_policy_profile: RecallPolicyProfile::default(),
87            embedding_provider_kind: EmbeddingProviderKind::default(),
88            embedding_dimensions: 64,
89            graph_expansion_max_hops: 1,
90            explain_recall: true,
91        }
92    }
93}
94
95impl EngineConfig {
96    pub fn tuning_info(&self) -> EngineTuningInfo {
97        EngineTuningInfo {
98            recall_scorer_kind: self.recall_scorer_kind,
99            recall_scoring_profile: self.recall_scoring_profile,
100            recall_planning_profile: self.recall_planning_profile,
101            recall_policy_profile: self.recall_policy_profile,
102            embedding_provider_kind: self.embedding_provider_kind,
103            embedding_dimensions: self.embedding_dimensions,
104            graph_expansion_max_hops: self.graph_expansion_max_hops,
105            compaction_summarize_after_record_count: self.compaction.summarize_after_record_count,
106            compaction_cold_archive_after_days: self.compaction.cold_archive_after_days,
107            compaction_cold_archive_importance_threshold_per_mille: self
108                .compaction
109                .cold_archive_importance_threshold_per_mille,
110        }
111    }
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
115pub struct RetentionPolicy {
116    pub ttl_days: u32,
117    pub archive_after_days: u32,
118    pub max_records_per_namespace: usize,
119    pub pinned_records_exempt: bool,
120}
121
122impl Default for RetentionPolicy {
123    fn default() -> Self {
124        Self {
125            ttl_days: 0,
126            archive_after_days: 0,
127            max_records_per_namespace: 5_000,
128            pinned_records_exempt: true,
129        }
130    }
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
134pub struct CompactionPolicy {
135    pub deduplicate_similar_records: bool,
136    pub summarize_after_record_count: usize,
137    pub prune_stale_graph_edges: bool,
138    pub cold_archive_after_days: u32,
139    pub cold_archive_importance_threshold_per_mille: u16,
140    pub maintenance_interval_operations: u32,
141    pub dry_run_supported: bool,
142}
143
144impl Default for CompactionPolicy {
145    fn default() -> Self {
146        Self {
147            deduplicate_similar_records: true,
148            summarize_after_record_count: 50,
149            prune_stale_graph_edges: true,
150            cold_archive_after_days: 0,
151            cold_archive_importance_threshold_per_mille: 250,
152            maintenance_interval_operations: 32,
153            dry_run_supported: true,
154        }
155    }
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
159pub struct IngestionPolicy {
160    pub idempotent_writes_required: bool,
161    pub deduplication_window_hours: u32,
162    pub allow_model_derived_memories: bool,
163    pub require_source_labels: bool,
164}
165
166impl Default for IngestionPolicy {
167    fn default() -> Self {
168        Self {
169            idempotent_writes_required: true,
170            deduplication_window_hours: 24,
171            allow_model_derived_memories: true,
172            require_source_labels: false,
173        }
174    }
175}