Skip to content

Fix capped large token totals in TUI stats#130

Merged
mike1858 merged 1 commit intomainfrom
fix/huge-token-counts
Mar 13, 2026
Merged

Fix capped large token totals in TUI stats#130
mike1858 merged 1 commit intomainfrom
fix/huge-token-counts

Conversation

@mike1858
Copy link
Member

@mike1858 mike1858 commented Mar 13, 2026

Summary

  • widen TUI aggregate token and cost fields from to
  • remove lossy casts in daily/session aggregation and MCP export paths
  • add a regression test covering totals beyond

Closes #129.

Verification

  • cargo build --quiet
  • cargo test --quiet
  • cargo clippy --quiet -- -D warnings
  • cargo doc --quiet
  • cargo fmt --all --quiet

Summary by CodeRabbit

  • Bug Fixes

    • Expanded token count and cost tracking capacity to handle larger values without overflow, preventing potential data loss in statistics accumulation.
  • Tests

    • Added test coverage to validate handling of statistics exceeding previous value limits.

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

📝 Walkthrough

Walkthrough

This PR expands numeric fields in the TuiStats struct from u32 to u64 to prevent value capping at u32::MAX (4,294,967,295). Supporting type conversions and arithmetic operations across contribution caching, MCP server, TUI rendering, and utility modules are updated to eliminate now-redundant casts and work with the expanded types.

Changes

Cohort / File(s) Summary
Core Type Definition
src/types.rs
TuiStats struct fields (input_tokens, output_tokens, reasoning_tokens, cached_tokens, cost_cents) expanded from u32 to u64. From<&Stats> implementation and set_cost/add_cost methods updated to use u64 arithmetic.
Conversion & Initialization
src/contribution_cache/single_message.rs, src/mcp/types.rs, src/mcp/server.rs, src/utils.rs
Numeric conversions updated: explicit u64 casts added where constructing TuiStats in single_message.rs; redundant casts removed in DailySummary::new and compare_tools; direct field aggregation without u32 narrowing in utils.rs.
Display & UI Rendering
src/tui.rs, src/tui/logic.rs
Counter and total variables in draw_*_stats_table functions changed from u32 to u64. accumulate_tui_stats arithmetic simplified by removing intermediate as u32 casts, relying on source field types.
Testing
src/tui/tests.rs
New test test_tui_stats_accumulation_exceeds_u32_max validates that accumulate_tui_stats correctly handles token sums exceeding u32::MAX.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop along, dear tokens bright,
No more capped at four-billion height!
From thirty-two to sixty-four we leap,
Your stats now soar, your values keep!
—A satisfied rabbit

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: widening TUI stat fields to handle larger token totals that were previously capped at u32 maximum.
Linked Issues check ✅ Passed The PR fully addresses issue #129 by converting TuiStats token/cost fields from u32 to u64, removing casts that caused capping at 4294967295, and adding regression test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the token capping issue: field type expansions, cast removals in aggregation paths, and test coverage—no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/huge-token-counts
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/tui/tests.rs (1)

328-355: Please cover the widened cost_cents path in this regression too.

The test proves the token counters can cross u32::MAX, but this PR widens cost totals for the same reason. One extra assertion above the old cents ceiling would keep add_cost from regressing independently.

Possible extension
 #[test]
 fn test_tui_stats_accumulation_exceeds_u32_max() {
-    let mut dst = TuiStats::default();
+    let mut dst = TuiStats {
+        cost_cents: u32::MAX as u64,
+        ..TuiStats::default()
+    };
     let src = Stats {
         input_tokens: u32::MAX as u64,
         output_tokens: 1,
         reasoning_tokens: 2,
         cached_tokens: 3,
+        cost: 0.01,
         ..Stats::default()
     };
 
     accumulate_tui_stats(&mut dst, &src);
     accumulate_tui_stats(
@@
     assert_eq!(dst.input_tokens, u32::MAX as u64 + 1);
     assert_eq!(dst.output_tokens, u32::MAX as u64 + 1);
     assert_eq!(dst.reasoning_tokens, u32::MAX as u64 + 2);
     assert_eq!(dst.cached_tokens, u32::MAX as u64 + 3);
+    assert_eq!(dst.cost_cents, u32::MAX as u64 + 1);
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tui/tests.rs` around lines 328 - 355, Extend the
test_tui_stats_accumulation_exceeds_u32_max test to also exercise the widened
cost totals by populating Stats.cost_cents with values at and past u32::MAX and
then asserting dst.cost_cents accumulates beyond the old u32 ceiling;
specifically, call accumulate_tui_stats (or the underlying add_cost path) with a
Stats instance whose cost_cents is u32::MAX as u64 and another with 1 (or vice
versa) and add assertions that dst.cost_cents == u32::MAX as u64 + 1 to ensure
add_cost and TuiStats.cost_cents no longer overflow at the previous u32 limit.
src/tui/logic.rs (1)

10-16: Consider moving this accumulation helper out of the TUI module.

src/utils.rs:221-242 now carries the same 6-field update logic. Extracting one shared helper in a neutral module would make it harder for the daily and session paths to drift again the next time a counter changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/tui/logic.rs` around lines 10 - 16, The TUI-specific function
accumulate_tui_stats duplicates logic present in src/utils.rs; extract the
six-field accumulation into a shared helper (e.g., pub fn accumulate_stats(dst:
&mut TuiStats, src: &Stats) or a more generic signature using the common
Stats-like fields) placed in a neutral module (utils or stats) and make it
public so both the TUI code and the code at utils.rs:221-242 call it; update the
accumulate_tui_stats call sites to use the new shared helper (or replace
accumulate_tui_stats with a thin wrapper that delegates to the shared function)
and keep the dst.add_cost(src.cost) logic and saturating_add usages intact,
ensuring the function visibility and imports are adjusted for the new module.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/tui/logic.rs`:
- Around line 10-16: The TUI-specific function accumulate_tui_stats duplicates
logic present in src/utils.rs; extract the six-field accumulation into a shared
helper (e.g., pub fn accumulate_stats(dst: &mut TuiStats, src: &Stats) or a more
generic signature using the common Stats-like fields) placed in a neutral module
(utils or stats) and make it public so both the TUI code and the code at
utils.rs:221-242 call it; update the accumulate_tui_stats call sites to use the
new shared helper (or replace accumulate_tui_stats with a thin wrapper that
delegates to the shared function) and keep the dst.add_cost(src.cost) logic and
saturating_add usages intact, ensuring the function visibility and imports are
adjusted for the new module.

In `@src/tui/tests.rs`:
- Around line 328-355: Extend the test_tui_stats_accumulation_exceeds_u32_max
test to also exercise the widened cost totals by populating Stats.cost_cents
with values at and past u32::MAX and then asserting dst.cost_cents accumulates
beyond the old u32 ceiling; specifically, call accumulate_tui_stats (or the
underlying add_cost path) with a Stats instance whose cost_cents is u32::MAX as
u64 and another with 1 (or vice versa) and add assertions that dst.cost_cents ==
u32::MAX as u64 + 1 to ensure add_cost and TuiStats.cost_cents no longer
overflow at the previous u32 limit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee8764d7-bd27-4f37-9d90-84b3d42e69ed

📥 Commits

Reviewing files that changed from the base of the PR and between af02f13 and 7cc988c.

📒 Files selected for processing (8)
  • src/contribution_cache/single_message.rs
  • src/mcp/server.rs
  • src/mcp/types.rs
  • src/tui.rs
  • src/tui/logic.rs
  • src/tui/tests.rs
  • src/types.rs
  • src/utils.rs

@mike1858 mike1858 merged commit 25dbdce into main Mar 13, 2026
6 checks passed
@mike1858 mike1858 deleted the fix/huge-token-counts branch March 13, 2026 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4294967295

1 participant