/** * Format a byte count into a human-readable string. * * @example formatBytes(1536) // '1.5 KB' * @example formatBytes(0) // '0 B' */ export function formatBytes(bytes: number): string { if (bytes <= 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`; } /** * Approximate token count for a text string. * * Uses a word-count × 1.3 heuristic (typical for English text with LLM tokenizers). */ export function estimateTokens(text: string): number { const trimmed = text.trim(); if (!trimmed) return 0; return Math.ceil(trimmed.split(/\s+/).length * 1.3); } /** * Best-effort model context window lookup based on model name. * * Checks for common context window markers in the model name string. * Falls back to 4096 if no marker is found. */ export function getModelContextWindow(modelName: string): number { const n = modelName.toLowerCase(); if (n.includes('128k')) return 128_000; if (n.includes('64k')) return 64_000; if (n.includes('32k')) return 32_000; if (n.includes('16k')) return 16_000; if (n.includes('8k')) return 8_000; return 4_096; } /** * Format a duration in seconds to a human-readable uptime string. * * @example formatUptime(90061) // '1d 1h 1m' * @example formatUptime(3661) // '1h 1m' * @example formatUptime(120) // '2m' */ export function formatUptime(seconds: number): string { const d = Math.floor(seconds / 86400); const h = Math.floor((seconds % 86400) / 3600); const m = Math.floor((seconds % 3600) / 60); if (d > 0) return `${d}d ${h}h ${m}m`; if (h > 0) return `${h}h ${m}m`; return `${m}m`; }