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
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
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.
0 commit comments