fix: forward service_tier param to Anthropic API (#23401)

* fix: forward service_tier param to Anthropic API

service_tier was silently dropped because it was missing from
AnthropicConfig.get_supported_openai_params(). Add it to the
supported params list and add a passthrough mapping in
map_openai_params() so it is forwarded as-is to the request body.

Fixes #23398

* fix: add service_tier to AnthropicMessagesRequestOptionalParams TypedDict

* fix: restrict service_tier to Anthropic-valid values only

* fix: honour drop_params flag for invalid service_tier values on Anthropic

When drop_params=False, passing an unrecognised service_tier (e.g. the
OpenAI-specific "default"/"flex"/"scale") now raises UnsupportedParamsError
instead of silently discarding the value. When drop_params=True the value
is still silently dropped. Also tightens the TypedDict field from Optional[str]
to Optional[Literal["auto", "standard_only"]] for static analysis.

Fixes https://github.com/BerriAI/litellm/issues/23398

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: silently drop unrecognised service_tier values for backward-compatibility

* fix: raise UnsupportedParamsError for invalid service_tier when drop_params=False

* values check for service tier

* verbose logging for supported values of service_tier

* support future additions to service_tier values

* fix: forward service_tier param to Anthropic API as pure passthrough

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Pradyumna Yadav 2026-03-13 02:10:38 +05:30 committed by GitHub
parent 011b8baeff
commit d34daeeda0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 60 additions and 0 deletions

View file

@ -195,6 +195,7 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
"speed",
"context_management",
"cache_control",
"service_tier",
]
if (
@ -1068,6 +1069,11 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
elif param == "cache_control" and isinstance(value, dict):
# Pass through top-level cache_control for automatic prompt caching
optional_params["cache_control"] = value
elif param == "service_tier" and isinstance(value, str):
# Pass through service_tier to the Anthropic API.
# Anthropic validates the value and returns an error for
# unsupported tiers.
optional_params["service_tier"] = value
## handle thinking tokens
self.update_optional_params_with_thinking_tokens(

View file

@ -364,6 +364,7 @@ class AnthropicMessagesRequestOptionalParams(TypedDict, total=False):
speed: Optional[str] # Fast mode support for Opus models
output_config: Optional[AnthropicOutputConfig] # Configuration for Claude's output behavior
cache_control: Optional[Dict[str, Any]] # Automatic prompt caching
service_tier: Optional[str] # Service tier for priority capacity (e.g. "auto", "standard_only")
class AnthropicMessagesRequest(AnthropicMessagesRequestOptionalParams, total=False):

View file

@ -3300,3 +3300,56 @@ def test_map_tool_helper_empty_parameters_get_default():
assert result is not None
assert result["input_schema"]["type"] == "object"
assert result["input_schema"].get("properties") == {}
@pytest.mark.parametrize("service_tier", ["auto", "standard_only"])
def test_service_tier_forwarded_to_anthropic(service_tier: str):
"""
service_tier must be forwarded as-is to the Anthropic API request body.
Fixes https://github.com/BerriAI/litellm/issues/23398
"""
config = AnthropicConfig()
result = config.map_openai_params(
non_default_params={"service_tier": service_tier},
optional_params={},
model="claude-sonnet-4-6",
drop_params=False,
)
assert result.get("service_tier") == service_tier
def test_service_tier_in_supported_params():
"""
service_tier must appear in get_supported_openai_params so it is not
silently dropped before map_openai_params is called.
Fixes https://github.com/BerriAI/litellm/issues/23398
"""
config = AnthropicConfig()
assert "service_tier" in config.get_supported_openai_params(
model="claude-sonnet-4-6"
)
@pytest.mark.parametrize("service_tier", ["default", "flex", "scale"])
def test_service_tier_any_string_forwarded_to_anthropic(service_tier: str):
"""
service_tier is forwarded as-is to the Anthropic API for all string
values. Anthropic validates the value and returns an error for
unsupported tiers.
Fixes https://github.com/BerriAI/litellm/issues/23398
"""
config = AnthropicConfig()
result = config.map_openai_params(
non_default_params={"service_tier": service_tier},
optional_params={},
model="claude-sonnet-4-6",
drop_params=False,
)
assert result.get("service_tier") == service_tier