diff --git a/src/anthropic/lib/streaming/_beta_messages.py b/src/anthropic/lib/streaming/_beta_messages.py index a760dcea..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": @@ -536,5 +537,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..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": @@ -480,5 +481,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.""" 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") 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" },