mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-15 23:31:29 +00:00
fix(anthropic,bedrock): reject unmapped reasoning_effort at mapping site
Both the chat completion path (AnthropicConfig.map_openai_params) and the Bedrock Converse path (_handle_reasoning_effort_parameter) used REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(value, value) which falls back to the raw input on unmapped keys. Combined with _map_reasoning_effort returning type='adaptive' for any string on Claude 4.6/4.7, garbage values (e.g. 'disabled') could leak into optional_params['output_config']['effort'] unvalidated if map_openai_params ran without the downstream transform_request or _validate_anthropic_adaptive_effort check. Mirror the /v1/messages pattern: use .get(value) (no fallback) and raise BadRequestError immediately when the value is unmapped, co-locating validation with the mapping for defense in depth.
This commit is contained in:
parent
e400de4654
commit
039b26626f
2 changed files with 38 additions and 2 deletions
|
|
@ -1133,9 +1133,28 @@ class AnthropicConfig(AnthropicModelInfo, BaseConfig):
|
|||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
# ``_map_reasoning_effort`` returns ``type=adaptive``
|
||||
# for any string on adaptive models without checking
|
||||
# the value, so reject unmapped efforts here (matching
|
||||
# the /v1/messages path) instead of relying on the
|
||||
# downstream ``_apply_output_config`` check. Co-locating
|
||||
# validation with the mapping prevents garbage from
|
||||
# leaking into ``optional_params`` if ``map_openai_params``
|
||||
# is ever called without a subsequent ``transform_request``.
|
||||
mapped_effort = AnthropicConfig.REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(
|
||||
value, value
|
||||
value
|
||||
)
|
||||
if mapped_effort is None:
|
||||
raise litellm.exceptions.BadRequestError(
|
||||
message=(
|
||||
f"Invalid reasoning_effort: {value!r}. "
|
||||
f"Must be one of: 'minimal', 'low', "
|
||||
f"'medium', 'high', 'xhigh', 'max', 'none'"
|
||||
),
|
||||
model=model,
|
||||
llm_provider=self.custom_llm_provider
|
||||
or "anthropic",
|
||||
)
|
||||
optional_params["output_config"] = {"effort": mapped_effort}
|
||||
elif param == "web_search_options" and isinstance(value, dict):
|
||||
hosted_web_search_tool = self.map_web_search_tool(
|
||||
|
|
|
|||
|
|
@ -485,11 +485,28 @@ class AmazonConverseConfig(BaseConfig):
|
|||
if AnthropicConfig._is_claude_4_6_model(
|
||||
model
|
||||
) or AnthropicConfig._is_claude_4_7_model(model):
|
||||
# Use ``.get()`` without a fallback so unmapped efforts
|
||||
# (e.g. ``"disabled"``) surface as a clean 400 here
|
||||
# rather than leaking the raw garbage string through to
|
||||
# ``_validate_anthropic_adaptive_effort`` (which does
|
||||
# catch it, but only because validation happens to run).
|
||||
# Matches the /v1/messages pattern where validation is
|
||||
# co-located with the mapping.
|
||||
mapped_effort = (
|
||||
AnthropicConfig.REASONING_EFFORT_TO_OUTPUT_CONFIG_EFFORT.get(
|
||||
reasoning_effort, reasoning_effort
|
||||
reasoning_effort
|
||||
)
|
||||
)
|
||||
if mapped_effort is None:
|
||||
raise litellm.exceptions.BadRequestError(
|
||||
message=(
|
||||
f"Invalid reasoning_effort: {reasoning_effort!r}. "
|
||||
f"Must be one of: 'minimal', 'low', 'medium', "
|
||||
f"'high', 'xhigh', 'max', 'none'"
|
||||
),
|
||||
model=model,
|
||||
llm_provider="bedrock_converse",
|
||||
)
|
||||
self._validate_anthropic_adaptive_effort(
|
||||
model=model, effort=mapped_effort
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue