"use client"; import { KeyRound, RefreshCw } from "lucide-react"; import { Badge, Spinner } from "@/components/ui/primitives"; import { Button } from "@/components/ui/button"; import { cn, timeAgo } from "@/lib/utils"; import { hasBench, providerTone, type ModelRow, type ProviderRow } from "./format"; export function ProviderCards({ providers, models, onDiscover, discovering }: { providers: ProviderRow[]; models: ModelRow[]; onDiscover: () => void; discovering: boolean }) { return (
{providers.map((p) => { const mine = models.filter((m) => m.provider === p.id); const avail = mine.filter((m) => m.available); const enabled = avail.filter((m) => m.enabled && m.category !== "embedding"); const tested = mine.filter(hasBench); const tone = p.configured ? (p.status === "error" ? "danger" : "success") : "warning"; return (
{p.name}
{p.configured ? (p.status === "error" ? "error" : "key configured") : "no API key"}
{[["listed", mine.length], ["available", avail.length], ["enabled", enabled.length], ["benchmarked", tested.length]].slice(0, 3).map(([l, n]) =>
{n}
{l}
)}
{tested.length} benchmarked{p.lastDiscoveryAt ? `discovered ${timeAgo(p.lastDiscoveryAt)}` : "never discovered"}
); })}
Live discovery

Re-lists /v1/models on each configured provider, flips availability, and adds new ids as disabled/untested. Benchmarks are only refreshed by pnpm bench:*.

); }