mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-13 03:59:12 +00:00
refactor(bedrock): rename is_claude_4_5_on_bedrock to supports_bedrock_prompt_cache_ttl (#46058)
Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
a4382657fd
commit
249add6f0d
6 changed files with 50 additions and 34 deletions
|
|
@ -5093,7 +5093,7 @@ def make_valid_bedrock_tool_name(input_tool_name: str) -> str:
|
|||
def add_cache_point_tool_block(tool: dict, model: str | None = None) -> BedrockToolBlock | None:
|
||||
from litellm.llms.bedrock.common_utils import (
|
||||
bedrock_model_accepts_cache_points,
|
||||
is_claude_4_5_on_bedrock,
|
||||
supports_bedrock_prompt_cache_ttl,
|
||||
)
|
||||
|
||||
cache_control: Final = tool.get("cache_control", None)
|
||||
|
|
@ -5103,7 +5103,7 @@ def add_cache_point_tool_block(tool: dict, model: str | None = None) -> BedrockT
|
|||
cache_point_block: Final[CachePointBlock] = {"type": "default"}
|
||||
if isinstance(cache_control, dict) and "ttl" in cache_control:
|
||||
ttl: Final = cache_control["ttl"]
|
||||
if ttl in ["5m", "1h"] and model is not None and is_claude_4_5_on_bedrock(model):
|
||||
if ttl in ["5m", "1h"] and model is not None and supports_bedrock_prompt_cache_ttl(model):
|
||||
cache_point_block["ttl"] = ttl
|
||||
return {"cachePoint": cache_point_block}
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ from ..common_utils import (
|
|||
get_anthropic_beta_from_headers,
|
||||
get_bedrock_tool_name,
|
||||
is_bedrock_application_inference_profile_arn,
|
||||
is_claude_4_5_on_bedrock,
|
||||
normalize_bedrock_opus_output_config_effort,
|
||||
supports_bedrock_prompt_cache_ttl,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -1385,7 +1385,7 @@ class AmazonConverseConfig(BaseConfig):
|
|||
cache_point: Final = CachePointBlock(type="default")
|
||||
if isinstance(control, dict) and "ttl" in control:
|
||||
ttl: Final = control["ttl"]
|
||||
if ttl in ["5m", "1h"] and model is not None and is_claude_4_5_on_bedrock(model):
|
||||
if ttl in ["5m", "1h"] and model is not None and supports_bedrock_prompt_cache_ttl(model):
|
||||
cache_point["ttl"] = ttl
|
||||
return cache_point
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import functools
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import warnings
|
||||
from collections.abc import Iterator, Mapping, Sequence
|
||||
from types import MappingProxyType
|
||||
from typing import TYPE_CHECKING, Any, Final, Literal, TypeAlias
|
||||
|
|
@ -1230,15 +1231,11 @@ def bedrock_supports_tool_search(model: str) -> bool:
|
|||
return AnthropicModelInfo.supports_model_capability(model, "supports_tool_search", "bedrock")
|
||||
|
||||
|
||||
def is_claude_4_5_on_bedrock(model: str) -> bool:
|
||||
def supports_bedrock_prompt_cache_ttl(model: str) -> bool:
|
||||
"""
|
||||
Check if the model supports Bedrock prompt caching with an extended '1h' TTL
|
||||
(in addition to the default 5m TTL).
|
||||
|
||||
Backed by the ``cache_creation_input_token_cost_above_1hr`` field in
|
||||
``model_prices_and_context_window.json`` instead of a hardcoded list of
|
||||
model-name patterns, so newly released models pick up support as soon as
|
||||
their pricing entry ships, with no code change required here.
|
||||
Whether Bedrock accepts a ``ttl`` ("5m"/"1h") on prompt ``cache_control``
|
||||
for this model, decided by ``cache_creation_input_token_cost_above_1hr`` on
|
||||
the model's or its base model's cost-map entry.
|
||||
"""
|
||||
return any(
|
||||
(litellm.model_cost.get(candidate) or {}).get("cache_creation_input_token_cost_above_1hr") is not None
|
||||
|
|
@ -1246,6 +1243,15 @@ def is_claude_4_5_on_bedrock(model: str) -> bool:
|
|||
)
|
||||
|
||||
|
||||
def is_claude_4_5_on_bedrock(model: str) -> bool:
|
||||
warnings.warn(
|
||||
"is_claude_4_5_on_bedrock is deprecated, use supports_bedrock_prompt_cache_ttl",
|
||||
UserWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return supports_bedrock_prompt_cache_ttl(model)
|
||||
|
||||
|
||||
_BEDROCK_MODEL_VERSION_SUFFIX_RE: Final = re.compile(r"-v\d+(?::\d+)?$")
|
||||
_DEPLOYMENT_MODEL_INFO: Final = TypeAdapter(dict[str, object])
|
||||
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ from litellm.llms.bedrock.common_utils import (
|
|||
bedrock_supports_tool_search,
|
||||
ensure_bedrock_anthropic_messages_tool_names,
|
||||
get_anthropic_beta_from_headers,
|
||||
is_claude_4_5_on_bedrock,
|
||||
normalize_bedrock_opus_output_config_effort,
|
||||
normalize_custom_field_on_tools,
|
||||
normalize_tool_input_schema_types_for_bedrock_invoke,
|
||||
strip_unsupported_bedrock_invoke_output_config_keys,
|
||||
supports_bedrock_prompt_cache_ttl,
|
||||
tools_without_eager_input_streaming,
|
||||
)
|
||||
from litellm.llms.bedrock.request_metadata import (
|
||||
|
|
@ -169,9 +169,9 @@ class AmazonAnthropicClaudeMessagesConfig(
|
|||
anthropic_messages_request: The request dictionary to modify in-place
|
||||
model: The model name to check if it supports ttl
|
||||
"""
|
||||
is_claude_4_5 = False
|
||||
supports_ttl = False
|
||||
if model:
|
||||
is_claude_4_5 = self._is_claude_4_5_on_bedrock(model)
|
||||
supports_ttl = self._supports_prompt_cache_ttl(model)
|
||||
|
||||
def _sanitize_cache_control(cache_control: dict) -> None:
|
||||
if not isinstance(cache_control, dict):
|
||||
|
|
@ -181,7 +181,7 @@ class AmazonAnthropicClaudeMessagesConfig(
|
|||
# Remove ttl for models that don't support it
|
||||
if "ttl" in cache_control:
|
||||
ttl: Final = cache_control["ttl"]
|
||||
if is_claude_4_5 and ttl in ["5m", "1h"]:
|
||||
if supports_ttl and ttl in ["5m", "1h"]:
|
||||
return
|
||||
cache_control.pop("ttl", None)
|
||||
|
||||
|
|
@ -386,19 +386,9 @@ class AmazonAnthropicClaudeMessagesConfig(
|
|||
]
|
||||
return any(pattern in model_lower for pattern in opus_4_5_patterns)
|
||||
|
||||
def _is_claude_4_5_on_bedrock(self, model: str) -> bool:
|
||||
"""
|
||||
Check if the model is Claude 4.5 on Bedrock.
|
||||
|
||||
Claude Sonnet 4.5, Haiku 4.5, and Opus 4.5 support 1-hour prompt caching.
|
||||
|
||||
Args:
|
||||
model: The model name
|
||||
|
||||
Returns:
|
||||
True if the model is Claude 4.5
|
||||
"""
|
||||
return is_claude_4_5_on_bedrock(model)
|
||||
def _supports_prompt_cache_ttl(self, model: str) -> bool:
|
||||
"""Whether Bedrock accepts a ``ttl`` on prompt ``cache_control`` for ``model``."""
|
||||
return supports_bedrock_prompt_cache_ttl(model)
|
||||
|
||||
def _supports_tool_search_on_bedrock(self, model: str) -> bool:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -5347,12 +5347,12 @@ def test_parallel_tool_calls_flag_decoupled_from_ttl_pricing(monkeypatch):
|
|||
The disable_parallel_tool_use gate must read supports_parallel_tool_use_config,
|
||||
not the 1h-TTL pricing field: a model carrying only the former still gets the flag.
|
||||
"""
|
||||
from litellm.llms.bedrock.common_utils import is_claude_4_5_on_bedrock
|
||||
from litellm.llms.bedrock.common_utils import supports_bedrock_prompt_cache_ttl
|
||||
|
||||
config = AmazonConverseConfig()
|
||||
model = "anthropic.claude-parallel-tool-use-only"
|
||||
monkeypatch.setitem(litellm.model_cost, model, {"supports_parallel_tool_use_config": True})
|
||||
assert is_claude_4_5_on_bedrock(model) is False
|
||||
assert supports_bedrock_prompt_cache_ttl(model) is False
|
||||
messages = [{"role": "user", "content": "What's the weather in SF and NYC?"}]
|
||||
|
||||
optional_params = config.map_openai_params(
|
||||
|
|
@ -5924,7 +5924,7 @@ def test_cache_control_injection_tool_config_honors_ttl_for_supported_model(monk
|
|||
cache_control behavior, instead of always emitting a bare
|
||||
{"type": "default"} cachePoint with no ttl.
|
||||
|
||||
Forces the bundled local cost map so `is_claude_4_5_on_bedrock` (which
|
||||
Forces the bundled local cost map so `supports_bedrock_prompt_cache_ttl` (which
|
||||
reads `cache_creation_input_token_cost_above_1hr` from litellm.model_cost)
|
||||
sees this branch's pricing data rather than the network-fetched `main`
|
||||
copy, which lacks it until merge.
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ def test_capability_lookups_fall_back_to_base_model_when_regional_entry_lacks_fi
|
|||
import litellm
|
||||
from litellm.llms.bedrock.common_utils import (
|
||||
bedrock_converse_supports_parallel_tool_use_config,
|
||||
is_claude_4_5_on_bedrock,
|
||||
supports_bedrock_prompt_cache_ttl,
|
||||
)
|
||||
|
||||
base = "anthropic.claude-fallback-test"
|
||||
|
|
@ -488,10 +488,30 @@ def test_capability_lookups_fall_back_to_base_model_when_regional_entry_lacks_fi
|
|||
},
|
||||
)
|
||||
|
||||
assert is_claude_4_5_on_bedrock(regional) is True
|
||||
assert supports_bedrock_prompt_cache_ttl(regional) is True
|
||||
assert bedrock_converse_supports_parallel_tool_use_config(regional) is True
|
||||
|
||||
|
||||
def test_deprecated_is_claude_4_5_on_bedrock_warns_and_matches_new_name(monkeypatch):
|
||||
import litellm
|
||||
from litellm.llms.bedrock.common_utils import (
|
||||
is_claude_4_5_on_bedrock,
|
||||
supports_bedrock_prompt_cache_ttl,
|
||||
)
|
||||
|
||||
with_ttl = "anthropic.claude-ttl-supported"
|
||||
without_ttl = "anthropic.claude-ttl-unsupported"
|
||||
monkeypatch.setitem(litellm.model_cost, with_ttl, {"cache_creation_input_token_cost_above_1hr": 1e-05})
|
||||
monkeypatch.setitem(litellm.model_cost, without_ttl, {"input_cost_per_token": 1e-06})
|
||||
|
||||
with pytest.warns(UserWarning, match="supports_bedrock_prompt_cache_ttl"):
|
||||
assert is_claude_4_5_on_bedrock(with_ttl) is True
|
||||
with pytest.warns(UserWarning, match="supports_bedrock_prompt_cache_ttl"):
|
||||
assert is_claude_4_5_on_bedrock(without_ttl) is False
|
||||
assert supports_bedrock_prompt_cache_ttl(with_ttl) is True
|
||||
assert supports_bedrock_prompt_cache_ttl(without_ttl) is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entry", "expected"),
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue