claude-flow 3.18.2 → 3.19.0
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
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",
|
|
@@ -23,6 +23,7 @@ const trainCommand = {
|
|
|
23
23
|
{ name: 'hyperbolic', type: 'boolean', description: 'Enable hyperbolic attention for hierarchical patterns', default: 'false' },
|
|
24
24
|
{ name: 'contrastive', type: 'boolean', description: 'Use contrastive learning (InfoNCE)', default: 'true' },
|
|
25
25
|
{ name: 'curriculum', type: 'boolean', description: 'Enable curriculum learning', default: 'false' },
|
|
26
|
+
{ name: 'backend', type: 'string', description: 'Training backend: auto (native when available), native (@ruvector/ruvllm TrainingPipeline, disk checkpoints), wasm (RuVector MicroLoRA/InfoNCE)', default: 'auto' },
|
|
26
27
|
],
|
|
27
28
|
examples: [
|
|
28
29
|
{ command: 'claude-flow neural train -p coordination -e 100', description: 'Train coordination patterns' },
|
|
@@ -35,6 +36,11 @@ const trainCommand = {
|
|
|
35
36
|
const learningRate = parseFloat(ctx.flags['learning-rate'] || '0.01');
|
|
36
37
|
const batchSize = parseInt(ctx.flags['batch-size'] || '32', 10);
|
|
37
38
|
const dim = Math.min(parseInt(ctx.flags.dim || '256', 10), 256);
|
|
39
|
+
// #2549 follow-up — backend routing: 'native' = @ruvector/ruvllm
|
|
40
|
+
// TrainingPipeline (real epochs/early-stopping/disk checkpoints),
|
|
41
|
+
// 'wasm' = RuVector MicroLoRA/InfoNCE (pre-3.19 behavior),
|
|
42
|
+
// 'auto' = native when the module resolves, else wasm.
|
|
43
|
+
const backendFlag = String(ctx.flags.backend || 'auto');
|
|
38
44
|
const useWasm = ctx.flags.wasm !== false;
|
|
39
45
|
const useFlash = ctx.flags.flash !== false;
|
|
40
46
|
const useMoE = ctx.flags.moe === true;
|
|
@@ -181,6 +187,34 @@ const trainCommand = {
|
|
|
181
187
|
}
|
|
182
188
|
}
|
|
183
189
|
spinner.setText(`Training with ${embeddings.length} embeddings...`);
|
|
190
|
+
// #2549 — native TrainingPipeline leg. In 'auto'/'native' mode the
|
|
191
|
+
// LoRA training runs through @ruvector/ruvllm with the checkpoint
|
|
192
|
+
// taken from the TRAINED pipeline (the old best-effort block saved
|
|
193
|
+
// a fresh adapter's untrained weights). SONA/ReasoningBank
|
|
194
|
+
// persistence in the loop below runs regardless of backend.
|
|
195
|
+
const nativeTraining = await import('../services/native-training.js');
|
|
196
|
+
const useNative = backendFlag === 'native'
|
|
197
|
+
|| (backendFlag === 'auto' && nativeTraining.nativeTrainingAvailable());
|
|
198
|
+
let nativeResult = null;
|
|
199
|
+
if (useNative) {
|
|
200
|
+
spinner.setText(`Training ${patternType} on native @ruvector/ruvllm pipeline...`);
|
|
201
|
+
const path = await import('path');
|
|
202
|
+
nativeResult = await nativeTraining.runNativeTraining({
|
|
203
|
+
embeddings,
|
|
204
|
+
epochs,
|
|
205
|
+
batchSize,
|
|
206
|
+
learningRate,
|
|
207
|
+
dim,
|
|
208
|
+
checkpointPath: path.join(process.cwd(), '.claude-flow', 'neural', `lora-checkpoint-${Date.now()}.json`),
|
|
209
|
+
});
|
|
210
|
+
if (!nativeResult && backendFlag === 'native') {
|
|
211
|
+
spinner.fail('Native backend requested (--backend native) but @ruvector/ruvllm training failed');
|
|
212
|
+
return { success: false, exitCode: 1 };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Native handles the LoRA leg; WASM contrastive runs when native
|
|
216
|
+
// didn't (absent module, or explicit --backend wasm).
|
|
217
|
+
const runWasmLeg = !nativeResult;
|
|
184
218
|
// Main training loop with WASM acceleration
|
|
185
219
|
for (let epoch = 0; epoch < epochs; epoch++) {
|
|
186
220
|
const epochStart = performance.now();
|
|
@@ -192,7 +226,7 @@ const trainCommand = {
|
|
|
192
226
|
if (batch.length === 0)
|
|
193
227
|
continue;
|
|
194
228
|
// Training step with contrastive learning
|
|
195
|
-
if (useContrastive && batch.length >= 3 && useWasm && wasmFeatures.length > 0) {
|
|
229
|
+
if (runWasmLeg && useContrastive && batch.length >= 3 && useWasm && wasmFeatures.length > 0) {
|
|
196
230
|
const anchor = batch[0];
|
|
197
231
|
const positives = [batch[1]];
|
|
198
232
|
const negatives = batch.slice(2);
|
|
@@ -260,17 +294,22 @@ const trainCommand = {
|
|
|
260
294
|
// Flush patterns to disk
|
|
261
295
|
flushPatterns();
|
|
262
296
|
const persistence = getPersistenceStatus();
|
|
263
|
-
//
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
297
|
+
// Checkpoint: when the native pipeline trained, its checkpoint (the
|
|
298
|
+
// TRAINED weights) was already written by runNativeTraining. The
|
|
299
|
+
// pre-3.19 fallback below saved a FRESH adapter's weights — only
|
|
300
|
+
// meaningful as a fallback when the native leg didn't run.
|
|
301
|
+
if (!nativeResult?.checkpointPath) {
|
|
302
|
+
try {
|
|
303
|
+
const { LoRAAdapter } = await import('../ruvector/lora-adapter.js');
|
|
304
|
+
const path = await import('path');
|
|
305
|
+
const cpDir = path.join(process.cwd(), '.claude-flow', 'neural');
|
|
306
|
+
const cpPath = path.join(cpDir, `lora-checkpoint-${Date.now()}.json`);
|
|
307
|
+
const adapter = new LoRAAdapter({ inputDim: dim, outputDim: dim, rank: 4 });
|
|
308
|
+
await adapter.initBackend();
|
|
309
|
+
await adapter.saveCheckpoint(cpPath);
|
|
310
|
+
}
|
|
311
|
+
catch { /* checkpoint save is best-effort */ }
|
|
272
312
|
}
|
|
273
|
-
catch { /* checkpoint save is best-effort */ }
|
|
274
313
|
output.writeln();
|
|
275
314
|
// Display results
|
|
276
315
|
const tableData = [
|
|
@@ -284,8 +323,18 @@ const trainCommand = {
|
|
|
284
323
|
{ metric: 'Total Time', value: `${(totalTime / 1000).toFixed(1)}s` },
|
|
285
324
|
{ metric: 'Avg Epoch Time', value: `${(epochTimes.reduce((a, b) => a + b, 0) / epochTimes.length).toFixed(2)}ms` },
|
|
286
325
|
];
|
|
326
|
+
// Native pipeline metrics (#2549 — the LoRA leg trained on ruvllm)
|
|
327
|
+
if (nativeResult) {
|
|
328
|
+
tableData.push({ metric: 'Backend', value: 'native (@ruvector/ruvllm TrainingPipeline)' }, { metric: 'Native Steps', value: String(nativeResult.steps) }, { metric: 'Final Loss', value: nativeResult.finalLoss.toExponential(3) }, { metric: 'Early Stopped', value: nativeResult.earlyStopped ? 'yes' : 'no' });
|
|
329
|
+
if (nativeResult.checkpointPath) {
|
|
330
|
+
tableData.push({
|
|
331
|
+
metric: 'Checkpoint',
|
|
332
|
+
value: `${nativeResult.checkpointPath}${nativeResult.checkpointBytes ? ` (${(nativeResult.checkpointBytes / 1024).toFixed(1)} KB)` : ''}`,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
}
|
|
287
336
|
// Add WASM-specific metrics
|
|
288
|
-
if (useWasm && wasmFeatures.length > 0) {
|
|
337
|
+
if (runWasmLeg && useWasm && wasmFeatures.length > 0) {
|
|
289
338
|
const backendUsed = ruvectorStats?.backend || 'unknown';
|
|
290
339
|
tableData.push({ metric: 'Backend', value: backendUsed === 'wasm' ? 'WASM (native)' : 'JS (fallback)' }, { metric: 'WASM Features', value: wasmFeatures.slice(0, 3).join(', ') }, { metric: 'LoRA Adaptations', value: String(adaptations) }, { metric: 'Avg Loss', value: (totalLoss / Math.max(1, epochs)).toFixed(4) });
|
|
291
340
|
if (ruvectorStats?.microLoraStats) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native training via @ruvector/ruvllm's TrainingPipeline (#2549 follow-up).
|
|
3
|
+
*
|
|
4
|
+
* `neural train` historically trained only on the RuVector WASM path
|
|
5
|
+
* (MicroLoRA + InfoNCE) and its "checkpoint" was a freshly-constructed
|
|
6
|
+
* adapter's weights — the native TrainingPipeline (real epochs, loss
|
|
7
|
+
* history, early stopping, EWC registration, disk checkpoints since
|
|
8
|
+
* ruvllm 2.5.7) was never exercised. This service routes the LoRA
|
|
9
|
+
* training leg through it.
|
|
10
|
+
*
|
|
11
|
+
* Batch formulation: pattern-alignment pairs — input = embedding[i],
|
|
12
|
+
* target = embedding[i+1 mod n], quality 1.0 — the MSE analogue of the
|
|
13
|
+
* WASM path's anchor→positive contrastive objective (adjacent training
|
|
14
|
+
* items belong to the same pattern family by construction).
|
|
15
|
+
*
|
|
16
|
+
* Graceful: returns null when @ruvector/ruvllm is absent or anything
|
|
17
|
+
* throws — callers fall back to the WASM path.
|
|
18
|
+
*/
|
|
19
|
+
export interface NativeTrainingResult {
|
|
20
|
+
epochs: number;
|
|
21
|
+
steps: number;
|
|
22
|
+
finalLoss: number;
|
|
23
|
+
bestValLoss: number | null;
|
|
24
|
+
durationMs: number;
|
|
25
|
+
earlyStopped: boolean;
|
|
26
|
+
checkpointPath?: string;
|
|
27
|
+
checkpointBytes?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface NativeTrainingOptions {
|
|
30
|
+
embeddings: Float32Array[];
|
|
31
|
+
epochs: number;
|
|
32
|
+
batchSize: number;
|
|
33
|
+
learningRate: number;
|
|
34
|
+
dim: number;
|
|
35
|
+
/** When set, the TRAINED pipeline checkpoints here (ruvllm >=2.5.7). */
|
|
36
|
+
checkpointPath?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function nativeTrainingAvailable(): boolean;
|
|
39
|
+
export declare function runNativeTraining(opts: NativeTrainingOptions): Promise<NativeTrainingResult | null>;
|
|
40
|
+
//# sourceMappingURL=native-training.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native training via @ruvector/ruvllm's TrainingPipeline (#2549 follow-up).
|
|
3
|
+
*
|
|
4
|
+
* `neural train` historically trained only on the RuVector WASM path
|
|
5
|
+
* (MicroLoRA + InfoNCE) and its "checkpoint" was a freshly-constructed
|
|
6
|
+
* adapter's weights — the native TrainingPipeline (real epochs, loss
|
|
7
|
+
* history, early stopping, EWC registration, disk checkpoints since
|
|
8
|
+
* ruvllm 2.5.7) was never exercised. This service routes the LoRA
|
|
9
|
+
* training leg through it.
|
|
10
|
+
*
|
|
11
|
+
* Batch formulation: pattern-alignment pairs — input = embedding[i],
|
|
12
|
+
* target = embedding[i+1 mod n], quality 1.0 — the MSE analogue of the
|
|
13
|
+
* WASM path's anchor→positive contrastive objective (adjacent training
|
|
14
|
+
* items belong to the same pattern family by construction).
|
|
15
|
+
*
|
|
16
|
+
* Graceful: returns null when @ruvector/ruvllm is absent or anything
|
|
17
|
+
* throws — callers fall back to the WASM path.
|
|
18
|
+
*/
|
|
19
|
+
import { createRequire } from 'module';
|
|
20
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
21
|
+
import { dirname } from 'path';
|
|
22
|
+
export function nativeTrainingAvailable() {
|
|
23
|
+
try {
|
|
24
|
+
createRequire(import.meta.url).resolve('@ruvector/ruvllm');
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function runNativeTraining(opts) {
|
|
32
|
+
const { embeddings, epochs, batchSize, learningRate, dim, checkpointPath } = opts;
|
|
33
|
+
if (embeddings.length < 2)
|
|
34
|
+
return null;
|
|
35
|
+
try {
|
|
36
|
+
const req = createRequire(import.meta.url);
|
|
37
|
+
const ruvllm = req('@ruvector/ruvllm');
|
|
38
|
+
const pipeline = new ruvllm.TrainingPipeline({
|
|
39
|
+
learningRate,
|
|
40
|
+
batchSize,
|
|
41
|
+
epochs,
|
|
42
|
+
inputDim: dim,
|
|
43
|
+
outputDim: dim,
|
|
44
|
+
});
|
|
45
|
+
// Pattern-alignment pairs, chunked into pipeline batches.
|
|
46
|
+
const inputs = [];
|
|
47
|
+
const targets = [];
|
|
48
|
+
const qualities = [];
|
|
49
|
+
for (let i = 0; i < embeddings.length; i++) {
|
|
50
|
+
inputs.push(Array.from(embeddings[i]));
|
|
51
|
+
targets.push(Array.from(embeddings[(i + 1) % embeddings.length]));
|
|
52
|
+
qualities.push(1.0);
|
|
53
|
+
}
|
|
54
|
+
for (let i = 0; i < inputs.length; i += batchSize) {
|
|
55
|
+
pipeline.addBatch(inputs.slice(i, i + batchSize), targets.slice(i, i + batchSize), qualities.slice(i, i + batchSize));
|
|
56
|
+
}
|
|
57
|
+
const r = pipeline.train();
|
|
58
|
+
const result = {
|
|
59
|
+
epochs: r.epochs,
|
|
60
|
+
steps: r.steps,
|
|
61
|
+
finalLoss: r.finalLoss,
|
|
62
|
+
bestValLoss: r.bestValLoss ?? null,
|
|
63
|
+
durationMs: r.durationMs,
|
|
64
|
+
earlyStopped: !!r.earlyStopped,
|
|
65
|
+
};
|
|
66
|
+
if (checkpointPath) {
|
|
67
|
+
try {
|
|
68
|
+
mkdirSync(dirname(checkpointPath), { recursive: true });
|
|
69
|
+
const saved = pipeline.saveCheckpoint(checkpointPath);
|
|
70
|
+
// <2.5.7 returns undefined and writes nothing — verify on disk.
|
|
71
|
+
if (existsSync(checkpointPath)) {
|
|
72
|
+
result.checkpointPath = checkpointPath;
|
|
73
|
+
result.checkpointBytes = saved?.bytes;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch { /* checkpoint is best-effort; training result stands */ }
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=native-training.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
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",
|