Anti-Gravity Provider
Anti-Gravity (agy) is a selectable provider alongside claude, codex and gemini — how to enable it, the dedicated virtual project and per-project default, the model story, the gap and error states, and how each turn runs under the hood.
What it is
Omniscio supports spawning Claude-Code-style sessions backed by Google's Anti-Gravity CLI (agy) as one of its selectable providers, alongside claude (the default), codex, gemini, and the rest of the pickable set. Anti-Gravity is Google's next-gen agentic CLI and a potential replacement for Gemini in this app — both wired up so users can pick whichever feels better.
What the user sees
An Anti-Gravity session looks identical in the sidebar and main pane to a Claude session — same status dots, same streaming bubbles, same Ctrl+Enter to send. The only user-visible differences:
- The session header shows the official upward-pointing "A" chevron mark (rendered in the brand blue
#3186FF), with no text label, instead of nothing. Every started session shows its engine mark next to the title — Claude included, in its brand orange (only logo-less internal engines like OpenClaw / orchestrator show nothing). The per-launch provider dropdown on a fresh session shows the same mark next to each row, also in full brand color. - Streaming is block-mode: the agent's reply appears as one chunk when the turn completes, not token-by-token as it generates. (agy v1.0.9 in headless mode emits nothing incrementally — Omniscio reads the finished reply from agy's on-disk transcript at end-of-turn. See "How it works under the hood".)
- Tool use auto-approves during a turn (agy's headless/CI mode approves its own tool steps). Omniscio no longer passes
--dangerously-skip-permissions— in agy v1.0.9 that flag made the agent loop forever on plain questions, and CI mode auto-approves without it. - The turn's tool activity (file reads, searches, subagents) shows as a compact
▸step list folded into the message — so a multi-step run shows its work, like Claude/Cursor. And if a turn is interrupted (e.g. the model is briefly overloaded and returns a 429, or stops before finishing), you get an honest, retryable "…was interrupted before finishing — re-send to retry" row instead of a stray half-sentence.
Where to find it
How to enable
Master toggle required first. Anti-Gravity, Gemini, and Codex are alternative providers — on a fresh install Anti-Gravity is already visible (the master toggle is ON by default since 2026-10-03); on a profile that last saved before that setting existed the entire Anti-Gravity setup section stays hidden in Settings → Accounts until you flip it on. Flip Settings → Accounts → Show alternative AI providers to ON and the Anti-Gravity panel appears. With the master off, the per-project "Default provider" radio collapses to a single Claude row and the session header's provider switcher (ChangeProviderButton) hides Anti-Gravity — it effectively does not exist in the UI even if every gate below is configured. Your "Allow Anti-Gravity sessions" toggle and per-project defaults are preserved across master-toggle flips.
You need both of these in place:
- Anti-Gravity CLI binary — install from https://antigravity.google/download#antigravity-cli. The installer drops the binary at
%LOCALAPPDATA%\agy\bin\agy.exe(Windows, viairm install.ps1 | iex) or~/.agy/bin/agy(POSIX, viacurl install.sh | bash). Omniscio discovers it on PATH first, then falls back to those install locations. The Settings panel shows Anti-Gravity CLI: Installed with the binary's live version (e.g.v1.0.9) in green or Not installed with a download link. The version is re-read each time the panel opens, so a self-updatedagyis never shown stale. - Settings → Account → Allow Anti-Gravity sessions toggle — off by default; same security stance as the API-key spawn guard.
There is no API key step. Anti-Gravity authenticates via Google Sign-In, and the credentials live inside the binary's OS keyring — Omniscio never touches them. To sign in:
- Click Sign in with Anti-Gravity in the Settings panel. Omniscio opens
agy --prompt-interactive "Hello"in a new, visible terminal window (a fresh Windows console; macOS Terminal) that you own — it stays open after Omniscio quits and after agy exits, so you can read the result. Complete the Google sign-in in the browser that opens, type/exitto close the interactive prompt, and you're done. The next session Omniscio spawns will reuse those credentials silently. (On Linux there's no in-app launcher — runagy --prompt-interactive Helloin a terminal yourself.)
Once toggle + binary are green, you can launch an Anti-Gravity session three ways:
- Per-launch override — on a fresh (zero-message) session, the ChangeProviderButton in the new session's main panel (the launch-config pickers on a fresh session) lets you pick a one-off provider before sending the first message. Non-ready providers appear
aria-disabledwith a "Set up…" / "Install…" suffix and deep-link to Settings. - Per-project default — Edit Project dialog (three-dot menu → Edit) has a "Default provider" section with one radio per pickable provider. Pick Anti-Gravity and the project's sidebar "+ New Session" button spawns Anti-Gravity automatically.
- Programmatically — anything that creates a session with
provider: 'antigravity'(recipes, agent-driven sessions, the API). Same readiness gates apply on the backend.
Dedicated __antigravity__ virtual project
Just like Gemini and Codex have their own virtual projects in the Omniscio sidebar group, Anti-Gravity has one too — gated behind Settings → Account → Enable dedicated Anti-Gravity project (off by default). Flip it on and an Anti-Gravity entry appears in the sidebar group below the existing Gemini and Codex rows. Sessions launched from there bypass the global "Allow Anti-Gravity sessions" toggle (being inside the dedicated VP is itself the affirmation that you want to use the provider). The binary check still applies.
Per-project default
Each project remembers a default provider in the projectDefaultProviders setting (a Record<projectId, ProviderId> — the value accepts any of the registry's pickable provider ids, 20 today, and the set grows automatically as new pickable providers ship). Empty by default — every project falls back to Claude. Change it from the project's three-dot menu → Edit → Default provider radios; the change persists immediately.
When you set a project's default to Anti-Gravity but Anti-Gravity isn't ready (toggle off or binary missing), an amber "!" badge appears on that project's sidebar row. Hover the badge for a tooltip explaining the gap; click it to deep-link straight to the right Settings panel. The badge re-checks on every render, so fixing the gap clears it without a refresh.
How it behaves
Choosing the model
Anti-Gravity has no per-session model picker — and never will. The agy CLI exposes no model flag; auth and model both live inside its own keyring (Google Sign-In), so Omniscio can't select a model for it. A fresh Anti-Gravity session shows no model dropdown — the provider-models registry deliberately leaves Anti-Gravity out, so an empty list renders no control rather than a dead one. See start-a-new-session.md.
Error states and fixes
Two gap codes — fewer than Gemini / Codex because there's no API key step:
| Gap | What it means | Click-to-fix lands you at… |
|---|---|---|
toggle-off |
"Allow Anti-Gravity sessions" is OFF in Settings | Settings → Account → Allow Anti-Gravity sessions toggle |
binary-missing |
agy CLI not on PATH or in known install paths |
Settings → Account → Anti-Gravity CLI binary panel |
If you're inside the dedicated __antigravity__ virtual project, the toggle-off gate is bypassed automatically — only binary-missing can stop the spawn there.
Signed out at turn time (no reply / empty bubble)
The two gaps above are checked before a spawn. A different failure happens during a turn: if agy is installed and the toggle is on but you are not signed in to Antigravity, agy --print launches an interactive Google sign-in, waits ~30 seconds, then exits "successfully" with no output at all (the auth error goes only to agy's own log). Earlier Omniscio builds showed this as a blank reply that quietly went back to "needs you" — no explanation.
Now any one-shot turn that finishes cleanly but produces zero output is surfaced as a real error row instead of a blank, and for Antigravity specifically Omniscio reads agy's own log and, when it sees the not-signed-in signature, shows: "Antigravity isn't signed in — open Settings → Accounts to sign in again." That row carries an "Open Anti-Gravity settings" button — clicking it jumps straight to Settings → Accounts → Anti-Gravity and flashes the row, so you don't navigate the named path by hand; click Sign in with Anti-Gravity there and re-send. The same one-tap "Open …" affordance appears on every provider sign-in/setup notice (Codex / Cursor / Pi / OpenCode / Claude "sign in again" / the Anthropic-compatible no-key rows) — see provider-setting-link-contract.md. This protects every one-shot engine (Cursor / OpenCode / Anti-Gravity) from the silent-empty-turn failure mode (Hermes migrated to persistent-external ACP 2026-08-01 and uses a different stall-detection path).
MCP servers — not available
Anti-Gravity sessions get none of your MCP servers, and this is an honest gap rather than a setting you are missing: agy is Google's own binary, so it does not read the .mcp.json Claude's spawn writes, and it exposes no MCP flag, config file or protocol field for Omniscio to translate into. The registry declares mcp: false for it, and the wiring grid's feature-mcp row marks it missing rather than pretending otherwise.
This is one of five engines in that position today — see no-channel-is-declared in provider-mcp-connector-contract.md, which lists each with the evidence for why. It is not the same defect that made managed tool servers invisible on the seven engines that do have a channel (Cursor, Codex, Gemini, Grok, Kimi Code, Hermes, DeepSeek Harness); that one was fixed 2026-09-28.
Comparison with Gemini
Anti-Gravity is Google's successor to Gemini CLI. From Omniscio's perspective:
| Concern | Gemini | Anti-Gravity |
|---|---|---|
| Auth | API key (env GEMINI_API_KEY injected per spawn) |
Google Sign-In via OS keyring (no env injection) |
| Streaming | NDJSON --output-format stream-json (token-by-token) |
Block mode (full reply at end-of-turn) |
| Multi-turn resume | Native --resume <uuid> |
Synthesized — Omniscio prepends prior turns into each prompt |
| Readiness gates | 3 (toggle + binary + key) | 2 (toggle + binary) |
| Binary install path | npm / volta / nvm | Standalone installer (%LOCALAPPDATA%\agy\bin / ~/.agy/bin) |
| Icon color | Violet | Sky-blue |
If you've used Gemini in Omniscio, the only behavior differences you'll notice in chat are (1) replies appear all-at-once instead of streaming, and (2) you sign in by clicking a button rather than pasting an API key.
For agents
How it works under the hood
Per-turn one-shot subprocess. For each user message Omniscio spawns, with the env CI=1 TERM=dumb NO_COLOR=1:
agy --print "<prompt>" --add-dir <workdir> --print-timeout 10m0s --log-file <temp>
Why the CI env (agy v1.0.9): on a plain stdout pipe — which Omniscio always gives the child via spawnCliChild — agy v1.0.9 hangs at startup and never reaches the model. CI=1 / TERM=dumb / NO_COLOR=1 make it believe it is non-interactive and run headless on the pipe. (This is also why Omniscio no longer passes --dangerously-skip-permissions: CI mode auto-approves tools, and that flag made the agent loop forever on non-coding prompts.)
Where the reply comes from (agy v1.0.9): in headless mode agy --print writes nothing to stdout — it records the whole turn to a per-conversation transcript on disk (~/.gemini/antigravity-cli/brain/<conv-id>/.system_generated/logs/transcript.jsonl). On a turn that exits cleanly with empty stdout, Omniscio reads that transcript: it captures the conversation id from agy's own --log-file (anchored on the literal Created conversation <id>, NOT the project-id line that shares the same uuid shape), then interprets the whole transcript (interpretAntigravityTranscript) and emits the model's real final reply — the last PLANNER_RESPONSE with text that has no pending tool call and no tool step after it (the clean reply a completed turn ends on). If the run was instead cut off mid-step — e.g. its Gemini backend hit a transient 429 "model overloaded", or it simply stopped before finishing — Omniscio does NOT surface the stray "I will view X next…" planning line that agy writes on every step; it shows an honest, retryable error row instead ("Antigravity's model was overloaded and the run was interrupted before finishing. Re-send to retry.", or a generic interrupted / no-final-answer variant). It also surfaces agy's tool activity — file reads, searches, subagents — as ▸ markers folded into the turn, so a multi-step run shows its work like the other engines. The recovered answer takes precedence: Omniscio reads the transcript FIRST and only when there is no reply does it check the log for the not-signed-in signature and surface the sign-in prompt (below). That order matters because agy logs a burst of benign "not logged into Antigravity" lines at startup on every run (its background pollers fire before the keyring loads), so a log scan would otherwise misread a perfectly successful turn as signed-out — which it did until 2026-06-30 (every signed-in turn was reported as "not signed in"). A turn ending with truly nothing on disk falls through to the shared empty-output error (an honest red row, never a blank). The older v1.0.0 "plain text on stdout" path is gone — see the post-mortem Update 2026-06-18 and Update 2026-06-30.
Why agy runs from the home directory (agy v1.0.13): the per-turn agy --print child is spawned with its working directory set to the user's home (homedir() on Windows), NOT the project folder — the project is delivered via --add-dir instead. agy v1.0.13 resolves its credentials and the transcript path as a drive-relative /Users/<name>/.gemini/... (it strips the drive letter), which on Windows resolves against the cwd's drive. If agy ran from a project on a non-C: drive (e.g. a Dev Drive), it would look for the signed-in token at <thatdrive>:\Users\... (nonexistent) → report "not signed in" even when you ARE signed in, and write its transcript to a dead path → every turn fails. Running from the home drive makes both resolve to the real %USERPROFILE%; the agent still reads/writes the project through --add-dir. See the post-mortem Update 2026-06-29.
There is no native conversation resume (no --resume <uuid> equivalent in agy v1.0.0). Omniscio achieves multi-turn by prepending the prior conversation into each prompt, and every prompt also leads with a short standing workspace guidance block:
[Workspace guidance:]
When creating or editing a file, write it directly to the requested path in a single step.
Do NOT run a recursive scan of a whole drive or large directory tree ... to find, measure,
or verify a file; that can hang the turn. Stay within the provided workspace directory.
[Previous conversation:]
User: What is 2+2?
Assistant: 4
User: And 3+3?
[New message:]
What about 5+5?
This is done by buildPromptWithHistory() in antigravity-session-manager.ts. Only operator and agent rows are included; system markers, tool blobs, and asides are filtered out. The history is capped at 50,000 characters — when the budget is exceeded the OLDEST entries are dropped, never the most recent. The workspace-guidance block (ANTIGRAVITY_WORKSPACE_GUIDANCE) is added fresh at prompt-build time on every turn — it is never persisted as a message, so it does not accumulate in history. It is a best-effort steer against a live-observed model flail (the headless model running a recursive whole-drive scan to "verify" a file, which hangs the turn until the print-timeout); see the post-mortem Update 2026-06-30 — workspace guidance.
Routing happens in session-handlers.ts: a SESSION_LAUNCH IPC with provider: 'antigravity' goes to antigravitySessionManager instead of processManager. The session row stores provider: 'antigravity' in the database column; the renderer's ProviderBadge reads that column and renders the Anti-Gravity icon.
Authentication flow: agy reads its credentials from the OS keyring on every spawn. Omniscio sets env: buildCleanSpawnEnv() (a sanitized environment with PATH and minimal vars) and explicitly does NOT inject any credential env var — there is no ANTIGRAVITY_API_KEY, no OAuth token. Whether the user is actually signed in is opaque to Omniscio before a turn runs.
When signed out, agy v1.0.8 does not report the auth failure on stdout/stderr — agy --print launches an interactive OAuth, times out after ~30s, then exits 0 with empty stdout AND empty stderr (the error goes only to agy's own --log-file). So Omniscio cannot rely on a non-zero exit or a stderr tail to detect it. Instead the runner passes agy --log-file <temp> and, only when a turn returns empty output, reads that log and matches the not-signed-in signature (detectAntigravityAuthFailure in antigravity-stream-translator.ts); on a match it surfaces the specific "Antigravity isn't signed in" message, otherwise the shared one-shot core's generic empty-output error. On an empty-output turn Omniscio reads the on-disk transcript reply FIRST (above) and consults this auth signature ONLY when no reply was recovered — so a genuine sign-out (which leaves no reply on disk) still surfaces the message, while a successful turn whose log carries agy's benign startup not-signed-in burst is never misread as signed-out. (Before 2026-06-30 the order was reversed, and because that burst appears on every run, every signed-in turn was wrongly reported as signed-out.) See the post-mortem Update 2026-06-16 (the empty-output guard), Update 2026-06-18 (the v1.0.9 pipe/transcript fix), and Update 2026-06-30 (the precedence fix), plus turn-conclusion-contract.md C2a.
Spawn safety: the per-turn child is spawned via spawnCliChild() so it inherits the Windows cmd.exe-quoting fix + Win32 Job Object assignment — if Omniscio crashes, the orphan agy process dies with it. The sign-in launcher deliberately does NOT use spawnCliChild() — instead it opens a new visible terminal window (cmd /c start "" cmd /k … on Windows, osascript Terminal on macOS) and spawns it detached + unref'd so the OAuth terminal owns its own lifecycle. agy's interactive sign-in is a TUI that needs a real console; attaching it to Omniscio's Job Object would kill it when Omniscio quits. (A prior bug spawned it detached with stdio:'ignore' and no console, so the prompt had nowhere to render and silently died — see provider-registry-contract.md.)
Telemetry: every successful non-Claude spawn fires the spawn_non_claude_session feature event, recording { provider: 'antigravity' } only — no session ID, project ID, or prompt content.
Files
- src/main/services/engines/antigravity-session-manager.ts — multi-turn orchestration + history prepending
- src/main/process/antigravity-turn-runner.ts — per-turn spawn
- src/main/process/antigravity-stream-translator.ts — pure result builder + the not-signed-in detector, conversation-id parser, and whole-transcript interpreter (
interpretAntigravityTranscript— real final answer vs. honest interrupted verdict vs.▸tool-activity markers) - src/main/services/engines/antigravity-binary-resolver.ts — binary discovery (PATH first, install locations fallback)
- src/main/services/engines/antigravity-auth-store.ts — sign-in launcher (no credentials stored — agy owns its own keyring)
- src/main/services/provider-setup/provider-readiness.ts — single source of truth for the 2-gate readiness check (used by ChangeProviderButton, Edit Project radios, project-row cue, spawn guard)
- src/renderer/src/features/sessions/ProviderSplitButton.tsx — sidebar "+ New Session" button (spawns the project default; no provider picker)
- src/renderer/src/features/sessions/ChangeProviderButton.tsx — per-launch provider override on a fresh session header
- src/renderer/src/features/sessions/ProviderBadge.tsx — Anti-Gravity icon in session header
Related
- gemini-provider.md — comparable provider with native NDJSON streaming and API-key auth
- codex-provider.md — same launcher / readiness model, different binary (JSON-RPC long-lived child)
- openclaw-provider.md — separate "alternative provider" model (remote WebSocket gateway, not a local CLI)
Last verified 2026-10-06