Skip to content

Commit a353339

Browse files
committed
docs(ai-chat): session-in-event-id header on turn-complete control records
Document the new sibling header that rides on every turn-complete record carrying the agent's committed-consume cursor on .in. The header is what lets the next worker boot seed its .in SSE subscribe past already-processed user messages without a wall-clock-derived dedup cutoff. - client-protocol: new row in the turn-complete header table; updated records-on-session-out summary; example block shows the third header - changelog: short paragraph under "what changed on the wire" framing the cursor as the seq-based replacement for the prior timestamp cutoff, with an explicit "custom transports should ignore" note
1 parent 64d223d commit a353339

2 files changed

Lines changed: 5 additions & 1 deletion

File tree

docs/ai-chat/changelog.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ body: ""
3131

3232
The control event names ("turn-complete", "upgrade-required") are unchanged conceptually — they just moved from `chunk.type` into a `trigger-control` header value. Body is always empty; metadata that previously rode in the chunk (e.g. `publicAccessToken`) now rides on sibling headers.
3333

34+
`turn-complete` also picks up a new optional sibling header — `["session-in-event-id", "<seq>"]` — carrying the agent's committed-consume cursor on `.in` as of this turn. It's an agent-internal contract that lets the next worker boot seed its `.in` SSE subscription past already-processed user messages, without relying on a wall-clock-derived dedup cutoff. Custom transports should ignore the header; it has no client-side meaning.
35+
3436
### Custom transport implementers
3537

3638
Built-in SDK transports (`TriggerChatTransport`, `AgentChat`) handle this transparently — `onTurnComplete` fires the same way with the same payload. Custom transports filtering on `chunk.type === "trigger:turn-complete"` need to switch to the header-based filter:

docs/ai-chat/client-protocol.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ Three kinds of records can arrive on the wire. They all share the `batch` envelo
369369
| Kind | `headers[0][0]` | `headers` carries | `body` |
370370
| --- | --- | --- | --- |
371371
| **Data record** | _empty array or non-empty name_ | (currently none from the agent) | JSON envelope `{"data": UIMessageChunk, "id": <partId>}` |
372-
| **Trigger control record** | `"trigger-control"` | `["trigger-control", <subtype>]` plus subtype-specific siblings (e.g. `["public-access-token", <jwt>]` on `turn-complete`) | empty string |
372+
| **Trigger control record** | `"trigger-control"` | `["trigger-control", <subtype>]` plus subtype-specific siblings (e.g. `["public-access-token", <jwt>]` and `["session-in-event-id", <seq>]` on `turn-complete`) | empty string |
373373
| **S2 command record** | `""` (empty name) | `["", "<op>"]` (currently `"trim"`) | opaque bytes — S2-interpreted |
374374
375375
**Uniform filter rule for custom readers:**
@@ -583,13 +583,15 @@ Signals that the agent's turn is finished — stop reading and wait for user inp
583583
headers:
584584
["trigger-control", "turn-complete"]
585585
["public-access-token", "eyJ..."] // optional, refreshed JWT
586+
["session-in-event-id", "42"] // optional, agent-internal resume cursor
586587
body: ""
587588
```
588589
589590
| Header | Description |
590591
| --- | --- |
591592
| `trigger-control: turn-complete` | Always present on this record. |
592593
| `public-access-token: <jwt>` (optional) | A refreshed JWT with the same session + run scopes. If present, replace your stored token. |
594+
| `session-in-event-id: <seq>` (optional) | Internal cursor used by the agent to resume `.in` across worker boots without replaying already-processed user messages. Custom transports should ignore this header — it carries no client-side meaning. |
593595
594596
When you receive this record:
595597
1. Update `publicAccessToken` if one is included on the headers.

0 commit comments

Comments
 (0)