241 lines
8.7 KiB
JavaScript
241 lines
8.7 KiB
JavaScript
/**
|
|
* Simulation Runner
|
|
*
|
|
* Orchestrates multi-agent swarms to test AgentDB functionality
|
|
*/
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { performance } from 'perf_hooks';
|
|
export async function runSimulation(scenario, options) {
|
|
const verbosity = parseInt(options.verbosity);
|
|
if (verbosity >= 1) {
|
|
console.log('🚀 AgentDB Simulation System v2.0.0');
|
|
console.log('═'.repeat(70));
|
|
console.log(`Scenario: ${scenario}`);
|
|
console.log(`Config: ${options.config}`);
|
|
console.log(`Model: ${options.model}`);
|
|
console.log(`Swarm Size: ${options.swarmSize}`);
|
|
console.log(`Iterations: ${options.iterations}`);
|
|
console.log(`Parallel: ${options.parallel}`);
|
|
console.log(`Streaming: ${options.stream}`);
|
|
console.log(`Optimize: ${options.optimize}`);
|
|
console.log('═'.repeat(70));
|
|
}
|
|
// Load scenario
|
|
const scenarioPath = path.join(process.cwd(), 'simulation', 'scenarios', `${scenario}.ts`);
|
|
if (!fs.existsSync(scenarioPath)) {
|
|
console.error(`❌ Scenario not found: ${scenario}`);
|
|
console.error(` Path: ${scenarioPath}`);
|
|
process.exit(1);
|
|
}
|
|
const startTime = performance.now();
|
|
const result = {
|
|
scenario,
|
|
startTime: Date.now(),
|
|
endTime: 0,
|
|
duration: 0,
|
|
iterations: parseInt(options.iterations),
|
|
agents: parseInt(options.swarmSize),
|
|
success: 0,
|
|
failures: 0,
|
|
metrics: {
|
|
opsPerSec: 0,
|
|
avgLatency: 0,
|
|
memoryUsage: 0,
|
|
errorRate: 0
|
|
},
|
|
details: []
|
|
};
|
|
try {
|
|
// Import and run scenario
|
|
const scenarioModule = await import(scenarioPath);
|
|
const scenarioRunner = scenarioModule.default;
|
|
if (verbosity >= 2) {
|
|
console.log(`\n🎯 Running scenario: ${scenario}\n`);
|
|
}
|
|
// Initialize swarm
|
|
const swarmConfig = {
|
|
size: parseInt(options.swarmSize),
|
|
model: options.model,
|
|
parallel: options.parallel,
|
|
stream: options.stream,
|
|
optimize: options.optimize,
|
|
verbosity
|
|
};
|
|
// Run iterations
|
|
for (let i = 0; i < parseInt(options.iterations); i++) {
|
|
if (verbosity >= 2) {
|
|
console.log(`\n📍 Iteration ${i + 1}/${options.iterations}`);
|
|
}
|
|
const iterationStart = performance.now();
|
|
try {
|
|
const iterationResult = await scenarioRunner.run(swarmConfig);
|
|
const iterationEnd = performance.now();
|
|
result.success++;
|
|
result.details.push({
|
|
iteration: i + 1,
|
|
duration: iterationEnd - iterationStart,
|
|
success: true,
|
|
data: iterationResult
|
|
});
|
|
if (verbosity >= 3) {
|
|
console.log(` ✅ Iteration ${i + 1} completed in ${(iterationEnd - iterationStart).toFixed(2)}ms`);
|
|
console.log(` Result:`, JSON.stringify(iterationResult, null, 2));
|
|
}
|
|
else if (verbosity >= 2) {
|
|
console.log(` ✅ Completed in ${(iterationEnd - iterationStart).toFixed(2)}ms`);
|
|
}
|
|
}
|
|
catch (error) {
|
|
const iterationEnd = performance.now();
|
|
result.failures++;
|
|
result.details.push({
|
|
iteration: i + 1,
|
|
duration: iterationEnd - iterationStart,
|
|
success: false,
|
|
error: error instanceof Error ? error.message : String(error)
|
|
});
|
|
if (verbosity >= 1) {
|
|
console.error(` ❌ Iteration ${i + 1} failed:`, error);
|
|
}
|
|
}
|
|
}
|
|
const endTime = performance.now();
|
|
result.endTime = Date.now();
|
|
result.duration = endTime - startTime;
|
|
// Calculate metrics
|
|
const successfulIterations = result.details.filter(d => d.success);
|
|
const totalDuration = successfulIterations.reduce((sum, d) => sum + d.duration, 0);
|
|
result.metrics.avgLatency = totalDuration / successfulIterations.length;
|
|
result.metrics.opsPerSec = (result.success / (result.duration / 1000));
|
|
result.metrics.errorRate = result.failures / result.iterations;
|
|
result.metrics.memoryUsage = process.memoryUsage().heapUsed / 1024 / 1024; // MB
|
|
// Display results
|
|
if (verbosity >= 1) {
|
|
console.log('\n' + '═'.repeat(70));
|
|
console.log('📊 SIMULATION RESULTS');
|
|
console.log('═'.repeat(70));
|
|
console.log(`Total Duration: ${(result.duration / 1000).toFixed(2)}s`);
|
|
console.log(`Iterations: ${result.iterations}`);
|
|
console.log(`Success: ${result.success} (${((result.success / result.iterations) * 100).toFixed(1)}%)`);
|
|
console.log(`Failures: ${result.failures} (${((result.failures / result.iterations) * 100).toFixed(1)}%)`);
|
|
console.log(`\nMetrics:`);
|
|
console.log(` Throughput: ${result.metrics.opsPerSec.toFixed(2)} ops/sec`);
|
|
console.log(` Avg Latency: ${result.metrics.avgLatency.toFixed(2)}ms`);
|
|
console.log(` Error Rate: ${(result.metrics.errorRate * 100).toFixed(2)}%`);
|
|
console.log(` Memory Usage: ${result.metrics.memoryUsage.toFixed(2)} MB`);
|
|
console.log('═'.repeat(70));
|
|
}
|
|
// Save results
|
|
const outputDir = path.join(process.cwd(), options.output);
|
|
if (!fs.existsSync(outputDir)) {
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
}
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
const outputPath = path.join(outputDir, `${scenario}-${timestamp}.json`);
|
|
fs.writeFileSync(outputPath, JSON.stringify(result, null, 2));
|
|
if (verbosity >= 1) {
|
|
console.log(`\n💾 Results saved to: ${outputPath}\n`);
|
|
}
|
|
}
|
|
catch (error) {
|
|
console.error('\n❌ Simulation failed:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
export async function listScenarios() {
|
|
const scenariosDir = path.join(process.cwd(), 'simulation', 'scenarios');
|
|
if (!fs.existsSync(scenariosDir)) {
|
|
console.log('No scenarios found. Create scenarios in simulation/scenarios/');
|
|
return;
|
|
}
|
|
const files = fs.readdirSync(scenariosDir).filter(f => f.endsWith('.ts'));
|
|
console.log('\n📋 Available Scenarios:\n');
|
|
for (const file of files) {
|
|
const scenarioName = file.replace('.ts', '');
|
|
const scenarioPath = path.join(scenariosDir, file);
|
|
try {
|
|
const module = await import(scenarioPath);
|
|
const description = module.default?.description || 'No description';
|
|
console.log(` ${scenarioName.padEnd(30)} - ${description}`);
|
|
}
|
|
catch (error) {
|
|
console.log(` ${scenarioName.padEnd(30)} - (Error loading)`);
|
|
}
|
|
}
|
|
console.log('');
|
|
}
|
|
export async function initScenario(scenario, options) {
|
|
const scenarioPath = path.join(process.cwd(), 'simulation', 'scenarios', `${scenario}.ts`);
|
|
if (fs.existsSync(scenarioPath)) {
|
|
console.error(`❌ Scenario already exists: ${scenario}`);
|
|
return;
|
|
}
|
|
const template = getTemplate(options.template);
|
|
fs.writeFileSync(scenarioPath, template);
|
|
console.log(`✅ Created scenario: ${scenario}`);
|
|
console.log(` Path: ${scenarioPath}`);
|
|
console.log(` Template: ${options.template}`);
|
|
}
|
|
function getTemplate(templateName) {
|
|
const templates = {
|
|
basic: `/**
|
|
* Basic Simulation Scenario
|
|
*/
|
|
|
|
export default {
|
|
description: 'Basic simulation scenario',
|
|
|
|
async run(config: any) {
|
|
// Your simulation logic here
|
|
return {
|
|
status: 'success',
|
|
data: {}
|
|
};
|
|
}
|
|
};
|
|
`,
|
|
swarm: `/**
|
|
* Swarm Simulation Scenario
|
|
*/
|
|
|
|
export default {
|
|
description: 'Multi-agent swarm simulation',
|
|
|
|
async run(config: any) {
|
|
const { swarmInit, agentSpawn } = await import('./swarms/coordinator.js');
|
|
|
|
// Initialize swarm
|
|
const swarm = await swarmInit({
|
|
topology: 'mesh',
|
|
maxAgents: config.size
|
|
});
|
|
|
|
// Spawn agents
|
|
const agents = [];
|
|
for (let i = 0; i < config.size; i++) {
|
|
const agent = await agentSpawn({
|
|
swarmId: swarm.id,
|
|
type: 'worker',
|
|
capabilities: ['agentdb']
|
|
});
|
|
agents.push(agent);
|
|
}
|
|
|
|
// Execute tasks
|
|
const results = await Promise.all(
|
|
agents.map(agent => agent.execute())
|
|
);
|
|
|
|
return {
|
|
status: 'success',
|
|
agents: agents.length,
|
|
results
|
|
};
|
|
}
|
|
};
|
|
`
|
|
};
|
|
return templates[templateName] || templates.basic;
|
|
}
|
|
//# sourceMappingURL=runner.js.map
|