Skip to content

feat(antigravity): add experimental native Messages provider - #185

Draft
chris7iu wants to merge 8 commits into
raine:mainfrom
chris7iu:feat/antigravity-argon
Draft

chris7iu wants to merge 8 commits into
raine:mainfrom
chris7iu:feat/antigravity-argon

Conversation

@chris7iu

@chris7iu chris7iu commented Oct 18, 2026 •

Copy link
Copy Markdown

Summary

Add an experimental, opt-in, default-off native Antigravity provider for Anthropic Messages and local count_tokens. This is not an agy subprocess wrapper: agent-executed tools cannot serve as faithful external Messages tool turns.

Supported exact selectors:

  • antigravity/gemini-4-argon-low
  • antigravity/gemini-4-argon-medium
  • antigravity/gemini-4-argon-high

Enablement is explicit (CCP_ANTIGRAVITY_ENABLED=1 or antigravity.enabled configuration). Default-disabled model discovery remains unchanged. This draft requests code/protocol review. Bounded low-tier native text/SSE and a single client-tool round-trip have now passed live acceptance on the consumer endpoint; this is not an all-account entitlement or universal compatibility claim.

Consumer endpoint correction and latest acceptance (2026-10-24)

The supported proxy-owned consumer OAuth flow now defaults to https://daily-cloudcode-pa.googleapis.com. Explicit CCP_ANTIGRAVITY_BASE_URL / antigravity.baseUrl origins still win, including production/custom HTTPS origins. Discovery and generation share the selected origin; fixed OAuth endpoints, proxy-default User-Agent, model suffixes and thinking settings are unchanged. This is not a new GCP/ADC/service-account routing implementation or a universal Google tier-policy claim.

A controlled, fixed-profile/request comparison returned production 429 → daily 200 with complete text SSE → production 429, while keeping the production manager alive across both production requests. The observed official agy 1.4.6 consumer path also selected daily. Committed tests remain synthetic; no raw account traffic, signatures or credentials are included.

Latest reviewed source, updated with current upstream:

  • Formatting, Clippy with -D warnings, build and 1,290 Rust tests passed, with zero failed/ignored/filtered tests.
  • Five focused regressions cover default/override/origin policy, shared discovery/generation selection, and an exact three-stage synthetic SSE/non-streaming tool replay. The two default-origin assertions failed before the fix.
  • Python: 83 unit tests with four optional HTTP skips, plus the four actual HTTP fixture bodies executed separately with zero skips/failures.
  • Documentation build passed: 22 pages, search index and llms outputs.
  • A fresh explicit-daily live canary passed all three requests: text SSE; exactly one auto-choice client tool call; then the matching tool result with the entire unchanged assistant content/replay carrier preserved, followed by the exact final response and end_turn.

Live scope is one fixed low-tier consumer profile, text, and one client-tool round-trip. Compiled-in default selection is separately covered offline; the live canary explicitly selected daily to avoid relying on an uninspected runtime configuration. No generation retry, account/project rotation, credential import or forced refresh test was added. Capability live_verified: false remains a static descriptor, not an assertion that this local canary never happened. Medium/high tiers, media, parallel same-name ID-less calls, incremental argument parity and measured large-context acceptance are not newly claimed.

The serving stack was not replaced or restarted. Production activation, dependent gateway acceptance and upstream approval remain separate; the provider stays experimental and default-off.

Provider and session contract

  • Native transport targets the Cloud Code Assist generation API, with proxy identification by default and an explicit native-API User-Agent override, bounded requests, no redirects and no automatic inference retries.
  • One fixed model/tier/profile/project session. Changing the selector or account/project requires a fresh client session; observed Claude Code behavior strips replay carriers across model changes.
  • Text/system/client-tool turns, bounded signed-history replay, and an explicit schema adapter with original-schema validation and lossless JSON-string codecs where native schema projection is insufficient. Codec guidance preserves complete accepted constraints and rejects oversized guidance rather than truncating it.
  • Completed parameterless native calls may omit args; caller input is {}, while native replay retains the original omission. Unsupported incremental arguments, media/server tools, forced-tool semantics and ambiguous repeated same-name ID-less parallel calls remain rejected.
  • Native output is bounded and collected into a validated signed turn; Messages streaming does not claim native-token latency or incremental-tool-argument parity.
  • Conservative, unmeasured 200,000-token client advertisement. No [1m] alias or verified native 1M claim. Model tier governs native thinking; generic effort hints cannot switch tiers.
  • OpenAI-compatible generation is explicitly not implemented for this provider.

Replay boundary

The versioned ccp:antigravity:v1: envelope retains raw native contents/signatures, stable session identity, caller/native tool mapping and codec information. Omitted/full visible thinking has the same reconstructed semantic history and local token estimate.

Its digest is consistency checking, not authentication. It does not authenticate every opaque native signature byte. A mutation confined to opaque signature material may pass local consistency and be rejected by the upstream after one attempt; the provider does not repair signatures, retry inference or log the carrier.

Authentication, cancellation and privacy

  • Explicit OAuth consent, PKCE S256 and independent one-time state; no automatic agy/Codex/Gemini credential import, account rotation or hidden onboarding.
  • Separate proxy-owned private credential storage; missing, corrupt and unreadable states are distinct. A stable sibling lock and profile/epoch checks protect login/logout/refresh, rather than locking the replaceable credential inode.
  • Refresh maintenance is manager-owned and single-flight. It acquires a bounded lock before network effects; validated token rotation is persisted independently of request cancellation and the network timer. Failed persistence retains a scoped pending replacement and never retries an obsolete refresh token. Ambiguous refresh outcomes require login. This does not promise crash-proof remote OAuth transactions.
  • Request cancellation owns generation transport only; it does not detach inference. Controlled TCP tests cover disconnection before native headers and during body collection. Local logout does not require valid transport configuration and does not touch another provider's files.
  • Incoming client credentials are not forwarded to native generation. Provider traffic/error reporting excludes prompts, carriers, signatures, tokens and account/project identifiers.

Manual OAuth completion

antigravity auth login --manual adds an explicit experimental Unix terminal flow: open the printed authorization URL, consent in the browser, and paste the displayed authorization code privately into the CLI. It does not open a browser or bind a callback listener. Automatic loopback login remains the default on all platforms; non-Unix manual mode is explicitly unsupported.

The hosted redirect is https://antigravity.google/oauth-callback. Current public page code confirms that it displays/copies the decoded code query value and removes it from browser history. This is not an access/refresh-token import or a signed completion envelope. A client registration permitting that hosted redirect is still required; no client ID/secret is bundled, and an earlier user-supplied registration/exchange flow completed on Linux. The latest canary reused that proxy-owned profile rather than re-running consent; other registrations, accounts and entitlements are not guaranteed.

Each attempt retains a fresh private S256 PKCE verifier and independent state. Bare-code completion has no returned state to validate and relies on authorization-server PKCE and downgrade enforcement; those server properties are not established by synthetic tests. An optional full completion URL must match the issued redirect and exactly one returned state, with strict encoding/duplicate/error validation. Token exchange remains single-attempt and protected by the existing profile/epoch transaction.

Manual input is now intentionally visible in an application-managed terminal viewport, with a character count and a left-truncation marker for long codes. The complete logical input remains bounded to 8 KiB under the same 180-second terminal input/output deadline. Kernel echo stays disabled; only accepted printable input is rendered through the independently owned nonblocking controlling terminal. Keep screen, scrollback, recordings and screenshots private. A known terminal width of at least 10 columns is required; detected resizing or incompatible active output translation cancels/refuses safely. Backspace/Delete edit the logical input; unsupported control/escape sequences retain the existing refusal behavior. Bounded coalesced repainting continues servicing cancellation under backpressure, including cancellation after Enter in the same read. Cleanup, one-shot exchange, committed-success semantics and bounded final diagnostics remain unchanged. Tests separate intentional terminal display from prohibited stdout/stderr/log disclosure and retain the real 180-second unread-output CLI regression. Linux was exercised; macOS/Windows runtime compatibility is not claimed.

Explicit User-Agent compatibility override

The default HTTP User-Agent is exactly claude-code-proxy/<package version>. CCP_ANTIGRAVITY_USER_AGENT, then antigravity.userAgent, can supply a full verbatim override for generation and loadCodeAssist only. OAuth code exchange and refresh retain the proxy default; generic CCP_USER_AGENT and incoming client headers do not select this override.

The documented optional agy1.3.5 example comes from pinned public protocol evidence. It is not auto-detected, automatically enabled, or a claim to match whichever agy version is installed. No version/changelist/platform fields are synthesized or rewritten in an explicit override.

Validation rejects empty/outer-whitespace, control/non-ASCII, overlong and non-Unicode values before native requests; headers are marked sensitive and errors/status omit raw values. Tests assert exactly one UA across native and OAuth operations, default/override precedence, hostile incoming-header isolation and unchanged no-retry/no-redirect behavior.

