Observability
Lap Timer
A pipeline run as a stopwatch — the hand sweeps through each stage's sector, with splits and the delta against the best lap.
1 variantMIT
Preview
Pipeline lap
eval run 418 · support-qa
Live
00:00.0
Lap 3 · 0 of 3 sectorsbest 44.1 s
| Sector | Split | Delta vs best |
|---|---|---|
| S1retrieve | 0.0 s | |
| S2generate | — | |
| S3score | — |
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/lap-timer.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { LapTimer } from "@/components/ui/lap-timer";
export function PipelineLap({ run }: { run: PipelineRun }) {
// Re-render on a frame clock (or every 100 ms) while the run is live.
const elapsed = useElapsed(run.startedAt, run.finishedAt);
return (
<LapTimer
title="Pipeline lap"
subtitle={`eval run ${run.id}`}
lap={`Lap ${run.attempt}`}
elapsed={elapsed}
best={run.bestLap} // seconds
running={!run.finishedAt}
sectors={run.stages.map((stage) => ({
id: stage.id,
label: stage.name, // "retrieve", "generate", "score"
best: stage.bestSplit,
split: stage.finishedAt ? stage.duration : undefined,
}))}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| sectors* | LapSector[] | — | Stages in order. Each one paints its arc on the dial; the first one without a split is the running one. |
| elapsed* | number | — | Seconds since the lap started. Drives the hand and the clock. |
| best | number | sum of sector bests | Best full lap in seconds. Marked on the dial and used for the delta next to the clock. |
| running | boolean | true | Whether the lap is still going. When false, the last split ends the lap. |
| dial | number | auto | Seconds per turn of the dial. Left out, it picks the smallest of 10 s, 15 s, 20 s, 30 s, 1 min… that fits the best lap. |
| title* | string | — | Header title. |
| subtitle | string | — | Secondary line under the title. |
| lap | string | — | Label above the dial next to the sector count, e.g. "Lap 3". |
| aside | ReactNode | — | Extra content on the right of the header, e.g. a status pill. |
| format | (seconds: number) => string | s.toFixed(1) + ' s' | Formats split times and the best lap. The clock is always mm:ss.t. |
| className | string | — | Extra classes for the root element. |
type LapSector = {
id: string;
label: string; // stage name
best: number; // best split, seconds
split?: number; // seconds, once the stage is done
};