agentic-flow 1.4.6 → 1.4.8

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.
@@ -0,0 +1,335 @@
1
+ /**
2
+ * ReasoningBank Memory Engine
3
+ * Implements the 4-phase learning loop: RETRIEVE → JUDGE → DISTILL → CONSOLIDATE
4
+ */
5
+ import { ReasoningBankDB } from './database.js';
6
+ import { createEmbeddingProvider, cosineSimilarity } from '../utils/embeddings.js';
7
+ import { piiScrubber } from '../utils/pii-scrubber.js';
8
+ export class ReasoningBankEngine {
9
+ db;
10
+ embeddings;
11
+ piiEnabled;
12
+ weights;
13
+ defaultK;
14
+ minConfidence;
15
+ consolidationThreshold;
16
+ memoriesSinceConsolidation = 0;
17
+ constructor(config) {
18
+ this.db = new ReasoningBankDB(config.dbPath);
19
+ this.embeddings = createEmbeddingProvider(config.embeddings?.provider || 'hash', {
20
+ apiKey: process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY,
21
+ model: config.embeddings?.model
22
+ });
23
+ this.piiEnabled = config.piiScrub?.enabled !== false;
24
+ this.weights = {
25
+ alpha: config.retrieval?.weights?.alpha || 0.65, // Similarity
26
+ beta: config.retrieval?.weights?.beta || 0.15, // Recency
27
+ gamma: config.retrieval?.weights?.gamma || 0.20, // Reliability
28
+ delta: config.retrieval?.weights?.delta || 0.10 // Diversity penalty
29
+ };
30
+ this.defaultK = config.retrieval?.k || 3;
31
+ this.minConfidence = config.retrieval?.minConfidence || 0.3;
32
+ this.consolidationThreshold = config.consolidation?.scheduleEvery || 20;
33
+ }
34
+ /**
35
+ * Phase 1: RETRIEVE - Get relevant memories using 4-factor scoring
36
+ */
37
+ async retrieve(options) {
38
+ const k = options.k || this.defaultK;
39
+ const lambda = options.lambda || 0.9;
40
+ // Generate query embedding
41
+ const queryEmbedding = await this.embeddings.generate(options.query);
42
+ // Get all memories
43
+ const allMemories = this.db.getAllMemories();
44
+ const embeddings = this.db.getAllEmbeddings();
45
+ // Filter by domain if specified
46
+ let candidates = allMemories;
47
+ if (options.domain) {
48
+ candidates = candidates.filter(m => m.pattern_data.domain === options.domain ||
49
+ m.pattern_data.domain?.startsWith(options.domain + '.'));
50
+ }
51
+ // Calculate scores for each candidate
52
+ const scoredCandidates = [];
53
+ for (const memory of candidates) {
54
+ const embedding = embeddings.get(memory.id);
55
+ if (!embedding)
56
+ continue;
57
+ // 1. Similarity score (cosine similarity)
58
+ const similarity = cosineSimilarity(queryEmbedding, embedding);
59
+ // 2. Recency score (exponential decay, 30-day half-life)
60
+ const ageDays = (Date.now() - new Date(memory.created_at).getTime()) / (1000 * 60 * 60 * 24);
61
+ const recency = Math.exp(-ageDays / 30);
62
+ // 3. Reliability score (confidence × sqrt(usage/10))
63
+ const reliability = Math.min(memory.confidence * Math.sqrt(memory.usage_count / 10), 1.0);
64
+ // Combined score (before diversity penalty)
65
+ const score = this.weights.alpha * similarity +
66
+ this.weights.beta * recency +
67
+ this.weights.gamma * reliability;
68
+ scoredCandidates.push({
69
+ ...memory,
70
+ score,
71
+ similarity,
72
+ recency,
73
+ reliability,
74
+ diversityPenalty: 0 // Will be calculated in MMR
75
+ });
76
+ }
77
+ // Sort by score
78
+ scoredCandidates.sort((a, b) => b.score - a.score);
79
+ // Apply MMR for diversity
80
+ const selected = this.selectWithMMR(scoredCandidates, queryEmbedding, k, lambda);
81
+ // Update usage counts
82
+ for (const memory of selected) {
83
+ this.db.updateMemoryUsage(memory.id);
84
+ }
85
+ // Filter by minimum confidence
86
+ return selected.filter(m => m.confidence >= this.minConfidence);
87
+ }
88
+ /**
89
+ * MMR (Maximal Marginal Relevance) Selection
90
+ * Balances relevance and diversity
91
+ */
92
+ selectWithMMR(candidates, queryEmbedding, k, lambda) {
93
+ const selected = [];
94
+ const remaining = [...candidates];
95
+ const embeddings = this.db.getAllEmbeddings();
96
+ while (selected.length < k && remaining.length > 0) {
97
+ let bestScore = -Infinity;
98
+ let bestIndex = -1;
99
+ for (let i = 0; i < remaining.length; i++) {
100
+ const candidate = remaining[i];
101
+ const candidateEmbedding = embeddings.get(candidate.id);
102
+ if (!candidateEmbedding)
103
+ continue;
104
+ // Relevance to query
105
+ const relevance = candidate.score;
106
+ // Maximum similarity to already selected
107
+ let maxSimilarity = 0;
108
+ if (selected.length > 0) {
109
+ for (const selectedMemory of selected) {
110
+ const selectedEmbedding = embeddings.get(selectedMemory.id);
111
+ if (selectedEmbedding) {
112
+ const sim = cosineSimilarity(candidateEmbedding, selectedEmbedding);
113
+ maxSimilarity = Math.max(maxSimilarity, sim);
114
+ }
115
+ }
116
+ }
117
+ // MMR score
118
+ const mmrScore = lambda * relevance - (1 - lambda) * maxSimilarity;
119
+ if (mmrScore > bestScore) {
120
+ bestScore = mmrScore;
121
+ bestIndex = i;
122
+ }
123
+ }
124
+ if (bestIndex >= 0) {
125
+ selected.push(remaining[bestIndex]);
126
+ remaining.splice(bestIndex, 1);
127
+ }
128
+ else {
129
+ break;
130
+ }
131
+ }
132
+ return selected;
133
+ }
134
+ /**
135
+ * Phase 2: JUDGE - Evaluate task outcome
136
+ */
137
+ async judge(trajectory) {
138
+ // Simple heuristic judge (can be upgraded to LLM)
139
+ const scrubbed = this.piiEnabled ? piiScrubber.scrub(trajectory) : trajectory;
140
+ // Heuristics for success/failure
141
+ const errorKeywords = ['error', 'failed', 'exception', 'timeout', 'unauthorized', 'forbidden'];
142
+ const successKeywords = ['success', 'completed', 'ok', '200', 'done'];
143
+ const lowerTrajectory = scrubbed.toLowerCase();
144
+ const hasError = errorKeywords.some(kw => lowerTrajectory.includes(kw));
145
+ const hasSuccess = successKeywords.some(kw => lowerTrajectory.includes(kw));
146
+ if (hasSuccess && !hasError) {
147
+ return { label: 'Success', confidence: 0.8, rationale: 'Success keywords found' };
148
+ }
149
+ else if (hasError && !hasSuccess) {
150
+ return { label: 'Failure', confidence: 0.8, rationale: 'Error keywords found' };
151
+ }
152
+ else if (hasSuccess && hasError) {
153
+ return { label: 'Success', confidence: 0.5, rationale: 'Mixed signals' };
154
+ }
155
+ else {
156
+ return { label: 'Failure', confidence: 0.5, rationale: 'No clear indicators' };
157
+ }
158
+ }
159
+ /**
160
+ * Phase 3: DISTILL - Extract patterns from trajectory
161
+ */
162
+ async distill(taskId, trajectory, verdict, domain) {
163
+ const scrubbed = this.piiEnabled ? piiScrubber.scrub(trajectory) : trajectory;
164
+ // Store trajectory
165
+ this.db.insertTrajectory({
166
+ task_id: taskId,
167
+ trajectory: scrubbed,
168
+ verdict: verdict.label,
169
+ confidence: verdict.confidence
170
+ });
171
+ // Extract pattern based on verdict
172
+ const pattern = verdict.label === 'Success'
173
+ ? this.extractSuccessPattern(scrubbed, domain)
174
+ : this.extractFailureGuardrail(scrubbed, domain);
175
+ // Store as memory
176
+ const memoryId = this.db.insertMemory({
177
+ title: pattern.title,
178
+ description: pattern.description,
179
+ content: pattern.content,
180
+ confidence: verdict.confidence,
181
+ usage_count: 0,
182
+ pattern_data: {
183
+ domain,
184
+ success_pattern: verdict.label === 'Success',
185
+ failure_guardrail: verdict.label === 'Failure'
186
+ }
187
+ });
188
+ // Generate and store embedding
189
+ const embedding = await this.embeddings.generate(pattern.content);
190
+ this.db.insertEmbedding(memoryId, embedding);
191
+ this.memoriesSinceConsolidation++;
192
+ return memoryId;
193
+ }
194
+ extractSuccessPattern(trajectory, domain) {
195
+ // Extract key steps from successful execution
196
+ const lines = trajectory.split('\n').filter(l => l.trim());
197
+ const keySteps = lines.slice(0, 5).join('\n');
198
+ return {
199
+ title: `Success pattern for ${domain}`,
200
+ description: `Successful execution strategy`,
201
+ content: `Successful approach:\n${keySteps}`
202
+ };
203
+ }
204
+ extractFailureGuardrail(trajectory, domain) {
205
+ // Extract error information
206
+ const lines = trajectory.split('\n').filter(l => l.trim());
207
+ const errorInfo = lines.find(l => l.toLowerCase().includes('error') ||
208
+ l.toLowerCase().includes('failed')) || 'Unknown error';
209
+ return {
210
+ title: `Failure guardrail for ${domain}`,
211
+ description: `Prevention strategy for common failures`,
212
+ content: `Avoid: ${errorInfo}\nRecommend: Check prerequisites and retry with backoff`
213
+ };
214
+ }
215
+ /**
216
+ * Phase 4: CONSOLIDATE - Deduplicate and prune
217
+ */
218
+ async consolidate(options) {
219
+ const startTime = Date.now();
220
+ const dedupeThreshold = options?.dedupeThreshold || 0.95;
221
+ const maxAgeDays = options?.prune?.maxAgeDays || 90;
222
+ const minConfidence = options?.prune?.minConfidence || 0.3;
223
+ const unusedDays = options?.prune?.unusedDays || 30;
224
+ // Find and merge duplicates
225
+ const duplicates = this.db.findDuplicates(dedupeThreshold);
226
+ for (const [id1, id2] of duplicates) {
227
+ const mem1 = this.db.getMemory(id1);
228
+ const mem2 = this.db.getMemory(id2);
229
+ if (mem1 && mem2) {
230
+ // Keep the one with higher confidence and usage
231
+ const keepId = mem1.confidence > mem2.confidence ||
232
+ (mem1.confidence === mem2.confidence && mem1.usage_count > mem2.usage_count)
233
+ ? id1 : id2;
234
+ const deleteId = keepId === id1 ? id2 : id1;
235
+ this.db.deleteMemory(deleteId);
236
+ }
237
+ }
238
+ // Prune old or low-quality memories
239
+ const allMemories = this.db.getAllMemories();
240
+ let pruned = 0;
241
+ for (const memory of allMemories) {
242
+ const ageDays = (Date.now() - new Date(memory.created_at).getTime()) / (1000 * 60 * 60 * 24);
243
+ const lastUsedDays = ageDays; // Simplified: assume last used = created
244
+ const shouldPrune = ageDays > maxAgeDays ||
245
+ memory.confidence < minConfidence ||
246
+ (memory.usage_count === 0 && lastUsedDays > unusedDays);
247
+ if (shouldPrune) {
248
+ this.db.deleteMemory(memory.id);
249
+ pruned++;
250
+ }
251
+ }
252
+ // Detect contradictions (simplified)
253
+ const contradictions = 0; // TODO: Implement semantic contradiction detection
254
+ this.memoriesSinceConsolidation = 0;
255
+ return {
256
+ processed: allMemories.length,
257
+ duplicates: duplicates.length,
258
+ contradictions,
259
+ pruned,
260
+ durationMs: Date.now() - startTime
261
+ };
262
+ }
263
+ /**
264
+ * High-level task execution with full learning loop
265
+ */
266
+ async runTask(options) {
267
+ // Phase 1: RETRIEVE
268
+ const memories = await this.retrieve({
269
+ query: options.query,
270
+ domain: options.domain
271
+ });
272
+ // EXECUTE
273
+ const result = await options.executeFn(memories);
274
+ // Phase 2: JUDGE
275
+ const verdict = await this.judge(result.log);
276
+ // Phase 3: DISTILL
277
+ await this.distill(options.taskId, result.log, verdict, options.domain);
278
+ // Phase 4: CONSOLIDATE (if threshold reached)
279
+ if (this.memoriesSinceConsolidation >= this.consolidationThreshold) {
280
+ await this.consolidate();
281
+ }
282
+ return {
283
+ success: result.success,
284
+ summary: `Task ${options.taskId}: ${verdict.label} (confidence: ${verdict.confidence})`,
285
+ memories,
286
+ verdict
287
+ };
288
+ }
289
+ /**
290
+ * MaTTS: Memory-aware Test-Time Scaling (Parallel)
291
+ */
292
+ async mattsParallel(options) {
293
+ const runs = await Promise.all(Array.from({ length: options.k }, async (_, i) => {
294
+ const memories = await this.retrieve({
295
+ query: options.query,
296
+ domain: options.domain
297
+ });
298
+ const result = await options.executeFn(memories);
299
+ const verdict = await this.judge(result.log);
300
+ this.db.insertMattsRun({
301
+ task_id: options.taskId,
302
+ run_index: i,
303
+ result: result.log,
304
+ verdict: verdict.label,
305
+ confidence: verdict.confidence
306
+ });
307
+ return { result, verdict };
308
+ }));
309
+ // Calculate consensus
310
+ const successes = runs.filter(r => r.verdict.label === 'Success').length;
311
+ const avgConfidence = runs.reduce((sum, r) => sum + r.verdict.confidence, 0) / runs.length;
312
+ const consensusVerdict = {
313
+ label: successes > runs.length / 2 ? 'Success' : 'Failure',
314
+ confidence: avgConfidence
315
+ };
316
+ return {
317
+ success: consensusVerdict.label === 'Success',
318
+ summary: `MaTTS Parallel: ${successes}/${runs.length} successes, consensus: ${consensusVerdict.label}`,
319
+ memories: [],
320
+ verdict: consensusVerdict
321
+ };
322
+ }
323
+ /**
324
+ * Get statistics
325
+ */
326
+ getStats() {
327
+ return this.db.getStats();
328
+ }
329
+ /**
330
+ * Close database connection
331
+ */
332
+ close() {
333
+ this.db.close();
334
+ }
335
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * ReasoningBank Type Definitions
3
+ * Based on arXiv:2509.25140 (Google DeepMind)
4
+ */
5
+ export {};
@@ -1,58 +1,57 @@
1
- // ReasoningBank CLI command handlers
1
+ /**
2
+ * ReasoningBank CLI Commands
3
+ * Handles demo, test, init, benchmark, status, consolidate, list
4
+ */
2
5
  import { spawn } from 'child_process';
3
- import { resolve } from 'path';
6
+ import { join } from 'path';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname } from 'path';
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
4
11
  export async function handleReasoningBankCommand(subcommand) {
5
- const rbPath = resolve(process.cwd(), 'src/reasoningbank');
6
- switch (subcommand) {
7
- case 'demo':
8
- console.log('\n🎯 Running ReasoningBank Demo Comparison...\n');
9
- console.log('This demo shows ReasoningBank learning from experience:');
10
- console.log('• Traditional: 0% success, repeats mistakes');
11
- console.log('• ReasoningBank: 100% success, learns & improves\n');
12
- await runScript(`${rbPath}/demo-comparison.ts`);
13
- break;
14
- case 'test':
15
- console.log('\n🧪 Running ReasoningBank Validation Tests...\n');
16
- await runScript(`${rbPath}/test-validation.ts`);
17
- console.log('\n');
18
- await runScript(`${rbPath}/test-retrieval.ts`);
19
- console.log('\n');
20
- await runScript(`${rbPath}/test-integration.ts`);
21
- break;
22
- case 'init':
23
- console.log('\n📦 Initializing ReasoningBank Database...\n');
24
- console.log('Creating memory database at .swarm/memory.db\n');
25
- await runBashCommand('mkdir -p .swarm');
26
- await runBashCommand('sqlite3 .swarm/memory.db < src/reasoningbank/migrations/000_base_schema.sql');
27
- await runBashCommand('sqlite3 .swarm/memory.db < src/reasoningbank/migrations/001_reasoningbank_schema.sql');
28
- console.log('✅ ReasoningBank database initialized!\n');
29
- break;
30
- case 'benchmark':
31
- console.log('\n⚡ Running ReasoningBank Performance Benchmarks...\n');
32
- await runScript(`${rbPath}/benchmark.ts`);
33
- break;
34
- case 'status':
35
- console.log('\n📊 ReasoningBank Memory Statistics\n');
36
- await runBashCommand(`sqlite3 .swarm/memory.db "SELECT
37
- (SELECT COUNT(*) FROM reasoning_memory) as total_memories,
38
- (SELECT COUNT(*) FROM reasoning_memory WHERE confidence > 0.7) as high_confidence,
39
- (SELECT COUNT(*) FROM task_trajectory) as total_tasks,
40
- (SELECT AVG(confidence) FROM reasoning_memory) as avg_confidence;"`);
41
- console.log('\n');
42
- break;
43
- case 'help':
44
- default:
45
- printReasoningBankHelp();
46
- break;
12
+ const args = process.argv.slice(4); // Get args after 'reasoningbank <subcommand>'
13
+ try {
14
+ switch (subcommand) {
15
+ case 'demo':
16
+ await runExternalScript('../reasoningbank/demo-comparison.js');
17
+ break;
18
+ case 'test':
19
+ await runExternalScript('../reasoningbank/test-validation.js');
20
+ break;
21
+ case 'init':
22
+ await initDatabase();
23
+ break;
24
+ case 'benchmark':
25
+ await runExternalScript('../reasoningbank/benchmark.js');
26
+ break;
27
+ case 'status':
28
+ await showStatus();
29
+ break;
30
+ case 'consolidate':
31
+ await runConsolidation();
32
+ break;
33
+ case 'list':
34
+ await listMemories(args);
35
+ break;
36
+ case 'help':
37
+ default:
38
+ printHelp();
39
+ break;
40
+ }
41
+ }
42
+ catch (error) {
43
+ console.error(`\n❌ Error: ${error instanceof Error ? error.message : String(error)}\n`);
44
+ process.exit(1);
47
45
  }
48
46
  }
49
- async function runScript(scriptPath) {
47
+ async function runExternalScript(relativePath) {
48
+ const scriptPath = join(__dirname, relativePath);
50
49
  return new Promise((resolve, reject) => {
51
- const proc = spawn('npx', ['tsx', scriptPath], {
50
+ const child = spawn('node', [scriptPath], {
52
51
  stdio: 'inherit',
53
- shell: true
52
+ cwd: process.cwd()
54
53
  });
55
- proc.on('close', (code) => {
54
+ child.on('exit', (code) => {
56
55
  if (code === 0) {
57
56
  resolve();
58
57
  }
@@ -60,77 +59,145 @@ async function runScript(scriptPath) {
60
59
  reject(new Error(`Script exited with code ${code}`));
61
60
  }
62
61
  });
63
- proc.on('error', (err) => {
64
- reject(err);
62
+ child.on('error', (error) => {
63
+ reject(error);
65
64
  });
66
65
  });
67
66
  }
68
- async function runBashCommand(command) {
69
- return new Promise((resolve, reject) => {
70
- const proc = spawn(command, {
71
- stdio: 'inherit',
72
- shell: true
73
- });
74
- proc.on('close', (code) => {
75
- if (code === 0) {
76
- resolve();
77
- }
78
- else {
79
- reject(new Error(`Command exited with code ${code}`));
80
- }
81
- });
82
- proc.on('error', (err) => {
83
- reject(err);
84
- });
85
- });
67
+ async function initDatabase() {
68
+ console.log('\n🔧 Initializing ReasoningBank Database');
69
+ console.log('═'.repeat(50));
70
+ const { initialize } = await import('../reasoningbank/index.js');
71
+ console.log('\nInitializing database with migrations...\n');
72
+ await initialize();
73
+ console.log('\n✅ Database initialized successfully!');
74
+ console.log('\nSchema created:');
75
+ console.log(' • patterns (reasoning memories)');
76
+ console.log(' • pattern_embeddings');
77
+ console.log(' • pattern_links');
78
+ console.log(' • task_trajectories');
79
+ console.log(' • matts_runs');
80
+ console.log(' • consolidation_runs');
81
+ console.log(' • metrics_log\n');
82
+ }
83
+ async function showStatus() {
84
+ console.log('\n📊 ReasoningBank Status');
85
+ console.log('═'.repeat(50));
86
+ const { db } = await import('../reasoningbank/index.js');
87
+ const dbInstance = db.getDb();
88
+ const stats = {
89
+ totalMemories: dbInstance.prepare("SELECT COUNT(*) as count FROM patterns WHERE type = 'reasoning_memory'").get(),
90
+ avgConfidence: dbInstance.prepare("SELECT AVG(confidence) as avg FROM patterns WHERE type = 'reasoning_memory'").get(),
91
+ totalEmbeddings: dbInstance.prepare('SELECT COUNT(*) as count FROM pattern_embeddings').get(),
92
+ totalTrajectories: dbInstance.prepare('SELECT COUNT(*) as count FROM task_trajectories').get()
93
+ };
94
+ console.log(`\n📈 Statistics:`);
95
+ console.log(` • Total memories: ${stats.totalMemories.count}`);
96
+ console.log(` • Average confidence: ${stats.avgConfidence.avg?.toFixed(2) || 'N/A'}`);
97
+ console.log(` • Total embeddings: ${stats.totalEmbeddings.count}`);
98
+ console.log(` • Total trajectories: ${stats.totalTrajectories.count}\n`);
86
99
  }
87
- function printReasoningBankHelp() {
100
+ async function runConsolidation() {
101
+ console.log('\n🔄 Running Memory Consolidation');
102
+ console.log('═'.repeat(50));
103
+ console.log('\nDeduplicating and pruning memories...\n');
104
+ const { consolidate } = await import('../reasoningbank/index.js');
105
+ const startTime = Date.now();
106
+ const result = await consolidate();
107
+ const duration = Date.now() - startTime;
108
+ console.log('✅ Consolidation complete!\n');
109
+ console.log(`📊 Results:`);
110
+ console.log(` • Memories processed: ${result.itemsProcessed}`);
111
+ console.log(` • Duplicates found: ${result.duplicatesFound}`);
112
+ console.log(` • Contradictions found: ${result.contradictionsFound}`);
113
+ console.log(` • Pruned: ${result.itemsPruned}`);
114
+ console.log(` • Duration: ${result.durationMs}ms\n`);
115
+ }
116
+ async function listMemories(args) {
117
+ const { db } = await import('../reasoningbank/index.js');
118
+ const dbInstance = db.getDb();
119
+ // Parse arguments
120
+ const sortBy = args.includes('--sort') ? args[args.indexOf('--sort') + 1] : 'created_at';
121
+ const limit = args.includes('--limit') ? parseInt(args[args.indexOf('--limit') + 1], 10) : 10;
122
+ console.log('\n📚 Memory Bank Contents');
123
+ console.log('═'.repeat(50));
124
+ console.log(`\nShowing top ${limit} memories (sorted by ${sortBy})\n`);
125
+ let orderBy = 'created_at DESC';
126
+ if (sortBy === 'confidence') {
127
+ orderBy = 'confidence DESC';
128
+ }
129
+ else if (sortBy === 'usage') {
130
+ orderBy = 'usage_count DESC';
131
+ }
132
+ const memories = dbInstance.prepare(`
133
+ SELECT
134
+ id,
135
+ json_extract(pattern_data, '$.title') as title,
136
+ json_extract(pattern_data, '$.description') as description,
137
+ json_extract(pattern_data, '$.domain') as domain,
138
+ confidence,
139
+ usage_count,
140
+ created_at
141
+ FROM patterns
142
+ WHERE type = 'reasoning_memory'
143
+ ORDER BY ${orderBy}
144
+ LIMIT ?
145
+ `).all(limit);
146
+ if (memories.length === 0) {
147
+ console.log('No memories found. Run `npx agentic-flow reasoningbank demo` to create some!\n');
148
+ return;
149
+ }
150
+ for (let i = 0; i < memories.length; i++) {
151
+ const mem = memories[i];
152
+ console.log(`${i + 1}. ${mem.title}`);
153
+ console.log(` Confidence: ${parseFloat(mem.confidence).toFixed(2)} | Usage: ${mem.usage_count} | Created: ${mem.created_at}`);
154
+ console.log(` Domain: ${mem.domain}`);
155
+ console.log(` ${mem.description}`);
156
+ console.log('');
157
+ }
158
+ }
159
+ function printHelp() {
88
160
  console.log(`
89
- 🧠 ReasoningBank - Memory System that Learns from Experience
161
+ 🧠 ReasoningBank - Closed-loop memory system for AI agents
90
162
 
91
163
  USAGE:
92
- npx agentic-flow reasoningbank <command>
164
+ npx agentic-flow reasoningbank <COMMAND>
93
165
 
94
166
  COMMANDS:
95
- demo Run interactive demo showing 0% → 100% success transformation
96
- test Run comprehensive validation suite (27 tests)
97
- init Initialize ReasoningBank database (.swarm/memory.db)
98
- benchmark Run performance benchmarks (retrieval, insertion, etc.)
99
- status Show memory statistics and database status
100
- help Show this help message
167
+ demo Run interactive demo showing learning progression
168
+ test Run validation test suite
169
+ init Initialize database schema
170
+ benchmark Run performance benchmarks
171
+ status Show memory statistics
172
+ consolidate Run memory consolidation now
173
+ list List memories with options
174
+ help Show this help message
175
+
176
+ LIST OPTIONS:
177
+ --sort <field> Sort by: confidence, usage, created_at (default)
178
+ --limit <n> Show top N memories (default: 10)
101
179
 
102
180
  EXAMPLES:
103
- # See the transformation from traditional to learning agents
181
+ # Run demo to see 0% 100% success transformation
104
182
  npx agentic-flow reasoningbank demo
105
183
 
106
- # Validate installation and run all tests
107
- npx agentic-flow reasoningbank test
108
-
109
- # Setup database for first-time use
184
+ # Initialize database
110
185
  npx agentic-flow reasoningbank init
111
186
 
112
- # Check memory bank statistics
113
- npx agentic-flow reasoningbank status
187
+ # Run validation tests
188
+ npx agentic-flow reasoningbank test
114
189
 
115
- FEATURES:
116
- Learns from both successes and failures
117
- ✅ 100% success rate after learning (vs 0% for traditional)
118
- ✅ 46% faster execution over time
119
- ✅ Knowledge transfers across similar tasks
120
- ✅ Zero manual intervention needed
190
+ # Show current statistics
191
+ npx agentic-flow reasoningbank status
121
192
 
122
- REQUIREMENTS:
123
- SQLite3 (for database operations)
124
- • ANTHROPIC_API_KEY (optional, for LLM-based learning)
193
+ # Consolidate memories (dedupe + prune)
194
+ npx agentic-flow reasoningbank consolidate
125
195
 
126
- Without API key: Uses heuristic fallbacks (70% accuracy)
127
- With API key: Uses LLM-based judgment (95% accuracy)
196
+ # List top 10 memories by confidence
197
+ npx agentic-flow reasoningbank list --sort confidence --limit 10
128
198
 
129
- DOCUMENTATION:
130
- Full README: src/reasoningbank/README.md
131
- • Demo Report: docs/REASONINGBANK-DEMO.md
132
- • Integration: docs/REASONINGBANK-CLI-INTEGRATION.md
133
- • Paper: https://arxiv.org/html/2509.25140v1
199
+ # List top 5 most used memories
200
+ npx agentic-flow reasoningbank list --sort usage --limit 5
134
201
 
135
202
  For more information: https://github.com/ruvnet/agentic-flow
136
203
  `);