@ruvector/ruvllm 2.5.6 → 2.6.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.
Files changed (71) hide show
  1. package/README.md +282 -282
  2. package/bin/cli.js +1020 -1020
  3. package/dist/cjs/benchmarks/embedding-benchmark.js +1 -1
  4. package/dist/cjs/benchmarks/index.js +1 -1
  5. package/dist/cjs/benchmarks/model-comparison.js +1 -1
  6. package/dist/cjs/benchmarks/routing-benchmark.js +1 -1
  7. package/dist/cjs/contrastive.js +70 -70
  8. package/dist/cjs/engine.js +13 -13
  9. package/dist/cjs/export.js +31 -31
  10. package/dist/cjs/federated.js +1 -1
  11. package/dist/cjs/index.js +1 -1
  12. package/dist/cjs/intelligence.js +1 -1
  13. package/dist/cjs/lora.d.ts +11 -0
  14. package/dist/cjs/lora.d.ts.map +1 -1
  15. package/dist/cjs/lora.js +16 -1
  16. package/dist/cjs/models.js +1 -1
  17. package/dist/cjs/native.js +1 -1
  18. package/dist/cjs/session.js +1 -1
  19. package/dist/cjs/simd.js +1 -1
  20. package/dist/cjs/sona.js +1 -1
  21. package/dist/cjs/streaming.js +1 -1
  22. package/dist/cjs/training.d.ts +66 -8
  23. package/dist/cjs/training.d.ts.map +1 -1
  24. package/dist/cjs/training.js +145 -15
  25. package/dist/cjs/types.d.ts +7 -0
  26. package/dist/cjs/types.d.ts.map +1 -1
  27. package/dist/cjs/types.js +1 -1
  28. package/dist/esm/benchmarks/embedding-benchmark.js +1 -1
  29. package/dist/esm/benchmarks/index.js +1 -1
  30. package/dist/esm/benchmarks/model-comparison.js +1 -1
  31. package/dist/esm/benchmarks/routing-benchmark.js +1 -1
  32. package/dist/esm/contrastive.js +70 -70
  33. package/dist/esm/engine.js +13 -13
  34. package/dist/esm/export.js +31 -31
  35. package/dist/esm/federated.js +1 -1
  36. package/dist/esm/index.js +1 -1
  37. package/dist/esm/intelligence.js +1 -1
  38. package/dist/esm/lora.d.ts +11 -0
  39. package/dist/esm/lora.d.ts.map +1 -1
  40. package/dist/esm/lora.js +16 -1
  41. package/dist/esm/models.js +1 -1
  42. package/dist/esm/native.js +1 -1
  43. package/dist/esm/session.js +1 -1
  44. package/dist/esm/simd.js +1 -1
  45. package/dist/esm/sona.js +1 -1
  46. package/dist/esm/streaming.js +1 -1
  47. package/dist/esm/training.d.ts +66 -8
  48. package/dist/esm/training.d.ts.map +1 -1
  49. package/dist/esm/training.js +145 -15
  50. package/dist/esm/types.d.ts +7 -0
  51. package/dist/esm/types.d.ts.map +1 -1
  52. package/dist/esm/types.js +1 -1
  53. package/package.json +133 -133
  54. package/scripts/ensemble-model-compare.js +287 -287
  55. package/scripts/huggingface/README.md +537 -537
  56. package/scripts/huggingface/publish.sh +112 -112
  57. package/scripts/hybrid-model-compare.js +373 -373
  58. package/scripts/improved-model-compare.js +288 -288
  59. package/scripts/optimized-model-compare.js +364 -364
  60. package/scripts/real-model-compare.js +280 -280
  61. package/scripts/training/agentic-flow-capabilities.json +329 -329
  62. package/scripts/training/claude-code-synth.js +505 -505
  63. package/scripts/training/claude-flow-capabilities.json +1322 -1322
  64. package/scripts/training/claude-hard-negatives.js +222 -222
  65. package/scripts/training/contrastive-finetune.js +517 -517
  66. package/scripts/training/ecosystem-triplets.jsonl +1466 -1466
  67. package/scripts/training/generate-ecosystem-triplets.js +1324 -1324
  68. package/scripts/training/routing-dataset.js +634 -634
  69. package/scripts/training/ruvector-capabilities.json +798 -798
  70. package/scripts/training/validate-ecosystem.js +381 -381
  71. package/scripts/training/validation-results.json +22 -22
@@ -1,287 +1,287 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Ensemble Model Comparison
4
- *
5
- * Strategies:
6
- * 1. Task prefix - prepend context to make tasks more aligned with descriptions
7
- * 2. Ensemble voting - combine multiple description variants
8
- * 3. Agent-specific thresholds based on training patterns
9
- */
10
-
11
- const { execSync } = require('child_process');
12
- const { existsSync } = require('fs');
13
- const { join } = require('path');
14
- const { homedir } = require('os');
15
-
16
- const MODELS_DIR = join(homedir(), '.ruvllm', 'models');
17
- const RUVLTRA_MODEL = join(MODELS_DIR, 'ruvltra-claude-code-0.5b-q4_k_m.gguf');
18
- const QWEN_MODEL = join(MODELS_DIR, 'qwen2.5-0.5b-instruct-q4_k_m.gguf');
19
-
20
- // Original V1 descriptions (best baseline)
21
- const DESCRIPTIONS_V1 = {
22
- coder: 'implement create write build add code function class component feature',
23
- researcher: 'research find investigate analyze explore search discover examine',
24
- reviewer: 'review check evaluate assess inspect examine code quality',
25
- tester: 'test unit integration e2e coverage mock assertion spec',
26
- architect: 'design architecture schema system structure plan database',
27
- 'security-architect': 'security vulnerability xss injection audit cve authentication',
28
- debugger: 'debug fix bug error issue broken crash exception trace',
29
- documenter: 'document readme jsdoc comment explain describe documentation',
30
- refactorer: 'refactor extract rename consolidate clean restructure simplify',
31
- optimizer: 'optimize performance slow fast cache speed memory latency',
32
- devops: 'deploy ci cd kubernetes docker pipeline container infrastructure',
33
- 'api-docs': 'openapi swagger api documentation graphql schema endpoint',
34
- planner: 'plan estimate prioritize sprint roadmap schedule milestone',
35
- };
36
-
37
- // V6: Keywords reformulated as action phrases
38
- const DESCRIPTIONS_V6 = {
39
- coder: 'implement new functionality write code build features create components',
40
- researcher: 'research and analyze investigate patterns explore best practices',
41
- reviewer: 'review code quality check pull requests evaluate implementations',
42
- tester: 'write tests create test coverage add unit and integration tests',
43
- architect: 'design system architecture plan database schemas structure systems',
44
- 'security-architect': 'audit security vulnerabilities check xss and injection attacks',
45
- debugger: 'debug and fix bugs trace errors resolve exceptions',
46
- documenter: 'write documentation add jsdoc comments create readme files',
47
- refactorer: 'refactor code modernize to async await restructure modules',
48
- optimizer: 'optimize performance improve speed cache data reduce latency',
49
- devops: 'deploy to cloud setup ci cd pipelines manage containers kubernetes',
50
- 'api-docs': 'generate openapi documentation create swagger api specs',
51
- planner: 'plan sprints create roadmaps estimate timelines schedule milestones',
52
- };
53
-
54
- // Task prefixes to try
55
- const TASK_PREFIXES = [
56
- '', // No prefix (baseline)
57
- 'Task: ', // Simple task prefix
58
- 'The developer needs to: ', // Contextual prefix
59
- 'Claude Code task - ', // Model-specific prefix
60
- ];
61
-
62
- const ROUTING_TESTS = [
63
- { task: 'Implement a binary search function in TypeScript', expected: 'coder' },
64
- { task: 'Write unit tests for the authentication module', expected: 'tester' },
65
- { task: 'Review the pull request for security vulnerabilities', expected: 'reviewer' },
66
- { task: 'Research best practices for React state management', expected: 'researcher' },
67
- { task: 'Design the database schema for user profiles', expected: 'architect' },
68
- { task: 'Fix the null pointer exception in the login handler', expected: 'debugger' },
69
- { task: 'Audit the API endpoints for XSS vulnerabilities', expected: 'security-architect' },
70
- { task: 'Write JSDoc comments for the utility functions', expected: 'documenter' },
71
- { task: 'Refactor the payment module to use async/await', expected: 'refactorer' },
72
- { task: 'Optimize the database queries for the dashboard', expected: 'optimizer' },
73
- { task: 'Set up the CI/CD pipeline for the microservices', expected: 'devops' },
74
- { task: 'Generate OpenAPI documentation for the REST API', expected: 'api-docs' },
75
- { task: 'Create a sprint plan for the next two weeks', expected: 'planner' },
76
- { task: 'Build a React component for user registration', expected: 'coder' },
77
- { task: 'Debug memory leak in the WebSocket handler', expected: 'debugger' },
78
- { task: 'Investigate slow API response times', expected: 'researcher' },
79
- { task: 'Check code for potential race conditions', expected: 'reviewer' },
80
- { task: 'Add integration tests for the payment gateway', expected: 'tester' },
81
- { task: 'Plan the architecture for real-time notifications', expected: 'architect' },
82
- { task: 'Cache the frequently accessed user data', expected: 'optimizer' },
83
- ];
84
-
85
- function getEmbedding(modelPath, text) {
86
- try {
87
- const sanitized = text.replace(/"/g, '\\"').replace(/\n/g, ' ');
88
- const result = execSync(
89
- `llama-embedding -m "${modelPath}" -p "${sanitized}" --embd-output-format json 2>/dev/null`,
90
- { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }
91
- );
92
- const json = JSON.parse(result);
93
- return json.data[json.data.length - 1].embedding;
94
- } catch {
95
- return null;
96
- }
97
- }
98
-
99
- function cosineSimilarity(a, b) {
100
- if (!a || !b || a.length !== b.length) return 0;
101
- let dot = 0, normA = 0, normB = 0;
102
- for (let i = 0; i < a.length; i++) {
103
- dot += a[i] * b[i];
104
- normA += a[i] * a[i];
105
- normB += b[i] * b[i];
106
- }
107
- return dot / (Math.sqrt(normA) * Math.sqrt(normB) || 1);
108
- }
109
-
110
- function routeTask(taskEmbedding, agentEmbeddings) {
111
- let bestAgent = 'coder';
112
- let bestSim = -1;
113
- const allScores = {};
114
- for (const [agent, emb] of Object.entries(agentEmbeddings)) {
115
- const sim = cosineSimilarity(taskEmbedding, emb);
116
- allScores[agent] = sim;
117
- if (sim > bestSim) {
118
- bestSim = sim;
119
- bestAgent = agent;
120
- }
121
- }
122
- return { agent: bestAgent, confidence: bestSim, scores: allScores };
123
- }
124
-
125
- /**
126
- * Ensemble routing - vote across multiple description sets
127
- */
128
- function routeTaskEnsemble(taskEmbedding, allAgentEmbeddings) {
129
- const votes = {};
130
- const agents = Object.keys(allAgentEmbeddings[0]);
131
-
132
- for (const agent of agents) votes[agent] = 0;
133
-
134
- // Each embedding set votes
135
- for (const agentEmbeddings of allAgentEmbeddings) {
136
- const { agent } = routeTask(taskEmbedding, agentEmbeddings);
137
- votes[agent] = (votes[agent] || 0) + 1;
138
- }
139
-
140
- // Return agent with most votes
141
- let bestAgent = 'coder';
142
- let maxVotes = 0;
143
- for (const [agent, count] of Object.entries(votes)) {
144
- if (count > maxVotes) {
145
- maxVotes = count;
146
- bestAgent = agent;
147
- }
148
- }
149
-
150
- return { agent: bestAgent, votes, voteCount: maxVotes };
151
- }
152
-
153
- function runBenchmark(modelPath, descriptions, prefix = '') {
154
- const agentEmbeddings = {};
155
- for (const [agent, desc] of Object.entries(descriptions)) {
156
- agentEmbeddings[agent] = getEmbedding(modelPath, desc);
157
- }
158
-
159
- let correct = 0;
160
- for (const test of ROUTING_TESTS) {
161
- const taskEmb = getEmbedding(modelPath, prefix + test.task);
162
- const { agent } = routeTask(taskEmb, agentEmbeddings);
163
- if (agent === test.expected) correct++;
164
- }
165
-
166
- return { accuracy: correct / ROUTING_TESTS.length, correct, total: ROUTING_TESTS.length };
167
- }
168
-
169
- function runEnsembleBenchmark(modelPath, descriptionSets, prefix = '') {
170
- // Precompute embeddings for all description sets
171
- const allAgentEmbeddings = descriptionSets.map(descriptions => {
172
- const embeds = {};
173
- for (const [agent, desc] of Object.entries(descriptions)) {
174
- embeds[agent] = getEmbedding(modelPath, desc);
175
- }
176
- return embeds;
177
- });
178
-
179
- let correct = 0;
180
- const results = [];
181
- for (const test of ROUTING_TESTS) {
182
- const taskEmb = getEmbedding(modelPath, prefix + test.task);
183
- const { agent, votes } = routeTaskEnsemble(taskEmb, allAgentEmbeddings);
184
- const isCorrect = agent === test.expected;
185
- if (isCorrect) correct++;
186
- results.push({ task: test.task, expected: test.expected, got: agent, correct: isCorrect, votes });
187
- }
188
-
189
- return { accuracy: correct / ROUTING_TESTS.length, correct, total: ROUTING_TESTS.length, results };
190
- }
191
-
192
- async function main() {
193
- console.log('\n╔═══════════════════════════════════════════════════════════════════════════════════╗');
194
- console.log('║ ENSEMBLE & PREFIX MODEL COMPARISON ║');
195
- console.log('╚═══════════════════════════════════════════════════════════════════════════════════╝\n');
196
-
197
- if (!existsSync(RUVLTRA_MODEL)) {
198
- console.error('RuvLTRA model not found.');
199
- process.exit(1);
200
- }
201
-
202
- // Test prefix variations
203
- console.log('─────────────────────────────────────────────────────────────────');
204
- console.log(' PREFIX VARIATIONS (RuvLTRA)');
205
- console.log('─────────────────────────────────────────────────────────────────\n');
206
-
207
- const prefixResults = {};
208
- for (const prefix of TASK_PREFIXES) {
209
- const label = prefix || '(no prefix)';
210
- process.stdout.write(` Testing "${label.padEnd(25)}"... `);
211
- const result = runBenchmark(RUVLTRA_MODEL, DESCRIPTIONS_V1, prefix);
212
- prefixResults[label] = result;
213
- console.log(`${(result.accuracy * 100).toFixed(1)}%`);
214
- }
215
-
216
- // Find best prefix
217
- const bestPrefix = Object.entries(prefixResults).reduce((a, b) =>
218
- a[1].accuracy > b[1].accuracy ? a : b
219
- );
220
-
221
- console.log(`\n Best prefix: "${bestPrefix[0]}" = ${(bestPrefix[1].accuracy * 100).toFixed(1)}%`);
222
-
223
- // Test ensemble voting
224
- console.log('\n─────────────────────────────────────────────────────────────────');
225
- console.log(' ENSEMBLE VOTING (RuvLTRA)');
226
- console.log('─────────────────────────────────────────────────────────────────\n');
227
-
228
- process.stdout.write(' Computing V1 + V6 ensemble... ');
229
- const ensembleResult = runEnsembleBenchmark(RUVLTRA_MODEL, [DESCRIPTIONS_V1, DESCRIPTIONS_V6], '');
230
- console.log(`${(ensembleResult.accuracy * 100).toFixed(1)}%`);
231
-
232
- // Compare with Qwen
233
- console.log('\n─────────────────────────────────────────────────────────────────');
234
- console.log(' QWEN COMPARISON');
235
- console.log('─────────────────────────────────────────────────────────────────\n');
236
-
237
- process.stdout.write(' Qwen V1 baseline... ');
238
- const qwenV1 = runBenchmark(QWEN_MODEL, DESCRIPTIONS_V1, '');
239
- console.log(`${(qwenV1.accuracy * 100).toFixed(1)}%`);
240
-
241
- process.stdout.write(' Qwen V1+V6 ensemble... ');
242
- const qwenEnsemble = runEnsembleBenchmark(QWEN_MODEL, [DESCRIPTIONS_V1, DESCRIPTIONS_V6], '');
243
- console.log(`${(qwenEnsemble.accuracy * 100).toFixed(1)}%`);
244
-
245
- // Final results table
246
- console.log('\n═══════════════════════════════════════════════════════════════════════════════════');
247
- console.log(' FINAL RESULTS');
248
- console.log('═══════════════════════════════════════════════════════════════════════════════════\n');
249
-
250
- const fmt = (v) => `${(v * 100).toFixed(1)}%`.padStart(10);
251
-
252
- console.log('┌───────────────────────────────┬────────────┬────────────┐');
253
- console.log('│ Strategy │ RuvLTRA │ Qwen │');
254
- console.log('├───────────────────────────────┼────────────┼────────────┤');
255
- console.log(`│ V1 Baseline │${fmt(prefixResults['(no prefix)'].accuracy)} │${fmt(qwenV1.accuracy)} │`);
256
- console.log(`│ V1 + Best Prefix │${fmt(bestPrefix[1].accuracy)} │ - │`);
257
- console.log(`│ V1+V6 Ensemble │${fmt(ensembleResult.accuracy)} │${fmt(qwenEnsemble.accuracy)} │`);
258
- console.log('└───────────────────────────────┴────────────┴────────────┘');
259
-
260
- // Best overall
261
- const ruvBest = Math.max(
262
- prefixResults['(no prefix)'].accuracy,
263
- bestPrefix[1].accuracy,
264
- ensembleResult.accuracy
265
- );
266
- const qwenBest = Math.max(qwenV1.accuracy, qwenEnsemble.accuracy);
267
-
268
- console.log(`\n RuvLTRA Best: ${(ruvBest * 100).toFixed(1)}%`);
269
- console.log(` Qwen Best: ${(qwenBest * 100).toFixed(1)}%`);
270
- console.log(` Advantage: RuvLTRA +${((ruvBest - qwenBest) * 100).toFixed(1)} points`);
271
-
272
- // Show detailed ensemble results
273
- console.log('\n─────────────────────────────────────────────────────────────────');
274
- console.log(' ENSEMBLE VOTING DETAILS (RuvLTRA)');
275
- console.log('─────────────────────────────────────────────────────────────────\n');
276
-
277
- for (const r of ensembleResult.results) {
278
- const mark = r.correct ? '✓' : '✗';
279
- const task = r.task.slice(0, 45).padEnd(45);
280
- const exp = r.expected.padEnd(18);
281
- console.log(`${mark} ${task} ${exp}${r.correct ? '' : '→ ' + r.got}`);
282
- }
283
-
284
- console.log('\n');
285
- }
286
-
287
- main().catch(console.error);
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Ensemble Model Comparison
4
+ *
5
+ * Strategies:
6
+ * 1. Task prefix - prepend context to make tasks more aligned with descriptions
7
+ * 2. Ensemble voting - combine multiple description variants
8
+ * 3. Agent-specific thresholds based on training patterns
9
+ */
10
+
11
+ const { execSync } = require('child_process');
12
+ const { existsSync } = require('fs');
13
+ const { join } = require('path');
14
+ const { homedir } = require('os');
15
+
16
+ const MODELS_DIR = join(homedir(), '.ruvllm', 'models');
17
+ const RUVLTRA_MODEL = join(MODELS_DIR, 'ruvltra-claude-code-0.5b-q4_k_m.gguf');
18
+ const QWEN_MODEL = join(MODELS_DIR, 'qwen2.5-0.5b-instruct-q4_k_m.gguf');
19
+
20
+ // Original V1 descriptions (best baseline)
21
+ const DESCRIPTIONS_V1 = {
22
+ coder: 'implement create write build add code function class component feature',
23
+ researcher: 'research find investigate analyze explore search discover examine',
24
+ reviewer: 'review check evaluate assess inspect examine code quality',
25
+ tester: 'test unit integration e2e coverage mock assertion spec',
26
+ architect: 'design architecture schema system structure plan database',
27
+ 'security-architect': 'security vulnerability xss injection audit cve authentication',
28
+ debugger: 'debug fix bug error issue broken crash exception trace',
29
+ documenter: 'document readme jsdoc comment explain describe documentation',
30
+ refactorer: 'refactor extract rename consolidate clean restructure simplify',
31
+ optimizer: 'optimize performance slow fast cache speed memory latency',
32
+ devops: 'deploy ci cd kubernetes docker pipeline container infrastructure',
33
+ 'api-docs': 'openapi swagger api documentation graphql schema endpoint',
34
+ planner: 'plan estimate prioritize sprint roadmap schedule milestone',
35
+ };
36
+
37
+ // V6: Keywords reformulated as action phrases
38
+ const DESCRIPTIONS_V6 = {
39
+ coder: 'implement new functionality write code build features create components',
40
+ researcher: 'research and analyze investigate patterns explore best practices',
41
+ reviewer: 'review code quality check pull requests evaluate implementations',
42
+ tester: 'write tests create test coverage add unit and integration tests',
43
+ architect: 'design system architecture plan database schemas structure systems',
44
+ 'security-architect': 'audit security vulnerabilities check xss and injection attacks',
45
+ debugger: 'debug and fix bugs trace errors resolve exceptions',
46
+ documenter: 'write documentation add jsdoc comments create readme files',
47
+ refactorer: 'refactor code modernize to async await restructure modules',
48
+ optimizer: 'optimize performance improve speed cache data reduce latency',
49
+ devops: 'deploy to cloud setup ci cd pipelines manage containers kubernetes',
50
+ 'api-docs': 'generate openapi documentation create swagger api specs',
51
+ planner: 'plan sprints create roadmaps estimate timelines schedule milestones',
52
+ };
53
+
54
+ // Task prefixes to try
55
+ const TASK_PREFIXES = [
56
+ '', // No prefix (baseline)
57
+ 'Task: ', // Simple task prefix
58
+ 'The developer needs to: ', // Contextual prefix
59
+ 'Claude Code task - ', // Model-specific prefix
60
+ ];
61
+
62
+ const ROUTING_TESTS = [
63
+ { task: 'Implement a binary search function in TypeScript', expected: 'coder' },
64
+ { task: 'Write unit tests for the authentication module', expected: 'tester' },
65
+ { task: 'Review the pull request for security vulnerabilities', expected: 'reviewer' },
66
+ { task: 'Research best practices for React state management', expected: 'researcher' },
67
+ { task: 'Design the database schema for user profiles', expected: 'architect' },
68
+ { task: 'Fix the null pointer exception in the login handler', expected: 'debugger' },
69
+ { task: 'Audit the API endpoints for XSS vulnerabilities', expected: 'security-architect' },
70
+ { task: 'Write JSDoc comments for the utility functions', expected: 'documenter' },
71
+ { task: 'Refactor the payment module to use async/await', expected: 'refactorer' },
72
+ { task: 'Optimize the database queries for the dashboard', expected: 'optimizer' },
73
+ { task: 'Set up the CI/CD pipeline for the microservices', expected: 'devops' },
74
+ { task: 'Generate OpenAPI documentation for the REST API', expected: 'api-docs' },
75
+ { task: 'Create a sprint plan for the next two weeks', expected: 'planner' },
76
+ { task: 'Build a React component for user registration', expected: 'coder' },
77
+ { task: 'Debug memory leak in the WebSocket handler', expected: 'debugger' },
78
+ { task: 'Investigate slow API response times', expected: 'researcher' },
79
+ { task: 'Check code for potential race conditions', expected: 'reviewer' },
80
+ { task: 'Add integration tests for the payment gateway', expected: 'tester' },
81
+ { task: 'Plan the architecture for real-time notifications', expected: 'architect' },
82
+ { task: 'Cache the frequently accessed user data', expected: 'optimizer' },
83
+ ];
84
+
85
+ function getEmbedding(modelPath, text) {
86
+ try {
87
+ const sanitized = text.replace(/"/g, '\\"').replace(/\n/g, ' ');
88
+ const result = execSync(
89
+ `llama-embedding -m "${modelPath}" -p "${sanitized}" --embd-output-format json 2>/dev/null`,
90
+ { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }
91
+ );
92
+ const json = JSON.parse(result);
93
+ return json.data[json.data.length - 1].embedding;
94
+ } catch {
95
+ return null;
96
+ }
97
+ }
98
+
99
+ function cosineSimilarity(a, b) {
100
+ if (!a || !b || a.length !== b.length) return 0;
101
+ let dot = 0, normA = 0, normB = 0;
102
+ for (let i = 0; i < a.length; i++) {
103
+ dot += a[i] * b[i];
104
+ normA += a[i] * a[i];
105
+ normB += b[i] * b[i];
106
+ }
107
+ return dot / (Math.sqrt(normA) * Math.sqrt(normB) || 1);
108
+ }
109
+
110
+ function routeTask(taskEmbedding, agentEmbeddings) {
111
+ let bestAgent = 'coder';
112
+ let bestSim = -1;
113
+ const allScores = {};
114
+ for (const [agent, emb] of Object.entries(agentEmbeddings)) {
115
+ const sim = cosineSimilarity(taskEmbedding, emb);
116
+ allScores[agent] = sim;
117
+ if (sim > bestSim) {
118
+ bestSim = sim;
119
+ bestAgent = agent;
120
+ }
121
+ }
122
+ return { agent: bestAgent, confidence: bestSim, scores: allScores };
123
+ }
124
+
125
+ /**
126
+ * Ensemble routing - vote across multiple description sets
127
+ */
128
+ function routeTaskEnsemble(taskEmbedding, allAgentEmbeddings) {
129
+ const votes = {};
130
+ const agents = Object.keys(allAgentEmbeddings[0]);
131
+
132
+ for (const agent of agents) votes[agent] = 0;
133
+
134
+ // Each embedding set votes
135
+ for (const agentEmbeddings of allAgentEmbeddings) {
136
+ const { agent } = routeTask(taskEmbedding, agentEmbeddings);
137
+ votes[agent] = (votes[agent] || 0) + 1;
138
+ }
139
+
140
+ // Return agent with most votes
141
+ let bestAgent = 'coder';
142
+ let maxVotes = 0;
143
+ for (const [agent, count] of Object.entries(votes)) {
144
+ if (count > maxVotes) {
145
+ maxVotes = count;
146
+ bestAgent = agent;
147
+ }
148
+ }
149
+
150
+ return { agent: bestAgent, votes, voteCount: maxVotes };
151
+ }
152
+
153
+ function runBenchmark(modelPath, descriptions, prefix = '') {
154
+ const agentEmbeddings = {};
155
+ for (const [agent, desc] of Object.entries(descriptions)) {
156
+ agentEmbeddings[agent] = getEmbedding(modelPath, desc);
157
+ }
158
+
159
+ let correct = 0;
160
+ for (const test of ROUTING_TESTS) {
161
+ const taskEmb = getEmbedding(modelPath, prefix + test.task);
162
+ const { agent } = routeTask(taskEmb, agentEmbeddings);
163
+ if (agent === test.expected) correct++;
164
+ }
165
+
166
+ return { accuracy: correct / ROUTING_TESTS.length, correct, total: ROUTING_TESTS.length };
167
+ }
168
+
169
+ function runEnsembleBenchmark(modelPath, descriptionSets, prefix = '') {
170
+ // Precompute embeddings for all description sets
171
+ const allAgentEmbeddings = descriptionSets.map(descriptions => {
172
+ const embeds = {};
173
+ for (const [agent, desc] of Object.entries(descriptions)) {
174
+ embeds[agent] = getEmbedding(modelPath, desc);
175
+ }
176
+ return embeds;
177
+ });
178
+
179
+ let correct = 0;
180
+ const results = [];
181
+ for (const test of ROUTING_TESTS) {
182
+ const taskEmb = getEmbedding(modelPath, prefix + test.task);
183
+ const { agent, votes } = routeTaskEnsemble(taskEmb, allAgentEmbeddings);
184
+ const isCorrect = agent === test.expected;
185
+ if (isCorrect) correct++;
186
+ results.push({ task: test.task, expected: test.expected, got: agent, correct: isCorrect, votes });
187
+ }
188
+
189
+ return { accuracy: correct / ROUTING_TESTS.length, correct, total: ROUTING_TESTS.length, results };
190
+ }
191
+
192
+ async function main() {
193
+ console.log('\n╔═══════════════════════════════════════════════════════════════════════════════════╗');
194
+ console.log('║ ENSEMBLE & PREFIX MODEL COMPARISON ║');
195
+ console.log('╚═══════════════════════════════════════════════════════════════════════════════════╝\n');
196
+
197
+ if (!existsSync(RUVLTRA_MODEL)) {
198
+ console.error('RuvLTRA model not found.');
199
+ process.exit(1);
200
+ }
201
+
202
+ // Test prefix variations
203
+ console.log('─────────────────────────────────────────────────────────────────');
204
+ console.log(' PREFIX VARIATIONS (RuvLTRA)');
205
+ console.log('─────────────────────────────────────────────────────────────────\n');
206
+
207
+ const prefixResults = {};
208
+ for (const prefix of TASK_PREFIXES) {
209
+ const label = prefix || '(no prefix)';
210
+ process.stdout.write(` Testing "${label.padEnd(25)}"... `);
211
+ const result = runBenchmark(RUVLTRA_MODEL, DESCRIPTIONS_V1, prefix);
212
+ prefixResults[label] = result;
213
+ console.log(`${(result.accuracy * 100).toFixed(1)}%`);
214
+ }
215
+
216
+ // Find best prefix
217
+ const bestPrefix = Object.entries(prefixResults).reduce((a, b) =>
218
+ a[1].accuracy > b[1].accuracy ? a : b
219
+ );
220
+
221
+ console.log(`\n Best prefix: "${bestPrefix[0]}" = ${(bestPrefix[1].accuracy * 100).toFixed(1)}%`);
222
+
223
+ // Test ensemble voting
224
+ console.log('\n─────────────────────────────────────────────────────────────────');
225
+ console.log(' ENSEMBLE VOTING (RuvLTRA)');
226
+ console.log('─────────────────────────────────────────────────────────────────\n');
227
+
228
+ process.stdout.write(' Computing V1 + V6 ensemble... ');
229
+ const ensembleResult = runEnsembleBenchmark(RUVLTRA_MODEL, [DESCRIPTIONS_V1, DESCRIPTIONS_V6], '');
230
+ console.log(`${(ensembleResult.accuracy * 100).toFixed(1)}%`);
231
+
232
+ // Compare with Qwen
233
+ console.log('\n─────────────────────────────────────────────────────────────────');
234
+ console.log(' QWEN COMPARISON');
235
+ console.log('─────────────────────────────────────────────────────────────────\n');
236
+
237
+ process.stdout.write(' Qwen V1 baseline... ');
238
+ const qwenV1 = runBenchmark(QWEN_MODEL, DESCRIPTIONS_V1, '');
239
+ console.log(`${(qwenV1.accuracy * 100).toFixed(1)}%`);
240
+
241
+ process.stdout.write(' Qwen V1+V6 ensemble... ');
242
+ const qwenEnsemble = runEnsembleBenchmark(QWEN_MODEL, [DESCRIPTIONS_V1, DESCRIPTIONS_V6], '');
243
+ console.log(`${(qwenEnsemble.accuracy * 100).toFixed(1)}%`);
244
+
245
+ // Final results table
246
+ console.log('\n═══════════════════════════════════════════════════════════════════════════════════');
247
+ console.log(' FINAL RESULTS');
248
+ console.log('═══════════════════════════════════════════════════════════════════════════════════\n');
249
+
250
+ const fmt = (v) => `${(v * 100).toFixed(1)}%`.padStart(10);
251
+
252
+ console.log('┌───────────────────────────────┬────────────┬────────────┐');
253
+ console.log('│ Strategy │ RuvLTRA │ Qwen │');
254
+ console.log('├───────────────────────────────┼────────────┼────────────┤');
255
+ console.log(`│ V1 Baseline │${fmt(prefixResults['(no prefix)'].accuracy)} │${fmt(qwenV1.accuracy)} │`);
256
+ console.log(`│ V1 + Best Prefix │${fmt(bestPrefix[1].accuracy)} │ - │`);
257
+ console.log(`│ V1+V6 Ensemble │${fmt(ensembleResult.accuracy)} │${fmt(qwenEnsemble.accuracy)} │`);
258
+ console.log('└───────────────────────────────┴────────────┴────────────┘');
259
+
260
+ // Best overall
261
+ const ruvBest = Math.max(
262
+ prefixResults['(no prefix)'].accuracy,
263
+ bestPrefix[1].accuracy,
264
+ ensembleResult.accuracy
265
+ );
266
+ const qwenBest = Math.max(qwenV1.accuracy, qwenEnsemble.accuracy);
267
+
268
+ console.log(`\n RuvLTRA Best: ${(ruvBest * 100).toFixed(1)}%`);
269
+ console.log(` Qwen Best: ${(qwenBest * 100).toFixed(1)}%`);
270
+ console.log(` Advantage: RuvLTRA +${((ruvBest - qwenBest) * 100).toFixed(1)} points`);
271
+
272
+ // Show detailed ensemble results
273
+ console.log('\n─────────────────────────────────────────────────────────────────');
274
+ console.log(' ENSEMBLE VOTING DETAILS (RuvLTRA)');
275
+ console.log('─────────────────────────────────────────────────────────────────\n');
276
+
277
+ for (const r of ensembleResult.results) {
278
+ const mark = r.correct ? '✓' : '✗';
279
+ const task = r.task.slice(0, 45).padEnd(45);
280
+ const exp = r.expected.padEnd(18);
281
+ console.log(`${mark} ${task} ${exp}${r.correct ? '' : '→ ' + r.got}`);
282
+ }
283
+
284
+ console.log('\n');
285
+ }
286
+
287
+ main().catch(console.error);