Skip to content

fix(rate-limits): read native Antigravity usage - #20797

Open
abti-ai wants to merge 1 commit into
stablyai:mainfrom
abti-ai:fix/antigravity-native-usage
Open

abti-ai wants to merge 1 commit into
stablyai:mainfrom
abti-ai:fix/antigravity-native-usage

Conversation

@abti-ai

@abti-ai abti-ai commented Sep 15, 2026

Copy link
Copy Markdown

Summary

  • Read Antigravity quota data from native agy --print /usage --output-format json instead of mirroring Gemini quota state.
  • Preserve Antigravity's independent Gemini and Claude/GPT quota groups and native 5h/weekly windows.
  • Integrate those buckets with Orca's existing Used/Remaining and compact/detailed usage UI patterns.

Behavior

  • Compact mode selects the tightest window independently per Antigravity group using the existing consumption-based rule; ties preserve first-in-order/session-first behavior.
  • Compact Usage shows bare percentage + reset countdown.
  • Compact status/menu shows % used / % left + reset countdown.
  • Detailed Usage keeps short 5h / wk; provider flyouts use localized Session / Weekly.
  • Unknown future windows preserve their source label or duration fallback.

Implementation

  • Uses execFileCaptureToTermination through Orca's shared runProcess / resolveSpawn path with fixed argv, no shell interpolation, AbortSignal handling, bounded output/deadline, and process-tree termination.
  • Antigravity refresh is independent from Gemini state/OAuth.
  • Shared tightest-window selection helper avoids renderer import cycles.

Validation

  • Focused Antigravity/status-bar tests: 107/107 passed after the final squash.
  • Typecheck, changed-code quality, formatting, lint/static analysis, localization, Electron/Vite build, Windows package, and all Node 24 test shards passed on the finalized feature revision.

@coderabbitai

coderabbitai Bot commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 5f524a7d-36e0-4b64-874c-1524267c8689

📥 Commits

Reviewing files that changed from the base of the PR and between 3ac77234b6bee157ebbb739aa30df6e74ba148ea and 03bce76.

📒 Files selected for processing (6)
  • src/main/rate-limits/antigravity-usage-fetcher.test.ts
  • src/main/rate-limits/antigravity-usage-fetcher.ts
  • src/renderer/src/components/status-bar/UsageRosterPanel.test.tsx
  • src/renderer/src/components/status-bar/UsageRosterPanel.tsx
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/renderer/src/components/status-bar/tooltip.tsx

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The change adds direct Antigravity usage fetching through the agy CLI. The refresh service now stores Antigravity results independently from Gemini. Shared rate-limit types include provider group metadata. Status-bar segments and tooltips render grouped Antigravity windows, native labels, usage percentages, and reset durations. Antigravity visibility now depends on its own configuration. Tests cover fetching, service integration, rendering, and visibility.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 03bce

This change switches Antigravity usage reporting from mirroring Gemini quota data to reading native quota data directly from the agy CLI, with independent refresh, grouped status-bar displays, and fallback handling for stale or failed reads. Review confirms that error and stale-data states remain visibly indicated to users rather than silently showing outdated data as current, and previously identified ordering and validation concerns have been addressed with test coverage. No unresolved correctness, stability, or security concerns were found in the reviewed scope, so the change appears ready to merge.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the implementation, behavior, motivation, and validation, but it omits most required template sections. It does not include an issue link, visual proof or an explicit N/A expl… Update the description to use the repository template. Add a valid Fixes #... issue reference, provide before-and-after visual proof or write N/A with a reason, complete the Testing checklist with platform details, complete AI Disclosur…
Docstring Coverage ⚠️ Warning Docstring coverage is 10.71% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 28 functions across 18 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: reading native Antigravity usage data.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the implementation, behavior, motivation, and validation, but it omits most required template sections. It does not include an issue link, visual proof or an explicit N/A explanation, testing checkboxes and platform details, AI disclosure, review section, boundary confirmation, notes, or the checklist.

Resolution

Update the description to use the repository template. Add a valid Fixes #... issue reference, provide before-and-after visual proof or write N/A with a reason, complete the Testing checklist with platform details, complete AI Disclosure, Review, Agent skill upstream boundary, Notes, and Checklist sections.

  • Fix all pre-merge checks with AI

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.

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: e3792a05-6083-42e2-923f-e91208f7bad9

📥 Commits

Reviewing files that changed from the base of the PR and between c9ae17f and 3ac77234b6bee157ebbb739aa30df6e74ba148ea.

📒 Files selected for processing (20)
  • src/main/rate-limits/antigravity-usage-fetcher.test.ts
  • src/main/rate-limits/antigravity-usage-fetcher.ts
  • src/main/rate-limits/antigravity-usage-mirror.test.ts
  • src/main/rate-limits/antigravity-usage-mirror.ts
  • src/main/rate-limits/service-antigravity-usage.test.ts
  • src/main/rate-limits/service/service-full-cycle-application.ts
  • src/main/rate-limits/service/service-full-cycle-preparation.ts
  • src/renderer/src/components/status-bar/StatusBarProviderSegment.test.tsx
  • src/renderer/src/components/status-bar/StatusBarProviderSegment.tsx
  • src/renderer/src/components/status-bar/UsageRosterPanel.test.tsx
  • src/renderer/src/components/status-bar/UsageRosterPanel.tsx
  • src/renderer/src/components/status-bar/antigravity-compact-metrics.tsx
  • src/renderer/src/components/status-bar/antigravity-usage-format.ts
  • src/renderer/src/components/status-bar/status-bar-provider-visibility.test.ts
  • src/renderer/src/components/status-bar/status-bar-provider-visibility.ts
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/renderer/src/components/status-bar/usage-section-selection.ts
  • src/renderer/src/components/status-bar/use-status-bar-controller.ts
  • src/shared/rate-limit-types.ts
💤 Files with no reviewable changes (2)
  • src/main/rate-limits/antigravity-usage-mirror.ts
  • src/main/rate-limits/antigravity-usage-mirror.test.ts

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

Comment thread src/renderer/src/components/status-bar/UsageRosterPanel.tsx Outdated

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

ℹ️ No critical issues — one real defect in the timeout classification, and the test that should catch it asserts a shape production never produces.

Reviewed changes

  • Native Antigravity fetcher — new fetchAntigravityRateLimits shells out to agy --print /usage --output-format json via execFileCaptureToTermination (fixed argv, no shell, AbortSignal, 10s deadline, 1 MiB cap), parses provider groups/buckets, and classifies failures.
  • Mirror removed — antigravity-usage-mirror.ts and its tests are deleted; Antigravity becomes its own Promise.allSettled slot, applied through applyStalePolicy so buckets participate in stale retention.
  • Visibility decoupled from Gemini — status-bar-provider-visibility.ts now treats antigravityUsageConfigured (checked status item + detected agy CLI) as the durable signal, no longer requiring the Gemini OAuth opt-in.
  • Renderer — grouped verbose/compact Antigravity rendering, per-group tightest-window selection (session-first ties), native 5h/wk/source-window labels, and a shared usage-section-selection helper.
  • Shared types — optional RateLimitWindow.windowLabel and RateLimitBucket.id/groupName/groupDescription (additive, wire-safe).

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/main/rate-limits/antigravity-usage-fetcher.ts Outdated
@abti-ai
abti-ai force-pushed the fix/antigravity-native-usage branch from 3ac7723 to 03bce76 Compare September 15, 2026 07:35

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

✅ No new issues found.

Reviewed changes

  • Timeout classification fixed — classifyAgyFailure now also matches killed === true / signal === 'SIGTERM', so a real deadline kill from execFileCaptureToTermination reaches the timeout-specific copy instead of the generic read-failure message. The regression test now rejects with the production shape ({ code: null, killed: true, signal: 'SIGTERM' }), matching the established git-username.ts#isExecTimeoutError predicate. Cancellation stays distinct: aborts are rethrown before classification.
  • Bucket sorting extracted and applied uniformly — UsageRosterPanel verbose rendering and the tooltip.tsx provider flyout now route Antigravity groups through sortAntigravityBuckets instead of ad-hoc .sort((a, b) => windowMinutes - …), so unknown windows (windowMinutes <= 0, e.g. a future daily window) render after known 5h/weekly windows, with duration-ascending then name tie-breaks. Non-Antigravity ordering is unchanged.
  • Coverage added — new tests assert the unknown-window-after-known ordering in UsageRosterPanel detailed mode, the Session < Weekly < daily ordering plus native labels in the provider flyout, and non-Antigravity ordering preservation.

Verified against runProcess / execFileCaptureToTermination that a deadline kill resolves timedOut: true with signal: 'SIGTERM' and code: null, so the new predicate is reachable. Focused tests pass (3 files, 71 tests).

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@abruption

Copy link
Copy Markdown
Contributor

I reproduced a concrete version-compatibility issue with the exact agy -p /usage --output-format json invocation on Agy 1.1.10: it starts an ordinary agent turn, reports token usage, and returns model-generated guidance rather than a structured quota report.

Tested on macOS arm64 using official release binaries, with archive SHA-256 verification, automatic updates disabled, and executable versions/hashes checked unchanged before and after each run:

Agy version Result Turns Reported total tokens
1.1.10 Model response; no command.data.groups; nonempty conversation ID 1 3,181
1.1.11 Four native quota buckets; empty conversation ID 0 0
1.1.21 Four native quota buckets; empty conversation ID 0 0
1.1.27 Four native quota buckets; empty conversation ID 0 0
1.2.4 baseline Four native quota buckets; empty conversation ID 0 0

The 1.1.10 response reported input_tokens: 2759, output_tokens: 422, thinking_tokens: 249, cache_read_tokens: 16294, and total_tokens: 3181, with status: SUCCESS and num_turns: 1. I ran this old-version probe only once.

This matches the official 1.1.11 release notes, which introduce direct handling of read-only slash commands in print mode without an agent turn or quota spend. The supported versions returned matching remaining fractions for all four buckets after the old-version probe; reset timestamps for the unused Claude/GPT pool advanced, so the complete outputs were not identical.

Could we gate this path on Agy >=1.1.11 before invoking /usage, return an actionable unsupported-version result for older versions, and add a regression proving that 1.1.10 never receives the usage invocation? Rejecting missing buckets after execution is too late to prevent inference or token spend during recurring refreshes.

This was a standalone CLI test with a 60-second harness deadline, not an Orca E2E run. The PR's 10-second timeout may stop the process sooner, but it does not establish that an unsupported CLI cannot start an agent turn before being stopped. This concern is specific to older versions; the tested supported versions reported zero turns and tokens.

@nwparker

Copy link
Copy Markdown
Contributor

I exercised the fetcher from this PR's current diff (head 03bce76ef0dca7f7309f1598953a4f45a92c595d) against the installed macOS agy, plus replayed its actual output through parseAgyUsageResponse. Both checks passed.

This machine uses an API-key configuration. The real command agy --print=/usage --output-format=json --print-timeout=30s exits 0 with:

{"conversation_id":"","status":"SUCCESS","response":"","duration_seconds":0,"num_turns":0,"usage":{"input_tokens":0,"output_tokens":0,"thinking_tokens":0,"cache_read_tokens":0,"total_tokens":0},"command":{"name":"usage","data":{"groups":[]}}}

Your fetcher correctly reports status: unavailable, no buckets, and no session/weekly percentages. ELI5: the command worked but supplied no quota numbers; that must not become “0% used” or Gemini's quota. This path works without reading Gemini's quota.

Scope of this verification: the candidate fetcher and empty-group parser path, run from the current Orca worktree. I have not verified populated OAuth quota groups or the full PR's rendered quota UI, so this is evidence for this edge case, not a merge approval. Text generation on this machine currently fails 401 ACCESS_TOKEN_TYPE_UNSUPPORTED, and I am checking whether an existing authenticated profile is available for the remaining live cases.

@nwparker

Copy link
Copy Markdown
Contributor

I took over the native quota implementation in draft #21654, preserving credit for #20797 and adding the pre-invocation version guard requested in its review. Agy 1.1.10, the 1.1.11 prerelease, and unknown version output never receive /usage; supported versions are checked on each refresh.

ELI5: Orca asks Antigravity for its own quota numbers instead of copying Gemini's meter. No returned numbers means “usage unavailable,” not “0% used.”

Verified the guarded production fetcher and actual Refresh → Antigravity usage panel against installed agy 1.2.7 on macOS. This machine returns empty quota groups. The PR includes that live screenshot and a separately labeled populated renderer fixture. 201 focused tests, full typecheck, and changed-code quality pass. Live populated OAuth quota, Windows/WSL/SSH, and paired-runtime behavior remain unverified; no auth changes or repeated old-version inference probe were made. The account login/card work remains open.

@nwparker

Copy link
Copy Markdown
Contributor

Review verdict: Do not merge as-is; superseded by #21654 → #21678. The branch overlaps the maintained quota migration but lacks the current version gate and configured executable/visibility contract. Keep its ideas only as historical context.

nwparker added a commit that referenced this pull request Sep 21, 2026
…21654)

Adopts native usage parsing and display from PR #20797, adding a pre-invocation version guard and legacy group labels.

Co-authored-by: Abhishek Tiwari <69499+abti@users.noreply.github.com>
@werlang

werlang commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Rebased this onto current main and added the missing piece from @abruption's review: a pre-check that gates /usage on agy >= 1.1.11 (fails closed on unreadable versions), with a regression proving 1.1.10 never receives the usage argv. Opened as #22055 with your commit preserved (authorship intact) — happy to close mine if you'd rather pick up the gate here.

@nwparker

Copy link
Copy Markdown
Contributor

sure can close, I'll pick it up

This branch has not been deployed

No deployments
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