ruvector 0.1.91 → 0.1.92
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/bin/cli.js +258 -10
- package/bin/mcp-server.js +26 -21
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -7380,13 +7380,13 @@ edgeNetCmd.command('status')
|
|
|
7380
7380
|
// REAL AGENT COMMANDS (Actual LLM Execution)
|
|
7381
7381
|
// ============================================
|
|
7382
7382
|
|
|
7383
|
-
const agentCmd = program.command('agent').description('Real AI agent execution
|
|
7383
|
+
const agentCmd = program.command('agent').description('Real AI agent execution - local ruvllm by default, or cloud APIs (Anthropic/OpenAI)');
|
|
7384
7384
|
|
|
7385
7385
|
agentCmd.command('run')
|
|
7386
|
-
.description('Execute a task with a real AI agent (
|
|
7386
|
+
.description('Execute a task with a real AI agent (local ruvllm by default, no API key needed)')
|
|
7387
7387
|
.argument('<type>', 'Agent type: researcher, coder, reviewer, tester, analyst, optimizer, coordinator, embedder')
|
|
7388
7388
|
.argument('<task>', 'Task description for the agent to execute')
|
|
7389
|
-
.option('-p, --provider <provider>', 'LLM provider: anthropic
|
|
7389
|
+
.option('-p, --provider <provider>', 'LLM provider: local (default), anthropic, openai', 'local')
|
|
7390
7390
|
.option('-m, --model <model>', 'Model tier: fast, balanced, powerful', 'balanced')
|
|
7391
7391
|
.option('-f, --files <files...>', 'Files to include as context')
|
|
7392
7392
|
.option('-c, --context <context>', 'Additional context string')
|
|
@@ -7396,14 +7396,19 @@ agentCmd.command('run')
|
|
|
7396
7396
|
.action(async (type, task, opts) => {
|
|
7397
7397
|
const spinner = ora('Initializing real agent...').start();
|
|
7398
7398
|
|
|
7399
|
-
// Check for API key
|
|
7399
|
+
// Check for API key (only required for cloud providers)
|
|
7400
7400
|
const apiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY;
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
console.log(chalk.
|
|
7406
|
-
console.log(chalk.
|
|
7401
|
+
const isLocal = opts.provider === 'local' || opts.provider === 'ruvllm';
|
|
7402
|
+
|
|
7403
|
+
if (!isLocal && !apiKey && type !== 'embedder') {
|
|
7404
|
+
spinner.fail('No API key found for cloud provider');
|
|
7405
|
+
console.log(chalk.red('\n❌ Cloud provider requires an API key.\n'));
|
|
7406
|
+
console.log(chalk.bold('Options:'));
|
|
7407
|
+
console.log(chalk.green(' 1. Use local ruvllm (default, no key needed):'));
|
|
7408
|
+
console.log(chalk.cyan(' ruvector agent run coder "task" -p local\n'));
|
|
7409
|
+
console.log(chalk.yellow(' 2. Or set a cloud API key:'));
|
|
7410
|
+
console.log(chalk.cyan(' export ANTHROPIC_API_KEY=your-key-here'));
|
|
7411
|
+
console.log(chalk.cyan(' export OPENAI_API_KEY=your-key-here'));
|
|
7407
7412
|
console.log(chalk.dim('\nGet an API key:'));
|
|
7408
7413
|
console.log(chalk.dim(' Anthropic: https://console.anthropic.com/'));
|
|
7409
7414
|
console.log(chalk.dim(' OpenAI: https://platform.openai.com/api-keys\n'));
|
|
@@ -7578,6 +7583,249 @@ agentCmd.command('balance')
|
|
|
7578
7583
|
}
|
|
7579
7584
|
});
|
|
7580
7585
|
|
|
7586
|
+
// ============================================
|
|
7587
|
+
// REAL WORKER POOL COMMANDS
|
|
7588
|
+
// ============================================
|
|
7589
|
+
|
|
7590
|
+
const workerCmd = program.command('worker').description('Real worker pool execution with Node.js worker_threads');
|
|
7591
|
+
|
|
7592
|
+
workerCmd.command('create')
|
|
7593
|
+
.description('Create a real worker pool for parallel task execution')
|
|
7594
|
+
.option('-s, --size <size>', 'Pool size (number of workers)', String(require('os').cpus().length - 1))
|
|
7595
|
+
.option('--relay <url>', 'Relay server URL for distributed mode')
|
|
7596
|
+
.option('--json', 'Output as JSON')
|
|
7597
|
+
.action(async (opts) => {
|
|
7598
|
+
const spinner = ora('Creating worker pool...').start();
|
|
7599
|
+
|
|
7600
|
+
try {
|
|
7601
|
+
let RealWorkerPool;
|
|
7602
|
+
try {
|
|
7603
|
+
const realWorkers = await import('@ruvector/edge-net/real-workers');
|
|
7604
|
+
RealWorkerPool = realWorkers.RealWorkerPool;
|
|
7605
|
+
} catch (e) {
|
|
7606
|
+
const realWorkersPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-workers.js');
|
|
7607
|
+
const realWorkers = await import(realWorkersPath);
|
|
7608
|
+
RealWorkerPool = realWorkers.RealWorkerPool;
|
|
7609
|
+
}
|
|
7610
|
+
|
|
7611
|
+
const pool = new RealWorkerPool({
|
|
7612
|
+
size: parseInt(opts.size) || require('os').cpus().length - 1,
|
|
7613
|
+
});
|
|
7614
|
+
|
|
7615
|
+
await pool.initialize();
|
|
7616
|
+
|
|
7617
|
+
spinner.succeed(`Worker pool created: ${pool.id}`);
|
|
7618
|
+
|
|
7619
|
+
const info = {
|
|
7620
|
+
id: pool.id,
|
|
7621
|
+
size: pool.size,
|
|
7622
|
+
workers: pool.workers.map(w => ({ id: w.id, status: w.status })),
|
|
7623
|
+
ready: pool.workers.filter(w => w.status === 'ready').length,
|
|
7624
|
+
};
|
|
7625
|
+
|
|
7626
|
+
if (opts.json) {
|
|
7627
|
+
console.log(JSON.stringify(info, null, 2));
|
|
7628
|
+
} else {
|
|
7629
|
+
console.log(chalk.bold.cyan('\n⚡ Real Worker Pool Created\n'));
|
|
7630
|
+
console.log(`${chalk.cyan('Pool ID:')} ${info.id}`);
|
|
7631
|
+
console.log(`${chalk.cyan('Size:')} ${info.size} workers`);
|
|
7632
|
+
console.log(`${chalk.cyan('Ready:')} ${info.ready}/${info.size}`);
|
|
7633
|
+
console.log();
|
|
7634
|
+
}
|
|
7635
|
+
|
|
7636
|
+
if (pool.shutdown) await pool.shutdown();
|
|
7637
|
+
else if (pool.close) await pool.close();
|
|
7638
|
+
|
|
7639
|
+
} catch (e) {
|
|
7640
|
+
spinner.fail(`Failed to create pool: ${e.message}`);
|
|
7641
|
+
}
|
|
7642
|
+
});
|
|
7643
|
+
|
|
7644
|
+
workerCmd.command('execute')
|
|
7645
|
+
.description('Execute a task on worker pool')
|
|
7646
|
+
.argument('<type>', 'Task type: compute, analyze, transform, batch')
|
|
7647
|
+
.argument('<data>', 'Task data (JSON string or simple value)')
|
|
7648
|
+
.option('-s, --size <size>', 'Pool size', '4')
|
|
7649
|
+
.option('--timeout <ms>', 'Task timeout in milliseconds', '30000')
|
|
7650
|
+
.option('--json', 'Output as JSON')
|
|
7651
|
+
.action(async (type, data, opts) => {
|
|
7652
|
+
const spinner = ora(`Executing ${type} task...`).start();
|
|
7653
|
+
|
|
7654
|
+
try {
|
|
7655
|
+
let RealWorkerPool;
|
|
7656
|
+
try {
|
|
7657
|
+
const realWorkers = await import('@ruvector/edge-net/real-workers');
|
|
7658
|
+
RealWorkerPool = realWorkers.RealWorkerPool;
|
|
7659
|
+
} catch (e) {
|
|
7660
|
+
const realWorkersPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-workers.js');
|
|
7661
|
+
const realWorkers = await import(realWorkersPath);
|
|
7662
|
+
RealWorkerPool = realWorkers.RealWorkerPool;
|
|
7663
|
+
}
|
|
7664
|
+
|
|
7665
|
+
const pool = new RealWorkerPool({ size: parseInt(opts.size) || 4 });
|
|
7666
|
+
await pool.initialize();
|
|
7667
|
+
|
|
7668
|
+
let taskData;
|
|
7669
|
+
try {
|
|
7670
|
+
taskData = JSON.parse(data);
|
|
7671
|
+
} catch {
|
|
7672
|
+
taskData = { input: data };
|
|
7673
|
+
}
|
|
7674
|
+
|
|
7675
|
+
const startTime = Date.now();
|
|
7676
|
+
const result = await pool.execute(type, taskData, {
|
|
7677
|
+
timeout: parseInt(opts.timeout) || 30000,
|
|
7678
|
+
});
|
|
7679
|
+
const duration = Date.now() - startTime;
|
|
7680
|
+
|
|
7681
|
+
spinner.succeed(`Task completed in ${(duration / 1000).toFixed(2)}s`);
|
|
7682
|
+
|
|
7683
|
+
if (opts.json) {
|
|
7684
|
+
console.log(JSON.stringify({ success: true, duration, result }, null, 2));
|
|
7685
|
+
} else {
|
|
7686
|
+
console.log(chalk.bold.cyan('\n⚡ Worker Execution Complete\n'));
|
|
7687
|
+
console.log(`${chalk.cyan('Type:')} ${type}`);
|
|
7688
|
+
console.log(`${chalk.cyan('Duration:')} ${(duration / 1000).toFixed(2)}s`);
|
|
7689
|
+
console.log(`${chalk.cyan('Worker:')} ${result.workerId || 'pool'}`);
|
|
7690
|
+
console.log(chalk.bold('\n📝 Result:\n'));
|
|
7691
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7692
|
+
console.log();
|
|
7693
|
+
}
|
|
7694
|
+
|
|
7695
|
+
if (pool.shutdown) await pool.shutdown();
|
|
7696
|
+
else if (pool.close) await pool.close();
|
|
7697
|
+
|
|
7698
|
+
} catch (e) {
|
|
7699
|
+
spinner.fail(`Execution failed: ${e.message}`);
|
|
7700
|
+
}
|
|
7701
|
+
});
|
|
7702
|
+
|
|
7703
|
+
workerCmd.command('info')
|
|
7704
|
+
.description('Show worker pool information')
|
|
7705
|
+
.action(() => {
|
|
7706
|
+
console.log(chalk.bold.cyan('\n⚡ Real Worker Pool System\n'));
|
|
7707
|
+
console.log(chalk.white('Execute parallel tasks using Node.js worker_threads.\n'));
|
|
7708
|
+
|
|
7709
|
+
console.log(chalk.bold('Task Types:'));
|
|
7710
|
+
console.log(chalk.dim(' compute - CPU-intensive computations'));
|
|
7711
|
+
console.log(chalk.dim(' analyze - Data analysis tasks'));
|
|
7712
|
+
console.log(chalk.dim(' transform - Data transformation'));
|
|
7713
|
+
console.log(chalk.dim(' batch - Batch processing'));
|
|
7714
|
+
|
|
7715
|
+
console.log(chalk.bold('\n📋 Examples:\n'));
|
|
7716
|
+
console.log(chalk.cyan(' ruvector worker create --size 8'));
|
|
7717
|
+
console.log(chalk.cyan(' ruvector worker execute compute \'{"n": 1000000}\''));
|
|
7718
|
+
console.log(chalk.cyan(' ruvector worker execute analyze \'{"data": [1,2,3,4,5]}\''));
|
|
7719
|
+
console.log();
|
|
7720
|
+
});
|
|
7721
|
+
|
|
7722
|
+
// ============================================
|
|
7723
|
+
// REAL WORKFLOW COMMANDS
|
|
7724
|
+
// ============================================
|
|
7725
|
+
|
|
7726
|
+
const workflowCmd = program.command('workflow').description('Real multi-agent workflow orchestration with LLM execution');
|
|
7727
|
+
|
|
7728
|
+
workflowCmd.command('run')
|
|
7729
|
+
.description('Run a multi-agent workflow (uses local ruvllm by default)')
|
|
7730
|
+
.argument('<template>', 'Workflow template: code-review, feature-dev, bug-fix, optimization, research')
|
|
7731
|
+
.argument('<input>', 'Input/context for the workflow')
|
|
7732
|
+
.option('-p, --provider <provider>', 'LLM provider: local (default), anthropic, openai', 'local')
|
|
7733
|
+
.option('-m, --model <model>', 'Model tier: fast, balanced, powerful', 'balanced')
|
|
7734
|
+
.option('--max-steps <n>', 'Maximum workflow steps', '10')
|
|
7735
|
+
.option('--json', 'Output as JSON')
|
|
7736
|
+
.action(async (template, input, opts) => {
|
|
7737
|
+
const spinner = ora(`Running ${template} workflow...`).start();
|
|
7738
|
+
|
|
7739
|
+
try {
|
|
7740
|
+
let RealWorkflowOrchestrator;
|
|
7741
|
+
try {
|
|
7742
|
+
const realWorkflows = await import('@ruvector/edge-net/real-workflows');
|
|
7743
|
+
RealWorkflowOrchestrator = realWorkflows.RealWorkflowOrchestrator;
|
|
7744
|
+
} catch (e) {
|
|
7745
|
+
const realWorkflowsPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-workflows.js');
|
|
7746
|
+
const realWorkflows = await import(realWorkflowsPath);
|
|
7747
|
+
RealWorkflowOrchestrator = realWorkflows.RealWorkflowOrchestrator;
|
|
7748
|
+
}
|
|
7749
|
+
|
|
7750
|
+
// Check for API key if using cloud provider
|
|
7751
|
+
const isLocal = opts.provider === 'local' || opts.provider === 'ruvllm';
|
|
7752
|
+
const apiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY;
|
|
7753
|
+
|
|
7754
|
+
if (!isLocal && !apiKey) {
|
|
7755
|
+
spinner.fail('No API key found for cloud provider');
|
|
7756
|
+
console.log(chalk.yellow('\n Use local provider (default) or set API key:'));
|
|
7757
|
+
console.log(chalk.cyan(' ruvector workflow run code-review "my code" -p local'));
|
|
7758
|
+
return;
|
|
7759
|
+
}
|
|
7760
|
+
|
|
7761
|
+
const orchestrator = new RealWorkflowOrchestrator({
|
|
7762
|
+
provider: isLocal ? 'local' : (process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai'),
|
|
7763
|
+
apiKey: isLocal ? undefined : apiKey,
|
|
7764
|
+
maxConcurrency: 2,
|
|
7765
|
+
});
|
|
7766
|
+
|
|
7767
|
+
await orchestrator.initialize();
|
|
7768
|
+
|
|
7769
|
+
const startTime = Date.now();
|
|
7770
|
+
const result = await orchestrator.run(template, input, {
|
|
7771
|
+
maxSteps: parseInt(opts.maxSteps) || 10,
|
|
7772
|
+
modelTier: opts.model,
|
|
7773
|
+
});
|
|
7774
|
+
const duration = Date.now() - startTime;
|
|
7775
|
+
|
|
7776
|
+
spinner.succeed(`Workflow completed in ${(duration / 1000).toFixed(2)}s`);
|
|
7777
|
+
|
|
7778
|
+
if (opts.json) {
|
|
7779
|
+
console.log(JSON.stringify({ success: true, duration, ...result }, null, 2));
|
|
7780
|
+
} else {
|
|
7781
|
+
console.log(chalk.bold.cyan(`\n🔄 Workflow: ${template}\n`));
|
|
7782
|
+
console.log(`${chalk.cyan('Duration:')} ${(duration / 1000).toFixed(2)}s`);
|
|
7783
|
+
console.log(`${chalk.cyan('Provider:')} ${opts.provider}`);
|
|
7784
|
+
const steps = result.steps || [];
|
|
7785
|
+
const completedSteps = steps.filter(s => s.status === 'completed').length;
|
|
7786
|
+
console.log(`${chalk.cyan('Steps:')} ${completedSteps}/${steps.length}`);
|
|
7787
|
+
|
|
7788
|
+
console.log(chalk.bold('\n📝 Results by Step:\n'));
|
|
7789
|
+
for (const [stepName, stepResult] of Object.entries(result.results || {})) {
|
|
7790
|
+
console.log(chalk.bold.green(` ${stepName}:`));
|
|
7791
|
+
const preview = typeof stepResult === 'string'
|
|
7792
|
+
? stepResult.slice(0, 200) + (stepResult.length > 200 ? '...' : '')
|
|
7793
|
+
: JSON.stringify(stepResult).slice(0, 200);
|
|
7794
|
+
console.log(chalk.dim(` ${preview}\n`));
|
|
7795
|
+
}
|
|
7796
|
+
}
|
|
7797
|
+
|
|
7798
|
+
await orchestrator.close();
|
|
7799
|
+
|
|
7800
|
+
} catch (e) {
|
|
7801
|
+
spinner.fail(`Workflow failed: ${e.message}`);
|
|
7802
|
+
}
|
|
7803
|
+
});
|
|
7804
|
+
|
|
7805
|
+
workflowCmd.command('templates')
|
|
7806
|
+
.description('List available workflow templates')
|
|
7807
|
+
.action(() => {
|
|
7808
|
+
console.log(chalk.bold.cyan('\n🔄 Workflow Templates\n'));
|
|
7809
|
+
|
|
7810
|
+
const templates = [
|
|
7811
|
+
{ name: 'code-review', desc: 'Analyze, review, test coverage, and optimize code', steps: 4 },
|
|
7812
|
+
{ name: 'feature-dev', desc: 'Research, implement, test, and review a feature', steps: 4 },
|
|
7813
|
+
{ name: 'bug-fix', desc: 'Analyze, fix, and verify a bug', steps: 3 },
|
|
7814
|
+
{ name: 'optimization', desc: 'Profile, identify bottlenecks, optimize, benchmark', steps: 4 },
|
|
7815
|
+
{ name: 'research', desc: 'Research, analyze, and create knowledge embeddings', steps: 3 },
|
|
7816
|
+
];
|
|
7817
|
+
|
|
7818
|
+
templates.forEach(t => {
|
|
7819
|
+
console.log(` ${chalk.green('•')} ${chalk.bold(t.name.padEnd(14))} ${t.desc}`);
|
|
7820
|
+
console.log(` ${chalk.dim(`Steps: ${t.steps}`)}`);
|
|
7821
|
+
});
|
|
7822
|
+
|
|
7823
|
+
console.log(chalk.bold('\n📋 Example:\n'));
|
|
7824
|
+
console.log(chalk.cyan(' ruvector workflow run code-review "Review my authentication module"'));
|
|
7825
|
+
console.log(chalk.cyan(' ruvector workflow run feature-dev "Add user profile page" -p anthropic'));
|
|
7826
|
+
console.log();
|
|
7827
|
+
});
|
|
7828
|
+
|
|
7581
7829
|
// MCP Server command
|
|
7582
7830
|
const mcpCmd = program.command('mcp').description('MCP (Model Context Protocol) server for Claude Code integration');
|
|
7583
7831
|
|
package/bin/mcp-server.js
CHANGED
|
@@ -294,7 +294,7 @@ class Intelligence {
|
|
|
294
294
|
const server = new Server(
|
|
295
295
|
{
|
|
296
296
|
name: 'ruvector',
|
|
297
|
-
version: '0.1.
|
|
297
|
+
version: '0.1.92',
|
|
298
298
|
},
|
|
299
299
|
{
|
|
300
300
|
capabilities: {
|
|
@@ -1127,7 +1127,7 @@ const TOOLS = [
|
|
|
1127
1127
|
},
|
|
1128
1128
|
{
|
|
1129
1129
|
name: 'agent_execute',
|
|
1130
|
-
description: 'REAL agent execution
|
|
1130
|
+
description: 'REAL agent execution using local ruvllm (default, no API key), or cloud APIs (Anthropic/OpenAI). Local runs without needing any API key.',
|
|
1131
1131
|
inputSchema: {
|
|
1132
1132
|
type: 'object',
|
|
1133
1133
|
properties: {
|
|
@@ -1137,7 +1137,7 @@ const TOOLS = [
|
|
|
1137
1137
|
enum: ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder']
|
|
1138
1138
|
},
|
|
1139
1139
|
task: { type: 'string', description: 'Task for the agent to execute' },
|
|
1140
|
-
provider: { type: 'string', enum: ['anthropic', 'openai'], description: 'LLM provider (
|
|
1140
|
+
provider: { type: 'string', enum: ['local', 'ruvllm', 'anthropic', 'openai'], default: 'local', description: 'LLM provider (local by default, no API key needed)' },
|
|
1141
1141
|
model: { type: 'string', enum: ['fast', 'balanced', 'powerful'], default: 'balanced', description: 'Model tier' },
|
|
1142
1142
|
context: { type: 'string', description: 'Additional context for the agent' },
|
|
1143
1143
|
max_tokens: { type: 'number', default: 4096, description: 'Maximum tokens in response' }
|
|
@@ -2819,7 +2819,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2819
2819
|
}
|
|
2820
2820
|
|
|
2821
2821
|
case 'agent_execute': {
|
|
2822
|
-
// REAL agent execution with
|
|
2822
|
+
// REAL agent execution with local ruvllm by default, or cloud APIs
|
|
2823
2823
|
const validTypes = ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder'];
|
|
2824
2824
|
const validModels = ['fast', 'balanced', 'powerful'];
|
|
2825
2825
|
|
|
@@ -2828,17 +2828,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2828
2828
|
const model = validModels.includes(args.model) ? args.model : 'balanced';
|
|
2829
2829
|
const maxTokens = Math.min(Math.max(parseInt(args.max_tokens) || 4096, 100), 8192);
|
|
2830
2830
|
|
|
2831
|
-
//
|
|
2831
|
+
// Determine provider (local by default)
|
|
2832
|
+
const provider = args.provider || 'local';
|
|
2833
|
+
const isLocal = provider === 'local' || provider === 'ruvllm';
|
|
2834
|
+
|
|
2835
|
+
// Check for API key (only required for cloud providers)
|
|
2832
2836
|
const apiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY;
|
|
2833
|
-
if (!apiKey && agentType !== 'embedder') {
|
|
2837
|
+
if (!isLocal && !apiKey && agentType !== 'embedder') {
|
|
2834
2838
|
return {
|
|
2835
2839
|
content: [{
|
|
2836
2840
|
type: 'text',
|
|
2837
2841
|
text: JSON.stringify({
|
|
2838
2842
|
success: false,
|
|
2839
|
-
error: 'No API key configured',
|
|
2840
|
-
message: 'Set ANTHROPIC_API_KEY or OPENAI_API_KEY
|
|
2841
|
-
|
|
2843
|
+
error: 'No API key configured for cloud provider',
|
|
2844
|
+
message: 'Set ANTHROPIC_API_KEY or OPENAI_API_KEY, or use local provider (default)',
|
|
2845
|
+
options: {
|
|
2846
|
+
local: 'Use provider=local (no API key needed)',
|
|
2842
2847
|
anthropic: 'https://console.anthropic.com/',
|
|
2843
2848
|
openai: 'https://platform.openai.com/api-keys'
|
|
2844
2849
|
}
|
|
@@ -2856,23 +2861,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2856
2861
|
RealAgentManager = realAgents.RealAgentManager;
|
|
2857
2862
|
} catch (e) {
|
|
2858
2863
|
// Fallback to local path for development
|
|
2859
|
-
const realAgentsPath = path.resolve(__dirname, '
|
|
2864
|
+
const realAgentsPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-agents.js');
|
|
2860
2865
|
const realAgents = await import(realAgentsPath);
|
|
2861
2866
|
RealAgentManager = realAgents.RealAgentManager;
|
|
2862
2867
|
}
|
|
2863
2868
|
|
|
2864
|
-
//
|
|
2865
|
-
const provider = args.provider || (process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai');
|
|
2866
|
-
|
|
2867
|
-
// Initialize manager
|
|
2869
|
+
// Initialize manager with selected provider
|
|
2868
2870
|
const manager = new RealAgentManager({
|
|
2869
|
-
provider,
|
|
2870
|
-
apiKey,
|
|
2871
|
+
provider: isLocal ? 'local' : (apiKey && process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai'),
|
|
2872
|
+
apiKey: isLocal ? undefined : apiKey,
|
|
2871
2873
|
});
|
|
2872
2874
|
await manager.initialize();
|
|
2873
2875
|
|
|
2874
2876
|
// Spawn and execute
|
|
2875
|
-
const
|
|
2877
|
+
const effectiveProvider = isLocal ? 'local' : (apiKey && process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai');
|
|
2878
|
+
const agent = await manager.spawn(agentType, { provider: effectiveProvider, model });
|
|
2876
2879
|
|
|
2877
2880
|
const context = {
|
|
2878
2881
|
model,
|
|
@@ -2892,15 +2895,17 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2892
2895
|
text: JSON.stringify({
|
|
2893
2896
|
success: true,
|
|
2894
2897
|
real_execution: true,
|
|
2898
|
+
local_mode: isLocal,
|
|
2895
2899
|
agent: {
|
|
2896
2900
|
id: agent.id,
|
|
2897
2901
|
type: agentType,
|
|
2898
|
-
provider,
|
|
2899
|
-
model: result.model
|
|
2902
|
+
provider: effectiveProvider,
|
|
2903
|
+
model: result.model || (isLocal ? 'ruvllm-balanced' : model)
|
|
2900
2904
|
},
|
|
2901
2905
|
execution: {
|
|
2902
2906
|
duration_ms: duration,
|
|
2903
|
-
tokens: agent.cost
|
|
2907
|
+
tokens: agent.cost,
|
|
2908
|
+
fallback: result.fallback || false
|
|
2904
2909
|
},
|
|
2905
2910
|
response: result.content
|
|
2906
2911
|
}, null, 2)
|
|
@@ -2933,7 +2938,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2933
2938
|
const realAgents = await import('@ruvector/edge-net/real-agents');
|
|
2934
2939
|
RelaySyncClient = realAgents.RelaySyncClient;
|
|
2935
2940
|
} catch (e) {
|
|
2936
|
-
const realAgentsPath = path.resolve(__dirname, '
|
|
2941
|
+
const realAgentsPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-agents.js');
|
|
2937
2942
|
const realAgents = await import(realAgentsPath);
|
|
2938
2943
|
RelaySyncClient = realAgents.RelaySyncClient;
|
|
2939
2944
|
}
|