---
title: "SDK Streaming & Events"
description: "Stream chat responses and event log updates via Server-Sent Events."
section: "Libraries"
group: "SDK"
---

# SDK Streaming & Events

Two things stream: **chat** (per-run, server-sent events) and **the workspace event log** (persistent WebSocket).

## Chat streaming

`client.chat(agentOrSwarmId, body)` returns an async generator of [`SSEEvent`](/types/index) objects. Iterate directly.

```ts
import Aeontel from "@aeontel/sdk";

const client = new Aeontel("sec_...");
const stream = await client.chat("agt_...", {
  messages: [{ role: "user", content: "Summarize this week's runs" }],
});

for await (const event of stream) {
  if (event.event === "text") {
    process.stdout.write(event.data);
  } else if (event.event === "tool_call") {
    console.log("\n→ tool:", event.data);
  }
}
```

Each event carries `{ event, data, id? }`. The `event` field maps to the SSE event type emitted by the run worker — `text`, `tool_call`, `tool_result`, `error`, `done`. Break out of the loop to close the connection.

## Workspace event stream

`client.events.stream({ workspaceId })` opens a WebSocket to the workspace event hub and emits every event as it's persisted.

```ts
const stream = client.events.stream({ workspaceId: "wsp_..." });

stream.on("run.completed", (event) => console.log("run done", event));
stream.on("agent.*", (event) => console.log("agent change", event));

// Later
stream.close();
```

Patterns support globs (`agent.*`). Call `stream.close()` when you're done.

Under the hood this is the same stream that powers `useEventStream` in `@aeontel/react` — the React hook adds query-cache invalidation on top.

## Reconnecting

Chat streams are cancelled when the async generator returns or you `break` out of the loop. `EventStream` reconnects automatically with backoff; use `stream.close()` to stop it for good.
