From d6f28a3da7f3d32700a80a7e402e63b35808bb1c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 7 Mar 2026 19:59:12 +0000 Subject: [PATCH] fix(usage): format near-million token counts as millions (#39129) Co-authored-by: CurryMessi --- CHANGELOG.md | 1 + src/utils/usage-format.test.ts | 2 ++ src/utils/usage-format.ts | 7 ++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f23c4ee355..8dc7d1de255 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -269,6 +269,7 @@ Docs: https://docs.openclaw.ai - Voice-call plugin schema parity: add missing manifest `configSchema` fields (`webhookSecurity`, `streaming.preStartTimeoutMs|maxPendingConnections|maxPendingConnectionsPerIp|maxConnections`, `staleCallReaperSeconds`) so gateway AJV validation accepts already-supported runtime config instead of failing with `additionalProperties` errors. (#38892) Thanks @giumex. - Agents/OpenAI WS reconnect retry accounting: avoid double retry scheduling when reconnect failures emit both `error` and `close`, so retry budgets track actual reconnect attempts instead of exhausting early. (#39133) Thanks @scoootscooob. - Daemon/Windows schtasks runtime detection: use locale-invariant `Last Run Result` running codes (`0x41301`/`267009`) as the primary running signal so `openclaw node status` no longer misreports active tasks as stopped on non-English Windows locales. (#39076) Thanks @ademczuk. +- Usage/token count formatting: round near-million token counts to millions (`1.0m`) instead of `1000k`, with explicit boundary coverage for `999_499` and `999_500`. (#39129) Thanks @CurryMessi. ## 2026.3.2 diff --git a/src/utils/usage-format.test.ts b/src/utils/usage-format.test.ts index 25dac6d612e..128e048001e 100644 --- a/src/utils/usage-format.test.ts +++ b/src/utils/usage-format.test.ts @@ -12,6 +12,8 @@ describe("usage-format", () => { expect(formatTokenCount(999)).toBe("999"); expect(formatTokenCount(1234)).toBe("1.2k"); expect(formatTokenCount(12000)).toBe("12k"); + expect(formatTokenCount(999_499)).toBe("999k"); + expect(formatTokenCount(999_500)).toBe("1.0m"); expect(formatTokenCount(2_500_000)).toBe("2.5m"); }); diff --git a/src/utils/usage-format.ts b/src/utils/usage-format.ts index f8182f5dbb0..1086163bf20 100644 --- a/src/utils/usage-format.ts +++ b/src/utils/usage-format.ts @@ -25,7 +25,12 @@ export function formatTokenCount(value?: number): string { return `${(safe / 1_000_000).toFixed(1)}m`; } if (safe >= 1_000) { - return `${(safe / 1_000).toFixed(safe >= 10_000 ? 0 : 1)}k`; + const precision = safe >= 10_000 ? 0 : 1; + const formattedThousands = (safe / 1_000).toFixed(precision); + if (Number(formattedThousands) >= 1_000) { + return `${(safe / 1_000_000).toFixed(1)}m`; + } + return `${formattedThousands}k`; } return String(Math.round(safe)); }