claude-flow 3.5.25 → 3.5.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow",
3
- "version": "3.5.25",
3
+ "version": "3.5.27",
4
4
  "description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -54,6 +54,7 @@
54
54
  "v3:security": "npm run security:audit && npm run security:test"
55
55
  },
56
56
  "dependencies": {
57
+ "@ruvector/ruvllm-wasm": "^2.0.0",
57
58
  "semver": "^7.6.0",
58
59
  "zod": "^3.22.4"
59
60
  },
@@ -34,6 +34,9 @@ import { coordinationTools } from './mcp-tools/coordination-tools.js';
34
34
  import { browserTools } from './mcp-tools/browser-tools.js';
35
35
  // Phase 6: AgentDB v3 controller tools
36
36
  import { agentdbTools } from './mcp-tools/agentdb-tools.js';
37
+ // RuVector WASM tools
38
+ import { ruvllmWasmTools } from './mcp-tools/ruvllm-tools.js';
39
+ import { wasmAgentTools } from './mcp-tools/wasm-agent-tools.js';
37
40
  /**
38
41
  * MCP Tool Registry
39
42
  * Maps tool names to their handler functions
@@ -73,6 +76,9 @@ registerTools([
73
76
  ...browserTools,
74
77
  // Phase 6: AgentDB v3 controller tools
75
78
  ...agentdbTools,
79
+ // RuVector WASM tools
80
+ ...ruvllmWasmTools,
81
+ ...wasmAgentTools,
76
82
  ]);
77
83
  /**
78
84
  * MCP Client Error
@@ -20,4 +20,6 @@ export { transferTools } from './transfer-tools.js';
20
20
  export { securityTools } from './security-tools.js';
21
21
  export { embeddingsTools } from './embeddings-tools.js';
22
22
  export { claimsTools } from './claims-tools.js';
23
+ export { wasmAgentTools } from './wasm-agent-tools.js';
24
+ export { ruvllmWasmTools } from './ruvllm-tools.js';
23
25
  //# sourceMappingURL=index.d.ts.map
@@ -19,4 +19,6 @@ export { transferTools } from './transfer-tools.js';
19
19
  export { securityTools } from './security-tools.js';
20
20
  export { embeddingsTools } from './embeddings-tools.js';
21
21
  export { claimsTools } from './claims-tools.js';
22
+ export { wasmAgentTools } from './wasm-agent-tools.js';
23
+ export { ruvllmWasmTools } from './ruvllm-tools.js';
22
24
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * RuVector LLM WASM MCP Tools
3
+ *
4
+ * Exposes @ruvector/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
@@ -0,0 +1,283 @@
1
+ /**
2
+ * RuVector LLM WASM MCP Tools
3
+ *
4
+ * Exposes @ruvector/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('../ruvector/ruvllm-wasm.js');
9
+ }
10
+ export const ruvllmWasmTools = [
11
+ {
12
+ name: 'ruvllm_status',
13
+ description: 'Get ruvllm-wasm availability and initialization status.',
14
+ inputSchema: { type: 'object', properties: {} },
15
+ handler: async () => {
16
+ try {
17
+ const mod = await loadRuvllmWasm();
18
+ const status = await mod.getRuvllmStatus();
19
+ return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] };
20
+ }
21
+ catch (err) {
22
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
23
+ }
24
+ },
25
+ },
26
+ {
27
+ name: 'ruvllm_hnsw_create',
28
+ description: 'Create a WASM HNSW router for semantic pattern routing. Max ~11 patterns (v2.0.1 limit).',
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ dimensions: { type: 'number', description: 'Embedding dimensions (e.g., 64, 128, 384)' },
33
+ maxPatterns: { type: 'number', description: 'Max patterns capacity (limit ~11 in v2.0.1)' },
34
+ efSearch: { type: 'number', description: 'HNSW ef search parameter (higher = more accurate, slower)' },
35
+ },
36
+ required: ['dimensions', 'maxPatterns'],
37
+ },
38
+ handler: async (args) => {
39
+ try {
40
+ const mod = await loadRuvllmWasm();
41
+ const router = await mod.createHnswRouter({
42
+ dimensions: args.dimensions,
43
+ maxPatterns: args.maxPatterns,
44
+ efSearch: args.efSearch,
45
+ });
46
+ // Store router in module-level registry
47
+ const id = `hnsw-${Date.now().toString(36)}`;
48
+ hnswRouters.set(id, router);
49
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, routerId: id, dimensions: args.dimensions, maxPatterns: args.maxPatterns }) }] };
50
+ }
51
+ catch (err) {
52
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
53
+ }
54
+ },
55
+ },
56
+ {
57
+ name: 'ruvllm_hnsw_add',
58
+ description: 'Add a pattern to an HNSW router. Embedding must match router dimensions.',
59
+ inputSchema: {
60
+ type: 'object',
61
+ properties: {
62
+ routerId: { type: 'string', description: 'HNSW router ID from ruvllm_hnsw_create' },
63
+ name: { type: 'string', description: 'Pattern name/label' },
64
+ embedding: { type: 'array', description: 'Float array embedding vector' },
65
+ metadata: { type: 'object', description: 'Optional metadata object' },
66
+ },
67
+ required: ['routerId', 'name', 'embedding'],
68
+ },
69
+ handler: async (args) => {
70
+ try {
71
+ const router = hnswRouters.get(args.routerId);
72
+ if (!router)
73
+ return { content: [{ type: 'text', text: JSON.stringify({ error: `Router not found: ${args.routerId}` }) }], isError: true };
74
+ const embedding = new Float32Array(args.embedding);
75
+ const ok = router.addPattern({
76
+ name: args.name,
77
+ embedding,
78
+ metadata: args.metadata,
79
+ });
80
+ return { content: [{ type: 'text', text: JSON.stringify({ success: ok, patternCount: router.patternCount() }) }] };
81
+ }
82
+ catch (err) {
83
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
84
+ }
85
+ },
86
+ },
87
+ {
88
+ name: 'ruvllm_hnsw_route',
89
+ description: 'Route a query embedding to nearest patterns in HNSW index.',
90
+ inputSchema: {
91
+ type: 'object',
92
+ properties: {
93
+ routerId: { type: 'string', description: 'HNSW router ID' },
94
+ query: { type: 'array', description: 'Query embedding vector' },
95
+ k: { type: 'number', description: 'Number of nearest neighbors (default: 3)' },
96
+ },
97
+ required: ['routerId', 'query'],
98
+ },
99
+ handler: async (args) => {
100
+ try {
101
+ const router = hnswRouters.get(args.routerId);
102
+ if (!router)
103
+ return { content: [{ type: 'text', text: JSON.stringify({ error: `Router not found: ${args.routerId}` }) }], isError: true };
104
+ const query = new Float32Array(args.query);
105
+ const results = router.route(query, args.k ?? 3);
106
+ return { content: [{ type: 'text', text: JSON.stringify({ results }) }] };
107
+ }
108
+ catch (err) {
109
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
110
+ }
111
+ },
112
+ },
113
+ {
114
+ name: 'ruvllm_sona_create',
115
+ description: 'Create a SONA instant adaptation loop (<1ms adaptation cycles).',
116
+ inputSchema: {
117
+ type: 'object',
118
+ properties: {
119
+ hiddenDim: { type: 'number', description: 'Hidden dimension (default: 64)' },
120
+ learningRate: { type: 'number', description: 'Learning rate (default: 0.01)' },
121
+ patternCapacity: { type: 'number', description: 'Max stored patterns' },
122
+ },
123
+ },
124
+ handler: async (args) => {
125
+ try {
126
+ const mod = await loadRuvllmWasm();
127
+ const sona = await mod.createSonaInstant({
128
+ hiddenDim: args.hiddenDim,
129
+ learningRate: args.learningRate,
130
+ patternCapacity: args.patternCapacity,
131
+ });
132
+ const id = `sona-${Date.now().toString(36)}`;
133
+ sonaInstances.set(id, sona);
134
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, sonaId: id }) }] };
135
+ }
136
+ catch (err) {
137
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
138
+ }
139
+ },
140
+ },
141
+ {
142
+ name: 'ruvllm_sona_adapt',
143
+ description: 'Run SONA instant adaptation with a quality signal.',
144
+ inputSchema: {
145
+ type: 'object',
146
+ properties: {
147
+ sonaId: { type: 'string', description: 'SONA instance ID' },
148
+ quality: { type: 'number', description: 'Quality signal (0.0-1.0)' },
149
+ },
150
+ required: ['sonaId', 'quality'],
151
+ },
152
+ handler: async (args) => {
153
+ try {
154
+ const sona = sonaInstances.get(args.sonaId);
155
+ if (!sona)
156
+ return { content: [{ type: 'text', text: JSON.stringify({ error: `SONA not found: ${args.sonaId}` }) }], isError: true };
157
+ sona.adapt(args.quality);
158
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, stats: sona.stats() }) }] };
159
+ }
160
+ catch (err) {
161
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
162
+ }
163
+ },
164
+ },
165
+ {
166
+ name: 'ruvllm_microlora_create',
167
+ description: 'Create a MicroLoRA adapter (ultra-lightweight LoRA, ranks 1-4).',
168
+ inputSchema: {
169
+ type: 'object',
170
+ properties: {
171
+ inputDim: { type: 'number', description: 'Input dimension' },
172
+ outputDim: { type: 'number', description: 'Output dimension' },
173
+ rank: { type: 'number', description: 'LoRA rank (1-4, default: 2)' },
174
+ alpha: { type: 'number', description: 'LoRA alpha scaling (default: 1.0)' },
175
+ },
176
+ required: ['inputDim', 'outputDim'],
177
+ },
178
+ handler: async (args) => {
179
+ try {
180
+ const mod = await loadRuvllmWasm();
181
+ const lora = await mod.createMicroLora({
182
+ inputDim: args.inputDim,
183
+ outputDim: args.outputDim,
184
+ rank: args.rank,
185
+ alpha: args.alpha,
186
+ });
187
+ const id = `lora-${Date.now().toString(36)}`;
188
+ loraInstances.set(id, lora);
189
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, loraId: id }) }] };
190
+ }
191
+ catch (err) {
192
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
193
+ }
194
+ },
195
+ },
196
+ {
197
+ name: 'ruvllm_microlora_adapt',
198
+ description: 'Adapt MicroLoRA weights with quality feedback.',
199
+ inputSchema: {
200
+ type: 'object',
201
+ properties: {
202
+ loraId: { type: 'string', description: 'MicroLoRA instance ID' },
203
+ quality: { type: 'number', description: 'Quality signal (0.0-1.0)' },
204
+ learningRate: { type: 'number', description: 'Learning rate (default: 0.01)' },
205
+ success: { type: 'boolean', description: 'Whether the adaptation was successful (default: true)' },
206
+ },
207
+ required: ['loraId', 'quality'],
208
+ },
209
+ handler: async (args) => {
210
+ try {
211
+ const lora = loraInstances.get(args.loraId);
212
+ if (!lora)
213
+ return { content: [{ type: 'text', text: JSON.stringify({ error: `MicroLoRA not found: ${args.loraId}` }) }], isError: true };
214
+ lora.adapt(args.quality, args.learningRate, args.success);
215
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, stats: lora.stats() }) }] };
216
+ }
217
+ catch (err) {
218
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
219
+ }
220
+ },
221
+ },
222
+ {
223
+ name: 'ruvllm_chat_format',
224
+ description: 'Format chat messages using a template (llama3, mistral, chatml, phi, gemma, or auto-detect).',
225
+ inputSchema: {
226
+ type: 'object',
227
+ properties: {
228
+ messages: {
229
+ type: 'array',
230
+ description: 'Array of {role, content} message objects',
231
+ },
232
+ template: { type: 'string', description: 'Template preset (llama3, mistral, chatml, phi, gemma) or model ID for auto-detection' },
233
+ },
234
+ required: ['messages', 'template'],
235
+ },
236
+ handler: async (args) => {
237
+ try {
238
+ const mod = await loadRuvllmWasm();
239
+ const messages = args.messages;
240
+ const templateStr = args.template;
241
+ const presets = ['llama3', 'mistral', 'chatml', 'phi', 'gemma'];
242
+ const template = presets.includes(templateStr)
243
+ ? templateStr
244
+ : { modelId: templateStr };
245
+ const formatted = await mod.formatChat(messages, template);
246
+ return { content: [{ type: 'text', text: formatted }] };
247
+ }
248
+ catch (err) {
249
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
250
+ }
251
+ },
252
+ },
253
+ {
254
+ name: 'ruvllm_generate_config',
255
+ description: 'Create a generation config (maxTokens, temperature, topP, etc.) as JSON.',
256
+ inputSchema: {
257
+ type: 'object',
258
+ properties: {
259
+ maxTokens: { type: 'number', description: 'Max tokens to generate' },
260
+ temperature: { type: 'number', description: 'Sampling temperature (note: f32 precision)' },
261
+ topP: { type: 'number', description: 'Top-p sampling' },
262
+ topK: { type: 'number', description: 'Top-k sampling' },
263
+ repetitionPenalty: { type: 'number', description: 'Repetition penalty' },
264
+ stopSequences: { type: 'array', description: 'Stop sequences' },
265
+ },
266
+ },
267
+ handler: async (args) => {
268
+ try {
269
+ const mod = await loadRuvllmWasm();
270
+ const config = await mod.createGenerateConfig(args);
271
+ return { content: [{ type: 'text', text: config }] };
272
+ }
273
+ catch (err) {
274
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
275
+ }
276
+ },
277
+ },
278
+ ];
279
+ // ── Instance Registries ──────────────────────────────────────
280
+ const hnswRouters = new Map();
281
+ const sonaInstances = new Map();
282
+ const loraInstances = new Map();
283
+ //# sourceMappingURL=ruvllm-tools.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * WASM Agent MCP Tools
3
+ *
4
+ * Exposes @ruvector/rvagent-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 wasmAgentTools: MCPTool[];
9
+ //# sourceMappingURL=wasm-agent-tools.d.ts.map
@@ -0,0 +1,230 @@
1
+ /**
2
+ * WASM Agent MCP Tools
3
+ *
4
+ * Exposes @ruvector/rvagent-wasm operations via MCP protocol.
5
+ * All tools gracefully degrade when the WASM package is not installed.
6
+ */
7
+ async function loadAgentWasm() {
8
+ const mod = await import('../ruvector/agent-wasm.js');
9
+ return mod;
10
+ }
11
+ export const wasmAgentTools = [
12
+ {
13
+ name: 'wasm_agent_create',
14
+ description: 'Create a sandboxed WASM agent with virtual filesystem (no OS access). Optionally use a gallery template.',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ template: { type: 'string', description: 'Gallery template name (coder, researcher, tester, reviewer, security, swarm)' },
19
+ model: { type: 'string', description: 'Model identifier (default: anthropic:claude-sonnet-4-20250514)' },
20
+ instructions: { type: 'string', description: 'System instructions for the agent' },
21
+ maxTurns: { type: 'number', description: 'Max conversation turns (default: 50)' },
22
+ },
23
+ },
24
+ handler: async (args) => {
25
+ try {
26
+ const wasm = await loadAgentWasm();
27
+ if (args.template) {
28
+ const info = await wasm.createAgentFromTemplate(args.template);
29
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, agent: info, source: 'gallery' }, null, 2) }] };
30
+ }
31
+ const info = await wasm.createWasmAgent({
32
+ model: args.model,
33
+ instructions: args.instructions,
34
+ maxTurns: args.maxTurns,
35
+ });
36
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, agent: info }, null, 2) }] };
37
+ }
38
+ catch (err) {
39
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
40
+ }
41
+ },
42
+ },
43
+ {
44
+ name: 'wasm_agent_prompt',
45
+ description: 'Send a prompt to a WASM agent and get a response.',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ agentId: { type: 'string', description: 'WASM agent ID' },
50
+ input: { type: 'string', description: 'User prompt to send' },
51
+ },
52
+ required: ['agentId', 'input'],
53
+ },
54
+ handler: async (args) => {
55
+ try {
56
+ const wasm = await loadAgentWasm();
57
+ const result = await wasm.promptWasmAgent(args.agentId, args.input);
58
+ return { content: [{ type: 'text', text: result }] };
59
+ }
60
+ catch (err) {
61
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
62
+ }
63
+ },
64
+ },
65
+ {
66
+ name: 'wasm_agent_tool',
67
+ description: 'Execute a tool on a WASM agent sandbox. Tools: read_file, write_file, edit_file, write_todos, list_files. Use flat format: {tool, path, content, ...}.',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: {
71
+ agentId: { type: 'string', description: 'WASM agent ID' },
72
+ toolName: { type: 'string', description: 'Tool name (read_file, write_file, edit_file, write_todos, list_files)' },
73
+ toolInput: { type: 'object', description: 'Tool parameters (flat: {path, content, old_string, new_string, todos})' },
74
+ },
75
+ required: ['agentId', 'toolName'],
76
+ },
77
+ handler: async (args) => {
78
+ try {
79
+ const wasm = await loadAgentWasm();
80
+ // Flat format: {tool: 'write_file', path: '...', content: '...'}
81
+ const toolCall = {
82
+ tool: args.toolName,
83
+ ...(args.toolInput ?? {}),
84
+ };
85
+ const result = await wasm.executeWasmTool(args.agentId, toolCall);
86
+ return { content: [{ type: 'text', text: JSON.stringify(result) }] };
87
+ }
88
+ catch (err) {
89
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
90
+ }
91
+ },
92
+ },
93
+ {
94
+ name: 'wasm_agent_list',
95
+ description: 'List all active WASM agents.',
96
+ inputSchema: { type: 'object', properties: {} },
97
+ handler: async () => {
98
+ try {
99
+ const wasm = await loadAgentWasm();
100
+ const agents = wasm.listWasmAgents();
101
+ return { content: [{ type: 'text', text: JSON.stringify({ agents, count: agents.length }, null, 2) }] };
102
+ }
103
+ catch (err) {
104
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
105
+ }
106
+ },
107
+ },
108
+ {
109
+ name: 'wasm_agent_terminate',
110
+ description: 'Terminate a WASM agent and free resources.',
111
+ inputSchema: {
112
+ type: 'object',
113
+ properties: {
114
+ agentId: { type: 'string', description: 'WASM agent ID' },
115
+ },
116
+ required: ['agentId'],
117
+ },
118
+ handler: async (args) => {
119
+ try {
120
+ const wasm = await loadAgentWasm();
121
+ const ok = wasm.terminateWasmAgent(args.agentId);
122
+ return { content: [{ type: 'text', text: JSON.stringify({ success: ok }) }] };
123
+ }
124
+ catch (err) {
125
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
126
+ }
127
+ },
128
+ },
129
+ {
130
+ name: 'wasm_agent_files',
131
+ description: 'Get a WASM agent\'s available tools and info.',
132
+ inputSchema: {
133
+ type: 'object',
134
+ properties: {
135
+ agentId: { type: 'string', description: 'WASM agent ID' },
136
+ },
137
+ required: ['agentId'],
138
+ },
139
+ handler: async (args) => {
140
+ try {
141
+ const wasm = await loadAgentWasm();
142
+ const tools = wasm.getWasmAgentTools(args.agentId);
143
+ const info = wasm.getWasmAgent(args.agentId);
144
+ return { content: [{ type: 'text', text: JSON.stringify({ tools, fileCount: info?.fileCount ?? 0, turnCount: info?.turnCount ?? 0 }, null, 2) }] };
145
+ }
146
+ catch (err) {
147
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
148
+ }
149
+ },
150
+ },
151
+ {
152
+ name: 'wasm_agent_export',
153
+ description: 'Export a WASM agent\'s full state (config, filesystem, conversation) as JSON.',
154
+ inputSchema: {
155
+ type: 'object',
156
+ properties: {
157
+ agentId: { type: 'string', description: 'WASM agent ID' },
158
+ },
159
+ required: ['agentId'],
160
+ },
161
+ handler: async (args) => {
162
+ try {
163
+ const wasm = await loadAgentWasm();
164
+ const state = wasm.exportWasmState(args.agentId);
165
+ return { content: [{ type: 'text', text: state }] };
166
+ }
167
+ catch (err) {
168
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
169
+ }
170
+ },
171
+ },
172
+ {
173
+ name: 'wasm_gallery_list',
174
+ description: 'List all available WASM agent gallery templates (Coder, Researcher, Tester, Reviewer, Security, Swarm).',
175
+ inputSchema: { type: 'object', properties: {} },
176
+ handler: async () => {
177
+ try {
178
+ const wasm = await loadAgentWasm();
179
+ const templates = await wasm.listGalleryTemplates();
180
+ return { content: [{ type: 'text', text: JSON.stringify({ templates, count: templates.length }, null, 2) }] };
181
+ }
182
+ catch (err) {
183
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
184
+ }
185
+ },
186
+ },
187
+ {
188
+ name: 'wasm_gallery_search',
189
+ description: 'Search WASM agent gallery templates by query.',
190
+ inputSchema: {
191
+ type: 'object',
192
+ properties: {
193
+ query: { type: 'string', description: 'Search query' },
194
+ },
195
+ required: ['query'],
196
+ },
197
+ handler: async (args) => {
198
+ try {
199
+ const wasm = await loadAgentWasm();
200
+ const results = await wasm.searchGalleryTemplates(args.query);
201
+ return { content: [{ type: 'text', text: JSON.stringify({ results, count: results.length }, null, 2) }] };
202
+ }
203
+ catch (err) {
204
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
205
+ }
206
+ },
207
+ },
208
+ {
209
+ name: 'wasm_gallery_create',
210
+ description: 'Create a WASM agent from a gallery template.',
211
+ inputSchema: {
212
+ type: 'object',
213
+ properties: {
214
+ template: { type: 'string', description: 'Template name (coder, researcher, tester, reviewer, security, swarm)' },
215
+ },
216
+ required: ['template'],
217
+ },
218
+ handler: async (args) => {
219
+ try {
220
+ const wasm = await loadAgentWasm();
221
+ const info = await wasm.createAgentFromTemplate(args.template);
222
+ return { content: [{ type: 'text', text: JSON.stringify({ success: true, agent: info, template: args.template }, null, 2) }] };
223
+ }
224
+ catch (err) {
225
+ return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
226
+ }
227
+ },
228
+ },
229
+ ];
230
+ //# sourceMappingURL=wasm-agent-tools.js.map
@@ -1315,6 +1315,60 @@ export async function loadEmbeddingModel(options) {
1315
1315
  loadTime: Date.now() - startTime
1316
1316
  };
1317
1317
  }
1318
+ // Fallback: Check for ruvector ONNX embedder (bundled MiniLM-L6-v2 since v0.2.15)
1319
+ // v0.2.16: LoRA B=0 fix makes AdaptiveEmbedder safe (identity when untrained)
1320
+ const ruvector = await import('ruvector').catch(() => null);
1321
+ if (ruvector?.initOnnxEmbedder) {
1322
+ try {
1323
+ await ruvector.initOnnxEmbedder();
1324
+ // Prefer AdaptiveEmbedder (LoRA adaptation capability, identity when untrained)
1325
+ if (ruvector.AdaptiveEmbedder) {
1326
+ try {
1327
+ const adaptive = new ruvector.AdaptiveEmbedder({ useEpisodic: false });
1328
+ if (adaptive?.embed && adaptive.isReady?.()) {
1329
+ if (verbose) {
1330
+ console.log('Loading ruvector AdaptiveEmbedder (all-MiniLM-L6-v2 + LoRA)...');
1331
+ }
1332
+ embeddingModelState = {
1333
+ loaded: true,
1334
+ model: (text) => adaptive.embed(text),
1335
+ tokenizer: null,
1336
+ dimensions: adaptive.getDimension?.() || 384
1337
+ };
1338
+ return {
1339
+ success: true,
1340
+ dimensions: adaptive.getDimension?.() || 384,
1341
+ modelName: 'ruvector/adaptive',
1342
+ loadTime: Date.now() - startTime
1343
+ };
1344
+ }
1345
+ }
1346
+ catch { /* fall through to OptimizedOnnxEmbedder */ }
1347
+ }
1348
+ // Fallback: OptimizedOnnxEmbedder (raw ONNX without LoRA)
1349
+ const onnxEmb = ruvector.getOptimizedOnnxEmbedder?.();
1350
+ if (onnxEmb?.embed && onnxEmb.isReady?.()) {
1351
+ if (verbose) {
1352
+ console.log('Loading ruvector ONNX embedder (all-MiniLM-L6-v2)...');
1353
+ }
1354
+ embeddingModelState = {
1355
+ loaded: true,
1356
+ model: (text) => onnxEmb.embed(text),
1357
+ tokenizer: null,
1358
+ dimensions: onnxEmb.getDimension?.() || 384
1359
+ };
1360
+ return {
1361
+ success: true,
1362
+ dimensions: onnxEmb.getDimension?.() || 384,
1363
+ modelName: 'ruvector/onnx',
1364
+ loadTime: Date.now() - startTime
1365
+ };
1366
+ }
1367
+ }
1368
+ catch {
1369
+ // ruvector ONNX init failed, continue to next fallback
1370
+ }
1371
+ }
1318
1372
  // Legacy fallback: Check for agentic-flow core embeddings
1319
1373
  const agenticFlow = await import('agentic-flow').catch(() => null);
1320
1374
  if (agenticFlow && agenticFlow.embeddings) {
@@ -1378,12 +1432,17 @@ export async function generateEmbedding(text) {
1378
1432
  if (state.model && typeof state.model === 'function') {
1379
1433
  try {
1380
1434
  const output = await state.model(text, { pooling: 'mean', normalize: true });
1381
- const embedding = Array.from(output.data);
1382
- return {
1383
- embedding,
1384
- dimensions: embedding.length,
1385
- model: 'onnx'
1386
- };
1435
+ // Handle both @xenova/transformers (output.data) and ruvector (plain array) formats
1436
+ const embedding = output?.data
1437
+ ? Array.from(output.data)
1438
+ : Array.isArray(output) ? output : null;
1439
+ if (embedding) {
1440
+ return {
1441
+ embedding,
1442
+ dimensions: embedding.length,
1443
+ model: 'onnx'
1444
+ };
1445
+ }
1387
1446
  }
1388
1447
  catch {
1389
1448
  // Fall through to fallback