From 8bcee82fc0ec7c1ff63cd75a87ef42ec50aa7d03 Mon Sep 17 00:00:00 2001 From: kragent66-glitch Date: Thu, 15 Oct 2026 02:05:03 +0000 Subject: [PATCH 1/2] fix(integrations): read a missing token estimate as unavailable, not zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Claude Code statusline and the Codex Stop hook decided "no data" from token_reduction() being None, which only checks that the totals are well-formed. A valid response with recall.estimator: null (estimation disabled) and zero totals is well-formed, so token_reduction returned 0 and the formatter printed "saved 0" — indistinguishable from a measured zero. Keep token_reduction() as the validity check in _load_stats so estimate-less responses stay online, and add a display helper that returns the reduction only when totals.comparable_preparations > 0. With nothing comparable it returns None, which savings_phrase already renders as "no data ". --- .../powercontext/scripts/statusline.py | 32 +++++++++++-- .../powercontext/hooks/token_savings.py | 32 +++++++++++-- tests/claude_code_plugin/test_statusline.py | 46 +++++++++++++++++++ tests/codex_plugin/test_token_savings.py | 41 +++++++++++++++++ 4 files changed, 141 insertions(+), 10 deletions(-) diff --git a/integrations/claude-code/plugins/powercontext/scripts/statusline.py b/integrations/claude-code/plugins/powercontext/scripts/statusline.py index bb2d092131..136e43b2b9 100644 --- a/integrations/claude-code/plugins/powercontext/scripts/statusline.py +++ b/integrations/claude-code/plugins/powercontext/scripts/statusline.py @@ -77,8 +77,8 @@ def _scaled(value: float, suffix: str) -> str: return f"{rounded:.{digits}f}".removesuffix(".0") + suffix -def token_reduction(value: object) -> int | None: - """Return a validated signed reduction from one scoped-statistics response.""" +def _validated_totals(value: object) -> dict[str, Any] | None: + """Return the validated recall totals of one scoped-statistics response.""" if not isinstance(value, dict): return None @@ -102,7 +102,29 @@ def token_reduction(value: object) -> int | None: reduction = totals.get("token_reduction") if not isinstance(reduction, int) or isinstance(reduction, bool): return None - return reduction + return totals + + +def token_reduction(value: object) -> int | None: + """Return a validated signed reduction from one scoped-statistics response.""" + + totals = _validated_totals(value) + return None if totals is None else totals["token_reduction"] + + +def measured_reduction(value: object) -> int | None: + """Return the reduction to display, or ``None`` when the window measured nothing. + + A window with no comparable preparations holds no estimate — estimation is + disabled, or the period had nothing comparable to measure — so it must read as + unavailable rather than as a measured zero. A window with comparable + preparations still reports a genuine zero reduction. + """ + + totals = _validated_totals(value) + if totals is None or totals["comparable_preparations"] == 0: + return None + return totals["token_reduction"] def savings_phrase(reduction: int | None, suffix: str) -> str: @@ -115,8 +137,8 @@ def savings_phrase(reduction: int | None, suffix: str) -> str: def format_statusline(today: object, month: object, *, color: bool = True) -> str: """Render the same two-window compression proxy used by OpenCode.""" - today_reduction = token_reduction(today) - month_reduction = token_reduction(month) + today_reduction = measured_reduction(today) + month_reduction = measured_reduction(month) if not color: return f"● PC online · {savings_phrase(today_reduction, 'today')} · {savings_phrase(month_reduction, 'in 30d')}" return "".join(( diff --git a/integrations/codex/plugins/powercontext/hooks/token_savings.py b/integrations/codex/plugins/powercontext/hooks/token_savings.py index 8fab9c39fc..07e65f6b73 100644 --- a/integrations/codex/plugins/powercontext/hooks/token_savings.py +++ b/integrations/codex/plugins/powercontext/hooks/token_savings.py @@ -87,8 +87,8 @@ def _scaled(value: float, suffix: str) -> str: return f"{rounded:.{digits}f}".removesuffix(".0") + suffix -def token_reduction(value: object) -> int | None: - """Return a validated signed reduction from one scoped-statistics response.""" +def _validated_totals(value: object) -> dict[str, Any] | None: + """Return the validated recall totals of one scoped-statistics response.""" if not isinstance(value, dict): return None @@ -111,7 +111,29 @@ def token_reduction(value: object) -> int | None: reduction = totals.get("token_reduction") if not isinstance(reduction, int) or isinstance(reduction, bool): return None - return reduction + return totals + + +def token_reduction(value: object) -> int | None: + """Return a validated signed reduction from one scoped-statistics response.""" + + totals = _validated_totals(value) + return None if totals is None else totals["token_reduction"] + + +def measured_reduction(value: object) -> int | None: + """Return the reduction to display, or ``None`` when the window measured nothing. + + A window with no comparable preparations holds no estimate — estimation is + disabled, or the period had nothing comparable to measure — so it must read as + unavailable rather than as a measured zero. A window with comparable + preparations still reports a genuine zero reduction. + """ + + totals = _validated_totals(value) + if totals is None or totals["comparable_preparations"] == 0: + return None + return totals["token_reduction"] def savings_phrase(reduction: int | None, suffix: str) -> str: @@ -125,8 +147,8 @@ def format_message(today: object, month: object) -> str: """Render the same two-window compression proxy used by OpenCode.""" return ( - f"PowerContext · {savings_phrase(token_reduction(today), 'today')}" - f" · {savings_phrase(token_reduction(month), 'in 30d')}" + f"PowerContext · {savings_phrase(measured_reduction(today), 'today')}" + f" · {savings_phrase(measured_reduction(month), 'in 30d')}" ) diff --git a/tests/claude_code_plugin/test_statusline.py b/tests/claude_code_plugin/test_statusline.py index 414c86c241..4272756557 100644 --- a/tests/claude_code_plugin/test_statusline.py +++ b/tests/claude_code_plugin/test_statusline.py @@ -570,3 +570,49 @@ def test_render_does_not_pair_another_servers_authorization_with_the_host_server assert "PC online" in rendered assert received assert {authorization for _, authorization in received} == {None} + + +def _without_estimate() -> dict[str, object]: + """A valid window where estimation is disabled: no comparable preparations.""" + + return { + "recall": { + "estimator": None, + "totals": { + "preparations": 0, + "ready_preparations": 0, + "comparable_preparations": 0, + "baseline_tokens": 0, + "recalled_tokens": 0, + "token_reduction": 0, + }, + } + } + + +def test_a_window_without_estimates_reads_as_unavailable_not_zero(statusline_module: ModuleType) -> None: + assert statusline_module.format_statusline(_without_estimate(), _without_estimate(), color=False) == ( + "● PC online · no data today · no data in 30d" + ) + # A window that measured comparable preparations still reports a genuine zero. + assert statusline_module.format_statusline(_stats(0), _stats(0), color=False) == ( + "● PC online · saved 0 today · saved 0 in 30d" + ) + + +def test_render_keeps_a_response_without_estimates_online( + statusline_module: ModuleType, + monkeypatch, + tmp_path: Path, +) -> None: + monkeypatch.setattr( + statusline_module.sys, + "stdin", + StringIO(json.dumps({"workspace": {"current_dir": str(tmp_path)}})), + ) + with _serve(_stats_handler(_without_estimate())) as server_url: + monkeypatch.setenv("POWERCONTEXT_CLAUDE_SERVER_URL", server_url) + rendered = statusline_module.render("http://127.0.0.1:9000") + + assert "PC online" in rendered + assert "no data today" in rendered diff --git a/tests/codex_plugin/test_token_savings.py b/tests/codex_plugin/test_token_savings.py index 4c6584ab04..00a175f675 100644 --- a/tests/codex_plugin/test_token_savings.py +++ b/tests/codex_plugin/test_token_savings.py @@ -740,3 +740,44 @@ def log_message(self, format: str, *args: Any) -> None: # noqa: A002 assert completed.returncode == 0 events = _diagnostics(io.StringIO(completed.stdout)) assert [event["outcome"] for event in events] == ["server_unavailable"] + + +def _without_estimate() -> dict[str, object]: + """A valid window where estimation is disabled: no comparable preparations.""" + + return { + "recall": { + "estimator": None, + "totals": { + "preparations": 0, + "ready_preparations": 0, + "comparable_preparations": 0, + "baseline_tokens": 0, + "recalled_tokens": 0, + "token_reduction": 0, + }, + } + } + + +def test_a_window_without_estimates_reads_as_unavailable_not_zero(token_savings_module: ModuleType) -> None: + assert token_savings_module.format_message(_without_estimate(), _without_estimate()) == ( + "PowerContext · no data today · no data in 30d" + ) + # A window that measured comparable preparations still reports a genuine zero. + assert token_savings_module.format_message(_stats(0), _stats(0)) == ( + "PowerContext · saved 0 today · saved 0 in 30d" + ) + + +def test_stop_keeps_a_response_without_estimates_online( + token_savings_module: ModuleType, + monkeypatch: pytest.MonkeyPatch, +) -> None: + with _serve(_stats_handler(_without_estimate())) as server_url: + output = _run_main(token_savings_module, monkeypatch, _settings(token_savings_module, server_url)) + + assert json.loads(output.getvalue()) == { + "continue": True, + "systemMessage": "PowerContext · no data today · no data in 30d", + } From 5c4220805349c178f526fa230cc6769846cb4779 Mon Sep 17 00:00:00 2001 From: kragent66-glitch Date: Sat, 17 Oct 2026 06:45:55 +0000 Subject: [PATCH 2/2] fix(integrations): return a typed recall-totals mapping from the helper `_validated_totals` narrowed `recall["totals"]` to `dict[Unknown, Unknown]` via `isinstance(..., dict)` and returned it under a `dict[str, Any] | None` annotation, so `ty check` reported `invalid-return-type` for both the Claude Code statusline and the Codex Stop hook. That hook is what the `quality` (Main) and `Recall effort (OceanBase)` (E2E harness) workflows run, so both gates failed on the previous head. Cast the narrowed mapping to the declared type; behaviour is unchanged. Add a helper-level regression test in each integration pinning that the reduction accessors yield an int or None, never the totals mapping: a missing estimate reads as unavailable (`None`) while a genuine measured zero still reads as `0`. --- .../plugins/powercontext/scripts/statusline.py | 4 ++-- .../plugins/powercontext/hooks/token_savings.py | 4 ++-- tests/claude_code_plugin/test_statusline.py | 14 ++++++++++++++ tests/codex_plugin/test_token_savings.py | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/integrations/claude-code/plugins/powercontext/scripts/statusline.py b/integrations/claude-code/plugins/powercontext/scripts/statusline.py index 136e43b2b9..fdf653c363 100644 --- a/integrations/claude-code/plugins/powercontext/scripts/statusline.py +++ b/integrations/claude-code/plugins/powercontext/scripts/statusline.py @@ -24,7 +24,7 @@ from decimal import ROUND_HALF_UP, Decimal from pathlib import Path from time import monotonic -from typing import Any, Protocol +from typing import Any, Protocol, cast from urllib.error import HTTPError from urllib.request import Request @@ -102,7 +102,7 @@ def _validated_totals(value: object) -> dict[str, Any] | None: reduction = totals.get("token_reduction") if not isinstance(reduction, int) or isinstance(reduction, bool): return None - return totals + return cast("dict[str, Any]", totals) def token_reduction(value: object) -> int | None: diff --git a/integrations/codex/plugins/powercontext/hooks/token_savings.py b/integrations/codex/plugins/powercontext/hooks/token_savings.py index 07e65f6b73..acde8002b3 100644 --- a/integrations/codex/plugins/powercontext/hooks/token_savings.py +++ b/integrations/codex/plugins/powercontext/hooks/token_savings.py @@ -22,7 +22,7 @@ from decimal import ROUND_HALF_UP, Decimal from pathlib import Path from time import monotonic -from typing import Any +from typing import Any, cast from urllib.error import HTTPError from urllib.request import Request @@ -111,7 +111,7 @@ def _validated_totals(value: object) -> dict[str, Any] | None: reduction = totals.get("token_reduction") if not isinstance(reduction, int) or isinstance(reduction, bool): return None - return totals + return cast("dict[str, Any]", totals) def token_reduction(value: object) -> int | None: diff --git a/tests/claude_code_plugin/test_statusline.py b/tests/claude_code_plugin/test_statusline.py index 4272756557..db48ec0f22 100644 --- a/tests/claude_code_plugin/test_statusline.py +++ b/tests/claude_code_plugin/test_statusline.py @@ -616,3 +616,17 @@ def test_render_keeps_a_response_without_estimates_online( assert "PC online" in rendered assert "no data today" in rendered + + +def test_the_reduction_helpers_return_an_int_or_none_not_the_totals(statusline_module: ModuleType) -> None: + """A well-formed window yields numbers, never the validated totals mapping. + + The display helper resolves a missing estimate to ``None`` (unavailable), while + the validity helper still reads the well-formed zero so the integration stays + online. + """ + + assert statusline_module.token_reduction(_without_estimate()) == 0 + assert statusline_module.measured_reduction(_without_estimate()) is None + assert statusline_module.token_reduction(_stats(0)) == 0 + assert statusline_module.measured_reduction(_stats(0)) == 0 diff --git a/tests/codex_plugin/test_token_savings.py b/tests/codex_plugin/test_token_savings.py index 00a175f675..7411ffead9 100644 --- a/tests/codex_plugin/test_token_savings.py +++ b/tests/codex_plugin/test_token_savings.py @@ -781,3 +781,17 @@ def test_stop_keeps_a_response_without_estimates_online( "continue": True, "systemMessage": "PowerContext · no data today · no data in 30d", } + + +def test_the_reduction_helpers_return_an_int_or_none_not_the_totals(token_savings_module: ModuleType) -> None: + """A well-formed window yields numbers, never the validated totals mapping. + + The display helper resolves a missing estimate to ``None`` (unavailable), while + the validity helper still reads the well-formed zero so the integration stays + online. + """ + + assert token_savings_module.token_reduction(_without_estimate()) == 0 + assert token_savings_module.measured_reduction(_without_estimate()) is None + assert token_savings_module.token_reduction(_stats(0)) == 0 + assert token_savings_module.measured_reduction(_stats(0)) == 0