From 1579752e06c13ba37f43a2c01679149bca31bb4e Mon Sep 17 00:00:00 2001 From: Leslie Cheng Date: Tue, 7 Oct 2025 20:53:38 -0700 Subject: [PATCH] Implement fix --- .../adapters/streaming_iterator.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 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 306bcd9bb2..bcfbee9fc3 100644 --- a/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py +++ b/litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py @@ -7,7 +7,7 @@ from collections import deque from typing import TYPE_CHECKING, Any, AsyncIterator, Iterator, Literal, Optional from litellm import verbose_logger -from litellm.types.llms.anthropic import UsageDelta +from litellm.types.llms.anthropic import UsageDelta, ToolUseBlock from litellm.types.utils import AdapterCompletionStreamWrapper if TYPE_CHECKING: @@ -270,7 +270,6 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): processed_chunk.get("delta", {}).get("stop_reason") is not None ): - self.holding_stop_reason_chunk = processed_chunk else: self.chunk_queue.append(processed_chunk) @@ -380,4 +379,11 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper): self.current_content_block_start = content_block_start return True + # For parallel tool calls, we'll necessarily have a new content block + # if we get a function name since it signals a new tool call + if block_type == "tool_use" and content_block_start.get("name"): + self.current_content_block_type = block_type + self.current_content_block_start = content_block_start + return True + return False