mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-11 08:38:24 +00:00
refactor(ui): keep guardrail usage code under the inline-object-arg lint budget
The staging merge pushed local/no-large-inline-object-arg to 567 against a 554 ceiling, and 15 of those hits came from this branch. useGuardrailsUsageDetail now takes the guardrail id positionally with the date window as its second argument, the usageUnits tests build CounterMath rows through a positional helper, and the overview fixture spreads a base row inside the array instead of calling a factory Claude-Session: https://claude.ai/code/session_01EX13mWex6RaBo9PYnkAtFW
This commit is contained in:
parent
0be8bb98b0
commit
b99d8ac38e
7 changed files with 46 additions and 45 deletions
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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: () =>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ vi.mock("./EvaluationSettingsModal", () => ({
|
|||
EvaluationSettingsModal: ({ open }: { open: boolean }) => (open ? <div>Evaluation settings modal</div> : null),
|
||||
}));
|
||||
|
||||
const row = (overrides: Partial<GuardrailUsageOverviewRow>): GuardrailUsageOverviewRow => ({
|
||||
const baseRow: GuardrailUsageOverviewRow = {
|
||||
id: "guardrail",
|
||||
name: "Guardrail",
|
||||
type: "content_filter",
|
||||
|
|
@ -34,20 +34,21 @@ const row = (overrides: Partial<GuardrailUsageOverviewRow>): 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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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}",
|
||||
|
|
|
|||
|
|
@ -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"]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue