feat(cost-optimization): open request details from optimized requests

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Krrish Dholakia 2026-07-20 14:55:27 +00:00
parent cd67a86f96
commit efc19be8d5
2 changed files with 140 additions and 24 deletions

View file

@ -1,10 +1,11 @@
import { render } from "@testing-library/react";
import { fireEvent, render } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import type { DailyData, SpendMetrics } from "@/components/UsagePage/types";
const mockUsePaginatedDailyActivity = vi.fn();
const mockUseQuery = vi.fn();
const mockUiSpendLogsCall = vi.fn();
vi.mock("@tanstack/react-query", () => ({
useQuery: (args: unknown) => mockUseQuery(args),
@ -17,6 +18,12 @@ vi.mock("@/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity", (
vi.mock("@/components/networking", () => ({
userDailyActivityCall: vi.fn(),
getCostOptimizationUsageLogs: vi.fn(),
uiSpendLogsCall: (args: unknown) => mockUiSpendLogsCall(args),
}));
vi.mock("@/components/view_logs/LogDetailsDrawer", () => ({
LogDetailsDrawer: ({ open, logEntry }: { open: boolean; logEntry: { request_id: string } | null }) =>
open && logEntry ? <div data-testid="log-details-drawer">{logEntry.request_id}</div> : null,
}));
vi.mock("@/components/shared/advanced_date_picker", () => ({
@ -61,31 +68,63 @@ const day = (date: string, metrics: Partial<SpendMetrics>): DailyData => ({
},
});
const detailLog = {
request_id: "req-123456789",
api_key: "key",
team_id: "team",
model: "test-model",
model_id: "model-id",
call_type: "completion",
spend: 0.02,
total_tokens: 150,
prompt_tokens: 100,
completion_tokens: 50,
startTime: "2026-07-13T12:00:00Z",
endTime: "2026-07-13T12:00:01Z",
messages: [],
response: {},
cache_hit: "",
metadata: {},
};
const renderWith = (results: DailyData[]) => {
mockUsePaginatedDailyActivity.mockReturnValue({ data: { results }, loading: false, isFetchingMore: false });
mockUseQuery.mockReturnValue({
data: {
logs: [
{
request_id: "req-123456789",
timestamp: "2026-07-13T12:00:00Z",
model: "test-model",
total_tokens: 150,
optimization_type: "both",
spend: 0.02,
savings: 0.14,
original_cost: 0.16,
mockUseQuery.mockImplementation((args: { queryKey: string[] }) =>
args.queryKey[0] === "cost-optimization-usage-logs"
? {
data: {
logs: [
{
request_id: "req-123456789",
timestamp: "2026-07-13T12:00:00Z",
model: "test-model",
total_tokens: 150,
optimization_type: "both",
spend: 0.02,
savings: 0.14,
original_cost: 0.16,
compression_savings_spend: 0.1,
prompt_caching_savings_spend: 0.04,
tokens_saved: 100,
cache_read_tokens: 50,
},
],
total: 1,
page: 1,
page_size: 50,
total_pages: 1,
},
isLoading: false,
isFetching: false,
error: null,
}
: {
data: { data: [detailLog], total: 1 },
isLoading: false,
isFetching: false,
error: null,
},
],
total: 1,
page: 1,
page_size: 50,
total_pages: 1,
},
isLoading: false,
isFetching: false,
error: null,
});
);
return render(<CostOptimizationView accessToken="test-token" userId="u1" userRole="proxy_admin" />);
};
@ -146,4 +185,23 @@ describe("CostOptimizationView", () => {
expect(getByText("$0.0200")).toBeInTheDocument();
expect(getByText("$0.1400")).toBeInTheDocument();
});
it("fetches and opens request details when an optimized request is clicked", async () => {
const { getByText, getByTestId } = renderWith([day("2026-07-12", { compression_savings_spend: 0.04 })]);
fireEvent.click(getByText("req-123456789"));
const detailQuery = mockUseQuery.mock.calls
.map(([args]) => args as { queryKey: string[]; queryFn: () => Promise<unknown> })
.find((args) => args.queryKey[0] === "cost-optimization-spend-log");
expect(detailQuery).toBeDefined();
await detailQuery?.queryFn();
expect(mockUiSpendLogsCall).toHaveBeenCalledWith(
expect.objectContaining({
accessToken: "test-token",
params: { request_id: "req-123456789" },
}),
);
expect(getByTestId("log-details-drawer")).toHaveTextContent("req-123456789");
});
});

View file

@ -3,12 +3,14 @@
import React, { useMemo, useState } from "react";
import { PiggyBank } from "lucide-react";
import { useQuery } from "@tanstack/react-query";
import moment from "moment";
import { AreaChart, DonutChart } from "@/components/shared/charts";
import AdvancedDatePicker from "@/components/shared/advanced_date_picker";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
getCostOptimizationUsageLogs,
uiSpendLogsCall,
type OptimizedRequestLog,
type OptimizedRequestLogsResponse,
userDailyActivityCall,
@ -17,6 +19,8 @@ import { DailyData, SpendMetrics } from "@/components/UsagePage/types";
import { formatNumberWithCommas } from "@/utils/dataUtils";
import { all_admin_roles } from "@/utils/roles";
import { usePaginatedDailyActivity } from "@/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity";
import { LogDetailsDrawer } from "@/components/view_logs/LogDetailsDrawer";
import type { LogEntry as ViewLogsLogEntry } from "@/components/view_logs/columns";
interface CostOptimizationViewProps {
accessToken: string | null;
@ -81,11 +85,13 @@ const OptimizedRequestsTable = ({
logsPage,
onPrevious,
onNext,
onRowClick,
}: {
data: OptimizedRequestLogsResponse;
logsPage: number;
onPrevious: () => void;
onNext: () => void;
onRowClick: (log: OptimizedRequestLog) => void;
}) => (
<>
<div className="overflow-x-auto">
@ -104,7 +110,19 @@ const OptimizedRequestsTable = ({
</thead>
<tbody>
{data.logs.map((log) => (
<tr key={log.request_id} className="border-b last:border-0">
<tr
key={log.request_id}
className="cursor-pointer border-b transition-colors hover:bg-muted/50 last:border-0"
onClick={() => onRowClick(log)}
onKeyDown={(event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
onRowClick(log);
}
}}
role="button"
tabIndex={0}
>
<td className="max-w-40 truncate px-3 py-3 font-mono text-xs" title={log.request_id}>
{log.request_id}
</td>
@ -183,6 +201,8 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
const [logsPage, setLogsPage] = useState(1);
const startDate = startTime ? startTime.toISOString().slice(0, 10) : "";
const endDate = endTime ? endTime.toISOString().slice(0, 10) : "";
const [selectedRequestId, setSelectedRequestId] = useState<string | null>(null);
const [drawerOpen, setDrawerOpen] = useState(false);
const {
data: optimizedLogsData,
isLoading: optimizedLogsLoading,
@ -206,6 +226,29 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
optimizedLogsError,
optimizedLogsData,
);
const drawerStartTime = startTime
? moment(startTime).utc().format("YYYY-MM-DD HH:mm:ss")
: moment().subtract(24, "hours").utc().format("YYYY-MM-DD HH:mm:ss");
const drawerEndTime = endTime
? moment(endTime).utc().endOf("day").format("YYYY-MM-DD HH:mm:ss")
: moment().utc().format("YYYY-MM-DD HH:mm:ss");
const { data: fullLogResponse } = useQuery({
queryKey: ["cost-optimization-spend-log", selectedRequestId, drawerStartTime, drawerEndTime],
queryFn: async () => {
if (!accessToken || !selectedRequestId) return null;
const response = await uiSpendLogsCall({
accessToken,
start_date: drawerStartTime,
end_date: drawerEndTime,
page: 1,
page_size: 10,
params: { request_id: selectedRequestId },
});
return response as { data: ViewLogsLogEntry[]; total: number };
},
enabled: Boolean(accessToken && selectedRequestId && drawerOpen),
});
const selectedLog: ViewLogsLogEntry | null = fullLogResponse?.data?.[0] ?? null;
const overTime = useMemo(
() =>
@ -313,6 +356,10 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
logsPage={logsPage}
onPrevious={() => setLogsPage((page) => Math.max(1, page - 1))}
onNext={() => setLogsPage((page) => Math.min(optimizedLogsData.total_pages, page + 1))}
onRowClick={(log) => {
setSelectedRequestId(log.request_id);
setDrawerOpen(true);
}}
/>
) : null}
{!optimizedLogsLoading && !optimizedLogsError && !optimizedLogsData?.logs.length && (
@ -320,6 +367,17 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
)}
</CardContent>
</Card>
<LogDetailsDrawer
open={drawerOpen}
onClose={() => {
setDrawerOpen(false);
setSelectedRequestId(null);
}}
logEntry={selectedLog}
accessToken={accessToken}
allLogs={selectedLog ? [selectedLog] : []}
startTime={drawerStartTime}
/>
</div>
);
};