From 070fb63a32366acfe514b43351d989d1e5f75c16 Mon Sep 17 00:00:00 2001 From: Charan Rathore <180254320+charan-rathore@users.noreply.github.com> Date: Fri, 23 Oct 2026 08:28:00 +0530 Subject: [PATCH] fix(bedrock): keep compatible message API version Fixes #2031 Signed-off-by: Charan Rathore <180254320+charan-rathore@users.noreply.github.com> --- src/anthropic/lib/bedrock/_client.py | 4 ++-- tests/lib/test_bedrock.py | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/anthropic/lib/bedrock/_client.py b/src/anthropic/lib/bedrock/_client.py index 5409532fe..49f0328c8 100644 --- a/src/anthropic/lib/bedrock/_client.py +++ b/src/anthropic/lib/bedrock/_client.py @@ -14,7 +14,6 @@ from ..._client import _keep_client_header_params from ..._compat import model_copy from ..._version import __version__ -from ..._constants import ANTHROPIC_API_VERSION from ..._streaming import Stream, AsyncStream from ..._exceptions import AnthropicError, APIStatusError from ..._middleware import MiddlewareInput @@ -32,13 +31,14 @@ _HttpxClientT = TypeVar("_HttpxClientT", bound=Union[httpx2.Client, httpx2.AsyncClient]) _DefaultStreamT = TypeVar("_DefaultStreamT", bound=Union[Stream[Any], AsyncStream[Any]]) +DEFAULT_VERSION = "bedrock-2023-05-31" def _prepare_options(input_options: FinalRequestOptions) -> FinalRequestOptions: options = model_copy(_keep_client_header_params(input_options), deep=True) if is_dict(options.json_data): - options.json_data.setdefault("anthropic_version", ANTHROPIC_API_VERSION) + options.json_data.setdefault("anthropic_version", DEFAULT_VERSION) if is_given(options.headers): betas = build_headers(options.headers)[0].get("anthropic-beta") diff --git a/tests/lib/test_bedrock.py b/tests/lib/test_bedrock.py index 901c93aec..df6c67537 100644 --- a/tests/lib/test_bedrock.py +++ b/tests/lib/test_bedrock.py @@ -16,7 +16,6 @@ from anthropic import APIStatusError, AnthropicBedrock, AsyncAnthropicBedrock, beta_tool, beta_async_tool from anthropic._compat import PYDANTIC_V1 from anthropic._models import FinalRequestOptions -from anthropic._constants import ANTHROPIC_API_VERSION from anthropic.lib.bedrock._client import _prepare_options from anthropic.lib.bedrock._stream_decoder import _chunk_bytes_to_sse @@ -203,6 +202,22 @@ def test_extra_body_anthropic_version_wins(respx_mock: MockRouter) -> None: assert json.loads(request.content)["anthropic_version"] == "2000-01-01" +@pytest.mark.respx() +def test_default_anthropic_version_is_bedrock_compatible(respx_mock: MockRouter) -> None: + respx_mock.post(re.compile(r"https://bedrock-runtime\.us-east-1\.amazonaws\.com/model/.*/invoke")).mock( + return_value=httpx2.Response(200, json={"foo": "bar"}), + ) + + sync_client.messages.create( + max_tokens=16, + messages=[{"role": "user", "content": "Say ok"}], + model="anthropic.claude-sonnet-4-5-20250929-v1:0", + ) + + request = cast("list[MockRequestCall]", respx_mock.calls)[0].request + assert json.loads(request.content)["anthropic_version"] == "bedrock-2023-05-31" + + @pytest.mark.respx() @pytest.mark.asyncio() async def test_extra_body_anthropic_version_wins_async(respx_mock: MockRouter) -> None: @@ -582,7 +597,7 @@ def _assert_tool_runner_calls(calls: t.List[MockRequestCall]) -> None: assert "anthropic-version" not in call.request.headers body = json.loads(call.request.content) assert "model" not in body and "stream" not in body and "output_format" not in body - assert body["anthropic_version"] == ANTHROPIC_API_VERSION + assert body["anthropic_version"] == "bedrock-2023-05-31" second = json.loads(calls[1].request.content) assert [m["role"] for m in second["messages"]] == ["user", "assistant", "user"] assert second["messages"][1]["content"][0]["type"] == "tool_use"