Patch Changes
-
#1412
8fb7c03Thanks @threepointone! - Stop provider tool-call replays from regressing tool part state during continuation streams (#1404).Some providers (notably the OpenAI Responses API) re-emit prior tool calls in continuation streams as a
tool-input-start→tool-input-delta→tool-input-available→tool-output-availablesequence carrying the sametoolCallIdand the sameoutputthe part already holds. The AI SDK'supdateToolPartmutates an existing tool part in place when the toolCallId matches, so a replayedtool-input-startwas clobbering anoutput-availablepart back toinput-streamingon the client and producing the worker warn_applyToolResult: Tool part with toolCallId X not in expected state.Two fixes:
_streamSSEReplynow drops replay tool-input chunks before broadcasting them to clients or storing them for resume, using the new sharedisReplayChunkhelper. The cloned server-side streaming message is never corrupted becauseapplyChunkToPartsis idempotent against existing toolCallIds for these chunk types (also fixed below)._applyToolResultacceptsoutput-availableandoutput-erroras valid starting states for idempotent re-application. A duplicatecf_agent_tool_result(cross-tab re-run, redelivered WS frame, provider replay round-trip) is now a silent no-op rather than a warn + skipped update. The cross-messagetool-output-available/tool-output-errorfallback in_streamSSEReplygets the same tolerance.
_findAndUpdateToolPartskips the SQLite write andMESSAGE_UPDATEDbroadcast when the apply produced no semantic change, so idempotent re-applies don't churn UI on connected tabs.