Merge: Network Discovery Agent deployment script - resolved conflicts
This commit is contained in:
commit
1d75f0c22c
2 changed files with 266 additions and 1 deletions
263
deploy/NetworkDiscoveryAgent.ts
Normal file
263
deploy/NetworkDiscoveryAgent.ts
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
#!/usr/bin/env bun
|
||||
/**
|
||||
* NetworkDiscoveryAgent Deployment Script
|
||||
* Agent 8 - Geographic Network Discovery and Analysis
|
||||
*
|
||||
* This script provides standalone deployment for the NetworkDiscoveryAgent,
|
||||
* which maps and analyzes the geographic distribution of the plant network.
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Map plant distribution across regions
|
||||
* - Identify network hotspots and clusters
|
||||
* - Suggest grower/consumer connections
|
||||
* - Track network growth patterns
|
||||
* - Detect coverage gaps
|
||||
*
|
||||
* Usage:
|
||||
* bun run deploy/NetworkDiscoveryAgent.ts
|
||||
* bun run deploy:network-discovery
|
||||
*
|
||||
* Environment Variables:
|
||||
* AGENT_INTERVAL_MS - Execution interval (default: 600000 = 10 min)
|
||||
* AGENT_LOG_LEVEL - Log level: debug, info, warn, error (default: info)
|
||||
* AGENT_AUTO_RESTART - Auto-restart on failure (default: true)
|
||||
* AGENT_MAX_RETRIES - Max retry attempts (default: 3)
|
||||
*/
|
||||
|
||||
import { getNetworkDiscoveryAgent, NetworkDiscoveryAgent } from '../lib/agents/NetworkDiscoveryAgent';
|
||||
|
||||
// Configuration from environment
|
||||
const config = {
|
||||
intervalMs: parseInt(process.env.AGENT_INTERVAL_MS || '600000'),
|
||||
logLevel: process.env.AGENT_LOG_LEVEL || 'info',
|
||||
autoRestart: process.env.AGENT_AUTO_RESTART !== 'false',
|
||||
maxRetries: parseInt(process.env.AGENT_MAX_RETRIES || '3'),
|
||||
};
|
||||
|
||||
// Logger utility
|
||||
const log = {
|
||||
debug: (...args: any[]) => config.logLevel === 'debug' && console.log('[DEBUG]', ...args),
|
||||
info: (...args: any[]) => ['debug', 'info'].includes(config.logLevel) && console.log('[INFO]', ...args),
|
||||
warn: (...args: any[]) => ['debug', 'info', 'warn'].includes(config.logLevel) && console.warn('[WARN]', ...args),
|
||||
error: (...args: any[]) => console.error('[ERROR]', ...args),
|
||||
};
|
||||
|
||||
/**
|
||||
* Format uptime as human-readable string
|
||||
*/
|
||||
function formatUptime(ms: number): string {
|
||||
const seconds = Math.floor(ms / 1000);
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
const days = Math.floor(hours / 24);
|
||||
|
||||
if (days > 0) return `${days}d ${hours % 24}h ${minutes % 60}m`;
|
||||
if (hours > 0) return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
|
||||
if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
|
||||
return `${seconds}s`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display agent status
|
||||
*/
|
||||
function displayStatus(agent: NetworkDiscoveryAgent): void {
|
||||
const metrics = agent.getMetrics();
|
||||
const analysis = agent.getNetworkAnalysis();
|
||||
const clusters = agent.getClusters();
|
||||
const gaps = agent.getCoverageGaps();
|
||||
const suggestions = agent.getConnectionSuggestions();
|
||||
const growth = agent.getGrowthHistory();
|
||||
const regions = agent.getRegionalStats();
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' NETWORK DISCOVERY AGENT - STATUS REPORT');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// Agent Metrics
|
||||
console.log('\n AGENT METRICS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
console.log(` Status: ${agent.status}`);
|
||||
console.log(` Uptime: ${formatUptime(metrics.uptime)}`);
|
||||
console.log(` Tasks Completed: ${metrics.tasksCompleted}`);
|
||||
console.log(` Tasks Failed: ${metrics.tasksFailed}`);
|
||||
console.log(` Avg Execution: ${Math.round(metrics.averageExecutionMs)}ms`);
|
||||
console.log(` Last Run: ${metrics.lastRunAt || 'Never'}`);
|
||||
|
||||
// Network Analysis
|
||||
console.log('\n NETWORK ANALYSIS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
console.log(` Total Nodes: ${analysis.totalNodes}`);
|
||||
console.log(` Connections: ${analysis.totalConnections}`);
|
||||
console.log(` Clusters: ${clusters.length}`);
|
||||
console.log(` Hotspots: ${analysis.hotspots.length}`);
|
||||
console.log(` Coverage Gaps: ${gaps.length}`);
|
||||
console.log(` Suggestions: ${suggestions.length}`);
|
||||
|
||||
// Cluster Details
|
||||
if (clusters.length > 0) {
|
||||
console.log('\n TOP CLUSTERS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
const topClusters = clusters.slice(0, 5);
|
||||
for (const cluster of topClusters) {
|
||||
console.log(` - ${cluster.activityLevel.toUpperCase()} activity cluster`);
|
||||
console.log(` Nodes: ${cluster.nodes.length}, Radius: ${cluster.radius}km`);
|
||||
if (cluster.dominantSpecies.length > 0) {
|
||||
console.log(` Species: ${cluster.dominantSpecies.slice(0, 3).join(', ')}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Coverage Gaps
|
||||
if (gaps.length > 0) {
|
||||
console.log('\n COVERAGE GAPS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
for (const gap of gaps.slice(0, 3)) {
|
||||
console.log(` - ${gap.populationDensity.toUpperCase()} area`);
|
||||
console.log(` Distance to nearest: ${gap.distanceToNearest}km`);
|
||||
console.log(` Potential demand: ${gap.potentialDemand}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Top Suggestions
|
||||
if (suggestions.length > 0) {
|
||||
console.log('\n TOP CONNECTION SUGGESTIONS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
for (const suggestion of suggestions.slice(0, 3)) {
|
||||
console.log(` - Strength: ${suggestion.strength}%`);
|
||||
console.log(` Distance: ${suggestion.distance}km`);
|
||||
console.log(` Reason: ${suggestion.reason}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Regional Stats
|
||||
if (regions.length > 0) {
|
||||
console.log('\n REGIONAL STATISTICS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
for (const region of regions) {
|
||||
if (region.nodeCount > 0) {
|
||||
console.log(` ${region.region}:`);
|
||||
console.log(` Nodes: ${region.nodeCount}, Plants: ${region.plantCount}`);
|
||||
console.log(` Species: ${region.uniqueSpecies}, Activity: ${region.avgActivityScore}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Growth Trend
|
||||
if (growth.length > 0) {
|
||||
const latest = growth[growth.length - 1];
|
||||
console.log('\n NETWORK GROWTH');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
console.log(` Total Nodes: ${latest.totalNodes}`);
|
||||
console.log(` Total Connections: ${latest.totalConnections}`);
|
||||
console.log(` New Nodes/Week: ${latest.newNodesWeek}`);
|
||||
console.log(` Geographic Span: ${latest.geographicExpansion}km`);
|
||||
}
|
||||
|
||||
// Alerts
|
||||
const alerts = agent.getAlerts();
|
||||
const unacknowledged = alerts.filter(a => !a.acknowledged);
|
||||
if (unacknowledged.length > 0) {
|
||||
console.log('\n ACTIVE ALERTS');
|
||||
console.log(' ' + '-'.repeat(40));
|
||||
for (const alert of unacknowledged.slice(0, 5)) {
|
||||
console.log(` [${alert.severity.toUpperCase()}] ${alert.title}`);
|
||||
console.log(` ${alert.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main deployment function
|
||||
*/
|
||||
async function deploy(): Promise<void> {
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' DEPLOYING NETWORK DISCOVERY AGENT (Agent 8)');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`\n Configuration:`);
|
||||
console.log(` - Interval: ${config.intervalMs}ms (${config.intervalMs / 60000} min)`);
|
||||
console.log(` - Log Level: ${config.logLevel}`);
|
||||
console.log(` - Auto Restart: ${config.autoRestart}`);
|
||||
console.log(` - Max Retries: ${config.maxRetries}`);
|
||||
console.log('');
|
||||
|
||||
// Get agent instance
|
||||
const agent = getNetworkDiscoveryAgent();
|
||||
|
||||
// Register event handlers
|
||||
agent.on('task_completed', (data) => {
|
||||
log.info(`Task completed: ${JSON.stringify(data.result)}`);
|
||||
});
|
||||
|
||||
agent.on('task_failed', (data) => {
|
||||
log.error(`Task failed: ${data.error}`);
|
||||
});
|
||||
|
||||
agent.on('agent_started', () => {
|
||||
log.info('Network Discovery Agent started');
|
||||
});
|
||||
|
||||
agent.on('agent_stopped', () => {
|
||||
log.info('Network Discovery Agent stopped');
|
||||
});
|
||||
|
||||
// Start the agent
|
||||
log.info('Starting Network Discovery Agent...');
|
||||
|
||||
try {
|
||||
await agent.start();
|
||||
log.info('Agent started successfully');
|
||||
|
||||
// Run initial discovery
|
||||
log.info('Running initial network discovery...');
|
||||
await agent.runOnce();
|
||||
log.info('Initial discovery complete');
|
||||
|
||||
// Display initial status
|
||||
displayStatus(agent);
|
||||
|
||||
// Set up periodic status display
|
||||
const statusInterval = setInterval(() => {
|
||||
displayStatus(agent);
|
||||
}, config.intervalMs);
|
||||
|
||||
// Handle shutdown signals
|
||||
const shutdown = async (signal: string) => {
|
||||
log.info(`Received ${signal}, shutting down...`);
|
||||
clearInterval(statusInterval);
|
||||
|
||||
try {
|
||||
await agent.stop();
|
||||
log.info('Agent stopped gracefully');
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
log.error('Error during shutdown:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
process.on('SIGINT', () => shutdown('SIGINT'));
|
||||
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
||||
|
||||
// Keep the process running
|
||||
log.info(`Agent running. Press Ctrl+C to stop.`);
|
||||
log.info(`Next discovery in ${config.intervalMs / 60000} minutes...`);
|
||||
|
||||
} catch (error) {
|
||||
log.error('Failed to start agent:', error);
|
||||
|
||||
if (config.autoRestart) {
|
||||
log.info('Auto-restart enabled, retrying in 10 seconds...');
|
||||
setTimeout(() => deploy(), 10000);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run deployment
|
||||
deploy().catch((error) => {
|
||||
console.error('Deployment failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
|
@ -28,7 +28,9 @@
|
|||
"db:seed": "bun run prisma/seed.ts",
|
||||
"db:studio": "prisma studio",
|
||||
"prepare": "husky install",
|
||||
"validate": "bun run type-check && bun run lint && bun run test"
|
||||
"validate": "bun run type-check && bun run lint && bun run test",
|
||||
"deploy:network-discovery": "bun run deploy/NetworkDiscoveryAgent.ts",
|
||||
"agent:network-discovery": "bun run deploy/NetworkDiscoveryAgent.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.937.0",
|
||||
|
|
|
|||
Loading…
Reference in a new issue