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
JavaScript
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