fix(ai): restore StructuredOutputStream assignability to AsyncIterable<StreamChunk>#587
Conversation
…e<StreamChunk>
`StructuredOutputStartEvent`, `StructuredOutputCompleteEvent`,
`ApprovalRequestedEvent`, and `ToolInputAvailableEvent` declared their shape
with `extends Omit<CustomEvent, 'name' | 'value'>`. Because `CustomEvent` is
inferred from a zod `passthrough` schema it carries a `[k: string]: unknown`
index signature, and `Omit` on a type with a `string` index signature
collapses every surviving property to `unknown` — including `type: 'CUSTOM'`.
That broke union assignability against `AGUIEvent`/`StreamChunk`, so
`toServerSentEventsResponse(stream)` failed to typecheck against streams
returned by `chat({ outputSchema, stream: true })`.
Switched to `extends CustomEvent` with refined `name`/`value` (a narrower
type for an inherited property is allowed), preserves `type: 'CUSTOM'` and
the existing discriminated-narrowing patterns.
Added a type-level regression test asserting
`StructuredOutputStream<T>` matches `AsyncIterable<StreamChunk>`.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR restores TypeScript assignability for ChangesEvent Type Assignability Fix
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 Changeset Version Preview1 package(s) bumped directly, 18 bumped as dependents. 🟩 Patch bumps
|
|
View your CI Pipeline Execution ↗ for commit 69916a8
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
Summary
StructuredOutputStartEvent,StructuredOutputCompleteEvent,ApprovalRequestedEvent, andToolInputAvailableEventdeclared their shape withextends Omit<CustomEvent, 'name' | 'value'>. BecauseCustomEventis inferred from a zodpassthroughschema, it carries a[k: string]: unknownindex signature, andOmiton a type with astringindex signature collapses every surviving property tounknown— includingtype: 'CUSTOM'. That broke union assignability againstAGUIEvent/StreamChunk, sotoServerSentEventsResponse(stream)failed to typecheck against the stream returned bychat({ outputSchema, stream: true })— the exact pattern documented indocs/structured-outputs/streaming.md.extends CustomEventwith refinedname/value(narrower types of inherited properties are allowed).type: 'CUSTOM'is preserved and existing discriminated-narrowing (chunk.type === 'CUSTOM' && chunk.name === '...') continues to give a fully typedvalue.chat-result-types.test.tsthat pinsStructuredOutputStream<T>toAsyncIterable<StreamChunk>so this can't silently regress again.Reproducer
Before the fix:
After the fix this compiles. Runtime behaviour is unchanged — this is a pure type-level bug fix.
Test plan
pnpm test:lib— 832 tests pass in@tanstack/aipnpm test:types— 32 projects passStructuredOutputStream<Person>⊂AsyncIterable<StreamChunk>structured-output.complete,structured-output.start,approval-requested,tool-input-availableSummary by CodeRabbit
Bug Fixes
Tests