How much of each provider subscription is left, and what the model calls used, for the host's usage page and status line.
The windows (percent used, reset time) come from the providers' rate-limit
headers on every model call (record/3, from Rho.LLM.ReqLLM)
and from their OAuth usage endpoints on demand (put_endpoint/5, with
Rho.Usage.Fetch), as omp reads them:
- Claude:
anthropic-ratelimit-unified-{5h,7d,7d_oi}-utilization(a fraction) and-reset(unix seconds);GET /api/oauth/usagegivesfive_hour/seven_day/limits[]in percent with ISO resets. - ChatGPT:
x-codex-{primary,secondary}-used-percent,-window-minutes,-reset-at(unix seconds);GET /backend-api/wham/usagegivesrate_limit.{primary,secondary}_window.
Everything is kept in usage.json in the data dir (no tokens, no
secrets; it survives restarts):
"limits": per provider,"windows"(id such as"5h"/"7d"→%{"label", "used" (percent), "resets_at" (unix s or nil)}),"checked_at","source"("headers"or"endpoint"),"plan""rate_limited": per provider, the last 429's"at","resets_at","model"and"message""days"("YYYY-MM-DD"→ model → counters, the last 31 days) and"total"(model → counters):"requests","errors","input","output","cacheRead","cacheWrite","cost"(dollars, notional on a subscription)
Summary
Functions
Counters per model for date (:total for all time).
The registry of subscribe/0's processes, under Rho.Supervisor.
2h 5m, 3d 4h, 12m, <1m.
Is provider's subscription used up at now: a window at 100 % that
resets later (the latest such reset), else a 429 recorded with a reset
still ahead? %{window: label | nil, resets_at: unix s} or nil.
The windows and plan a usage endpoint's JSON reports: {windows, plan}.
The windows a model call's response headers report (%{} without any).
A provider's "limits" entry (checked_at, source, plan), or nil.
Everything recorded so far (an empty store when there's no readable file).
A window's percent used now, rounded (0 once its reset time has passed).
Stores what a provider's usage endpoint returned (windows from from_endpoint/3).
A provider's last 429, or nil.
Records one model call to model: a request (an error unless it carries
usage) with its tokens and cost, the windows its headers report, and a
429 with when it resets.
A session's counters from its entries: every assistant message is a
request, stopReason: "error" an error.
The status line's figure for provider: "5h 42% · wk 18%", plus
" · 429 2h 5m" while its last rate limit hasn't reset; nil before any
numbers. A window whose reset has passed counts as 0%.
Sends the caller {:rho_usage, :changed} after every change to the
store (a model call, an endpoint refresh), so the chat's status line
follows calls made anywhere. A no-op while Rho.Supervisor isn't running.
Counters summed over every model.
A provider's windows, 5h then 7d then the rest by id: [{id, window}].
Types
Functions
Counters per model for date (:total for all time).
@spec child_spec(term()) :: Supervisor.child_spec()
The registry of subscribe/0's processes, under Rho.Supervisor.
2h 5m, 3d 4h, 12m, <1m.
@spec exhausted(map(), atom(), integer()) :: %{window: String.t() | nil, resets_at: integer()} | nil
Is provider's subscription used up at now: a window at 100 % that
resets later (the latest such reset), else a 429 recorded with a reset
still ahead? %{window: label | nil, resets_at: unix s} or nil.
@spec from_endpoint(atom(), map(), integer()) :: {%{required(String.t()) => map()}, String.t() | nil}
The windows and plan a usage endpoint's JSON reports: {windows, plan}.
@spec from_headers(atom(), %{required(String.t()) => String.t()}) :: %{ required(String.t()) => map() }
The windows a model call's response headers report (%{} without any).
A provider's "limits" entry (checked_at, source, plan), or nil.
Everything recorded so far (an empty store when there's no readable file).
@spec percent(map(), integer()) :: non_neg_integer()
A window's percent used now, rounded (0 once its reset time has passed).
Stores what a provider's usage endpoint returned (windows from from_endpoint/3).
A provider's last 429, or nil.
Records one model call to model: a request (an error unless it carries
usage) with its tokens and cost, the windows its headers report, and a
429 with when it resets.
A session's counters from its entries: every assistant message is a
request, stopReason: "error" an error.
The status line's figure for provider: "5h 42% · wk 18%", plus
" · 429 2h 5m" while its last rate limit hasn't reset; nil before any
numbers. A window whose reset has passed counts as 0%.
@spec subscribe() :: :ok
Sends the caller {:rho_usage, :changed} after every change to the
store (a model call, an endpoint refresh), so the chat's status line
follows calls made anywhere. A no-op while Rho.Supervisor isn't running.
Counters summed over every model.
A provider's windows, 5h then 7d then the rest by id: [{id, window}].