@ruvector/edge-net 0.1.5 → 0.1.7
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 +5 -1
- package/real-agents.js +480 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruvector/edge-net",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Distributed compute intelligence network with AI agents and workers - contribute browser compute, spawn distributed AI agents, earn credits. Features Time Crystal coordination, Neural DAG attention, P2P swarm intelligence, and multi-agent workflows.",
|
|
6
6
|
"main": "ruvector_edge_net.js",
|
|
@@ -114,5 +114,9 @@
|
|
|
114
114
|
"network": "node network.js stats",
|
|
115
115
|
"peers": "node join.js --peers",
|
|
116
116
|
"history": "node join.js --history"
|
|
117
|
+
},
|
|
118
|
+
"dependencies": {
|
|
119
|
+
"@ruvector/ruvllm": "^0.2.3",
|
|
120
|
+
"@xenova/transformers": "^2.17.2"
|
|
117
121
|
}
|
|
118
122
|
}
|
package/real-agents.js
CHANGED
|
@@ -21,19 +21,57 @@ import { join } from 'path';
|
|
|
21
21
|
// ============================================
|
|
22
22
|
|
|
23
23
|
const LLM_PROVIDERS = {
|
|
24
|
-
//
|
|
24
|
+
// ONNX LLM via transformers.js - Default, no API key needed
|
|
25
|
+
// Uses real ONNX models (SmolLM, TinyLlama, etc.)
|
|
25
26
|
local: {
|
|
26
|
-
name: '
|
|
27
|
+
name: 'ONNX Local',
|
|
27
28
|
type: 'local',
|
|
29
|
+
backend: 'onnx', // Primary: transformers.js ONNX
|
|
28
30
|
models: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
// TRM (Tiny Random Models) - Fastest
|
|
32
|
+
fast: process.env.ONNX_MODEL_FAST || 'Xenova/distilgpt2',
|
|
33
|
+
// SmolLM - Better quality
|
|
34
|
+
balanced: process.env.ONNX_MODEL || 'HuggingFaceTB/SmolLM-135M-Instruct',
|
|
35
|
+
// TinyLlama - Best small model
|
|
36
|
+
powerful: process.env.ONNX_MODEL_POWERFUL || 'HuggingFaceTB/SmolLM-360M-Instruct',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
onnx: {
|
|
40
|
+
name: 'ONNX Transformers.js',
|
|
41
|
+
type: 'local',
|
|
42
|
+
backend: 'onnx',
|
|
43
|
+
models: {
|
|
44
|
+
// TRM - Ultra tiny models
|
|
45
|
+
'trm-tinystories': 'Xenova/TinyStories-33M',
|
|
46
|
+
'trm-gpt2': 'Xenova/gpt2',
|
|
47
|
+
'trm-distilgpt2': 'Xenova/distilgpt2',
|
|
48
|
+
// SmolLM series
|
|
49
|
+
fast: 'HuggingFaceTB/SmolLM-135M-Instruct',
|
|
50
|
+
balanced: 'HuggingFaceTB/SmolLM-360M-Instruct',
|
|
51
|
+
powerful: 'TinyLlama/TinyLlama-1.1B-Chat-v1.0',
|
|
52
|
+
// Named models
|
|
53
|
+
'smollm-135m': 'HuggingFaceTB/SmolLM-135M-Instruct',
|
|
54
|
+
'smollm-360m': 'HuggingFaceTB/SmolLM-360M-Instruct',
|
|
55
|
+
'smollm2-135m': 'HuggingFaceTB/SmolLM2-135M-Instruct',
|
|
56
|
+
'tinyllama': 'TinyLlama/TinyLlama-1.1B-Chat-v1.0',
|
|
57
|
+
'qwen2.5-0.5b': 'Qwen/Qwen2.5-0.5B-Instruct',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
ollama: {
|
|
61
|
+
name: 'Ollama',
|
|
62
|
+
type: 'local',
|
|
63
|
+
backend: 'ollama',
|
|
64
|
+
baseUrl: process.env.OLLAMA_HOST || 'http://localhost:11434',
|
|
65
|
+
models: {
|
|
66
|
+
fast: process.env.OLLAMA_MODEL_FAST || 'qwen2.5:0.5b',
|
|
67
|
+
balanced: process.env.OLLAMA_MODEL || 'qwen2.5:1.5b',
|
|
68
|
+
powerful: process.env.OLLAMA_MODEL_POWERFUL || 'qwen2.5:3b',
|
|
32
69
|
},
|
|
33
70
|
},
|
|
34
71
|
ruvllm: {
|
|
35
|
-
name: 'RuvLLM',
|
|
72
|
+
name: 'RuvLLM (Legacy)',
|
|
36
73
|
type: 'local',
|
|
74
|
+
backend: 'ruvllm',
|
|
37
75
|
models: {
|
|
38
76
|
fast: 'ruvllm-fast',
|
|
39
77
|
balanced: 'ruvllm-balanced',
|
|
@@ -124,13 +162,92 @@ export class LLMClient {
|
|
|
124
162
|
throw new Error(`Unknown LLM provider: ${this.provider}`);
|
|
125
163
|
}
|
|
126
164
|
|
|
127
|
-
// Initialize local LLM
|
|
165
|
+
// Initialize local LLM backends
|
|
128
166
|
this.ruvllm = null;
|
|
129
167
|
this.ruvllmInitialized = false;
|
|
168
|
+
this.onnxPipeline = null;
|
|
169
|
+
this.onnxInitialized = false;
|
|
170
|
+
this.onnxModel = null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Initialize ONNX LLM via transformers.js
|
|
175
|
+
* This is the primary local inference method
|
|
176
|
+
*/
|
|
177
|
+
async initOnnx(modelId) {
|
|
178
|
+
if (this.onnxInitialized && this.onnxModel === modelId) return true;
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
console.log(`[LLM] Loading ONNX model: ${modelId}...`);
|
|
182
|
+
console.log('[LLM] First load may take a few minutes to download the model...');
|
|
183
|
+
|
|
184
|
+
const transformers = await import('@xenova/transformers');
|
|
185
|
+
const { pipeline, env } = transformers;
|
|
186
|
+
|
|
187
|
+
// Configure cache
|
|
188
|
+
env.cacheDir = process.env.ONNX_CACHE_DIR ||
|
|
189
|
+
(process.env.HOME ? `${process.env.HOME}/.ruvector/models/onnx` : '/tmp/.ruvector/models/onnx');
|
|
190
|
+
env.allowRemoteModels = true;
|
|
191
|
+
env.allowLocalModels = true;
|
|
192
|
+
|
|
193
|
+
// Create text generation pipeline
|
|
194
|
+
this.onnxPipeline = await pipeline('text-generation', modelId, {
|
|
195
|
+
quantized: true,
|
|
196
|
+
device: 'cpu',
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
this.onnxModel = modelId;
|
|
200
|
+
this.onnxInitialized = true;
|
|
201
|
+
console.log(`[LLM] ONNX model ready: ${modelId}`);
|
|
202
|
+
return true;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.warn('[LLM] ONNX init failed:', error.message);
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Call ONNX LLM for text generation
|
|
211
|
+
*/
|
|
212
|
+
async callOnnx(modelId, systemPrompt, userMessage, options = {}) {
|
|
213
|
+
await this.initOnnx(modelId);
|
|
214
|
+
if (!this.onnxPipeline) {
|
|
215
|
+
throw new Error('ONNX pipeline not initialized');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Build prompt (simple format for small models)
|
|
219
|
+
const prompt = systemPrompt
|
|
220
|
+
? `${systemPrompt}\n\nUser: ${userMessage}\n\nAssistant:`
|
|
221
|
+
: userMessage;
|
|
222
|
+
|
|
223
|
+
const start = Date.now();
|
|
224
|
+
|
|
225
|
+
const outputs = await this.onnxPipeline(prompt, {
|
|
226
|
+
max_new_tokens: options.maxTokens || 256,
|
|
227
|
+
temperature: options.temperature || 0.7,
|
|
228
|
+
top_p: options.topP || 0.9,
|
|
229
|
+
top_k: options.topK || 50,
|
|
230
|
+
repetition_penalty: 1.1,
|
|
231
|
+
do_sample: (options.temperature || 0.7) > 0,
|
|
232
|
+
return_full_text: false,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const timeMs = Date.now() - start;
|
|
236
|
+
const generatedText = outputs[0]?.generated_text || '';
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
content: generatedText.trim(),
|
|
240
|
+
model: modelId,
|
|
241
|
+
timeMs,
|
|
242
|
+
usage: {
|
|
243
|
+
input_tokens: Math.ceil(prompt.length / 4),
|
|
244
|
+
output_tokens: Math.ceil(generatedText.length / 4),
|
|
245
|
+
},
|
|
246
|
+
};
|
|
130
247
|
}
|
|
131
248
|
|
|
132
249
|
/**
|
|
133
|
-
* Initialize
|
|
250
|
+
* Initialize legacy ruvllm
|
|
134
251
|
*/
|
|
135
252
|
async initLocal() {
|
|
136
253
|
if (this.ruvllmInitialized) return;
|
|
@@ -172,45 +289,377 @@ export class LLMClient {
|
|
|
172
289
|
}
|
|
173
290
|
|
|
174
291
|
/**
|
|
175
|
-
* Call local
|
|
292
|
+
* Call local LLM (ONNX primary, Ollama fallback)
|
|
176
293
|
*/
|
|
177
294
|
async callLocal(systemPrompt, userMessage, options = {}) {
|
|
178
|
-
await this.initLocal();
|
|
179
|
-
|
|
180
295
|
const modelTier = options.model || this.model;
|
|
181
|
-
const
|
|
296
|
+
const modelName = this.config.models[modelTier] || this.config.models.balanced;
|
|
297
|
+
const backend = this.config.backend || 'onnx';
|
|
182
298
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
299
|
+
// ========================================
|
|
300
|
+
// 1. ONNX via transformers.js (Primary - REAL AI)
|
|
301
|
+
// ========================================
|
|
302
|
+
if (backend === 'onnx' || this.provider === 'local' || this.provider === 'onnx') {
|
|
303
|
+
try {
|
|
304
|
+
const onnxModelId = this.config.models[modelTier] || modelName;
|
|
305
|
+
const response = await this.callOnnx(onnxModelId, systemPrompt, userMessage, options);
|
|
306
|
+
|
|
307
|
+
// Validate response is meaningful
|
|
308
|
+
if (response.content && response.content.length > 5) {
|
|
309
|
+
return {
|
|
310
|
+
content: response.content,
|
|
311
|
+
model: response.model,
|
|
312
|
+
usage: response.usage,
|
|
313
|
+
stopReason: 'end',
|
|
314
|
+
local: true,
|
|
315
|
+
onnx: true,
|
|
316
|
+
timeMs: response.timeMs,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.log(`[LLM] ONNX not available: ${error.message}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// ========================================
|
|
325
|
+
// 2. Ollama (Fallback if ONNX unavailable)
|
|
326
|
+
// ========================================
|
|
327
|
+
if (backend === 'ollama' || this.config.baseUrl) {
|
|
328
|
+
const baseUrl = this.config.baseUrl || 'http://localhost:11434';
|
|
329
|
+
const ollamaModel = this.config.models[modelTier] || 'qwen2.5:0.5b';
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
const response = await this.callOllama(baseUrl, ollamaModel, systemPrompt, userMessage, options);
|
|
333
|
+
if (response) {
|
|
334
|
+
return {
|
|
335
|
+
content: response.content,
|
|
336
|
+
model: ollamaModel,
|
|
337
|
+
usage: response.usage || { input_tokens: 0, output_tokens: 0 },
|
|
338
|
+
stopReason: 'end',
|
|
339
|
+
local: true,
|
|
340
|
+
ollama: true,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
} catch (error) {
|
|
344
|
+
console.log(`[LLM] Ollama not available: ${error.message}`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
189
347
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
348
|
+
// ========================================
|
|
349
|
+
// 3. Legacy RuvLLM (if explicitly selected)
|
|
350
|
+
// ========================================
|
|
351
|
+
if (backend === 'ruvllm' || this.provider === 'ruvllm') {
|
|
352
|
+
await this.initLocal();
|
|
353
|
+
if (this.ruvllm) {
|
|
354
|
+
const prompt = `${systemPrompt}\n\n${userMessage}`;
|
|
355
|
+
const response = this.ruvllm.query(prompt, {
|
|
356
|
+
maxTokens: options.maxTokens || this.maxTokens,
|
|
357
|
+
temperature: options.temperature || 0.7,
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Check if response is valid (not garbage)
|
|
361
|
+
const isValidResponse = response.text &&
|
|
362
|
+
response.text.length > 10 &&
|
|
363
|
+
/[a-zA-Z]{3,}/.test(response.text) &&
|
|
364
|
+
!/^[>A-Z~|%#@\\+]+/.test(response.text);
|
|
365
|
+
|
|
366
|
+
if (isValidResponse) {
|
|
367
|
+
return {
|
|
368
|
+
content: response.text,
|
|
369
|
+
model: `ruvllm-${modelTier}`,
|
|
370
|
+
usage: { input_tokens: prompt.length, output_tokens: response.text.length },
|
|
371
|
+
stopReason: 'end',
|
|
372
|
+
confidence: response.confidence,
|
|
373
|
+
local: true,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
198
377
|
}
|
|
199
378
|
|
|
200
|
-
//
|
|
201
|
-
|
|
202
|
-
|
|
379
|
+
// ========================================
|
|
380
|
+
// 4. Smart Template Fallback (Last resort)
|
|
381
|
+
// ========================================
|
|
382
|
+
console.log('[LLM] Using smart template generation');
|
|
383
|
+
console.log('[LLM] Install @xenova/transformers for real ONNX AI inference');
|
|
384
|
+
const fallbackResponse = this.generateSmartResponse(systemPrompt, userMessage);
|
|
203
385
|
|
|
204
386
|
return {
|
|
205
387
|
content: fallbackResponse,
|
|
206
|
-
model: `
|
|
207
|
-
usage: { input_tokens:
|
|
388
|
+
model: `template-${modelTier}`,
|
|
389
|
+
usage: { input_tokens: systemPrompt.length + userMessage.length, output_tokens: fallbackResponse.length },
|
|
208
390
|
stopReason: 'end',
|
|
209
391
|
local: true,
|
|
210
392
|
fallback: true,
|
|
211
393
|
};
|
|
212
394
|
}
|
|
213
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Call Ollama API
|
|
398
|
+
*/
|
|
399
|
+
async callOllama(baseUrl, model, systemPrompt, userMessage, options = {}) {
|
|
400
|
+
const url = `${baseUrl}/api/chat`;
|
|
401
|
+
|
|
402
|
+
const body = {
|
|
403
|
+
model,
|
|
404
|
+
messages: [
|
|
405
|
+
{ role: 'system', content: systemPrompt },
|
|
406
|
+
{ role: 'user', content: userMessage },
|
|
407
|
+
],
|
|
408
|
+
stream: false,
|
|
409
|
+
options: {
|
|
410
|
+
temperature: options.temperature || 0.7,
|
|
411
|
+
num_predict: options.maxTokens || this.maxTokens,
|
|
412
|
+
},
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const response = await fetch(url, {
|
|
416
|
+
method: 'POST',
|
|
417
|
+
headers: { 'Content-Type': 'application/json' },
|
|
418
|
+
body: JSON.stringify(body),
|
|
419
|
+
signal: AbortSignal.timeout(options.timeout || 120000), // 2 min timeout
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
if (!response.ok) {
|
|
423
|
+
const errorText = await response.text();
|
|
424
|
+
throw new Error(`Ollama error ${response.status}: ${errorText}`);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const result = await response.json();
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
content: result.message?.content || '',
|
|
431
|
+
usage: {
|
|
432
|
+
input_tokens: result.prompt_eval_count || 0,
|
|
433
|
+
output_tokens: result.eval_count || 0,
|
|
434
|
+
},
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Generate smart contextual response based on task type
|
|
440
|
+
*/
|
|
441
|
+
generateSmartResponse(systemPrompt, userMessage) {
|
|
442
|
+
const task = userMessage.toLowerCase();
|
|
443
|
+
const promptLower = systemPrompt.toLowerCase();
|
|
444
|
+
|
|
445
|
+
// Review (check first - priority over code)
|
|
446
|
+
if (promptLower.includes('review') || task.includes('review')) {
|
|
447
|
+
return this.generateReviewResponse(userMessage);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Test
|
|
451
|
+
if (promptLower.includes('test') || task.includes('test')) {
|
|
452
|
+
return this.generateTestResponse(userMessage);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Research/analysis
|
|
456
|
+
if (promptLower.includes('research') || promptLower.includes('analy') || task.includes('research') || task.includes('analy')) {
|
|
457
|
+
return this.generateResearchResponse(userMessage);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Code generation (check keywords in user message)
|
|
461
|
+
if (promptLower.includes('coding') || promptLower.includes('coder') ||
|
|
462
|
+
task.includes('write') || task.includes('function') || task.includes('implement') ||
|
|
463
|
+
task.includes('create') || task.includes('build')) {
|
|
464
|
+
return this.generateCodeResponse(userMessage);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Default
|
|
468
|
+
return this.generateDefaultResponse(userMessage);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
generateCodeResponse(task) {
|
|
472
|
+
const taskLower = task.toLowerCase();
|
|
473
|
+
|
|
474
|
+
if (taskLower.includes('hello world')) {
|
|
475
|
+
return `Here's a hello world implementation:
|
|
476
|
+
|
|
477
|
+
\`\`\`javascript
|
|
478
|
+
function helloWorld() {
|
|
479
|
+
console.log('Hello, World!');
|
|
480
|
+
return 'Hello, World!';
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Usage
|
|
484
|
+
helloWorld();
|
|
485
|
+
\`\`\`
|
|
486
|
+
|
|
487
|
+
This function prints "Hello, World!" to the console and returns the string.`;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if (taskLower.includes('sort') || taskLower.includes('array')) {
|
|
491
|
+
return `Here's a sorting implementation:
|
|
492
|
+
|
|
493
|
+
\`\`\`javascript
|
|
494
|
+
function sortArray(arr, ascending = true) {
|
|
495
|
+
return [...arr].sort((a, b) => ascending ? a - b : b - a);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Example usage
|
|
499
|
+
const numbers = [5, 2, 8, 1, 9];
|
|
500
|
+
console.log(sortArray(numbers)); // [1, 2, 5, 8, 9]
|
|
501
|
+
console.log(sortArray(numbers, false)); // [9, 8, 5, 2, 1]
|
|
502
|
+
\`\`\``;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (taskLower.includes('fetch') || taskLower.includes('api') || taskLower.includes('http')) {
|
|
506
|
+
return `Here's an API fetch implementation:
|
|
507
|
+
|
|
508
|
+
\`\`\`javascript
|
|
509
|
+
async function fetchData(url, options = {}) {
|
|
510
|
+
try {
|
|
511
|
+
const response = await fetch(url, {
|
|
512
|
+
method: options.method || 'GET',
|
|
513
|
+
headers: { 'Content-Type': 'application/json', ...options.headers },
|
|
514
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
if (!response.ok) {
|
|
518
|
+
throw new Error(\`HTTP error! status: \${response.status}\`);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return await response.json();
|
|
522
|
+
} catch (error) {
|
|
523
|
+
console.error('Fetch error:', error);
|
|
524
|
+
throw error;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Usage
|
|
529
|
+
const data = await fetchData('https://api.example.com/data');
|
|
530
|
+
\`\`\``;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Generic code response
|
|
534
|
+
return `Based on your request: "${task.slice(0, 100)}..."
|
|
535
|
+
|
|
536
|
+
\`\`\`javascript
|
|
537
|
+
// Implementation
|
|
538
|
+
function solution(input) {
|
|
539
|
+
// Process input
|
|
540
|
+
const result = processInput(input);
|
|
541
|
+
|
|
542
|
+
// Apply transformation
|
|
543
|
+
const transformed = transform(result);
|
|
544
|
+
|
|
545
|
+
return transformed;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function processInput(data) {
|
|
549
|
+
// Validate and prepare data
|
|
550
|
+
return data;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
function transform(data) {
|
|
554
|
+
// Apply business logic
|
|
555
|
+
return { success: true, data };
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
module.exports = { solution };
|
|
559
|
+
\`\`\`
|
|
560
|
+
|
|
561
|
+
This provides a basic structure. For a complete implementation, please specify the exact requirements or use a cloud provider (-p anthropic or -p openai).`;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
generateResearchResponse(task) {
|
|
565
|
+
return `## Research Summary: ${task.slice(0, 60)}...
|
|
566
|
+
|
|
567
|
+
### Key Findings
|
|
568
|
+
|
|
569
|
+
1. **Overview**: This topic requires careful analysis of multiple factors.
|
|
570
|
+
|
|
571
|
+
2. **Primary Considerations**:
|
|
572
|
+
- Understand the core requirements
|
|
573
|
+
- Identify key stakeholders and constraints
|
|
574
|
+
- Review existing solutions and best practices
|
|
575
|
+
|
|
576
|
+
3. **Recommended Approach**:
|
|
577
|
+
- Start with a clear problem definition
|
|
578
|
+
- Gather data from reliable sources
|
|
579
|
+
- Validate assumptions with evidence
|
|
580
|
+
|
|
581
|
+
4. **Next Steps**:
|
|
582
|
+
- Conduct detailed analysis
|
|
583
|
+
- Document findings
|
|
584
|
+
- Present recommendations
|
|
585
|
+
|
|
586
|
+
*Note: For comprehensive research with real sources, use a cloud provider with -p anthropic or -p openai.*`;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
generateReviewResponse(task) {
|
|
590
|
+
return `## Code Review Summary
|
|
591
|
+
|
|
592
|
+
**Task**: ${task.slice(0, 80)}...
|
|
593
|
+
|
|
594
|
+
### Assessment
|
|
595
|
+
|
|
596
|
+
✅ **Strengths**:
|
|
597
|
+
- Code structure appears organized
|
|
598
|
+
- Basic functionality is present
|
|
599
|
+
|
|
600
|
+
⚠️ **Suggestions for Improvement**:
|
|
601
|
+
1. Add error handling for edge cases
|
|
602
|
+
2. Include input validation
|
|
603
|
+
3. Add JSDoc comments for documentation
|
|
604
|
+
4. Consider adding unit tests
|
|
605
|
+
5. Review for potential security issues
|
|
606
|
+
|
|
607
|
+
### Recommendations
|
|
608
|
+
- Follow consistent naming conventions
|
|
609
|
+
- Extract repeated logic into helper functions
|
|
610
|
+
- Add logging for debugging
|
|
611
|
+
|
|
612
|
+
*For detailed code analysis, use a cloud provider.*`;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
generateTestResponse(task) {
|
|
616
|
+
return `## Test Plan: ${task.slice(0, 60)}...
|
|
617
|
+
|
|
618
|
+
\`\`\`javascript
|
|
619
|
+
describe('Feature Tests', () => {
|
|
620
|
+
beforeEach(() => {
|
|
621
|
+
// Setup test environment
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
afterEach(() => {
|
|
625
|
+
// Cleanup
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
test('should handle normal input', () => {
|
|
629
|
+
const result = functionUnderTest(normalInput);
|
|
630
|
+
expect(result).toBeDefined();
|
|
631
|
+
expect(result.success).toBe(true);
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test('should handle edge cases', () => {
|
|
635
|
+
expect(() => functionUnderTest(null)).toThrow();
|
|
636
|
+
expect(() => functionUnderTest(undefined)).toThrow();
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
test('should handle error conditions', () => {
|
|
640
|
+
const result = functionUnderTest(invalidInput);
|
|
641
|
+
expect(result.error).toBeDefined();
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
\`\`\`
|
|
645
|
+
|
|
646
|
+
### Test Coverage Recommendations
|
|
647
|
+
- Unit tests for core functions
|
|
648
|
+
- Integration tests for API endpoints
|
|
649
|
+
- Edge case testing
|
|
650
|
+
- Performance benchmarks`;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
generateDefaultResponse(task) {
|
|
654
|
+
return `Response to: ${task.slice(0, 100)}...
|
|
655
|
+
|
|
656
|
+
This is a local response generated without cloud API calls. For full LLM capabilities:
|
|
657
|
+
1. Install @ruvector/ruvllm for local AI
|
|
658
|
+
2. Or set ANTHROPIC_API_KEY/OPENAI_API_KEY for cloud
|
|
659
|
+
|
|
660
|
+
Task acknowledged and processed locally.`;
|
|
661
|
+
}
|
|
662
|
+
|
|
214
663
|
/**
|
|
215
664
|
* Generate fallback response for basic tasks
|
|
216
665
|
*/
|