A focused regression exposed existing full-environment UTF-8 snapshots panicking before native validation. The follow-up excludes only this independently OS-string-validated key from legacy snapshot iteration, preserving other valid entries/order/collection behavior. Invalid native configuration remains provider-scoped; unrelated non-Unicode entries still fail, now with fixed redacted panic text. Linux CLI and injected Windows ASCII-name comparisons are tested; no Windows runtime claim is made.

Read-only capability contract

GET /v1/models?include_capabilities=true adds a versioned native-provider capability descriptor. Plain /v1/models remains baseline-compatible when disabled. antigravity auth status --json exposes the same safe local descriptor; exit 0 means a report was emitted, not that the provider is ready.

Capability/status reads do not refresh credentials, look up projects, run inference or create directories. Serving metadata comes from the serving provider instance. Local configuration readiness is not proof of Google access.

Validation

Offline checks used disposable non-root containers with private process/network namespaces, isolated homes/configuration and synthetic endpoints. No production gateway, real account credentials or host auth sockets were mounted for those offline checks. The bounded live acceptance used only an explicitly consented proxy-owned profile.

  • Baseline: 1,119 Rust tests passed.
  • Earlier reviewed candidate under ordinary process umask 0022: formatting, Clippy with -D warnings, build and 1,283 Rust tests passed. Credential/evidence/cache roots remained private, and source hashes were unchanged during the run.
  • Current Python validation: 83 tests, zero failures/errors, four opt-in HTTP fixture skips. Those four original HTTP fixture bodies were separately executed with four passes and zero skips. No actual Claude process was launched for this fixture run. Synthetic parameterless-call golden bytes match Rust; the original v1 field/digest format and earlier golden vectors remain unchanged.
  • The optional developer launcher requires an explicit local image and native ELF executable, validates the nonroot caller, keeps host-only cleanup evidence separate from container-writable output, and never pulls images or launches Claude on the host. Its revised lifecycle is unit-tested with process stubs, not a fresh actual-client execution.
  • Tests-first regressions cover schema-guidance loss (including typeless anyOf siblings), credential mode handling, cancellation-independent refresh persistence, failed-write recovery, profile/epoch/logout races, effective-target raw-byte validation, assistant-fragment boundaries, parameterless-call replay and display-independent estimates.
  • Existing-provider regression tests are included in the full Rust gate. Status/error/Retry-After and single-attempt behavior have synthetic transport controls; reqwest retries are explicitly disabled.
  • Earlier isolated real-Claude-Code compatibility runs against a fake endpoint informed the fixed-model contract. They are historical evidence, not a fresh end-to-end verification of the final changed fixtures or Google's service.

An independent read-only review's concrete findings were reproduced and fixed; a second pass found and verified the additional typeless-anyOf guidance correction. Runtime acceptance is reported separately from the local suite and does not expand the declared compatibility scope.

Protocol provenance and limitations

Implementation is based on pinned public MIT-licensed protocol evidence from cortexkit/antigravity-auth at f5a836df058a99cee6099ad308b9675e4ef11026, with provenance/licensing recorded in the contribution. Reference observations for the low tier are distinct from catalog-inferred medium/high encodings; none establish this user's entitlement or an official service guarantee.

No device identity/attestation copying, missing-signature sentinel, signature stripping, borrowed account/project identity or provider fallback is added. The optional User-Agent override is explicit compatibility metadata, not proof of official-client identity or entitlement. No binary/version installation or production activation is part of this PR. The dependent model-gateway frontend contribution is separate and must validate this native capability contract rather than assume a release already contains it.

The visible-input follow-up also includes a synthetic actual-CLI HTTP CONNECT fixture: accepted manual input makes exactly one CONNECT oauth2.googleapis.com:443 through a child-scoped HTTPS_PROXY, while rejected/cancelled input makes none. The fixture does not contact Google and is not live OAuth/entitlement acceptance. Independent frozen-source review found and closed a same-read Enter/cancellation bug with a real PTY RED→GREEN regression.

Safe upstream error diagnostics

Native non-2xx generation responses retain their HTTP status and Anthropic error type, with a fixed-format diagnostic suffix containing only allowlisted Google status/reason/domain labels, a quota-detail presence classification, and validated retry hints. Unknown or malformed values remain unclassified; arbitrary upstream messages, metadata, account/project identifiers and error bodies are never reflected. HTTP 429 or RESOURCE_EXHAUSTED alone is not treated as exhausted subscription quota.

