mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-04 02:31:27 +00:00
fix(guardrails): skip malformed guardrail entries instead of failing the usage batch
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
7ebb169a4d
commit
586d51f15e
2 changed files with 27 additions and 5 deletions
|
|
@ -356,12 +356,12 @@ async def process_spend_logs_guardrail_usage(
|
|||
"flagged_count": 0,
|
||||
}
|
||||
)
|
||||
index_rows_by_key: Final[dict[tuple[object, object], dict[str, object]]] = {}
|
||||
index_rows_by_key: Final[dict[tuple[str, str], dict[str, object]]] = {}
|
||||
|
||||
for payload in logs_to_process:
|
||||
request_id = payload.get("request_id")
|
||||
start_time = _parse_payload_start_time(payload)
|
||||
if not request_id or start_time is None:
|
||||
if not isinstance(request_id, str) or not request_id or start_time is None:
|
||||
continue
|
||||
date_key = _date_str(start_time)
|
||||
|
||||
|
|
@ -370,13 +370,14 @@ async def process_spend_logs_guardrail_usage(
|
|||
{
|
||||
e["guardrail_name"]: e["guardrail_id"]
|
||||
for e in entries
|
||||
if e.get("guardrail_id") and e.get("guardrail_name")
|
||||
if e.get("guardrail_id") and isinstance(e.get("guardrail_name"), str)
|
||||
}
|
||||
)
|
||||
for entry in entries:
|
||||
guardrail_name = entry.get("guardrail_name") or ""
|
||||
raw_name = entry.get("guardrail_name")
|
||||
guardrail_name = raw_name if isinstance(raw_name, str) else ""
|
||||
guardrail_id = entry.get("guardrail_id") or ids_by_name.get(guardrail_name) or guardrail_name
|
||||
if not guardrail_id:
|
||||
if not isinstance(guardrail_id, str) or not guardrail_id:
|
||||
continue
|
||||
action = guardrail_status_to_action(entry.get("guardrail_status"))
|
||||
if action != "not_run":
|
||||
|
|
|
|||
|
|
@ -405,6 +405,27 @@ async def test_not_run_entry_shares_index_key_with_evaluated_sibling_of_same_nam
|
|||
assert (metrics_create["guardrail_id"], metrics_create["requests_evaluated"]) == ("cf-uuid", 1)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_malformed_not_run_entry_does_not_drop_the_batch():
|
||||
prisma = _prisma()
|
||||
payload = _payload("r1")
|
||||
payload["metadata"] = json.dumps(
|
||||
{
|
||||
"guardrail_information": [
|
||||
{"guardrail_name": ["not", "a", "string"], "guardrail_status": "not_run"},
|
||||
{"guardrail_name": "cf", "guardrail_id": "cf-uuid", "guardrail_status": "success"},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
await process_spend_logs_guardrail_usage(prisma, [payload])
|
||||
|
||||
index_rows = prisma.db.litellm_spendlogguardrailindex.create_many.call_args.kwargs["data"]
|
||||
assert [row["guardrail_id"] for row in index_rows] == ["cf-uuid"]
|
||||
metrics_create = prisma.db.litellm_dailyguardrailmetrics.upsert.call_args.kwargs["data"]["create"]
|
||||
assert metrics_create["requests_evaluated"] == 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_batch_of_only_not_run_entries_writes_no_metrics_row():
|
||||
prisma = _prisma()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue