diff --git a/litellm/__init__.py b/litellm/__init__.py index 62477dd6264..fc6dc35fe55 100644 --- a/litellm/__init__.py +++ b/litellm/__init__.py @@ -47,6 +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 drop_params_env_flag from litellm._logging import ( set_verbose, _turn_on_debug, @@ -238,7 +239,7 @@ token: Optional[str] = ( ) telemetry = True max_tokens: int = DEFAULT_MAX_TOKENS # OpenAI Defaults -drop_params = bool(os.getenv("LITELLM_DROP_PARAMS", False)) +drop_params = drop_params_env_flag(os.environ, 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) diff --git a/litellm/litellm_core_utils/core_helpers.py b/litellm/litellm_core_utils/core_helpers.py index 2cdcfe4879c..eacc3e4860a 100644 --- a/litellm/litellm_core_utils/core_helpers.py +++ b/litellm/litellm_core_utils/core_helpers.py @@ -1,10 +1,12 @@ # What is this? ## Helper utilities import copy +import logging from collections.abc import Iterable, Mapping from typing import TYPE_CHECKING, Any, Final, Literal import httpx +from pydantic import TypeAdapter, ValidationError from litellm._logging import verbose_logger from litellm.types.llms.openai import AllMessageValues, OpenAIChatCompletionFinishReason @@ -37,6 +39,41 @@ def safe_divide_seconds(seconds: float, denominator: float, default: float | Non return float(seconds / denominator) +_DROP_PARAMS_BOOL: Final = TypeAdapter(bool) + + +def normalize_drop_params(value: object) -> bool | None: + if value is None or isinstance(value, bool): + return value + try: + return _DROP_PARAMS_BOOL.validate_python(value.strip() if isinstance(value, str) else value) + except ValidationError: + 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) + + +DROP_PARAMS_ENV_VAR: Final = "LITELLM_DROP_PARAMS" + + +def drop_params_env_flag(environ: Mapping[str, str], logger: logging.Logger) -> bool: + configured: Final = environ.get(DROP_PARAMS_ENV_VAR, "").strip() + if configured == "": + return False + normalized: Final = normalize_drop_params(configured) + if normalized is None: + logger.warning( + "%s=%r is not a flag value, treating it as on. Set it to true or false", DROP_PARAMS_ENV_VAR, configured + ) + return True + return normalized + + def safe_divide( numerator: float, denominator: float, diff --git a/litellm/litellm_core_utils/get_litellm_params.py b/litellm/litellm_core_utils/get_litellm_params.py index 1fd79db15a6..92b32d32dc0 100644 --- a/litellm/litellm_core_utils/get_litellm_params.py +++ b/litellm/litellm_core_utils/get_litellm_params.py @@ -2,6 +2,7 @@ from collections.abc import Mapping, MutableMapping from types import MappingProxyType from typing import Final +from litellm.litellm_core_utils.core_helpers import normalize_drop_params from litellm.llms.openai.data_residency import infer_openai_data_residency AWS_CREDENTIAL_KWARGS_KEYS: Final = frozenset( @@ -113,7 +114,7 @@ def get_litellm_params( custom_prompt_dict: dict | None = None, litellm_metadata: dict | None = None, disable_add_transform_inline_image_block: bool | None = None, - drop_params: bool | None = None, + drop_params: bool | str | None = None, prompt_id: str | None = None, prompt_variables: dict | None = None, async_call: bool | None = None, @@ -175,7 +176,7 @@ def get_litellm_params( "custom_prompt_dict": custom_prompt_dict, "litellm_metadata": litellm_metadata, "disable_add_transform_inline_image_block": disable_add_transform_inline_image_block, - "drop_params": drop_params, + "drop_params": normalize_drop_params(drop_params), "prompt_id": prompt_id, "prompt_variables": prompt_variables, "async_call": async_call, diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 238fd841ce1..a617aec9f5c 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -278,6 +278,7 @@ 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, ) from litellm.litellm_core_utils.credential_accessor import CredentialAccessor @@ -5519,6 +5520,8 @@ class ProxyConfig: parse_budget_reset_time(value) setattr(litellm, key, value) + elif key == "drop_params": + 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", diff --git a/litellm/responses/main.py b/litellm/responses/main.py index fa14eb5f3c4..7a210cdd970 100644 --- a/litellm/responses/main.py +++ b/litellm/responses/main.py @@ -17,6 +17,7 @@ from litellm.completion_extras.litellm_responses_transformation.transformation i from litellm.constants import request_timeout from litellm.integrations.anthropic_cache_control_hook import CARRY_UNMATCHED_MESSAGE_POINTS from litellm.litellm_core_utils.asyncify import run_async_function +from litellm.litellm_core_utils.core_helpers import normalize_drop_params from litellm.litellm_core_utils.litellm_logging import Logging as LiteLLMLoggingObj from litellm.litellm_core_utils.prompt_templates.common_utils import ( update_responses_input_with_model_file_ids, @@ -1257,7 +1258,7 @@ def responses( responses_api_provider_config=responses_api_provider_config, response_api_optional_params=response_api_optional_params, allowed_openai_params=allowed_openai_params, - drop_params=request_drop_params if isinstance(request_drop_params, bool) else None, + drop_params=normalize_drop_params(request_drop_params), ) litellm_logging_obj.update_from_kwargs( @@ -2085,7 +2086,7 @@ def compact_responses( responses_api_provider_config=responses_api_provider_config, response_api_optional_params=response_api_optional_params, allowed_openai_params=None, - drop_params=request_drop_params if isinstance(request_drop_params, bool) else None, + drop_params=normalize_drop_params(request_drop_params), ) # Pre Call logging diff --git a/litellm/router.py b/litellm/router.py index b0a1ddd164e..e1095fe26f3 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -9420,6 +9420,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: diff --git a/litellm/types/router.py b/litellm/types/router.py index 0db482d8a58..5c9eab30f3d 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -12,7 +12,9 @@ import httpx from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from typing_extensions import Protocol, ReadOnly, Required, TypedDict, runtime_checkable +from litellm._logging import verbose_logger from litellm._uuid import uuid +from litellm.litellm_core_utils.core_helpers import normalize_drop_params if TYPE_CHECKING: from litellm.router import Router @@ -314,6 +316,7 @@ class GenericLiteLLMParams(CredentialLiteLLMParams, CustomPricingLiteLLMParams): timeout: float | str | httpx.Timeout | None = None # if str, pass in as os.environ/ stream_timeout: float | str | None = None # timeout when making stream=True calls, if str, pass in as os.environ/ max_retries: int | None = None + drop_params: bool | str | None = None organization: str | None = None # for openai orgs configurable_clientside_auth_params: CONFIGURABLE_CLIENTSIDE_AUTH_PARAMS = None litellm_credential_name: str | None = None @@ -404,6 +407,18 @@ class GenericLiteLLMParams(CredentialLiteLLMParams, CustomPricingLiteLLMParams): return filtered return data + @field_validator("drop_params", mode="before") + @classmethod + def coerce_drop_params(cls, value: object) -> bool | str | None: + normalized: Final = normalize_drop_params(value) + if normalized is not None: + return normalized + if isinstance(value, str): + return value + if value is not None: + verbose_logger.warning("drop_params=%r is not a flag value, treating it as unset", value) + return None + def __contains__(self, key) -> bool: # Define custom behavior for the 'in' operator return hasattr(self, key) diff --git a/litellm/utils.py b/litellm/utils.py index 141ec323776..33ef57e1837 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -80,6 +80,7 @@ from litellm.constants import ( PROVIDERS_THAT_AUTHENTICATE_ON_PROVIDER_INFO, TOOL_CHOICE_OBJECT_TOKEN_COUNT, ) +from litellm.litellm_core_utils.core_helpers import normalize_drop_params from litellm.litellm_core_utils.fallback_generalizations import ( match_capability_generalizations, ) @@ -3239,7 +3240,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: Final[Mapping[str, object]] = passed_params.pop("kwargs") for k, v in special_params.items(): passed_params[k] = v @@ -3347,7 +3348,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: Final[Mapping[str, object]] = passed_params.pop("kwargs") for k, v in special_params.items(): @@ -3475,7 +3476,7 @@ def get_optional_params_embeddings( custom_llm_provider = passed_params.pop("custom_llm_provider", None) special_params: Final = 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 @@ -4202,6 +4203,7 @@ def get_optional_params( base_model: str | None = None, **kwargs, ): + drop_params = normalize_drop_params(drop_params) # rebind-ok: config and DB deployments pass "true" as a string passed_params: Final = locals().copy() special_params: Final = passed_params.pop("kwargs") # Remove base_model from passed_params so it doesn't interfere with @@ -4279,20 +4281,20 @@ def get_optional_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "anthropic_text": optional_params = litellm.AnthropicTextConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) optional_params = litellm.AnthropicTextConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "cohere_chat" or custom_llm_provider == "cohere": @@ -4301,14 +4303,14 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "triton": optional_params = litellm.TritonConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=drop_params if drop_params is not None else False, + drop_params=bool(drop_params), ) elif custom_llm_provider == "maritalk": @@ -4316,35 +4318,35 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "replicate": optional_params = litellm.ReplicateConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "predibase": optional_params = litellm.PredibaseConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "huggingface": optional_params = litellm.HuggingFaceChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "together_ai": optional_params = litellm.TogetherAIChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "vertex_ai" and ( model in litellm.vertex_chat_models @@ -4358,7 +4360,7 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "gemini": @@ -4366,21 +4368,21 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "vertex_ai_beta" or (custom_llm_provider == "vertex_ai" and "gemini" in model): optional_params = litellm.VertexGeminiConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif litellm.VertexAIAnthropicConfig.is_supported_model(model=model, custom_llm_provider=custom_llm_provider): optional_params = litellm.VertexAIAnthropicConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "vertex_ai": if model in litellm.vertex_mistral_models: @@ -4389,35 +4391,35 @@ def get_optional_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) else: optional_params = litellm.MistralConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif model in litellm.vertex_ai_ai21_models: optional_params = litellm.VertexAIAi21Config().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif provider_config is not None: optional_params = provider_config.map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) else: # use generic openai-like param mapping optional_params = litellm.VertexAILlama3Config().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "sagemaker": @@ -4426,7 +4428,7 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "bedrock": BedrockModelInfo: Final = getattr(sys.modules[__name__], "BedrockModelInfo") @@ -4437,14 +4439,14 @@ def get_optional_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif bedrock_route == "openai": optional_params = litellm.AmazonBedrockOpenAIConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif "anthropic" in bedrock_base_model and bedrock_route == "invoke": if bedrock_base_model in litellm.AmazonAnthropicConfig.get_legacy_anthropic_model_names(): @@ -4452,21 +4454,21 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) else: optional_params = litellm.AmazonAnthropicClaudeConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif provider_config is not None: optional_params = provider_config.map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) if bedrock_route == "claude_platform": optional_params = BedrockModelInfo.map_claude_platform_auth_params( @@ -4477,28 +4479,28 @@ def get_optional_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "ollama": optional_params = litellm.OllamaConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "ollama_chat": optional_params = litellm.OllamaChatConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "nlp_cloud": optional_params = litellm.NLPCloudConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "petals": @@ -4506,35 +4508,35 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "deepinfra": optional_params = litellm.DeepInfraConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "perplexity" and provider_config is not None: optional_params = provider_config.map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "mistral" or custom_llm_provider == "codestral": optional_params = litellm.MistralConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "text-completion-codestral": optional_params = litellm.CodestralTextCompletionConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "text-completion-inception": @@ -4542,7 +4544,7 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "databricks": @@ -4550,21 +4552,21 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "nvidia_nim": optional_params = litellm.NvidiaNimConfig().map_openai_params( model=model, non_default_params=non_default_params, optional_params=optional_params, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "cerebras": optional_params = litellm.CerebrasConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "xai": optional_params = litellm.XAIChatConfig().map_openai_params( @@ -4577,77 +4579,77 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "fireworks_ai": optional_params = litellm.FireworksAIConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "volcengine": optional_params = litellm.VolcEngineConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "hosted_vllm": optional_params = litellm.HostedVLLMChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "vllm": optional_params = litellm.VLLMConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "groq": optional_params = litellm.GroqChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "bedrock_mantle": optional_params = litellm.BedrockMantleChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "deepseek": optional_params = litellm.DeepSeekChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "tencent": optional_params = litellm.TencentChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "openrouter": optional_params = litellm.OpenrouterConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "watsonx": optional_params = litellm.IBMWatsonXChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) # WatsonX-text param check for param in passed_params: @@ -4660,21 +4662,21 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "openai": optional_params = litellm.OpenAIConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "nebius": optional_params = litellm.NebiusConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif custom_llm_provider == "azure": _azure_detection_model: Final = base_model or model @@ -4683,14 +4685,14 @@ def get_optional_params( non_default_params=non_default_params, optional_params=optional_params, model=_azure_detection_model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif litellm.AzureOpenAIGPT5Config.is_model_gpt_5_model(model=_azure_detection_model): optional_params = litellm.AzureOpenAIGPT5Config().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=_azure_detection_model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) else: verbose_logger.debug( @@ -4709,21 +4711,21 @@ def get_optional_params( optional_params=optional_params, model=_azure_detection_model, api_version=api_version, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) elif provider_config is not None: optional_params = provider_config.map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) else: # assume passing in params for openai-like api optional_params = litellm.OpenAILikeChatConfig().map_openai_params( non_default_params=non_default_params, optional_params=optional_params, model=model, - drop_params=(drop_params if drop_params is not None and isinstance(drop_params, bool) else False), + drop_params=bool(drop_params), ) # if user passed in non-default kwargs for specific providers/models, pass them along optional_params = add_provider_specific_params_to_optional_params( diff --git a/tests/test_litellm/litellm_core_utils/test_core_helpers.py b/tests/test_litellm/litellm_core_utils/test_core_helpers.py index 93cb01e1969..e937be47441 100644 --- a/tests/test_litellm/litellm_core_utils/test_core_helpers.py +++ b/tests/test_litellm/litellm_core_utils/test_core_helpers.py @@ -1,11 +1,16 @@ """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_env_flag, + drop_params_flag, get_or_create_metadata_bucket, map_finish_reason, + normalize_drop_params, reconstruct_model_name, redact_nested_match_and_regex_keys, ) @@ -257,6 +262,73 @@ class TestRedactNestedMatchAndRegexKeys: 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), + ("yes", True), + ("off", False), + ("1", True), + (1, True), + (0, False), + (None, None), + ("", None), + ("os.environ/DROP_PARAMS", None), + ("v2:gcm:not-a-flag", None), + (2, None), + ], +) +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 + + +@pytest.mark.parametrize( + "environ, expected", + [ + ({}, False), + ({"LITELLM_DROP_PARAMS": ""}, False), + ({"LITELLM_DROP_PARAMS": " "}, False), + ({"LITELLM_DROP_PARAMS": "true"}, True), + ({"LITELLM_DROP_PARAMS": " False "}, False), + ({"LITELLM_DROP_PARAMS": "0"}, False), + ], +) +def test_drop_params_env_flag_reads_a_flag_without_a_warning(environ, expected, caplog): + with caplog.at_level(logging.WARNING, logger="drop-params-test"): + assert drop_params_env_flag(environ, logging.getLogger("drop-params-test")) is expected + assert caplog.text == "" + + +@pytest.mark.parametrize("configured", ["temperature", "temperature,top_p", "enabled"]) +def test_drop_params_env_flag_keeps_a_non_flag_value_on_with_a_warning(configured, caplog): + with caplog.at_level(logging.WARNING, logger="drop-params-test"): + assert drop_params_env_flag({"LITELLM_DROP_PARAMS": configured}, logging.getLogger("drop-params-test")) is True + assert ( + f"LITELLM_DROP_PARAMS={configured!r} is not a flag value, treating it as on. Set it to true or false" + in caplog.text + ) + + class TestIsExpectedClientError: def test_status_ranges(self): from litellm.litellm_core_utils.core_helpers import is_expected_client_error diff --git a/tests/test_litellm/litellm_core_utils/test_get_litellm_params.py b/tests/test_litellm/litellm_core_utils/test_get_litellm_params.py index fb4cb494bee..f026ff57719 100644 --- a/tests/test_litellm/litellm_core_utils/test_get_litellm_params.py +++ b/tests/test_litellm/litellm_core_utils/test_get_litellm_params.py @@ -215,3 +215,11 @@ class TestMetadataFallsBackToLitellmMetadata: assert result["metadata"] is not litellm_metadata result["metadata"].pop("trace_id") assert litellm_metadata == {"trace_id": "trace-1"} + + +@pytest.mark.parametrize( + "value, expected", + [("true", True), ("false", False), (" TRUE ", True), (True, True), (None, None), ("os.environ/DROP_PARAMS", None)], +) +def test_drop_params_strings_reach_litellm_params_as_flags(value, expected): + assert get_litellm_params(drop_params=value)["drop_params"] is expected diff --git a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py index d90338f8480..c02f886fc31 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py @@ -30,7 +30,7 @@ from litellm.proxy.management_endpoints.model_management_endpoints import ( ) from litellm.proxy.utils import PrismaClient from litellm.router import Router -from litellm.types.router import Deployment, LiteLLM_Params, updateDeployment +from litellm.types.router import Deployment, LiteLLM_Params, ModelInfo, updateDeployment, updateLiteLLMParams async def _passthrough_row(update_data): @@ -3070,6 +3070,31 @@ class TestUpdateDBModelBlocked: assert "blocked" not in result +class TestUpdateDBModelKeepsLegacyDropParams: + def test_partial_patch_keeps_encrypted_string_drop_params(self, monkeypatch): + from litellm.proxy.common_utils.encrypt_decrypt_utils import decrypt_value_helper + from litellm.proxy.management_endpoints.model_management_endpoints import update_db_model + + monkeypatch.setenv("LITELLM_SALT_KEY", "sk-1234") + legacy_row = Deployment( + model_name="gpt-5-nano", + litellm_params=LiteLLM_Params( + model="openai/gpt-5-nano", + api_key=encrypt_value_helper(value="sk-old"), + drop_params=encrypt_value_helper(value="true"), + ), + model_info=ModelInfo(id="legacy-row"), + ) + + result = update_db_model( + db_model=legacy_row, + updated_patch=updateDeployment(litellm_params=updateLiteLLMParams(api_key="sk-new")), + ) + + stored = json.loads(result["litellm_params"]) + assert decrypt_value_helper(value=stored["drop_params"], key="drop_params") == "true" + + def _build_db_model_with_pricing(): """Wildcard deployment with custom pricing in litellm_params; Deployment.__init__ mirrors SPECIAL_MODEL_INFO_PARAMS into model_info, so both blobs hold the rate.""" diff --git a/tests/test_litellm/proxy/proxy_server/test_proxy_config.py b/tests/test_litellm/proxy/proxy_server/test_proxy_config.py index ae4ec4086bb..e79448d0620 100644 --- a/tests/test_litellm/proxy/proxy_server/test_proxy_config.py +++ b/tests/test_litellm/proxy/proxy_server/test_proxy_config.py @@ -20,6 +20,7 @@ import pytest import litellm from litellm.proxy._types import CommonProxyErrors +from litellm.proxy.common_utils.encrypt_decrypt_utils import encrypt_value_helper from litellm.proxy.proxy_server import ( ProxyConfig, _is_remote_module_url, @@ -2428,6 +2429,111 @@ def test_ProxyConfig__add_deployment_resolves_env_refs_on_arbitrary_field(monkey assert deployment.litellm_params.some_future_field == "resolved-custom-value" +@pytest.mark.parametrize( + "stored_drop_params", + ["true", "os.environ/DROP_PARAMS_FLAG"], +) +def test_ProxyConfig__add_deployment_turns_stored_drop_params_string_into_bool(monkeypatch, stored_drop_params): + monkeypatch.setenv("LITELLM_SALT_KEY", "sk-1234") + monkeypatch.setenv("DROP_PARAMS_FLAG", "true") + fake_router = MagicMock() + fake_router.upsert_deployment = MagicMock(return_value=True) + monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", fake_router) + pc = ProxyConfig() + db_model = SimpleNamespace( + model_id="model-1", + model_name="gpt-5-nano", + model_info={"id": "model-1"}, + litellm_params={ + "model": encrypt_value_helper(value="openai/gpt-5-nano"), + "drop_params": encrypt_value_helper(value=stored_drop_params), + }, + blocked=False, + ) + + added = pc._add_deployment(db_models=[db_model]) + deployment = fake_router.upsert_deployment.call_args.kwargs["deployment"] + + assert added == 1 + assert deployment.litellm_params.drop_params is True + + +def test_ProxyConfig__add_deployment_keeps_loading_rows_after_a_non_flag_drop_params(monkeypatch): + monkeypatch.setenv("LITELLM_SALT_KEY", "sk-1234") + fake_router = MagicMock() + fake_router.upsert_deployment = MagicMock(return_value=True) + monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", fake_router) + pc = ProxyConfig() + + def db_model(model_id, drop_params): + return SimpleNamespace( + model_id=model_id, + model_name="gpt-5-nano", + model_info={"id": model_id}, + litellm_params={ + "model": encrypt_value_helper(value="openai/gpt-5-nano"), + "drop_params": encrypt_value_helper(value=drop_params), + }, + blocked=False, + ) + + added = pc._add_deployment(db_models=[db_model("bad-row", 2), db_model("good-after", "true")]) + deployments = [call.kwargs["deployment"] for call in fake_router.upsert_deployment.call_args_list] + + assert added == 2 + assert [d.litellm_params.drop_params for d in deployments] == [None, True] + + +@pytest.mark.asyncio +@pytest.mark.parametrize("configured, expected", [("true", True), ("false", False)]) +async def test_ProxyConfig_load_config_turns_litellm_settings_drop_params_string_into_bool( + tmp_path, monkeypatch, configured, expected +): + f = tmp_path / "c.yaml" + f.write_text(f'model_list: []\nlitellm_settings:\n drop_params: "{configured}"\n') + monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None) + monkeypatch.setattr("litellm.proxy.proxy_server.store_model_in_db", False) + monkeypatch.delenv("LITELLM_CONFIG_BUCKET_NAME", raising=False) + monkeypatch.setattr(litellm, "drop_params", not expected) + + await ProxyConfig().load_config(router=None, config_file_path=str(f)) + + assert litellm.drop_params is expected + + +@pytest.mark.asyncio +async def test_ProxyConfig_load_config_resolves_a_litellm_settings_drop_params_env_ref(tmp_path, monkeypatch): + f = tmp_path / "c.yaml" + f.write_text("model_list: []\nlitellm_settings:\n drop_params: os.environ/DROP_PARAMS_FROM_ENV\n") + monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None) + monkeypatch.setattr("litellm.proxy.proxy_server.store_model_in_db", False) + monkeypatch.delenv("LITELLM_CONFIG_BUCKET_NAME", raising=False) + monkeypatch.setenv("DROP_PARAMS_FROM_ENV", "true") + monkeypatch.setattr(litellm, "drop_params", False) + + await ProxyConfig().load_config(router=None, config_file_path=str(f)) + + assert litellm.drop_params is True + + +@pytest.mark.asyncio +async def test_ProxyConfig_load_config_warns_and_turns_off_a_non_flag_litellm_settings_drop_params( + tmp_path, monkeypatch, caplog +): + f = tmp_path / "c.yaml" + f.write_text("model_list: []\nlitellm_settings:\n drop_params: ture\n") + monkeypatch.setattr("litellm.proxy.proxy_server.prisma_client", None) + monkeypatch.setattr("litellm.proxy.proxy_server.store_model_in_db", False) + monkeypatch.delenv("LITELLM_CONFIG_BUCKET_NAME", raising=False) + monkeypatch.setattr(litellm, "drop_params", True) + + with caplog.at_level(logging.WARNING, logger="LiteLLM Proxy"): + await ProxyConfig().load_config(router=None, config_file_path=str(f)) + + assert litellm.drop_params is False + assert "litellm_settings.drop_params='ture' is not a flag value, treating it as off" in caplog.text + + # --------------------------------------------------------------------------- # ProxyConfig.decrypt_model_list_from_db # --------------------------------------------------------------------------- diff --git a/tests/test_litellm/responses/test_responses_api_request_body.py b/tests/test_litellm/responses/test_responses_api_request_body.py index 3e60906ec6d..5fced458208 100644 --- a/tests/test_litellm/responses/test_responses_api_request_body.py +++ b/tests/test_litellm/responses/test_responses_api_request_body.py @@ -246,8 +246,10 @@ async def test_aresponses_keeps_include_obfuscation_in_stream_options(): @pytest.mark.asyncio +@pytest.mark.parametrize("drop_params", [True, "true"]) async def test_aresponses_request_level_drop_params_drops_bedrock_mantle_service_tier( monkeypatch, + drop_params, ): """ Request-level drop_params=True (as the proxy injects for agentic CLIs) must @@ -271,7 +273,7 @@ async def test_aresponses_request_level_drop_params_drops_bedrock_mantle_service aws_region_name="us-east-1", input="hi", service_tier="priority", - drop_params=True, + drop_params=drop_params, ) mock_post.assert_called_once() diff --git a/tests/test_litellm/test_drop_params_env_var.py b/tests/test_litellm/test_drop_params_env_var.py new file mode 100644 index 00000000000..1e0b7801ef1 --- /dev/null +++ b/tests/test_litellm/test_drop_params_env_var.py @@ -0,0 +1,33 @@ +import os +import subprocess +import sys + +import pytest + + +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"), ("", "False")]) +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_stays_on_with_a_warning(): + result = _import_litellm_with("temperature") + + assert result.stdout.strip() == "True" + assert ( + "LITELLM_DROP_PARAMS='temperature' is not a flag value, treating it as on. Set it to true or false" + in result.stderr + ) diff --git a/tests/test_litellm/test_router.py b/tests/test_litellm/test_router.py index 29df6df0477..7bfde0def09 100644 --- a/tests/test_litellm/test_router.py +++ b/tests/test_litellm/test_router.py @@ -14434,3 +14434,70 @@ async def test_router_max_parallel_requests_slot_released_when_stream_closed_ear assert tracker.peak == 1 assert tracker.current == 0 + + +@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!" + + +@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 diff --git a/tests/test_litellm/test_utils.py b/tests/test_litellm/test_utils.py index 4ce68b71079..fee5e3a2e4c 100644 --- a/tests/test_litellm/test_utils.py +++ b/tests/test_litellm/test_utils.py @@ -6094,6 +6094,34 @@ class TestFinalOptionalParamsLineRedaction: assert "'temperature': 0.25" in printed +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, + ) + + def _credential_warnings(caplog: pytest.LogCaptureFixture) -> list[str]: return [record.getMessage() for record in caplog.records if "litellm_credential_name=" in record.getMessage()] diff --git a/tests/test_litellm/types/test_router.py b/tests/test_litellm/types/test_router.py index accd3b32a0d..fd933a9d993 100644 --- a/tests/test_litellm/types/test_router.py +++ b/tests/test_litellm/types/test_router.py @@ -1,8 +1,11 @@ +import logging + import pytest from litellm.types.router import ( SPECIAL_MODEL_INFO_PARAMS, Deployment, + GenericLiteLLMParams, LiteLLM_Params, ModelInfo, ) @@ -89,3 +92,33 @@ def test_pricing_strings_are_coerced_to_float(): def test_invalid_pricing_is_rejected(): with pytest.raises(ValueError, match='validation error for ModelInfo'): ModelInfo(id="x", input_cost_per_token="free") + + +@pytest.mark.parametrize( + "value, expected", + [ + (True, True), + ("true", True), + (" False ", False), + ("yes", True), + (None, None), + ("os.environ/DROP_PARAMS", "os.environ/DROP_PARAMS"), + ("v2:gcm:ciphertext-from-a-pre-fix-row", "v2:gcm:ciphertext-from-a-pre-fix-row"), + ], +) +def test_drop_params_coerces_flags_and_keeps_unresolved_strings(value, expected): + assert GenericLiteLLMParams(drop_params=value).drop_params == expected + + +@pytest.mark.parametrize("value", [2, 2.5, [], {}]) +def test_drop_params_ignores_non_flag_non_string_values_with_a_warning(value, caplog): + with caplog.at_level(logging.WARNING, logger="LiteLLM"): + assert GenericLiteLLMParams(drop_params=value).drop_params is None + assert f"drop_params={value!r} is not a flag value" in caplog.text + + +@pytest.mark.parametrize("value", [True, "true", None, "os.environ/DROP_PARAMS", "v2:gcm:ciphertext-from-a-pre-fix-row"]) +def test_drop_params_flags_and_strings_log_nothing(value, caplog): + with caplog.at_level(logging.WARNING, logger="LiteLLM"): + GenericLiteLLMParams(drop_params=value) + assert caplog.text == "" diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index b52f0922390..cf486b4d612 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -29449,6 +29449,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 | string | null; /** Gcs Bucket Name */ gcs_bucket_name?: string | null; /** Google Maps Grounding Cost Per Query */ @@ -39632,6 +39634,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 | string | null; /** Gcs Bucket Name */ gcs_bucket_name?: string | null; /** Google Maps Grounding Cost Per Query */