import { cn } from "~/lib/utils"; import { type ContextWindowSnapshot, formatContextWindowTokens } from "~/lib/contextWindow"; import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover"; function formatPercentage(value: number | null): string | null { if (value === null || !Number.isFinite(value)) { return null; } if (value < 10) { return `${value.toFixed(1).replace(/\.0$/, "")}%`; } return `${Math.round(value)}%`; } export function ContextWindowMeter(props: { usage: ContextWindowSnapshot }) { const { usage } = props; const usedPercentage = formatPercentage(usage.usedPercentage); const normalizedPercentage = Math.max(0, Math.min(100, usage.usedPercentage ?? 0)); const radius = 9.75; const circumference = 2 * Math.PI * radius; const dashOffset = circumference - (normalizedPercentage / 100) * circumference; return ( {usage.usedPercentage !== null ? Math.round(usage.usedPercentage) : formatContextWindowTokens(usage.usedTokens)} } />
Context window
{usage.maxTokens !== null && usedPercentage ? (
{usedPercentage} ⋅ {formatContextWindowTokens(usage.usedTokens)} / {formatContextWindowTokens(usage.maxTokens ?? null)} context used
) : (
{formatContextWindowTokens(usage.usedTokens)} tokens used so far
)} {(usage.totalProcessedTokens ?? null) !== null && (usage.totalProcessedTokens ?? 0) > usage.usedTokens ? (
Total processed: {formatContextWindowTokens(usage.totalProcessedTokens ?? null)}{" "} tokens
) : null} {usage.compactsAutomatically ? (
Automatically compacts its context when needed.
) : null}
); }