mark-improving-agent 2.2.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.
Files changed (79) hide show
  1. package/README.md +335 -0
  2. package/VERSION +1 -0
  3. package/bin/cli.js +12 -0
  4. package/dist/agent/context.js +78 -0
  5. package/dist/agent/index.js +6 -0
  6. package/dist/agent/runtime.js +195 -0
  7. package/dist/agent/task-graph.js +209 -0
  8. package/dist/agent/types.js +1 -0
  9. package/dist/cli/index.js +206 -0
  10. package/dist/core/cognition/active-inference.js +296 -0
  11. package/dist/core/cognition/cognitive-architecture.js +263 -0
  12. package/dist/core/cognition/dual-process.js +102 -0
  13. package/dist/core/cognition/index.js +13 -0
  14. package/dist/core/cognition/learning-from-failure.js +184 -0
  15. package/dist/core/cognition/meta-agent.js +407 -0
  16. package/dist/core/cognition/metacognition.js +322 -0
  17. package/dist/core/cognition/react.js +177 -0
  18. package/dist/core/cognition/retrieval-anchor.js +99 -0
  19. package/dist/core/cognition/self-evolution.js +294 -0
  20. package/dist/core/cognition/self-verification.js +190 -0
  21. package/dist/core/cognition/thought-graph.js +495 -0
  22. package/dist/core/cognition/tool-augmented-llm.js +188 -0
  23. package/dist/core/cognition/tool-execution-verifier.js +204 -0
  24. package/dist/core/collaboration/agentic-loop.js +165 -0
  25. package/dist/core/collaboration/index.js +3 -0
  26. package/dist/core/collaboration/multi-agent-system.js +186 -0
  27. package/dist/core/collaboration/multi-agent.js +110 -0
  28. package/dist/core/consciousness/emotion-engine.js +101 -0
  29. package/dist/core/consciousness/flow-machine.js +121 -0
  30. package/dist/core/consciousness/index.js +4 -0
  31. package/dist/core/consciousness/personality.js +103 -0
  32. package/dist/core/consciousness/types.js +1 -0
  33. package/dist/core/emotional-protocol.js +54 -0
  34. package/dist/core/evolution/engine.js +194 -0
  35. package/dist/core/evolution/goal-engine.js +153 -0
  36. package/dist/core/evolution/index.js +6 -0
  37. package/dist/core/evolution/meta-learning.js +172 -0
  38. package/dist/core/evolution/reflection.js +158 -0
  39. package/dist/core/evolution/self-healer.js +139 -0
  40. package/dist/core/evolution/types.js +1 -0
  41. package/dist/core/healing-rl.js +266 -0
  42. package/dist/core/heartbeat.js +408 -0
  43. package/dist/core/identity/index.js +3 -0
  44. package/dist/core/identity/reflexion.js +165 -0
  45. package/dist/core/identity/self-model.js +274 -0
  46. package/dist/core/identity/self-verifier.js +158 -0
  47. package/dist/core/identity/types.js +12 -0
  48. package/dist/core/lesson-bank.js +301 -0
  49. package/dist/core/memory/adaptive-rag.js +440 -0
  50. package/dist/core/memory/archive-store.js +187 -0
  51. package/dist/core/memory/dream-consolidation.js +366 -0
  52. package/dist/core/memory/embedder.js +130 -0
  53. package/dist/core/memory/hopfield-network.js +128 -0
  54. package/dist/core/memory/index.js +9 -0
  55. package/dist/core/memory/knowledge-graph.js +151 -0
  56. package/dist/core/memory/spaced-repetition.js +113 -0
  57. package/dist/core/memory/store.js +404 -0
  58. package/dist/core/memory/types.js +1 -0
  59. package/dist/core/psychology/analysis.js +456 -0
  60. package/dist/core/psychology/index.js +1 -0
  61. package/dist/core/rollback-manager.js +191 -0
  62. package/dist/core/security/index.js +1 -0
  63. package/dist/core/security/privacy.js +132 -0
  64. package/dist/core/truth-teller.js +253 -0
  65. package/dist/core/truthfulness.js +99 -0
  66. package/dist/core/types.js +2 -0
  67. package/dist/event/bus.js +47 -0
  68. package/dist/index.js +8 -0
  69. package/dist/skills/dag.js +181 -0
  70. package/dist/skills/index.js +5 -0
  71. package/dist/skills/registry.js +40 -0
  72. package/dist/skills/types.js +1 -0
  73. package/dist/storage/archive.js +77 -0
  74. package/dist/storage/checkpoint.js +119 -0
  75. package/dist/storage/types.js +1 -0
  76. package/dist/utils/config.js +81 -0
  77. package/dist/utils/logger.js +49 -0
  78. package/dist/version.js +1 -0
  79. package/package.json +37 -0
