1use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct MemoryV3Config {
9 pub data_dir: PathBuf,
11
12 pub storage: StorageConfig,
14
15 pub indexes: IndexConfig,
17
18 pub embeddings: EmbeddingConfig,
20
21 pub encryption: EncryptionConfig,
23
24 pub auto_capture: AutoCaptureConfig,
26
27 pub performance: PerformanceConfig,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct StorageConfig {
33 pub hot_max_bytes: usize,
35
36 pub warm_max_bytes: usize,
38
39 pub cold_compression: String,
41
42 pub frozen_compression: String,
44
45 pub archive_after_days: u32,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize)]
50pub struct IndexConfig {
51 pub temporal: bool,
53
54 pub semantic: bool,
56
57 pub causal: bool,
59
60 pub entity: bool,
62
63 pub procedural: bool,
65
66 pub rebuild_on_start: bool,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct EmbeddingConfig {
72 pub provider: String,
74
75 pub dimension: usize,
77
78 pub api_url: Option<String>,
80
81 pub api_key_env: Option<String>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct EncryptionConfig {
87 pub enabled: bool,
89
90 pub key_source: String,
92
93 pub keyfile_path: Option<PathBuf>,
95
96 pub password_env: Option<String>,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct AutoCaptureConfig {
102 pub enabled: bool,
104
105 pub messages: bool,
107
108 pub tools: bool,
110
111 pub files: bool,
113
114 pub checkpoint_interval: u32,
116
117 pub pressure_threshold: f32,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct PerformanceConfig {
123 pub mmap_threshold_bytes: usize,
125
126 pub index_cache_size: usize,
128
129 pub write_buffer_size: usize,
131
132 pub background_threads: usize,
134}
135
136impl Default for MemoryV3Config {
137 fn default() -> Self {
138 Self {
139 data_dir: PathBuf::from(".agentic/memory"),
140 storage: StorageConfig {
141 hot_max_bytes: 10 * 1024 * 1024,
142 warm_max_bytes: 100 * 1024 * 1024,
143 cold_compression: "default".to_string(),
144 frozen_compression: "best".to_string(),
145 archive_after_days: 365,
146 },
147 indexes: IndexConfig {
148 temporal: true,
149 semantic: true,
150 causal: true,
151 entity: true,
152 procedural: true,
153 rebuild_on_start: false,
154 },
155 embeddings: EmbeddingConfig {
156 provider: "tfidf".to_string(),
157 dimension: 384,
158 api_url: None,
159 api_key_env: None,
160 },
161 encryption: EncryptionConfig {
162 enabled: false,
163 key_source: "password".to_string(),
164 keyfile_path: None,
165 password_env: None,
166 },
167 auto_capture: AutoCaptureConfig {
168 enabled: true,
169 messages: true,
170 tools: true,
171 files: true,
172 checkpoint_interval: 50,
173 pressure_threshold: 0.75,
174 },
175 performance: PerformanceConfig {
176 mmap_threshold_bytes: 1024 * 1024,
177 index_cache_size: 10000,
178 write_buffer_size: 64 * 1024,
179 background_threads: 2,
180 },
181 }
182 }
183}
184
185impl MemoryV3Config {
186 pub fn load(path: &PathBuf) -> Result<Self, Box<dyn std::error::Error>> {
188 let content = std::fs::read_to_string(path)?;
189 let config: Self = toml::from_str(&content)?;
190 Ok(config)
191 }
192
193 pub fn save(&self, path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
195 let content = toml::to_string_pretty(self)?;
196 std::fs::write(path, content)?;
197 Ok(())
198 }
199
200 pub fn load_or_default() -> Self {
202 let default_path = dirs::config_dir()
203 .unwrap_or_else(|| PathBuf::from("."))
204 .join("agentic")
205 .join("memory.toml");
206
207 Self::load(&default_path).unwrap_or_default()
208 }
209}