@cortexkit/pi-antigravity-auth 1.1.0 → 2.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.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../core/src/logger.ts", "../../core/src/fingerprint.ts", "../../core/src/constants.ts", "../../core/src/auth.ts", "../../core/src/agy-transport.ts", "../../core/src/agy-request-metadata.ts", "../../core/src/project.ts", "../../core/src/model-registry.ts", "../../core/src/transform/model-resolver.ts", "../../core/src/transform/gemini.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/credential-cache.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 * Device Fingerprint Generator for Rate Limit Mitigation\n *\n * Uses the agy CLI 1.1.5 content-request identity captured with mitmproxy:\n * an Antigravity CLI User-Agent with explicit client, OS, architecture, and auth metadata.\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.1.5\";\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 authMethod = \"consumer\",\n): string {\n const osType = normalizeHarnessPlatform(platform);\n const normalizedArch = normalizeHarnessArch(arch);\n return `antigravity/cli/${version} (aidev_client; os_type=${osType}; arch=${normalizedArch}; auth_method=${authMethod})`;\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 and the\n * pre-1.1.3 platform/arch-only User-Agent to the captured metadata 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", "/**\n * Constants used for Antigravity OAuth flows and Cloud Code Assist API integration.\n */\n\nimport { buildAntigravityHarnessUserAgent } from \"./fingerprint.ts\";\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.1.5 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;\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 return {\n \"User-Agent\": buildAntigravityHarnessUserAgent(),\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", "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\nimport { buildAntigravityHarnessUserAgent } from \"./fingerprint.ts\"\n\nconst DEFAULT_HTTPS_PORT = 443\nconst DEFAULT_PROXY_PORT = 8080\n\nexport const DEFAULT_AGY_RESPONSE_HEADER_TIMEOUT_MS = 180_000\n// Max time the response body may stall (no bytes received) before the socket is\n// destroyed. Streaming responses emit data far more frequently than this; a\n// truly hung body would otherwise hold the socket open indefinitely.\nexport const DEFAULT_AGY_IDLE_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 /**\n * Maximum time the response body may stall (no bytes) before the socket is\n * destroyed. Resets on every received chunk. Defaults to\n * DEFAULT_AGY_IDLE_TIMEOUT_MS.\n */\n idleTimeoutMs?: 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 contentLength?: number\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\") ?? buildAntigravityHarnessUserAgent()\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 let contentLength: number | undefined\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 (lowerKey === \"content-length\") {\n const parsed = Number.parseInt(value, 10)\n if (Number.isFinite(parsed) && parsed >= 0) {\n contentLength = parsed\n }\n // Drop content-length from the surfaced headers when gzip is set, since\n // the decoded body length differs from the wire length.\n if (gzip) 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 contentLength,\n }\n}\n\nexport class ContentLengthStream extends Transform {\n private remaining: number\n\n constructor(contentLength: number) {\n super()\n this.remaining = contentLength\n }\n\n override _transform(chunk: Buffer, _encoding: BufferEncoding, callback: (error?: Error | null) => void): void {\n if (this.remaining <= 0) {\n callback()\n return\n }\n if (chunk.length <= this.remaining) {\n this.remaining -= chunk.length\n this.push(chunk)\n } else {\n // Emit only up to the declared length; discard any trailing bytes that\n // belong to the next keep-alive response.\n this.push(chunk.subarray(0, this.remaining))\n this.remaining = 0\n }\n if (this.remaining <= 0) {\n this.push(null)\n }\n callback()\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 idleTimeoutMs?: number,\n onDebug?: (message: string) => void,\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 } else if (typeof head.contentLength === \"number\") {\n // Non-chunked with a known length: emit exactly contentLength bytes then\n // end, rather than reading until socket EOF (which over-reads on keep-alive\n // connections and never ends if the server keeps the socket open).\n responseBody = responseBody.pipe(new ContentLengthStream(head.contentLength))\n }\n if (head.gzip) {\n responseBody = responseBody.pipe(createGunzip())\n }\n\n // Idle-read watchdog: if no body bytes arrive within idleTimeoutMs, destroy\n // the socket so a hung/stalled response can't hold the connection forever.\n let idleTimer: ReturnType<typeof setTimeout> | undefined\n const clearIdle = () => {\n if (idleTimer) {\n clearTimeout(idleTimer)\n idleTimer = undefined\n }\n }\n const armIdle = () => {\n if (!idleTimeoutMs || idleTimeoutMs <= 0) return\n clearIdle()\n idleTimer = setTimeout(() => {\n onDebug?.(`agy transport idle timeout after ${idleTimeoutMs}ms with no body data`)\n socket.destroy(new Error(`Antigravity response stalled: no data for ${idleTimeoutMs}ms`))\n }, idleTimeoutMs)\n }\n socket.on(\"data\", armIdle)\n armIdle()\n\n const abort = () => socket.destroy(new DOMException(\"The operation was aborted\", \"AbortError\"))\n const cleanup = () => {\n clearIdle()\n socket.off(\"data\", armIdle)\n signal?.removeEventListener(\"abort\", abort)\n }\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 if (options.signal?.aborted) {\n throw new DOMException(\"The operation was aborted\", \"AbortError\")\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 const idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_AGY_IDLE_TIMEOUT_MS\n options.onDebug?.(`agy transport connecting to ${parsedUrl.hostname} with header timeout ${timeoutMs}ms`)\n // Race the connect against abort so a cancel during TLS/proxy connect is\n // honored immediately instead of waiting out the connect timeout.\n const socket = await connectTlsWithAbort(parsedUrl, timeoutMs, options.signal, 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, idleTimeoutMs, options.onDebug)\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\nasync function connectTlsWithAbort(\n targetUrl: URL,\n timeoutMs: number,\n signal: AbortSignal | null | undefined,\n onDebug?: (message: string) => void,\n): Promise<tls.TLSSocket> {\n if (!signal) {\n return connectTls(targetUrl, timeoutMs, onDebug)\n }\n const connectPromise = connectTls(targetUrl, timeoutMs, onDebug)\n let onAbort: (() => void) | undefined\n const abortPromise = new Promise<never>((_, reject) => {\n onAbort = () => reject(new DOMException(\"The operation was aborted\", \"AbortError\"))\n signal.addEventListener(\"abort\", onAbort, { once: true })\n })\n try {\n return await Promise.race([connectPromise, abortPromise])\n } catch (error) {\n // If abort won the race, make sure the in-flight socket is torn down once it resolves.\n void connectPromise.then((socket) => socket.destroy()).catch(() => {})\n throw error\n } finally {\n if (onAbort) signal.removeEventListener(\"abort\", onAbort)\n }\n}\n", "import { Buffer } from \"node:buffer\"\nimport { randomUUID } from \"node:crypto\"\n\nconst FNV1A_64_OFFSET_BASIS = 0xcbf29ce484222325n\nconst FNV1A_64_PRIME = 0x100000001b3n\nconst DEFAULT_SESSION_STATE_TTL_MS = 24 * 60 * 60 * 1000\nconst DEFAULT_MAX_SESSION_STATES = 256\n\nconst AGY_REQUEST_FIELD_ORDER = [\n \"contents\",\n \"systemInstruction\",\n \"tools\",\n \"toolConfig\",\n \"labels\",\n \"generationConfig\",\n \"sessionId\",\n] as const\n\nconst AGY_MODEL_ENUM_BY_WIRE_MODEL: Readonly<Record<string, string>> = {\n \"gemini-3.5-flash-extra-low\": \"MODEL_PLACEHOLDER_M187\",\n \"gemini-3.5-flash-low\": \"MODEL_PLACEHOLDER_M20\",\n \"gemini-3-flash-agent\": \"MODEL_PLACEHOLDER_M84\",\n \"gemini-3.6-flash-low\": \"MODEL_PLACEHOLDER_M266\",\n \"gemini-3.6-flash-medium\": \"MODEL_PLACEHOLDER_M265\",\n \"gemini-3.6-flash-high\": \"MODEL_PLACEHOLDER_M264\",\n \"gemini-3.1-pro-low\": \"MODEL_PLACEHOLDER_M36\",\n \"gemini-pro-agent\": \"MODEL_PLACEHOLDER_M16\",\n \"claude-sonnet-4-6\": \"MODEL_PLACEHOLDER_M35\",\n \"claude-opus-4-6-thinking\": \"MODEL_PLACEHOLDER_M26\",\n \"gemini-3.1-flash-image\": \"MODEL_PLACEHOLDER_M21\",\n \"gpt-oss-120b-medium\": \"MODEL_OPENAI_GPT_OSS_120B_MEDIUM\",\n}\n\nexport interface AgyRequestSessionContext {\n conversationId: string\n trajectoryId: string\n numericSessionId: string\n usedClaude?: boolean\n usedNonGeminiModel?: boolean\n}\n\ninterface StoredAgyRequestSession {\n context: AgyRequestSessionContext\n lastAccessedAt: number\n lastRequestTimestamp: number\n}\n\nexport interface AgyRequestSessionStoreOptions {\n ttlMs?: number\n maxEntries?: number\n now?: () => number\n}\n\nexport interface AgyRequestScope {\n session: AgyRequestSessionContext\n timestamp: number\n}\n\nexport interface AgyRequestLabels {\n last_step_index: string\n model_enum?: string\n trajectory_id: string\n used_claude: \"true\" | \"false\"\n used_claude_conservative: \"true\" | \"false\"\n used_non_gemini_model: \"true\" | \"false\"\n}\n\nexport interface AgyAgentRequestMetadata {\n requestId: string\n sessionId: string\n labels: AgyRequestLabels\n lastStepIndex: number\n}\n\nexport function fnv1a64Signed(input: string): string {\n let hash = FNV1A_64_OFFSET_BASIS\n for (const byte of Buffer.from(input, \"utf8\")) {\n hash ^= BigInt(byte)\n hash = BigInt.asUintN(64, hash * FNV1A_64_PRIME)\n }\n return BigInt.asIntN(64, hash).toString()\n}\n\nexport function createAgyRequestSessionContext(\n workspaceUri: string,\n ids: { conversationId?: string; trajectoryId?: string } = {},\n): AgyRequestSessionContext {\n return {\n conversationId: ids.conversationId ?? randomUUID(),\n trajectoryId: ids.trajectoryId ?? randomUUID(),\n numericSessionId: fnv1a64Signed(workspaceUri),\n }\n}\n\nexport class AgyRequestSessionStore {\n private readonly entries = new Map<string, StoredAgyRequestSession>()\n private readonly workspaceUri: string\n private readonly ttlMs: number\n private readonly maxEntries: number\n private readonly now: () => number\n\n constructor(workspaceUri: string, options: AgyRequestSessionStoreOptions = {}) {\n this.workspaceUri = workspaceUri\n this.ttlMs = options.ttlMs ?? DEFAULT_SESSION_STATE_TTL_MS\n this.maxEntries = options.maxEntries ?? DEFAULT_MAX_SESSION_STATES\n this.now = options.now ?? Date.now\n }\n\n getOrCreate(key: string): AgyRequestSessionContext {\n const timestamp = this.now()\n this.prune(timestamp, key)\n\n const existing = this.entries.get(key)\n if (existing) {\n existing.lastAccessedAt = timestamp\n return existing.context\n }\n\n const context = createAgyRequestSessionContext(this.workspaceUri)\n this.entries.set(key, {\n context,\n lastAccessedAt: timestamp,\n lastRequestTimestamp: 0,\n })\n return context\n }\n\n beginRequest(key: string): AgyRequestScope {\n const session = this.getOrCreate(key)\n const stored = this.entries.get(key)!\n const timestamp = Math.max(stored.lastAccessedAt, stored.lastRequestTimestamp + 1)\n stored.lastRequestTimestamp = timestamp\n return { session, timestamp }\n }\n\n has(key: string): boolean {\n return this.entries.has(key)\n }\n\n delete(key: string): void {\n this.entries.delete(key)\n }\n\n get size(): number {\n return this.entries.size\n }\n\n private prune(timestamp: number, preservedKey: string): void {\n const expiry = timestamp - this.ttlMs\n for (const [key, value] of this.entries) {\n if (key !== preservedKey && value.lastAccessedAt < expiry) {\n this.entries.delete(key)\n }\n }\n\n while (this.entries.size >= this.maxEntries && !this.entries.has(preservedKey)) {\n let oldestKey: string | null = null\n let oldestAccess = Number.POSITIVE_INFINITY\n for (const [key, value] of this.entries) {\n if (key !== preservedKey && value.lastAccessedAt < oldestAccess) {\n oldestKey = key\n oldestAccess = value.lastAccessedAt\n }\n }\n if (!oldestKey) {\n break\n }\n this.entries.delete(oldestKey)\n }\n }\n}\n\nexport function getAgyModelEnum(model: string): string | undefined {\n return AGY_MODEL_ENUM_BY_WIRE_MODEL[model.toLowerCase()]\n}\n\nexport function orderAgyRequestPayloadInPlace(payload: Record<string, unknown>): void {\n const ordered: Record<string, unknown> = {}\n const remaining = new Set(Object.keys(payload))\n\n for (const key of AGY_REQUEST_FIELD_ORDER) {\n if (key in payload) {\n ordered[key] = payload[key]\n remaining.delete(key)\n }\n }\n for (const key of remaining) {\n ordered[key] = payload[key]\n }\n\n for (const key of Object.keys(payload)) {\n delete payload[key]\n }\n Object.assign(payload, ordered)\n}\n\nexport function countAgyRequestSteps(payload: Record<string, unknown>): number {\n const contents = payload.contents\n if (!Array.isArray(contents)) {\n return 1\n }\n\n let partCount = 0\n for (const content of contents) {\n if (!content || typeof content !== \"object\" || Array.isArray(content)) {\n continue\n }\n const parts = (content as Record<string, unknown>).parts\n if (Array.isArray(parts)) {\n partCount += parts.length\n }\n }\n return Math.max(1, partCount)\n}\n\nexport function buildAgyAgentRequestMetadata(\n session: AgyRequestSessionContext,\n payload: Record<string, unknown>,\n model: string,\n timestamp = Date.now(),\n): AgyAgentRequestMetadata {\n const lastStepIndex = countAgyRequestSteps(payload)\n const isClaude = model.toLowerCase().startsWith(\"claude-\")\n const isNonGemini = isClaude || model.toLowerCase().startsWith(\"gpt-\")\n session.usedClaude = session.usedClaude === true || isClaude\n session.usedNonGeminiModel = session.usedNonGeminiModel === true || isNonGemini\n const modelEnum = getAgyModelEnum(model)\n const labels: AgyRequestLabels = {\n last_step_index: String(lastStepIndex),\n ...(modelEnum ? { model_enum: modelEnum } : {}),\n trajectory_id: session.trajectoryId,\n used_claude: session.usedClaude ? \"true\" : \"false\",\n used_claude_conservative: session.usedClaude ? \"true\" : \"false\",\n used_non_gemini_model: session.usedNonGeminiModel ? \"true\" : \"false\",\n }\n\n return {\n requestId: `agent/${session.conversationId}/${timestamp}/${session.trajectoryId}/${lastStepIndex + 1}`,\n sessionId: session.numericSessionId,\n labels,\n lastStepIndex,\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 AntigravityTieredRouteMetadata {\n defaultModel: string\n byTier: Partial<Record<ThinkingTier, string>>\n}\n\ninterface GeminiFlashRouteMetadata {\n antigravity: AntigravityTieredRouteMetadata\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.6-flash\": defineModel(\"antigravity-gemini-3.6-flash\", {\n name: \"Gemini 3.6 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-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-medium\": defineModel(\"antigravity-gpt-oss-120b-medium\", {\n name: \"GPT-OSS 120B Medium (Antigravity)\",\n reasoning: true,\n limit: { context: 131072, output: 32768 },\n modalities: DEFAULT_MODALITIES,\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-3.6-flash-low\": \"gemini-3.6-flash\",\n \"gemini-3.6-flash-medium\": \"gemini-3.6-flash\",\n \"gemini-3.6-flash-high\": \"gemini-3.6-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 \"gpt-oss-120b\": \"gpt-oss-120b-medium\",\n}\n\nconst GEMINI_35_FLASH_ROUTES: GeminiFlashRouteMetadata = {\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 GEMINI_36_FLASH_ROUTES: AntigravityTieredRouteMetadata = {\n defaultModel: \"gemini-3.6-flash-medium\",\n byTier: {\n low: \"gemini-3.6-flash-low\",\n medium: \"gemini-3.6-flash-medium\",\n high: \"gemini-3.6-flash-high\",\n },\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.6-flash-low\": \"gemini-flash\",\n \"gemini-3.6-flash-medium\": \"gemini-flash\",\n \"gemini-3.6-flash-high\": \"gemini-flash\",\n \"gemini-3.6-flash-tiered\": \"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.6-flash\",\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 \"antigravity-gemini-3.1-flash-image\",\n \"antigravity-gpt-oss-120b-medium\",\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 getGemini36FlashAntigravityModel(tier?: ThinkingTier): string {\n if (!tier) {\n return GEMINI_36_FLASH_ROUTES.defaultModel\n }\n return GEMINI_36_FLASH_ROUTES.byTier[tier] ?? GEMINI_36_FLASH_ROUTES.defaultModel\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 getGemini36FlashAntigravityModel,\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 getAgyGeminiFlashThinkingBudget(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 and 3.6 Flash use live-catalog route maps\n // with numeric thinking budgets instead.\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 const isGemini36Flash = /^gemini-3\\.6-flash/i.test(baseName);\n const isGptOss120b = /^gpt-oss-120b(?:-medium)?$/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: getAgyGeminiFlashThinkingBudget(tier),\n tier: tier ?? \"medium\",\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n if (isGemini36Flash && quotaPreference === \"antigravity\") {\n return {\n actualModel: getGemini36FlashAntigravityModel(tier ?? \"medium\"),\n thinkingBudget: getAgyGeminiFlashThinkingBudget(tier),\n tier: tier ?? \"medium\",\n isThinkingModel: true,\n quotaPreference,\n explicitQuota,\n };\n }\n\n if (isGptOss120b && quotaPreference === \"antigravity\") {\n return {\n actualModel: \"gpt-oss-120b-medium\",\n thinkingBudget: 8192,\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", "/**\n * Gemini-specific Request Transformations\n * \n * Handles Gemini model-specific request transformations including:\n * - Thinking config (camelCase keys, thinkingLevel for Gemini 3)\n * - Tool normalization (function/custom format)\n * - Schema transformation (JSON Schema -> Gemini Schema format)\n */\n\nimport type { RequestPayload, ThinkingConfig, ThinkingTier, GoogleSearchConfig } from \"./types.ts\";\n\n/**\n * Transform a JSON Schema to Gemini-compatible format.\n * Based on @google/genai SDK's processJsonSchema() function.\n * \n * Key transformations:\n * - Converts type values to uppercase (object -> OBJECT)\n * - Removes unsupported fields like additionalProperties, $schema\n * - Recursively processes nested schemas (properties, items, anyOf, etc.)\n * \n * @param schema - A JSON Schema object or primitive value\n * @returns Gemini-compatible schema\n * \n * Fields that Gemini API rejects and must be removed from schemas.\n * Antigravity uses strict protobuf-backed JSON validation.\n */\nconst UNSUPPORTED_SCHEMA_FIELDS = new Set([\n \"additionalProperties\",\n \"$schema\",\n \"$id\",\n \"$comment\",\n \"$ref\",\n \"$defs\",\n \"definitions\",\n \"const\",\n \"contentMediaType\",\n \"contentEncoding\",\n \"if\",\n \"then\",\n \"else\",\n \"not\",\n \"patternProperties\",\n \"unevaluatedProperties\",\n \"unevaluatedItems\",\n \"dependentRequired\",\n \"dependentSchemas\",\n \"propertyNames\",\n \"minContains\",\n \"maxContains\",\n]);\n\nconst NUMERIC_SCHEMA_CONSTRAINTS = new Set([\n \"minLength\",\n \"maxLength\",\n \"minItems\",\n \"maxItems\",\n \"minProperties\",\n \"maxProperties\",\n \"minimum\",\n \"maximum\",\n \"exclusiveMinimum\",\n \"exclusiveMaximum\",\n \"multipleOf\",\n])\n\nexport interface GeminiSchemaOptions {\n /**\n * AGY's GPT bridge re-encodes protobuf numeric constraints as strings before\n * OpenAI JSON Schema validation. Move them to descriptions instead.\n */\n moveNumericConstraintsToDescription?: boolean\n}\n\nexport function toGeminiSchema(schema: unknown, options: GeminiSchemaOptions = {}): unknown {\n // Return primitives and arrays as-is\n if (!schema || typeof schema !== \"object\" || Array.isArray(schema)) {\n return schema;\n }\n\n const inputSchema = schema as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n const numericConstraintHints: string[] = [];\n\n // First pass: collect all property names for required validation\n const propertyNames = new Set<string>();\n if (inputSchema.properties && typeof inputSchema.properties === \"object\") {\n for (const propName of Object.keys(inputSchema.properties as Record<string, unknown>)) {\n propertyNames.add(propName);\n }\n }\n\n for (const [key, value] of Object.entries(inputSchema)) {\n // Skip unsupported fields that Gemini API rejects\n if (UNSUPPORTED_SCHEMA_FIELDS.has(key)) {\n continue;\n }\n\n if (key === \"type\" && typeof value === \"string\") {\n // Convert type to uppercase for Gemini API\n result[key] = value.toUpperCase();\n } else if (key === \"properties\" && typeof value === \"object\" && value !== null) {\n // Recursively transform nested property schemas\n const props: Record<string, unknown> = {};\n for (const [propName, propSchema] of Object.entries(value as Record<string, unknown>)) {\n props[propName] = toGeminiSchema(propSchema, options);\n }\n result[key] = props;\n } else if (key === \"items\" && typeof value === \"object\") {\n // Transform array items schema\n result[key] = toGeminiSchema(value, options);\n } else if ((key === \"anyOf\" || key === \"oneOf\" || key === \"allOf\") && Array.isArray(value)) {\n // Transform union type schemas\n result[key] = value.map((item) => toGeminiSchema(item, options));\n } else if (key === \"enum\" && Array.isArray(value)) {\n // Keep enum values as-is\n result[key] = value;\n } else if (\n options.moveNumericConstraintsToDescription &&\n NUMERIC_SCHEMA_CONSTRAINTS.has(key)\n ) {\n if (typeof value === \"string\" || typeof value === \"number\") {\n numericConstraintHints.push(`${key}: ${value}`)\n }\n } else if (key === \"default\" || key === \"examples\") {\n // Keep default and examples as-is\n result[key] = value;\n } else if (key === \"required\" && Array.isArray(value)) {\n // Filter required array to only include properties that exist\n // This fixes: \"parameters.required[X]: property is not defined\"\n if (propertyNames.size > 0) {\n const validRequired = value.filter((prop) =>\n typeof prop === \"string\" && propertyNames.has(prop)\n );\n if (validRequired.length > 0) {\n result[key] = validRequired;\n }\n // If no valid required properties, omit the required field entirely\n } else {\n // If there are no properties, keep required as-is (might be a schema without properties)\n result[key] = value;\n }\n } else {\n result[key] = value;\n }\n }\n\n if (numericConstraintHints.length > 0) {\n const hint = numericConstraintHints.join(\", \")\n result.description = typeof result.description === \"string\" && result.description\n ? `${result.description} (${hint})`\n : hint\n }\n\n // Issue #80: Ensure array schemas have an 'items' field\n // Gemini API requires: \"parameters.properties[X].items: missing field\"\n if (result.type === \"ARRAY\" && !result.items) {\n result.items = { type: \"STRING\" };\n }\n\n return result;\n}\n\n/**\n * Check if a model is a Gemini model (not Claude).\n */\nexport function isGeminiModel(model: string): boolean {\n const lower = model.toLowerCase();\n return lower.includes(\"gemini\") && !lower.includes(\"claude\");\n}\n\n/**\n * Check if a model is Gemini 3 (uses thinkingLevel string).\n */\nexport function isGemini3Model(model: string): boolean {\n return model.toLowerCase().includes(\"gemini-3\");\n}\n\n/**\n * Check if a model is Gemini 2.5 (uses numeric thinkingBudget).\n */\nexport function isGemini25Model(model: string): boolean {\n return model.toLowerCase().includes(\"gemini-2.5\");\n}\n\n/**\n * Check if a model is an image generation model.\n * Image models don't support thinking and require imageConfig.\n */\nexport function isImageGenerationModel(model: string): boolean {\n const lower = model.toLowerCase();\n return (\n lower.includes(\"image\") ||\n lower.includes(\"imagen\")\n );\n}\n\n/**\n * Build Gemini 3 thinking config with thinkingLevel string.\n */\nexport function buildGemini3ThinkingConfig(\n includeThoughts: boolean,\n thinkingLevel: ThinkingTier,\n): ThinkingConfig {\n return {\n includeThoughts,\n thinkingLevel,\n };\n}\n\n/**\n * Build Gemini 2.5 thinking config with numeric thinkingBudget.\n */\nexport function buildGemini25ThinkingConfig(\n includeThoughts: boolean,\n thinkingBudget?: number,\n): ThinkingConfig {\n return {\n includeThoughts,\n ...(typeof thinkingBudget === \"number\" && thinkingBudget > 0 ? { thinkingBudget } : {}),\n };\n}\n\n/**\n * Image generation config for Gemini image models.\n * \n * Supported aspect ratios: \"1:1\", \"2:3\", \"3:2\", \"3:4\", \"4:3\", \"4:5\", \"5:4\", \"9:16\", \"16:9\", \"21:9\"\n */\nexport interface ImageConfig {\n aspectRatio?: string;\n}\n\n/**\n * Valid aspect ratios for image generation.\n */\nconst VALID_ASPECT_RATIOS = [\"1:1\", \"2:3\", \"3:2\", \"3:4\", \"4:3\", \"4:5\", \"5:4\", \"9:16\", \"16:9\", \"21:9\"];\n\n/**\n * Build image generation config for Gemini image models.\n * \n * Configuration is read from environment variables:\n * - OPENCODE_IMAGE_ASPECT_RATIO: Aspect ratio (e.g., \"16:9\", \"4:3\")\n * \n * Defaults to 1:1 aspect ratio if not specified.\n * \n * Note: Resolution setting is not currently supported by the Antigravity API.\n */\nexport function buildImageGenerationConfig(): ImageConfig {\n // Read aspect ratio from environment or default to 1:1\n const aspectRatio = process.env.OPENCODE_IMAGE_ASPECT_RATIO || \"1:1\";\n\n if (VALID_ASPECT_RATIOS.includes(aspectRatio)) {\n return { aspectRatio };\n }\n\n console.warn(`[gemini] Invalid aspect ratio \"${aspectRatio}\". Using default \"1:1\". Valid values: ${VALID_ASPECT_RATIOS.join(\", \")}`);\n\n // Default to 1:1 square aspect ratio\n return { aspectRatio: \"1:1\" };\n}\n\n/**\n * Normalize tools for Gemini models.\n * Ensures tools have proper function-style format.\n * \n * @returns Debug info about tool normalization\n */\nexport function normalizeGeminiTools(\n payload: RequestPayload,\n schemaOptions: GeminiSchemaOptions = {},\n): { toolDebugMissing: number; toolDebugSummaries: string[] } {\n let toolDebugMissing = 0;\n const toolDebugSummaries: string[] = [];\n\n if (!Array.isArray(payload.tools)) {\n return { toolDebugMissing, toolDebugSummaries };\n }\n\n payload.tools = (payload.tools as unknown[]).map((tool: unknown, toolIndex: number) => {\n const t = tool as Record<string, unknown>;\n\n // Skip normalization for Google Search tools (both old and new API)\n if (t.googleSearch || t.googleSearchRetrieval) {\n return t;\n }\n\n if (Array.isArray(t.functionDeclarations)) {\n return {\n ...t,\n functionDeclarations: t.functionDeclarations.map((declaration) => {\n const normalized = { ...(declaration as Record<string, unknown>) }\n const rawSchema = normalized.parameters ?? normalized.parametersJsonSchema ?? {\n type: \"OBJECT\",\n properties: {},\n }\n normalized.parameters = toGeminiSchema(rawSchema, schemaOptions)\n delete normalized.parametersJsonSchema\n return normalized\n }),\n }\n }\n\n const newTool = { ...t };\n\n const schemaCandidates = [\n (newTool.function as Record<string, unknown> | undefined)?.input_schema,\n (newTool.function as Record<string, unknown> | undefined)?.parameters,\n (newTool.function as Record<string, unknown> | undefined)?.inputSchema,\n (newTool.custom as Record<string, unknown> | undefined)?.input_schema,\n (newTool.custom as Record<string, unknown> | undefined)?.parameters,\n newTool.parameters,\n newTool.input_schema,\n newTool.inputSchema,\n ].filter(Boolean);\n\n const placeholderSchema: Record<string, unknown> = {\n type: \"OBJECT\",\n properties: {\n _placeholder: {\n type: \"BOOLEAN\",\n description: \"Placeholder. Always pass true.\",\n },\n },\n required: [\"_placeholder\"],\n };\n\n let schema = schemaCandidates[0] as Record<string, unknown> | undefined;\n const schemaObjectOk = schema && typeof schema === \"object\" && !Array.isArray(schema);\n if (!schemaObjectOk) {\n schema = placeholderSchema;\n toolDebugMissing += 1;\n } else {\n // Transform existing schema to Gemini-compatible format\n schema = toGeminiSchema(schema, schemaOptions) as Record<string, unknown>;\n }\n\n const nameCandidate =\n newTool.name ||\n (newTool.function as Record<string, unknown> | undefined)?.name ||\n (newTool.custom as Record<string, unknown> | undefined)?.name ||\n `tool-${toolIndex}`;\n\n // Always update function.input_schema with transformed schema\n if (newTool.function && schema) {\n (newTool.function as Record<string, unknown>).input_schema = schema;\n }\n\n // Always update custom.input_schema with transformed schema\n if (newTool.custom && schema) {\n (newTool.custom as Record<string, unknown>).input_schema = schema;\n }\n\n // Create custom from function if missing\n if (!newTool.custom && newTool.function) {\n const fn = newTool.function as Record<string, unknown>;\n newTool.custom = {\n name: fn.name || nameCandidate,\n description: fn.description,\n input_schema: schema,\n };\n }\n\n // Create custom if both missing\n if (!newTool.custom && !newTool.function) {\n newTool.custom = {\n name: nameCandidate,\n description: newTool.description,\n input_schema: schema,\n };\n\n if (!newTool.parameters && !newTool.input_schema && !newTool.inputSchema) {\n newTool.parameters = schema;\n }\n }\n\n if (newTool.custom && !(newTool.custom as Record<string, unknown>).input_schema) {\n (newTool.custom as Record<string, unknown>).input_schema = {\n type: \"OBJECT\",\n properties: {},\n };\n toolDebugMissing += 1;\n }\n\n toolDebugSummaries.push(\n `idx=${toolIndex}, hasCustom=${!!newTool.custom}, customSchema=${!!(newTool.custom as Record<string, unknown> | undefined)?.input_schema}, hasFunction=${!!newTool.function}, functionSchema=${!!(newTool.function as Record<string, unknown> | undefined)?.input_schema}`,\n );\n\n // Strip custom wrappers for Gemini; only function-style is accepted.\n if (newTool.custom) {\n delete newTool.custom;\n }\n\n return newTool;\n });\n\n return { toolDebugMissing, toolDebugSummaries };\n}\n\n/**\n * Apply all Gemini-specific transformations to a request payload.\n */\nexport interface GeminiTransformOptions {\n /** The effective model name (resolved) */\n model: string;\n /** Tier-based thinking budget (from model suffix, for Gemini 2.5) */\n tierThinkingBudget?: number;\n /** Tier-based thinking level (from model suffix, for Gemini 3) */\n tierThinkingLevel?: ThinkingTier;\n /** Normalized thinking config from user settings */\n normalizedThinking?: { includeThoughts?: boolean; thinkingBudget?: number };\n /** Google Search configuration */\n googleSearch?: GoogleSearchConfig;\n}\n\nexport interface GeminiTransformResult {\n toolDebugMissing: number;\n toolDebugSummaries: string[];\n /** Number of function declarations after wrapping */\n wrappedFunctionCount: number;\n /** Number of passthrough tools (googleSearch, googleSearchRetrieval, codeExecution) */\n passthroughToolCount: number;\n}\n\n/**\n * Apply all Gemini-specific transformations.\n */\nexport function applyGeminiTransforms(\n payload: RequestPayload,\n options: GeminiTransformOptions,\n): GeminiTransformResult {\n const { model, tierThinkingBudget, tierThinkingLevel, normalizedThinking, googleSearch } = options;\n\n // 1. Apply thinking config if needed\n if (normalizedThinking) {\n let thinkingConfig: ThinkingConfig;\n\n if (tierThinkingLevel && isGemini3Model(model)) {\n // Gemini 3 uses thinkingLevel string\n thinkingConfig = buildGemini3ThinkingConfig(\n normalizedThinking.includeThoughts ?? true,\n tierThinkingLevel,\n );\n } else {\n // Gemini 2.5 and others use numeric budget\n const thinkingBudget = tierThinkingBudget ?? normalizedThinking.thinkingBudget;\n thinkingConfig = buildGemini25ThinkingConfig(\n normalizedThinking.includeThoughts ?? true,\n thinkingBudget,\n );\n }\n\n const generationConfig = (payload.generationConfig ?? {}) as Record<string, unknown>;\n generationConfig.thinkingConfig = thinkingConfig;\n payload.generationConfig = generationConfig;\n }\n\n // 2. Apply Google Search (Grounding) if enabled\n // Uses the new googleSearch API for Gemini 2.0+ / Gemini 3 models\n // Note: The old googleSearchRetrieval with dynamicRetrievalConfig is deprecated\n // The new API doesn't support threshold - the model decides when to search automatically\n if (googleSearch && googleSearch.mode === 'auto') {\n const tools = (payload.tools as unknown[]) || [];\n if (!payload.tools) {\n payload.tools = tools;\n }\n\n // Add Google Search tool using new API format for Gemini 2.0+\n // See: https://ai.google.dev/gemini-api/docs/grounding\n (payload.tools as any[]).push({\n googleSearch: {},\n });\n }\n\n // 3. Normalize tools\n const result = normalizeGeminiTools(payload, {\n moveNumericConstraintsToDescription: model.toLowerCase().startsWith(\"gpt-oss-\"),\n });\n\n // 4. Wrap tools in functionDeclarations format (fixes #203, #206)\n // Antigravity strict protobuf validation rejects wrapper-level 'parameters' field\n // Must be: [{ functionDeclarations: [{ name, description, parameters }] }]\n const wrapResult = wrapToolsAsFunctionDeclarations(payload);\n\n return {\n ...result,\n wrappedFunctionCount: wrapResult.wrappedFunctionCount,\n passthroughToolCount: wrapResult.passthroughToolCount,\n };\n}\n\nexport interface WrapToolsResult {\n wrappedFunctionCount: number;\n passthroughToolCount: number;\n}\n\n/**\n * Wrap tools array in Gemini's required functionDeclarations format.\n * \n * Gemini/Antigravity API expects:\n * { tools: [{ functionDeclarations: [{ name, description, parameters }] }] }\n * \n * NOT:\n * { tools: [{ function: {...}, parameters: {...} }] }\n * \n * The wrapper-level 'parameters' field causes:\n * \"Unknown name 'parameters' at 'request.tools[0]'\"\n */\n/**\n * Detect if a tool is a web search tool in any of the supported formats:\n * - Claude/Anthropic: { type: \"web_search_20250305\" } or { name: \"web_search\" }\n * - Gemini native: { googleSearch: {} } or { googleSearchRetrieval: {} }\n */\nfunction isWebSearchTool(tool: Record<string, unknown>): boolean {\n // 1. Gemini native format\n if (tool.googleSearch || tool.googleSearchRetrieval) {\n return true;\n }\n\n // 2. Claude/Anthropic format: { type: \"web_search_20250305\" }\n if (tool.type === \"web_search_20250305\") {\n return true;\n }\n\n // 3. Simple name-based format: { name: \"web_search\" | \"google_search\" }\n const name = tool.name as string | undefined;\n if (name === \"web_search\" || name === \"google_search\") {\n return true;\n }\n\n return false;\n}\n\nexport function wrapToolsAsFunctionDeclarations(payload: RequestPayload): WrapToolsResult {\n if (!Array.isArray(payload.tools) || payload.tools.length === 0) {\n return { wrappedFunctionCount: 0, passthroughToolCount: 0 };\n }\n\n const functionDeclarations: Array<{\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n }> = [];\n\n const passthroughTools: unknown[] = [];\n let hasWebSearchTool = false;\n\n for (const tool of payload.tools as Array<Record<string, unknown>>) {\n // Handle passthrough tools (Google Search and Code Execution)\n if (tool.googleSearch || tool.googleSearchRetrieval || tool.codeExecution) {\n passthroughTools.push(tool);\n continue;\n }\n\n // Detect and convert web search tools to Gemini format\n if (isWebSearchTool(tool)) {\n hasWebSearchTool = true;\n continue; // Will be added as { googleSearch: {} } at the end\n }\n\n if (tool.functionDeclarations) {\n if (Array.isArray(tool.functionDeclarations)) {\n for (const decl of tool.functionDeclarations as Array<Record<string, unknown>>) {\n functionDeclarations.push({\n name: String(decl.name || `tool-${functionDeclarations.length}`),\n description: String(decl.description || \"\"),\n parameters: (decl.parameters as Record<string, unknown>) || { type: \"OBJECT\", properties: {} },\n });\n }\n }\n continue;\n }\n\n const fn = tool.function as Record<string, unknown> | undefined;\n const custom = tool.custom as Record<string, unknown> | undefined;\n\n const name = String(\n tool.name ||\n fn?.name ||\n custom?.name ||\n `tool-${functionDeclarations.length}`\n );\n\n const description = String(\n tool.description ||\n fn?.description ||\n custom?.description ||\n \"\"\n );\n\n const schema = (\n fn?.input_schema ||\n fn?.parameters ||\n fn?.inputSchema ||\n custom?.input_schema ||\n custom?.parameters ||\n tool.parameters ||\n tool.input_schema ||\n tool.inputSchema ||\n { type: \"OBJECT\", properties: {} }\n ) as Record<string, unknown>;\n\n functionDeclarations.push({\n name,\n description,\n parameters: schema,\n });\n }\n\n const finalTools: unknown[] = [];\n\n if (functionDeclarations.length > 0) {\n finalTools.push({ functionDeclarations });\n }\n\n finalTools.push(...passthroughTools);\n\n // Add googleSearch tool if a web search tool was detected\n // Note: googleSearch cannot be combined with functionDeclarations in the same request\n // If there are function declarations, we skip adding googleSearch (Gemini API limitation)\n if (hasWebSearchTool && functionDeclarations.length === 0) {\n finalTools.push({ googleSearch: {} });\n } else if (hasWebSearchTool && functionDeclarations.length > 0) {\n // Log warning: web search requested but can't be used with functions\n console.warn(\n \"[gemini] web_search tool detected but cannot be combined with function declarations. \" +\n \"Use the explicit google_search() tool call instead.\"\n );\n }\n\n payload.tools = finalTools;\n\n return {\n wrappedFunctionCount: functionDeclarations.length,\n passthroughToolCount: passthroughTools.length + (hasWebSearchTool && functionDeclarations.length === 0 ? 1 : 0),\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", "/**\n * In-process bridge for the packed refresh string.\n *\n * pi's provider framework extracts the bearer token via `oauth.getApiKey` and\n * passes only that access token to `streamSimple` (as `options.apiKey`). The\n * packed refresh (`refreshToken|projectId|managedProjectId`) that login/refresh\n * resolved is therefore not visible to the stream. We cache it here, keyed by\n * the access token, so the stream can recover the managed-project context and\n * avoid a redundant loadCodeAssist round-trip on every turn.\n */\n\nconst packedRefreshByAccessToken = new Map<string, string>()\n// Single-account extension: keep the map tiny.\nconst MAX_ENTRIES = 4\n\nexport function rememberPackedRefresh(accessToken: string, packedRefresh: string): void {\n if (!accessToken) return\n if (packedRefreshByAccessToken.has(accessToken)) {\n packedRefreshByAccessToken.delete(accessToken)\n } else if (packedRefreshByAccessToken.size >= MAX_ENTRIES) {\n const oldest = packedRefreshByAccessToken.keys().next().value\n if (oldest !== undefined) packedRefreshByAccessToken.delete(oldest)\n }\n packedRefreshByAccessToken.set(accessToken, packedRefresh)\n}\n\nexport function getPackedRefresh(accessToken: string): string | undefined {\n return packedRefreshByAccessToken.get(accessToken)\n}\n", "import {\n ANTIGRAVITY_ENDPOINT,\n AgyRequestSessionStore,\n buildAgyAgentRequestMetadata,\n buildAntigravityHarnessUserAgent,\n ensureProjectContext,\n fetchWithAgyCliTransport,\n orderAgyRequestPayloadInPlace,\n resolveModelForHeaderStyle,\n type AgyRequestScope,\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 ThinkingLevel,\n type ToolCall,\n} from \"@earendil-works/pi-ai\"\n\nimport { buildGeminiRequest } from \"./convert.ts\"\nimport { getPackedRefresh } from \"./credential-cache.ts\"\n\nconst STREAM_ACTION = \"streamGenerateContent\"\nconst FALLBACK_SESSION_KEY = \"__default__\"\nconst requestSessions = new AgyRequestSessionStore(\"\")\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 getRequestSessionKey(context: Context, options?: SimpleStreamOptions): string {\n if (options?.sessionId) {\n return options.sessionId\n }\n const firstTimestamp = context.messages[0]?.timestamp\n return firstTimestamp !== undefined ? `message:${firstTimestamp}` : FALLBACK_SESSION_KEY\n}\n\nexport function finalizePiAntigravityRequest(\n request: Record<string, unknown>,\n wireModel: string,\n scope: AgyRequestScope,\n): string {\n if (Array.isArray(request.tools) && request.tools.length > 0) {\n request.toolConfig = { functionCallingConfig: { mode: \"VALIDATED\" } }\n }\n\n const metadata = buildAgyAgentRequestMetadata(\n scope.session,\n request,\n wireModel,\n scope.timestamp,\n )\n request.labels = metadata.labels\n request.sessionId = metadata.sessionId\n orderAgyRequestPayloadInPlace(request)\n return metadata.requestId\n}\n\nexport function resolvePiAntigravityModel(model: Model<Api>, reasoning?: ThinkingLevel) {\n const lower = model.id.toLowerCase()\n const supportsAgyTiers = model.reasoning && (\n lower.includes(\"gemini-3\")\n || (lower.includes(\"claude\") && lower.includes(\"thinking\"))\n )\n\n if (!supportsAgyTiers || !reasoning) {\n return resolveModelForHeaderStyle(model.id, \"antigravity\")\n }\n\n const tier = reasoning === \"minimal\"\n ? \"low\"\n : reasoning === \"xhigh\"\n ? \"high\"\n : reasoning\n const baseModel = model.id.replace(/-(minimal|low|medium|high|xhigh)$/i, \"\")\n return resolveModelForHeaderStyle(`${baseModel}-${tier}`, \"antigravity\")\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 = resolvePiAntigravityModel(options.model, options.streamOptions?.reasoning)\n const wireModel = resolved.actualModel\n\n // Recover the packed refresh (refreshToken|projectId|managedProjectId) that\n // login/refresh resolved; pi only hands the stream the bare access token.\n // With it, ensureProjectContext returns the cached managedProjectId directly\n // instead of re-running loadCodeAssist every turn.\n const packedRefresh = getPackedRefresh(options.accessToken) ?? \"\"\n const projectContext = await ensureProjectContext({\n type: \"oauth\",\n refresh: packedRefresh,\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 requestScope = requestSessions.beginRequest(\n getRequestSessionKey(options.context, options.streamOptions),\n )\n const requestId = finalizePiAntigravityRequest(request, wireModel, requestScope)\n\n const envelope = {\n project: projectContext.effectiveProjectId,\n requestId,\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 { toGeminiSchema } from \"@cortexkit/antigravity-auth-core\"\nimport 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 parameters?: 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 // Match the agy wire format (MITM-verified): field name is `parameters`\n // (not `parametersJsonSchema`) and schemas are sanitized to Gemini shape\n // (UPPERCASE types, unsupported keywords stripped) via core's toGeminiSchema.\n functionDeclarations: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: toGeminiSchema(tool.parameters),\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 { rememberPackedRefresh } from \"./credential-cache.ts\"\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())\n // Pi's AssistantMessage protocol has no image-output content type. Keep\n // generation-only image routes out of the chat model catalog rather than\n // advertising output that the stream contract cannot represent.\n .filter((model) => !model.modalities.output.includes(\"image\"))\n .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) => {\n // Bridge the packed refresh (refreshToken|projectId|managedProjectId)\n // to the stream, which otherwise only receives the bare access token.\n rememberPackedRefresh(credentials.access, credentials.refresh)\n return credentials.access\n },\n },\n streamSimple: streamCortexKitAntigravity,\n })\n}\n"],
5
- "mappings": "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",
6
- "names": ["log", "Buffer", "Buffer", "Buffer", "isClaudeModel", "Buffer", "Buffer", "Buffer", "decode", "encode", "encode", "decode", "encoder", "log", "decoder"]
3
+ "sources": ["../src/index.ts", "../src/credential-cache.ts", "../src/stream.ts", "../src/convert.ts"],
4
+ "sourcesContent": ["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 { rememberPackedRefresh } from './credential-cache.ts'\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())\n // Pi's AssistantMessage protocol has no image-output content type. Keep\n // generation-only image routes out of the chat model catalog rather than\n // advertising output that the stream contract cannot represent.\n .filter((model) => !model.modalities.output.includes('image'))\n .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) => {\n // Bridge the packed refresh (refreshToken|projectId|managedProjectId)\n // to the stream, which otherwise only receives the bare access token.\n rememberPackedRefresh(credentials.access, credentials.refresh)\n return credentials.access\n },\n },\n streamSimple: streamCortexKitAntigravity,\n })\n}\n", "/**\n * In-process bridge for the packed refresh string.\n *\n * pi's provider framework extracts the bearer token via `oauth.getApiKey` and\n * passes only that access token to `streamSimple` (as `options.apiKey`). The\n * packed refresh (`refreshToken|projectId|managedProjectId`) that login/refresh\n * resolved is therefore not visible to the stream. We cache it here, keyed by\n * the access token, so the stream can recover the managed-project context and\n * avoid a redundant loadCodeAssist round-trip on every turn.\n */\n\nconst packedRefreshByAccessToken = new Map<string, string>()\n// Single-account extension: keep the map tiny.\nconst MAX_ENTRIES = 4\n\nexport function rememberPackedRefresh(\n accessToken: string,\n packedRefresh: string,\n): void {\n if (!accessToken) return\n if (packedRefreshByAccessToken.has(accessToken)) {\n packedRefreshByAccessToken.delete(accessToken)\n } else if (packedRefreshByAccessToken.size >= MAX_ENTRIES) {\n const oldest = packedRefreshByAccessToken.keys().next().value\n if (oldest !== undefined) packedRefreshByAccessToken.delete(oldest)\n }\n packedRefreshByAccessToken.set(accessToken, packedRefresh)\n}\n\nexport function getPackedRefresh(accessToken: string): string | undefined {\n return packedRefreshByAccessToken.get(accessToken)\n}\n", "import {\n type AgyRequestScope,\n AgyRequestSessionStore,\n ANTIGRAVITY_ENDPOINT,\n buildAgyAgentRequestMetadata,\n buildAntigravityHarnessUserAgent,\n ensureProjectContext,\n fetchWithAgyCliTransport,\n orderAgyRequestPayloadInPlace,\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 ThinkingContent,\n type ThinkingLevel,\n type ToolCall,\n} from '@earendil-works/pi-ai'\n\nimport { buildGeminiRequest } from './convert.ts'\nimport { getPackedRefresh } from './credential-cache.ts'\n\nconst STREAM_ACTION = 'streamGenerateContent'\nconst FALLBACK_SESSION_KEY = '__default__'\nconst TRAILING_USAGE_TIMEOUT_MS = 1_000\nconst requestSessions = new AgyRequestSessionStore('')\n\nasync function nextWithTimeout<T>(\n iterator: AsyncIterator<T>,\n timeoutMs: number,\n onTimeout: () => void,\n): Promise<IteratorResult<T> | undefined> {\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n iterator.next(),\n new Promise<undefined>((resolve) => {\n timer = setTimeout(() => {\n onTimeout()\n resolve(undefined)\n }, timeoutMs)\n }),\n ])\n } finally {\n if (timer) clearTimeout(timer)\n }\n}\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\nexport interface GeminiResponsePart {\n text?: string\n thought?: boolean\n thoughtSignature?: string\n functionCall?: { name?: string; args?: Record<string, unknown>; id?: string }\n}\n\nexport interface GeminiToolCallState {\n pendingThoughtSignature?: string\n}\n\nexport function convertGeminiToolCallPart(\n part: GeminiResponsePart,\n state: GeminiToolCallState,\n): ToolCall | undefined {\n // Antigravity emits a batch signature on a preceding empty thought part;\n // native replay attaches it to the first function call in that batch.\n if (part.thought && !part.text && part.thoughtSignature) {\n state.pendingThoughtSignature = part.thoughtSignature\n }\n\n if (!part.functionCall) return undefined\n\n const thoughtSignature =\n part.thoughtSignature ?? state.pendingThoughtSignature\n state.pendingThoughtSignature = undefined\n\n return {\n type: 'toolCall',\n id: part.functionCall.id ?? `call_${crypto.randomUUID()}`,\n name: part.functionCall.name ?? '',\n arguments: (part.functionCall.args ?? {}) as Record<string, unknown>,\n ...(thoughtSignature ? { thoughtSignature } : {}),\n }\n}\n\nexport function updateUsage(\n model: Model<Api>,\n output: AssistantMessage,\n usage?: GeminiUsageMetadata,\n): 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 =\n 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 (\n usage.candidatesTokenCount !== undefined ||\n usage.thoughtsTokenCount !== undefined\n ) {\n output.usage.output =\n (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0)\n }\n output.usage.cacheRead = cacheRead\n output.usage.totalTokens =\n output.usage.input +\n output.usage.output +\n output.usage.cacheRead +\n output.usage.cacheWrite\n calculateCost(model, output.usage)\n}\n\nexport async function* parseGeminiSse(\n response: Response,\n): 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 getRequestSessionKey(\n context: Context,\n options?: SimpleStreamOptions,\n): string {\n if (options?.sessionId) {\n return options.sessionId\n }\n const firstTimestamp = context.messages[0]?.timestamp\n return firstTimestamp !== undefined\n ? `message:${firstTimestamp}`\n : FALLBACK_SESSION_KEY\n}\n\nexport function finalizePiAntigravityRequest(\n request: Record<string, unknown>,\n wireModel: string,\n scope: AgyRequestScope,\n): string {\n if (Array.isArray(request.tools) && request.tools.length > 0) {\n request.toolConfig = { functionCallingConfig: { mode: 'VALIDATED' } }\n }\n\n const metadata = buildAgyAgentRequestMetadata(\n scope.session,\n request,\n wireModel,\n scope.timestamp,\n { stepCountMode: 'cli' },\n )\n request.labels = metadata.labels\n request.sessionId = metadata.sessionId\n orderAgyRequestPayloadInPlace(request)\n return metadata.requestId\n}\n\nexport function resolvePiAntigravityModel(\n model: Model<Api>,\n reasoning?: ThinkingLevel,\n) {\n const lower = model.id.toLowerCase()\n const supportsAgyTiers =\n model.reasoning &&\n (lower.includes('gemini-3') ||\n (lower.includes('claude') && lower.includes('thinking')))\n\n if (!supportsAgyTiers || !reasoning) {\n return resolveModelForHeaderStyle(model.id, 'antigravity')\n }\n\n const tier =\n reasoning === 'minimal' ? 'low' : reasoning === 'xhigh' ? 'high' : reasoning\n const baseModel = model.id.replace(/-(minimal|low|medium|high|xhigh)$/i, '')\n return resolveModelForHeaderStyle(`${baseModel}-${tier}`, 'antigravity')\n}\n\nasync function sendAntigravityRequest(options: {\n model: Model<Api>\n context: Context\n streamOptions?: SimpleStreamOptions\n accessToken: string\n sessionKey: string\n signal?: AbortSignal\n}): Promise<Response> {\n const resolved = resolvePiAntigravityModel(\n options.model,\n options.streamOptions?.reasoning,\n )\n const wireModel = resolved.actualModel\n\n // Recover the packed refresh (refreshToken|projectId|managedProjectId) that\n // login/refresh resolved; pi only hands the stream the bare access token.\n // With it, ensureProjectContext returns the cached managedProjectId directly\n // instead of re-running loadCodeAssist every turn.\n const packedRefresh = getPackedRefresh(options.accessToken) ?? ''\n const projectContext = await ensureProjectContext({\n type: 'oauth',\n refresh: packedRefresh,\n access: options.accessToken,\n expires: Date.now() + 60_000,\n })\n\n const request = buildGeminiRequest(options.context, {\n provider: options.model.provider,\n model: options.model.id,\n }) 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 requestScope = requestSessions.beginRequest(options.sessionKey)\n const requestId = finalizePiAntigravityRequest(\n request,\n wireModel,\n requestScope,\n )\n\n const envelope = {\n project: projectContext.effectiveProjectId,\n requestId,\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.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)\n throw new Error('Missing Antigravity OAuth access token')\n\n const sessionKey = getRequestSessionKey(context, options)\n const trailingUsageAbort = new AbortController()\n const requestSignal = options?.signal\n ? AbortSignal.any([options.signal, trailingUsageAbort.signal])\n : trailingUsageAbort.signal\n const response = await sendAntigravityRequest({\n model,\n context,\n streamOptions: options,\n accessToken,\n sessionKey,\n signal: requestSignal,\n })\n\n if (!response.ok) {\n throw new Error(\n `Antigravity request failed: HTTP ${response.status} ${await response.text()}`,\n )\n }\n\n const content = output.content as Array<\n TextContent | ThinkingContent | ToolCall\n >\n const toolCallState: GeminiToolCallState = {}\n let textIndex = -1\n let thinkingIndex = -1\n let terminalSeen = false\n\n const closeText = () => {\n if (textIndex === -1) return\n const block = content[textIndex]\n if (block?.type === 'text') {\n stream.push({\n type: 'text_end',\n contentIndex: textIndex,\n content: block.text,\n partial: output,\n })\n }\n textIndex = -1\n }\n\n const closeThinking = () => {\n if (thinkingIndex === -1) return\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n stream.push({\n type: 'thinking_end',\n contentIndex: thinkingIndex,\n content: block.thinking,\n partial: output,\n })\n }\n thinkingIndex = -1\n }\n\n const chunkIterator = parseGeminiSse(response)[Symbol.asyncIterator]()\n while (true) {\n const next = terminalSeen\n ? await nextWithTimeout(\n chunkIterator,\n TRAILING_USAGE_TIMEOUT_MS,\n () => trailingUsageAbort.abort(),\n )\n : await chunkIterator.next()\n if (!next) break\n if (next.done) break\n\n const chunk = next.value\n updateUsage(model, output, chunk.usageMetadata)\n\n if (terminalSeen) {\n if (chunk.usageMetadata) break\n continue\n }\n\n const candidate = chunk.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n if (\n !part.thought &&\n !part.functionCall &&\n !part.text &&\n part.thoughtSignature\n ) {\n const block = textIndex === -1 ? undefined : content[textIndex]\n if (block?.type === 'text') {\n block.textSignature = part.thoughtSignature\n } else {\n toolCallState.pendingThoughtSignature = part.thoughtSignature\n }\n continue\n }\n\n const toolCall = convertGeminiToolCallPart(part, toolCallState)\n if (toolCall) {\n closeText()\n closeThinking()\n content.push(toolCall)\n const idx = content.length - 1\n stream.push({\n type: 'toolcall_start',\n contentIndex: idx,\n partial: output,\n })\n stream.push({\n type: 'toolcall_end',\n contentIndex: idx,\n toolCall,\n partial: output,\n })\n output.stopReason = 'toolUse'\n continue\n }\n\n if (part.thought) {\n if (typeof part.text !== 'string' || part.text.length === 0)\n continue\n closeText()\n if (thinkingIndex === -1) {\n content.push({\n type: 'thinking',\n thinking: '',\n ...(part.thoughtSignature\n ? { thinkingSignature: part.thoughtSignature }\n : {}),\n })\n thinkingIndex = content.length - 1\n stream.push({\n type: 'thinking_start',\n contentIndex: thinkingIndex,\n partial: output,\n })\n }\n const block = content[thinkingIndex]\n if (block?.type === 'thinking') {\n block.thinking += part.text\n if (part.thoughtSignature)\n block.thinkingSignature = part.thoughtSignature\n stream.push({\n type: 'thinking_delta',\n contentIndex: thinkingIndex,\n delta: part.text,\n partial: output,\n })\n }\n continue\n }\n\n if (typeof part.text === 'string' && part.text.length > 0) {\n closeThinking()\n if (textIndex === -1) {\n const textSignature =\n part.thoughtSignature ?? toolCallState.pendingThoughtSignature\n toolCallState.pendingThoughtSignature = undefined\n content.push({\n type: 'text',\n text: '',\n ...(textSignature ? { textSignature } : {}),\n })\n textIndex = content.length - 1\n stream.push({\n type: 'text_start',\n contentIndex: textIndex,\n partial: output,\n })\n }\n const block = content[textIndex]\n if (block?.type === 'text') {\n block.text += part.text\n if (part.thoughtSignature)\n block.textSignature = part.thoughtSignature\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 closeText()\n closeThinking()\n if (output.stopReason !== 'toolUse') {\n output.stopReason = mapFinishReason(candidate.finishReason)\n }\n terminalSeen = true\n const needsTrailingUsage =\n model.id.toLowerCase().includes('gpt-oss') && !chunk.usageMetadata\n if (!needsTrailingUsage) break\n }\n }\n\n if (terminalSeen) {\n try {\n await chunkIterator.return?.(undefined)\n } catch (error) {\n if (!trailingUsageAbort.signal.aborted) throw error\n }\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 if (output.stopReason === 'stop' || output.stopReason === 'length') {\n requestSessions.completeExecution(sessionKey)\n }\n stream.end()\n } catch (error) {\n output.stopReason = options?.signal?.aborted ? 'aborted' : 'error'\n output.errorMessage =\n 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 { toGeminiSchema } from '@cortexkit/antigravity-auth-core'\nimport type {\n AssistantMessage,\n Context,\n ImageContent,\n Message,\n TextContent,\n Tool,\n ToolResultMessage,\n} from '@earendil-works/pi-ai'\n\n/** Gemini `contents` part shapes. */\ntype GeminiPart =\n | { text: string; thought?: boolean; thoughtSignature?: string }\n | { inlineData: { mimeType: string; data: string } }\n | {\n functionCall: { name: string; args: Record<string, unknown>; id: string }\n thoughtSignature?: string\n }\n | {\n functionResponse: {\n name: string\n response: Record<string, unknown>\n id: string\n }\n }\n\ninterface GeminiContent {\n role: 'user' | 'model'\n parts: GeminiPart[]\n}\n\ninterface GeminiTool {\n functionDeclarations: Array<{\n name: string\n description: string\n parameters?: 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(\n content: Array<TextContent | ImageContent>,\n): 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(\n message: AssistantMessage,\n preserveSignedHistory: boolean,\n): GeminiPart[] {\n const parts: GeminiPart[] = []\n for (const block of message.content) {\n if (block.type === 'thinking') {\n if (preserveSignedHistory && block.thinking) {\n parts.push({\n text: sanitize(block.thinking),\n thought: true,\n ...(block.thinkingSignature\n ? { thoughtSignature: block.thinkingSignature }\n : {}),\n })\n }\n } else if (block.type === 'text' && block.text.trim()) {\n parts.push({\n text: sanitize(block.text),\n ...(preserveSignedHistory && block.textSignature\n ? { thoughtSignature: block.textSignature }\n : {}),\n })\n } else if (block.type === 'toolCall') {\n parts.push({\n functionCall: {\n name: block.name,\n args: (block.arguments ?? {}) as Record<string, unknown>,\n id: block.id,\n },\n ...(preserveSignedHistory && block.thoughtSignature\n ? { thoughtSignature: block.thoughtSignature }\n : {}),\n })\n }\n }\n return parts\n}\n\nfunction toolResultResponse(\n message: ToolResultMessage,\n): 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\nexport interface BuildGeminiRequestOptions {\n provider?: string\n model?: string\n}\n\nfunction isSameTargetModel(\n message: AssistantMessage,\n options: BuildGeminiRequestOptions | undefined,\n): boolean {\n if (!options?.provider || !options.model) return true\n return (\n message.provider === options.provider && message.model === options.model\n )\n}\n\nfunction convertMessages(\n messages: Message[],\n options?: BuildGeminiRequestOptions,\n): GeminiContent[] {\n const contents: GeminiContent[] = []\n const callMatchesTarget = new Map<string, boolean>()\n\n for (const message of messages) {\n if (message?.role !== 'assistant') continue\n const matchesTarget = isSameTargetModel(message, options)\n for (const block of message.content) {\n if (block.type === 'toolCall') {\n callMatchesTarget.set(block.id, matchesTarget)\n }\n }\n }\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(\n message.content as Array<TextContent | ImageContent>,\n )\n if (parts.length) contents.push({ role: 'user', parts })\n continue\n }\n\n if (message.role === 'assistant') {\n const parts = convertAssistantParts(\n message,\n isSameTargetModel(message, options),\n )\n if (parts.length) contents.push({ role: 'model', parts })\n continue\n }\n\n if (message.role === 'toolResult') {\n const role =\n callMatchesTarget.get(message.toolCallId) === true ? 'model' : 'user'\n const part: GeminiPart = {\n functionResponse: {\n name: message.toolName,\n response: toolResultResponse(message),\n id: message.toolCallId,\n },\n }\n // Gemini groups consecutive function responses into one user turn.\n const last = contents[contents.length - 1]\n if (\n last &&\n last.role === role &&\n last.parts.every((p) => 'functionResponse' in p)\n ) {\n last.parts.push(part)\n } else {\n contents.push({ role, 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 // Match the agy wire format (MITM-verified): field name is `parameters`\n // (not `parametersJsonSchema`) and schemas are sanitized to Gemini shape\n // (UPPERCASE types, unsupported keywords stripped) via core's toGeminiSchema.\n functionDeclarations: tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n parameters: toGeminiSchema(tool.parameters),\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(\n context: Context,\n options?: BuildGeminiRequestOptions,\n): GeminiRequest {\n const request: GeminiRequest = {\n contents: convertMessages(context.messages, options),\n }\n\n const tools = convertTools(context.tools)\n if (tools) request.tools = tools\n\n if (context.systemPrompt?.trim()) {\n request.systemInstruction = {\n parts: [{ text: sanitize(context.systemPrompt) }],\n }\n }\n\n return request\n}\n"],
5
+ "mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACMP,IAAM,6BAA6B,oBAAI,IAAoB;AAE3D,IAAM,cAAc;AAEb,SAAS,sBACd,aACA,eACM;AACN,MAAI,CAAC,YAAa;AAClB,MAAI,2BAA2B,IAAI,WAAW,GAAG;AAC/C,+BAA2B,OAAO,WAAW;AAAA,EAC/C,WAAW,2BAA2B,QAAQ,aAAa;AACzD,UAAM,SAAS,2BAA2B,KAAK,EAAE,KAAK,EAAE;AACxD,QAAI,WAAW,OAAW,4BAA2B,OAAO,MAAM;AAAA,EACpE;AACA,6BAA2B,IAAI,aAAa,aAAa;AAC3D;AAEO,SAAS,iBAAiB,aAAyC;AACxE,SAAO,2BAA2B,IAAI,WAAW;AACnD;;;AC/BA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EAKE;AAAA,EACA;AAAA,OAQK;;;ACzBP,SAAS,sBAAsB;AA8C/B,SAAS,SAAS,MAAsB;AACtC,SAAO,KAAK,QAAQ,qBAAqB,QAAQ;AACnD;AAEA,SAAS,iBACP,SACc;AACd,QAAM,QAAsB,CAAC;AAC7B,aAAW,QAAQ,SAAS;AAC1B,QAAI,KAAK,SAAS,QAAQ;AACxB,UAAI,KAAK,KAAM,OAAM,KAAK,EAAE,MAAM,SAAS,KAAK,IAAI,EAAE,CAAC;AAAA,IACzD,WAAW,KAAK,SAAS,WAAW,KAAK,MAAM;AAC7C,YAAM,KAAK,EAAE,YAAY,EAAE,UAAU,KAAK,UAAU,MAAM,KAAK,KAAK,EAAE,CAAC;AAAA,IACzE;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,sBACP,SACA,uBACc;AACd,QAAM,QAAsB,CAAC;AAC7B,aAAW,SAAS,QAAQ,SAAS;AACnC,QAAI,MAAM,SAAS,YAAY;AAC7B,UAAI,yBAAyB,MAAM,UAAU;AAC3C,cAAM,KAAK;AAAA,UACT,MAAM,SAAS,MAAM,QAAQ;AAAA,UAC7B,SAAS;AAAA,UACT,GAAI,MAAM,oBACN,EAAE,kBAAkB,MAAM,kBAAkB,IAC5C,CAAC;AAAA,QACP,CAAC;AAAA,MACH;AAAA,IACF,WAAW,MAAM,SAAS,UAAU,MAAM,KAAK,KAAK,GAAG;AACrD,YAAM,KAAK;AAAA,QACT,MAAM,SAAS,MAAM,IAAI;AAAA,QACzB,GAAI,yBAAyB,MAAM,gBAC/B,EAAE,kBAAkB,MAAM,cAAc,IACxC,CAAC;AAAA,MACP,CAAC;AAAA,IACH,WAAW,MAAM,SAAS,YAAY;AACpC,YAAM,KAAK;AAAA,QACT,cAAc;AAAA,UACZ,MAAM,MAAM;AAAA,UACZ,MAAO,MAAM,aAAa,CAAC;AAAA,UAC3B,IAAI,MAAM;AAAA,QACZ;AAAA,QACA,GAAI,yBAAyB,MAAM,mBAC/B,EAAE,kBAAkB,MAAM,iBAAiB,IAC3C,CAAC;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBACP,SACyB;AACzB,QAAM,OAAO,QAAQ,QAClB,OAAO,CAAC,SAA8B,KAAK,SAAS,MAAM,EAC1D,IAAI,CAAC,SAAS,KAAK,IAAI,EACvB,KAAK,IAAI;AACZ,MAAI,QAAQ,SAAS;AACnB,WAAO,EAAE,OAAO,QAAQ,QAAQ;AAAA,EAClC;AACA,SAAO,EAAE,QAAQ,KAAK;AACxB;AAOA,SAAS,kBACP,SACA,SACS;AACT,MAAI,CAAC,SAAS,YAAY,CAAC,QAAQ,MAAO,QAAO;AACjD,SACE,QAAQ,aAAa,QAAQ,YAAY,QAAQ,UAAU,QAAQ;AAEvE;AAEA,SAAS,gBACP,UACA,SACiB;AACjB,QAAM,WAA4B,CAAC;AACnC,QAAM,oBAAoB,oBAAI,IAAqB;AAEnD,aAAW,WAAW,UAAU;AAC9B,QAAI,SAAS,SAAS,YAAa;AACnC,UAAM,gBAAgB,kBAAkB,SAAS,OAAO;AACxD,eAAW,SAAS,QAAQ,SAAS;AACnC,UAAI,MAAM,SAAS,YAAY;AAC7B,0BAAkB,IAAI,MAAM,IAAI,aAAa;AAAA,MAC/C;AAAA,IACF;AAAA,EACF;AAEA,aAAW,WAAW,UAAU;AAC9B,QAAI,CAAC,QAAS;AAEd,QAAI,QAAQ,SAAS,QAAQ;AAC3B,YAAM,QACJ,OAAO,QAAQ,YAAY,WACvB,QAAQ,QAAQ,KAAK,IACnB,CAAC,EAAE,MAAM,SAAS,QAAQ,OAAO,EAAE,CAAC,IACpC,CAAC,IACH;AAAA,QACE,QAAQ;AAAA,MACV;AACN,UAAI,MAAM,OAAQ,UAAS,KAAK,EAAE,MAAM,QAAQ,MAAM,CAAC;AACvD;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,aAAa;AAChC,YAAM,QAAQ;AAAA,QACZ;AAAA,QACA,kBAAkB,SAAS,OAAO;AAAA,MACpC;AACA,UAAI,MAAM,OAAQ,UAAS,KAAK,EAAE,MAAM,SAAS,MAAM,CAAC;AACxD;AAAA,IACF;AAEA,QAAI,QAAQ,SAAS,cAAc;AACjC,YAAM,OACJ,kBAAkB,IAAI,QAAQ,UAAU,MAAM,OAAO,UAAU;AACjE,YAAM,OAAmB;AAAA,QACvB,kBAAkB;AAAA,UAChB,MAAM,QAAQ;AAAA,UACd,UAAU,mBAAmB,OAAO;AAAA,UACpC,IAAI,QAAQ;AAAA,QACd;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,SAAS,SAAS,CAAC;AACzC,UACE,QACA,KAAK,SAAS,QACd,KAAK,MAAM,MAAM,CAAC,MAAM,sBAAsB,CAAC,GAC/C;AACA,aAAK,MAAM,KAAK,IAAI;AAAA,MACtB,OAAO;AACL,iBAAS,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,OAAqD;AACzE,MAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,SAAO;AAAA,IACL;AAAA;AAAA;AAAA;AAAA,MAIE,sBAAsB,MAAM,IAAI,CAAC,UAAU;AAAA,QACzC,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,YAAY,eAAe,KAAK,UAAU;AAAA,MAC5C,EAAE;AAAA,IACJ;AAAA,EACF;AACF;AAMO,SAAS,mBACd,SACA,SACe;AACf,QAAM,UAAyB;AAAA,IAC7B,UAAU,gBAAgB,QAAQ,UAAU,OAAO;AAAA,EACrD;AAEA,QAAM,QAAQ,aAAa,QAAQ,KAAK;AACxC,MAAI,MAAO,SAAQ,QAAQ;AAE3B,MAAI,QAAQ,cAAc,KAAK,GAAG;AAChC,YAAQ,oBAAoB;AAAA,MAC1B,OAAO,CAAC,EAAE,MAAM,SAAS,QAAQ,YAAY,EAAE,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,SAAO;AACT;;;ADhNA,IAAM,gBAAgB;AACtB,IAAM,uBAAuB;AAC7B,IAAM,4BAA4B;AAClC,IAAM,kBAAkB,IAAI,uBAAuB,EAAE;AAErD,eAAe,gBACb,UACA,WACA,WACwC;AACxC,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK;AAAA,MACxB,SAAS,KAAK;AAAA,MACd,IAAI,QAAmB,CAAC,YAAY;AAClC,gBAAQ,WAAW,MAAM;AACvB,oBAAU;AACV,kBAAQ,MAAS;AAAA,QACnB,GAAG,SAAS;AAAA,MACd,CAAC;AAAA,IACH,CAAC;AAAA,EACH,UAAE;AACA,QAAI,MAAO,cAAa,KAAK;AAAA,EAC/B;AACF;AAEA,SAAS,gBAAgB,QAA+C;AACtE,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO,SAAS,SAAS;AAAA,EAC7B;AACF;AAEA,SAAS,aAAa,OAAqC;AACzD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC;AAAA,IACV,KAAK,MAAM;AAAA,IACX,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,IACb,OAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,EAAE;AAAA,IACrE;AAAA,IACA,YAAY;AAAA,IACZ,WAAW,KAAK,IAAI;AAAA,EACtB;AACF;AAwBA,SAAS,YAAY,KAAiC;AACpD,MAAI,OAAO,OAAO,QAAQ,YAAY,cAAc,KAAK;AACvD,UAAM,QAAS,IAA+B;AAC9C,QAAI,SAAS,OAAO,UAAU,UAAU;AACtC,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAaO,SAAS,0BACd,MACA,OACsB;AAGtB,MAAI,KAAK,WAAW,CAAC,KAAK,QAAQ,KAAK,kBAAkB;AACvD,UAAM,0BAA0B,KAAK;AAAA,EACvC;AAEA,MAAI,CAAC,KAAK,aAAc,QAAO;AAE/B,QAAM,mBACJ,KAAK,oBAAoB,MAAM;AACjC,QAAM,0BAA0B;AAEhC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI,KAAK,aAAa,MAAM,QAAQ,OAAO,WAAW,CAAC;AAAA,IACvD,MAAM,KAAK,aAAa,QAAQ;AAAA,IAChC,WAAY,KAAK,aAAa,QAAQ,CAAC;AAAA,IACvC,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;AAAA,EACjD;AACF;AAEO,SAAS,YACd,OACA,QACA,OACM;AACN,MAAI,CAAC,MAAO;AACZ,QAAM,YAAY,MAAM,2BAA2B,OAAO,MAAM;AAEhE,QAAM,cACJ,MAAM,oBAAoB,OAAO,MAAM,QAAQ,OAAO,MAAM;AAC9D,SAAO,MAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,SAAS;AAGxD,MACE,MAAM,yBAAyB,UAC/B,MAAM,uBAAuB,QAC7B;AACA,WAAO,MAAM,UACV,MAAM,wBAAwB,MAAM,MAAM,sBAAsB;AAAA,EACrE;AACA,SAAO,MAAM,YAAY;AACzB,SAAO,MAAM,cACX,OAAO,MAAM,QACb,OAAO,MAAM,SACb,OAAO,MAAM,YACb,OAAO,MAAM;AACf,gBAAc,OAAO,OAAO,KAAK;AACnC;AAEA,gBAAuB,eACrB,UACmC;AACnC,MAAI,CAAC,SAAS,KAAM;AACpB,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,QAAM,aAAa,WAAW,OAA6C;AACzE,eAAW,QAAQ,MAAM,MAAM,IAAI,GAAG;AACpC,UAAI,CAAC,KAAK,WAAW,OAAO,EAAG;AAC/B,YAAM,OAAO,KAAK,MAAM,CAAC,EAAE,KAAK;AAChC,UAAI,CAAC,QAAQ,SAAS,SAAU;AAChC,UAAI;AACF,cAAM,YAAY,KAAK,MAAM,IAAI,CAAC;AAAA,MACpC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,WAAO,MAAM;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAGV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,EAAE,QAAQ,SAAS,IAAI;AACvE,UAAI,WAAW,OAAO,QAAQ,MAAM;AACpC,aAAO,aAAa,IAAI;AACtB,cAAM,QAAQ,OAAO,MAAM,GAAG,QAAQ;AACtC,iBAAS,OAAO,MAAM,WAAW,CAAC;AAClC,mBAAW,OAAO,QAAQ,MAAM;AAChC,eAAO,WAAW,KAAK;AAAA,MACzB;AAAA,IACF;AAEA,QAAI,OAAO,KAAK,GAAG;AACjB,aAAO,WAAW,MAAM;AAAA,IAC1B;AAAA,EACF,UAAE;AACA,WAAO,YAAY;AAAA,EACrB;AACF;AAEA,SAAS,qBACP,SACA,SACQ;AACR,MAAI,SAAS,WAAW;AACtB,WAAO,QAAQ;AAAA,EACjB;AACA,QAAM,iBAAiB,QAAQ,SAAS,CAAC,GAAG;AAC5C,SAAO,mBAAmB,SACtB,WAAW,cAAc,KACzB;AACN;AAEO,SAAS,6BACd,SACA,WACA,OACQ;AACR,MAAI,MAAM,QAAQ,QAAQ,KAAK,KAAK,QAAQ,MAAM,SAAS,GAAG;AAC5D,YAAQ,aAAa,EAAE,uBAAuB,EAAE,MAAM,YAAY,EAAE;AAAA,EACtE;AAEA,QAAM,WAAW;AAAA,IACf,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,EAAE,eAAe,MAAM;AAAA,EACzB;AACA,UAAQ,SAAS,SAAS;AAC1B,UAAQ,YAAY,SAAS;AAC7B,gCAA8B,OAAO;AACrC,SAAO,SAAS;AAClB;AAEO,SAAS,0BACd,OACA,WACA;AACA,QAAM,QAAQ,MAAM,GAAG,YAAY;AACnC,QAAM,mBACJ,MAAM,cACL,MAAM,SAAS,UAAU,KACvB,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,UAAU;AAE1D,MAAI,CAAC,oBAAoB,CAAC,WAAW;AACnC,WAAO,2BAA2B,MAAM,IAAI,aAAa;AAAA,EAC3D;AAEA,QAAM,OACJ,cAAc,YAAY,QAAQ,cAAc,UAAU,SAAS;AACrE,QAAM,YAAY,MAAM,GAAG,QAAQ,sCAAsC,EAAE;AAC3E,SAAO,2BAA2B,GAAG,SAAS,IAAI,IAAI,IAAI,aAAa;AACzE;AAEA,eAAe,uBAAuB,SAOhB;AACpB,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR,QAAQ,eAAe;AAAA,EACzB;AACA,QAAM,YAAY,SAAS;AAM3B,QAAM,gBAAgB,iBAAiB,QAAQ,WAAW,KAAK;AAC/D,QAAM,iBAAiB,MAAM,qBAAqB;AAAA,IAChD,MAAM;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,QAAQ;AAAA,IAChB,SAAS,KAAK,IAAI,IAAI;AAAA,EACxB,CAAC;AAED,QAAM,UAAU,mBAAmB,QAAQ,SAAS;AAAA,IAClD,UAAU,QAAQ,MAAM;AAAA,IACxB,OAAO,QAAQ,MAAM;AAAA,EACvB,CAAC;AACD,QAAM,mBAA4C,CAAC;AAEnD,MAAI,SAAS,eAAe;AAC1B,qBAAiB,iBAAiB;AAAA,MAChC,iBAAiB;AAAA,MACjB,eAAe,SAAS;AAAA,IAC1B;AAAA,EACF,WAAW,OAAO,SAAS,mBAAmB,UAAU;AACtD,qBAAiB,iBAAiB;AAAA,MAChC,iBAAiB;AAAA,MACjB,gBAAgB,SAAS;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,eAAe,aAAa,QAAQ,MAAM;AACpE,MAAI,OAAO,cAAc,UAAU;AACjC,qBAAiB,kBAAkB;AAAA,EACrC;AAEA,MAAI,OAAO,KAAK,gBAAgB,EAAE,SAAS,GAAG;AAC5C,YAAQ,mBAAmB;AAAA,EAC7B;AAEA,QAAM,eAAe,gBAAgB,aAAa,QAAQ,UAAU;AACpE,QAAM,YAAY;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,WAAW;AAAA,IACf,SAAS,eAAe;AAAA,IACxB;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,WAAW;AAAA,IACX,aAAa;AAAA,EACf;AAEA,QAAM,MAAM,GAAG,oBAAoB,eAAe,aAAa;AAE/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,QAAQ,WAAW;AAAA,QAC5C,gBAAgB;AAAA,QAChB,cAAc,iCAAiC;AAAA,QAC/C,mBAAmB;AAAA,MACrB;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ;AAAA,IAC/B;AAAA,IACA,EAAE,QAAQ,QAAQ,UAAU,QAAQ,eAAe,UAAU,KAAK;AAAA,EACpE;AACF;AAEO,SAAS,2BACd,OACA,SACA,SAC6B;AAC7B,QAAM,SAAS,kCAAkC;AAEjD,QAAM,YAAY;AAChB,UAAM,SAAS,aAAa,KAAK;AACjC,WAAO,KAAK,EAAE,MAAM,SAAS,SAAS,OAAO,CAAC;AAE9C,QAAI;AACF,YAAM,cAAc,SAAS,UAAU;AACvC,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,wCAAwC;AAE1D,YAAM,aAAa,qBAAqB,SAAS,OAAO;AACxD,YAAM,qBAAqB,IAAI,gBAAgB;AAC/C,YAAM,gBAAgB,SAAS,SAC3B,YAAY,IAAI,CAAC,QAAQ,QAAQ,mBAAmB,MAAM,CAAC,IAC3D,mBAAmB;AACvB,YAAM,WAAW,MAAM,uBAAuB;AAAA,QAC5C;AAAA,QACA;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,MACV,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI;AAAA,UACR,oCAAoC,SAAS,MAAM,IAAI,MAAM,SAAS,KAAK,CAAC;AAAA,QAC9E;AAAA,MACF;AAEA,YAAM,UAAU,OAAO;AAGvB,YAAM,gBAAqC,CAAC;AAC5C,UAAI,YAAY;AAChB,UAAI,gBAAgB;AACpB,UAAI,eAAe;AAEnB,YAAM,YAAY,MAAM;AACtB,YAAI,cAAc,GAAI;AACtB,cAAM,QAAQ,QAAQ,SAAS;AAC/B,YAAI,OAAO,SAAS,QAAQ;AAC1B,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,cAAc;AAAA,YACd,SAAS,MAAM;AAAA,YACf,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AACA,oBAAY;AAAA,MACd;AAEA,YAAM,gBAAgB,MAAM;AAC1B,YAAI,kBAAkB,GAAI;AAC1B,cAAM,QAAQ,QAAQ,aAAa;AACnC,YAAI,OAAO,SAAS,YAAY;AAC9B,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,cAAc;AAAA,YACd,SAAS,MAAM;AAAA,YACf,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AACA,wBAAgB;AAAA,MAClB;AAEA,YAAM,gBAAgB,eAAe,QAAQ,EAAE,OAAO,aAAa,EAAE;AACrE,aAAO,MAAM;AACX,cAAM,OAAO,eACT,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA,MAAM,mBAAmB,MAAM;AAAA,QACjC,IACA,MAAM,cAAc,KAAK;AAC7B,YAAI,CAAC,KAAM;AACX,YAAI,KAAK,KAAM;AAEf,cAAM,QAAQ,KAAK;AACnB,oBAAY,OAAO,QAAQ,MAAM,aAAa;AAE9C,YAAI,cAAc;AAChB,cAAI,MAAM,cAAe;AACzB;AAAA,QACF;AAEA,cAAM,YAAY,MAAM,aAAa,CAAC;AACtC,cAAM,QAAQ,WAAW,SAAS,SAAS,CAAC;AAE5C,mBAAW,QAAQ,OAAO;AACxB,cACE,CAAC,KAAK,WACN,CAAC,KAAK,gBACN,CAAC,KAAK,QACN,KAAK,kBACL;AACA,kBAAM,QAAQ,cAAc,KAAK,SAAY,QAAQ,SAAS;AAC9D,gBAAI,OAAO,SAAS,QAAQ;AAC1B,oBAAM,gBAAgB,KAAK;AAAA,YAC7B,OAAO;AACL,4BAAc,0BAA0B,KAAK;AAAA,YAC/C;AACA;AAAA,UACF;AAEA,gBAAM,WAAW,0BAA0B,MAAM,aAAa;AAC9D,cAAI,UAAU;AACZ,sBAAU;AACV,0BAAc;AACd,oBAAQ,KAAK,QAAQ;AACrB,kBAAM,MAAM,QAAQ,SAAS;AAC7B,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,cAAc;AAAA,cACd,SAAS;AAAA,YACX,CAAC;AACD,mBAAO,KAAK;AAAA,cACV,MAAM;AAAA,cACN,cAAc;AAAA,cACd;AAAA,cACA,SAAS;AAAA,YACX,CAAC;AACD,mBAAO,aAAa;AACpB;AAAA,UACF;AAEA,cAAI,KAAK,SAAS;AAChB,gBAAI,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,WAAW;AACxD;AACF,sBAAU;AACV,gBAAI,kBAAkB,IAAI;AACxB,sBAAQ,KAAK;AAAA,gBACX,MAAM;AAAA,gBACN,UAAU;AAAA,gBACV,GAAI,KAAK,mBACL,EAAE,mBAAmB,KAAK,iBAAiB,IAC3C,CAAC;AAAA,cACP,CAAC;AACD,8BAAgB,QAAQ,SAAS;AACjC,qBAAO,KAAK;AAAA,gBACV,MAAM;AAAA,gBACN,cAAc;AAAA,gBACd,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AACA,kBAAM,QAAQ,QAAQ,aAAa;AACnC,gBAAI,OAAO,SAAS,YAAY;AAC9B,oBAAM,YAAY,KAAK;AACvB,kBAAI,KAAK;AACP,sBAAM,oBAAoB,KAAK;AACjC,qBAAO,KAAK;AAAA,gBACV,MAAM;AAAA,gBACN,cAAc;AAAA,gBACd,OAAO,KAAK;AAAA,gBACZ,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AACA;AAAA,UACF;AAEA,cAAI,OAAO,KAAK,SAAS,YAAY,KAAK,KAAK,SAAS,GAAG;AACzD,0BAAc;AACd,gBAAI,cAAc,IAAI;AACpB,oBAAM,gBACJ,KAAK,oBAAoB,cAAc;AACzC,4BAAc,0BAA0B;AACxC,sBAAQ,KAAK;AAAA,gBACX,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,cAC3C,CAAC;AACD,0BAAY,QAAQ,SAAS;AAC7B,qBAAO,KAAK;AAAA,gBACV,MAAM;AAAA,gBACN,cAAc;AAAA,gBACd,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AACA,kBAAM,QAAQ,QAAQ,SAAS;AAC/B,gBAAI,OAAO,SAAS,QAAQ;AAC1B,oBAAM,QAAQ,KAAK;AACnB,kBAAI,KAAK;AACP,sBAAM,gBAAgB,KAAK;AAC7B,qBAAO,KAAK;AAAA,gBACV,MAAM;AAAA,gBACN,cAAc;AAAA,gBACd,OAAO,KAAK;AAAA,gBACZ,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAEA,YAAI,WAAW,cAAc;AAC3B,oBAAU;AACV,wBAAc;AACd,cAAI,OAAO,eAAe,WAAW;AACnC,mBAAO,aAAa,gBAAgB,UAAU,YAAY;AAAA,UAC5D;AACA,yBAAe;AACf,gBAAM,qBACJ,MAAM,GAAG,YAAY,EAAE,SAAS,SAAS,KAAK,CAAC,MAAM;AACvD,cAAI,CAAC,mBAAoB;AAAA,QAC3B;AAAA,MACF;AAEA,UAAI,cAAc;AAChB,YAAI;AACF,gBAAM,cAAc,SAAS,MAAS;AAAA,QACxC,SAAS,OAAO;AACd,cAAI,CAAC,mBAAmB,OAAO,QAAS,OAAM;AAAA,QAChD;AACA,cAAM,SAAS,MAAM,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC9C;AAEA,UAAI,SAAS,QAAQ,QAAS,OAAM,IAAI,MAAM,qBAAqB;AAEnE,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN,QAAQ,OAAO;AAAA,QACf,SAAS;AAAA,MACX,CAAC;AACD,UAAI,OAAO,eAAe,UAAU,OAAO,eAAe,UAAU;AAClE,wBAAgB,kBAAkB,UAAU;AAAA,MAC9C;AACA,aAAO,IAAI;AAAA,IACb,SAAS,OAAO;AACd,aAAO,aAAa,SAAS,QAAQ,UAAU,YAAY;AAC3D,aAAO,eACL,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACvD,aAAO,KAAK,EAAE,MAAM,SAAS,QAAQ,OAAO,YAAY,OAAO,OAAO,CAAC;AACvE,aAAO,IAAI;AAAA,IACb;AAAA,EACF,GAAG;AAEH,SAAO;AACT;;;AFtlBA,IAAM,0BAA0B;AAEhC,SAAS,iBAA0C;AACjD,SAAO,CAAC,QAAQ,OAAO;AACzB;AAEA,eAAe,iBACb,WAC2B;AAC3B,QAAM,OAAO,MAAM,qBAAqB;AACxC,YAAU,OAAO,EAAE,KAAK,KAAK,IAAI,CAAC;AAClC,QAAM,OAAO,MAAM,UAAU,SAAS;AAAA,IACpC,SAAS;AAAA,EACX,CAAC;AAID,QAAM,YAAY,IAAI,IAAI,KAAK,GAAG,EAAE,aAAa,IAAI,OAAO,KAAK;AAGjE,MAAI,UAAU,KAAK,KAAK;AACxB,MAAI,QAAQ;AACZ,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,UAAM,YAAY,IAAI,aAAa,IAAI,MAAM;AAC7C,UAAM,aAAa,IAAI,aAAa,IAAI,OAAO;AAC/C,QAAI,UAAW,WAAU;AACzB,QAAI,WAAY,SAAQ;AAAA,EAC1B,QAAQ;AAAA,EAER;AAEA,QAAM,SAAS,MAAM,oBAAoB,SAAS,KAAK;AACvD,MAAI,OAAO,SAAS,WAAW;AAC7B,UAAM,IAAI,MAAM,sCAAsC,OAAO,KAAK,EAAE;AAAA,EACtE;AAEA,SAAO;AAAA,IACL,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO;AAAA,IACf,SAAS,OAAO;AAAA,EAClB;AACF;AAEA,eAAe,8BACb,aAC2B;AAE3B,QAAM,eAAe,YAAY,QAAQ,MAAM,GAAG,EAAE,CAAC,KAAK,YAAY;AACtE,QAAM,YAAY,MAAM,wBAAwB,YAAY;AAE5D,QAAM,kBAAkB,YAAY,QAAQ,SAAS,GAAG,IACpD,YAAY,QAAQ,MAAM,YAAY,QAAQ,QAAQ,GAAG,CAAC,IAC1D;AACJ,SAAO;AAAA,IACL,SAAS,GAAG,UAAU,OAAO,GAAG,eAAe;AAAA,IAC/C,QAAQ,UAAU;AAAA,IAClB,SAAS,UAAU;AAAA,EACrB;AACF;AAEe,SAAR,2BAA4C,IAAwB;AACzE,QAAM,SAAS,OAAO,OAAO,0BAA0B,CAAC,EAIrD,OAAO,CAAC,UAAU,CAAC,MAAM,WAAW,OAAO,SAAS,OAAO,CAAC,EAC5D,IAAI,CAAC,WAAW;AAAA,IACf,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM;AAAA,IACjB,OAAO,eAAe;AAAA,IACtB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,EAAE;AAAA,IACzD,eAAe,MAAM,MAAM;AAAA,IAC3B,WAAW,MAAM,MAAM;AAAA,EACzB,EAAE;AAEJ,KAAG,iBAAiB,yBAAyB;AAAA,IAC3C,MAAM;AAAA,IACN,SAAS;AAAA,IACT,KAAK;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,MACP,cAAc;AAAA,MACd,WAAW,CAAC,gBAAgB;AAG1B,8BAAsB,YAAY,QAAQ,YAAY,OAAO;AAC7D,eAAO,YAAY;AAAA,MACrB;AAAA,IACF;AAAA,IACA,cAAc;AAAA,EAChB,CAAC;AACH;",
6
+ "names": []
7
7
  }