mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(guardrails): keep stable config id collision-safe for same-named guardrails
A deterministic per-name id made two config guardrails sharing a guardrail_name collide on the same id and hit the in-memory dedup early-return, so the second was dropped. Use the stable id for the first occurrence and fall back to a unique id on clash, preserving prior multi-registration behavior while keeping the id stable for the normal (unique-name, initialized-once) case. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
a4feb921fa
commit
ac1c69663f
2 changed files with 39 additions and 1 deletions
|
|
@ -438,7 +438,8 @@ class InMemoryGuardrailHandler:
|
|||
if provided_id:
|
||||
guardrail_id = provided_id
|
||||
elif source == "config":
|
||||
guardrail_id = get_stable_config_guardrail_id(guardrail["guardrail_name"])
|
||||
stable_id = get_stable_config_guardrail_id(guardrail["guardrail_name"])
|
||||
guardrail_id = stable_id if stable_id not in self.IN_MEMORY_GUARDRAILS else str(uuid.uuid4())
|
||||
else:
|
||||
guardrail_id = str(uuid.uuid4())
|
||||
guardrail["guardrail_id"] = guardrail_id
|
||||
|
|
|
|||
|
|
@ -405,6 +405,43 @@ def test_config_guardrail_id_is_stable_across_boots():
|
|||
registry_module.guardrail_initializer_registry.pop("stable_id_test", None)
|
||||
|
||||
|
||||
def test_same_name_config_guardrails_in_one_process_get_distinct_ids():
|
||||
"""
|
||||
The deterministic id must not collapse two same-named guardrails registered
|
||||
in one process into one entry (that would drop the second guardrail via the
|
||||
early-return dedup). The first occurrence gets the stable id; a later clash
|
||||
falls back to a unique id so both stay registered.
|
||||
"""
|
||||
from litellm.proxy.guardrails import guardrail_registry as registry_module
|
||||
|
||||
def _initializer(litellm_params, guardrail):
|
||||
return CustomGuardrail(
|
||||
guardrail_name=guardrail["guardrail_name"],
|
||||
event_hook=GuardrailEventHooks.pre_call,
|
||||
default_on=False,
|
||||
)
|
||||
|
||||
registry_module.guardrail_initializer_registry["dup_name_test"] = _initializer
|
||||
try:
|
||||
handler = InMemoryGuardrailHandler()
|
||||
params = {"guardrail": "dup_name_test", "mode": "pre_call"}
|
||||
|
||||
first = handler.initialize_guardrail(
|
||||
guardrail={"guardrail_name": "dup", "litellm_params": dict(params)},
|
||||
source="config",
|
||||
)
|
||||
second = handler.initialize_guardrail(
|
||||
guardrail={"guardrail_name": "dup", "litellm_params": dict(params)},
|
||||
source="config",
|
||||
)
|
||||
|
||||
assert first["guardrail_id"] == registry_module.get_stable_config_guardrail_id("dup")
|
||||
assert second["guardrail_id"] != first["guardrail_id"]
|
||||
assert len(handler.IN_MEMORY_GUARDRAILS) == 2
|
||||
finally:
|
||||
registry_module.guardrail_initializer_registry.pop("dup_name_test", None)
|
||||
|
||||
|
||||
def test_explicit_config_guardrail_id_is_preserved():
|
||||
"""An operator-provided guardrail_id must win over the derived-from-name id."""
|
||||
from litellm.proxy.guardrails import guardrail_registry as registry_module
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue