Skip to content

Serve cached usage data when a provider fetch fails#3

Open
Plenvorik wants to merge 1 commit into
KodyMike:mainfrom
Plenvorik:feature/cache-staleness
Open

Serve cached usage data when a provider fetch fails#3
Plenvorik wants to merge 1 commit into
KodyMike:mainfrom
Plenvorik:feature/cache-staleness

Conversation

@Plenvorik
Copy link
Copy Markdown

Anthropic's undocumented /api/oauth/usage endpoint rate-limits
aggressively, so users with this widget often see a red "Rate limited"
message with no numbers, even though the previously-reported numbers
are still perfectly useful context. See #1 and
anthropics/claude-code#31637.

This patch keeps a per-provider disk cache in
~/.cache/com.aiusagemonitor/{provider}.json. On a successful fetch
the cache is rewritten atomically and the result is stamped with
fetched_at and stale: false. On a fetch failure the cached data is
returned instead, marked stale: true, and the existing error message
is extended to "<reason> · showing cached data (Xm old)". If no
cache exists yet the original error path is preserved unchanged — no
regression for first-time users.

UI changes reuse existing labels and bars, with minimal footprint:

  • CompactRepresentation: centre percentage text switches to
    Kirigami.Theme.disabledTextColor while stale. This is
    provider-agnostic — it applies to whichever provider is currently
    shown in the panel.
  • FullRepresentation: the Claude and Gemini error labels shift from
    negativeTextColor to neutralTextColor when stale, and their bar
    Loader.active conditions are extended so cached bars remain
    visible alongside the explanatory message. Codex is not touched in
    the full view because its code path never produces an error field —
    it parses local JSONL files and silently skips malformed lines. If
    a failure mode is ever added, the same pattern would apply.

No new labels, no tooltips, no config schema changes.

GNOME extension not touched — changes are KDE only. The JS/CSS
structure makes a blind port plausible, but I didn't want to ship
untested code there. Happy to mirror the changes if a GNOME user can
verify.

Tested locally with two panel instances polling Claude at 1 min each.
Fresh fetches stamp and cache as expected; simulated 429 falls back
to cache with stale=true and the extended error message; bars
remain visible under stale state; no cache yields the original error
path unchanged.

Anthropic's /api/oauth/usage endpoint rate-limits aggressively, so
users often saw a red "Rate limited" message with no numbers, even
though the previous values were still useful context.

The Python fetcher now keeps a per-provider disk cache in
~/.cache/com.aiusagemonitor/{provider}.json. On a successful fetch the
cache is rewritten atomically and the result is stamped with
fetched_at and stale=false. On a fetch failure the cached data is
returned instead, marked stale=true, and the error message is extended
to "<reason> · showing cached data (Xm old)" so the user understands
the bars below are from the cache. If no cache exists yet the original
error path is preserved unchanged.

UI changes are minimal and reuse the existing labels and bars:

- CompactRepresentation: centre percentage text switches to
  Kirigami.Theme.disabledTextColor while the active provider's data
  is stale (the ring itself stays on the utilization scale).
- FullRepresentation: Claude and Gemini error labels shift from
  negativeTextColor (red) to neutralTextColor (KDE's softer warning
  colour) when stale. The bar Loader conditions are extended from
  `!cd.error` to `!cd.error || cd.stale === true` so cached bars stay
  visible alongside the explanatory message.

No schema changes, no new labels, no tooltips. KDE only; the GNOME
extension is untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant