Skip to content

Add Antigravity to the agents panel, with the sign-in kept by any harness - #14704

Closed
ivanvan08 wants to merge 11 commits into
omacom:quattrofrom
ivanvan08:agents-antigravity-any-harness
Closed

ivanvan08 wants to merge 11 commits into
omacom:quattrofrom
ivanvan08:agents-antigravity-any-harness

Conversation

@ivanvan08

@ivanvan08 ivanvan08 commented Oct 9, 2026 •

Copy link
Copy Markdown

Adds the Google Antigravity collector to the agents panel, split out of #14039 so it can land on its own, rebased onto the current quattro.

The collector work itself is steph4n's (#11989), keyed to agy and trimmed of its invented limits by @dhh, and it carries steph4n's #14098 guard for Go's year-0001 timestamps. The other collectors #14039 brings in (Hermes, Z.ai, Ollama Cloud, MiniMax, OpenRouter, DeepSeek) are deliberately out of scope here.

Sign-in

Antigravity's plan and 5-hour and weekly limits come from Google's Cloud Code API (loadCodeAssist and retrieveUserQuotaSummary), and until now only a signed-in agy could reach them. Every harness that runs models on an Antigravity subscription signs in with the same Google client, so the collector now reads the sign-in wherever it is:

  • agy's Secret Service keyring entry, or its antigravity-oauth-token file when there is no keyring
  • omp's agent.db
  • pi's auth.json (both under PI_CODING_AGENT_DIR when it is set)
  • opencode's google sign-in, only when the Antigravity plugin's antigravity-accounts.json is there

Of those, the token refreshed most recently is asked first, and one Google refuses (401/403) gives way to the next. Tokens are only ever read: nothing is refreshed into, or written back to, another harness' store. A lapsed token keeps showing the last limits, marked stale, until the harness that owns the sign-in runs again, the same as agy and Grok today.

omp is asked through omp usage --json --provider google-antigravity, which refreshes its own sign-in on the way; its stored token then only names the plan.

The panel's Sign-in required link runs omarchy-agent-account-add, which knows Claude, Codex, and Grok only, so an Antigravity record names its sign-in state in words and carries the instruction in authHelpText, which the panel prints where that link would have been. Hermes reaches Antigravity only through plugins that run agy, so its usage is already agy's and is not counted twice.

Local stats

Antigravity driven from another harness left the panel's local stats empty. Answers that ran on pi, omp, or OpenClaw's google-antigravity provider, and opencode's antigravity- models, now count as prompts with their tokens, the way the Codex collector already counts pi and opencode sessions. A forked session's copy of an answer counts once. agy's own history, conversation summaries, and transcripts are unchanged.

Tests

  • test/shell.d/agent-usage-agy-harness-test.sh (new) covers limits and stats from a harness sign-in, omp's CLI, a refused token falling through to the next, a lapsed token keeping its limits, another Google account's kept limits never standing in, opencode only counting with its plugin, and one answer in a forked session counting once.
  • agent-usage-agy-limits-test.sh, agent-usage-agy-scanner-test.sh, agent-usage-agy-timestamps-test.sh, agent-usage-update-test.sh, and agents-panel-test.sh pass.

Checked on a clean Omarchy 4.0.4 VM, no agy installed and only a pi sign-in in place: the panel shows Antigravity with its Pro plan and its Session, Weekly, and Claude/GPT meters.
The token counting was checked against real omp and pi sessions instead: the record's prompts, sessions, active days, per-day, and per-model totals all agree with a separate recount over those sessions.

@greptile-apps

greptile-apps Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issue remains.

Summary

Adds Antigravity plans, limits, and local usage to the agents panel. Sign-ins can come from agy, omp, pi, or opencode.

  • Since the last review, only the default endpoint constant was renamed. Its uses were updated together.
  • All four earlier findings are addressed: saved limits match an account, fallback limits survive failed checks, different accounts' plans and limits stay separate, and bad transcript token values no longer stop collection.
  • No new actionable issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A["agy, omp, pi, opencode sign-ins"] --> B["Try newest usable sign-in"]
  B --> C["Google API or omp usage"]
  C --> D["Account-matched plan and limits"]
  E["Native and harness history"] --> F["Local usage totals"]
  D --> G["Antigravity JSON record"]
  F --> G
  G --> H["Agents panel"]
Loading

Reviews (6) · Last reviewed commit: "Name the fallback destination for what i..." · Reviewed by Greptile

Comment thread bin/omarchy-agent-usage-agy Outdated
Comment thread bin/omarchy-agent-usage-agy Outdated
@ivanvan08

Copy link
Copy Markdown
Author

Both findings are addressed in fe4d504:

Another account's limits appear — the cache now records an account identity: the email when the harness keeps one, otherwise a digest of that harness' own token (the refresh token when it has one, else the access token, which changes with the account or a refresh). Nothing is reused unless the identity matches, so an unmatched cache is dropped instead of passed off as the new account's. opencode, which records no email, is covered by that digest. agent-usage-agy-harness-test.sh now replaces an opencode sign-in and asserts its predecessor's limits are gone.

Bad tokens stop updates — the native transcript counts go through the same number() guard as the harness records, so one row with a non-numeric count costs only its own value. agent-usage-agy-scanner-test.sh appends a transcript step with "prompt_token_count":"unknown" and a null count, then asserts the record still publishes the rest.

Comment thread bin/omarchy-agent-usage-agy Outdated
@ivanvan08

ivanvan08 commented Oct 9, 2026 •

Copy link
Copy Markdown
Author

Two more in da0797b, plus a sweep of the same area:

The plan label followed the wrong account. The label kept from an earlier check describes the account that earned it, but a probe for another account can answer with limits and no plan, and it was standing in for that account. It now stays only for its own account's answer.

Saved fallback limits disappeared (the review's finding). Limits were kept only when the first sign-in matched the account in the cache, so the run after a refused newer sign-in dropped the limits of an account that was still signed in. They are now kept while any sign-in for that account is here, and the short reuse window applies only to the account the saved answer describes.

The section offered a sign-in it cannot do. Panel.qml reads usageStatusText "Waiting for auth" and "Sign-in expired" as "offer to sign in here", and its link runs omarchy-agent-account-add --reauth :primary agy — a provider that script rejects, and which, when the machine's default agent is Claude, Codex, or Grok, would re-sign in that agent instead. Antigravity is signed in outside the panel, so its record now says No Antigravity sign-in or Antigravity sign-in expired and leaves the instruction to authHelpText, which the panel prints where the link would have been. Checked in a VM: the section shows "The Antigravity sign-in omp keeps expired. Start omp to refresh it." with the last limits below it, and no link.

Smaller: a day evidenced only by a conversation transcript now counts as an active day, as every other source does, and a damaged cache entry is dropped rather than raised over.

Each behaviour above is pinned by a test that fails when the guard is removed (checked by reverting each one in turn).

Comment thread bin/omarchy-agent-usage-agy
@jandrusk

Copy link
Copy Markdown

Thanks for splitting this out. Just so it's on one page: there are now several open Antigravity collectors, #14039 (the full batch), this one, #14884 and #15056. It's probably worth deciding on one before anyone does a detailed review.

One small thing in bin/omarchy-agent-usage-agy: post() sends the bearer token to whatever CLOUD_CODE_URL says. It's only the user's own environment, but since this script now also picks up tokens from omp/pi/opencode, I'd keep the destination fixed (or at least require https://):

base = (os.environ.get("CLOUD_CODE_URL") or "https://daily-cloudcode-pa.googleapis.com").rstrip("/")
if not base.startswith("https://"):
  base = "https://daily-cloudcode-pa.googleapis.com"

steph4n-gh and others added 11 commits October 14, 2026 13:44
Add the omarchy-agent-usage-antigravity collector to monitor Google
Antigravity usage alongside the other agents in the agents bar panel.

Authoritative subscription tier and quota limits (rolling 5-hour session,
weekly limits, and scoped 3P model allowances) are probed from the Google
Cloud Code API via Secret Service keyring credentials with rolling local
history estimation as fallback.
The record shares the id omarchy-default-agent and omarchy-agent use for
the CLI. Limits now come only from Google's quota answer, kept from the
last good check and marked stale (limitsStale, limitsFetchedAt) after a
failed one, instead of being estimated from prompt counts. The plan is
no longer assumed to be Pro, and transcript steps without reported usage
no longer get estimated tokens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without agy, the agents panel had no way to show an Antigravity plan or
limits even when another harness was signed in to it. Those harnesses
sign in with the same Google client agy uses, so their access tokens
reach the same Cloud Code quota API.

The collector now also reads agy's file fallback, omp's agent.db, pi's
auth.json, and opencode's google sign-in when the Antigravity plugin's
accounts file is present. The most recently refreshed token is asked
first; one Google refuses gives way to the next. Tokens are only read,
never refreshed or written back. Kept limits are tied to the Google
account they came from.
Antigravity run from pi, omp, OpenClaw, or opencode's Antigravity plugin
left the panel's local stats empty without agy. Their answers on the
google-antigravity provider (or opencode's antigravity- models) now count
as prompts with their tokens, the way the Codex collector counts pi and
opencode sessions. A forked session's copy of an answer counts once.
Hermes reaches Antigravity only through plugins that run agy, so its
usage is already agy's.

omp's limits come from `omp usage`, which refreshes omp's own sign-in,
so they stay live after the token in its database lapses; that token is
then used only for the plan. When omp cannot answer, its token is tried
like any other.
Kept limits were reused whenever the emails were absent, so a sign-in
swapped behind the collector's back could show the previous account's
plan and limits, marked live for the first minute. The cache now records
an account identity: the email when the harness keeps one, else a digest
of that harness' own token. Nothing is reused unless the identity
matches, so an unmatched cache goes rather than pass for another account.

A transcript step whose token counts are not numbers took the whole
collector down with it, publishing nothing. Those counts now go through
the same guard as the harness records, so only the bad value is lost.
Sweep of what the panel gets from an Antigravity record:

- The plan label kept from an earlier check describes the account that
  earned it. A probe answering for another account can report limits
  without a plan, and that label was standing in for it.
- Limits were kept only when the *first* sign-in matched the account in
  the cache, so the run after a refused newer sign-in dropped the limits
  of an account that was still signed in; they are now kept while any
  sign-in for that account is here, and the short reuse window only
  applies to the account the saved answer describes.

The panel reads "Waiting for auth" and "Sign-in expired" as "offer to
sign in here", and that link runs omarchy-agent-account-add, which knows
Claude, Codex, and Grok only: Antigravity's section offered a link that
would fail, or re-sign in another agent, instead of saying what to do.
Its record now names the state in words and leaves the instruction to
authHelpText, which the panel prints where the link would have been.

Two smaller ones: a day evidenced only by a conversation transcript now
counts as an active day, as every other source does, and a damaged cache
entry is dropped rather than raised over.
A newer sign-in that answers with a plan but no quota windows for it left
the kept account's meters beside that plan, as one subscription. Limits
kept from an earlier check now stand in only for the account that earned
them, or for a run in which nothing answered, and the plan that answered
is the plan that shows.
The bearer token this collector sends is no longer only the one agy
keeps: it can now come from omp's, pi's, or opencode's store, so a
destination named in the environment is taken only when it is an https
one, and anything else falls back to Google's own endpoint. The https
override itself stays, for a mirror someone sets deliberately.
The sibling collector sets the idiom: API_BASE_URL beside an environment
FIREWORKS_API_BASE_URL. DEFAULT_CLOUD_CODE_URL beside CLOUD_CODE_URL reads
as the default rather than as the variable itself.
@ivanvan08

Copy link
Copy Markdown
Author

Superseded by #14040, which is now merged into quattro and carries this work, credited in its table. The two pieces that were still missing after that merge are carried over as #16507 (omp's Antigravity sign-in under PI_CODING_AGENT_DIR) and #16508 (ollama's key from omp's agent.db), both against quattro. Thanks!

@ivanvan08 ivanvan08 closed this Oct 24, 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.

4 participants