@cortexkit/pi-antigravity-auth 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/src/logger.ts", "../../core/src/constants.ts", "../../core/src/auth.ts", "../../core/src/fingerprint.ts", "../../core/src/agy-transport.ts", "../../core/src/project.ts", "../../core/src/model-registry.ts", "../../core/src/transform/model-resolver.ts", "../../../node_modules/jose/dist/node/esm/runtime/base64url.js", "../../../node_modules/jose/dist/node/esm/lib/buffer_utils.js", "../../../node_modules/jose/dist/node/esm/util/base64url.js", "../../../node_modules/@openauthjs/openauth/dist/esm/pkce.js", "../../core/src/antigravity/oauth.ts", "../src/stream.ts", "../src/convert.ts", "../src/index.ts"],
4
+ "sourcesContent": ["/**\n * Harness-agnostic structured logger for the Antigravity core.\n *\n * Core code never talks to a specific harness UI. Instead it emits log\n * records to a pluggable sink. Harnesses (OpenCode, pi) register their own\n * sink via `setLogSink()` to route logs into their TUI/log panel. When no\n * sink is registered, an env-gated console fallback is used.\n */\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\"\n\nexport interface Logger {\n debug(message: string, extra?: Record<string, unknown>): void\n info(message: string, extra?: Record<string, unknown>): void\n warn(message: string, extra?: Record<string, unknown>): void\n error(message: string, extra?: Record<string, unknown>): void\n}\n\nexport interface LogRecord {\n service: string\n level: LogLevel\n message: string\n extra?: Record<string, unknown>\n}\n\nexport type LogSink = (record: LogRecord) => void\n\nconst ENV_CONSOLE_LOG = \"ANTIGRAVITY_CORE_CONSOLE_LOG\"\n\nlet _sink: LogSink | null = null\n\n/**\n * Register the harness-specific log sink. Pass `null` to clear it.\n */\nexport function setLogSink(sink: LogSink | null): void {\n _sink = sink\n}\n\nfunction isTruthyFlag(flag?: string): boolean {\n return flag === \"1\" || flag?.toLowerCase() === \"true\"\n}\n\nfunction isConsoleLogEnabled(): boolean {\n return isTruthyFlag(process.env[ENV_CONSOLE_LOG])\n}\n\nfunction writeConsoleLog(level: LogLevel, ...args: unknown[]): void {\n switch (level) {\n case \"debug\":\n console.debug(...args)\n break\n case \"info\":\n console.info(...args)\n break\n case \"warn\":\n console.warn(...args)\n break\n case \"error\":\n console.error(...args)\n break\n }\n}\n\n/**\n * Create a logger for a specific module. Records are forwarded to the\n * registered sink, with an env-gated console fallback.\n */\nexport function createLogger(module: string): Logger {\n const service = `antigravity.${module}`\n\n const log = (level: LogLevel, message: string, extra?: Record<string, unknown>): void => {\n if (_sink) {\n try {\n _sink({ service, level, message, extra })\n } catch {\n // Never let logging failures break core logic.\n }\n }\n\n if (isConsoleLogEnabled()) {\n const prefix = `[${service}]`\n const args = extra ? [prefix, message, extra] : [prefix, message]\n writeConsoleLog(level, ...args)\n }\n }\n\n return {\n debug: (message, extra) => log(\"debug\", message, extra),\n info: (message, extra) => log(\"info\", message, extra),\n warn: (message, extra) => log(\"warn\", message, extra),\n error: (message, extra) => log(\"error\", message, extra),\n }\n}\n", "/**\n * Constants used for Antigravity OAuth flows and Cloud Code Assist API integration.\n */\nexport const ANTIGRAVITY_CLIENT_ID = \"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com\";\n\n/**\n * Client secret issued for the Antigravity OAuth application.\n */\nexport const ANTIGRAVITY_CLIENT_SECRET = \"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\";\n\n/**\n * Scopes required for Antigravity integrations.\n */\nexport const ANTIGRAVITY_SCOPES: readonly string[] = [\n \"https://www.googleapis.com/auth/cloud-platform\",\n \"https://www.googleapis.com/auth/userinfo.email\",\n \"https://www.googleapis.com/auth/userinfo.profile\",\n \"https://www.googleapis.com/auth/cclog\",\n \"https://www.googleapis.com/auth/experimentsandconfigs\",\n];\n\n/**\n * OAuth redirect URI used by the local CLI callback server.\n */\nexport const ANTIGRAVITY_REDIRECT_URI = \"http://localhost:51121/oauth-callback\";\n\n/**\n * Root endpoints for the Antigravity API (in fallback order).\n * Live agy CLI 1.0.4 traffic uses daily-cloudcode-pa.googleapis.com.\n */\nexport const ANTIGRAVITY_ENDPOINT_DAILY = \"https://daily-cloudcode-pa.googleapis.com\";\nexport const ANTIGRAVITY_ENDPOINT_AUTOPUSH = \"https://autopush-cloudcode-pa.sandbox.googleapis.com\";\nexport const ANTIGRAVITY_ENDPOINT_PROD = \"https://cloudcode-pa.googleapis.com\";\n\n/**\n * Endpoint fallback order (daily \u2192 prod).\n * Autopush removed to reduce unnecessary fallback API calls \u2014 it rarely works when daily fails.\n * Shared across request handling and project discovery to mirror CLIProxy behavior.\n */\nexport const ANTIGRAVITY_ENDPOINT_FALLBACKS = [\n ANTIGRAVITY_ENDPOINT_DAILY,\n ANTIGRAVITY_ENDPOINT_PROD,\n] as const;\n/**\n * Preferred endpoint order for project discovery.\n * agy CLI probes daily-cloudcode-pa.googleapis.com first.\n */\nexport const ANTIGRAVITY_LOAD_ENDPOINTS = [\n ANTIGRAVITY_ENDPOINT_DAILY,\n ANTIGRAVITY_ENDPOINT_PROD,\n] as const;\n/**\n * Primary endpoint to use (captured agy CLI daily endpoint).\n */\nexport const ANTIGRAVITY_ENDPOINT = ANTIGRAVITY_ENDPOINT_DAILY;\n\n/**\n * Gemini CLI endpoint (production).\n * Used for models without :antigravity suffix.\n * Same as opencode-gemini-auth's GEMINI_CODE_ASSIST_ENDPOINT.\n */\nexport const GEMINI_CLI_ENDPOINT = ANTIGRAVITY_ENDPOINT_PROD;\n\n/**\n * Hardcoded project id used when Antigravity does not return one (e.g., business/workspace accounts).\n */\nexport const ANTIGRAVITY_DEFAULT_PROJECT_ID = \"rising-fact-p41fc\";\n\nexport const ANTIGRAVITY_VERSION_FALLBACK = \"1.18.3\";\nlet antigravityVersion = ANTIGRAVITY_VERSION_FALLBACK;\nlet versionLocked = false;\n\nexport function getAntigravityVersion(): string { return antigravityVersion; }\n\n/**\n * Set the runtime Antigravity version. Can only be called once (at startup).\n * Subsequent calls are silently ignored to prevent accidental mutation.\n */\nexport function setAntigravityVersion(version: string): void {\n if (versionLocked) return;\n antigravityVersion = version;\n versionLocked = true;\n}\n\n/** @deprecated Use getAntigravityVersion() for runtime access. */\nexport const ANTIGRAVITY_VERSION = ANTIGRAVITY_VERSION_FALLBACK;\n\nexport function getAntigravityHeaders(): HeaderSet & { \"Client-Metadata\": string } {\n return {\n \"User-Agent\": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/${getAntigravityVersion()} Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36`,\n \"X-Goog-Api-Client\": \"google-cloud-sdk vscode_cloudshelleditor/0.1\",\n \"Client-Metadata\": `{\"ideType\":\"ANTIGRAVITY\",\"platform\":\"${process.platform === \"win32\" ? \"WINDOWS\" : \"MACOS\"}\",\"pluginType\":\"GEMINI\"}`,\n };\n}\n\n/** @deprecated Use getAntigravityHeaders() for runtime access. */\nexport const ANTIGRAVITY_HEADERS = {\n \"User-Agent\": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Antigravity/${ANTIGRAVITY_VERSION} Chrome/138.0.7204.235 Electron/37.3.1 Safari/537.36`,\n \"X-Goog-Api-Client\": \"google-cloud-sdk vscode_cloudshelleditor/0.1\",\n \"Client-Metadata\": `{\"ideType\":\"ANTIGRAVITY\",\"platform\":\"${process.platform === \"win32\" ? \"WINDOWS\" : \"MACOS\"}\",\"pluginType\":\"GEMINI\"}`,\n} as const;\n\nexport const GEMINI_CLI_VERSION = \"1.0.0\";\n\n/**\n * Default model used in Gemini CLI User-Agent when no model is specified.\n */\nexport const GEMINI_CLI_DEFAULT_MODEL = \"gemini-2.5-pro\";\n\n/**\n * Build Gemini CLI User-Agent string matching the official google-gemini/gemini-cli format.\n * Format: `GeminiCLI/{version}/{model} ({platform}; {arch})`\n *\n * @see https://github.com/google-gemini/gemini-cli\n */\nexport function buildGeminiCliUserAgent(model?: string): string {\n const effectiveModel = model || GEMINI_CLI_DEFAULT_MODEL;\n const platform = process.platform || \"darwin\";\n const arch = process.arch || \"arm64\";\n return `GeminiCLI/${GEMINI_CLI_VERSION}/${effectiveModel} (${platform}; ${arch})`;\n}\n\n/** @deprecated Use buildGeminiCliUserAgent() for runtime access. */\nexport const GEMINI_CLI_HEADERS = {\n \"User-Agent\": \"google-api-nodejs-client/9.15.1\",\n \"X-Goog-Api-Client\": \"gl-node/22.17.0\",\n \"Client-Metadata\": \"ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI\",\n} as const;\nfunction buildAntigravityPlatformArch(): string {\n const platform = process.platform === \"win32\" ? \"windows\" : process.platform || \"unknown\";\n const arch = process.arch === \"x64\" ? \"amd64\" : process.arch === \"ia32\" ? \"386\" : process.arch || \"unknown\";\n return `${platform}/${arch}`;\n}\n\nexport type HeaderSet = {\n \"User-Agent\": string;\n \"X-Goog-Api-Client\"?: string;\n \"Client-Metadata\"?: string;\n};\n\nexport function getRandomizedHeaders(style: HeaderStyle, model?: string): HeaderSet {\n if (style === \"gemini-cli\") {\n return {\n \"User-Agent\": buildGeminiCliUserAgent(model),\n \"X-Goog-Api-Client\": GEMINI_CLI_HEADERS[\"X-Goog-Api-Client\"],\n \"Client-Metadata\": GEMINI_CLI_HEADERS[\"Client-Metadata\"],\n };\n }\n const platform = buildAntigravityPlatformArch();\n return {\n \"User-Agent\": `antigravity/cli/1.0.4 ${platform}`,\n };\n}\n\nexport type HeaderStyle = \"antigravity\" | \"gemini-cli\";\n\n/**\n * Provider identifier shared between the plugin loader and credential store.\n */\nexport const ANTIGRAVITY_PROVIDER_ID = \"google\";\n\n// ============================================================================\n// TOOL HALLUCINATION PREVENTION (Ported from LLM-API-Key-Proxy)\n// ============================================================================\n\n/**\n * System instruction for Claude tool usage hardening.\n * Prevents hallucinated parameters by explicitly stating the rules.\n * \n * This is injected when tools are present to reduce cases where Claude\n * uses parameter names from its training data instead of the actual schema.\n */\nexport const CLAUDE_TOOL_SYSTEM_INSTRUCTION = `CRITICAL TOOL USAGE INSTRUCTIONS:\nYou are operating in a custom environment where tool definitions differ from your training data.\nYou MUST follow these rules strictly:\n\n1. DO NOT use your internal training data to guess tool parameters\n2. ONLY use the exact parameter structure defined in the tool schema\n3. Parameter names in schemas are EXACT - do not substitute with similar names from your training\n4. Array parameters have specific item types - check the schema's 'items' field for the exact structure\n5. When you see \"STRICT PARAMETERS\" in a tool description, those type definitions override any assumptions\n6. Tool use in agentic workflows is REQUIRED - you must call tools with the exact parameters specified\n\nIf you are unsure about a tool's parameters, YOU MUST read the schema definition carefully.`;\n\n/**\n * Template for parameter signature injection into tool descriptions.\n * {params} will be replaced with the actual parameter list.\n */\nexport const CLAUDE_DESCRIPTION_PROMPT = \"\\n\\n\u26A0\uFE0F STRICT PARAMETERS: {params}.\";\n\nexport const EMPTY_SCHEMA_PLACEHOLDER_NAME = \"_placeholder\";\nexport const EMPTY_SCHEMA_PLACEHOLDER_DESCRIPTION = \"Placeholder. Always pass true.\";\n\n/**\n * Sentinel value to bypass thought signature validation.\n * \n * When a thinking block has an invalid or missing signature (e.g., cache miss,\n * session mismatch, plugin restart), this sentinel can be injected to skip\n * validation instead of failing with \"Invalid signature in thinking block\".\n * \n * This is an officially supported Google API feature, used by:\n * - gemini-cli: https://github.com/google-gemini/gemini-cli\n * - Google .NET SDK: PredictionServiceChatClient.cs\n * \n * @see https://ai.google.dev/gemini-api/docs/thought-signatures\n */\nexport const SKIP_THOUGHT_SIGNATURE = \"skip_thought_signature_validator\";\n\n// ============================================================================\n// GOOGLE SEARCH TOOL CONSTANTS\n// ============================================================================\n\n/**\n * Model used for Google Search grounding requests.\n * Uses gemini-2.5-flash for fast, cost-effective search operations. (3-flash is always at capacity and doesn't support souce citation).\n */\nexport const SEARCH_MODEL = \"gemini-2.5-flash\";\n\n/**\n * Thinking budget for deep search (more thorough analysis).\n */\nexport const SEARCH_THINKING_BUDGET_DEEP = 16384;\n\n/**\n * Thinking budget for fast search (quick results).\n */\nexport const SEARCH_THINKING_BUDGET_FAST = 4096;\n\n/**\n * Timeout for search requests in milliseconds (60 seconds).\n */\nexport const SEARCH_TIMEOUT_MS = 60000;\n\n/**\n * System instruction for the Google Search tool.\n */\nexport const SEARCH_SYSTEM_INSTRUCTION = `You are an expert web search assistant with access to Google Search and URL analysis tools.\n\nYour capabilities:\n- Use google_search to find real-time information from the web\n- Use url_context to fetch and analyze content from specific URLs when provided\n\nGuidelines:\n- Always provide accurate, well-sourced information\n- Cite your sources when presenting facts\n- If analyzing URLs, extract the most relevant information\n- Be concise but comprehensive in your responses\n- If information is uncertain or conflicting, acknowledge it\n- Focus on answering the user's question directly`;\n\n", "import type { OAuthAuthDetails, RefreshParts } from \"./auth-types.ts\";\n\nconst ACCESS_TOKEN_EXPIRY_BUFFER_MS = 60 * 1000;\n\nexport function isOAuthAuth(auth: unknown): auth is OAuthAuthDetails {\n return typeof auth === \"object\" && auth !== null && \"type\" in auth && auth.type === \"oauth\";\n}\n\n/**\n * Splits a packed refresh string into its constituent refresh token and project IDs.\n */\nexport function parseRefreshParts(refresh: string): RefreshParts {\n const [refreshToken = \"\", projectId = \"\", managedProjectId = \"\"] = (refresh ?? \"\").split(\"|\");\n return {\n refreshToken,\n projectId: projectId || undefined,\n managedProjectId: managedProjectId || undefined,\n };\n}\n\n/**\n * Serializes refresh token parts into the stored string format.\n */\nexport function formatRefreshParts(parts: RefreshParts): string {\n const projectSegment = parts.projectId ?? \"\";\n const base = `${parts.refreshToken}|${projectSegment}`;\n return parts.managedProjectId ? `${base}|${parts.managedProjectId}` : base;\n}\n\n/**\n * Determines whether an access token is expired or missing, with buffer for clock skew.\n */\nexport function accessTokenExpired(auth: OAuthAuthDetails): boolean {\n if (!auth.access || typeof auth.expires !== \"number\") {\n return true;\n }\n return auth.expires <= Date.now() + ACCESS_TOKEN_EXPIRY_BUFFER_MS;\n}\n\n/**\n * Calculates absolute expiry timestamp based on a duration.\n * @param requestTimeMs The local time when the request was initiated\n * @param expiresInSeconds The duration returned by the server\n */\nexport function calculateTokenExpiry(requestTimeMs: number, expiresInSeconds: unknown): number {\n const seconds = typeof expiresInSeconds === \"number\" ? expiresInSeconds : 3600;\n // Safety check for bad data - if it's not a positive number, treat as immediately expired\n if (isNaN(seconds) || seconds <= 0) {\n return requestTimeMs;\n }\n return requestTimeMs + seconds * 1000;\n}\n", "/**\n * Device Fingerprint Generator for Rate Limit Mitigation\n *\n * Uses the agy CLI content-request identity captured with mitmproxy:\n * a short Antigravity CLI User-Agent with a normalized runtime platform tuple.\n * The stored deviceId/sessionToken fields are\n * retained for account history, but content requests only send User-Agent.\n */\n\nimport * as crypto from \"node:crypto\";\n\nexport const AGY_CLI_VERSION = \"1.0.4\";\nconst ANTIGRAVITY_API_CLIENT = \"antigravity-cli\";\n\nexport interface ClientMetadata {\n ideType: string;\n platform: string;\n pluginType: string;\n}\n\nexport interface Fingerprint {\n deviceId: string;\n sessionToken: string;\n userAgent: string;\n apiClient: string;\n clientMetadata: ClientMetadata;\n createdAt: number;\n}\n/**\n * Fingerprint version for history tracking.\n * Stores a snapshot of a fingerprint with metadata about when/why it was saved.\n */\nexport interface FingerprintVersion {\n fingerprint: Fingerprint;\n timestamp: number;\n reason: 'initial' | 'regenerated' | 'restored';\n}\n\n/** Maximum number of fingerprint versions to keep per account */\nexport const MAX_FINGERPRINT_HISTORY = 5;\n\nexport interface FingerprintHeaders {\n \"User-Agent\": string;\n}\n\nfunction normalizeHarnessPlatform(platform = process.platform): string {\n return platform === \"win32\" ? \"windows\" : platform || \"unknown\";\n}\n\nfunction normalizeHarnessArch(arch = process.arch): string {\n switch (arch) {\n case \"x64\":\n return \"amd64\";\n case \"ia32\":\n return \"386\";\n default:\n return arch || \"unknown\";\n }\n}\n\nexport function buildAntigravityHarnessPlatformArch(\n platform = process.platform,\n arch = process.arch,\n): string {\n return `${normalizeHarnessPlatform(platform)}/${normalizeHarnessArch(arch)}`;\n}\n\nexport function buildAntigravityHarnessUserAgent(\n version = AGY_CLI_VERSION,\n platform = process.platform,\n arch = process.arch,\n): string {\n return `antigravity/cli/${version} ${buildAntigravityHarnessPlatformArch(platform, arch)}`;\n}\n\nexport function buildAntigravityHarnessLoadCodeAssistUserAgent(version = AGY_CLI_VERSION): string {\n return buildAntigravityHarnessUserAgent(version);\n}\n\nfunction platformToMetadataPlatform(platform: string = process.platform): \"WINDOWS\" | \"MACOS\" {\n return platform === \"win32\" ? \"WINDOWS\" : \"MACOS\";\n}\n\nexport function buildAntigravityLoadCodeAssistMetadata(): Record<string, string> {\n return { ideType: \"ANTIGRAVITY\" };\n}\n\nexport function buildAntigravityHarnessBootstrapHeaders(accessToken: string): Record<string, string> {\n return {\n \"User-Agent\": buildAntigravityHarnessLoadCodeAssistUserAgent(),\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n };\n}\n\nfunction generateDeviceId(): string {\n return crypto.randomUUID();\n}\n\nfunction generateSessionToken(): string {\n return crypto.randomBytes(16).toString(\"hex\");\n}\n\n/**\n * Generate the per-account content-request fingerprint.\n * The outward HTTP identity is stable; deviceId/sessionToken remain unique for history.\n */\nexport function generateFingerprint(): Fingerprint {\n return {\n deviceId: generateDeviceId(),\n sessionToken: generateSessionToken(),\n userAgent: buildAntigravityHarnessUserAgent(),\n apiClient: ANTIGRAVITY_API_CLIENT,\n clientMetadata: {\n ideType: \"ANTIGRAVITY\",\n platform: platformToMetadataPlatform(),\n pluginType: \"GEMINI\",\n },\n createdAt: Date.now(),\n };\n}\n\n/**\n * Collect the current content-request fingerprint.\n */\nexport function collectCurrentFingerprint(): Fingerprint {\n return generateFingerprint();\n}\n\n/**\n * Update a saved fingerprint's User-Agent to the current Antigravity\n * agy CLI identity. This migrates older randomized fingerprints such as\n * win32/x64 to the captured CLI-compatible platform/arch form.\n * Returns true if the User-Agent was changed.\n */\nexport function updateFingerprintVersion(fingerprint: Fingerprint): boolean {\n const userAgent = buildAntigravityHarnessUserAgent();\n if (fingerprint.userAgent === userAgent) {\n return false;\n }\n\n fingerprint.userAgent = userAgent;\n return true;\n}\n\n/**\n * Build HTTP headers from a fingerprint object.\n * These headers are used to identify the \"device\" making API requests.\n */\nexport function buildFingerprintHeaders(fingerprint: Fingerprint | null): Partial<FingerprintHeaders> {\n if (!fingerprint) {\n return {};\n }\n\n return {\n \"User-Agent\": fingerprint.userAgent,\n };\n}\n\n/**\n * Session-level fingerprint instance.\n * Generated once at module load, persists for the lifetime of the process.\n */\nlet sessionFingerprint: Fingerprint | null = null;\n\n/**\n * Get or create the session fingerprint.\n * Returns the same fingerprint for all calls within a session.\n */\nexport function getSessionFingerprint(): Fingerprint {\n if (!sessionFingerprint) {\n sessionFingerprint = generateFingerprint();\n }\n return sessionFingerprint;\n}\n\n/**\n * Regenerate the session fingerprint.\n * Call this to get a fresh identity (e.g., after rate limiting).\n */\nexport function regenerateSessionFingerprint(): Fingerprint {\n sessionFingerprint = generateFingerprint();\n return sessionFingerprint;\n}\n", "import * as net from \"node:net\"\nimport * as tls from \"node:tls\"\nimport { Buffer } from \"node:buffer\"\nimport { PassThrough, Readable, Transform } from \"node:stream\"\nimport { createGunzip } from \"node:zlib\"\n\nconst DEFAULT_HTTPS_PORT = 443\nconst DEFAULT_PROXY_PORT = 8080\n\nexport const DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS = 180_000\n\nexport type AgyTransportOptions = {\n /**\n * Maximum time to wait for the request to connect and receive HTTP response headers.\n * The response body/stream is not bounded by this timeout.\n */\n timeoutMs?: number\n signal?: AbortSignal | null\n onDebug?: (message: string) => void\n}\n\ntype HeaderPair = readonly [string, string]\n\ntype ParsedResponseHead = {\n status: number\n statusText: string\n headers: Headers\n chunked: boolean\n gzip: boolean\n}\n\nfunction headersToRecord(headers?: HeadersInit): Record<string, string> {\n const result: Record<string, string> = {}\n if (!headers) return result\n\n const normalized = new Headers(headers)\n normalized.forEach((value, key) => {\n result[key.toLowerCase()] = value\n })\n return result\n}\n\nfunction getHeader(headers: Record<string, string>, name: string): string | undefined {\n return headers[name.toLowerCase()]\n}\n\nfunction bodyToBuffer(body: BodyInit | null | undefined): Buffer {\n if (body == null) return Buffer.alloc(0)\n if (typeof body === \"string\") return Buffer.from(body)\n if (body instanceof Uint8Array) return Buffer.from(body)\n if (body instanceof ArrayBuffer) return Buffer.from(body)\n throw new Error(\"agy transport only supports string/byte request bodies\")\n}\n\nfunction shouldUseChunkedBody(url: URL): boolean {\n return url.pathname.includes(\":streamGenerateContent\")\n}\n\nexport function buildAgyCliHeaderPairs(url: string, init: RequestInit = {}): HeaderPair[] {\n const parsedUrl = new URL(url)\n const headers = headersToRecord(init.headers)\n const body = bodyToBuffer(init.body)\n const host = parsedUrl.port ? `${parsedUrl.hostname}:${parsedUrl.port}` : parsedUrl.hostname\n const userAgent = getHeader(headers, \"User-Agent\") ?? \"antigravity/cli/1.0.4 darwin/arm64\"\n const authorization = getHeader(headers, \"Authorization\")\n const contentType = getHeader(headers, \"Content-Type\") ?? \"application/json\"\n const acceptEncoding = getHeader(headers, \"Accept-Encoding\") ?? \"gzip\"\n const chunked = shouldUseChunkedBody(parsedUrl)\n\n const pairs: HeaderPair[] = [\n [\"Host\", host],\n [\"User-Agent\", userAgent],\n ]\n\n if (chunked) {\n pairs.push([\"Transfer-Encoding\", \"chunked\"])\n } else {\n pairs.push([\"Content-Length\", String(body.byteLength)])\n }\n\n if (authorization) {\n pairs.push([\"Authorization\", authorization])\n }\n pairs.push([\"Content-Type\", contentType])\n pairs.push([\"Accept-Encoding\", acceptEncoding])\n\n return pairs\n}\n\nfunction noProxyIncludes(hostname: string): boolean {\n const raw = process.env.NO_PROXY || process.env.no_proxy || \"\"\n if (!raw) return false\n const host = hostname.toLowerCase()\n return raw.split(\",\").map((entry) => entry.trim().toLowerCase()).some((entry) => {\n if (!entry) return false\n if (entry === \"*\") return true\n if (entry.startsWith(\".\")) return host.endsWith(entry)\n return host === entry || host.endsWith(`.${entry}`)\n })\n}\n\nfunction getHttpsProxy(url: URL): URL | undefined {\n if (url.protocol !== \"https:\" || noProxyIncludes(url.hostname)) return undefined\n const rawProxy = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.ALL_PROXY || process.env.all_proxy\n if (!rawProxy) return undefined\n try {\n return new URL(rawProxy)\n } catch {\n return undefined\n }\n}\n\nfunction waitForHead(socket: net.Socket, timeoutMs: number, onTimeout: () => void): Promise<{ head: string; leftover: Buffer }> {\n return new Promise((resolve, reject) => {\n let buffer = Buffer.alloc(0)\n const timeout = setTimeout(() => {\n onTimeout()\n cleanup(() => reject(new Error(`Antigravity request timed out waiting for response headers after ${timeoutMs}ms`)))\n }, timeoutMs)\n\n const cleanup = (finish: () => void) => {\n socket.off(\"data\", onData)\n socket.off(\"error\", onError)\n clearTimeout(timeout)\n finish()\n }\n\n const onError = (error: Error) => cleanup(() => reject(error))\n const onData = (chunk: Buffer) => {\n buffer = Buffer.concat([buffer, chunk])\n const marker = buffer.indexOf(\"\\r\\n\\r\\n\")\n if (marker === -1) return\n const head = buffer.subarray(0, marker).toString(\"latin1\")\n const leftover = buffer.subarray(marker + 4)\n cleanup(() => resolve({ head, leftover }))\n }\n\n socket.on(\"data\", onData)\n socket.once(\"error\", onError)\n })\n}\n\nasync function connectViaProxy(proxyUrl: URL, targetUrl: URL, timeoutMs: number, onDebug?: (message: string) => void): Promise<tls.TLSSocket> {\n const proxySocket = net.connect({\n host: proxyUrl.hostname,\n port: Number(proxyUrl.port || DEFAULT_PROXY_PORT),\n })\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n onDebug?.(`agy transport proxy connect timeout after ${timeoutMs}ms`)\n proxySocket.destroy()\n reject(new Error(`Antigravity request timed out connecting to HTTPS proxy after ${timeoutMs}ms`))\n }, timeoutMs)\n const cleanup = () => clearTimeout(timeout)\n proxySocket.once(\"connect\", () => {\n cleanup()\n resolve()\n })\n proxySocket.once(\"error\", (error) => {\n cleanup()\n reject(error)\n })\n })\n\n const targetHost = targetUrl.hostname\n const targetPort = Number(targetUrl.port || DEFAULT_HTTPS_PORT)\n const auth = proxyUrl.username\n ? `Proxy-Authorization: Basic ${Buffer.from(`${decodeURIComponent(proxyUrl.username)}:${decodeURIComponent(proxyUrl.password)}`).toString(\"base64\")}\\r\\n`\n : \"\"\n\n proxySocket.write(\n `CONNECT ${targetHost}:${targetPort} HTTP/1.1\\r\\n` +\n `Host: ${targetHost}:${targetPort}\\r\\n` +\n auth +\n \"\\r\\n\",\n )\n\n const { head, leftover } = await waitForHead(proxySocket, timeoutMs, () => {\n onDebug?.(`agy transport proxy CONNECT response timeout after ${timeoutMs}ms`)\n proxySocket.destroy()\n })\n if (!/^HTTP\\/1\\.[01] 2\\d\\d\\b/.test(head)) {\n proxySocket.destroy()\n throw new Error(`Proxy CONNECT failed: ${head.split(\"\\r\\n\")[0] ?? \"unknown\"}`)\n }\n if (leftover.length > 0) {\n proxySocket.unshift(leftover)\n }\n\n return await new Promise<tls.TLSSocket>((resolve, reject) => {\n const tlsSocket = tls.connect({ socket: proxySocket, servername: targetHost })\n const timeout = setTimeout(() => {\n onDebug?.(`agy transport proxy TLS handshake timeout after ${timeoutMs}ms`)\n tlsSocket.destroy()\n reject(new Error(`Antigravity request timed out during proxy TLS handshake after ${timeoutMs}ms`))\n }, timeoutMs)\n const cleanup = () => clearTimeout(timeout)\n tlsSocket.once(\"secureConnect\", () => {\n cleanup()\n resolve(tlsSocket)\n })\n tlsSocket.once(\"error\", (error) => {\n cleanup()\n reject(error)\n })\n })\n}\n\nasync function connectDirect(targetUrl: URL, timeoutMs: number, onDebug?: (message: string) => void): Promise<tls.TLSSocket> {\n return await new Promise<tls.TLSSocket>((resolve, reject) => {\n const socket = tls.connect({\n host: targetUrl.hostname,\n port: Number(targetUrl.port || DEFAULT_HTTPS_PORT),\n servername: targetUrl.hostname,\n })\n const timeout = setTimeout(() => {\n onDebug?.(`agy transport TLS connect timeout after ${timeoutMs}ms`)\n socket.destroy()\n reject(new Error(`Antigravity request timed out connecting after ${timeoutMs}ms`))\n }, timeoutMs)\n const cleanup = () => clearTimeout(timeout)\n socket.once(\"secureConnect\", () => {\n cleanup()\n resolve(socket)\n })\n socket.once(\"error\", (error) => {\n cleanup()\n reject(error)\n })\n })\n}\n\nasync function connectTls(targetUrl: URL, timeoutMs: number, onDebug?: (message: string) => void): Promise<tls.TLSSocket> {\n const proxyUrl = getHttpsProxy(targetUrl)\n return proxyUrl ? await connectViaProxy(proxyUrl, targetUrl, timeoutMs, onDebug) : await connectDirect(targetUrl, timeoutMs, onDebug)\n}\n\nfunction serializeRequest(url: URL, init: RequestInit, body: Buffer): Buffer {\n const method = init.method ?? \"POST\"\n const path = `${url.pathname}${url.search}`\n const headerLines = buildAgyCliHeaderPairs(url.toString(), init)\n .map(([key, value]) => `${key}: ${value}`)\n .join(\"\\r\\n\")\n const head = Buffer.from(`${method} ${path} HTTP/1.1\\r\\n${headerLines}\\r\\n\\r\\n`)\n\n if (body.byteLength === 0) {\n return head\n }\n\n if (!shouldUseChunkedBody(url)) {\n return Buffer.concat([head, body])\n }\n\n return Buffer.concat([\n head,\n Buffer.from(`${body.byteLength.toString(16)}\\r\\n`),\n body,\n Buffer.from(\"\\r\\n0\\r\\n\\r\\n\"),\n ])\n}\n\nfunction parseResponseHead(head: string): ParsedResponseHead {\n const lines = head.split(\"\\r\\n\")\n const statusLine = lines.shift() ?? \"\"\n const match = /^HTTP\\/1\\.[01]\\s+(\\d{3})\\s*(.*)$/.exec(statusLine)\n if (!match) {\n throw new Error(`Invalid HTTP response: ${statusLine}`)\n }\n\n const headers = new Headers()\n let chunked = false\n let gzip = false\n for (const line of lines) {\n const index = line.indexOf(\":\")\n if (index <= 0) continue\n const key = line.slice(0, index)\n const value = line.slice(index + 1).trim()\n const lowerKey = key.toLowerCase()\n const lowerValue = value.toLowerCase()\n if (lowerKey === \"transfer-encoding\" && lowerValue.includes(\"chunked\")) {\n chunked = true\n continue\n }\n if (lowerKey === \"content-encoding\" && lowerValue.includes(\"gzip\")) {\n gzip = true\n continue\n }\n if (gzip && lowerKey === \"content-length\") {\n continue\n }\n headers.append(key, value)\n }\n\n return {\n status: Number(match[1]),\n statusText: match[2] ?? \"\",\n headers,\n chunked,\n gzip,\n }\n}\n\nclass ChunkedDecodeStream extends Transform {\n private buffer = Buffer.alloc(0)\n\n override _transform(chunk: Buffer, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n this.buffer = Buffer.concat([this.buffer, chunk])\n try {\n this.flushAvailableChunks()\n callback()\n } catch (error) {\n callback(error instanceof Error ? error : new Error(String(error)))\n }\n }\n\n override _flush(callback: (error?: Error | null) => void): void {\n try {\n this.flushAvailableChunks()\n callback()\n } catch (error) {\n callback(error instanceof Error ? error : new Error(String(error)))\n }\n }\n\n private flushAvailableChunks(): void {\n while (true) {\n const lineEnd = this.buffer.indexOf(\"\\r\\n\")\n if (lineEnd === -1) return\n const sizeLine = this.buffer.subarray(0, lineEnd).toString(\"latin1\")\n const sizeText = sizeLine.split(\";\", 1)[0]?.trim() ?? \"\"\n const size = Number.parseInt(sizeText, 16)\n if (!Number.isFinite(size)) {\n throw new Error(`Invalid chunk size: ${sizeLine}`)\n }\n const chunkStart = lineEnd + 2\n const chunkEnd = chunkStart + size\n const nextOffset = chunkEnd + 2\n if (this.buffer.length < nextOffset) return\n if (size === 0) {\n this.buffer = Buffer.alloc(0)\n this.push(null)\n return\n }\n this.push(this.buffer.subarray(chunkStart, chunkEnd))\n this.buffer = this.buffer.subarray(nextOffset)\n }\n }\n}\n\nfunction buildResponseStream(\n socket: tls.TLSSocket,\n leftover: Buffer,\n head: ParsedResponseHead,\n signal?: AbortSignal | null,\n): ReadableStream<Uint8Array> {\n const source = new PassThrough()\n if (leftover.length > 0) {\n source.write(leftover)\n }\n socket.pipe(source)\n\n let responseBody: Readable = source\n if (head.chunked) {\n responseBody = responseBody.pipe(new ChunkedDecodeStream())\n }\n if (head.gzip) {\n responseBody = responseBody.pipe(createGunzip())\n }\n\n const abort = () => socket.destroy(new DOMException(\"The operation was aborted\", \"AbortError\"))\n const cleanup = () => signal?.removeEventListener(\"abort\", abort)\n if (signal?.aborted) {\n abort()\n } else {\n signal?.addEventListener(\"abort\", abort, { once: true })\n }\n\n responseBody.once(\"end\", () => {\n cleanup()\n socket.destroy()\n })\n responseBody.once(\"error\", () => {\n cleanup()\n socket.destroy()\n })\n responseBody.once(\"close\", cleanup)\n return Readable.toWeb(responseBody) as ReadableStream<Uint8Array>\n}\n\nexport async function fetchWithAgyCliTransport(\n url: string,\n init: RequestInit = {},\n options: AgyTransportOptions = {},\n): Promise<Response> {\n const parsedUrl = new URL(url)\n if (parsedUrl.protocol !== \"https:\") {\n throw new Error(`agy transport only supports https URLs: ${url}`)\n }\n\n const body = bodyToBuffer(init.body)\n const requestBytes = serializeRequest(parsedUrl, init, body)\n const timeoutMs = options.timeoutMs ?? DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS\n options.onDebug?.(`agy transport connecting to ${parsedUrl.hostname} with header timeout ${timeoutMs}ms`)\n const socket = await connectTls(parsedUrl, timeoutMs, options.onDebug)\n\n const abort = () => {\n socket.destroy(new DOMException(\"The operation was aborted\", \"AbortError\"))\n }\n\n try {\n options.signal?.addEventListener(\"abort\", abort, { once: true })\n socket.write(requestBytes)\n options.onDebug?.(`agy transport request dispatched (${requestBytes.byteLength} bytes)`)\n\n const { head, leftover } = await waitForHead(socket, timeoutMs, () => {\n options.onDebug?.(`agy transport response header timeout after ${timeoutMs}ms`)\n socket.destroy()\n })\n const parsedHead = parseResponseHead(head)\n options.onDebug?.(`agy transport response headers received: ${parsedHead.status} ${parsedHead.statusText}`)\n const bodyStream = buildResponseStream(socket, leftover, parsedHead, options.signal)\n return new Response(bodyStream, {\n status: parsedHead.status,\n statusText: parsedHead.statusText,\n headers: parsedHead.headers,\n })\n } catch (error) {\n socket.destroy()\n throw error\n } finally {\n options.signal?.removeEventListener(\"abort\", abort)\n }\n}\n", "import {\n ANTIGRAVITY_ENDPOINT_FALLBACKS,\n ANTIGRAVITY_LOAD_ENDPOINTS,\n ANTIGRAVITY_ENDPOINT_PROD,\n ANTIGRAVITY_DEFAULT_PROJECT_ID,\n} from \"./constants.ts\";\nimport { fetchWithAgyCliTransport } from \"./agy-transport.ts\";\nimport { formatRefreshParts, parseRefreshParts } from \"./auth.ts\";\nimport {\n buildAntigravityHarnessBootstrapHeaders,\n buildAntigravityLoadCodeAssistMetadata,\n} from \"./fingerprint.ts\";\nimport { createLogger } from \"./logger.ts\";\nimport type { OAuthAuthDetails, ProjectContextResult } from \"./auth-types.ts\";\n\nconst log = createLogger(\"project\");\n\n/** TTL for project context cache entries (30 minutes). */\nconst PROJECT_CONTEXT_CACHE_TTL_MS = 30 * 60 * 1000;\n\ninterface CachedProjectContext {\n result: ProjectContextResult;\n cachedAt: number;\n}\n\nconst projectContextResultCache = new Map<string, CachedProjectContext>();\nconst projectContextPendingCache = new Map<string, Promise<ProjectContextResult>>();\nconst provisionFailedKeys = new Set<string>();\ninterface AntigravityUserTier {\n id?: string;\n isDefault?: boolean;\n userDefinedCloudaicompanionProject?: boolean;\n}\n\ninterface LoadCodeAssistPayload {\n cloudaicompanionProject?: string | { id?: string };\n currentTier?: {\n id?: string;\n };\n allowedTiers?: AntigravityUserTier[];\n}\n\ninterface OnboardUserPayload {\n done?: boolean;\n response?: {\n cloudaicompanionProject?: {\n id?: string;\n };\n };\n}\n\nfunction buildBootstrapRequestBody(extra: Record<string, unknown> = {}): Record<string, unknown> {\n return {\n ...extra,\n metadata: buildAntigravityLoadCodeAssistMetadata(),\n };\n}\n\n/**\n * Selects the default tier ID from the allowed tiers list.\n */\nfunction getDefaultTierId(allowedTiers?: AntigravityUserTier[]): string | undefined {\n if (!allowedTiers || allowedTiers.length === 0) {\n return undefined;\n }\n for (const tier of allowedTiers) {\n if (tier?.isDefault) {\n return tier.id;\n }\n }\n return allowedTiers[0]?.id;\n}\n\n/**\n * Promise-based delay utility.\n */\nfunction wait(ms: number): Promise<void> {\n return new Promise(function (resolve) {\n setTimeout(resolve, ms);\n });\n}\n\n/**\n * Extracts the cloudaicompanion project id from loadCodeAssist responses.\n */\nfunction extractManagedProjectId(payload: LoadCodeAssistPayload | null): string | undefined {\n if (!payload) {\n return undefined;\n }\n if (typeof payload.cloudaicompanionProject === \"string\") {\n return payload.cloudaicompanionProject;\n }\n if (payload.cloudaicompanionProject && typeof payload.cloudaicompanionProject.id === \"string\") {\n return payload.cloudaicompanionProject.id;\n }\n return undefined;\n}\n\n/**\n * Generates a cache key for project context based on refresh token.\n */\nfunction getCacheKey(auth: OAuthAuthDetails): string | undefined {\n const refresh = auth.refresh?.trim();\n return refresh ? refresh : undefined;\n}\n\n/**\n * Clears cached project context results and pending promises, globally or for a refresh key.\n */\nexport function invalidateProjectContextCache(refresh?: string): void {\n if (!refresh) {\n projectContextPendingCache.clear();\n projectContextResultCache.clear();\n provisionFailedKeys.clear();\n return;\n }\n projectContextPendingCache.delete(refresh);\n projectContextResultCache.delete(refresh);\n provisionFailedKeys.delete(refresh);\n}\n\nexport function clearProvisionFailedKeys(): void {\n provisionFailedKeys.clear();\n}\n\n/**\n * Loads managed project information for the given access token and optional project.\n */\nexport async function loadManagedProject(\n accessToken: string,\n _projectId?: string,\n): Promise<LoadCodeAssistPayload | null> {\n const requestBody = buildBootstrapRequestBody();\n const loadHeaders = buildAntigravityHarnessBootstrapHeaders(accessToken);\n\n const loadEndpoints = Array.from(\n new Set<string>([...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS]),\n );\n\n for (const baseEndpoint of loadEndpoints) {\n try {\n const response = await fetchWithAgyCliTransport(\n `${baseEndpoint}/v1internal:loadCodeAssist`,\n {\n method: \"POST\",\n headers: loadHeaders,\n body: JSON.stringify(requestBody),\n },\n );\n\n if (!response.ok) {\n continue;\n }\n\n return (await response.json()) as LoadCodeAssistPayload;\n } catch (error) {\n log.debug(\"Failed to load managed project\", { endpoint: baseEndpoint, error: String(error) });\n continue;\n }\n }\n\n return null;\n}\n\n\n/**\n * Onboards a managed project for the user, optionally retrying until completion.\n */\nexport async function onboardManagedProject(\n accessToken: string,\n tierId: string,\n projectId?: string,\n attempts = 10,\n delayMs = 5000,\n): Promise<string | undefined> {\n const requestBody: Record<string, unknown> = { tierId };\n const onboardEndpoints = Array.from(\n new Set<string>([ANTIGRAVITY_ENDPOINT_PROD, ...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS]),\n );\n\n for (const baseEndpoint of onboardEndpoints) {\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n try {\n const response = await fetchWithAgyCliTransport(\n `${baseEndpoint}/v1internal:onboardUser`,\n {\n method: \"POST\",\n headers: buildAntigravityHarnessBootstrapHeaders(accessToken),\n body: JSON.stringify(requestBody),\n },\n );\n\n if (!response.ok) {\n log.debug(\"Onboard request failed\", {\n endpoint: baseEndpoint,\n status: response.status,\n statusText: response.statusText,\n });\n break;\n }\n\n const payload = (await response.json()) as OnboardUserPayload;\n const managedProjectId = payload.response?.cloudaicompanionProject?.id;\n if (payload.done && managedProjectId) {\n return managedProjectId;\n }\n if (payload.done && projectId) {\n return projectId;\n }\n } catch (error) {\n log.debug(\"Failed to onboard managed project\", { endpoint: baseEndpoint, error: String(error) });\n break;\n }\n\n await wait(delayMs);\n }\n }\n\n return undefined;\n}\n\n/**\n * Resolves an effective project ID for the current auth state, caching results per refresh token.\n */\nexport async function ensureProjectContext(auth: OAuthAuthDetails): Promise<ProjectContextResult> {\n const accessToken = auth.access;\n if (!accessToken) {\n return { auth, effectiveProjectId: \"\" };\n }\n\n const cacheKey = getCacheKey(auth);\n if (cacheKey) {\n const cached = projectContextResultCache.get(cacheKey);\n if (cached && (Date.now() - cached.cachedAt) < PROJECT_CONTEXT_CACHE_TTL_MS) {\n return cached.result;\n }\n if (cached) {\n // Expired \u2014 evict stale entry\n projectContextResultCache.delete(cacheKey);\n } const pending = projectContextPendingCache.get(cacheKey);\n if (pending) {\n return pending;\n }\n }\n\n const resolveContext = async (): Promise<ProjectContextResult> => {\n const parts = parseRefreshParts(auth.refresh);\n if (parts.managedProjectId) {\n return { auth, effectiveProjectId: parts.managedProjectId };\n }\n\n const fallbackProjectId = ANTIGRAVITY_DEFAULT_PROJECT_ID;\n\n if (cacheKey && provisionFailedKeys.has(cacheKey)) {\n const effectiveProjectId = parts.projectId || fallbackProjectId;\n return { auth, effectiveProjectId };\n }\n\n const persistManagedProject = async (managedProjectId: string): Promise<ProjectContextResult> => {\n const updatedAuth: OAuthAuthDetails = {\n ...auth,\n refresh: formatRefreshParts({\n refreshToken: parts.refreshToken,\n projectId: parts.projectId,\n managedProjectId,\n }),\n };\n\n return { auth: updatedAuth, effectiveProjectId: managedProjectId };\n };\n\n // Try to resolve a managed project from Antigravity if possible.\n const loadPayload = await loadManagedProject(accessToken, parts.projectId ?? fallbackProjectId);\n const resolvedManagedProjectId = extractManagedProjectId(loadPayload);\n\n if (resolvedManagedProjectId) {\n return persistManagedProject(resolvedManagedProjectId);\n }\n\n // No managed project found - try to auto-provision one via onboarding.\n // This handles accounts that were added before managed project provisioning was required.\n const tierId = getDefaultTierId(loadPayload?.allowedTiers) ?? \"free-tier\";\n log.debug(\"Auto-provisioning managed project\", { tierId, projectId: parts.projectId });\n \n const provisionedProjectId = await onboardManagedProject(\n accessToken,\n tierId,\n parts.projectId,\n );\n\n if (provisionedProjectId) {\n log.debug(\"Successfully provisioned managed project\", { provisionedProjectId });\n return persistManagedProject(provisionedProjectId);\n }\n\n log.warn(\"Failed to provision managed project - account may not work correctly\", {\n hasProjectId: !!parts.projectId,\n });\n\n if (cacheKey) {\n provisionFailedKeys.add(cacheKey);\n }\n\n if (parts.projectId) {\n return { auth, effectiveProjectId: parts.projectId };\n }\n\n // No project id present in auth; fall back to the hardcoded id for requests.\n return { auth, effectiveProjectId: fallbackProjectId };\n };\n\n if (!cacheKey) {\n return resolveContext();\n }\n\n const promise = resolveContext()\n .then((result) => {\n const nextKey = getCacheKey(result.auth) ?? cacheKey;\n projectContextPendingCache.delete(cacheKey);\n projectContextResultCache.set(nextKey, { result, cachedAt: Date.now() });\n if (nextKey !== cacheKey) {\n projectContextResultCache.delete(cacheKey);\n }\n return result;\n })\n .catch((error) => {\n projectContextPendingCache.delete(cacheKey);\n throw error;\n });\n\n projectContextPendingCache.set(cacheKey, promise);\n return promise;\n}\n", "import type { ProviderModel } from \"./model-types.ts\"\nimport type { ThinkingTier } from \"./transform/types.ts\"\n\nexport type ModelThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\"\n\nexport interface ModelThinkingConfig {\n thinkingBudget: number\n}\n\nexport interface ModelVariant {\n thinkingLevel?: ModelThinkingLevel\n thinkingConfig?: ModelThinkingConfig\n disabled?: boolean\n}\n\nexport interface ModelLimit {\n context: number\n output: number\n}\n\nexport type ModelModality = \"text\" | \"image\" | \"pdf\"\nexport type ModelQuotaGroup = \"claude\" | \"gemini-pro\" | \"gemini-flash\" | \"gpt-oss\"\n\nexport interface ModelModalities {\n input: ModelModality[]\n output: ModelModality[]\n}\n\nexport interface OpencodeModelDefinition extends ProviderModel {\n id: string\n name: string\n release_date: string\n attachment: boolean\n reasoning: boolean\n temperature: boolean\n tool_call: boolean\n limit: ModelLimit\n modalities: ModelModalities\n cost: {\n input: number\n output: number\n }\n options: Record<string, unknown>\n variants?: Record<string, ModelVariant>\n}\n\nexport type OpencodeModelDefinitions = Record<string, OpencodeModelDefinition>\n\ninterface OpencodeModelDefinitionInput {\n name: string\n reasoning: boolean\n limit: ModelLimit\n modalities: ModelModalities\n variants?: Record<string, ModelVariant>\n}\n\ninterface Gemini35FlashRouteMetadata {\n antigravity: {\n defaultModel: string\n byTier: Partial<Record<ThinkingTier, string>>\n }\n geminiCliFallbackModel: string\n}\n\nconst DEFAULT_MODALITIES: ModelModalities = {\n input: [\"text\", \"image\", \"pdf\"],\n output: [\"text\"],\n}\n\nconst MODEL_RELEASE_DATE = \"\"\nconst DEFAULT_COST = { input: 0, output: 0 }\nconst DEFAULT_OPTIONS: Record<string, unknown> = {}\n\nfunction defineModel(\n id: string,\n model: OpencodeModelDefinitionInput,\n): OpencodeModelDefinition {\n return {\n id,\n release_date: MODEL_RELEASE_DATE,\n attachment: model.modalities.input.some((modality) => modality !== \"text\"),\n temperature: true,\n tool_call: true,\n cost: { ...DEFAULT_COST },\n options: { ...DEFAULT_OPTIONS },\n ...model,\n }\n}\n\nconst ALL_MODEL_DEFINITIONS: OpencodeModelDefinitions = {\n \"antigravity-gemini-3.1-pro\": defineModel(\"antigravity-gemini-3.1-pro\", {\n name: \"Gemini 3.1 Pro (Antigravity)\",\n reasoning: true,\n limit: { context: 1048576, output: 65535 },\n modalities: DEFAULT_MODALITIES,\n variants: {\n low: { thinkingLevel: \"low\" },\n high: { thinkingLevel: \"high\" },\n },\n }),\n \"antigravity-gemini-3.5-flash\": defineModel(\"antigravity-gemini-3.5-flash\", {\n name: \"Gemini 3.5 Flash (Antigravity)\",\n reasoning: true,\n limit: { context: 1048576, output: 65536 },\n modalities: DEFAULT_MODALITIES,\n variants: {\n low: { thinkingLevel: \"low\" },\n high: { thinkingLevel: \"high\" },\n },\n }),\n \"antigravity-claude-sonnet-4-6-thinking\": defineModel(\"antigravity-claude-sonnet-4-6-thinking\", {\n name: \"Claude Sonnet 4.6 Thinking (Antigravity)\",\n reasoning: true,\n limit: { context: 250000, output: 64000 },\n modalities: DEFAULT_MODALITIES,\n variants: {\n low: { disabled: true },\n high: { disabled: true },\n },\n }),\n \"antigravity-claude-opus-4-6-thinking\": defineModel(\"antigravity-claude-opus-4-6-thinking\", {\n name: \"Claude Opus 4.6 Thinking (Antigravity)\",\n reasoning: true,\n limit: { context: 250000, output: 64000 },\n modalities: DEFAULT_MODALITIES,\n variants: {\n low: { disabled: true },\n high: { disabled: true },\n },\n }),\n \"antigravity-gemini-3.1-flash-image\": defineModel(\"antigravity-gemini-3.1-flash-image\", {\n name: \"Gemini 3.1 Flash Image (Antigravity)\",\n reasoning: false,\n limit: { context: 66000, output: 33000 },\n modalities: {\n input: [\"text\", \"image\"],\n output: [\"text\", \"image\"],\n },\n }),\n \"antigravity-gpt-oss-120b\": defineModel(\"antigravity-gpt-oss-120b\", {\n name: \"GPT-OSS 120B (Antigravity)\",\n reasoning: false,\n limit: { context: 128000, output: 16384 },\n modalities: DEFAULT_MODALITIES,\n variants: {\n medium: {},\n },\n }),\n \"gemini-2.5-flash\": defineModel(\"gemini-2.5-flash\", {\n name: \"Gemini 2.5 Flash (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65536 },\n modalities: DEFAULT_MODALITIES,\n }),\n \"gemini-2.5-pro\": defineModel(\"gemini-2.5-pro\", {\n name: \"Gemini 2.5 Pro (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65536 },\n modalities: DEFAULT_MODALITIES,\n }),\n \"gemini-3-flash-preview\": defineModel(\"gemini-3-flash-preview\", {\n name: \"Gemini 3 Flash Preview (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65536 },\n modalities: DEFAULT_MODALITIES,\n }),\n \"gemini-3.1-pro-preview\": defineModel(\"gemini-3.1-pro-preview\", {\n name: \"Gemini 3.1 Pro Preview (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65535 },\n modalities: DEFAULT_MODALITIES,\n }),\n \"gemini-3.5-flash-preview\": defineModel(\"gemini-3.5-flash-preview\", {\n name: \"Gemini 3.5 Flash Preview (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65536 },\n modalities: DEFAULT_MODALITIES,\n }),\n \"gemini-3.1-flash-image\": defineModel(\"gemini-3.1-flash-image\", {\n name: \"Gemini 3.1 Flash Image (Gemini CLI)\",\n reasoning: false,\n limit: { context: 66000, output: 33000 },\n modalities: {\n input: [\"text\", \"image\"],\n output: [\"text\", \"image\"],\n },\n }),\n \"gemini-3.1-flash-image-preview\": defineModel(\"gemini-3.1-flash-image-preview\", {\n name: \"Gemini 3.1 Flash Image Preview (Gemini CLI)\",\n reasoning: false,\n limit: { context: 66000, output: 33000 },\n modalities: {\n input: [\"text\", \"image\"],\n output: [\"text\", \"image\"],\n },\n }),\n \"gemini-3.1-pro-preview-customtools\": defineModel(\"gemini-3.1-pro-preview-customtools\", {\n name: \"Gemini 3.1 Pro Preview Custom Tools (Gemini CLI)\",\n reasoning: true,\n limit: { context: 1048576, output: 65535 },\n modalities: DEFAULT_MODALITIES,\n }),\n}\n\nconst RESOLVER_ALIASES: Record<string, string> = {\n \"gemini-3.1-pro-low\": \"gemini-3.1-pro\",\n \"gemini-3.1-pro-high\": \"gemini-3.1-pro\",\n \"gemini-3-flash-low\": \"gemini-3-flash\",\n \"gemini-3-flash-medium\": \"gemini-3-flash\",\n \"gemini-3-flash-high\": \"gemini-3-flash\",\n \"gemini-3.5-flash-low\": \"gemini-3.5-flash\",\n \"gemini-3.5-flash-medium\": \"gemini-3.5-flash\",\n \"gemini-3.5-flash-high\": \"gemini-3.5-flash\",\n \"gemini-claude-opus-4-6-thinking-low\": \"claude-opus-4-6-thinking\",\n \"gemini-claude-opus-4-6-thinking-medium\": \"claude-opus-4-6-thinking\",\n \"gemini-claude-opus-4-6-thinking-high\": \"claude-opus-4-6-thinking\",\n \"gemini-claude-sonnet-4-6-thinking-low\": \"claude-sonnet-4-6\",\n \"gemini-claude-sonnet-4-6-thinking-medium\": \"claude-sonnet-4-6\",\n \"gemini-claude-sonnet-4-6-thinking-high\": \"claude-sonnet-4-6\",\n \"gemini-claude-sonnet-4-6\": \"claude-sonnet-4-6\",\n \"claude-sonnet-4-6-thinking\": \"claude-sonnet-4-6\",\n \"claude-sonnet-4-6-thinking-low\": \"claude-sonnet-4-6\",\n \"claude-sonnet-4-6-thinking-medium\": \"claude-sonnet-4-6\",\n \"claude-sonnet-4-6-thinking-high\": \"claude-sonnet-4-6\",\n}\n\nconst GEMINI_35_FLASH_ROUTES: Gemini35FlashRouteMetadata = {\n antigravity: {\n defaultModel: \"gemini-3-flash-agent\",\n byTier: {\n low: \"gemini-3.5-flash-extra-low\",\n medium: \"gemini-3.5-flash-low\",\n high: \"gemini-3-flash-agent\",\n },\n },\n geminiCliFallbackModel: \"gemini-3-flash-preview\",\n}\n\nconst QUOTA_GROUP_BY_MODEL_ID: Record<string, ModelQuotaGroup> = {\n \"claude-opus-4-6-thinking\": \"claude\",\n \"claude-opus-4-6\": \"claude\",\n \"claude-sonnet-4-6-thinking\": \"claude\",\n \"claude-sonnet-4-6\": \"claude\",\n \"gemini-pro-agent\": \"gemini-pro\",\n \"gemini-3.1-pro\": \"gemini-pro\",\n \"gemini-3.1-pro-low\": \"gemini-pro\",\n \"gemini-3.1-pro-high\": \"gemini-pro\",\n \"gemini-3-flash\": \"gemini-flash\",\n \"gemini-3-flash-agent\": \"gemini-flash\",\n \"gemini-3.5-flash-low\": \"gemini-flash\",\n \"gemini-3.5-flash-extra-low\": \"gemini-flash\",\n \"gemini-3.1-flash-image\": \"gemini-flash\",\n \"gpt-oss-120b\": \"gpt-oss\",\n \"gpt-oss-120b-medium\": \"gpt-oss\",\n}\n\nconst ANTIGRAVITY_OPENCODE_MODEL_IDS = [\n \"antigravity-gemini-3.5-flash\",\n \"antigravity-gemini-3.1-pro\",\n \"antigravity-claude-sonnet-4-6-thinking\",\n \"antigravity-claude-opus-4-6-thinking\",\n] as const\n\nfunction pickModelDefinitions(ids: readonly string[]): OpencodeModelDefinitions {\n return Object.fromEntries(ids.map((id) => [id, ALL_MODEL_DEFINITIONS[id]!]))\n}\n\nexport const OPENCODE_MODEL_DEFINITIONS = pickModelDefinitions(ANTIGRAVITY_OPENCODE_MODEL_IDS)\n\nexport function getPublicModelDefinitions(): OpencodeModelDefinitions {\n return OPENCODE_MODEL_DEFINITIONS\n}\n\nexport function getAntigravityOpencodeModelIds(): string[] {\n return [...ANTIGRAVITY_OPENCODE_MODEL_IDS]\n}\n\nexport function getResolverAliasMap(): Record<string, string> {\n return RESOLVER_ALIASES\n}\n\nexport function getGemini35FlashAntigravityModel(tier?: ThinkingTier): string {\n if (!tier) {\n return GEMINI_35_FLASH_ROUTES.antigravity.defaultModel\n }\n return GEMINI_35_FLASH_ROUTES.antigravity.byTier[tier] ?? GEMINI_35_FLASH_ROUTES.antigravity.defaultModel\n}\n\nexport function getGemini35FlashGeminiCliFallbackModel(): string {\n return GEMINI_35_FLASH_ROUTES.geminiCliFallbackModel\n}\n\nexport function getQuotaGroupForModel(modelId: string): ModelQuotaGroup | undefined {\n return QUOTA_GROUP_BY_MODEL_ID[modelId.toLowerCase()]\n}\n", "/**\n * Model Resolution with Thinking Tier Support\n * \n * Resolves model names with tier suffixes (e.g., gemini-3-pro-high, claude-opus-4-6-thinking-low)\n * to their actual API model names and corresponding thinking configurations.\n */\n\nimport {\n getGemini35FlashAntigravityModel,\n getGemini35FlashGeminiCliFallbackModel,\n getResolverAliasMap,\n} from \"../model-registry.ts\";\nimport type { ResolvedModel, ThinkingTier, GoogleSearchConfig } from \"./types.ts\";\n\nexport interface ModelResolverOptions {\n cli_first?: boolean;\n}\n\n/**\n * Thinking tier budgets by model family.\n * Claude and Gemini 2.5 Pro use numeric budgets.\n */\nexport const THINKING_TIER_BUDGETS = {\n claude: { low: 8192, medium: 16384, high: 32768 },\n \"gemini-2.5-pro\": { low: 8192, medium: 16384, high: 32768 },\n \"gemini-2.5-flash\": { low: 6144, medium: 12288, high: 24576 },\n default: { low: 4096, medium: 8192, high: 16384 },\n} as const;\n\n/**\n * Gemini 3 uses thinkingLevel strings instead of numeric budgets.\n * Flash supports: minimal, low, medium, high\n * Pro supports: low, high (no minimal/medium)\n */\nexport const GEMINI_3_THINKING_LEVELS = [\"minimal\", \"low\", \"medium\", \"high\"] as const;\n\n/**\n * Model aliases - maps user-friendly names to API model names.\n * \n * Format:\n * - Gemini 3.x Pro variants: gemini-3.1-pro-{low,high}\n * - Claude thinking variants: claude-{model}-thinking-{low,medium,high}\n * - Claude non-thinking: claude-{model} (no -thinking suffix)\n */\nexport const MODEL_ALIASES: Record<string, string> = getResolverAliasMap();\nconst TIER_REGEX = /-(minimal|low|medium|high)$/;\nconst QUOTA_PREFIX_REGEX = /^antigravity-/i;\nconst GEMINI_3_PRO_REGEX = /^gemini-3(?:\\.\\d+)?-pro/i;\nconst GEMINI_3_FLASH_REGEX = /^gemini-3(?:\\.\\d+)?-flash/i;\n\n// ANTIGRAVITY_ONLY_MODELS removed - all models now default to antigravity\n\n/**\n * Image generation models - always route to Antigravity.\n * These models don't support thinking and require imageConfig.\n */\nconst IMAGE_GENERATION_MODELS = /image|imagen/i;\n\n// Legacy LEGACY_ANTIGRAVITY_GEMINI3 regex removed - all Gemini models now default to antigravity\n\n/**\n * Models that support thinking tier suffixes.\n * Only these models should have -low/-medium/-high stripped as thinking tiers.\n * GPT models like gpt-oss-120b-medium should NOT have -medium stripped.\n */\nfunction supportsThinkingTiers(model: string): boolean {\n const lower = model.toLowerCase();\n return (\n lower.includes(\"gemini-3\") ||\n lower.includes(\"gemini-2.5\") ||\n (lower.includes(\"claude\") && lower.includes(\"thinking\"))\n );\n}\n\n/**\n * Extracts thinking tier from model name suffix.\n * Only extracts tier for models that support thinking tiers.\n */\nfunction extractThinkingTierFromModel(model: string): ThinkingTier | undefined {\n // Only extract tier for models that support thinking tiers\n if (!supportsThinkingTiers(model)) {\n return undefined;\n }\n const tierMatch = model.match(TIER_REGEX);\n return tierMatch?.[1] as ThinkingTier | undefined;\n}\n\n/**\n * Determines the budget family for a model.\n */\nfunction getBudgetFamily(model: string): keyof typeof THINKING_TIER_BUDGETS {\n if (model.includes(\"claude\")) {\n return \"claude\";\n }\n if (model.includes(\"gemini-2.5-pro\")) {\n return \"gemini-2.5-pro\";\n }\n if (model.includes(\"gemini-2.5-flash\")) {\n return \"gemini-2.5-flash\";\n }\n return \"default\";\n}\n\n/**\n * Checks if a model is a thinking-capable model.\n */\nfunction isThinkingCapableModel(model: string): boolean {\n const lower = model.toLowerCase();\n return (\n lower.includes(\"thinking\") ||\n lower.includes(\"gemini-3\") ||\n lower.includes(\"gemini-2.5\")\n );\n}\n\nfunction isGemini3ProModel(model: string): boolean {\n return GEMINI_3_PRO_REGEX.test(model);\n}\n\nfunction isGemini3FlashModel(model: string): boolean {\n return GEMINI_3_FLASH_REGEX.test(model);\n}\n\nfunction isGemini35FlashModel(model: string): boolean {\n return /^gemini-3\\.5-flash/i.test(model);\n}\n\nfunction resolveGemini35FlashAntigravityModel(tier?: ThinkingTier): string {\n return getGemini35FlashAntigravityModel(tier);\n}\n\nfunction getAgyGemini35FlashThinkingBudget(tier?: ThinkingTier): number {\n switch (tier) {\n case \"low\":\n return 1000;\n case \"high\":\n return 10000;\n case \"medium\":\n default:\n return 4000;\n }\n}\n\nfunction getAgyGemini31ProModel(tier?: ThinkingTier): string {\n return tier === \"high\" ? \"gemini-pro-agent\" : \"gemini-3.1-pro-low\";\n}\n\nfunction getAgyGemini31ProThinkingBudget(tier?: ThinkingTier): number {\n return tier === \"high\" ? 10001 : 1001;\n}\n\n/**\n * Resolves a model name with optional tier suffix and quota prefix to its actual API model name\n * and corresponding thinking configuration.\n *\n * Quota routing:\n * - Default to Antigravity quota unless cli_first is enabled for Gemini models\n * - Fallback to Gemini CLI happens at account rotation level when Antigravity is exhausted\n * - \"antigravity-\" prefix marks explicit quota (no fallback allowed)\n * - Claude and image models always use Antigravity\n *\n * Examples:\n * - \"gemini-2.5-flash\" \u2192 { quotaPreference: \"antigravity\" }\n * - \"antigravity-gemini-3.1-pro-high\" \u2192 { quotaPreference: \"antigravity\", explicitQuota: true } * - \"claude-opus-4-6-thinking-medium\" \u2192 { quotaPreference: \"antigravity\" }\n *\n * @param requestedModel - The model name from the request\n * @param options - Optional configuration including cli_first preference\n * @returns Resolved model with thinking configuration\n */\nexport function resolveModelWithTier(requestedModel: string, options: ModelResolverOptions = {}): ResolvedModel {\n const isAntigravity = QUOTA_PREFIX_REGEX.test(requestedModel);\n const modelWithoutQuota = requestedModel.replace(QUOTA_PREFIX_REGEX, \"\");\n\n const tier = extractThinkingTierFromModel(modelWithoutQuota);\n const baseName = tier ? modelWithoutQuota.replace(TIER_REGEX, \"\") : modelWithoutQuota;\n\n const isImageModel = IMAGE_GENERATION_MODELS.test(modelWithoutQuota);\n const isClaudeModel = modelWithoutQuota.toLowerCase().includes(\"claude\");\n \n // All models default to Antigravity quota unless cli_first is enabled\n // Fallback to gemini-cli happens at the account rotation level when Antigravity is exhausted\n const preferGeminiCli = options.cli_first === true && !isAntigravity && !isImageModel && !isClaudeModel;\n const quotaPreference = preferGeminiCli ? \"gemini-cli\" as const : \"antigravity\" as const;\n const explicitQuota = isAntigravity || isImageModel;\n\n const isGemini3 = modelWithoutQuota.toLowerCase().startsWith(\"gemini-3\");\n const skipAlias = isAntigravity && isGemini3;\n\n // For older Antigravity Gemini 3 models without explicit tier, append the\n // tier to the model id. Gemini 3.5 Flash is different: live Antigravity\n // exposes high as `gemini-3-flash-agent` and medium/low as\n // `gemini-3.5-flash-low`.\n const isGemini3Pro = isGemini3ProModel(modelWithoutQuota);\n const isGemini3Flash = isGemini3FlashModel(modelWithoutQuota);\n const isGemini31Pro = /^gemini-3\\.1-pro/i.test(baseName);\n const isGemini35Flash = /^gemini-3\\.5-flash/i.test(baseName);\n\n if (isGemini31Pro && quotaPreference === \"antigravity\") {\n return {\n actualModel: getAgyGemini31ProModel(tier),\n thinkingBudget: getAgyGemini31ProThinkingBudget(tier),\n tier,\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n if (isGemini35Flash && quotaPreference === \"antigravity\") {\n return {\n actualModel: resolveGemini35FlashAntigravityModel(tier ?? \"medium\"),\n thinkingBudget: getAgyGemini35FlashThinkingBudget(tier),\n tier: tier ?? \"medium\",\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n \n let antigravityModel = modelWithoutQuota;\n if (skipAlias) {\n if ((isGemini3Pro || isGemini3Flash) && !tier && !isImageModel) {\n const defaultTier = isGemini3Pro ? \"low\" : \"medium\";\n antigravityModel = `${modelWithoutQuota}-${defaultTier}`;\n }\n // When tier is present, modelWithoutQuota already contains the tier suffix\n // (e.g., \"gemini-3.5-flash-high\") \u2014 no modification needed\n }\n const actualModel = skipAlias\n ? antigravityModel\n : MODEL_ALIASES[modelWithoutQuota] || MODEL_ALIASES[baseName] || baseName;\n\n const resolvedModel = actualModel;\n\n const isThinking = isThinkingCapableModel(resolvedModel);\n\n // Image generation models don't support thinking - return early without thinking config\n if (isImageModel) {\n return {\n actualModel: resolvedModel,\n isThinkingModel: false,\n isImageModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n // Check if this is a Gemini 3 model (works for both aliased and skipAlias paths)\n const isEffectiveGemini3 = resolvedModel.toLowerCase().includes(\"gemini-3\");\n const lowerModelWithoutQuota = modelWithoutQuota.toLowerCase();\n const isClaudeThinking =\n (resolvedModel.toLowerCase().includes(\"claude\") && resolvedModel.toLowerCase().includes(\"thinking\")) ||\n (lowerModelWithoutQuota.includes(\"claude\") && lowerModelWithoutQuota.includes(\"thinking\")) ||\n lowerModelWithoutQuota === \"gemini-claude-sonnet-4-6\";\n\n if (!tier) {\n // Gemini 3 models without explicit tier get a default thinkingLevel\n if (isEffectiveGemini3) {\n return {\n actualModel: resolvedModel,\n thinkingLevel: isGemini35Flash ? \"medium\" : \"low\",\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n // agy CLI sends a compact 1024-token budget for Claude thinking models.\n if (isClaudeThinking) {\n return {\n actualModel: resolvedModel,\n thinkingBudget: 1024,\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n } return { actualModel: resolvedModel, isThinkingModel: isThinking, quotaPreference, explicitQuota };\n }\n\n // Gemini 3 models with tier always get thinkingLevel set\n if (isEffectiveGemini3) {\n return {\n actualModel: resolvedModel,\n thinkingLevel: tier,\n tier,\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n if (isClaudeThinking) {\n return {\n actualModel: resolvedModel,\n thinkingBudget: 1024,\n tier,\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n const budgetFamily = getBudgetFamily(resolvedModel);\n const budgets = THINKING_TIER_BUDGETS[budgetFamily];\n const thinkingBudget = budgets[tier];\n\n return {\n actualModel: resolvedModel,\n thinkingBudget,\n tier,\n isThinkingModel: isThinking,\n quotaPreference,\n explicitQuota,\n };\n}\n\n/**\n * Gets the model family for routing decisions.\n */\nexport function getModelFamily(model: string): \"claude\" | \"gemini-flash\" | \"gemini-pro\" {\n const lower = model.toLowerCase();\n if (lower.includes(\"claude\")) {\n return \"claude\";\n }\n if (lower.includes(\"flash\")) {\n return \"gemini-flash\";\n }\n return \"gemini-pro\";\n}\n\n/**\n * Variant config from OpenCode's providerOptions.\n */\nexport interface VariantConfig {\n thinkingBudget?: number;\n googleSearch?: GoogleSearchConfig;\n}\n\n/**\n * Maps a thinking budget to Gemini 3 thinking level.\n * \u22648192 \u2192 low, \u226416384 \u2192 medium, >16384 \u2192 high\n */\nfunction budgetToGemini3Level(budget: number): \"low\" | \"medium\" | \"high\" {\n if (budget <= 8192) return \"low\";\n if (budget <= 16384) return \"medium\";\n return \"high\";\n}\n\n/**\n * Resolves model name for a specific headerStyle (quota fallback support).\n * Transforms model names when switching between gemini-cli and antigravity quotas.\n * \n * Issue #103: When quota fallback occurs, model names need to be transformed:\n * - gemini-3-flash-preview (gemini-cli) \u2192 gemini-3-flash (antigravity)\n * - gemini-3-flash (antigravity) \u2192 gemini-3-flash-preview (gemini-cli) */\nexport function resolveModelForHeaderStyle(\n requestedModel: string,\n headerStyle: \"antigravity\" | \"gemini-cli\"\n): ResolvedModel {\n const lower = requestedModel.toLowerCase();\n const isGemini3 = lower.includes(\"gemini-3\");\n \n if (!isGemini3) {\n return resolveModelWithTier(requestedModel);\n }\n\n if (headerStyle === \"antigravity\") {\n let transformedModel = requestedModel\n .replace(/-preview-customtools$/i, \"\")\n .replace(/-preview$/i, \"\")\n .replace(/^antigravity-/i, \"\");\n \n const isGemini3Pro = isGemini3ProModel(transformedModel);\n const isGemini3Flash = isGemini3FlashModel(transformedModel);\n const hasTierSuffix = /-(minimal|low|medium|high)$/i.test(transformedModel);\n const isImageModel = IMAGE_GENERATION_MODELS.test(transformedModel);\n const isGemini35Flash = isGemini35FlashModel(transformedModel.replace(TIER_REGEX, \"\"));\n \n // Don't add tier suffix to image models - they don't support thinking\n if ((isGemini3Pro || isGemini3Flash) && !isGemini35Flash && !hasTierSuffix && !isImageModel) {\n const defaultTier = isGemini3Pro ? \"low\" : \"medium\";\n transformedModel = `${transformedModel}-${defaultTier}`;\n } \n const prefixedModel = `antigravity-${transformedModel}`;\n return resolveModelWithTier(prefixedModel);\n }\n \n if (headerStyle === \"gemini-cli\") {\n const requestedTier = extractThinkingTierFromModel(requestedModel.replace(/^antigravity-/i, \"\"));\n let transformedModel = requestedModel\n .replace(/^antigravity-/i, \"\")\n .replace(/-(minimal|low|medium|high)$/i, \"\");\n\n const hasPreviewSuffix = /-preview($|-)/i.test(transformedModel);\n // Gemini Code Assist still exposes Gemini 3.5 Flash through the\n // gemini-3-flash-preview bucket; retrieveUserQuota does not list a\n // gemini-3.5-flash bucket for the gemini-cli header path.\n const isGemini35Flash = isGemini35FlashModel(transformedModel);\n if (isGemini35Flash) {\n transformedModel = getGemini35FlashGeminiCliFallbackModel();\n } else if (!hasPreviewSuffix) {\n transformedModel = `${transformedModel}-preview`;\n }\n\n const resolved = resolveModelWithTier(transformedModel, { cli_first: true });\n return {\n ...resolved,\n thinkingLevel: requestedTier ?? resolved.thinkingLevel,\n tier: requestedTier ?? resolved.tier,\n quotaPreference: \"gemini-cli\",\n };\n }\n\n return resolveModelWithTier(requestedModel);\n}\n\n/**\n * Resolves model with variant config from providerOptions.\n * Variant config takes priority over tier suffix in model name.\n */\nexport function resolveModelWithVariant(\n requestedModel: string,\n variantConfig?: VariantConfig\n): ResolvedModel {\n const base = resolveModelWithTier(requestedModel);\n\n if (!variantConfig) {\n return base;\n }\n\n // Apply Google Search config if present\n if (variantConfig.googleSearch) {\n base.googleSearch = variantConfig.googleSearch;\n base.configSource = \"variant\";\n }\n\n if (!variantConfig.thinkingBudget) {\n return base;\n }\n\n const budget = variantConfig.thinkingBudget;\n const isGemini3 = base.actualModel.toLowerCase().includes(\"gemini-3\");\n\n if (isGemini3) {\n const level = budgetToGemini3Level(budget);\n const requestedBase = requestedModel\n .replace(/^antigravity-/i, \"\")\n .replace(TIER_REGEX, \"\");\n const isGemini35FlashAlias = isGemini35FlashModel(requestedBase) ||\n base.actualModel === \"gemini-3-flash-agent\" ||\n base.actualModel === \"gemini-3.5-flash-low\";\n const isAntigravityGemini3WithTier = base.quotaPreference === \"antigravity\" &&\n (isGemini3ProModel(base.actualModel) || isGemini3FlashModel(base.actualModel));\n\n let actualModel = base.actualModel;\n if (isGemini35FlashAlias) {\n actualModel = resolveGemini35FlashAntigravityModel(level);\n } else if (isAntigravityGemini3WithTier) {\n const baseModel = base.actualModel.replace(/-(low|medium|high)$/, \"\");\n actualModel = `${baseModel}-${level}`;\n }\n return {\n ...base,\n actualModel,\n thinkingLevel: level,\n thinkingBudget: undefined,\n configSource: \"variant\",\n };\n }\n\n return {\n ...base,\n thinkingBudget: budget,\n configSource: \"variant\",\n };\n}\n", "import { Buffer } from 'node:buffer';\nimport { decoder } from '../lib/buffer_utils.js';\nfunction normalize(input) {\n let encoded = input;\n if (encoded instanceof Uint8Array) {\n encoded = decoder.decode(encoded);\n }\n return encoded;\n}\nconst encode = (input) => Buffer.from(input).toString('base64url');\nexport const decodeBase64 = (input) => new Uint8Array(Buffer.from(input, 'base64'));\nexport const encodeBase64 = (input) => Buffer.from(input).toString('base64');\nexport { encode };\nexport const decode = (input) => new Uint8Array(Buffer.from(normalize(input), 'base64url'));\n", "import digest from '../runtime/digest.js';\nexport const encoder = new TextEncoder();\nexport const decoder = new TextDecoder();\nconst MAX_INT32 = 2 ** 32;\nexport function concat(...buffers) {\n const size = buffers.reduce((acc, { length }) => acc + length, 0);\n const buf = new Uint8Array(size);\n let i = 0;\n for (const buffer of buffers) {\n buf.set(buffer, i);\n i += buffer.length;\n }\n return buf;\n}\nexport function p2s(alg, p2sInput) {\n return concat(encoder.encode(alg), new Uint8Array([0]), p2sInput);\n}\nfunction writeUInt32BE(buf, value, offset) {\n if (value < 0 || value >= MAX_INT32) {\n throw new RangeError(`value must be >= 0 and <= ${MAX_INT32 - 1}. Received ${value}`);\n }\n buf.set([value >>> 24, value >>> 16, value >>> 8, value & 0xff], offset);\n}\nexport function uint64be(value) {\n const high = Math.floor(value / MAX_INT32);\n const low = value % MAX_INT32;\n const buf = new Uint8Array(8);\n writeUInt32BE(buf, high, 0);\n writeUInt32BE(buf, low, 4);\n return buf;\n}\nexport function uint32be(value) {\n const buf = new Uint8Array(4);\n writeUInt32BE(buf, value);\n return buf;\n}\nexport function lengthAndInput(input) {\n return concat(uint32be(input.length), input);\n}\nexport async function concatKdf(secret, bits, value) {\n const iterations = Math.ceil((bits >> 3) / 32);\n const res = new Uint8Array(iterations * 32);\n for (let iter = 0; iter < iterations; iter++) {\n const buf = new Uint8Array(4 + secret.length + value.length);\n buf.set(uint32be(iter + 1));\n buf.set(secret, 4);\n buf.set(value, 4 + secret.length);\n res.set(await digest('sha256', buf), iter * 32);\n }\n return res.slice(0, bits >> 3);\n}\n", "import * as base64url from '../runtime/base64url.js';\nexport const encode = base64url.encode;\nexport const decode = base64url.decode;\n", "// src/pkce.ts\nimport { base64url } from \"jose\";\nfunction generateVerifier(length) {\n const buffer = new Uint8Array(length);\n crypto.getRandomValues(buffer);\n return base64url.encode(buffer);\n}\nasync function generateChallenge(verifier, method) {\n if (method === \"plain\")\n return verifier;\n const encoder = new TextEncoder;\n const data = encoder.encode(verifier);\n const hash = await crypto.subtle.digest(\"SHA-256\", data);\n return base64url.encode(new Uint8Array(hash));\n}\nasync function generatePKCE(length = 64) {\n if (length < 43 || length > 128) {\n throw new Error(\"Code verifier length must be between 43 and 128 characters\");\n }\n const verifier = generateVerifier(length);\n const challenge = await generateChallenge(verifier, \"S256\");\n return {\n verifier,\n challenge,\n method: \"S256\"\n };\n}\nasync function validatePKCE(verifier, challenge, method = \"S256\") {\n const generatedChallenge = await generateChallenge(verifier, method);\n return generatedChallenge === challenge;\n}\nexport {\n validatePKCE,\n generatePKCE\n};\n", "import { generatePKCE } from \"@openauthjs/openauth/pkce\";\n\nimport {\n ANTIGRAVITY_CLIENT_ID,\n ANTIGRAVITY_CLIENT_SECRET,\n ANTIGRAVITY_REDIRECT_URI,\n ANTIGRAVITY_SCOPES,\n ANTIGRAVITY_ENDPOINT_FALLBACKS,\n ANTIGRAVITY_LOAD_ENDPOINTS,\n GEMINI_CLI_HEADERS,\n} from \"../constants.ts\";\nimport { createLogger } from \"../logger.ts\";\nimport { calculateTokenExpiry } from \"../auth.ts\";\nimport { fetchWithAgyCliTransport } from \"../agy-transport.ts\";\nimport {\n buildAntigravityHarnessBootstrapHeaders,\n buildAntigravityLoadCodeAssistMetadata,\n} from \"../fingerprint.ts\";\n\nconst log = createLogger(\"oauth\");\n\ninterface PkcePair {\n challenge: string;\n verifier: string;\n}\n\ninterface AntigravityAuthState {\n verifier: string;\n projectId: string;\n}\n\n/**\n * Result returned to the caller after constructing an OAuth authorization URL.\n */\nexport interface AntigravityAuthorization {\n url: string;\n verifier: string;\n projectId: string;\n}\n\ninterface AntigravityTokenExchangeSuccess {\n type: \"success\";\n refresh: string;\n access: string;\n expires: number;\n email?: string;\n projectId: string;\n}\n\ninterface AntigravityTokenExchangeFailure {\n type: \"failed\";\n error: string;\n}\n\nexport type AntigravityTokenExchangeResult =\n | AntigravityTokenExchangeSuccess\n | AntigravityTokenExchangeFailure;\n\nexport interface AntigravityRefreshResult {\n access: string;\n refresh: string;\n expires: number;\n}\n\n/**\n * Refresh an Antigravity OAuth access token using a bare refresh token.\n * Harness-agnostic: performs only the token POST and returns the new\n * credentials. Persistence/caching is the caller's responsibility.\n */\nexport async function refreshAntigravityToken(\n refreshToken: string,\n): Promise<AntigravityRefreshResult> {\n const startTime = Date.now();\n const response = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: refreshToken,\n client_id: ANTIGRAVITY_CLIENT_ID,\n client_secret: ANTIGRAVITY_CLIENT_SECRET,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"\");\n throw new Error(\n `Antigravity token refresh failed (${response.status} ${response.statusText})${errorText ? ` - ${errorText}` : \"\"}`,\n );\n }\n\n const payload = (await response.json()) as {\n access_token: string;\n expires_in: number;\n refresh_token?: string;\n };\n\n return {\n access: payload.access_token,\n refresh: payload.refresh_token ?? refreshToken,\n expires: calculateTokenExpiry(startTime, payload.expires_in),\n };\n}\n\ninterface AntigravityTokenResponse {\n access_token: string;\n expires_in: number;\n refresh_token: string;\n}\n\ninterface AntigravityUserInfo {\n email?: string;\n}\n\n/**\n * Encode an object into a URL-safe base64 string.\n */\nfunction encodeState(payload: AntigravityAuthState): string {\n return Buffer.from(JSON.stringify(payload), \"utf8\").toString(\"base64url\");\n}\n\n/**\n * Decode an OAuth state parameter back into its structured representation.\n */\nfunction decodeState(state: string): AntigravityAuthState {\n const normalized = state.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = normalized.padEnd(normalized.length + ((4 - normalized.length % 4) % 4), \"=\");\n const json = Buffer.from(padded, \"base64\").toString(\"utf8\");\n const parsed = JSON.parse(json);\n if (typeof parsed.verifier !== \"string\") {\n throw new Error(\"Missing PKCE verifier in state\");\n }\n return {\n verifier: parsed.verifier,\n projectId: typeof parsed.projectId === \"string\" ? parsed.projectId : \"\",\n };\n}\n\n/**\n * Build the Antigravity OAuth authorization URL including PKCE and optional project metadata.\n */\nexport async function authorizeAntigravity(projectId = \"\"): Promise<AntigravityAuthorization> {\n const pkce = (await generatePKCE()) as PkcePair;\n\n const url = new URL(\"https://accounts.google.com/o/oauth2/v2/auth\");\n url.searchParams.set(\"client_id\", ANTIGRAVITY_CLIENT_ID);\n url.searchParams.set(\"response_type\", \"code\");\n url.searchParams.set(\"redirect_uri\", ANTIGRAVITY_REDIRECT_URI);\n url.searchParams.set(\"scope\", ANTIGRAVITY_SCOPES.join(\" \"));\n url.searchParams.set(\"code_challenge\", pkce.challenge);\n url.searchParams.set(\"code_challenge_method\", \"S256\");\n url.searchParams.set(\n \"state\",\n encodeState({ verifier: pkce.verifier, projectId: projectId || \"\" }),\n );\n url.searchParams.set(\"access_type\", \"offline\");\n url.searchParams.set(\"prompt\", \"consent\");\n\n return {\n url: url.toString(),\n verifier: pkce.verifier,\n projectId: projectId || \"\",\n };\n}\n\nasync function fetchProjectID(accessToken: string): Promise<string> {\n const errors: string[] = [];\n const loadHeaders = buildAntigravityHarnessBootstrapHeaders(accessToken);\n\n const loadEndpoints = Array.from(\n new Set<string>([...ANTIGRAVITY_LOAD_ENDPOINTS, ...ANTIGRAVITY_ENDPOINT_FALLBACKS]),\n );\n\n for (const baseEndpoint of loadEndpoints) {\n try {\n const url = `${baseEndpoint}/v1internal:loadCodeAssist`;\n const response = await fetchWithAgyCliTransport(url, {\n method: \"POST\",\n headers: loadHeaders,\n body: JSON.stringify({ metadata: buildAntigravityLoadCodeAssistMetadata() }),\n }, { timeoutMs: 10000 });\n\n if (!response.ok) {\n const message = await response.text().catch(() => \"\");\n errors.push(\n `loadCodeAssist ${response.status} at ${baseEndpoint}${\n message ? `: ${message}` : \"\"\n }`,\n );\n continue;\n }\n\n const data = await response.json();\n if (typeof data.cloudaicompanionProject === \"string\" && data.cloudaicompanionProject) {\n return data.cloudaicompanionProject;\n }\n if (\n data.cloudaicompanionProject &&\n typeof data.cloudaicompanionProject.id === \"string\" &&\n data.cloudaicompanionProject.id\n ) {\n return data.cloudaicompanionProject.id;\n }\n\n errors.push(`loadCodeAssist missing project id at ${baseEndpoint}`);\n } catch (e) {\n errors.push(\n `loadCodeAssist error at ${baseEndpoint}: ${\n e instanceof Error ? e.message : String(e)\n }`,\n );\n }\n }\n\n if (errors.length) {\n log.warn(\"Failed to resolve Antigravity project via loadCodeAssist\", { errors: errors.join(\"; \") });\n }\n return \"\";\n}\n\n/**\n * Exchange an authorization code for Antigravity CLI access and refresh tokens.\n */\nexport async function exchangeAntigravity(\n code: string,\n state: string,\n): Promise<AntigravityTokenExchangeResult> {\n try {\n const { verifier, projectId } = decodeState(state);\n\n const startTime = Date.now();\n const tokenResponse = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded;charset=UTF-8\",\n \"Accept\": \"*/*\",\n \"Accept-Encoding\": \"gzip, deflate, br\",\n \"User-Agent\": GEMINI_CLI_HEADERS[\"User-Agent\"],\n },\n body: new URLSearchParams({\n client_id: ANTIGRAVITY_CLIENT_ID,\n client_secret: ANTIGRAVITY_CLIENT_SECRET,\n code,\n grant_type: \"authorization_code\",\n redirect_uri: ANTIGRAVITY_REDIRECT_URI,\n code_verifier: verifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const errorText = await tokenResponse.text();\n return { type: \"failed\", error: errorText };\n }\n\n const tokenPayload = (await tokenResponse.json()) as AntigravityTokenResponse;\n\n const userInfoResponse = await fetch(\n \"https://www.googleapis.com/oauth2/v1/userinfo?alt=json\",\n {\n headers: {\n Authorization: `Bearer ${tokenPayload.access_token}`,\n \"User-Agent\": GEMINI_CLI_HEADERS[\"User-Agent\"],\n },\n },\n );\n\n const userInfo = userInfoResponse.ok\n ? ((await userInfoResponse.json()) as AntigravityUserInfo)\n : {};\n\n const refreshToken = tokenPayload.refresh_token;\n if (!refreshToken) {\n return { type: \"failed\", error: \"Missing refresh token in response\" };\n }\n\n let effectiveProjectId = projectId;\n if (!effectiveProjectId) {\n effectiveProjectId = await fetchProjectID(tokenPayload.access_token);\n }\n\n const storedRefresh = `${refreshToken}|${effectiveProjectId || \"\"}`;\n\n return {\n type: \"success\",\n refresh: storedRefresh,\n access: tokenPayload.access_token,\n expires: calculateTokenExpiry(startTime, tokenPayload.expires_in),\n email: userInfo.email,\n projectId: effectiveProjectId || \"\",\n };\n } catch (error) {\n return {\n type: \"failed\",\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n", "import {\n ANTIGRAVITY_ENDPOINT,\n buildAntigravityHarnessUserAgent,\n ensureProjectContext,\n fetchWithAgyCliTransport,\n resolveModelForHeaderStyle,\n} from \"@cortexkit/antigravity-auth-core\"\nimport {\n type Api,\n type AssistantMessage,\n type AssistantMessageEventStream,\n type Context,\n calculateCost,\n createAssistantMessageEventStream,\n type Model,\n type SimpleStreamOptions,\n type StopReason,\n type TextContent,\n type ToolCall,\n} from \"@earendil-works/pi-ai\"\n\nimport { buildGeminiRequest } from \"./convert.ts\"\n\nconst STREAM_ACTION = \"streamGenerateContent\"\n\nfunction mapFinishReason(reason: string | null | undefined): StopReason {\n switch (reason) {\n case \"STOP\":\n return \"stop\"\n case \"MAX_TOKENS\":\n return \"length\"\n default:\n return reason ? \"stop\" : \"stop\"\n }\n}\n\nfunction createOutput(model: Model<Api>): AssistantMessage {\n return {\n role: \"assistant\",\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: \"stop\",\n timestamp: Date.now(),\n }\n}\n\ninterface GeminiUsageMetadata {\n promptTokenCount?: number\n candidatesTokenCount?: number\n cachedContentTokenCount?: number\n thoughtsTokenCount?: number\n totalTokenCount?: number\n}\n\ninterface GeminiStreamChunk {\n candidates?: Array<{\n content?: { role?: string; parts?: GeminiResponsePart[] }\n finishReason?: string\n }>\n usageMetadata?: GeminiUsageMetadata\n}\n\n/**\n * Antigravity wraps each streamGenerateContent SSE chunk under a `response`\n * key: `data: {\"response\": {\"candidates\": [...], \"usageMetadata\": {...}}}`.\n * Unwrap it so downstream sees the plain Gemini chunk. MITM-verified against\n * agy 1.0.4 on 2026-06-13.\n */\nfunction unwrapChunk(raw: unknown): GeminiStreamChunk {\n if (raw && typeof raw === \"object\" && \"response\" in raw) {\n const inner = (raw as { response?: unknown }).response\n if (inner && typeof inner === \"object\") {\n return inner as GeminiStreamChunk\n }\n }\n return raw as GeminiStreamChunk\n}\n\ninterface GeminiResponsePart {\n text?: string\n thought?: boolean\n thoughtSignature?: string\n functionCall?: { name?: string; args?: Record<string, unknown> }\n}\n\nexport function updateUsage(model: Model<Api>, output: AssistantMessage, usage?: GeminiUsageMetadata): void {\n if (!usage) return\n const cacheRead = usage.cachedContentTokenCount ?? output.usage.cacheRead\n // Antigravity reports promptTokenCount as the full (uncached + cached) prompt.\n const promptTotal = usage.promptTokenCount ?? output.usage.input + output.usage.cacheRead\n output.usage.input = Math.max(0, promptTotal - cacheRead)\n // candidatesTokenCount excludes thinking; thoughtsTokenCount is billed as\n // output too. totalTokenCount = prompt + candidates + thoughts (MITM-verified).\n if (usage.candidatesTokenCount !== undefined || usage.thoughtsTokenCount !== undefined) {\n output.usage.output = (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0)\n }\n output.usage.cacheRead = cacheRead\n output.usage.totalTokens =\n output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite\n calculateCost(model, output.usage)\n}\n\nexport async function* parseGeminiSse(response: Response): AsyncGenerator<GeminiStreamChunk> {\n if (!response.body) return\n const reader = response.body.getReader()\n const decoder = new TextDecoder()\n let buffer = \"\"\n\n const parseFrame = function* (frame: string): Generator<GeminiStreamChunk> {\n for (const line of frame.split(\"\\n\")) {\n if (!line.startsWith(\"data:\")) continue\n const data = line.slice(5).trim()\n if (!data || data === \"[DONE]\") continue\n try {\n yield unwrapChunk(JSON.parse(data))\n } catch {\n // Ignore malformed SSE frames.\n }\n }\n }\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n // Antigravity uses CRLF line endings (`\\r\\n\\r\\n` frame separators);\n // normalize so a single boundary check works for both LF and CRLF.\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, \"\\n\")\n let boundary = buffer.indexOf(\"\\n\\n\")\n while (boundary !== -1) {\n const frame = buffer.slice(0, boundary)\n buffer = buffer.slice(boundary + 2)\n boundary = buffer.indexOf(\"\\n\\n\")\n yield* parseFrame(frame)\n }\n }\n // Flush any trailing frame that did not end with a blank-line separator.\n if (buffer.trim()) {\n yield* parseFrame(buffer)\n }\n } finally {\n reader.releaseLock()\n }\n}\n\nfunction buildRequestId(): string {\n return `agent/${crypto.randomUUID()}/${Date.now()}/${crypto.randomUUID()}/2`\n}\n\nasync function sendAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n accessToken: string\n}): Promise<Response> {\n const resolved = resolveModelForHeaderStyle(options.model.id, \"antigravity\")\n const wireModel = resolved.actualModel\n\n const projectContext = await ensureProjectContext({\n type: \"oauth\",\n refresh: \"\",\n access: options.accessToken,\n expires: Date.now() + 60_000,\n })\n\n const request = buildGeminiRequest(options.context) as unknown as Record<string, unknown>\n const generationConfig: Record<string, unknown> = {}\n\n if (resolved.thinkingLevel) {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingLevel: resolved.thinkingLevel,\n }\n } else if (typeof resolved.thinkingBudget === \"number\") {\n generationConfig.thinkingConfig = {\n includeThoughts: true,\n thinkingBudget: resolved.thinkingBudget,\n }\n }\n\n const maxTokens = options.streamOptions?.maxTokens ?? options.model.maxTokens\n if (typeof maxTokens === \"number\") {\n generationConfig.maxOutputTokens = maxTokens\n }\n\n if (Object.keys(generationConfig).length > 0) {\n request.generationConfig = generationConfig\n }\n\n const envelope = {\n project: projectContext.effectiveProjectId,\n requestId: buildRequestId(),\n request,\n model: wireModel,\n userAgent: \"antigravity\",\n requestType: \"agent\",\n }\n\n const url = `${ANTIGRAVITY_ENDPOINT}/v1internal:${STREAM_ACTION}?alt=sse`\n\n return fetchWithAgyCliTransport(\n url,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${options.accessToken}`,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": buildAntigravityHarnessUserAgent(),\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify(envelope),\n },\n { signal: options.streamOptions?.signal ?? null },\n )\n}\n\nexport function streamCortexKitAntigravity(\n model: Model<Api>,\n context: Context,\n options?: SimpleStreamOptions,\n): AssistantMessageEventStream {\n const stream = createAssistantMessageEventStream()\n\n void (async () => {\n const output = createOutput(model)\n stream.push({ type: \"start\", partial: output })\n\n try {\n const accessToken = options?.apiKey ?? \"\"\n if (!accessToken) throw new Error(\"Missing Antigravity OAuth access token\")\n\n const response = await sendAntigravityRequest({\n model,\n context,\n streamOptions: options,\n accessToken,\n })\n\n if (!response.ok) {\n throw new Error(`Antigravity request failed: HTTP ${response.status} ${await response.text()}`)\n }\n\n const content = output.content as Array<TextContent | ToolCall>\n let textIndex = -1\n let finished = false\n\n for await (const chunk of parseGeminiSse(response)) {\n updateUsage(model, output, chunk.usageMetadata)\n\n const candidate = chunk.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n if (part.functionCall) {\n const toolCall: ToolCall = {\n type: \"toolCall\",\n id: `call_${crypto.randomUUID()}`,\n name: part.functionCall.name ?? \"\",\n arguments: (part.functionCall.args ?? {}) as Record<string, unknown>,\n ...(part.thoughtSignature ? { thoughtSignature: part.thoughtSignature } : {}),\n }\n content.push(toolCall)\n const idx = content.length - 1\n textIndex = -1\n stream.push({ type: \"toolcall_start\", contentIndex: idx, partial: output })\n stream.push({ type: \"toolcall_end\", contentIndex: idx, toolCall, partial: output })\n output.stopReason = \"toolUse\"\n } else if (typeof part.text === \"string\" && part.text.length > 0 && !part.thought) {\n if (textIndex === -1) {\n content.push({ type: \"text\", text: \"\" })\n textIndex = content.length - 1\n stream.push({ type: \"text_start\", contentIndex: textIndex, partial: output })\n }\n const block = content[textIndex]\n if (block && block.type === \"text\") {\n block.text += part.text\n stream.push({\n type: \"text_delta\",\n contentIndex: textIndex,\n delta: part.text,\n partial: output,\n })\n }\n }\n }\n\n if (candidate?.finishReason) {\n if (textIndex !== -1) {\n const block = content[textIndex]\n if (block && block.type === \"text\") {\n stream.push({ type: \"text_end\", contentIndex: textIndex, content: block.text, partial: output })\n }\n textIndex = -1\n }\n if (output.stopReason !== \"toolUse\") {\n output.stopReason = mapFinishReason(candidate.finishReason)\n }\n // The AGY raw-socket transport may keep the response body open after\n // the terminal chunk, which would hang the SSE reader. Stop consuming\n // once a finishReason arrives so the turn terminates promptly.\n finished = true\n break\n }\n }\n\n if (finished) {\n await response.body?.cancel().catch(() => {})\n }\n\n if (options?.signal?.aborted) throw new Error(\"Request was aborted\")\n\n stream.push({\n type: \"done\",\n reason: output.stopReason as \"stop\" | \"length\" | \"toolUse\",\n message: output,\n })\n stream.end()\n } catch (error) {\n output.stopReason = options?.signal?.aborted ? \"aborted\" : \"error\"\n output.errorMessage = error instanceof Error ? error.message : String(error)\n stream.push({ type: \"error\", reason: output.stopReason, error: output })\n stream.end()\n }\n })()\n\n return stream\n}\n", "import type {\n Context,\n ImageContent,\n Message,\n TextContent,\n ThinkingContent,\n Tool,\n ToolCall,\n ToolResultMessage,\n} from \"@earendil-works/pi-ai\"\n\n/** Gemini `contents` part shapes. */\ntype GeminiPart =\n | { text: string }\n | { inlineData: { mimeType: string; data: string } }\n | { functionCall: { name: string; args: Record<string, unknown> }; thoughtSignature?: string }\n | { functionResponse: { name: string; response: Record<string, unknown> } }\n\ninterface GeminiContent {\n role: \"user\" | \"model\"\n parts: GeminiPart[]\n}\n\ninterface GeminiTool {\n functionDeclarations: Array<{\n name: string\n description: string\n parametersJsonSchema?: Record<string, unknown>\n }>\n}\n\nexport interface GeminiRequest {\n contents: GeminiContent[]\n tools?: GeminiTool[]\n systemInstruction?: { parts: GeminiPart[] }\n}\n\nfunction sanitize(text: string): string {\n return text.replace(/[\\uD800-\\uDFFF]/gu, \"\\uFFFD\")\n}\n\nfunction convertUserParts(content: Array<TextContent | ImageContent>): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const item of content) {\n if (item.type === \"text\") {\n if (item.text) parts.push({ text: sanitize(item.text) })\n } else if (item.type === \"image\" && item.data) {\n parts.push({ inlineData: { mimeType: item.mimeType, data: item.data } })\n }\n }\n return parts\n}\n\nfunction convertAssistantParts(content: Array<TextContent | ThinkingContent | ToolCall>): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const block of content) {\n if (block.type === \"text\" && block.text.trim()) {\n parts.push({ text: sanitize(block.text) })\n } else if (block.type === \"toolCall\") {\n // Antigravity requires the prior functionCall to echo its\n // thoughtSignature on replay (400 INVALID_ARGUMENT otherwise).\n parts.push({\n functionCall: {\n name: block.name,\n args: (block.arguments ?? {}) as Record<string, unknown>,\n },\n ...(block.thoughtSignature ? { thoughtSignature: block.thoughtSignature } : {}),\n })\n }\n // Thinking blocks are intentionally not replayed: OpenCode/pi history does\n // not carry replayable signed Antigravity thinking, and unsigned thinking\n // is rejected. The model regenerates thinking each turn.\n }\n return parts\n}\n\nfunction toolResultResponse(message: ToolResultMessage): Record<string, unknown> {\n const text = message.content\n .filter((item): item is TextContent => item.type === \"text\")\n .map((item) => item.text)\n .join(\"\\n\")\n if (message.isError) {\n return { error: text || \"Error\" }\n }\n return { output: text }\n}\n\nfunction convertMessages(messages: Message[]): GeminiContent[] {\n const contents: GeminiContent[] = []\n\n for (const message of messages) {\n if (!message) continue\n\n if (message.role === \"user\") {\n const parts =\n typeof message.content === \"string\"\n ? message.content.trim()\n ? [{ text: sanitize(message.content) }]\n : []\n : convertUserParts(message.content as Array<TextContent | ImageContent>)\n if (parts.length) contents.push({ role: \"user\", parts })\n continue\n }\n\n if (message.role === \"assistant\") {\n const parts = convertAssistantParts(message.content)\n if (parts.length) contents.push({ role: \"model\", parts })\n continue\n }\n\n if (message.role === \"toolResult\") {\n const part: GeminiPart = {\n functionResponse: {\n name: message.toolName,\n response: toolResultResponse(message),\n },\n }\n // Gemini groups consecutive function responses into one user turn.\n const last = contents[contents.length - 1]\n if (last && last.role === \"user\" && last.parts.every((p) => \"functionResponse\" in p)) {\n last.parts.push(part)\n } else {\n contents.push({ role: \"user\", parts: [part] })\n }\n }\n }\n\n return contents\n}\n\nfunction convertTools(tools: Tool[] | undefined): GeminiTool[] | undefined {\n if (!tools?.length) return undefined\n return [\n {\n functionDeclarations: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parametersJsonSchema: tool.parameters as Record<string, unknown>,\n })),\n },\n ]\n}\n\n/**\n * Convert a pi `Context` into a Gemini `generateContent` request body\n * (the inner `request` object of the Antigravity envelope).\n */\nexport function buildGeminiRequest(context: Context): GeminiRequest {\n const request: GeminiRequest = {\n contents: convertMessages(context.messages),\n }\n\n const tools = convertTools(context.tools)\n if (tools) request.tools = tools\n\n if (context.systemPrompt?.trim()) {\n request.systemInstruction = { parts: [{ text: sanitize(context.systemPrompt) }] }\n }\n\n return request\n}\n", "import {\n authorizeAntigravity,\n exchangeAntigravity,\n getPublicModelDefinitions,\n refreshAntigravityToken,\n} from \"@cortexkit/antigravity-auth-core\"\nimport type {\n OAuthCredentials,\n OAuthLoginCallbacks,\n} from \"@earendil-works/pi-ai\"\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\"\n\nimport { streamCortexKitAntigravity } from \"./stream.ts\"\n\nconst ANTIGRAVITY_PROVIDER_ID = \"google-antigravity\"\n\nfunction textImageInput(): Array<\"text\" | \"image\"> {\n return [\"text\", \"image\"]\n}\n\nasync function loginAntigravity(\n callbacks: OAuthLoginCallbacks,\n): Promise<OAuthCredentials> {\n const auth = await authorizeAntigravity()\n callbacks.onAuth({ url: auth.url })\n const code = await callbacks.onPrompt({\n message: \"Paste the Antigravity OAuth callback URL or code:\",\n })\n\n // The state (PKCE verifier + project) is carried in the authorize URL; reuse\n // it so the code exchange can recover the verifier.\n const authState = new URL(auth.url).searchParams.get(\"state\") ?? \"\"\n\n // Accept either a raw code or a full redirect URL with ?code= and &state=.\n let rawCode = code.trim()\n let state = authState\n try {\n const url = new URL(rawCode)\n const codeParam = url.searchParams.get(\"code\")\n const stateParam = url.searchParams.get(\"state\")\n if (codeParam) rawCode = codeParam\n if (stateParam) state = stateParam\n } catch {\n // Not a URL \u2014 treat the input as a bare authorization code.\n }\n\n const result = await exchangeAntigravity(rawCode, state)\n if (result.type !== \"success\") {\n throw new Error(`Antigravity OAuth exchange failed: ${result.error}`)\n }\n\n return {\n refresh: result.refresh,\n access: result.access,\n expires: result.expires,\n }\n}\n\nasync function refreshAntigravityCredentials(\n credentials: OAuthCredentials,\n): Promise<OAuthCredentials> {\n // Stored refresh is `refreshToken|projectId|managedProjectId`.\n const refreshToken = credentials.refresh.split(\"|\")[0] ?? credentials.refresh\n const refreshed = await refreshAntigravityToken(refreshToken)\n // Preserve the project segments packed into the stored refresh string.\n const projectSegments = credentials.refresh.includes(\"|\")\n ? credentials.refresh.slice(credentials.refresh.indexOf(\"|\"))\n : \"\"\n return {\n refresh: `${refreshed.refresh}${projectSegments}`,\n access: refreshed.access,\n expires: refreshed.expires,\n }\n}\n\nexport default function cortexKitPiAntigravityAuth(pi: ExtensionAPI): void {\n const models = Object.values(getPublicModelDefinitions()).map((model) => ({\n id: model.id,\n name: model.name,\n reasoning: model.reasoning,\n input: textImageInput(),\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n contextWindow: model.limit.context,\n maxTokens: model.limit.output,\n }))\n\n pi.registerProvider(ANTIGRAVITY_PROVIDER_ID, {\n name: \"Google Antigravity (CortexKit OAuth)\",\n baseUrl: \"https://cloudcode-pa.googleapis.com\",\n api: \"google-generative-ai\",\n models,\n oauth: {\n name: \"Google Antigravity (CortexKit)\",\n login: loginAntigravity,\n refreshToken: refreshAntigravityCredentials,\n getApiKey: (credentials) => credentials.access,\n },\n streamSimple: streamCortexKitAntigravity,\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["log", "Buffer", "isClaudeModel", "Buffer", "Buffer", "Buffer", "decode", "encode", "encode", "decode", "encoder", "log", "decoder"]
7
+ }
@@ -0,0 +1,3 @@
1
+ export declare function getPiConfigDir(): string;
2
+ export declare function getPiAntigravityAuthFile(): string;
3
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAGA,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAKjD"}
@@ -0,0 +1,32 @@
1
+ import { type Api, type AssistantMessage, type AssistantMessageEventStream, type Context, type Model, type SimpleStreamOptions } from "@earendil-works/pi-ai";
2
+ interface GeminiUsageMetadata {
3
+ promptTokenCount?: number;
4
+ candidatesTokenCount?: number;
5
+ cachedContentTokenCount?: number;
6
+ thoughtsTokenCount?: number;
7
+ totalTokenCount?: number;
8
+ }
9
+ interface GeminiStreamChunk {
10
+ candidates?: Array<{
11
+ content?: {
12
+ role?: string;
13
+ parts?: GeminiResponsePart[];
14
+ };
15
+ finishReason?: string;
16
+ }>;
17
+ usageMetadata?: GeminiUsageMetadata;
18
+ }
19
+ interface GeminiResponsePart {
20
+ text?: string;
21
+ thought?: boolean;
22
+ thoughtSignature?: string;
23
+ functionCall?: {
24
+ name?: string;
25
+ args?: Record<string, unknown>;
26
+ };
27
+ }
28
+ export declare function updateUsage(model: Model<Api>, output: AssistantMessage, usage?: GeminiUsageMetadata): void;
29
+ export declare function parseGeminiSse(response: Response): AsyncGenerator<GeminiStreamChunk>;
30
+ export declare function streamCortexKitAntigravity(model: Model<Api>, context: Context, options?: SimpleStreamOptions): AssistantMessageEventStream;
31
+ export {};
32
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,GAAG,EACR,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,OAAO,EAGZ,KAAK,KAAK,EACV,KAAK,mBAAmB,EAIzB,MAAM,uBAAuB,CAAA;AAqC9B,UAAU,mBAAmB;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,UAAU,iBAAiB;IACzB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,OAAO,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,kBAAkB,EAAE,CAAA;SAAE,CAAA;QACzD,YAAY,CAAC,EAAE,MAAM,CAAA;KACtB,CAAC,CAAA;IACF,aAAa,CAAC,EAAE,mBAAmB,CAAA;CACpC;AAkBD,UAAU,kBAAkB;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;CACjE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAe1G;AAED,wBAAuB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,iBAAiB,CAAC,CAyC3F;AAyED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,2BAA2B,CA0G7B"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@cortexkit/pi-antigravity-auth",
3
+ "version": "1.0.0",
4
+ "description": "Google Antigravity OAuth extension for pi - access Gemini 3 and Claude 4.6 using Google credentials",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "CortexKit",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/cortexkit/antigravity-auth.git",
11
+ "directory": "packages/pi"
12
+ },
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "import": "./dist/index.js",
18
+ "types": "./dist/index.d.ts"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "keywords": [
27
+ "pi-package",
28
+ "google",
29
+ "antigravity",
30
+ "gemini",
31
+ "oauth",
32
+ "claude"
33
+ ],
34
+ "pi": {
35
+ "extensions": [
36
+ "./dist/index.js"
37
+ ]
38
+ },
39
+ "scripts": {
40
+ "build": "rm -rf dist && tsc -p tsconfig.build.json --emitDeclarationOnly && esbuild src/index.ts --bundle --platform=node --format=esm --external:@earendil-works/* --alias:@cortexkit/antigravity-auth-core=../core/src/index.ts --outfile=dist/index.js --sourcemap",
41
+ "typecheck": "tsc --noEmit",
42
+ "test": "vitest run",
43
+ "prepublishOnly": "npm run build"
44
+ },
45
+ "dependencies": {
46
+ "@cortexkit/antigravity-auth-core": "1.0.0"
47
+ },
48
+ "peerDependencies": {
49
+ "@earendil-works/pi-ai": "*",
50
+ "@earendil-works/pi-coding-agent": "*",
51
+ "@earendil-works/pi-tui": "*"
52
+ },
53
+ "devDependencies": {
54
+ "@earendil-works/pi-ai": "^0.79.1",
55
+ "@earendil-works/pi-coding-agent": "^0.79.1",
56
+ "@earendil-works/pi-tui": "^0.79.1",
57
+ "@types/node": "^24.10.1",
58
+ "typescript": "^5.0.0",
59
+ "vitest": "^3.0.0"
60
+ }
61
+ }