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
docs(ai-chat): bounded session.out + header-form control records
- overview: new paragraph framing session.out as bounded (~one turn at
steady state), trim record after each turn-complete, durable snapshot
for full history, eventually-consistent trim window for resume
- new "Records on session.out" subsection naming the three record kinds
(data, trigger control, S2 command) and the uniform header-based
filter rule custom transports need
- trigger:turn-complete and trigger:upgrade-required rewritten as
header-form control records under the trigger-control namespace;
legacy chunk.type shape called out as the prior wire
- self-contained parser example updated to route the three record kinds
- refreshing-the-token and validation-error blocks updated for the
public-access-token header on turn-complete
- end-to-end curl recipe updated to grep on trigger-control
- resuming-a-stream block spells out single-turn vs multi-turn-away
resume contract
- backend / chat history: cross-reference to records taxonomy and a note
that the agent's accumulator (not session.out) is the source of truth
for full history
- changelog: headline entry for the wire change + dashboard snapshot
read on the Sessions detail page
Copy file name to clipboardExpand all lines: docs/ai-chat/backend.mdx
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -357,6 +357,10 @@ See [Actions](/ai-chat/actions).
357
357
358
358
Imperative API for reading and modifying the accumulated message history. Works from any hook (`onAction`, `onTurnStart`, `onBeforeTurnComplete`, `onTurnComplete`, `hydrateMessages`) or from `run()` and AI SDK tools.
359
359
360
+
<Note>
361
+
The agent's accumulator — not `session.out` — is the source of truth for the full conversation. The `.out` stream is a bounded sliding window (roughly one turn at steady state, see [Records on `session.out`](/ai-chat/client-protocol#records-on-session-out)); the durable history lives in the agent's accumulator and is persisted to S3 between turns for fast next-run boots. `chat.history` reads and mutates that accumulator directly.
362
+
</Note>
363
+
360
364
**Reads.** Synchronous against the current accumulator state.
## `session.out` is now bounded — header-form control records + per-turn trim
10
+
11
+
Long-lived chats were accumulating `session.out` records forever (every turn appends; nothing trimmed). The Sessions dashboard re-streamed the entire history from `seq_num=0` on every page load, and OOM-retry boot scanned the whole stream to find the last turn-complete. Surfaced by Arena AI: "what's the lifetime of these streams?"
12
+
13
+
After this release `session.out` stays roughly **one turn long forever** at steady state. After each `turn-complete`, the agent appends an S2 `trim` command record pointing back to the previous turn-complete's seq_num. Full conversation history continues to live in the durable S3 snapshot, not on the stream. Resume across a single turn boundary still works (the previous `turn-complete` is still on the stream and S2's eventually-consistent trim window gives 10-60s of grace); resume across multiple turns of inactivity falls back to the snapshot.
14
+
15
+
### What changed on the wire
16
+
17
+
`trigger:turn-complete` and `trigger:upgrade-required` are no longer JSON data chunks on `session.out`. They're now **header-form control records** under a uniform `trigger-control` namespace:
18
+
19
+
```
20
+
headers:
21
+
["trigger-control", "turn-complete"]
22
+
["public-access-token", "eyJ..."] // optional, refreshed JWT on turn-complete
23
+
body: ""
24
+
```
25
+
26
+
```
27
+
headers:
28
+
["trigger-control", "upgrade-required"]
29
+
body: ""
30
+
```
31
+
32
+
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.
33
+
34
+
### Custom transport implementers
35
+
36
+
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:
// refresh token from record.headers, end turn, etc.
44
+
}
45
+
```
46
+
47
+
The full uniform filter rule (data records vs control records vs S2 command records like `trim`) is documented at [Records on `session.out`](/ai-chat/client-protocol#records-on-session-out).
48
+
49
+
### Sessions dashboard snapshot read
50
+
51
+
The Sessions detail page in the trigger.dev dashboard now reads the agent's S3 snapshot first via a presigned URL, then SSE-tails from `snapshot.lastOutEventId`. Bandwidth and time-to-first-render are O(unread turns) instead of O(session lifetime). Sessions that registered a `hydrateMessages` hook (which skips snapshot writes) show only the most recent turn — those customers typically have their own DB-backed dashboards.
52
+
53
+
### Breaking surface
54
+
55
+
- Custom transports parsing `chunk.type` for turn-complete / upgrade-required must switch to the `trigger-control` header check.
56
+
- Snapshot consumers should import `ChatSnapshotV1` / `ChatSnapshotV1Schema` from `@trigger.dev/core/v3` (now an exported shape, not SDK-internal).
57
+
58
+
Hard cutover — no compat shim. v4.5 is prerelease.
59
+
60
+
### Docs
61
+
62
+
-[Records on `session.out`](/ai-chat/client-protocol#records-on-session-out) — full filter rule for data / control / command records.
63
+
-[Resuming a stream](/ai-chat/client-protocol#resuming-a-stream) — explicit single-turn vs multi-turn-away semantics.
64
+
-[`turn-complete` control record](/ai-chat/client-protocol#turn-complete-control-record) and [`upgrade-required` control record](/ai-chat/client-protocol#upgrade-required-control-record) — replaced the old chunk-shape docs.
0 commit comments