From 3bcf8251040fac04c80fb4ab4dd6880cda773216 Mon Sep 17 00:00:00 2001 From: claude Date: Fri, 21 Aug 2026 23:46:24 +0000 Subject: [PATCH] feat(ai_review): fmt_tokens() humanizes token counts --- pilot/ai_review.py | 20 ++++++++++++++++++ tests/pilot/test_ai_review.py | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/pilot/ai_review.py b/pilot/ai_review.py index 9dfee33..31c7a1b 100644 --- a/pilot/ai_review.py +++ b/pilot/ai_review.py @@ -141,6 +141,26 @@ def truncate_diff(text: str, max_chars: int) -> tuple[str, bool, int]: return text[:max_chars] + f"\n\n[diff truncated at {max_chars} characters]\n", True, orig_len +def fmt_tokens(n) -> str: + """1234567 -> '1,234,567 (1.2M)'; 0 -> '0'; <1000 -> comma-only; None/negative -> '?'. + + Always returns the full comma-separated number; the short suffix is a + parenthetical for fast scanning. Caps at B; the cost model never exceeds M. + """ + if n is None: + return "?" + if not isinstance(n, (int, float)) or n < 0: + return "?" + n = int(n) + if n < 1000: + return f"{n:,}" + if n < 1_000_000: + return f"{n:,} ({n / 1000:.1f}K)" + if n < 1_000_000_000: + return f"{n:,} ({n / 1_000_000:.1f}M)" + return f"{n:,} ({n / 1_000_000_000:.1f}B)" + + def parse_text_blocks(content: list) -> str: """Join `type:"text"` blocks from an Anthropic /v1/messages response. diff --git a/tests/pilot/test_ai_review.py b/tests/pilot/test_ai_review.py index 591bb5e..c72176d 100644 --- a/tests/pilot/test_ai_review.py +++ b/tests/pilot/test_ai_review.py @@ -18,6 +18,7 @@ from ai_review import ( # noqa: E402 build_user_prompt, compute_attribution, findings_table, + fmt_tokens, format_review_body, inline_comment_body, parse_diff_anchors, @@ -1629,3 +1630,41 @@ def test_render_collapsible_usage_omits_lenses_when_single_primary(): out = _render_collapsible_usage(usage, "headroom/glm-5.2:cloud", None) assert "Lenses" not in out + +# --------------------------------------------------------------------------- +# fmt_tokens +# --------------------------------------------------------------------------- + + +def test_fmt_tokens_zero(): + assert fmt_tokens(0) == "0" + + +def test_fmt_tokens_small_no_short(): + assert fmt_tokens(42) == "42" + assert fmt_tokens(999) == "999" + + +def test_fmt_tokens_thousands(): + assert fmt_tokens(1000) == "1,000 (1.0K)" + assert fmt_tokens(1234) == "1,234 (1.2K)" + assert fmt_tokens(9999) == "9,999 (10.0K)" + + +def test_fmt_tokens_millions(): + assert fmt_tokens(1_000_000) == "1,000,000 (1.0M)" + assert fmt_tokens(2_071_025) == "2,071,025 (2.1M)" + assert fmt_tokens(1_234_567) == "1,234,567 (1.2M)" + + +def test_fmt_tokens_billions(): + assert fmt_tokens(1_234_567_890) == "1,234,567,890 (1.2B)" + + +def test_fmt_tokens_none(): + assert fmt_tokens(None) == "?" + + +def test_fmt_tokens_negative(): + assert fmt_tokens(-1) == "?" +