tasq/node_modules/agentdb/simulation/runner.ts

301 lines
8.5 KiB
TypeScript

/**
* 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';
interface SimulationOptions {
config: string;
verbosity: string;
iterations: string;
swarmSize: string;
model: string;
parallel: boolean;
output: string;
stream: boolean;
optimize: boolean;
}
interface SimulationResult {
scenario: string;
startTime: number;
endTime: number;
duration: number;
iterations: number;
agents: number;
success: number;
failures: number;
metrics: {
opsPerSec: number;
avgLatency: number;
memoryUsage: number;
errorRate: number;
};
details: any[];
}
export async function runSimulation(scenario: string, options: SimulationOptions): Promise<void> {
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: SimulationResult = {
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(): Promise<void> {
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: string, options: any): Promise<void> {
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: string): string {
const templates: Record<string, string> = {
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;
}