Skip to content

Fix StreamEndEvent.Error regression and StreamResetEvent gap in tool …

67b2772
Select commit
Loading
Failed to load commit list.
Open

Fix Vercel AI SDK adapter bugs from code review #132

Fix StreamEndEvent.Error regression and StreamResetEvent gap in tool …
67b2772
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed May 11, 2026 in 14m 0s

Code review found 2 important issues

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

Details

Severity Count
🔴 Important 2
🟡 Nit 0
🟣 Pre-existing 1
Severity File:Line Issue
🔴 Important adapter/vercelaisdk/uimessagestream/handler.go:579-587 StreamResetEvent leaves orphan tool-input chunks with no resolution
🔴 Important adapter/vercelaisdk/uimessagestream/handler.go:579-587 streamToolTurn switch missing llm.ErrorEvent case (asymmetric with StreamModel)
🟣 Pre-existing adapter/vercelaisdk/uimessagestream/handler.go:524 streamToolTurn drops ResponseFormat, Options, and Metadata on every turn

Annotations

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

See this annotation in the file changed.

@claude claude / Claude Code Review

StreamResetEvent leaves orphan tool-input chunks with no resolution

The new StreamResetEvent case at handler.go:579-588 clears the in-memory toolRequests slice (so executeTools won't re-fire them), but the tool-input-start and tool-input-available SSE chunks for those tool requests have already been written to the wire by handleToolTurnPart at handler.go:619-625. The result is an orphaned tool-input-available with no matching tool-output-available or tool-output-error, violating the Vercel UI Message Stream pairing invariant and leaving useChat clients with a pe

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

See this annotation in the file changed.

@claude claude / Claude Code Review

streamToolTurn switch missing llm.ErrorEvent case (asymmetric with StreamModel)

streamToolTurn's event switch is missing a `case llm.ErrorEvent`, leaving it asymmetric with StreamModel. StreamModel handles ErrorEvent at handler.go:451-456 (logs warning, emits an error chunk to the wire), but in tool-calling mode any provider yielding a recoverable ErrorEvent (openai/model.go:156, google/model.go:168) is silently dropped via Go's type-switch fall-through. Fix is a one-case mirror: `case llm.ErrorEvent: logger.Warn(...); _ = ew.WriteChunk(Chunk{"type":"error","errorText":"An 

Check notice on line 524 in adapter/vercelaisdk/uimessagestream/handler.go

See this annotation in the file changed.

@claude claude / Claude Code Review

streamToolTurn drops ResponseFormat, Options, and Metadata on every turn

**Pre-existing** (from #131): Inside `streamToolTurn`, the per-iteration `iterReq` (handler.go:549-553) is constructed by copying only `Messages`, `Tools`, and `ToolChoice` from the caller's `req` — silently dropping `ResponseFormat`, `Options`, and `Metadata` on every model call inside the loop. Programmatic callers of the exported `StreamModelWithTools` who set `Options` (e.g. `anthropic.Options{MaxTokens: 1000, Temperature: 0.1}`) see them honored on turn 1 only — turns 2..N use provider defa