1pub mod archetype;
5pub mod attention;
6pub mod build;
7#[cfg(not(target_arch = "wasm32"))]
8pub mod cache;
9pub mod config;
10pub mod embedding_index;
11pub mod embeddings;
12pub mod emotional;
13#[cfg(not(target_arch = "wasm32"))]
14pub mod federation;
15pub mod fingerprint;
16pub mod hebbian;
17
18pub mod merkle;
19pub mod mirror;
20pub mod query;
21pub mod reader;
22pub mod resonance;
23pub mod sequential_thinking;
24pub mod snapshot;
25
26pub mod dream;
27pub mod emotional_contagion;
28pub mod multimodal;
29pub mod predictive_cache;
30pub mod temporal_archetype;
31pub mod thought_graph;
32pub mod viz;
33
34#[cfg(target_arch = "wasm32")]
35pub mod wasm;
36
37#[cfg(feature = "python")]
38#[allow(non_local_definitions)]
39pub mod python;
40
41#[cfg(feature = "gpu")]
42pub mod gpu;
43
44pub mod cli;
45
46pub use reader::{
48 read_append_log, store_memory, AppendEntry, BlockHeader, DataStore, MicroscopeReader,
49 RadialResult, ResultSet,
50};
51
52pub use cli::{Cli, Cmd};
54
55pub const DEFAULT_CONFIG_PATH: &str = "config.toml";
57pub const BLOCK_DATA_SIZE: usize = 256;
58pub const HEADER_SIZE: usize = 32;
59pub const META_HEADER_SIZE: usize = 16;
60pub const DEPTH_ENTRY_SIZE: usize = 8;
61pub const LAYER_NAMES: &[&str] = &[
62 "identity",
63 "long_term",
64 "short_term",
65 "associative",
66 "emotional",
67 "relational",
68 "reflections",
69 "crypto_chain",
70 "echo_cache",
71 "rust_state",
72];
73
74pub fn layer_to_id(name: &str) -> u8 {
77 LAYER_NAMES.iter().position(|&n| n == name).unwrap_or(0) as u8
78}
79
80pub fn crc16_ccitt(data: &[u8]) -> u16 {
82 let mut crc: u16 = 0xFFFF;
83 for &byte in data {
84 crc ^= (byte as u16) << 8;
85 for _ in 0..8 {
86 if crc & 0x8000 != 0 {
87 crc = (crc << 1) ^ 0x1021;
88 } else {
89 crc <<= 1;
90 }
91 }
92 }
93 crc
94}
95
96pub fn content_coords(text: &str, layer: &str) -> (f32, f32, f32) {
97 let mut h: [u64; 3] = [0xcbf29ce484222325, 0x100000001b3, 0xa5a5a5a5a5a5a5a5];
98 for &b in text.as_bytes().iter().take(128) {
99 h[0] = h[0].wrapping_mul(0x100000001b3) ^ b as u64;
100 h[1] = h[1].wrapping_mul(0x100000001b3) ^ b as u64;
101 h[2] = h[2].wrapping_mul(0x1000193) ^ b as u64;
102 }
103 let bx = (h[0] & 0xFFFF) as f32 / 65535.0;
104 let by = (h[1] & 0xFFFF) as f32 / 65535.0;
105 let bz = (h[2] & 0xFFFF) as f32 / 65535.0;
106
107 let (ox, oy, oz) = match layer {
108 "long_term" => (0.0, 0.0, 0.0),
109 "associative" => (0.3, 0.0, 0.0),
110 "emotional" => (0.0, 0.3, 0.0),
111 "relational" => (0.3, 0.3, 0.0),
112 "reflections" => (0.0, 0.0, 0.3),
113 "crypto_chain" => (0.3, 0.0, 0.3),
114 "echo_cache" => (0.0, 0.3, 0.3),
115 "short_term" => (0.15, 0.15, 0.15),
116 "rust_state" => (0.15, 0.0, 0.15),
117 _ => (0.25, 0.25, 0.25),
118 };
119
120 (ox + bx * 0.25, oy + by * 0.25, oz + bz * 0.25)
121}
122
123fn semantic_coords(text: &str, weight: f32) -> Option<(f32, f32, f32)> {
124 if weight <= 0.0 {
125 return None;
126 }
127 use embeddings::{EmbeddingProvider, MockEmbeddingProvider};
128 let provider = MockEmbeddingProvider::new(128);
129 if let Ok(emb) = provider.embed(text) {
130 if emb.len() >= 3 {
131 let sx = (emb[0] + 1.0) / 2.0;
132 let sy = (emb[1] + 1.0) / 2.0;
133 let sz = (emb[2] + 1.0) / 2.0;
134 return Some((sx, sy, sz));
135 }
136 }
137 None
138}
139
140pub fn content_coords_blended(text: &str, layer: &str, weight: f32) -> (f32, f32, f32) {
141 let (hx, hy, hz) = content_coords(text, layer);
142 if weight <= 0.0 {
143 return (hx, hy, hz);
144 }
145 match semantic_coords(text, weight) {
146 Some((sx, sy, sz)) => {
147 let w = weight.clamp(0.0, 1.0);
148 (
149 (1.0 - w) * hx + w * sx,
150 (1.0 - w) * hy + w * sy,
151 (1.0 - w) * hz + w * sz,
152 )
153 }
154 None => (hx, hy, hz),
155 }
156}
157
158pub fn hex_str(bytes: &[u8]) -> String {
159 bytes
160 .iter()
161 .map(|b| format!("{:02x}", b))
162 .collect::<Vec<_>>()
163 .join("")
164}
165
166pub fn safe_truncate(s: &str, max_bytes: usize) -> String {
167 if s.len() <= max_bytes {
168 return s.to_string();
169 }
170 let mut end = max_bytes;
171 while end > 0 && !s.is_char_boundary(end) {
172 end -= 1;
173 }
174 s[..end].to_string()
175}
176
177pub fn to_block(text: &str) -> Vec<u8> {
178 let bytes = text.as_bytes();
179 if bytes.len() <= BLOCK_DATA_SIZE {
180 bytes.to_vec()
181 } else {
182 let mut v = bytes[..BLOCK_DATA_SIZE - 3].to_vec();
183 v.extend_from_slice(b"...");
184 v
185 }
186}
187
188pub fn auto_zoom(query: &str) -> (u8, u8) {
191 let stopwords = ["a", "the", "is", "of", "and", "to", "in", "it", "on", "for"];
192 let unique_content_words = query
193 .to_lowercase()
194 .split_whitespace()
195 .filter(|w| !stopwords.contains(w) && w.len() > 2)
196 .count();
197
198 if unique_content_words <= 1 {
199 return (1, 1);
200 }
201 if unique_content_words <= 3 {
202 return (2, 1);
203 }
204 if unique_content_words <= 6 {
205 return (3, 1);
206 }
207 if unique_content_words <= 10 {
208 return (4, 1);
209 }
210 (5, 1)
211}
212
213pub fn auto_depth(text: &str) -> u8 {
214 let len = text.len();
215 if len >= 100 {
216 3
217 } else if len >= 40 {
218 4
219 } else if len >= 15 {
220 5
221 } else {
222 6
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 #[test]
231 fn test_crc16_ccitt_known_vector() {
232 let data = b"123456789";
233 assert_eq!(crc16_ccitt(data), 0x29B1);
234 }
235
236 #[test]
237 fn test_crc16_empty() {
238 assert_eq!(crc16_ccitt(b""), 0xFFFF);
239 }
240
241 #[test]
242 fn test_crc16_deterministic() {
243 let a = crc16_ccitt(b"hello world");
244 let b = crc16_ccitt(b"hello world");
245 assert_eq!(a, b);
246 assert_ne!(a, crc16_ccitt(b"hello worl!"));
247 }
248}