fix(bedrock): drop toolSpec.strict for Claude Sonnet 5 on Converse (#33196)
Some checks failed
OSS Daily Guardrails / Run OSS daily safe checks (push) Has been cancelled

Bedrock routes Claude Sonnet 5 through the same Anthropic-compatible
validator as Opus 4.7/4.8 and Sonnet 4, which rejects toolSpec.strict
with 'tools.0.custom.strict: Extra inputs are not permitted'. Set
bedrock_converse_supports_strict_tools: false on all six Sonnet 5
entries so the existing gate strips the field, matching the fix shape
of #31582

Co-authored-by: Yaroslav Budyanskiy <y_budyanskiy@wargaming.net>
This commit is contained in:
Yaroslav 2026-07-30 21:37:28 +03:00 • committed by GitHub
parent 5d4c4d0fce
commit 7c56317edf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 5 deletions

View file

@ -1759,6 +1759,7 @@
"prompt_cache_min_tokens": 2048
},
"anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.5e-06,
"cache_creation_input_token_cost_above_1hr": 4e-06,
"cache_read_input_token_cost": 2e-07,
@ -1795,6 +1796,7 @@
"prompt_cache_min_tokens": 1024
},
"global.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.5e-06,
"cache_creation_input_token_cost_above_1hr": 4e-06,
"cache_read_input_token_cost": 2e-07,
@ -1831,6 +1833,7 @@
"prompt_cache_min_tokens": 1024
},
"us.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1867,6 +1870,7 @@
"prompt_cache_min_tokens": 1024
},
"eu.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1903,6 +1907,7 @@
"prompt_cache_min_tokens": 1024
},
"au.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1939,6 +1944,7 @@
"prompt_cache_min_tokens": 1024
},
"jp.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,

View file

@ -1759,6 +1759,7 @@
"prompt_cache_min_tokens": 2048
},
"anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.5e-06,
"cache_creation_input_token_cost_above_1hr": 4e-06,
"cache_read_input_token_cost": 2e-07,
@ -1795,6 +1796,7 @@
"prompt_cache_min_tokens": 1024
},
"global.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.5e-06,
"cache_creation_input_token_cost_above_1hr": 4e-06,
"cache_read_input_token_cost": 2e-07,
@ -1831,6 +1833,7 @@
"prompt_cache_min_tokens": 1024
},
"us.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1867,6 +1870,7 @@
"prompt_cache_min_tokens": 1024
},
"eu.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1903,6 +1907,7 @@
"prompt_cache_min_tokens": 1024
},
"au.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,
@ -1939,6 +1944,7 @@
"prompt_cache_min_tokens": 1024
},
"jp.anthropic.claude-sonnet-5": {
"bedrock_converse_supports_strict_tools": false,
"cache_creation_input_token_cost": 2.75e-06,
"cache_creation_input_token_cost_above_1hr": 4.4e-06,
"cache_read_input_token_cost": 2.2e-07,

View file

@ -1,9 +1,9 @@
"""Regression tests for Bedrock Converse ``toolSpec.strict`` forwarding.
Bedrock Converse routes Claude Opus 4.7/4.8 and Claude Sonnet 4 through an
Anthropic-compatible validator that rejects ``toolSpec.strict`` even though
Anthropic's native API accepts ``strict`` as a top-level tool field. See
BerriAI/litellm#31582.
Bedrock Converse routes Claude Opus 4.7/4.8, Claude Sonnet 4 and Claude
Sonnet 5 through an Anthropic-compatible validator that rejects
``toolSpec.strict`` even though Anthropic's native API accepts ``strict``
as a top-level tool field. See BerriAI/litellm#31582.
"""
import pytest
@ -48,12 +48,18 @@ _STRICT_TOOL = [
"bedrock/us.anthropic.claude-sonnet-4-20250514-v1:0",
"bedrock/eu.anthropic.claude-sonnet-4-20250514-v1:0",
"bedrock/apac.anthropic.claude-sonnet-4-20250514-v1:0",
"anthropic.claude-sonnet-5",
"bedrock/global.anthropic.claude-sonnet-5",
"bedrock/us.anthropic.claude-sonnet-5",
"bedrock/eu.anthropic.claude-sonnet-5",
"bedrock/au.anthropic.claude-sonnet-5",
"bedrock/jp.anthropic.claude-sonnet-5",
],
)
def test_bedrock_tools_pt_strict_dropped_for_strict_unsupported_models(
model_id: str,
) -> None:
"""Opus 4.7/4.8 and Sonnet 4 reject toolSpec.strict and additionalProperties."""
"""Opus 4.7/4.8, Sonnet 4 and Sonnet 5 reject toolSpec.strict and additionalProperties."""
result = _bedrock_tools_pt(_STRICT_TOOL, model=model_id)
tool_spec = result[0]["toolSpec"]
assert (
@ -129,6 +135,11 @@ def test_bedrock_converse_supports_strict_tools_helper() -> None:
)
is False
)
assert bedrock_converse_supports_strict_tools("anthropic.claude-sonnet-5") is False
assert (
bedrock_converse_supports_strict_tools("bedrock/us.anthropic.claude-sonnet-5")
is False
)
@pytest.mark.parametrize(
@ -143,6 +154,12 @@ def test_bedrock_converse_supports_strict_tools_helper() -> None:
"us.anthropic.claude-sonnet-4-20250514-v1:0",
"eu.anthropic.claude-sonnet-4-20250514-v1:0",
"apac.anthropic.claude-sonnet-4-20250514-v1:0",
"anthropic.claude-sonnet-5",
"global.anthropic.claude-sonnet-5",
"us.anthropic.claude-sonnet-5",
"eu.anthropic.claude-sonnet-5",
"au.anthropic.claude-sonnet-5",
"jp.anthropic.claude-sonnet-5",
],
)
def test_strict_tools_flag_set_in_model_cost_map(cost_map_key: str) -> None: