Skip to content

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

Open
shaked-frame wants to merge 2 commits intoTanStack: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 2 commits intoTanStack:mainfrom
shaked-frame:fix/anthropic-tool-parent-message-id

Conversation

@shaked-frame
Copy link
Copy Markdown

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

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

  • Bug Fixes

    • Ensure tool call events in streamed chats include the parent message ID so tool calls correctly link to their originating message.
    • Improve handling of tool-first streaming flows where tool data arrives before text content.
  • Tests

    • Added tests covering tool-first flows and verifying message identity, ordering, and parent/child relationships.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a878a9c9-5acc-4ea7-aae7-e748dddd919e

📥 Commits

Reviewing files that changed from the base of the PR and between dc23cbf and 4884561.

📒 Files selected for processing (1)
  • packages/typescript/ai-anthropic/src/adapters/text.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/typescript/ai-anthropic/src/adapters/text.ts

📝 Walkthrough

Walkthrough

Anthropic adapter now attaches parentMessageId (the originating messageId) to emitted TOOL_CALL_START events in tool-first streaming flows; two new tests verify that adapter emission and downstream stream processing preserve and use this server-provided message id.

Changes

Cohort / File(s) Summary
Anthropic Text Adapter
packages/typescript/ai-anthropic/src/adapters/text.ts
Adds parentMessageId: messageId to the TOOL_CALL_START event payload in two code paths: on first input_json_delta for streaming tool_use, and on content_block_stop when a tool_use block ends before args streaming begins.
Anthropic Adapter Tests
packages/typescript/ai-anthropic/tests/anthropic-adapter.test.ts
New stream-processing test mocking a tool-first Anthropic response; asserts the emitted TOOL_CALL_START chunk contains parentMessageId equal to the TEXT_MESSAGE_START messageId.
Stream Processor Tests
packages/typescript/ai/tests/stream-processor.test.ts
New test ensures that when TOOL_CALL_START includes parentMessageId, the resulting assistant UIMessage uses that server-provided id and that parts are ordered and populated correctly (tool-call then text).

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I hop through streams where messages start,
I stitch IDs so no parts drift apart,
Tools jump first, then text will flow,
Parent IDs keep the message whole — hooray, let's go! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description includes clear summary of changes and references the linked issue (#477), but is missing the required 🎯 Changes section structure and checklist items from the template. Complete the PR description using the provided template: add structured 🎯 Changes section, check off the checklist items, and confirm changeset generation for release impact.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding parentMessageId preservation to Anthropic tool-first streams, which directly addresses the linked issue about message id instability.
Linked Issues check ✅ Passed The code changes directly address issue #477 by adding parentMessageId to TOOL_CALL_START chunks, enabling tool-first streams to bind to the eventual assistant message id, and include regression tests validating the fix.
Out of Scope Changes check ✅ Passed All changes are focused and scoped: modifications to the Anthropic adapter to emit parentMessageId, plus two targeted regression tests validating the fix—no extraneous changes detected.
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.

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

1 participant