microscope_memory/
sequential_thinking.rs1use crate::config::Config;
5use crate::reader::MicroscopeReader;
6use std::time::Instant;
7
8#[derive(Debug, Clone)]
9pub struct ThoughtStep {
10 pub thought_number: usize,
11 pub total_thoughts: usize,
12 pub content: String,
13 pub is_revision: bool,
14 pub revises_thought: Option<usize>,
15 pub timestamp: Instant,
16}
17
18pub struct ThinkingChain {
19 pub steps: Vec<ThoughtStep>,
20 pub max_steps: usize,
21 pub next_thought_needed: bool,
22}
23
24impl ThinkingChain {
25 pub fn new(max_steps: usize) -> Self {
26 Self {
27 steps: Vec::new(),
28 max_steps,
29 next_thought_needed: true,
30 }
31 }
32
33 pub fn add_step(&mut self, content: String, is_revision: bool, revises: Option<usize>) {
35 let step_num = self.steps.len() + 1;
36 self.steps.push(ThoughtStep {
37 thought_number: step_num,
38 total_thoughts: self.max_steps,
39 content,
40 is_revision,
41 revises_thought: revises,
42 timestamp: Instant::now(),
43 });
44
45 if step_num >= self.max_steps {
46 self.next_thought_needed = false;
47 }
48 }
49
50 pub fn brainstorm(&mut self, reader: &MicroscopeReader, config: &Config, initial_query: &str) {
52 println!("🧠 Sequential Thinking: Processing '{}'...", initial_query);
53
54 let results = reader.find_text(initial_query, 5);
56 if let Some(&(_depth, idx)) = results.first() {
57 self.add_step(reader.text(idx).to_string(), false, None);
58 }
59
60 while self.next_thought_needed && self.steps.len() < self.max_steps {
62 let last_idx = if let Some(last) = self.steps.last() {
63 let text = &last.content;
65 reader
66 .find_text(text, 1)
67 .first()
68 .map(|&(_, i)| i)
69 .unwrap_or(0)
70 } else {
71 break;
72 };
73
74 let h = reader.header(last_idx);
75
76 let result_set = reader.radial_search(
78 config,
79 h.x,
80 h.y,
81 h.z,
82 h.depth,
83 config.search.zoom_weight * 0.5, 10, );
86
87 let retrieved: Vec<String> = result_set
88 .all()
89 .iter()
90 .map(|r| reader.text(r.block_idx).to_string())
91 .collect();
92
93 if let Some(next_text) = retrieved.get(1) {
94 self.add_step(next_text.clone(), false, None);
96 } else {
97 self.next_thought_needed = false;
98 }
99 }
100 }
101
102 pub fn display(&self) {
103 for step in &self.steps {
104 let prefix = if step.is_revision {
105 "🔄 REVISION"
106 } else {
107 "💭 THOUGHT"
108 };
109 println!(
110 "[{}/{}] {} ({}): {}",
111 step.thought_number,
112 step.total_thoughts,
113 prefix,
114 step.revises_thought
115 .map(|n| n.to_string())
116 .unwrap_or_else(|| "new".to_string()),
117 step.content
118 );
119 }
120 }
121}