From a4d4b197e5a1710afe4ee002579312ee184452c2 Mon Sep 17 00:00:00 2001 From: yen0304 Date: Tue, 9 Jun 2026 10:33:44 +0800 Subject: [PATCH] fix(streaming): accumulate compaction_delta content and add error context for JSON parsing Two fixes for streaming event accumulation: 1. Beta streaming: compaction_delta handler replaced content instead of accumulating it. If compaction content is streamed across multiple deltas, all but the last chunk were lost. The TypeScript SDK correctly concatenates: `(content || '') + delta.content`. This aligns the Python SDK with that behavior and with the pattern used by text_delta and thinking_delta in the same file. 2. GA streaming: from_json() for input_json_delta lacked error handling that the Beta path already has. When the model produces malformed JSON, GA users got a raw ValueError with no context. Now surfaces the same helpful message as the Beta path. --- src/anthropic/lib/streaming/_beta_messages.py | 2 +- src/anthropic/lib/streaming/_messages.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/anthropic/lib/streaming/_beta_messages.py b/src/anthropic/lib/streaming/_beta_messages.py index 7736b6bd5..a4a16da17 100644 --- a/src/anthropic/lib/streaming/_beta_messages.py +++ b/src/anthropic/lib/streaming/_beta_messages.py @@ -525,7 +525,7 @@ def accumulate_event( content.signature = event.delta.signature elif event.delta.type == "compaction_delta": if content.type == "compaction": - content.content = event.delta.content + content.content = (content.content or "") + (event.delta.content or "") content.encrypted_content = event.delta.encrypted_content else: # we only want exhaustive checking for linters, not at runtime diff --git a/src/anthropic/lib/streaming/_messages.py b/src/anthropic/lib/streaming/_messages.py index 5c0da9992..004182e6e 100644 --- a/src/anthropic/lib/streaming/_messages.py +++ b/src/anthropic/lib/streaming/_messages.py @@ -477,7 +477,12 @@ def accumulate_event( json_buf += bytes(event.delta.partial_json, "utf-8") if json_buf: - content.input = from_json(json_buf, partial_mode=True) + try: + content.input = from_json(json_buf, partial_mode=True) + except ValueError as e: + raise ValueError( + f"Unable to parse tool parameter JSON from model. Please retry your request or adjust your prompt. Error: {e}. JSON: {json_buf.decode('utf-8')}" + ) from e setattr(content, JSON_BUF_PROPERTY, json_buf) elif event.delta.type == "citations_delta":