fix(anthropic): preserve all streaming content block types#1695
Open
Stephen Belanger (Qard) wants to merge 2 commits intomainfrom
Open
fix(anthropic): preserve all streaming content block types#1695Stephen Belanger (Qard) wants to merge 2 commits intomainfrom
Stephen Belanger (Qard) wants to merge 2 commits intomainfrom
Conversation
, #1621) - Extend `AnthropicOutputContentBlock` with `thinking` and `citations` variants - Add `AnthropicCitation` interface to vendor types - Add `thinking_delta`, `citations_delta`, and `signature_delta` to stream event delta union - Replace flat `string[]` accumulator with structured `{ textDeltas, citations }` per block - Handle `thinking_delta` events (accumulated like text) - Handle `citations_delta` events (accumulated separately and merged into finalized text block) - Make `finalizeContentBlock()` forward-compatible: unknown block types are now preserved as-is instead of being silently deleted, fixing `server_tool_use`, `web_search_tool_result` and any future Anthropic content block types - Keep structured output when any text block carries citations - Add unit tests for all new block types and mixed content scenarios Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TypeScript cannot narrow a discriminated union member when a catch-all
{ type: string } overlaps with specific literal types. Use runtime
'in' checks + casts to safely extract fields from known delta types
while still allowing unknown future delta types to fall through.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
Luca Forstner (lforst)
left a comment
There was a problem hiding this comment.
I would honestly love some more e2e test coverage for this because we gain version coverage!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes three related issues where the Anthropic streaming aggregation silently dropped content block types it didn't recognize:
server_tool_use,web_search_tool_result) dropped in streaming instrumentation #1660 —server_tool_useandweb_search_tool_resultblocks dropped in streaming instrumentationcitationsandcitations_deltalost in streaming instrumentation #1661 —citationsandcitations_deltaevents lost in streaming instrumentationthinking,thinking_delta) not capturedRoot cause
finalizeContentBlock()had a catch-all that deleted any block type that wasn'ttextortool_use. Additionally, thecontent_block_deltahandler only recognizedtext_deltaandinput_json_delta, sothinking_deltaandcitations_deltaevents were ignored.Changes
anthropic.ts): Addthinkingblock type,citations?on text blocks,AnthropicCitationinterface, and new delta union members (thinking_delta,citations_delta,signature_delta)string[]with structured{ textDeltas, citations }per blockthinking_delta→ accumulate totextDeltas;citations_delta→ accumulate tocitations;signature_delta→ ignorefinalizeContentBlock(): Handlethinkingblocks (jointextDeltasintothinkingfield); merge citations onto finalized text blocks; default case now preserves unknown blocks as-is instead of deleting them{ role, content }form when any text block has citationsserver_tool_use,web_search_tool_result, unknown future types, and mixed contentTest plan
cd js && pnpm test— all 845 unit tests passpnpm run lint— no new errorspnpm run formatting— no formatting issues🤖 Generated with Claude Code