1use anyhow::Result;
5use std::path::Path;
6use std::sync::{Arc, RwLock};
7
8use crate::mem8::{
9 consciousness::ConsciousnessEngine,
10 format::{CompressedWave, M8Writer},
11 reactive::{ReactiveLayer, ReactiveMemory, ReactivePattern, ReactiveResponse, SensorInput},
12 wave::{FrequencyBand, MemoryWave, WaveGrid},
13};
14
15pub struct SmartTreeMem8 {
17 wave_grid: Arc<RwLock<WaveGrid>>,
19 reactive_memory: Arc<RwLock<ReactiveMemory>>,
21 consciousness: Arc<ConsciousnessEngine>,
23 current_depth: u16,
25}
26
27impl Default for SmartTreeMem8 {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl SmartTreeMem8 {
34 pub fn new() -> Self {
36 #[cfg(not(test))]
37 let wave_grid = Arc::new(RwLock::new(WaveGrid::new()));
38
39 #[cfg(test)]
40 let wave_grid = Arc::new(RwLock::new(WaveGrid::new_test()));
41
42 let reactive_memory = Arc::new(RwLock::new(ReactiveMemory::new(wave_grid.clone())));
43 let consciousness = Arc::new(ConsciousnessEngine::new(wave_grid.clone()));
44
45 Self {
46 wave_grid,
47 reactive_memory,
48 consciousness,
49 current_depth: 0,
50 }
51 }
52
53 pub fn store_directory_memory(
55 &mut self,
56 path: &Path,
57 metadata: DirectoryMetadata,
58 ) -> Result<()> {
59 let (x, y) = self.path_to_coordinates(path);
61
62 let wave = self.create_directory_wave(&metadata);
64
65 self.wave_grid
67 .write()
68 .unwrap()
69 .store(x, y, self.current_depth, wave);
70
71 self.current_depth = if self.current_depth == 65535 {
73 0
74 } else {
75 self.current_depth + 1
76 };
77
78 Ok(())
79 }
80
81 fn path_to_coordinates(&self, path: &Path) -> (u8, u8) {
83 let path_str = path.to_string_lossy();
85 let hash = self.simple_hash(&path_str);
86
87 let x = (hash & 0xFF) as u8;
88 let y = ((hash >> 8) & 0xFF) as u8;
89
90 (x, y)
91 }
92
93 pub fn simple_hash(&self, s: &str) -> u64 {
95 let mut hash = 5381u64;
96 for byte in s.bytes() {
97 hash = ((hash << 5).wrapping_add(hash)).wrapping_add(byte as u64);
98 }
99 hash
100 }
101
102 fn create_directory_wave(&self, metadata: &DirectoryMetadata) -> MemoryWave {
104 let frequency = match metadata.primary_type {
106 ContentType::Code => FrequencyBand::Technical.frequency(0.5),
107 ContentType::Documentation => FrequencyBand::Conversational.frequency(0.5),
108 ContentType::Configuration => FrequencyBand::DeepStructural.frequency(0.5),
109 ContentType::Data => FrequencyBand::Implementation.frequency(0.5),
110 ContentType::Media => FrequencyBand::Abstract.frequency(0.5),
111 };
112
113 let amplitude =
115 (metadata.importance * 0.7 + metadata.normalized_size * 0.3).clamp(0.1, 1.0);
116
117 let mut wave = MemoryWave::new(frequency, amplitude);
118
119 wave.valence = match metadata.health {
121 DirectoryHealth::Healthy => 0.5,
122 DirectoryHealth::Warning => -0.2,
123 DirectoryHealth::Critical => -0.8,
124 };
125
126 wave.arousal = metadata.activity_level;
128
129 if metadata.days_since_modified > 365 {
131 wave.decay_tau = Some(std::time::Duration::from_secs(86400)); } else if metadata.days_since_modified > 30 {
133 wave.decay_tau = Some(std::time::Duration::from_secs(604800)); } else {
135 wave.decay_tau = None; }
137
138 wave
139 }
140
141 pub fn query_path_memories(&self, pattern: &str) -> Vec<PathMemory> {
143 let grid = self.wave_grid.read().unwrap();
144 let mut memories = Vec::new();
145
146 for x in 0..=255u8 {
148 for y in 0..=255u8 {
149 for z in (self.current_depth.saturating_sub(1000)..self.current_depth).step_by(10) {
151 if let Some(wave) = grid.get(x, y, z) {
152 if wave.calculate_decay() > 0.1 {
153 memories.push(PathMemory {
155 coordinates: (x, y, z),
156 wave: wave.clone(),
157 relevance: self.calculate_relevance(wave, pattern),
158 });
159 }
160 }
161 }
162 }
163 }
164
165 memories.sort_by(|a, b| b.relevance.partial_cmp(&a.relevance).unwrap());
167 memories.truncate(20); memories
170 }
171
172 fn calculate_relevance(&self, wave: &MemoryWave, pattern: &str) -> f32 {
174 let pattern_freq = if pattern.contains("src") || pattern.contains("lib") {
176 FrequencyBand::Technical.frequency(0.5)
177 } else if pattern.contains("doc") || pattern.contains("README") {
178 FrequencyBand::Conversational.frequency(0.5)
179 } else if pattern.contains("config") || pattern.contains("toml") {
180 FrequencyBand::DeepStructural.frequency(0.5)
181 } else {
182 FrequencyBand::Implementation.frequency(0.5)
183 };
184
185 let freq_diff = (wave.frequency - pattern_freq).abs() / 1000.0;
187 let freq_score = 1.0 - freq_diff.clamp(0.0, 1.0);
188
189 freq_score * wave.amplitude * wave.calculate_decay()
191 }
192
193 pub fn register_directory_patterns(&mut self) {
195 let large_dir_pattern = ReactivePattern {
197 id: "large_directory".to_string(),
198 threshold: 0.7,
199 weight: 1.0,
200 response: Arc::new(|| ReactiveResponse {
201 layer: ReactiveLayer::SubcorticalReaction,
202 strength: 0.8,
203 action: "Enable streaming mode for large directory".to_string(),
204 latency: std::time::Duration::from_millis(30),
205 }),
206 };
207
208 let security_pattern = ReactivePattern {
210 id: "security_threat".to_string(),
211 threshold: 0.5,
212 weight: 1.5,
213 response: Arc::new(|| ReactiveResponse {
214 layer: ReactiveLayer::HardwareReflex,
215 strength: 0.95,
216 action: "Block access to suspicious directory".to_string(),
217 latency: std::time::Duration::from_millis(5),
218 }),
219 };
220
221 let mut reactive = self.reactive_memory.write().unwrap();
223 reactive.register_pattern(ReactiveLayer::SubcorticalReaction, large_dir_pattern);
224 reactive.register_pattern(ReactiveLayer::HardwareReflex, security_pattern);
225 }
226
227 pub fn process_directory_event(&self, event: DirectoryEvent) -> Option<ReactiveResponse> {
229 let input = match event {
230 DirectoryEvent::LargeDirectory { size, .. } => SensorInput::Visual {
231 intensity: (size as f32 / 1_000_000.0).clamp(0.0, 1.0),
232 motion: 0.0,
233 looming: size > 10_000_000,
234 },
235 DirectoryEvent::SecurityThreat { severity, .. } => SensorInput::Threat {
236 severity,
237 proximity: 1.0,
238 pattern: "malicious_file".to_string(),
239 },
240 DirectoryEvent::RapidChange { rate, .. } => SensorInput::Visual {
241 intensity: 0.5,
242 motion: rate,
243 looming: false,
244 },
245 };
246
247 self.reactive_memory.read().unwrap().process(&input)
248 }
249
250 pub fn update_consciousness(&self) {
252 self.consciousness.update();
253 }
254
255 pub fn export_memories<W: std::io::Write>(&self, writer: W) -> Result<()> {
257 let mut m8_writer = M8Writer::new(writer);
258 let grid = self.wave_grid.read().unwrap();
259
260 let mut compressed_waves = Vec::new();
262 let mut id = 0;
263
264 for x in 0..=255u8 {
265 for y in 0..=255u8 {
266 for z in 0..100u16 {
267 if let Some(wave) = grid.get(x, y, z) {
269 if wave.calculate_decay() > 0.01 {
270 compressed_waves.push(CompressedWave::from_wave(wave, id));
271 id += 1;
272 }
273 }
274 }
275 }
276 }
277
278 m8_writer.add_wave_memory(&compressed_waves)?;
279 m8_writer.finish()?;
280
281 Ok(())
282 }
283
284 pub fn active_memory_count(&self) -> usize {
286 self.wave_grid.read().unwrap().active_memory_count()
287 }
288
289 pub fn store_wave_at_coordinates(
291 &mut self,
292 x: u8,
293 y: u8,
294 z: u16,
295 wave: MemoryWave,
296 ) -> Result<()> {
297 self.wave_grid.write().unwrap().store(x, y, z, wave);
298 Ok(())
299 }
300
301 pub fn string_to_coordinates(&self, s: &str) -> (u8, u8) {
303 let hash = self.simple_hash(s);
304 ((hash & 0xFF) as u8, ((hash >> 8) & 0xFF) as u8)
305 }
306}
307
308#[derive(Debug)]
310pub struct DirectoryMetadata {
311 pub primary_type: ContentType,
312 pub importance: f32, pub normalized_size: f32, pub health: DirectoryHealth,
315 pub activity_level: f32, pub days_since_modified: u32,
317}
318
319#[derive(Debug)]
320pub enum ContentType {
321 Code,
322 Documentation,
323 Configuration,
324 Data,
325 Media,
326}
327
328#[derive(Debug)]
329pub enum DirectoryHealth {
330 Healthy,
331 Warning,
332 Critical,
333}
334
335#[derive(Debug)]
337pub struct PathMemory {
338 pub coordinates: (u8, u8, u16),
339 pub wave: Arc<MemoryWave>,
340 pub relevance: f32,
341}
342
343#[derive(Debug)]
345pub enum DirectoryEvent {
346 LargeDirectory { path: String, size: u64 },
347 SecurityThreat { path: String, severity: f32 },
348 RapidChange { path: String, rate: f32 },
349}
350
351pub fn integrate_with_smart_tree() -> Result<()> {
353 let mut mem8 = SmartTreeMem8::new();
354
355 mem8.register_directory_patterns();
357
358 let metadata = DirectoryMetadata {
360 primary_type: ContentType::Code,
361 importance: 0.8,
362 normalized_size: 0.6,
363 health: DirectoryHealth::Healthy,
364 activity_level: 0.7,
365 days_since_modified: 5,
366 };
367
368 mem8.store_directory_memory(Path::new("src/lib.rs"), metadata)?;
369
370 let memories = mem8.query_path_memories("src");
372 println!("Found {} memories related to 'src'", memories.len());
373
374 let event = DirectoryEvent::LargeDirectory {
376 path: "node_modules".to_string(),
377 size: 50_000_000,
378 };
379
380 if let Some(response) = mem8.process_directory_event(event) {
381 println!(
382 "Reactive response: {} ({}ms)",
383 response.action,
384 response.latency.as_millis()
385 );
386 }
387
388 mem8.update_consciousness();
390
391 let mut buffer = Vec::new();
393 mem8.export_memories(&mut buffer)?;
394 println!("Exported {} bytes of memories", buffer.len());
395
396 Ok(())
397}
398
399#[cfg(test)]
400mod tests {
401 use super::*;
402
403 #[test]
404 #[ignore = "Consciousness update or memory export may hang"]
405 fn test_smart_tree_integration() {
406 if std::env::var("CI").is_ok() || std::env::var("GITHUB_ACTIONS").is_ok() {
408 println!("Skipping smart tree integration test in CI environment");
409 return;
410 }
411 integrate_with_smart_tree().unwrap();
412 }
413
414 #[test]
415 fn test_path_to_coordinates() {
416 let mem8 = SmartTreeMem8::new();
417 let (x1, y1) = mem8.path_to_coordinates(Path::new("src/main.rs"));
418 let (x2, y2) = mem8.path_to_coordinates(Path::new("src/lib.rs"));
419
420 assert!(x1 != x2 || y1 != y2);
422 }
423}