mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-30 06:43:27 +00:00
fix(guardrails): keep the privaite restore map out of background request state
Background Responses results are fetched by a later poll that the post-call success and streaming hooks never see, so the fake-to-original map stashed in request metadata would persist in stored request state with no consumer left to pop it. The pre-call hook now skips the stash for background requests; those responses keep their placeholders, which is the fail-closed behavior. Regression test included.
This commit is contained in:
parent
66eb3d56ad
commit
6c6dfcaee1
2 changed files with 24 additions and 1 deletions
|
|
@ -282,10 +282,18 @@ class PrivaiteGuardrail(CustomGuardrail):
|
|||
|
||||
raise HTTPException(status_code=400, detail={"error": str(exc)}) from exc
|
||||
|
||||
if mapping is not None and self.deanonymize and not mapping.is_empty:
|
||||
if (
|
||||
mapping is not None
|
||||
and self.deanonymize
|
||||
and not mapping.is_empty
|
||||
and not data.get("background")
|
||||
):
|
||||
# Carry a plain fake->original dict to the post-call hook on the same
|
||||
# request, the same channel LiteLLM's Presidio guardrail uses. The
|
||||
# post-call hook pops it again so it does not linger in metadata.
|
||||
# Background requests are excluded: their result is fetched by a later
|
||||
# poll the post-call hooks never see, so the map would persist in
|
||||
# request state with no consumer; those responses keep placeholders.
|
||||
data.setdefault("metadata", {})["privaite_map"] = dict(mapping.get_all_fakes())
|
||||
return data
|
||||
|
||||
|
|
|
|||
|
|
@ -347,6 +347,21 @@ async def test_pre_call_without_pii_does_not_stash():
|
|||
assert "privaite_map" not in out.get("metadata", {})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pre_call_background_request_anonymizes_but_does_not_stash():
|
||||
# Background results are fetched by a later poll the post-call hooks never
|
||||
# see, so the fake->original map must not persist in request state.
|
||||
gr = _make_guardrail()
|
||||
data = {
|
||||
"input": "Email Marie Dupont at marie@acme.com",
|
||||
"background": True,
|
||||
}
|
||||
out = await gr.async_pre_call_hook(None, None, data, "aresponses")
|
||||
assert "Marie Dupont" not in out["input"]
|
||||
assert "<PERSON_1>" in out["input"]
|
||||
assert "privaite_map" not in out.get("metadata", {})
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_pre_call_clears_client_supplied_map():
|
||||
# metadata is caller-controlled: a client-supplied privaite_map must be
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue