claude-flow 2.7.0-alpha → 2.7.0-alpha.2

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.
@@ -1568,6 +1568,57 @@ ${commands.map((cmd) => `- [${cmd}](./${cmd}.md)`).join('\n')}
1568
1568
 
1569
1569
  // Initialize memory database with fallback support
1570
1570
  try {
1571
+ // Check if database exists BEFORE creating it
1572
+ const dbPath = '.swarm/memory.db';
1573
+ const { existsSync } = await import('fs');
1574
+ const dbExistedBefore = existsSync(dbPath);
1575
+
1576
+ // Handle ReasoningBank migration BEFORE FallbackMemoryStore initialization
1577
+ // This prevents schema conflicts with old databases
1578
+ if (dbExistedBefore) {
1579
+ console.log(' 🔍 Checking existing database for ReasoningBank schema...');
1580
+
1581
+ try {
1582
+ const {
1583
+ initializeReasoningBank,
1584
+ checkReasoningBankTables,
1585
+ migrateReasoningBank
1586
+ } = await import('../../../reasoningbank/reasoningbank-adapter.js');
1587
+
1588
+ // Set the database path for ReasoningBank
1589
+ process.env.CLAUDE_FLOW_DB_PATH = dbPath;
1590
+
1591
+ const tableCheck = await checkReasoningBankTables();
1592
+
1593
+ if (tableCheck.exists) {
1594
+ console.log(' ✅ ReasoningBank schema already complete');
1595
+ } else if (force) {
1596
+ // User used --force flag, migrate the database
1597
+ console.log(` 🔄 Migrating database: ${tableCheck.missingTables.length} tables missing`);
1598
+ console.log(` Missing: ${tableCheck.missingTables.join(', ')}`);
1599
+
1600
+ const migrationResult = await migrateReasoningBank();
1601
+
1602
+ if (migrationResult.success) {
1603
+ printSuccess(` ✓ Migration complete: added ${migrationResult.addedTables?.length || 0} tables`);
1604
+ console.log(' Use --reasoningbank flag to enable AI-powered memory features');
1605
+ } else {
1606
+ console.log(` âš ī¸ Migration failed: ${migrationResult.message}`);
1607
+ console.log(' Basic memory will work, use: memory init --reasoningbank to retry');
1608
+ }
1609
+ } else {
1610
+ // Database exists with missing tables but no --force flag
1611
+ console.log(` â„šī¸ Database has ${tableCheck.missingTables.length} missing ReasoningBank tables`);
1612
+ console.log(` Missing: ${tableCheck.missingTables.join(', ')}`);
1613
+ console.log(' Use --force to migrate existing database');
1614
+ console.log(' Or use: memory init --reasoningbank');
1615
+ }
1616
+ } catch (rbErr) {
1617
+ console.log(` âš ī¸ ReasoningBank check failed: ${rbErr.message}`);
1618
+ console.log(' Will attempt normal initialization...');
1619
+ }
1620
+ }
1621
+
1571
1622
  // Import and initialize FallbackMemoryStore to create the database
1572
1623
  const { FallbackMemoryStore } = await import('../../../memory/fallback-store.js');
1573
1624
  const memoryStore = new FallbackMemoryStore();
@@ -1580,6 +1631,25 @@ ${commands.map((cmd) => `- [${cmd}](./${cmd}.md)`).join('\n')}
1580
1631
  );
1581
1632
  } else {
1582
1633
  printSuccess('✓ Initialized memory database (.swarm/memory.db)');
1634
+
1635
+ // Initialize ReasoningBank schema for fresh databases
1636
+ if (!dbExistedBefore) {
1637
+ try {
1638
+ const {
1639
+ initializeReasoningBank
1640
+ } = await import('../../../reasoningbank/reasoningbank-adapter.js');
1641
+
1642
+ // Set the database path for ReasoningBank
1643
+ process.env.CLAUDE_FLOW_DB_PATH = dbPath;
1644
+
1645
+ console.log(' 🧠 Initializing ReasoningBank schema...');
1646
+ await initializeReasoningBank();
1647
+ printSuccess(' ✓ ReasoningBank schema initialized (use --reasoningbank flag for AI-powered memory)');
1648
+ } catch (rbErr) {
1649
+ console.log(` âš ī¸ ReasoningBank initialization failed: ${rbErr.message}`);
1650
+ console.log(' Basic memory will work, use: memory init --reasoningbank to retry');
1651
+ }
1652
+ }
1583
1653
  }
1584
1654
 
1585
1655
  memoryStore.close();
@@ -422,24 +422,61 @@ async function isReasoningBankInitialized() {
422
422
  async function handleReasoningBankCommand(command, subArgs, flags) {
423
423
  const initialized = await isReasoningBankInitialized();
424
424
 
425
+ // Lazy load the adapter (ES modules)
426
+ const { initializeReasoningBank, storeMemory, queryMemories, listMemories, getStatus, checkReasoningBankTables, migrateReasoningBank } = await import('../../reasoningbank/reasoningbank-adapter.js');
427
+
425
428
  // Special handling for 'init' command
426
429
  if (command === 'init') {
430
+ const dbPath = '.swarm/memory.db';
431
+
427
432
  if (initialized) {
428
- printWarning('âš ī¸ ReasoningBank already initialized');
429
- console.log('Database: .swarm/memory.db');
430
- console.log('\nTo reinitialize, delete .swarm/memory.db first');
433
+ // Database exists - check if migration is needed
434
+ printInfo('🔍 Checking existing database for ReasoningBank schema...\n');
435
+
436
+ try {
437
+ // Set the database path for ReasoningBank
438
+ process.env.CLAUDE_FLOW_DB_PATH = dbPath;
439
+
440
+ const tableCheck = await checkReasoningBankTables();
441
+
442
+ if (tableCheck.exists) {
443
+ printSuccess('✅ ReasoningBank already complete');
444
+ console.log('Database: .swarm/memory.db');
445
+ console.log('All ReasoningBank tables present\n');
446
+ console.log('Use --reasoningbank flag with memory commands to enable AI features');
447
+ return;
448
+ }
449
+
450
+ // Missing tables found - run migration
451
+ console.log(`🔄 Migrating database: ${tableCheck.missingTables.length} tables missing`);
452
+ console.log(` Missing: ${tableCheck.missingTables.join(', ')}\n`);
453
+
454
+ const migrationResult = await migrateReasoningBank();
455
+
456
+ if (migrationResult.success) {
457
+ printSuccess(`✓ Migration complete: added ${migrationResult.addedTables?.length || 0} tables`);
458
+ console.log('\nNext steps:');
459
+ console.log(' 1. Store memories: memory store key "value" --reasoningbank');
460
+ console.log(' 2. Query memories: memory query "search" --reasoningbank');
461
+ console.log(' 3. Check status: memory status --reasoningbank');
462
+ } else {
463
+ printError(`❌ Migration failed: ${migrationResult.message}`);
464
+ console.log('Try running: init --force to reinitialize');
465
+ }
466
+ } catch (error) {
467
+ printError('❌ Migration check failed');
468
+ console.error(error.message);
469
+ console.log('\nTry running: init --force to reinitialize');
470
+ }
431
471
  return;
432
472
  }
433
473
 
474
+ // Fresh initialization
434
475
  printInfo('🧠 Initializing ReasoningBank...');
435
476
  console.log('This will create: .swarm/memory.db\n');
436
477
 
437
478
  try {
438
- const { stdout, stderr } = await execAsync('npx agentic-flow reasoningbank init', {
439
- timeout: 30000,
440
- });
441
-
442
- if (stdout) console.log(stdout);
479
+ await initializeReasoningBank();
443
480
  printSuccess('✅ ReasoningBank initialized successfully!');
444
481
  console.log('\nNext steps:');
445
482
  console.log(' 1. Store memories: memory store key "value" --reasoningbank');
@@ -448,9 +485,6 @@ async function handleReasoningBankCommand(command, subArgs, flags) {
448
485
  } catch (error) {
449
486
  printError('❌ Failed to initialize ReasoningBank');
450
487
  console.error(error.message);
451
- if (error.stderr) {
452
- console.error('Details:', error.stderr);
453
- }
454
488
  }
455
489
  return;
456
490
  }
@@ -463,21 +497,156 @@ async function handleReasoningBankCommand(command, subArgs, flags) {
463
497
  return;
464
498
  }
465
499
 
466
- // Delegate to agentic-flow reasoningbank commands
467
500
  printInfo(`🧠 Using ReasoningBank mode...`);
468
501
 
469
502
  try {
470
- const cmd = buildReasoningBankCommand(command, subArgs, flags);
471
- const { stdout, stderr } = await execAsync(cmd, { timeout: 30000 });
472
-
473
- if (stdout) console.log(stdout);
474
- if (stderr && !stderr.includes('Warning')) console.error(stderr);
503
+ // Handle different commands
504
+ switch (command) {
505
+ case 'store':
506
+ await handleReasoningBankStore(subArgs, flags, storeMemory);
507
+ break;
508
+
509
+ case 'query':
510
+ await handleReasoningBankQuery(subArgs, flags, queryMemories);
511
+ break;
512
+
513
+ case 'list':
514
+ await handleReasoningBankList(subArgs, flags, listMemories);
515
+ break;
516
+
517
+ case 'status':
518
+ await handleReasoningBankStatus(getStatus);
519
+ break;
520
+
521
+ case 'consolidate':
522
+ case 'demo':
523
+ case 'test':
524
+ case 'benchmark':
525
+ // These still use CLI commands
526
+ const cmd = `npx agentic-flow reasoningbank ${command}`;
527
+ const { stdout } = await execAsync(cmd, { timeout: 60000 });
528
+ if (stdout) console.log(stdout);
529
+ break;
530
+
531
+ default:
532
+ printError(`Unknown ReasoningBank command: ${command}`);
533
+ }
475
534
  } catch (error) {
476
535
  printError(`❌ ReasoningBank command failed`);
477
536
  console.error(error.message);
478
537
  }
479
538
  }
480
539
 
540
+ // NEW: Handle ReasoningBank store
541
+ async function handleReasoningBankStore(subArgs, flags, storeMemory) {
542
+ const key = subArgs[1];
543
+ const value = subArgs.slice(2).join(' ');
544
+
545
+ if (!key || !value) {
546
+ printError('Usage: memory store <key> <value> --reasoningbank');
547
+ return;
548
+ }
549
+
550
+ try {
551
+ const namespace = flags?.namespace || flags?.ns || getArgValue(subArgs, '--namespace') || 'default';
552
+
553
+ const memoryId = await storeMemory(key, value, {
554
+ namespace,
555
+ agent: 'memory-agent',
556
+ domain: namespace,
557
+ });
558
+
559
+ printSuccess('✅ Stored successfully in ReasoningBank');
560
+ console.log(`📝 Key: ${key}`);
561
+ console.log(`🧠 Memory ID: ${memoryId}`);
562
+ console.log(`đŸ“Ļ Namespace: ${namespace}`);
563
+ console.log(`💾 Size: ${new TextEncoder().encode(value).length} bytes`);
564
+ console.log(`🔍 Semantic search: enabled`);
565
+ } catch (error) {
566
+ printError(`Failed to store: ${error.message}`);
567
+ }
568
+ }
569
+
570
+ // NEW: Handle ReasoningBank query
571
+ async function handleReasoningBankQuery(subArgs, flags, queryMemories) {
572
+ const search = subArgs.slice(1).join(' ');
573
+
574
+ if (!search) {
575
+ printError('Usage: memory query <search> --reasoningbank');
576
+ return;
577
+ }
578
+
579
+ try {
580
+ const namespace = flags?.namespace || flags?.ns || getArgValue(subArgs, '--namespace');
581
+ const results = await queryMemories(search, {
582
+ domain: namespace || 'general',
583
+ limit: 10,
584
+ });
585
+
586
+ if (results.length === 0) {
587
+ printWarning('No results found');
588
+ return;
589
+ }
590
+
591
+ printSuccess(`Found ${results.length} results (semantic search):`);
592
+
593
+ for (const entry of results) {
594
+ console.log(`\n📌 ${entry.key}`);
595
+ console.log(` Namespace: ${entry.namespace}`);
596
+ console.log(` Value: ${entry.value.substring(0, 100)}${entry.value.length > 100 ? '...' : ''}`);
597
+ console.log(` Confidence: ${(entry.confidence * 100).toFixed(1)}%`);
598
+ console.log(` Usage: ${entry.usage_count} times`);
599
+ if (entry.score) {
600
+ console.log(` Match Score: ${(entry.score * 100).toFixed(1)}%`);
601
+ }
602
+ console.log(` Stored: ${new Date(entry.created_at).toLocaleString()}`);
603
+ }
604
+ } catch (error) {
605
+ printError(`Failed to query: ${error.message}`);
606
+ }
607
+ }
608
+
609
+ // NEW: Handle ReasoningBank list
610
+ async function handleReasoningBankList(subArgs, flags, listMemories) {
611
+ try {
612
+ const sort = flags?.sort || getArgValue(subArgs, '--sort') || 'created_at';
613
+ const limit = parseInt(flags?.limit || getArgValue(subArgs, '--limit') || '10');
614
+
615
+ const results = await listMemories({ sort, limit });
616
+
617
+ if (results.length === 0) {
618
+ printWarning('No memories found');
619
+ return;
620
+ }
621
+
622
+ printSuccess(`ReasoningBank memories (${results.length} shown):`);
623
+
624
+ for (const entry of results) {
625
+ console.log(`\n📌 ${entry.key}`);
626
+ console.log(` Value: ${entry.value.substring(0, 80)}${entry.value.length > 80 ? '...' : ''}`);
627
+ console.log(` Confidence: ${(entry.confidence * 100).toFixed(1)}% | Usage: ${entry.usage_count}`);
628
+ }
629
+ } catch (error) {
630
+ printError(`Failed to list: ${error.message}`);
631
+ }
632
+ }
633
+
634
+ // NEW: Handle ReasoningBank status
635
+ async function handleReasoningBankStatus(getStatus) {
636
+ try {
637
+ const stats = await getStatus();
638
+
639
+ printSuccess('📊 ReasoningBank Status:');
640
+ console.log(` Total memories: ${stats.total_memories}`);
641
+ console.log(` Average confidence: ${(stats.avg_confidence * 100).toFixed(1)}%`);
642
+ console.log(` Total usage: ${stats.total_usage}`);
643
+ console.log(` Embeddings: ${stats.total_embeddings}`);
644
+ console.log(` Trajectories: ${stats.total_trajectories}`);
645
+ } catch (error) {
646
+ printError(`Failed to get status: ${error.message}`);
647
+ }
648
+ }
649
+
481
650
  // NEW: Build agentic-flow reasoningbank command
482
651
  function buildReasoningBankCommand(command, subArgs, flags) {
483
652
  const parts = ['npx', 'agentic-flow', 'reasoningbank'];
@@ -504,6 +673,9 @@ function buildReasoningBankCommand(command, subArgs, flags) {
504
673
  }
505
674
  });
506
675
 
676
+ // Add required --agent parameter
677
+ parts.push('--agent', 'memory-agent');
678
+
507
679
  return parts.join(' ');
508
680
  }
509
681
 
@@ -0,0 +1,273 @@
1
+ /**
2
+ * ReasoningBank Adapter for Claude-Flow
3
+ *
4
+ * Wraps agentic-flow's ReasoningBank SDK for use in claude-flow memory commands
5
+ */
6
+
7
+ import { db, initialize, retrieveMemories, computeEmbedding, loadConfig } from 'agentic-flow/dist/reasoningbank/index.js';
8
+ import { v4 as uuidv4 } from 'uuid';
9
+
10
+ /**
11
+ * Initialize ReasoningBank database
12
+ */
13
+ export async function initializeReasoningBank() {
14
+ // Set database path
15
+ process.env.CLAUDE_FLOW_DB_PATH = '.swarm/memory.db';
16
+
17
+ await initialize();
18
+ return true;
19
+ }
20
+
21
+ /**
22
+ * Store a memory in ReasoningBank
23
+ */
24
+ export async function storeMemory(key, value, options = {}) {
25
+ const memoryId = `mem_${uuidv4()}`;
26
+
27
+ const memory = {
28
+ id: memoryId,
29
+ type: options.type || 'fact',
30
+ pattern_data: JSON.stringify({
31
+ key,
32
+ value,
33
+ namespace: options.namespace || 'default',
34
+ agent: options.agent || 'memory-agent',
35
+ domain: options.domain || 'general',
36
+ }),
37
+ confidence: options.confidence || 0.8,
38
+ usage_count: 0,
39
+ created_at: new Date().toISOString(),
40
+ };
41
+
42
+ // Store memory
43
+ db.upsertMemory(memory);
44
+
45
+ // Compute and store embedding for semantic search
46
+ try {
47
+ const config = loadConfig();
48
+ const embeddingModel = config.embeddings.provider || 'claude';
49
+
50
+ const embedding = await computeEmbedding(`${key}: ${value}`);
51
+ const vectorArray = new Float32Array(embedding);
52
+
53
+ db.upsertEmbedding({
54
+ memory_id: memoryId,
55
+ vector: vectorArray,
56
+ model: embeddingModel, // Dynamic model from config
57
+ dims: vectorArray.length, // Required: embedding dimensions
58
+ created_at: new Date().toISOString(),
59
+ });
60
+ } catch (error) {
61
+ console.warn('[ReasoningBank] Warning: Could not compute embedding:', error.message);
62
+ // Continue without embedding - memory is still stored
63
+ }
64
+
65
+ return memoryId;
66
+ }
67
+
68
+ /**
69
+ * Query memories from ReasoningBank
70
+ */
71
+ export async function queryMemories(searchQuery, options = {}) {
72
+ try {
73
+ // Use ReasoningBank's semantic retrieval
74
+ const memories = await retrieveMemories(searchQuery, {
75
+ domain: options.domain || 'general',
76
+ agent: options.agent || 'memory-agent',
77
+ k: options.limit || 10,
78
+ });
79
+
80
+ return memories.map(mem => {
81
+ try {
82
+ const data = JSON.parse(mem.pattern_data);
83
+ return {
84
+ id: mem.id,
85
+ key: data.key,
86
+ value: data.value,
87
+ namespace: data.namespace,
88
+ confidence: mem.confidence,
89
+ usage_count: mem.usage_count,
90
+ created_at: mem.created_at,
91
+ score: mem.score || 0,
92
+ };
93
+ } catch {
94
+ return null;
95
+ }
96
+ }).filter(Boolean);
97
+ } catch (error) {
98
+ // Fallback to simple query if semantic search fails
99
+ console.warn('[ReasoningBank] Semantic search failed, using simple query:', error.message);
100
+
101
+ const dbInstance = db.getDb();
102
+ const rows = dbInstance.prepare(`
103
+ SELECT * FROM patterns
104
+ WHERE pattern_data LIKE ?
105
+ ORDER BY confidence DESC, usage_count DESC
106
+ LIMIT ?
107
+ `).all(`%${searchQuery}%`, options.limit || 10);
108
+
109
+ return rows.map(row => {
110
+ try {
111
+ const data = JSON.parse(row.pattern_data);
112
+ return {
113
+ id: row.id,
114
+ key: data.key,
115
+ value: data.value,
116
+ namespace: data.namespace,
117
+ confidence: row.confidence,
118
+ usage_count: row.usage_count,
119
+ created_at: row.created_at,
120
+ };
121
+ } catch {
122
+ return null;
123
+ }
124
+ }).filter(Boolean);
125
+ }
126
+ }
127
+
128
+ /**
129
+ * List all memories
130
+ */
131
+ export async function listMemories(options = {}) {
132
+ const dbInstance = db.getDb();
133
+
134
+ const limit = options.limit || 10;
135
+ const sortBy = options.sort || 'created_at';
136
+ const sortOrder = options.order || 'DESC';
137
+
138
+ const rows = dbInstance.prepare(`
139
+ SELECT * FROM patterns
140
+ ORDER BY ${sortBy} ${sortOrder}
141
+ LIMIT ?
142
+ `).all(limit);
143
+
144
+ return rows.map(row => {
145
+ try {
146
+ const data = JSON.parse(row.pattern_data);
147
+ return {
148
+ id: row.id,
149
+ key: data.key,
150
+ value: data.value,
151
+ namespace: data.namespace,
152
+ confidence: row.confidence,
153
+ usage_count: row.usage_count,
154
+ created_at: row.created_at,
155
+ };
156
+ } catch {
157
+ return null;
158
+ }
159
+ }).filter(Boolean);
160
+ }
161
+
162
+ /**
163
+ * Get ReasoningBank statistics
164
+ */
165
+ export async function getStatus() {
166
+ const dbInstance = db.getDb();
167
+
168
+ const stats = dbInstance.prepare(`
169
+ SELECT
170
+ COUNT(*) as total_memories,
171
+ AVG(confidence) as avg_confidence,
172
+ SUM(usage_count) as total_usage
173
+ FROM patterns
174
+ `).get();
175
+
176
+ const embeddingCount = dbInstance.prepare(`
177
+ SELECT COUNT(*) as count FROM pattern_embeddings
178
+ `).get();
179
+
180
+ const trajectoryCount = dbInstance.prepare(`
181
+ SELECT COUNT(*) as count FROM task_trajectories
182
+ `).get();
183
+
184
+ return {
185
+ total_memories: stats.total_memories || 0,
186
+ avg_confidence: stats.avg_confidence || 0,
187
+ total_usage: stats.total_usage || 0,
188
+ total_embeddings: embeddingCount.count || 0,
189
+ total_trajectories: trajectoryCount.count || 0,
190
+ };
191
+ }
192
+
193
+ /**
194
+ * Check which ReasoningBank tables are present in the database
195
+ * Returns object with table names and their existence status
196
+ */
197
+ export async function checkReasoningBankTables() {
198
+ try {
199
+ const dbInstance = db.getDb();
200
+
201
+ // Required ReasoningBank tables
202
+ const requiredTables = [
203
+ 'patterns',
204
+ 'pattern_embeddings',
205
+ 'pattern_links',
206
+ 'task_trajectories',
207
+ 'matts_runs',
208
+ 'consolidation_runs',
209
+ 'metrics_log'
210
+ ];
211
+
212
+ // Query existing tables
213
+ const existingTables = dbInstance.prepare(`
214
+ SELECT name FROM sqlite_master
215
+ WHERE type='table'
216
+ `).all().map(row => row.name);
217
+
218
+ // Check which required tables are missing
219
+ const missingTables = requiredTables.filter(table => !existingTables.includes(table));
220
+
221
+ return {
222
+ exists: missingTables.length === 0,
223
+ existingTables,
224
+ missingTables,
225
+ requiredTables
226
+ };
227
+ } catch (error) {
228
+ return {
229
+ exists: false,
230
+ existingTables: [],
231
+ missingTables: [],
232
+ requiredTables: [],
233
+ error: error.message
234
+ };
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Migrate existing database to add missing ReasoningBank tables
240
+ */
241
+ export async function migrateReasoningBank() {
242
+ try {
243
+ // Check current state
244
+ const tableCheck = await checkReasoningBankTables();
245
+
246
+ if (tableCheck.exists) {
247
+ return {
248
+ success: true,
249
+ message: 'All ReasoningBank tables already exist',
250
+ migrated: false
251
+ };
252
+ }
253
+
254
+ // Run full initialization which will create missing tables
255
+ await initializeReasoningBank();
256
+
257
+ // Verify migration
258
+ const afterCheck = await checkReasoningBankTables();
259
+
260
+ return {
261
+ success: afterCheck.exists,
262
+ message: `Migration completed: ${tableCheck.missingTables.length} tables added`,
263
+ migrated: true,
264
+ addedTables: tableCheck.missingTables
265
+ };
266
+ } catch (error) {
267
+ return {
268
+ success: false,
269
+ message: `Migration failed: ${error.message}`,
270
+ error: error.message
271
+ };
272
+ }
273
+ }