Skip to content

WebSocket

Cortex provides a WebSocket endpoint for real-time event delivery. Events include agent status changes, task updates, swarm activity, and chat messages.

Connection

wss://api.cortex.acrobi.com/api/ws?token=<JWT>

The connection requires a valid JWT access token passed as a query parameter. The server validates the token and extracts the user ID for channel scoping.

Connection Example (JavaScript)

javascript
const ws = new WebSocket(`wss://api.cortex.acrobi.com/api/ws?token=${accessToken}`);

ws.onopen = () => {
  console.log('Connected to Cortex WebSocket');
  // Subscribe to channels
  ws.send(JSON.stringify({ type: 'subscribe', channelId: 'agent:my-agent' }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log('Event:', data.type, data.payload);
};

ws.onclose = (event) => {
  console.log('Disconnected:', event.code, event.reason);
  // Reconnect with exponential backoff
};

Channel Subscriptions

After connecting, subscribe to specific channels to receive relevant events:

json
{ "type": "subscribe", "channelId": "agent:my-coder-agent" }

The server confirms with:

json
{ "type": "subscribed", "channelId": "agent:my-coder-agent" }

Channel Types

Channel PatternEvents Received
agent:<name>Status changes, execution updates for a specific agent
swarm:<id>Swarm phase changes, agent assignments, task progress
project:<id>All activity within a project
org:<id>Organization-wide events
task:<id>Updates to a specific task

Event Types

Agent Events

EventTriggerPayload
agent.spawnedAgent execution started{ agentId, agentName, taskId, timestamp }
agent.completedAgent execution finished{ agentId, agentName, taskId, result, duration, timestamp }
agent.failedAgent execution errored{ agentId, agentName, taskId, error, timestamp }
agent.statusAgent status changed (error/blocked only){ agentId, agentName, status, message, timestamp }

Task Events

EventTriggerPayload
task.createdNew task created{ taskId, title, projectId, timestamp }
task.status_changedTask status updated{ taskId, oldStatus, newStatus, timestamp }
task.updatedTask details modified{ taskId, changes, timestamp }
task.deletedTask removed{ taskId, timestamp }

Swarm/Chief Events

EventTriggerPayload
chief.plan.createdChief created execution plan{ planId, tasks, timestamp }
chief.task.assignedChief assigned task to agent{ taskId, agentName, timestamp }
chief.task.progressTask progress update{ taskId, progress, message, timestamp }
swarm.phase.startedSwarm entered new phase{ swarmId, phase, timestamp }
swarm.phase.completedSwarm phase finished{ swarmId, phase, results, timestamp }

Quality Gate Events

EventTriggerPayload
gate.passedQuality gate passed{ taskId, gate, timestamp }
gate.failedQuality gate failed{ taskId, gate, reason, timestamp }

Chat Events

EventTriggerPayload
chat.messageNew chat message{ messageId, agentId, content, timestamp }

Architecture

The WebSocket system runs on a single Cloudflare Durable Object (WebSocketRoom):

  • Zero persistent storage — all connection state is in-memory (Map<WebSocket, Session>)
  • Channel-scoped subscriptions — clients only receive events they subscribed to
  • Fire-and-forget broadcasts — events are pushed without delivery confirmation
  • Cost: ~$1.50/month at 1,000 concurrent connections

When a connection closes (client disconnect, error, or DO hibernation), all session state is lost. Clients should implement reconnection with exponential backoff.

For Desktop Users

The Electron desktop app includes an embedded local WebSocket server. Desktop users get real-time events locally without cloud WebSocket connections.

Reconnection Strategy

javascript
let reconnectDelay = 1000; // Start at 1s
const maxDelay = 30000;    // Cap at 30s

function connect() {
  const ws = new WebSocket(url);
  
  ws.onopen = () => {
    reconnectDelay = 1000; // Reset on success
    // Re-subscribe to channels
  };
  
  ws.onclose = () => {
    setTimeout(() => {
      reconnectDelay = Math.min(reconnectDelay * 2, maxDelay);
      connect();
    }, reconnectDelay);
  };
}

Scaling

See Scaling Architecture for how Cortex handles 50,000+ concurrent connections through per-org DO sharding and the desktop local-first approach.

Built by Acrobi