TanStack AI version
v0.61.0
Framework/Library version
React v19.2.0
Describe the bug and the steps to reproduce it
StreamProcessor has no handler for TEXT_MESSAGE_CHUNK. The event reaches
the default branch of processChunk and the processor drops it. There is no
warning.
AG-UI defines TEXT_MESSAGE_CHUNK as a short form of the
TEXT_MESSAGE_START / TEXT_MESSAGE_CONTENT / TEXT_MESSAGE_END triad. A
server can send one chunk event instead of three events. The AG-UI spec gives
the expansion job to the client stream transformer.
Two parts of this repository say that the event is supported:
packages/ai/src/types.ts declares TextMessageChunkEvent and puts it in
the AGUIEvent union. That union is the exported StreamChunk type.
packages/ai/src/utilities/spec-event-keys.ts gives the event an allowlist
entry, so stripToSpec keeps messageId, role, delta, and metadata
at the top level.
The runtime does not match this. TOOL_CALL_CHUNK and
REASONING_MESSAGE_CHUNK have the same problem.
Steps to reproduce
live:
https://codesandbox.io/p/sandbox/hvf3mx
Open the sandbox. It needs no API key and makes no network calls. The AG-UI
events are constants in src/App.js.
- Build a
StreamProcessor.
- Send
RUN_STARTED, then one TEXT_MESSAGE_CHUNK with a messageId, a
delta, and a metadata.error, then RUN_ERROR.
- Read
processor.getMessages().
- Do the same again with the explicit triad in place of the chunk event.
Result
The chunk event loses three things that the triad keeps:
| The server sent this, and the client |
TEXT_MESSAGE_CHUNK |
START / CONTENT / END |
shows the text "the run failed" |
lost |
yes |
keeps the message id "msg-1" |
lost |
yes |
keeps metadata.error |
lost |
yes |
The assistant message is not absent. It is empty, and it has a new id:
[{ "id": "msg-1790507900666-2mxf4p", "role": "assistant", "parts": [] }]
RUN_ERROR created that message. The id msg-1 from the server is gone, so a
later event that uses msg-1 cannot find the message.
Expected result
Both forms describe the same turn. Both must produce the same message.
Notes
MESSAGES_SNAPSHOT is a plain messages[], so a reload of a saved thread
shows the correct text. The fault is visible only during a live run. A unit
test that sends the triad cannot find this fault.
processChunk already has the three handlers that an expansion needs. A
case per chunk event can call them, hold the open message id, and close the
message when the id changes or when finalizeStream runs.
Related: #1465 tried this and closed without a merge. #1460 added the AG-UI 1.0
types and left the runtime out of scope.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://codesandbox.io/p/sandbox/hvf3mx
Screenshots or Videos (Optional)
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct
TanStack AI version
v0.61.0
Framework/Library version
React v19.2.0
Describe the bug and the steps to reproduce it
StreamProcessorhas no handler forTEXT_MESSAGE_CHUNK. The event reachesthe
defaultbranch ofprocessChunkand the processor drops it. There is nowarning.
AG-UI defines
TEXT_MESSAGE_CHUNKas a short form of theTEXT_MESSAGE_START/TEXT_MESSAGE_CONTENT/TEXT_MESSAGE_ENDtriad. Aserver can send one chunk event instead of three events. The AG-UI spec gives
the expansion job to the client stream transformer.
Two parts of this repository say that the event is supported:
packages/ai/src/types.tsdeclaresTextMessageChunkEventand puts it inthe
AGUIEventunion. That union is the exportedStreamChunktype.packages/ai/src/utilities/spec-event-keys.tsgives the event an allowlistentry, so
stripToSpeckeepsmessageId,role,delta, andmetadataat the top level.
The runtime does not match this.
TOOL_CALL_CHUNKandREASONING_MESSAGE_CHUNKhave the same problem.Steps to reproduce
live:
https://codesandbox.io/p/sandbox/hvf3mx
Open the sandbox. It needs no API key and makes no network calls. The AG-UI
events are constants in
src/App.js.StreamProcessor.RUN_STARTED, then oneTEXT_MESSAGE_CHUNKwith amessageId, adelta, and ametadata.error, thenRUN_ERROR.processor.getMessages().Result
The chunk event loses three things that the triad keeps:
"the run failed""msg-1"metadata.errorThe assistant message is not absent. It is empty, and it has a new id:
[{ "id": "msg-1790507900666-2mxf4p", "role": "assistant", "parts": [] }]RUN_ERROR created that message. The id msg-1 from the server is gone, so a
later event that uses msg-1 cannot find the message.
Expected result
Both forms describe the same turn. Both must produce the same message.
Notes
MESSAGES_SNAPSHOT is a plain messages[], so a reload of a saved thread
shows the correct text. The fault is visible only during a live run. A unit
test that sends the triad cannot find this fault.
processChunk already has the three handlers that an expansion needs. A
case per chunk event can call them, hold the open message id, and close the
message when the id changes or when finalizeStream runs.
Related: #1465 tried this and closed without a merge. #1460 added the AG-UI 1.0
types and left the runtime out of scope.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://codesandbox.io/p/sandbox/hvf3mx
Screenshots or Videos (Optional)
Do you intend to try to help solve this bug with your own PR?
None
Terms & Code of Conduct