agentic-flow 1.6.6 → 1.7.1
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/.claude/skills/.claude-flow/metrics/agent-metrics.json +1 -0
- package/.claude/skills/.claude-flow/metrics/performance.json +87 -0
- package/.claude/skills/.claude-flow/metrics/task-metrics.json +10 -0
- package/.claude/skills/skill-builder/.claude-flow/metrics/agent-metrics.json +1 -0
- package/.claude/skills/skill-builder/.claude-flow/metrics/performance.json +87 -0
- package/.claude/skills/skill-builder/.claude-flow/metrics/task-metrics.json +10 -0
- package/CHANGELOG.md +0 -30
- package/README.md +16 -2
- package/dist/agentdb/benchmarks/comprehensive-benchmark.js +664 -0
- package/dist/agentdb/benchmarks/frontier-benchmark.js +419 -0
- package/dist/agentdb/benchmarks/reflexion-benchmark.js +370 -0
- package/dist/agentdb/cli/agentdb-cli.js +717 -0
- package/dist/agentdb/controllers/CausalMemoryGraph.js +322 -0
- package/dist/agentdb/controllers/CausalRecall.js +281 -0
- package/dist/agentdb/controllers/EmbeddingService.js +118 -0
- package/dist/agentdb/controllers/ExplainableRecall.js +387 -0
- package/dist/agentdb/controllers/NightlyLearner.js +382 -0
- package/dist/agentdb/controllers/ReflexionMemory.js +239 -0
- package/dist/agentdb/controllers/SkillLibrary.js +276 -0
- package/dist/agentdb/controllers/frontier-index.js +9 -0
- package/dist/agentdb/controllers/index.js +8 -0
- package/dist/agentdb/index.js +32 -0
- package/dist/agentdb/optimizations/BatchOperations.js +198 -0
- package/dist/agentdb/optimizations/QueryOptimizer.js +225 -0
- package/dist/agentdb/optimizations/index.js +7 -0
- package/dist/agentdb/tests/frontier-features.test.js +665 -0
- package/dist/cli/skills-manager.js +1297 -0
- package/dist/cli/update-message.js +175 -0
- package/dist/cli-proxy.js +2 -26
- package/dist/mcp/standalone-stdio.js +200 -4
- package/dist/memory/SharedMemoryPool.js +211 -0
- package/dist/memory/index.js +6 -0
- package/dist/reasoningbank/AdvancedMemory.js +239 -0
- package/dist/reasoningbank/HybridBackend.js +305 -0
- package/dist/reasoningbank/index-new.js +87 -0
- package/dist/reasoningbank/index.js +0 -4
- package/dist/utils/cli.js +0 -5
- package/docs/AGENTDB_TESTING.md +411 -0
- package/package.json +4 -4
- package/scripts/run-validation.sh +165 -0
- package/scripts/test-agentdb.sh +153 -0
- package/wasm/reasoningbank/reasoningbank_wasm_bg.js +2 -2
- package/wasm/reasoningbank/reasoningbank_wasm_bg.wasm +0 -0
- package/docs/AGENTDB_INTEGRATION.md +0 -379
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Memory System - Full Implementation for v1.7.1
|
|
3
|
+
*
|
|
4
|
+
* Provides high-level memory operations on top of HybridReasoningBank:
|
|
5
|
+
* - Auto-consolidation (patterns → skills) using NightlyLearner
|
|
6
|
+
* - Episodic replay (learn from failures)
|
|
7
|
+
* - Causal reasoning (what-if analysis)
|
|
8
|
+
* - Skill composition (combine learned skills)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { AdvancedMemorySystem } from 'agentic-flow/reasoningbank';
|
|
13
|
+
*
|
|
14
|
+
* const memory = new AdvancedMemorySystem();
|
|
15
|
+
*
|
|
16
|
+
* // Auto-consolidate patterns into skills
|
|
17
|
+
* const result = await memory.autoConsolidate({ minUses: 3, minSuccessRate: 0.7 });
|
|
18
|
+
*
|
|
19
|
+
* // Learn from failures
|
|
20
|
+
* const failures = await memory.replayFailures('authentication', 5);
|
|
21
|
+
*
|
|
22
|
+
* // Causal what-if analysis
|
|
23
|
+
* const insight = await memory.whatIfAnalysis('add caching');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import { HybridReasoningBank } from './HybridBackend.js';
|
|
27
|
+
import { NightlyLearner } from 'agentdb/controllers/NightlyLearner';
|
|
28
|
+
import { SharedMemoryPool } from '../memory/SharedMemoryPool.js';
|
|
29
|
+
export class AdvancedMemorySystem {
|
|
30
|
+
reasoning;
|
|
31
|
+
learner;
|
|
32
|
+
pool;
|
|
33
|
+
constructor(options = {}) {
|
|
34
|
+
this.reasoning = new HybridReasoningBank(options);
|
|
35
|
+
this.pool = SharedMemoryPool.getInstance();
|
|
36
|
+
const db = this.pool.getDatabase();
|
|
37
|
+
const embedder = this.pool.getEmbedder();
|
|
38
|
+
// Initialize NightlyLearner with optimized config
|
|
39
|
+
this.learner = new NightlyLearner(db, embedder, {
|
|
40
|
+
minSimilarity: 0.7,
|
|
41
|
+
minSampleSize: 5,
|
|
42
|
+
confidenceThreshold: 0.6,
|
|
43
|
+
upliftThreshold: 0.1,
|
|
44
|
+
pruneOldEdges: true,
|
|
45
|
+
edgeMaxAgeDays: 90,
|
|
46
|
+
autoExperiments: true,
|
|
47
|
+
experimentBudget: 100
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Auto-consolidate successful patterns into skills
|
|
52
|
+
*
|
|
53
|
+
* Uses NightlyLearner to:
|
|
54
|
+
* 1. Discover causal edges from episode patterns
|
|
55
|
+
* 2. Complete A/B experiments
|
|
56
|
+
* 3. Calculate uplift for experiments
|
|
57
|
+
* 4. Prune low-confidence edges
|
|
58
|
+
* 5. Consolidate high-performing patterns into skills
|
|
59
|
+
*/
|
|
60
|
+
async autoConsolidate(options = {}) {
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
try {
|
|
63
|
+
// Run NightlyLearner's discovery and consolidation pipeline
|
|
64
|
+
const report = await this.learner.run();
|
|
65
|
+
// Also run skill consolidation from HybridReasoningBank
|
|
66
|
+
const skillResult = await this.reasoning.autoConsolidate(options.minUses || 3, options.minSuccessRate || 0.7, options.lookbackDays || 30);
|
|
67
|
+
return {
|
|
68
|
+
skillsCreated: skillResult.skillsCreated + (report.edgesDiscovered || 0),
|
|
69
|
+
causalEdgesCreated: report.edgesDiscovered || 0,
|
|
70
|
+
patternsAnalyzed: report.experimentsCompleted || 0,
|
|
71
|
+
executionTimeMs: Date.now() - startTime,
|
|
72
|
+
recommendations: report.recommendations || []
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error('[AdvancedMemorySystem] Auto-consolidation failed:', error);
|
|
77
|
+
// Fallback to basic consolidation
|
|
78
|
+
const skillResult = await this.reasoning.autoConsolidate(options.minUses || 3, options.minSuccessRate || 0.7, options.lookbackDays || 30);
|
|
79
|
+
return {
|
|
80
|
+
skillsCreated: skillResult.skillsCreated,
|
|
81
|
+
causalEdgesCreated: 0,
|
|
82
|
+
patternsAnalyzed: 0,
|
|
83
|
+
executionTimeMs: Date.now() - startTime,
|
|
84
|
+
recommendations: ['Causal discovery unavailable - basic consolidation completed']
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Learn from past failures with episodic replay
|
|
90
|
+
*
|
|
91
|
+
* Retrieves failed attempts, extracts lessons, and provides recommendations
|
|
92
|
+
*/
|
|
93
|
+
async replayFailures(task, k = 5) {
|
|
94
|
+
const failures = await this.reasoning.retrievePatterns(task, {
|
|
95
|
+
k,
|
|
96
|
+
onlyFailures: true
|
|
97
|
+
});
|
|
98
|
+
return failures.map(f => ({
|
|
99
|
+
critique: f.critique || this.extractCritique(f),
|
|
100
|
+
whatWentWrong: this.analyzeFailure(f),
|
|
101
|
+
howToFix: this.generateFixes(f),
|
|
102
|
+
similarFailures: failures.length
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract critique from failure pattern
|
|
107
|
+
*/
|
|
108
|
+
extractCritique(failure) {
|
|
109
|
+
if (failure.critique)
|
|
110
|
+
return failure.critique;
|
|
111
|
+
if (failure.task)
|
|
112
|
+
return `Failed at: ${failure.task}`;
|
|
113
|
+
return 'No critique available';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Analyze what went wrong in a failure
|
|
117
|
+
*/
|
|
118
|
+
analyzeFailure(failure) {
|
|
119
|
+
const issues = [];
|
|
120
|
+
if (failure.reward !== undefined && failure.reward < 0.3) {
|
|
121
|
+
issues.push('Low success rate observed');
|
|
122
|
+
}
|
|
123
|
+
if (failure.latencyMs && failure.latencyMs > 5000) {
|
|
124
|
+
issues.push('High latency detected');
|
|
125
|
+
}
|
|
126
|
+
if (failure.task) {
|
|
127
|
+
issues.push(`Task type: ${failure.task}`);
|
|
128
|
+
}
|
|
129
|
+
if (issues.length === 0) {
|
|
130
|
+
issues.push('General failure - review approach');
|
|
131
|
+
}
|
|
132
|
+
return issues;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Generate fix recommendations
|
|
136
|
+
*/
|
|
137
|
+
generateFixes(failure) {
|
|
138
|
+
const fixes = [];
|
|
139
|
+
// Look for successful patterns with similar tasks
|
|
140
|
+
fixes.push('Review similar successful patterns');
|
|
141
|
+
if (failure.latencyMs && failure.latencyMs > 5000) {
|
|
142
|
+
fixes.push('Optimize for lower latency');
|
|
143
|
+
}
|
|
144
|
+
if (failure.reward !== undefined && failure.reward < 0.3) {
|
|
145
|
+
fixes.push('Consider alternative approach');
|
|
146
|
+
}
|
|
147
|
+
fixes.push('Add more validation and error handling');
|
|
148
|
+
return fixes;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* What-if causal analysis
|
|
152
|
+
*
|
|
153
|
+
* Analyzes potential outcomes of taking an action based on causal evidence
|
|
154
|
+
*/
|
|
155
|
+
async whatIfAnalysis(action) {
|
|
156
|
+
const causalInsight = await this.reasoning.whatIfAnalysis(action);
|
|
157
|
+
// Generate impact description
|
|
158
|
+
let expectedImpact = '';
|
|
159
|
+
if (causalInsight.avgUplift > 0.2) {
|
|
160
|
+
expectedImpact = `Highly beneficial: Expected +${(causalInsight.avgUplift * 100).toFixed(1)}% improvement`;
|
|
161
|
+
}
|
|
162
|
+
else if (causalInsight.avgUplift > 0.1) {
|
|
163
|
+
expectedImpact = `Beneficial: Expected +${(causalInsight.avgUplift * 100).toFixed(1)}% improvement`;
|
|
164
|
+
}
|
|
165
|
+
else if (causalInsight.avgUplift > 0) {
|
|
166
|
+
expectedImpact = `Slightly positive: Expected +${(causalInsight.avgUplift * 100).toFixed(1)}% improvement`;
|
|
167
|
+
}
|
|
168
|
+
else if (causalInsight.avgUplift < -0.1) {
|
|
169
|
+
expectedImpact = `Harmful: Expected ${(causalInsight.avgUplift * 100).toFixed(1)}% degradation`;
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
expectedImpact = 'Neutral or insufficient evidence';
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
...causalInsight,
|
|
176
|
+
expectedImpact
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Compose multiple skills for a complex task
|
|
181
|
+
*
|
|
182
|
+
* Finds relevant skills and creates an execution plan
|
|
183
|
+
*/
|
|
184
|
+
async composeSkills(task, k = 5) {
|
|
185
|
+
const skills = await this.reasoning.searchSkills(task, k);
|
|
186
|
+
// Sort by success rate and usage
|
|
187
|
+
const sortedSkills = skills.sort((a, b) => {
|
|
188
|
+
const scoreA = (a.successRate || 0) * 0.7 + (Math.log(a.uses || 1) / 10) * 0.3;
|
|
189
|
+
const scoreB = (b.successRate || 0) * 0.7 + (Math.log(b.uses || 1) / 10) * 0.3;
|
|
190
|
+
return scoreB - scoreA;
|
|
191
|
+
});
|
|
192
|
+
// Create composition plan
|
|
193
|
+
let compositionPlan = '';
|
|
194
|
+
if (sortedSkills.length === 0) {
|
|
195
|
+
compositionPlan = 'No relevant skills found';
|
|
196
|
+
}
|
|
197
|
+
else if (sortedSkills.length === 1) {
|
|
198
|
+
compositionPlan = sortedSkills[0].name;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
compositionPlan = sortedSkills.slice(0, 3).map(s => s.name).join(' → ');
|
|
202
|
+
}
|
|
203
|
+
// Calculate expected success rate (weighted average)
|
|
204
|
+
let expectedSuccessRate = 0;
|
|
205
|
+
if (sortedSkills.length > 0) {
|
|
206
|
+
const weights = sortedSkills.map(s => s.uses || 1);
|
|
207
|
+
const totalWeight = weights.reduce((sum, w) => sum + w, 0);
|
|
208
|
+
expectedSuccessRate = sortedSkills.reduce((sum, s, i) => sum + (s.successRate || 0) * weights[i] / totalWeight, 0);
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
availableSkills: sortedSkills,
|
|
212
|
+
compositionPlan,
|
|
213
|
+
expectedSuccessRate
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Run automated learning cycle
|
|
218
|
+
*
|
|
219
|
+
* Discovers causal edges, consolidates skills, and optimizes performance
|
|
220
|
+
*/
|
|
221
|
+
async runLearningCycle() {
|
|
222
|
+
return this.autoConsolidate({
|
|
223
|
+
minUses: 3,
|
|
224
|
+
minSuccessRate: 0.7,
|
|
225
|
+
lookbackDays: 30,
|
|
226
|
+
dryRun: false
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Get comprehensive memory statistics
|
|
231
|
+
*/
|
|
232
|
+
getStats() {
|
|
233
|
+
return {
|
|
234
|
+
reasoningBank: this.reasoning.getStats(),
|
|
235
|
+
learner: 'NightlyLearner configured with auto-experiments',
|
|
236
|
+
memoryPool: this.pool.getStats()
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hybrid ReasoningBank Backend - Full Implementation for v1.7.1
|
|
3
|
+
*
|
|
4
|
+
* Combines Rust WASM (compute) + AgentDB TypeScript (storage) for optimal performance:
|
|
5
|
+
* - WASM: 10x faster similarity computation
|
|
6
|
+
* - AgentDB: Persistent SQLite storage with frontier memory
|
|
7
|
+
* - CausalRecall: Utility-based reranking with causal uplift
|
|
8
|
+
* - Automatic backend selection based on task requirements
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { HybridReasoningBank } from 'agentic-flow/reasoningbank';
|
|
13
|
+
*
|
|
14
|
+
* const rb = new HybridReasoningBank({ preferWasm: true });
|
|
15
|
+
* await rb.storePattern({ task: '...', success: true, reward: 0.95 });
|
|
16
|
+
* const patterns = await rb.retrievePatterns('similar task', { k: 5 });
|
|
17
|
+
* const strategy = await rb.learnStrategy('API optimization');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { SharedMemoryPool } from '../memory/SharedMemoryPool.js';
|
|
21
|
+
import { ReflexionMemory } from 'agentdb/controllers/ReflexionMemory';
|
|
22
|
+
import { SkillLibrary } from 'agentdb/controllers/SkillLibrary';
|
|
23
|
+
import { CausalRecall } from 'agentdb/controllers/CausalRecall';
|
|
24
|
+
import { CausalMemoryGraph } from 'agentdb/controllers/CausalMemoryGraph';
|
|
25
|
+
export class HybridReasoningBank {
|
|
26
|
+
memory;
|
|
27
|
+
reflexion;
|
|
28
|
+
skills;
|
|
29
|
+
causalRecall;
|
|
30
|
+
causalGraph;
|
|
31
|
+
useWasm;
|
|
32
|
+
wasmModule;
|
|
33
|
+
constructor(options = {}) {
|
|
34
|
+
this.memory = SharedMemoryPool.getInstance();
|
|
35
|
+
const db = this.memory.getDatabase();
|
|
36
|
+
const embedder = this.memory.getEmbedder();
|
|
37
|
+
this.reflexion = new ReflexionMemory(db, embedder);
|
|
38
|
+
this.skills = new SkillLibrary(db, embedder);
|
|
39
|
+
this.causalGraph = new CausalMemoryGraph(db);
|
|
40
|
+
// CausalRecall with optimized rerank config
|
|
41
|
+
this.causalRecall = new CausalRecall(db, embedder, {
|
|
42
|
+
alpha: 0.6, // 60% weight on similarity
|
|
43
|
+
beta: 0.3, // 30% weight on causal uplift
|
|
44
|
+
gamma: 0.1, // 10% penalty for latency
|
|
45
|
+
minConfidence: 0.7
|
|
46
|
+
});
|
|
47
|
+
this.useWasm = options.preferWasm ?? true;
|
|
48
|
+
this.wasmModule = null;
|
|
49
|
+
// Try to load WASM module
|
|
50
|
+
if (this.useWasm) {
|
|
51
|
+
this.loadWasmModule().catch(err => {
|
|
52
|
+
console.warn('[HybridReasoningBank] WASM unavailable, using TypeScript:', err.message);
|
|
53
|
+
this.useWasm = false;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async loadWasmModule() {
|
|
58
|
+
try {
|
|
59
|
+
// Dynamic import for WASM module
|
|
60
|
+
const wasm = await import('../../wasm/reasoningbank/reasoningbank_wasm.js');
|
|
61
|
+
this.wasmModule = wasm;
|
|
62
|
+
console.log('[HybridReasoningBank] WASM module loaded successfully');
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throw new Error(`WASM load failed: ${error}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Store a reasoning pattern
|
|
70
|
+
*/
|
|
71
|
+
async storePattern(pattern) {
|
|
72
|
+
const episodeId = await this.reflexion.storeEpisode(pattern);
|
|
73
|
+
// Store causal edge if action led to outcome
|
|
74
|
+
if (pattern.input && pattern.output && pattern.success) {
|
|
75
|
+
try {
|
|
76
|
+
this.causalGraph.addCausalEdge({
|
|
77
|
+
fromMemoryId: episodeId,
|
|
78
|
+
fromMemoryType: 'episode',
|
|
79
|
+
toMemoryId: episodeId + 1, // Next episode
|
|
80
|
+
toMemoryType: 'episode',
|
|
81
|
+
similarity: pattern.reward,
|
|
82
|
+
uplift: pattern.success ? pattern.reward : -pattern.reward,
|
|
83
|
+
confidence: 0.8,
|
|
84
|
+
sampleSize: 1,
|
|
85
|
+
metadata: {
|
|
86
|
+
sessionId: pattern.sessionId,
|
|
87
|
+
task: pattern.task
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
console.warn('[HybridReasoningBank] Failed to record causal edge:', error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return episodeId;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Retrieve similar patterns with optional WASM acceleration
|
|
99
|
+
*/
|
|
100
|
+
async retrievePatterns(query, options = {}) {
|
|
101
|
+
const { k = 5, minReward, onlySuccesses, onlyFailures } = options;
|
|
102
|
+
// Check cache first
|
|
103
|
+
const cacheKey = `retrieve:${query}:${k}:${onlySuccesses}:${onlyFailures}`;
|
|
104
|
+
const cached = this.memory.getCachedQuery(cacheKey);
|
|
105
|
+
if (cached)
|
|
106
|
+
return cached;
|
|
107
|
+
// Use CausalRecall for intelligent retrieval with utility-based ranking
|
|
108
|
+
try {
|
|
109
|
+
const result = await this.causalRecall.recall(`query-${Date.now()}`, query, k, undefined, // requirements
|
|
110
|
+
'public' // accessLevel
|
|
111
|
+
);
|
|
112
|
+
// Convert candidates to pattern format and filter
|
|
113
|
+
let patterns = result.candidates.map(c => ({
|
|
114
|
+
task: c.content,
|
|
115
|
+
similarity: c.similarity,
|
|
116
|
+
uplift: c.uplift || 0,
|
|
117
|
+
utilityScore: c.utilityScore,
|
|
118
|
+
type: c.type,
|
|
119
|
+
id: c.id
|
|
120
|
+
}));
|
|
121
|
+
// Apply filters
|
|
122
|
+
if (minReward !== undefined) {
|
|
123
|
+
patterns = patterns.filter(p => (p.uplift || 0) >= minReward);
|
|
124
|
+
}
|
|
125
|
+
// Cache and return
|
|
126
|
+
this.memory.cacheQuery(cacheKey, patterns, 60000);
|
|
127
|
+
return patterns;
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.warn('[HybridReasoningBank] CausalRecall failed, falling back to ReflexionMemory:', error);
|
|
131
|
+
// Fallback to basic ReflexionMemory
|
|
132
|
+
const results = await this.reflexion.retrieveRelevant({
|
|
133
|
+
task: query,
|
|
134
|
+
k,
|
|
135
|
+
minReward,
|
|
136
|
+
onlySuccesses,
|
|
137
|
+
onlyFailures
|
|
138
|
+
});
|
|
139
|
+
this.memory.cacheQuery(cacheKey, results, 60000);
|
|
140
|
+
return results;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Learn optimal strategy for a task
|
|
145
|
+
*
|
|
146
|
+
* Combines pattern retrieval with causal analysis to provide evidence-based recommendations
|
|
147
|
+
*/
|
|
148
|
+
async learnStrategy(task) {
|
|
149
|
+
// Get successful patterns
|
|
150
|
+
const patterns = await this.retrievePatterns(task, { k: 10, onlySuccesses: true });
|
|
151
|
+
// Get causal effects for this task type
|
|
152
|
+
let causalData;
|
|
153
|
+
try {
|
|
154
|
+
// Note: queryCausalEffects requires specific memory IDs
|
|
155
|
+
// For task-level analysis, we'll use pattern success rates instead
|
|
156
|
+
const stats = await this.reflexion.getTaskStats(task, 30);
|
|
157
|
+
if (stats.totalAttempts > 0) {
|
|
158
|
+
causalData = {
|
|
159
|
+
action: task,
|
|
160
|
+
avgReward: stats.avgReward || 0,
|
|
161
|
+
avgUplift: stats.improvementTrend || 0,
|
|
162
|
+
confidence: Math.min(stats.totalAttempts / 10, 1.0),
|
|
163
|
+
evidenceCount: stats.totalAttempts,
|
|
164
|
+
recommendation: (stats.improvementTrend || 0) > 0.1 ? 'DO_IT' :
|
|
165
|
+
(stats.improvementTrend || 0) < -0.1 ? 'AVOID' : 'NEUTRAL'
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
console.warn('[HybridReasoningBank] Causal analysis failed:', error);
|
|
171
|
+
}
|
|
172
|
+
// Fallback if no causal data
|
|
173
|
+
if (!causalData) {
|
|
174
|
+
causalData = {
|
|
175
|
+
action: task,
|
|
176
|
+
avgReward: patterns.length > 0 ? (patterns[0].reward || 0) : 0,
|
|
177
|
+
avgUplift: 0,
|
|
178
|
+
confidence: patterns.length > 0 ? 0.6 : 0.3,
|
|
179
|
+
evidenceCount: patterns.length,
|
|
180
|
+
recommendation: patterns.length > 0 ? 'DO_IT' : 'NEUTRAL'
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
// Calculate overall confidence
|
|
184
|
+
const patternConf = Math.min(patterns.length / 10, 1.0); // 10+ patterns = full confidence
|
|
185
|
+
const causalConf = causalData.confidence;
|
|
186
|
+
const confidence = 0.6 * patternConf + 0.4 * causalConf;
|
|
187
|
+
// Generate recommendation
|
|
188
|
+
let recommendation = '';
|
|
189
|
+
if (confidence > 0.8 && causalData.avgUplift > 0.1) {
|
|
190
|
+
recommendation = `Strong evidence for success (${patterns.length} patterns, +${(causalData.avgUplift * 100).toFixed(1)}% uplift)`;
|
|
191
|
+
}
|
|
192
|
+
else if (confidence > 0.5) {
|
|
193
|
+
recommendation = `Moderate evidence (${patterns.length} patterns available)`;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
recommendation = `Limited evidence - proceed with caution`;
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
patterns,
|
|
200
|
+
causality: causalData,
|
|
201
|
+
confidence,
|
|
202
|
+
recommendation
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Auto-consolidate patterns into skills
|
|
207
|
+
*/
|
|
208
|
+
async autoConsolidate(minUses = 3, minSuccessRate = 0.7, lookbackDays = 30) {
|
|
209
|
+
// Get task statistics
|
|
210
|
+
const stats = await this.reflexion.getTaskStats('', lookbackDays);
|
|
211
|
+
if (stats.totalAttempts < minUses || stats.successRate < minSuccessRate) {
|
|
212
|
+
return { skillsCreated: 0 };
|
|
213
|
+
}
|
|
214
|
+
// Get successful episodes for consolidation
|
|
215
|
+
const episodes = await this.reflexion.retrieveRelevant({
|
|
216
|
+
task: '',
|
|
217
|
+
k: 50,
|
|
218
|
+
onlySuccesses: true,
|
|
219
|
+
timeWindowDays: lookbackDays
|
|
220
|
+
});
|
|
221
|
+
// Group by task type and consolidate
|
|
222
|
+
const taskGroups = new Map();
|
|
223
|
+
episodes.forEach(ep => {
|
|
224
|
+
const group = taskGroups.get(ep.task) || [];
|
|
225
|
+
group.push(ep);
|
|
226
|
+
taskGroups.set(ep.task, group);
|
|
227
|
+
});
|
|
228
|
+
let skillsCreated = 0;
|
|
229
|
+
for (const [task, group] of taskGroups) {
|
|
230
|
+
if (group.length >= minUses) {
|
|
231
|
+
const successRate = group.filter(e => e.success).length / group.length;
|
|
232
|
+
if (successRate >= minSuccessRate) {
|
|
233
|
+
await this.skills.createSkill({
|
|
234
|
+
name: `skill_${task.replace(/\s+/g, '_').toLowerCase()}`,
|
|
235
|
+
description: `Consolidated from ${group.length} successful episodes`,
|
|
236
|
+
signature: { inputs: {}, outputs: {} },
|
|
237
|
+
successRate,
|
|
238
|
+
uses: group.length,
|
|
239
|
+
avgReward: group.reduce((sum, e) => sum + e.reward, 0) / group.length,
|
|
240
|
+
avgLatencyMs: group.reduce((sum, e) => sum + (e.latencyMs || 0), 0) / group.length,
|
|
241
|
+
metadata: { consolidatedAt: Date.now(), taskType: task }
|
|
242
|
+
});
|
|
243
|
+
skillsCreated++;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return { skillsCreated };
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* What-if causal analysis
|
|
251
|
+
*/
|
|
252
|
+
async whatIfAnalysis(action) {
|
|
253
|
+
try {
|
|
254
|
+
// Use task statistics for what-if analysis
|
|
255
|
+
const stats = await this.reflexion.getTaskStats(action, 30);
|
|
256
|
+
if (stats.totalAttempts === 0) {
|
|
257
|
+
return {
|
|
258
|
+
action,
|
|
259
|
+
avgReward: 0,
|
|
260
|
+
avgUplift: 0,
|
|
261
|
+
confidence: 0,
|
|
262
|
+
evidenceCount: 0,
|
|
263
|
+
recommendation: 'NEUTRAL'
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
const avgUplift = stats.improvementTrend || 0;
|
|
267
|
+
const confidence = Math.min(stats.totalAttempts / 10, 1.0);
|
|
268
|
+
return {
|
|
269
|
+
action,
|
|
270
|
+
avgReward: stats.avgReward || 0,
|
|
271
|
+
avgUplift,
|
|
272
|
+
confidence,
|
|
273
|
+
evidenceCount: stats.totalAttempts,
|
|
274
|
+
recommendation: avgUplift > 0.1 ? 'DO_IT' : avgUplift < -0.1 ? 'AVOID' : 'NEUTRAL'
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
console.error('[HybridReasoningBank] What-if analysis failed:', error);
|
|
279
|
+
return {
|
|
280
|
+
action,
|
|
281
|
+
avgReward: 0,
|
|
282
|
+
avgUplift: 0,
|
|
283
|
+
confidence: 0,
|
|
284
|
+
evidenceCount: 0,
|
|
285
|
+
recommendation: 'NEUTRAL'
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Search for relevant skills
|
|
291
|
+
*/
|
|
292
|
+
async searchSkills(taskType, k = 5) {
|
|
293
|
+
return this.skills.searchSkills({ task: taskType, k, minSuccessRate: 0.5 });
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get statistics
|
|
297
|
+
*/
|
|
298
|
+
getStats() {
|
|
299
|
+
return {
|
|
300
|
+
causalRecall: this.causalRecall.getStats(),
|
|
301
|
+
reflexion: {}, // ReflexionMemory doesn't expose global stats
|
|
302
|
+
skills: 0 // Would need to query database
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReasoningBank - Closed-loop memory system for AI agents
|
|
3
|
+
* Based on arXiv:2509.25140 (Google DeepMind)
|
|
4
|
+
*
|
|
5
|
+
* @since v1.7.0 - Integrated AgentDB for optimal performance
|
|
6
|
+
*/
|
|
7
|
+
// New hybrid backend (recommended for new code)
|
|
8
|
+
export { HybridReasoningBank } from './HybridBackend.js';
|
|
9
|
+
export { AdvancedMemorySystem } from './AdvancedMemory.js';
|
|
10
|
+
// Re-export AgentDB controllers for advanced usage
|
|
11
|
+
export { ReflexionMemory } from 'agentdb/controllers/ReflexionMemory';
|
|
12
|
+
export { SkillLibrary } from 'agentdb/controllers/SkillLibrary';
|
|
13
|
+
export { CausalMemoryGraph } from 'agentdb/controllers/CausalMemoryGraph';
|
|
14
|
+
export { CausalRecall } from 'agentdb/controllers/CausalRecall';
|
|
15
|
+
export { NightlyLearner } from 'agentdb/controllers/NightlyLearner';
|
|
16
|
+
export { EmbeddingService } from 'agentdb/controllers/EmbeddingService';
|
|
17
|
+
// Original ReasoningBank implementations (backwards compatibility)
|
|
18
|
+
export { retrieveMemories, formatMemoriesForPrompt } from './core/retrieve.js';
|
|
19
|
+
export { judgeTrajectory } from './core/judge.js';
|
|
20
|
+
export { distillMemories } from './core/distill.js';
|
|
21
|
+
export { consolidate, shouldConsolidate } from './core/consolidate.js';
|
|
22
|
+
export { mattsParallel, mattsSequential } from './core/matts.js';
|
|
23
|
+
export { computeEmbedding, clearEmbeddingCache } from './utils/embeddings.js';
|
|
24
|
+
export { mmrSelection, cosineSimilarity } from './utils/mmr.js';
|
|
25
|
+
export { scrubPII, containsPII, scrubMemory } from './utils/pii-scrubber.js';
|
|
26
|
+
export { loadConfig } from './utils/config.js';
|
|
27
|
+
// Re-export database utilities
|
|
28
|
+
import * as db from './db/queries.js';
|
|
29
|
+
export { db };
|
|
30
|
+
// Original functions (backwards compatibility)
|
|
31
|
+
import { loadConfig } from './utils/config.js';
|
|
32
|
+
import { retrieveMemories } from './core/retrieve.js';
|
|
33
|
+
import { judgeTrajectory } from './core/judge.js';
|
|
34
|
+
import { distillMemories } from './core/distill.js';
|
|
35
|
+
import { shouldConsolidate as shouldCons, consolidate as cons } from './core/consolidate.js';
|
|
36
|
+
export async function initialize() {
|
|
37
|
+
const config = loadConfig();
|
|
38
|
+
console.log('[ReasoningBank] Initializing...');
|
|
39
|
+
console.log(`[ReasoningBank] Enabled: ${!!process.env.REASONINGBANK_ENABLED}`);
|
|
40
|
+
console.log(`[ReasoningBank] Database: ${process.env.CLAUDE_FLOW_DB_PATH || '.swarm/memory.db'}`);
|
|
41
|
+
console.log(`[ReasoningBank] Embeddings: ${config.embeddings.provider}`);
|
|
42
|
+
console.log(`[ReasoningBank] Retrieval k: ${config.retrieve.k}`);
|
|
43
|
+
try {
|
|
44
|
+
await db.runMigrations();
|
|
45
|
+
console.log(`[ReasoningBank] Database migrated successfully`);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('[ReasoningBank] Migration error:', error);
|
|
49
|
+
throw new Error('ReasoningBank initialization failed: could not run migrations');
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const dbConn = db.getDb();
|
|
53
|
+
const tables = dbConn.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'pattern%'").all();
|
|
54
|
+
console.log(`[ReasoningBank] Database OK: ${tables.length} tables found`);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('[ReasoningBank] Database error:', error);
|
|
58
|
+
throw new Error('ReasoningBank initialization failed: database not accessible');
|
|
59
|
+
}
|
|
60
|
+
console.log('[ReasoningBank] Initialization complete');
|
|
61
|
+
}
|
|
62
|
+
export async function runTask(options) {
|
|
63
|
+
console.log(`[ReasoningBank] Running task: ${options.taskId}`);
|
|
64
|
+
const memories = await retrieveMemories(options.query, {
|
|
65
|
+
domain: options.domain,
|
|
66
|
+
agent: options.agentId
|
|
67
|
+
});
|
|
68
|
+
console.log(`[ReasoningBank] Retrieved ${memories.length} memories`);
|
|
69
|
+
const trajectory = await options.executeFn(memories);
|
|
70
|
+
const verdict = await judgeTrajectory(trajectory, options.query);
|
|
71
|
+
console.log(`[ReasoningBank] Verdict: ${verdict.label} (${verdict.confidence})`);
|
|
72
|
+
const newMemories = await distillMemories(trajectory, verdict, options.query, {
|
|
73
|
+
taskId: options.taskId,
|
|
74
|
+
agentId: options.agentId,
|
|
75
|
+
domain: options.domain
|
|
76
|
+
});
|
|
77
|
+
console.log(`[ReasoningBank] Distilled ${newMemories.length} new memories`);
|
|
78
|
+
let consolidated = false;
|
|
79
|
+
if (shouldCons()) {
|
|
80
|
+
console.log('[ReasoningBank] Running consolidation...');
|
|
81
|
+
await cons();
|
|
82
|
+
consolidated = true;
|
|
83
|
+
}
|
|
84
|
+
return { verdict, usedMemories: memories, newMemories, consolidated };
|
|
85
|
+
}
|
|
86
|
+
export const VERSION = '1.7.0';
|
|
87
|
+
export const PAPER_URL = 'https://arxiv.org/html/2509.25140v1';
|
|
@@ -99,10 +99,6 @@ export async function runTask(options) {
|
|
|
99
99
|
consolidated
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
-
// AgentDB Integration
|
|
103
|
-
// Ultra-fast vector database drop-in replacement
|
|
104
|
-
// 150x-12,500x faster than legacy implementation
|
|
105
|
-
export { createAgentDBAdapter, createDefaultAgentDBAdapter, migrateToAgentDB, validateMigration } from './agentdb-adapter.js';
|
|
106
102
|
// Version info
|
|
107
103
|
export const VERSION = '1.0.0';
|
|
108
104
|
export const PAPER_URL = 'https://arxiv.org/html/2509.25140v1';
|
package/dist/utils/cli.js
CHANGED
|
@@ -49,11 +49,6 @@ export function parseArgs() {
|
|
|
49
49
|
options.mode = 'reasoningbank';
|
|
50
50
|
return options;
|
|
51
51
|
}
|
|
52
|
-
// Check for agentdb command
|
|
53
|
-
if (args[0] === 'agentdb') {
|
|
54
|
-
options.mode = 'agentdb';
|
|
55
|
-
return options;
|
|
56
|
-
}
|
|
57
52
|
for (let i = 0; i < args.length; i++) {
|
|
58
53
|
const arg = args[i];
|
|
59
54
|
switch (arg) {
|