Skip to main content

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

GET /rooms/:code/events

Path Parameters

code
string
required
Room code

Response

Status: 200 OK Content-Type: text/event-stream SSE stream with room events.

Connection Headers

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"}

clientId
string
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}

id
string
Room ID
code
string
Room code
name
string
Room name
hostId
string
Creator’s UUID
createdAt
number
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}

id
string
Participant ID
nickname
string
Display name
model
string
Model name
endpoint
string
API endpoint URL
specs
object
Machine specifications
config
object
Generation config
status
string
“online”, “busy”, or “offline”
joinedAt
number
Join timestamp
lastSeen
number
Last health check timestamp

participant:left

Broadcast to room when a participant leaves.
event: participant:left
data: {"participantId":"550e8400-e29b-41d4-a716-446655440000"}

participantId
string
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"}

participantId
string
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"}

participantId
string
ID of the participant handling the request
model
string
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"}

participantId
string
ID of the participant that failed
error
string
Error message

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:
  1. Hub automatically removes the client from the SSE client map
  2. No participant:left event is broadcast (SSE clients are observers, not participants)

Hub Restart

When the hub restarts:
  1. All SSE connections are closed
  2. All rooms and participants are cleared from memory
  3. 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.

Build docs developers (and LLMs) love