Skip to content

Feat: add opencode implementation to the agents plugin (with the new usage endpoint) - #6779

Closed
felixzsh wants to merge 11 commits into
omacom:quattrofrom
felixzsh:feat/opencode-go-usage
Closed

felixzsh wants to merge 11 commits into
omacom:quattrofrom
felixzsh:feat/opencode-go-usage

Conversation

@felixzsh

Copy link
Copy Markdown
Contributor

Summary

Adds official support for OpenCode Go subscriptions to the agents usage
widget, following the same architecture as the existing claude, codex,
and fireworks collectors: one omarchy-agent-usage-<agent> collector
prints a display-ready JSON record that the panel discovers by convention —
no panel changes needed.

image

What's new

  • bin/omarchy-agent-usage-opencode-go — new collector:
    • Plan limits from OpenCode's new official usage API,
      GET https://opencode.ai/zen/go/v1/usage (merged upstream in
      feat(console): add go usage endpoint anomalyco/opencode#16513), authenticated with the Go API key from
      ~/.local/share/opencode/auth.json (or OPENCODE_GO_API_KEY). It
      returns the rolling 5-hour, weekly, and monthly windows as percentages
      with reset timestamps — the same numbers the opencode.ai dashboard shows
      — so the panel's meters are authoritative account-wide.
    • Token stats from opencode's own SQLite database
      (~/.local/share/opencode/opencode.db), counting assistant messages on
      the opencode-go provider, split by day and model with cache and
      reasoning separated — the same database the claude and codex
      collectors already read for their own providers.
    • Accepts both the deployed response shape
      (usage.{rolling,weekly,monthly}.{percent,resetsAt}) and the merged PR
      shape ({rolling,weekly,monthly}Usage.{usagePercent,resetInSec}), and
      tolerates Cloudflare's User-Agent check on opencode.ai.
  • Mark — the official OpenCode "O" glyph (lobehub icon set) as
    assets/opencode-go.svg with a -light twin, following the codex
    convention.
  • Tests — test/shell.d/agent-usage-opencode-scanner-test.sh: 20
    assertions, ~1s, fully offline (fixture database + mocked endpoint).
  • Docs — the agents plugin README gains a collector row and an
    "OpenCode Go limits" section.

Verification

  • Ran the collector against a live account: the limits probe returns real
    percentages (rolling/weekly/monthly) and the token stats come from the
    local database (359 prompts, per-model breakdown).
  • bash test/shell.d/agent-usage-opencode-scanner-test.sh passes (20/20).

Notes

  • The Go usage endpoint is server-side and already live; no opencode client
    update is required.
  • No public API exposes usage by day or by model, so the token breakdown
    comes from the local database (same as claude/codex), while the limit
    percentages are the account-wide truth from the API.

Collects local token stats from opencode's own database (assistant
messages on the opencode-go provider) and the authoritative plan limits
from GET /zen/go/v1/usage — the same rolling 5-hour, weekly, and monthly
percentages the opencode.ai dashboard shows. Reads the key from
OPENCODE_GO_API_KEY or the opencode-go entry of ~/.local/share/opencode/
auth.json, and accepts both the deployed response shape and the merged PR
shape defensively. Probes are cached for 15s and kept as the answer of
record on transient failure, with retryAdvised for the panel.
The official opencode-go glyph as a white mark for dark surfaces and a
dark twin for light ones, following the codex.svg convention.
Fixture opencode database rows (today, older, wrong-provider, zero-token),
both endpoint response shapes, percent scaling, rate-limited windows, key
precedence, and failure paths keep local stats.
The hero meta line is the plan, never the product: claude shows its
subscription tier and codex its planType there. "OpenCode Go" duplicated
the Go plan, so the display name is now just OpenCode and tierLabel keeps
the Go plan. Tests pin both fields.
Copilot AI balanced review requested due to automatic review settings August 12, 2026 23:38
@felixzsh felixzsh changed the title Feat: add opencode implementation to the agents plugin (using the new api) Feat: add opencode implementation to the agents plugin (using the new usage endpoint) Aug 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds OpenCode Go usage and subscription-limit collection to the Agents panel.

Changes:

  • Adds an OpenCode Go collector using the usage API and local SQLite data.
  • Adds provider icons and documentation.
  • Adds offline collector tests.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 2 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
bin/omarchy-agent-usage-opencode-go Implements API limits, local statistics, and caching.
test/shell.d/agent-usage-opencode-scanner-test.sh Tests parsing, statistics, credentials, and failures.
shell/plugins/agents/README.md Documents OpenCode Go support.
shell/plugins/agents/assets/opencode-go.svg Adds the dark-surface provider icon.
shell/plugins/agents/assets/opencode-go-light.svg Adds the light-surface provider icon.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +141 to +143
os.environ["XDG_CACHE_HOME"] = str(fresh_cache("live"))
scanner.GoUsageClient = LiveClient
live_record = scanner.scan(auth_path, db, "https://example.invalid")
@felixzsh felixzsh changed the title Feat: add opencode implementation to the agents plugin (using the new usage endpoint) Feat: add opencode implementation to the agents plugin (with the new usage endpoint) Aug 12, 2026
The client swaps never exercise the real transport, so GoUsageClient.probe
is now driven against a stubbed urllib.request.urlopen, the way the claude
limits test stubs it: the request path and its bearer, accept, and
user-agent headers are asserted, the deployed response shape is decoded,
and a rejected key, a server status, and a transport failure each map to
their distinct GoUsageError.
Copilot AI review requested due to automatic review settings August 12, 2026 23:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated no new comments.

@felixzsh

Copy link
Copy Markdown
Contributor Author

its good to go

dhh and others added 2 commits August 13, 2026 03:12
The per-value heuristic rendered 1% as a full meter and 0.5% as half of
one: any value above 1 was divided by 100 while its neighbors below 1
were not, so one payload could mix scales. Detect the scale across the
whole payload the way the claude collector does — any value reaching 1
means percentages — and normalize every window with it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A probe failure fell back to the cached limits forever, so a window
whose reset time had long passed kept a dead meter on the panel, and a
rejected API key hid behind that silent fallback with no status at all.
Filter the cache through the same window-expiry check the claude
collector uses, flag auth and transport failures on the error itself,
and answer a rejected key with a "Sign-in rejected" status and the
remedy. A missing key now keeps still-open windows under "Waiting for
auth" too, matching claude's fallback handling.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 13, 2026 10:19
@dhh

dhh commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Reviewed. The collector's contract compliance, discovery naming, DB scan, and test isolation are all solid — and opencode-go as the id is exactly right, since plain opencode would claim Anthropic/OpenAI-through-opencode usage the other collectors already attribute. I pushed two commits fixing behaviors that diverged from the claude collector this code mirrors:

  1. Percent scale: the per-value > 1 heuristic made the meter discontinuous right after a window reset — 0.5% rendered as 50% and exactly 1% as a full meter. The scale is now detected payload-wide, the way the claude collector does it.
  2. Cached limits: the probe cache was served forever on any error, including a rejected key — a dead meter with a reset time in the past and no explanation. Cached windows are now dropped once their reset has passed, and a rejected key says "Sign-in rejected" instead of being papered over.

Both are pinned by new test cases (32 assertions, all green).

— 🤖 Claude, posting on behalf of @dhh

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated no new comments.

@felixzsh

Copy link
Copy Markdown
Contributor Author

i think we should do something similar #6780

The database holds every historical message, JSON included, so the scan now
filters in SQL (LIKE gates plus json_valid/json_extract with providerID
opencode-go) instead of parsing tens-of-MB blobs in Python. The stats cache
gains a versioned envelope stamped with the scan date, negative-age and
cross-day misses, and never persists a scan cut short by a database error;
cache-layer failures degrade to a direct scan instead of a crash.
A versioned, dated envelope on first scan, corrupt-cache recovery,
limits-only reuse with a force bypass, dated and future-dated misses,
malformed opencode rows that must not abort the scan, an interrupted scan
that must never be cached, and an unwritable cache root that falls back to
a direct scan.
Copilot AI review requested due to automatic review settings August 13, 2026 14:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated no new comments.

@markbus-ai

Copy link
Copy Markdown
Contributor

Oh, I had opened a PR hoping to push for the implementation of this new endpoint; your work is great.

@felixzsh

felixzsh commented Aug 14, 2026 •

Copy link
Copy Markdown
Contributor Author

i would recommend to first merge this pr #6542

Copilot AI review requested due to automatic review settings August 16, 2026 00:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 5 changed files in this pull request and generated no new comments.

@jesseburlamaque

Copy link
Copy Markdown

My question is: what's the plan for Zen?

Is Zen intended to be a separate collector/PR (e.g., omarchy-agent-usage-opencode-zen), or is the goal for this PR to eventually cover both Go and Zen under one opencode agent?

For context, I noticed #6526 takes the approach of splitting them into two separate records (opencode-zen and opencode-go), while this PR started as opencode-go and was later renamed to opencode. It would be great to understand preferred direction. Happy to help test either route.

@felixzsh

Copy link
Copy Markdown
Contributor Author

My question is: what's the plan for Zen?

Is Zen intended to be a separate collector/PR (e.g., omarchy-agent-usage-opencode-zen), or is the goal for this PR to eventually cover both Go and Zen under one opencode agent?

For context, I noticed #6526 takes the approach of splitting them into two separate records (opencode-zen and opencode-go), while this PR started as opencode-go and was later renamed to opencode. It would be great to understand preferred direction. Happy to help test either route.

there are no official api endpoints for zen as far as i know, but either way zen its different, its pay as you go so that would fit in a section that doesn't exits in this agents plugin, something like credits, idk i just use opencode go subscription

kczimm added a commit to kczimm/omarchy that referenced this pull request Aug 28, 2026
Adds native support for OpenCode Go subscriptions in the agents panel.
Queries OpenCode's official /zen/go/v1/usage API for rolling (5h),
weekly, and monthly limit usage with reset timers.

Unique features compared to other PRs (omacom#7157, omacom#8065, omacom#6526, omacom#6779, omacom#6464):
- Pi session scanning for local token stats
- Harness-agnostic key discovery (Pi, OpenCode CLI, env var)
- Account-scoped metadata (scope, hasPromptStats)

Key design decisions:
- Uses curl instead of urllib to bypass Cloudflare TLS fingerprinting
- Includes light/dark icon variants matching OpenCode brand colors
- Adds test coverage for auth lookup, API parsing, and error handling
@bjarneo

bjarneo commented Sep 20, 2026

Copy link
Copy Markdown
Member

Automated duplication check: this pull request looks similar to #8065, which covers the same OpenCode usage collector. I keep that one open and close this one to consolidate review.

If you feel this is the wrong decision, please open the PR again with a note on the difference.

@bjarneo bjarneo closed this Sep 20, 2026
@felixzsh

felixzsh commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor Author

@bjarneo mine was older and had better test coverage, but i know it was kinda outdated and opencode v2 is on the horizon, i will re-open a pr with the updated and improved implementation

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.

6 participants