Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,33 @@ def _is_claude_opus_4_5(self, model: str) -> bool:
]
return any(pattern in model_lower for pattern in opus_4_5_patterns)

def _supports_tool_search_on_bedrock(self, model: str) -> bool:
"""
Check if the model supports tool search on Bedrock.

On Amazon Bedrock, server-side tool search is supported on Claude Opus 4.5
and Claude Sonnet 4.5 with the tool-search-tool-2025-10-19 beta header.

Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool

Args:
model: The model name

Returns:
True if the model supports tool search on Bedrock
"""
model_lower = model.lower()

# Supported models for tool search on Bedrock
supported_patterns = [
# Opus 4.5
"opus-4.5", "opus_4.5", "opus-4-5", "opus_4_5",
# Sonnet 4.5
"sonnet-4.5", "sonnet_4.5", "sonnet-4-5", "sonnet_4_5",
]

return any(pattern in model_lower for pattern in supported_patterns)

def _filter_unsupported_beta_headers_for_bedrock(
self, model: str, beta_set: set
) -> None:
Expand All @@ -186,13 +213,14 @@ def _filter_unsupported_beta_headers_for_bedrock(

Extended thinking beta headers are only supported on specific Claude 4+ models.
Advanced tool use headers are not supported on Bedrock Invoke API, but need to be
translated to Bedrock-specific headers for Claude Opus 4.5.
translated to Bedrock-specific headers for models that support tool search
(Claude Opus 4.5, Sonnet 4.5).
This prevents 400 "invalid beta flag" errors on Bedrock.

Note: Bedrock Invoke API fails with a 400 error when unsupported beta headers
are sent, returning: {"message":"invalid beta flag"}

Translation for Claude Opus 4.5:
Translation for models supporting tool search (Opus 4.5, Sonnet 4.5):
- advanced-tool-use-2025-11-20 -> tool-search-tool-2025-10-19 + tool-examples-2025-10-29

Args:
Expand Down Expand Up @@ -226,10 +254,11 @@ def _filter_unsupported_beta_headers_for_bedrock(
# Remove all filtered headers
for beta in beta_headers_to_remove:
beta_set.discard(beta)
# 3. Translate advanced-tool-use to Bedrock-specific headers for Claude Opus 4.5

# 3. Translate advanced-tool-use to Bedrock-specific headers for models that support tool search
# Ref: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages-request-response.html
if has_advanced_tool_use and self._is_claude_opus_4_5(model):
# Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool
if has_advanced_tool_use and self._supports_tool_search_on_bedrock(model):
beta_set.add("tool-search-tool-2025-10-19")
beta_set.add("tool-examples-2025-10-29")

Expand Down
59 changes: 48 additions & 11 deletions tests/test_litellm/llms/bedrock/test_anthropic_beta_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,29 +427,66 @@ def test_messages_advanced_tool_use_translation_opus_4_5(self):
"tool-examples-2025-10-29 should be added for Opus 4.5"
)

def test_messages_advanced_tool_use_filtered_non_opus_4_5(self):
"""Test that advanced-tool-use header is filtered out for non-Opus 4.5 models.

The translation to Bedrock-specific headers should only happen for Opus 4.5.
For other models, the advanced-tool-use header should just be removed.
def test_messages_advanced_tool_use_translation_sonnet_4_5(self):
"""Test that advanced-tool-use header is translated to Bedrock-specific headers for Sonnet 4.5.

Regression test for: Claude Code sends advanced-tool-use-2025-11-20 header which needs
to be translated to tool-search-tool-2025-10-19 and tool-examples-2025-10-29 for
Bedrock Invoke API on Claude Sonnet 4.5.

Ref: https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-search-tool
"""
config = AmazonAnthropicClaudeMessagesConfig()
headers = {"anthropic-beta": "advanced-tool-use-2025-11-20"}

# Test with Sonnet 4.5 (not Opus 4.5)

result = config.transform_anthropic_messages_request(
model="us.anthropic.claude-sonnet-4-5-20250929-v1:0",
messages=[{"role": "user", "content": "Test"}],
anthropic_messages_optional_request_params={"max_tokens": 100},
litellm_params={},
headers=headers
)


assert "anthropic_beta" in result
beta_headers = result["anthropic_beta"]

# advanced-tool-use should be removed
assert "advanced-tool-use-2025-11-20" not in beta_headers, (
"advanced-tool-use-2025-11-20 should be removed for Bedrock Invoke API"
)

# Bedrock-specific headers should be added for Sonnet 4.5
assert "tool-search-tool-2025-10-19" in beta_headers, (
"tool-search-tool-2025-10-19 should be added for Sonnet 4.5"
)
assert "tool-examples-2025-10-29" in beta_headers, (
"tool-examples-2025-10-29 should be added for Sonnet 4.5"
)

def test_messages_advanced_tool_use_filtered_unsupported_model(self):
"""Test that advanced-tool-use header is filtered out for models that don't support tool search.

The translation to Bedrock-specific headers should only happen for models that
support tool search on Bedrock (Opus 4.5, Sonnet 4.5).
For other models, the advanced-tool-use header should just be removed.
"""
config = AmazonAnthropicClaudeMessagesConfig()
headers = {"anthropic-beta": "advanced-tool-use-2025-11-20"}

# Test with Claude 3.5 Sonnet (does NOT support tool search on Bedrock)
result = config.transform_anthropic_messages_request(
model="us.anthropic.claude-3-5-sonnet-20241022-v2:0",
messages=[{"role": "user", "content": "Test"}],
anthropic_messages_optional_request_params={"max_tokens": 100},
litellm_params={},
headers=headers
)

beta_headers = result.get("anthropic_beta", [])

# advanced-tool-use should be removed
assert "advanced-tool-use-2025-11-20" not in beta_headers
# Bedrock-specific headers should NOT be added for non-Opus 4.5

# Bedrock-specific headers should NOT be added for unsupported models
assert "tool-search-tool-2025-10-19" not in beta_headers
assert "tool-examples-2025-10-29" not in beta_headers
Loading