Spaces:
Paused
Paused
| // π 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<string, unknown>; | |
| 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<string, AgentInfo>(); | |
| 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<ThoughtEvent>) => { | |
| 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<unknown> { | |
| 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<string, unknown> = {}, 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(); | |