fix(lens): resolve the analysis provider logo from the model catalog

This commit is contained in:
Ishaan Jaff 2026-10-03 18:09:50 -07:00
parent 6fb7e8124f
commit 3c8309272f
No known key found for this signature in database
3 changed files with 22 additions and 9 deletions

View file

@ -3,6 +3,7 @@
import { ArrowRight, PanelRight, X } from "lucide-react";
import type { ReactNode } from "react";
import { useModelCostMap } from "@/app/(dashboard)/hooks/models/useModelCostMap";
import { ProviderLogo } from "@/components/molecules/models/ProviderLogo";
import { agoLabel } from "@/components/view_logs/TraceView/lensField";
import { Button } from "@/components/ui/button";
@ -18,8 +19,9 @@ const MARK = { issue: "●", clear: "✓", unknown: "–" } as const;
const LOGO = { sm: "size-3.5", md: "size-[18px]" } as const;
export function ModelName({ model, size = "sm" }: { model: string; size?: keyof typeof LOGO }) {
const { data: catalog } = useModelCostMap();
if (!model) return null;
const provider = providerOf(model);
const provider = providerOf(model, catalog ?? {});
return (
<span data-testid="live-model" className="inline-flex shrink-0 items-center gap-1.5 text-foreground">
{provider && <ProviderLogo provider={provider} className={cn("shrink-0", LOGO[size])} />}

View file

@ -60,6 +60,13 @@ describe("provider from model", () => {
expect(providerOf("/weird")).toBe("");
});
it("resolves a bare model name through the model catalog", () => {
const catalog = { "gpt-5.6": { litellm_provider: "openai" }, "cerebras/gpt-oss-120b": { litellm_provider: "cerebras" } };
expect(providerOf("gpt-5.6", catalog)).toBe("openai");
expect(providerOf("my-alias", catalog)).toBe("");
expect(analysisModel(["", "gpt-5.6"], catalog)).toBe("gpt-5.6");
});
it("prefers a model that names its provider over a bare alias", () => {
expect(analysisModel(["analysis", "", "cerebras/gpt-oss-120b"])).toBe("cerebras/gpt-oss-120b");
expect(analysisModel(["", "analysis"])).toBe("analysis");
@ -342,9 +349,9 @@ describe("honest live list", () => {
it("says how many traces are in flight and how many are done", () => {
const job = (reviewed: number, selected: number) => ({ reviewed, coverage: { selected } }) as unknown as Job;
expect(nowLine(job(18, 30), 4)).toBe("Reviewing 4 at a time · 18 of 30 done");
expect(nowLine(job(30, 30), 0)).toBe("30 of 30 done");
expect(nowLine(job(3, 0), 1)).toBe("Reviewing 1 at a time · 3 done");
expect(nowLine(job(18, 30), 4)).toBe("18 of 30 · 4 in flight");
expect(nowLine(job(30, 30), 0)).toBe("30 of 30");
expect(nowLine(job(3, 0), 1)).toBe("3 done · 1 in flight");
});
it("keeps a trace as the same row from in flight to finished", () => {

View file

@ -31,7 +31,11 @@ export function reviewKey(review: Pick<Review, "execution_id" | "at">): string {
return `${review.execution_id}@${review.at}`;
}
export function providerOf(model: string): string {
export type ProviderCatalog = Readonly<Record<string, { litellm_provider?: string } | undefined>>;
export function providerOf(model: string, catalog: ProviderCatalog = {}): string {
const known = catalog[model]?.litellm_provider;
if (known) return known.toLowerCase();
const slash = model.indexOf("/");
return slash > 0 ? model.slice(0, slash).toLowerCase() : "";
}
@ -104,8 +108,8 @@ export function unseen(reviews: readonly Review[], seen: ReadonlySet<string>): R
return reviews.filter((review) => !seen.has(reviewKey(review)));
}
export function analysisModel(candidates: readonly string[]): string {
return candidates.find((model) => providerOf(model)) ?? candidates.find(Boolean) ?? "";
export function analysisModel(candidates: readonly string[], catalog: ProviderCatalog = {}): string {
return candidates.find((model) => providerOf(model, catalog)) ?? candidates.find(Boolean) ?? "";
}
const SHORT_LABEL = 48;
@ -232,8 +236,8 @@ export function liveRows(reading: readonly InFlight[], reviews: readonly Review[
export function nowLine(job: Pick<Job, "coverage" | "reviewed">, reading: number): string {
const { selected } = job.coverage;
const done = selected ? `${Math.min(job.reviewed, selected)} of ${selected} done` : `${job.reviewed} done`;
return reading ? `Reviewing ${reading} at a time · ${done}` : done;
const done = selected ? `${Math.min(job.reviewed, selected)} of ${selected}` : `${job.reviewed} done`;
return reading ? `${done} · ${reading} in flight` : done;
}
export function durationLabel(ms: number): string {