mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-14 23:21:35 +00:00
fix(policy_engine): merge guardrail metadata writes back on block and modify_response so failure spend records keep guardrail cost and status
This commit is contained in:
parent
badefa395c
commit
bcee01a7a7
3 changed files with 46 additions and 1 deletions
|
|
@ -236,6 +236,7 @@ class PipelineExecutor:
|
|||
step_results=step_results,
|
||||
error_message=error_detail,
|
||||
original_exception=original_exception,
|
||||
modified_data=working_data if working_data != data else None,
|
||||
)
|
||||
|
||||
if action == "modify_response":
|
||||
|
|
@ -243,6 +244,7 @@ class PipelineExecutor:
|
|||
terminal_action="modify_response",
|
||||
step_results=step_results,
|
||||
modify_response_message=step.modify_response_message or error_detail,
|
||||
modified_data=working_data if working_data != data else None,
|
||||
)
|
||||
|
||||
# action == "next" → continue to next step
|
||||
|
|
|
|||
|
|
@ -1838,7 +1838,9 @@ class ProxyLogging:
|
|||
payload (already sent upstream) must stay untouched; a replacement
|
||||
response carried in ``modified_data`` is adopted by the caller, and
|
||||
metadata-bucket writes (applied guardrails, guardrail logging info)
|
||||
are merged back so headers and spend logs still see them. On the
|
||||
are merged back so headers and spend logs still see them, on block
|
||||
and modify_response too, so failure spend records keep guardrail
|
||||
cost and status. On the
|
||||
streaming path it is the buffered chunk list, carried into
|
||||
``ModifyResponseException.original_response`` for usage reporting.
|
||||
"""
|
||||
|
|
@ -1850,6 +1852,9 @@ class ProxyLogging:
|
|||
_merge_pipeline_metadata_writes(data, result.modified_data)
|
||||
return data
|
||||
|
||||
if result.modified_data is not None:
|
||||
_merge_pipeline_metadata_writes(data, result.modified_data)
|
||||
|
||||
if result.terminal_action == "block":
|
||||
original_exception: Final = result.original_exception
|
||||
if original_exception is not None and not _exception_changes_request_flow(original_exception):
|
||||
|
|
|
|||
|
|
@ -1197,6 +1197,44 @@ async def test_post_call_pipeline_guardrail_metadata_writes_reach_request_data(
|
|||
assert slg_entries[0]["guardrail_name"] == "gr-post"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_post_call_pipeline_block_keeps_guardrail_metadata_writes(
|
||||
proxy_logging, make_user_api_key_auth, monkeypatch
|
||||
):
|
||||
class BlockingWriterGuardrail(CustomGuardrail):
|
||||
async def async_post_call_success_hook(self, data, user_api_key_dict, response):
|
||||
add_guardrail_to_applied_guardrails_header(request_data=data, guardrail_name="gr-post")
|
||||
self.add_standard_logging_guardrail_information_to_request_data(
|
||||
guardrail_json_response={"verdict": "fail"},
|
||||
request_data=data,
|
||||
guardrail_status="guardrail_intervened",
|
||||
)
|
||||
raise HTTPException(status_code=400, detail={"error": "output blocked"})
|
||||
|
||||
monkeypatch.setattr(
|
||||
litellm,
|
||||
"callbacks",
|
||||
[
|
||||
BlockingWriterGuardrail(
|
||||
guardrail_name="gr-post", event_hook=GuardrailEventHooks.post_call, default_on=False
|
||||
)
|
||||
],
|
||||
)
|
||||
monkeypatch.setattr("litellm.proxy.proxy_server.llm_router", None, raising=False)
|
||||
data = _post_call_pipeline_data()
|
||||
|
||||
with pytest.raises(HTTPException):
|
||||
await proxy_logging.post_call_success_hook(
|
||||
data=data, response=litellm.ModelResponse(), user_api_key_dict=make_user_api_key_auth()
|
||||
)
|
||||
|
||||
assert data["metadata"]["applied_guardrails"] == ["gr-post"]
|
||||
slg_entries = data["metadata"]["standard_logging_guardrail_information"]
|
||||
assert len(slg_entries) == 1
|
||||
assert slg_entries[0]["guardrail_name"] == "gr-post"
|
||||
assert slg_entries[0]["guardrail_status"] == "guardrail_intervened"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_post_call_pipeline_managed_parallel_guardrail_runs_exactly_once(
|
||||
proxy_logging, make_user_api_key_auth, monkeypatch
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue