fix: anthropic during call guardrail error

This commit is contained in:
Yuta Saito
2026-01-14 13:37:01 +09:00
parent 2ea6fcb584
commit c5ced033c9
4 changed files with 45 additions and 65 deletions
+1 -16
View File
@@ -649,9 +649,7 @@ class ProxyBaseLLMRequestProcessing:
proxy_logging_obj.during_call_hook(
data=self.data,
user_api_key_dict=user_api_key_dict,
call_type=ProxyBaseLLMRequestProcessing._get_pre_call_type(
route_type=route_type # type: ignore
),
call_type=route_type, # type: ignore
)
)
@@ -1004,19 +1002,6 @@ class ProxyBaseLLMRequestProcessing:
headers=headers,
)
@staticmethod
def _get_pre_call_type(
route_type: Literal["acompletion", "aembedding", "aresponses", "allm_passthrough_route"],
) -> Literal["completion", "embedding", "responses", "allm_passthrough_route"]:
if route_type == "acompletion":
return "completion"
elif route_type == "aembedding":
return "embedding"
elif route_type == "aresponses":
return "responses"
elif route_type == "allm_passthrough_route":
return "allm_passthrough_route"
#########################################################
# Proxy Level Streaming Data Generator
#########################################################
@@ -640,10 +640,6 @@ def test_embedding(mock_aembedding, client_no_auth):
pre_call_kwargs.get("call_type") == "aembedding"
), f"expected pre_call_hook to receive call_type='aembedding', got {pre_call_kwargs.get('call_type')}"
during_call_kwargs = mock_during_hook.await_args_list[0].kwargs
assert (
during_call_kwargs.get("call_type") == "embedding"
), f"expected during_call_hook to receive call_type='embedding', got {during_call_kwargs.get('call_type')}"
except Exception as e:
pytest.fail(f"LiteLLM Proxy test failed. Exception - {str(e)}")
@@ -492,51 +492,6 @@ class TestCustomGuardrailPassthroughSupport:
assert result is True
class TestPassthroughCallTypeHandling:
"""Tests for passthrough call type handling in common_request_processing."""
def test_get_pre_call_type_with_allm_passthrough_route(self):
"""
Test that _get_pre_call_type correctly maps allm_passthrough_route.
This tests Fix #1: allm_passthrough_route was not being handled, causing call_type to be None.
"""
from litellm.proxy.common_request_processing import (
ProxyBaseLLMRequestProcessing,
)
# Test the mapping
result = ProxyBaseLLMRequestProcessing._get_pre_call_type(
route_type="allm_passthrough_route"
)
# Should return allm_passthrough_route, not None
assert result == "allm_passthrough_route"
def test_get_pre_call_type_preserves_standard_mappings(self):
"""
Test that _get_pre_call_type still correctly maps standard route types.
Ensures Fix #1 didn't break existing functionality.
"""
from litellm.proxy.common_request_processing import (
ProxyBaseLLMRequestProcessing,
)
# Test standard mappings are preserved
assert (
ProxyBaseLLMRequestProcessing._get_pre_call_type(route_type="acompletion")
== "completion"
)
assert (
ProxyBaseLLMRequestProcessing._get_pre_call_type(route_type="aembedding")
== "embedding"
)
assert (
ProxyBaseLLMRequestProcessing._get_pre_call_type(route_type="aresponses")
== "responses"
)
class TestEventTypeLogging:
"""Tests for event_type logging in guardrail information."""
@@ -4,6 +4,7 @@ import pytest
from litellm.caching import DualCache
from litellm.integrations.custom_guardrail import CustomGuardrail
from litellm.llms.base_llm.guardrail_translation.base_translation import BaseTranslation
from litellm.proxy._experimental.mcp_server.guardrail_translation.handler import (
MCPGuardrailTranslationHandler,
)
@@ -30,11 +31,28 @@ class RecordingGuardrail(CustomGuardrail):
return {"texts": inputs.get("texts", [])}
class _NoopTranslation(BaseTranslation):
"""Test translation handler that simply echoes input/output."""
async def process_input_messages(self, data, guardrail_to_apply, litellm_logging_obj=None): # type: ignore[override]
return data
async def process_output_response( # type: ignore[override]
self,
response,
guardrail_to_apply,
litellm_logging_obj=None,
user_api_key_dict=None,
):
return response
@pytest.fixture(autouse=True)
def _inject_mcp_handler_mapping():
"""Inject MCP handler mapping so the unified guardrail can run inside tests."""
unified_module.endpoint_guardrail_translation_mappings = {
CallTypes.call_mcp_tool: MCPGuardrailTranslationHandler,
CallTypes.anthropic_messages: _NoopTranslation,
}
yield
unified_module.endpoint_guardrail_translation_mappings = None
@@ -82,3 +100,29 @@ async def test_moderation_hook_uses_mcp_event_type():
)
assert guardrail.event_history == [GuardrailEventHooks.during_mcp_call]
@pytest.mark.asyncio
async def test_moderation_hook_runs_for_anthropic_messages():
"""Ensure anthropic_messages requests still trigger guardrail moderation."""
handler = UnifiedLLMGuardrails()
guardrail = RecordingGuardrail()
data = {
"guardrail_to_apply": guardrail,
"messages": [
{
"role": "user",
"content": "Hello Anthropics",
}
],
"model": "anthropic.claude-3",
}
await handler.async_moderation_hook(
data=data,
user_api_key_dict=None,
call_type=CallTypes.anthropic_messages.value,
)
assert guardrail.event_history == [GuardrailEventHooks.during_call]