fix(ui): remove Top models by task card from Model Leaderboard (#44502)

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Ishaan Jaffer <155045088+ishaan-berri@users.noreply.github.com>
This commit is contained in:
devin-ai-integration[bot] 2026-10-05 08:42:19 -07:00 • committed by GitHub
parent 9cc15e9320
commit adb59a7af8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 8 additions and 177 deletions

View file

@ -20,7 +20,6 @@ vi.mock("recharts", () => ({
</div>
),
CartesianGrid: () => null,
Treemap: () => null,
XAxis: () => null,
YAxis: () => null,
}));
@ -45,48 +44,26 @@ const response = {
daily_totals: [{ date: "2026-09-28", spend: 2.5, prompt_tokens: 1000, completion_tokens: 2000, requests: 12 }],
};
const taskResponse = {
start_date: "2025-09-29",
end_date: "2026-09-28",
tasks: [
{
task_type: "code_generation",
label: "Code Generation",
category: "Code",
value: 2.5,
share: 100,
leader: "fast-chat",
provider: "openai",
},
],
};
const mockApi = (tasks: unknown = taskResponse) =>
vi
.mocked(apiClient.get)
.mockImplementation((path: string) =>
path === "/model-insights/tasks" ? (tasks as Promise<unknown>) : Promise.resolve(response),
);
describe("ModelInsightsView", () => {
beforeEach(() => {
vi.mocked(apiClient.get).mockReset();
mockApi(Promise.resolve(taskResponse));
vi.mocked(apiClient.get).mockResolvedValue(response);
});
it("shows the ranking with share and the task legend from the API response", async () => {
it("shows the ranking with share from the API response", async () => {
render(<ModelInsightsView accessToken="token" />);
expect(await screen.findByText("fast-chat")).toBeInTheDocument();
expect(screen.getByText("by openai")).toBeInTheDocument();
expect(await screen.findByText("Code")).toBeInTheDocument();
expect(screen.getAllByText("100.0%")).toHaveLength(2);
expect(screen.getAllByText("100.0%")).toHaveLength(1);
expect(screen.queryByText("Top models by task")).not.toBeInTheDocument();
expect(screen.getByRole("tab", { name: "tokens" })).toHaveAttribute("aria-selected", "true");
expect(screen.getByRole("tab", { name: "log" })).toBeInTheDocument();
expect(apiClient.get).toHaveBeenCalledWith("/model-insights", {
accessToken: "token",
query: { metric: "tokens" },
});
expect(apiClient.get).not.toHaveBeenCalledWith("/model-insights/tasks", expect.anything());
});
it("refetches with the selected metric so top models are ranked by it", async () => {
@ -103,24 +80,6 @@ describe("ModelInsightsView", () => {
);
});
it("does not refetch the task breakdown when the chart metric changes", async () => {
render(<ModelInsightsView accessToken="token" />);
await screen.findByText("Code");
const taskCalls = () =>
vi.mocked(apiClient.get).mock.calls.filter(([path]) => path === "/model-insights/tasks").length;
const before = taskCalls();
await userEvent.click(screen.getByRole("tab", { name: "requests" }));
await waitFor(() =>
expect(apiClient.get).toHaveBeenCalledWith("/model-insights", {
accessToken: "token",
query: { metric: "requests" },
}),
);
expect(taskCalls()).toBe(before);
});
it("shows the API error instead of loading forever", async () => {
vi.mocked(apiClient.get).mockRejectedValue(new Error("Only proxy admins can view deployment-wide model insights"));
render(<ModelInsightsView accessToken="token" />);
@ -133,11 +92,7 @@ describe("ModelInsightsView", () => {
render(<ModelInsightsView accessToken="token" />);
await screen.findByText("fast-chat");
let resolve: (value: typeof response) => void = () => {};
vi.mocked(apiClient.get).mockImplementation((path: string) =>
path === "/model-insights/tasks"
? Promise.resolve(taskResponse)
: new Promise((done) => (resolve = done as typeof resolve)),
);
vi.mocked(apiClient.get).mockImplementation(() => new Promise((done) => (resolve = done as typeof resolve)));
await userEvent.click(screen.getByRole("tab", { name: "spend" }));

View file

@ -2,8 +2,8 @@
import { Page } from "@/components/shared/Page";
import React from "react";
import { Bar, BarChart, CartesianGrid, Treemap, XAxis, YAxis } from "recharts";
import { ArrowDownRight, ArrowUpRight, BarChart3, Layers, Minus } from "lucide-react";
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
import { ArrowDownRight, ArrowUpRight, BarChart3, Minus } from "lucide-react";
import { apiClient } from "@/components/networking";
import { extractErrorMessage } from "@/utils/errorUtils";
@ -12,7 +12,6 @@ import { PageHeader, PageHeaderDescription, PageHeaderTitle } from "@/components
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
@ -22,8 +21,6 @@ import {
Granularity,
Metric,
ModelInsightsResponse,
ModelInsightTasksResponse,
TaskSummary,
modelOrder,
rankModels,
RankedModel,
@ -41,13 +38,6 @@ const PALETTE = [
"#6366f1",
"#f97316",
];
const FALLBACK_COLOR = "#64748b";
const CATEGORY_COLORS: Record<string, string> = {
General: "#ee8650",
Agent: "#7666e4",
Code: "#5fb074",
Data: "#3b82f6",
};
const SCALES = ["linear", "log"] as const;
const GRANULARITIES = ["day", "week"] as const;
const GRANULARITY_LABELS: Record<Granularity, string> = { day: "Daily", week: "Weekly" };
@ -90,37 +80,11 @@ const RankingRow = ({ model, rank }: { model: RankedModel; rank: number }) => (
</li>
);
type TileProps = TaskSummary & { x: number; y: number; width: number; height: number; index: number };
const TaskTileContent = ({ x, y, width, height, category, label, leader }: TileProps) => {
if (width <= 0 || height <= 0) return null;
const color = CATEGORY_COLORS[category] ?? FALLBACK_COLOR;
const fits = width > 90 && height > 44;
return (
<g>
<rect x={x} y={y} width={width} height={height} fill={color} stroke="#fff" strokeWidth={2} />
{fits && (
<>
<text x={x + 12} y={y + 26} fill="#fff" fontSize={16} fontWeight={500}>
{label}
</text>
<text x={x + 12} y={y + 46} fill="#ffffffcc" fontSize={12}>
{leader}
</text>
</>
)}
</g>
);
};
export default function ModelInsightsView({ accessToken }: { accessToken: string | null }) {
const [loaded, setLoaded] = React.useState<{ metric: Metric; response: ModelInsightsResponse } | null>(null);
const [metric, setMetric] = React.useState<Metric>("tokens");
const [scale, setScale] = React.useState<Scale>("linear");
const [granularity, setGranularity] = React.useState<Granularity>("day");
const [taskMetric, setTaskMetric] = React.useState<Metric>("spend");
const [taskData, setTaskData] = React.useState<ModelInsightTasksResponse | null>(null);
const [taskError, setTaskError] = React.useState<string | null>(null);
const [error, setError] = React.useState<string | null>(null);
React.useEffect(() => {
@ -141,24 +105,6 @@ export default function ModelInsightsView({ accessToken }: { accessToken: string
};
}, [accessToken, metric]);
React.useEffect(() => {
if (!accessToken) return;
let cancelled = false;
apiClient
.get<ModelInsightTasksResponse>("/model-insights/tasks", { accessToken, query: { metric: taskMetric } })
.then((response) => {
if (cancelled) return;
setTaskError(null);
setTaskData(response);
})
.catch((err: unknown) => {
if (!cancelled) setTaskError(extractErrorMessage(err));
});
return () => {
cancelled = true;
};
}, [accessToken, taskMetric]);
const data = loaded?.response ?? null;
const shown = loaded?.metric ?? metric;
const isStale = loaded !== null && loaded.metric !== metric;
@ -176,15 +122,6 @@ export default function ModelInsightsView({ accessToken }: { accessToken: string
() => (data ? rankModels(data.top_models, data.daily, shown, range) : []),
[data, shown, range],
);
const tiles = React.useMemo(() => taskData?.tasks ?? [], [taskData]);
const categoryShares = React.useMemo(
() =>
[...new Set(tiles.map((tile) => tile.category))].map((category) => ({
category,
share: tiles.filter((tile) => tile.category === category).reduce((sum, tile) => sum + tile.share, 0),
})),
[tiles],
);
if (error) {
return (
@ -317,57 +254,6 @@ export default function ModelInsightsView({ accessToken }: { accessToken: string
</CardContent>
</Card>
<Card>
<CardHeader className="flex-row items-start justify-between space-y-0">
<div>
<CardTitle className="flex items-center gap-2">
<Layers className="size-5" /> Top models by task
</CardTitle>
<CardDescription>
Each task&apos;s share of {METRIC_LABELS[taskMetric]}, labelled with its leading model
</CardDescription>
</div>
<Select value={taskMetric} onValueChange={(value) => setTaskMetric(value as Metric)}>
<SelectTrigger className="w-44" aria-label="Task metric">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="spend">Share of spend</SelectItem>
<SelectItem value="requests">Share of requests</SelectItem>
<SelectItem value="tokens">Share of tokens</SelectItem>
</SelectContent>
</Select>
</CardHeader>
<CardContent className="space-y-4">
{taskError && (
<Alert variant="destructive">
<AlertTitle>Could not load tasks</AlertTitle>
<AlertDescription>{taskError}</AlertDescription>
</Alert>
)}
<ChartContainer config={{}} className="h-[360px] w-full aspect-auto">
<Treemap
data={tiles.map((tile) => ({ ...tile, name: tile.task_type }))}
dataKey="value"
isAnimationActive={false}
content={<TaskTileContent {...({} as TileProps)} />}
/>
</ChartContainer>
<ul className="flex flex-wrap gap-x-6 gap-y-2">
{categoryShares.map(({ category, share }) => (
<li key={category} className="flex items-center gap-2 text-sm">
<span
className="size-3 rounded-full"
style={{ backgroundColor: CATEGORY_COLORS[category] ?? FALLBACK_COLOR }}
/>
<span className="text-muted-foreground">{category}</span>
<span className="font-medium tabular-nums">{share.toFixed(1)}%</span>
</li>
))}
</ul>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Cost per session</CardTitle>

View file

@ -21,16 +21,6 @@ export type ModelInsightsResponse = {
daily_totals: DailyTotal[];
top_models: ModelMetric[];
};
export type TaskSummary = {
task_type: string;
label: string;
category: string;
value: number;
share: number;
leader: string;
provider: string;
};
export type ModelInsightTasksResponse = { start_date: string; end_date: string; tasks: TaskSummary[] };
export type RankedModel = { model_group: string; provider: string; share: number; delta: number };
export type Granularity = "day" | "week";