claude-flow 3.5.72 → 3.5.74
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/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/neural.js +54 -0
- package/v3/@claude-flow/cli/dist/src/init/claudemd-generator.js +15 -17
- package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-tools.js +6 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/agentdb-tools.js +14 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +76 -1
- package/v3/@claude-flow/cli/dist/src/mcp-tools/neural-tools.js +8 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/ruvllm-tools.js +26 -2
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.d.ts +14 -1
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +69 -1
- package/v3/@claude-flow/cli/dist/src/memory/sona-optimizer.d.ts +43 -3
- package/v3/@claude-flow/cli/dist/src/memory/sona-optimizer.js +150 -7
- package/v3/@claude-flow/cli/dist/src/ruvector/graph-backend.d.ts +79 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/graph-backend.js +220 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/lora-adapter.d.ts +22 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/lora-adapter.js +92 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/vector-db.d.ts +4 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/vector-db.js +22 -1
- package/v3/@claude-flow/cli/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "3.5.
|
|
3
|
+
"version": "3.5.74",
|
|
4
4
|
"description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -260,6 +260,17 @@ const trainCommand = {
|
|
|
260
260
|
// Flush patterns to disk
|
|
261
261
|
flushPatterns();
|
|
262
262
|
const persistence = getPersistenceStatus();
|
|
263
|
+
// Save LoRA checkpoint via ruvllm TrainingPipeline if available
|
|
264
|
+
try {
|
|
265
|
+
const { LoRAAdapter } = await import('../ruvector/lora-adapter.js');
|
|
266
|
+
const path = await import('path');
|
|
267
|
+
const cpDir = path.join(process.cwd(), '.claude-flow', 'neural');
|
|
268
|
+
const cpPath = path.join(cpDir, `lora-checkpoint-${Date.now()}.json`);
|
|
269
|
+
const adapter = new LoRAAdapter({ inputDim: dim, outputDim: dim, rank: 4 });
|
|
270
|
+
await adapter.initBackend();
|
|
271
|
+
await adapter.saveCheckpoint(cpPath);
|
|
272
|
+
}
|
|
273
|
+
catch { /* checkpoint save is best-effort */ }
|
|
263
274
|
output.writeln();
|
|
264
275
|
// Display results
|
|
265
276
|
const tableData = [
|
|
@@ -421,6 +432,43 @@ const statusCommand = {
|
|
|
421
432
|
status: output.success('Available'),
|
|
422
433
|
details: '~4x memory reduction',
|
|
423
434
|
},
|
|
435
|
+
{
|
|
436
|
+
component: 'ruvllm Coordinator',
|
|
437
|
+
status: stats._ruvllmBackend === 'active' ? output.success('Active') : output.dim('Unavailable'),
|
|
438
|
+
details: stats._ruvllmBackend === 'active'
|
|
439
|
+
? `SonaCoordinator | ${stats._ruvllmTrajectories} trajectories`
|
|
440
|
+
: 'Install @ruvector/ruvllm',
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
component: 'Contrastive Trainer',
|
|
444
|
+
status: stats._contrastiveTrainer && stats._contrastiveTrainer !== 'unavailable' ? output.success('Active') : output.dim('Unavailable'),
|
|
445
|
+
details: stats._contrastiveTrainer && stats._contrastiveTrainer !== 'unavailable'
|
|
446
|
+
? `${stats._contrastiveTrainer.triplets ?? 0} triplets, ${stats._contrastiveTrainer.agents ?? 0} agents`
|
|
447
|
+
: 'Install @ruvector/ruvllm',
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
component: 'Training Pipeline',
|
|
451
|
+
status: stats._trainingBackend === 'ruvllm' ? output.success('Active') : output.dim(stats._trainingBackend || 'Unavailable'),
|
|
452
|
+
details: stats._trainingBackend === 'ruvllm'
|
|
453
|
+
? 'ruvllm checkpoints enabled'
|
|
454
|
+
: 'JS fallback (no checkpoints)',
|
|
455
|
+
},
|
|
456
|
+
await (async () => {
|
|
457
|
+
try {
|
|
458
|
+
const { getGraphStats } = await import('../ruvector/graph-backend.js');
|
|
459
|
+
const gs = await getGraphStats();
|
|
460
|
+
return {
|
|
461
|
+
component: 'Graph Database',
|
|
462
|
+
status: gs.backend === 'graph-node' ? output.success('Active') : output.dim('Unavailable'),
|
|
463
|
+
details: gs.backend === 'graph-node'
|
|
464
|
+
? `${gs.totalNodes} nodes, ${gs.totalEdges} edges`
|
|
465
|
+
: 'Install @ruvector/graph-node',
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
catch {
|
|
469
|
+
return { component: 'Graph Database', status: output.dim('Unavailable'), details: 'Not loaded' };
|
|
470
|
+
}
|
|
471
|
+
})(),
|
|
424
472
|
],
|
|
425
473
|
});
|
|
426
474
|
if (verbose) {
|
|
@@ -678,6 +726,12 @@ const optimizeCommand = {
|
|
|
678
726
|
await initializeIntelligence();
|
|
679
727
|
const patterns = await getAllPatterns();
|
|
680
728
|
const stats = getIntelligenceStats();
|
|
729
|
+
// Trigger ruvllm background learning if available
|
|
730
|
+
try {
|
|
731
|
+
const { runBackgroundLearning } = await import('../memory/intelligence.js');
|
|
732
|
+
await runBackgroundLearning();
|
|
733
|
+
}
|
|
734
|
+
catch { /* background learning is best-effort */ }
|
|
681
735
|
// Get actual pattern storage size
|
|
682
736
|
const patternDir = path.join(process.cwd(), '.claude-flow', 'neural');
|
|
683
737
|
let beforeSize = 0;
|
|
@@ -52,9 +52,8 @@ function concurrencyRules() {
|
|
|
52
52
|
return `## Concurrency: 1 MESSAGE = ALL RELATED OPERATIONS
|
|
53
53
|
|
|
54
54
|
- All operations MUST be concurrent/parallel in a single message
|
|
55
|
-
- Use Claude Code's
|
|
56
|
-
- ALWAYS
|
|
57
|
-
- ALWAYS spawn ALL agents in ONE message with full instructions via Task tool
|
|
55
|
+
- Use Claude Code's Agent tool for spawning agents, not just MCP
|
|
56
|
+
- ALWAYS spawn ALL agents in ONE message with full instructions via Agent tool
|
|
58
57
|
- ALWAYS batch ALL file reads/writes/edits in ONE message
|
|
59
58
|
- ALWAYS batch ALL Bash commands in ONE message`;
|
|
60
59
|
}
|
|
@@ -62,9 +61,9 @@ function swarmOrchestration() {
|
|
|
62
61
|
return `## Swarm Orchestration
|
|
63
62
|
|
|
64
63
|
- MUST initialize the swarm using CLI tools when starting complex tasks
|
|
65
|
-
- MUST spawn concurrent agents using Claude Code's
|
|
66
|
-
- Never use CLI tools alone for execution —
|
|
67
|
-
- MUST call CLI tools AND
|
|
64
|
+
- MUST spawn concurrent agents using Claude Code's Agent tool
|
|
65
|
+
- Never use CLI tools alone for execution — Agent tool agents do the actual work
|
|
66
|
+
- MUST call CLI tools AND Agent tool in ONE message for complex work
|
|
68
67
|
|
|
69
68
|
### 3-Tier Model Routing (ADR-026)
|
|
70
69
|
|
|
@@ -74,8 +73,7 @@ function swarmOrchestration() {
|
|
|
74
73
|
| **2** | Haiku | ~500ms | $0.0002 | Simple tasks, low complexity (<30%) |
|
|
75
74
|
| **3** | Sonnet/Opus | 2-5s | $0.003-0.015 | Complex reasoning, architecture, security (>30%) |
|
|
76
75
|
|
|
77
|
-
-
|
|
78
|
-
- Use Edit tool directly when \`[AGENT_BOOSTER_AVAILABLE]\``;
|
|
76
|
+
- For Tier 1 simple transforms, use Edit tool directly — no LLM agent needed`;
|
|
79
77
|
}
|
|
80
78
|
function antiDriftConfig() {
|
|
81
79
|
return `## Swarm Configuration & Anti-Drift
|
|
@@ -103,11 +101,11 @@ When the user requests a complex task, spawn agents in background and WAIT:
|
|
|
103
101
|
Bash("npx @claude-flow/cli@latest swarm init --topology hierarchical --max-agents 8 --strategy specialized")
|
|
104
102
|
|
|
105
103
|
// STEP 2: Spawn ALL agents IN BACKGROUND in a SINGLE message
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
Agent("Research requirements", "Analyze codebase patterns and store findings in memory", {subagent_type: "researcher", run_in_background: true})
|
|
105
|
+
Agent("Design architecture", "Design architecture based on research", {subagent_type: "system-architect", run_in_background: true})
|
|
106
|
+
Agent("Implement solution", "Implement the solution following the design", {subagent_type: "coder", run_in_background: true})
|
|
107
|
+
Agent("Write tests", "Write comprehensive tests for the implementation", {subagent_type: "tester", run_in_background: true})
|
|
108
|
+
Agent("Review code quality", "Review code quality, security, and best practices", {subagent_type: "reviewer", run_in_background: true})
|
|
111
109
|
\`\`\`
|
|
112
110
|
|
|
113
111
|
### Agent Routing
|
|
@@ -128,10 +126,10 @@ Task({prompt: "Review code quality...", subagent_type: "reviewer", run_in_backgr
|
|
|
128
126
|
function executionRules() {
|
|
129
127
|
return `## Swarm Execution Rules
|
|
130
128
|
|
|
131
|
-
- ALWAYS use \`run_in_background: true\` for all
|
|
132
|
-
- ALWAYS put ALL
|
|
129
|
+
- ALWAYS use \`run_in_background: true\` for all Agent tool calls
|
|
130
|
+
- ALWAYS put ALL Agent calls in ONE message for parallel execution
|
|
133
131
|
- After spawning, STOP — do NOT add more tool calls or check status
|
|
134
|
-
- Never poll
|
|
132
|
+
- Never poll agent status repeatedly — trust agents to return
|
|
135
133
|
- When agent results arrive, review ALL results before proceeding`;
|
|
136
134
|
}
|
|
137
135
|
function cliCommandsTable() {
|
|
@@ -407,7 +405,7 @@ npx @claude-flow/cli@latest doctor --fix
|
|
|
407
405
|
|
|
408
406
|
## Claude Code vs MCP Tools
|
|
409
407
|
|
|
410
|
-
- **Claude Code
|
|
408
|
+
- **Claude Code Agent tool** handles execution: agents, file ops, code generation, git
|
|
411
409
|
- **MCP tools** (via ToolSearch) handle coordination: swarm, memory, hooks, routing, hive-mind
|
|
412
410
|
- **CLI commands** (via Bash) are the same tools with terminal output
|
|
413
411
|
- Use \`ToolSearch("keyword")\` to discover available MCP tools
|
|
@@ -184,6 +184,12 @@ export const agentTools = [
|
|
|
184
184
|
};
|
|
185
185
|
store.agents[agentId] = agent;
|
|
186
186
|
saveAgentStore(store);
|
|
187
|
+
// Record agent in graph database (ADR-087, best-effort)
|
|
188
|
+
try {
|
|
189
|
+
const { addNode } = await import('../ruvector/graph-backend.js');
|
|
190
|
+
await addNode({ id: agentId, type: 'agent', name: agentType });
|
|
191
|
+
}
|
|
192
|
+
catch { /* graph-node not available */ }
|
|
187
193
|
// Include Agent Booster routing info if applicable
|
|
188
194
|
const response = {
|
|
189
195
|
success: true,
|
|
@@ -243,6 +243,20 @@ export const agentdbCausalEdge = {
|
|
|
243
243
|
return { success: false, error: 'targetId is required (non-empty string)' };
|
|
244
244
|
if (!relation)
|
|
245
245
|
return { success: false, error: 'relation is required (non-empty string)' };
|
|
246
|
+
// Try native graph-node backend first (ADR-087)
|
|
247
|
+
try {
|
|
248
|
+
const graphBackend = await import('../ruvector/graph-backend.js');
|
|
249
|
+
if (await graphBackend.isGraphBackendAvailable()) {
|
|
250
|
+
const graphResult = await graphBackend.recordCausalEdge(sourceId, targetId, relation, typeof params.weight === 'number' ? validateScore(params.weight, 0.5) : undefined);
|
|
251
|
+
if (graphResult.success) {
|
|
252
|
+
// Also record in AgentDB bridge for compatibility
|
|
253
|
+
const bridge = await getBridge();
|
|
254
|
+
await bridge.bridgeRecordCausalEdge({ sourceId, targetId, relation, weight: typeof params.weight === 'number' ? validateScore(params.weight, 0.5) : undefined }).catch(() => { });
|
|
255
|
+
return { ...graphResult, _graphNodeBackend: true };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch { /* graph-node not available, fall through */ }
|
|
246
260
|
const bridge = await getBridge();
|
|
247
261
|
const result = await bridge.bridgeRecordCausalEdge({
|
|
248
262
|
sourceId,
|
|
@@ -291,6 +291,7 @@ async function getSemanticRouter() {
|
|
|
291
291
|
}
|
|
292
292
|
nativeVectorDb = db;
|
|
293
293
|
routerBackend = 'native';
|
|
294
|
+
console.log('[hooks] Semantic router initialized: native VectorDb (HNSW, 16k+ routes/s)');
|
|
294
295
|
return { router: null, backend: routerBackend, native: nativeVectorDb };
|
|
295
296
|
}
|
|
296
297
|
}
|
|
@@ -312,10 +313,12 @@ async function getSemanticRouter() {
|
|
|
312
313
|
});
|
|
313
314
|
}
|
|
314
315
|
routerBackend = 'pure-js';
|
|
316
|
+
console.log('[hooks] Semantic router initialized: pure JS (cosine, 47k routes/s)');
|
|
315
317
|
}
|
|
316
318
|
catch {
|
|
317
319
|
semanticRouter = null;
|
|
318
320
|
routerBackend = 'none';
|
|
321
|
+
console.log('[hooks] Semantic router initialized: none (no backend available)');
|
|
319
322
|
}
|
|
320
323
|
return { router: semanticRouter, backend: routerBackend, native: nativeVectorDb };
|
|
321
324
|
}
|
|
@@ -2030,6 +2033,46 @@ export const hooksIntelligence = {
|
|
|
2030
2033
|
implemented: true,
|
|
2031
2034
|
note: 'Real ONNX embeddings via Xenova/all-MiniLM-L6-v2',
|
|
2032
2035
|
},
|
|
2036
|
+
ruvllmCoordinator: await (async () => {
|
|
2037
|
+
try {
|
|
2038
|
+
const { getIntelligenceStats } = await import('../memory/intelligence.js');
|
|
2039
|
+
const s = getIntelligenceStats();
|
|
2040
|
+
return { status: s._ruvllmBackend || 'unavailable', trajectories: s._ruvllmTrajectories || 0, note: s._ruvllmBackend === 'active' ? 'SonaCoordinator forwarding trajectories' : '@ruvector/ruvllm not loaded' };
|
|
2041
|
+
}
|
|
2042
|
+
catch {
|
|
2043
|
+
return { status: 'unavailable', trajectories: 0, note: 'Not initialized' };
|
|
2044
|
+
}
|
|
2045
|
+
})(),
|
|
2046
|
+
contrastiveTrainer: await (async () => {
|
|
2047
|
+
try {
|
|
2048
|
+
const { getSONAStats } = await import('../memory/sona-optimizer.js');
|
|
2049
|
+
const s = await getSONAStats();
|
|
2050
|
+
return { status: s._contrastiveTrainer !== 'unavailable' ? 'active' : 'unavailable', details: s._contrastiveTrainer, note: s._contrastiveTrainer !== 'unavailable' ? 'Agent embedding learning active' : '@ruvector/ruvllm not loaded' };
|
|
2051
|
+
}
|
|
2052
|
+
catch {
|
|
2053
|
+
return { status: 'unavailable', details: null, note: 'Not initialized' };
|
|
2054
|
+
}
|
|
2055
|
+
})(),
|
|
2056
|
+
trainingPipeline: await (async () => {
|
|
2057
|
+
try {
|
|
2058
|
+
const loraInst = await getLoRAAdapter();
|
|
2059
|
+
const s = loraInst?.getStats();
|
|
2060
|
+
return { status: s?._trainingBackend || 'unavailable', note: s?._trainingBackend === 'ruvllm' ? 'Checkpoint save/load via ruvllm' : 'JS fallback' };
|
|
2061
|
+
}
|
|
2062
|
+
catch {
|
|
2063
|
+
return { status: 'unavailable', note: 'Not initialized' };
|
|
2064
|
+
}
|
|
2065
|
+
})(),
|
|
2066
|
+
graphDatabase: await (async () => {
|
|
2067
|
+
try {
|
|
2068
|
+
const { getGraphStats } = await import('../ruvector/graph-backend.js');
|
|
2069
|
+
const gs = await getGraphStats();
|
|
2070
|
+
return { status: gs.backend, totalNodes: gs.totalNodes, totalEdges: gs.totalEdges, avgDegree: gs.avgDegree, note: gs.backend === 'graph-node' ? 'Native Rust graph with hyperedges and k-hop queries' : '@ruvector/graph-node not loaded' };
|
|
2071
|
+
}
|
|
2072
|
+
catch {
|
|
2073
|
+
return { status: 'unavailable', totalNodes: 0, totalEdges: 0, avgDegree: 0, note: 'Not initialized' };
|
|
2074
|
+
}
|
|
2075
|
+
})(),
|
|
2033
2076
|
},
|
|
2034
2077
|
realMetrics: {
|
|
2035
2078
|
trajectories: realStats.trajectories,
|
|
@@ -2041,7 +2084,7 @@ export const hooksIntelligence = {
|
|
|
2041
2084
|
working: [
|
|
2042
2085
|
'memory-store', 'embeddings', 'trajectory-recording', 'claims', 'swarm-coordination',
|
|
2043
2086
|
'hnsw-index', 'pattern-storage', 'sona-optimizer', 'ewc-consolidation', 'moe-routing',
|
|
2044
|
-
'flash-attention', 'lora-adapter'
|
|
2087
|
+
'flash-attention', 'lora-adapter', 'ruvllm-coordinator', 'contrastive-trainer', 'training-pipeline', 'graph-database'
|
|
2045
2088
|
],
|
|
2046
2089
|
partial: [],
|
|
2047
2090
|
notImplemented: [],
|
|
@@ -2304,6 +2347,12 @@ export const hooksTrajectoryEnd = {
|
|
|
2304
2347
|
// SONA learning failed, continue without it
|
|
2305
2348
|
}
|
|
2306
2349
|
}
|
|
2350
|
+
// Trigger ruvllm background learning after trajectory end
|
|
2351
|
+
try {
|
|
2352
|
+
const { runBackgroundLearning } = await import('../memory/intelligence.js');
|
|
2353
|
+
await runBackgroundLearning();
|
|
2354
|
+
}
|
|
2355
|
+
catch { /* best-effort */ }
|
|
2307
2356
|
// Try EWC++ consolidation on successful trajectories
|
|
2308
2357
|
if (success) {
|
|
2309
2358
|
const ewc = await getEWCConsolidator();
|
|
@@ -2668,12 +2717,38 @@ export const hooksIntelligenceStats = {
|
|
|
2668
2717
|
implementation: 'real-lora',
|
|
2669
2718
|
};
|
|
2670
2719
|
}
|
|
2720
|
+
// ruvllm native backend stats
|
|
2721
|
+
let ruvllmStats = { coordinator: 'unavailable', trajectories: 0, contrastiveTrainer: 'unavailable', trainingBackend: 'unavailable', graphDatabase: { backend: 'unavailable', totalNodes: 0, totalEdges: 0 } };
|
|
2722
|
+
try {
|
|
2723
|
+
const { getIntelligenceStats } = await import('../memory/intelligence.js');
|
|
2724
|
+
const iStats = getIntelligenceStats();
|
|
2725
|
+
ruvllmStats.coordinator = iStats._ruvllmBackend || 'unavailable';
|
|
2726
|
+
ruvllmStats.trajectories = iStats._ruvllmTrajectories || 0;
|
|
2727
|
+
}
|
|
2728
|
+
catch { /* not initialized */ }
|
|
2729
|
+
try {
|
|
2730
|
+
const { getSONAStats: getSONA } = await import('../memory/sona-optimizer.js');
|
|
2731
|
+
const sStats = await getSONA();
|
|
2732
|
+
ruvllmStats.contrastiveTrainer = sStats._contrastiveTrainer || 'unavailable';
|
|
2733
|
+
}
|
|
2734
|
+
catch { /* not initialized */ }
|
|
2735
|
+
if (lora) {
|
|
2736
|
+
const ls = lora.getStats();
|
|
2737
|
+
ruvllmStats.trainingBackend = ls._trainingBackend || 'unavailable';
|
|
2738
|
+
}
|
|
2739
|
+
try {
|
|
2740
|
+
const { getGraphStats } = await import('../ruvector/graph-backend.js');
|
|
2741
|
+
const gs = await getGraphStats();
|
|
2742
|
+
ruvllmStats.graphDatabase = { backend: gs.backend, totalNodes: gs.totalNodes, totalEdges: gs.totalEdges, avgDegree: gs.avgDegree };
|
|
2743
|
+
}
|
|
2744
|
+
catch { /* not available */ }
|
|
2671
2745
|
const stats = {
|
|
2672
2746
|
sona: sonaStats,
|
|
2673
2747
|
moe: moeStats,
|
|
2674
2748
|
ewc: ewcStats,
|
|
2675
2749
|
flash: flashStats,
|
|
2676
2750
|
lora: loraStats,
|
|
2751
|
+
ruvllm: ruvllmStats,
|
|
2677
2752
|
hnsw: {
|
|
2678
2753
|
indexSize: memoryStats.memory.indexSize,
|
|
2679
2754
|
avgSearchTimeMs: 0.12,
|
|
@@ -131,7 +131,11 @@ async function generateEmbedding(text, dims = 384) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
// Hash-based deterministic embedding (better than pure random for consistency)
|
|
134
|
+
// NOTE: No semantic meaning — only useful for consistent deduplication, not similarity search
|
|
134
135
|
if (text) {
|
|
136
|
+
if (embeddingServiceName === 'none') {
|
|
137
|
+
embeddingServiceName = 'hash-fallback';
|
|
138
|
+
}
|
|
135
139
|
const hash = text.split('').reduce((acc, char, i) => {
|
|
136
140
|
return acc + char.charCodeAt(0) * (i + 1);
|
|
137
141
|
}, 0);
|
|
@@ -238,6 +242,7 @@ export const neuralTools = [
|
|
|
238
242
|
return {
|
|
239
243
|
success: true,
|
|
240
244
|
_realEmbedding: !!realEmbeddings,
|
|
245
|
+
_embeddingSource: embeddingServiceName,
|
|
241
246
|
embeddingProvider: embeddingServiceName,
|
|
242
247
|
modelId,
|
|
243
248
|
type: modelType,
|
|
@@ -307,6 +312,7 @@ export const neuralTools = [
|
|
|
307
312
|
return {
|
|
308
313
|
success: true,
|
|
309
314
|
_realEmbedding: !!realEmbeddings,
|
|
315
|
+
_embeddingSource: embeddingServiceName,
|
|
310
316
|
embeddingProvider: embeddingServiceName,
|
|
311
317
|
_hasStoredPatterns: storedPatterns.length > 0,
|
|
312
318
|
modelId: model?.id || 'default',
|
|
@@ -397,6 +403,7 @@ export const neuralTools = [
|
|
|
397
403
|
return {
|
|
398
404
|
success: true,
|
|
399
405
|
_realEmbedding: !!realEmbeddings,
|
|
406
|
+
_embeddingSource: embeddingServiceName,
|
|
400
407
|
embeddingProvider: embeddingServiceName,
|
|
401
408
|
patternId,
|
|
402
409
|
name: pattern.name,
|
|
@@ -420,6 +427,7 @@ export const neuralTools = [
|
|
|
420
427
|
return {
|
|
421
428
|
_realSimilarity: true,
|
|
422
429
|
_realEmbedding: !!realEmbeddings,
|
|
430
|
+
_embeddingSource: embeddingServiceName,
|
|
423
431
|
embeddingProvider: embeddingServiceName,
|
|
424
432
|
query,
|
|
425
433
|
results: results.map(r => ({
|
|
@@ -16,8 +16,32 @@ export const ruvllmWasmTools = [
|
|
|
16
16
|
handler: async () => {
|
|
17
17
|
try {
|
|
18
18
|
const mod = await loadRuvllmWasm();
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
const wasmStatus = await mod.getRuvllmStatus();
|
|
20
|
+
// Also include native ruvllm CJS backend status (ADR-086)
|
|
21
|
+
let nativeBackend = { available: false };
|
|
22
|
+
try {
|
|
23
|
+
const { getIntelligenceStats } = await import('../memory/intelligence.js');
|
|
24
|
+
const iStats = getIntelligenceStats();
|
|
25
|
+
const { getSONAStats } = await import('../memory/sona-optimizer.js');
|
|
26
|
+
const sStats = await getSONAStats();
|
|
27
|
+
nativeBackend = {
|
|
28
|
+
available: iStats._ruvllmBackend === 'active',
|
|
29
|
+
coordinator: iStats._ruvllmBackend || 'unavailable',
|
|
30
|
+
trajectories: iStats._ruvllmTrajectories || 0,
|
|
31
|
+
contrastiveTrainer: sStats._contrastiveTrainer !== 'unavailable' ? 'active' : 'unavailable',
|
|
32
|
+
trainingBackend: iStats._trainingBackend || 'unknown',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch { /* not initialized yet */ }
|
|
36
|
+
// Graph database status (ADR-087)
|
|
37
|
+
let graphStatus = { available: false };
|
|
38
|
+
try {
|
|
39
|
+
const { getGraphStats } = await import('../ruvector/graph-backend.js');
|
|
40
|
+
const gs = await getGraphStats();
|
|
41
|
+
graphStatus = { available: gs.backend === 'graph-node', ...gs };
|
|
42
|
+
}
|
|
43
|
+
catch { /* not loaded */ }
|
|
44
|
+
return { content: [{ type: 'text', text: JSON.stringify({ wasm: wasmStatus, native: nativeBackend, graph: graphStatus }, null, 2) }] };
|
|
21
45
|
}
|
|
22
46
|
catch (err) {
|
|
23
47
|
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
@@ -250,7 +250,15 @@ export declare function findSimilarPatterns(query: string, options?: {
|
|
|
250
250
|
/**
|
|
251
251
|
* Get intelligence system statistics
|
|
252
252
|
*/
|
|
253
|
-
export declare function getIntelligenceStats(): IntelligenceStats
|
|
253
|
+
export declare function getIntelligenceStats(): IntelligenceStats & {
|
|
254
|
+
_ruvllmBackend: string;
|
|
255
|
+
_ruvllmTrajectories: number;
|
|
256
|
+
_contrastiveTrainer?: {
|
|
257
|
+
triplets: number;
|
|
258
|
+
agents: number;
|
|
259
|
+
} | string;
|
|
260
|
+
_trainingBackend?: string;
|
|
261
|
+
};
|
|
254
262
|
/**
|
|
255
263
|
* Get SONA coordinator for advanced operations
|
|
256
264
|
*/
|
|
@@ -329,6 +337,11 @@ export declare function clearAllPatterns(): Promise<void>;
|
|
|
329
337
|
* Get the neural data directory path
|
|
330
338
|
*/
|
|
331
339
|
export declare function getNeuralDataDir(): string;
|
|
340
|
+
/**
|
|
341
|
+
* Trigger background learning on the @ruvector/ruvllm SonaCoordinator.
|
|
342
|
+
* No-op if ruvllm is not installed.
|
|
343
|
+
*/
|
|
344
|
+
export declare function runBackgroundLearning(): Promise<void>;
|
|
332
345
|
/**
|
|
333
346
|
* Get persistence status
|
|
334
347
|
*/
|
|
@@ -559,6 +559,26 @@ class LocalReasoningBank {
|
|
|
559
559
|
}
|
|
560
560
|
}
|
|
561
561
|
// ============================================================================
|
|
562
|
+
// @ruvector/ruvllm SonaCoordinator Integration
|
|
563
|
+
// ============================================================================
|
|
564
|
+
let ruvllmCoordinator = null;
|
|
565
|
+
let ruvllmLoaded = false;
|
|
566
|
+
async function loadRuvllmCoordinator() {
|
|
567
|
+
if (ruvllmLoaded)
|
|
568
|
+
return ruvllmCoordinator;
|
|
569
|
+
ruvllmLoaded = true;
|
|
570
|
+
try {
|
|
571
|
+
const { createRequire } = await import('module');
|
|
572
|
+
const requireCjs = createRequire(import.meta.url);
|
|
573
|
+
const ruvllm = requireCjs('@ruvector/ruvllm');
|
|
574
|
+
ruvllmCoordinator = new ruvllm.SonaCoordinator(ruvllm.DEFAULT_SONA_CONFIG);
|
|
575
|
+
return ruvllmCoordinator;
|
|
576
|
+
}
|
|
577
|
+
catch {
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
// ============================================================================
|
|
562
582
|
// Module State
|
|
563
583
|
// ============================================================================
|
|
564
584
|
let sonaCoordinator = null;
|
|
@@ -634,6 +654,8 @@ export async function initializeIntelligence(config) {
|
|
|
634
654
|
});
|
|
635
655
|
// Load persisted stats if available
|
|
636
656
|
loadPersistedStats();
|
|
657
|
+
// Eagerly load ruvllm coordinator so stats reflect backend status
|
|
658
|
+
await loadRuvllmCoordinator();
|
|
637
659
|
intelligenceInitialized = true;
|
|
638
660
|
return {
|
|
639
661
|
success: true,
|
|
@@ -773,6 +795,26 @@ export async function recordTrajectory(steps, verdict) {
|
|
|
773
795
|
}
|
|
774
796
|
}
|
|
775
797
|
}
|
|
798
|
+
// Forward trajectory to @ruvector/ruvllm SonaCoordinator if available
|
|
799
|
+
const ruvllmCoord = await loadRuvllmCoordinator();
|
|
800
|
+
if (ruvllmCoord) {
|
|
801
|
+
try {
|
|
802
|
+
const avgQuality = verdict === 'success' ? 1.0 : verdict === 'partial' ? 0.5 : 0.0;
|
|
803
|
+
ruvllmCoord.recordTrajectory({
|
|
804
|
+
steps: enrichedSteps.map(s => ({
|
|
805
|
+
state: s.content,
|
|
806
|
+
action: s.type,
|
|
807
|
+
reward: avgQuality,
|
|
808
|
+
embedding: s.embedding || []
|
|
809
|
+
})),
|
|
810
|
+
totalReward: avgQuality,
|
|
811
|
+
success: verdict === 'success'
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
catch {
|
|
815
|
+
// ruvllm recording failed silently
|
|
816
|
+
}
|
|
817
|
+
}
|
|
776
818
|
globalStats.trajectoriesRecorded++;
|
|
777
819
|
globalStats.lastAdaptation = Date.now();
|
|
778
820
|
savePersistedStats();
|
|
@@ -837,6 +879,19 @@ export async function findSimilarPatterns(query, options) {
|
|
|
837
879
|
export function getIntelligenceStats() {
|
|
838
880
|
const sonaStats = sonaCoordinator?.stats();
|
|
839
881
|
const bankStats = reasoningBank?.stats();
|
|
882
|
+
const ruvllmStats = ruvllmCoordinator?.stats?.() || null;
|
|
883
|
+
// Fetch cross-module stats for unified reporting
|
|
884
|
+
let contrastiveTrainer = 'unavailable';
|
|
885
|
+
let trainingBackend = 'unavailable';
|
|
886
|
+
try {
|
|
887
|
+
// Synchronous check — contrastiveTrainer is module-level in sona-optimizer
|
|
888
|
+
// We read it via the SONAOptimizer singleton if available
|
|
889
|
+
const sonaModule = globalThis.__claudeFlowSonaStats;
|
|
890
|
+
if (sonaModule) {
|
|
891
|
+
contrastiveTrainer = sonaModule._contrastiveTrainer || 'unavailable';
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
catch { /* not available */ }
|
|
840
895
|
return {
|
|
841
896
|
sonaEnabled: !!sonaCoordinator,
|
|
842
897
|
reasoningBankSize: bankStats?.size ?? 0,
|
|
@@ -844,7 +899,11 @@ export function getIntelligenceStats() {
|
|
|
844
899
|
signalsProcessed: globalStats.signalsProcessed,
|
|
845
900
|
trajectoriesRecorded: globalStats.trajectoriesRecorded,
|
|
846
901
|
lastAdaptation: globalStats.lastAdaptation,
|
|
847
|
-
avgAdaptationTime: sonaStats?.avgAdaptationMs ?? 0
|
|
902
|
+
avgAdaptationTime: sonaStats?.avgAdaptationMs ?? 0,
|
|
903
|
+
_ruvllmBackend: ruvllmStats ? 'active' : 'unavailable',
|
|
904
|
+
_ruvllmTrajectories: ruvllmStats?.trajectoriesBuffered || 0,
|
|
905
|
+
_contrastiveTrainer: contrastiveTrainer,
|
|
906
|
+
_trainingBackend: trainingBackend,
|
|
848
907
|
};
|
|
849
908
|
}
|
|
850
909
|
/**
|
|
@@ -1088,6 +1147,15 @@ export async function clearAllPatterns() {
|
|
|
1088
1147
|
export function getNeuralDataDir() {
|
|
1089
1148
|
return getDataDir();
|
|
1090
1149
|
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Trigger background learning on the @ruvector/ruvllm SonaCoordinator.
|
|
1152
|
+
* No-op if ruvllm is not installed.
|
|
1153
|
+
*/
|
|
1154
|
+
export async function runBackgroundLearning() {
|
|
1155
|
+
const coord = await loadRuvllmCoordinator();
|
|
1156
|
+
if (coord)
|
|
1157
|
+
coord.runBackgroundLoop();
|
|
1158
|
+
}
|
|
1091
1159
|
/**
|
|
1092
1160
|
* Get persistence status
|
|
1093
1161
|
*/
|
|
@@ -60,7 +60,7 @@ export interface RoutingSuggestion {
|
|
|
60
60
|
/** Whether Q-learning was used */
|
|
61
61
|
usedQLearning: boolean;
|
|
62
62
|
/** Source of recommendation */
|
|
63
|
-
source: 'sona-pattern' | 'q-learning' | 'keyword
|
|
63
|
+
source: 'sona-native' | 'sona-pattern' | 'q-learning' | 'sona-keyword' | 'default';
|
|
64
64
|
/** Alternative agents with scores */
|
|
65
65
|
alternatives: Array<{
|
|
66
66
|
agent: string;
|
|
@@ -87,6 +87,11 @@ export interface SONAStats {
|
|
|
87
87
|
qLearningEnabled: boolean;
|
|
88
88
|
/** Time of last learning update */
|
|
89
89
|
lastUpdate: number | null;
|
|
90
|
+
/** Contrastive trainer status (from @ruvector/ruvllm) */
|
|
91
|
+
_contrastiveTrainer?: {
|
|
92
|
+
triplets: number;
|
|
93
|
+
agents: number;
|
|
94
|
+
} | 'unavailable';
|
|
90
95
|
}
|
|
91
96
|
/**
|
|
92
97
|
* SONA Optimizer for adaptive routing based on trajectory outcomes
|
|
@@ -103,9 +108,20 @@ export declare class SONAOptimizer {
|
|
|
103
108
|
private persistencePath;
|
|
104
109
|
private qLearningRouter;
|
|
105
110
|
private qLearningEnabled;
|
|
111
|
+
/** Real @ruvector/sona engine — null if native not available, undefined if not yet tried */
|
|
112
|
+
private sonaEngine;
|
|
106
113
|
constructor(options?: {
|
|
107
114
|
persistencePath?: string;
|
|
108
115
|
});
|
|
116
|
+
/**
|
|
117
|
+
* Attempt to load the native @ruvector/sona engine (once).
|
|
118
|
+
* Sets `sonaEngine` to the engine instance or null if unavailable.
|
|
119
|
+
*/
|
|
120
|
+
private loadSonaEngine;
|
|
121
|
+
/**
|
|
122
|
+
* Infer an agent type string from a SONA pattern result object.
|
|
123
|
+
*/
|
|
124
|
+
private inferAgentFromPattern;
|
|
109
125
|
/**
|
|
110
126
|
* Initialize the optimizer and load persisted state
|
|
111
127
|
*/
|
|
@@ -124,13 +140,31 @@ export declare class SONAOptimizer {
|
|
|
124
140
|
keywordsExtracted: string[];
|
|
125
141
|
};
|
|
126
142
|
/**
|
|
127
|
-
* Get routing suggestion based on learned patterns
|
|
143
|
+
* Get routing suggestion based on learned patterns.
|
|
144
|
+
*
|
|
145
|
+
* Priority order:
|
|
146
|
+
* 1. Real @ruvector/sona native engine (if available and has matches)
|
|
147
|
+
* 2. SONA learned pattern matching (keyword overlap + confidence)
|
|
148
|
+
* 3. Q-learning router (if enabled)
|
|
149
|
+
* 4. Keyword heuristic
|
|
150
|
+
* 5. Default fallback
|
|
128
151
|
*/
|
|
129
|
-
getRoutingSuggestion(task: string): RoutingSuggestion
|
|
152
|
+
getRoutingSuggestion(task: string): Promise<RoutingSuggestion>;
|
|
130
153
|
/**
|
|
131
154
|
* Get optimizer statistics
|
|
132
155
|
*/
|
|
133
156
|
getStats(): SONAStats;
|
|
157
|
+
/**
|
|
158
|
+
* Trigger contrastive training on accumulated agent embeddings.
|
|
159
|
+
* Returns training metrics or { trained: false } if insufficient data.
|
|
160
|
+
*
|
|
161
|
+
* @param _epochs - reserved for future use (epochs are set at ContrastiveTrainer construction)
|
|
162
|
+
*/
|
|
163
|
+
trainAgentEmbeddings(_epochs?: number): Promise<{
|
|
164
|
+
trained: boolean;
|
|
165
|
+
loss?: number;
|
|
166
|
+
triplets?: number;
|
|
167
|
+
}>;
|
|
134
168
|
/**
|
|
135
169
|
* Apply temporal decay to pattern confidence
|
|
136
170
|
* Reduces confidence of unused patterns
|
|
@@ -148,6 +182,12 @@ export declare class SONAOptimizer {
|
|
|
148
182
|
* Import patterns (for migration or testing)
|
|
149
183
|
*/
|
|
150
184
|
importPatterns(patterns: Record<string, LearnedPattern>): number;
|
|
185
|
+
/**
|
|
186
|
+
* Convert extracted keywords into a lightweight 384-dim embedding proxy.
|
|
187
|
+
* Uses a deterministic hash-scatter so each keyword set maps to a
|
|
188
|
+
* consistent unit-length vector compatible with ContrastiveTrainer.
|
|
189
|
+
*/
|
|
190
|
+
private keywordsToEmbedding;
|
|
151
191
|
/**
|
|
152
192
|
* Extract meaningful keywords from task description
|
|
153
193
|
*/
|