From d0d6286739a8390e2de6f197a33c793aadeed975 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:31:11 -0700 Subject: [PATCH] fix(usage-window): keep an allowance whose reset is unknown Greptile: "Unknown resets hide valid gauges". parse_gauges accepts a valid allowance with an unknown reset, but _bp_window dropped the row because the reset was not an int; with every reset unknown, build_nous_credits_snapshot fell back to the dollar view and lost the window plan. The row now keeps its percent with reset_at=None, which every renderer already shows as no reset phrase (the same shape other providers' windows use). --- agent/account_usage.py | 12 ++++++------ tests/agent/test_credits_usage_window.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/agent/account_usage.py b/agent/account_usage.py index 5512d180ee..6f648870d7 100644 --- a/agent/account_usage.py +++ b/agent/account_usage.py @@ -202,13 +202,13 @@ def _nous_snapshot(windows: list, details: list, tail: list, *, source: str, pla def _bp_window(label: str, used_bp: Any, resets_at_ms: Any) -> Optional[AccountUsageWindow]: - """One usage-window gauge row from basis points + an epoch-ms reset; None when either is not an int.""" - if isinstance(used_bp, bool) or not isinstance(used_bp, int) or isinstance(resets_at_ms, bool) or not isinstance(resets_at_ms, int): + """One usage-window gauge row from basis points + an epoch-ms reset (already bounded by + ``usage_gauges.parse_gauges``); None when the percent is not an int. An unknown reset keeps the row, + shown without a reset.""" + if isinstance(used_bp, bool) or not isinstance(used_bp, int): return None - try: - reset_at = datetime.fromtimestamp(resets_at_ms / 1000, tz=UTC) - except (ValueError, OverflowError, OSError): - return None # an implausible server stamp drops the row, never the whole /usage view + known = isinstance(resets_at_ms, int) and not isinstance(resets_at_ms, bool) + reset_at = datetime.fromtimestamp(resets_at_ms / 1000, tz=UTC) if known else None return AccountUsageWindow(label=label, used_percent=max(0.0, min(100.0, used_bp / BP_FULL * 100.0)), reset_at=reset_at) diff --git a/tests/agent/test_credits_usage_window.py b/tests/agent/test_credits_usage_window.py index 81f273b89d..125e75e602 100644 --- a/tests/agent/test_credits_usage_window.py +++ b/tests/agent/test_credits_usage_window.py @@ -766,6 +766,19 @@ class TestUsageCommand: "resets_at_ms": now + 3600_000}, *_gauges(100, 200, **kw)] assert next(w.label for w in account_usage.build_nous_credits_snapshot(info).windows) == "Next 5 hours" + def test_an_unknown_reset_keeps_the_allowance_row(self): + """A valid percent with no usable reset still shows as a window row (no reset phrase), never the + dollar view: the window plan's details stay on screen.""" + from agent import account_usage + gauges = [{"id": "day", "scope": "all", "label": "Today", "used_bp": 4_200}, + {"id": "week", "scope": "all", "label": "This week", "used_bp": 1_000, "resets_at_ms": "soon"}] + info = SimpleNamespace(logged_in=True, paid_service_access=True, paid_service_access_info=None, subscription=None, + usage_window=SimpleNamespace(gauges=gauges, paused_reason=None)) + snap = account_usage.build_nous_credits_snapshot(info) + assert snap.usage_window and [(w.label, round(w.used_percent), w.reset_at) for w in snap.windows] == [ + ("Today", 42, None), ("This week", 10, None)] + assert not any("resets" in line for line in account_usage.render_account_usage_lines(snap)) + def test_header_gauge_raises_stale_portal_percents(self, monkeypatch): from agent import account_usage monkeypatch.setattr("hermes_cli.nous_account.nous_portal_topup_url", lambda info: "https://portal/topup")