musubi-sdd 3.10.0 → 5.1.0
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 +24 -19
- package/package.json +1 -1
- package/src/agents/agent-loop.js +532 -0
- package/src/agents/agentic/code-generator.js +767 -0
- package/src/agents/agentic/code-reviewer.js +698 -0
- package/src/agents/agentic/index.js +43 -0
- package/src/agents/function-tool.js +432 -0
- package/src/agents/index.js +45 -0
- package/src/agents/schema-generator.js +514 -0
- package/src/analyzers/ast-extractor.js +870 -0
- package/src/analyzers/context-optimizer.js +681 -0
- package/src/analyzers/repository-map.js +692 -0
- package/src/integrations/index.js +7 -1
- package/src/integrations/mcp/index.js +175 -0
- package/src/integrations/mcp/mcp-context-provider.js +472 -0
- package/src/integrations/mcp/mcp-discovery.js +436 -0
- package/src/integrations/mcp/mcp-tool-registry.js +467 -0
- package/src/integrations/mcp-connector.js +818 -0
- package/src/integrations/tool-discovery.js +589 -0
- package/src/managers/index.js +7 -0
- package/src/managers/skill-tools.js +565 -0
- package/src/monitoring/cost-tracker.js +7 -0
- package/src/monitoring/incident-manager.js +10 -0
- package/src/monitoring/observability.js +10 -0
- package/src/monitoring/quality-dashboard.js +491 -0
- package/src/monitoring/release-manager.js +10 -0
- package/src/orchestration/agent-skill-binding.js +655 -0
- package/src/orchestration/error-handler.js +827 -0
- package/src/orchestration/index.js +235 -1
- package/src/orchestration/mcp-tool-adapters.js +896 -0
- package/src/orchestration/reasoning/index.js +58 -0
- package/src/orchestration/reasoning/planning-engine.js +831 -0
- package/src/orchestration/reasoning/reasoning-engine.js +710 -0
- package/src/orchestration/reasoning/self-correction.js +751 -0
- package/src/orchestration/skill-executor.js +665 -0
- package/src/orchestration/skill-registry.js +650 -0
- package/src/orchestration/workflow-examples.js +1072 -0
- package/src/orchestration/workflow-executor.js +779 -0
- package/src/phase4-integration.js +248 -0
- package/src/phase5-integration.js +402 -0
- package/src/steering/steering-auto-update.js +572 -0
- package/src/steering/steering-validator.js +547 -0
- package/src/templates/template-constraints.js +646 -0
- package/src/validators/advanced-validation.js +580 -0
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file reasoning-engine.js
|
|
3
|
+
* @description Agentic reasoning engine for autonomous problem solving
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { EventEmitter } = require('events');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Reasoning strategy types
|
|
13
|
+
* @enum {string}
|
|
14
|
+
*/
|
|
15
|
+
const STRATEGY = {
|
|
16
|
+
CHAIN_OF_THOUGHT: 'chain-of-thought',
|
|
17
|
+
TREE_OF_THOUGHT: 'tree-of-thought',
|
|
18
|
+
REFLECTION: 'reflection',
|
|
19
|
+
DECOMPOSITION: 'decomposition',
|
|
20
|
+
ANALOGY: 'analogy'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Reasoning step types
|
|
25
|
+
* @enum {string}
|
|
26
|
+
*/
|
|
27
|
+
const STEP_TYPE = {
|
|
28
|
+
OBSERVE: 'observe',
|
|
29
|
+
THINK: 'think',
|
|
30
|
+
PLAN: 'plan',
|
|
31
|
+
ACT: 'act',
|
|
32
|
+
REFLECT: 'reflect',
|
|
33
|
+
REFINE: 'refine'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {Object} ReasoningStep
|
|
38
|
+
* @property {string} id - Step identifier
|
|
39
|
+
* @property {string} type - Step type (STEP_TYPE)
|
|
40
|
+
* @property {string} content - Step content/reasoning
|
|
41
|
+
* @property {Object} [metadata] - Additional metadata
|
|
42
|
+
* @property {number} confidence - Confidence score (0-1)
|
|
43
|
+
* @property {number} timestamp - Creation timestamp
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @typedef {Object} ReasoningTrace
|
|
48
|
+
* @property {string} id - Trace identifier
|
|
49
|
+
* @property {string} problem - Original problem statement
|
|
50
|
+
* @property {string} strategy - Reasoning strategy used
|
|
51
|
+
* @property {ReasoningStep[]} steps - Reasoning steps
|
|
52
|
+
* @property {string} [conclusion] - Final conclusion
|
|
53
|
+
* @property {boolean} successful - Whether reasoning succeeded
|
|
54
|
+
* @property {number} totalTime - Total reasoning time
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef {Object} ReasoningOptions
|
|
59
|
+
* @property {string} [strategy=STRATEGY.CHAIN_OF_THOUGHT] - Reasoning strategy
|
|
60
|
+
* @property {number} [maxSteps=20] - Maximum reasoning steps
|
|
61
|
+
* @property {number} [minConfidence=0.6] - Minimum confidence threshold
|
|
62
|
+
* @property {boolean} [enableReflection=true] - Enable self-reflection
|
|
63
|
+
* @property {boolean} [enableBacktracking=true] - Enable backtracking on failure
|
|
64
|
+
* @property {number} [timeout=60000] - Reasoning timeout in ms
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reasoning Engine class for autonomous problem solving
|
|
69
|
+
* @extends EventEmitter
|
|
70
|
+
*/
|
|
71
|
+
class ReasoningEngine extends EventEmitter {
|
|
72
|
+
/**
|
|
73
|
+
* Create reasoning engine
|
|
74
|
+
* @param {ReasoningOptions} [options={}] - Engine options
|
|
75
|
+
*/
|
|
76
|
+
constructor(options = {}) {
|
|
77
|
+
super();
|
|
78
|
+
|
|
79
|
+
this.strategy = options.strategy || STRATEGY.CHAIN_OF_THOUGHT;
|
|
80
|
+
this.maxSteps = options.maxSteps ?? 20;
|
|
81
|
+
this.minConfidence = options.minConfidence ?? 0.6;
|
|
82
|
+
this.enableReflection = options.enableReflection ?? true;
|
|
83
|
+
this.enableBacktracking = options.enableBacktracking ?? true;
|
|
84
|
+
this.timeout = options.timeout ?? 60000;
|
|
85
|
+
|
|
86
|
+
// State
|
|
87
|
+
this.traces = new Map();
|
|
88
|
+
this.currentTrace = null;
|
|
89
|
+
this.stepCounter = 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Start reasoning about a problem
|
|
94
|
+
* @param {string} problem - Problem statement
|
|
95
|
+
* @param {Object} [context={}] - Additional context
|
|
96
|
+
* @returns {Promise<ReasoningTrace>}
|
|
97
|
+
*/
|
|
98
|
+
async reason(problem, context = {}) {
|
|
99
|
+
const traceId = this.generateId();
|
|
100
|
+
const startTime = Date.now();
|
|
101
|
+
|
|
102
|
+
const trace = {
|
|
103
|
+
id: traceId,
|
|
104
|
+
problem,
|
|
105
|
+
strategy: this.strategy,
|
|
106
|
+
steps: [],
|
|
107
|
+
conclusion: null,
|
|
108
|
+
successful: false,
|
|
109
|
+
totalTime: 0
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
this.currentTrace = trace;
|
|
113
|
+
this.traces.set(traceId, trace);
|
|
114
|
+
|
|
115
|
+
this.emit('reasoning:start', { traceId, problem, strategy: this.strategy });
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// Select reasoning strategy
|
|
119
|
+
let result;
|
|
120
|
+
switch (this.strategy) {
|
|
121
|
+
case STRATEGY.CHAIN_OF_THOUGHT:
|
|
122
|
+
result = await this.chainOfThought(problem, context);
|
|
123
|
+
break;
|
|
124
|
+
case STRATEGY.TREE_OF_THOUGHT:
|
|
125
|
+
result = await this.treeOfThought(problem, context);
|
|
126
|
+
break;
|
|
127
|
+
case STRATEGY.REFLECTION:
|
|
128
|
+
result = await this.reflectiveReasoning(problem, context);
|
|
129
|
+
break;
|
|
130
|
+
case STRATEGY.DECOMPOSITION:
|
|
131
|
+
result = await this.decompositionReasoning(problem, context);
|
|
132
|
+
break;
|
|
133
|
+
case STRATEGY.ANALOGY:
|
|
134
|
+
result = await this.analogyReasoning(problem, context);
|
|
135
|
+
break;
|
|
136
|
+
default:
|
|
137
|
+
result = await this.chainOfThought(problem, context);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
trace.conclusion = result.conclusion;
|
|
141
|
+
trace.successful = result.successful;
|
|
142
|
+
|
|
143
|
+
} catch (error) {
|
|
144
|
+
this.addStep(STEP_TYPE.REFLECT, `Reasoning failed: ${error.message}`, { error: error.message }, 0);
|
|
145
|
+
trace.successful = false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
trace.totalTime = Date.now() - startTime;
|
|
149
|
+
this.currentTrace = null;
|
|
150
|
+
|
|
151
|
+
this.emit('reasoning:complete', { trace });
|
|
152
|
+
|
|
153
|
+
return trace;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Chain of Thought reasoning
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
160
|
+
async chainOfThought(problem, context) {
|
|
161
|
+
// Step 1: Observe
|
|
162
|
+
this.addStep(STEP_TYPE.OBSERVE, `Analyzing problem: ${problem}`, { context }, 0.9);
|
|
163
|
+
|
|
164
|
+
// Step 2: Decompose into sub-problems
|
|
165
|
+
const subProblems = this.decomposeProlem(problem);
|
|
166
|
+
this.addStep(STEP_TYPE.THINK, `Identified ${subProblems.length} sub-problems:\n${subProblems.map((p, i) => `${i + 1}. ${p}`).join('\n')}`, { subProblems }, 0.8);
|
|
167
|
+
|
|
168
|
+
// Step 3: Process each sub-problem
|
|
169
|
+
const solutions = [];
|
|
170
|
+
for (const subProblem of subProblems) {
|
|
171
|
+
this.addStep(STEP_TYPE.THINK, `Working on: ${subProblem}`, {}, 0.7);
|
|
172
|
+
|
|
173
|
+
const solution = await this.solveSubProblem(subProblem, context);
|
|
174
|
+
solutions.push({ problem: subProblem, solution });
|
|
175
|
+
|
|
176
|
+
this.addStep(STEP_TYPE.ACT, `Solution: ${solution}`, { subProblem, solution }, 0.8);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Step 4: Synthesize
|
|
180
|
+
const conclusion = this.synthesize(solutions);
|
|
181
|
+
this.addStep(STEP_TYPE.PLAN, `Synthesizing solutions into final answer`, { solutionCount: solutions.length }, 0.85);
|
|
182
|
+
|
|
183
|
+
// Step 5: Reflect if enabled
|
|
184
|
+
if (this.enableReflection) {
|
|
185
|
+
const reflection = this.reflect(problem, conclusion, solutions);
|
|
186
|
+
this.addStep(STEP_TYPE.REFLECT, reflection.content, { confidence: reflection.confidence }, reflection.confidence);
|
|
187
|
+
|
|
188
|
+
if (reflection.confidence < this.minConfidence && this.enableBacktracking) {
|
|
189
|
+
return this.backtrack(problem, context, reflection);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return { conclusion, successful: true };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Tree of Thought reasoning - explore multiple paths
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
async treeOfThought(problem, context) {
|
|
201
|
+
const branches = [];
|
|
202
|
+
const maxBranches = 3;
|
|
203
|
+
|
|
204
|
+
this.addStep(STEP_TYPE.OBSERVE, `Exploring multiple reasoning paths for: ${problem}`, {}, 0.9);
|
|
205
|
+
|
|
206
|
+
// Generate multiple initial thoughts
|
|
207
|
+
const initialThoughts = this.generateThoughts(problem, maxBranches);
|
|
208
|
+
this.addStep(STEP_TYPE.THINK, `Generated ${initialThoughts.length} reasoning branches`, { branches: initialThoughts }, 0.8);
|
|
209
|
+
|
|
210
|
+
// Explore each branch
|
|
211
|
+
for (const thought of initialThoughts) {
|
|
212
|
+
const branch = {
|
|
213
|
+
thought,
|
|
214
|
+
steps: [],
|
|
215
|
+
conclusion: null,
|
|
216
|
+
score: 0
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
this.addStep(STEP_TYPE.PLAN, `Exploring branch: ${thought}`, {}, 0.7);
|
|
220
|
+
|
|
221
|
+
// Develop this branch
|
|
222
|
+
const developed = await this.developBranch(thought, problem, context);
|
|
223
|
+
branch.steps = developed.steps;
|
|
224
|
+
branch.conclusion = developed.conclusion;
|
|
225
|
+
branch.score = this.evaluateBranch(branch);
|
|
226
|
+
|
|
227
|
+
branches.push(branch);
|
|
228
|
+
this.addStep(STEP_TYPE.REFLECT, `Branch score: ${branch.score.toFixed(2)}`, { conclusion: branch.conclusion }, branch.score);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Select best branch
|
|
232
|
+
branches.sort((a, b) => b.score - a.score);
|
|
233
|
+
const best = branches[0];
|
|
234
|
+
|
|
235
|
+
this.addStep(STEP_TYPE.ACT, `Selected best reasoning path with score ${best.score.toFixed(2)}`, { conclusion: best.conclusion }, best.score);
|
|
236
|
+
|
|
237
|
+
return { conclusion: best.conclusion, successful: best.score >= this.minConfidence };
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Reflective reasoning - iterate and improve
|
|
242
|
+
* @private
|
|
243
|
+
*/
|
|
244
|
+
async reflectiveReasoning(problem, context) {
|
|
245
|
+
let currentSolution = null;
|
|
246
|
+
let iterations = 0;
|
|
247
|
+
const maxIterations = 3;
|
|
248
|
+
|
|
249
|
+
this.addStep(STEP_TYPE.OBSERVE, `Starting reflective reasoning for: ${problem}`, {}, 0.9);
|
|
250
|
+
|
|
251
|
+
while (iterations < maxIterations) {
|
|
252
|
+
iterations++;
|
|
253
|
+
|
|
254
|
+
// Generate or refine solution
|
|
255
|
+
if (!currentSolution) {
|
|
256
|
+
currentSolution = await this.generateInitialSolution(problem, context);
|
|
257
|
+
this.addStep(STEP_TYPE.THINK, `Initial solution: ${currentSolution}`, { iteration: iterations }, 0.7);
|
|
258
|
+
} else {
|
|
259
|
+
currentSolution = await this.refineSolution(currentSolution, problem, context);
|
|
260
|
+
this.addStep(STEP_TYPE.REFINE, `Refined solution: ${currentSolution}`, { iteration: iterations }, 0.8);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Reflect on solution
|
|
264
|
+
const reflection = this.reflect(problem, currentSolution, []);
|
|
265
|
+
this.addStep(STEP_TYPE.REFLECT, reflection.content, { confidence: reflection.confidence }, reflection.confidence);
|
|
266
|
+
|
|
267
|
+
if (reflection.confidence >= this.minConfidence) {
|
|
268
|
+
return { conclusion: currentSolution, successful: true };
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return { conclusion: currentSolution, successful: false };
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Decomposition reasoning - divide and conquer
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
async decompositionReasoning(problem, context) {
|
|
280
|
+
this.addStep(STEP_TYPE.OBSERVE, `Decomposing problem: ${problem}`, {}, 0.9);
|
|
281
|
+
|
|
282
|
+
// Hierarchical decomposition
|
|
283
|
+
const decomposition = this.hierarchicalDecompose(problem);
|
|
284
|
+
this.addStep(STEP_TYPE.PLAN, `Problem decomposition:\n${this.formatDecomposition(decomposition)}`, { decomposition }, 0.85);
|
|
285
|
+
|
|
286
|
+
// Solve bottom-up
|
|
287
|
+
const solved = await this.solveBottomUp(decomposition, context);
|
|
288
|
+
this.addStep(STEP_TYPE.ACT, `Solved ${solved.solvedCount} sub-problems`, { solved: solved.results }, 0.8);
|
|
289
|
+
|
|
290
|
+
// Compose solution
|
|
291
|
+
const conclusion = this.composeSolution(solved.results);
|
|
292
|
+
this.addStep(STEP_TYPE.THINK, `Composed final solution`, { conclusion }, 0.85);
|
|
293
|
+
|
|
294
|
+
return { conclusion, successful: true };
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Analogy reasoning - use similar cases
|
|
299
|
+
* @private
|
|
300
|
+
*/
|
|
301
|
+
async analogyReasoning(problem, context) {
|
|
302
|
+
this.addStep(STEP_TYPE.OBSERVE, `Finding analogies for: ${problem}`, {}, 0.9);
|
|
303
|
+
|
|
304
|
+
// Find similar cases
|
|
305
|
+
const analogies = this.findAnalogies(problem, context);
|
|
306
|
+
this.addStep(STEP_TYPE.THINK, `Found ${analogies.length} similar cases`, { analogies }, 0.8);
|
|
307
|
+
|
|
308
|
+
if (analogies.length === 0) {
|
|
309
|
+
this.addStep(STEP_TYPE.REFLECT, 'No suitable analogies found, falling back to chain of thought', {}, 0.5);
|
|
310
|
+
return this.chainOfThought(problem, context);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Apply best analogy
|
|
314
|
+
const best = analogies[0];
|
|
315
|
+
this.addStep(STEP_TYPE.PLAN, `Applying analogy: ${best.description}`, { analogy: best }, 0.75);
|
|
316
|
+
|
|
317
|
+
const conclusion = this.applyAnalogy(best, problem, context);
|
|
318
|
+
this.addStep(STEP_TYPE.ACT, `Derived solution from analogy`, { conclusion }, 0.8);
|
|
319
|
+
|
|
320
|
+
return { conclusion, successful: true };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Add a reasoning step
|
|
325
|
+
* @param {string} type - Step type
|
|
326
|
+
* @param {string} content - Step content
|
|
327
|
+
* @param {Object} metadata - Additional metadata
|
|
328
|
+
* @param {number} confidence - Confidence score
|
|
329
|
+
*/
|
|
330
|
+
addStep(type, content, metadata = {}, confidence = 0.5) {
|
|
331
|
+
if (!this.currentTrace) return;
|
|
332
|
+
|
|
333
|
+
const step = {
|
|
334
|
+
id: `step-${++this.stepCounter}`,
|
|
335
|
+
type,
|
|
336
|
+
content,
|
|
337
|
+
metadata,
|
|
338
|
+
confidence,
|
|
339
|
+
timestamp: Date.now()
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
this.currentTrace.steps.push(step);
|
|
343
|
+
this.emit('reasoning:step', { step, traceId: this.currentTrace.id });
|
|
344
|
+
|
|
345
|
+
// Check step limit
|
|
346
|
+
if (this.currentTrace.steps.length >= this.maxSteps) {
|
|
347
|
+
throw new Error('Maximum reasoning steps exceeded');
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Decompose problem into sub-problems
|
|
353
|
+
* @private
|
|
354
|
+
*/
|
|
355
|
+
decomposeProlem(problem) {
|
|
356
|
+
// Simple keyword-based decomposition
|
|
357
|
+
const parts = [];
|
|
358
|
+
|
|
359
|
+
// Look for conjunction patterns
|
|
360
|
+
const conjunctions = ['and', 'then', 'also', 'additionally', 'furthermore'];
|
|
361
|
+
let remaining = problem;
|
|
362
|
+
|
|
363
|
+
for (const conj of conjunctions) {
|
|
364
|
+
const regex = new RegExp(`\\s+${conj}\\s+`, 'gi');
|
|
365
|
+
if (regex.test(remaining)) {
|
|
366
|
+
const split = remaining.split(regex);
|
|
367
|
+
parts.push(...split);
|
|
368
|
+
remaining = '';
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (remaining) {
|
|
374
|
+
parts.push(remaining);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Clean up and filter
|
|
378
|
+
return parts
|
|
379
|
+
.map(p => p.trim())
|
|
380
|
+
.filter(p => p.length > 0);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Solve a sub-problem
|
|
385
|
+
* @private
|
|
386
|
+
*/
|
|
387
|
+
async solveSubProblem(subProblem, context) {
|
|
388
|
+
// Simplified solution generation
|
|
389
|
+
return `Resolved: ${subProblem.substring(0, 50)}...`;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Synthesize solutions
|
|
394
|
+
* @private
|
|
395
|
+
*/
|
|
396
|
+
synthesize(solutions) {
|
|
397
|
+
if (solutions.length === 0) return 'No solutions found';
|
|
398
|
+
if (solutions.length === 1) return solutions[0].solution;
|
|
399
|
+
|
|
400
|
+
return solutions.map(s => s.solution).join(' → ');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Reflect on solution
|
|
405
|
+
* @private
|
|
406
|
+
*/
|
|
407
|
+
reflect(problem, conclusion, solutions) {
|
|
408
|
+
// Simple reflection logic
|
|
409
|
+
const hasConclusion = conclusion && conclusion.length > 0;
|
|
410
|
+
const hasMultipleSolutions = solutions.length > 1;
|
|
411
|
+
|
|
412
|
+
let confidence = 0.5;
|
|
413
|
+
let content = 'Analyzing solution quality...';
|
|
414
|
+
|
|
415
|
+
if (hasConclusion) {
|
|
416
|
+
confidence += 0.2;
|
|
417
|
+
content = 'Solution generated successfully.';
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (hasMultipleSolutions) {
|
|
421
|
+
confidence += 0.1;
|
|
422
|
+
content += ' Multiple approaches considered.';
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// Check if conclusion addresses the problem
|
|
426
|
+
const problemWords = problem.toLowerCase().split(/\s+/);
|
|
427
|
+
const conclusionWords = (conclusion || '').toLowerCase().split(/\s+/);
|
|
428
|
+
const overlap = problemWords.filter(w => conclusionWords.includes(w)).length;
|
|
429
|
+
|
|
430
|
+
if (overlap > 2) {
|
|
431
|
+
confidence += 0.1;
|
|
432
|
+
content += ' Conclusion appears relevant to problem.';
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return { confidence: Math.min(confidence, 1), content };
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Backtrack and try alternative approach
|
|
440
|
+
* @private
|
|
441
|
+
*/
|
|
442
|
+
async backtrack(problem, context, reflection) {
|
|
443
|
+
this.addStep(STEP_TYPE.REFLECT, `Confidence too low (${reflection.confidence.toFixed(2)}), backtracking...`, {}, reflection.confidence);
|
|
444
|
+
|
|
445
|
+
// Try decomposition as fallback
|
|
446
|
+
const decomposition = this.decomposeProlem(problem);
|
|
447
|
+
if (decomposition.length > 1) {
|
|
448
|
+
const solutions = [];
|
|
449
|
+
for (const sub of decomposition) {
|
|
450
|
+
const solution = await this.solveSubProblem(sub, context);
|
|
451
|
+
solutions.push({ problem: sub, solution });
|
|
452
|
+
}
|
|
453
|
+
const conclusion = this.synthesize(solutions);
|
|
454
|
+
return { conclusion, successful: true };
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return { conclusion: 'Unable to reach confident solution', successful: false };
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Generate multiple initial thoughts
|
|
462
|
+
* @private
|
|
463
|
+
*/
|
|
464
|
+
generateThoughts(problem, count) {
|
|
465
|
+
const thoughts = [];
|
|
466
|
+
const approaches = [
|
|
467
|
+
'Direct approach: ',
|
|
468
|
+
'Step-by-step: ',
|
|
469
|
+
'Alternative perspective: '
|
|
470
|
+
];
|
|
471
|
+
|
|
472
|
+
for (let i = 0; i < Math.min(count, approaches.length); i++) {
|
|
473
|
+
thoughts.push(`${approaches[i]}${problem.substring(0, 50)}`);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return thoughts;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Develop a reasoning branch
|
|
481
|
+
* @private
|
|
482
|
+
*/
|
|
483
|
+
async developBranch(thought, problem, context) {
|
|
484
|
+
const steps = [];
|
|
485
|
+
|
|
486
|
+
steps.push({ content: `Developing: ${thought}`, type: 'develop' });
|
|
487
|
+
steps.push({ content: `Analyzing implications`, type: 'analyze' });
|
|
488
|
+
|
|
489
|
+
const conclusion = `Branch conclusion for: ${thought.substring(0, 30)}`;
|
|
490
|
+
|
|
491
|
+
return { steps, conclusion };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Evaluate a reasoning branch
|
|
496
|
+
* @private
|
|
497
|
+
*/
|
|
498
|
+
evaluateBranch(branch) {
|
|
499
|
+
// Simple scoring based on step count and conclusion
|
|
500
|
+
let score = 0.5;
|
|
501
|
+
|
|
502
|
+
if (branch.conclusion) score += 0.2;
|
|
503
|
+
if (branch.steps.length > 0) score += 0.1;
|
|
504
|
+
if (branch.steps.length > 2) score += 0.1;
|
|
505
|
+
|
|
506
|
+
return Math.min(score, 1);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Generate initial solution
|
|
511
|
+
* @private
|
|
512
|
+
*/
|
|
513
|
+
async generateInitialSolution(problem, context) {
|
|
514
|
+
return `Initial approach to: ${problem.substring(0, 50)}`;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Refine existing solution
|
|
519
|
+
* @private
|
|
520
|
+
*/
|
|
521
|
+
async refineSolution(solution, problem, context) {
|
|
522
|
+
return `Refined: ${solution}`;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Hierarchical decomposition
|
|
527
|
+
* @private
|
|
528
|
+
*/
|
|
529
|
+
hierarchicalDecompose(problem) {
|
|
530
|
+
return {
|
|
531
|
+
root: problem,
|
|
532
|
+
children: this.decomposeProlem(problem).map(p => ({
|
|
533
|
+
content: p,
|
|
534
|
+
children: []
|
|
535
|
+
}))
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Format decomposition for display
|
|
541
|
+
* @private
|
|
542
|
+
*/
|
|
543
|
+
formatDecomposition(decomposition, indent = 0) {
|
|
544
|
+
const prefix = ' '.repeat(indent);
|
|
545
|
+
let result = `${prefix}└ ${decomposition.root || decomposition.content}`;
|
|
546
|
+
|
|
547
|
+
if (decomposition.children) {
|
|
548
|
+
for (const child of decomposition.children) {
|
|
549
|
+
result += '\n' + this.formatDecomposition(child, indent + 1);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return result;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Solve problems bottom-up
|
|
558
|
+
* @private
|
|
559
|
+
*/
|
|
560
|
+
async solveBottomUp(decomposition, context) {
|
|
561
|
+
const results = [];
|
|
562
|
+
|
|
563
|
+
// Solve leaf nodes first
|
|
564
|
+
if (decomposition.children) {
|
|
565
|
+
for (const child of decomposition.children) {
|
|
566
|
+
const solution = await this.solveSubProblem(child.content, context);
|
|
567
|
+
results.push({ problem: child.content, solution });
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return { results, solvedCount: results.length };
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Compose solution from parts
|
|
576
|
+
* @private
|
|
577
|
+
*/
|
|
578
|
+
composeSolution(results) {
|
|
579
|
+
if (results.length === 0) return 'No solution components';
|
|
580
|
+
return results.map(r => r.solution).join('; ');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Find analogies for problem
|
|
585
|
+
* @private
|
|
586
|
+
*/
|
|
587
|
+
findAnalogies(problem, context) {
|
|
588
|
+
// Placeholder for analogy retrieval
|
|
589
|
+
// In real implementation, would search knowledge base
|
|
590
|
+
return [];
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Apply analogy to derive solution
|
|
595
|
+
* @private
|
|
596
|
+
*/
|
|
597
|
+
applyAnalogy(analogy, problem, context) {
|
|
598
|
+
return `Applied ${analogy.description} to derive solution`;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Generate unique ID
|
|
603
|
+
* @private
|
|
604
|
+
*/
|
|
605
|
+
generateId() {
|
|
606
|
+
return `trace-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Get reasoning trace by ID
|
|
611
|
+
* @param {string} traceId - Trace identifier
|
|
612
|
+
* @returns {ReasoningTrace|null}
|
|
613
|
+
*/
|
|
614
|
+
getTrace(traceId) {
|
|
615
|
+
return this.traces.get(traceId) || null;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Get all traces
|
|
620
|
+
* @returns {ReasoningTrace[]}
|
|
621
|
+
*/
|
|
622
|
+
getAllTraces() {
|
|
623
|
+
return Array.from(this.traces.values());
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/**
|
|
627
|
+
* Clear all traces
|
|
628
|
+
*/
|
|
629
|
+
clearTraces() {
|
|
630
|
+
this.traces.clear();
|
|
631
|
+
this.stepCounter = 0;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Get statistics
|
|
636
|
+
* @returns {Object}
|
|
637
|
+
*/
|
|
638
|
+
getStats() {
|
|
639
|
+
const traces = this.getAllTraces();
|
|
640
|
+
const successful = traces.filter(t => t.successful).length;
|
|
641
|
+
const totalSteps = traces.reduce((sum, t) => sum + t.steps.length, 0);
|
|
642
|
+
const avgTime = traces.length > 0
|
|
643
|
+
? traces.reduce((sum, t) => sum + t.totalTime, 0) / traces.length
|
|
644
|
+
: 0;
|
|
645
|
+
|
|
646
|
+
return {
|
|
647
|
+
totalTraces: traces.length,
|
|
648
|
+
successfulTraces: successful,
|
|
649
|
+
successRate: traces.length > 0 ? successful / traces.length : 0,
|
|
650
|
+
totalSteps,
|
|
651
|
+
averageStepsPerTrace: traces.length > 0 ? totalSteps / traces.length : 0,
|
|
652
|
+
averageTime: avgTime
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Export trace to readable format
|
|
658
|
+
* @param {string} traceId - Trace identifier
|
|
659
|
+
* @returns {string}
|
|
660
|
+
*/
|
|
661
|
+
exportTrace(traceId) {
|
|
662
|
+
const trace = this.getTrace(traceId);
|
|
663
|
+
if (!trace) return '';
|
|
664
|
+
|
|
665
|
+
let output = `# Reasoning Trace: ${trace.id}\n\n`;
|
|
666
|
+
output += `**Problem:** ${trace.problem}\n\n`;
|
|
667
|
+
output += `**Strategy:** ${trace.strategy}\n\n`;
|
|
668
|
+
output += `## Steps\n\n`;
|
|
669
|
+
|
|
670
|
+
for (const step of trace.steps) {
|
|
671
|
+
output += `### ${step.type.toUpperCase()} (confidence: ${step.confidence.toFixed(2)})\n`;
|
|
672
|
+
output += `${step.content}\n\n`;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
output += `## Conclusion\n\n`;
|
|
676
|
+
output += `${trace.conclusion || 'No conclusion reached'}\n\n`;
|
|
677
|
+
output += `**Successful:** ${trace.successful ? 'Yes' : 'No'}\n`;
|
|
678
|
+
output += `**Total Time:** ${trace.totalTime}ms\n`;
|
|
679
|
+
|
|
680
|
+
return output;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Create reasoning engine
|
|
686
|
+
* @param {ReasoningOptions} [options={}] - Engine options
|
|
687
|
+
* @returns {ReasoningEngine}
|
|
688
|
+
*/
|
|
689
|
+
function createReasoningEngine(options = {}) {
|
|
690
|
+
return new ReasoningEngine(options);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Run reasoning on problem
|
|
695
|
+
* @param {string} problem - Problem statement
|
|
696
|
+
* @param {Object} [options={}] - Reasoning options
|
|
697
|
+
* @returns {Promise<ReasoningTrace>}
|
|
698
|
+
*/
|
|
699
|
+
async function reason(problem, options = {}) {
|
|
700
|
+
const engine = createReasoningEngine(options);
|
|
701
|
+
return engine.reason(problem, options.context || {});
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
module.exports = {
|
|
705
|
+
ReasoningEngine,
|
|
706
|
+
createReasoningEngine,
|
|
707
|
+
reason,
|
|
708
|
+
STRATEGY,
|
|
709
|
+
STEP_TYPE
|
|
710
|
+
};
|