Skip to content

fix: preserve anthropic assistant ids in tool-first streams#480

Open
shaked-frame wants to merge 6 commits into
TanStack:mainfrom
shaked-frame:fix/anthropic-tool-parent-message-id
Open

fix: preserve anthropic assistant ids in tool-first streams#480
shaked-frame wants to merge 6 commits into
TanStack:mainfrom
shaked-frame:fix/anthropic-tool-parent-message-id

Conversation

@shaked-frame

@shaked-frame shaked-frame commented Apr 20, 2026

Copy link
Copy Markdown

Summary

  • add parentMessageId to Anthropic TOOL_CALL_START chunks so tool-first streams bind to the eventual assistant message id immediately
  • add an Anthropic adapter regression covering tool-first streams and asserting the tool call chunk references the same assistant message id as TEXT_MESSAGE_START
  • add a stream processor regression showing tool-first flows with parentMessageId preserve a single assistant message instead of creating a temporary local id

fixes #477

Verification

  • pnpm exec vitest run packages/typescript/ai/tests/stream-processor.test.ts
  • pnpm test:lib -- --runInBand in packages/typescript/ai
    • the new stream-processor regression passed
    • the package command still hits existing workspace resolution issues (@tanstack/ai-event-client, examples/ts-svelte-chat/.svelte-kit/tsconfig.json)
  • pnpm test:lib -- --runInBand in packages/typescript/ai-anthropic
    • blocked by an existing @tanstack/ai package-entry resolution issue before the adapter test file runs

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed an issue where streaming tool calls would create temporary message IDs that changed mid-stream. Tool calls are now properly bound to their parent assistant messages, ensuring stable message IDs throughout streaming across all supported providers.

@coderabbitai

coderabbitai Bot commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds a changeset file documenting a fix for AG-UI stream handling. Tool call start events now include parentMessageId to bind them to the stable assistant message id, preventing temporary message creation and mid-stream id changes when tool calls arrive before text across all provider adapters.

Changes

Stream Stability Fix Release Notes

Layer / File(s) Summary
Stream stability fix changelog
.changeset/tool-first-parent-message-id.md
Changeset documenting the fix where TOOL_CALL_START events now carry parentMessageId tied to the per-stream assistant message id, preventing StreamProcessor from creating temporary messages that would later cause mid-stream id changes. The fix spans all adapters: Anthropic, OpenAI (Responses and Chat Completions), OpenRouter, Gemini (including experimental text-interactions), and Ollama.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Suggested reviewers

  • tombeckenham
  • AlemTuzlak

Poem

A bunny's stream now flows so true,
Tool calls bind to parent, tried and new,
No id remounts in mid-stream glow—
Stability fixed from head to toe! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers key aspects but lacks evidence of PR checklist completion and changeset generation verification, which the template requires. Clarify whether the Contributing guide steps were followed and confirm changeset was created as required by the template checklist.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main fix: preserving Anthropic assistant IDs in tool-first streams, which is the primary objective of this changeset.
Linked Issues check ✅ Passed The PR successfully addresses issue #477 by implementing parentMessageId on TOOL_CALL_START chunks, stabilizing assistant message IDs through tool-first streams as required.
Out of Scope Changes check ✅ Passed All changes focus on fixing the tool-first stream ID stability issue in issue #477; the changeset entry documents the fix without introducing unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@shaked-frame shaked-frame force-pushed the fix/anthropic-tool-parent-message-id branch from 05bd931 to 7c7945c Compare June 1, 2026 09:38
@shaked-frame

Copy link
Copy Markdown
Author

rebased and pushed after resolving conflicts

tombeckenham added a commit to shaked-frame/ai that referenced this pull request Jun 10, 2026
Bind TOOL_CALL_START to the stream's stable assistant message id via
AG-UI `parentMessageId` in every text adapter, so a tool call that
streams before any text no longer forces the assistant message id to
change mid-stream (which destabilises UIMessage.id and can remount the
message subtree in useChat). Fixes TanStack#477.

Extends TanStack#480 (Anthropic only) to:
- @tanstack/openai-base (Responses + Chat Completions)
- @tanstack/ai-openrouter (Responses + Chat Completions)
- @tanstack/ai-gemini (text + experimental text-interactions)
- @tanstack/ai-ollama

Adds a tool-first regression per adapter asserting the TOOL_CALL_START
parentMessageId equals the TEXT_MESSAGE_START messageId.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bind TOOL_CALL_START to the stream's stable assistant message id via
AG-UI `parentMessageId` in every text adapter, so a tool call that
streams before any text no longer forces the assistant message id to
change mid-stream (which destabilises UIMessage.id and can remount the
message subtree in useChat). Fixes TanStack#477.

Extends TanStack#480 (Anthropic only) to:
- @tanstack/openai-base (Responses + Chat Completions)
- @tanstack/ai-openrouter (Responses + Chat Completions)
- @tanstack/ai-gemini (text + experimental text-interactions)
- @tanstack/ai-ollama

Adds a tool-first regression per adapter asserting the TOOL_CALL_START
parentMessageId equals the TEXT_MESSAGE_START messageId.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tombeckenham tombeckenham force-pushed the fix/anthropic-tool-parent-message-id branch from d24a601 to b79fc03 Compare June 10, 2026 07:18

@tombeckenham tombeckenham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. I fixed it in the rest of the adpaters as well.

@tombeckenham tombeckenham requested a review from AlemTuzlak June 10, 2026 07:34
@nx-cloud

nx-cloud Bot commented Jun 10, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit b79fc03

Command Status Duration Result
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-10 07:34:57 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jun 10, 2026

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@480

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@480

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@480

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@480

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@480

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@480

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@480

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@480

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@480

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@480

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@480

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@480

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@480

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@480

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@480

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@480

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@480

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@480

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@480

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@480

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@480

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@480

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@480

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@480

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@480

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@480

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@480

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@480

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@480

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@480

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@480

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@480

commit: b79fc03

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useChat assistant message.id changes mid-stream for Anthropic tool-first responses

3 participants