Skip to content

Commit 3028029

Browse files
committed
docs(ai-chat): add changelog entry for May 7 chat-prerelease
Covers the chat.history read primitives (getPendingToolCalls, getResolvedToolCalls, extractNewToolResults, getChain, findMessage) and the HITL addToolOutput id-regen fix.
1 parent 4f66238 commit 3028029

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

docs/ai-chat/changelog.mdx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,50 @@ sidebarTitle: "Changelog"
44
description: "Pre-release updates for AI chat agents."
55
---
66

7+
<Update label="May 7, 2026" description="0.0.0-chat-prerelease-20260507131256" tags={["SDK"]}>
8+
9+
## `chat.history` read primitives for HITL flows
10+
11+
Customers building human-in-the-loop tools were re-implementing the same accumulator-walking logic to figure out which tool calls were pending, which were resolved, and which results in an incoming wire message were actually new. Lifted into the SDK as five new methods on `chat.history`:
12+
13+
| Method | Description |
14+
|---|---|
15+
| `chat.history.getPendingToolCalls()` | Tool calls on the most recent assistant message in `input-available` state — gates fresh user turns during HITL. |
16+
| `chat.history.getResolvedToolCalls()` | All tool calls in the chain in `output-available` or `output-error` state. |
17+
| `chat.history.extractNewToolResults(message)` | Tool results in `message` whose `toolCallId` is not already resolved on the chain. Most useful in `hydrateMessages` against an incoming wire message, before the runtime merges it. |
18+
| `chat.history.getChain()` | Same as `chat.history.all()` — alias that reads better alongside parent-aware APIs. |
19+
| `chat.history.findMessage(messageId)` | Direct lookup; `undefined` if absent. |
20+
21+
```ts
22+
// Refuse a regenerate while a tool call is awaiting an answer
23+
onAction: async ({ action }) => {
24+
if (action.type === "regenerate") {
25+
if (chat.history.getPendingToolCalls().length > 0) return;
26+
chat.history.slice(0, -1);
27+
}
28+
},
29+
30+
// Side-effect once per net-new tool result on incoming wire messages
31+
hydrateMessages: async ({ incomingMessages }) => {
32+
for (const msg of incomingMessages) {
33+
for (const r of chat.history.extractNewToolResults(msg)) {
34+
await auditLog.record({ id: r.toolCallId, output: r.output, errorText: r.errorText });
35+
}
36+
}
37+
return incomingMessages;
38+
},
39+
```
40+
41+
See [`chat.history`](/ai-chat/backend#chat-history) and [Human-in-the-loop](/ai-chat/patterns/human-in-the-loop).
42+
43+
## Fix: HITL `addToolOutput` resume preserves the assistant message id
44+
45+
In some HITL flows the AI SDK regenerated the assistant message id when the user's `addToolOutput` answer round-tripped back to the agent. The fresh id slipped past the runtime's id-based merge, leaving the resolved tool answer attached to a sibling assistant message instead of the head, which broke downstream dedup and rendered the tool answer twice.
46+
47+
The runtime now records `toolCallId → head messageId` whenever an assistant with tool parts lands in the accumulator and rewrites the incoming id back via that map before the merge. Customers who had a content-match workaround for this can drop it.
48+
49+
</Update>
50+
751
<Update label="May 6, 2026" description="0.0.0-chat-prerelease-20260506093419" tags={["SDK", "Breaking"]}>
852

953
## `chat.agent` actions are no longer turns

0 commit comments

Comments
 (0)