Skip to content

fix(subagents): roll formatTokenShort over to "m" at 1000k#88209

Merged
steipete merged 3 commits into
openclaw:mainfrom
coder999999999:fix/format-token-short-rollover
May 31, 2026
Merged

fix(subagents): roll formatTokenShort over to "m" at 1000k#88209
steipete merged 3 commits into
openclaw:mainfrom
coder999999999:fix/format-token-short-rollover

Conversation

@coder999999999

Copy link
Copy Markdown
Contributor

Summary

formatTokenShort in src/shared/subagents-format.ts emitted an out-of-scheme "1000k" for token counts in [999_500, 999_999]. The n < 1_000_000 branch returned `${Math.round(n / 1_000)}k`, and Math.round rounds those values up to 1000, so the formatter produced "1000k" instead of rolling over to the million branch ("1m").

The sibling formatter formatTokenCount (src/utils/usage-format.ts) already guards this exact case (if (Number(formattedThousands) >= 1_000) return …m), so the correct behavior is established in core — formatTokenShort simply omitted the rollover check.

User impact: formatTokenShort feeds formatTokenUsageDisplay, rendered in the subagent list usage line (src/agents/subagent-list.ts:246). A subagent that consumed ~999.5k–999.999k tokens displayed "1000k" instead of "1m".

Fix

Fall through to the "m" branch when the rounded thousands reach 1000, mirroring formatTokenCount. One small change plus rollover-boundary regression rows.

Real behavior proof (required for external PRs)

Behavior addressed: token counts in the 999.5k–999.999k range rendered as 1000k in the subagent usage display because the thousands-rounding branch could reach 1000 without advancing to the million unit. After this patch they render as 1m.

Real environment tested: local macOS checkout on fresh main. The proof drives the real production formatTokenShort (the exact function the subagent list calls through formatTokenUsageDisplay) over its boundary inputs. No mocks of the function under test.

Exact steps or command run after this patch: I added rollover-boundary rows to the formatter's table test, ran them against the unpatched formatTokenShort (they emitted 1000k), then applied the fix and re-ran. Command:

node scripts/run-vitest.mjs src/shared/subagents-format.test.ts

Evidence after fix: copied live console output from node scripts/run-vitest.mjs

BEFORE (unpatched, Math.round reaches 1000):
  x formats token counts with integer, kilo, and million branches
  AssertionError: expected '1000k' to be '1m'
  Expected: "1m"
  Received: "1000k"
  Tests  1 failed | 4 passed (5)

AFTER (this fix):
  Test Files  1 passed (1)
  Tests  5 passed (5)

Observed result after fix: the node scripts/run-vitest.mjs run shows formatTokenShort(999_500) and formatTokenShort(999_999) now return "1m" (previously "1000k"), while formatTokenShort(999_499) is unchanged at "999k".

What was not tested: I did not capture a live screenshot of the subagent list TUI; the proof drives the exact formatter that view renders, over the boundary inputs, via node scripts/run-vitest.mjs.

Tests and validation

  • node scripts/run-vitest.mjs src/shared/subagents-format.test.ts -> 5 passed (new rollover-boundary rows: 999_499 -> 999k, 999_500/999_999 -> 1m).
  • Before/after isolation above: the new rows fail (1000k) on the unpatched source and pass with the fix.
  • oxfmt --check clean, oxlint clean, tsgo:core exit 0, tsgo:core:test exit 0, git diff --check clean. Diff is +11 / -1 across 2 files.

Copilot AI review requested due to automatic review settings May 30, 2026 02:43

Copilot AI 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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Fixes a rounding edge case in formatTokenShort where values just below 1,000,000 would render as the out-of-scheme "1000k" instead of advancing to the million branch.

Changes:

  • Guard the thousands branch so rounded values that reach 1000 fall through to the million branch.
  • Add regression tests covering the 999_499 / 999_500 / 999_999 boundary.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/shared/subagents-format.ts Adds fall-through logic when rounding hits 1000 in the thousands branch.
src/shared/subagents-format.test.ts Adds boundary tests for the rounding rollover.

@openclaw-barnacle openclaw-barnacle Bot added the proof: supplied External PR includes structured after-fix real behavior proof. label May 30, 2026
@clawsweeper

clawsweeper Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 31, 2026, 6:56 PM ET / 22:56 UTC.

Summary
The PR updates the shared subagent token formatter and compact announce-stats formatter to roll rounded thousand values over to the million unit, with regression coverage for both display paths.

PR surface: Source +11, Tests +36. Total +47 across 4 files.

Reproducibility: yes. from source inspection: current main formats rounded thousands before checking the million rollover, so boundary values like 999,500 can produce 1000k. I did not run the test locally because this review was constrained to read-only inspection.

Review metrics: none identified.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Next step before merge

  • [P2] No repair lane is needed because the PR already contains a focused fix, tests, and sufficient real behavior proof; the remaining action is ordinary maintainer review/merge.

Security
Cleared: The diff only changes local TypeScript formatting logic and colocated tests; it does not touch secrets, dependency resolution, CI, package metadata, or code-execution paths.

Review details

Best possible solution:

Land the focused rollover fix after ordinary maintainer checks, keeping both token display surfaces aligned with the existing compact unit scheme.

Do we have a high-confidence way to reproduce the issue?

Yes from source inspection: current main formats rounded thousands before checking the million rollover, so boundary values like 999,500 can produce 1000k. I did not run the test locally because this review was constrained to read-only inspection.

Is this the best way to solve the issue?

Yes. The PR changes the narrow formatter branches that own this display behavior and adds boundary regression coverage instead of adding a second formatting path.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 290b19275be6.

Label changes

Label changes:

  • add P2: This fixes a real but narrow subagent token-display correctness bug with limited user-facing blast radius.
  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.

Label justifications:

  • P2: This fixes a real but narrow subagent token-display correctness bug with limited user-facing blast radius.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied before/after live node scripts/run-vitest.mjs src/shared/subagents-format.test.ts output showing the boundary regression failing before the patch and passing after it.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied before/after live node scripts/run-vitest.mjs src/shared/subagents-format.test.ts output showing the boundary regression failing before the patch and passing after it.
Evidence reviewed

PR surface:

Source +11, Tests +36. Total +47 across 4 files.

View PR surface stats
Area Files Added Removed Net
Source 2 13 2 +11
Tests 2 36 0 +36
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 4 49 2 +47

What I checked:

  • Repository policy read: Root AGENTS.md was provided in full and applied: PR review used whole-surface reading, maintainer notes check, source/caller/test inspection, and history/owner review before verdict. (AGENTS.md:1, 290b19275be6)
  • Scoped policy search: No additional scoped AGENTS.md files were present under the touched src/agents or src/shared paths, and no matching .agents/maintainer-notes directory was found in this checkout.
  • Current main bug source: On current main, formatTokenShort still returns Math.round(n / 1_000) + "k" for values below one million, so 999,500 through 999,999 can format as 1000k. (src/shared/subagents-format.ts:14, 290b19275be6)
  • User-visible caller path: formatTokenUsageDisplay calls formatTokenShort for input, output, and total token counts, and subagent-list.ts renders that display in the subagent usage line. (src/shared/subagents-format.ts:20, 290b19275be6)
  • Sibling formatting precedent: The compact announce formatter on current main has the same one-decimal thousands rollover problem before this PR, while src/utils/usage-format.ts already guards rounded thousands that reach 1000 and rolls them into the million unit. (src/agents/subagent-announce-output.ts:514, 290b19275be6)
  • PR diff inspection: The head diff adds rollover guards to both token formatting surfaces and adds focused regression assertions for formatTokenShort and buildCompactAnnounceStatsLine. (src/shared/subagents-format.ts:14, a6a6c10f96cd)

Likely related people:

  • Peter Steinberger: Recent commits touched the shared subagent formatter tests and the broader subagent announcement/list surfaces, including the maintainer-side head update for this PR. (role: recent area contributor; confidence: high; commits: 290b19275be6, a6a6c10f96cd; files: src/shared/subagents-format.test.ts, src/agents/subagent-announce-output.ts, src/agents/subagent-announce-output.test.ts)
  • Davin Sijangga: Git history shows the shared subagents-format test coverage was introduced in prior merged work, making this a useful routing candidate for formatter expectations. (role: introduced adjacent tests; confidence: medium; commits: c2f19987cdb1; files: src/shared/subagents-format.test.ts)
  • clawsweeper[bot]: Recent merged automation commits touched src/agents/subagent-list.ts, the user-visible caller for formatTokenUsageDisplay, though bot ownership should be treated as routing context rather than human code ownership. (role: recent area contributor automation; confidence: low; commits: 2af51f22c537; files: src/agents/subagent-list.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 30, 2026
@steipete steipete self-assigned this May 31, 2026

@steipete steipete 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.

Thanks for the tight boundary fix. I found one remaining sibling surface that should be covered before merge.

[P2] Cover compact subagent announce stats too

The PR fixes formatTokenShort, so the subagent list no longer renders 999_999 as 1000k, but the compact subagent completion stats still use the private formatter in src/agents/subagent-announce-output.ts:506. That path is also subagent usage display text, and on this PR head (ec84ca5e850b301c56e7edc4735d128312a39df2) a direct runtime probe now gives:

formatTokenShort(999999) -> 1m
buildCompactAnnounceStatsLine(...) -> Stats: runtime n/a • tokens 1000.0k (in 1000.0k / out 0)

So merging this leaves the same out-of-scheme token unit in parent completion announcements. Please either reuse the shared subagent formatter there or add the same rollover guard plus a focused regression row for buildCompactAnnounceStatsLine.

coder999999999 and others added 2 commits May 31, 2026 23:52
formatTokenShort emitted an out-of-scheme "1000k" for token counts in
[999_500, 999_999]: the n < 1_000_000 branch used Math.round(n / 1_000),
which rounds up to 1000 near the boundary, instead of advancing to the
million branch. The sibling formatTokenCount already guards this exact case.

Surfaces in the subagent list usage display (formatTokenUsageDisplay ->
subagent-list.ts), so a subagent that used ~999.5k-999.999k tokens showed
"1000k" instead of "1m".

Fall through to the "m" branch when the rounded thousands reach 1000. Add
rollover-boundary regression rows.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@steipete
steipete force-pushed the fix/format-token-short-rollover branch from ec84ca5 to a6a6c10 Compare May 31, 2026 22:53
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S and removed size: XS labels May 31, 2026

@steipete steipete 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.

Maintainer fix pushed to head a6a6c10f96cda74c36c8a00582bb19d208c4d54d.

What changed:

  • kept the original formatTokenShort rollover fix
  • added the same unit rollover guard for compact subagent announcement stats
  • added regression coverage for buildCompactAnnounceStatsLine at the 999,999-token boundary

Verification:

  • focused runtime probe: formatTokenShort(999999) -> 1m; compact announce stats -> Stats: runtime n/a • tokens 1.0m (in 1.0m / out 0)
  • oxfmt --check on the touched formatter/test files
  • git diff --check origin/main..HEAD
  • autoreview local closeout: clean, no accepted/actionable findings; parallel runtime probe passed

Local Vitest note: node scripts/run-vitest.mjs ... entered a non-exiting Vitest path on this machine, so I stopped it and used the focused runtime probe plus exact-head CI for final gate.

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. P2 Normal backlog priority with limited blast radius. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels May 31, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 31, 2026

@steipete steipete 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.

Final maintainer fix proof for head c053f4737e06b7dffcacd4257982231c229213af.

What changed since the original PR:

  • compact subagent announcement stats now roll one-decimal thousands over to the million unit instead of rendering 1000.0k
  • buildCompactAnnounceStatsLine has a regression row for the 999,999-token boundary
  • test fixture now matches the typed session-entry shape

Verification:

  • focused runtime probe: formatTokenShort(999999) -> 1m; compact announce stats -> Stats: runtime n/a • tokens 1.0m (in 1.0m / out 0)
  • oxfmt --check on touched formatter/test files
  • git diff --check origin/main..HEAD
  • node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test-pr88209.tsbuildinfo
  • autoreview local closeout: clean, no accepted/actionable findings
  • exact-head CI: Real behavior proof, check-test-types, check-prod-types, check-guards, security-fast, preflight passed

Known unrelated current-main reds: check-lint, checks-node-agentic-gateway-methods, and checks-node-agentic-control-plane-agent-chat are also red on current origin/main and do not touch this formatter patch.

@steipete
steipete merged commit cb98479 into openclaw:main May 31, 2026
159 of 162 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants