Skip to content

Fix Vercel AI SDK adapter bugs from code review

45709e6
Select commit
Loading
Failed to load commit list.
Open

Fix Vercel AI SDK adapter bugs from code review #132

Fix Vercel AI SDK adapter bugs from code review
45709e6
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed May 11, 2026 in 11m 24s

Code review found 3 important issues

Found 5 candidates, confirmed 3. See review comments for details.

Details

Severity Count
🔴 Important 3
🟡 Nit 0
🟣 Pre-existing 0
Severity File:Line Issue
🔴 Important adapter/vercelaisdk/uimessagestream/handler.go:344 handleContentPart leaves reasoning span open before tool-input chunks
🔴 Important adapter/vercelaisdk/uimessagestream/handler.go:554-555 Duplicate finish/[DONE] on iterator error in StreamModelWithTools
🔴 Important adapter/vercelaisdk/uimessagestream/handler.go:513-514 Unpaired finish-step emitted on maxTurns exhaustion

Annotations

Check failure on line 344 in adapter/vercelaisdk/uimessagestream/handler.go

See this annotation in the file changed.

@claude claude / Claude Code Review

handleContentPart leaves reasoning span open before tool-input chunks

The PartToolRequest case in handleContentPart only calls endTextAndAdvance() and leaves any open reasoning span open while tool-input-start/tool-input-available chunks are emitted; reasoning-end arrives later (on next text or in closeSpans), out of order on the wire. The mirror in handleToolTurnPart already closes both spans correctly — add sw.endReasoning() before sw.endTextAndAdvance() in handler.go:343 to fix.

Check failure on line 555 in adapter/vercelaisdk/uimessagestream/handler.go

See this annotation in the file changed.

@claude claude / Claude Code Review

Duplicate finish/[DONE] on iterator error in StreamModelWithTools

On iterator error inside `streamToolTurn`, the function writes the full terminal sequence (`error`, `finish-step`, `finish`, `[DONE]`) and returns `finishReasonError`, but the caller `StreamModelWithTools` then unconditionally writes ANOTHER `finish` chunk and ANOTHER `[DONE]` because `len(toolRequests)==0` is true. The result is a duplicated terminal sequence `...finish, [DONE], finish, [DONE]` — an SSE protocol violation reachable on any network blip mid-stream during a tool-calling turn. Eith

Check failure on line 514 in adapter/vercelaisdk/uimessagestream/handler.go

See this annotation in the file changed.

@claude claude / Claude Code Review

Unpaired finish-step emitted on maxTurns exhaustion

On maxTurns exhaustion, the trailing `finish-step` chunk at handler.go:514 has no preceding `start-step`, violating the UI Message Stream protocol's matched-pair requirement. Each turn already emits its own paired `finish-step` via `writeToolTurnEnd`, so this extra one is unpaired. Either omit the trailing `finish-step`, or emit a `start-step` before the post-loop tool outputs to properly wrap them in a step.