@@ -0,0 +1,322 @@
1
+ /**
2
+ * Metacognition - Self-Improving Agent with Metacognitive Capabilities
3
+ *
4
+ * Paper: "Self-Improving Agents with Intrinsic Metacognitive Abilities" (2025)
5
+ * Key mechanisms:
6
+ * - Performance Monitoring: Track success/failure of reasoning
7
+ * - Strategy Selection: Choose between different reasoning approaches
8
+ * - Strategy Execution: Implement selected strategy
9
+ * - Self-Verification: Verify own outputs
10
+ * - Confidence Estimation: Know when you don't know
11
+ *
12
+ * Paper: "MetaDreamer - Meta-RL for Dream-like Learning"
13
+ * - Three-level optimization: Environment-specific, Cross-domain, Rapid adaptation
14
+ */
15
+ import { randomUUID } from 'crypto';
16
+ import { createSelfVerificationEngine } from './self-verification.js';
17
+ const DEFAULT_CONFIDENCE_THRESHOLD = 0.7;
18
+ const STRATEGY_SWITCH_THRESHOLD = 0.3;
19
+ const RAPID_ADAPTATION_TASKS = 5;
20
+ export function createMetacognitionEngine() {
21
+ // Strategy performance tracking
22
+ const strategyPerformance = new Map();
23
+ // Initialize strategy performance
24
+ const strategies = [
25
+ 'direct', 'chain-of-thought', 'self-verified', 'replan', 'multi-path', 'backtrack', 'meta-learn'
26
+ ];
27
+ for (const strategy of strategies) {
28
+ strategyPerformance.set(strategy, {
29
+ strategy,
30
+ attempts: 0,
31
+ successes: 0,
32
+ failures: 0,
33
+ avgConfidence: 0.5,
34
+ avgTimeMs: 0,
35
+ successRate: 0,
36
+ });
37
+ }
38
+ // Meta-learning history
39
+ const metaLearningHistory = [];
40
+ // Current state
41
+ let currentStrategy = 'chain-of-thought';
42
+ let totalReasoningCycles = 0;
43
+ let successfulCycles = 0;
44
+ let failedCycles = 0;
45
+ let strategySwitches = 0;
46
+ let selfCorrections = 0;
47
+ let totalConfidence = 0;
48
+ // Self-verification engine
49
+ const verificationEngine = createSelfVerificationEngine();
50
+ function updateStrategyPerformance(strategy, success, confidence, timeMs) {
51
+ const perf = strategyPerformance.get(strategy);
52
+ perf.attempts++;
53
+ if (success) {
54
+ perf.successes++;
55
+ }
56
+ else {
57
+ perf.failures++;
58
+ }
59
+ // Running average for confidence
60
+ perf.avgConfidence = (perf.avgConfidence * (perf.attempts - 1) + confidence) / perf.attempts;
61
+ // Running average for time
62
+ perf.avgTimeMs = (perf.avgTimeMs * (perf.attempts - 1) + timeMs) / perf.attempts;
63
+ // Success rate
64
+ perf.successRate = perf.successes / perf.attempts;
65
+ }
66
+ function monitor(thought, context) {
67
+ totalReasoningCycles++;
68
+ return getMetrics();
69
+ }
70
+ function evaluate(metrics) {
71
+ const currentPerf = metrics.strategyPerformance.get(currentStrategy);
72
+ const alternatives = strategies.filter(s => s !== currentStrategy);
73
+ // Check if current strategy is failing
74
+ if (currentPerf.successRate < STRATEGY_SWITCH_THRESHOLD) {
75
+ const bestAlternative = selectBestStrategy(metrics);
76
+ return {
77
+ strategy: bestAlternative.strategy,
78
+ confidence: bestAlternative.confidence,
79
+ reason: `Current strategy "${currentStrategy}" has low success rate (${currentPerf.successRate.toFixed(2)})`,
80
+ alternatives,
81
+ };
82
+ }
83
+ // Check if meta-learning suggests a better strategy
84
+ const recentTasks = metaLearningHistory.slice(-RAPID_ADAPTATION_TASKS);
85
+ const taskStrategyMap = new Map();
86
+ for (const entry of recentTasks) {
87
+ if (entry.success) {
88
+ taskStrategyMap.set(entry.task, entry.strategy);
89
+ }
90
+ }
91
+ // If we've seen this type of task, use the learned strategy
92
+ const matchingEntry = recentTasks.reverse().find(e => e.task === recentTasks[recentTasks.length - 1]?.task);
93
+ if (matchingEntry?.success) {
94
+ return {
95
+ strategy: matchingEntry.strategy,
96
+ confidence: 0.8,
97
+ reason: 'Meta-learned strategy from past experience',
98
+ alternatives,
99
+ };
100
+ }
101
+ return {
102
+ strategy: currentStrategy,
103
+ confidence: currentPerf.avgConfidence,
104
+ reason: `Current strategy performing adequately (${currentPerf.successRate.toFixed(2)})`,
105
+ alternatives,
106
+ };
107
+ }
108
+ function regulate(strategy) {
109
+ if (strategy !== currentStrategy) {
110
+ strategySwitches++;
111
+ currentStrategy = strategy;
112
+ }
113
+ }
114
+ function plan(task, context) {
115
+ const executionTrace = [];
116
+ const startTime = Date.now();
117
+ // Select best strategy based on current performance
118
+ const selection = selectBestStrategy(getMetrics());
119
+ let finalStrategy = selection.strategy;
120
+ regulate(finalStrategy);
121
+ const initialStep = {
122
+ strategy: finalStrategy,
123
+ thought: `Planning to solve: ${task.slice(0, 100)}...`,
124
+ confidence: selection.confidence,
125
+ verified: false,
126
+ corrected: false,
127
+ timestamp: Date.now(),
128
+ };
129
+ executionTrace.push(initialStep);
130
+ // Execute with selected strategy
131
+ const selfImprovements = [];
132
+ return {
133
+ id: randomUUID(),
134
+ initialStrategy: selection.strategy,
135
+ executionTrace,
136
+ finalStrategy,
137
+ success: true, // Will be updated after execution
138
+ confidence: selection.confidence,
139
+ selfImprovements,
140
+ timestamp: startTime,
141
+ };
142
+ }
143
+ async function executeWithStrategy(task, strategy, context) {
144
+ const startTime = Date.now();
145
+ regulate(strategy);
146
+ let result = '';
147
+ let confidence = 0.5;
148
+ let verified = false;
149
+ switch (strategy) {
150
+ case 'direct':
151
+ // No reasoning, direct response
152
+ result = `Direct response to: ${task.slice(0, 50)}...`;
153
+ confidence = 0.6;
154
+ verified = true;
155
+ break;
156
+ case 'chain-of-thought':
157
+ // Step-by-step reasoning
158
+ result = `CoT reasoning for: ${task.slice(0, 50)}...`;
159
+ confidence = 0.75;
160
+ break;
161
+ case 'self-verified':
162
+ // Reasoning with self-verification
163
+ const steps = task.split('.');
164
+ const verifiedSteps = steps.map(step => verificationEngine.verifyStep(step, context));
165
+ result = verifiedSteps.map(s => s.step).join('. ');
166
+ confidence = verifiedSteps.reduce((sum, s) => sum + s.confidence, 0) / verifiedSteps.length;
167
+ verified = verifiedSteps.every(s => s.isValid);
168
+ if (!verified)
169
+ selfCorrections++;
170
+ break;
171
+ case 'replan':
172
+ // Replan based on feedback
173
+ result = `Replanned approach for: ${task.slice(0, 50)}...`;
174
+ confidence = 0.7;
175
+ break;
176
+ case 'multi-path':
177
+ // Try multiple approaches
178
+ result = `Multi-path exploration for: ${task.slice(0, 50)}...`;
179
+ confidence = 0.8;
180
+ break;
181
+ case 'backtrack':
182
+ // Revert and try alternatives
183
+ result = `Backtracking approach for: ${task.slice(0, 50)}...`;
184
+ confidence = 0.65;
185
+ break;
186
+ case 'meta-learn':
187
+ // Meta-learning approach
188
+ const learnedStrategy = metaLearningHistory
189
+ .filter(e => e.task.includes(task.slice(0, 20)))
190
+ .sort((a, b) => b.timestamp - a.timestamp)[0];
191
+ if (learnedStrategy) {
192
+ result = `Meta-learned approach for: ${task.slice(0, 50)}...`;
193
+ confidence = 0.85;
194
+ }
195
+ else {
196
+ result = `Exploratory approach for: ${task.slice(0, 50)}...`;
197
+ confidence = 0.5;
198
+ }
199
+ break;
200
+ }
201
+ const timeMs = Date.now() - startTime;
202
+ const success = confidence >= DEFAULT_CONFIDENCE_THRESHOLD;
203
+ updateStrategyPerformance(strategy, success, confidence, timeMs);
204
+ monitor(result);
205
+ if (success)
206
+ successfulCycles++;
207
+ else
208
+ failedCycles++;
209
+ totalConfidence += confidence;
210
+ return { result, confidence, verified };
211
+ }
212
+ function verifyThought(thought, context) {
213
+ return verificationEngine.verifyStep(thought, context);
214
+ }
215
+ function estimateConfidence(thought) {
216
+ const verification = verifyThought(thought);
217
+ return verification.confidence;
218
+ }
219
+ function knowWhenYouDontKnow(thought) {
220
+ const confidence = estimateConfidence(thought);
221
+ if (confidence < 0.5) {
222
+ return {
223
+ knows: false,
224
+ confidence,
225
+ reason: 'Low verification confidence - uncertainty detected',
226
+ };
227
+ }
228
+ // Check for hedge words that indicate uncertainty
229
+ const hedgeWords = ['可能', '也许', '不确定', '大概', 'perhaps', 'maybe', 'uncertain'];
230
+ const hasHedges = hedgeWords.some(h => thought.toLowerCase().includes(h));
231
+ if (hasHedges && confidence < 0.7) {
232
+ return {
233
+ knows: false,
234
+ confidence,
235
+ reason: 'Hedge words detected with moderate uncertainty',
236
+ };
237
+ }
238
+ return {
239
+ knows: true,
240
+ confidence,
241
+ reason: 'Verification passed with acceptable confidence',
242
+ };
243
+ }
244
+ function shouldSwitchStrategy(metrics) {
245
+ const currentPerf = metrics.strategyPerformance.get(currentStrategy);
246
+ return currentPerf.successRate < STRATEGY_SWITCH_THRESHOLD;
247
+ }
248
+ function selectBestStrategy(metrics) {
249
+ const alternatives = strategies.filter(s => s !== currentStrategy);
250
+ let bestStrategy = currentStrategy;
251
+ let bestScore = 0;
252
+ for (const strategy of alternatives) {
253
+ const perf = metrics.strategyPerformance.get(strategy);
254
+ // Score = success rate weighted by confidence
255
+ const score = perf.successRate * perf.avgConfidence;
256
+ if (score > bestScore) {
257
+ bestScore = score;
258
+ bestStrategy = strategy;
259
+ }
260
+ }
261
+ const bestPerf = metrics.strategyPerformance.get(bestStrategy);
262
+ return {
263
+ strategy: bestStrategy,
264
+ confidence: bestPerf.avgConfidence,
265
+ reason: `Best performing strategy based on success rate (${bestPerf.successRate.toFixed(2)}) and confidence`,
266
+ alternatives,
267
+ };
268
+ }
269
+ function learnFromExperience(task, strategy, success, feedback) {
270
+ metaLearningHistory.push({
271
+ task: task.slice(0, 100),
272
+ strategy,
273
+ success,
274
+ feedback,
275
+ timestamp: Date.now(),
276
+ });
277
+ // Keep only last 100 entries
278
+ if (metaLearningHistory.length > 100) {
279
+ metaLearningHistory.shift();
280
+ }
281
+ }
282
+ function getMetaLearnedStrategies() {
283
+ const counts = new Map();
284
+ for (const entry of metaLearningHistory) {
285
+ if (entry.success) {
286
+ counts.set(entry.strategy, (counts.get(entry.strategy) || 0) + 1);
287
+ }
288
+ }
289
+ return counts;
290
+ }
291
+ function getMetrics() {
292
+ return {
293
+ totalReasoningCycles,
294
+ successfulCycles,
295
+ failedCycles,
296
+ strategySwitches,
297
+ selfCorrections,
298
+ averageConfidence: totalReasoningCycles > 0 ? totalConfidence / totalReasoningCycles : 0,
299
+ currentStrategy,
300
+ strategyPerformance: new Map(strategyPerformance),
301
+ };
302
+ }
303
+ function getStrategyPerformance(strategy) {
304
+ return strategyPerformance.get(strategy);
305
+ }
306
+ return {
307
+ monitor,
308
+ evaluate,
309
+ regulate,
310
+ plan,
311
+ executeWithStrategy,
312
+ verifyThought,
313
+ estimateConfidence,
314
+ knowWhenYouDontKnow,
315
+ shouldSwitchStrategy,
316
+ selectBestStrategy,
317
+ learnFromExperience,
318
+ getMetaLearnedStrategies,
319
+ getMetrics,
320
+ getStrategyPerformance,
321
+ };
322
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * ReAct - Reasoning and Acting Integration
3
+ *
4
+ * Paper: "ReAct: Synergizing Reasoning and Acting in Language Models"
5
+ * Concept: Thought-Observation-Action cycle for self-correcting reasoning
6
+ *
7
+ * Key mechanisms:
8
+ * - Reasoning (Thought): Why am I doing this?
9
+ * - Observation: What happened when I did it?
10
+ * - Action: What should I do next?
11
+ * - Self-correction based on observations
12
+ */
13
+ /**
14
+ * Create a ReAct engine for self-correcting reasoning
15
+ *
16
+ * The ReAct cycle:
17
+ * 1. Thought: Why am I doing this?
18
+ * 2. Action: What should I do?
19
+ * 3. Observation: What happened?
20
+ * 4. Evaluate: Did this help? If not, correct.
21
+ */
22
+ export function createReActEngine() {
23
+ let totalRuns = 0;
24
+ let totalCorrections = 0;
25
+ let successfulRuns = 0;
26
+ async function reason(context) {
27
+ totalRuns++;
28
+ const steps = [];
29
+ let corrections = 0;
30
+ let currentGoal = context.goal;
31
+ let success = false;
32
+ let finalAnswer = '';
33
+ for (let stepNum = 1; stepNum <= context.maxSteps; stepNum++) {
34
+ // Step 1: Thought - analyze the situation
35
+ const thought = think(currentGoal, stepNum);
36
+ // Step 2: Action - decide what to do
37
+ const action = selectAction(currentGoal, steps);
38
+ // Step 3: Execute and observe
39
+ const result = await act(action);
40
+ const observation = observe(action, result);
41
+ // Step 4: Evaluate
42
+ const isCorrect = evaluateStep(currentGoal, action, result, steps);
43
+ const reactStep = {
44
+ stepNumber: stepNum,
45
+ thought,
46
+ action,
47
+ observation,
48
+ isCorrect,
49
+ timestamp: Date.now(),
50
+ };
51
+ steps.push(reactStep);
52
+ // Self-correction if needed
53
+ if (!isCorrect && context.enableSelfCorrection) {
54
+ const correctedSteps = correct(steps, observation);
55
+ if (correctedSteps.length > steps.length) {
56
+ corrections++;
57
+ totalCorrections++;
58
+ }
59
+ }
60
+ // Check for success
61
+ if (checkSuccess(currentGoal, result)) {
62
+ success = true;
63
+ finalAnswer = result;
64
+ break;
65
+ }
66
+ // Adjust goal if needed
67
+ currentGoal = adjustGoal(currentGoal, result);
68
+ }
69
+ if (success) {
70
+ successfulRuns++;
71
+ }
72
+ return {
73
+ success,
74
+ steps,
75
+ finalAnswer: finalAnswer || 'Goal not achieved within max steps',
76
+ corrections,
77
+ confidence: steps.length > 0
78
+ ? (steps.filter(s => s.isCorrect).length / steps.length)
79
+ : 0,
80
+ };
81
+ }
82
+ function think(goal, step) {
83
+ // Analyze the goal and current state
84
+ return `[Step ${step}] Reasoning: ${goal}
85
+ - What is the current state?
86
+ - What actions are available?
87
+ - What is the most promising next step?
88
+ - What could go wrong?`;
89
+ }
90
+ async function act(action) {
91
+ // In a real implementation, this would execute the action
92
+ // For now, simulate execution
93
+ return `Executed: ${action}`;
94
+ }
95
+ function observe(action, result) {
96
+ // Analyze what happened
97
+ if (result.includes('Error') || result.includes('Failed')) {
98
+ return `Observation: Action failed - ${result}`;
99
+ }
100
+ if (result.includes('Executed')) {
101
+ return `Observation: Action succeeded - ${result}`;
102
+ }
103
+ return `Observation: ${result}`;
104
+ }
105
+ function selectAction(goal, steps) {
106
+ // Simple action selection based on goal
107
+ if (goal.toLowerCase().includes('search')) {
108
+ return 'search_memory';
109
+ }
110
+ if (goal.toLowerCase().includes('verify')) {
111
+ return 'check_consistency';
112
+ }
113
+ if (goal.toLowerCase().includes('learn')) {
114
+ return 'store_lesson';
115
+ }
116
+ return 'analyze_and_decide';
117
+ }
118
+ function evaluateStep(goal, action, result, steps) {
119
+ // Check if this step helped achieve the goal
120
+ const goalKeywords = goal.toLowerCase().split(/\s+/);
121
+ const resultLower = result.toLowerCase();
122
+ // Simple evaluation: did we make progress?
123
+ const progressIndicators = ['success', 'completed', 'achieved', 'found', 'verified'];
124
+ const hasProgress = progressIndicators.some(ind => resultLower.includes(ind));
125
+ return hasProgress;
126
+ }
127
+ function checkSuccess(goal, result) {
128
+ const resultLower = result.toLowerCase();
129
+ const successIndicators = ['success', 'completed', 'achieved', 'found', 'verified', 'done'];
130
+ for (const indicator of successIndicators) {
131
+ if (resultLower.includes(indicator)) {
132
+ return true;
133
+ }
134
+ }
135
+ return false;
136
+ }
137
+ function adjustGoal(goal, result) {
138
+ // Adjust goal based on what happened
139
+ if (result.includes('failed') || result.includes('error')) {
140
+ return `retry: ${goal}`;
141
+ }
142
+ return goal;
143
+ }
144
+ function correct(steps, error) {
145
+ // Self-correction mechanism
146
+ totalCorrections++;
147
+ const lastStep = steps[steps.length - 1];
148
+ if (lastStep) {
149
+ // Add correction step
150
+ const correctionStep = {
151
+ stepNumber: steps.length + 1,
152
+ thought: `Self-correction: Previous step failed. ${error}`,
153
+ action: 'adjust_approach',
154
+ observation: 'Re-evaluating with new information',
155
+ isCorrect: true,
156
+ timestamp: Date.now(),
157
+ };
158
+ return [...steps, correctionStep];
159
+ }
160
+ return steps;
161
+ }
162
+ function getStats() {
163
+ return {
164
+ totalRuns,
165
+ corrections: totalCorrections,
166
+ successRate: totalRuns > 0 ? successfulRuns / totalRuns : 0,
167
+ };
168
+ }
169
+ return {
170
+ reason,
171
+ think,
172
+ act,
173
+ observe,
174
+ correct,
175
+ getStats,
176
+ };
177
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Retrieval Anchor - Context-Augmented Reasoning
3
+ *
4
+ * Based on paper: LLM Cognitive Architecture (2025)
5
+ * Uses relevant documents/memories as anchors for reasoning.
6
+ */
7
+ import { randomUUID } from 'crypto';
8
+ /**
9
+ * Create a retrieval anchor engine
10
+ * Uses semantic similarity for anchor selection
11
+ */
12
+ export function createRetrievalAnchorEngine() {
13
+ const anchors = new Map();
14
+ /**
15
+ * Simple keyword-based relevance scoring
16
+ * In production, would use embeddings
17
+ */
18
+ function computeRelevance(query, content) {
19
+ const queryWords = query.toLowerCase().split(/\s+/).filter(w => w.length > 2);
20
+ const contentLower = content.toLowerCase();
21
+ if (queryWords.length === 0)
22
+ return 0.5;
23
+ let matches = 0;
24
+ for (const word of queryWords) {
25
+ if (contentLower.includes(word)) {
26
+ matches++;
27
+ }
28
+ }
29
+ return matches / queryWords.length;
30
+ }
31
+ function addAnchor(content, source, relevance = 0.8) {
32
+ const anchor = {
33
+ id: `anchor-${Date.now()}-${randomUUID().slice(0, 8)}`,
34
+ content,
35
+ source,
36
+ relevance,
37
+ recency: 1.0,
38
+ reliability: 0.8,
39
+ usedInReasoning: false,
40
+ createdAt: Date.now(),
41
+ };
42
+ anchors.set(anchor.id, anchor);
43
+ return anchor;
44
+ }
45
+ function query(q) {
46
+ const results = [];
47
+ const maxAnchors = q.maxAnchors ?? 5;
48
+ const minRelevance = q.minRelevance ?? 0.3;
49
+ for (const anchor of anchors.values()) {
50
+ const relevance = computeRelevance(q.query, anchor.content);
51
+ if (relevance >= minRelevance) {
52
+ results.push({ ...anchor, relevance });
53
+ }
54
+ }
55
+ // Sort by relevance, then recency if preferred
56
+ results.sort((a, b) => {
57
+ const relevanceDiff = b.relevance - a.relevance;
58
+ if (q.preferRecent && Math.abs(relevanceDiff) < 0.1) {
59
+ return b.createdAt - a.createdAt;
60
+ }
61
+ return relevanceDiff;
62
+ });
63
+ return results.slice(0, maxAnchors);
64
+ }
65
+ function selectAnchor(q) {
66
+ const results = query({ query: q, maxAnchors: 1, minRelevance: 0.4 });
67
+ return results[0] ?? null;
68
+ }
69
+ function markUsed(anchorId) {
70
+ const anchor = anchors.get(anchorId);
71
+ if (anchor) {
72
+ anchor.usedInReasoning = true;
73
+ }
74
+ }
75
+ function getStats() {
76
+ let used = 0;
77
+ let unused = 0;
78
+ for (const anchor of anchors.values()) {
79
+ if (anchor.usedInReasoning) {
80
+ used++;
81
+ }
82
+ else {
83
+ unused++;
84
+ }
85
+ }
86
+ return {
87
+ total: anchors.size,
88
+ used,
89
+ unused,
90
+ };
91
+ }
92
+ return {
93
+ addAnchor,
94
+ query,
95
+ selectAnchor,
96
+ markUsed,
97
+ getStats,
98
+ };
99
+ }