mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
[Fix] UI - Add css to truncate long request ids in request viewer (#16665)
* Add css to truncate long request ids in request viewer * Show tooltip with entire request id when request id is truncated
This commit is contained in:
parent
4167a64853
commit
69fcedb6d9
2 changed files with 81 additions and 15 deletions
63
ui/litellm-dashboard/src/components/view_logs/index.test.tsx
Normal file
63
ui/litellm-dashboard/src/components/view_logs/index.test.tsx
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
import { render } from "@testing-library/react";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { RequestViewer } from "./index";
|
||||
import type { LogEntry } from "./columns";
|
||||
import type { Row } from "@tanstack/react-table";
|
||||
|
||||
const baseLogEntry: LogEntry = {
|
||||
request_id: "chatcmpl-test-id",
|
||||
api_key: "api-key",
|
||||
team_id: "team-id",
|
||||
model: "gpt-4",
|
||||
model_id: "gpt-4",
|
||||
call_type: "chat",
|
||||
spend: 0,
|
||||
total_tokens: 0,
|
||||
prompt_tokens: 0,
|
||||
completion_tokens: 0,
|
||||
startTime: "2025-11-14T00:00:00Z",
|
||||
endTime: "2025-11-14T00:00:00Z",
|
||||
cache_hit: "miss",
|
||||
duration: 1,
|
||||
messages: [{ role: "user", content: "hello" }],
|
||||
response: { status: "ok" },
|
||||
metadata: {
|
||||
status: "success",
|
||||
additional_usage_values: {
|
||||
cache_read_input_tokens: 0,
|
||||
cache_creation_input_tokens: 0,
|
||||
},
|
||||
},
|
||||
request_tags: {},
|
||||
custom_llm_provider: "openai",
|
||||
api_base: "https://api.example.com",
|
||||
};
|
||||
|
||||
const createRow = (overrides: Partial<LogEntry> = {}): Row<LogEntry> =>
|
||||
({
|
||||
original: {
|
||||
...baseLogEntry,
|
||||
...overrides,
|
||||
},
|
||||
}) as unknown as Row<LogEntry>;
|
||||
|
||||
describe("Request Viewer", () => {
|
||||
it("renders the request details heading", () => {
|
||||
const { getByText } = render(<RequestViewer row={createRow()} />);
|
||||
expect(getByText("Request Details")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should truncate the request id if it is longer than 64 characters", () => {
|
||||
const LONG_REQUEST_ID = "a".repeat(128);
|
||||
const TRUNCATED_REQUEST_ID = `${"a".repeat(64)}...`;
|
||||
const { getByText } = render(
|
||||
<RequestViewer
|
||||
row={createRow({
|
||||
request_id: LONG_REQUEST_ID,
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(getByText(TRUNCATED_REQUEST_ID)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -26,6 +26,7 @@ import { Tab, TabGroup, TabList, TabPanels, TabPanel, Switch } from "@tremor/rea
|
|||
import AuditLogs from "./audit_logs";
|
||||
import { getTimeRangeDisplay } from "./logs_utils";
|
||||
import { formatNumberWithCommas } from "@/utils/dataUtils";
|
||||
import { truncateString } from "@/utils/textUtils";
|
||||
|
||||
interface SpendLogsTableProps {
|
||||
accessToken: string | null;
|
||||
|
|
@ -791,11 +792,7 @@ export function RequestViewer({ row }: { row: Row<LogEntry> }) {
|
|||
|
||||
// Extract guardrail information from metadata if available
|
||||
const guardrailInfo = row.original.metadata?.guardrail_information;
|
||||
const guardrailEntries = Array.isArray(guardrailInfo)
|
||||
? guardrailInfo
|
||||
: guardrailInfo
|
||||
? [guardrailInfo]
|
||||
: [];
|
||||
const guardrailEntries = Array.isArray(guardrailInfo) ? guardrailInfo : guardrailInfo ? [guardrailInfo] : [];
|
||||
const hasGuardrailData = guardrailEntries.length > 0;
|
||||
|
||||
// Calculate total masked entities if guardrail data exists
|
||||
|
|
@ -806,18 +803,18 @@ export function RequestViewer({ row }: { row: Row<LogEntry> }) {
|
|||
}
|
||||
return (
|
||||
sum +
|
||||
Object.values(maskedCounts).reduce<number>(
|
||||
(acc, count) => (typeof count === "number" ? acc + count : acc),
|
||||
0,
|
||||
)
|
||||
Object.values(maskedCounts).reduce<number>((acc, count) => (typeof count === "number" ? acc + count : acc), 0)
|
||||
);
|
||||
}, 0);
|
||||
|
||||
const primaryGuardrailLabel = guardrailEntries.length === 1
|
||||
? guardrailEntries[0]?.guardrail_name ?? "-"
|
||||
: guardrailEntries.length > 1
|
||||
? `${guardrailEntries.length} guardrails`
|
||||
: "-";
|
||||
const primaryGuardrailLabel =
|
||||
guardrailEntries.length === 1
|
||||
? guardrailEntries[0]?.guardrail_name ?? "-"
|
||||
: guardrailEntries.length > 1
|
||||
? `${guardrailEntries.length} guardrails`
|
||||
: "-";
|
||||
|
||||
const truncatedRequestId = truncateString(row.original.request_id, 64);
|
||||
|
||||
return (
|
||||
<div className="p-6 bg-gray-50 space-y-6 w-full max-w-full overflow-hidden box-border">
|
||||
|
|
@ -830,7 +827,13 @@ export function RequestViewer({ row }: { row: Row<LogEntry> }) {
|
|||
<div className="space-y-2">
|
||||
<div className="flex">
|
||||
<span className="font-medium w-1/3">Request ID:</span>
|
||||
<span className="font-mono text-sm">{row.original.request_id}</span>
|
||||
{row.original.request_id.length > 64 ? (
|
||||
<Tooltip title={row.original.request_id}>
|
||||
<span className="font-mono text-sm">{truncatedRequestId}</span>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<span className="font-mono text-sm">{row.original.request_id}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex">
|
||||
<span className="font-medium w-1/3">Model:</span>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue