fix(anthropic): silently drop trailing chunks after usage; remove dead _polyfill_result key

- streaming_iterator: in sync __next__, after the usage chunk has been
  merged and emitted, silently consume any trailing provider events
  via 'continue' instead of forwarding them through the queue. Trailing
  chunks would translate to content_block_delta or message_delta and
  violate Anthropic SSE ordering after the final message_delta. The
  async __anext__ already drops these via 'if not self.queued_usage_chunk:'
  gating, so this aligns sync and async behavior.

- handler: drop unused '_polyfill_result' from ANTHROPIC_ONLY_REQUEST_KEYS.
  PolyfillResult is passed as an explicit arg to the adapter methods, never
  through extra_kwargs, so the entry was dead code.

Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
Cursor Agent 2026-05-26 13:13:26 +00:00
parent 868fa20913
commit b8fd48ae01
No known key found for this signature in database
2 changed files with 8 additions and 6 deletions

View file

@ -37,7 +37,7 @@ if TYPE_CHECKING:
# Anthropic-only keys already mapped by the translator; strip on extra_kwargs re-merge.
ANTHROPIC_ONLY_REQUEST_KEYS: frozenset[str] = frozenset(
{"output_config", "context_management", "_polyfill_result"}
{"output_config", "context_management"}
)

View file

@ -208,11 +208,13 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
return self.chunk_queue.popleft()
if self.queued_usage_chunk:
# Usage has already been merged + emitted. Pass any trailing
# provider events through directly instead of silently
# dropping them in the for-loop body.
self.chunk_queue.append(processed_chunk)
return self.chunk_queue.popleft()
# Usage has already been merged + emitted. Any trailing
# provider events would violate Anthropic SSE ordering
# (no chunks may follow the final ``message_delta``), so
# silently drop them — matches the async ``__anext__``
# behavior where the block-handling logic is gated on
# ``not self.queued_usage_chunk``.
continue
if should_start_new_block and not self.sent_content_block_finish:
# Queue the sequence: content_block_stop -> content_block_start