From a6e20e697ff72e58e12ef71e5aee724b2de71380 Mon Sep 17 00:00:00 2001 From: ashutosh0x Date: Thu, 22 Jan 2026 10:33:26 +0530 Subject: [PATCH 1/4] fix(tests): make mock_aws_config Windows compatible --- tests/lib/test_bedrock.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/lib/test_bedrock.py b/tests/lib/test_bedrock.py index fe62da43..dee7d5c7 100644 --- a/tests/lib/test_bedrock.py +++ b/tests/lib/test_bedrock.py @@ -1,4 +1,5 @@ import re +import os import typing as t import tempfile from typing import TypedDict, cast @@ -53,12 +54,18 @@ def mock_aws_config( profiles: t.List[AwsConfigProfile], monkeypatch: t.Any, ) -> t.Iterable[None]: - with tempfile.NamedTemporaryFile(mode="w+", delete=True) as temp_file: + temp_file = tempfile.NamedTemporaryFile(mode="w+", delete=False) + try: for profile in profiles: temp_file.write(profile_to_ini(profile)) temp_file.flush() + temp_file.close() monkeypatch.setenv("AWS_CONFIG_FILE", str(temp_file.name)) + monkeypatch.setenv("AWS_SDK_LOAD_CONFIG", "1") yield + finally: + if os.path.exists(temp_file.name): + os.unlink(temp_file.name) @pytest.mark.filterwarnings("ignore::DeprecationWarning") From b0cb1ddc9c826a505b7d9ab832883bd901513163 Mon Sep 17 00:00:00 2001 From: ashutosh0x Date: Thu, 22 Jan 2026 11:17:06 +0530 Subject: [PATCH 2/4] feat: add thinking_tokens support to usage models and streaming accumulation --- src/anthropic/lib/streaming/_beta_messages.py | 2 ++ src/anthropic/lib/streaming/_messages.py | 2 ++ src/anthropic/types/beta/beta_message_delta_usage.py | 3 +++ src/anthropic/types/beta/beta_usage.py | 3 +++ src/anthropic/types/message_delta_usage.py | 3 +++ src/anthropic/types/usage.py | 3 +++ 6 files changed, 16 insertions(+) diff --git a/src/anthropic/lib/streaming/_beta_messages.py b/src/anthropic/lib/streaming/_beta_messages.py index a760dcea..0518a777 100644 --- a/src/anthropic/lib/streaming/_beta_messages.py +++ b/src/anthropic/lib/streaming/_beta_messages.py @@ -536,5 +536,7 @@ def accumulate_event( current_snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens if event.usage.server_tool_use is not None: current_snapshot.usage.server_tool_use = event.usage.server_tool_use + if event.usage.thinking_tokens is not None: + current_snapshot.usage.thinking_tokens = event.usage.thinking_tokens return current_snapshot diff --git a/src/anthropic/lib/streaming/_messages.py b/src/anthropic/lib/streaming/_messages.py index 857f9734..355f389c 100644 --- a/src/anthropic/lib/streaming/_messages.py +++ b/src/anthropic/lib/streaming/_messages.py @@ -480,5 +480,7 @@ def accumulate_event( current_snapshot.usage.cache_read_input_tokens = event.usage.cache_read_input_tokens if event.usage.server_tool_use is not None: current_snapshot.usage.server_tool_use = event.usage.server_tool_use + if event.usage.thinking_tokens is not None: + current_snapshot.usage.thinking_tokens = event.usage.thinking_tokens return current_snapshot diff --git a/src/anthropic/types/beta/beta_message_delta_usage.py b/src/anthropic/types/beta/beta_message_delta_usage.py index 11c815d8..6fbea23d 100644 --- a/src/anthropic/types/beta/beta_message_delta_usage.py +++ b/src/anthropic/types/beta/beta_message_delta_usage.py @@ -23,3 +23,6 @@ class BetaMessageDeltaUsage(BaseModel): server_tool_use: Optional[BetaServerToolUsage] = None """The number of server tool requests.""" + + thinking_tokens: Optional[int] = None + """The cumulative number of tokens used for thinking.""" diff --git a/src/anthropic/types/beta/beta_usage.py b/src/anthropic/types/beta/beta_usage.py index 387d24c1..c14524c8 100644 --- a/src/anthropic/types/beta/beta_usage.py +++ b/src/anthropic/types/beta/beta_usage.py @@ -29,5 +29,8 @@ class BetaUsage(BaseModel): server_tool_use: Optional[BetaServerToolUsage] = None """The number of server tool requests.""" + thinking_tokens: Optional[int] = None + """The number of tokens used for thinking.""" + service_tier: Optional[Literal["standard", "priority", "batch"]] = None """If the request used the priority, standard, or batch tier.""" diff --git a/src/anthropic/types/message_delta_usage.py b/src/anthropic/types/message_delta_usage.py index 11bd49d7..3e4dd9dd 100644 --- a/src/anthropic/types/message_delta_usage.py +++ b/src/anthropic/types/message_delta_usage.py @@ -23,3 +23,6 @@ class MessageDeltaUsage(BaseModel): server_tool_use: Optional[ServerToolUsage] = None """The number of server tool requests.""" + + thinking_tokens: Optional[int] = None + """The cumulative number of tokens used for thinking.""" diff --git a/src/anthropic/types/usage.py b/src/anthropic/types/usage.py index 21f7037c..4a14eafb 100644 --- a/src/anthropic/types/usage.py +++ b/src/anthropic/types/usage.py @@ -29,5 +29,8 @@ class Usage(BaseModel): server_tool_use: Optional[ServerToolUsage] = None """The number of server tool requests.""" + thinking_tokens: Optional[int] = None + """The number of tokens used for thinking.""" + service_tier: Optional[Literal["standard", "priority", "batch"]] = None """If the request used the priority, standard, or batch tier.""" From 1e05695f7a0a72e67068c409b41a0f64b6455e43 Mon Sep 17 00:00:00 2001 From: ashutosh0x Date: Thu, 22 Jan 2026 13:00:11 +0530 Subject: [PATCH 3/4] chore: update uv.lock --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index f2064b8c..14f72de9 100644 --- a/uv.lock +++ b/uv.lock @@ -185,7 +185,7 @@ wheels = [ [[package]] name = "anthropic" -version = "0.75.0" +version = "0.76.0" source = { editable = "." } dependencies = [ { name = "anyio" }, From f95a8a46a47e978b5ee0ff3d67cf08394cde23d8 Mon Sep 17 00:00:00 2001 From: ashutosh0x Date: Thu, 22 Jan 2026 13:39:41 +0530 Subject: [PATCH 4/4] fix(streaming): handle out-of-order content blocks in accumulation --- src/anthropic/lib/streaming/_beta_messages.py | 13 +++++++------ src/anthropic/lib/streaming/_messages.py | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/anthropic/lib/streaming/_beta_messages.py b/src/anthropic/lib/streaming/_beta_messages.py index 0518a777..35c5ccc6 100644 --- a/src/anthropic/lib/streaming/_beta_messages.py +++ b/src/anthropic/lib/streaming/_beta_messages.py @@ -464,13 +464,14 @@ def accumulate_event( raise RuntimeError(f'Unexpected event order, got {event.type} before "message_start"') if event.type == "content_block_start": - # TODO: check index - current_snapshot.content.append( - cast( - Any, # Pydantic does not support generic unions at runtime - construct_type(type_=ParsedBetaContentBlock, value=event.content_block.to_dict()), - ), + new_block = cast( + Any, # Pydantic does not support generic unions at runtime + construct_type(type_=ParsedBetaContentBlock, value=event.content_block.to_dict()), ) + if event.index >= len(current_snapshot.content): + current_snapshot.content.extend([None] * (event.index - len(current_snapshot.content) + 1)) # type: ignore[arg-type] + + current_snapshot.content[event.index] = new_block elif event.type == "content_block_delta": content = current_snapshot.content[event.index] if event.delta.type == "text_delta": diff --git a/src/anthropic/lib/streaming/_messages.py b/src/anthropic/lib/streaming/_messages.py index 355f389c..96e545bc 100644 --- a/src/anthropic/lib/streaming/_messages.py +++ b/src/anthropic/lib/streaming/_messages.py @@ -424,13 +424,14 @@ def accumulate_event( raise RuntimeError(f'Unexpected event order, got {event.type} before "message_start"') if event.type == "content_block_start": - # TODO: check index - current_snapshot.content.append( - cast( - ContentBlock, - construct_type(type_=ContentBlock, value=event.content_block.model_dump()), - ), + new_block = cast( + ContentBlock, + construct_type(type_=ContentBlock, value=event.content_block.model_dump()), ) + if event.index >= len(current_snapshot.content): + current_snapshot.content.extend([None] * (event.index - len(current_snapshot.content) + 1)) # type: ignore[arg-type] + + current_snapshot.content[event.index] = new_block elif event.type == "content_block_delta": content = current_snapshot.content[event.index] if event.delta.type == "text_delta":