src — gateway
src — gateway
The src/gateway module provides a robust, centralized WebSocket gateway designed for multi-client communication. It acts as a unified control plane, enabling real-time interaction between various clients such as agents, tools, and user interfaces. Inspired by established WebSocket gateway patterns, it offers features like session management, authentication, message routing, and agent registration.
This module is critical for enabling the real-time, interactive nature of the system, allowing different components to communicate and coordinate seamlessly.
Core Concepts
Before diving into the components, understanding the fundamental concepts is key:
GatewayMessage: The standard format for all communication through the gateway. Each message has atype, a uniqueid, an optionalsessionId, apayload(typed based ontype), and atimestamp.ClientState: Represents the internal state of a connected client, including its authentication status, associated sessions, connection timestamps, and metadata.- Session: A logical grouping of clients. Messages can be broadcast to all clients within a specific session, facilitating collaborative or multi-participant interactions.
- Agent: A specialized client (e.g., an AI agent, a tool runner) that registers its capabilities with the gateway. The gateway can then route requests to appropriate agents.
Architecture Overview
The gateway module employs an abstract base server (GatewayServer) and a concrete WebSocket implementation (WebSocketGateway). This separation allows for potential future transport layers while keeping core logic consistent.
classDiagram
direction LR
class EventEmitter {
+emit()
+on()
}
class GatewayServer {
-config: GatewayConfig
-clients: Map<string, ClientState>
-sessions: SessionManager
-handlers: Map<GatewayMessageType, MessageHandler>
+constructor()
+start()
+stop()
+registerHandler()
#onConnect()
#onDisconnect()
#onMessage()
#sendToClient()
+broadcastToSession()
}
class WebSocketGateway {
-wsConfig: WebSocketTransportConfig
-wss: WebSocketServer
-httpServer: HttpServer
-wsClients: Map<string, WebSocketClient>
+constructor()
+start()
+stop()
-handleConnection()
-handleMessage()
#sendToClient()
+broadcast()
+broadcastToSession()
}
class SessionManager {
-sessions: Map<string, Session>
+createSession()
+addClient()
+removeClient()
+getClients()
+cleanup()
}
class AgentRegistry {
-agents: Map<string, RegisteredAgent>
-gateway: WebSocketGateway
+constructor()
+register()
+updateStatus()
+getAgent()
+findByCapability()
}
EventEmitter <|-- GatewayServer
GatewayServer <|-- WebSocketGateway
GatewayServer "1" *-- "1" SessionManager : manages
WebSocketGateway "1" *-- "1" AgentRegistry : uses
GatewayServer(src/gateway/server.ts): The abstract base class. It defines the core logic for managing client states, sessions, message handlers, and authentication. It's transport-agnostic, meaning it doesn't care how messages are sent or received, only what to do with them.WebSocketGateway(src/gateway/ws-transport.ts): ExtendsGatewayServerto provide a concrete implementation using WebSockets. It handles the low-level WebSocket server setup, connection management, message serialization/deserialization, and heartbeat mechanisms.SessionManager(src/gateway/server.ts): A utility class used byGatewayServerto manage logical sessions, allowing clients to join and leave, and facilitating message broadcasting within a session.AgentRegistry(src/gateway/ws-transport.ts): Manages the registration and lifecycle of various agents (e.g., AI models, tool executors) connected via theWebSocketGateway.
Key Components
1. src/gateway/types.ts
This file defines all the essential types and interfaces used throughout the gateway module:
GatewayMessageType: A union type listing all supported message types (e.g.,'connect','auth','chat','session_create','error').GatewayMessage: The generic interface for all messages, encapsulatingtype,id,sessionId,payload, andtimestamp.- Payload Interfaces: Specific interfaces for the
payloadof each message type, such asConnectPayload,AuthPayload,ChatPayload,ErrorPayload, etc. ClientState: Describes the internal state maintained for each connected client.GatewayConfig&WebSocketTransportConfig: Configuration interfaces for the base gateway and its WebSocket-specific extensions, including authentication modes, ports, timeouts, and security settings.DEFAULT_GATEWAY_CONFIG&DEFAULT_WS_CONFIG: Default configuration objects for easy setup.GatewayEvents: Defines the custom events emitted by theGatewayServer(e.g.,client:connect,session:create).
2. src/gateway/server.ts
This file contains the core, transport-agnostic logic of the gateway.
createMessage(type, payload, sessionId?)
A utility function to construct a standard GatewayMessage object, assigning a unique ID and timestamp.
createErrorMessage(code, message, details?)
A specialized utility to create an error type GatewayMessage with a structured error payload.
SessionManager Class
Manages the lifecycle and client membership of sessions.
createSession(sessionId, options?): Initializes a new session.getSession(sessionId): Retrieves session details.addClient(sessionId, clientId): Adds a client to a specified session.removeClient(sessionId, clientId): Removes a client from a session.getClients(sessionId): Returns a list of client IDs in a session.cleanup(): Removes sessions that no longer have any connected clients.getAllSessions(): Returns details for all active sessions.
GatewayServer Class
The abstract base class for the gateway server. It extends EventEmitter to allow for event-driven communication within the server.
constructor(config?): Initializes the server with provided or default configuration and sets up default message handlers.setupDefaultHandlers(): Registers handlers for common message types likeping,connect,auth,session_create,session_join,session_leave,session_patch, andpresence.connect: Handles the initial client handshake, providingHelloOkPayloadwith gateway status and presence snapshot. Includes logic for skipping local TLS pairing.auth: Processes authentication requests based onauthMode(token, password, or none). CallsvalidateTokenfor custom token validation.- Session Handlers: Manage client membership in sessions via the
SessionManager. validateToken(token): A protected method intended for override. By default, it accepts all tokens if authentication is disabled. Developers should override this for custom token validation logic.registerHandler(type, handler): Allows external modules to register custom handlers for specificGatewayMessageTypes.onConnect(clientId): Protected method called when a new client connects. InitializesClientStateand emitsclient:connect.onDisconnect(clientId): Protected method called when a client disconnects. Cleans up client's session memberships and emitsclient:disconnect.onMessage(clientId, message, send): Protected method that processes incomingGatewayMessages. It updates client activity, enforces authentication, and dispatches the message to the appropriate registered handler. If no specific handler is found, it emits a genericmessageevent.broadcastToSession(sessionId, message, excludeClientId?): Sends a message to all clients within a specified session, optionally excluding one client.sendToClient(clientId, message): An abstract protected method that must be implemented by transport-specific subclasses (e.g.,WebSocketGateway) to send a message to a single client.start()/stop(): Lifecycle methods to start and stop the server, including managing the internal ping interval for client liveness and session cleanup.getBindAddress(): Resolves the network interface to bind to based onGatewayConfig.bindmode.getStats(): Provides runtime statistics about connected clients and active sessions.
Singleton Access
getGatewayServer(config?): Returns a singleton instance ofGatewayServer, creating it if it doesn't exist.resetGatewayServer(): Stops and clears the singletonGatewayServerinstance.
3. src/gateway/ws-transport.ts
This file implements the WebSocket-specific transport layer for the gateway.
WebSocketTransportConfig & DEFAULT_WS_CONFIG
Extends GatewayConfig with WebSocket-specific settings like path, perMessageDeflate, maxPayload, heartbeatInterval, clientTimeout, and corsOrigins.
isOriginAllowed(origin, allowedOrigins)
A security utility function to validate incoming WebSocket connection origins against a list of allowed patterns, supporting wildcards. This is crucial for preventing Cross-Site WebSocket Hijacking (CSWH).
WebSocketGateway Class
Extends GatewayServer to provide a concrete WebSocket implementation.
constructor(config?): Initializes with WebSocket-specific configuration.start(): Overrides the basestart()method.- Creates an
http.Serverfor the WebSocket server and a basic HTTP health check endpoint. - Initializes
WebSocketServer(wss) with configured path, compression, and payload limits. - Implements
verifyClientfor CORS origin validation usingisOriginAllowedand handles stripping proxy headers from untrusted sources (GHSA-5wcw-8jjv-m286). - Sets up
connectionanderrorlisteners for thewss. - Starts the WebSocket heartbeat mechanism.
- Listens on the configured port and host.
- Calls
super.start()to activate baseGatewayServerlogic. stop(): Overrides the basestop()method.- Stops the WebSocket heartbeat.
- Closes all active client WebSocket connections.
- Shuts down the
WebSocketServerandhttp.Server. - Calls
super.stop(). handleConnection(socket, request): Manages a new incoming WebSocket connection.- Generates a unique
clientId. - Creates a
WebSocketClientobject, storing theWebSocketinstance andClientState. - Calls
this.onConnect(clientId)(fromGatewayServer). - Registers listeners for
message,pong,close, anderrorevents on thesocket. - Sends an initial
session_infomessage to the client. handleMessage(client, data): Processes raw incoming WebSocket data.- Updates client activity and
isAlivestatus. - Parses the JSON message.
- Performs basic message validation (type, id, size).
- Delegates to
this.onMessage(client.id, message, send)(fromGatewayServer). handleDisconnect(client, code, reason): Handles client disconnection.- Removes the client from
wsClients. - Calls
this.onDisconnect(client.id)(fromGatewayServer). - Emits
client:disconnect:detailswith additional context. sendToClient(clientId, message): Implements the abstract method fromGatewayServer. Serializes theGatewayMessageto JSON and sends it over the client's WebSocket.broadcast(message, filter?): Sends a message to all connected WebSocket clients, optionally filtered.broadcastToSession(sessionId, message, excludeClientId?): Overrides the base method for WebSocket-specific session broadcasting, iterating throughwsClientsand checking session membership.startHeartbeat()/stopHeartbeat(): Manages a periodic interval to sendpingmessages to clients and terminate unresponsive connections, ensuring client liveness.getWebSocketStats(): Provides WebSocket-specific runtime statistics.getClientInfo(clientId): Retrieves detailed information about a specific connected WebSocket client.kickClient(clientId, reason?): Forcibly disconnects a client.
AgentRegistry Class
Manages the registration and status of agents connected to the WebSocketGateway.
constructor(gateway): Takes aWebSocketGatewayinstance and listens forclient:disconnectevents to automatically update agent statuses.register(agent): Registers a new agent with its capabilities.unregister(agentId): Removes an agent from the registry.updateStatus(agentId, status, clientId?): Updates an agent's online status and associated client ID.getAgent(agentId): Retrieves an agent by ID.getAllAgents()/getOnlineAgents(): Returns lists of agents.findByCapability(capability): Finds agents that possess a specific capability (e.g.,'chat','tools:code_interpreter').findByType(type): Finds agents of a specific type (e.g.,'pi','webchat').broadcastToAgents(message, filter?): Sends a message to all online agents, optionally filtered.getStats(): Provides statistics about registered agents (total, online, by type).
Control Messages
ControlMessageType: Defines types for internal gateway coordination messages (e.g.,agent_register,route_request).ControlMessage: Interface for internal control messages.createControlMessage(type, source, payload, target?): Utility to create control messages.
Singleton Access
getWebSocketGateway(config?): Returns a singleton instance ofWebSocketGateway, creating it if it doesn't exist.resetWebSocketGateway(): Stops and clears the singletonWebSocketGatewayinstance.
Message Flow Example: Client Connect and Auth
- Client Connect:
- A client establishes a WebSocket connection to
ws://.: /ws WebSocketGateway.handleConnectionis triggered.- A
clientIdis generated, and aWebSocketClientobject is created. GatewayServer.onConnect(clientId)is called, initializing theClientStatefor this client.- A
session_infomessage is sent to the client, indicating connection status and if authentication is required. - The client then sends a
connectmessage (e.g.,createMessage('connect', { deviceId: '...', role: 'control' })). WebSocketGateway.handleMessagereceives and parses it, then callsGatewayServer.onMessage.GatewayServer.onMessagedispatches to theconnecthandler (set up insetupDefaultHandlers).- The
connecthandler updates client metadata and sends ahello_okmessage back to the client with gateway uptime, presence, and auth requirements.
- Client Authentication:
- If
authRequiredwas true, the client sends anauthmessage (e.g.,createMessage('auth', { token: 'my-api-key' })). GatewayServer.onMessagedispatches to theauthhandler.- The
authhandler checksGatewayConfig.authMode. - If
passwordmode, it validatespayload.passwordagainstconfig.authPassword. - If
tokenmode (default), it callsthis.validateToken(payload.token). - If authentication succeeds,
ClientState.authenticatedis set totrue,userIdis assigned, andclient:authis emitted. Anauth_successmessage is sent to the client. - If authentication fails, an
errormessage is sent to the client.
Extensibility
- Custom Message Handlers: Developers can register their own
MessageHandlerfunctions usinggateway.registerHandler('my_custom_type', async (clientId, message, send) => { ... })to extend gateway functionality. - Custom Authentication: Override the
validateTokenmethod in a subclass ofGatewayServer(orWebSocketGateway) to integrate with custom authentication systems (e.g., JWT validation, database lookups). - Agent Integration: Agents can register themselves with the
AgentRegistryto advertise their capabilities, allowing the gateway to route specific tasks or queries to them.
Security Considerations
- Authentication: The gateway supports token, password, or no authentication. It's crucial to enable and configure authentication (
authEnabled: true,authMode: 'token') in production environments. - CORS Origin Validation:
WebSocketGatewayincludesisOriginAllowedto validate theOriginheader of incoming WebSocket connections against a configurable list ofcorsOrigins. This prevents unauthorized domains from connecting. A warning is logged ifcorsOriginsis*and authentication is enabled, highlighting a potential security risk. - Trusted Proxies: The
WebSocketGatewayhandlesx-forwarded-*headers. If a connection comes from an untrusted IP and includes these headers, they are stripped to prevent IP spoofing or origin manipulation (GHSA-5wcw-8jjv-m286). ConfiguretrustedProxiesto list your legitimate proxy servers. - Message Size Limits:
maxMessageSizeprevents denial-of-service attacks via excessively large messages. - Connection Timeouts:
connectionTimeoutMsandclientTimeout(for WebSocket) help manage inactive connections and free up resources.
Connection to the Rest of the Codebase
The src/gateway module serves as the central nervous system for real-time communication. Other modules would interact with it by:
- Clients: Connecting to the
WebSocketGatewayand sending/receivingGatewayMessages. - Agents/Tools: Registering their capabilities with the
AgentRegistryand listening for specificGatewayMessagetypes (e.g.,tool_start,chat). - Core Logic: Registering custom
MessageHandlers with theGatewayServerto process application-specific messages (e.g., handlingchatmessages, orchestrating tool calls). - UI/Frontend: Using the gateway to send user input and receive real-time updates (chat streams, tool progress, presence).
By providing a well-defined message format and a robust, extensible server, the src/gateway module ensures that all components can communicate effectively and securely in a real-time environment.