claude-flow 3.18.0 → 3.18.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.
- package/package.json +3 -2
- package/v3/@claude-flow/cli/dist/src/commands/neural.js +28 -6
- package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +20 -5
- package/v3/@claude-flow/cli/dist/src/ruvector/lora-adapter.d.ts +17 -0
- package/v3/@claude-flow/cli/dist/src/ruvector/lora-adapter.js +57 -4
- 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.18.
|
|
3
|
+
"version": "3.18.2",
|
|
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",
|
|
@@ -116,7 +116,8 @@
|
|
|
116
116
|
"ws": ">=8.21.0",
|
|
117
117
|
"@grpc/grpc-js": ">=1.14.4",
|
|
118
118
|
"form-data": ">=4.0.6",
|
|
119
|
-
"http-proxy-middleware": ">=3.0.7"
|
|
119
|
+
"http-proxy-middleware": ">=3.0.7",
|
|
120
|
+
"@ruvector/ruvllm": ">=2.5.7"
|
|
120
121
|
},
|
|
121
122
|
"devDependencies": {
|
|
122
123
|
"@openai/codex": "^0.98.0",
|
|
@@ -451,17 +451,39 @@ const statusCommand = {
|
|
|
451
451
|
},
|
|
452
452
|
{
|
|
453
453
|
component: 'Contrastive Trainer',
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
// #2549 — three states: live session (object with counts),
|
|
455
|
+
// 'available' (module resolves, no in-process session — the
|
|
456
|
+
// normal case for a read-only status process), 'unavailable'
|
|
457
|
+
// (module genuinely does not resolve).
|
|
458
|
+
status: typeof stats._contrastiveTrainer === 'object'
|
|
459
|
+
? output.success('Active')
|
|
460
|
+
: stats._contrastiveTrainer === 'available'
|
|
461
|
+
? output.success('Available')
|
|
462
|
+
: output.dim('Unavailable'),
|
|
463
|
+
details: typeof stats._contrastiveTrainer === 'object'
|
|
456
464
|
? `${stats._contrastiveTrainer.triplets ?? 0} triplets, ${stats._contrastiveTrainer.agents ?? 0} agents`
|
|
457
|
-
:
|
|
465
|
+
: stats._contrastiveTrainer === 'available'
|
|
466
|
+
? 'ready — trains in-process on demand'
|
|
467
|
+
: 'Install @ruvector/ruvllm',
|
|
458
468
|
},
|
|
459
469
|
{
|
|
460
470
|
component: 'Training Pipeline',
|
|
461
|
-
status: stats._trainingBackend === 'ruvllm' ? output.success('
|
|
471
|
+
status: stats._trainingBackend === 'ruvllm' ? output.success('Available') : output.dim(stats._trainingBackend || 'Unavailable'),
|
|
472
|
+
// Checkpoint capability is version-gated: saveCheckpoint(path)
|
|
473
|
+
// was a silent no-op before @ruvector/ruvllm 2.5.7 (#2549).
|
|
462
474
|
details: stats._trainingBackend === 'ruvllm'
|
|
463
|
-
?
|
|
464
|
-
|
|
475
|
+
? await (async () => {
|
|
476
|
+
try {
|
|
477
|
+
const { nativeCheckpointsSupported } = await import('../ruvector/lora-adapter.js');
|
|
478
|
+
return nativeCheckpointsSupported()
|
|
479
|
+
? 'native @ruvector/ruvllm pipeline + disk checkpoints'
|
|
480
|
+
: 'native @ruvector/ruvllm pipeline (checkpoints need >=2.5.7)';
|
|
481
|
+
}
|
|
482
|
+
catch {
|
|
483
|
+
return 'native @ruvector/ruvllm pipeline';
|
|
484
|
+
}
|
|
485
|
+
})()
|
|
486
|
+
: 'JS fallback',
|
|
465
487
|
},
|
|
466
488
|
await (async () => {
|
|
467
489
|
try {
|
|
@@ -14,6 +14,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
|
14
14
|
import { homedir } from 'node:os';
|
|
15
15
|
import { createRequire } from 'node:module';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
|
+
import { resolveTrainingBackend } from '../ruvector/lora-adapter.js';
|
|
17
18
|
// ============================================================================
|
|
18
19
|
// Persistence Configuration
|
|
19
20
|
// ============================================================================
|
|
@@ -1006,15 +1007,29 @@ export function getIntelligenceStats() {
|
|
|
1006
1007
|
loadRuvllmCoordinatorSync();
|
|
1007
1008
|
}
|
|
1008
1009
|
const ruvllmStats = ruvllmCoordinator?.stats?.() || null;
|
|
1009
|
-
// Fetch cross-module stats for unified reporting
|
|
1010
|
+
// Fetch cross-module stats for unified reporting.
|
|
1011
|
+
//
|
|
1012
|
+
// #2549 — two prior defects here: `trainingBackend` was declared and
|
|
1013
|
+
// returned but never assigned (always 'unavailable'), and contrastive
|
|
1014
|
+
// availability was read ONLY from an in-process global that a fresh
|
|
1015
|
+
// read-only `neural status` process never populates. Both made the
|
|
1016
|
+
// native @ruvector/ruvllm path invisible even when installed. Backend
|
|
1017
|
+
// now comes from the lora-adapter's capability probe; the global still
|
|
1018
|
+
// wins when present because it carries live in-process session counts.
|
|
1010
1019
|
let contrastiveTrainer = 'unavailable';
|
|
1011
1020
|
let trainingBackend = 'unavailable';
|
|
1012
1021
|
try {
|
|
1013
|
-
|
|
1014
|
-
|
|
1022
|
+
trainingBackend = resolveTrainingBackend();
|
|
1023
|
+
}
|
|
1024
|
+
catch { /* module absent — stay 'unavailable' */ }
|
|
1025
|
+
try {
|
|
1015
1026
|
const sonaModule = globalThis.__claudeFlowSonaStats;
|
|
1016
|
-
if (sonaModule) {
|
|
1017
|
-
contrastiveTrainer = sonaModule._contrastiveTrainer
|
|
1027
|
+
if (sonaModule?._contrastiveTrainer) {
|
|
1028
|
+
contrastiveTrainer = sonaModule._contrastiveTrainer;
|
|
1029
|
+
}
|
|
1030
|
+
else if (trainingBackend === 'ruvllm') {
|
|
1031
|
+
// Module resolves but no in-process session — available, idle.
|
|
1032
|
+
contrastiveTrainer = 'available';
|
|
1018
1033
|
}
|
|
1019
1034
|
}
|
|
1020
1035
|
catch { /* not available */ }
|
|
@@ -97,6 +97,23 @@ export interface LoRAStats {
|
|
|
97
97
|
/** Training backend in use ('ruvllm' | 'js-fallback') */
|
|
98
98
|
_trainingBackend?: string;
|
|
99
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Which training backend a train call would use — WITHOUT loading the
|
|
102
|
+
* pipeline (#2549). Before this existed, status surfaces read module state
|
|
103
|
+
* that only a prior in-process train populates, so a fresh read-only
|
|
104
|
+
* process always reported 'js-fallback'/'unavailable' even with
|
|
105
|
+
* @ruvector/ruvllm installed. The pipeline stays lazy: this only probes
|
|
106
|
+
* module resolution.
|
|
107
|
+
*/
|
|
108
|
+
export declare function resolveTrainingBackend(): 'ruvllm' | 'js-fallback';
|
|
109
|
+
/**
|
|
110
|
+
* Whether the resolved @ruvector/ruvllm persists checkpoints to disk.
|
|
111
|
+
* saveCheckpoint(path) was a silent no-op (private, void, wrote 0 bytes)
|
|
112
|
+
* before 2.5.7 — status surfaces must not advertise checkpoints against
|
|
113
|
+
* older versions. Reads the resolved package's version; the package does
|
|
114
|
+
* not export ./package.json, so walk up from the resolved entry instead.
|
|
115
|
+
*/
|
|
116
|
+
export declare function nativeCheckpointsSupported(): boolean;
|
|
100
117
|
/**
|
|
101
118
|
* Low-Rank Adaptation module for efficient embedding fine-tuning
|
|
102
119
|
*/
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
21
21
|
import { dirname, join } from 'path';
|
|
22
|
+
import { createRequire } from 'module';
|
|
22
23
|
// ============================================================================
|
|
23
24
|
// Types & Constants
|
|
24
25
|
// ============================================================================
|
|
@@ -57,6 +58,53 @@ const DEFAULT_CONFIG = {
|
|
|
57
58
|
// ============================================================================
|
|
58
59
|
let ruvllmPipeline = null;
|
|
59
60
|
let pipelineLoaded = false;
|
|
61
|
+
/**
|
|
62
|
+
* Which training backend a train call would use — WITHOUT loading the
|
|
63
|
+
* pipeline (#2549). Before this existed, status surfaces read module state
|
|
64
|
+
* that only a prior in-process train populates, so a fresh read-only
|
|
65
|
+
* process always reported 'js-fallback'/'unavailable' even with
|
|
66
|
+
* @ruvector/ruvllm installed. The pipeline stays lazy: this only probes
|
|
67
|
+
* module resolution.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveTrainingBackend() {
|
|
70
|
+
if (pipelineLoaded)
|
|
71
|
+
return ruvllmPipeline ? 'ruvllm' : 'js-fallback';
|
|
72
|
+
try {
|
|
73
|
+
createRequire(import.meta.url).resolve('@ruvector/ruvllm');
|
|
74
|
+
return 'ruvllm';
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return 'js-fallback';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Whether the resolved @ruvector/ruvllm persists checkpoints to disk.
|
|
82
|
+
* saveCheckpoint(path) was a silent no-op (private, void, wrote 0 bytes)
|
|
83
|
+
* before 2.5.7 — status surfaces must not advertise checkpoints against
|
|
84
|
+
* older versions. Reads the resolved package's version; the package does
|
|
85
|
+
* not export ./package.json, so walk up from the resolved entry instead.
|
|
86
|
+
*/
|
|
87
|
+
export function nativeCheckpointsSupported() {
|
|
88
|
+
try {
|
|
89
|
+
const req = createRequire(import.meta.url);
|
|
90
|
+
let dir = dirname(req.resolve('@ruvector/ruvllm'));
|
|
91
|
+
for (let i = 0; i < 5; i++) {
|
|
92
|
+
const pkgPath = join(dir, 'package.json');
|
|
93
|
+
if (existsSync(pkgPath)) {
|
|
94
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
95
|
+
if (pkg.name !== '@ruvector/ruvllm') {
|
|
96
|
+
dir = dirname(dir);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const [maj, min, pat] = String(pkg.version).split('.').map(Number);
|
|
100
|
+
return maj > 2 || (maj === 2 && (min > 5 || (min === 5 && pat >= 7)));
|
|
101
|
+
}
|
|
102
|
+
dir = dirname(dir);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch { /* unresolved — no native checkpoints */ }
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
60
108
|
async function loadTrainingPipeline(adapter) {
|
|
61
109
|
if (pipelineLoaded)
|
|
62
110
|
return ruvllmPipeline;
|
|
@@ -295,9 +343,7 @@ export class LoRAAdapter {
|
|
|
295
343
|
? this.adaptationNormSum / this.totalAdaptations
|
|
296
344
|
: 0,
|
|
297
345
|
lastUpdate: this.lastUpdate,
|
|
298
|
-
_trainingBackend:
|
|
299
|
-
? (ruvllmPipeline ? 'ruvllm' : 'js-fallback')
|
|
300
|
-
: 'js-fallback',
|
|
346
|
+
_trainingBackend: resolveTrainingBackend(),
|
|
301
347
|
};
|
|
302
348
|
}
|
|
303
349
|
/**
|
|
@@ -390,11 +436,18 @@ export class LoRAAdapter {
|
|
|
390
436
|
* Falls back to writing our own weight JSON if ruvllm is unavailable.
|
|
391
437
|
*/
|
|
392
438
|
async saveCheckpoint(path) {
|
|
439
|
+
// Parent dir must exist for BOTH paths: ruvllm <2.5.7 never wrote a
|
|
440
|
+
// file at all, and the JS fallback's writeFileSync throws ENOENT on a
|
|
441
|
+
// missing dir — which the catch silently converted to `false` (#2549).
|
|
442
|
+
try {
|
|
443
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
444
|
+
}
|
|
445
|
+
catch { /* fs errors surface on write below */ }
|
|
393
446
|
const pipeline = await loadTrainingPipeline(this);
|
|
394
447
|
if (pipeline) {
|
|
395
448
|
try {
|
|
396
449
|
pipeline.saveCheckpoint(path);
|
|
397
|
-
// Verify ruvllm actually wrote the file (
|
|
450
|
+
// Verify ruvllm actually wrote the file (<2.5.7 is a silent no-op)
|
|
398
451
|
const fs = await import('fs');
|
|
399
452
|
if (fs.existsSync(path))
|
|
400
453
|
return true;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.18.
|
|
3
|
+
"version": "3.18.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|