Skip to content

feat(antigravity): add Antigravity CLI OAuth provider - #29385

Closed
longbowlu wants to merge 1 commit into
NousResearch:mainfrom
longbowlu:feat/antigravity-cli-provider
Closed

feat(antigravity): add Antigravity CLI OAuth provider#29385
longbowlu wants to merge 1 commit into
NousResearch:mainfrom
longbowlu:feat/antigravity-cli-provider

Conversation

@longbowlu

@longbowlu longbowlu commented May 20, 2026

Copy link
Copy Markdown

Summary

Adds antigravity-cli as an OAuth-backed inference provider for Hermes.

The implementation keeps Antigravity separate from both the regular gemini API-key provider and the existing google-gemini-cli OAuth provider. Users opt in by selecting antigravity-cli from hermes model or by setting HERMES_INFERENCE_PROVIDER=antigravity-cli.

Why

Google has announced that Antigravity CLI is the consumer migration path for Gemini CLI. The official Google Developers Blog post, "An important update: Transitioning Gemini CLI to Antigravity CLI", says Antigravity CLI is available now and gives a June 18, 2026 transition date for consumer Gemini CLI / Gemini Code Assist request serving.

Hermes already supports Gemini CLI OAuth as a provider. Adding an isolated antigravity-cli provider keeps that subscription-backed workflow available as Google moves consumer usage toward Antigravity CLI, while avoiding changes to the existing Gemini CLI and API-key Gemini providers.

Implementation

  • Reads Antigravity CLI credentials from ~/.gemini/antigravity-cli/antigravity-oauth-token.
  • Refreshes access tokens with OAuth client credentials discovered from the installed agy binary or explicit environment overrides.
  • Reuses the existing GeminiCloudCodeClient path with a credential_source switch for Antigravity-specific auth and the daily Code Assist agent endpoint.
  • Keeps model selection curated through Hermes' provider model list rather than exposing raw backend model keys.
  • Adds interactive hermes model and hermes auth support, provider aliases, config/env wiring, docs, and focused regression coverage.
  • Does not start an Antigravity browser login from Hermes; if credentials are missing, Hermes tells the user to run agy first.

Design Notes and Alternatives Considered

  • Separate provider instead of folding into google-gemini-cli: Antigravity uses a separate CLI token store, daily Code Assist endpoint, user-agent/request-type envelope, and request ID shape. Keeping it behind antigravity-cli avoids changing Gemini CLI behavior and makes the new path easy to remove or adjust if Antigravity changes.
  • Direct backend adapter instead of shelling out to agy --print: agy --print is an agent CLI, not a stable transport API. It can perform workspace/config inspection and its native auth behavior may depend on OS-level login state. Hermes needs a deterministic provider adapter, so this follows the existing Gemini CLI provider pattern and calls the Code Assist backend directly.
  • No Hermes-owned Antigravity login flow: The Antigravity CLI owns login and token-file creation today. Hermes only reads and refreshes existing credentials; when credentials are missing, it tells users to run agy first.
  • SSE transport for Antigravity, even for non-streaming callers: Antigravity agent requests use the verified streamGenerateContent?alt=sse Code Assist path. For OpenAI-compatible stream=False calls, Hermes still sends the Antigravity request through that SSE endpoint and aggregates the events back into a normal non-streaming completion. For stream=True, Hermes exposes OpenAI-shaped delta chunks. This avoids inventing an unverified non-streaming Antigravity endpoint while preserving the OpenAI-compatible interface.
  • Curated model list instead of dumping backend model keys: This matches the Gemini CLI provider behavior and avoids exposing backend-only or unstable model identifiers as user-facing choices.
  • Opt-in live smoke coverage: The live Antigravity test requires local CLI credentials and can consume Google quota, so normal CI stays hermetic and the live check is gated behind HERMES_LIVE_TESTS=1.

Compatibility and Risk Controls

  • The provider is opt-in only. Existing gemini and google-gemini-cli behavior is unchanged.
  • Antigravity credentials are isolated to the Antigravity CLI token store; Hermes does not migrate or merge them into the Gemini CLI OAuth store.
  • Hermes does not persist discovered project IDs back into the Antigravity token file.
  • OAuth refresh tries all discovered client credential candidates before treating invalid_grant as final and clearing local credentials.
  • No OAuth client secrets, refresh tokens, API keys, local paths, or private config are checked in.
  • Tests use placeholder credentials, and live Antigravity coverage is gated behind HERMES_LIVE_TESTS=1.

