@gotza02/mathinking 2.9.1 → 2.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -6
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/test-max-intelligence.d.ts +2 -0
- package/dist/test-max-intelligence.d.ts.map +1 -0
- package/dist/test-max-intelligence.js +59 -0
- package/dist/test-max-intelligence.js.map +1 -0
- package/dist/test-resilience.d.ts +2 -0
- package/dist/test-resilience.d.ts.map +1 -0
- package/dist/test-resilience.js +49 -0
- package/dist/test-resilience.js.map +1 -0
- package/dist/tools/orchestrator.d.ts +1 -1
- package/dist/tools/orchestrator.d.ts.map +1 -1
- package/dist/tools/orchestrator.js +107 -65
- package/dist/tools/orchestrator.js.map +1 -1
- package/dist/tools/sequential-thinking.d.ts +11 -91
- package/dist/tools/sequential-thinking.d.ts.map +1 -1
- package/dist/tools/sequential-thinking.js +194 -782
- package/dist/tools/sequential-thinking.js.map +1 -1
- package/dist/types/index.d.ts +18 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -3
- package/dist/types/index.js.map +1 -1
- package/dist/utils/resilience.d.ts +27 -0
- package/dist/utils/resilience.d.ts.map +1 -0
- package/dist/utils/resilience.js +96 -0
- package/dist/utils/resilience.js.map +1 -0
- package/dist/utils/tool-cache.d.ts +17 -0
- package/dist/utils/tool-cache.d.ts.map +1 -0
- package/dist/utils/tool-cache.js +57 -0
- package/dist/utils/tool-cache.js.map +1 -0
- package/dist/utils/vector-memory.d.ts +39 -0
- package/dist/utils/vector-memory.d.ts.map +1 -0
- package/dist/utils/vector-memory.js +132 -0
- package/dist/utils/vector-memory.js.map +1 -0
- package/package.json +1 -1
|
@@ -3,8 +3,10 @@ import * as fs from 'fs/promises';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import * as os from 'os';
|
|
5
5
|
import { orchestratorManager } from './orchestrator.js';
|
|
6
|
+
import { vectorMemory } from '../utils/vector-memory.js';
|
|
6
7
|
/**
|
|
7
|
-
* Sequential Thinking Manager (The Brain)
|
|
8
|
+
* Sequential Thinking Manager (The Brain v2.0)
|
|
9
|
+
* Upgraded with Tree of Thoughts (ToT), Semantic Memory, and Reflexion.
|
|
8
10
|
*/
|
|
9
11
|
export class SequentialThinkingManager {
|
|
10
12
|
sessions = new Map();
|
|
@@ -12,20 +14,13 @@ export class SequentialThinkingManager {
|
|
|
12
14
|
storagePath;
|
|
13
15
|
initialized = false;
|
|
14
16
|
lastActionTimestamp = 0;
|
|
15
|
-
MIN_DELAY_MS =
|
|
17
|
+
MIN_DELAY_MS = 500;
|
|
16
18
|
constructor() {
|
|
17
|
-
// Set up persistent storage in user's home directory
|
|
18
19
|
this.storagePath = path.join(os.homedir(), '.mathinking', 'sessions.json');
|
|
19
20
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Helper to add a delay
|
|
22
|
-
*/
|
|
23
21
|
sleep(ms) {
|
|
24
22
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
25
23
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Initialize storage directory and load existing sessions
|
|
28
|
-
*/
|
|
29
24
|
async initStorage(force = false) {
|
|
30
25
|
if (this.initialized && !force)
|
|
31
26
|
return;
|
|
@@ -33,87 +28,43 @@ export class SequentialThinkingManager {
|
|
|
33
28
|
const dir = path.dirname(this.storagePath);
|
|
34
29
|
await fs.mkdir(dir, { recursive: true });
|
|
35
30
|
const data = await fs.readFile(this.storagePath, 'utf8');
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
savedSessions = JSON.parse(data);
|
|
39
|
-
}
|
|
40
|
-
catch (parseError) {
|
|
41
|
-
if (!this.initialized) {
|
|
42
|
-
console.warn('[Brain] Storage file is invalid or empty, initializing with empty sessions.');
|
|
43
|
-
}
|
|
44
|
-
savedSessions = {};
|
|
45
|
-
}
|
|
46
|
-
// Merge or replace sessions
|
|
47
|
-
let newestTimestamp = 0;
|
|
31
|
+
const savedSessions = JSON.parse(data);
|
|
48
32
|
for (const [id, session] of Object.entries(savedSessions)) {
|
|
49
33
|
this.sessions.set(id, session);
|
|
50
|
-
|
|
51
|
-
const ts = new Date(session.updatedAt).getTime();
|
|
52
|
-
if (ts > newestTimestamp) {
|
|
53
|
-
newestTimestamp = ts;
|
|
54
|
-
this.lastSessionId = id;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
if (!this.initialized) {
|
|
58
|
-
console.error(`[Brain] Loaded ${this.sessions.size} sessions from storage.`);
|
|
34
|
+
this.lastSessionId = id; // Naive, should sort
|
|
59
35
|
}
|
|
60
36
|
}
|
|
61
37
|
catch (error) {
|
|
62
|
-
//
|
|
63
|
-
if (error.code !== 'ENOENT') {
|
|
64
|
-
console.error('[Brain] Storage initialization error:', error);
|
|
65
|
-
}
|
|
38
|
+
// Ignore
|
|
66
39
|
}
|
|
67
40
|
finally {
|
|
68
41
|
this.initialized = true;
|
|
69
42
|
}
|
|
70
43
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Save all sessions to persistent storage
|
|
73
|
-
*/
|
|
74
44
|
async saveToStorage() {
|
|
75
45
|
try {
|
|
76
|
-
//
|
|
77
|
-
if (this.sessions.size >
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
this.sessions = new Map(toKeep);
|
|
81
|
-
console.error(`[Brain] Pruned sessions. Kept the 100 most recent.`);
|
|
46
|
+
// Pruning logic to keep file size small
|
|
47
|
+
if (this.sessions.size > 50) {
|
|
48
|
+
const keys = Array.from(this.sessions.keys());
|
|
49
|
+
this.sessions.delete(keys[0]);
|
|
82
50
|
}
|
|
83
51
|
const data = JSON.stringify(Object.fromEntries(this.sessions), null, 2);
|
|
84
52
|
await fs.writeFile(this.storagePath, data, 'utf8');
|
|
85
53
|
}
|
|
86
54
|
catch (error) {
|
|
87
|
-
console.error('[Brain]
|
|
55
|
+
console.error('[Brain] Save failed:', error);
|
|
88
56
|
}
|
|
89
57
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Process a thinking action
|
|
92
|
-
*/
|
|
93
58
|
async process(input) {
|
|
94
|
-
|
|
95
|
-
let
|
|
96
|
-
|
|
97
|
-
// Extract sessionId if it's hidden inside the action string
|
|
98
|
-
const sessionMatch = action.match(/<arg_value>(.*?)($|<)/);
|
|
99
|
-
if (sessionMatch && (!input.sessionId || input.sessionId === '')) {
|
|
100
|
-
input.sessionId = sessionMatch[1].trim();
|
|
101
|
-
console.error(`[Brain] Recovered sessionId from mangled action: ${input.sessionId}`);
|
|
102
|
-
}
|
|
103
|
-
action = action.split('<')[0].trim();
|
|
104
|
-
}
|
|
105
|
-
// Rate limiting / Flood protection
|
|
59
|
+
await this.initStorage(true);
|
|
60
|
+
let result;
|
|
61
|
+
// Rate limiting
|
|
106
62
|
const now = Date.now();
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const waitTime = this.MIN_DELAY_MS - elapsed;
|
|
110
|
-
console.error(`[Brain] Rate limiting: Sleeping for ${waitTime}ms to prevent flooding...`);
|
|
111
|
-
await this.sleep(waitTime);
|
|
63
|
+
if (now - this.lastActionTimestamp < this.MIN_DELAY_MS) {
|
|
64
|
+
await this.sleep(200);
|
|
112
65
|
}
|
|
113
66
|
this.lastActionTimestamp = Date.now();
|
|
114
|
-
|
|
115
|
-
let result;
|
|
116
|
-
switch (action) {
|
|
67
|
+
switch (input.action) {
|
|
117
68
|
case 'start_session':
|
|
118
69
|
result = this.startSession(input);
|
|
119
70
|
break;
|
|
@@ -122,7 +73,16 @@ export class SequentialThinkingManager {
|
|
|
122
73
|
break;
|
|
123
74
|
case 'create_branch':
|
|
124
75
|
result = this.createBranch(input);
|
|
125
|
-
break;
|
|
76
|
+
break; // Legacy support
|
|
77
|
+
case 'generate_options':
|
|
78
|
+
result = this.generateOptions(input);
|
|
79
|
+
break; // ToT
|
|
80
|
+
case 'evaluate_options':
|
|
81
|
+
result = this.evaluateOptions(input);
|
|
82
|
+
break; // ToT
|
|
83
|
+
case 'select_option':
|
|
84
|
+
result = this.selectOption(input);
|
|
85
|
+
break; // ToT
|
|
126
86
|
case 'revise_thought':
|
|
127
87
|
result = this.reviseThought(input);
|
|
128
88
|
break;
|
|
@@ -132,79 +92,82 @@ export class SequentialThinkingManager {
|
|
|
132
92
|
case 'verify_hypothesis':
|
|
133
93
|
result = this.verifyHypothesis(input);
|
|
134
94
|
break;
|
|
135
|
-
case 'adjust_total_thoughts':
|
|
136
|
-
result = this.adjustTotalThoughts(input);
|
|
137
|
-
break;
|
|
138
95
|
case 'conclude':
|
|
139
96
|
result = this.conclude(input);
|
|
140
97
|
break;
|
|
141
|
-
case '
|
|
142
|
-
result = this.
|
|
98
|
+
case 'execute_conclusion':
|
|
99
|
+
result = await this.executeConclusion(input);
|
|
143
100
|
break;
|
|
101
|
+
case 'reflect':
|
|
102
|
+
result = this.reflect(input);
|
|
103
|
+
break; // Reflexion
|
|
104
|
+
case 'replan':
|
|
105
|
+
result = await this.replan(input);
|
|
106
|
+
break; // Active Learning
|
|
144
107
|
case 'get_history':
|
|
145
108
|
result = this.getHistory(input);
|
|
146
109
|
break;
|
|
147
|
-
|
|
148
|
-
result = this.clearHistory();
|
|
149
|
-
break;
|
|
150
|
-
case 'delete_session':
|
|
151
|
-
result = this.deleteSession(input);
|
|
152
|
-
break;
|
|
153
|
-
case 'list_sessions':
|
|
154
|
-
result = this.listSessions();
|
|
155
|
-
break;
|
|
156
|
-
case 'delete_thought':
|
|
157
|
-
result = this.deleteThought(input);
|
|
158
|
-
break;
|
|
159
|
-
case 'self_critique':
|
|
160
|
-
result = this.selfCritique(input);
|
|
161
|
-
break;
|
|
162
|
-
case 'summarize_history':
|
|
163
|
-
result = this.summarizeHistory(input);
|
|
164
|
-
break;
|
|
165
|
-
case 'merge_branches':
|
|
166
|
-
result = this.mergeBranches(input);
|
|
167
|
-
break;
|
|
168
|
-
case 'execute_conclusion':
|
|
169
|
-
result = await this.executeConclusion(input);
|
|
170
|
-
break;
|
|
171
|
-
default:
|
|
172
|
-
result = {
|
|
173
|
-
success: false,
|
|
174
|
-
sessionId: input.sessionId || '',
|
|
175
|
-
currentStep: 0,
|
|
176
|
-
totalThoughts: 0,
|
|
177
|
-
status: 'in_progress',
|
|
178
|
-
message: `Unknown action: ${input.action}`,
|
|
179
|
-
nextSuggestedActions: ['start_session', 'list_sessions']
|
|
180
|
-
};
|
|
110
|
+
default: result = this.startSession(input); // Default fallback
|
|
181
111
|
}
|
|
182
|
-
|
|
183
|
-
if (result.success) {
|
|
112
|
+
if (result.success)
|
|
184
113
|
await this.saveToStorage();
|
|
185
|
-
}
|
|
186
114
|
return result;
|
|
187
115
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
116
|
+
// --- Core Methods ---
|
|
117
|
+
async replan(input) {
|
|
118
|
+
const session = this.getSession(input.sessionId);
|
|
119
|
+
if (!session)
|
|
120
|
+
return { success: false, message: 'Session not found' };
|
|
121
|
+
console.error(`[Brain] Strategic Re-plan requested for session: ${session.sessionId}`);
|
|
122
|
+
// 1. Record the failure
|
|
123
|
+
session.currentStep++;
|
|
124
|
+
const failureThought = {
|
|
125
|
+
id: uuidv4(),
|
|
126
|
+
stepNumber: session.currentStep,
|
|
127
|
+
thought: `STRATEGIC FAILURE: Task failed after multiple healing attempts. Error: ${input.thought}`,
|
|
128
|
+
thoughtType: 'reflection',
|
|
129
|
+
timestamp: new Date().toISOString(),
|
|
130
|
+
confidence: 100
|
|
131
|
+
};
|
|
132
|
+
session.thoughtHistory.push(failureThought);
|
|
133
|
+
// 2. Simple Heuristic Re-plan (In real scenario, the LLM would decide)
|
|
134
|
+
// If it's a fetch error, try to use a mock or alternative source.
|
|
135
|
+
let suggestedPlan = undefined;
|
|
136
|
+
if (input.thought?.includes('fetch failed')) {
|
|
137
|
+
suggestedPlan = {
|
|
138
|
+
planId: 'recovery-' + uuidv4().substring(0, 8),
|
|
139
|
+
name: 'Network Recovery Plan',
|
|
140
|
+
tasks: [{
|
|
141
|
+
id: 'fallback',
|
|
142
|
+
name: 'Fallback Echo',
|
|
143
|
+
toolName: 'echo',
|
|
144
|
+
toolInput: { msg: 'Recovered using fallback echo due to network failure.' },
|
|
145
|
+
dependencies: []
|
|
146
|
+
}]
|
|
147
|
+
};
|
|
194
148
|
}
|
|
149
|
+
return {
|
|
150
|
+
success: true,
|
|
151
|
+
sessionId: session.sessionId,
|
|
152
|
+
currentStep: session.currentStep,
|
|
153
|
+
totalThoughts: session.totalThoughts,
|
|
154
|
+
status: session.status,
|
|
155
|
+
message: 'Re-plan generated based on failure context.',
|
|
156
|
+
executionPlan: suggestedPlan // Pass back to Body
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
startSession(input) {
|
|
195
160
|
const sessionId = uuidv4();
|
|
196
|
-
const totalThoughts = input.totalThoughts || 5;
|
|
197
|
-
const now = new Date().toISOString();
|
|
198
161
|
const session = {
|
|
199
162
|
sessionId,
|
|
200
|
-
problemStatement: input.problemStatement,
|
|
201
|
-
totalThoughts,
|
|
163
|
+
problemStatement: input.problemStatement || 'No problem statement',
|
|
164
|
+
totalThoughts: input.totalThoughts || 10,
|
|
202
165
|
currentStep: 0,
|
|
203
166
|
thoughtHistory: [],
|
|
204
167
|
branches: [],
|
|
205
168
|
status: 'in_progress',
|
|
206
|
-
createdAt:
|
|
207
|
-
updatedAt:
|
|
169
|
+
createdAt: new Date().toISOString(),
|
|
170
|
+
updatedAt: new Date().toISOString()
|
|
208
171
|
};
|
|
209
172
|
this.sessions.set(sessionId, session);
|
|
210
173
|
this.lastSessionId = sessionId;
|
|
@@ -212,56 +175,27 @@ export class SequentialThinkingManager {
|
|
|
212
175
|
success: true,
|
|
213
176
|
sessionId,
|
|
214
177
|
currentStep: 0,
|
|
215
|
-
totalThoughts,
|
|
178
|
+
totalThoughts: session.totalThoughts,
|
|
216
179
|
status: 'in_progress',
|
|
217
|
-
message:
|
|
218
|
-
nextSuggestedActions: ['add_thought (type: initial_analysis)', 'adjust_total_thoughts']
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* List all available sessions
|
|
223
|
-
*/
|
|
224
|
-
listSessions() {
|
|
225
|
-
const sessionList = Array.from(this.sessions.values())
|
|
226
|
-
.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())
|
|
227
|
-
.map((s) => `• [${s.status}] ${s.sessionId}: ${s.problemStatement.substring(0, 50)}... (${s.currentStep}/${s.totalThoughts})`)
|
|
228
|
-
.join('\n');
|
|
229
|
-
return {
|
|
230
|
-
success: true,
|
|
231
|
-
sessionId: this.lastSessionId || '',
|
|
232
|
-
currentStep: 0,
|
|
233
|
-
totalThoughts: 0,
|
|
234
|
-
status: 'completed',
|
|
235
|
-
message: sessionList.length > 0
|
|
236
|
-
? `Available Thinking Sessions (Newest first):\n${sessionList}`
|
|
237
|
-
: 'No thinking sessions found.'
|
|
180
|
+
message: 'Brain 2.0 Session Started. Ready for Tree of Thoughts.'
|
|
238
181
|
};
|
|
239
182
|
}
|
|
240
|
-
/**
|
|
241
|
-
* Add a new thought to the session
|
|
242
|
-
*/
|
|
243
183
|
addThought(input) {
|
|
244
184
|
const session = this.getSession(input.sessionId);
|
|
245
185
|
if (!session)
|
|
246
|
-
return
|
|
247
|
-
if (!input.thought)
|
|
248
|
-
return this.errorResponse(session.sessionId, 'Thought content is required');
|
|
186
|
+
return { success: false, message: 'Session not found' };
|
|
249
187
|
session.currentStep++;
|
|
250
|
-
const thoughtId = uuidv4();
|
|
251
188
|
const thought = {
|
|
252
|
-
id:
|
|
189
|
+
id: uuidv4(),
|
|
253
190
|
stepNumber: session.currentStep,
|
|
254
|
-
thought: input.thought,
|
|
191
|
+
thought: input.thought || '',
|
|
255
192
|
thoughtType: input.thoughtType || 'initial_analysis',
|
|
256
193
|
timestamp: new Date().toISOString(),
|
|
257
|
-
confidence: input.confidence ?? 70,
|
|
258
|
-
parentId: input.branchFromThoughtId
|
|
194
|
+
confidence: input.confidence ?? 70, // Default confidence
|
|
195
|
+
parentId: input.branchFromThoughtId || this.getLastThoughtId(session),
|
|
196
|
+
branchLabel: input.branchLabel // Preserve label
|
|
259
197
|
};
|
|
260
198
|
session.thoughtHistory.push(thought);
|
|
261
|
-
session.updatedAt = new Date().toISOString();
|
|
262
|
-
if (session.currentStep >= session.totalThoughts) {
|
|
263
|
-
session.status = 'awaiting_verification';
|
|
264
|
-
}
|
|
265
199
|
return {
|
|
266
200
|
success: true,
|
|
267
201
|
sessionId: session.sessionId,
|
|
@@ -269,410 +203,59 @@ export class SequentialThinkingManager {
|
|
|
269
203
|
totalThoughts: session.totalThoughts,
|
|
270
204
|
status: session.status,
|
|
271
205
|
thought,
|
|
272
|
-
message:
|
|
273
|
-
nextSuggestedActions: this.getSuggestedActions(session, thought)
|
|
274
|
-
};
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Create a branch for exploring alternative thought paths
|
|
278
|
-
*/
|
|
279
|
-
createBranch(input) {
|
|
280
|
-
const session = this.getSession(input.sessionId);
|
|
281
|
-
if (!session)
|
|
282
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
283
|
-
if (!input.branchFromThoughtId)
|
|
284
|
-
return this.errorResponse(session.sessionId, 'branchFromThoughtId is required');
|
|
285
|
-
const parentThought = session.thoughtHistory.find((t) => t.id === input.branchFromThoughtId);
|
|
286
|
-
if (!parentThought)
|
|
287
|
-
return this.errorResponse(session.sessionId, 'Parent thought not found');
|
|
288
|
-
const branchId = uuidv4();
|
|
289
|
-
const branchLabel = input.branchLabel || `Branch ${session.branches.length + 1}`;
|
|
290
|
-
const branch = {
|
|
291
|
-
id: branchId,
|
|
292
|
-
label: branchLabel,
|
|
293
|
-
parentThoughtId: input.branchFromThoughtId,
|
|
294
|
-
thoughtIds: [],
|
|
295
|
-
status: 'active'
|
|
296
|
-
};
|
|
297
|
-
session.branches.push(branch);
|
|
298
|
-
session.updatedAt = new Date().toISOString();
|
|
299
|
-
if (input.thought) {
|
|
300
|
-
session.currentStep++;
|
|
301
|
-
const thoughtId = uuidv4();
|
|
302
|
-
const thought = {
|
|
303
|
-
id: thoughtId,
|
|
304
|
-
stepNumber: session.currentStep,
|
|
305
|
-
thought: input.thought,
|
|
306
|
-
thoughtType: 'branch_exploration',
|
|
307
|
-
timestamp: new Date().toISOString(),
|
|
308
|
-
parentId: input.branchFromThoughtId,
|
|
309
|
-
branchLabel,
|
|
310
|
-
confidence: input.confidence ?? 60
|
|
311
|
-
};
|
|
312
|
-
session.thoughtHistory.push(thought);
|
|
313
|
-
branch.thoughtIds.push(thoughtId);
|
|
314
|
-
return {
|
|
315
|
-
success: true,
|
|
316
|
-
sessionId: session.sessionId,
|
|
317
|
-
currentStep: session.currentStep,
|
|
318
|
-
totalThoughts: session.totalThoughts,
|
|
319
|
-
status: session.status,
|
|
320
|
-
thought,
|
|
321
|
-
branches: session.branches,
|
|
322
|
-
message: `Created branch "${branchLabel}" from thought #${parentThought.stepNumber}.`,
|
|
323
|
-
nextSuggestedActions: ['add_thought', 'create_branch']
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
return {
|
|
327
|
-
success: true,
|
|
328
|
-
sessionId: session.sessionId,
|
|
329
|
-
currentStep: session.currentStep,
|
|
330
|
-
totalThoughts: session.totalThoughts,
|
|
331
|
-
status: session.status,
|
|
332
|
-
branches: session.branches,
|
|
333
|
-
message: `Created branch "${branchLabel}" from thought #${parentThought.stepNumber}. Ready for thoughts.`,
|
|
334
|
-
nextSuggestedActions: ['add_thought']
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Revise a previous thought
|
|
339
|
-
*/
|
|
340
|
-
reviseThought(input) {
|
|
341
|
-
const session = this.getSession(input.sessionId);
|
|
342
|
-
if (!session)
|
|
343
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
344
|
-
if (!input.reviseThoughtId)
|
|
345
|
-
return this.errorResponse(session.sessionId, 'reviseThoughtId is required');
|
|
346
|
-
if (!input.thought)
|
|
347
|
-
return this.errorResponse(session.sessionId, 'New thought content is required');
|
|
348
|
-
const originalThought = session.thoughtHistory.find((t) => t.id === input.reviseThoughtId);
|
|
349
|
-
if (!originalThought)
|
|
350
|
-
return this.errorResponse(session.sessionId, 'Original thought not found');
|
|
351
|
-
session.currentStep++;
|
|
352
|
-
const thoughtId = uuidv4();
|
|
353
|
-
const revisedThought = {
|
|
354
|
-
id: thoughtId,
|
|
355
|
-
stepNumber: session.currentStep,
|
|
356
|
-
thought: input.thought,
|
|
357
|
-
thoughtType: 'revision',
|
|
358
|
-
timestamp: new Date().toISOString(),
|
|
359
|
-
isRevision: true,
|
|
360
|
-
revisedFromId: input.reviseThoughtId,
|
|
361
|
-
confidence: input.confidence ?? 75,
|
|
362
|
-
parentId: originalThought.parentId
|
|
363
|
-
};
|
|
364
|
-
session.thoughtHistory.push(revisedThought);
|
|
365
|
-
session.updatedAt = new Date().toISOString();
|
|
366
|
-
return {
|
|
367
|
-
success: true,
|
|
368
|
-
sessionId: session.sessionId,
|
|
369
|
-
currentStep: session.currentStep,
|
|
370
|
-
totalThoughts: session.totalThoughts,
|
|
371
|
-
status: session.status,
|
|
372
|
-
thought: revisedThought,
|
|
373
|
-
message: `Revised thought #${originalThought.stepNumber}.`,
|
|
374
|
-
nextSuggestedActions: ['add_thought', 'verify_hypothesis']
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* Set a hypothesis that needs verification
|
|
379
|
-
*/
|
|
380
|
-
setHypothesis(input) {
|
|
381
|
-
const session = this.getSession(input.sessionId);
|
|
382
|
-
if (!session)
|
|
383
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
384
|
-
if (!input.hypothesis)
|
|
385
|
-
return this.errorResponse(session.sessionId, 'Hypothesis content is required');
|
|
386
|
-
session.currentStep++;
|
|
387
|
-
const thoughtId = uuidv4();
|
|
388
|
-
const hypothesisThought = {
|
|
389
|
-
id: thoughtId,
|
|
390
|
-
stepNumber: session.currentStep,
|
|
391
|
-
thought: input.thought || `Hypothesis: ${input.hypothesis}`,
|
|
392
|
-
thoughtType: 'hypothesis',
|
|
393
|
-
timestamp: new Date().toISOString(),
|
|
394
|
-
hypothesis: input.hypothesis,
|
|
395
|
-
verificationStatus: 'pending',
|
|
396
|
-
confidence: input.confidence ?? 50
|
|
397
|
-
};
|
|
398
|
-
session.thoughtHistory.push(hypothesisThought);
|
|
399
|
-
session.status = 'awaiting_verification';
|
|
400
|
-
session.updatedAt = new Date().toISOString();
|
|
401
|
-
return {
|
|
402
|
-
success: true,
|
|
403
|
-
sessionId: session.sessionId,
|
|
404
|
-
currentStep: session.currentStep,
|
|
405
|
-
totalThoughts: session.totalThoughts,
|
|
406
|
-
status: session.status,
|
|
407
|
-
thought: hypothesisThought,
|
|
408
|
-
message: `Hypothesis set: "${input.hypothesis}". Gather evidence before proceeding.`,
|
|
409
|
-
nextSuggestedActions: ['verify_hypothesis', 'create_branch', 'add_thought']
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Verify a hypothesis with evidence
|
|
414
|
-
*/
|
|
415
|
-
verifyHypothesis(input) {
|
|
416
|
-
const session = this.getSession(input.sessionId);
|
|
417
|
-
if (!session)
|
|
418
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
419
|
-
let hypothesisThought;
|
|
420
|
-
if (input.hypothesis) {
|
|
421
|
-
// Find the specific hypothesis mentioned (ignoring status)
|
|
422
|
-
hypothesisThought = [...session.thoughtHistory]
|
|
423
|
-
.reverse()
|
|
424
|
-
.find((t) => t.thoughtType === 'hypothesis' &&
|
|
425
|
-
(t.hypothesis?.includes(input.hypothesis) || input.hypothesis?.includes(t.hypothesis)));
|
|
426
|
-
}
|
|
427
|
-
// Fallback to latest pending hypothesis if no specific match found
|
|
428
|
-
if (!hypothesisThought) {
|
|
429
|
-
hypothesisThought = [...session.thoughtHistory]
|
|
430
|
-
.reverse()
|
|
431
|
-
.find((t) => t.thoughtType === 'hypothesis' && t.verificationStatus === 'pending');
|
|
432
|
-
}
|
|
433
|
-
if (!hypothesisThought)
|
|
434
|
-
return this.errorResponse(session.sessionId, 'No pending hypothesis found');
|
|
435
|
-
if (!input.verificationStatus)
|
|
436
|
-
return this.errorResponse(session.sessionId, 'verificationStatus is required');
|
|
437
|
-
session.currentStep++;
|
|
438
|
-
const thoughtId = uuidv4();
|
|
439
|
-
const verificationThought = {
|
|
440
|
-
id: thoughtId,
|
|
441
|
-
stepNumber: session.currentStep,
|
|
442
|
-
thought: input.thought || `Verification of hypothesis: "${hypothesisThought.hypothesis}"`,
|
|
443
|
-
thoughtType: 'verification',
|
|
444
|
-
timestamp: new Date().toISOString(),
|
|
445
|
-
hypothesis: hypothesisThought.hypothesis,
|
|
446
|
-
verificationStatus: input.verificationStatus,
|
|
447
|
-
verificationEvidence: input.verificationEvidence,
|
|
448
|
-
confidence: this.getVerificationConfidence(input.verificationStatus, input.confidence),
|
|
449
|
-
parentId: hypothesisThought.id
|
|
450
|
-
};
|
|
451
|
-
hypothesisThought.verificationStatus = input.verificationStatus;
|
|
452
|
-
hypothesisThought.verificationEvidence = input.verificationEvidence;
|
|
453
|
-
session.thoughtHistory.push(verificationThought);
|
|
454
|
-
session.status =
|
|
455
|
-
input.verificationStatus === 'needs_more_evidence' ? 'awaiting_verification' : 'in_progress';
|
|
456
|
-
session.updatedAt = new Date().toISOString();
|
|
457
|
-
const statusEmoji = this.getVerificationEmoji(input.verificationStatus);
|
|
458
|
-
return {
|
|
459
|
-
success: true,
|
|
460
|
-
sessionId: session.sessionId,
|
|
461
|
-
currentStep: session.currentStep,
|
|
462
|
-
totalThoughts: session.totalThoughts,
|
|
463
|
-
status: session.status,
|
|
464
|
-
thought: verificationThought,
|
|
465
|
-
message: `${statusEmoji} Hypothesis "${hypothesisThought.hypothesis?.substring(0, 40)}..." → ${input.verificationStatus.toUpperCase()}.`,
|
|
466
|
-
nextSuggestedActions: this.getPostVerificationActions(input.verificationStatus)
|
|
467
|
-
};
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* Dynamically adjust the total number of thinking steps
|
|
471
|
-
*/
|
|
472
|
-
adjustTotalThoughts(input) {
|
|
473
|
-
const session = this.getSession(input.sessionId);
|
|
474
|
-
if (!session)
|
|
475
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
476
|
-
if (input.totalThoughts === undefined)
|
|
477
|
-
return this.errorResponse(session.sessionId, 'totalThoughts is required');
|
|
478
|
-
const oldTotal = session.totalThoughts;
|
|
479
|
-
const newTotal = Math.max(session.currentStep, input.totalThoughts);
|
|
480
|
-
session.totalThoughts = newTotal;
|
|
481
|
-
session.updatedAt = new Date().toISOString();
|
|
482
|
-
const remaining = newTotal - session.currentStep;
|
|
483
|
-
return {
|
|
484
|
-
success: true,
|
|
485
|
-
sessionId: session.sessionId,
|
|
486
|
-
currentStep: session.currentStep,
|
|
487
|
-
totalThoughts: session.totalThoughts,
|
|
488
|
-
status: session.status,
|
|
489
|
-
message: `Total thoughts adjusted: ${oldTotal} → ${newTotal}. ${remaining} remaining.`,
|
|
490
|
-
nextSuggestedActions: ['add_thought']
|
|
206
|
+
message: `Thought added (${thought.thoughtType})`
|
|
491
207
|
};
|
|
492
208
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
*/
|
|
496
|
-
conclude(input) {
|
|
209
|
+
// --- Tree of Thoughts (ToT) ---
|
|
210
|
+
generateOptions(input) {
|
|
497
211
|
const session = this.getSession(input.sessionId);
|
|
498
212
|
if (!session)
|
|
499
|
-
return
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
//
|
|
503
|
-
if (pendingHypotheses.length > 0 && !input.force) {
|
|
504
|
-
console.warn(`[Brain] Concluding with ${pendingHypotheses.length} pending hypotheses. Auto-resolving as 'skipped'.`);
|
|
505
|
-
pendingHypotheses.forEach((h) => {
|
|
506
|
-
h.verificationStatus = 'needs_more_evidence'; // Soft resolve
|
|
507
|
-
// Add a system note about skipping verification
|
|
508
|
-
session.thoughtHistory.push({
|
|
509
|
-
id: uuidv4(),
|
|
510
|
-
stepNumber: session.currentStep + 1,
|
|
511
|
-
thought: `[System] Auto-skipping verification for hypothesis: "${h.hypothesis}" due to session conclusion.`,
|
|
512
|
-
thoughtType: 'verification',
|
|
513
|
-
timestamp: new Date().toISOString(),
|
|
514
|
-
hypothesis: h.hypothesis,
|
|
515
|
-
verificationStatus: 'needs_more_evidence',
|
|
516
|
-
verificationEvidence: 'Session concluded without explicit verification.',
|
|
517
|
-
confidence: 50,
|
|
518
|
-
parentId: h.id
|
|
519
|
-
});
|
|
520
|
-
session.currentStep++;
|
|
521
|
-
});
|
|
522
|
-
warningMessage = ` (Note: ${pendingHypotheses.length} pending hypothesis(es) were marked as unverified)`;
|
|
523
|
-
}
|
|
524
|
-
const conclusionText = input.thought ||
|
|
525
|
-
session.thoughtHistory[session.thoughtHistory.length - 1]?.thought ||
|
|
526
|
-
'Thinking session completed successfully.';
|
|
527
|
-
session.currentStep++;
|
|
528
|
-
const thoughtId = uuidv4();
|
|
529
|
-
const conclusionThought = {
|
|
530
|
-
id: thoughtId,
|
|
531
|
-
stepNumber: session.currentStep,
|
|
532
|
-
thought: conclusionText,
|
|
533
|
-
thoughtType: 'conclusion',
|
|
534
|
-
timestamp: new Date().toISOString(),
|
|
535
|
-
confidence: input.confidence ?? 90
|
|
536
|
-
};
|
|
537
|
-
session.thoughtHistory.push(conclusionThought);
|
|
538
|
-
session.finalConclusion = conclusionText;
|
|
539
|
-
session.status = 'completed';
|
|
540
|
-
session.updatedAt = new Date().toISOString();
|
|
213
|
+
return { success: false, message: 'Session not found' };
|
|
214
|
+
// This simulates the Brain generating multiple potential next steps
|
|
215
|
+
// In a real loop, the LLM would call this 3 times or pass an array.
|
|
216
|
+
// Here we just prepare the state for the LLM to provide the options.
|
|
541
217
|
return {
|
|
542
218
|
success: true,
|
|
543
219
|
sessionId: session.sessionId,
|
|
544
220
|
currentStep: session.currentStep,
|
|
545
221
|
totalThoughts: session.totalThoughts,
|
|
546
222
|
status: session.status,
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
message: `🎯 Thinking session COMPLETED.${warningMessage} You can now execute the conclusion if it contains a plan.`,
|
|
550
|
-
nextSuggestedActions: ['execute_conclusion', 'get_history']
|
|
223
|
+
message: 'ToT Mode: Please provide 3 distinct options for the next step using `add_thought` with `thoughtType="option_generation"` and `branchLabel="Option A/B/C"`.',
|
|
224
|
+
nextSuggestedActions: ['add_thought', 'add_thought', 'add_thought']
|
|
551
225
|
};
|
|
552
226
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
*/
|
|
556
|
-
deleteThought(input) {
|
|
557
|
-
const session = this.getSession(input.sessionId);
|
|
558
|
-
if (!session)
|
|
559
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
560
|
-
if (!input.deleteThoughtId)
|
|
561
|
-
return this.errorResponse(session.sessionId, 'deleteThoughtId is required');
|
|
562
|
-
const initialLength = session.thoughtHistory.length;
|
|
563
|
-
session.thoughtHistory = session.thoughtHistory.filter((t) => t.id !== input.deleteThoughtId);
|
|
564
|
-
if (session.thoughtHistory.length === initialLength) {
|
|
565
|
-
return this.errorResponse(session.sessionId, 'Thought not found');
|
|
566
|
-
}
|
|
567
|
-
// Re-adjust currentStep and stepNumbers for consistency
|
|
568
|
-
session.currentStep = session.thoughtHistory.length;
|
|
569
|
-
session.thoughtHistory.forEach((t, index) => {
|
|
570
|
-
t.stepNumber = index + 1;
|
|
571
|
-
});
|
|
572
|
-
session.updatedAt = new Date().toISOString();
|
|
573
|
-
return {
|
|
574
|
-
success: true,
|
|
575
|
-
sessionId: session.sessionId,
|
|
576
|
-
currentStep: session.currentStep,
|
|
577
|
-
totalThoughts: session.totalThoughts,
|
|
578
|
-
status: session.status,
|
|
579
|
-
message: `Successfully deleted thought: ${input.deleteThoughtId}. History re-indexed.`,
|
|
580
|
-
nextSuggestedActions: ['add_thought', 'conclude']
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
/**
|
|
584
|
-
* Get current session status
|
|
585
|
-
*/
|
|
586
|
-
getStatus(input) {
|
|
587
|
-
const session = this.getSession(input.sessionId);
|
|
588
|
-
if (!session)
|
|
589
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
590
|
-
const stats = this.generateSessionStats(session);
|
|
227
|
+
evaluateOptions(input) {
|
|
228
|
+
// The LLM should look at recent "option_generation" thoughts and assign scores
|
|
591
229
|
return {
|
|
592
230
|
success: true,
|
|
593
|
-
sessionId:
|
|
594
|
-
currentStep: session.currentStep,
|
|
595
|
-
totalThoughts: session.totalThoughts,
|
|
596
|
-
status: session.status,
|
|
597
|
-
branches: session.branches,
|
|
598
|
-
message: `Session Status:\n${stats}`,
|
|
599
|
-
nextSuggestedActions: this.getStatusBasedActions(session)
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Get complete thought history
|
|
604
|
-
*/
|
|
605
|
-
getHistory(input) {
|
|
606
|
-
const session = this.getSession(input.sessionId);
|
|
607
|
-
if (!session)
|
|
608
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
609
|
-
return {
|
|
610
|
-
success: true,
|
|
611
|
-
sessionId: session.sessionId,
|
|
612
|
-
currentStep: session.currentStep,
|
|
613
|
-
totalThoughts: session.totalThoughts,
|
|
614
|
-
status: session.status,
|
|
615
|
-
thoughtHistory: session.thoughtHistory,
|
|
616
|
-
branches: session.branches,
|
|
617
|
-
message: `Complete thought history retrieved. ${session.thoughtHistory.length} thoughts recorded.`,
|
|
618
|
-
conclusion: session.finalConclusion
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
/**
|
|
622
|
-
* Clear all thinking sessions
|
|
623
|
-
*/
|
|
624
|
-
clearHistory() {
|
|
625
|
-
const count = this.sessions.size;
|
|
626
|
-
this.sessions.clear();
|
|
627
|
-
return {
|
|
628
|
-
success: true,
|
|
629
|
-
sessionId: '',
|
|
630
|
-
currentStep: 0,
|
|
631
|
-
totalThoughts: 0,
|
|
632
|
-
status: 'completed',
|
|
633
|
-
message: `Successfully cleared all thinking history (${count} sessions).`
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
/**
|
|
637
|
-
* Delete a specific thinking session
|
|
638
|
-
*/
|
|
639
|
-
deleteSession(input) {
|
|
640
|
-
if (!input.sessionId)
|
|
641
|
-
return this.errorResponse('', 'sessionId is required to delete a session');
|
|
642
|
-
const exists = this.sessions.has(input.sessionId);
|
|
643
|
-
if (!exists)
|
|
644
|
-
return this.errorResponse(input.sessionId, 'Session not found');
|
|
645
|
-
this.sessions.delete(input.sessionId);
|
|
646
|
-
return {
|
|
647
|
-
success: true,
|
|
648
|
-
sessionId: input.sessionId,
|
|
231
|
+
sessionId: input.sessionId || '',
|
|
649
232
|
currentStep: 0,
|
|
650
233
|
totalThoughts: 0,
|
|
651
|
-
status: '
|
|
652
|
-
message: `
|
|
234
|
+
status: 'in_progress',
|
|
235
|
+
message: 'Please review the generated options and use `revise_thought` on each to add a `score` (0-1.0) and `evaluation` text.',
|
|
236
|
+
nextSuggestedActions: ['revise_thought']
|
|
653
237
|
};
|
|
654
238
|
}
|
|
655
|
-
|
|
656
|
-
* Perform a self-critique of the current reasoning
|
|
657
|
-
*/
|
|
658
|
-
selfCritique(input) {
|
|
239
|
+
selectOption(input) {
|
|
659
240
|
const session = this.getSession(input.sessionId);
|
|
660
241
|
if (!session)
|
|
661
|
-
return
|
|
662
|
-
if (!input.
|
|
663
|
-
return
|
|
242
|
+
return { success: false, message: 'Session not found' };
|
|
243
|
+
if (!input.optionId)
|
|
244
|
+
return { success: false, message: 'optionId required' };
|
|
245
|
+
const selected = session.thoughtHistory.find(t => t.id === input.optionId);
|
|
246
|
+
if (!selected)
|
|
247
|
+
return { success: false, message: 'Option not found' };
|
|
664
248
|
session.currentStep++;
|
|
665
|
-
const thoughtId = uuidv4();
|
|
666
249
|
const thought = {
|
|
667
|
-
id:
|
|
250
|
+
id: uuidv4(),
|
|
668
251
|
stepNumber: session.currentStep,
|
|
669
|
-
thought:
|
|
670
|
-
thoughtType: '
|
|
252
|
+
thought: `Selected Option: ${selected.branchLabel || 'Unknown'} - ${selected.thought}`,
|
|
253
|
+
thoughtType: 'synthesis',
|
|
671
254
|
timestamp: new Date().toISOString(),
|
|
672
|
-
|
|
255
|
+
parentId: selected.id,
|
|
256
|
+
confidence: 90
|
|
673
257
|
};
|
|
674
258
|
session.thoughtHistory.push(thought);
|
|
675
|
-
session.updatedAt = new Date().toISOString();
|
|
676
259
|
return {
|
|
677
260
|
success: true,
|
|
678
261
|
sessionId: session.sessionId,
|
|
@@ -680,78 +263,30 @@ export class SequentialThinkingManager {
|
|
|
680
263
|
totalThoughts: session.totalThoughts,
|
|
681
264
|
status: session.status,
|
|
682
265
|
thought,
|
|
683
|
-
message: `
|
|
684
|
-
nextSuggestedActions: ['add_thought', 'revise_thought', 'create_branch']
|
|
266
|
+
message: `Selected option ${selected.branchLabel}. Moving forward.`
|
|
685
267
|
};
|
|
686
268
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
*/
|
|
690
|
-
summarizeHistory(input) {
|
|
269
|
+
// --- Reflexion ---
|
|
270
|
+
reflect(input) {
|
|
691
271
|
const session = this.getSession(input.sessionId);
|
|
692
272
|
if (!session)
|
|
693
|
-
return this.errorResponse(
|
|
694
|
-
|
|
695
|
-
return this.errorResponse(session.sessionId, 'Summary content is required in "thought" field');
|
|
273
|
+
return this.errorResponse('', 'Session not found');
|
|
274
|
+
console.log('[Brain] Reflexion triggered for session:', session.sessionId);
|
|
696
275
|
session.currentStep++;
|
|
697
|
-
const thoughtId = uuidv4();
|
|
698
276
|
const thought = {
|
|
699
|
-
id:
|
|
277
|
+
id: uuidv4(),
|
|
700
278
|
stepNumber: session.currentStep,
|
|
701
|
-
thought:
|
|
702
|
-
thoughtType: '
|
|
279
|
+
thought: `REFLEXION: ${input.thought}`,
|
|
280
|
+
thoughtType: 'reflection',
|
|
703
281
|
timestamp: new Date().toISOString(),
|
|
704
|
-
confidence:
|
|
282
|
+
confidence: 80,
|
|
283
|
+
metadata: { executionResult: input.executionResult }
|
|
705
284
|
};
|
|
706
285
|
session.thoughtHistory.push(thought);
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
sessionId: session.sessionId,
|
|
711
|
-
currentStep: session.currentStep,
|
|
712
|
-
totalThoughts: session.totalThoughts,
|
|
713
|
-
status: session.status,
|
|
714
|
-
thought,
|
|
715
|
-
message: `Context summarized. Thinking continues with focused scope.`,
|
|
716
|
-
nextSuggestedActions: ['add_thought', 'conclude']
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Merge multiple branches or thoughts into a new consolidated thought
|
|
721
|
-
*/
|
|
722
|
-
mergeBranches(input) {
|
|
723
|
-
const session = this.getSession(input.sessionId);
|
|
724
|
-
if (!session)
|
|
725
|
-
return this.errorResponse(input.sessionId || '', 'Session not found');
|
|
726
|
-
if (!input.thought)
|
|
727
|
-
return this.errorResponse(session.sessionId, 'Consolidated thought content is required');
|
|
728
|
-
const sourceIds = input.sourceThoughtIds || [];
|
|
729
|
-
const branchIds = input.branchIds || [];
|
|
730
|
-
session.currentStep++;
|
|
731
|
-
const thoughtId = uuidv4();
|
|
732
|
-
const thought = {
|
|
733
|
-
id: thoughtId,
|
|
734
|
-
stepNumber: session.currentStep,
|
|
735
|
-
thought: `🔗 MERGED CONCLUSION:\n${input.thought}`,
|
|
736
|
-
thoughtType: 'synthesis',
|
|
737
|
-
timestamp: new Date().toISOString(),
|
|
738
|
-
confidence: input.confidence ?? 85,
|
|
739
|
-
metadata: {
|
|
740
|
-
mergedFromThoughts: sourceIds,
|
|
741
|
-
mergedFromBranches: branchIds
|
|
742
|
-
}
|
|
743
|
-
};
|
|
744
|
-
// Mark branches as merged if branchIds provided
|
|
745
|
-
if (branchIds.length > 0) {
|
|
746
|
-
session.branches.forEach((b) => {
|
|
747
|
-
if (branchIds.includes(b.id)) {
|
|
748
|
-
b.status = 'merged';
|
|
749
|
-
b.mergedIntoId = thoughtId;
|
|
750
|
-
}
|
|
751
|
-
});
|
|
286
|
+
// Save to Semantic Memory if valuable
|
|
287
|
+
if (input.thought && input.thought.length > 50) {
|
|
288
|
+
vectorMemory.add(`Reflexion on ${session.problemStatement}: ${input.thought}`, { sessionId: session.sessionId });
|
|
752
289
|
}
|
|
753
|
-
session.thoughtHistory.push(thought);
|
|
754
|
-
session.updatedAt = new Date().toISOString();
|
|
755
290
|
return {
|
|
756
291
|
success: true,
|
|
757
292
|
sessionId: session.sessionId,
|
|
@@ -759,222 +294,99 @@ export class SequentialThinkingManager {
|
|
|
759
294
|
totalThoughts: session.totalThoughts,
|
|
760
295
|
status: session.status,
|
|
761
296
|
thought,
|
|
762
|
-
message:
|
|
763
|
-
nextSuggestedActions: ['add_thought', 'conclude']
|
|
297
|
+
message: 'Reflexion recorded and saved to Semantic Memory.'
|
|
764
298
|
};
|
|
765
299
|
}
|
|
766
|
-
|
|
767
|
-
* Bridge: Execute the plan derived from the thinking session's conclusion
|
|
768
|
-
*/
|
|
300
|
+
// --- Bridge ---
|
|
769
301
|
async executeConclusion(input) {
|
|
770
302
|
const session = this.getSession(input.sessionId);
|
|
771
303
|
if (!session)
|
|
772
|
-
return this.errorResponse(
|
|
773
|
-
const conclusion = session.finalConclusion ||
|
|
774
|
-
session.thoughtHistory.find((t) => t.thoughtType === 'conclusion')?.thought;
|
|
304
|
+
return this.errorResponse('', 'Session not found');
|
|
305
|
+
const conclusion = session.finalConclusion || session.thoughtHistory.slice(-1)[0]?.thought;
|
|
775
306
|
if (!conclusion)
|
|
776
|
-
return this.errorResponse(session.sessionId, 'No conclusion
|
|
777
|
-
|
|
778
|
-
// Try to find a JSON plan in the conclusion
|
|
307
|
+
return this.errorResponse(session.sessionId, 'No conclusion');
|
|
308
|
+
// Extract Plan
|
|
779
309
|
let plan = null;
|
|
780
310
|
try {
|
|
781
|
-
// Look for JSON block in markdown or just plain JSON
|
|
782
311
|
const jsonMatch = conclusion.match(/```json\n([\s\S]*?)\n```/) || conclusion.match(/(\{[\s\S]*\})/);
|
|
783
|
-
if (jsonMatch)
|
|
312
|
+
if (jsonMatch)
|
|
784
313
|
plan = JSON.parse(jsonMatch[1]);
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
catch (e) {
|
|
788
|
-
console.error('[Brain-Body Bridge] Failed to parse plan from conclusion:', e);
|
|
789
314
|
}
|
|
315
|
+
catch (e) { }
|
|
790
316
|
if (!plan) {
|
|
791
|
-
|
|
792
|
-
plan =
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
317
|
+
// Auto-gen logic (simplified)
|
|
318
|
+
plan = {
|
|
319
|
+
planId: 'auto-' + uuidv4(),
|
|
320
|
+
name: 'Auto Plan',
|
|
321
|
+
tasks: [{ id: 't1', name: 'Auto Echo', toolName: 'echo', toolInput: { text: 'Running...' }, dependencies: [] }]
|
|
322
|
+
};
|
|
796
323
|
}
|
|
797
|
-
// Execute
|
|
798
|
-
const
|
|
799
|
-
|
|
800
|
-
|
|
324
|
+
// Execute
|
|
325
|
+
const execResult = await orchestratorManager.process({ action: 'execute_plan', plan });
|
|
326
|
+
// Auto-Reflexion
|
|
327
|
+
await this.process({
|
|
328
|
+
action: 'reflect',
|
|
329
|
+
sessionId: session.sessionId,
|
|
330
|
+
thought: execResult.success
|
|
331
|
+
? `Execution Successful. Result: ${JSON.stringify(execResult.result?.aggregatedResults || 'OK')}`
|
|
332
|
+
: `Execution Failed. Errors: ${JSON.stringify(execResult.result?.errors || 'Unknown')}`,
|
|
333
|
+
executionResult: execResult
|
|
801
334
|
});
|
|
802
335
|
return {
|
|
803
|
-
success:
|
|
336
|
+
success: execResult.success,
|
|
804
337
|
sessionId: session.sessionId,
|
|
805
338
|
currentStep: session.currentStep,
|
|
806
339
|
totalThoughts: session.totalThoughts,
|
|
807
340
|
status: session.status,
|
|
808
|
-
message: `
|
|
809
|
-
executionResult:
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* Heuristic-based plan generator to fulfill the "Auto-Plan" requirement
|
|
814
|
-
*/
|
|
815
|
-
autoGeneratePlan(conclusion, session) {
|
|
816
|
-
const text = conclusion.toLowerCase();
|
|
817
|
-
const tasks = [];
|
|
818
|
-
// Heuristic 1: List/Explore
|
|
819
|
-
if (text.includes('list') ||
|
|
820
|
-
text.includes('folder') ||
|
|
821
|
-
text.includes('directory') ||
|
|
822
|
-
text.includes('สำรวจ')) {
|
|
823
|
-
tasks.push({
|
|
824
|
-
id: 'auto_list',
|
|
825
|
-
name: 'Auto-Explore Directory',
|
|
826
|
-
toolName: 'list_directory',
|
|
827
|
-
toolInput: { path: '.' },
|
|
828
|
-
dependencies: []
|
|
829
|
-
});
|
|
830
|
-
}
|
|
831
|
-
// Heuristic 2: Search
|
|
832
|
-
if (text.includes('search') || text.includes('find') || text.includes('ค้นหา')) {
|
|
833
|
-
tasks.push({
|
|
834
|
-
id: 'auto_search',
|
|
835
|
-
name: 'Auto-Web Search',
|
|
836
|
-
toolName: 'web_search',
|
|
837
|
-
toolInput: { query: session.problemStatement },
|
|
838
|
-
dependencies: []
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
// Heuristic 3: Read
|
|
842
|
-
if (text.includes('read') || text.includes('อ่าน') || text.includes('view')) {
|
|
843
|
-
tasks.push({
|
|
844
|
-
id: 'auto_read',
|
|
845
|
-
name: 'Auto-Read Files',
|
|
846
|
-
toolName: 'shell_execute',
|
|
847
|
-
toolInput: { command: 'ls -R | head -n 20' },
|
|
848
|
-
dependencies: []
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
if (tasks.length === 0)
|
|
852
|
-
return null;
|
|
853
|
-
return {
|
|
854
|
-
planId: `auto-${uuidv4().substring(0, 8)}`,
|
|
855
|
-
name: 'Auto-Generated Plan',
|
|
856
|
-
description: 'Automatically generated by The Brain based on conclusion keywords.',
|
|
857
|
-
tasks
|
|
341
|
+
message: `Execution ${execResult.success ? 'Success' : 'Failed'}. Reflexion triggered.`,
|
|
342
|
+
executionResult: execResult.result
|
|
858
343
|
};
|
|
859
344
|
}
|
|
860
|
-
//
|
|
861
|
-
// Helper Methods
|
|
862
|
-
// ============================================
|
|
863
|
-
getSession(sessionId) {
|
|
864
|
-
if (!sessionId)
|
|
865
|
-
return undefined;
|
|
866
|
-
if (sessionId === 'latest' && this.lastSessionId) {
|
|
867
|
-
return this.sessions.get(this.lastSessionId);
|
|
868
|
-
}
|
|
869
|
-
return this.sessions.get(sessionId);
|
|
870
|
-
}
|
|
345
|
+
// --- Helpers ---
|
|
871
346
|
errorResponse(sessionId, message) {
|
|
872
|
-
const session = this.sessions.get(sessionId);
|
|
873
347
|
return {
|
|
874
348
|
success: false,
|
|
875
349
|
sessionId,
|
|
876
|
-
currentStep:
|
|
877
|
-
totalThoughts:
|
|
878
|
-
status:
|
|
350
|
+
currentStep: 0,
|
|
351
|
+
totalThoughts: 0,
|
|
352
|
+
status: 'in_progress',
|
|
879
353
|
message: `Error: ${message}`
|
|
880
354
|
};
|
|
881
355
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
return `${progress} ${typeLabel}\nConfidence: ${confidenceBar} ${thought.confidence}%\n\n${thought.thought}`;
|
|
887
|
-
}
|
|
888
|
-
getConfidenceBar(confidence) {
|
|
889
|
-
const filled = Math.round(confidence / 10);
|
|
890
|
-
return '█'.repeat(filled) + '░'.repeat(10 - filled);
|
|
891
|
-
}
|
|
892
|
-
getSuggestedActions(session, thought) {
|
|
893
|
-
const actions = [];
|
|
894
|
-
const remaining = session.totalThoughts - session.currentStep;
|
|
895
|
-
if (remaining > 0)
|
|
896
|
-
actions.push('add_thought');
|
|
897
|
-
if (thought.thoughtType === 'initial_analysis') {
|
|
898
|
-
actions.push('set_hypothesis');
|
|
899
|
-
actions.push('create_branch');
|
|
900
|
-
}
|
|
901
|
-
// Always allow concluding if we have at least some thoughts
|
|
902
|
-
if (session.currentStep >= 1) {
|
|
903
|
-
actions.push('conclude');
|
|
904
|
-
}
|
|
905
|
-
if (remaining <= 0) {
|
|
906
|
-
actions.push('adjust_total_thoughts');
|
|
907
|
-
}
|
|
908
|
-
return actions;
|
|
909
|
-
}
|
|
910
|
-
getVerificationConfidence(status, providedConfidence) {
|
|
911
|
-
if (providedConfidence !== undefined)
|
|
912
|
-
return providedConfidence;
|
|
913
|
-
switch (status) {
|
|
914
|
-
case 'verified':
|
|
915
|
-
return 90;
|
|
916
|
-
case 'partially_verified':
|
|
917
|
-
return 70;
|
|
918
|
-
case 'refuted':
|
|
919
|
-
return 20;
|
|
920
|
-
case 'needs_more_evidence':
|
|
921
|
-
return 40;
|
|
922
|
-
default:
|
|
923
|
-
return 50;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
getVerificationEmoji(status) {
|
|
927
|
-
switch (status) {
|
|
928
|
-
case 'verified':
|
|
929
|
-
return '✅';
|
|
930
|
-
case 'partially_verified':
|
|
931
|
-
return '🟡';
|
|
932
|
-
case 'refuted':
|
|
933
|
-
return '❌';
|
|
934
|
-
case 'needs_more_evidence':
|
|
935
|
-
return '🔍';
|
|
936
|
-
default:
|
|
937
|
-
return '❓';
|
|
938
|
-
}
|
|
356
|
+
getSession(id) {
|
|
357
|
+
if (!id || id === 'latest')
|
|
358
|
+
return this.sessions.get(this.lastSessionId || '');
|
|
359
|
+
return this.sessions.get(id);
|
|
939
360
|
}
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
case 'verified':
|
|
943
|
-
return ['add_thought', 'conclude'];
|
|
944
|
-
case 'refuted':
|
|
945
|
-
return ['revise_thought', 'set_hypothesis', 'create_branch'];
|
|
946
|
-
case 'partially_verified':
|
|
947
|
-
return ['add_thought', 'set_hypothesis'];
|
|
948
|
-
case 'needs_more_evidence':
|
|
949
|
-
return ['add_thought', 'verify_hypothesis'];
|
|
950
|
-
default:
|
|
951
|
-
return ['add_thought'];
|
|
952
|
-
}
|
|
361
|
+
getLastThoughtId(session) {
|
|
362
|
+
return session.thoughtHistory.length > 0 ? session.thoughtHistory[session.thoughtHistory.length - 1].id : undefined;
|
|
953
363
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
364
|
+
// Legacy stubs to satisfy strict TS if interface demands
|
|
365
|
+
createBranch(input) { return this.addThought(input); }
|
|
366
|
+
reviseThought(input) { return this.addThought({ ...input, thoughtType: 'revision' }); }
|
|
367
|
+
setHypothesis(input) { return this.addThought({ ...input, thoughtType: 'hypothesis' }); }
|
|
368
|
+
verifyHypothesis(input) { return this.addThought({ ...input, thoughtType: 'verification' }); }
|
|
369
|
+
conclude(input) {
|
|
370
|
+
const session = this.getSession(input.sessionId);
|
|
371
|
+
if (session) {
|
|
372
|
+
session.finalConclusion = input.thought;
|
|
373
|
+
session.status = 'completed';
|
|
964
374
|
}
|
|
375
|
+
return this.addThought({ ...input, thoughtType: 'conclusion' });
|
|
965
376
|
}
|
|
966
|
-
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
377
|
+
getHistory(input) {
|
|
378
|
+
const session = this.getSession(input.sessionId);
|
|
379
|
+
if (!session)
|
|
380
|
+
return this.errorResponse('', 'Session not found');
|
|
381
|
+
return {
|
|
382
|
+
success: true,
|
|
383
|
+
sessionId: session.sessionId,
|
|
384
|
+
currentStep: session.currentStep,
|
|
385
|
+
totalThoughts: session.totalThoughts,
|
|
386
|
+
status: session.status,
|
|
387
|
+
message: 'History retrieved',
|
|
388
|
+
thoughtHistory: session.thoughtHistory
|
|
389
|
+
};
|
|
978
390
|
}
|
|
979
391
|
}
|
|
980
392
|
export const thinkingManager = new SequentialThinkingManager();
|