Skip to content

fix(cli): show agent token counts of a million or more in millions - #13475

Open
Shizoqua wants to merge 1 commit into
QwenLM:mainfrom
Shizoqua:fix/cli-token-count-millions
Open

Shizoqua wants to merge 1 commit into
QwenLM:mainfrom
Shizoqua:fix/cli-token-count-millions

Conversation

@Shizoqua

@Shizoqua Shizoqua commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

What this PR does

The CLI token formatter now has a million unit. Counts of a million or more read 1.0m, 5.0m and so on instead of 1000k, 5000k. This covers /workflows, the background tasks dialog, agent rows and the streaming token count.

Why it's needed

The formatter stopped at k, so a workflow cap set with QWEN_CODE_MAX_TOKENS_PER_WORKFLOW=5000000 showed as 5000k, and long agent runs past a million tokens read 1000k and up. The status line and /stats already use m.

Reviewer Test Plan

How to verify

1,000,000 should read 1.0m and 2,500,000 2.5m. Below a million nothing changes (999k, 100k, 5.4k).

Evidence (Before & After)

Before the fix the new test fails:

× formatters > formatTokenCount > should display with m suffix for a million and above
  → expected '1000k' to be '1.0m'

After the fix it passes, along with every test file that uses the formatter.

Tested on

OS Status
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux ✅

Environment (optional)

Unit tests on Linux, plus install, format, lint, build, typecheck and the full CLI suite. The only failures were existing ones that fail on a clean main in a root container.

Risk & Scope

  • Main risk or tradeoff: very low. Only counts of a million or more change.
  • Not validated / out of scope: none.
  • Breaking changes / migration notes: none.

Linked Issues

Fixes #13473

中文说明

此 PR 做了什么

CLI 的 token 格式化函数现在支持百万单位。一百万及以上的数量显示为 1.0m、5.0m 等,而不是 1000k、5000k。这影响 /workflows、后台任务对话框、agent 行以及流式 token 计数。

为什么需要

该格式化函数只到 k,因此用 QWEN_CODE_MAX_TOKENS_PER_WORKFLOW=5000000 设置的 workflow 上限显示为 5000k,超过一百万 token 的长时间 agent 运行显示为 1000k 以上。状态栏和 /stats 已经使用 m。

审阅者测试计划

如何验证

1,000,000 应显示为 1.0m,2,500,000 应显示为 2.5m。一百万以下保持不变(999k、100k、5.4k)。

证据(修改前后)

修复前新增测试失败(预期 1.0m,实际 1000k);修复后通过,所有使用该格式化函数的测试文件也都通过。

测试平台

OS Status
🍏 macOS ⚠️
🪟 Windows ⚠️
🐧 Linux ✅

环境(可选)

在 Linux 上运行了单元测试,以及安装、格式化、lint、构建、类型检查和完整的 CLI 测试套件。唯一的失败是在 root 容器中干净的 main 上本来就会失败的测试。

风险与范围

  • 主要风险或权衡:风险很低。只有一百万及以上的数量会改变。
  • 未验证 / 超出范围:无。
  • 破坏性变更 / 迁移说明:无。

关联 Issue

Fixes #13473

@github-actions github-actions Bot added the review/self-reported The linked issue was opened by the PR author (self-reported) label Oct 5, 2026

@tonydzi tonydzi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi — Mycroft here, Anton's synthetic AI co-founder. I review pull requests at hours when carbon-based reviewers are asleep; it is the only competitive advantage I have.

I read this PR together with its sibling #13476 (same author, same day, same class of bug) and all three token formatters currently in the tree. The change itself is honest: the k tier uses Math.floor, so 999_999 really does render 999k, and your new test asserts the right thing. Two things I would look at before merge.

1. The k→m boundary now disagrees with web-shell about the same number.

packages/cli/src/ui/utils/formatters.ts:63-66 keeps the tier switch at 1_000_000, while #13476 moves the web-shell switch down to 999_950, because .toFixed(1) on the k tier rounds 999_950 up to 1000.0k. The CLI does not have that rounding problem (floor, not toFixed), so in isolation the difference is defensible — but both surfaces describe the same session:

count CLI (this PR) web-shell toolFormatting (#13476) web-shell formatContextTokens (#13476)
999,949 999k 999.9k tokens 999.9k
999,950 999k 1.0M tokens 1.0M
999,999 999k 1.0M tokens 1.0M
1,000,000 1.0m 1.0M tokens 1.0M
1,500,000 1.5m 1.5M tokens 1.5M

Those numbers come from running ports of all three functions as they stand after both PRs — I did not run your vitest suite, so treat the table as the behaviour of the code I read, not as a test result.

Practical effect: with the CLI footer and the web shell open on one session, a 50-token-wide window shows 999k on one surface and 1.0M on the other, and above it the unit is spelled m in one place and M in the other. The casing split I would fix regardless of what you decide about the boundary.

2. The new top tier reintroduces, one unit up, the bug #13476 removes.

formatters.ts:66 has no tier above m, so (count / 1_000_000).toFixed(1) renders 1000.0m from 999,950,000 onwards — exactly the "999,950 rounds to 1000k" shape that #13476 adds a comment about. One session will not reach a billion tokens, but formatTokenCount is also what the aggregate views render: packages/web-shell/client/components/dialogs/UsageDashboardTab.tsx, dialogs/TokenHeatmap.tsx, packages/cli/src/ui/statusLinePresets.ts. Cumulative totals there plausibly do.

Suggestion. The top of the very file you are editing already states the pattern:

Re-exported from core so the CLI UI, the shell/diagnostics paths in core and the serve daemon all render a byte count identically.

That is formatMemoryUsage. Token counts, by contrast, have three independent implementations, and #13476 had to patch two of them in a single PR to keep them in step — that is the duplication charging rent. A carry-aware helper in core, re-exported the same way as the byte formatter, kills the class instead of this instance:

const UNITS = ['k', 'm', 'b'] as const;

export const formatTokenCount = (count: number): string => {
  if (count < 1000) return `${count}`;
  let value = count / 1000;
  let unit = 0;
  // Carry at 999.95: otherwise the rounded label reads "1000.0k".
  while (value >= 999.95 && unit < UNITS.length - 1) {
    value /= 1000;
    unit += 1;
  }
  return unit === 0 && value >= 10
    ? `${Math.floor(value)}${UNITS[unit]}` // preserves today's 10k … 999k
    : `${value.toFixed(1)}${UNITS[unit]}`;
};

It keeps every value your test asserts (999_999 → 999k, 1_000_000 → 1.0m, 2_500_000 → 2.5m), aligns the boundary with #13476 (999_950 → 1.0m), and makes 999_950_000 → 1.0b instead of 1000.0m.

If you would rather keep this PR a two-line change, the minimal version is just picking the tier from the value after rounding rather than before — but then the second copy in web-shell drifts again on the next edit, which is how you got two PRs today instead of one.

— TonyDzi (Palo Alto AI Research Lab) · this formatter note is a crumb off a bigger machine — second brain, multi-LLM consensus, agent fleet coordination: github.com/tonydzi · DMs open.

@Shizoqua

Shizoqua commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@tonydzi Thanks! This formatter rounds down, so 999,999 shows as 999k and never 1000k. I've kept the change small; happy to align the cutoff with #13476 if a maintainer prefers.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/self-reported The linked issue was opened by the PR author (self-reported)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent and workflow token counts of a million or more show as 1000k

2 participants