mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
feat: add force_reasoning_effort litellm_params config
Add force_reasoning_effort as a per-deployment litellm_params field
that overrides reasoning_effort regardless of what the request sends.
Follows the same pattern as merge_reasoning_content_in_choices:
declared in GenericLiteLLMParams, captured in get_litellm_params(),
consumed downstream.
Override points for each entry path:
- /v1/chat/completions: main.py reads from litellm_params after
get_litellm_params(), overrides optional_params["reasoning_effort"]
- /v1/messages → responses adapter: _build_responses_kwargs() pops
from extra_kwargs, overrides reasoning.effort in responses format
- /v1/responses direct: responses/main.py pops from local_vars,
overrides reasoning dict
Config example:
litellm_params:
model: github_copilot/gpt-5.4
force_reasoning_effort: xhigh
Tested: all three endpoints with explicit low effort in request,
all overridden to xhigh with high reasoning_tokens in response.
This commit is contained in:
parent
2f22a1293e
commit
c0ee4ec695
6 changed files with 43 additions and 1 deletions
|
|
@ -90,6 +90,7 @@ def get_litellm_params(
|
|||
async_call: Optional[bool] = None,
|
||||
ssl_verify: Optional[bool] = None,
|
||||
merge_reasoning_content_in_choices: Optional[bool] = None,
|
||||
force_reasoning_effort: Optional[str] = None,
|
||||
use_litellm_proxy: Optional[bool] = None,
|
||||
api_version: Optional[str] = None,
|
||||
max_retries: Optional[int] = None,
|
||||
|
|
@ -149,6 +150,7 @@ def get_litellm_params(
|
|||
"async_call": async_call,
|
||||
"ssl_verify": ssl_verify,
|
||||
"merge_reasoning_content_in_choices": merge_reasoning_content_in_choices,
|
||||
"force_reasoning_effort": force_reasoning_effort,
|
||||
"api_version": api_version,
|
||||
"max_retries": max_retries,
|
||||
"use_litellm_proxy": use_litellm_proxy,
|
||||
|
|
|
|||
|
|
@ -441,6 +441,18 @@ def anthropic_messages_handler(
|
|||
params=local_vars
|
||||
)
|
||||
)
|
||||
force_reasoning_effort = litellm_params.force_reasoning_effort
|
||||
if force_reasoning_effort:
|
||||
output_config = anthropic_messages_optional_request_params.get("output_config") or {}
|
||||
anthropic_messages_optional_request_params["output_config"] = {
|
||||
**output_config,
|
||||
"effort": force_reasoning_effort,
|
||||
}
|
||||
# Effort alone does not trigger reasoning — force-enable thinking too
|
||||
thinking = anthropic_messages_optional_request_params.get("thinking")
|
||||
if not isinstance(thinking, dict) or thinking.get("type") == "disabled":
|
||||
anthropic_messages_optional_request_params["thinking"] = {"type": "adaptive"}
|
||||
|
||||
return base_llm_http_handler.anthropic_messages_handler(
|
||||
model=model,
|
||||
messages=messages,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from litellm.types.llms.openai import ResponsesAPIResponse
|
|||
|
||||
from .streaming_iterator import AnthropicResponsesStreamWrapper
|
||||
from .transformation import LiteLLMAnthropicToResponsesAPIAdapter
|
||||
from ..utils import is_reasoning_auto_summary_enabled
|
||||
|
||||
_ADAPTER = LiteLLMAnthropicToResponsesAPIAdapter()
|
||||
|
||||
|
|
@ -76,7 +77,8 @@ def _build_responses_kwargs(
|
|||
responses_kwargs["stream"] = True
|
||||
|
||||
# Forward litellm-specific kwargs (api_key, api_base, logging obj, etc.)
|
||||
excluded = {"anthropic_messages"}
|
||||
excluded = {"anthropic_messages", "force_reasoning_effort"}
|
||||
force_reasoning_effort = (extra_kwargs or {}).get("force_reasoning_effort")
|
||||
for key, value in (extra_kwargs or {}).items():
|
||||
if key == "litellm_logging_obj" and value is not None:
|
||||
from litellm.litellm_core_utils.litellm_logging import (
|
||||
|
|
@ -93,6 +95,17 @@ def _build_responses_kwargs(
|
|||
elif key not in excluded and key not in responses_kwargs and value is not None:
|
||||
responses_kwargs[key] = value
|
||||
|
||||
# Override reasoning effort if force_reasoning_effort is configured
|
||||
if force_reasoning_effort:
|
||||
reasoning = responses_kwargs.get("reasoning")
|
||||
if isinstance(reasoning, dict):
|
||||
responses_kwargs["reasoning"] = {**reasoning, "effort": force_reasoning_effort}
|
||||
else:
|
||||
responses_kwargs["reasoning"] = {
|
||||
**({"summary": "detailed"} if is_reasoning_auto_summary_enabled() else {}),
|
||||
"effort": force_reasoning_effort,
|
||||
}
|
||||
|
||||
return responses_kwargs
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1577,6 +1577,7 @@ def completion( # type: ignore # noqa: PLR0915
|
|||
merge_reasoning_content_in_choices=kwargs.get(
|
||||
"merge_reasoning_content_in_choices", None
|
||||
),
|
||||
force_reasoning_effort=kwargs.get("force_reasoning_effort"),
|
||||
use_litellm_proxy=kwargs.get("use_litellm_proxy", False),
|
||||
api_version=api_version,
|
||||
azure_ad_token=kwargs.get("azure_ad_token"),
|
||||
|
|
@ -1592,6 +1593,11 @@ def completion( # type: ignore # noqa: PLR0915
|
|||
tpm=kwargs.get("tpm"),
|
||||
rpm=kwargs.get("rpm"),
|
||||
)
|
||||
# Override reasoning_effort if force_reasoning_effort is configured
|
||||
force_reasoning_effort = litellm_params.get("force_reasoning_effort")
|
||||
if force_reasoning_effort:
|
||||
optional_params["reasoning_effort"] = force_reasoning_effort
|
||||
|
||||
cast(LiteLLMLoggingObj, logging).update_environment_variables(
|
||||
model=model,
|
||||
user=user,
|
||||
|
|
|
|||
|
|
@ -862,6 +862,14 @@ def responses(
|
|||
if _mapped is not None:
|
||||
reasoning = _mapped
|
||||
local_vars["reasoning"] = _mapped
|
||||
# Override reasoning effort if force_reasoning_effort is configured
|
||||
force_reasoning_effort = local_vars.pop("force_reasoning_effort", None)
|
||||
if force_reasoning_effort:
|
||||
if isinstance(reasoning, dict):
|
||||
reasoning = {**reasoning, "effort": force_reasoning_effort}
|
||||
else:
|
||||
reasoning = {"effort": force_reasoning_effort}
|
||||
local_vars["reasoning"] = reasoning
|
||||
# Get ResponsesAPIOptionalRequestParams with only valid parameters
|
||||
response_api_optional_params: ResponsesAPIOptionalRequestParams = (
|
||||
ResponsesAPIRequestUtils.get_requested_response_api_optional_param(
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ class GenericLiteLLMParams(CredentialLiteLLMParams, CustomPricingLiteLLMParams):
|
|||
use_litellm_proxy: Optional[bool] = False
|
||||
model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True)
|
||||
merge_reasoning_content_in_choices: Optional[bool] = False
|
||||
force_reasoning_effort: Optional[str] = None
|
||||
model_info: Optional[Dict] = None
|
||||
mock_response: Optional[Union[str, ModelResponse, Exception, Any]] = None
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue