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 { describe, expect, it, vi } from "vitest";
import type { DailyData, SpendMetrics } from "@/components/UsagePage/types"; import type { DailyData, SpendMetrics } from "@/components/UsagePage/types";
const mockUsePaginatedDailyActivity = vi.fn(); const mockUsePaginatedDailyActivity = vi.fn();
const mockUseQuery = vi.fn(); const mockUseQuery = vi.fn();
const mockUiSpendLogsCall = vi.fn();
vi.mock("@tanstack/react-query", () => ({ vi.mock("@tanstack/react-query", () => ({
useQuery: (args: unknown) => mockUseQuery(args), useQuery: (args: unknown) => mockUseQuery(args),
@ -17,6 +18,12 @@ vi.mock("@/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity", (
vi.mock("@/components/networking", () => ({ vi.mock("@/components/networking", () => ({
userDailyActivityCall: vi.fn(), userDailyActivityCall: vi.fn(),
getCostOptimizationUsageLogs: 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", () => ({ 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[]) => { const renderWith = (results: DailyData[]) => {
mockUsePaginatedDailyActivity.mockReturnValue({ data: { results }, loading: false, isFetchingMore: false }); mockUsePaginatedDailyActivity.mockReturnValue({ data: { results }, loading: false, isFetchingMore: false });
mockUseQuery.mockReturnValue({ mockUseQuery.mockImplementation((args: { queryKey: string[] }) =>
data: { args.queryKey[0] === "cost-optimization-usage-logs"
logs: [ ? {
{ data: {
request_id: "req-123456789", logs: [
timestamp: "2026-07-13T12:00:00Z", {
model: "test-model", request_id: "req-123456789",
total_tokens: 150, timestamp: "2026-07-13T12:00:00Z",
optimization_type: "both", model: "test-model",
spend: 0.02, total_tokens: 150,
savings: 0.14, optimization_type: "both",
original_cost: 0.16, 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" />); 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.0200")).toBeInTheDocument();
expect(getByText("$0.1400")).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 React, { useMemo, useState } from "react";
import { PiggyBank } from "lucide-react"; import { PiggyBank } from "lucide-react";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import moment from "moment";
import { AreaChart, DonutChart } from "@/components/shared/charts"; import { AreaChart, DonutChart } from "@/components/shared/charts";
import AdvancedDatePicker from "@/components/shared/advanced_date_picker"; import AdvancedDatePicker from "@/components/shared/advanced_date_picker";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { import {
getCostOptimizationUsageLogs, getCostOptimizationUsageLogs,
uiSpendLogsCall,
type OptimizedRequestLog, type OptimizedRequestLog,
type OptimizedRequestLogsResponse, type OptimizedRequestLogsResponse,
userDailyActivityCall, userDailyActivityCall,
@ -17,6 +19,8 @@ import { DailyData, SpendMetrics } from "@/components/UsagePage/types";
import { formatNumberWithCommas } from "@/utils/dataUtils"; import { formatNumberWithCommas } from "@/utils/dataUtils";
import { all_admin_roles } from "@/utils/roles"; import { all_admin_roles } from "@/utils/roles";
import { usePaginatedDailyActivity } from "@/app/(dashboard)/usage/_components/hooks/usePaginatedDailyActivity"; 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 { interface CostOptimizationViewProps {
accessToken: string | null; accessToken: string | null;
@ -81,11 +85,13 @@ const OptimizedRequestsTable = ({
logsPage, logsPage,
onPrevious, onPrevious,
onNext, onNext,
onRowClick,
}: { }: {
data: OptimizedRequestLogsResponse; data: OptimizedRequestLogsResponse;
logsPage: number; logsPage: number;
onPrevious: () => void; onPrevious: () => void;
onNext: () => void; onNext: () => void;
onRowClick: (log: OptimizedRequestLog) => void;
}) => ( }) => (
<> <>
<div className="overflow-x-auto"> <div className="overflow-x-auto">
@ -104,7 +110,19 @@ const OptimizedRequestsTable = ({
</thead> </thead>
<tbody> <tbody>
{data.logs.map((log) => ( {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}> <td className="max-w-40 truncate px-3 py-3 font-mono text-xs" title={log.request_id}>
{log.request_id} {log.request_id}
</td> </td>
@ -183,6 +201,8 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
const [logsPage, setLogsPage] = useState(1); const [logsPage, setLogsPage] = useState(1);
const startDate = startTime ? startTime.toISOString().slice(0, 10) : ""; const startDate = startTime ? startTime.toISOString().slice(0, 10) : "";
const endDate = endTime ? endTime.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 { const {
data: optimizedLogsData, data: optimizedLogsData,
isLoading: optimizedLogsLoading, isLoading: optimizedLogsLoading,
@ -206,6 +226,29 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
optimizedLogsError, optimizedLogsError,
optimizedLogsData, 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( const overTime = useMemo(
() => () =>
@ -313,6 +356,10 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
logsPage={logsPage} logsPage={logsPage}
onPrevious={() => setLogsPage((page) => Math.max(1, page - 1))} onPrevious={() => setLogsPage((page) => Math.max(1, page - 1))}
onNext={() => setLogsPage((page) => Math.min(optimizedLogsData.total_pages, page + 1))} onNext={() => setLogsPage((page) => Math.min(optimizedLogsData.total_pages, page + 1))}
onRowClick={(log) => {
setSelectedRequestId(log.request_id);
setDrawerOpen(true);
}}
/> />
) : null} ) : null}
{!optimizedLogsLoading && !optimizedLogsError && !optimizedLogsData?.logs.length && ( {!optimizedLogsLoading && !optimizedLogsError && !optimizedLogsData?.logs.length && (
@ -320,6 +367,17 @@ const CostOptimizationView: React.FC<CostOptimizationViewProps> = ({ accessToken
)} )}
</CardContent> </CardContent>
</Card> </Card>
<LogDetailsDrawer
open={drawerOpen}
onClose={() => {
setDrawerOpen(false);
setSelectedRequestId(null);
}}
logEntry={selectedLog}
accessToken={accessToken}
allLogs={selectedLog ? [selectedLog] : []}
startTime={drawerStartTime}
/>
</div> </div>
); );
}; };