mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
fix(drop_params): warn when a deployment or env drop_params value is not a flag
A deployment drop_params string that is not a flag value (a typo like ture) stayed silently off. The router now logs one warning per deployment. LITELLM_DROP_PARAMS and litellm_settings.drop_params share the same helper, so a non-flag value there warns as well instead of flipping silently from on to off
This commit is contained in:
parent
b7c2decb7d
commit
d594b9385e
7 changed files with 84 additions and 14 deletions
|
|
@ -47,7 +47,7 @@ from typing import (
|
|||
)
|
||||
from litellm.types.integrations.datadog import DatadogInitParams
|
||||
from litellm.types.integrations.newrelic import NewRelicInitParams
|
||||
from litellm.litellm_core_utils.core_helpers import normalize_drop_params
|
||||
from litellm.litellm_core_utils.core_helpers import drop_params_flag
|
||||
from litellm._logging import (
|
||||
set_verbose,
|
||||
_turn_on_debug,
|
||||
|
|
@ -239,7 +239,7 @@ token: Optional[str] = (
|
|||
)
|
||||
telemetry = True
|
||||
max_tokens: int = DEFAULT_MAX_TOKENS # OpenAI Defaults
|
||||
drop_params = bool(normalize_drop_params(os.getenv("LITELLM_DROP_PARAMS")))
|
||||
drop_params = drop_params_flag(os.getenv("LITELLM_DROP_PARAMS"), "LITELLM_DROP_PARAMS", verbose_logger)
|
||||
modify_params = bool(os.getenv("LITELLM_MODIFY_PARAMS", False))
|
||||
use_chat_completions_url_for_anthropic_messages: bool = bool(
|
||||
os.getenv("LITELLM_USE_CHAT_COMPLETIONS_URL_FOR_ANTHROPIC_MESSAGES", False)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
# What is this?
|
||||
## Helper utilities
|
||||
import copy
|
||||
import logging
|
||||
from collections.abc import Iterable, Mapping
|
||||
from typing import TYPE_CHECKING, Any, Final, Literal
|
||||
|
||||
|
|
@ -50,6 +51,13 @@ def normalize_drop_params(value: object) -> bool | None:
|
|||
return None
|
||||
|
||||
|
||||
def drop_params_flag(value: object, source: str, logger: logging.Logger) -> bool:
|
||||
normalized: Final = normalize_drop_params(value)
|
||||
if normalized is None and value is not None:
|
||||
logger.warning("%s=%r is not a flag value, treating it as off", source, value)
|
||||
return bool(normalized)
|
||||
|
||||
|
||||
def safe_divide(
|
||||
numerator: float,
|
||||
denominator: float,
|
||||
|
|
|
|||
|
|
@ -278,8 +278,8 @@ from litellm.litellm_core_utils.asyncify import asyncify
|
|||
from litellm.litellm_core_utils.audio_utils.utils import resolve_speech_media_type
|
||||
from litellm.litellm_core_utils.core_helpers import (
|
||||
_get_parent_otel_span_from_kwargs,
|
||||
drop_params_flag,
|
||||
get_litellm_metadata_from_kwargs,
|
||||
normalize_drop_params,
|
||||
)
|
||||
from litellm.litellm_core_utils.credential_accessor import CredentialAccessor
|
||||
from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj
|
||||
|
|
@ -5510,7 +5510,7 @@ class ProxyConfig:
|
|||
parse_budget_reset_time(value)
|
||||
setattr(litellm, key, value)
|
||||
elif key == "drop_params":
|
||||
litellm.drop_params = _drop_params_from_litellm_settings(value)
|
||||
litellm.drop_params = drop_params_flag(value, "litellm_settings.drop_params", verbose_proxy_logger)
|
||||
else:
|
||||
verbose_proxy_logger.debug(
|
||||
"%s setting litellm.%s=%s%s",
|
||||
|
|
@ -16915,13 +16915,6 @@ def _redact_config_param_value_for_logging(param_name: str | None, param_value:
|
|||
return param_value
|
||||
|
||||
|
||||
def _drop_params_from_litellm_settings(value: object) -> bool:
|
||||
normalized: Final = normalize_drop_params(value)
|
||||
if normalized is None and value is not None:
|
||||
verbose_proxy_logger.warning("litellm_settings.drop_params=%r is not a flag value, treating it as off", value)
|
||||
return bool(normalized)
|
||||
|
||||
|
||||
def _redact_general_setting_value(field_name: str, value: JsonValue, is_full_admin: bool) -> JsonValue:
|
||||
if is_full_admin:
|
||||
return value
|
||||
|
|
|
|||
|
|
@ -9366,6 +9366,12 @@ class Router:
|
|||
#### VALIDATE MODEL ########
|
||||
# Check if this is a prompt management model before validating as LLM provider
|
||||
litellm_model: Final = deployment.litellm_params.model
|
||||
if isinstance(deployment.litellm_params.drop_params, str):
|
||||
verbose_router_logger.warning(
|
||||
"model=%s drop_params=%r is not a flag value, treating it as unset",
|
||||
deployment.model_name,
|
||||
deployment.litellm_params.drop_params,
|
||||
)
|
||||
is_prompt_management_model = False
|
||||
|
||||
if "/" in litellm_model:
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
"""Tests for litellm_core_utils.core_helpers module."""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.litellm_core_utils.core_helpers import (
|
||||
_FINISH_REASON_MAP,
|
||||
drop_params_flag,
|
||||
get_or_create_metadata_bucket,
|
||||
map_finish_reason,
|
||||
normalize_drop_params,
|
||||
|
|
@ -284,6 +287,20 @@ def test_normalize_drop_params(value, expected):
|
|||
assert normalize_drop_params(value) is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value, expected", [("true", True), ("off", False), (None, False)])
|
||||
def test_drop_params_flag_returns_a_bool_without_a_warning(value, expected, caplog):
|
||||
with caplog.at_level(logging.WARNING, logger="drop-params-test"):
|
||||
assert drop_params_flag(value, "LITELLM_DROP_PARAMS", logging.getLogger("drop-params-test")) is expected
|
||||
assert caplog.text == ""
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["temperature", "ture", 2])
|
||||
def test_drop_params_flag_treats_non_flag_values_as_off_with_a_warning(value, caplog):
|
||||
with caplog.at_level(logging.WARNING, logger="drop-params-test"):
|
||||
assert drop_params_flag(value, "LITELLM_DROP_PARAMS", logging.getLogger("drop-params-test")) is False
|
||||
assert f"LITELLM_DROP_PARAMS={value!r} is not a flag value, treating it as off" in caplog.text
|
||||
|
||||
|
||||
class TestIsExpectedClientError:
|
||||
def test_status_ranges(self):
|
||||
from litellm.litellm_core_utils.core_helpers import is_expected_client_error
|
||||
|
|
|
|||
|
|
@ -5,13 +5,26 @@ import sys
|
|||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize("configured, expected", [("false", "False"), ("true", "True")])
|
||||
def test_litellm_drop_params_env_var_is_parsed_as_a_flag(configured, expected):
|
||||
result = subprocess.run(
|
||||
def _import_litellm_with(configured: str) -> subprocess.CompletedProcess[str]:
|
||||
return subprocess.run(
|
||||
[sys.executable, "-c", "import litellm; print(litellm.drop_params)"],
|
||||
env={**os.environ, "LITELLM_DROP_PARAMS": configured},
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("configured, expected", [("false", "False"), ("true", "True")])
|
||||
def test_litellm_drop_params_env_var_is_parsed_as_a_flag(configured, expected):
|
||||
result = _import_litellm_with(configured)
|
||||
|
||||
assert result.stdout.strip() == expected
|
||||
assert "is not a flag value" not in result.stderr
|
||||
|
||||
|
||||
def test_litellm_drop_params_env_var_non_flag_value_is_off_with_a_warning():
|
||||
result = _import_litellm_with("temperature")
|
||||
|
||||
assert result.stdout.strip() == "False"
|
||||
assert "LITELLM_DROP_PARAMS='temperature' is not a flag value, treating it as off" in result.stderr
|
||||
|
|
|
|||
|
|
@ -14424,3 +14424,36 @@ async def test_router_deployment_drop_params_string_true_is_honored(monkeypatch)
|
|||
temperature=0.1,
|
||||
)
|
||||
assert response.choices[0].message.content == "Hello, world!"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", ["ture", "enabled"])
|
||||
def test_router_warns_when_a_deployment_drop_params_string_is_not_a_flag(value, caplog):
|
||||
with caplog.at_level(logging.WARNING, logger="LiteLLM Router"):
|
||||
router = Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "gpt-5-nano",
|
||||
"litellm_params": {"model": "openai/gpt-5-nano", "api_key": "sk-fake", "drop_params": value},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
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 == value
|
||||
assert f"model=gpt-5-nano drop_params={value!r} is not a flag value, treating it as unset" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [True, "true", "off", None])
|
||||
def test_router_stays_quiet_when_a_deployment_drop_params_is_a_flag(value, caplog):
|
||||
with caplog.at_level(logging.WARNING, logger="LiteLLM Router"):
|
||||
Router(
|
||||
model_list=[
|
||||
{
|
||||
"model_name": "gpt-5-nano",
|
||||
"litellm_params": {"model": "openai/gpt-5-nano", "api_key": "sk-fake", "drop_params": value},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
assert "is not a flag value" not in caplog.text
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue