This commit is contained in:
Tanishq 2026-10-29 00:41:34 +05:30 • committed by GitHub
commit bdb41290ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 137 additions and 3 deletions

View file

@ -10,6 +10,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { UiLoadingSpinner } from "@/components/ui/ui-loading-spinner";
import { LogEntry } from "../types";
import { getResponseCacheStatus } from "../responseCache";
import { formatNumberWithCommas } from "@/utils/dataUtils";
import { PROMPT_CACHE_CREATION_TOOLTIP, PROMPT_CACHE_READ_TOOLTIP } from "@/utils/promptCacheUsage";
import GuardrailViewer from "./sections/GuardrailViewer/GuardrailViewer";
@ -481,10 +482,10 @@ function MetricsSection({ logEntry, metadata }: { logEntry: LogEntry; metadata:
? new Date(completionStartTime).getTime() - new Date(logEntry.startTime).getTime()
: null;
const responseCacheValue = String(logEntry.cache_hit ?? "").toLowerCase();
const responseCacheStatus = getResponseCacheStatus(logEntry);
const responseCacheKey = logEntry.cache_key && logEntry.cache_key !== "Cache OFF" ? logEntry.cache_key : undefined;
const isResponseCacheHit = responseCacheValue === "true";
const showResponseCache = isResponseCacheHit || responseCacheValue === "false" || responseCacheKey != null;
const isResponseCacheHit = responseCacheStatus === "hit";
const showResponseCache = responseCacheStatus !== undefined;
const promptCacheReadTokens = Number(metadata?.additional_usage_values?.cache_read_input_tokens) || 0;
const promptCacheCreationTokens = Number(metadata?.additional_usage_values?.cache_creation_input_tokens) || 0;

View file

@ -0,0 +1,83 @@
import { render, screen, within } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { DataTable } from "@/components/shared/DataTable";
import type { LogEntry } from "../types";
import { getRequestLogsTableColumns } from "./RequestLogsTableColumns";
const logEntry = (overrides: Partial<LogEntry>): LogEntry => ({
request_id: "request",
api_key: "key",
team_id: "team",
model: "test-model",
model_id: "model",
call_type: "acompletion",
spend: 0,
total_tokens: 10,
prompt_tokens: 5,
completion_tokens: 5,
startTime: "2026-01-01T00:00:00Z",
endTime: "2026-01-01T00:00:01Z",
cache_hit: "None",
messages: [],
response: {},
...overrides,
});
function renderCacheCells(logs: LogEntry[]) {
render(
<DataTable
data={logs}
columns={getRequestLogsTableColumns({ onKeyHashClick: vi.fn(), onSessionClick: vi.fn() })}
getRowId={(row) => row.request_id}
/>,
);
const header = screen.getByRole("columnheader", { name: "Cache Hit" });
const columnIndex = screen.getAllByRole("columnheader").indexOf(header);
return screen
.getAllByRole("row")
.slice(1)
.map((row) => within(row).getAllByRole("cell")[columnIndex]);
}
describe("Request log cache hits", () => {
it("distinguishes a response cache hit, an enabled cache miss and caching disabled", () => {
const cells = renderCacheCells([
logEntry({ request_id: "hit", cache_hit: "True" }),
logEntry({ request_id: "miss", cache_key: "response-cache-key" }),
logEntry({ request_id: "off", cache_key: "Cache OFF" }),
]);
expect(cells[0]).toHaveTextContent(/^Yes$/);
expect(cells[1]).toHaveTextContent(/^No$/);
expect(cells[2]).toHaveTextContent(/^-$/);
});
it("shows session hit counts instead of the representative request's cache status", () => {
const sessions: Partial<LogEntry>[] = [
{ request_id: "mixed", cache_hit: "False", session_total_count: 3, session_cache_hit_count: 2 },
{ request_id: "one-hit", cache_hit: "False", session_total_count: 2, session_cache_hit_count: 1 },
{ request_id: "no-hits", session_total_count: 2, session_cache_hit_count: 0 },
{ request_id: "unknown", cache_hit: "True", session_total_count: 2 },
];
const cells = renderCacheCells(sessions.map(logEntry));
expect(cells[0]).toHaveTextContent(/^2 hits$/);
expect(cells[1]).toHaveTextContent(/^1 hit$/);
expect(cells[2]).toHaveTextContent(/^0 hits$/);
expect(cells[3]).toHaveTextContent(/^-$/);
});
it("does not report provider prompt caching as a response cache hit", () => {
const promptCached: Partial<LogEntry> = {
cache_key: "Cache OFF",
session_total_count: 1,
session_cache_hit_count: 0,
metadata: { additional_usage_values: { cache_read_input_tokens: 100 } },
};
const [cell] = renderCacheCells([logEntry(promptCached)]);
expect(cell).toHaveTextContent(/^-$/);
});
});

View file

@ -10,6 +10,7 @@ import { copyToClipboard, getSpendString } from "@/utils/dataUtils";
import { getProviderLogoAndName } from "../../provider_info_helpers";
import { getBatchIdFromRequestId, getBatchRequestCounts, isBatchCallType } from "../batchLogUtils";
import type { LogEntry } from "../types";
import { getResponseCacheStatus } from "../responseCache";
import { AGENT_CALL_TYPES, MCP_CALL_TYPES } from "../constants";
import { AgentBadge, AgentIcon, BatchBadge, LlmBadge, McpBadge, SparkleIcon, WrenchIcon } from "./TypeBadges";
@ -159,6 +160,25 @@ export const getRequestLogsTableColumns = ({
return <StatusBadge tone={isSuccess ? "success" : "error"} label={isSuccess ? "Success" : "Failure"} />;
},
},
{
id: "cache_hit",
accessorKey: "cache_hit",
header: "Cache Hit",
size: 100,
enableSorting: false,
cell: ({ row }) => {
const log = row.original;
if ((log.session_total_count ?? 1) > 1) {
const hits = log.session_cache_hit_count;
return (
<span className="whitespace-nowrap">{hits == null ? "-" : `${hits} ${hits === 1 ? "hit" : "hits"}`}</span>
);
}
const status = getResponseCacheStatus(log);
if (status === "hit") return <StatusBadge tone="success" label="Yes" />;
return <span>{status === "miss" ? "No" : "-"}</span>;
},
},
{
id: "session_id",
accessorKey: "session_id",

View file

@ -0,0 +1,22 @@
import { describe, expect, it } from "vitest";
import { getResponseCacheStatus } from "./responseCache";
describe("getResponseCacheStatus", () => {
it.each([
{ cache_hit: "True", cache_key: undefined, expected: "hit" },
{ cache_hit: "true", cache_key: "response-key", expected: "hit" },
{ cache_hit: "TRUE", cache_key: "Cache OFF", expected: "hit" },
{ cache_hit: "False", cache_key: undefined, expected: "miss" },
{ cache_hit: "false", cache_key: "response-key", expected: "miss" },
{ cache_hit: "FALSE", cache_key: "Cache OFF", expected: "miss" },
{ cache_hit: "None", cache_key: "response-key", expected: "miss" },
{ cache_hit: "", cache_key: "response-key", expected: "miss" },
{ cache_hit: "None", cache_key: "Cache OFF", expected: undefined },
{ cache_hit: "None", cache_key: undefined, expected: undefined },
{ cache_hit: "None", cache_key: "", expected: undefined },
{ cache_hit: "", cache_key: undefined, expected: undefined },
])("returns $expected for cache_hit=$cache_hit and cache_key=$cache_key", ({ cache_hit, cache_key, expected }) => {
expect(getResponseCacheStatus({ cache_hit, cache_key })).toBe(expected);
});
});

View file

@ -0,0 +1,8 @@
import type { LogEntry } from "./types";
export function getResponseCacheStatus(log: Pick<LogEntry, "cache_hit" | "cache_key">): "hit" | "miss" | undefined {
const value = String(log.cache_hit ?? "").toLowerCase();
if (value === "true") return "hit";
if (value === "false" || (log.cache_key && log.cache_key !== "Cache OFF")) return "miss";
return undefined;
}