UNPKG

tlnt

Version:

TLNT - HMS-Powered Multi-Agent Platform with Government Agency Analysis, Deep Research, and Enterprise-Ready Deployment. Self-optimizing multi-domain AI agent with continuous learning and enterprise-grade performance monitoring.

460 lines 16.6 kB
import { EventEmitter } from 'events'; import { MessageBus } from './messageBus.js'; import { AgentHub } from './agentHub.js'; /** * Unified System Launcher for HMS Dev components * Manages all system components with configurable startup modes */ export class UnifiedLauncher extends EventEmitter { config; running = false; components = new Map(); processes = new Map(); // Core components messageBus; agentHub; // Async tasks monitoringTasks = new Set(); constructor(config = {}) { super(); this.config = { redisUrl: config.redisUrl || 'redis://localhost:6379', apiHost: config.apiHost || '0.0.0.0', apiPort: config.apiPort || 8080, enableMessageBus: config.enableMessageBus ?? true, enableAgentHub: config.enableAgentHub ?? true, enableWatchMode: config.enableWatchMode ?? true, enableMetrics: config.enableMetrics ?? true, enableDashboard: config.enableDashboard ?? true, developmentMode: config.developmentMode ?? false, debugLogging: config.debugLogging ?? false, watchdogLogDir: config.watchdogLogDir || './logs/watchdog', watchdogCompress: config.watchdogCompress ?? true, watchdogRetentionHours: config.watchdogRetentionHours ?? 168, // 7 days dashboardHost: config.dashboardHost || 'localhost', dashboardPort: config.dashboardPort || 8090, messageBusConfig: config.messageBusConfig || {} }; this.setupSignalHandlers(); } setupSignalHandlers() { process.on('SIGINT', () => this.handleShutdown('SIGINT')); process.on('SIGTERM', () => this.handleShutdown('SIGTERM')); process.on('uncaughtException', (error) => this.handleError('uncaughtException', error)); process.on('unhandledRejection', (reason) => this.handleError('unhandledRejection', reason)); } handleShutdown(signal) { console.log(`Received ${signal}, initiating graceful shutdown...`); this.shutdown().catch(error => { console.error('Error during shutdown:', error); process.exit(1); }); } handleError(type, error) { console.error(`${type}:`, error); this.emit('error', { type, error }); } /** * Start all configured components */ async start() { if (this.running) { throw new Error('Launcher is already running'); } console.log('🚀 Starting HMS Dev Unified System...'); this.running = true; const startupTasks = []; // 1. Initialize message bus first if (this.config.enableMessageBus) { startupTasks.push(() => this.startMessageBus()); } // 2. Initialize agent hub if (this.config.enableAgentHub) { startupTasks.push(() => this.startAgentHub()); } // 3. Start watch mode if (this.config.enableWatchMode) { startupTasks.push(() => this.startWatchMode()); } // 4. Start metrics collection if (this.config.enableMetrics) { startupTasks.push(() => this.startMetrics()); } // 5. Start dashboard if (this.config.enableDashboard) { startupTasks.push(() => this.startDashboard()); } // Execute startup tasks sequentially for (const task of startupTasks) { try { await task(); } catch (error) { console.error('Startup task failed:', error); await this.shutdown(); throw error; } } // Start monitoring loop this.startMonitoring(); console.log('✅ HMS Dev Unified System startup complete'); this.emit('started'); } /** * Stop all components gracefully */ async shutdown() { if (!this.running) return; console.log('🛑 Shutting down HMS Dev Unified System...'); this.running = false; // Clear monitoring tasks for (const task of this.monitoringTasks) { clearInterval(task); } this.monitoringTasks.clear(); // Stop components in reverse order const shutdownTasks = []; // Stop dashboard if (this.hasComponent('dashboard')) { shutdownTasks.push(this.stopDashboard()); } // Stop metrics if (this.hasComponent('metrics')) { shutdownTasks.push(this.stopMetrics()); } // Stop watch mode if (this.hasComponent('watchMode')) { shutdownTasks.push(this.stopWatchMode()); } // Stop agent hub if (this.agentHub) { shutdownTasks.push(this.stopAgentHub()); } // Stop message bus last if (this.messageBus) { shutdownTasks.push(this.stopMessageBus()); } // Wait for all shutdowns await Promise.allSettled(shutdownTasks); console.log('✅ HMS Dev Unified System shutdown complete'); this.emit('stopped'); } async startMessageBus() { console.log('📡 Starting message bus...'); this.setComponentStatus('messageBus', 'starting'); try { this.messageBus = new MessageBus({ redisUrl: this.config.redisUrl, ...this.config.messageBusConfig }); await this.messageBus.connect(); this.messageBus.on('connected', () => { this.setComponentStatus('messageBus', 'running'); }); this.messageBus.on('error', (error) => { this.setComponentStatus('messageBus', 'error', { error }); }); this.messageBus.on('disconnected', () => { this.setComponentStatus('messageBus', 'stopped'); }); console.log('✅ Message bus started'); } catch (error) { this.setComponentStatus('messageBus', 'error', { error }); throw error; } } async stopMessageBus() { if (!this.messageBus) return; console.log('📡 Stopping message bus...'); this.setComponentStatus('messageBus', 'stopping'); try { await this.messageBus.disconnect(); this.messageBus = undefined; this.setComponentStatus('messageBus', 'stopped'); console.log('✅ Message bus stopped'); } catch (error) { console.error('Error stopping message bus:', error); this.setComponentStatus('messageBus', 'error', { error }); } } async startAgentHub() { console.log('🤖 Starting agent hub...'); this.setComponentStatus('agentHub', 'starting'); try { this.agentHub = new AgentHub(); await this.agentHub.initialize(); this.agentHub.on('initialized', () => { this.setComponentStatus('agentHub', 'running'); }); this.agentHub.on('error', (error) => { this.setComponentStatus('agentHub', 'error', { error }); }); console.log('✅ Agent hub started'); } catch (error) { this.setComponentStatus('agentHub', 'error', { error }); throw error; } } async stopAgentHub() { if (!this.agentHub) return; console.log('🤖 Stopping agent hub...'); this.setComponentStatus('agentHub', 'stopping'); try { // Agent hub doesn't have an explicit stop method, just clean up this.agentHub.removeAllListeners(); this.agentHub = undefined; this.setComponentStatus('agentHub', 'stopped'); console.log('✅ Agent hub stopped'); } catch (error) { console.error('Error stopping agent hub:', error); this.setComponentStatus('agentHub', 'error', { error }); } } async startWatchMode() { console.log('👁️ Starting watch mode...'); this.setComponentStatus('watchMode', 'starting'); try { // For now, simulate watch mode startup // In full implementation, this would start the Python watch mode components await new Promise(resolve => setTimeout(resolve, 1000)); this.setComponentStatus('watchMode', 'running'); console.log('✅ Watch mode started'); } catch (error) { this.setComponentStatus('watchMode', 'error', { error }); throw error; } } async stopWatchMode() { console.log('👁️ Stopping watch mode...'); this.setComponentStatus('watchMode', 'stopping'); try { // Cleanup watch mode this.setComponentStatus('watchMode', 'stopped'); console.log('✅ Watch mode stopped'); } catch (error) { console.error('Error stopping watch mode:', error); this.setComponentStatus('watchMode', 'error', { error }); } } async startMetrics() { console.log('📊 Starting metrics collection...'); this.setComponentStatus('metrics', 'starting'); try { // For now, simulate metrics startup await new Promise(resolve => setTimeout(resolve, 500)); this.setComponentStatus('metrics', 'running'); console.log('✅ Metrics collection started'); } catch (error) { this.setComponentStatus('metrics', 'error', { error }); throw error; } } async stopMetrics() { console.log('📊 Stopping metrics collection...'); this.setComponentStatus('metrics', 'stopping'); try { // Cleanup metrics this.setComponentStatus('metrics', 'stopped'); console.log('✅ Metrics collection stopped'); } catch (error) { console.error('Error stopping metrics:', error); this.setComponentStatus('metrics', 'error', { error }); } } async startDashboard() { console.log('🎛️ Starting dashboard...'); this.setComponentStatus('dashboard', 'starting'); try { // For now, simulate dashboard startup await new Promise(resolve => setTimeout(resolve, 1000)); this.setComponentStatus('dashboard', 'running'); console.log(`✅ Dashboard started on ${this.config.dashboardHost}:${this.config.dashboardPort}`); console.log(`📊 Access dashboard at: http://${this.config.dashboardHost}:${this.config.dashboardPort}`); } catch (error) { this.setComponentStatus('dashboard', 'error', { error }); throw error; } } async stopDashboard() { console.log('🎛️ Stopping dashboard...'); this.setComponentStatus('dashboard', 'stopping'); try { // Cleanup dashboard this.setComponentStatus('dashboard', 'stopped'); console.log('✅ Dashboard stopped'); } catch (error) { console.error('Error stopping dashboard:', error); this.setComponentStatus('dashboard', 'error', { error }); } } startMonitoring() { const monitoringInterval = setInterval(() => { this.performHealthChecks().catch(error => { console.error('Health check failed:', error); }); }, 30000); // Every 30 seconds this.monitoringTasks.add(monitoringInterval); } async performHealthChecks() { const checks = []; if (this.messageBus) { checks.push(this.checkMessageBusHealth()); } if (this.agentHub) { checks.push(this.checkAgentHubHealth()); } await Promise.allSettled(checks); } async checkMessageBusHealth() { try { const health = await this.messageBus.healthCheck(); if (health.status === 'unhealthy') { this.setComponentStatus('messageBus', 'error', { error: new Error('Message bus health check failed'), details: health.details }); } } catch (error) { this.setComponentStatus('messageBus', 'error', { error }); } } async checkAgentHubHealth() { try { const health = await this.agentHub.healthCheck(); if (health.status === 'unhealthy') { this.setComponentStatus('agentHub', 'error', { error: new Error('Agent hub health check failed'), details: health.details }); } } catch (error) { this.setComponentStatus('agentHub', 'error', { error }); } } setComponentStatus(name, status, metadata) { const existing = this.components.get(name); const componentStatus = { name, status, startTime: existing?.startTime || (status === 'starting' ? Date.now() : undefined), ...metadata }; this.components.set(name, componentStatus); this.emit('componentStatusChanged', componentStatus); if (this.config.debugLogging) { console.log(`Component ${name}: ${status}`); } } hasComponent(name) { const component = this.components.get(name); return component?.status === 'running' || component?.status === 'starting'; } /** * Get current system status */ getSystemStatus() { return { running: this.running, uptime: this.running ? Date.now() - (this.components.get('messageBus')?.startTime || Date.now()) : 0, components: Array.from(this.components.values()), config: { apiHost: this.config.apiHost, apiPort: this.config.apiPort, dashboardHost: this.config.dashboardHost, dashboardPort: this.config.dashboardPort, developmentMode: this.config.developmentMode, } }; } /** * Get message bus instance */ getMessageBus() { return this.messageBus; } /** * Get agent hub instance */ getAgentHub() { return this.agentHub; } /** * Execute a skill on the agent hub */ async executeSkill(skillName, context, args) { if (!this.agentHub) { throw new Error('Agent hub not available'); } return this.agentHub.execute(skillName, context, args); } /** * Send a message via the message bus */ async sendMessage(channel, message) { if (!this.messageBus) { throw new Error('Message bus not available'); } return this.messageBus.publish(channel, message); } /** * Check if the system is healthy */ async healthCheck() { const componentHealth = Array.from(this.components.values()).map(comp => ({ name: comp.name, status: comp.status, healthy: comp.status === 'running' })); const allHealthy = componentHealth.every(comp => comp.healthy); return { status: allHealthy && this.running ? 'healthy' : 'unhealthy', details: { running: this.running, components: componentHealth, uptime: this.getSystemStatus().uptime } }; } } /** * Create a launcher from configuration */ export function createLauncher(config) { return new UnifiedLauncher(config); } /** * Create launcher from command line arguments */ export function createLauncherFromArgs(args) { const config = { redisUrl: args.redisUrl, apiHost: args.host, apiPort: args.port, enableMessageBus: !args.noMessageBus, enableAgentHub: !args.noAgentHub, enableWatchMode: !args.noWatchMode && !args.watchOnly, enableMetrics: !args.noMetrics, enableDashboard: !args.noDashboard, developmentMode: args.dev, debugLogging: args.debug || args.dev, dashboardHost: args.dashboardHost, dashboardPort: args.dashboardPort, }; return new UnifiedLauncher(config); } //# sourceMappingURL=unifiedLauncher.js.map