Known Limitations

  • Antigravity CLI is new and its backend contract is not documented as a public SDK. The implementation is isolated behind antigravity-cli so it can be adjusted without changing existing Gemini providers.
  • Hermes does not implement initial Antigravity login. Users must run agy first so the official CLI owns browser login and token-file creation.
  • Hermes does not shell out to agy --print; that path is intentionally avoided because it is an agent CLI, not a deterministic provider transport.
  • Usage/accounting metadata follows the current GeminiCloudCodeClient behavior; this PR focuses on provider support, request/response translation, tool calls, reasoning text, and streaming/non-streaming completion behavior.

Reviewer Notes

Antigravity CLI is new, so this intentionally mirrors the existing Gemini CLI provider shape where possible while isolating Antigravity-specific token storage and request-envelope behavior behind the new provider.

The model flow includes an explicit warning before reusing local CLI OAuth credentials. Refresh tries all discovered OAuth client credential candidates before treating invalid_grant as final and clearing the local token file.

Verification

  • scripts/run_tests.sh tests/hermes_cli/test_model_provider_persistence.py tests/agent/test_antigravity_oauth.py tests/agent/test_gemini_cloudcode.py tests/agent/transports/test_chat_completions.py tests/run_agent/test_antigravity_cloudcode_client.py
    • public extraction workspace: 196 passed
    • private development workspace: 190 passed
  • HERMES_LIVE_TESTS=1 scripts/run_tests.sh tests/agent/test_antigravity_cloudcode_live.py
    • 1 passed
  • git diff --check upstream/main...HEAD
    • clean
  • python -m py_compile on changed runtime and test modules
    • clean

## Summary

Adds `antigravity-cli` as a first-class OAuth-backed inference provider.
Hermes reads the local Antigravity CLI token store, refreshes access tokens with
OAuth client credentials discovered from the installed `agy` binary or explicit
environment overrides, and sends chat completions through the Code Assist daily
agent backend using the same OpenAI-compatible facade as `google-gemini-cli`.

This keeps the existing `gemini` API-key provider and `google-gemini-cli` OAuth
provider separate. Users opt in by selecting `antigravity-cli` from `hermes model`
or by setting `HERMES_INFERENCE_PROVIDER=antigravity-cli`.

## Architecture

- `agent/antigravity_oauth.py`: Antigravity token-file loading, refresh,
  cross-process locking, atomic writes, credential clearing, and OAuth client
  credential discovery from `agy`.
- `agent/gemini_cloudcode_adapter.py`: Adds a `credential_source` switch so the
  existing Cloud Code adapter can use Antigravity OAuth tokens and the daily
  agent request envelope without changing Gemini CLI behavior.
- `agent/google_code_assist.py`: Allows the shared project-context discovery
  helpers to target the Antigravity daily Code Assist endpoint.
- `hermes_cli/auth.py`, `runtime_provider.py`, `providers.py`, `models.py`,
  `config.py`, `main.py`, and `auth_commands.py`: Provider registration,
  aliases, optional environment variables, runtime credential resolution,
  `hermes auth` integration, and the interactive model flow.
- `agent/transports/chat_completions.py` and `agent/agent_runtime_helpers.py`:
  Route `antigravity-cli` through `GeminiCloudCodeClient` with
  `credential_source="antigravity-cli"`.

## Provider behavior

- Antigravity token source is isolated from the Gemini CLI OAuth store:
  `~/.gemini/antigravity-cli/antigravity-oauth-token`.
- Hermes does not start its own Antigravity browser login. If the token file is
  missing, the model flow tells users to run `agy` and complete Antigravity login.
- Hermes does not write discovered project IDs back into the Antigravity token
  file. Project context is resolved per client and cached in memory.
- Model choices follow the same curated-provider pattern as `google-gemini-cli`;
  the picker does not dump raw backend model keys.
- The model flow shows an upfront warning and requires explicit `y` confirmation
  before reading or refreshing local Antigravity OAuth credentials.
- Refresh tries all discovered OAuth client credential candidates before treating
  `invalid_grant` as authoritative and clearing the token file.

## Public contribution hygiene

- No real OAuth client secrets, refresh tokens, API keys, local paths, or private
  configuration are checked in.
- Test credentials are explicit placeholders.
- Public commit metadata uses the GitHub noreply identity.

## Tests

Focused regression coverage includes:

- Antigravity OAuth token load/save/refresh, invalid-grant clearing,
  multi-candidate client fallback, malformed expiry handling, metadata
  preservation, concurrent refresh dedupe, and runtime credential shape.
- Provider registration, aliases, optional env vars, auth command wiring,
  runtime provider dispatch, and model/config persistence.
- Interactive model flow success, missing-token no-op, and warning cancellation.
- Cloud Code adapter routing with Antigravity credential source, daily backend
  agent envelope, project-context isolation, model ID pass-through, thinking
  config preservation, streaming SSE, non-streaming SSE aggregation, and
  non-streaming SSE tool-call aggregation.
- Chat completions transport and run-agent client construction.
- Opt-in live smoke test for Antigravity recommended Gemini models.

Test commands run:

- `scripts/run_tests.sh tests/hermes_cli/test_model_provider_persistence.py tests/agent/test_antigravity_oauth.py tests/agent/test_gemini_cloudcode.py tests/agent/transports/test_chat_completions.py tests/run_agent/test_antigravity_cloudcode_client.py` -> 196 passed in the public extraction workspace.
- Same focused suite in the private development workspace -> 190 passed.
- `HERMES_LIVE_TESTS=1 scripts/run_tests.sh tests/agent/test_antigravity_cloudcode_live.py` -> 1 passed.
- `git diff --check upstream/main...HEAD` -> clean.
- `python -m py_compile` on changed runtime and test modules -> clean.
@longbowlu
longbowlu force-pushed the feat/antigravity-cli-provider branch from 3a873fd to 1defe12 Compare May 20, 2026 16:35
@alt-glitch alt-glitch added type/feature New feature or request P2 Medium — degraded but workaround exists comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard provider/gemini Google Gemini (AI Studio, Cloud Code) labels May 20, 2026
@pmos69

pmos69 commented May 20, 2026

Copy link
Copy Markdown
Contributor

Thanks for putting this together. I wanted to flag that there is now an alternate implementation in #29474, with a different auth/model-discovery tradeoff rather than a disagreement with the overall Antigravity-provider direction.

The main differences are:

  • feat(cli): add native Antigravity OAuth provider #29474 uses a Hermes-owned Antigravity OAuth PKCE flow and stores credentials separately under ~/.hermes/auth/antigravity_oauth.json, instead of reading an agy token file.
  • In local Windows testing, authenticated agy state did not appear to create ~/.gemini/antigravity-cli/antigravity-oauth-token, so relying on that file may be less portable across platforms/install shapes.
  • feat(cli): add native Antigravity OAuth provider #29474 asks Antigravity fetchAvailableModels for the signed-in account's available agent models, with filtering and a curated fallback. In testing this surfaced account-entitled models that are not available through the older Gemini CLI path.
  • It also preserves provider-supplied tool-call IDs through the Gemini Code Assist translation path, which matters for Claude-backed Antigravity models.

Your approach has clear merits, especially keeping initial login owned by the official CLI and avoiding shelling out to agy for inference. I mostly wanted to give maintainers visibility into the alternative so they can choose the auth boundary they prefer.

@pmos69

pmos69 commented May 20, 2026

Copy link
Copy Markdown
Contributor

