mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
Merge f7954617cf into 7083c47998
This commit is contained in:
commit
6d9c2e4c87
2 changed files with 50 additions and 0 deletions
|
|
@ -14,6 +14,7 @@ from datetime import datetime
|
|||
from re import Pattern
|
||||
from typing import TYPE_CHECKING, Any, Final, Literal, Optional, TypedDict, cast
|
||||
|
||||
import openai
|
||||
import yaml
|
||||
from fastapi import HTTPException
|
||||
|
||||
|
|
@ -2056,6 +2057,13 @@ class ContentFilterGuardrail(CustomGuardrail):
|
|||
except HTTPException:
|
||||
status = "guardrail_intervened"
|
||||
raise
|
||||
except openai.OpenAIError as e:
|
||||
# Upstream provider/stream error propagating through the iterator.
|
||||
# The guardrail never evaluated content, so it must not be recorded
|
||||
# as a guardrail failure. "not_run" is the canonical status here.
|
||||
status = "not_run"
|
||||
exception_str = str(e)
|
||||
raise
|
||||
except Exception as e:
|
||||
status = "guardrail_failed_to_respond"
|
||||
exception_str = str(e)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import openai
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from litellm.proxy.guardrails.guardrail_hooks.litellm_content_filter.content_filter import (
|
||||
ContentFilterGuardrail,
|
||||
)
|
||||
from litellm.types.guardrails import GuardrailEventHooks
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_streaming_hook_upstream_error_is_not_run():
|
||||
"""
|
||||
When the upstream stream raises a provider error (openai.OpenAIError
|
||||
subclass), the content filter never evaluates content. The error must
|
||||
propagate unchanged and be logged as "not_run", not as a guardrail
|
||||
failure. Regression test for issue #31004.
|
||||
"""
|
||||
guardrail = ContentFilterGuardrail(
|
||||
guardrail_name="test-streaming-upstream-error",
|
||||
patterns=[],
|
||||
event_hook=GuardrailEventHooks.during_call,
|
||||
)
|
||||
|
||||
async def mock_stream():
|
||||
raise openai.APIError("Provider returned error", request=MagicMock(), body=None)
|
||||
yield # pragma: no cover - makes this an async generator
|
||||
|
||||
user_api_key_dict = MagicMock()
|
||||
request_data: dict = {}
|
||||
|
||||
with pytest.raises(openai.APIError):
|
||||
async for _ in guardrail.async_post_call_streaming_iterator_hook(
|
||||
user_api_key_dict=user_api_key_dict,
|
||||
response=mock_stream(),
|
||||
request_data=request_data,
|
||||
):
|
||||
pass
|
||||
|
||||
info = request_data["metadata"]["standard_logging_guardrail_information"][0]
|
||||
assert info["guardrail_status"] == "not_run"
|
||||
Loading…
Add table
Reference in a new issue