feat(cost): show USD cost in REPL + TUI status bars - #193
Merged
Conversation
The status bar already showed token counts and (after the multi-provider rewrite) split them by worker vs advisor. This PR adds the dollar cost segment so users can see the spend at a glance — separately for worker and advisor accumulators, summed to one display number. ## Display Both surfaces append a `cost $X.XXX` segment after the token counts: ``` REPL: ... tokens: 5400 in / 320 out (advisor: 1326 in / 282 out) · cost $0.021 TUI: ... tokens 5720 · advisor 1326/282 · cost $0.021 ``` Hidden when zero (no API turns or no known pricing). ## Pricing Mirrors `typescript/src/utils/modelCost.ts` byte-for-byte: * haiku-4-5: $1 in / $5 out per Mtok (HAIKU_45 tier) * sonnet-4-6 + family: $3 in / $15 out (3_15 tier) * opus-4-5/4-6/4-7: $5 in / $25 out (5_25 tier) * opus-4-0/4-1 (legacy): $15 in / $75 out (15_75 tier) * Cache pricing: 1.25× input for creation, ~1/10 input for read Per-model exact match → strip openrouter `<vendor>/` prefix → family prefix → None. Critic-driven: returning None for unknowns (instead of silently mispricing as Sonnet-3/15 like the old default did) prevents 10× errors on non-Claude models like DeepSeek ($0.27 vs $3). ## Files | File | Change | |---|---| | `src/services/pricing.py` | Rewrote with TS-mirrored tiers, modern model table, family-prefix list, openrouter vendor-prefix handling. New `get_pricing(model) → dict\|None`, `is_known_pricing`, `compute_session_cost`, `format_cost_usd` helpers. `compute_cost` returns 0 for unknowns instead of falling to default. | | `src/services/cost_tracker.py` | Legacy facade now uses `get_pricing(model) or DEFAULT_PRICING` to preserve always-charge-something contract while letting the new path see None. | | `src/repl/core.py` | `_bottom_toolbar` appends `· cost $X.XXX` segment. | | `src/tui/widgets/status_line.py` | `_compose_text` appends `cost $X.XXX` to right_bits. | | `tests/test_pricing_status_bar.py` | New, 24 tests covering get_pricing/compute_cost/compute_session_cost/format_cost_usd + boundary cases (1¢ cutoff, $10 cutoff) + critic-flagged regression tests (unknown returns None, no bare opus-4 prefix). | ## Critic-driven fixes (one round, all addressed) * **C1** (critical): `DEFAULT_PRICING` was Sonnet 3/15 — silently mispricing DeepSeek/Gemini/GPT-5 by ~10×. Now unknowns return None and the status segment is suppressed. Honesty over false precision. * **C2** (critical): `claude-opus-4` bare prefix would have routed future variants (claude-opus-4-9-…) onto the legacy 15/75 tier. Dropped the bare entry so future Opus variants fall through to None. * **C3** (critical): dead `claude-haiku-3-5` prefix (canonical name is `claude-3-5-haiku-…`). Dropped. * **S5**: REPL had `cost: $X.XXX` (colon) while TUI had `cost $X.XXX` (space). Unified to space-separated on both surfaces. ## Tests * **658 passed** across the full advisor + adapter + TUI + smoke + cost_tracker + new pricing suites. * Live helper output sanity-check: - typical (haiku-4-5 worker + opus-4-7 advisor): $0.021 total - heavy session: $3.150 total Matches Anthropic list prices to the digit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
singlaamitesh
pushed a commit
to singlaamitesh/clawcodex
that referenced
this pull request
Jul 7, 2026
…s-bar-cost feat(cost): show USD cost in REPL + TUI status bars
singlaamitesh
pushed a commit
to singlaamitesh/clawcodex
that referenced
this pull request
Jul 7, 2026
…fficient /advisor) Two new entries at the top of the README News section: 1. Codebase stats: 890 files / 183,768 lines (up from 894 / 177,428 on 2026-05-16; net +6.3k lines / -4 files in five days). The file delta is the agent_loop.py consolidation; the line additions are the /advisor multi-provider rewrite + status-bar cost work. 2. /advisor mode as a token-efficient coding agent — narrates the PR agentforce314#181 → agentforce314#193 arc as one story: - Cheap worker (haiku-4-5) + expensive reviewer (opus-4-7) only at decision points ≈ 6× cheaper than opus-only on typical sessions - Explicit <provider>:<model> syntax (agentforce314#192) - Cross-provider routing verified (deepseek worker + opus advisor via litellm, agentforce314#182/agentforce314#184/agentforce314#192) - Reviewer-quality prompt (agentforce314#188) — Gaps/Risks/Do-next format - Live cost + token visibility in status bar (agentforce314#190/agentforce314#191/agentforce314#193) - /advisor slash command + dedicated TUI row (agentforce314#181) Docs-only — no code or test changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The status bar already shows token counts split by worker vs advisor (from PR #191). This PR adds the dollar cost segment — same split, summed into one display number.
Display
```
REPL: ... tokens: 5400 in / 320 out (advisor: 1326 in / 282 out) · cost $0.021
TUI: ... tokens 5720 · advisor 1326/282 · cost $0.021
```
Hidden when zero — either no API turns yet, or the worker/advisor model isn't in our known-pricing list (see critic C1 fix below).
Pricing tiers — mirror of TS
modelCost.tsLookup: exact match → strip openrouter
<vendor>/prefix → family prefix → None.Critic-driven fixes (one round, all addressed)
DEFAULT_PRICINGwas Sonnet 3/15 — would silently misprice DeepSeek/Gemini/GPT-5 by ~10×. Now unknowns return None and the cost segment is suppressed. Honesty over false precision.claude-opus-4prefix would have routed future variants (e.g.claude-opus-4-9) onto the legacy 15/75 tier. Dropped.claude-haiku-3-5prefix removed (canonical form isclaude-3-5-haiku-…).cost \$X.XXX(space-separated) on both REPL and TUI — was inconsistent.Files
src/services/pricing.pyget_pricingreturns dict or None. New helpersis_known_pricing,compute_session_cost,format_cost_usd.src/services/cost_tracker.pyget_pricing(model) or DEFAULT_PRICING— preserves always-charge-something contract while the new path sees None.src/repl/core.py_bottom_toolbarappends cost segment.src/tui/widgets/status_line.py_compose_textappends cost segment to right_bits.tests/test_pricing_status_bar.pyTests
Honest caveat
Cost reflects upstream Anthropic list prices. Routes through litellm/openrouter/bedrock may bill differently (your actual invoice could be a markup or a discount). The displayed number is a directional estimate, not your invoice.
🤖 Generated with Claude Code