cd /news/ai-tools/oh-my-pi-enable-antigravity · home › topics › ai-tools › article
[ARTICLE · art-167137] src=gist.github.com ↗ pub= topic=ai-tools verified=true sentiment=· neutral

oh my pi enable antigravity

A developer published an extension for oh-my-pi (version 18.18.4 and later) that re-enables Google Antigravity logins and models after upstream PR #18622 added a `disabled` rule to the google-antigravity catalog entry. The extension strips the restrictive auth policy hooks, wraps the provider definition to bypass the free-tier eligibility check, and resolves a project ID via the loadCodeAssist endpoint, falling back to "aicode-consumers" when none is found.

by read4 min views1 publishedNov 10, 2026

| | /** | | | * Extension to re-enable Google Antigravity logins and models in oh-my-pi >= 18.18.4, | | | * and bypass the artificial "ineligible account" location/free-tier block. | | | * | | | * Upstream PR #18622 added a disabled rule to google-antigravity in the catalog, | | | * and google-antigravity-project has a rigid check that throws if free-tier is | | | * flagged as ineligible, even when the user has valid OAuth credentials, paid tier, | | | * or an active cloudaicompanionProject. | | | */ |

|  | import * as compatAuth from "@oh-my-pi/pi-catalog/compat/auth"; | 
|  | import { getProviderDefinition, registerOAuthProvider } from "@oh-my-pi/pi-ai"; | 
|  | import { Database } from "bun:sqlite"; | 
|  | import { getAgentDbPath } from "@oh-my-pi/pi-utils"; | 

| | // 1. Clear d status and remove restrictive built-in hooks |

|  | const policy = compatAuth.authPolicyFor("google-antigravity"); | 
|  | if (policy) { | 
|  | delete (policy as any).disabled; | 
|  | if (policy.login) { | 
|  | delete (policy.login as any).afterExchange; | 

| | } |

|  | if (policy.refresh) { | 
|  | delete (policy.refresh as any).afterRefresh; | 

| | } | | | } | | | // 2. Wrap provider definition to bypass the eligibility check |

|  | const def = getProviderDefinition("google-antigravity"); | 
|  | const formatApiKey = (creds: any) => | 
|  | JSON.stringify({ | 

| | token: creds.access, | | | projectId: creds.projectId, | | | refreshToken: creds.refresh, | | | expiresAt: creds.expires, | | | email: creds.email, | | | accountId: creds.accountId, |

|  | }); | 
|  | if (def && def.login) { | 

| | const originalLogin = def.login; | | | const originalRefreshToken = def.refreshToken; | | | const resolveProjectId = async ( | | | accessToken: string, | | | onProgress?: (msg: string) => void, | | | signal?: AbortSignal | | | ): Promise<string> => { | | | let projectId = | | | process.env.GOOGLE_CLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT_ID; | | | if (!projectId) { | | | onProgress?.("Checking Antigravity project status..."); | | | try { |

|  | const res = await fetch( | 
|  | "https://daily-cloudcode-pa.googleapis.com/v1internal:loadCodeAssist", | 

| | { | | | method: "POST", |

|  | headers: { | 
|  | Authorization: `Bearer ${accessToken}`, | 

| | "Content-Type": "application/json", | | | "User-Agent": "antigravity", | | | }, | | | body: JSON.stringify({ metadata: { ideType: "ANTIGRAVITY" } }), | | | signal, | | | } |

|  | ); | 
|  | if (res.ok) { | 
|  | const data = (await res.json()) as any; | 

| | projectId = | | | typeof data.cloudaicompanionProject === "string" | | | ? data.cloudaicompanionProject | | | : data.cloudaicompanionProject?.id; | | | } | | | } catch {} | | | } | | | return projectId || "aicode-consumers"; |

|  | }; | 
|  | const customLogin = async (ctrl: any) => { | 

| | // def.login handles local callback server and OAuth token exchange with Google | | | const creds = await originalLogin(ctrl); | | | // Resolve project without the artificial free-tier location eligibility block | | | const projectId = | | | creds.projectId || | | | (await resolveProjectId(creds.access, ctrl.onProgress, ctrl.signal)); | | | return { | | | ...creds, | | | projectId, |

|  | }; | 
|  | }; | 
|  | const customRefreshToken = async (creds: any, signal?: AbortSignal) => { | 
|  | const refreshed = await originalRefreshToken(creds, signal); | 

| | return { | | | ...refreshed, | | | projectId: creds.projectId || refreshed.projectId || "aicode-consumers", |

|  | }; | 
|  | }; | 
|  | registerOAuthProvider({ | 
|  | id: "google-antigravity", | 

| | name: def.name, | | | login: customLogin, | | | refreshToken: customRefreshToken, | | | getApiKey: formatApiKey, |

|  | }); | 
|  | registerOAuthProvider({ | 

| | id: "antigravity", | | | name: def.name, | | | storeCredentialsAs: "google-antigravity", | | | login: customLogin, | | | refreshToken: customRefreshToken, | | | getApiKey: formatApiKey, | | | }); | | | } | | | // 3. Bump auth_change_revision so CredentialPool picks up credentials | | | try { |

|  | const db = new Database(getAgentDbPath()); | 
|  | db.run("UPDATE auth_change_revision SET revision = revision + 1 WHERE id = 1"); | 
|  | db.close(); | 
|  | } catch {} | 
|  | export default function (api: any) { | 
|  | if (api.extension) { | 

| | api.extension.registersProviders = true; | | | } |

|  | api.on("session_start", async (_event: any, ctx: any) => { | 
|  | if (ctx.model && ctx.model.provider !== "google-antigravity") { | 
|  | const target = ctx.modelRegistry.find("google-antigravity", "gemini-3.8-flash"); | 
|  | if (target) { | 
|  | await api.runtime.setModel(target); | 

| | } | | | } | | | }); | | | } |

── more in #ai-tools 4 stories · sorted by recency
── more on @google 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/oh-my-pi-enable-anti…] indexed:0 read:4min 2026-11-10 · —