/**
* Antigravity wire constants and header spoofing.
* Copied from oh-my-pi's pi-catalog wire/gemini-headers module.
*/
import type { GoogleThinkingConfig, GoogleThinkingLevel } from "./helpers.js";
export const ANTIGRAVITY_DAILY_ENDPOINT = "https://daily-cloudcode-pa.googleapis.com";
export const ANTIGRAVITY_SANDBOX_ENDPOINT = "https://daily-cloudcode-pa.sandbox.googleapis.com";
export const ANTIGRAVITY_ENDPOINT_FALLBACKS = [ANTIGRAVITY_DAILY_ENDPOINT, ANTIGRAVITY_SANDBOX_ENDPOINT] as const;
export const CLAUDE_THINKING_BETA_HEADER = "interleaved-thinking-2025-05-14";
/**
* User agent format captured from the real antigravity/hub client:
* `antigravity/hub/2.8.0 (aidev_client; os_type=darwin; arch=arm64; cl=963137146)`.
* The backend gates newer models on the client version. os_type/arch are pinned
* to the darwin/arm64 reference client, independent of the host platform.
*/
export const DEFAULT_ANTIGRAVITY_VERSION = "2.8.0";
const ANTIGRAVITY_VERSION_MANIFEST_URL =
"https://antigravity-hub-auto-updater-974169037036.us-central1.run.app/manifest/latest-arm64-mac.yml";
const ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS = 5_000;
let discoveredAntigravityVersion: string | null = null;
let antigravityVersionFetch: Promise<void> | null = null;
export function getAntigravityVersion(): string {
return process.env.PI_AI_ANTIGRAVITY_VERSION || discoveredAntigravityVersion || DEFAULT_ANTIGRAVITY_VERSION;
}
export function parseAntigravityManifestVersion(yamlText: string): string | null {
for (const line of yamlText.split(/\r?\n/)) {
const match = /^\s*version\s*:\s*(?:"([^"]*)"|'([^']*)'|([^\s#]+))\s*(?:#.*)?$/.exec(line);
if (!match) continue;
const version = (match[1] ?? match[2] ?? match[3] ?? "").trim();
return /^\d+\.\d+\.\d+$/.test(version) ? version : null;
}
return null;
}
export function ensureAntigravityVersion(fetcher: typeof fetch = fetch, signal?: AbortSignal): Promise<void> {
if (process.env.PI_AI_ANTIGRAVITY_VERSION || discoveredAntigravityVersion) return Promise.resolve();
if (antigravityVersionFetch) return antigravityVersionFetch;
antigravityVersionFetch = (async () => {
try {
const timeoutSignal = AbortSignal.timeout(ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS);
const response = await fetcher(ANTIGRAVITY_VERSION_MANIFEST_URL, {
headers: { "Cache-Control": "no-cache", "User-Agent": "electron-builder" },
signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal,
});
if (response.ok) {
discoveredAntigravityVersion = parseAntigravityManifestVersion(await response.text());
}
} catch {
// Silent: the pinned fallback remains valid when version discovery fails.
} finally {
if (!discoveredAntigravityVersion) antigravityVersionFetch = null;
}
})();
return antigravityVersionFetch;
}
export function getAntigravityUserAgent(): string {
const version = getAntigravityVersion();
// The backend does not validate `cl`; only the version gates models.
const cl = process.env.PI_AI_ANTIGRAVITY_CL || "963137146";
const os = process.env.PI_AI_ANTIGRAVITY_OS || "darwin";
const arch = process.env.PI_AI_ANTIGRAVITY_ARCH || "arm64";
return `antigravity/hub/${version} (aidev_client; os_type=${os}; arch=${arch}; cl=${cl})`;
}
export interface AntigravityModelWireProfile {
modelEnum?: string;
maxOutputTokens: number;
}
/**
* Per-wire-id Antigravity request constants, captured from the real
* antigravity/hub client. `modelEnum` is the opaque labels.model_enum token;
* Anthropic-backed wire ids are accepted without one.
*/
export const ANTIGRAVITY_MODEL_WIRE_PROFILES: Readonly<Record<string, AntigravityModelWireProfile>> = {
"gemini-3.5-flash-extra-low": { modelEnum: "MODEL_PLACEHOLDER_M187", maxOutputTokens: 65536 },
"gemini-3.5-flash-low": { modelEnum: "MODEL_PLACEHOLDER_M20", maxOutputTokens: 65536 },
"gemini-3-flash-agent": { modelEnum: "MODEL_PLACEHOLDER_M132", maxOutputTokens: 65536 },
"gemini-3.1-pro-low": { modelEnum: "MODEL_PLACEHOLDER_M36", maxOutputTokens: 65535 },
"gemini-pro-agent": { modelEnum: "MODEL_PLACEHOLDER_M16", maxOutputTokens: 65535 },
"claude-sonnet-4-6": { maxOutputTokens: 64000 },
"claude-opus-4-6-thinking": { maxOutputTokens: 64000 },
};
export function getAntigravityModelWireProfile(wireModelId: string): AntigravityModelWireProfile | undefined {
return ANTIGRAVITY_MODEL_WIRE_PROFILES[wireModelId];
}
export interface AntigravityThinkingOptions {
enabled: boolean;
budgetTokens?: number;
level?: GoogleThinkingLevel;
suppress?: { level: GoogleThinkingLevel } | { budget: number };
}
export interface AntigravityWireGenerationConfig {
maxOutputTokens?: number;
temperature?: number;
topP?: number;
topK?: number;
minP?: number;
presencePenalty?: number;
repetitionPenalty?: number;
thinkingConfig?: GoogleThinkingConfig;
}