"use client"; import type { ModelFitScore } from "@/lib/modelfit"; const FIT_COLOR: Record = { comfortable: "text-emerald-400", tight: "text-amber-400", not_recommended: "text-orange-400", impossible: "text-red-400", }; const LABEL_SHORT: Record = { "Excellent fit": "★★★", "Recommended": "★★", "Usable with limits": "★", "Not recommended": "–", "Does not fit": "✗", }; export function ComparisonTable({ scores }: { scores: ModelFitScore[] }) { if (scores.length === 0) { return (

No models scored yet. Use Model Search to select models and compute scores.

); } function exportCSV() { const header = [ "model_id", "quantization", "overall", "hardware_fit", "speed_fit", "rag_fit", "task_fit", "deployment_fit", "label", "vram_gb", "disk_gb", "tok_per_sec_measured", "fit_level", ].join(","); const rows = scores.map((s) => { const re = s.resource_estimate; return [ JSON.stringify(s.model_id), s.best_quantization, s.overall_score, s.hardware_fit, s.speed_fit, s.rag_fit, s.task_fit, s.deployment_fit, JSON.stringify(s.label), re?.estimated_vram_gb ?? "", re?.estimated_disk_gb ?? "", s.benchmark?.avg_tok_per_sec ?? "", re?.fit_level ?? "", ].join(","); }); const csv = [header, ...rows].join("\n"); const blob = new Blob([csv], { type: "text/csv" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "modelfit-comparison.csv"; a.click(); URL.revokeObjectURL(url); } function exportJSON() { const blob = new Blob([JSON.stringify(scores, null, 2)], { type: "application/json" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "modelfit-comparison.json"; a.click(); URL.revokeObjectURL(url); } function exportMarkdown() { const header = `| Model | Quant | Score | HW | Speed | RAG | VRAM est. | Tok/s | Fit | Label |`; const sep = `|-------|-------|------:|---:|------:|----:|----------:|------:|-----|-------|`; const rows = scores.map((s) => { const re = s.resource_estimate; const model = s.model_id.replace(/^(ollama:|hf:|local:)/, ""); const toks = s.benchmark?.avg_tok_per_sec != null ? String(s.benchmark.avg_tok_per_sec) : "—"; const vram = re ? `${re.estimated_vram_gb} GB` : "—"; const fit = re?.fit_level?.replace("_", " ") ?? "unknown"; const speed = `${Math.round(s.speed_fit)}${s.estimate_used ? "*" : ""}`; return `| ${model} | ${s.best_quantization} | ${Math.round(s.overall_score)} | ${Math.round(s.hardware_fit)} | ${speed} | ${Math.round(s.rag_fit)} | ${vram} | ${toks} | ${fit} | ${s.label} |`; }); const md = [`## Auralynq ModelFit Comparison`, ``, header, sep, ...rows, ``, `\\* speed score uses estimates — run benchmark for measured tok/s`].join("\n"); const blob = new Blob([md], { type: "text/markdown" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "modelfit-comparison.md"; a.click(); URL.revokeObjectURL(url); } return (
{scores.map((s) => { const re = s.resource_estimate; return ( ); })}
Model Quant Score HW Speed RAG VRAM est. Disk est. Tok/s Fit Label
{s.model_id.replace(/^(ollama:|hf:|local:)/, "")} {s.best_quantization} {Math.round(s.overall_score)} {Math.round(s.hardware_fit)} {Math.round(s.speed_fit)} {s.estimate_used && *} {Math.round(s.rag_fit)} {re ? `${re.estimated_vram_gb} GB` : "—"} est. {re ? `${re.estimated_disk_gb} GB` : "—"} {s.benchmark?.avg_tok_per_sec != null ? ( {s.benchmark.avg_tok_per_sec} ) : ( not run )} {re?.fit_level?.replace("_", " ") ?? "unknown"} {LABEL_SHORT[s.label] ?? ""} {s.label}

* speed score uses estimates — run benchmark for measured tok/s

); }