Conversation
- Add _estimate_premium_cost() helper that uses lookup_model_pricing() to compute ~multiplier×calls estimates for active sessions - render_cost_view: replace 'N/A' Premium Cost with ~estimated value in the 'Since last shutdown' row - render_live_sessions: add 'Est. Cost' column showing estimated premium cost for each active session - Add tests for estimated cost with known, free (0×), and premium (3×) models in both render_cost_view and render_live_sessions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Wires the existing pricing.py model-multiplier lookup into the CLI report rendering so active sessions can show an estimated premium-request cost instead of N/A.
Changes:
- Add
_estimate_premium_cost()helper that useslookup_model_pricing(model).multiplier × callsand formats as~N. - Show estimated cost for active sessions in
render_cost_view(“↳ Since last shutdown” row) and add an “Est. Cost” column torender_live_sessions. - Extend
test_report.pyto validate the new estimated-cost display behavior for premium and free models.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/copilot_usage/report.py |
Imports pricing lookup, adds estimate helper, and renders estimated cost in cost view + live sessions table. |
tests/copilot_usage/test_report.py |
Adds/updates tests asserting the estimated-cost output appears and matches expected multipliers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Resumed/active session with post-resume stats (even when 0) | ||
| messages = str(s.active_user_messages) | ||
| output_tok = s.active_output_tokens | ||
| est_cost = _estimate_premium_cost(s.model, s.active_model_calls) | ||
| else: |
There was a problem hiding this comment.
In render_live_sessions, the decision to use active_* fields vs totals (has_active_stats) doesn't account for active_model_calls. A resumed session could have post-resume model calls while active_user_messages/active_output_tokens remain 0, causing the code to take the “pure-active” path and compute est_cost from model_calls instead of active_model_calls. Consider including s.active_model_calls > 0 in the has_active_stats condition so the Est. Cost column reflects post-resume activity correctly.
There was a problem hiding this comment.
Good catch. Added s.active_model_calls > 0 to the has_active_stats condition so resumed sessions with post-resume model calls correctly use active_model_calls for the Est. Cost column.
Generated by Review Responder
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
astral.sh
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "astral.sh"See Network Configuration for more information.
| def _estimate_premium_cost(model: str | None, calls: int) -> str: | ||
| """Return a ``~``-prefixed estimated premium cost string. | ||
|
|
||
| Uses :func:`lookup_model_pricing` to look up the multiplier for *model* | ||
| and multiplies by *calls*. Returns ``"—"`` when *model* is ``None``. | ||
| """ | ||
| if model is None: | ||
| return "—" | ||
| pricing = lookup_model_pricing(model) | ||
| cost = round(calls * pricing.multiplier) | ||
| return f"~{cost}" |
There was a problem hiding this comment.
lookup_model_pricing() emits a UserWarning for unknown models. Because _estimate_premium_cost() is called in normal CLI rendering paths, an unrecognized model name could surface warnings to end users (stderr) and/or spam logs. Consider suppressing this warning in _estimate_premium_cost (or adding a non-warning lookup API) so unknown models degrade gracefully to the default 1× multiplier without noisy output.
There was a problem hiding this comment.
Fixed. _estimate_premium_cost now wraps the lookup_model_pricing call in warnings.catch_warnings() with warnings.simplefilter("ignore", UserWarning) so unknown models degrade gracefully to the 1× default without emitting user-visible warnings.
Generated by Review Responder
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
astral.sh
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "astral.sh"See Network Configuration for more information.
| if s.is_active: | ||
| est = _estimate_premium_cost(s.model, s.active_model_calls) | ||
| table.add_row( | ||
| " ↳ Since last shutdown", | ||
| s.model or "—", | ||
| "N/A", | ||
| "N/A", | ||
| est, |
There was a problem hiding this comment.
render_cost_view’s docstring still says the active-session “Since last shutdown” row uses N/A for premium cost, but the implementation now renders an estimated value. Please update the docstring to match the new behavior so CLI output expectations stay documented correctly.
There was a problem hiding this comment.
Updated the docstring to reflect the current behavior — it now says the "↳ Since last shutdown" row shows an estimated premium cost (~N) and N/A for requests.
Generated by Review Responder
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
astral.sh
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "astral.sh"See Network Configuration for more information.
| # The "Since last shutdown" row should NOT show "N/A" for Premium Cost | ||
| lines = output.splitlines() | ||
| shutdown_line = next( | ||
| (line for line in lines if "Since last shutdown" in line), "" | ||
| ) | ||
| assert "N/A" not in shutdown_line or shutdown_line.count("N/A") == 1 |
There was a problem hiding this comment.
This assertion can pass even if the “Since last shutdown” row is missing: shutdown_line defaults to "", and the condition will be true when the line isn’t found. Consider asserting the row was found (e.g., that shutdown_line is non-empty / using next(..., None) and asserting not None) and then asserting it contains exactly one N/A (for the Requests column only).
| # The "Since last shutdown" row should NOT show "N/A" for Premium Cost | |
| lines = output.splitlines() | |
| shutdown_line = next( | |
| (line for line in lines if "Since last shutdown" in line), "" | |
| ) | |
| assert "N/A" not in shutdown_line or shutdown_line.count("N/A") == 1 | |
| # The "Since last shutdown" row should NOT show "N/A" for Premium Cost. | |
| # It may show exactly one "N/A" (for the Requests column only). | |
| lines = output.splitlines() | |
| shutdown_line = next( | |
| (line for line in lines if "Since last shutdown" in line), | |
| None, | |
| ) | |
| assert shutdown_line is not None | |
| assert shutdown_line.count("N/A") == 1 |
There was a problem hiding this comment.
Applied the suggested fix. The test now asserts shutdown_line is not None (ensuring the row exists) and shutdown_line.count("N/A") == 1 (exactly one N/A for the Requests column only).
Generated by Review Responder
Warning
⚠️ Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
astral.sh
To allow these domains, add them to the network.allowed list in your workflow frontmatter:
network:
allowed:
- defaults
- "astral.sh"See Network Configuration for more information.
There was a problem hiding this comment.
Quality Gate: APPROVED ✅
Code Quality: Good
_estimate_premium_cost()is a clean private helper with proper docstring andNonehandling- Uses the existing, well-tested
lookup_model_pricing()which never raises exceptions (graceful fallback for unknown models) - Follows existing patterns: private naming convention, not added to
__all__, consistent formatting - 6 new meaningful tests covering known models, free models (0× multiplier), and premium models (3× multiplier) across both
render_cost_viewandrender_live_sessions - Existing test assertions updated correctly (
N/A→~N)
Impact: MEDIUM
- Presentation-layer changes only: adds "Est. Cost" column to live sessions table, replaces "N/A" with estimated cost in cost view's "Since last shutdown" row
- No changes to data models, API contracts, or core business logic
- Core computation is trivial:
round(calls × multiplier) - Well-covered by new tests
Auto-approving for merge.
Closes #181
Changes
pricing.pywas fully tested but never imported by any production module. This PR wires it into the CLI's cost display:render_cost_view↳ Since last shutdownrow now shows an estimated premium cost (~N) instead ofN/A, computed asround(active_model_calls × lookup_model_pricing(model).multiplier).~prefix signals that the value is an approximation (no shutdown data yet).render_live_sessions~Nestimate for each active session.Helper
_estimate_premium_cost(model, calls)function encapsulates the lookup and formatting. Returns"—"when model isNone.Tests
test_active_session_estimated_cost_known_model— active session with a known model shows numeric estimated cost, notN/A.test_estimated_cost_zero_for_free_model—gpt-5-mini(0× multiplier) yields~0.test_estimated_cost_premium_model_multiplier— 3 calls ofclaude-opus-4.6(3× multiplier) yields~9.test_est_cost_column_present/test_est_cost_premium_model/test_est_cost_free_model— live sessions table includes and populates the Est. Cost column.test_pricing.pytests pass unchanged.CI
All 426 tests pass · 98% coverage · ruff/pyright/bandit clean.
Warning
The following domain was blocked by the firewall during workflow execution:
astral.shTo allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.