Skip to content

add Antigravity OAuth login and Antigravity image generation support - #1

Open
remorses wants to merge 2 commits into
mainfrom
antigravity-oauth-image-support-clean
Open

add Antigravity OAuth login and Antigravity image generation support#1
remorses wants to merge 2 commits into
mainfrom
antigravity-oauth-image-support-clean

Conversation

@remorses

@remorses remorses commented Mar 12, 2026

Copy link
Copy Markdown
Owner

What changed

  • Added Antigravity OAuth login to egaki with PKCE browser flow, localhost callback handling, and callback-URL completion for shared/manual auth flows.
  • Added Antigravity provider support in credentials/login/status, including OAuth token persistence, refresh handling, and project discovery/onboarding helpers.
  • Added a dedicated Antigravity image generation module and wired model routing so antigravity-gemini-3-pro-image runs through Antigravity endpoints.
  • Improved runtime error output for Antigravity permission/configuration failures by surfacing actionable verification and API activation URLs.
  • Updated README with an Antigravity support matrix and explicit per-user/per-project gating notes.

Current status / limitation

  • This is currently not working end-to-end for generation in my testing setup.
  • Antigravity image requests still fail due to Google account/project gating (for example cloudaicompanion.companions.generateChat permission and project/API access issues).
  • The PR keeps the integration and error handling in place so the failure mode is clear and actionable, but successful generation still depends on account/project permissions.

Why
This makes Antigravity a first-class auth + generation path in egaki, aligns behavior with the opencode plugin flow, and makes account/project gating failures understandable and recoverable without digging through raw API payloads.

Implement Antigravity OAuth as a first-class provider in egaki, including browser PKCE login, callback-url completion, stored OAuth session metadata, token refresh, and project discovery helpers for Antigravity-backed requests.

Add Antigravity image generation routing in a dedicated module, keep execution Antigravity-only, and improve error UX with actionable verification/API-activation links so account/project gating failures are explicit.

Document Antigravity support and per-user gating behavior in README, including OAuth env setup required to avoid hardcoding OAuth client credentials in repo.

@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: 69b1cfc315

ℹ️ 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/antigravity-auth.ts
Comment on lines +508 to +509
const child = spawn('xdg-open', [url], { detached: true, stdio: 'ignore' })
child.unref()

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 Handle missing browser opener without crashing OAuth login

On Linux, this spawn('xdg-open', ...) call has no error handler, so systems without xdg-open (common in CI/headless environments) emit an unhandled error event (ENOENT) and terminate the process before OAuth can complete. Since antigravityOAuthLogin() always calls openBrowser(), egaki login --provider antigravity exits instead of continuing with the printed URL/manual completion flow.

Useful? React with 👍 / 👎.

Comment thread src/antigravity-image.ts
}

if (successfulProjectId && successfulProjectId !== auth.projectId) {
saveAntigravityAuth({ ...auth, projectId: successfulProjectId })

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 Preserve refreshed auth when saving discovered project

This write uses the original auth snapshot, not the possibly refreshed credentials saved earlier by getValidAntigravityAccessToken(..., onRefresh). When a request succeeds with a different project ID, it can overwrite newly refreshed access/refresh/expires fields with stale values, causing repeated refresh churn or loss of rotated refresh tokens on subsequent runs.

Useful? React with 👍 / 👎.

remorses added a commit that referenced this pull request Jun 17, 2026
Implement a custom SpeechModelV3 wrapping the Cartesia REST API
`POST https://api.cartesia.ai/tts/bytes` since there is no
`@ai-sdk/cartesia` npm package.

**New file: `cli/src/cli/cartesia-provider.ts`**
- Implements `SpeechModel` interface against Cartesia TTS bytes endpoint
- Uses `Cartesia-Version: 2026-03-01` header (current API version)
- Bearer auth via `CARTESIA_API_KEY` env var
- Structured `output_format` objects for mp3/wav/raw
- Speed control via `generation_config.speed` (range 0.6-1.5)
- Language selection (42 languages via ISO 639-1 codes)
- Default voice: Katie en-US Female

**Speech catalog (`speech-catalog.ts`)**
- Added `sonic-3.5` (latest, #1 naturalness, sub-90ms latency)
- Added `sonic-3` (previous gen, still high quality)
- Pricing estimated from Startup plan (~$39/M chars)
- 5 recommended voice IDs from Cartesia docs

**Speech models (`speech-models.ts`)**
- Added `cartesia` entry to `SPEECH_PROVIDER_SDKS` with lazy import

**Credentials (`credentials.ts`)**
- Added `cartesia` provider with `CARTESIA_API_KEY` env var
- Key hint points to https://play.cartesia.ai/keys

**CLI (`cli.ts`)**
- Updated speech command description to mention Cartesia
- Updated voice/speed/language help text
- Added Cartesia example command

Tested end-to-end: created API key via Cartesia dashboard,
logged in with `egaki login --provider cartesia`, generated
English and Italian speech with sonic-3.5. Build passes,
all 224 tests pass, no lintcn issues in new files.

Session: ses_13341448effesFGa4ZZ3VsK6HO
remorses added a commit that referenced this pull request Jun 17, 2026
**CLI imports (#1):** cli.ts now imports *Uncached variants so the CLI
commands (egaki image, video, speech, transcribe) continue to work with
raw result types instead of the cached { src } shape.

**SSE race condition (#2):** subscribe to onProgressChange before reading
the first snapshot, then loop: read -> yield -> check total -> await.
This prevents the stream from hanging when a generation finishes between
yield and subscribe.

**Stale progress cleanup (#3):** guard setState calls in connectToProgress
with `progressAbortController === controller` so an old aborted stream
does not clear state from a newer active connection.

**Error auto-clear by unique ID (#4):** each error gets a unique _id
(key + timestamp + random). The 8s auto-clear timer removes by _id, not
by generation key, so rapid duplicate failures are cleared independently.

**Documented normalization limits (#5):** added AGENTS.md section for
cachedGenerate with explicit note that params must be JSON-serializable;
Date, Map, Set serialize to {} and should be passed as primitives.

**getCacheInfo from wrapper (#6):** cachedGenerate now returns a callable
with a .getCacheInfo(params) method that uses the same cacheKey config.
Server components use wrapper.getCacheInfo() instead of the standalone
getCacheInfo() to guarantee hash consistency.

Session: ses_12ab29c60ffeiueHKd83cdmM4r
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