Connect to Events
Establish a Server-Sent Events (SSE) connection to receive real-time updates for a room.
curl -N http://localhost:3000/rooms/ABC123/events
Endpoint
Path Parameters
Response
Status: 200 OK
Content-Type: text/event-stream
SSE stream with room events.
Content-Type : text/event-stream
Cache-Control : no-cache
Connection : keep-alive
Access-Control-Allow-Origin : *
Initial Connection Event
On connection, the hub sends a connected event:
event: connected
data: {"clientId":"550e8400-e29b-41d4-a716-446655440000"}
Unique client connection ID (UUID)
Event Types
room:created
Broadcast globally when a new room is created.
event: room:created
data: {"id":"V1StGXR8_Z5jdHi6B-myT","code":"ABC123","name":"My Team Room","hostId":"550e8400-e29b-41d4-a716-446655440000","createdAt":1709409600000}
Creation timestamp (milliseconds)
participant:joined
Broadcast to room when a participant joins.
event: participant:joined
data: {"id":"550e8400-e29b-41d4-a716-446655440000","nickname":"Alice","model":"llama3.2:3b","endpoint":"http://localhost:11434","specs":{},"config":{},"status":"online","joinedAt":1709409600000,"lastSeen":1709409600000}
“online”, “busy”, or “offline”
Last health check timestamp
participant:left
Broadcast to room when a participant leaves.
event: participant:left
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000"}
ID of the participant who left
participant:offline
Broadcast to room when a participant is marked offline due to missed health checks.
Participants are marked offline after 30 seconds without a health check (3 missed intervals).
event: participant:offline
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000"}
ID of the offline participant
llm:request
Broadcast to room when a chat completion request is routed to a participant.
event: llm:request
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000","model":"llama3.2:3b"}
ID of the participant handling the request
Model specified in the original request
llm:complete
Not currently implemented in hub.ts. Reserved for future use.
Would broadcast to room when a chat completion finishes successfully.
llm:error
Broadcast to room when a chat completion request fails.
event: llm:error
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000","error":"Connection refused"}
ID of the participant that failed
Event Filtering
Clients connected to /rooms/:code/events receive:
Room-specific events : participant:joined, participant:left, participant:offline, llm:request, llm:error
Global events : room:created (all clients)
Clients do not receive events from other rooms.
Example: JavaScript Client
const eventSource = new EventSource ( 'http://localhost:3000/rooms/ABC123/events' );
// Connection established
eventSource . addEventListener ( 'connected' , ( event ) => {
const data = JSON . parse ( event . data );
console . log ( 'Connected:' , data . clientId );
});
// Participant joined
eventSource . addEventListener ( 'participant:joined' , ( event ) => {
const participant = JSON . parse ( event . data );
console . log ( 'Participant joined:' , participant . nickname );
});
// Participant left
eventSource . addEventListener ( 'participant:left' , ( event ) => {
const data = JSON . parse ( event . data );
console . log ( 'Participant left:' , data . participantId );
});
// Participant offline
eventSource . addEventListener ( 'participant:offline' , ( event ) => {
const data = JSON . parse ( event . data );
console . log ( 'Participant offline:' , data . participantId );
});
// LLM request started
eventSource . addEventListener ( 'llm:request' , ( event ) => {
const data = JSON . parse ( event . data );
console . log ( 'LLM request:' , data . participantId , data . model );
});
// LLM request failed
eventSource . addEventListener ( 'llm:error' , ( event ) => {
const data = JSON . parse ( event . data );
console . error ( 'LLM error:' , data . participantId , data . error );
});
// Room created (global)
eventSource . addEventListener ( 'room:created' , ( event ) => {
const room = JSON . parse ( event . data );
console . log ( 'Room created:' , room . name , room . code );
});
// Connection error
eventSource . onerror = ( error ) => {
console . error ( 'SSE error:' , error );
eventSource . close ();
};
Example: curl
curl -N http://localhost:3000/rooms/ABC123/events
Output:
event: connected
data: {"clientId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890"}
event: participant:joined
data: {"id":"550e8400-e29b-41d4-a716-446655440000","nickname":"Alice","model":"llama3.2:3b","endpoint":"http://localhost:11434","specs":{},"config":{},"status":"online","joinedAt":1709409600000,"lastSeen":1709409600000}
event: llm:request
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000","model":"*"}
...
Connection Management
Client Disconnect
When a client disconnects:
Hub automatically removes the client from the SSE client map
No participant:left event is broadcast (SSE clients are observers, not participants)
Hub Restart
When the hub restarts:
All SSE connections are closed
All rooms and participants are cleared from memory
Clients must reconnect and participants must rejoin
Cleanup
The hub closes all SSE connections when calling Hub.close():
const hub = createHub ();
// Later...
hub . close (); // Closes all SSE connections, stops health checks, clears rooms
Error Response
Status: 404{
"error" : "Room not found"
}
SSE connection is rejected if the room doesn’t exist.