fix(anthropic): skip content-less keepalive chunks in streaming bridge

A chunk with empty choices and no usage carries no content, billing, or
finish reason, so translating it emitted a premature message_delta and
broke Anthropic SSE ordering. Skip such keepalives in both the sync and
async iterator loops; usage-only trailing chunks (choices=[] with usage)
still flow through.
This commit is contained in:
Mateo Wang 2026-06-24 08:06:27 -07:00 • committed by Sameer Kankute
parent dc3a098f6a
commit ac679561f5
No known key found for this signature in database

View file

@ -388,6 +388,9 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
if chunk == "None" or chunk is None:
raise Exception
if not chunk.choices and getattr(chunk, "usage", None) is None:
continue
should_start_new_block = self._should_start_new_content_block(chunk)
if should_start_new_block:
self._increment_content_block_index()
@ -609,6 +612,9 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
if chunk == "None" or chunk is None:
raise Exception
if not chunk.choices and getattr(chunk, "usage", None) is None:
continue
# Check if we need to start a new content block
should_start_new_block = self._should_start_new_content_block(chunk)
if should_start_new_block: