@claude-flow/cli 3.10.14 → 3.10.16
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/dist/src/mcp-tools/hooks-tools.d.ts +7 -0
- package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hooks-tools.js +91 -0
- package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
- package/dist/src/mcp-tools/neural-tools.d.ts +11 -0
- package/dist/src/mcp-tools/neural-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/neural-tools.js +20 -0
- package/dist/src/mcp-tools/neural-tools.js.map +1 -1
- package/dist/src/memory/intelligence.d.ts +45 -0
- package/dist/src/memory/intelligence.d.ts.map +1 -1
- package/dist/src/memory/intelligence.js +72 -0
- package/dist/src/memory/intelligence.js.map +1 -1
- package/dist/src/memory/memory-bridge.d.ts +15 -0
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +37 -0
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/memory/structured-distill.d.ts +48 -0
- package/dist/src/memory/structured-distill.d.ts.map +1 -0
- package/dist/src/memory/structured-distill.js +125 -0
- package/dist/src/memory/structured-distill.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/benchmark-self-learning.mjs +26 -0
- package/scripts/benchmark-trajectory-mrr.mjs +191 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.16",
|
|
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",
|
|
@@ -125,6 +125,14 @@ async function main() {
|
|
|
125
125
|
}
|
|
126
126
|
const dtE = performance.now() - tE;
|
|
127
127
|
|
|
128
|
+
// -------------------------------------------------------------------------
|
|
129
|
+
// §F — getUnifiedLearningStats (ADR-075)
|
|
130
|
+
// -------------------------------------------------------------------------
|
|
131
|
+
const tF = performance.now();
|
|
132
|
+
const unified = await intel.getUnifiedLearningStats();
|
|
133
|
+
const dtF = performance.now() - tF;
|
|
134
|
+
const unifiedOk = unified.global && unified.sona && unified.memoryBridge && unified.neuralPatterns && unified.consistency;
|
|
135
|
+
|
|
128
136
|
// -------------------------------------------------------------------------
|
|
129
137
|
// Summary
|
|
130
138
|
// -------------------------------------------------------------------------
|
|
@@ -170,6 +178,22 @@ async function main() {
|
|
|
170
178
|
note: 'MCP trajectory tools feed sonaCoordinator (see hooks_intelligence_stats), not globalStats — observable outcomes checked here',
|
|
171
179
|
elapsedMs: Number(dtE.toFixed(2)),
|
|
172
180
|
},
|
|
181
|
+
F_unifiedStats: {
|
|
182
|
+
shape: ['global', 'sona', 'memoryBridge', 'neuralPatterns', 'consistency'],
|
|
183
|
+
observed: {
|
|
184
|
+
'global.patternsLearned': unified.global.patternsLearned,
|
|
185
|
+
'global.trajectoriesRecorded': unified.global.trajectoriesRecorded,
|
|
186
|
+
'global.signalsProcessed': unified.global.signalsProcessed,
|
|
187
|
+
'memoryBridge.totalEntries': unified.memoryBridge.totalEntries,
|
|
188
|
+
'memoryBridge.reachable': unified.memoryBridge.reachable,
|
|
189
|
+
'neuralPatterns.patternCount': unified.neuralPatterns.patternCount,
|
|
190
|
+
'sona.available': unified.sona.available,
|
|
191
|
+
'consistency.notes': unified.consistency.notes.length,
|
|
192
|
+
},
|
|
193
|
+
passed: !!unifiedOk,
|
|
194
|
+
note: 'ADR-075 — one aggregator across the 4 stores. Each sub-view names its source.',
|
|
195
|
+
elapsedMs: Number(dtF.toFixed(2)),
|
|
196
|
+
},
|
|
173
197
|
},
|
|
174
198
|
finalState: {
|
|
175
199
|
signalsProcessed: A_after.signalsProcessed,
|
|
@@ -194,6 +218,8 @@ async function main() {
|
|
|
194
218
|
console.log(`| C task-completed (record-only) | ${N} | trajectories+${summary.sections.C_taskCompleted_recordedOnly.trajectoriesDelta} (expected 0) | ${summary.sections.C_taskCompleted_recordedOnly.passed ? '✅' : '❌'} | ${summary.sections.C_taskCompleted_recordedOnly.elapsedMs} |`);
|
|
195
219
|
console.log(`| D pretrain → neural_patterns | ${items.length} | stored=${summary.sections.D_pretrain_neuralPatterns.stored}, listed=${summary.sections.D_pretrain_neuralPatterns.listTotal} | ${summary.sections.D_pretrain_neuralPatterns.passed ? '✅' : '❌'} | ${summary.sections.D_pretrain_neuralPatterns.elapsedMs} |`);
|
|
196
220
|
console.log(`| E multi-step trajectory | ${summary.sections.E_multiStepTrajectory.cycles} | persisted=${summary.sections.E_multiStepTrajectory.persistedCount}, sonaUpdate=${summary.sections.E_multiStepTrajectory.sonaUpdateCount} | ${summary.sections.E_multiStepTrajectory.passed ? '✅' : '❌'} | ${summary.sections.E_multiStepTrajectory.elapsedMs} |`);
|
|
221
|
+
const f = summary.sections.F_unifiedStats;
|
|
222
|
+
console.log(`| F unified-stats | 4 stores | bridge.reachable=${f.observed['memoryBridge.reachable']}, sona.available=${f.observed['sona.available']}, neural.count=${f.observed['neuralPatterns.patternCount']}, notes=${f.observed['consistency.notes']} | ${f.passed ? '✅' : '❌'} | ${f.elapsedMs} |`);
|
|
197
223
|
console.log('');
|
|
198
224
|
console.log(`Final state: signalsProcessed=${summary.finalState.signalsProcessed}, trajectoriesRecorded=${summary.finalState.trajectoriesRecorded}, patternsLearned=${summary.finalState.patternsLearned}`);
|
|
199
225
|
console.log(`Overall: ${allPassed ? '✅ ALL PASSED' : '❌ FAILED'}`);
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// benchmark-trajectory-mrr.mjs — proof harness for Structured Distillation
|
|
3
|
+
// (#2241 §SOTA, arXiv:2603.13017).
|
|
4
|
+
//
|
|
5
|
+
// Measures retrieval MRR for raw vs structured-distilled trajectory content
|
|
6
|
+
// against a paired corpus. The arXiv paper reports raw → distilled MRR
|
|
7
|
+
// going from 0.745 to 0.759 on a 214 K-pair consensus-graded set; our corpus
|
|
8
|
+
// is much smaller and hand-curated, so the absolute numbers won't match,
|
|
9
|
+
// but the *direction* of the delta is what we're proving.
|
|
10
|
+
//
|
|
11
|
+
// Two embedders are supported:
|
|
12
|
+
// - Real ONNX (Xenova/all-MiniLM-L6-v2 384-dim) via @claude-flow/embeddings
|
|
13
|
+
// when available. Best signal.
|
|
14
|
+
// - Hash-based deterministic fallback when ONNX isn't installed. Lower
|
|
15
|
+
// signal; results still relative-comparable.
|
|
16
|
+
//
|
|
17
|
+
// Usage:
|
|
18
|
+
// node scripts/benchmark-trajectory-mrr.mjs # default
|
|
19
|
+
// BENCH_JSON=1 node scripts/benchmark-trajectory-mrr.mjs
|
|
20
|
+
// BENCH_NO_WRITE=1 node scripts/benchmark-trajectory-mrr.mjs
|
|
21
|
+
|
|
22
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
23
|
+
import { fileURLToPath } from 'node:url';
|
|
24
|
+
import { dirname, join, resolve } from 'node:path';
|
|
25
|
+
import { performance } from 'node:perf_hooks';
|
|
26
|
+
|
|
27
|
+
const SCRIPT_DIR = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const CLI_ROOT = resolve(SCRIPT_DIR, '..');
|
|
29
|
+
const REPO_ROOT = resolve(SCRIPT_DIR, '../../../..');
|
|
30
|
+
const RUNS_DIR = join(REPO_ROOT, 'docs', 'benchmarks', 'runs');
|
|
31
|
+
|
|
32
|
+
const { distillAndSerialise, compressionRatio } = await import(
|
|
33
|
+
join(CLI_ROOT, 'dist/src/memory/structured-distill.js')
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Embedder — prefers real ONNX, falls back to hash-based deterministic.
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
async function loadEmbedder() {
|
|
40
|
+
// Tier 1: AgentDB's bridge-loaded ONNX embedder (the path the live MCP
|
|
41
|
+
// server + vitest tests use, so we measure what users actually get).
|
|
42
|
+
try {
|
|
43
|
+
const mb = await import(join(CLI_ROOT, 'dist/src/memory/memory-bridge.js'));
|
|
44
|
+
const probe = await mb.bridgeGenerateEmbedding('warm-up').catch(() => null);
|
|
45
|
+
if (probe && probe.embedding && probe.embedding.length > 0 && probe.backend === 'onnx') {
|
|
46
|
+
return {
|
|
47
|
+
name: `bridge ONNX (${probe.model}, ${probe.dimensions}-dim)`,
|
|
48
|
+
embed: async (text) => {
|
|
49
|
+
const r = await mb.bridgeGenerateEmbedding(text);
|
|
50
|
+
if (!r) throw new Error('bridge embed returned null');
|
|
51
|
+
return r.embedding;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
} catch { /* fall through */ }
|
|
56
|
+
// Tier 2: hash-based deterministic. Clearly degraded; produces only
|
|
57
|
+
// direction-of-effect signal, not absolute MRR numbers comparable to paper.
|
|
58
|
+
console.error('⚠️ Real ONNX embedder unavailable — using hash-based deterministic fallback. Absolute MRR numbers are NOT comparable to the arXiv paper in this mode; relative comparison is also weak.');
|
|
59
|
+
return {
|
|
60
|
+
name: 'hash-fallback (no semantic signal — degraded mode)',
|
|
61
|
+
embed: async (text) => hashEmbed(text, 384),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function hashEmbed(text, dims) {
|
|
66
|
+
const v = new Float32Array(dims);
|
|
67
|
+
let seed = 0;
|
|
68
|
+
for (let i = 0; i < text.length; i++) seed = (seed * 31 + text.charCodeAt(i)) | 0;
|
|
69
|
+
let s = Math.abs(seed) | 1;
|
|
70
|
+
for (let i = 0; i < dims; i++) {
|
|
71
|
+
s = (s * 1103515245 + 12345) & 0x7fffffff;
|
|
72
|
+
v[i] = (s / 0x7fffffff) * 2 - 1;
|
|
73
|
+
}
|
|
74
|
+
// L2 normalise
|
|
75
|
+
let n = 0;
|
|
76
|
+
for (let i = 0; i < dims; i++) n += v[i] * v[i];
|
|
77
|
+
n = Math.sqrt(n) || 1;
|
|
78
|
+
for (let i = 0; i < dims; i++) v[i] /= n;
|
|
79
|
+
return Array.from(v);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function cosine(a, b) {
|
|
83
|
+
let s = 0;
|
|
84
|
+
for (let i = 0; i < a.length; i++) s += a[i] * b[i];
|
|
85
|
+
return s;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Main
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
async function main() {
|
|
92
|
+
const corpusPath = join(CLI_ROOT, 'bench', 'trajectory-mrr-corpus.json');
|
|
93
|
+
const corpus = JSON.parse(readFileSync(corpusPath, 'utf-8'));
|
|
94
|
+
const trajectories = corpus.trajectories;
|
|
95
|
+
const embedder = await loadEmbedder();
|
|
96
|
+
|
|
97
|
+
// Per-trajectory: embed both raw and distilled forms.
|
|
98
|
+
const tEmbed0 = performance.now();
|
|
99
|
+
const rawEmbs = [];
|
|
100
|
+
const distEmbs = [];
|
|
101
|
+
let totalRawBytes = 0;
|
|
102
|
+
let totalDistBytes = 0;
|
|
103
|
+
for (const t of trajectories) {
|
|
104
|
+
const distilled = distillAndSerialise(t.raw);
|
|
105
|
+
totalRawBytes += t.raw.length;
|
|
106
|
+
totalDistBytes += distilled.length;
|
|
107
|
+
rawEmbs.push(await embedder.embed(t.raw));
|
|
108
|
+
distEmbs.push(await embedder.embed(distilled));
|
|
109
|
+
}
|
|
110
|
+
const embedMs = performance.now() - tEmbed0;
|
|
111
|
+
|
|
112
|
+
// For each (query, gold) pair: rank all trajectories by cosine to the query
|
|
113
|
+
// embedding. MRR = mean of 1 / rank-of-gold across all queries.
|
|
114
|
+
const tQuery0 = performance.now();
|
|
115
|
+
let rrRaw = 0, rrDist = 0;
|
|
116
|
+
const perQuery = [];
|
|
117
|
+
for (let i = 0; i < trajectories.length; i++) {
|
|
118
|
+
const q = await embedder.embed(trajectories[i].query);
|
|
119
|
+
const rankRaw = rankOf(q, rawEmbs, i);
|
|
120
|
+
const rankDist = rankOf(q, distEmbs, i);
|
|
121
|
+
rrRaw += 1 / rankRaw;
|
|
122
|
+
rrDist += 1 / rankDist;
|
|
123
|
+
perQuery.push({ id: trajectories[i].id, rankRaw, rankDist });
|
|
124
|
+
}
|
|
125
|
+
const queryMs = performance.now() - tQuery0;
|
|
126
|
+
|
|
127
|
+
const N = trajectories.length;
|
|
128
|
+
const mrrRaw = rrRaw / N;
|
|
129
|
+
const mrrDist = rrDist / N;
|
|
130
|
+
const delta = mrrDist - mrrRaw;
|
|
131
|
+
const compression = totalRawBytes / Math.max(1, totalDistBytes);
|
|
132
|
+
|
|
133
|
+
const summary = {
|
|
134
|
+
runAt: new Date().toISOString(),
|
|
135
|
+
benchmark: 'trajectory-mrr',
|
|
136
|
+
embedder: embedder.name,
|
|
137
|
+
corpusVersion: corpus.version,
|
|
138
|
+
corpusSize: N,
|
|
139
|
+
mrr: {
|
|
140
|
+
raw: Number(mrrRaw.toFixed(4)),
|
|
141
|
+
distilled: Number(mrrDist.toFixed(4)),
|
|
142
|
+
delta: Number(delta.toFixed(4)),
|
|
143
|
+
paperReference: { raw: 0.745, distilled: 0.759, delta: 0.014, source: 'arXiv:2603.13017' },
|
|
144
|
+
},
|
|
145
|
+
compression: {
|
|
146
|
+
totalRawBytes,
|
|
147
|
+
totalDistBytes,
|
|
148
|
+
ratio: Number(compression.toFixed(2)),
|
|
149
|
+
paperReference: { tokensRaw: 371, tokensDistilled: 38, ratio: 9.76, source: 'arXiv:2603.13017' },
|
|
150
|
+
},
|
|
151
|
+
latencyMs: {
|
|
152
|
+
embedAll: Number(embedMs.toFixed(2)),
|
|
153
|
+
queryAll: Number(queryMs.toFixed(2)),
|
|
154
|
+
perDistill: Number((embedMs / (2 * N)).toFixed(4)),
|
|
155
|
+
},
|
|
156
|
+
distilledIsBetter: delta > 0,
|
|
157
|
+
perQueryRanks: perQuery,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (process.env.BENCH_JSON) {
|
|
161
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
162
|
+
} else {
|
|
163
|
+
console.log(`# Trajectory MRR benchmark (#2241 §Structured Distillation)`);
|
|
164
|
+
console.log(`Embedder: ${embedder.name}`);
|
|
165
|
+
console.log(`Corpus: N=${N} (v${corpus.version})`);
|
|
166
|
+
console.log('');
|
|
167
|
+
console.log('| Metric | Raw | Distilled | Δ |');
|
|
168
|
+
console.log('|---|---:|---:|---:|');
|
|
169
|
+
console.log(`| MRR | ${summary.mrr.raw} | ${summary.mrr.distilled} | ${summary.mrr.delta >= 0 ? '+' : ''}${summary.mrr.delta} |`);
|
|
170
|
+
console.log(`| Total bytes | ${totalRawBytes} | ${totalDistBytes} | ${compression.toFixed(2)}× compression |`);
|
|
171
|
+
console.log('');
|
|
172
|
+
console.log(`Distilled is ${summary.distilledIsBetter ? 'BETTER ✅' : 'WORSE ❌'} than raw on this corpus.`);
|
|
173
|
+
console.log(`Paper (arXiv:2603.13017): MRR raw 0.745 → distilled 0.759 (Δ +0.014); compression ~9.76× (371→38 tokens).`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (!process.env.BENCH_NO_WRITE) {
|
|
177
|
+
mkdirSync(RUNS_DIR, { recursive: true });
|
|
178
|
+
const stamp = summary.runAt.replace(/[:.]/g, '-');
|
|
179
|
+
writeFileSync(join(RUNS_DIR, `trajectory-mrr-${stamp}.json`), JSON.stringify(summary, null, 2));
|
|
180
|
+
writeFileSync(join(RUNS_DIR, 'trajectory-mrr-latest.json'), JSON.stringify(summary, null, 2));
|
|
181
|
+
if (!process.env.BENCH_JSON) console.log(`\nWrote ${join(RUNS_DIR, `trajectory-mrr-${stamp}.json`)}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function rankOf(query, embeddings, goldIndex) {
|
|
186
|
+
const scored = embeddings.map((e, i) => ({ i, score: cosine(query, e) }));
|
|
187
|
+
scored.sort((a, b) => b.score - a.score);
|
|
188
|
+
return scored.findIndex((s) => s.i === goldIndex) + 1;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
main().catch((err) => { console.error(err); process.exit(1); });
|