Skip to content

feat(quota): per-account Gem/Cla quota for Google Antigravity (#1082) - #3213

Merged
lidge-jun merged 1 commit into
devfrom
codex/antigravity-account-quota-1082
Sep 1, 2026
Merged

feat(quota): per-account Gem/Cla quota for Google Antigravity (#1082)#3213
lidge-jun merged 1 commit into
devfrom
codex/antigravity-account-quota-1082

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Per-account Gem / Cla quota rows for Google Antigravity ([Feature]: add per-account Gem/Cla quota display for Google Antigravity #1082). supportsPerAccountQuota now includes google-antigravity; each stored account is probed with its own bearer (same refresh hygiene as the Anthropic probe: fresh stored access is used as-is, background local-cli slots never trigger a CLI-adopting refresh) and its own Cloud Code Assist project id. The fetchAvailableModelsGem/Cla classification is extracted into one function shared by the provider-level and per-account probes, so the semantics are identical.
  • Closes both structural blockers that stalled contributor PR feat(quota): add per-account Gem/Cla quota probing for Google Antigravity (#1082) #2123 across three review rounds, by construction rather than by adding a cache dimension:
    • The per-account probe always targets Google's Cloud Code Assist host (https://daily-cloudcode-pa.googleapis.com), not the configurable baseUrl. A custom base URL is a routing choice for requests, not a second source of Google's accounting for a stored credential, so the existing provider\0accountId cache/in-flight identity and generation reconciliation stay exact across config changes.
    • Every stored bearer goes out through providerOutboundPost (resolved/pinned transport, manual redirect handling); a blocked or redirecting destination yields unavailable and no token is sent.
  • Missing project id, redirect, non-2xx, or transport rejection → unavailable (last-good preserved), never 0%. The provider-level probe is unchanged.
  • No UI or route change: /api/oauth/accounts?quota=1 and ocx account list --quota already project customWindows per account. Docs updated in reference/cli/providers-accounts.md.

Closes #1082

Verification

  • bun x tsc --noEmit clean; bun run privacy:scan passed.
  • bun test tests/provider-account-quota.test.ts tests/provider-quota.test.ts tests/oauth-store-multi.test.ts tests/core-lab-boundary.test.ts → 166 pass / 0 fail. New: two accounts probed with distinct bearer + project id on the fixed host via the injected pinned transport (plain fetch throws if touched), distinct Gem/Cla percentages and reset times per row; a rejected destination sends no bearer and yields unavailable; a redirecting upstream yields unavailable and an account without a project id makes no request.
  • Full suite runs in CI on this PR.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • New Features
    • Added per-account Gem and Cla quota visibility for Google Antigravity accounts.
    • Quota results now reflect each account’s stored project and credentials.
    • Unavailable status is shown when project details are missing, requests fail, or redirects occur.
  • Documentation
    • Updated provider account quota documentation with Google Antigravity requirements, quota windows, and unavailable conditions.
  • Tests
    • Added coverage for account-specific credentials, project IDs, secure requests, redirects, and missing credentials.

supportsPerAccountQuota now includes google-antigravity. Each stored
account is probed with its own bearer (same refresh hygiene as
Anthropic) and its own Cloud Code Assist project id, and the existing
Gem/Cla classification is shared with the provider-level probe. The
per-account probe always targets Google's Cloud Code Assist host over
the pinned provider-outbound transport, so a configured baseUrl cannot
redirect stored bearers and the provider+account cache identity stays
exact across config changes; redirects, blocked destinations, and a
missing project id yield unavailable, never 0%. No UI change: the
account list already projects customWindows.

Supersedes PR #2123 (design credit: account loop and token hygiene).
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 1, 2026 20:16
@lidge-jun
lidge-jun merged commit ef7b3c9 into dev Sep 1, 2026
6 of 7 checks passed
@lidge-jun
lidge-jun deleted the codex/antigravity-account-quota-1082 branch September 1, 2026 20:17
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T20:20:54.017725Z fd55b6f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Team

Run ID: 4cfbb319-2c9e-42b0-9de8-a52f738421f1

📥 Commits

Reviewing files that changed from the base of the PR and between d975fea and fd55b6f.

📒 Files selected for processing (5)
  • devlog/_plan/260902_nonbug_adoption_backlog/110_wp11_antigravity_account_quota.md
  • devlog/_plan/260902_nonbug_adoption_backlog/111_wp11_audit_r1_synthesis.md
  • docs-site/src/content/docs/reference/cli/providers-accounts.md
  • src/providers/quota.ts
  • tests/provider-account-quota.test.ts

📝 Walkthrough

Walkthrough

Google Antigravity now supports per-account Gem and Cla quota probing. Each account uses its own access token and project ID through the pinned Google transport. Missing projects, redirects, and probe failures produce unavailable results. Documentation and focused tests cover the behavior.

Changes

Google Antigravity per-account quota

Layer / File(s) Summary
Quota capability and account dispatch
src/providers/quota.ts, devlog/_plan/.../110_wp11_antigravity_account_quota.md, devlog/_plan/.../111_wp11_audit_r1_synthesis.md, docs-site/src/content/docs/reference/cli/providers-accounts.md
google-antigravity is enabled for per-account quota. The account path uses each stored credential's token and projectId. Planning records and provider documentation describe the fixed endpoint and unavailable conditions.
Pinned Antigravity quota probe
src/providers/quota.ts
The probe posts to Google's fixed Cloud Code Assist host through providerOutboundPost. Redirects, transport errors, non-2xx responses, and unparseable data return unavailable results. Shared parsing produces Gem and Cla quota windows for both provider-level and account-level probes.
Account isolation and failure validation
tests/provider-account-quota.test.ts
Tests verify separate bearer/project pairs for two accounts, pinned transport usage, private-destination rejection, redirect handling, and skipping accounts without a project ID.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: ingwannu

Sequence Diagram(s)

sequenceDiagram
  participant AccountQuota
  participant fetchAntigravityUsageQuota
  participant providerOutboundPost
  participant GoogleCloudCodeAssist
  AccountQuota->>fetchAntigravityUsageQuota: accessToken and projectId
  fetchAntigravityUsageQuota->>providerOutboundPost: POST fixed Google endpoint
  providerOutboundPost->>GoogleCloudCodeAssist: pinned request with bearer and project
  GoogleCloudCodeAssist-->>providerOutboundPost: quota response or redirect
  providerOutboundPost-->>fetchAntigravityUsageQuota: response
  fetchAntigravityUsageQuota-->>AccountQuota: Gem and Cla quota or unavailable
Loading
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/antigravity-account-quota-1082

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd55b6f841

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/providers/quota.ts
if (!response.ok) return null;
const customWindows = antigravityWindowsFromModels(asRecord(await readQuotaJson(response)));
if (customWindows.length === 0) return null;
return { customWindows, updatedAt: Date.now() };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Rank Antigravity accounts by the requested family

After a dashboard or --quota probe populates this cache for a multi-account Antigravity provider, generic OAuth pre-dispatch ranking in src/oauth/account-quota-rank.ts computes headroom from the maximum of every customWindows percentage without knowing the requested model. Because Gem and Cla are mutually exclusive model-family limits rather than concurrent account-wide limits, an account with exhausted Gemini quota but ample Claude quota is incorrectly deprioritized for Claude requests, potentially selecting an account whose Claude allowance is exhausted and causing avoidable 429s; make the ranking select the window for the requested Antigravity model family, or keep these family-specific rows out of generic account-wide ranking.

Useful? React with 👍 / 👎.

Comment thread src/providers/quota.ts
// Per-account Gem/Cla windows (#1082). The project id is part of the stored
// credential; without it the probe cannot be made, and that is "unavailable",
// never 0%.
const projectId = getAccountCredential(provider, accountId)?.projectId;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the token and project ID in one credential snapshot

If the same Antigravity account is refreshed, reauthenticated, or re-imported after getTokenForAccountQuotaProbe resolves but before this second store read, the request can pair one credential generation's bearer with another generation's projectId. Google may reject the probe, or a token authorized for both projects may cache the wrong quota under this account for the TTL; return the bearer and project ID together from a full account-scoped snapshot while preserving the existing background-local-cli refresh guard. This token/credential pairing path is a repository-defined security boundary.

AGENTS.md reference: src/AGENTS.md:L20-L20

Useful? React with 👍 / 👎.


Google Antigravity rows carry the same `Gem` / `Cla` windows as the provider-level quota, computed
from that account's own credential and Cloud Code Assist project id. The per-account probe always
talks to Google's Cloud Code Assist host through the pinned outbound transport, regardless of a

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Qualify the transport pinning claim in proxy mode

When HTTP_PROXY/HTTPS_PROXY is configured and this public host does not match NO_PROXY, providerOutboundRequest deliberately sends the request through globalThis.fetch (src/lib/provider-outbound.ts:170-172) and warns that the final route and peer cannot be pinned locally. Therefore this unconditional user-facing statement is false in a supported environment; document that direct connections are resolved and pinned while proxy-mode connections preserve the configured proxy routing and its weaker peer guarantee.

AGENTS.md reference: docs-site/AGENTS.md:L7-L10

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant