mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(bedrock): strip unsupported Files API betas for Invoke
Bedrock Invoke rejects files-api and code-execution betas; omit them while keeping other anthropic_beta flags. Add unit tests. Made-with: Cursor
This commit is contained in:
parent
cae8613660
commit
22d218d430
4 changed files with 64 additions and 6 deletions
|
|
@ -9,6 +9,7 @@ from litellm.llms.bedrock.chat.invoke_transformations.base_invoke_transformation
|
|||
from litellm.llms.bedrock.common_utils import (
|
||||
get_anthropic_beta_from_headers,
|
||||
remove_custom_field_from_tools,
|
||||
strip_unsupported_file_api_betas_for_bedrock_invoke,
|
||||
)
|
||||
from litellm.types.llms.anthropic import ANTHROPIC_TOOL_SEARCH_BETA_HEADER
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
|
|
@ -143,9 +144,11 @@ class AmazonAnthropicClaudeConfig(AmazonInvokeConfig, AnthropicConfig):
|
|||
beta_set.add("tool-search-tool-2025-10-19")
|
||||
|
||||
# Filter out beta headers that Bedrock Invoke doesn't support
|
||||
# Uses centralized configuration from anthropic_beta_headers_config.json
|
||||
beta_list = list(beta_set)
|
||||
_anthropic_request["anthropic_beta"] = beta_list
|
||||
beta_list = strip_unsupported_file_api_betas_for_bedrock_invoke(list(beta_set))
|
||||
if beta_list:
|
||||
_anthropic_request["anthropic_beta"] = beta_list
|
||||
else:
|
||||
_anthropic_request.pop("anthropic_beta", None)
|
||||
|
||||
return _anthropic_request
|
||||
|
||||
|
|
|
|||
|
|
@ -907,6 +907,21 @@ def get_anthropic_beta_from_headers(headers: dict) -> List[str]:
|
|||
return []
|
||||
|
||||
|
||||
# Anthropic's Files API uses these betas when using file_id / hosted files. Bedrock Invoke
|
||||
# rejects them with "invalid beta flag". Document blocks with source.url still work without them.
|
||||
BEDROCK_INVOKE_UNSUPPORTED_FILE_API_BETAS: frozenset[str] = frozenset(
|
||||
{
|
||||
"files-api-2025-04-14",
|
||||
"code-execution-2025-05-22",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def strip_unsupported_file_api_betas_for_bedrock_invoke(betas: List[str]) -> List[str]:
|
||||
"""Drop Files-API-only betas from anthropic_beta before Bedrock Invoke."""
|
||||
return [b for b in betas if b not in BEDROCK_INVOKE_UNSUPPORTED_FILE_API_BETAS]
|
||||
|
||||
|
||||
class CommonBatchFilesUtils:
|
||||
"""
|
||||
Common utilities for Bedrock batch and file operations.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ from litellm.llms.bedrock.common_utils import (
|
|||
get_anthropic_beta_from_headers,
|
||||
is_claude_4_5_on_bedrock,
|
||||
remove_custom_field_from_tools,
|
||||
strip_unsupported_file_api_betas_for_bedrock_invoke,
|
||||
)
|
||||
from litellm.types.llms.anthropic import ANTHROPIC_TOOL_SEARCH_BETA_HEADER
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
|
|
@ -460,8 +461,11 @@ class AmazonAnthropicClaudeMessagesConfig(
|
|||
if "tool-search-tool-2025-10-19" in beta_set:
|
||||
beta_set.add("tool-examples-2025-10-29")
|
||||
|
||||
if beta_set:
|
||||
anthropic_messages_request["anthropic_beta"] = list(beta_set)
|
||||
beta_list = strip_unsupported_file_api_betas_for_bedrock_invoke(list(beta_set))
|
||||
if beta_list:
|
||||
anthropic_messages_request["anthropic_beta"] = beta_list
|
||||
else:
|
||||
anthropic_messages_request.pop("anthropic_beta", None)
|
||||
|
||||
return anthropic_messages_request
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ from litellm.llms.bedrock.chat.converse_transformation import AmazonConverseConf
|
|||
from litellm.llms.bedrock.chat.invoke_transformations.anthropic_claude3_transformation import (
|
||||
AmazonAnthropicClaudeConfig,
|
||||
)
|
||||
from litellm.llms.bedrock.common_utils import get_anthropic_beta_from_headers
|
||||
from litellm.llms.bedrock.common_utils import (
|
||||
get_anthropic_beta_from_headers,
|
||||
strip_unsupported_file_api_betas_for_bedrock_invoke,
|
||||
)
|
||||
from litellm.llms.bedrock.messages.invoke_transformations.anthropic_claude3_transformation import (
|
||||
AmazonAnthropicClaudeMessagesConfig,
|
||||
)
|
||||
|
|
@ -64,6 +67,39 @@ class TestAnthropicBetaHeaderSupport:
|
|||
# Beta flags are stored as sets, so order may vary
|
||||
assert set(result["anthropic_beta"]) == {"context-1m-2025-08-07", "computer-use-2024-10-22"}
|
||||
|
||||
def test_invoke_omits_file_api_betas_for_openai_style_file_url(self):
|
||||
"""Bedrock returns invalid beta flag if Files API betas are sent; URL docs work without them."""
|
||||
config = AmazonAnthropicClaudeConfig()
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "What's this file about?"},
|
||||
{
|
||||
"type": "file",
|
||||
"file": {
|
||||
"file_id": "https://upload.wikimedia.org/wikipedia/commons/2/20/Re_example.pdf"
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
result = config.transform_request(
|
||||
model="anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||||
messages=messages,
|
||||
optional_params={},
|
||||
litellm_params={},
|
||||
headers={},
|
||||
)
|
||||
betas = result.get("anthropic_beta", [])
|
||||
assert "files-api-2025-04-14" not in betas
|
||||
assert "code-execution-2025-05-22" not in betas
|
||||
|
||||
def test_strip_unsupported_file_api_betas_helper(self):
|
||||
assert strip_unsupported_file_api_betas_for_bedrock_invoke(
|
||||
["context-1m-2025-08-07", "files-api-2025-04-14", "code-execution-2025-05-22"]
|
||||
) == ["context-1m-2025-08-07"]
|
||||
|
||||
def test_converse_transformation_anthropic_beta(self):
|
||||
"""Test that Converse API transformation includes anthropic_beta in additionalModelRequestFields."""
|
||||
config = AmazonConverseConfig()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue