172 lines
5.6 KiB
TypeScript
172 lines
5.6 KiB
TypeScript
import fs from "node:fs";
|
||
import path from "node:path";
|
||
import { ImageResponse } from "next/og";
|
||
import { fmtParams, getRun, getRuns, limitOf } from "@/lib/results";
|
||
|
||
/**
|
||
* Shareable score card as a PNG.
|
||
*
|
||
* One image serves two jobs: the download button and the OpenGraph tag, so a
|
||
* pasted link unfurls as the card itself. Fonts are bundled rather than
|
||
* fetched at request time — satori needs real font buffers, and a network
|
||
* dependency inside image generation fails in exactly the situations where
|
||
* you want a share link to work.
|
||
*
|
||
* Note: satori supports flexbox only. Every container needs an explicit
|
||
* display value; CSS grid silently renders nothing.
|
||
*/
|
||
|
||
export const dynamic = "force-static";
|
||
|
||
export function generateStaticParams() {
|
||
return getRuns().map((r) => ({ id: r.run_id.slice(0, 8) }));
|
||
}
|
||
|
||
const FONT_DIR = path.join(process.cwd(), "assets", "fonts");
|
||
const font = (file: string) => fs.readFileSync(path.join(FONT_DIR, file));
|
||
|
||
const VOID = "#08090b";
|
||
const RULE = "#1e232b";
|
||
const INK = "#e8e6e1";
|
||
const DIM = "#79818d";
|
||
const DIMMER = "#4a515b";
|
||
const SIGNAL = "#f2b134";
|
||
const REFERENCE = "#5896ae";
|
||
|
||
function Stat({
|
||
label,
|
||
value,
|
||
unit,
|
||
color = INK,
|
||
hint,
|
||
}: {
|
||
label: string;
|
||
value: string;
|
||
unit?: string;
|
||
color?: string;
|
||
hint?: string;
|
||
}) {
|
||
return (
|
||
<div style={{ display: "flex", flexDirection: "column", flex: 1 }}>
|
||
<div style={{ fontSize: 15, letterSpacing: 3, color: DIMMER, textTransform: "uppercase" }}>
|
||
{label}
|
||
</div>
|
||
<div style={{ display: "flex", alignItems: "baseline", marginTop: 12 }}>
|
||
<span style={{ fontFamily: "Instrument", fontSize: 62, color, lineHeight: 1 }}>{value}</span>
|
||
{unit && <span style={{ fontSize: 17, color: DIMMER, marginLeft: 7 }}>{unit}</span>}
|
||
</div>
|
||
{hint && <div style={{ fontSize: 14, color: DIMMER, marginTop: 8 }}>{hint}</div>}
|
||
</div>
|
||
);
|
||
}
|
||
|
||
export async function GET(
|
||
_req: Request,
|
||
{ params }: { params: Promise<{ id: string }> },
|
||
) {
|
||
const { id } = await params;
|
||
const run = getRun(id);
|
||
if (!run) return new Response("not found", { status: 404 });
|
||
|
||
const v = run.verdict;
|
||
const limit = limitOf(run);
|
||
const perf = run.perf?.points ?? [];
|
||
const single = perf.find((p) => p.concurrency === 1);
|
||
const peak = perf.length
|
||
? perf.reduce((a, b) => (b.output_tps_total > a.output_tps_total ? b : a))
|
||
: null;
|
||
|
||
return new ImageResponse(
|
||
(
|
||
<div
|
||
style={{
|
||
width: "100%",
|
||
height: "100%",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
background: VOID,
|
||
fontFamily: "Plex",
|
||
color: INK,
|
||
padding: 56,
|
||
}}
|
||
>
|
||
{/* header */}
|
||
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline" }}>
|
||
<div style={{ display: "flex", alignItems: "baseline" }}>
|
||
<span style={{ fontFamily: "Instrument", fontSize: 30 }}>bench</span>
|
||
<span style={{ fontFamily: "Instrument", fontSize: 30, color: DIMMER }}>.karti.ai</span>
|
||
</div>
|
||
<span style={{ fontSize: 15, letterSpacing: 3, color: DIMMER, textTransform: "uppercase" }}>
|
||
{run.timestamp.slice(0, 10)}
|
||
</span>
|
||
</div>
|
||
|
||
<div style={{ display: "flex", height: 1, background: RULE, marginTop: 24, marginBottom: 40 }} />
|
||
|
||
{/* title */}
|
||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||
<span style={{ fontFamily: "Instrument", fontSize: 68, lineHeight: 1.05 }}>
|
||
{run.target.display_name}
|
||
</span>
|
||
<span style={{ fontSize: 18, color: DIM, marginTop: 16 }}>
|
||
{run.host.hardware} · {fmtParams(run.target)} ·{" "}
|
||
{run.target.quant?.toUpperCase()} · {run.target.serving.engine}
|
||
</span>
|
||
</div>
|
||
|
||
{/* stats */}
|
||
<div style={{ display: "flex", marginTop: "auto", gap: 24 }}>
|
||
<Stat
|
||
label="signal"
|
||
value={v.signal_score != null ? v.signal_score.toFixed(3) : "—"}
|
||
color={SIGNAL}
|
||
hint="our workloads"
|
||
/>
|
||
<Stat
|
||
label="reference"
|
||
value={v.reference_score != null ? v.reference_score.toFixed(3) : "—"}
|
||
color={REFERENCE}
|
||
hint={limit ? `capped ${limit}` : "calibration"}
|
||
/>
|
||
<Stat
|
||
label="single stream"
|
||
value={single ? single.output_tps_per_stream.toFixed(1) : "—"}
|
||
unit="tok/s"
|
||
hint={single?.ttft_p50_ms ? `ttft ${Math.round(single.ttft_p50_ms)}ms` : undefined}
|
||
/>
|
||
<Stat
|
||
label="peak"
|
||
value={peak ? peak.output_tps_total.toFixed(0) : "—"}
|
||
unit="tok/s"
|
||
hint={peak ? `at ×${peak.concurrency}` : undefined}
|
||
/>
|
||
</div>
|
||
|
||
{/* tick strip — a measurement scale across the full plate */}
|
||
<div style={{ display: "flex", marginTop: 40, justifyContent: "space-between", width: "100%" }}>
|
||
{Array.from({ length: 96 }).map((_, i) => (
|
||
<div
|
||
key={i}
|
||
style={{
|
||
display: "flex",
|
||
width: 1,
|
||
height: 8,
|
||
background: i % 6 === 0 ? SIGNAL : RULE,
|
||
}}
|
||
/>
|
||
))}
|
||
</div>
|
||
</div>
|
||
),
|
||
{
|
||
width: 1200,
|
||
height: 630,
|
||
fonts: [
|
||
{ name: "Instrument", data: font("InstrumentSerif-Regular.ttf"), style: "normal", weight: 400 },
|
||
{ name: "Plex", data: font("IBMPlexMono-Regular.ttf"), style: "normal", weight: 400 },
|
||
{ name: "Plex", data: font("IBMPlexMono-SemiBold.ttf"), style: "normal", weight: 600 },
|
||
],
|
||
},
|
||
);
|
||
}
|