From 42cefdaaac00989627e4f02e4dfa29a8b647111f Mon Sep 17 00:00:00 2001 From: Kevin Rajan Date: Tue, 29 Sep 2026 19:10:05 -0500 Subject: [PATCH] [muse] fix(shared): promote rounded-up token counts into the next unit formatTokens(999500) printed "1000K" and formatTokens(999999999) printed "1000M": the unit suffix was chosen before trim() rounded, so values that round up across a unit boundary displayed with the wrong suffix. The scaled text is now checked for a rounded-up "1000" and promoted (999.5K -> "1M"). Red-on-base: packages/shared/src/usageFormat.test.ts "promotes a rounded-up boundary into the next unit instead of printing 1000K" failed on base with expected '1000K' to be '1M'; green after the fix. Full file: 10/10 passed. --- Authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction. --- packages/shared/src/usageFormat.test.ts | 14 ++++++++++++++ packages/shared/src/usageFormat.ts | 23 +++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/packages/shared/src/usageFormat.test.ts b/packages/shared/src/usageFormat.test.ts index 3a47ede3bcc83..e5c8d56345da1 100644 --- a/packages/shared/src/usageFormat.test.ts +++ b/packages/shared/src/usageFormat.test.ts @@ -7,9 +7,23 @@ import { formatHourShort, formatPercent, formatRelativeHourShort, + formatTokens, makeWindow, } from "./usageFormat.ts"; +describe("formatTokens", () => { + it("promotes a rounded-up boundary into the next unit instead of printing 1000K", () => { + expect(formatTokens(999_499)).toBe("999K"); + expect(formatTokens(999_500)).toBe("1M"); + expect(formatTokens(999_999)).toBe("1M"); + expect(formatTokens(999_999_999)).toBe("1B"); + expect(formatTokens(1_500_000)).toBe("1.50M"); + expect(formatTokens(-999_500)).toBe("-1M"); + expect(formatTokens(804)).toBe("804"); + expect(formatTokens(76_700_000)).toBe("76.7M"); + }); +}); + describe("formatPercent", () => { it("distinguishes a small positive share from zero", () => { expect(formatPercent(0)).toBe("0.0%"); diff --git a/packages/shared/src/usageFormat.ts b/packages/shared/src/usageFormat.ts index 83b2d53fb99fb..6b067653429bf 100644 --- a/packages/shared/src/usageFormat.ts +++ b/packages/shared/src/usageFormat.ts @@ -25,16 +25,31 @@ export function formatCount(value: number): string { return INTEGER.format(Math.round(value)); } +const TOKEN_UNITS = [ + [1e12, "T"], + [1e9, "B"], + [1e6, "M"], + [1e3, "K"], +] as const; + /** * Compacts a token count to three significant figures with a unit suffix, so * columns of numbers line up at a glance (`19.9B`, `76.7M`, `804K`). */ export function formatTokens(value: number): string { const abs = Math.abs(value); - if (abs >= 1e12) return `${trim(value / 1e12)}T`; - if (abs >= 1e9) return `${trim(value / 1e9)}B`; - if (abs >= 1e6) return `${trim(value / 1e6)}M`; - if (abs >= 1e3) return `${trim(value / 1e3)}K`; + for (let i = 0; i < TOKEN_UNITS.length; i++) { + const [scale, suffix] = TOKEN_UNITS[i]; + if (abs < scale) continue; + const text = trim(value / scale); + // trim() rounds: 999.5K would otherwise print "1000K". Promote a + // rounded-up boundary into the next unit so columns stay aligned. + if ((text === "1000" || text === "-1000") && i > 0) { + const [nextScale, nextSuffix] = TOKEN_UNITS[i - 1]; + return `${trim(value / nextScale)}${nextSuffix}`; + } + return `${text}${suffix}`; + } return INTEGER.format(Math.round(value)); }