monomind 1.11.4 → 1.11.6
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/packages/@monomind/cli/dist/src/commands/benchmark.js +17 -45
- package/packages/@monomind/cli/dist/src/commands/route.js +18 -35
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +2 -7
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +2 -2
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -2
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +1 -2
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +49 -115
- package/packages/@monomind/cli/dist/src/monovector/index.d.ts +1 -8
- package/packages/@monomind/cli/dist/src/monovector/index.js +1 -13
- package/packages/@monomind/cli/package.json +1 -2
- package/scripts/build-monovector.sh +1 -1
- package/scripts/publish-monovector.sh +1 -1
- package/scripts/verify-appliance.sh +1 -18
- package/packages/@monomind/cli/bundled-graph/dist/src/build.js +0 -73
- package/packages/@monomind/cli/bundled-graph/dist/src/cluster.js +0 -120
- package/packages/@monomind/cli/bundled-graph/package.json +0 -57
- package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.d.ts +0 -9
- package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.js +0 -295
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.6",
|
|
4
4
|
"description": "Monomind - 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",
|
|
@@ -32,46 +32,18 @@ const pretrainCommand = {
|
|
|
32
32
|
const outputFormat = ctx.flags.output || 'text';
|
|
33
33
|
const saveFile = ctx.flags.save;
|
|
34
34
|
const verbose = ctx.flags.verbose === true;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// Save to file if requested
|
|
48
|
-
if (saveFile) {
|
|
49
|
-
const resultsDir = join(process.cwd(), '.monomind', 'benchmarks');
|
|
50
|
-
if (!existsSync(resultsDir)) {
|
|
51
|
-
mkdirSync(resultsDir, { recursive: true });
|
|
52
|
-
}
|
|
53
|
-
const savePath = saveFile.startsWith('/') ? saveFile : join(resultsDir, saveFile);
|
|
54
|
-
const saveTmp = savePath + '.tmp';
|
|
55
|
-
writeFileSync(saveTmp, JSON.stringify(results, null, 2));
|
|
56
|
-
renameSync(saveTmp, savePath);
|
|
57
|
-
output.writeln(output.success(`Results saved to ${savePath}`));
|
|
58
|
-
}
|
|
59
|
-
const allPassed = results.results.every(r => r.targetMet);
|
|
60
|
-
return {
|
|
61
|
-
success: true,
|
|
62
|
-
message: allPassed
|
|
63
|
-
? 'All benchmark targets met!'
|
|
64
|
-
: `${results.results.filter(r => r.targetMet).length}/${results.results.length} targets met`,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
69
|
-
output.writeln(output.error(`Benchmark failed: ${errorMsg}`));
|
|
70
|
-
return {
|
|
71
|
-
success: false,
|
|
72
|
-
message: `Benchmark failed: ${errorMsg}`,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
35
|
+
void iterations;
|
|
36
|
+
void warmup;
|
|
37
|
+
void verbose;
|
|
38
|
+
void outputFormat;
|
|
39
|
+
void saveFile;
|
|
40
|
+
output.writeln();
|
|
41
|
+
output.writeln(output.bold('Pattern-Learning Benchmark'));
|
|
42
|
+
output.writeln(output.dim('─'.repeat(50)));
|
|
43
|
+
output.writeln(output.dim(' The native SONA/EWC++/MoE pre-training benchmark was removed in the lean build.'));
|
|
44
|
+
output.writeln(output.dim(' Use "monomind benchmark neural" to benchmark the active pure-JS intelligence layer.'));
|
|
45
|
+
output.writeln();
|
|
46
|
+
return { success: true };
|
|
75
47
|
},
|
|
76
48
|
};
|
|
77
49
|
// ============================================================================
|
|
@@ -79,7 +51,7 @@ const pretrainCommand = {
|
|
|
79
51
|
// ============================================================================
|
|
80
52
|
const neuralCommand = {
|
|
81
53
|
name: 'neural',
|
|
82
|
-
description: 'Benchmark neural operations (embeddings,
|
|
54
|
+
description: 'Benchmark neural operations (embeddings, HNSW, cosine similarity)',
|
|
83
55
|
options: [
|
|
84
56
|
{ name: 'iterations', short: 'i', type: 'number', description: 'Benchmark iterations', default: '100' },
|
|
85
57
|
{ name: 'dimension', short: 'd', type: 'number', description: 'Embedding dimension', default: '384' },
|
|
@@ -182,8 +154,8 @@ const neuralCommand = {
|
|
|
182
154
|
target: 5.0,
|
|
183
155
|
met: cosineMean <= 5.0,
|
|
184
156
|
});
|
|
185
|
-
// 3.
|
|
186
|
-
spinner.setText('Benchmarking
|
|
157
|
+
// 3. Softmax-weighted top-K search (pure-JS)
|
|
158
|
+
spinner.setText('Benchmarking softmax top-K search...');
|
|
187
159
|
const flashTimes = [];
|
|
188
160
|
try {
|
|
189
161
|
const memory = await import('../memory/memory-initializer.js');
|
|
@@ -196,13 +168,13 @@ const neuralCommand = {
|
|
|
196
168
|
}
|
|
197
169
|
}
|
|
198
170
|
catch {
|
|
199
|
-
//
|
|
171
|
+
// not available
|
|
200
172
|
}
|
|
201
173
|
if (flashTimes.length > 0) {
|
|
202
174
|
const flashMean = flashTimes.reduce((a, b) => a + b, 0) / flashTimes.length;
|
|
203
175
|
const flashSorted = [...flashTimes].sort((a, b) => a - b);
|
|
204
176
|
results.push({
|
|
205
|
-
name: '
|
|
177
|
+
name: 'Softmax Top-K Search',
|
|
206
178
|
mean: flashMean,
|
|
207
179
|
p95: percentile(flashSorted, 95),
|
|
208
180
|
p99: percentile(flashSorted, 99),
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* github.com/nokhodian/monomind
|
|
12
12
|
*/
|
|
13
13
|
import { output } from '../output.js';
|
|
14
|
-
import { createKeywordRouter,
|
|
14
|
+
import { createKeywordRouter, } from '../monovector/index.js';
|
|
15
15
|
/**
|
|
16
16
|
* Available agent types for routing
|
|
17
17
|
*/
|
|
@@ -86,7 +86,7 @@ const routeTaskCommand = {
|
|
|
86
86
|
],
|
|
87
87
|
examples: [
|
|
88
88
|
{ command: 'monomind route task "implement authentication"', description: 'Route task to best agent' },
|
|
89
|
-
{ command: 'monomind route task "write unit tests" --q-learning', description: 'Use
|
|
89
|
+
{ command: 'monomind route task "write unit tests" --q-learning', description: 'Use keyword-based routing' },
|
|
90
90
|
{ command: 'monomind route task "review code" --agent reviewer', description: 'Force specific agent' },
|
|
91
91
|
],
|
|
92
92
|
action: async (ctx) => {
|
|
@@ -103,7 +103,7 @@ const routeTaskCommand = {
|
|
|
103
103
|
spinner.start();
|
|
104
104
|
try {
|
|
105
105
|
if (forceAgent) {
|
|
106
|
-
//
|
|
106
|
+
// Use specified agent directly
|
|
107
107
|
const agent = getAgentType(forceAgent) ||
|
|
108
108
|
AGENT_TYPES.find(a => a.name.toLowerCase() === forceAgent.toLowerCase());
|
|
109
109
|
if (!agent) {
|
|
@@ -134,7 +134,7 @@ const routeTaskCommand = {
|
|
|
134
134
|
}
|
|
135
135
|
return { success: true, data: { agentId: agent.id, agentName: agent.name } };
|
|
136
136
|
}
|
|
137
|
-
// Use
|
|
137
|
+
// Use keyword-based routing
|
|
138
138
|
const router = await getRouter();
|
|
139
139
|
const result = await router.route(taskDescription, useExploration);
|
|
140
140
|
const agent = getAgentType(result.route) || AGENT_TYPES[0];
|
|
@@ -177,7 +177,7 @@ const routeTaskCommand = {
|
|
|
177
177
|
``,
|
|
178
178
|
`Description: ${agent.description}`,
|
|
179
179
|
`Capabilities: ${capabilities.join(', ')}`,
|
|
180
|
-
].join('\n'), '
|
|
180
|
+
].join('\n'), 'Keyword Routing');
|
|
181
181
|
if (alternatives.length > 0) {
|
|
182
182
|
output.writeln();
|
|
183
183
|
output.writeln(output.bold('Alternatives:'));
|
|
@@ -263,7 +263,7 @@ const listAgentsCommand = {
|
|
|
263
263
|
// ============================================================================
|
|
264
264
|
const statsCommand = {
|
|
265
265
|
name: 'stats',
|
|
266
|
-
description: 'Show
|
|
266
|
+
description: 'Show keyword router statistics',
|
|
267
267
|
options: [
|
|
268
268
|
{
|
|
269
269
|
name: 'json',
|
|
@@ -281,18 +281,12 @@ const statsCommand = {
|
|
|
281
281
|
try {
|
|
282
282
|
const router = await getRouter();
|
|
283
283
|
const stats = router.getStats();
|
|
284
|
-
const monovectorAvailable = await isMonovectorAvailable();
|
|
285
|
-
const monovectorStatus = {
|
|
286
|
-
available: monovectorAvailable,
|
|
287
|
-
wasmAccelerated: stats.useNative === 1,
|
|
288
|
-
backend: stats.useNative === 1 ? 'monovector-native' : 'fallback',
|
|
289
|
-
};
|
|
290
284
|
if (jsonOutput) {
|
|
291
|
-
output.printJson({ stats,
|
|
285
|
+
output.printJson({ stats, backend: 'keyword-routing-js' });
|
|
292
286
|
}
|
|
293
287
|
else {
|
|
294
288
|
output.writeln();
|
|
295
|
-
output.writeln(output.bold('
|
|
289
|
+
output.writeln(output.bold('Keyword Router Statistics'));
|
|
296
290
|
output.writeln();
|
|
297
291
|
output.printTable({
|
|
298
292
|
columns: [
|
|
@@ -301,22 +295,13 @@ const statsCommand = {
|
|
|
301
295
|
],
|
|
302
296
|
data: [
|
|
303
297
|
{ metric: 'Update Count', value: String(stats.updateCount) },
|
|
304
|
-
{ metric: '
|
|
298
|
+
{ metric: 'Pattern Count', value: String(stats.qTableSize) },
|
|
305
299
|
{ metric: 'Step Count', value: String(stats.stepCount) },
|
|
306
|
-
{ metric: '
|
|
307
|
-
{ metric: 'Avg TD Error', value: stats.avgTDError.toFixed(4) },
|
|
308
|
-
{ metric: 'Native Backend', value: stats.useNative === 1 ? 'Yes' : 'No' },
|
|
300
|
+
{ metric: 'Backend', value: 'keyword-routing (JS)' },
|
|
309
301
|
],
|
|
310
302
|
});
|
|
311
|
-
output.writeln();
|
|
312
|
-
output.writeln(output.bold('MonoVector Status'));
|
|
313
|
-
output.printList([
|
|
314
|
-
`Available: ${monovectorStatus.available ? output.success('Yes') : output.warning('No (using fallback)')}`,
|
|
315
|
-
`WASM Accelerated: ${monovectorStatus.wasmAccelerated ? output.success('Yes') : 'No'}`,
|
|
316
|
-
`Backend: ${monovectorStatus.backend}`,
|
|
317
|
-
]);
|
|
318
303
|
}
|
|
319
|
-
return { success: true, data: { stats
|
|
304
|
+
return { success: true, data: { stats } };
|
|
320
305
|
}
|
|
321
306
|
catch (error) {
|
|
322
307
|
output.printError(error instanceof Error ? error.message : String(error));
|
|
@@ -406,7 +391,7 @@ const feedbackCommand = {
|
|
|
406
391
|
// ============================================================================
|
|
407
392
|
const resetCommand = {
|
|
408
393
|
name: 'reset',
|
|
409
|
-
description: 'Reset the
|
|
394
|
+
description: 'Reset the keyword router state',
|
|
410
395
|
options: [
|
|
411
396
|
{
|
|
412
397
|
name: 'force',
|
|
@@ -430,7 +415,7 @@ const resetCommand = {
|
|
|
430
415
|
try {
|
|
431
416
|
const router = await getRouter();
|
|
432
417
|
router.reset();
|
|
433
|
-
output.printSuccess('
|
|
418
|
+
output.printSuccess('Keyword router state has been reset');
|
|
434
419
|
return { success: true };
|
|
435
420
|
}
|
|
436
421
|
catch (error) {
|
|
@@ -854,7 +839,7 @@ const semanticRouteCommand = {
|
|
|
854
839
|
// ============================================================================
|
|
855
840
|
export const routeCommand = {
|
|
856
841
|
name: 'route',
|
|
857
|
-
description: 'Intelligent task-to-agent routing using
|
|
842
|
+
description: 'Intelligent task-to-agent routing using keyword matching',
|
|
858
843
|
subcommands: [
|
|
859
844
|
routeTaskCommand,
|
|
860
845
|
semanticRouteCommand,
|
|
@@ -870,7 +855,7 @@ export const routeCommand = {
|
|
|
870
855
|
{
|
|
871
856
|
name: 'q-learning',
|
|
872
857
|
short: 'q',
|
|
873
|
-
description: 'Use
|
|
858
|
+
description: 'Use keyword-based agent selection',
|
|
874
859
|
type: 'boolean',
|
|
875
860
|
default: true,
|
|
876
861
|
},
|
|
@@ -883,7 +868,7 @@ export const routeCommand = {
|
|
|
883
868
|
],
|
|
884
869
|
examples: [
|
|
885
870
|
{ command: 'monomind route "implement feature"', description: 'Route task to best agent' },
|
|
886
|
-
{ command: 'monomind route "write tests" --q-learning', description: 'Use
|
|
871
|
+
{ command: 'monomind route "write tests" --q-learning', description: 'Use keyword-based routing' },
|
|
887
872
|
{ command: 'monomind route --agent coder "fix bug"', description: 'Force specific agent' },
|
|
888
873
|
{ command: 'monomind route list-agents', description: 'List available agents' },
|
|
889
874
|
{ command: 'monomind route stats', description: 'Show routing statistics' },
|
|
@@ -923,12 +908,10 @@ export const routeCommand = {
|
|
|
923
908
|
'Provides confidence scores and alternatives',
|
|
924
909
|
]);
|
|
925
910
|
output.writeln();
|
|
926
|
-
// Show quick status
|
|
927
|
-
const monovectorAvailable = await isMonovectorAvailable();
|
|
928
911
|
output.writeln(output.bold('Backend Status:'));
|
|
929
912
|
output.printList([
|
|
930
|
-
`
|
|
931
|
-
`
|
|
913
|
+
`Routing: ${output.success('keyword-based (JS)')}`,
|
|
914
|
+
`Learning: trajectory recording + outcome correlation`,
|
|
932
915
|
]);
|
|
933
916
|
output.writeln();
|
|
934
917
|
output.writeln(output.dim('Run "monomind route <subcommand> --help" for more info'));
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import { mkdirSync, writeFileSync, renameSync, existsSync, readFileSync, statSync, unlinkSync, readdirSync } from 'fs';
|
|
6
6
|
import { dirname, join, resolve, sep } from 'path';
|
|
7
7
|
import { getProjectCwd } from './types.js';
|
|
8
|
-
import { getCapabilities } from '../monovector/capabilities.js';
|
|
9
8
|
import { randomUUID } from 'node:crypto';
|
|
10
9
|
import { recordRoute, joinOutcome, joinLatestUnresolved } from '../monovector/route-outcomes.js';
|
|
11
10
|
import { recordCommand, deriveRecentSuccess } from '../monovector/command-outcomes.js';
|
|
@@ -706,8 +705,6 @@ export const hooksRoute = {
|
|
|
706
705
|
const agentdbConfidence = Math.round(agentdbRoute.confidence * 100) / 100;
|
|
707
706
|
// Record the route recommendation so post-task can join the actual outcome
|
|
708
707
|
const routeId = randomUUID();
|
|
709
|
-
const caps = await getCapabilities();
|
|
710
|
-
const learningMode = (caps.sona || caps.router === 'native' || caps.attention) ? 'native' : 'js';
|
|
711
708
|
await recordRoute(getRouteOutcomesBaseDir(), {
|
|
712
709
|
routeId,
|
|
713
710
|
ts: Date.now(),
|
|
@@ -715,7 +712,7 @@ export const hooksRoute = {
|
|
|
715
712
|
recommendedAgent: agents[0],
|
|
716
713
|
routingMethod: agentdbMethod,
|
|
717
714
|
confidence: agentdbConfidence,
|
|
718
|
-
learningMode,
|
|
715
|
+
learningMode: 'js',
|
|
719
716
|
});
|
|
720
717
|
return {
|
|
721
718
|
routeId,
|
|
@@ -797,8 +794,6 @@ export const hooksRoute = {
|
|
|
797
794
|
const primaryConfidence = Math.round(confidence * 100) / 100;
|
|
798
795
|
// Record the route recommendation so post-task can join the actual outcome
|
|
799
796
|
const routeId = randomUUID();
|
|
800
|
-
const caps = await getCapabilities();
|
|
801
|
-
const learningMode = (caps.sona || caps.router === 'native' || caps.attention) ? 'native' : 'js';
|
|
802
797
|
await recordRoute(getRouteOutcomesBaseDir(), {
|
|
803
798
|
routeId,
|
|
804
799
|
ts: Date.now(),
|
|
@@ -806,7 +801,7 @@ export const hooksRoute = {
|
|
|
806
801
|
recommendedAgent: agents[0],
|
|
807
802
|
routingMethod,
|
|
808
803
|
confidence: primaryConfidence,
|
|
809
|
-
learningMode,
|
|
804
|
+
learningMode: 'js',
|
|
810
805
|
});
|
|
811
806
|
return {
|
|
812
807
|
routeId,
|
|
@@ -18,7 +18,7 @@ import { homedir } from 'os';
|
|
|
18
18
|
import { execSync } from 'child_process';
|
|
19
19
|
import { createServer } from 'http';
|
|
20
20
|
import { performance } from 'perf_hooks';
|
|
21
|
-
import { openDb, closeDb, ftsSearch, getNode, getNodesForFile, getEdgesForSource, getEdgesForTarget, countNodes, countEdges, snapshotFromDb, toHtml,
|
|
21
|
+
import { openDb, closeDb, ftsSearch, getNode, getNodesForFile, getEdgesForSource, getEdgesForTarget, countNodes, countEdges, snapshotFromDb, toHtml, } from '@monoes/monograph';
|
|
22
22
|
// ─── Tier 1: Fully implementable from primitives ───────────────────────────────
|
|
23
23
|
// 1. hybridQuery
|
|
24
24
|
// BM25-only at monograph@1.1.0 (no vector storage). score = -rank (descending, .toFixed-safe).
|
|
@@ -878,7 +878,7 @@ export async function installSkillsForPlatform(repoPath, communities, opts) {
|
|
|
878
878
|
}
|
|
879
879
|
// 18. runEmbed — embeddings unsupported at 1.1.0; throws so handler catches gracefully
|
|
880
880
|
export async function runEmbed(_db, _opts) {
|
|
881
|
-
throw new
|
|
881
|
+
throw new Error('Embeddings are not supported in @monoes/monograph@1.1.0 — no vector storage in this schema version.');
|
|
882
882
|
}
|
|
883
883
|
// ─── Groups (Tier 2) ──────────────────────────────────────────────────────────
|
|
884
884
|
// Helper: read group config (groups.json or group.yaml)
|
|
@@ -416,8 +416,7 @@ export declare function bridgeContextSynthesize(params: {
|
|
|
416
416
|
}): Promise<any>;
|
|
417
417
|
/**
|
|
418
418
|
* Route via SemanticRouter.
|
|
419
|
-
* Available since agentdb 3.0.0-alpha.10 —
|
|
420
|
-
* semantic matching with keyword fallback.
|
|
419
|
+
* Available since agentdb 3.0.0-alpha.10 — semantic matching with keyword fallback.
|
|
421
420
|
*/
|
|
422
421
|
export declare function bridgeSemanticRoute(params: {
|
|
423
422
|
input: string;
|
|
@@ -1671,8 +1671,7 @@ export async function bridgeContextSynthesize(params) {
|
|
|
1671
1671
|
}
|
|
1672
1672
|
/**
|
|
1673
1673
|
* Route via SemanticRouter.
|
|
1674
|
-
* Available since agentdb 3.0.0-alpha.10 —
|
|
1675
|
-
* semantic matching with keyword fallback.
|
|
1674
|
+
* Available since agentdb 3.0.0-alpha.10 — semantic matching with keyword fallback.
|
|
1676
1675
|
*/
|
|
1677
1676
|
export async function bridgeSemanticRoute(params) {
|
|
1678
1677
|
const registry = await getRegistry();
|
|
@@ -378,121 +378,13 @@ export async function getHNSWIndex(options) {
|
|
|
378
378
|
}
|
|
379
379
|
hnswInitializing = true;
|
|
380
380
|
try {
|
|
381
|
-
//
|
|
382
|
-
//
|
|
383
|
-
//
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
hnswInitializing = false;
|
|
387
|
-
return null; // HNSW not available — pure-JS fallback path
|
|
388
|
-
}
|
|
389
|
-
// ESM returns { default: { VectorDb, ... } }, CJS returns { VectorDb, ... }
|
|
390
|
-
const monovectorCore = monovectorModule.default || monovectorModule;
|
|
391
|
-
if (!monovectorCore?.VectorDb) {
|
|
392
|
-
hnswInitializing = false;
|
|
393
|
-
return null; // VectorDb not found
|
|
394
|
-
}
|
|
395
|
-
const { VectorDb } = monovectorCore;
|
|
396
|
-
// Persistent storage paths — resolve to absolute to survive CWD changes
|
|
397
|
-
const swarmDir = path.resolve(process.cwd(), '.swarm');
|
|
398
|
-
if (!fs.existsSync(swarmDir)) {
|
|
399
|
-
fs.mkdirSync(swarmDir, { recursive: true });
|
|
400
|
-
}
|
|
401
|
-
const hnswPath = path.join(swarmDir, 'hnsw.index');
|
|
402
|
-
const metadataPath = path.join(swarmDir, 'hnsw.metadata.json');
|
|
403
|
-
const dbPath = options?.dbPath ? path.resolve(options.dbPath) : path.join(swarmDir, 'memory.db');
|
|
404
|
-
// Create HNSW index with persistent storage
|
|
405
|
-
// @monoes/core uses string enum for distanceMetric: 'Cosine', 'Euclidean', 'DotProduct', 'Manhattan'
|
|
406
|
-
const db = new VectorDb({
|
|
407
|
-
dimensions,
|
|
408
|
-
distanceMetric: 'Cosine',
|
|
409
|
-
storagePath: hnswPath // Persistent storage!
|
|
410
|
-
});
|
|
411
|
-
// Load metadata (entry info) if exists
|
|
412
|
-
const entries = new Map();
|
|
413
|
-
if (fs.existsSync(metadataPath)) {
|
|
414
|
-
try {
|
|
415
|
-
const metadataJson = fs.readFileSync(metadataPath, 'utf-8');
|
|
416
|
-
const metadata = JSON.parse(metadataJson);
|
|
417
|
-
for (const [key, value] of metadata) {
|
|
418
|
-
entries.set(key, value);
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
catch {
|
|
422
|
-
// Metadata load failed, will rebuild
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
hnswIndex = {
|
|
426
|
-
db,
|
|
427
|
-
entries,
|
|
428
|
-
dimensions,
|
|
429
|
-
initialized: false
|
|
430
|
-
};
|
|
431
|
-
// Check if index already has data (from persistent storage)
|
|
432
|
-
const existingLen = await db.len();
|
|
433
|
-
if (existingLen > 0 && entries.size > 0) {
|
|
434
|
-
// Index loaded from disk, skip SQLite sync
|
|
435
|
-
hnswIndex.initialized = true;
|
|
436
|
-
hnswInitializing = false;
|
|
437
|
-
return hnswIndex;
|
|
438
|
-
}
|
|
439
|
-
if (fs.existsSync(dbPath)) {
|
|
440
|
-
try {
|
|
441
|
-
// Reject symlinks and oversized DB files. Without this a symlink at the
|
|
442
|
-
// dbPath pointing at /dev/zero or a 100GB sparse file would OOM the CLI
|
|
443
|
-
// on the next memory operation.
|
|
444
|
-
const stat = fs.lstatSync(dbPath);
|
|
445
|
-
if (stat.isSymbolicLink() || stat.size > 256 * 1024 * 1024) {
|
|
446
|
-
return null;
|
|
447
|
-
}
|
|
448
|
-
const initSqlJs = (await import('sql.js')).default;
|
|
449
|
-
const SQL = await initSqlJs();
|
|
450
|
-
const fileBuffer = fs.readFileSync(dbPath);
|
|
451
|
-
const sqlDb = new SQL.Database(fileBuffer);
|
|
452
|
-
// Load all entries with embeddings
|
|
453
|
-
const result = sqlDb.exec(`
|
|
454
|
-
SELECT id, key, namespace, content, embedding
|
|
455
|
-
FROM memory_entries
|
|
456
|
-
WHERE status = 'active' AND embedding IS NOT NULL
|
|
457
|
-
LIMIT 10000
|
|
458
|
-
`);
|
|
459
|
-
if (result[0]?.values) {
|
|
460
|
-
for (const row of result[0].values) {
|
|
461
|
-
const [id, key, ns, content, embeddingJson] = row;
|
|
462
|
-
if (embeddingJson) {
|
|
463
|
-
try {
|
|
464
|
-
const embedding = safeParseEmbeddingLocal(embeddingJson);
|
|
465
|
-
if (!embedding)
|
|
466
|
-
continue;
|
|
467
|
-
const vector = new Float32Array(embedding);
|
|
468
|
-
await db.insert({
|
|
469
|
-
id: String(id),
|
|
470
|
-
vector
|
|
471
|
-
});
|
|
472
|
-
hnswIndex.entries.set(String(id), {
|
|
473
|
-
id: String(id),
|
|
474
|
-
key: key || String(id),
|
|
475
|
-
namespace: ns || 'default',
|
|
476
|
-
content: content || ''
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
catch {
|
|
480
|
-
// Skip invalid embeddings
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
sqlDb.close();
|
|
486
|
-
}
|
|
487
|
-
catch {
|
|
488
|
-
// SQLite load failed, start with empty index
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
// initialized = true even on empty DB — absence of vectors is a valid ready state,
|
|
492
|
-
// not a failure. The concurrent-waiter null-check at line ~395 relies on this.
|
|
493
|
-
hnswIndex.initialized = true;
|
|
381
|
+
// Native @monoes/core HNSW (WASM VectorDb) was removed in the lean teardown.
|
|
382
|
+
// This function is kept for callers that check its return value — all callers
|
|
383
|
+
// already handle null by falling back to the pure-JS / brute-force path.
|
|
384
|
+
// The AgentDB bridge (memory-bridge.ts) provides HNSW via agentdb instead.
|
|
385
|
+
// Native backend removed — return null so callers use the pure-JS fallback.
|
|
494
386
|
hnswInitializing = false;
|
|
495
|
-
return
|
|
387
|
+
return null;
|
|
496
388
|
}
|
|
497
389
|
catch {
|
|
498
390
|
hnswInitializing = false;
|
|
@@ -576,7 +468,7 @@ export async function searchHNSWIndex(queryEmbedding, options) {
|
|
|
576
468
|
continue;
|
|
577
469
|
}
|
|
578
470
|
// Convert cosine distance to similarity score (1 - distance)
|
|
579
|
-
// Cosine distance
|
|
471
|
+
// Cosine distance convention: 0 = identical, 2 = opposite
|
|
580
472
|
const score = 1 - (result.score / 2);
|
|
581
473
|
filtered.push({
|
|
582
474
|
id: entry.id.substring(0, 12),
|
|
@@ -1329,6 +1221,48 @@ export async function loadEmbeddingModel(options) {
|
|
|
1329
1221
|
}
|
|
1330
1222
|
}
|
|
1331
1223
|
try {
|
|
1224
|
+
// Tier 0: @monomind/embeddings — bundles @xenova/transformers as a hard dep, so it
|
|
1225
|
+
// resolves from the CLI even when a bare `import('@xenova/transformers')` does NOT
|
|
1226
|
+
// (the CLI doesn't declare @xenova directly). Without this, the chain below falls
|
|
1227
|
+
// straight through to the hash fallback and "semantic" search is lexical-only.
|
|
1228
|
+
const embPkg = await import('@monomind/embeddings').catch(() => null);
|
|
1229
|
+
if (embPkg && typeof embPkg.createEmbeddingService === 'function') {
|
|
1230
|
+
try {
|
|
1231
|
+
const service = embPkg.createEmbeddingService({
|
|
1232
|
+
provider: 'transformers',
|
|
1233
|
+
model: 'Xenova/all-MiniLM-L6-v2',
|
|
1234
|
+
normalization: 'l2',
|
|
1235
|
+
enableCache: true,
|
|
1236
|
+
});
|
|
1237
|
+
// Probe triggers the (lazy) model load and verifies real vectors come back.
|
|
1238
|
+
const probe = await service.embed('probe');
|
|
1239
|
+
const probeVec = probe?.embedding;
|
|
1240
|
+
const dims = (probeVec && probeVec.length) || 384;
|
|
1241
|
+
if (probeVec && dims > 1) {
|
|
1242
|
+
if (verbose) {
|
|
1243
|
+
console.log(`Loaded @monomind/embeddings (Transformers MiniLM-L6, ${dims}d)...`);
|
|
1244
|
+
}
|
|
1245
|
+
embeddingModelState = {
|
|
1246
|
+
loaded: true,
|
|
1247
|
+
// Match generateEmbedding's consumer: a callable returning a plain number[]
|
|
1248
|
+
// (it accepts either `{ data }` or an Array.isArray(...) result).
|
|
1249
|
+
model: async (text) => Array.from((await service.embed(String(text))).embedding),
|
|
1250
|
+
tokenizer: null,
|
|
1251
|
+
dimensions: dims,
|
|
1252
|
+
};
|
|
1253
|
+
return {
|
|
1254
|
+
success: true,
|
|
1255
|
+
dimensions: dims,
|
|
1256
|
+
modelName: '@monomind/embeddings (transformers/MiniLM-L6)',
|
|
1257
|
+
loadTime: Date.now() - startTime,
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
catch {
|
|
1262
|
+
// Embeddings package present but model load failed (offline / download error);
|
|
1263
|
+
// fall through to the remaining providers and ultimately the hash fallback.
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1332
1266
|
// Try to import @xenova/transformers for ONNX embeddings
|
|
1333
1267
|
const transformers = await import('@xenova/transformers').catch(() => null);
|
|
1334
1268
|
if (transformers) {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MonoVector Integration Module for Monomind CLI (lean)
|
|
3
3
|
*
|
|
4
|
-
* After the SONA / native / WASM teardown this module provides
|
|
5
|
-
* lightweight surface:
|
|
6
|
-
* - Capability probing: getCapabilities() — stubbed, always reports JS-only
|
|
4
|
+
* After the SONA / native / WASM teardown this module provides:
|
|
7
5
|
* - Initialization state: createInitState()
|
|
8
6
|
* - Keyword-based task routing: createKeywordRouter()
|
|
9
7
|
* - Route recommendation→outcome records: recordRoute(), joinOutcome(), accuracy
|
|
@@ -11,7 +9,6 @@
|
|
|
11
9
|
*
|
|
12
10
|
* @module @monomind/cli/monovector
|
|
13
11
|
*/
|
|
14
|
-
export { getCapabilities, getCachedCapabilities, resetCapabilitiesCache, refreshCapabilities, type MonoesCapabilities } from './capabilities.js';
|
|
15
12
|
export { createInitState, type InitState, type InitStatus } from './init-state.js';
|
|
16
13
|
export { recordRoute, joinOutcome, joinLatestUnresolved, readOutcomes, computeRoutingAccuracy, computeAdherence, type RouteOutcomeRecord, type RoutingAccuracy, } from './route-outcomes.js';
|
|
17
14
|
export { DiffClassifier, createDiffClassifier, analyzeDiff, analyzeDiffSync, assessFileRisk, assessOverallRisk, classifyDiff, suggestReviewers, getGitDiffNumstat, getGitDiffNumstatAsync, clearDiffCache, clearAllDiffCaches, type DiffClassification, type DiffHunk, type DiffChange, type FileDiff, type DiffAnalysis, type DiffClassifierConfig, type DiffFile, type RiskLevel, type FileRisk, type OverallRisk, type DiffAnalysisResult, } from './diff-classifier.js';
|
|
@@ -54,8 +51,4 @@ export interface KeywordRouterConfig {
|
|
|
54
51
|
discountFactor?: number;
|
|
55
52
|
}
|
|
56
53
|
export declare function createKeywordRouter(_config?: KeywordRouterConfig): KeywordRouter;
|
|
57
|
-
/** @deprecated Use (await getCapabilities()).sona */
|
|
58
|
-
export declare function isMonovectorAvailable(): Promise<boolean>;
|
|
59
|
-
/** @deprecated Use (await getCapabilities()).learningWasm */
|
|
60
|
-
export declare function isWasmBackendAvailable(): Promise<boolean>;
|
|
61
54
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MonoVector Integration Module for Monomind CLI (lean)
|
|
3
3
|
*
|
|
4
|
-
* After the SONA / native / WASM teardown this module provides
|
|
5
|
-
* lightweight surface:
|
|
6
|
-
* - Capability probing: getCapabilities() — stubbed, always reports JS-only
|
|
4
|
+
* After the SONA / native / WASM teardown this module provides:
|
|
7
5
|
* - Initialization state: createInitState()
|
|
8
6
|
* - Keyword-based task routing: createKeywordRouter()
|
|
9
7
|
* - Route recommendation→outcome records: recordRoute(), joinOutcome(), accuracy
|
|
@@ -11,8 +9,6 @@
|
|
|
11
9
|
*
|
|
12
10
|
* @module @monomind/cli/monovector
|
|
13
11
|
*/
|
|
14
|
-
import { getCapabilities } from './capabilities.js';
|
|
15
|
-
export { getCapabilities, getCachedCapabilities, resetCapabilitiesCache, refreshCapabilities } from './capabilities.js';
|
|
16
12
|
export { createInitState } from './init-state.js';
|
|
17
13
|
export { recordRoute, joinOutcome, joinLatestUnresolved, readOutcomes, computeRoutingAccuracy, computeAdherence, } from './route-outcomes.js';
|
|
18
14
|
export { DiffClassifier, createDiffClassifier, analyzeDiff, analyzeDiffSync, assessFileRisk, assessOverallRisk, classifyDiff, suggestReviewers, getGitDiffNumstat, getGitDiffNumstatAsync, clearDiffCache, clearAllDiffCaches, } from './diff-classifier.js';
|
|
@@ -56,12 +52,4 @@ export function createKeywordRouter(_config) {
|
|
|
56
52
|
import() { },
|
|
57
53
|
};
|
|
58
54
|
}
|
|
59
|
-
/** @deprecated Use (await getCapabilities()).sona */
|
|
60
|
-
export async function isMonovectorAvailable() {
|
|
61
|
-
return (await getCapabilities()).sona;
|
|
62
|
-
}
|
|
63
|
-
/** @deprecated Use (await getCapabilities()).learningWasm */
|
|
64
|
-
export async function isWasmBackendAvailable() {
|
|
65
|
-
return (await getCapabilities()).learningWasm;
|
|
66
|
-
}
|
|
67
55
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind 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",
|
|
@@ -68,7 +68,6 @@
|
|
|
68
68
|
"dist",
|
|
69
69
|
"bin",
|
|
70
70
|
".claude",
|
|
71
|
-
"bundled-graph",
|
|
72
71
|
"scripts",
|
|
73
72
|
"README.md"
|
|
74
73
|
],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
set -e
|
|
3
3
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
4
|
-
PACKAGES=(learning-wasm exotic-wasm attention-wasm gnn-wasm
|
|
4
|
+
PACKAGES=(learning-wasm exotic-wasm attention-wasm gnn-wasm)
|
|
5
5
|
for pkg in "${PACKAGES[@]}"; do
|
|
6
6
|
echo "Building @monovector/$pkg..."
|
|
7
7
|
(cd "$REPO_ROOT/packages/@monoes/$pkg" && npm run build)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
set -e
|
|
7
7
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
8
8
|
|
|
9
|
-
PACKAGES=(learning-wasm exotic-wasm attention-wasm gnn-wasm
|
|
9
|
+
PACKAGES=(learning-wasm exotic-wasm attention-wasm gnn-wasm)
|
|
10
10
|
|
|
11
11
|
for pkg in "${PACKAGES[@]}"; do
|
|
12
12
|
PKG_DIR="$REPO_ROOT/packages/@monoes/$pkg/pkg"
|
|
@@ -423,24 +423,7 @@ if should_run "rvf"; then
|
|
|
423
423
|
rm -rf "$RVF_DIR"
|
|
424
424
|
fi
|
|
425
425
|
|
|
426
|
-
#
|
|
427
|
-
if should_run "ruvllm"; then
|
|
428
|
-
section 27 "Local Model Inference (ruvLLM / RuVector)"
|
|
429
|
-
if [ "${SKIP_MODELS:-0}" = "1" ]; then
|
|
430
|
-
check_skip "ruvllm: model load" "SKIP_MODELS=1"
|
|
431
|
-
check_skip "ruvllm: tokenize" "SKIP_MODELS=1"
|
|
432
|
-
check_skip "ruvllm: generate" "SKIP_MODELS=1"
|
|
433
|
-
check_skip "ruvllm: stream" "SKIP_MODELS=1"
|
|
434
|
-
elif command -v monomind-ruvllm >/dev/null 2>&1; then
|
|
435
|
-
check_warn "ruvllm: engine available" monomind-ruvllm --version
|
|
436
|
-
check_warn "ruvllm: model list" monomind-ruvllm models list
|
|
437
|
-
check_warn "ruvllm: tokenize" monomind-ruvllm tokenize --text "Hello world"
|
|
438
|
-
check_warn "ruvllm: generate" monomind-ruvllm generate --prompt "2+2=" --max-tokens 10
|
|
439
|
-
else
|
|
440
|
-
check_skip "ruvllm: engine" "monomind-ruvllm not installed (future: ADR-058 Phase 3)"
|
|
441
|
-
check_skip "ruvllm: inference" "monomind-ruvllm not installed"
|
|
442
|
-
fi
|
|
443
|
-
fi
|
|
426
|
+
# Section 27 (local model inference) was removed — native LLM module not in lean build
|
|
444
427
|
|
|
445
428
|
# ── 28. API Key Vault ─────────────────────────────────────────
|
|
446
429
|
if should_run "vault"; then
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import Graph from 'graphology';
|
|
2
|
-
// Mirrors upstream graphify's _normalize_id: lowercase + collapse non-alphanumeric to underscores.
|
|
3
|
-
function normalizeId(s) {
|
|
4
|
-
return s.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '').toLowerCase();
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Build a graphology Graph from extracted nodes and edges.
|
|
8
|
-
* Deduplicates nodes by id, merges parallel edges with higher weight.
|
|
9
|
-
*/
|
|
10
|
-
export function buildGraph(extraction) {
|
|
11
|
-
const graph = new Graph({ type: 'directed', multi: false });
|
|
12
|
-
// Add all nodes — merge attributes if already present (dedup by id)
|
|
13
|
-
for (const node of extraction.nodes) {
|
|
14
|
-
if (!graph.hasNode(node.id)) {
|
|
15
|
-
graph.addNode(node.id, { ...node });
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
graph.mergeNodeAttributes(node.id, { ...node });
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// Build normalized ID lookup to remap mismatched edge endpoints before stubbing.
|
|
22
|
-
const normToId = new Map();
|
|
23
|
-
graph.forEachNode((id) => {
|
|
24
|
-
normToId.set(normalizeId(id), id);
|
|
25
|
-
});
|
|
26
|
-
// Add edges — skip self-loops, remap via normalization, stub only true externals
|
|
27
|
-
for (const edge of extraction.edges) {
|
|
28
|
-
let src = edge.source;
|
|
29
|
-
let tgt = edge.target;
|
|
30
|
-
if (!graph.hasNode(src)) {
|
|
31
|
-
const remapped = normToId.get(normalizeId(src));
|
|
32
|
-
if (remapped) {
|
|
33
|
-
src = remapped;
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
graph.addNode(src, { id: src, label: src, fileType: 'unknown', sourceFile: '' });
|
|
37
|
-
normToId.set(normalizeId(src), src);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (!graph.hasNode(tgt)) {
|
|
41
|
-
const remapped = normToId.get(normalizeId(tgt));
|
|
42
|
-
if (remapped) {
|
|
43
|
-
tgt = remapped;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
graph.addNode(tgt, { id: tgt, label: tgt, fileType: 'unknown', sourceFile: '' });
|
|
47
|
-
normToId.set(normalizeId(tgt), tgt);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (src === tgt)
|
|
51
|
-
continue;
|
|
52
|
-
try {
|
|
53
|
-
graph.addEdge(src, tgt, {
|
|
54
|
-
relation: edge.relation,
|
|
55
|
-
confidence: edge.confidence,
|
|
56
|
-
confidenceScore: edge.confidenceScore,
|
|
57
|
-
weight: edge.weight ?? 1,
|
|
58
|
-
sourceFile: edge.sourceFile,
|
|
59
|
-
sourceLocation: edge.sourceLocation,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
// Edge already exists — bump its weight
|
|
64
|
-
const existing = graph.edge(src, tgt);
|
|
65
|
-
if (existing) {
|
|
66
|
-
const prev = graph.getEdgeAttribute(existing, 'weight') ?? 1;
|
|
67
|
-
graph.setEdgeAttribute(existing, 'weight', prev + 1);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return graph;
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=build.js.map
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import Graph from 'graphology';
|
|
2
|
-
export async function detectCommunities(graph) {
|
|
3
|
-
let louvainFn = null;
|
|
4
|
-
try {
|
|
5
|
-
const mod = await import('graphology-communities-louvain');
|
|
6
|
-
louvainFn = mod.default;
|
|
7
|
-
}
|
|
8
|
-
catch { /* louvain not available */ }
|
|
9
|
-
if (louvainFn) {
|
|
10
|
-
try {
|
|
11
|
-
const assignment = louvainFn(graph);
|
|
12
|
-
for (const [nodeId, communityId] of Object.entries(assignment)) {
|
|
13
|
-
graph.setNodeAttribute(nodeId, 'community', communityId);
|
|
14
|
-
}
|
|
15
|
-
const communities = {};
|
|
16
|
-
for (const [nodeId, communityId] of Object.entries(assignment)) {
|
|
17
|
-
if (!communities[communityId])
|
|
18
|
-
communities[communityId] = [];
|
|
19
|
-
communities[communityId].push(nodeId);
|
|
20
|
-
}
|
|
21
|
-
return splitOversizedCommunities(graph, communities, 0.25, louvainFn);
|
|
22
|
-
}
|
|
23
|
-
catch { /* fall through */ }
|
|
24
|
-
}
|
|
25
|
-
return splitOversizedCommunities(graph, fallbackCluster(graph), 0.25, louvainFn);
|
|
26
|
-
}
|
|
27
|
-
function fallbackCluster(graph) {
|
|
28
|
-
const dirMap = new Map();
|
|
29
|
-
let nextId = 0;
|
|
30
|
-
const communities = {};
|
|
31
|
-
graph.forEachNode((id, attrs) => {
|
|
32
|
-
const file = attrs.sourceFile || '';
|
|
33
|
-
const parts = file.split('/');
|
|
34
|
-
const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : 'root';
|
|
35
|
-
if (!dirMap.has(dir))
|
|
36
|
-
dirMap.set(dir, nextId++);
|
|
37
|
-
const cid = dirMap.get(dir);
|
|
38
|
-
graph.setNodeAttribute(id, 'community', cid);
|
|
39
|
-
if (!communities[cid])
|
|
40
|
-
communities[cid] = [];
|
|
41
|
-
communities[cid].push(id);
|
|
42
|
-
});
|
|
43
|
-
return communities;
|
|
44
|
-
}
|
|
45
|
-
export function cohesionScore(graph, communityNodes) {
|
|
46
|
-
const memberSet = new Set(communityNodes);
|
|
47
|
-
let totalEdges = 0;
|
|
48
|
-
let internalEdges = 0;
|
|
49
|
-
graph.forEachEdge((_edge, _attrs, source, target) => {
|
|
50
|
-
const srcIn = memberSet.has(source);
|
|
51
|
-
const tgtIn = memberSet.has(target);
|
|
52
|
-
if (srcIn || tgtIn) {
|
|
53
|
-
totalEdges++;
|
|
54
|
-
if (srcIn && tgtIn)
|
|
55
|
-
internalEdges++;
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
return totalEdges === 0 ? 1.0 : internalEdges / totalEdges;
|
|
59
|
-
}
|
|
60
|
-
export function splitOversizedCommunities(graph, communities, threshold = 0.25, louvainFn = null) {
|
|
61
|
-
const maxSize = threshold * graph.order;
|
|
62
|
-
const allIds = Object.keys(communities).map(Number);
|
|
63
|
-
let nextId = allIds.length > 0 ? Math.max(...allIds) + 1 : 0;
|
|
64
|
-
for (const [cidStr, members] of Object.entries(communities)) {
|
|
65
|
-
if (members.length <= maxSize)
|
|
66
|
-
continue;
|
|
67
|
-
const cid = Number(cidStr);
|
|
68
|
-
// Attempt topology-based second pass via Louvain on the community subgraph
|
|
69
|
-
if (louvainFn && members.length >= 10) {
|
|
70
|
-
try {
|
|
71
|
-
const memberSet = new Set(members);
|
|
72
|
-
const subG = new Graph({ type: 'undirected', multi: false });
|
|
73
|
-
for (const nodeId of members)
|
|
74
|
-
subG.addNode(nodeId);
|
|
75
|
-
graph.forEachEdge((_e, _a, source, target) => {
|
|
76
|
-
if (memberSet.has(source) && memberSet.has(target) && source !== target && !subG.hasEdge(source, target))
|
|
77
|
-
subG.addEdge(source, target);
|
|
78
|
-
});
|
|
79
|
-
const subAssignment = louvainFn(subG);
|
|
80
|
-
const subCommunityCount = new Set(Object.values(subAssignment)).size;
|
|
81
|
-
if (subCommunityCount > 1 && subCommunityCount <= Math.ceil(members.length / 2)) {
|
|
82
|
-
const subIdMap = new Map();
|
|
83
|
-
const newSubIds = {};
|
|
84
|
-
for (const [nodeId, localId] of Object.entries(subAssignment)) {
|
|
85
|
-
if (!subIdMap.has(localId))
|
|
86
|
-
subIdMap.set(localId, nextId++);
|
|
87
|
-
const globalId = subIdMap.get(localId);
|
|
88
|
-
graph.setNodeAttribute(nodeId, 'community', globalId);
|
|
89
|
-
if (!newSubIds[globalId])
|
|
90
|
-
newSubIds[globalId] = [];
|
|
91
|
-
newSubIds[globalId].push(nodeId);
|
|
92
|
-
}
|
|
93
|
-
delete communities[cid];
|
|
94
|
-
Object.assign(communities, newSubIds);
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
catch { /* fall through to directory heuristic */ }
|
|
99
|
-
}
|
|
100
|
-
// Directory heuristic fallback
|
|
101
|
-
const subMap = new Map();
|
|
102
|
-
const newSubIds = {};
|
|
103
|
-
for (const nodeId of members) {
|
|
104
|
-
const file = graph.getNodeAttribute(nodeId, 'sourceFile') || '';
|
|
105
|
-
const parts = file.split('/');
|
|
106
|
-
const parentDir = parts.length > 1 ? parts[parts.length - 2] : 'root';
|
|
107
|
-
if (!subMap.has(parentDir))
|
|
108
|
-
subMap.set(parentDir, nextId++);
|
|
109
|
-
const subId = subMap.get(parentDir);
|
|
110
|
-
graph.setNodeAttribute(nodeId, 'community', subId);
|
|
111
|
-
if (!newSubIds[subId])
|
|
112
|
-
newSubIds[subId] = [];
|
|
113
|
-
newSubIds[subId].push(nodeId);
|
|
114
|
-
}
|
|
115
|
-
delete communities[cid];
|
|
116
|
-
Object.assign(communities, newSubIds);
|
|
117
|
-
}
|
|
118
|
-
return communities;
|
|
119
|
-
}
|
|
120
|
-
//# sourceMappingURL=cluster.js.map
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@monomind/graph",
|
|
3
|
-
"version": "1.4.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Knowledge graph engine for monomind — AST extraction, graph construction, community detection, and persistent codebase understanding",
|
|
6
|
-
"main": "./dist/src/index.js",
|
|
7
|
-
"types": "./dist/src/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/src/index.d.ts",
|
|
11
|
-
"import": "./dist/src/index.js"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"dist",
|
|
16
|
-
"src"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "tsc",
|
|
20
|
-
"test": "vitest run",
|
|
21
|
-
"clean": "rm -rf dist"
|
|
22
|
-
},
|
|
23
|
-
"dependencies": {
|
|
24
|
-
"graphology": "^0.25.4",
|
|
25
|
-
"graphology-types": "^0.24.7",
|
|
26
|
-
"graphology-communities-louvain": "^2.0.1",
|
|
27
|
-
"graphology-shortest-path": "^2.0.2",
|
|
28
|
-
"graphology-traversal": "^0.3.1",
|
|
29
|
-
"graphology-metrics": "^2.4.0",
|
|
30
|
-
"chokidar": "^3.6.0"
|
|
31
|
-
},
|
|
32
|
-
"devDependencies": {
|
|
33
|
-
"@types/node": "^20.0.0",
|
|
34
|
-
"typescript": "^5.3.0",
|
|
35
|
-
"vitest": "^4.1.4"
|
|
36
|
-
},
|
|
37
|
-
"optionalDependencies": {
|
|
38
|
-
"node-tree-sitter": "^0.22.4",
|
|
39
|
-
"tree-sitter-typescript": "^0.23.2",
|
|
40
|
-
"tree-sitter-javascript": "^0.23.1",
|
|
41
|
-
"tree-sitter-python": "^0.23.6",
|
|
42
|
-
"tree-sitter-go": "^0.23.4",
|
|
43
|
-
"tree-sitter-rust": "^0.23.2",
|
|
44
|
-
"tree-sitter-java": "^0.23.5",
|
|
45
|
-
"tree-sitter-c": "^0.23.4",
|
|
46
|
-
"tree-sitter-cpp": "^0.23.4",
|
|
47
|
-
"tree-sitter-ruby": "^0.23.1",
|
|
48
|
-
"tree-sitter-c-sharp": "^0.23.1",
|
|
49
|
-
"tree-sitter-kotlin": "^0.3.9",
|
|
50
|
-
"tree-sitter-swift": "^0.6.1",
|
|
51
|
-
"tree-sitter-scala": "^0.23.4",
|
|
52
|
-
"tree-sitter-php": "^0.23.11"
|
|
53
|
-
},
|
|
54
|
-
"publishConfig": {
|
|
55
|
-
"access": "public"
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MonoVector LLM WASM MCP Tools
|
|
3
|
-
*
|
|
4
|
-
* Exposes @monoes/ruvllm-wasm operations via MCP protocol.
|
|
5
|
-
* All tools gracefully degrade when the WASM package is not installed.
|
|
6
|
-
*/
|
|
7
|
-
import type { MCPTool } from './types.js';
|
|
8
|
-
export declare const ruvllmWasmTools: MCPTool[];
|
|
9
|
-
//# sourceMappingURL=ruvllm-tools.d.ts.map
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MonoVector LLM WASM MCP Tools
|
|
3
|
-
*
|
|
4
|
-
* Exposes @monoes/ruvllm-wasm operations via MCP protocol.
|
|
5
|
-
* All tools gracefully degrade when the WASM package is not installed.
|
|
6
|
-
*/
|
|
7
|
-
async function loadRuvllmWasm() {
|
|
8
|
-
return import('../monovector/ruvllm-wasm.js');
|
|
9
|
-
}
|
|
10
|
-
// ── Instance Registries ──────────────────────────────────────
|
|
11
|
-
const hnswRouters = new Map();
|
|
12
|
-
const sonaInstances = new Map();
|
|
13
|
-
const loraInstances = new Map();
|
|
14
|
-
// ── Map eviction (prevents WASM object leaks in long-running MCP servers) ────
|
|
15
|
-
const MAX_MAP_SIZE = 50;
|
|
16
|
-
function setWithEviction(map, key, value) {
|
|
17
|
-
if (map.size >= MAX_MAP_SIZE) {
|
|
18
|
-
// Evict the oldest entry (first inserted)
|
|
19
|
-
const firstKey = map.keys().next().value;
|
|
20
|
-
map.delete(firstKey);
|
|
21
|
-
}
|
|
22
|
-
map.set(key, value);
|
|
23
|
-
}
|
|
24
|
-
export const ruvllmWasmTools = [
|
|
25
|
-
{
|
|
26
|
-
name: 'ruvllm_status',
|
|
27
|
-
description: 'Get ruvllm-wasm availability and initialization status.',
|
|
28
|
-
inputSchema: { type: 'object', properties: {} },
|
|
29
|
-
handler: async () => {
|
|
30
|
-
try {
|
|
31
|
-
const mod = await loadRuvllmWasm();
|
|
32
|
-
const status = await mod.getRuvllmStatus();
|
|
33
|
-
return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] };
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
name: 'ruvllm_hnsw_create',
|
|
42
|
-
description: 'Create a WASM HNSW router for semantic pattern routing. Max ~11 patterns (v2.0.1 limit).',
|
|
43
|
-
inputSchema: {
|
|
44
|
-
type: 'object',
|
|
45
|
-
properties: {
|
|
46
|
-
dimensions: { type: 'number', description: 'Embedding dimensions (e.g., 64, 128, 384)' },
|
|
47
|
-
maxPatterns: { type: 'number', description: 'Max patterns capacity (limit ~11 in v2.0.1)' },
|
|
48
|
-
efSearch: { type: 'number', description: 'HNSW ef search parameter (higher = more accurate, slower)' },
|
|
49
|
-
},
|
|
50
|
-
required: ['dimensions', 'maxPatterns'],
|
|
51
|
-
},
|
|
52
|
-
handler: async (args) => {
|
|
53
|
-
try {
|
|
54
|
-
const mod = await loadRuvllmWasm();
|
|
55
|
-
const router = await mod.createHnswRouter({
|
|
56
|
-
dimensions: args.dimensions,
|
|
57
|
-
maxPatterns: args.maxPatterns,
|
|
58
|
-
efSearch: args.efSearch,
|
|
59
|
-
});
|
|
60
|
-
// Store router in module-level registry
|
|
61
|
-
const id = `hnsw-${Date.now().toString(36)}`;
|
|
62
|
-
setWithEviction(hnswRouters, id, router);
|
|
63
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: true, routerId: id, dimensions: args.dimensions, maxPatterns: args.maxPatterns }) }] };
|
|
64
|
-
}
|
|
65
|
-
catch (err) {
|
|
66
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'ruvllm_hnsw_add',
|
|
72
|
-
description: 'Add a pattern to an HNSW router. Embedding must match router dimensions.',
|
|
73
|
-
inputSchema: {
|
|
74
|
-
type: 'object',
|
|
75
|
-
properties: {
|
|
76
|
-
routerId: { type: 'string', description: 'HNSW router ID from ruvllm_hnsw_create' },
|
|
77
|
-
name: { type: 'string', description: 'Pattern name/label' },
|
|
78
|
-
embedding: { type: 'array', items: { type: 'number' }, description: 'Float array embedding vector' },
|
|
79
|
-
metadata: { type: 'object', description: 'Optional metadata object' },
|
|
80
|
-
},
|
|
81
|
-
required: ['routerId', 'name', 'embedding'],
|
|
82
|
-
},
|
|
83
|
-
handler: async (args) => {
|
|
84
|
-
try {
|
|
85
|
-
const router = hnswRouters.get(args.routerId);
|
|
86
|
-
if (!router)
|
|
87
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: `Router not found: ${args.routerId}` }) }], isError: true };
|
|
88
|
-
const embedding = new Float32Array(args.embedding);
|
|
89
|
-
const ok = router.addPattern({
|
|
90
|
-
name: args.name,
|
|
91
|
-
embedding,
|
|
92
|
-
metadata: args.metadata,
|
|
93
|
-
});
|
|
94
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: ok, patternCount: router.patternCount() }) }] };
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
name: 'ruvllm_hnsw_route',
|
|
103
|
-
description: 'Route a query embedding to nearest patterns in HNSW index.',
|
|
104
|
-
inputSchema: {
|
|
105
|
-
type: 'object',
|
|
106
|
-
properties: {
|
|
107
|
-
routerId: { type: 'string', description: 'HNSW router ID' },
|
|
108
|
-
query: { type: 'array', items: { type: 'number' }, description: 'Query embedding vector' },
|
|
109
|
-
k: { type: 'number', description: 'Number of nearest neighbors (default: 3)' },
|
|
110
|
-
},
|
|
111
|
-
required: ['routerId', 'query'],
|
|
112
|
-
},
|
|
113
|
-
handler: async (args) => {
|
|
114
|
-
try {
|
|
115
|
-
const router = hnswRouters.get(args.routerId);
|
|
116
|
-
if (!router)
|
|
117
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: `Router not found: ${args.routerId}` }) }], isError: true };
|
|
118
|
-
const query = new Float32Array(args.query);
|
|
119
|
-
const k = typeof args.k === 'number' && args.k > 0 ? Math.floor(args.k) : 3;
|
|
120
|
-
const results = router.route(query, k);
|
|
121
|
-
return { content: [{ type: 'text', text: JSON.stringify({ results }) }] };
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: 'ruvllm_sona_create',
|
|
130
|
-
description: 'Create a SONA instant adaptation loop (<1ms adaptation cycles).',
|
|
131
|
-
inputSchema: {
|
|
132
|
-
type: 'object',
|
|
133
|
-
properties: {
|
|
134
|
-
hiddenDim: { type: 'number', description: 'Hidden dimension (default: 64)' },
|
|
135
|
-
learningRate: { type: 'number', description: 'Learning rate (default: 0.01)' },
|
|
136
|
-
patternCapacity: { type: 'number', description: 'Max stored patterns' },
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
handler: async (args) => {
|
|
140
|
-
try {
|
|
141
|
-
const mod = await loadRuvllmWasm();
|
|
142
|
-
const sona = await mod.createSonaInstant({
|
|
143
|
-
hiddenDim: args.hiddenDim,
|
|
144
|
-
learningRate: args.learningRate,
|
|
145
|
-
patternCapacity: args.patternCapacity,
|
|
146
|
-
});
|
|
147
|
-
const id = `sona-${Date.now().toString(36)}`;
|
|
148
|
-
setWithEviction(sonaInstances, id, sona);
|
|
149
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: true, sonaId: id }) }] };
|
|
150
|
-
}
|
|
151
|
-
catch (err) {
|
|
152
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
name: 'ruvllm_sona_adapt',
|
|
158
|
-
description: 'Run SONA instant adaptation with a quality signal.',
|
|
159
|
-
inputSchema: {
|
|
160
|
-
type: 'object',
|
|
161
|
-
properties: {
|
|
162
|
-
sonaId: { type: 'string', description: 'SONA instance ID' },
|
|
163
|
-
quality: { type: 'number', description: 'Quality signal (0.0-1.0)' },
|
|
164
|
-
},
|
|
165
|
-
required: ['sonaId', 'quality'],
|
|
166
|
-
},
|
|
167
|
-
handler: async (args) => {
|
|
168
|
-
try {
|
|
169
|
-
const sona = sonaInstances.get(args.sonaId);
|
|
170
|
-
if (!sona)
|
|
171
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: `SONA not found: ${args.sonaId}` }) }], isError: true };
|
|
172
|
-
sona.adapt(args.quality);
|
|
173
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: true, stats: sona.stats() }) }] };
|
|
174
|
-
}
|
|
175
|
-
catch (err) {
|
|
176
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
name: 'ruvllm_microlora_create',
|
|
182
|
-
description: 'Create a MicroLoRA adapter (ultra-lightweight LoRA, ranks 1-4).',
|
|
183
|
-
inputSchema: {
|
|
184
|
-
type: 'object',
|
|
185
|
-
properties: {
|
|
186
|
-
inputDim: { type: 'number', description: 'Input dimension' },
|
|
187
|
-
outputDim: { type: 'number', description: 'Output dimension' },
|
|
188
|
-
rank: { type: 'number', description: 'LoRA rank (1-4, default: 2)' },
|
|
189
|
-
alpha: { type: 'number', description: 'LoRA alpha scaling (default: 1.0)' },
|
|
190
|
-
},
|
|
191
|
-
required: ['inputDim', 'outputDim'],
|
|
192
|
-
},
|
|
193
|
-
handler: async (args) => {
|
|
194
|
-
try {
|
|
195
|
-
const mod = await loadRuvllmWasm();
|
|
196
|
-
const lora = await mod.createMicroLora({
|
|
197
|
-
inputDim: args.inputDim,
|
|
198
|
-
outputDim: args.outputDim,
|
|
199
|
-
rank: args.rank,
|
|
200
|
-
alpha: args.alpha,
|
|
201
|
-
});
|
|
202
|
-
const id = `lora-${Date.now().toString(36)}`;
|
|
203
|
-
setWithEviction(loraInstances, id, lora);
|
|
204
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: true, loraId: id }) }] };
|
|
205
|
-
}
|
|
206
|
-
catch (err) {
|
|
207
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
name: 'ruvllm_microlora_adapt',
|
|
213
|
-
description: 'Adapt MicroLoRA weights with quality feedback.',
|
|
214
|
-
inputSchema: {
|
|
215
|
-
type: 'object',
|
|
216
|
-
properties: {
|
|
217
|
-
loraId: { type: 'string', description: 'MicroLoRA instance ID' },
|
|
218
|
-
quality: { type: 'number', description: 'Quality signal (0.0-1.0)' },
|
|
219
|
-
learningRate: { type: 'number', description: 'Learning rate (default: 0.01)' },
|
|
220
|
-
success: { type: 'boolean', description: 'Whether the adaptation was successful (default: true)' },
|
|
221
|
-
},
|
|
222
|
-
required: ['loraId', 'quality'],
|
|
223
|
-
},
|
|
224
|
-
handler: async (args) => {
|
|
225
|
-
try {
|
|
226
|
-
const lora = loraInstances.get(args.loraId);
|
|
227
|
-
if (!lora)
|
|
228
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: `MicroLoRA not found: ${args.loraId}` }) }], isError: true };
|
|
229
|
-
lora.adapt(args.quality, args.learningRate, args.success);
|
|
230
|
-
return { content: [{ type: 'text', text: JSON.stringify({ success: true, stats: lora.stats() }) }] };
|
|
231
|
-
}
|
|
232
|
-
catch (err) {
|
|
233
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
name: 'ruvllm_chat_format',
|
|
239
|
-
description: 'Format chat messages using a template (llama3, mistral, chatml, phi, gemma, or auto-detect).',
|
|
240
|
-
inputSchema: {
|
|
241
|
-
type: 'object',
|
|
242
|
-
properties: {
|
|
243
|
-
messages: {
|
|
244
|
-
type: 'array',
|
|
245
|
-
items: { type: 'object', properties: { role: { type: 'string' }, content: { type: 'string' } }, required: ['role', 'content'] },
|
|
246
|
-
description: 'Array of {role, content} message objects',
|
|
247
|
-
},
|
|
248
|
-
template: { type: 'string', description: 'Template preset (llama3, mistral, chatml, phi, gemma) or model ID for auto-detection' },
|
|
249
|
-
},
|
|
250
|
-
required: ['messages', 'template'],
|
|
251
|
-
},
|
|
252
|
-
handler: async (args) => {
|
|
253
|
-
try {
|
|
254
|
-
const mod = await loadRuvllmWasm();
|
|
255
|
-
const messages = args.messages;
|
|
256
|
-
const templateStr = args.template;
|
|
257
|
-
const presets = ['llama3', 'mistral', 'chatml', 'phi', 'gemma'];
|
|
258
|
-
const template = presets.includes(templateStr)
|
|
259
|
-
? templateStr
|
|
260
|
-
: { modelId: templateStr };
|
|
261
|
-
const formatted = await mod.formatChat(messages, template);
|
|
262
|
-
return { content: [{ type: 'text', text: formatted }] };
|
|
263
|
-
}
|
|
264
|
-
catch (err) {
|
|
265
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
266
|
-
}
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
{
|
|
270
|
-
name: 'ruvllm_generate_config',
|
|
271
|
-
description: 'Create a generation config (maxTokens, temperature, topP, etc.) as JSON.',
|
|
272
|
-
inputSchema: {
|
|
273
|
-
type: 'object',
|
|
274
|
-
properties: {
|
|
275
|
-
maxTokens: { type: 'number', description: 'Max tokens to generate' },
|
|
276
|
-
temperature: { type: 'number', description: 'Sampling temperature (note: f32 precision)' },
|
|
277
|
-
topP: { type: 'number', description: 'Top-p sampling' },
|
|
278
|
-
topK: { type: 'number', description: 'Top-k sampling' },
|
|
279
|
-
repetitionPenalty: { type: 'number', description: 'Repetition penalty' },
|
|
280
|
-
stopSequences: { type: 'array', items: { type: 'string' }, description: 'Stop sequences' },
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
handler: async (args) => {
|
|
284
|
-
try {
|
|
285
|
-
const mod = await loadRuvllmWasm();
|
|
286
|
-
const config = await mod.createGenerateConfig(args);
|
|
287
|
-
return { content: [{ type: 'text', text: config }] };
|
|
288
|
-
}
|
|
289
|
-
catch (err) {
|
|
290
|
-
return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
|
-
},
|
|
294
|
-
];
|
|
295
|
-
//# sourceMappingURL=ruvllm-tools.js.map
|