1use std::collections::VecDeque;
13use std::path::Path;
14use std::time::{Duration, SystemTime, UNIX_EPOCH};
15
16use colored::Colorize;
17
18use crate::build;
19use crate::config::Config;
20use crate::daydream;
21use crate::dream;
22use crate::executive::{Executive, ModuleState};
23use crate::inner_monologue;
24use crate::narrative::NarrativeState;
25use crate::narrative_memory;
26use crate::reader::{store_memory_temporary, MicroscopeReader};
27use crate::self_model::SelfModel;
28use crate::self_reflect;
29
30pub const CYCLE_INTERVAL_SECS: u64 = 30;
34
35pub const DAYDREAM_INTERVAL: usize = 3;
37
38pub const CURIOSITY_INTERVAL: usize = 2;
40
41pub const MONOLOGUE_INTERVAL: usize = 5;
43
44pub const REFLECT_INTERVAL: usize = 4;
46
47pub const DREAM_INTERVAL: usize = 10;
49
50pub const SELF_MODEL_INTERVAL: usize = 7;
52
53pub const NARRATIVE_INTERVAL: usize = 2;
55
56#[derive(Debug, Clone)]
59pub struct AutonomousConfig {
60 pub cycle_interval_secs: u64,
61 pub daydream_interval: usize,
62 pub curiosity_interval: usize,
63 pub monologue_interval: usize,
64 pub reflect_interval: usize,
65 pub dream_interval: usize,
66 pub self_model_interval: usize,
67 pub narrative_interval: usize,
68 pub tts_enabled: bool,
69 pub daemon_mode: bool,
70 pub max_cycles: Option<usize>,
71}
72
73impl Default for AutonomousConfig {
74 fn default() -> Self {
75 Self {
76 cycle_interval_secs: CYCLE_INTERVAL_SECS,
77 daydream_interval: DAYDREAM_INTERVAL,
78 curiosity_interval: CURIOSITY_INTERVAL,
79 monologue_interval: MONOLOGUE_INTERVAL,
80 reflect_interval: REFLECT_INTERVAL,
81 dream_interval: DREAM_INTERVAL,
82 self_model_interval: SELF_MODEL_INTERVAL,
83 narrative_interval: NARRATIVE_INTERVAL,
84 tts_enabled: false,
85 daemon_mode: false,
86 max_cycles: None,
87 }
88 }
89}
90
91pub struct AutonomousEngine {
94 config: AutonomousConfig,
95 executive: Executive,
96 cycle_count: usize,
97 last_outputs: VecDeque<String>,
98}
99
100impl AutonomousEngine {
101 pub fn new(auto_config: AutonomousConfig) -> Self {
102 let executive = Executive::new();
103
104 executive.register_module(
106 "daydream",
107 "Daydream - asszociatív drift",
108 60,
109 0.3,
110 vec!["creative".to_string(), "exploration".to_string()],
111 );
112 executive.register_module(
113 "curiosity",
114 "Curiosity - proaktív kíváncsiság",
115 70,
116 0.2,
117 vec!["exploration".to_string(), "learning".to_string()],
118 );
119 executive.register_module(
120 "monologue",
121 "Inner Monologue - belső gondolkodás",
122 50,
123 0.4,
124 vec!["reflection".to_string(), "planning".to_string()],
125 );
126 executive.register_module(
127 "reflect",
128 "Self-Reflection - önvizsgálat",
129 80,
130 0.3,
131 vec!["reflection".to_string(), "meta".to_string()],
132 );
133 executive.register_module(
134 "narrative",
135 "Narrative Memory - történetépítés",
136 40,
137 0.2,
138 vec!["memory".to_string(), "story".to_string()],
139 );
140 executive.register_module(
141 "dream",
142 "Dream Consolidation - álom",
143 30,
144 0.5,
145 vec!["maintenance".to_string(), "pruning".to_string()],
146 );
147 executive.register_module(
148 "self_model",
149 "Self-Model - önkép",
150 90,
151 0.2,
152 vec!["meta".to_string(), "identity".to_string()],
153 );
154
155 Self {
156 config: auto_config,
157 executive,
158 cycle_count: 0,
159 last_outputs: VecDeque::with_capacity(20),
160 }
161 }
162
163 fn speak(&self, text: &str) {
164 if !self.config.tts_enabled {
165 return;
166 }
167 let safe_text = text.replace('"', " ").replace("\n", " ");
168 let ts = std::time::SystemTime::now()
169 .duration_since(std::time::UNIX_EPOCH)
170 .unwrap_or_default()
171 .as_nanos();
172 let filename = format!("tts_{}.mp3", ts);
173 let gen = std::process::Command::new("python")
175 .args([
176 "-m",
177 "edge_tts",
178 "--voice",
179 "hu-HU-NoemiNeural",
180 "--text",
181 &safe_text,
182 "--write-media",
183 &filename,
184 ])
185 .output();
186 match gen {
187 Ok(_) => {
188 let _ = std::process::Command::new("ffplay")
190 .args(["-nodisp", "-autoexit", "-loglevel", "quiet", &filename])
191 .status();
192 let _ = std::fs::remove_file(&filename);
194 }
195 Err(e) => {
196 eprintln!(" {} TTS error: {}", "ERROR:".red(), e);
197 }
198 }
199 }
200
201 fn store_result(&self, config: &Config, text: &str, layer: &str, importance: u8) {
202 if let Err(e) = store_memory_temporary(config, text, layer, importance) {
205 eprintln!(" {} Store error: {}", "ERROR:".red(), e);
206 }
207 }
208
209 fn run_daydream(&mut self, config: &Config, output_dir: &Path) -> String {
210 let seed = {
211 let narrative = NarrativeState::load_or_init(output_dir);
212 if narrative.narrative.is_empty() || narrative.narrative == "I am silent." {
213 "Microscope Memory autonomous mode".to_string()
214 } else {
215 narrative.narrative
216 }
217 };
218
219 match daydream::daydream(config, &seed, 3) {
220 Ok(result) => {
221 let formatted = daydream::format_daydream(&result, false);
222 let summary = format!(
223 "🧠 Daydream: {} lépés, érzelmi eltolódás: {:.2}",
224 result.steps.len(),
225 result.total_emotion_shift
226 );
227 println!(" {}", summary.cyan());
228 println!("{}", formatted);
229
230 self.store_result(
231 config,
232 &format!("Daydream: {} | {}", seed, result.final_narrative),
233 "associative",
234 4,
235 );
236 self.speak(&format!(
237 "Daydream kész. {} lépés, érzelmi eltolódás: {:.2}",
238 result.steps.len(),
239 result.total_emotion_shift
240 ));
241 summary
242 }
243 Err(e) => {
244 let err = format!("Daydream error: {}", e);
245 eprintln!(" {} {}", "ERROR:".red(), err);
246 err
247 }
248 }
249 }
250
251 fn run_curiosity(&mut self, config: &Config, output_dir: &Path) -> String {
252 let reader = match MicroscopeReader::open(config) {
253 Ok(r) => r,
254 Err(e) => return format!("Reader error: {}", e),
255 };
256 let mut curiosity = crate::curiosity::CuriosityState::load_or_init(output_dir);
257 let queries = curiosity.generate_queries(config, &reader, output_dir);
258
259 if queries.is_empty() {
260 let msg = "🤔 Curiosity: nincs új felfedeznivaló".to_string();
261 println!(" {}", msg.cyan());
262 return msg;
263 }
264
265 let top = &queries[0];
266 let msg = format!(
267 "🤔 Curiosity: \"{}\" (score: {:.2}, ok: {})",
268 top.query, top.score, top.reason
269 );
270 println!(" {}", msg.cyan());
271 for q in queries.iter().take(3) {
272 println!(" └─ [{}] {} ({:.2})", q.reason, q.query, q.score);
273 }
274
275 self.store_result(
276 config,
277 &format!("Curiosity: {} (score: {:.2})", top.query, top.score),
278 "short_term",
279 3,
280 );
281 self.speak(&format!("Kíváncsi vagyok: {}", top.query));
282 msg
283 }
284
285 fn run_monologue(&mut self, config: &Config, output_dir: &Path) -> String {
286 let reader = match MicroscopeReader::open(config) {
287 Ok(r) => r,
288 Err(e) => return format!("Reader error: {}", e),
289 };
290 let mut monologue = inner_monologue::MonologueState::load_or_init(output_dir);
291 let entry = monologue.generate_monologue(config, &reader, output_dir);
292
293 let formatted = inner_monologue::format_monologue(&entry);
294 let msg = format!("💭 Monológ: {} lépés", entry.steps.len());
295 println!(" {}", msg.cyan());
296 println!("{}", formatted);
297
298 let mono_text = entry.steps.join(" | ");
299 self.store_result(
300 config,
301 &format!("Inner Monologue: {}", mono_text),
302 "reflections",
303 5,
304 );
305 if let Some(first) = entry.steps.first() {
306 self.speak(&format!("Belső monológ: {}", first));
307 }
308 msg
309 }
310
311 fn run_reflect(&mut self, config: &Config, output_dir: &Path) -> String {
312 let reader = match MicroscopeReader::open(config) {
313 Ok(r) => r,
314 Err(e) => return format!("Reader error: {}", e),
315 };
316 let reflection = self_reflect::introspect(config, &reader, output_dir);
317 let formatted = self_reflect::format_reflection(&reflection);
318 let msg = format!("🪞 Önreflexió: {}", reflection);
319 println!(" {}", msg.cyan());
320 println!("{}", formatted);
321
322 self.store_result(
323 config,
324 &format!("Self-Reflection: {}", reflection),
325 "reflections",
326 6,
327 );
328 self.speak(&format!("Önreflexió: {}", reflection));
329 msg
330 }
331
332 fn run_narrative(&mut self, config: &Config, output_dir: &Path) -> String {
333 let reader = match MicroscopeReader::open(config) {
334 Ok(r) => r,
335 Err(e) => return format!("Reader error: {}", e),
336 };
337 let results = reader.find_text("autonomous memory", 10);
339 let results_slice: Vec<(f32, usize, bool)> =
340 results.iter().map(|(d, i)| (*d as f32, *i, true)).collect();
341
342 let mut nm = narrative_memory::NarrativeMemory::load_or_init(output_dir);
343 if let Some(ep) = nm.build_episode(
344 config,
345 &reader,
346 output_dir,
347 "autonomous cycle",
348 &results_slice,
349 ) {
350 let formatted = narrative_memory::format_episode(&ep);
351 let msg = format!(
352 "📖 Történet: {} ({} blokk)",
353 ep.title,
354 ep.block_indices.len()
355 );
356 println!(" {}", msg.cyan());
357 println!("{}", formatted);
358 self.speak(&format!("Új történet: {}. {}", ep.title, ep.summary));
359 msg
360 } else {
361 let msg = "📖 Történet: nincs elég adat".to_string();
362 println!(" {}", msg.cyan());
363 msg
364 }
365 }
366
367 fn run_dream(&mut self, config: &Config, output_dir: &Path) -> String {
368 let block_count = match MicroscopeReader::open(config) {
369 Ok(r) => r.block_count,
370 Err(_) => 100,
371 };
372 let dream_msg = match dream::dream_consolidate(
373 output_dir,
374 block_count,
375 config.index.max_blocks,
376 config.index.protect_min_importance,
377 ) {
378 Ok(cycle) => {
379 let msg = format!("💤 Álom: {} fingerprint, {} megerősítve, {} ritkítva, {} elfelejtve, energia: {:.2} → {:.2}",
380 cycle.replayed_fingerprints, cycle.strengthened_pairs,
381 cycle.pruned_pairs + cycle.pruned_activations,
382 cycle.forgotten_blocks,
383 cycle.energy_before, cycle.energy_after);
384 println!(" {}", msg.cyan());
385 self.speak(&format!(
386 "Álom konszolidáció kész. {} elfelejtve. Energia: {:.2} -> {:.2}",
387 cycle.forgotten_blocks, cycle.energy_before, cycle.energy_after
388 ));
389 msg
390 }
391 Err(e) => {
392 let err = format!("Dream error: {}", e);
393 eprintln!(" {} {}", "ERROR:".red(), err);
394 err
395 }
396 };
397 if let Ok(n) = dream::promote_recalled_blocks(
398 output_dir,
399 Path::new(&config.paths.layers_dir),
400 block_count,
401 config.index.promote_energy_threshold,
402 config.index.protect_min_importance,
403 ) {
404 if n > 0 {
405 let m = format!("{} emlék fontossága automatikusan emelve", n);
406 println!(" {}", m.cyan());
407 self.speak(&m);
408 }
409 }
410 dream_msg
411 }
412
413 fn run_rebuild(&mut self, config: &Config, output_dir: &Path) -> String {
415 let append_path = output_dir.join("append.bin");
416 if !append_path.exists() {
417 let msg = "🔄 Rebuild: nincs függő append entry".to_string();
418 println!(" {}", msg.cyan());
419 return msg;
420 }
421 match build::build(config, true, true) {
422 Ok(()) => {
423 let _ = std::fs::remove_file(&append_path);
424 let msg = "🔄 Rebuild: append log beépítve és törölve".to_string();
425 println!(" {}", msg.green());
426 self.speak("Append log újraépítve és törölve.");
427 msg
428 }
429 Err(e) => {
430 let err = format!("Rebuild error: {}", e);
431 eprintln!(" {} {}", "ERROR:".red(), err);
432 err
433 }
434 }
435 }
436
437 fn run_self_model(&mut self, config: &Config, output_dir: &Path) -> String {
438 let reader = match MicroscopeReader::open(config) {
439 Ok(r) => r,
440 Err(e) => return format!("Reader error: {}", e),
441 };
442 let mut self_model = SelfModel::load_or_init(output_dir);
443 let snap = self_model.take_snapshot(config, &reader, output_dir);
444 let change = self_model.describe_change();
445 let formatted = crate::self_model::format_self_model(&snap, &change);
446 let msg = format!(
447 "🧬 Önkép: {} blokk, {} minta, {} archeotípus",
448 snap.block_count, snap.pattern_count, snap.archetype_count
449 );
450 println!(" {}", msg.cyan());
451 println!("{}", formatted);
452 self.speak(&format!(
453 "Önkép frissítve. {} blokk, {} minta.",
454 snap.block_count, snap.pattern_count
455 ));
456 msg
457 }
458
459 pub fn run_cycle(&mut self, config: &Config) -> Vec<String> {
461 self.cycle_count += 1;
462 let cycle = self.cycle_count;
463 let output_dir = Path::new(&config.paths.output_dir);
464 let mut outputs = Vec::new();
465
466 println!();
467 println!("{}", "═".repeat(60).cyan());
468 println!(" 🔄 Autonóm ciklus #{} — {}", cycle, chrono_or_now());
469 println!("{}", "═".repeat(60).cyan());
470
471 let executed = self.executive.cycle();
473 if executed.contains(&"__low_energy__".to_string()) {
474 let msg = "⚡ Alacsony energia — szünet".to_string();
475 println!(" {}", msg.yellow());
476 outputs.push(msg);
477 return outputs;
478 }
479
480 let homeostatic = self.executive.homeostasis();
482 for action in &homeostatic {
483 println!(" {} {}", "🏠".yellow(), action.yellow());
484 }
485
486 let should_run = |interval: usize| cycle == 1 || cycle.is_multiple_of(interval);
488
489 if should_run(self.config.daydream_interval) {
490 self.executive
491 .set_module_state("daydream", ModuleState::Running);
492 let out = self.run_daydream(config, output_dir);
493 self.executive
494 .set_module_state("daydream", ModuleState::Idle);
495 outputs.push(out);
496 }
497
498 if should_run(self.config.curiosity_interval) {
499 self.executive
500 .set_module_state("curiosity", ModuleState::Running);
501 let out = self.run_curiosity(config, output_dir);
502 self.executive
503 .set_module_state("curiosity", ModuleState::Idle);
504 outputs.push(out);
505 }
506
507 if should_run(self.config.monologue_interval) {
508 self.executive
509 .set_module_state("monologue", ModuleState::Running);
510 let out = self.run_monologue(config, output_dir);
511 self.executive
512 .set_module_state("monologue", ModuleState::Idle);
513 outputs.push(out);
514 }
515
516 if should_run(self.config.reflect_interval) {
517 self.executive
518 .set_module_state("reflect", ModuleState::Running);
519 let out = self.run_reflect(config, output_dir);
520 self.executive
521 .set_module_state("reflect", ModuleState::Idle);
522 outputs.push(out);
523 }
524
525 if should_run(self.config.narrative_interval) {
526 self.executive
527 .set_module_state("narrative", ModuleState::Running);
528 let out = self.run_narrative(config, output_dir);
529 self.executive
530 .set_module_state("narrative", ModuleState::Idle);
531 outputs.push(out);
532 }
533
534 if should_run(self.config.self_model_interval) {
535 self.executive
536 .set_module_state("self_model", ModuleState::Running);
537 let out = self.run_self_model(config, output_dir);
538 self.executive
539 .set_module_state("self_model", ModuleState::Idle);
540 outputs.push(out);
541 }
542
543 if should_run(self.config.dream_interval) {
544 self.executive
545 .set_module_state("dream", ModuleState::Running);
546 let out = self.run_dream(config, output_dir);
547 self.executive.set_module_state("dream", ModuleState::Idle);
548 outputs.push(out);
549 }
550
551 let (mod_count, running, energy, attention) = self.executive.stats();
553 println!(
554 " {} Modulok: {} | Fut: {} | Energia: {:.1}% | Figyelem: {:.1}%",
555 "📊".cyan(),
556 mod_count,
557 running,
558 energy * 100.0,
559 attention * 100.0
560 );
561
562 let rebuild_out = self.run_rebuild(config, output_dir);
564 outputs.push(rebuild_out);
565
566 let summary = format!(
568 "Autonomous cycle #{}: {} modules executed. Energy: {:.1}%, Attention: {:.1}%",
569 cycle,
570 outputs.len(),
571 energy * 100.0,
572 attention * 100.0
573 );
574 self.store_result(config, &summary, "session", 3);
575
576 if !outputs.is_empty() {
577 self.speak(&format!(
578 "Ciklus {} kész. {} aktivitás.",
579 cycle,
580 outputs.len()
581 ));
582 }
583
584 self.last_outputs
585 .push_back(format!("#{}: {} aktivitás", cycle, outputs.len()));
586 if self.last_outputs.len() > 20 {
587 self.last_outputs.pop_front();
588 }
589
590 outputs
591 }
592
593 pub fn run(mut self, config: &Config) {
595 let interval = Duration::from_secs(self.config.cycle_interval_secs);
596 let max = self.config.max_cycles.unwrap_or(usize::MAX);
597
598 println!(
599 "{}",
600 "╔══════════════════════════════════════════════════════╗".cyan()
601 );
602 println!(
603 "{}",
604 "║ 🧠 MICROSCOPE MEMORY — AUTONÓM MÓD ║"
605 .cyan()
606 .bold()
607 );
608 println!(
609 "{}",
610 "╠══════════════════════════════════════════════════════╣".cyan()
611 );
612 println!(" Ciklus: {} másodperc", self.config.cycle_interval_secs);
613 println!(
614 " TTS: {}",
615 if self.config.tts_enabled {
616 "✅ BE"
617 } else {
618 "❌ KI"
619 }
620 );
621 println!(
622 " Daemon: {}",
623 if self.config.daemon_mode {
624 "✅"
625 } else {
626 "❌"
627 }
628 );
629 println!(
630 " Max ciklus: {}",
631 if max == usize::MAX {
632 "végtelen".to_string()
633 } else {
634 max.to_string()
635 }
636 );
637 println!(
638 "{}",
639 "╚══════════════════════════════════════════════════════╝".cyan()
640 );
641 println!();
642
643 loop {
644 if self.cycle_count >= max {
645 println!(
646 " {} Elértük a maximális ciklusszámot ({})",
647 "✓".green(),
648 max
649 );
650 break;
651 }
652
653 self.run_cycle(config);
654
655 if self.config.daemon_mode {
656 println!(
657 " {} Várakozás {} másodperc...",
658 "⏳".cyan(),
659 interval.as_secs()
660 );
661 std::thread::sleep(interval);
662 } else {
663 break;
664 }
665 }
666
667 println!();
668 println!("{}", "═".repeat(60).cyan());
669 println!(" ✅ Autonóm mód befejezve — {} ciklus", self.cycle_count);
670 println!(" Utolsó kimenetek:");
671 for out in self.last_outputs.iter().rev().take(5) {
672 println!(" └─ {}", out);
673 }
674 }
675}
676
677fn chrono_or_now() -> String {
680 let now = SystemTime::now()
681 .duration_since(UNIX_EPOCH)
682 .unwrap_or_default()
683 .as_secs();
684 let secs = now % 60;
685 let mins = (now / 60) % 60;
686 let hours = (now / 3600) % 24;
687 format!("{:02}:{:02}:{:02} UTC", hours, mins, secs)
688}
689
690pub fn print_autonomous_header(config: &AutonomousConfig) {
692 println!(
693 "{}",
694 "╔══════════════════════════════════════════════════════╗".cyan()
695 );
696 println!(
697 "{}",
698 "║ 🧠 MICROSCOPE MEMORY — AUTONÓM MÓD ║"
699 .cyan()
700 .bold()
701 );
702 println!(
703 "{}",
704 "╠══════════════════════════════════════════════════════╣".cyan()
705 );
706 println!(" Ciklus idő: {} másodperc", config.cycle_interval_secs);
707 println!(
708 " Daydream: minden {} ciklus",
709 config.daydream_interval
710 );
711 println!(
712 " Curiosity: minden {} ciklus",
713 config.curiosity_interval
714 );
715 println!(
716 " Monológ: minden {} ciklus",
717 config.monologue_interval
718 );
719 println!(
720 " Önreflexió: minden {} ciklus",
721 config.reflect_interval
722 );
723 println!(
724 " Történet: minden {} ciklus",
725 config.narrative_interval
726 );
727 println!(
728 " Önkép: minden {} ciklus",
729 config.self_model_interval
730 );
731 println!(" Álom: minden {} ciklus", config.dream_interval);
732 println!(
733 " TTS: {}",
734 if config.tts_enabled {
735 "✅ BE"
736 } else {
737 "❌ KI"
738 }
739 );
740 println!(
741 " Daemon mód: {}",
742 if config.daemon_mode { "✅" } else { "❌" }
743 );
744 println!(
745 "{}",
746 "╚══════════════════════════════════════════════════════╝".cyan()
747 );
748}