mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
fix(utils): honor string drop_params values from config and DB deployments
This commit is contained in:
parent
a7d01cb1ac
commit
1e59cd9e35
7 changed files with 113 additions and 3 deletions
|
|
@ -36,6 +36,18 @@ def safe_divide_seconds(seconds: float, denominator: float, default: Optional[fl
|
|||
return float(seconds / denominator)
|
||||
|
||||
|
||||
def normalize_drop_params(value: object) -> bool | None:
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
if isinstance(value, str):
|
||||
lowered = value.strip().lower()
|
||||
if lowered == "true":
|
||||
return True
|
||||
if lowered == "false":
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
def safe_divide(
|
||||
numerator: Union[int, float],
|
||||
denominator: Union[int, float],
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_valida
|
|||
from typing_extensions import Protocol, Required, TypedDict, runtime_checkable
|
||||
|
||||
from litellm._uuid import uuid
|
||||
from litellm.litellm_core_utils.core_helpers import normalize_drop_params
|
||||
|
||||
from .completion import CompletionRequest
|
||||
from .embedding import EmbeddingRequest
|
||||
|
|
@ -233,6 +234,7 @@ class GenericLiteLLMParams(CredentialLiteLLMParams, CustomPricingLiteLLMParams):
|
|||
None # timeout when making stream=True calls, if str, pass in as os.environ/
|
||||
)
|
||||
max_retries: Optional[int] = None
|
||||
drop_params: Optional[bool] = None
|
||||
organization: Optional[str] = None # for openai orgs
|
||||
configurable_clientside_auth_params: CONFIGURABLE_CLIENTSIDE_AUTH_PARAMS = None
|
||||
litellm_credential_name: Optional[str] = None
|
||||
|
|
@ -311,6 +313,11 @@ class GenericLiteLLMParams(CredentialLiteLLMParams, CustomPricingLiteLLMParams):
|
|||
return filtered
|
||||
return data
|
||||
|
||||
@field_validator("drop_params", mode="before")
|
||||
@classmethod
|
||||
def coerce_drop_params(cls, value: object) -> Optional[bool]:
|
||||
return normalize_drop_params(value)
|
||||
|
||||
def __contains__(self, key):
|
||||
# Define custom behavior for the 'in' operator
|
||||
return hasattr(self, key)
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ from litellm._lazy_imports import (
|
|||
_get_token_counter_new,
|
||||
)
|
||||
from litellm._uuid import uuid
|
||||
from litellm.litellm_core_utils.core_helpers import normalize_drop_params
|
||||
from litellm.litellm_core_utils.fallback_generalizations import (
|
||||
match_capability_generalizations,
|
||||
)
|
||||
|
|
@ -2852,7 +2853,7 @@ def get_optional_params_transcription(
|
|||
|
||||
passed_params.pop("OPENAI_TRANSCRIPTION_PARAMS")
|
||||
custom_llm_provider = passed_params.pop("custom_llm_provider")
|
||||
drop_params = passed_params.pop("drop_params")
|
||||
drop_params = normalize_drop_params(passed_params.pop("drop_params"))
|
||||
special_params = passed_params.pop("kwargs")
|
||||
for k, v in special_params.items():
|
||||
passed_params[k] = v
|
||||
|
|
@ -2960,7 +2961,7 @@ def get_optional_params_image_gen(
|
|||
model = passed_params.pop("model", None)
|
||||
custom_llm_provider = passed_params.pop("custom_llm_provider")
|
||||
provider_config = passed_params.pop("provider_config", None)
|
||||
drop_params = passed_params.pop("drop_params", None)
|
||||
drop_params = normalize_drop_params(passed_params.pop("drop_params", None))
|
||||
additional_drop_params = passed_params.pop("additional_drop_params", None)
|
||||
special_params = passed_params.pop("kwargs")
|
||||
for k, v in special_params.items():
|
||||
|
|
@ -3084,7 +3085,7 @@ def get_optional_params_embeddings(
|
|||
custom_llm_provider = passed_params.pop("custom_llm_provider", None)
|
||||
special_params = passed_params.pop("kwargs")
|
||||
|
||||
drop_params = passed_params.pop("drop_params", None)
|
||||
drop_params = normalize_drop_params(passed_params.pop("drop_params", None))
|
||||
additional_drop_params = passed_params.pop("additional_drop_params", None)
|
||||
allowed_openai_params = passed_params.pop("allowed_openai_params", None) or []
|
||||
# Remove function objects from passed_params to avoid JSON serialization errors
|
||||
|
|
@ -3797,6 +3798,8 @@ def get_optional_params(
|
|||
):
|
||||
passed_params = locals().copy()
|
||||
special_params = passed_params.pop("kwargs")
|
||||
drop_params = normalize_drop_params(drop_params)
|
||||
passed_params["drop_params"] = drop_params
|
||||
# Remove base_model from passed_params so it doesn't interfere with
|
||||
# non_default_params / _check_valid_arg — it's a routing hint, not an
|
||||
# OpenAI param.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import pytest
|
|||
from litellm.litellm_core_utils.core_helpers import (
|
||||
_FINISH_REASON_MAP,
|
||||
map_finish_reason,
|
||||
normalize_drop_params,
|
||||
reconstruct_model_name,
|
||||
redact_nested_match_and_regex_keys,
|
||||
)
|
||||
|
|
@ -201,3 +202,24 @@ class TestRedactNestedMatchAndRegexKeys:
|
|||
def test_passes_through_none_and_str(self):
|
||||
assert redact_nested_match_and_regex_keys(None) is None
|
||||
assert redact_nested_match_and_regex_keys("plain") == "plain"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
[
|
||||
(True, True),
|
||||
(False, False),
|
||||
("true", True),
|
||||
("True", True),
|
||||
(" TRUE ", True),
|
||||
("false", False),
|
||||
("False", False),
|
||||
(None, None),
|
||||
("yes", None),
|
||||
("", None),
|
||||
(1, None),
|
||||
(0, None),
|
||||
],
|
||||
)
|
||||
def test_normalize_drop_params(value, expected):
|
||||
assert normalize_drop_params(value) is expected
|
||||
|
|
|
|||
|
|
@ -5430,3 +5430,37 @@ class TestRouterRequestTimeoutPropagation:
|
|||
)
|
||||
== 60
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_router_deployment_drop_params_string_true_is_honored(monkeypatch):
|
||||
from litellm import Router
|
||||
|
||||
monkeypatch.setattr(litellm, "drop_params", False)
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "gpt-5-nano",
|
||||
"litellm_params": {
|
||||
"model": "openai/gpt-5-nano",
|
||||
"api_key": "sk-fake",
|
||||
"temperature": 1,
|
||||
"reasoning_effort": "minimal",
|
||||
"drop_params": "true",
|
||||
"mock_response": "Hello, world!",
|
||||
},
|
||||
}
|
||||
],
|
||||
num_retries=0,
|
||||
)
|
||||
|
||||
deployment = router.get_deployment_by_model_group_name(model_group_name="gpt-5-nano")
|
||||
assert deployment is not None
|
||||
assert deployment.litellm_params.drop_params is True
|
||||
|
||||
response = await router.acompletion(
|
||||
model="gpt-5-nano",
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
temperature=0.1,
|
||||
)
|
||||
assert response.choices[0].message.content == "Hello, world!"
|
||||
|
|
|
|||
|
|
@ -4814,3 +4814,31 @@ def test_is_prompt_caching_valid_prompt_explicit_min_token_count_overrides_model
|
|||
is_prompt_caching_valid_prompt(model="claude-opus-4-8", messages=PROMPT_CACHE_MESSAGES, min_token_count=8192)
|
||||
is False
|
||||
)
|
||||
|
||||
|
||||
class TestDropParamsStringCoercion:
|
||||
@pytest.mark.parametrize("drop_params", ["true", "True", True])
|
||||
def test_truthy_drop_params_drops_unsupported_temperature(self, drop_params, monkeypatch):
|
||||
from litellm.utils import get_optional_params
|
||||
|
||||
monkeypatch.setattr(litellm, "drop_params", False)
|
||||
result = get_optional_params(
|
||||
model="gpt-5-nano",
|
||||
custom_llm_provider="openai",
|
||||
temperature=0.1,
|
||||
drop_params=drop_params,
|
||||
)
|
||||
assert "temperature" not in result
|
||||
|
||||
@pytest.mark.parametrize("drop_params", ["false", False, None])
|
||||
def test_falsy_drop_params_still_raises(self, drop_params, monkeypatch):
|
||||
from litellm.utils import get_optional_params
|
||||
|
||||
monkeypatch.setattr(litellm, "drop_params", False)
|
||||
with pytest.raises(litellm.UnsupportedParamsError):
|
||||
get_optional_params(
|
||||
model="gpt-5-nano",
|
||||
custom_llm_provider="openai",
|
||||
temperature=0.1,
|
||||
drop_params=drop_params,
|
||||
)
|
||||
|
|
|
|||
4
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
4
ui/litellm-dashboard/src/lib/http/schema.d.ts
generated
vendored
|
|
@ -25667,6 +25667,8 @@ export interface components {
|
|||
default_api_key_rpm_limit?: number | null;
|
||||
/** Default Api Key Tpm Limit */
|
||||
default_api_key_tpm_limit?: number | null;
|
||||
/** Drop Params */
|
||||
drop_params?: boolean | null;
|
||||
/** Gcs Bucket Name */
|
||||
gcs_bucket_name?: string | null;
|
||||
/** Input Cost Per Audio Per Second */
|
||||
|
|
@ -33503,6 +33505,8 @@ export interface components {
|
|||
default_api_key_rpm_limit?: number | null;
|
||||
/** Default Api Key Tpm Limit */
|
||||
default_api_key_tpm_limit?: number | null;
|
||||
/** Drop Params */
|
||||
drop_params?: boolean | null;
|
||||
/** Gcs Bucket Name */
|
||||
gcs_bucket_name?: string | null;
|
||||
/** Input Cost Per Audio Per Second */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue