// 🐝 TELEPATHY: NeuralBus.ts // Ansvarlig for 0ms kommunikation mellem agenter og frontend. // Real-time event streaming via WebSockets import { Server as SocketIOServer, Socket } from 'socket.io'; import { Server as HttpServer } from 'http'; export interface ThoughtEvent { agent: string; timestamp: number; thought: string; context: Record; type?: 'INFO' | 'WARNING' | 'ERROR' | 'SUCCESS' | 'THOUGHT'; } export interface AgentInfo { id: string; name: string; connectedAt: Date; lastActivity: Date; } export class NeuralBus { private static instance: NeuralBus; private io: SocketIOServer | null = null; private connectedAgents = new Map(); private thoughtHistory: ThoughtEvent[] = []; private maxHistorySize = 1000; private constructor() { console.log('🐝 [HIVE] Neural Bus Initializing...'); } public static getInstance(): NeuralBus { if (!NeuralBus.instance) { NeuralBus.instance = new NeuralBus(); } return NeuralBus.instance; } public attach(httpServer: HttpServer): void { this.io = new SocketIOServer(httpServer, { cors: { origin: "*", methods: ["GET", "POST"] }, pingTimeout: 60000, pingInterval: 25000 }); console.log('🐝 [HIVE] Neural Telepathy Bus Online'); this.io.on('connection', (socket: Socket) => { const agentName = socket.handshake.query.agent as string || `Agent-${socket.id.slice(0, 6)}`; // Register agent this.connectedAgents.set(socket.id, { id: socket.id, name: agentName, connectedAt: new Date(), lastActivity: new Date() }); console.log(`🐝 [HIVE] Agent Connected: ${agentName} (${socket.id})`); // Notify all agents of new connection this.io?.emit('AGENT_JOINED', { agent: agentName, totalAgents: this.connectedAgents.size }); // Handle incoming thoughts socket.on('THOUGHT', (data: Partial) => { const thought: ThoughtEvent = { agent: agentName, timestamp: Date.now(), thought: data.thought || '', context: data.context || {}, type: data.type || 'THOUGHT' }; this.recordThought(thought); socket.broadcast.emit('THOUGHT_STREAM', thought); // Update activity const agent = this.connectedAgents.get(socket.id); if (agent) agent.lastActivity = new Date(); }); // Handle queries socket.on('QUERY', async (data: { type: string; payload: unknown }, callback) => { const response = await this.handleQuery(data.type, data.payload); if (callback) callback(response); }); // Handle disconnection socket.on('disconnect', () => { const agent = this.connectedAgents.get(socket.id); this.connectedAgents.delete(socket.id); console.log(`🐝 [HIVE] Agent Disconnected: ${agent?.name || socket.id}`); this.io?.emit('AGENT_LEFT', { agent: agent?.name, totalAgents: this.connectedAgents.size }); }); }); } private recordThought(thought: ThoughtEvent): void { this.thoughtHistory.push(thought); // Trim history if too large if (this.thoughtHistory.length > this.maxHistorySize) { this.thoughtHistory = this.thoughtHistory.slice(-this.maxHistorySize); } } private async handleQuery(type: string, payload: unknown): Promise { switch (type) { case 'GET_AGENTS': return Array.from(this.connectedAgents.values()); case 'GET_HISTORY': const count = (payload as { count?: number })?.count || 50; return this.thoughtHistory.slice(-count); case 'GET_STATS': return this.getStats(); default: return { error: 'Unknown query type' }; } } // Public API for emitting thoughts from server-side public emitThought(agent: string, thought: string, context: Record = {}, type: ThoughtEvent['type'] = 'INFO'): void { if (this.io) { const event: ThoughtEvent = { agent, timestamp: Date.now(), thought, context, type }; this.recordThought(event); this.io.emit('THOUGHT_STREAM', event); } } public emitToAgent(agentId: string, event: string, data: unknown): void { if (this.io) { this.io.to(agentId).emit(event, data); } } public broadcast(event: string, data: unknown): void { if (this.io) { this.io.emit(event, data); } } public getStats() { return { connectedAgents: this.connectedAgents.size, agents: Array.from(this.connectedAgents.values()).map(a => ({ name: a.name, connectedAt: a.connectedAt, lastActivity: a.lastActivity })), thoughtsRecorded: this.thoughtHistory.length, isOnline: this.io !== null }; } public getRecentThoughts(count: number = 50): ThoughtEvent[] { return this.thoughtHistory.slice(-count); } } export const neuralBus = NeuralBus.getInstance();