From 4742de1b06c799e9849fe6057832594f7f5399f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Mar 2026 15:48:16 +0000 Subject: [PATCH 1/2] fix: update stale docstring and suppress UserWarning in cost rendering (#198) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update render_cost_view docstring to reflect that it renders an estimated premium cost (not N/A) for active sessions. - Suppress UserWarning inside _estimate_premium_cost so unknown models degrade gracefully to the default 1× multiplier without noisy output. - Add tests for _estimate_premium_cost (including no-warning assertion) and for render_cost_view with unknown model. Closes #198 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/copilot_usage/report.py | 11 +++++-- tests/copilot_usage/test_report.py | 51 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/copilot_usage/report.py b/src/copilot_usage/report.py index 8c0a34c..82d5d5f 100644 --- a/src/copilot_usage/report.py +++ b/src/copilot_usage/report.py @@ -133,10 +133,15 @@ def _estimate_premium_cost(model: str | None, calls: int) -> str: Uses :func:`lookup_model_pricing` to look up the multiplier for *model* and multiplies by *calls*. Returns ``"—"`` when *model* is ``None``. + + Warnings from :func:`lookup_model_pricing` (e.g. unknown models) are + suppressed so that normal CLI rendering never emits noise on stderr. """ if model is None: return "—" - pricing = lookup_model_pricing(model) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", UserWarning) + pricing = lookup_model_pricing(model) cost = round(calls * pricing.multiplier) return f"~{cost}" @@ -914,8 +919,8 @@ def render_cost_view( """Render per-session, per-model cost breakdown. Filters sessions by date range when *since* and/or *until* are given. - For active sessions, appends a "↳ Since last shutdown" row with N/A - for premium and the active model calls / output tokens. + For active sessions, appends a "↳ Since last shutdown" row with an + estimated premium cost and the active model calls / output tokens. """ console = target_console or Console() filtered = _filter_sessions(sessions, since, until) diff --git a/tests/copilot_usage/test_report.py b/tests/copilot_usage/test_report.py index 94376cd..501203b 100644 --- a/tests/copilot_usage/test_report.py +++ b/tests/copilot_usage/test_report.py @@ -25,6 +25,7 @@ from copilot_usage.report import ( _aggregate_model_metrics, _build_event_details, + _estimate_premium_cost, _event_type_label, _filter_sessions, _format_detail_duration, @@ -1963,6 +1964,56 @@ def test_pure_active_never_shutdown_cost_falls_back(self) -> None: f"Output Tokens in active row should be 0, got '{cols[6]}'" ) + def test_active_session_unknown_model_no_warning(self) -> None: + """Active session with an unknown model must not emit UserWarning.""" + session = SessionSummary( + session_id="unknown-model-1234", + name="Unknown Model", + model="experimental-model-42", + start_time=datetime(2025, 1, 15, 10, 0, tzinfo=UTC), + is_active=True, + model_calls=4, + user_messages=2, + active_model_calls=2, + active_output_tokens=300, + ) + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + output = _capture_cost_view([session]) + assert "Since last shutdown" in output + assert len(caught) == 0, ( + f"Expected no warnings, got {[str(w.message) for w in caught]}" + ) + + +# --------------------------------------------------------------------------- +# _estimate_premium_cost tests +# --------------------------------------------------------------------------- + + +class TestEstimatePremiumCost: + """Tests for _estimate_premium_cost helper.""" + + def test_none_model_returns_dash(self) -> None: + assert _estimate_premium_cost(None, 5) == "—" + + def test_known_model_returns_estimate(self) -> None: + # claude-opus-4.6 has a 3× multiplier → 3 calls × 3.0 = ~9 + assert _estimate_premium_cost("claude-opus-4.6", 3) == "~9" + + def test_unknown_model_no_warning(self) -> None: + """Unknown model degrades to 1× multiplier without emitting warnings.""" + with warnings.catch_warnings(record=True) as caught: + warnings.simplefilter("always") + result = _estimate_premium_cost("totally-unknown-model-xyz", 7) + assert result == "~7" # 7 calls × 1.0 = ~7 + assert len(caught) == 0, ( + f"Expected no warnings, got {[str(w.message) for w in caught]}" + ) + + def test_zero_calls_returns_zero(self) -> None: + assert _estimate_premium_cost("claude-sonnet-4", 0) == "~0" + class TestRenderFullSummaryHelperReuse: """Verify _render_historical_section delegates to shared table helpers.""" From 18fe5953f569201b544799377804b85fae828ae1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 21 Mar 2026 15:54:50 +0000 Subject: [PATCH 2/2] fix: address review comments Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/copilot_usage/test_report.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/copilot_usage/test_report.py b/tests/copilot_usage/test_report.py index 501203b..d1732fe 100644 --- a/tests/copilot_usage/test_report.py +++ b/tests/copilot_usage/test_report.py @@ -1978,11 +1978,11 @@ def test_active_session_unknown_model_no_warning(self) -> None: active_output_tokens=300, ) with warnings.catch_warnings(record=True) as caught: - warnings.simplefilter("always") + warnings.simplefilter("always", UserWarning) output = _capture_cost_view([session]) assert "Since last shutdown" in output assert len(caught) == 0, ( - f"Expected no warnings, got {[str(w.message) for w in caught]}" + f"Expected no UserWarning, got {[str(w.message) for w in caught]}" ) @@ -2004,11 +2004,11 @@ def test_known_model_returns_estimate(self) -> None: def test_unknown_model_no_warning(self) -> None: """Unknown model degrades to 1× multiplier without emitting warnings.""" with warnings.catch_warnings(record=True) as caught: - warnings.simplefilter("always") + warnings.simplefilter("always", UserWarning) result = _estimate_premium_cost("totally-unknown-model-xyz", 7) assert result == "~7" # 7 calls × 1.0 = ~7 assert len(caught) == 0, ( - f"Expected no warnings, got {[str(w.message) for w in caught]}" + f"Expected no UserWarning, got {[str(w.message) for w in caught]}" ) def test_zero_calls_returns_zero(self) -> None: