From fb9b495772ba27d5c79e6784718393dfeab48728 Mon Sep 17 00:00:00 2001 From: GeGeeWhy Date: Sun, 12 Apr 2026 00:03:05 +0800 Subject: [PATCH] fix: Emit trigger chunk as delta when it carries data during block transitions When a new content block starts, the trigger chunk was previously discarded. This caused data loss when the provider (e.g. Gemini) returns complete function-call arguments in the same chunk as the function name. Now the trigger chunk is appended to the queue if its type is content_block_delta, preserving the data in both sync and async streams. --- .../adapters/streaming_iterator.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py index 6bddad09f21..2675709090c 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py @@ -129,8 +129,6 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): if should_start_new_block and not self.sent_content_block_finish: # Queue the sequence: content_block_stop -> content_block_start - # The trigger chunk itself is not emitted as a delta since the - # content_block_start already carries the relevant information. self.chunk_queue.append( { "type": "content_block_stop", @@ -144,6 +142,11 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): "content_block": self.current_content_block_start, } ) + # Also emit the trigger chunk as a delta when it carries + # data (e.g. Gemini returns complete function-call arguments + # in the same chunk that contains the function name). + if processed_chunk.get("type") == "content_block_delta": + self.chunk_queue.append(processed_chunk) self.sent_content_block_finish = False return self.chunk_queue.popleft() @@ -305,8 +308,6 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): if not self.queued_usage_chunk: if should_start_new_block and not self.sent_content_block_finish: # Queue the sequence: content_block_stop -> content_block_start - # The trigger chunk itself is not emitted as a delta since the - # content_block_start already carries the relevant information. # 1. Stop current content block self.chunk_queue.append( @@ -325,6 +326,12 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): } ) + # 3. Also emit the trigger chunk as a delta when it + # carries data (e.g. Gemini returns complete function-call + # arguments in the same chunk that contains the function name). + if processed_chunk.get("type") == "content_block_delta": + self.chunk_queue.append(processed_chunk) + # Reset state for new block self.sent_content_block_finish = False