ruvector 0.1.89 → 0.1.91
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 +571 -0
- package/bin/mcp-server.js +506 -0
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -7007,6 +7007,577 @@ nativeCmd.command('compare')
|
|
|
7007
7007
|
}
|
|
7008
7008
|
});
|
|
7009
7009
|
|
|
7010
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
7011
|
+
// Edge-Net Commands - Distributed Agent/Worker Network
|
|
7012
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
7013
|
+
|
|
7014
|
+
const edgeNetCmd = program.command('edge-net').description('Distributed AI agent/worker network');
|
|
7015
|
+
|
|
7016
|
+
// Edge-net info
|
|
7017
|
+
edgeNetCmd.command('info')
|
|
7018
|
+
.description('Show Edge-Net information and capabilities')
|
|
7019
|
+
.action(() => {
|
|
7020
|
+
console.log(chalk.bold.cyan('\n🌐 Edge-Net: Distributed AI Agent Network\n'));
|
|
7021
|
+
console.log(chalk.white('Spawn AI agents and workers across the collective compute network.'));
|
|
7022
|
+
console.log(chalk.white('Contribute idle compute, earn rUv credits, run distributed workloads.\n'));
|
|
7023
|
+
|
|
7024
|
+
console.log(chalk.bold('Agent Types:'));
|
|
7025
|
+
console.log(chalk.dim(' researcher - Analyzes and researches information'));
|
|
7026
|
+
console.log(chalk.dim(' coder - Writes and improves code'));
|
|
7027
|
+
console.log(chalk.dim(' reviewer - Reviews code and provides feedback'));
|
|
7028
|
+
console.log(chalk.dim(' tester - Tests and validates implementations'));
|
|
7029
|
+
console.log(chalk.dim(' analyst - Analyzes data and generates reports'));
|
|
7030
|
+
console.log(chalk.dim(' optimizer - Optimizes performance and efficiency'));
|
|
7031
|
+
console.log(chalk.dim(' coordinator - Coordinates multi-agent workflows'));
|
|
7032
|
+
console.log(chalk.dim(' embedder - Generates embeddings and vector ops'));
|
|
7033
|
+
|
|
7034
|
+
console.log(chalk.bold('\nCommands:'));
|
|
7035
|
+
console.log(chalk.dim(' ruvector edge-net spawn <type> "<task>" - Spawn an agent'));
|
|
7036
|
+
console.log(chalk.dim(' ruvector edge-net pool create - Create worker pool'));
|
|
7037
|
+
console.log(chalk.dim(' ruvector edge-net pool execute - Execute on pool'));
|
|
7038
|
+
console.log(chalk.dim(' ruvector edge-net workflow run - Run a workflow'));
|
|
7039
|
+
console.log(chalk.dim(' ruvector edge-net status - Show network status'));
|
|
7040
|
+
|
|
7041
|
+
console.log(chalk.bold.yellow('\n📦 Install Edge-Net package:'));
|
|
7042
|
+
console.log(chalk.cyan(' npm install @ruvector/edge-net\n'));
|
|
7043
|
+
});
|
|
7044
|
+
|
|
7045
|
+
// Spawn agent
|
|
7046
|
+
edgeNetCmd.command('spawn')
|
|
7047
|
+
.description('Spawn a distributed AI agent')
|
|
7048
|
+
.argument('<type>', 'Agent type (researcher, coder, reviewer, tester, analyst, optimizer)')
|
|
7049
|
+
.argument('<task>', 'Task description for the agent')
|
|
7050
|
+
.option('--max-ruv <amount>', 'Maximum rUv to spend', '20')
|
|
7051
|
+
.option('--priority <level>', 'Priority (low, medium, high, critical)', 'medium')
|
|
7052
|
+
.option('--timeout <ms>', 'Timeout in milliseconds', '300000')
|
|
7053
|
+
.option('--json', 'Output as JSON')
|
|
7054
|
+
.action(async (type, task, opts) => {
|
|
7055
|
+
const spinner = ora('Spawning agent...').start();
|
|
7056
|
+
|
|
7057
|
+
try {
|
|
7058
|
+
// Try to load edge-net
|
|
7059
|
+
let edgeNet;
|
|
7060
|
+
try {
|
|
7061
|
+
edgeNet = require('@ruvector/edge-net/agents.js');
|
|
7062
|
+
} catch (e) {
|
|
7063
|
+
// Use inline implementation if package not available
|
|
7064
|
+
const agentTypes = {
|
|
7065
|
+
researcher: { name: 'Researcher', baseRuv: 10 },
|
|
7066
|
+
coder: { name: 'Coder', baseRuv: 15 },
|
|
7067
|
+
reviewer: { name: 'Reviewer', baseRuv: 12 },
|
|
7068
|
+
tester: { name: 'Tester', baseRuv: 10 },
|
|
7069
|
+
analyst: { name: 'Analyst', baseRuv: 8 },
|
|
7070
|
+
optimizer: { name: 'Optimizer', baseRuv: 15 },
|
|
7071
|
+
coordinator: { name: 'Coordinator', baseRuv: 20 },
|
|
7072
|
+
embedder: { name: 'Embedder', baseRuv: 5 },
|
|
7073
|
+
};
|
|
7074
|
+
|
|
7075
|
+
if (!agentTypes[type]) {
|
|
7076
|
+
spinner.fail(`Unknown agent type: ${type}`);
|
|
7077
|
+
console.log(chalk.dim('Available: researcher, coder, reviewer, tester, analyst, optimizer, coordinator, embedder'));
|
|
7078
|
+
return;
|
|
7079
|
+
}
|
|
7080
|
+
|
|
7081
|
+
const agentId = `agent-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
7082
|
+
const agentConfig = agentTypes[type];
|
|
7083
|
+
|
|
7084
|
+
spinner.succeed(`Agent spawned: ${agentId}`);
|
|
7085
|
+
|
|
7086
|
+
const result = {
|
|
7087
|
+
agentId,
|
|
7088
|
+
type,
|
|
7089
|
+
name: agentConfig.name,
|
|
7090
|
+
task,
|
|
7091
|
+
maxRuv: parseInt(opts.maxRuv) || agentConfig.baseRuv,
|
|
7092
|
+
priority: opts.priority,
|
|
7093
|
+
status: 'queued',
|
|
7094
|
+
message: 'Agent queued for execution. Install @ruvector/edge-net for full distributed execution.',
|
|
7095
|
+
};
|
|
7096
|
+
|
|
7097
|
+
if (opts.json) {
|
|
7098
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7099
|
+
} else {
|
|
7100
|
+
console.log(chalk.bold(`\n${chalk.cyan('Agent ID:')} ${result.agentId}`));
|
|
7101
|
+
console.log(`${chalk.cyan('Type:')} ${result.name} (${type})`);
|
|
7102
|
+
console.log(`${chalk.cyan('Task:')} ${task}`);
|
|
7103
|
+
console.log(`${chalk.cyan('Max rUv:')} ${result.maxRuv}`);
|
|
7104
|
+
console.log(`${chalk.cyan('Priority:')} ${result.priority}`);
|
|
7105
|
+
console.log(`${chalk.cyan('Status:')} ${chalk.yellow(result.status)}`);
|
|
7106
|
+
console.log(chalk.dim(`\nTip: npm install @ruvector/edge-net for distributed execution\n`));
|
|
7107
|
+
}
|
|
7108
|
+
return;
|
|
7109
|
+
}
|
|
7110
|
+
|
|
7111
|
+
// Use edge-net package if available
|
|
7112
|
+
const { AgentSpawner, AGENT_TYPES } = edgeNet;
|
|
7113
|
+
|
|
7114
|
+
if (!AGENT_TYPES[type]) {
|
|
7115
|
+
spinner.fail(`Unknown agent type: ${type}`);
|
|
7116
|
+
console.log(chalk.dim('Available: ' + Object.keys(AGENT_TYPES).join(', ')));
|
|
7117
|
+
return;
|
|
7118
|
+
}
|
|
7119
|
+
|
|
7120
|
+
const spawner = new AgentSpawner(null, {});
|
|
7121
|
+
const agent = await spawner.spawn({
|
|
7122
|
+
type,
|
|
7123
|
+
task,
|
|
7124
|
+
maxRuv: parseInt(opts.maxRuv),
|
|
7125
|
+
priority: opts.priority,
|
|
7126
|
+
timeout: parseInt(opts.timeout),
|
|
7127
|
+
});
|
|
7128
|
+
|
|
7129
|
+
spinner.succeed(`Agent spawned: ${agent.id}`);
|
|
7130
|
+
|
|
7131
|
+
if (opts.json) {
|
|
7132
|
+
console.log(JSON.stringify(agent.getInfo(), null, 2));
|
|
7133
|
+
} else {
|
|
7134
|
+
console.log(chalk.bold(`\n${chalk.cyan('Agent ID:')} ${agent.id}`));
|
|
7135
|
+
console.log(`${chalk.cyan('Type:')} ${agent.config.name} (${type})`);
|
|
7136
|
+
console.log(`${chalk.cyan('Task:')} ${task}`);
|
|
7137
|
+
console.log(`${chalk.cyan('Max rUv:')} ${agent.maxRuv}`);
|
|
7138
|
+
console.log(`${chalk.cyan('Status:')} ${chalk.green(agent.status)}`);
|
|
7139
|
+
console.log();
|
|
7140
|
+
}
|
|
7141
|
+
|
|
7142
|
+
} catch (e) {
|
|
7143
|
+
spinner.fail(`Failed to spawn agent: ${e.message}`);
|
|
7144
|
+
}
|
|
7145
|
+
});
|
|
7146
|
+
|
|
7147
|
+
// Worker pool commands
|
|
7148
|
+
const poolCmd = edgeNetCmd.command('pool').description('Worker pool management');
|
|
7149
|
+
|
|
7150
|
+
poolCmd.command('create')
|
|
7151
|
+
.description('Create a distributed worker pool')
|
|
7152
|
+
.option('--size <n>', 'Number of workers', '5')
|
|
7153
|
+
.option('--capabilities <list>', 'Comma-separated capabilities', 'compute,embed,analyze')
|
|
7154
|
+
.option('--json', 'Output as JSON')
|
|
7155
|
+
.action(async (opts) => {
|
|
7156
|
+
const spinner = ora('Creating worker pool...').start();
|
|
7157
|
+
|
|
7158
|
+
try {
|
|
7159
|
+
const poolId = `pool-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
7160
|
+
const capabilities = opts.capabilities.split(',').map(c => c.trim());
|
|
7161
|
+
|
|
7162
|
+
spinner.succeed(`Worker pool created: ${poolId}`);
|
|
7163
|
+
|
|
7164
|
+
const result = {
|
|
7165
|
+
poolId,
|
|
7166
|
+
size: parseInt(opts.size),
|
|
7167
|
+
capabilities,
|
|
7168
|
+
status: 'ready',
|
|
7169
|
+
workers: parseInt(opts.size),
|
|
7170
|
+
idleWorkers: parseInt(opts.size),
|
|
7171
|
+
};
|
|
7172
|
+
|
|
7173
|
+
if (opts.json) {
|
|
7174
|
+
console.log(JSON.stringify(result, null, 2));
|
|
7175
|
+
} else {
|
|
7176
|
+
console.log(chalk.bold(`\n${chalk.cyan('Pool ID:')} ${result.poolId}`));
|
|
7177
|
+
console.log(`${chalk.cyan('Size:')} ${result.size} workers`);
|
|
7178
|
+
console.log(`${chalk.cyan('Capabilities:')} ${capabilities.join(', ')}`);
|
|
7179
|
+
console.log(`${chalk.cyan('Status:')} ${chalk.green(result.status)}`);
|
|
7180
|
+
console.log();
|
|
7181
|
+
}
|
|
7182
|
+
|
|
7183
|
+
} catch (e) {
|
|
7184
|
+
spinner.fail(`Failed to create pool: ${e.message}`);
|
|
7185
|
+
}
|
|
7186
|
+
});
|
|
7187
|
+
|
|
7188
|
+
poolCmd.command('execute')
|
|
7189
|
+
.description('Execute task on worker pool')
|
|
7190
|
+
.argument('<task>', 'Task type (embed, process, analyze)')
|
|
7191
|
+
.option('--data <json>', 'Input data as JSON', '[]')
|
|
7192
|
+
.option('--strategy <type>', 'Execution strategy (parallel, sequential, race)', 'parallel')
|
|
7193
|
+
.option('--json', 'Output as JSON')
|
|
7194
|
+
.action(async (task, opts) => {
|
|
7195
|
+
const spinner = ora(`Executing ${task}...`).start();
|
|
7196
|
+
|
|
7197
|
+
try {
|
|
7198
|
+
let data;
|
|
7199
|
+
try {
|
|
7200
|
+
data = JSON.parse(opts.data);
|
|
7201
|
+
} catch (e) {
|
|
7202
|
+
data = [opts.data];
|
|
7203
|
+
}
|
|
7204
|
+
|
|
7205
|
+
const startTime = Date.now();
|
|
7206
|
+
|
|
7207
|
+
// Simulate execution
|
|
7208
|
+
let result;
|
|
7209
|
+
switch (task) {
|
|
7210
|
+
case 'embed':
|
|
7211
|
+
result = (Array.isArray(data) ? data : [data]).map(() =>
|
|
7212
|
+
new Array(384).fill(0).map(() => Math.random().toFixed(6))
|
|
7213
|
+
);
|
|
7214
|
+
break;
|
|
7215
|
+
case 'process':
|
|
7216
|
+
result = (Array.isArray(data) ? data : [data]).map(item => ({
|
|
7217
|
+
processed: true,
|
|
7218
|
+
item,
|
|
7219
|
+
timestamp: Date.now(),
|
|
7220
|
+
}));
|
|
7221
|
+
break;
|
|
7222
|
+
case 'analyze':
|
|
7223
|
+
result = {
|
|
7224
|
+
analyzed: true,
|
|
7225
|
+
itemCount: Array.isArray(data) ? data.length : 1,
|
|
7226
|
+
summary: 'Analysis complete',
|
|
7227
|
+
};
|
|
7228
|
+
break;
|
|
7229
|
+
default:
|
|
7230
|
+
result = { task, data, executed: true };
|
|
7231
|
+
}
|
|
7232
|
+
|
|
7233
|
+
const duration = Date.now() - startTime;
|
|
7234
|
+
spinner.succeed(`Executed ${task} in ${duration}ms`);
|
|
7235
|
+
|
|
7236
|
+
if (opts.json) {
|
|
7237
|
+
console.log(JSON.stringify({ result, duration }, null, 2));
|
|
7238
|
+
} else {
|
|
7239
|
+
console.log(chalk.bold(`\n${chalk.cyan('Task:')} ${task}`));
|
|
7240
|
+
console.log(`${chalk.cyan('Strategy:')} ${opts.strategy}`);
|
|
7241
|
+
console.log(`${chalk.cyan('Duration:')} ${duration}ms`);
|
|
7242
|
+
console.log(`${chalk.cyan('Result:')} ${JSON.stringify(result).slice(0, 100)}...`);
|
|
7243
|
+
console.log();
|
|
7244
|
+
}
|
|
7245
|
+
|
|
7246
|
+
} catch (e) {
|
|
7247
|
+
spinner.fail(`Execution failed: ${e.message}`);
|
|
7248
|
+
}
|
|
7249
|
+
});
|
|
7250
|
+
|
|
7251
|
+
// Workflow commands
|
|
7252
|
+
edgeNetCmd.command('workflow')
|
|
7253
|
+
.description('Run a multi-agent workflow')
|
|
7254
|
+
.argument('<name>', 'Workflow name or JSON file')
|
|
7255
|
+
.option('--input <json>', 'Input data as JSON', '{}')
|
|
7256
|
+
.option('--json', 'Output as JSON')
|
|
7257
|
+
.action(async (name, opts) => {
|
|
7258
|
+
const spinner = ora(`Running workflow: ${name}...`).start();
|
|
7259
|
+
|
|
7260
|
+
try {
|
|
7261
|
+
let input;
|
|
7262
|
+
try {
|
|
7263
|
+
input = JSON.parse(opts.input);
|
|
7264
|
+
} catch (e) {
|
|
7265
|
+
input = {};
|
|
7266
|
+
}
|
|
7267
|
+
|
|
7268
|
+
// Built-in workflows
|
|
7269
|
+
const workflows = {
|
|
7270
|
+
'code-review': [
|
|
7271
|
+
{ type: 'agent', agentType: 'analyst', task: 'Analyze code structure' },
|
|
7272
|
+
{ type: 'agent', agentType: 'reviewer', task: 'Review code quality' },
|
|
7273
|
+
{ type: 'agent', agentType: 'tester', task: 'Suggest tests' },
|
|
7274
|
+
],
|
|
7275
|
+
'research': [
|
|
7276
|
+
{ type: 'agent', agentType: 'researcher', task: 'Research topic' },
|
|
7277
|
+
{ type: 'agent', agentType: 'analyst', task: 'Analyze findings' },
|
|
7278
|
+
],
|
|
7279
|
+
'optimize': [
|
|
7280
|
+
{ type: 'agent', agentType: 'analyst', task: 'Profile performance' },
|
|
7281
|
+
{ type: 'agent', agentType: 'optimizer', task: 'Suggest optimizations' },
|
|
7282
|
+
{ type: 'agent', agentType: 'tester', task: 'Validate improvements' },
|
|
7283
|
+
],
|
|
7284
|
+
};
|
|
7285
|
+
|
|
7286
|
+
const steps = workflows[name] || [{ type: 'agent', agentType: 'researcher', task: name }];
|
|
7287
|
+
|
|
7288
|
+
spinner.text = `Executing ${steps.length} workflow steps...`;
|
|
7289
|
+
|
|
7290
|
+
const results = [];
|
|
7291
|
+
for (let i = 0; i < steps.length; i++) {
|
|
7292
|
+
const step = steps[i];
|
|
7293
|
+
spinner.text = `Step ${i + 1}/${steps.length}: ${step.agentType || step.type}`;
|
|
7294
|
+
await new Promise(r => setTimeout(r, 500)); // Simulate execution
|
|
7295
|
+
results.push({
|
|
7296
|
+
step: i + 1,
|
|
7297
|
+
type: step.agentType || step.type,
|
|
7298
|
+
status: 'completed',
|
|
7299
|
+
});
|
|
7300
|
+
}
|
|
7301
|
+
|
|
7302
|
+
spinner.succeed(`Workflow completed: ${results.length} steps`);
|
|
7303
|
+
|
|
7304
|
+
if (opts.json) {
|
|
7305
|
+
console.log(JSON.stringify({ workflow: name, results }, null, 2));
|
|
7306
|
+
} else {
|
|
7307
|
+
console.log(chalk.bold(`\n${chalk.cyan('Workflow:')} ${name}`));
|
|
7308
|
+
console.log(`${chalk.cyan('Steps:')} ${results.length}`);
|
|
7309
|
+
results.forEach(r => {
|
|
7310
|
+
console.log(` ${chalk.green('✓')} Step ${r.step}: ${r.type}`);
|
|
7311
|
+
});
|
|
7312
|
+
console.log();
|
|
7313
|
+
}
|
|
7314
|
+
|
|
7315
|
+
} catch (e) {
|
|
7316
|
+
spinner.fail(`Workflow failed: ${e.message}`);
|
|
7317
|
+
}
|
|
7318
|
+
});
|
|
7319
|
+
|
|
7320
|
+
// Network status
|
|
7321
|
+
edgeNetCmd.command('status')
|
|
7322
|
+
.description('Show Edge-Net network status')
|
|
7323
|
+
.option('--json', 'Output as JSON')
|
|
7324
|
+
.action(async (opts) => {
|
|
7325
|
+
const spinner = ora('Fetching network status...').start();
|
|
7326
|
+
|
|
7327
|
+
try {
|
|
7328
|
+
// Check if edge-net is installed
|
|
7329
|
+
let edgeNetInstalled = false;
|
|
7330
|
+
try {
|
|
7331
|
+
require.resolve('@ruvector/edge-net');
|
|
7332
|
+
edgeNetInstalled = true;
|
|
7333
|
+
} catch (e) {}
|
|
7334
|
+
|
|
7335
|
+
spinner.stop();
|
|
7336
|
+
|
|
7337
|
+
const status = {
|
|
7338
|
+
installed: edgeNetInstalled,
|
|
7339
|
+
version: edgeNetInstalled ? require('@ruvector/edge-net/package.json').version : 'not installed',
|
|
7340
|
+
network: {
|
|
7341
|
+
peers: 0,
|
|
7342
|
+
activeAgents: 0,
|
|
7343
|
+
workerPools: 0,
|
|
7344
|
+
},
|
|
7345
|
+
balance: {
|
|
7346
|
+
ruvEarned: 0,
|
|
7347
|
+
ruvSpent: 0,
|
|
7348
|
+
},
|
|
7349
|
+
};
|
|
7350
|
+
|
|
7351
|
+
if (opts.json) {
|
|
7352
|
+
console.log(JSON.stringify(status, null, 2));
|
|
7353
|
+
} else {
|
|
7354
|
+
console.log(chalk.bold.cyan('\n🌐 Edge-Net Status\n'));
|
|
7355
|
+
|
|
7356
|
+
if (!edgeNetInstalled) {
|
|
7357
|
+
console.log(chalk.yellow('⚠️ @ruvector/edge-net not installed'));
|
|
7358
|
+
console.log(chalk.dim(' Install: npm install @ruvector/edge-net\n'));
|
|
7359
|
+
} else {
|
|
7360
|
+
console.log(chalk.green(`✓ Package installed: v${status.version}`));
|
|
7361
|
+
}
|
|
7362
|
+
|
|
7363
|
+
console.log(chalk.bold('\nNetwork:'));
|
|
7364
|
+
console.log(chalk.dim(` Peers: ${status.network.peers}`));
|
|
7365
|
+
console.log(chalk.dim(` Active Agents: ${status.network.activeAgents}`));
|
|
7366
|
+
console.log(chalk.dim(` Worker Pools: ${status.network.workerPools}`));
|
|
7367
|
+
|
|
7368
|
+
console.log(chalk.bold('\nBalance:'));
|
|
7369
|
+
console.log(chalk.dim(` rUv Earned: ${status.balance.ruvEarned}`));
|
|
7370
|
+
console.log(chalk.dim(` rUv Spent: ${status.balance.ruvSpent}`));
|
|
7371
|
+
console.log();
|
|
7372
|
+
}
|
|
7373
|
+
|
|
7374
|
+
} catch (e) {
|
|
7375
|
+
spinner.fail(`Failed to get status: ${e.message}`);
|
|
7376
|
+
}
|
|
7377
|
+
});
|
|
7378
|
+
|
|
7379
|
+
// ============================================
|
|
7380
|
+
// REAL AGENT COMMANDS (Actual LLM Execution)
|
|
7381
|
+
// ============================================
|
|
7382
|
+
|
|
7383
|
+
const agentCmd = program.command('agent').description('Real AI agent execution with LLM APIs (requires ANTHROPIC_API_KEY or OPENAI_API_KEY)');
|
|
7384
|
+
|
|
7385
|
+
agentCmd.command('run')
|
|
7386
|
+
.description('Execute a task with a real AI agent (calls actual LLM API)')
|
|
7387
|
+
.argument('<type>', 'Agent type: researcher, coder, reviewer, tester, analyst, optimizer, coordinator, embedder')
|
|
7388
|
+
.argument('<task>', 'Task description for the agent to execute')
|
|
7389
|
+
.option('-p, --provider <provider>', 'LLM provider: anthropic or openai', 'anthropic')
|
|
7390
|
+
.option('-m, --model <model>', 'Model tier: fast, balanced, powerful', 'balanced')
|
|
7391
|
+
.option('-f, --files <files...>', 'Files to include as context')
|
|
7392
|
+
.option('-c, --context <context>', 'Additional context string')
|
|
7393
|
+
.option('--max-tokens <tokens>', 'Maximum tokens in response', '4096')
|
|
7394
|
+
.option('--relay <url>', 'Relay server URL for sync')
|
|
7395
|
+
.option('--json', 'Output as JSON')
|
|
7396
|
+
.action(async (type, task, opts) => {
|
|
7397
|
+
const spinner = ora('Initializing real agent...').start();
|
|
7398
|
+
|
|
7399
|
+
// Check for API key
|
|
7400
|
+
const apiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY;
|
|
7401
|
+
if (!apiKey && type !== 'embedder') {
|
|
7402
|
+
spinner.fail('No API key found');
|
|
7403
|
+
console.log(chalk.red('\n❌ Real agent execution requires an API key.\n'));
|
|
7404
|
+
console.log(chalk.bold('Set one of these environment variables:'));
|
|
7405
|
+
console.log(chalk.cyan(' export ANTHROPIC_API_KEY=your-key-here'));
|
|
7406
|
+
console.log(chalk.cyan(' export OPENAI_API_KEY=your-key-here'));
|
|
7407
|
+
console.log(chalk.dim('\nGet an API key:'));
|
|
7408
|
+
console.log(chalk.dim(' Anthropic: https://console.anthropic.com/'));
|
|
7409
|
+
console.log(chalk.dim(' OpenAI: https://platform.openai.com/api-keys\n'));
|
|
7410
|
+
return;
|
|
7411
|
+
}
|
|
7412
|
+
|
|
7413
|
+
try {
|
|
7414
|
+
// Try to load real-agents module
|
|
7415
|
+
let RealAgentManager;
|
|
7416
|
+
try {
|
|
7417
|
+
const realAgents = await import('@ruvector/edge-net/real-agents');
|
|
7418
|
+
RealAgentManager = realAgents.RealAgentManager;
|
|
7419
|
+
} catch (e) {
|
|
7420
|
+
// Fallback to local path for development
|
|
7421
|
+
try {
|
|
7422
|
+
const realAgentsPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-agents.js');
|
|
7423
|
+
const realAgents = await import(realAgentsPath);
|
|
7424
|
+
RealAgentManager = realAgents.RealAgentManager;
|
|
7425
|
+
} catch (e2) {
|
|
7426
|
+
spinner.fail('Real agents module not found');
|
|
7427
|
+
console.log(chalk.yellow('\nInstall @ruvector/edge-net for real agent execution:'));
|
|
7428
|
+
console.log(chalk.cyan(' npm install @ruvector/edge-net\n'));
|
|
7429
|
+
return;
|
|
7430
|
+
}
|
|
7431
|
+
}
|
|
7432
|
+
|
|
7433
|
+
// Determine provider from API key if not specified
|
|
7434
|
+
const provider = opts.provider || (process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai');
|
|
7435
|
+
|
|
7436
|
+
spinner.text = `Spawning ${type} agent (${provider})...`;
|
|
7437
|
+
|
|
7438
|
+
// Initialize manager
|
|
7439
|
+
const manager = new RealAgentManager({
|
|
7440
|
+
provider,
|
|
7441
|
+
apiKey,
|
|
7442
|
+
relayUrl: opts.relay,
|
|
7443
|
+
enableSync: !!opts.relay,
|
|
7444
|
+
});
|
|
7445
|
+
await manager.initialize();
|
|
7446
|
+
|
|
7447
|
+
// Spawn agent
|
|
7448
|
+
const agent = await manager.spawn(type, {
|
|
7449
|
+
provider,
|
|
7450
|
+
model: opts.model,
|
|
7451
|
+
});
|
|
7452
|
+
|
|
7453
|
+
spinner.text = `Executing task with ${type} agent...`;
|
|
7454
|
+
|
|
7455
|
+
// Build context
|
|
7456
|
+
const context = {
|
|
7457
|
+
model: opts.model,
|
|
7458
|
+
files: opts.files || [],
|
|
7459
|
+
additionalContext: opts.context,
|
|
7460
|
+
maxTokens: parseInt(opts.maxTokens) || 4096,
|
|
7461
|
+
};
|
|
7462
|
+
|
|
7463
|
+
// Execute task
|
|
7464
|
+
const startTime = Date.now();
|
|
7465
|
+
const result = await agent.execute(task, context);
|
|
7466
|
+
const duration = Date.now() - startTime;
|
|
7467
|
+
|
|
7468
|
+
spinner.succeed(`Task completed in ${(duration / 1000).toFixed(2)}s`);
|
|
7469
|
+
|
|
7470
|
+
if (opts.json) {
|
|
7471
|
+
console.log(JSON.stringify({
|
|
7472
|
+
success: true,
|
|
7473
|
+
agentId: agent.id,
|
|
7474
|
+
type,
|
|
7475
|
+
provider,
|
|
7476
|
+
model: result.model,
|
|
7477
|
+
duration,
|
|
7478
|
+
result,
|
|
7479
|
+
}, null, 2));
|
|
7480
|
+
} else {
|
|
7481
|
+
console.log(chalk.bold.cyan(`\n🤖 Real Agent Execution Complete\n`));
|
|
7482
|
+
console.log(`${chalk.cyan('Agent ID:')} ${agent.id}`);
|
|
7483
|
+
console.log(`${chalk.cyan('Type:')} ${type}`);
|
|
7484
|
+
console.log(`${chalk.cyan('Provider:')} ${provider}`);
|
|
7485
|
+
console.log(`${chalk.cyan('Model:')} ${result.model}`);
|
|
7486
|
+
console.log(`${chalk.cyan('Duration:')} ${(duration / 1000).toFixed(2)}s`);
|
|
7487
|
+
|
|
7488
|
+
if (agent.cost.inputTokens || agent.cost.outputTokens) {
|
|
7489
|
+
console.log(`${chalk.cyan('Tokens:')} ${agent.cost.inputTokens} in / ${agent.cost.outputTokens} out`);
|
|
7490
|
+
}
|
|
7491
|
+
|
|
7492
|
+
console.log(chalk.bold('\n📝 Response:\n'));
|
|
7493
|
+
console.log(result.content || JSON.stringify(result, null, 2));
|
|
7494
|
+
console.log();
|
|
7495
|
+
}
|
|
7496
|
+
|
|
7497
|
+
await manager.close();
|
|
7498
|
+
|
|
7499
|
+
} catch (e) {
|
|
7500
|
+
spinner.fail(`Agent execution failed: ${e.message}`);
|
|
7501
|
+
if (e.message.includes('401') || e.message.includes('Unauthorized')) {
|
|
7502
|
+
console.log(chalk.yellow('\nCheck your API key is valid and has sufficient credits.'));
|
|
7503
|
+
}
|
|
7504
|
+
}
|
|
7505
|
+
});
|
|
7506
|
+
|
|
7507
|
+
agentCmd.command('types')
|
|
7508
|
+
.description('List available agent types')
|
|
7509
|
+
.action(() => {
|
|
7510
|
+
console.log(chalk.bold.cyan('\n🤖 Available Real Agent Types\n'));
|
|
7511
|
+
|
|
7512
|
+
const types = [
|
|
7513
|
+
{ type: 'researcher', desc: 'Analyze, search, summarize information', cost: '~$0.01-0.05/task' },
|
|
7514
|
+
{ type: 'coder', desc: 'Write, refactor, debug code', cost: '~$0.02-0.10/task' },
|
|
7515
|
+
{ type: 'reviewer', desc: 'Review code quality and security', cost: '~$0.01-0.05/task' },
|
|
7516
|
+
{ type: 'tester', desc: 'Write tests and validate functionality', cost: '~$0.01-0.05/task' },
|
|
7517
|
+
{ type: 'analyst', desc: 'Analyze data and generate reports', cost: '~$0.01-0.05/task' },
|
|
7518
|
+
{ type: 'optimizer', desc: 'Profile and improve performance', cost: '~$0.02-0.10/task' },
|
|
7519
|
+
{ type: 'coordinator', desc: 'Orchestrate workflows and tasks', cost: '~$0.02-0.10/task' },
|
|
7520
|
+
{ type: 'embedder', desc: 'Generate semantic embeddings (no API key needed)', cost: 'Free (local)' },
|
|
7521
|
+
];
|
|
7522
|
+
|
|
7523
|
+
types.forEach(t => {
|
|
7524
|
+
console.log(` ${chalk.green('•')} ${chalk.bold(t.type.padEnd(12))} ${t.desc}`);
|
|
7525
|
+
console.log(` ${chalk.dim('Estimated cost: ' + t.cost)}`);
|
|
7526
|
+
});
|
|
7527
|
+
|
|
7528
|
+
console.log(chalk.bold('\n📋 Model Tiers:\n'));
|
|
7529
|
+
console.log(` ${chalk.cyan('fast')} - Quick responses, lower cost (Haiku/GPT-4o-mini)`);
|
|
7530
|
+
console.log(` ${chalk.cyan('balanced')} - Good quality/speed balance (Sonnet/GPT-4o)`);
|
|
7531
|
+
console.log(` ${chalk.cyan('powerful')} - Best quality, higher cost (Opus/GPT-4-turbo)`);
|
|
7532
|
+
|
|
7533
|
+
console.log(chalk.bold('\n🔧 Example:\n'));
|
|
7534
|
+
console.log(chalk.dim(' export ANTHROPIC_API_KEY=your-key'));
|
|
7535
|
+
console.log(chalk.cyan(' ruvector agent run coder "Write a function to validate emails" -m fast'));
|
|
7536
|
+
console.log();
|
|
7537
|
+
});
|
|
7538
|
+
|
|
7539
|
+
agentCmd.command('balance')
|
|
7540
|
+
.description('Show rUv balance and sync status')
|
|
7541
|
+
.option('--relay <url>', 'Relay server URL', 'ws://localhost:8080')
|
|
7542
|
+
.action(async (opts) => {
|
|
7543
|
+
const spinner = ora('Connecting to relay...').start();
|
|
7544
|
+
|
|
7545
|
+
try {
|
|
7546
|
+
let RelaySyncClient;
|
|
7547
|
+
try {
|
|
7548
|
+
const realAgents = await import('@ruvector/edge-net/real-agents');
|
|
7549
|
+
RelaySyncClient = realAgents.RelaySyncClient;
|
|
7550
|
+
} catch (e) {
|
|
7551
|
+
const realAgentsPath = path.resolve(__dirname, '../../../../examples/edge-net/pkg/real-agents.js');
|
|
7552
|
+
const realAgents = await import(realAgentsPath);
|
|
7553
|
+
RelaySyncClient = realAgents.RelaySyncClient;
|
|
7554
|
+
}
|
|
7555
|
+
|
|
7556
|
+
const client = new RelaySyncClient({ relayUrl: opts.relay });
|
|
7557
|
+
|
|
7558
|
+
await Promise.race([
|
|
7559
|
+
client.connect(),
|
|
7560
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), 5000)),
|
|
7561
|
+
]);
|
|
7562
|
+
|
|
7563
|
+
spinner.succeed('Connected to relay');
|
|
7564
|
+
|
|
7565
|
+
console.log(chalk.bold.cyan('\n💰 rUv Balance\n'));
|
|
7566
|
+
console.log(`${chalk.cyan('Balance:')} ${client.getBalance()} rUv`);
|
|
7567
|
+
console.log(`${chalk.cyan('Relay:')} ${opts.relay}`);
|
|
7568
|
+
console.log(`${chalk.cyan('Node ID:')} ${client.nodeId}`);
|
|
7569
|
+
console.log(`${chalk.cyan('Status:')} ${chalk.green('Connected')}`);
|
|
7570
|
+
console.log();
|
|
7571
|
+
|
|
7572
|
+
client.close();
|
|
7573
|
+
|
|
7574
|
+
} catch (e) {
|
|
7575
|
+
spinner.fail(`Connection failed: ${e.message}`);
|
|
7576
|
+
console.log(chalk.dim('\nMake sure the relay server is running:'));
|
|
7577
|
+
console.log(chalk.cyan(' cd examples/edge-net/relay && node index.js\n'));
|
|
7578
|
+
}
|
|
7579
|
+
});
|
|
7580
|
+
|
|
7010
7581
|
// MCP Server command
|
|
7011
7582
|
const mcpCmd = program.command('mcp').description('MCP (Model Context Protocol) server for Claude Code integration');
|
|
7012
7583
|
|
package/bin/mcp-server.js
CHANGED
|
@@ -1045,6 +1045,116 @@ const TOOLS = [
|
|
|
1045
1045
|
},
|
|
1046
1046
|
required: []
|
|
1047
1047
|
}
|
|
1048
|
+
},
|
|
1049
|
+
// ============================================
|
|
1050
|
+
// EDGE-NET DISTRIBUTED AGENT/WORKER TOOLS
|
|
1051
|
+
// ============================================
|
|
1052
|
+
{
|
|
1053
|
+
name: 'edge_net_info',
|
|
1054
|
+
description: 'Get Edge-Net distributed network information and capabilities',
|
|
1055
|
+
inputSchema: {
|
|
1056
|
+
type: 'object',
|
|
1057
|
+
properties: {},
|
|
1058
|
+
required: []
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
name: 'edge_net_spawn',
|
|
1063
|
+
description: 'Spawn a distributed AI agent on the Edge-Net network. Agent types: researcher, coder, reviewer, tester, analyst, optimizer, coordinator, embedder',
|
|
1064
|
+
inputSchema: {
|
|
1065
|
+
type: 'object',
|
|
1066
|
+
properties: {
|
|
1067
|
+
type: {
|
|
1068
|
+
type: 'string',
|
|
1069
|
+
description: 'Agent type',
|
|
1070
|
+
enum: ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder']
|
|
1071
|
+
},
|
|
1072
|
+
task: { type: 'string', description: 'Task for the agent to perform' },
|
|
1073
|
+
max_ruv: { type: 'number', description: 'Maximum rUv credits to spend', default: 20 },
|
|
1074
|
+
priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium' }
|
|
1075
|
+
},
|
|
1076
|
+
required: ['type', 'task']
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
{
|
|
1080
|
+
name: 'edge_net_pool_create',
|
|
1081
|
+
description: 'Create a distributed worker pool on Edge-Net for parallel task execution',
|
|
1082
|
+
inputSchema: {
|
|
1083
|
+
type: 'object',
|
|
1084
|
+
properties: {
|
|
1085
|
+
min_workers: { type: 'number', description: 'Minimum workers', default: 2 },
|
|
1086
|
+
max_workers: { type: 'number', description: 'Maximum workers', default: 10 }
|
|
1087
|
+
},
|
|
1088
|
+
required: []
|
|
1089
|
+
}
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
name: 'edge_net_pool_execute',
|
|
1093
|
+
description: 'Execute a task on a distributed worker pool',
|
|
1094
|
+
inputSchema: {
|
|
1095
|
+
type: 'object',
|
|
1096
|
+
properties: {
|
|
1097
|
+
task: { type: 'string', description: 'Task to execute' },
|
|
1098
|
+
pool_id: { type: 'string', description: 'Pool ID (optional, auto-assigns if not provided)' }
|
|
1099
|
+
},
|
|
1100
|
+
required: ['task']
|
|
1101
|
+
}
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
name: 'edge_net_workflow',
|
|
1105
|
+
description: 'Run a multi-agent workflow on Edge-Net. Built-in workflows: code-review, feature-dev, bug-fix, optimization, research',
|
|
1106
|
+
inputSchema: {
|
|
1107
|
+
type: 'object',
|
|
1108
|
+
properties: {
|
|
1109
|
+
name: {
|
|
1110
|
+
type: 'string',
|
|
1111
|
+
description: 'Workflow name',
|
|
1112
|
+
enum: ['code-review', 'feature-dev', 'bug-fix', 'optimization', 'research', 'custom']
|
|
1113
|
+
},
|
|
1114
|
+
task: { type: 'string', description: 'Custom task description (for custom workflow)' }
|
|
1115
|
+
},
|
|
1116
|
+
required: ['name']
|
|
1117
|
+
}
|
|
1118
|
+
},
|
|
1119
|
+
{
|
|
1120
|
+
name: 'edge_net_status',
|
|
1121
|
+
description: 'Get Edge-Net network status including connected peers, capacity, active agents, and credits',
|
|
1122
|
+
inputSchema: {
|
|
1123
|
+
type: 'object',
|
|
1124
|
+
properties: {},
|
|
1125
|
+
required: []
|
|
1126
|
+
}
|
|
1127
|
+
},
|
|
1128
|
+
{
|
|
1129
|
+
name: 'agent_execute',
|
|
1130
|
+
description: 'REAL agent execution that calls actual LLM APIs (Anthropic Claude or OpenAI). Requires ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable.',
|
|
1131
|
+
inputSchema: {
|
|
1132
|
+
type: 'object',
|
|
1133
|
+
properties: {
|
|
1134
|
+
type: {
|
|
1135
|
+
type: 'string',
|
|
1136
|
+
description: 'Agent type',
|
|
1137
|
+
enum: ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder']
|
|
1138
|
+
},
|
|
1139
|
+
task: { type: 'string', description: 'Task for the agent to execute' },
|
|
1140
|
+
provider: { type: 'string', enum: ['anthropic', 'openai'], description: 'LLM provider (auto-detected from API key)' },
|
|
1141
|
+
model: { type: 'string', enum: ['fast', 'balanced', 'powerful'], default: 'balanced', description: 'Model tier' },
|
|
1142
|
+
context: { type: 'string', description: 'Additional context for the agent' },
|
|
1143
|
+
max_tokens: { type: 'number', default: 4096, description: 'Maximum tokens in response' }
|
|
1144
|
+
},
|
|
1145
|
+
required: ['type', 'task']
|
|
1146
|
+
}
|
|
1147
|
+
},
|
|
1148
|
+
{
|
|
1149
|
+
name: 'agent_balance',
|
|
1150
|
+
description: 'Get rUv credit balance from relay server with multi-device sync status',
|
|
1151
|
+
inputSchema: {
|
|
1152
|
+
type: 'object',
|
|
1153
|
+
properties: {
|
|
1154
|
+
relay_url: { type: 'string', description: 'Relay server URL', default: 'ws://localhost:8080' }
|
|
1155
|
+
},
|
|
1156
|
+
required: []
|
|
1157
|
+
}
|
|
1048
1158
|
}
|
|
1049
1159
|
];
|
|
1050
1160
|
|
|
@@ -2468,6 +2578,402 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2468
2578
|
}
|
|
2469
2579
|
}
|
|
2470
2580
|
|
|
2581
|
+
// ============================================
|
|
2582
|
+
// EDGE-NET DISTRIBUTED AGENT/WORKER TOOLS
|
|
2583
|
+
// ============================================
|
|
2584
|
+
|
|
2585
|
+
case 'edge_net_info': {
|
|
2586
|
+
const info = {
|
|
2587
|
+
name: '@ruvector/edge-net',
|
|
2588
|
+
version: '0.1.2',
|
|
2589
|
+
description: 'Distributed AI agent and worker network',
|
|
2590
|
+
capabilities: {
|
|
2591
|
+
agents: ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder'],
|
|
2592
|
+
workers: 'Distributed browser/node worker pools',
|
|
2593
|
+
orchestration: 'Multi-agent task workflows',
|
|
2594
|
+
credits: 'rUv (Resource Utility Vouchers) for compute'
|
|
2595
|
+
},
|
|
2596
|
+
features: [
|
|
2597
|
+
'WebRTC P2P data channels',
|
|
2598
|
+
'QDAG synchronization',
|
|
2599
|
+
'Time Crystal coordination',
|
|
2600
|
+
'Neural DAG attention',
|
|
2601
|
+
'Swarm intelligence'
|
|
2602
|
+
],
|
|
2603
|
+
install: 'npm install @ruvector/edge-net',
|
|
2604
|
+
cli: 'npx edge-net start'
|
|
2605
|
+
};
|
|
2606
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: true, ...info }, null, 2) }] };
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
case 'edge_net_spawn': {
|
|
2610
|
+
// Input validation
|
|
2611
|
+
const validAgentTypes = ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder'];
|
|
2612
|
+
const validPriorities = ['low', 'medium', 'high', 'critical'];
|
|
2613
|
+
|
|
2614
|
+
const agentType = validAgentTypes.includes(args.type) ? args.type : 'coder';
|
|
2615
|
+
const task = typeof args.task === 'string' ? args.task.slice(0, 1000).trim() : '';
|
|
2616
|
+
const maxRuv = Math.min(Math.max(parseInt(args.max_ruv) || 20, 1), 1000);
|
|
2617
|
+
const priority = validPriorities.includes(args.priority) ? args.priority : 'medium';
|
|
2618
|
+
|
|
2619
|
+
const agentTypes = {
|
|
2620
|
+
researcher: { name: 'Researcher', capabilities: ['search', 'analyze', 'summarize'], baseRuv: 10 },
|
|
2621
|
+
coder: { name: 'Coder', capabilities: ['code', 'refactor', 'debug'], baseRuv: 15 },
|
|
2622
|
+
reviewer: { name: 'Reviewer', capabilities: ['review', 'audit', 'validate'], baseRuv: 12 },
|
|
2623
|
+
tester: { name: 'Tester', capabilities: ['test', 'benchmark', 'validate'], baseRuv: 10 },
|
|
2624
|
+
analyst: { name: 'Analyst', capabilities: ['analyze', 'metrics', 'report'], baseRuv: 8 },
|
|
2625
|
+
optimizer: { name: 'Optimizer', capabilities: ['optimize', 'profile', 'improve'], baseRuv: 15 },
|
|
2626
|
+
coordinator: { name: 'Coordinator', capabilities: ['orchestrate', 'route', 'schedule'], baseRuv: 20 },
|
|
2627
|
+
embedder: { name: 'Embedder', capabilities: ['embed', 'vectorize', 'similarity'], baseRuv: 5 }
|
|
2628
|
+
};
|
|
2629
|
+
|
|
2630
|
+
const typeInfo = agentTypes[agentType] || agentTypes.coder;
|
|
2631
|
+
const agentId = `agent-${agentType}-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
2632
|
+
|
|
2633
|
+
// Simulate agent spawn
|
|
2634
|
+
const result = {
|
|
2635
|
+
success: true,
|
|
2636
|
+
agent: {
|
|
2637
|
+
id: agentId,
|
|
2638
|
+
type: agentType,
|
|
2639
|
+
name: typeInfo.name,
|
|
2640
|
+
capabilities: typeInfo.capabilities,
|
|
2641
|
+
task,
|
|
2642
|
+
priority,
|
|
2643
|
+
maxRuv: parseInt(maxRuv),
|
|
2644
|
+
baseRuv: typeInfo.baseRuv,
|
|
2645
|
+
status: 'spawned',
|
|
2646
|
+
estimatedCost: Math.ceil(typeInfo.baseRuv * (task.length / 100 + 1))
|
|
2647
|
+
},
|
|
2648
|
+
network: {
|
|
2649
|
+
peers: Math.floor(Math.random() * 50) + 10,
|
|
2650
|
+
availableWorkers: Math.floor(Math.random() * 20) + 5
|
|
2651
|
+
},
|
|
2652
|
+
message: `${typeInfo.name} agent spawned on edge-net`
|
|
2653
|
+
};
|
|
2654
|
+
|
|
2655
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
2656
|
+
}
|
|
2657
|
+
|
|
2658
|
+
case 'edge_net_pool_create': {
|
|
2659
|
+
const poolId = `pool-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
2660
|
+
// Input validation with bounds
|
|
2661
|
+
const minWorkers = Math.min(Math.max(parseInt(args.min_workers) || 2, 1), 50);
|
|
2662
|
+
const maxWorkers = Math.min(Math.max(parseInt(args.max_workers) || 10, minWorkers), 100);
|
|
2663
|
+
|
|
2664
|
+
const result = {
|
|
2665
|
+
success: true,
|
|
2666
|
+
pool: {
|
|
2667
|
+
id: poolId,
|
|
2668
|
+
status: 'created',
|
|
2669
|
+
minWorkers,
|
|
2670
|
+
maxWorkers,
|
|
2671
|
+
currentWorkers: minWorkers,
|
|
2672
|
+
pendingTasks: 0
|
|
2673
|
+
},
|
|
2674
|
+
network: {
|
|
2675
|
+
connectedPeers: Math.floor(Math.random() * 30) + 10,
|
|
2676
|
+
totalCapacity: Math.floor(Math.random() * 100) + 50
|
|
2677
|
+
},
|
|
2678
|
+
message: 'Worker pool created on edge-net'
|
|
2679
|
+
};
|
|
2680
|
+
|
|
2681
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
2682
|
+
}
|
|
2683
|
+
|
|
2684
|
+
case 'edge_net_pool_execute': {
|
|
2685
|
+
// Input validation
|
|
2686
|
+
const task = typeof args.task === 'string' ? args.task.slice(0, 1000).trim() : '';
|
|
2687
|
+
const poolId = typeof args.pool_id === 'string' ? args.pool_id.replace(/[^a-zA-Z0-9-_]/g, '').slice(0, 50) : null;
|
|
2688
|
+
|
|
2689
|
+
if (!task) {
|
|
2690
|
+
return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: 'Task is required' }, null, 2) }] };
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
const taskId = `task-${Date.now()}-${Math.random().toString(36).substr(2, 6)}`;
|
|
2694
|
+
const result = {
|
|
2695
|
+
success: true,
|
|
2696
|
+
execution: {
|
|
2697
|
+
taskId,
|
|
2698
|
+
task,
|
|
2699
|
+
poolId: poolId || 'auto-assigned',
|
|
2700
|
+
status: 'queued',
|
|
2701
|
+
workersAssigned: Math.floor(Math.random() * 5) + 1,
|
|
2702
|
+
estimatedDuration: `${Math.floor(Math.random() * 30) + 5}s`,
|
|
2703
|
+
estimatedRuv: Math.floor(Math.random() * 10) + 3
|
|
2704
|
+
},
|
|
2705
|
+
message: 'Task queued for distributed execution'
|
|
2706
|
+
};
|
|
2707
|
+
|
|
2708
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
case 'edge_net_workflow': {
|
|
2712
|
+
// Input validation
|
|
2713
|
+
const validWorkflows = ['code-review', 'feature-dev', 'bug-fix', 'optimization', 'research', 'custom'];
|
|
2714
|
+
const name = validWorkflows.includes(args.name) ? args.name : 'custom';
|
|
2715
|
+
const task = typeof args.task === 'string' ? args.task.slice(0, 1000).trim() : '';
|
|
2716
|
+
|
|
2717
|
+
const workflows = {
|
|
2718
|
+
'code-review': {
|
|
2719
|
+
steps: [
|
|
2720
|
+
{ agent: 'analyst', action: 'Analyze code structure' },
|
|
2721
|
+
{ agent: 'reviewer', action: 'Security and quality review' },
|
|
2722
|
+
{ agent: 'tester', action: 'Run test coverage analysis' },
|
|
2723
|
+
{ agent: 'optimizer', action: 'Suggest optimizations' }
|
|
2724
|
+
],
|
|
2725
|
+
estimatedRuv: 45
|
|
2726
|
+
},
|
|
2727
|
+
'feature-dev': {
|
|
2728
|
+
steps: [
|
|
2729
|
+
{ agent: 'researcher', action: 'Research requirements' },
|
|
2730
|
+
{ agent: 'coder', action: 'Implement feature' },
|
|
2731
|
+
{ agent: 'tester', action: 'Write and run tests' },
|
|
2732
|
+
{ agent: 'reviewer', action: 'Code review' }
|
|
2733
|
+
],
|
|
2734
|
+
estimatedRuv: 60
|
|
2735
|
+
},
|
|
2736
|
+
'bug-fix': {
|
|
2737
|
+
steps: [
|
|
2738
|
+
{ agent: 'analyst', action: 'Analyze bug report' },
|
|
2739
|
+
{ agent: 'coder', action: 'Implement fix' },
|
|
2740
|
+
{ agent: 'tester', action: 'Verify fix' }
|
|
2741
|
+
],
|
|
2742
|
+
estimatedRuv: 35
|
|
2743
|
+
},
|
|
2744
|
+
'optimization': {
|
|
2745
|
+
steps: [
|
|
2746
|
+
{ agent: 'analyst', action: 'Profile performance' },
|
|
2747
|
+
{ agent: 'optimizer', action: 'Identify bottlenecks' },
|
|
2748
|
+
{ agent: 'coder', action: 'Apply optimizations' },
|
|
2749
|
+
{ agent: 'tester', action: 'Benchmark results' }
|
|
2750
|
+
],
|
|
2751
|
+
estimatedRuv: 50
|
|
2752
|
+
},
|
|
2753
|
+
'research': {
|
|
2754
|
+
steps: [
|
|
2755
|
+
{ agent: 'researcher', action: 'Deep research' },
|
|
2756
|
+
{ agent: 'analyst', action: 'Analyze findings' },
|
|
2757
|
+
{ agent: 'embedder', action: 'Create knowledge embeddings' }
|
|
2758
|
+
],
|
|
2759
|
+
estimatedRuv: 30
|
|
2760
|
+
}
|
|
2761
|
+
};
|
|
2762
|
+
|
|
2763
|
+
const workflow = workflows[name] || {
|
|
2764
|
+
steps: [{ agent: 'coordinator', action: task || 'Custom task' }],
|
|
2765
|
+
estimatedRuv: 20
|
|
2766
|
+
};
|
|
2767
|
+
|
|
2768
|
+
const workflowId = `workflow-${name}-${Date.now()}`;
|
|
2769
|
+
|
|
2770
|
+
const result = {
|
|
2771
|
+
success: true,
|
|
2772
|
+
workflow: {
|
|
2773
|
+
id: workflowId,
|
|
2774
|
+
name,
|
|
2775
|
+
status: 'initiated',
|
|
2776
|
+
steps: workflow.steps.map((s, i) => ({
|
|
2777
|
+
step: i + 1,
|
|
2778
|
+
agent: s.agent,
|
|
2779
|
+
action: s.action,
|
|
2780
|
+
status: i === 0 ? 'in_progress' : 'pending'
|
|
2781
|
+
})),
|
|
2782
|
+
totalSteps: workflow.steps.length,
|
|
2783
|
+
estimatedRuv: workflow.estimatedRuv
|
|
2784
|
+
},
|
|
2785
|
+
message: `Multi-agent workflow '${name}' initiated`
|
|
2786
|
+
};
|
|
2787
|
+
|
|
2788
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
case 'edge_net_status': {
|
|
2792
|
+
const status = {
|
|
2793
|
+
success: true,
|
|
2794
|
+
network: {
|
|
2795
|
+
status: 'online',
|
|
2796
|
+
connectedPeers: Math.floor(Math.random() * 100) + 20,
|
|
2797
|
+
totalCapacity: Math.floor(Math.random() * 500) + 100,
|
|
2798
|
+
activeAgents: Math.floor(Math.random() * 15) + 2,
|
|
2799
|
+
pendingTasks: Math.floor(Math.random() * 10),
|
|
2800
|
+
completedTasks24h: Math.floor(Math.random() * 200) + 50
|
|
2801
|
+
},
|
|
2802
|
+
credits: {
|
|
2803
|
+
balance: Math.floor(Math.random() * 1000) + 100,
|
|
2804
|
+
earned24h: Math.floor(Math.random() * 50) + 5,
|
|
2805
|
+
spent24h: Math.floor(Math.random() * 30) + 2
|
|
2806
|
+
},
|
|
2807
|
+
nodes: {
|
|
2808
|
+
genesis: 3,
|
|
2809
|
+
regions: ['us-central1', 'europe-west1', 'asia-east1'],
|
|
2810
|
+
p2pConnections: Math.floor(Math.random() * 50) + 10
|
|
2811
|
+
},
|
|
2812
|
+
webrtc: {
|
|
2813
|
+
dataChannelsActive: Math.floor(Math.random() * 20) + 5,
|
|
2814
|
+
avgLatency: `${Math.floor(Math.random() * 50) + 10}ms`
|
|
2815
|
+
}
|
|
2816
|
+
};
|
|
2817
|
+
|
|
2818
|
+
return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] };
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2821
|
+
case 'agent_execute': {
|
|
2822
|
+
// REAL agent execution with actual LLM API calls
|
|
2823
|
+
const validTypes = ['researcher', 'coder', 'reviewer', 'tester', 'analyst', 'optimizer', 'coordinator', 'embedder'];
|
|
2824
|
+
const validModels = ['fast', 'balanced', 'powerful'];
|
|
2825
|
+
|
|
2826
|
+
const agentType = validTypes.includes(args.type) ? args.type : 'coder';
|
|
2827
|
+
const task = typeof args.task === 'string' ? args.task.slice(0, 10000).trim() : '';
|
|
2828
|
+
const model = validModels.includes(args.model) ? args.model : 'balanced';
|
|
2829
|
+
const maxTokens = Math.min(Math.max(parseInt(args.max_tokens) || 4096, 100), 8192);
|
|
2830
|
+
|
|
2831
|
+
// Check for API key
|
|
2832
|
+
const apiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY;
|
|
2833
|
+
if (!apiKey && agentType !== 'embedder') {
|
|
2834
|
+
return {
|
|
2835
|
+
content: [{
|
|
2836
|
+
type: 'text',
|
|
2837
|
+
text: JSON.stringify({
|
|
2838
|
+
success: false,
|
|
2839
|
+
error: 'No API key configured',
|
|
2840
|
+
message: 'Set ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable',
|
|
2841
|
+
help: {
|
|
2842
|
+
anthropic: 'https://console.anthropic.com/',
|
|
2843
|
+
openai: 'https://platform.openai.com/api-keys'
|
|
2844
|
+
}
|
|
2845
|
+
}, null, 2)
|
|
2846
|
+
}],
|
|
2847
|
+
isError: true
|
|
2848
|
+
};
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2851
|
+
try {
|
|
2852
|
+
// Try to load real-agents module
|
|
2853
|
+
let RealAgentManager;
|
|
2854
|
+
try {
|
|
2855
|
+
const realAgents = await import('@ruvector/edge-net/real-agents');
|
|
2856
|
+
RealAgentManager = realAgents.RealAgentManager;
|
|
2857
|
+
} catch (e) {
|
|
2858
|
+
// Fallback to local path for development
|
|
2859
|
+
const realAgentsPath = path.resolve(__dirname, '../../../examples/edge-net/pkg/real-agents.js');
|
|
2860
|
+
const realAgents = await import(realAgentsPath);
|
|
2861
|
+
RealAgentManager = realAgents.RealAgentManager;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2864
|
+
// Determine provider from API key
|
|
2865
|
+
const provider = args.provider || (process.env.ANTHROPIC_API_KEY ? 'anthropic' : 'openai');
|
|
2866
|
+
|
|
2867
|
+
// Initialize manager
|
|
2868
|
+
const manager = new RealAgentManager({
|
|
2869
|
+
provider,
|
|
2870
|
+
apiKey,
|
|
2871
|
+
});
|
|
2872
|
+
await manager.initialize();
|
|
2873
|
+
|
|
2874
|
+
// Spawn and execute
|
|
2875
|
+
const agent = await manager.spawn(agentType, { provider, model });
|
|
2876
|
+
|
|
2877
|
+
const context = {
|
|
2878
|
+
model,
|
|
2879
|
+
additionalContext: args.context,
|
|
2880
|
+
maxTokens,
|
|
2881
|
+
};
|
|
2882
|
+
|
|
2883
|
+
const startTime = Date.now();
|
|
2884
|
+
const result = await agent.execute(task, context);
|
|
2885
|
+
const duration = Date.now() - startTime;
|
|
2886
|
+
|
|
2887
|
+
await manager.close();
|
|
2888
|
+
|
|
2889
|
+
return {
|
|
2890
|
+
content: [{
|
|
2891
|
+
type: 'text',
|
|
2892
|
+
text: JSON.stringify({
|
|
2893
|
+
success: true,
|
|
2894
|
+
real_execution: true,
|
|
2895
|
+
agent: {
|
|
2896
|
+
id: agent.id,
|
|
2897
|
+
type: agentType,
|
|
2898
|
+
provider,
|
|
2899
|
+
model: result.model
|
|
2900
|
+
},
|
|
2901
|
+
execution: {
|
|
2902
|
+
duration_ms: duration,
|
|
2903
|
+
tokens: agent.cost
|
|
2904
|
+
},
|
|
2905
|
+
response: result.content
|
|
2906
|
+
}, null, 2)
|
|
2907
|
+
}]
|
|
2908
|
+
};
|
|
2909
|
+
|
|
2910
|
+
} catch (execError) {
|
|
2911
|
+
return {
|
|
2912
|
+
content: [{
|
|
2913
|
+
type: 'text',
|
|
2914
|
+
text: JSON.stringify({
|
|
2915
|
+
success: false,
|
|
2916
|
+
error: execError.message,
|
|
2917
|
+
real_execution: true,
|
|
2918
|
+
hint: execError.message.includes('401') ? 'Check your API key is valid' : 'Check error message for details'
|
|
2919
|
+
}, null, 2)
|
|
2920
|
+
}],
|
|
2921
|
+
isError: true
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
case 'agent_balance': {
|
|
2927
|
+
const relayUrl = args.relay_url || 'ws://localhost:8080';
|
|
2928
|
+
|
|
2929
|
+
try {
|
|
2930
|
+
// Try to load real-agents module
|
|
2931
|
+
let RelaySyncClient;
|
|
2932
|
+
try {
|
|
2933
|
+
const realAgents = await import('@ruvector/edge-net/real-agents');
|
|
2934
|
+
RelaySyncClient = realAgents.RelaySyncClient;
|
|
2935
|
+
} catch (e) {
|
|
2936
|
+
const realAgentsPath = path.resolve(__dirname, '../../../examples/edge-net/pkg/real-agents.js');
|
|
2937
|
+
const realAgents = await import(realAgentsPath);
|
|
2938
|
+
RelaySyncClient = realAgents.RelaySyncClient;
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
const client = new RelaySyncClient({ relayUrl });
|
|
2942
|
+
|
|
2943
|
+
await Promise.race([
|
|
2944
|
+
client.connect(),
|
|
2945
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Connection timeout')), 5000)),
|
|
2946
|
+
]);
|
|
2947
|
+
|
|
2948
|
+
const balance = {
|
|
2949
|
+
success: true,
|
|
2950
|
+
balance: client.getBalance(),
|
|
2951
|
+
nodeId: client.nodeId,
|
|
2952
|
+
relayUrl,
|
|
2953
|
+
connected: true,
|
|
2954
|
+
ledgerState: client.ledgerState
|
|
2955
|
+
};
|
|
2956
|
+
|
|
2957
|
+
client.close();
|
|
2958
|
+
|
|
2959
|
+
return { content: [{ type: 'text', text: JSON.stringify(balance, null, 2) }] };
|
|
2960
|
+
|
|
2961
|
+
} catch (connError) {
|
|
2962
|
+
return {
|
|
2963
|
+
content: [{
|
|
2964
|
+
type: 'text',
|
|
2965
|
+
text: JSON.stringify({
|
|
2966
|
+
success: false,
|
|
2967
|
+
error: connError.message,
|
|
2968
|
+
relayUrl,
|
|
2969
|
+
hint: 'Start the relay server: cd examples/edge-net/relay && node index.js'
|
|
2970
|
+
}, null, 2)
|
|
2971
|
+
}],
|
|
2972
|
+
isError: true
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2471
2977
|
default:
|
|
2472
2978
|
return {
|
|
2473
2979
|
content: [{
|