You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/ai-chat/client-protocol.mdx
+21-6Lines changed: 21 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -258,19 +258,34 @@ Last-Event-ID: 42
258
258
259
259
`SSEStreamSubscription` tracks this automatically via its `lastEventId` option.
260
260
261
-
### `X-Session-Settled` — fast close on idle reconnects
261
+
### `X-Peek-Settled` / `X-Session-Settled` — opt-in fast close on idle reconnects
262
262
263
-
When you reconnect to `.out` and the last record on the session is a `trigger:turn-complete` marker (the agent has finished a turn and is either idle-waiting or exited), the server responds with:
263
+
On **reconnect-on-reload** paths (resuming a chat where nothing may be streaming), send `X-Peek-Settled: 1` as a request header when opening the SSE. When present, the server peeks the tail record of `.out`; if it's `trigger:turn-complete`(agent finished a turn and is idle-waiting or exited), the SSE:
264
264
265
-
- `X-Session-Settled: true` response header
266
-
- A fast SSE close (milliseconds instead of the usual 60s long-poll)
265
+
- Uses `wait=0` internally — drains any residual records and closes in~1s instead of long-polling for 60s.
266
+
- Sets the `X-Session-Settled: true` response header so the client can tell the close is terminal rather than a mid-stream drop.
267
267
268
-
This lets the client distinguish a close that means "nothing is streaming right now" from a normal mid-stream disconnect. Your transport can use this to settle into a "ready" state on page reload without maintaining its own `isStreaming` flag.
268
+
**Do not send `X-Peek-Settled` on the active-send response-stream path.** The peek would race the newly-triggered turn's first chunk — if the agent hasn't written the new turn's first record yet, the peek sees the prior turn's `trigger:turn-complete` and closes the SSE before the response lands on S2. The built-in `TriggerChatTransport.reconnectToStream` sets the header;`sendMessages → subscribeToStream` does not.
Set on `GET /realtime/v1/sessions/:session/out` when the tail record is a terminal chunk (for chat agents: `trigger:turn-complete`). The server uses a short-wait drain instead of long-polling, so the SSE closes in milliseconds rather than up to 60 seconds. Clients can use this to tell a "nothing is streaming right now" close apart from a normal long-poll close.
215
+
On `GET /realtime/v1/sessions/:session/out`, the client can send `X-Peek-Settled: 1` to ask the server to peek the tail record before proxying. If the last chunk on `.out` is a terminal marker (for chat agents: `trigger:turn-complete`), the server:
216
+
217
+
- Uses `wait=0` on the downstream read — drains any residual records and closes in ~1s instead of long-polling for 60s.
218
+
- Sets `X-Session-Settled: true` on the response so the client can tell the close is terminal rather than a normal long-poll cycle.
219
+
220
+
Without `X-Peek-Settled`, the SSE always long-polls (unconditional `wait` from the caller). Clients should only opt in on **reconnect-on-reload** paths — sending the header while a turn is about to be triggered races the new turn's first chunk and would close the SSE before records land.
0 commit comments