usage — Subscription Quota, Always Visible
TL;DR
Real-time quota and balances for 8 providers in the status bar: Kimi/Grok/Zhipu/MiniMax/Codex percentage + reset countdown, Copilot tier/limit, DeepSeek/OpenRouter balances; amber/red when nearly exhausted, switches with the model.
Overview
Subscription coding agents (Kimi For Coding, SuperGrok, …) all have usage quotas, but checking them means opening a web console or trusting memory — until a 429 reveals you ran out. @piex-dev/usage puts available subscription status in the pi status bar: Kimi/Grok/Zhipu/MiniMax/Codex show percentage + reset countdown, Copilot shows its tier and limit state, and DeepSeek/OpenRouter show balances; the data source switches with the model. Fully automatic, zero interaction.
Usage: 5-Hour:21%🕙3h45 7-Day:26%🕙6d17h Kimi / Zhipu / MiniMax
Usage: 7-Day:32%🕙4d3h Grok
Usage: Copilot Pro
Usage: 5H:21%🕙3h45 7D:26%🕙6d17h Credits:12 OpenAI Codex (Plus/Pro/Team)
Usage: 今¥7.81 7d¥26.91 30d¥148.46 充值余额:¥50,560.02 DeepSeek
Usage: 余额:$37.50 OpenRouterHow it works
Data sources: every provider has an official (some undocumented but stable) usage endpoint returning quota, reset times, or balances — Kimi GET https://api.kimi.com/coding/v1/usages (weekly limit/used/remaining/resetTime + rolling-window limits); Grok GET https://cli-chat-proxy.grok.com/v1/billing?format=credits (weekly credit percent + period); Codex (openai-codex) GET https://chatgpt.com/backend-api/wham/usage (ChatGPT subscription windows + per-feature windows + credits + plan, reset_at in epoch seconds). Credentials: resolved via ctx.modelRegistry.getProviderAuth(provider) — pi auto-refreshes expired OAuth tokens, the extension never touches refresh flows or persists any secret.
DeepSeek official billing: balance comes from the official endpoint (user/balance, API-key auth, returning total/topped-up/granted); the per-day cost API (platform.deepseek.com/api/v0/usage/cost) only accepts a browser session token — set DEEPSEEK_PLATFORM_TOKEN (DevTools → any api/v0 request → Authorization header) to show official today/7d/30d spend with daily breakdown. The token is a login session (days to weeks); when expired the status bar shows token失效 and degrades to balance-only; unset shows balance only.
Zhipu / MiniMax / OpenRouter (ported from cc-switch): the three adapters are ported from cc-switch's usage/balance queries. Zhipu (zai-coding-cn / zai) uses GET {open.bigmodel.cn|api.z.ai}/api/monitor/usage/quota/limit with API-key auth (no Bearer prefix), returning 5-hour + weekly used percentages; MiniMax (minimax-cn / minimax) uses GET https://api.minimaxi.com|io/v1/api/openplatform/coding_plan/remains and inverts remaining percentages; both render like Kimi. OpenRouter (openrouter) uses GET https://openrouter.ai/api/v1/credits and shows remaining credits (total − usage; warn below $10, red below $2). SiliconFlow/StepFun/Novita balances and Volcengine's AK/SK-signed quota have no matching provider id in pi and were not ported.
Copilot limits: GitHub Copilot has no public usage/balance endpoint (the billing API requires a copilot-scoped OAuth app; the Copilot API has no usage endpoint). The official token endpoint (copilot_internal/v2/token) exposes only the subscription SKU and the limited-user quota (non-null only while rate-limited). The Copilot adapter therefore shows a tier badge (Copilot Pro / Copilot Free(OSS)) and a red limited marker with reset countdown when rate-limited — the endpoint ceiling; there is no percentage balance. The limited-state check best-effort reads pi's GitHub OAuth token from auth.json (honoring PI_CODING_AGENT_DIR) solely to call the official token endpoint; it never writes or logs the token.
Model-gated display: on session_start / model_select the extension checks model.provider; only providers with an adapter show quota, everything else clears the status bar. Three refresh layers: event-driven (immediately after every turn_end), background poll (default 300s, USAGE_POLL_SECONDS), and a local 30s countdown ticker that re-renders without API calls.
Usage
Install
pi install npm:@piex-dev/usageSource: extensions/usage
Commands
Zero interaction: pick a Kimi / Grok / Zhipu / MiniMax / Codex / OpenRouter / DeepSeek / Copilot model and quota appears; switch away and it clears. Or refresh and inspect manually:
/usage # force refresh + details (per-window usage/reset times, membership, SKU, balances, Codex plan & feature windows)Configuration
| Env var | Default | Meaning |
|---|---|---|
USAGE_POLL_SECONDS | 300 | API poll interval (seconds) |
USAGE_SHOW_XAI_MONTHLY | unset | Set to 1 to show Grok monthly unified billing (not shown on the official console; hidden by default) |
Verify
pi -e ./extensions/usage/src/usage.ts -p "say hi" --no-sessionImplementation
Package: extensions/usage — src/adapters.ts (data-source adapters) + src/usage.ts (event wiring), ~440 lines. Adapter architecture: adapters.ts defines the QuotaAdapter interface (providerIds + fetch) with built-in kimiAdapter and xaiAdapter; usage.ts handles model_select/session_start gating, turn_end refresh, polling and countdown tickers, and the /usage command. Adding a provider is just a new adapter — event wiring stays untouched.
<window-label>:<percent-used>%🕙<reset-countdown>
# usage ≥ 90% red, ≥ 70% yellow
# countdown: 6d17h (days) / 3h45 (hours) / 45m (minutes)Details: getProviderAuth headers already carry the Bearer prefix — stripped once, then re-applied by adapters, avoiding the Bearer Bearer double prefix (xAI rejects it); Grok matches both xai and xai-oauth provider ids with token fallback; Codex parses reset_at as epoch seconds, falls back to reset_after_seconds, and never fabricates a reset time when both are absent; Codex accepts only the official https://chatgpt.com model/auth origin so proxy credentials are never forwarded to OpenAI; undocumented endpoints may change — parse failures show <label>: offline and retry on the next cycle, and the Grok monthly endpoint is best-effort (failure never breaks the main display).
Design notes
| Alternative | Mechanism | piex choice |
|---|---|---|
| Official console | Web page, opened manually | Status bar resident: quota + countdown always visible, warned before 429s |
| Community tools (kimi-code-usage etc.) | CLI/MCP queries, run manually | Event-driven: refreshed on turn_end, zero interaction |
| pi built-in footer usage | Token cost within the session | Coexist: usage shows account-level subscription quota; complementary |
Key trade-offs: account-level quota over session-level cost (exhaustion is the hard stop), status-bar residency over on-demand queries (visible is preventable).
Changelog
Roadmap
| Direction | Plan |
|---|---|
| More providers | Claude subscription (api.anthropic.com/api/oauth/usage) plugs into the same adapter interface (Codex shipped in 0.2.0) |
| Custom thresholds | USAGE_WARN_RATIO / USAGE_ERROR_RATIO as env vars |
| Usage trend | Store snapshots locally; show "−2% vs last" in the status bar |
| Collapsible windows | With multiple rolling windows, show only the tightest by default; full list in details |
Version history
| Version | Date | Changes |
|---|---|---|
| 0.2.0 | 2026-08-28 | OpenAI Codex (openai-codex) adapter: account primary/secondary windows + the active model's own feature window (e.g. Spark 5H shown only when the model is gpt-5.3-codex-spark; other models' feature windows live in details) + credits + plan; credits-only and limited responses remain displayable, with explicit red limited state; all feature primary/secondary windows and reset times are preserved; custom proxy origins are rejected before credentials are sent |
| 0.1.0 | 2026-07-31 | Initial release: Kimi (weekly + rolling windows) and Grok (weekly credits) in the status bar; model-gated display; three-layer refresh (turn_end + 300s poll + 30s countdown ticker); /usage details command; optional monthly display via USAGE_SHOW_XAI_MONTHLY |
Source Markdown: docs/packages/usage.md