All docs

Developer experience

Streaming and WebSocket events

Real-time stream of token deltas, tool calls, artifacts, and run updates over WebSocket.

Streaming and WebSocket events

The streaming surface emits 17 event types over a Socket.IO connection: token deltas, tool call lifecycles, artifact creates, BGO run updates, errors, finishes. The chat panel and @platosdev/client consume the same stream; an event you see in the dashboard is the same event the SDK forwards.

What it is

Two long-lived connections share the streaming protocol:

  • The chat stream connection (/agents/{agentId}/chat/stream) streams events for an in-flight turn.
  • The connections gateway (/connections) streams entity-side events plus tool sync.

Event types include:

  • text-delta: incremental token output.
  • tool-call-start, tool-call-args, tool-call-result, tool-call-error.
  • artifact-created, artifact-updated.
  • step-start, step-finish: per-step lifecycle (multi-step turns).
  • memory-write, memory-recall-result.
  • run-update: from agent-tool-block.task.ts; surfaces BGO progress in the chat stream.
  • approval-pending, approval-resolved.
  • error, finish.

tool-sync-ws.service.ts:130-135, 281-284 carries the load-bearing early-message-buffer invariant. The buffer listener is attached before the async auth handshake; once auth completes, frames are replayed in order. Removing the buffer drops events during the connect race. Do not violate.

Why it matters

Latency is the difference between "this feels live" and "this feels like a form submit". A turn that takes 3 seconds total but streams the first token at 200ms feels faster than a 1.5-second turn that lands as a single block. The 17-event protocol covers every meaningful state change, so a UI can render rich progress without polling.

The same event stream powers BGO progress. A run_update event mid-stream tells the chat panel "the BGO is at 40%"; the user sees a progress bar without a separate WebSocket. This was the PPR-25/26 unification.

How to use it

Consume from @platosdev/client

const stream = await platos.threads.stream({ threadId, message: "Hi" });

for await (const event of stream) {
  switch (event.type) {
    case "text-delta": process.stdout.write(event.delta); break;
    case "tool-call-start": console.log("tool", event.tool); break;
    case "artifact-created": handleArtifact(event); break;
    case "finish": stream.close(); break;
  }
}

Consume from the browser

The @platosdev/client ships a React hook:

import { usePlatosStream } from "@platosdev/client/react";

function Chat({ threadId }: { threadId: string }) {
  const { events, send } = usePlatosStream({ threadId });
  // events is the running event log; render as you wish.
}

Reconnect

The SDK reconnects automatically with exponential backoff. The reconnect resumes from the last event id; events emitted during the disconnect are replayed up to a 30-second buffer. Beyond 30 seconds, the SDK starts a fresh stream and re-fetches the message history.

Consume from a custom client

Use socket.io-client directly:

const socket = io("https://platos.example.com", {
  path: "/streaming",
  auth: { token: sessionToken },
});

socket.on("text-delta", (e) => console.log(e.delta));
socket.on("finish", () => socket.disconnect());

Common pitfalls

  • The early-message-buffer in tool-sync-ws.service.ts is the entity-side equivalent. Frames are buffered before auth and replayed after; do not bypass.
  • A chat client that only handles text-delta and finish will miss tool calls, artifacts, BGO updates, approvals. The 17 event types are not optional; handle every one or your users see the agent "stuck" mid-turn.
  • The Socket.IO transport prefers WebSocket but falls back to long-polling; on networks with WebSocket inspection, fallback latency increases. Configure transports: ["websocket"] if your network allows.
  • Event ordering is preserved within a turn but not across turns. Two simultaneous turns on different threads can interleave; switch on event.threadId if you multiplex.
  • SDKs: the consumer SDK that wraps the stream.
  • Chat and Postman mode: the dashboard consumer.
  • Tools: the tool-call event lifecycle plus the early-message buffer.

Talk to Platos

Powered by the Platos runtime

Powered by Platos →