"use client" import type { ComponentType, CSSProperties } from "react" import { useAudienceMode } from "@/components/audience-mode-provider" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader } from "@/components/ui/card" import { useRouter } from "next/navigation" import { AlertTriangle, BadgeCheck, BookOpenText, ChartNoAxesColumn, Database, ExternalLink, FlaskConical, Scale, Users, } from "lucide-react" import type { BenchmarkEvalListItem } from "@/lib/eval-processing" import { getCategoryColor } from "@/lib/benchmark-schema" const LICENSE_COLORS: Record = { "mit": "bg-emerald-100 text-emerald-800 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-200", "apache": "bg-sky-100 text-sky-800 border-sky-200 dark:bg-sky-950/40 dark:text-sky-200", "cc by": "bg-violet-100 text-violet-800 border-violet-200 dark:bg-violet-950/40 dark:text-violet-200", "cc0": "bg-teal-100 text-teal-800 border-teal-200 dark:bg-teal-950/40 dark:text-teal-200", "cc-by-sa": "bg-indigo-100 text-indigo-800 border-indigo-200 dark:bg-indigo-950/40 dark:text-indigo-200", } function licenseBadgeClass(license: string): string { const l = license.toLowerCase() for (const [key, cls] of Object.entries(LICENSE_COLORS)) { if (l.includes(key)) return cls } return "bg-muted text-muted-foreground border-border" } function shortenLicense(license: string): string { if (!license || license === "Not specified") return "" // Shorten known verbose license names if (license.toLowerCase().includes("creative commons attribution 4")) return "CC BY 4.0" if (license.toLowerCase().includes("creative commons zero")) return "CC0" if (license.toLowerCase().includes("apache license 2") || license.toLowerCase().includes("apache 2")) return "Apache 2.0" if (license.toLowerCase().includes("mit license")) return "MIT" if (license.toLowerCase().includes("cc-by-sa")) return "CC BY-SA" if (license.length > 24) return license.slice(0, 22) + "…" return license } interface EvalCardProps { summary: BenchmarkEvalListItem delayMs?: number } export function EvalCard({ summary, delayMs = 0 }: EvalCardProps) { const router = useRouter() const { mode } = useAudienceMode() const isResearchView = mode === "research" const scorePercent = `${Math.round(summary.avg_score_norm * 100)}%` const card = summary.benchmark_card const domains: string[] = summary.tags?.domains ?? card?.benchmark_details?.domains ?? [] const license = card?.ethical_and_legal_considerations?.data_licensing ?? "" const shortLicense = shortenLicense(license) // Use the benchmark overview as a richer description when available const overviewText = card?.benchmark_details?.overview // Policy: rich context from metadata card const policyGoal = card?.purpose_and_intended_users?.goal const policyLimitations = card?.purpose_and_intended_users?.limitations const policyAudience = card?.purpose_and_intended_users?.audience const audienceText = Array.isArray(policyAudience) ? policyAudience.slice(0, 2).join("; ") : typeof policyAudience === "string" ? policyAudience : null // Research: score interpretation + similar benchmarks const scoreInterpretation = card?.methodology?.interpretation const rawSimilar = card?.benchmark_details?.similar_benchmarks const similarBenchmarks: string[] = Array.isArray(rawSimilar) ? rawSimilar : rawSimilar ? [rawSimilar] : [] const domainPreview = domains.slice(0, 2) // Source provenance pulled from the pipeline's source_data const sourceData = summary.source_data const reproducibilitySummary = summary.reproducibility_summary const reproducibilityGapCount = reproducibilitySummary?.has_reproducibility_gap_count ?? summary.missing_generation_config_count const reproducibilityResultsTotal = reproducibilitySummary?.results_total ?? summary.models_count const datasetName = sourceData?.dataset_name const datasetUrl = sourceData?.dataset_url ?? (Array.isArray(sourceData?.url) ? sourceData?.url?.[0] : sourceData?.url) ?? (sourceData?.hf_repo ? `https://huggingface.co/datasets/${sourceData.hf_repo}` : undefined) const datasetVersion = sourceData?.dataset_version const sourceTypeLabel = sourceData?.source_type return ( router.push(`/evals/${summary.evaluation_id}`)} >
Single Benchmark
{summary.category && ( {summary.category} )}
{shortLicense && ( {shortLicense} )}
{summary.evaluation_name}
Composite benchmark: {summary.composite_benchmark_name}
{overviewText ?? summary.metric_config.evaluation_description}
{summary.third_party_ratio > 0 && ( Independently evaluated )} {reproducibilityGapCount > 0 && ( Documentation gaps )}
{domains.length > 0 && (
Domain coverage {domainPreview.map((domain) => ( {domain} ))} {domains.length > domainPreview.length && +{domains.length - domainPreview.length} more}
)}
{isResearchView ? ( <>
{/* Research: score interpretation from metadata */} {scoreInterpretation && (
Score interpretation

{scoreInterpretation}

)}
Methodology
{summary.tags?.tasks && summary.tags.tasks.length > 0 && ( )} {summary.latest_source_name && ( )} 0 ? `${reproducibilityGapCount} of ${reproducibilityResultsTotal} scores have setup gaps` : "Fully documented" } /> {similarBenchmarks.length > 0 && ( )}
{(datasetName || datasetUrl || sourceTypeLabel) && ( )} ) : ( <> {/* Policy: goal from metadata card */}
Purpose
{policyGoal ?? "General single-benchmark evaluation"}
{/* Policy: audience + limitations from metadata */} {(audienceText || policyLimitations) && (
{audienceText && (
Intended for: {audienceText}
)} {policyLimitations && (
Known limitation: {policyLimitations}
)}
)}
{reproducibilityGapCount > 0 && (

{reproducibilityGapCount} of {reproducibilityResultsTotal} reported scores are not fully documented.

)}
{(datasetName || datasetUrl || sourceTypeLabel) && ( )} )}
) } function MetricPill({ icon: Icon, label, value, tone, }: { icon: ComponentType<{ className?: string }> label: string value: string tone: string }) { return (
{label}
{value}
) } function DataRow({ label, value }: { label: string; value: string }) { return (
{label} {value}
) } function ProvenanceRow({ datasetName, datasetUrl, datasetVersion, sourceType, }: { datasetName?: string datasetUrl?: string datasetVersion?: string sourceType?: string }) { return (
Source dataset
{datasetName && ( {datasetName} {datasetVersion ? · v{datasetVersion} : null} )} {sourceType && ( {sourceType.replace(/_/g, " ")} )} {datasetUrl && ( event.stopPropagation()} className="ml-auto inline-flex items-center gap-1 text-xs font-medium text-primary hover:underline" > View source )}
) }