diff --git a/litellm/proxy/guardrails/guardrail_hooks/promptguard/promptguard.py b/litellm/proxy/guardrails/guardrail_hooks/promptguard/promptguard.py index c136b05c5f3..f37e36d2c43 100644 --- a/litellm/proxy/guardrails/guardrail_hooks/promptguard/promptguard.py +++ b/litellm/proxy/guardrails/guardrail_hooks/promptguard/promptguard.py @@ -148,6 +148,7 @@ class PromptGuardGuardrail(CustomGuardrail): "Content-Type": "application/json", }, json=payload, + timeout=10.0, ) response.raise_for_status() result = response.json() @@ -184,11 +185,14 @@ class PromptGuardGuardrail(CustomGuardrail): if redacted: if structured_messages: inputs["structured_messages"] = redacted - extracted = self._extract_texts_from_messages( - redacted, - ) - if extracted: - inputs["texts"] = extracted + if "texts" in inputs: + extracted = ( + self._extract_texts_from_messages( + redacted, + ) + ) + if extracted: + inputs["texts"] = extracted return inputs diff --git a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_promptguard.py b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_promptguard.py index 79ea62fa410..e5e2face752 100644 --- a/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_promptguard.py +++ b/tests/test_litellm/proxy/guardrails/guardrail_hooks/test_promptguard.py @@ -375,6 +375,37 @@ class TestPromptGuardRedactAction: assert result["structured_messages"] == redacted assert "My SSN is *********" in result["texts"] + @pytest.mark.asyncio + async def test_redact_structured_only_does_not_create_texts( + self, promptguard_guardrail, mock_request_data + ): + """When only structured_messages are provided, redact should not inject a texts key.""" + original = [ + {"role": "user", "content": "My SSN is 123-45-6789"}, + ] + redacted = [ + {"role": "user", "content": "My SSN is *********"}, + ] + resp = _make_response( + { + "decision": "redact", + "event_id": "evt-009", + "redacted_messages": redacted, + } + ) + with patch.object( + promptguard_guardrail.async_handler, + "post", + return_value=resp, + ): + result = await promptguard_guardrail.apply_guardrail( + inputs={"structured_messages": original}, + request_data=mock_request_data, + input_type="request", + ) + assert result["structured_messages"] == redacted + assert "texts" not in result + @pytest.mark.asyncio async def test_redact_texts_only_without_structured( self, promptguard_guardrail, mock_request_data