Files
openchamber/packages/web/server/lib/quota/DOCUMENTATION.md
T
Bohdan Triapitsyn 5917325d49 feat: switch OpenCode Go usage to API
OpenCode Go now reads quota usage with a bearer API key from OpenCode auth.json
Removes the old workspace ID and browser cookie credential flow
Deletes legacy OpenCode Go credential files during upgrade
2026-08-12 01:49:22 +03:00

7.8 KiB

Quota Module Documentation

Purpose

This module fetches quota and usage signals for supported providers in the web server runtime.

Entrypoints and structure

  • packages/web/server/lib/quota/index.js: public entrypoint imported by packages/web/server/index.js.
  • packages/web/server/lib/quota/routes.js: Express route registration for quota endpoints.
  • packages/web/server/lib/quota/providers/index.js: provider registry, configured-provider list, and provider dispatcher.
  • packages/web/server/lib/quota/providers/google/: Google-specific auth, API, and transform modules.
  • packages/web/server/lib/quota/utils/: shared auth, transform, and formatting helpers.

Supported provider IDs (dispatcher)

These provider IDs are currently dispatchable via fetchQuotaForProvider(providerId) in packages/web/server/lib/quota/providers/index.js.

Provider ID Display name Module Auth aliases/keys
claude Claude providers/claude.js anthropic, claude
codex Codex providers/codex.js openai, codex, chatgpt
cursor Cursor providers/cursor.js Environment/token files, OpenChamber-managed credentials, or explicit one-time Cursor import
crof CrofAI providers/crof.js crof (API key under key or token)
deepseek DeepSeek providers/deepseek.js deepseek (API key under key or token)
google Google providers/google/index.js google, google.oauth, Antigravity accounts file
github-copilot GitHub Copilot providers/copilot.js github-copilot, copilot
github-copilot-addon GitHub Copilot Add-on providers/copilot.js github-copilot, copilot
kimi-for-coding Kimi for Coding providers/kimi.js kimi-for-coding, kimi
nano-gpt NanoGPT providers/nanogpt.js nano-gpt, nanogpt, nano_gpt
openrouter OpenRouter providers/openrouter.js openrouter
zai-coding-plan z.ai providers/zai.js zai-coding-plan, zai, z.ai
zhipuai-coding-plan Zhipu AI Coding Plan providers/zhipuai-coding-plan.js zhipuai-coding-plan, zhipuai, zhipu
minimax-coding-plan MiniMax Coding Plan (minimax.io) providers/minimax-coding-plan.js / providers/minimax-shared.js minimax-coding-plan
minimax-cn-coding-plan MiniMax Coding Plan (minimaxi.com) providers/minimax-cn-coding-plan.js / providers/minimax-shared.js minimax-cn-coding-plan
ollama-cloud Ollama Cloud providers/ollama-cloud.js Manual cookie stored under ~/.config/openchamber/quota/
wafer Wafer.ai providers/wafer.js wafer, wafer-ai, wafer_ai, wafer.ai
opencode-go OpenCode Go providers/opencode-go.js opencode-go API key from OpenCode auth.json
neuralwatt NeuralWatt providers/neuralwatt.js neuralwatt (API key under key or token)
xai xAI providers/xai.js xai OAuth entry in OpenCode auth.json

Internal-only provider module

  • providers/openai.js exists for logic parity/reuse but is intentionally not registered for dispatcher ID routing.

Response contract

All providers should return results via shared helpers to preserve API shape:

  • Required fields: providerId, providerName, ok, configured, usage, fetchedAt
  • Optional field: error
  • Unsupported provider requests should return ok: false, configured: false, error: Unsupported provider

Provider modules must export providerId, providerName, aliases, isConfigured(auth?), and fetchQuota(). fetchQuota() should return a quota result with usage.windows keyed by window name (for example 5h, 7d, daily) and optional provider-specific usage.models data.

Ollama Cloud and Cursor credentials are explicitly managed through Settings. OpenCode Go usage uses GET https://opencode.ai/zen/go/v1/usage with the opencode-go API key from OpenCode auth.json as a bearer token. The server validates managed credentials before atomic 0600 writes and never returns secrets through its API. OpenChamber never scans browser cookie stores or automatically reads Cursor storage; Cursor import is an explicit one-time user action and never modifies Cursor's database.

On the first OpenCode Go usage refresh after upgrading, OpenChamber deletes the obsolete quota/opencode-go.json credential file without reading its cookie value.

Add a new provider (quick steps)

  1. Choose module shape based on complexity:
    • Simple providers: create packages/web/server/lib/quota/providers/<provider>.js.
    • Complex providers (multi-source auth, multiple API calls, non-trivial transforms): create packages/web/server/lib/quota/providers/<provider>/ with split modules like Google (index.js, auth.js, api.js, transforms.js).
  2. Export providerId, providerName, aliases, isConfigured, and fetchQuota.
  3. Use shared helpers from packages/web/server/lib/quota/utils/index.js (buildResult, toUsageWindow, auth/conversion helpers) to keep payload shape consistent.
  4. Register the provider in packages/web/server/lib/quota/providers/index.js.
  5. If needed for direct use, export a named fetcher from packages/web/server/lib/quota/providers/index.js and packages/web/server/lib/quota/index.js.
  6. Update this file with the new provider ID, module path, and alias/auth details.
  7. Validate with bun run type-check, bun run lint, and bun run build.

MiniMax M3 / Token Plan migration

In 2025/2026 MiniMax rebranded "Coding Plan" to "Token Plan" alongside the M3 model release. The API underwent breaking changes:

  • Endpoint fallback: The provider tries /v1/token_plan/remains (M3) first, falling back to legacy /v1/api/openplatform/coding_plan/remains.
  • Field semantics: On the token_plan/remains endpoint, current_interval_usage_count returns remaining quota (not consumed). The provider computes used = total - remaining for this endpoint. The legacy coding_plan/remains endpoint retains the old semantics (usage_count = consumed).
  • Percentage-based plans: Legacy Coding Plan accounts return current_interval_total_count: 0 but include current_interval_remaining_percent. The provider prefers this field when count fields are absent.
  • model_remains array: Now contains entries for multiple model categories (chat, speech, video, image). The provider selects the chat-model entry by matching MiniMax-M*, then general/chat/text by name, then any entry with a remaining percent.
  • Window status: The current_interval_status and current_weekly_status fields indicate whether a window is active. Status 3 means the window is not applicable for the current plan tier (e.g. legacy plans without weekly limits). The provider omits inactive windows.

Kimi for Coding field semantics

GET https://api.kimi.com/coding/v1/usages is inconsistent about which field carries consumption:

  • The weekly usage block returns used (consumed) with no remaining field.
  • Each limits[].detail rate-limit block returns remaining (available) with no used field.

The provider computes usedPercent from whichever of used/remaining is present (used takes precedence when both exist) rather than assuming one field name. Both packages/web/server/lib/quota/providers/kimi.js and packages/vscode/src/quotaProviders.ts (fetchKimiQuota) must stay in sync — the VS Code extension duplicates this parsing logic rather than importing it.

Notes for contributors

  • Keep provider IDs stable; clients use them directly.
  • Avoid adding alias-based dispatch in fetchQuotaForProvider; dispatch currently expects exact provider IDs.
  • Keep Google behavior changes isolated and review providers/google/* together.
  • Z.ai Coding Plan exposes separate 5-hour and weekly TOKENS_LIMIT entries plus a monthly TIME_LIMIT for MCP tools; web and VS Code must preserve all three windows.