For maintainers comparing the two Antigravity approaches: I've posted a neutral side-by-side of where #29385 and this PR's alternate (#29474) diverge — credential source, login ownership, model discovery, adapter shape — at #29474 (comment) . It's framed as tradeoffs rather than a recommendation, to make the auth-boundary choice explicit.

@GalegO

GalegO commented May 23, 2026

Copy link
Copy Markdown

Documentation: Antigravity (Windows) Integration in Hermes

This document records the necessary modifications to make the google-antigravity provider compatible with the Windows environment, natively reading access keys from agy.exe (Antigravity CLI) and fixing specific parameters for the Code Assist API.


1. The Problem with the Original Pull Requests

Hermes relied on two major PRs that introduced the google-antigravity provider, but neither worked perfectly in isolation within the Windows 11 64bits environment:

PR 29474: Browser-Based OAuth Approach

This PR implemented a native adapter inside Hermes with an OAuth flow identical to the Google Gemini CLI (opening the browser, exchanging codes for tokens, and writing to a .json file).

  • Why it failed: The agy.exe binary (used in Antigravity) has its OAuth Client Secret obfuscated or not publicly distributed. Therefore, when Hermes attempted to make the token exchange request by sending an empty Client Secret (or "not_a_secret"), the backend rejected it with an invalid_client error.

PR 29385: Binary Reading Approach (Linux/macOS)

This PR suggested not rebuilding the OAuth flow from scratch, but rather reading the token that the agy binary itself had already authenticated.

  • Why it failed (on Windows): The original code for this PR assumed that tokens were saved in a simple hidden .json text file (as happens on macOS and Linux). However, on Windows, agy.exe uses the Windows Credential Manager securely under the gemini:antigravity key.

2. The Implemented Hybrid Solution

We took the excellent architecture and adapters from PR 29474 and implemented the credential interception logic from PR 29385, but completely rewritten specifically for Windows cryptography and credential vault APIs.

Change 1: agent/antigravity_oauth.py (The Windows Vault)

  • Removed the entire manual flow of opening the browser (start_oauth_flow).
  • Implemented native reading via the ctypes library and advapi32.dll.
  • Hermes now calls the Windows CredReadW API to successfully extract the JSON blob corresponding to gemini:antigravity.
  • Auto-Refresh: If the token read from Windows is close to expiring, we added logic to run subprocess.run(["agy", "--print", " "]) in the background. This forces the Antigravity CLI to perform the renewal via the backend and update the Windows Credential Manager. Hermes then simply reads the updated version!

Change 2: Code Assist API Configuration

We found two minor payload and endpoint details (which were correct in PR 29385 but were lost or contained errors in PR 29474):

agent/antigravity_code_assist.py

The base URL was pointing to a "sandbox" environment that was not responding (returning 404 Not Found).

- ANTIGRAVITY_CODE_ASSIST_ENDPOINT = "https://daily-cloudcode-pa.sandbox.googleapis.com"
+ ANTIGRAVITY_CODE_ASSIST_ENDPOINT = "https://daily-cloudcode-pa.googleapis.com"

agent/antigravity_cloudcode_adapter.py

The Code Assist API for the Antigravity entity requires specific identification metadata (requestId, requestType, and userAgent) at the root of the payload. We updated the request wrapper to comply with these backend requirements:

wrapped = {
    "project": ctx.project_id,
    "requestId": self._next_antigravity_request_id(),
    "model": model,
    "userAgent": "antigravity",
    "requestType": "agent",
    "request": inner,
}

Change 3: User Configuration (config.yaml)

Finally, we identified that the user's personal configuration file (C:\Users\<username>\AppData\Local\hermes\config.yaml) used the display name (Gemini 3.1 Pro (Low)) instead of the technical ID (gemini-3.1-pro-low). Hermes sent the friendly name to the backend, which also resulted in a 404 Requested entity was not found error. The config.yaml file has been normalized.


Tip

Backup Created!
For security purposes, the three key integration files (antigravity_oauth.py, antigravity_code_assist.py, and antigravity_cloudcode_adapter.py) have been copied to the backup folder at C:\Users\<username>\OneDrive\Dev\FORK\Hermes\antigravity_windows_backup\.

Files changes during the process:
antigravity_windows_backup.zip

V2: Working on Docker in Ubuntu (VPS)
Install AGY CLI and auth on Linux bash, not into Docker.
hermes_agy_docker_linux.zip

@teknium1

Copy link
Copy Markdown
Contributor

Superseded by #50454 (merged) — #50454

We landed the native google-antigravity OAuth provider via @pmos69's #29474 (submitted first), salvaged onto current main with a Hermes-owned PKCE flow rather than reading the agy token file. Your implementation tackled the same migration — thanks for the contribution and for surfacing this early. The merged provider does not depend on an external agy binary, which was the main tradeoff between the two approaches.

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

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/gemini Google Gemini (AI Studio, Cloud Code) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants