minicpm5-webgpu / src /lib /contextUsage.ts
fatih-can's picture
MiniCPM5-2B WebGPU chat frontend
c7592d1 verified
Raw History Blame Contribute Delete
1.53 kB
/**
* How full the context window is.
*
* The figure comes from WebLLM's own `usage.prompt_tokens` - the exact tokens of
* the prompt we just sent - so this needs no tokenizer and no guessing.
*/
export type ContextLevel = "normal" | "high" | "near-limit";
/** Above this share of the window the meter warns. */
export const CONTEXT_HIGH = 0.75;
/** Above this the next turn is likely to start dropping history. */
export const CONTEXT_NEAR_LIMIT = 0.95;
export function contextRatio(used: number | null, max: number): number | null {
if (used === null || !Number.isFinite(used) || !(max > 0)) return null;
return Math.min(1, Math.max(0, used / max));
}
export function contextLevel(ratio: number): ContextLevel {
if (ratio >= CONTEXT_NEAR_LIMIT) return "near-limit";
if (ratio >= CONTEXT_HIGH) return "high";
return "normal";
}
/** Compact token count for a tight status line: 950 -> "950", 12400 -> "12.4k". */
export function formatTokens(tokens: number): string {
if (!Number.isFinite(tokens) || tokens < 0) return "0";
if (tokens < 1000) return `${Math.round(tokens)}`;
const k = tokens / 1000;
if (k >= 100) return `${Math.round(k)}k`;
// One decimal, but no pointless ".0": "8k" rather than "8.0k".
return `${k.toFixed(1).replace(/\.0$/, "")}k`;
}
/** "12.4k / 32k" - the label next to the meter. */
export function formatContextPair(used: number | null, max: number): string | null {
if (used === null || !(max > 0)) return null;
return `${formatTokens(used)} / ${formatTokens(max)}`;
}