diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
index 3d00e29245d..9f2a4c42228 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.test.tsx
@@ -89,9 +89,8 @@ describe("GuardrailDetail", () => {
it("should request the detail and the logs for the guardrail and date range", async () => {
renderDetail();
- expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith({
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith("pii-detector", {
accessToken: "test-token",
- guardrailId: "pii-detector",
startDate: "2026-07-01",
endDate: "2026-07-24",
});
@@ -166,7 +165,10 @@ describe("GuardrailDetail", () => {
it("should not request anything without an access token", () => {
mockUseGuardrailsUsageDetail.mockReturnValue(loaded(undefined));
renderDetail({ accessToken: null });
- expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(expect.objectContaining({ accessToken: null }));
+ expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(
+ "pii-detector",
+ expect.objectContaining({ accessToken: null }),
+ );
expect(mockGetGuardrailsUsageLogs).not.toHaveBeenCalled();
});
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
index 1e82f1fee85..81c39258f67 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailDetail.tsx
@@ -38,7 +38,7 @@ export function GuardrailDetail({ guardrailId, onBack, accessToken = null, start
data: detailData,
isLoading: detailLoading,
error: detailError,
- } = useGuardrailsUsageDetail({ accessToken, guardrailId, startDate, endDate });
+ } = useGuardrailsUsageDetail(guardrailId, { accessToken, startDate, endDate });
const { data: logsData, isLoading: logsLoading } = useQuery({
queryKey: ["guardrails-usage-logs", guardrailId, logsPage, logsPageSize],
queryFn: () =>
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
index e86b6fa53b6..df106fc38c3 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsMonitorView.test.tsx
@@ -107,7 +107,8 @@ describe("GuardrailsMonitorView", () => {
expect(await screen.findByRole("heading", { name: "PII Guard" })).toBeInTheDocument();
expect(mockUseGuardrailsUsageDetail).toHaveBeenCalledWith(
- expect.objectContaining({ accessToken: "test-token", guardrailId: "gr-pii", startDate: expect.any(String) }),
+ "gr-pii",
+ expect.objectContaining({ accessToken: "test-token", startDate: expect.any(String) }),
);
expect(screen.queryByRole("heading", { name: /Guardrails Monitor/i })).not.toBeInTheDocument();
});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
index 959ed8b172e..ead5fc9f845 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails-monitor/_components/GuardrailsOverview.test.tsx
@@ -20,7 +20,7 @@ vi.mock("./EvaluationSettingsModal", () => ({
EvaluationSettingsModal: ({ open }: { open: boolean }) => (open ?
Evaluation settings modal
: null),
}));
-const row = (overrides: Partial): GuardrailUsageOverviewRow => ({
+const baseRow: GuardrailUsageOverviewRow = {
id: "guardrail",
name: "Guardrail",
type: "content_filter",
@@ -34,20 +34,21 @@ const row = (overrides: Partial): GuardrailUsageOverv
usageUnits: {},
cost: null,
untrackedUsageUnits: {},
- ...overrides,
-});
+};
const overview: GuardrailUsageOverview = {
rows: [
- row({
+ {
+ ...baseRow,
id: "guardrail-low",
name: "Low Failure Guardrail",
requestsEvaluated: 1200,
failRate: 2.5,
avgLatency: 45,
trend: "down",
- }),
- row({
+ },
+ {
+ ...baseRow,
id: "guardrail-high",
name: "High Failure Guardrail",
provider: "Bedrock",
@@ -58,8 +59,9 @@ const overview: GuardrailUsageOverview = {
usageUnits: { contentPolicyUnits: 1000, sensitiveInformationPolicyUnits: 250 },
cost: 0.15,
untrackedUsageUnits: { sensitiveInformationPolicyUnits: 250 },
- }),
- row({
+ },
+ {
+ ...baseRow,
id: "guardrail-free",
name: "Free Bedrock Guardrail",
provider: "Bedrock",
@@ -67,7 +69,7 @@ const overview: GuardrailUsageOverview = {
failRate: 0,
usageUnits: { contentPolicyUnits: 40 },
cost: 0,
- }),
+ },
],
chart: [],
totalRequests: 1510,
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
index f0b2709484d..70fc874fb50 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.test.ts
@@ -50,9 +50,8 @@ describe("useGuardrailsUsageDetail", () => {
it("queries GET /guardrails/usage/detail/{guardrail_id} with the id as a path param", () => {
renderHook(() =>
- useGuardrailsUsageDetail({
+ useGuardrailsUsageDetail("bedrock-pii-mask", {
accessToken: "sk",
- guardrailId: "bedrock-pii-mask",
startDate: "2026-09-01",
endDate: "2026-09-04",
}),
@@ -73,7 +72,7 @@ describe("useGuardrailsUsageDetail", () => {
it("stays disabled without a guardrail id", () => {
renderHook(() =>
- useGuardrailsUsageDetail({ accessToken: "sk", guardrailId: "", startDate: "2026-09-01", endDate: "2026-09-04" }),
+ useGuardrailsUsageDetail("", { accessToken: "sk", startDate: "2026-09-01", endDate: "2026-09-04" }),
);
expect(lastCall()[3].enabled).toBe(false);
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
index dc7f58fbc8f..5569bdc8beb 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
+++ b/ui/litellm-dashboard/src/app/(dashboard)/hooks/guardrails/useGuardrailsUsage.ts
@@ -24,12 +24,10 @@ export const useGuardrailsUsageOverview = ({ accessToken, startDate, endDate }:
{ enabled: Boolean(accessToken) },
);
-export const useGuardrailsUsageDetail = ({
- accessToken,
- guardrailId,
- startDate,
- endDate,
-}: GuardrailsUsageWindow & { guardrailId: string }) =>
+export const useGuardrailsUsageDetail = (
+ guardrailId: string,
+ { accessToken, startDate, endDate }: GuardrailsUsageWindow,
+) =>
$api.useQuery(
"get",
"/guardrails/usage/detail/{guardrail_id}",
diff --git a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
index 8e2baaaa3c5..dd5b564b49a 100644
--- a/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
+++ b/ui/litellm-dashboard/src/components/GuardrailsMonitor/usageUnits.test.ts
@@ -9,8 +9,16 @@ import {
unitPrice,
unitsMathRows,
unpricedSummary,
+ type CounterMath,
} from "./usageUnits";
+const counterOf = (counter: string, units: number, unpriced: number, cost: number | null): CounterMath => ({
+ counter,
+ units,
+ unpriced,
+ cost,
+});
+
describe("formatCost", () => {
it("renders a dash when nothing was priced", () => {
expect(formatCost(null)).toBe("—");
@@ -66,15 +74,12 @@ describe("unpricedSummary", () => {
describe("unitPrice", () => {
it("backs the per-unit price out of the priced share only", () => {
- expect(unitPrice({ counter: "contentPolicyUnits", units: 1200, unpriced: 200, cost: 0.15 })).toBeCloseTo(
- 0.00015,
- 10,
- );
+ expect(unitPrice(counterOf("contentPolicyUnits", 1200, 200, 0.15))).toBeCloseTo(0.00015, 10);
});
it("is null when nothing was priced", () => {
- expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toBeNull();
- expect(unitPrice({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: 0 })).toBeNull();
+ expect(unitPrice(counterOf("someFutureCounter", 7, 7, null))).toBeNull();
+ expect(unitPrice(counterOf("someFutureCounter", 7, 7, 0))).toBeNull();
});
});
@@ -93,7 +98,7 @@ describe("formatUnitPrice", () => {
describe("counterMathRow", () => {
it("shows units × price = cost for a fully priced counter", () => {
- expect(counterMathRow({ counter: "contentPolicyUnits", units: 1000, unpriced: 0, cost: 0.15 })).toEqual({
+ expect(counterMathRow(counterOf("contentPolicyUnits", 1000, 0, 0.15))).toEqual({
label: "Content Policy",
parts: ["1,000", "× $0.00015", "= $0.1500"],
note: null,
@@ -101,20 +106,18 @@ describe("counterMathRow", () => {
});
it("prices only the priced share and calls out the rest", () => {
- expect(counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 2, cost: 0.0006 })).toEqual(
- {
- label: "Sensitive Information Policy",
- parts: ["6", "× $0.0001", "= $0.0006"],
- note: "2 unpriced units left out",
- },
+ expect(counterMathRow(counterOf("sensitiveInformationPolicyUnits", 8, 2, 0.0006))).toEqual({
+ label: "Sensitive Information Policy",
+ parts: ["6", "× $0.0001", "= $0.0006"],
+ note: "2 unpriced units left out",
+ });
+ expect(counterMathRow(counterOf("sensitiveInformationPolicyUnits", 8, 1, 0.0007)).note).toBe(
+ "1 unpriced unit left out",
);
- expect(
- counterMathRow({ counter: "sensitiveInformationPolicyUnits", units: 8, unpriced: 1, cost: 0.0007 }).note,
- ).toBe("1 unpriced unit left out");
});
it("says so when a counter has no known price at all", () => {
- expect(counterMathRow({ counter: "someFutureCounter", units: 7, unpriced: 7, cost: null })).toEqual({
+ expect(counterMathRow(counterOf("someFutureCounter", 7, 7, null))).toEqual({
label: "Some Future Counter",
parts: ["7", "× —", "= —"],
note: "no known price, left out",
@@ -122,11 +125,7 @@ describe("counterMathRow", () => {
});
it("shows a free counter as × $0", () => {
- expect(counterMathRow({ counter: "wordPolicyUnits", units: 2, unpriced: 0, cost: 0 }).parts).toEqual([
- "2",
- "× $0",
- "= $0.0000",
- ]);
+ expect(counterMathRow(counterOf("wordPolicyUnits", 2, 0, 0)).parts).toEqual(["2", "× $0", "= $0.0000"]);
});
});