Skip to content

fix(usage): read opencode's limits with the OpenCode Console sign-in - #60

Merged
viktorvillalobos merged 2 commits into
mainfrom
fix/bug/opencode-usage
Oct 19, 2026
Merged

viktorvillalobos merged 2 commits into
mainfrom
fix/bug/opencode-usage

Conversation

@viktorvillalobos

Copy link
Copy Markdown
Contributor

Problem

OpenCode 2 connects the account with /connect and stores an OAuth sign-in to the OpenCode Console (credential table, integration opencode), not a Go API key (opencode-go). Leon only looked for the Go key, so for a Go subscriber the usage view said "Limits cannot be read for this agent here".

Change

  • opencode.rs: reads the console sign-in (OAuth access with its expires, or a service-account/Zen key) from OPENCODE_AUTH_CONTENT, auth.json and the credential database, read only.
  • network.rs: new Credentials::opencode_console (default Missing). opencode_usage uses the Go key first and falls back to the console sign-in. With the console sign-in:
    • Go windows are read from zen/go/v1/usage (the endpoint accepts the console token).
    • A refusal for missing entitlement means the workspace pays from Zen credits: Reason::PayAsYouGo, plan Zen ("no limit to read; the balance is on the opencode console").
    • An expired or rejected sign-in is SessionExpired. Leon never refreshes it, because the refresh token is single use and spending it would sign opencode out.
  • model.rs: Reason::PayAsYouGo.
  • Docs: CHANGELOG, README, SETTINGS, ARCHITECTURE.

The Zen balance has no public endpoint for a user token: the console's routes return 404, and /api/v1/budgets/members needs an admin service-account key.

Verification

  • leon --diagnose usage --network opencode against a real Go account signed in through /connect: 5-hour 0%, weekly 0%, monthly 19%, plan Go.
  • The Zen branch has not been run against a live account (the account used has Go). It is covered by tests with the 402/403 entitlement refusals.
  • cargo test -p leon-usage passes (195 tests, 6 new). cargo clippy -p leon-usage --all-targets -D warnings is clean.

Note: PayAsYouGo is a new serialized reason, so an older peer cannot decode a Zen reading.

OpenCode 2 connects the account with /connect and stores an OAuth
sign-in to the console (entry `opencode`), not a Go API key, so the
usage view had nothing to read. Without a Go key the console sign-in
now reads the Go meters; a workspace without Go pays from Zen credits
and says so (Reason::PayAsYouGo). An expired sign-in is left for
opencode to renew: its refresh token is single use.
@viktorvillalobos
viktorvillalobos merged commit 8b6532f into main Oct 19, 2026
10 checks passed
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