fix(anthropic adapter): move current_content_block_start to __init__

Move the default TextBlock dict from a class-level attribute to __init__ so
concurrent stream instances don't share the same mutable dict. The class-level
default could be mutated in-place via tool_block['name'] = original_name in
_should_start_new_content_block, leaking state across streams. This mirrors
the existing fix already applied to chunk_queue.

Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
Cursor Agent 2026-05-28 03:25:09 +00:00
parent 3926fd09b6
commit 764c4ba5c8
No known key found for this signature in database

View file

@ -52,10 +52,6 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
holding_stop_reason_chunk: Optional[Any] = None
queued_usage_chunk: bool = False
current_content_block_index: int = 0
current_content_block_start: ContentBlockContentBlockDict = TextBlock(
type="text",
text="",
)
def __init__(
self,
@ -80,6 +76,16 @@ class AnthropicStreamWrapper(AdapterCompletionStreamWrapper):
# here (not at class level) so concurrent streams don't share the same
# deque and corrupt each other's SSE event order.
self.chunk_queue: deque = deque()
# Per-instance default content block. Must be initialized here (not at
# class level) so concurrent streams don't share the same mutable dict
# — `_should_start_new_content_block` mutates `tool_block["name"]` in
# place, which would otherwise leak across streams.
self.current_content_block_start: (
"AnthropicStreamWrapper.ContentBlockContentBlockDict"
) = self.TextBlock(
type="text",
text="",
)
def _merge_usage_into_held_stop_reason_chunk(self, chunk: Any) -> Dict[str, Any]:
"""Merge usage data from ``chunk`` into the held ``message_delta`` chunk.