Error inspection is limited to 8 KiB and at most one second, clamped to the original 30-second header deadline; duplicate/deep/malformed/oversized/incomplete bodies fail closed. Retry-After forwarding now accepts only a single bounded decimal delay or canonical IMF-fixdate, reconstructed locally; legacy date formats and arbitrary strings are rejected. RetryInfo fractions are checked and rounded up, reported separately rather than synthesizing an HTTP header. No automatic retry, fallback, auth change or success/replay-path change.

Tests exercise real local HTTP errors in JSON and SSE-requested modes, retry conflicts, bounded trickle/overflow/cancellation, and verbose/stderr log redaction. Full formatting, Clippy-Dwarnings, build and 1,283 Rust tests passed on the reviewed frozen source. The bounded low-tier live SSE/tool results are reported separately; synthetic error checks do not establish all-account entitlement or production readiness.

Proven pre-send refresh recovery

Refresh failures now distinguish typed, proven pre-send connector failures from ambiguous exchanges. With the pinned reqwest/hyper transport and redirects/retries disabled, only a complete bounded connector-error chain whose first eligible I/O cause is ConnectionRefused or TimedOut qualifies for one additional application send. TLS verification/protocol failures, proxy authentication failures and non-allowlisted connect failures do not retry; neither do HTTP errors or ambiguous post-send failures. Private connector timeouts without an allowlisted I/O cause remain non-retryable. Internal library reconnection of provably unstarted requests means this is an application-send bound, not a socket-connection count.

The retry waits 200 ms, shares the original 30-second network deadline, and starts only with at least 16 seconds remaining. Proven pre-send exhaustion preserves credentials and applies a manager-local, scope-bound 30-second foreground-only cooldown with fixed 503 diagnostics. No autonomous retry task, generation retry or authorization-code-exchange retry was added. Ambiguous outcomes retain the existing uncertain-rotation protection; cooldown is neither cross-process nor crash-durable. Singleflight, epoch/lock checks, cancellation-independent persistence and graceful shutdown remain protected.

Fourteen new tests cover real connector behavior, refused-connection recovery, proxy/TLS exclusion, accepted-POST disconnects, deadline/backoff boundaries, cooldown scope, concurrent waiters, cancellation and shutdown. Full formatting, Clippy with -D warnings, build and 1,283 Rust tests passed on the independently reviewed frozen source. No live refresh against an uncertain user token was attempted.

Official agy release notes document proactive refresh and transient-failure session preservation, but its CLI refresh implementation is not public; this is not claimed to reproduce its exact retry algorithm.

🤖 Generated with Claude Code

chris7iu and others added 8 commits October 18, 2026 12:24
Add explicit OAuth/profile storage, cancellation-safe token refresh, bounded native transport and lossless fixed-session replay/schema adaptation. Keep disabled discovery baseline-compatible, expose read-only capabilities, and provide local count estimates with documented limitations.

Validated offline under umask 022 with formatting, Clippy, build, 1206 Rust tests and 83 Python fixture/launcher tests. Native Google acceptance remains unverified; no live provider or service activation is included.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Default all outbound requests to claude-code-proxy/<version>. Apply a validated provider-specific full User-Agent only to generation and project discovery, preserving proxy identity for OAuth and exact override bytes.

Keep the independently validated OS-string override outside legacy UTF-8 environment snapshots, with redacted failures and unchanged provider-scoped invalid configuration behavior. Tests-first regressions, independent review, fmt, Clippy, build and 1222 isolated tests pass under umask 022. No live activation.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Add opt-in hosted-code completion with PKCE and strict URL/state validation, private bounded Unix terminal input, and explicit post-commit and bounded-exit semantics. Keep automatic callback login unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Render visible input with a bounded terminal viewport, preserve cancellation
and redaction guarantees, and verify native proxy routing with a local fixture.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Expose only allowlisted Google error labels and validated retry hints,
while preserving HTTP status and never retrying failed generation.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Bound refresh retries within the original deadline, preserve credentials
with scoped cooldowns, and retain fail-closed ambiguous-rotation handling.

Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Use the consumer Cloud Code origin for discovery and generation while
preserving explicit endpoint overrides and fixed OAuth URLs. Add
selection regressions and lossless non-streaming client-tool replay
coverage against synthetic upstream SSE.

Co-Authored-By: Claude Code <noreply@anthropic.com>

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.

1 participant