Skip to content

fix(providers): gate OpenCode Go quota on the canonical base URL - #2027

Closed
yzxcj797 wants to merge 12 commits into
lidge-jun:devfrom
yzxcj797:fix/opencode-go-quota-gating-1924
Closed

fix(providers): gate OpenCode Go quota on the canonical base URL#2027
yzxcj797 wants to merge 12 commits into
lidge-jun:devfrom
yzxcj797:fix/opencode-go-quota-gating-1924

Conversation

@yzxcj797

@yzxcj797 yzxcj797 commented Aug 18, 2026

Copy link
Copy Markdown

Summary

Fixes #1924.

Root cause (as reported)

The OpenCode Go quota probe gated on the provider's name:

if ((provider.authMode ?? "key") === "key" && name === "opencode-go") {
  return fetchOpenCodeGoQuota(name, provider);
}

so in multi-account setups — sibling providers pointing at the canonical https://opencode.ai/zen/go/v1 for subscription balancing — only the provider literally named opencode-go produced quota rows; the dashboard showed no rate-limit panel for the siblings. The neighboring branches (Kimi, A6api, CommandCode) already gate on their canonical base URLs, and fetchOpenCodeGoQuota itself re-validates isCanonicalOpenCodeGoBaseUrl(config.baseUrl) before sending the bearer key, making the name check both too narrow and redundant.

Fix

-if ((provider.authMode ?? "key") === "key" && name === "opencode-go") {
+if ((provider.authMode ?? "key") === "key" && isCanonicalOpenCodeGoBaseUrl(provider.baseUrl)) {

Safe against key leakage to non-canonical hosts: the fetch still re-validates the canonical URL before the bearer key leaves.

Tests

Two regression tests in tests/opencode-go-quota.test.ts:

  • the exact repro: a sibling provider named opencode-go-2 on the canonical base URL now reports quota alongside opencode-go (both rows present, both fetches made) — on main this yields only one row;
  • a provider named opencode-go on a non-canonical base URL never probes opencode.ai with the key.

(Couldn't run the bun test suite locally on this Windows checkout; relying on CI.)

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Bug Fixes

    • Improved OpenCode Go quota detection for providers using the canonical service URL, regardless of provider name.
    • Prevented quota checks and usage reports for providers configured with other base URLs.
  • Tests

    • Added coverage for quota detection across supported provider configurations.

lidge-jun and others added 12 commits August 18, 2026 11:55
Promote dev to main: Wave 5 campaign (107 commits)
Promote dev to main: CodeQL lidge-jun#87 ReDoS fix + closeout correction
Promote dev to main: Wave 5 record corrections
Promote dev to main: alert-precision record
Promote dev to main: post-scan closing note
[WRONG BRANCH] Promote dev to main: v2.25.0 release
The quota probe required the provider to be literally named opencode-go,
so multi-account setups pointing sibling providers at the canonical
https://opencode.ai/zen/go/v1 base URL showed no rate-limit panel and
produced no report rows (lidge-jun#1924). The Kimmi/A6api/CommandCode branches
already gate on their canonical base URLs, and fetchOpenCodeGoQuota
re-validates the canonical URL before sending the bearer key, so the
name check was both too narrow and redundant.

Gate on isCanonicalOpenCodeGoBaseUrl(provider.baseUrl) instead.
Regression tests cover the sibling-provider repro and that a
non-canonical base URL never probes opencode.ai.
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 18, 2026
@github-actions github-actions Bot changed the title fix(providers): gate OpenCode Go quota on the canonical base URL [WRONG BRANCH] fix(providers): gate OpenCode Go quota on the canonical base URL Aug 18, 2026
@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3900e68b-3f1c-4f37-8d7b-c98143690ac3

📥 Commits

Reviewing files that changed from the base of the PR and between e97fb26 and 154b535.

📒 Files selected for processing (2)
  • src/providers/quota.ts
  • tests/opencode-go-quota.test.ts

Included review availability: Your plan includes up to 10 reviews per rolling hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

OpenCode Go quota probing now targets every key-auth provider using the canonical base URL. Tests cover multiple provider names on that URL and exclude providers using other base URLs.

Changes

OpenCode Go quota probing

Layer / File(s) Summary
Canonical URL quota dispatch and coverage
src/providers/quota.ts, tests/opencode-go-quota.test.ts
At src/providers/quota.ts:2087, quota dispatch matches the canonical OpenCode Go base URL instead of the literal opencode-go provider name. Tests at tests/opencode-go-quota.test.ts:91-150 verify reports for multiple key-auth providers on the canonical URL and no probes or reports for noncanonical URLs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 154b5

The change enables quota reporting for sibling providers using the canonical OpenCode Go URL while avoiding probes from non-canonical hosts. No actionable merge-blocking risk remains beyond normal checks and review.

Possibly related PRs

Suggested reviewers: ingwannu, wibias

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The change enables quota probing for every key-auth provider on the canonical URL and adds regression tests for canonical and non-canonical cases.
Out of Scope Changes check ✅ Passed The changes are limited to the OpenCode Go quota gate and focused regression tests, with no unrelated scope identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: gating OpenCode Go quota probing by the canonical base URL.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • wrong branch ancestry; rebase onto the latest dev. hygiene: unsponsored_surface.

What to do

  • Rebase onto the current dev branch instead of opening from main.
  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: package.json.
  • Tick all four boxes in the PR description once you're done (currently 0/4).

Review readiness checklist

  • ⬜ All CI tests are green on my local testing.
  • ⬜ I pushed my PR to the latest dev commit.
  • ⬜ I resolved all correct Codex and CodeRabbit findings.
  • ⬜ My PR is ready for review.

0/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.
@yzxcj797 Tick the boxes once your local CI is green, your branch is on the latest dev commit, and every correct Codex and CodeRabbit finding is resolved.

@github-actions
github-actions Bot marked this pull request as draft August 18, 2026 12:31
@Ingwannu Ingwannu changed the title [WRONG BRANCH] fix(providers): gate OpenCode Go quota on the canonical base URL fix(providers): gate OpenCode Go quota on the canonical base URL Aug 18, 2026
@Ingwannu
Ingwannu changed the base branch from main to dev August 18, 2026 12:36
@Ingwannu

Copy link
Copy Markdown
Owner

Retargeted this draft from release-only main to integration branch dev.

The reported defect is real on current dev: maybeFetchProviderQuota still gates OpenCode Go on the literal provider name even though fetchOpenCodeGoQuota already pins the credential destination to the canonical base URL. The implementation direction is appropriately narrow and the non-canonical-host regression protects the credential boundary.

Please rebase the branch onto current dev, run the focused quota tests/typecheck/privacy scan, resolve any exact-head review findings, and tick the readiness checklist before marking it ready. I will review the resulting exact head; this draft is not pre-approved for merge yet.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 27 / 80

draft 이고 readiness 4칸이 비어 있습니다. #1924 는 quota 디스패치가 name === "opencode-go" 라서 같은 canonical URL 의 sibling 이 패널에 안 나오던 문제입니다. 한 줄을 isCanonicalOpenCodeGoBaseUrl(provider.baseUrl) 로 바꿉니다. Kimi / A6api / CommandCode 와 같은 게이트입니다. 같은 diff 에 package.json 2.24.22.25.0 이 있습니다.

fetchOpenCodeGoQuota 가 이미 canonical URL 을 다시 보고 Bearer 를 보냅니다. 이름 검사는 중복이면서 좁았습니다. 이제 이름이 달라도 같은 host 면 프로브합니다. 이름이 opencode-go 이고 baseUrl 이 다른 제공자는 프로브하지 않습니다. 테스트가 그 두 축을 봅니다. opencode-go-2 가 리포트에 같이 나오고, api.example.com 에서는 opencode.ai 로 fetch 가 없습니다.

canonical URL 을 가리키는 모든 key-auth 제공자가 Go usage 엔드포인트를 칩니다. 구독이 아닌 호스트 재사용이면 불필요한 프로브가 생깁니다. 이웃 프로바이더와 같은 트레이드오프입니다. authMode 기본 "key" 는 그대로입니다. 본문은 로컬 bun 을 못 돌렸습니다.

해결방안: package.json 버전 hunk 를 빼십시오. draft 체크리스트를 채우십시오. isCanonicalOpenCodeGoBaseUrlundefined baseUrl 에서 false 인지만 기존 헬퍼와 맞는지 확인하십시오. 동작 자체는 한 줄이라 그 두 가지만 정리되면 닫힙니다.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun

Copy link
Copy Markdown
Owner

Thank you @yzxcj797 — absorbed as #2164, and the diagnosis is yours. Gating quota dispatch on the literal name opencode-go is exactly why the sibling rows in #1924 had no quota panel, and swapping that for the destination is the right move.

One correction. Your predicate compares the base URL but does not check the adapter, so a row pointed at https://opencode.ai/zen/go/v1 through a different adapter would still be probed — a different protocol to the same host, and not the provider whose quota shape we parse.

The repository already has the predicate for this: registryEntryForProviderDestination matches on normalized endpoint plus adapter plus key auth, and is already how renamed fixed-key rows are identified elsewhere (opencode-zen-rate-limit.ts, derive.ts). #2164 uses that.

Worth recording what was considered and rejected: providerMatchesRegistryTransport("opencode-go", provider) would have needed preserveCustomDestination: true on the registry entry, which also changes routing for a same-named custom row. That might be worth doing on its own merits — it is not something a quota fix should do as a side effect.

Your branch was marked CONFLICTING only because of an inherited package.json bump; quota.ts and its test had no real conflict against dev. Same note as on your #2082: cutting from dev rather than the release line avoids it.

Your sibling-row test is carried over and it fails on unpatched dev. Full suite 13562 pass / 0 fail. Closing in favor of #2164, credited to you.

yansigit pushed a commit to yansigit/opencodex that referenced this pull request Aug 20, 2026
…amed

A multi-account setup points several provider rows at the same OpenCode
Go endpoint under names the registry has never heard of --
opencode-go-2 through -5. Quota dispatch gated on the literal name
"opencode-go", so those rows had no dashboard quota panel and no report
in `ocx provider quota --refresh --json` even though each one holds a
working key for the same upstream (lidge-jun#1924).

Identity is now answered by registryEntryForProviderDestination, the
predicate this repository already uses for renamed fixed-key rows: it
matches on normalized endpoint plus adapter plus key auth. A bare URL
comparison would have been enough for the reported symptom but would
also probe a row that points at that host through a different adapter,
which speaks a different protocol and is not the provider whose quota
shape we parse.

The defensive canonical-URL check inside fetchOpenCodeGoQuota stays.
Whether an API key may be sent to a host must not depend on the dispatch
gate above it being correct.

Absorbed from lidge-jun#2027 by @yzxcj797.
yansigit pushed a commit to yansigit/opencodex that referenced this pull request Aug 20, 2026
…amed

A multi-account setup points several provider rows at the same OpenCode
Go endpoint under names the registry has never heard of --
opencode-go-2 through -5. Quota dispatch gated on the literal name
"opencode-go", so those rows had no dashboard quota panel and no report
in `ocx provider quota --refresh --json` even though each one holds a
working key for the same upstream (lidge-jun#1924).

Identity is now answered by registryEntryForProviderDestination, the
predicate this repository already uses for renamed fixed-key rows: it
matches on normalized endpoint plus adapter plus key auth. A bare URL
comparison would have been enough for the reported symptom but would
also probe a row that points at that host through a different adapter,
which speaks a different protocol and is not the provider whose quota
shape we parse.

The defensive canonical-URL check inside fetchOpenCodeGoQuota stays.
Whether an API key may be sent to a host must not depend on the dispatch
gate above it being correct.

Absorbed from lidge-jun#2027 by @yzxcj797.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quota probe for OpenCode Go is gated on the literal provider name, so additional Go providers (multi-account setups) show no quota

3 participants