import type { Theme } from "@earendil-works/pi-coding-agent"; import { computeCacheHitPercent } from "./cache-math.js"; import type { CacheUsageTotals } from "./types.js"; /** Hit rates at or above this are considered healthy (green). */ const HIT_RATE_HEALTHY = 95; /** Hit rates at or above this (but below healthy) need attention (yellow). */ const HIT_RATE_ATTENTION = 80; /** * Colorizes a hit-rate value using pi's theme: green >= 95%, yellow 80-95%, * red < 80%. Callers should pad plain text *before* colorizing so ANSI codes * do not disturb column alignment. */ export function hitRateColor(theme: Theme, percent: number, text: string): string { if (percent >= HIT_RATE_HEALTHY) return theme.fg("success", text); if (percent >= HIT_RATE_ATTENTION) return theme.fg("warning", text); return theme.fg("error", text); } /** * Compact token formatting: 16,868,357 -> "16.9M". Always fits in 6 chars * for any practical token count, so fixed-width table columns never overflow. */ export function formatCompact(value: number): string { const abs = Math.abs(value); const fmt = (v: number, suffix: string): string => v.toFixed(1).replace(/\.0$/, "") + suffix; if (abs >= 1_000_000_000) return fmt(value / 1_000_000_000, "B"); if (abs >= 1_000_000) return fmt(value / 1_000_000, "M"); if (abs >= 1_000) return fmt(value / 1_000, "k"); return String(value); } export function formatPercent(value: number): string { return `${value.toFixed(1)}%`; } export function shortModelName(provider: string, model: string): string { return `${provider}/${model}`; } export function summarizeHitPercent(totals: CacheUsageTotals): number { return computeCacheHitPercent(totals.input, totals.cacheRead, totals.cacheWrite); }