Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions litellm/proxy/guardrails/guardrail_hooks/xecguard/xecguard.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@
httpxSpecialProvider,
)
from litellm.types.guardrails import GuardrailEventHooks
from litellm.types.utils import GenericGuardrailAPIInputs, GuardrailStatus
from litellm.types.utils import (
GenericGuardrailAPIInputs,
GuardrailStatus,
StandardLoggingGuardrailInformation,
)

if TYPE_CHECKING:
from litellm.litellm_core_utils.litellm_logging import (
Expand Down Expand Up @@ -243,16 +247,21 @@ async def async_logging_hook(
"guardrail_intervened" if scan_result.get("decision") == "UNSAFE" else "success"
)
end_time = datetime.now()
kwargs["standard_logging_object"]["guardrail_information"] = {
"duration": (end_time - start_time).total_seconds(),
"end_time": end_time.timestamp(),
"guardrail_mode": "logging_only",
"guardrail_name": "xecguard",
"guardrail_response": scan_result,
"guardrail_status": guardrail_status,
"masked_entity_count": None,
"start_time": start_time.timestamp(),
}
slg = StandardLoggingGuardrailInformation(
guardrail_name=self.guardrail_name or "xecguard",
guardrail_mode="logging_only",
guardrail_response=scan_result,
guardrail_status=guardrail_status,
start_time=start_time.timestamp(),
end_time=end_time.timestamp(),
duration=(end_time - start_time).total_seconds(),
masked_entity_count=None,
)
existing = kwargs["standard_logging_object"].get("guardrail_information")
if isinstance(existing, list):
existing.append(slg)
else:
kwargs["standard_logging_object"]["guardrail_information"] = [slg]

except Exception as exc:
verbose_proxy_logger.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,10 @@ async def test_async_logging_hook_with_response_records_info(
)
assert out_kwargs is kwargs
assert out_result is result
info = kwargs["standard_logging_object"]["guardrail_information"]
info_list = kwargs["standard_logging_object"]["guardrail_information"]
assert isinstance(info_list, list), "guardrail_information must be a list"
assert len(info_list) == 1
info = info_list[0]
assert info["guardrail_mode"] == "logging_only"
assert info["guardrail_name"] == "xecguard"
assert info["guardrail_status"] == "success"
Expand Down Expand Up @@ -1680,7 +1683,9 @@ async def test_async_logging_hook_unsafe_decision_recorded(
result=_build_model_response("x"),
call_type="acompletion",
)
info = kwargs["standard_logging_object"]["guardrail_information"]
info_list = kwargs["standard_logging_object"]["guardrail_information"]
assert isinstance(info_list, list), "guardrail_information must be a list"
info = info_list[0]
assert info["guardrail_status"] == "guardrail_intervened"

@pytest.mark.asyncio
Expand Down
Loading