Skip to content

Add OpenCode Go to AI usage widget - #7157

Closed
AI091 wants to merge 5 commits into
omacom:quattrofrom
AI091:opencode-go-usage
Closed

AI091 wants to merge 5 commits into
omacom:quattrofrom
AI091:opencode-go-usage

Conversation

@AI091

@AI091 AI091 commented Aug 16, 2026

Copy link
Copy Markdown

Summary

Adds an OpenCode Go tab to the agents panel.

OpenCode Go panel

Changes

  • bin/omarchy-agent-usage-opencode-go — collector
  • shell/plugins/agents/assets/opencode-go{,-light}.svg — logo
  • manifest.json, README.md, manual/17-ai.md — defaults + docs
  • test/shell.d/agent-usage-opencode-go-scanner-test.sh — tests

Built with OpenCode Go :), Kimi K3 & DeepSeek V4 Pro

AI091 added 2 commits August 16, 2026 19:39
Collect OpenCode Go usage as a new agents-panel collector: local token
stats from opencode's message database, plus rolling/weekly/monthly rate
limits from opencode's key-authenticated usage endpoint. Adds the OpenCode
Go mark and registers the provider in the panel defaults.
Copilot AI balanced review requested due to automatic review settings August 16, 2026 16:40

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

Note

Copilot was unable to run its full agentic suite in this review.

Adds OpenCode Go support to the Omarchy agents panel by introducing a new usage/limits collector, wiring it into the plugin configuration, and documenting/testing the new provider.

Changes:

  • Added omarchy-agent-usage-opencode-go collector to scan opencode’s SQLite DB for local token usage and fetch rate-limit windows from opencode.ai.
  • Added a comprehensive shell test covering scanning behavior, malformed rows, caching, and limits/key resolution.
  • Updated agents plugin manifest, docs, and assets to expose/configure the new opencode-go provider.

Reviewed changes

Copilot reviewed 4 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/shell.d/agent-usage-opencode-go-scanner-test.sh Adds end-to-end shell coverage for OpenCode Go scanning, caching, and limits behavior
shell/plugins/agents/manifest.json Enables the opencode-go provider and updates plugin description
shell/plugins/agents/assets/opencode-go.svg Adds OpenCode Go icon (dark)
shell/plugins/agents/assets/opencode-go-light.svg Adds OpenCode Go icon (light)
shell/plugins/agents/README.md Documents the new provider and configuration/key resolution
manual/17-ai.md Updates the manual to mention OpenCode Go support and limit windows
bin/omarchy-agent-usage-opencode-go Implements the OpenCode Go collector (local stats + limits fetching + caching)

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

Copilot AI review requested due to automatic review settings August 16, 2026 16: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 4 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

test/shell.d/agent-usage-opencode-go-scanner-test.sh:151

  • If the test harness enables set -e (commonly done in shared base-test.sh), find exiting non-zero when the directory doesn’t exist will abort the script before the explicit assertion runs. To make the test reliably report the intended failure, guard the command substitution (e.g., append || true) so missing cache paths flow into the [[ ... ]] || fail ... check instead of exiting early.
cache_file=$(find "$CACHE_HOME/.cache/omarchy/agent-usage" -maxdepth 1 -name 'opencode-go-scan-*.json' -print -quit 2>/dev/null)
[[ -n "$cache_file" && -s "$cache_file" ]] ||
  fail "OpenCode Go collector leaves a cache file behind" "$result"

@AI091 AI091 changed the title Add OpenCode Go usage collector Add OpenCode Go usage to ai usage widget Aug 19, 2026
@AI091 AI091 changed the title Add OpenCode Go usage to ai usage widget Add OpenCode Go to ai usage widget Aug 19, 2026
@AI091 AI091 changed the title Add OpenCode Go to ai usage widget Add OpenCode Go to AI usage widget Aug 19, 2026
omarchybot and others added 2 commits August 22, 2026 05:48
The block that stubs urlopen ran without HOME or XDG_CACHE_HOME pointing at the fixture, so its first successful fetch wrote the stubbed windows through write_limits_cache into the real ~/.cache/omarchy/agent-usage/opencode-go-limits.json. That is the file the collector falls back to when opencode.ai returns 429 or the network is down, so anyone who ran ./test/shell could later see 1% / 50% / 0.5% meters labelled "OpenCode Go limits stale".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two things the endpoint can return that the meters could not survive. A 200 whose body has no usage object — `{}`, `{"usage": null}`, or a JSON error body — reached `usage.get` on a non-dict and raised AttributeError, so the collector exited non-zero, omarchy-agent-usage-update reported it failed, and the record was never rewritten: the tab froze on whatever the last good run left. And a window that reported a percentage but no reset time was dropped whole, taking the percentage with it; since the panel's hero and its 90% alarm read the fullest window, losing one silently under-reports how close the next prompt is to the limit. omarchy-agent-usage-codex already emits an empty resetsAt for that case and Panel.qml renders it without a countdown.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@omarchybot

Copy link
Copy Markdown
Collaborator

Reviewed on a worker VM against quattro (head 301e533c): full read of the collector, targeted probes of what it does with an absent, empty, corrupt, newer-schema and hostile-row opencode.db and with odd endpoint responses, plus ./test/cli (116 assertions) and test/shell.d/agent-usage-opencode-go-scanner-test.sh, agent-usage-update-test.sh, agents-panel-test.sh, the claude/codex/fireworks scanner suites, manifest-entrypoints-test.sh and plugin-validate-test.sh through the compositor-backed wrapper. All green. I did not verify the panel visually.

The approach holds up. A malformed, truncated or v2-only database produces a clean all-zero record and exit 0 rather than a traceback, the token arithmetic matches omarchy-agent-usage-claude's scan of the same table, and the ids line up end to end — filename suffix, AGENT_ID, the manifest.json key and assets/opencode-go.svg are all opencode-go, which is what makes --except opencode-go and the panel's retryAdvised re-run actually reach this collector.

Pushed three commits to opencode-go-usage:

4dc1335c — the block that stubs urlopen ran python3 without HOME/XDG_CACHE_HOME pointing at the fixture, so its first successful fetch_limits wrote the stubbed windows through write_limits_cache into the real ~/.cache/omarchy/agent-usage/opencode-go-limits.json. That is the file the collector falls back to on a 429 or a network blip, so anyone who ran ./test/shell could afterwards see fabricated 1% / 50% / 0.5% meters labelled "OpenCode Go limits stale". Confirmed by running the suite on a worker before and after: the old test writes that file into the real home, the new one does not.

2e29c6dd, first half — fetch_limits guarded payload with isinstance but not the value under "usage", so a 200 whose body is {}, {"usage": null}, {"usage": [...]} or a JSON error body reached usage.get on a non-dict and raised AttributeError. The collector then exits non-zero, omarchy-agent-usage-update reports it failed, and the record is never rewritten — the tab freezes on whatever the last good run left. A bare {} is enough to trigger it, which is a shape the code elsewhere clearly anticipates: "No usage data returned for this key." was unreachable.

2e29c6dd, second half — a window carrying a percent but no resetsAt was dropped whole, taking the percentage with it. Panel.qml's hero and its 90% alarm read the fullest window, so losing one silently under-reports how close the next prompt is to the limit. omarchy-agent-usage-codex:517 already emits "" for a missing reset and Panel.qml renders that without a countdown.

Left for you — all real, none of them mine to decide:

  1. The stale-limits cache has no expiry. read_limits_cache serves whatever was last written, so after an outage the meters can keep showing a window that has since reset — an old 95% describing an allowance that is now untouched. omarchy-agent-usage-claude:769-791 already solves exactly this with limit_window_open / usable_cached_limits, which drops cached windows whose resetsAt has passed and deliberately keeps ones with no reset time. I did not push it because the test's transient-failure fixture uses resetsAt of 2026-08-16, now in the past, so adopting the filter means reworking those fixtures too.

  2. The same cache is one fixed path, not keyed to the account. Change OPENCODE_API_KEY and hit a transient error on the first fetch and you are shown the previous account's usage.

  3. local_day() does not guard a created of 0 or negative the way omarchy-agent-usage-claude:499 does (if created > 0 else today). A row with created: -2000000000 lands on 1906-08-16 in activeDates and adds a day to activeDays. I could not establish that opencode ever writes such a row, so I left it.

  4. Only the v1 message table is read. On a v2-only install (session_message, provider under $.model.providerID) this reports zeros and the tab quietly never appears — no crash, I checked. Worth saying that omarchy-agent-usage-claude and -codex have the same gap today, so this is not something you introduced.

  5. With no API key the record carries neither usageStatusText nor authHelpText, so the tab shows usage with no explanation of why there are no meters. Your test asserts this on purpose, so I left it alone.

One style note: AGENTS.md says not to quote variables inside [[ ]], and [[ -n "$cache_file" && -s "$cache_file" ]] at line 152 is the only quoted instance in all of test/shell.d. Behaviour is identical either way — flagging it only because 301e533c added those quotes deliberately.

Waiting on the maintainer. This is not the only OpenCode Go collector open: #7687, #7082, #6464, #6526 and #6779 all cover the same ground, and #6464 and #6526 create the same bin/omarchy-agent-usage-opencode-go path this PR does. Which one lands is not a reviewer's call.

Second opinion from codex at xhigh reasoning, run as an independent reviewer. It found the missing usage guard and the dropped reset-time window on its own before I pushed either fix — its independence is not currently guaranteed, so read that as agreement rather than confirmation. It did contribute the stale-cache expiry and account-scoping problems above, which I had not reasoned about and then verified against omarchy-agent-usage-claude. I rejected its claim that the README prose breaks the house wrapping rule: that rule covers plans/, docs/ and manual/, and shell/plugins/agents/README.md is already wrapped the same way throughout.

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
@Brams-s

Brams-s commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Thanks for the focused provider implementation. The collector shape, provider IDs, malformed-row handling, and targeted shell coverage look consistent with the existing agents architecture.

A few non-blocking follow-ups are worth considering before merge:

  • The limits cache is currently reusable after its reset time has passed. During a transient API failure, this could display an old percentage for a window that has already reset. Claude's collector already has a resetsAt-aware cache usability check that could be reused or mirrored here.
  • The cache path is not account-scoped. If the API key changes and the next request fails transiently, the previous account's cached limits could be shown. A stable account/key fingerprint in the cache filename or payload would prevent that.
  • The scanner currently handles the v1 message table, while newer OpenCode databases may use session_message and store the provider under model.providerID. Reporting a clean zero is safe, but an explicit schema/version status would make no data distinguishable from an unsupported database schema.
  • created <= 0 currently appears able to produce an invalid historical day. Treating non-positive timestamps as today, as the Claude collector does, would avoid polluting active-day and chart data if malformed rows occur.

These are follow-ups rather than blockers, and I have not confirmed that every case occurs in production OpenCode databases. The existing tests appear strong; the remaining validation gap noted in the PR is visual verification of the panel.

@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
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.

5 participants