diff --git a/litellm/types/guardrails.py b/litellm/types/guardrails.py index 5ecc7d1cd1d..eea0a26b332 100644 --- a/litellm/types/guardrails.py +++ b/litellm/types/guardrails.py @@ -5,11 +5,6 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator from typing_extensions import Required, TypedDict -from litellm.types.llms.openai import ( - AllMessageValues, - ChatCompletionToolCallChunk, - ChatCompletionToolParam, -) from litellm.types.proxy.guardrails.guardrail_hooks.enkryptai import ( EnkryptAIGuardrailConfigs, ) @@ -673,20 +668,20 @@ class LitellmParams( description="When to apply the guardrail (pre_call, post_call, during_call, logging_only)" ) - @field_validator("default_action", mode="before", check_fields=False) - @classmethod - def normalize_default_action_litellm_params(cls, v): - """Normalize default_action to lowercase for ALL guardrail types.""" - if isinstance(v, str): - return v.lower() - return v - - @field_validator("on_disallowed_action", mode="before", check_fields=False) + @field_validator( + "mode", + "default_action", + "on_disallowed_action", + mode="before", + check_fields=False, + ) @classmethod - def normalize_on_disallowed_action_litellm_params(cls, v): - """Normalize on_disallowed_action to lowercase for ALL guardrail types.""" + def normalize_lowercase(cls, v): + """Normalize string and list fields to lowercase for ALL guardrail types.""" if isinstance(v, str): return v.lower() + if isinstance(v, list): + return [x.lower() if isinstance(x, str) else x for x in v] return v def __init__(self, **kwargs): @@ -695,7 +690,7 @@ def __init__(self, **kwargs): kwargs["default_on"] = default_on else: kwargs["default_on"] = False - + super().__init__(**kwargs) def __contains__(self, key): diff --git a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py index 5714cd5c487..7c151c80ae3 100644 --- a/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py +++ b/tests/litellm-proxy-extras/test_litellm_proxy_extras_utils.py @@ -2,8 +2,11 @@ import sys sys.path.insert( - 0, os.path.abspath("../..") -) # Adds the parent directory to the system path + 0, + os.path.abspath( + os.path.join(os.path.dirname(__file__), "../../litellm-proxy-extras") + ), +) from litellm_proxy_extras.utils import ProxyExtrasDBManager @@ -99,6 +102,11 @@ def test_is_idempotent_error_case_insensitive(self): error_message = "COLUMN 'ID' ALREADY EXISTS" assert ProxyExtrasDBManager._is_idempotent_error(error_message) is True + def test_is_idempotent_error_does_not_exist(self): + """Test detection of 'does not exist' error""" + error_message = "ERROR: index 'idx' does not exist" + assert ProxyExtrasDBManager._is_idempotent_error(error_message) is True + def test_is_idempotent_error_negative(self): """Test that non-idempotent errors are not detected as idempotent errors""" error_message = "Database error code: 42501 - permission denied"