copilot-api-plus 1.0.50 → 1.0.51
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/README.md +31 -0
- package/dist/error-DNWWcl_s.js +3 -0
- package/dist/{error-CvU5otz-.js → error-SzJ4KHd8.js} +7 -2
- package/dist/error-SzJ4KHd8.js.map +1 -0
- package/dist/get-models-uEbEgq0L.js.map +1 -1
- package/dist/{get-user-BzIEATcF.js → get-user-DEDD9jIs.js} +2 -2
- package/dist/get-user-DEDD9jIs.js.map +1 -0
- package/dist/get-user-HhhC3uQr.js +5 -0
- package/dist/main.js +50 -16
- package/dist/main.js.map +1 -1
- package/dist/{token-B777vbx8.js → token-CpxbiiIw.js} +31 -9
- package/dist/token-CpxbiiIw.js.map +1 -0
- package/dist/token-DkNaoDp7.js +7 -0
- package/package.json +1 -1
- package/dist/error-CsShqJjE.js +0 -3
- package/dist/error-CvU5otz-.js.map +0 -1
- package/dist/get-user-BzIEATcF.js.map +0 -1
- package/dist/get-user-CsQCc3Qx.js +0 -5
- package/dist/token-B777vbx8.js.map +0 -1
- package/dist/token-CCg0yU7a.js +0 -7
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":["fs","path","os","crypto","options","debug","options","config","options","auth","clearAntigravityAuth","options","path","version","options","options","config","newConfig: ProxyConfig","process","commandBlock: string","apiKeyAuthMiddleware: MiddlewareHandler","pendingTokenUsage: TokenUsage | undefined","path","model: string | undefined","start","state","ANTIGRAVITY_USER_AGENT","convertMessages","contents: Array<unknown>","systemInstruction: unknown","parts: Array<unknown>","GEMINI_ALLOWED_FIELDS","convertTypeValue","cleanProperties","cleanedProps: Record<string, unknown>","cleanJsonSchema","cleaned: Record<string, unknown>","convertTools","functionDeclarations: Array<unknown>","body: Record<string, unknown>","createErrorResponse","error: Record<string, unknown>","handleApiError","transformStreamResponse","transformNonStreamResponse","encoder","state","message: Record<string, unknown>","toolCalls: Array<unknown>","app","rateLimitTracker: Record<string, RateLimitInfo>","contents: Array<AntigravityContent>","systemInstruction: { parts: Array<{ text: string }> } | undefined","parts: Array<unknown>","cleanedProps: Record<string, unknown>","cleaned: Record<string, unknown>","functionDeclarations: Array<unknown>","innerRequest: Record<string, unknown>","result: Record<string, unknown>","MAX_RETRIES","parseRetryDelay","state","content: Array<unknown>","body: AnthropicMessageRequest","encoder","groups: Array<MessageGroup>","group: Array<Message>","state","x","headers: Record<string, string>","fetchOptions: RequestInit","lastError: unknown","response: Response | undefined","error: unknown","handleCompletion","isNonStreaming","handleCompletion","newMessages: Array<Message>","contentParts: Array<ContentPart>","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null","state","events: Array<AnthropicStreamEventData>","events","streamState: AnthropicStreamState","events","usage","MAX_RETRIES","DEFAULT_RETRY_DELAY","parseRetryDelay","body: ZenChatCompletionRequest","MAX_RETRIES","DEFAULT_RETRY_DELAY","parseRetryDelay","body: ZenMessageRequest","body: ZenResponsesRequest","options","getApiKey","getAntigravityModels","HTTPError","clearGithubToken","modelList: Array<{ id: string }> | undefined","apiKeys: Array<string> | undefined"],"sources":["../node_modules/dotenv/package.json","../node_modules/dotenv/lib/main.js","../node_modules/dotenv/lib/env-options.js","../node_modules/dotenv/lib/cli-options.js","../node_modules/dotenv/config.js","../src/lib/config.ts","../src/lib/proxy.ts","../src/antigravity.ts","../src/auth.ts","../src/services/github/get-copilot-usage.ts","../src/check-usage.ts","../src/debug.ts","../src/logout.ts","../src/proxy-config.ts","../src/lib/shell.ts","../src/lib/api-key-auth.ts","../src/lib/model-logger.ts","../src/services/antigravity/stream-parser.ts","../src/services/antigravity/create-chat-completions.ts","../src/routes/antigravity/chat-completions/route.ts","../src/lib/request-queue.ts","../src/services/antigravity/anthropic-events.ts","../src/services/antigravity/create-messages.ts","../src/routes/antigravity/messages/route.ts","../src/routes/antigravity/models/route.ts","../src/lib/approval.ts","../src/lib/tokenizer.ts","../src/lib/context-compression.ts","../src/lib/rate-limit.ts","../src/services/copilot/create-chat-completions.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/services/copilot/create-embeddings.ts","../src/routes/embeddings/route.ts","../src/routes/messages/utils.ts","../src/routes/messages/non-stream-translation.ts","../src/routes/messages/count-tokens-handler.ts","../src/routes/messages/stream-translation.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/services/zen/create-chat-completions.ts","../src/routes/zen/chat-completions/route.ts","../src/services/zen/create-messages.ts","../src/routes/zen/messages/route.ts","../src/routes/zen/models/route.ts","../src/services/zen/create-responses.ts","../src/routes/zen/responses/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"dotenv\",\n \"version\": \"17.2.3\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\n// Array of tips to display randomly\nconst TIPS = [\n '🔐 encrypt with Dotenvx: https://dotenvx.com',\n '🔐 prevent committing .env to code: https://dotenvx.com/precommit',\n '🔐 prevent building .env in docker: https://dotenvx.com/prebuild',\n '📡 add observability to secrets: https://dotenvx.com/ops',\n '👥 sync secrets across teammates & machines: https://dotenvx.com/ops',\n '🗂️ backup and recover secrets: https://dotenvx.com/ops',\n '✅ audit secrets and track compliance: https://dotenvx.com/ops',\n '🔄 add secrets lifecycle management: https://dotenvx.com/ops',\n '🔑 add access controls to secrets: https://dotenvx.com/ops',\n '🛠️ run anywhere with `dotenvx run -- yourcommand`',\n '⚙️ specify custom .env file path with { path: \\'/custom/path/.env\\' }',\n '⚙️ enable debug logging with { debug: true }',\n '⚙️ override existing env vars with { override: true }',\n '⚙️ suppress all logs with { quiet: true }',\n '⚙️ write to custom object with { processEnv: myObject }',\n '⚙️ load multiple .env files with { path: [\\'.env.local\\', \\'.env\\'] }'\n]\n\n// Get a random tip from the tips array\nfunction _getRandomTip () {\n return TIPS[Math.floor(Math.random() * TIPS.length)]\n}\n\nfunction parseBoolean (value) {\n if (typeof value === 'string') {\n return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())\n }\n return Boolean(value)\n}\n\nfunction supportsAnsi () {\n return process.stdout.isTTY // && process.env.TERM !== 'dumb'\n}\n\nfunction dim (text) {\n return supportsAnsi() ? `\\x1b[2m${text}\\x1b[0m` : text\n}\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.error(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))\n const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))\n let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n const populated = DotenvModule.populate(processEnv, parsedAll, options)\n\n // handle user settings DOTENV_CONFIG_ options inside .env file(s)\n debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)\n quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(populated).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')} ${dim(`-- tip: ${_getRandomTip()}`)}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n const populated = {}\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n }\n\n return populated\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","// ../config.js accepts options via environment variables\nconst options = {}\n\nif (process.env.DOTENV_CONFIG_ENCODING != null) {\n options.encoding = process.env.DOTENV_CONFIG_ENCODING\n}\n\nif (process.env.DOTENV_CONFIG_PATH != null) {\n options.path = process.env.DOTENV_CONFIG_PATH\n}\n\nif (process.env.DOTENV_CONFIG_QUIET != null) {\n options.quiet = process.env.DOTENV_CONFIG_QUIET\n}\n\nif (process.env.DOTENV_CONFIG_DEBUG != null) {\n options.debug = process.env.DOTENV_CONFIG_DEBUG\n}\n\nif (process.env.DOTENV_CONFIG_OVERRIDE != null) {\n options.override = process.env.DOTENV_CONFIG_OVERRIDE\n}\n\nif (process.env.DOTENV_CONFIG_DOTENV_KEY != null) {\n options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY\n}\n\nmodule.exports = options\n","const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/\n\nmodule.exports = function optionMatcher (args) {\n const options = args.reduce(function (acc, cur) {\n const matches = cur.match(re)\n if (matches) {\n acc[matches[1]] = matches[2]\n }\n return acc\n }, {})\n\n if (!('quiet' in options)) {\n options.quiet = 'true'\n }\n\n return options\n}\n","(function () {\n require('./lib/main').config(\n Object.assign(\n {},\n require('./lib/env-options'),\n require('./lib/cli-options')(process.argv)\n )\n )\n})()\n","/**\n * Configuration file management\n * Handles persistent configuration storage for proxy settings and other options\n */\n\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport { PATHS } from \"./paths\"\n\nconst CONFIG_FILENAME = \"config.json\"\n\nexport interface ProxyConfig {\n enabled: boolean\n httpProxy?: string\n httpsProxy?: string\n noProxy?: string\n}\n\nexport interface AppConfig {\n proxy?: ProxyConfig\n}\n\n/**\n * Get the path to the config file\n */\nexport function getConfigPath(): string {\n return path.join(PATHS.DATA_DIR, CONFIG_FILENAME)\n}\n\n/**\n * Load configuration from file\n */\nexport async function loadConfig(): Promise<AppConfig> {\n try {\n const configPath = getConfigPath()\n const content = await fs.readFile(configPath)\n // Buffer can be passed to JSON.parse directly (better performance)\n return JSON.parse(content as unknown as string) as AppConfig\n } catch {\n return {}\n }\n}\n\n/**\n * Save configuration to file\n */\nexport async function saveConfig(config: AppConfig): Promise<void> {\n const configPath = getConfigPath()\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), \"utf8\")\n consola.debug(`Configuration saved to ${configPath}`)\n}\n\n/**\n * Get proxy configuration\n */\nexport async function getProxyConfig(): Promise<ProxyConfig | undefined> {\n const config = await loadConfig()\n return config.proxy\n}\n\n/**\n * Save proxy configuration\n */\nexport async function saveProxyConfig(proxyConfig: ProxyConfig): Promise<void> {\n const config = await loadConfig()\n config.proxy = proxyConfig\n await saveConfig(config)\n}\n\n/**\n * Clear proxy configuration\n */\nexport async function clearProxyConfig(): Promise<void> {\n const config = await loadConfig()\n delete config.proxy\n await saveConfig(config)\n}\n\n/**\n * Apply saved proxy configuration to environment variables\n * This should be called at startup to restore proxy settings\n */\nexport async function applyProxyConfig(): Promise<boolean> {\n const proxyConfig = await getProxyConfig()\n\n if (!proxyConfig || !proxyConfig.enabled) {\n return false\n }\n\n if (proxyConfig.httpProxy) {\n process.env.HTTP_PROXY = proxyConfig.httpProxy\n process.env.http_proxy = proxyConfig.httpProxy\n }\n\n if (proxyConfig.httpsProxy) {\n process.env.HTTPS_PROXY = proxyConfig.httpsProxy\n process.env.https_proxy = proxyConfig.httpsProxy\n }\n\n if (proxyConfig.noProxy) {\n process.env.NO_PROXY = proxyConfig.noProxy\n process.env.no_proxy = proxyConfig.noProxy\n }\n\n consola.info(\"Proxy configuration loaded from saved settings\")\n if (proxyConfig.httpProxy) {\n consola.info(` HTTP_PROXY: ${proxyConfig.httpProxy}`)\n }\n if (proxyConfig.httpsProxy) {\n consola.info(` HTTPS_PROXY: ${proxyConfig.httpsProxy}`)\n }\n if (proxyConfig.noProxy) {\n consola.info(` NO_PROXY: ${proxyConfig.noProxy}`)\n }\n\n return true\n}\n","import consola from \"consola\"\nimport { getProxyForUrl } from \"proxy-from-env\"\nimport { Agent, ProxyAgent, setGlobalDispatcher, type Dispatcher } from \"undici\"\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== \"undefined\") return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin =\n typeof options.origin === \"string\" ?\n new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n } catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n } catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug(\"HTTP proxy configured from environment (per-URL)\")\n } catch (err) {\n consola.debug(\"Proxy setup skipped:\", err)\n }\n}\n","#!/usr/bin/env node\n\nimport \"dotenv/config\"\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { applyProxyConfig } from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\n\n/**\n * Add a new Antigravity account via OAuth\n */\nasync function addAccount(): Promise<void> {\n const { setupAntigravity, loadAntigravityAuth } = await import(\n \"~/services/antigravity/auth\"\n )\n\n const existingAuth = await loadAntigravityAuth()\n if (existingAuth && existingAuth.accounts.length > 0) {\n const enabledCount = existingAuth.accounts.filter((a) => a.enable).length\n consola.info(\n `Found ${existingAuth.accounts.length} existing accounts (${enabledCount} enabled)`,\n )\n }\n\n await setupAntigravity()\n}\n\n/**\n * List all Antigravity accounts\n */\nasync function listAccounts(): Promise<void> {\n const { loadAntigravityAuth } = await import(\"~/services/antigravity/auth\")\n\n const auth = await loadAntigravityAuth()\n\n if (!auth || auth.accounts.length === 0) {\n consola.info(\"No Antigravity accounts configured\")\n return\n }\n\n consola.info(`\\nAntigravity Accounts (${auth.accounts.length} total):`)\n consola.info(\"=\".repeat(50))\n\n for (let i = 0; i < auth.accounts.length; i++) {\n const account = auth.accounts[i]\n const isCurrent = i === auth.currentIndex\n const status = account.enable ? \"enabled\" : \"disabled\"\n const marker = isCurrent ? \"→ \" : \" \"\n const projectId = account.project_id || \"unknown\"\n\n consola.info(\n `${marker}[${i}] Project: ${projectId} | Status: ${status}${isCurrent ? \" (current)\" : \"\"}`,\n )\n }\n}\n\n/**\n * Remove an Antigravity account by index\n */\nasync function removeAccount(index: number): Promise<void> {\n const { loadAntigravityAuth, saveAntigravityAuth } = await import(\n \"~/services/antigravity/auth\"\n )\n\n const auth = await loadAntigravityAuth()\n\n if (!auth || auth.accounts.length === 0) {\n consola.error(\"No Antigravity accounts configured\")\n return\n }\n\n if (index < 0 || index >= auth.accounts.length) {\n consola.error(\n `Invalid index. Must be between 0 and ${auth.accounts.length - 1}`,\n )\n return\n }\n\n const removed = auth.accounts.splice(index, 1)[0]\n\n // Adjust current index if needed\n if (auth.currentIndex >= auth.accounts.length) {\n auth.currentIndex = Math.max(0, auth.accounts.length - 1)\n }\n\n await saveAntigravityAuth(auth)\n consola.success(\n `Removed account ${index} (Project: ${removed.project_id || \"unknown\"})`,\n )\n}\n\n/**\n * Clear all Antigravity accounts\n */\nasync function clearAccounts(): Promise<void> {\n const { clearAntigravityAuth } = await import(\"~/services/antigravity/auth\")\n\n const confirm = await consola.prompt(\n \"Are you sure you want to remove all Antigravity accounts?\",\n { type: \"confirm\", initial: false },\n )\n\n if (confirm) {\n await clearAntigravityAuth()\n }\n}\n\nexport const antigravity = defineCommand({\n meta: {\n name: \"antigravity\",\n description: \"Manage Google Antigravity accounts\",\n },\n subCommands: {\n add: defineCommand({\n meta: {\n name: \"add\",\n description: \"Add a new Antigravity account via OAuth\",\n },\n async run() {\n await ensurePaths()\n const savedProxyApplied = await applyProxyConfig()\n if (savedProxyApplied) {\n initProxyFromEnv()\n }\n await addAccount()\n },\n }),\n list: defineCommand({\n meta: {\n name: \"list\",\n description: \"List all Antigravity accounts\",\n },\n async run() {\n await ensurePaths()\n await listAccounts()\n },\n }),\n remove: defineCommand({\n meta: {\n name: \"remove\",\n description: \"Remove an Antigravity account by index\",\n },\n args: {\n index: {\n type: \"positional\",\n description: \"Account index to remove (use 'list' to see indexes)\",\n required: true,\n },\n },\n async run({ args }) {\n await ensurePaths()\n const indexStr = String(args.index)\n const index = Number.parseInt(indexStr, 10)\n if (Number.isNaN(index)) {\n consola.error(\"Index must be a number\")\n return\n }\n await removeAccount(index)\n },\n }),\n clear: defineCommand({\n meta: {\n name: \"clear\",\n description: \"Remove all Antigravity accounts\",\n },\n async run() {\n await ensurePaths()\n await clearAccounts()\n },\n }),\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (): Promise<CopilotUsageResponse> => {\n const response = await fetch(`${GITHUB_API_BASE_URL}/copilot_internal/user`, {\n headers: githubHeaders(state),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\n\nimport { getProxyConfig, type ProxyConfig } from \"./lib/config\"\nimport { PATHS } from \"./lib/paths\"\nimport { getAntigravityAuthPath } from \"./services/antigravity/auth\"\nimport { getZenAuthPath } from \"./services/zen/auth\"\n\ninterface DebugInfo {\n version: string\n runtime: {\n name: string\n version: string\n platform: string\n arch: string\n }\n paths: {\n APP_DIR: string\n GITHUB_TOKEN_PATH: string\n ZEN_AUTH_PATH: string\n ANTIGRAVITY_AUTH_PATH: string\n }\n credentials: {\n github: boolean\n zen: boolean\n antigravity: boolean\n }\n proxy?: ProxyConfig\n}\n\ninterface RunDebugOptions {\n json: boolean\n}\n\nasync function getPackageVersion(): Promise<string> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url).pathname\n // @ts-expect-error https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v59.0.1/docs/rules/prefer-json-parse-buffer.md\n // JSON.parse() can actually parse buffers\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath)) as {\n version: string\n }\n return packageJson.version\n } catch {\n return \"unknown\"\n }\n}\n\nfunction getRuntimeInfo() {\n const isBun = typeof Bun !== \"undefined\"\n\n return {\n name: isBun ? \"bun\" : \"node\",\n version: isBun ? Bun.version : process.version.slice(1),\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nasync function checkTokenExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.GITHUB_TOKEN_PATH)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function checkFileExists(path: string): Promise<boolean> {\n try {\n const stats = await fs.stat(path)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(path, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const zenAuthPath = getZenAuthPath()\n const antigravityAuthPath = getAntigravityAuthPath()\n\n const [version, githubExists, zenExists, antigravityExists, proxyConfig] =\n await Promise.all([\n getPackageVersion(),\n checkTokenExists(),\n checkFileExists(zenAuthPath),\n checkFileExists(antigravityAuthPath),\n getProxyConfig(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,\n ZEN_AUTH_PATH: zenAuthPath,\n ANTIGRAVITY_AUTH_PATH: antigravityAuthPath,\n },\n credentials: {\n github: githubExists,\n zen: zenExists,\n antigravity: antigravityExists,\n },\n proxy: proxyConfig,\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n let proxyStatus = \"Not configured\"\n if (info.proxy) {\n proxyStatus =\n info.proxy.enabled ?\n `Enabled (${info.proxy.httpProxy || info.proxy.httpsProxy})`\n : \"Disabled\"\n }\n\n consola.info(`copilot-api-plus debug\n\nVersion: ${info.version}\nRuntime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})\n\nPaths:\n APP_DIR: ${info.paths.APP_DIR}\n GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}\n ZEN_AUTH_PATH: ${info.paths.ZEN_AUTH_PATH}\n ANTIGRAVITY_AUTH_PATH: ${info.paths.ANTIGRAVITY_AUTH_PATH}\n\nCredentials:\n GitHub Copilot: ${info.credentials.github ? \"✅ Configured\" : \"❌ Not configured\"}\n OpenCode Zen: ${info.credentials.zen ? \"✅ Configured\" : \"❌ Not configured\"}\n Google Antigravity: ${info.credentials.antigravity ? \"✅ Configured\" : \"❌ Not configured\"}\n\nProxy: ${proxyStatus}`)\n}\n\nfunction printDebugInfoJson(info: DebugInfo): void {\n console.log(JSON.stringify(info, null, 2))\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n printDebugInfoJson(debugInfo)\n } else {\n printDebugInfoPlain(debugInfo)\n }\n}\n\nexport const debug = defineCommand({\n meta: {\n name: \"debug\",\n description: \"Print debug information about the application\",\n },\n args: {\n json: {\n type: \"boolean\",\n default: false,\n description: \"Output debug information as JSON\",\n },\n },\n run({ args }) {\n return runDebug({\n json: args.json,\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths, PATHS } from \"./lib/paths\"\nimport { clearGithubToken } from \"./lib/token\"\nimport {\n clearAntigravityAuth,\n getAntigravityAuthPath,\n} from \"./services/antigravity/auth\"\nimport { clearZenAuth, getZenAuthPath } from \"./services/zen/auth\"\n\nexport async function runLogout(options: {\n github?: boolean\n zen?: boolean\n antigravity?: boolean\n all?: boolean\n}): Promise<void> {\n await ensurePaths()\n\n if (options.all) {\n // Clear all credentials\n await clearGithubToken()\n await clearZenAuth()\n await clearAntigravityAuth()\n consola.success(\"Logged out from all services\")\n consola.info(`GitHub token: ${PATHS.GITHUB_TOKEN_PATH}`)\n consola.info(`Zen API key: ${getZenAuthPath()}`)\n consola.info(`Antigravity accounts: ${getAntigravityAuthPath()}`)\n return\n }\n\n if (options.github) {\n // Clear only GitHub token\n await clearGithubToken()\n consola.success(\"Logged out from GitHub Copilot\")\n consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`)\n return\n }\n\n if (options.zen) {\n // Clear only Zen API key\n await clearZenAuth()\n consola.success(\"Logged out from OpenCode Zen\")\n consola.info(`Zen API key location: ${getZenAuthPath()}`)\n return\n }\n\n if (options.antigravity) {\n // Clear only Antigravity accounts\n await clearAntigravityAuth()\n consola.success(\"Logged out from Google Antigravity\")\n consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`)\n return\n }\n\n // Default: show interactive prompt\n const choice = await consola.prompt(\n \"Which credentials do you want to clear?\",\n {\n type: \"select\",\n options: [\n \"GitHub Copilot token\",\n \"OpenCode Zen API key\",\n \"Google Antigravity accounts\",\n \"All credentials\",\n ],\n },\n )\n\n switch (choice) {\n case \"GitHub Copilot token\": {\n await clearGithubToken()\n consola.success(\"Logged out from GitHub Copilot\")\n consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`)\n\n break\n }\n case \"OpenCode Zen API key\": {\n await clearZenAuth()\n consola.success(\"Logged out from OpenCode Zen\")\n consola.info(`Zen API key location: ${getZenAuthPath()}`)\n\n break\n }\n case \"Google Antigravity accounts\": {\n await clearAntigravityAuth()\n consola.success(\"Logged out from Google Antigravity\")\n consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`)\n\n break\n }\n case \"All credentials\": {\n await clearGithubToken()\n await clearZenAuth()\n await clearAntigravityAuth()\n consola.success(\"Logged out from all services\")\n\n break\n }\n // No default\n }\n}\n\nexport const logout = defineCommand({\n meta: {\n name: \"logout\",\n description: \"Clear stored credentials and logout\",\n },\n args: {\n github: {\n alias: \"g\",\n type: \"boolean\",\n default: false,\n description: \"Clear only GitHub Copilot token\",\n },\n zen: {\n alias: \"z\",\n type: \"boolean\",\n default: false,\n description: \"Clear only OpenCode Zen API key\",\n },\n antigravity: {\n type: \"boolean\",\n default: false,\n description: \"Clear only Google Antigravity accounts\",\n },\n all: {\n alias: \"a\",\n type: \"boolean\",\n default: false,\n description: \"Clear all credentials (GitHub, Zen, and Antigravity)\",\n },\n },\n run({ args }) {\n return runLogout({\n github: args.github,\n zen: args.zen,\n antigravity: args.antigravity,\n all: args.all,\n })\n },\n})\n","/**\n * Proxy configuration command\n * Allows users to configure, enable, disable, and view proxy settings\n */\n\n/* eslint-disable max-lines-per-function */\n/* eslint-disable complexity */\n\nimport * as p from \"@clack/prompts\"\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n clearProxyConfig,\n getProxyConfig,\n saveProxyConfig,\n type ProxyConfig,\n} from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\n\nexport const proxy = defineCommand({\n meta: {\n name: \"proxy\",\n description: \"Configure proxy settings (persistent)\",\n },\n args: {\n set: {\n type: \"boolean\",\n default: false,\n description: \"Set proxy configuration interactively\",\n },\n enable: {\n type: \"boolean\",\n default: false,\n description: \"Enable saved proxy configuration\",\n },\n disable: {\n type: \"boolean\",\n default: false,\n description: \"Disable proxy (keep settings)\",\n },\n clear: {\n type: \"boolean\",\n default: false,\n description: \"Clear all proxy settings\",\n },\n show: {\n type: \"boolean\",\n default: false,\n description: \"Show current proxy configuration\",\n },\n \"http-proxy\": {\n type: \"string\",\n description: \"HTTP proxy URL (e.g., http://proxy:8080)\",\n },\n \"https-proxy\": {\n type: \"string\",\n description: \"HTTPS proxy URL (e.g., http://proxy:8080)\",\n },\n \"no-proxy\": {\n type: \"string\",\n description: \"Comma-separated list of hosts to bypass proxy\",\n },\n },\n async run({ args }) {\n await ensurePaths()\n\n // Show current configuration\n if (\n args.show\n || (!args.set\n && !args.enable\n && !args.disable\n && !args.clear\n && !args[\"http-proxy\"]\n && !args[\"https-proxy\"])\n ) {\n const config = await getProxyConfig()\n if (!config) {\n consola.info(\"No proxy configuration saved.\")\n consola.info(\"\")\n consola.info(\"To configure proxy, use one of:\")\n consola.info(\n \" copilot-api-plus proxy --set # Interactive setup\",\n )\n consola.info(\n \" copilot-api-plus proxy --http-proxy http://proxy:8080 # Direct set\",\n )\n return\n }\n\n consola.info(\"Current proxy configuration:\")\n consola.info(` Status: ${config.enabled ? \"✅ Enabled\" : \"❌ Disabled\"}`)\n if (config.httpProxy) {\n consola.info(` HTTP_PROXY: ${config.httpProxy}`)\n }\n if (config.httpsProxy) {\n consola.info(` HTTPS_PROXY: ${config.httpsProxy}`)\n }\n if (config.noProxy) {\n consola.info(` NO_PROXY: ${config.noProxy}`)\n }\n return\n }\n\n // Clear proxy settings\n if (args.clear) {\n await clearProxyConfig()\n consola.success(\"Proxy configuration cleared.\")\n return\n }\n\n // Enable proxy\n if (args.enable) {\n const config = await getProxyConfig()\n if (!config) {\n consola.error(\n \"No proxy configuration saved. Use --set to configure first.\",\n )\n return\n }\n config.enabled = true\n await saveProxyConfig(config)\n consola.success(\"Proxy enabled. It will be used on next server start.\")\n return\n }\n\n // Disable proxy\n if (args.disable) {\n const config = await getProxyConfig()\n if (!config) {\n consola.info(\"No proxy configuration to disable.\")\n return\n }\n config.enabled = false\n await saveProxyConfig(config)\n consola.success(\"Proxy disabled. Settings are preserved.\")\n return\n }\n\n // Direct set via command line args\n if (args[\"http-proxy\"] || args[\"https-proxy\"]) {\n const newConfig: ProxyConfig = {\n enabled: true,\n httpProxy: args[\"http-proxy\"],\n httpsProxy: args[\"https-proxy\"] || args[\"http-proxy\"], // Use HTTP proxy for HTTPS if not specified\n noProxy: args[\"no-proxy\"],\n }\n await saveProxyConfig(newConfig)\n consola.success(\"Proxy configuration saved and enabled.\")\n consola.info(` HTTP_PROXY: ${newConfig.httpProxy || \"(not set)\"}`)\n consola.info(` HTTPS_PROXY: ${newConfig.httpsProxy || \"(not set)\"}`)\n if (newConfig.noProxy) {\n consola.info(` NO_PROXY: ${newConfig.noProxy}`)\n }\n return\n }\n\n // Interactive setup\n if (args.set) {\n p.intro(\"Proxy Configuration\")\n\n const existingConfig = await getProxyConfig()\n\n const httpProxy = await p.text({\n message: \"HTTP Proxy URL\",\n placeholder: \"http://proxy:8080\",\n initialValue: existingConfig?.httpProxy || \"\",\n })\n\n if (p.isCancel(httpProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const httpsProxy = await p.text({\n message: \"HTTPS Proxy URL (leave empty to use HTTP proxy)\",\n placeholder: \"http://proxy:8080\",\n initialValue: existingConfig?.httpsProxy || \"\",\n })\n\n if (p.isCancel(httpsProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const noProxy = await p.text({\n message: \"No Proxy (comma-separated hosts to bypass)\",\n placeholder: \"localhost,127.0.0.1,.local\",\n initialValue: existingConfig?.noProxy || \"\",\n })\n\n if (p.isCancel(noProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const enable = await p.confirm({\n message: \"Enable proxy now?\",\n initialValue: true,\n })\n\n if (p.isCancel(enable)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const newConfig: ProxyConfig = {\n enabled: enable,\n httpProxy: httpProxy || undefined,\n httpsProxy: httpsProxy || httpProxy || undefined,\n noProxy: noProxy || undefined,\n }\n\n await saveProxyConfig(newConfig)\n\n p.outro(`Proxy configuration saved${enable ? \" and enabled\" : \"\"}.`)\n }\n },\n})\n","import { execSync } from \"node:child_process\"\nimport process from \"node:process\"\n\ntype ShellName = \"bash\" | \"zsh\" | \"fish\" | \"powershell\" | \"cmd\" | \"sh\"\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === \"win32\") {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: \"pipe\" }).toString()\n\n if (parentProcess.toLowerCase().includes(\"powershell.exe\")) {\n return \"powershell\"\n }\n } catch {\n return \"cmd\"\n }\n\n return \"cmd\"\n } else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith(\"zsh\")) return \"zsh\"\n if (shellPath.endsWith(\"fish\")) return \"fish\"\n if (shellPath.endsWith(\"bash\")) return \"bash\"\n }\n\n return \"sh\"\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = \"\",\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case \"powershell\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join(\"; \")\n break\n }\n case \"cmd\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(\" & \")\n break\n }\n case \"fish\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join(\"; \")\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \")\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : \"\"\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === \"cmd\" ? \" & \" : \" && \"\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from \"hono\"\n\nimport { HTTPException } from \"hono/http-exception\"\n\nimport { state } from \"./state\"\n\n/**\n * Retrieve an API key from the incoming request.\n *\n * Checks common locations where clients supply keys (Authorization Bearer header, `x-api-key` header, or `apiKey` query parameter) and returns the first one found.\n *\n * @returns The extracted API key, or `undefined` if no key is present.\n */\nfunction extractApiKey(c: Context): string | undefined {\n // OpenAI format: Authorization header with Bearer prefix\n const authHeader = c.req.header(\"authorization\")\n if (authHeader?.startsWith(\"Bearer \")) {\n return authHeader.slice(7) // Remove 'Bearer ' prefix\n }\n\n // Anthropic format: x-api-key header\n const anthropicKey = c.req.header(\"x-api-key\")\n if (anthropicKey) {\n return anthropicKey\n }\n\n // Fallback: query parameter, for extra compatibility of `/usage` or `/token` route\n const queryKey = c.req.query(\"apiKey\")\n if (queryKey) {\n return queryKey\n }\n\n return undefined\n}\n\n/**\n * API key authentication middleware\n * Validates that the request contains a valid API key if API keys are configured\n */\nexport const apiKeyAuthMiddleware: MiddlewareHandler = async (c, next) => {\n // If no API keys are configured, skip authentication\n if (!state.apiKeys || state.apiKeys.length === 0) {\n await next()\n return\n }\n\n const providedKey = extractApiKey(c)\n\n // If no API key is provided, return 401\n if (!providedKey) {\n throw new HTTPException(401, {\n message:\n \"API key required. Please provide a valid API key in the Authorization header (Bearer token) or x-api-key header.\",\n })\n }\n\n // Check if the provided key matches any of the configured keys\n const isValidKey = state.apiKeys.includes(providedKey)\n\n if (!isValidKey) {\n throw new HTTPException(401, {\n message: \"Invalid API key. Please provide a valid API key.\",\n })\n }\n\n // Key is valid, continue with the request\n await next()\n}\n","/**\n * Custom logger middleware that displays model name before timestamp\n */\n\nimport type { Context, MiddlewareHandler, Next } from \"hono\"\n\n/**\n * Global token usage store for passing usage info from handlers to logger.\n * Handlers call setTokenUsage() when usage is available,\n * logger reads and clears it after await next().\n */\nlet pendingTokenUsage: TokenUsage | undefined\n\nexport interface TokenUsage {\n inputTokens: number\n outputTokens: number\n cacheReadTokens?: number\n cacheCreationTokens?: number\n}\n\nexport function setTokenUsage(usage: TokenUsage): void {\n pendingTokenUsage = usage\n}\n\n/**\n * Get timestamp string in format HH:mm:ss\n */\nfunction getTime(): string {\n return new Date().toLocaleTimeString(\"en-US\", { hour12: false })\n}\n\n/**\n * Format duration in human readable format\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\n/**\n * Format token usage for log output\n */\nexport function formatTokenUsage(usage: TokenUsage): string {\n const parts = [`in:${usage.inputTokens}`, `out:${usage.outputTokens}`]\n if (usage.cacheReadTokens) {\n parts.push(`cache_read:${usage.cacheReadTokens}`)\n }\n if (usage.cacheCreationTokens) {\n parts.push(`cache_create:${usage.cacheCreationTokens}`)\n }\n return parts.join(\" \")\n}\n\n/**\n * Extract model name from request body\n */\nasync function extractModel(c: Context): Promise<string | undefined> {\n try {\n // Clone the request to avoid consuming the body\n const clonedReq = c.req.raw.clone()\n const body = (await clonedReq.json()) as { model?: string }\n return body.model\n } catch {\n return undefined\n }\n}\n\n/**\n * Custom logger middleware that shows model name before timestamp\n *\n * Output format:\n * [model] HH:mm:ss <-- METHOD /path\n * [model] HH:mm:ss --> METHOD /path STATUS DURATION [in:N out:N]\n */\nexport function modelLogger(): MiddlewareHandler {\n return async (c: Context, next: Next) => {\n const method = c.req.method\n const path = c.req.path\n const queryString =\n c.req.raw.url.includes(\"?\") ? `?${c.req.raw.url.split(\"?\")[1]}` : \"\"\n const fullPath = `${path}${queryString}`\n\n // Extract model for POST requests with JSON body\n let model: string | undefined\n if (method === \"POST\" && c.req.header(\"content-type\")?.includes(\"json\")) {\n model = await extractModel(c)\n }\n\n const modelPrefix = model ? `[${model}] ` : \"\"\n const startTime = getTime()\n\n // Clear any stale usage before handling\n pendingTokenUsage = undefined\n\n // Log incoming request\n console.log(`${modelPrefix}${startTime} <-- ${method} ${fullPath}`)\n\n const start = Date.now()\n await next()\n const duration = Date.now() - start\n const endTime = getTime()\n\n // Read and clear token usage (set by handlers during await next())\n const usage = pendingTokenUsage\n pendingTokenUsage = undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const usageSuffix = usage ? ` [${formatTokenUsage(usage)}]` : \"\"\n\n // Log outgoing response\n console.log(\n `${modelPrefix}${endTime} --> ${method} ${fullPath} ${c.res.status} ${formatDuration(duration)}${usageSuffix}`,\n )\n }\n}\n","/**\n * Antigravity Stream Parser\n *\n * Parses SSE stream responses from Antigravity API and emits events.\n * Extracted for better code organization and reduced complexity.\n */\n\n/** Parsed part from Antigravity response */\nexport interface AntigravityPart {\n text?: string\n thought?: boolean\n functionCall?: {\n name: string\n args: unknown\n }\n}\n\n/** Parsed candidate from Antigravity response */\nexport interface AntigravityCandidate {\n content?: {\n parts?: Array<AntigravityPart>\n }\n finishReason?: string\n}\n\n/** Usage metadata from Antigravity response */\nexport interface AntigravityUsage {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n}\n\n/** Parsed Antigravity SSE data */\nexport interface AntigravityData {\n response?: {\n candidates?: Array<AntigravityCandidate>\n usageMetadata?: AntigravityUsage\n }\n candidates?: Array<AntigravityCandidate>\n usageMetadata?: AntigravityUsage\n}\n\n/** Stream state for tracking parsing progress */\nexport interface StreamState {\n buffer: string\n inputTokens: number\n outputTokens: number\n contentBlockIndex: number\n thinkingBlockStarted: boolean\n textBlockStarted: boolean\n}\n\n/** Events emitted during stream parsing */\nexport type StreamEvent =\n | { type: \"thinking_start\"; index: number }\n | { type: \"thinking_delta\"; index: number; text: string }\n | { type: \"thinking_stop\"; index: number }\n | { type: \"text_start\"; index: number }\n | { type: \"text_delta\"; index: number; text: string }\n | { type: \"text_stop\"; index: number }\n | { type: \"tool_use\"; index: number; name: string; args: unknown }\n | { type: \"usage\"; inputTokens: number; outputTokens: number }\n | { type: \"finish\"; stopReason: string }\n\n/**\n * Create initial stream state\n */\nexport function createStreamState(): StreamState {\n return {\n buffer: \"\",\n inputTokens: 0,\n outputTokens: 0,\n contentBlockIndex: 0,\n thinkingBlockStarted: false,\n textBlockStarted: false,\n }\n}\n\n/**\n * Parse a single SSE line and return the JSON data if valid\n */\nexport function parseSSELine(line: string): AntigravityData | null {\n if (!line.startsWith(\"data: \")) {\n return null\n }\n\n const data = line.slice(6).trim()\n if (data === \"[DONE]\" || data === \"\") {\n return null\n }\n\n try {\n return JSON.parse(data) as AntigravityData\n } catch {\n return null\n }\n}\n\n/**\n * Extract candidates and usage from parsed data\n */\nexport function extractFromData(data: AntigravityData): {\n candidates: Array<AntigravityCandidate>\n usage: AntigravityUsage | undefined\n} {\n const candidates = data.response?.candidates || data.candidates || []\n const usage = data.response?.usageMetadata || data.usageMetadata\n return { candidates, usage }\n}\n\n/**\n * Process a single part and emit events\n */\nexport function processPart(\n part: AntigravityPart,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Handle thinking content\n if (part.thought && part.text) {\n processThinkingPart(part.text, state, emit)\n return\n }\n\n // Handle regular text content\n if (part.text && !part.thought) {\n processTextPart(part.text, state, emit)\n return\n }\n\n // Handle function calls\n if (part.functionCall) {\n processToolPart(part.functionCall, state, emit)\n }\n}\n\n/**\n * Process thinking content\n */\nfunction processThinkingPart(\n text: string,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n if (!state.thinkingBlockStarted) {\n emit({ type: \"thinking_start\", index: state.contentBlockIndex })\n state.thinkingBlockStarted = true\n }\n emit({ type: \"thinking_delta\", index: state.contentBlockIndex, text })\n}\n\n/**\n * Process text content\n */\nfunction processTextPart(\n text: string,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Close thinking block if open\n if (state.thinkingBlockStarted && !state.textBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.thinkingBlockStarted = false\n }\n\n // Start text block if not started\n if (!state.textBlockStarted) {\n emit({ type: \"text_start\", index: state.contentBlockIndex })\n state.textBlockStarted = true\n }\n\n emit({ type: \"text_delta\", index: state.contentBlockIndex, text })\n}\n\n/**\n * Process tool/function call\n */\nfunction processToolPart(\n functionCall: { name: string; args: unknown },\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Close previous block if open\n if (state.textBlockStarted) {\n emit({ type: \"text_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.textBlockStarted = false\n } else if (state.thinkingBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.thinkingBlockStarted = false\n }\n\n emit({\n type: \"tool_use\",\n index: state.contentBlockIndex,\n name: functionCall.name,\n args: functionCall.args,\n })\n state.contentBlockIndex++\n}\n\n/**\n * Handle finish reason and close open blocks\n */\nexport function handleFinish(\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n if (state.textBlockStarted) {\n emit({ type: \"text_stop\", index: state.contentBlockIndex })\n state.textBlockStarted = false\n } else if (state.thinkingBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.thinkingBlockStarted = false\n }\n\n emit({\n type: \"usage\",\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n })\n emit({ type: \"finish\", stopReason: \"end_turn\" })\n}\n\n/**\n * Process chunk and update buffer, returning complete lines\n */\nexport function processChunk(chunk: string, state: StreamState): Array<string> {\n state.buffer += chunk\n const lines = state.buffer.split(\"\\n\")\n state.buffer = lines.pop() || \"\"\n return lines\n}\n","/**\n * Google Antigravity Chat Completions\n *\n * Proxy chat completion requests to Google Antigravity API or standard Gemini API.\n * Supports two authentication methods:\n * - API Key: Uses standard Gemini API (generativelanguage.googleapis.com)\n * - OAuth: Uses Antigravity private API (daily-cloudcode-pa.sandbox.googleapis.com)\n *\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nimport consola from \"consola\"\n\nimport {\n disableCurrentAccount,\n getApiKey,\n getValidAccessToken,\n rotateAccount,\n} from \"./auth\"\nimport { isThinkingModel } from \"./get-models\"\nimport {\n createStreamState,\n extractFromData,\n parseSSELine,\n processChunk,\n type AntigravityPart,\n type StreamState,\n} from \"./stream-parser\"\n\n// Antigravity API endpoints (OAuth authentication)\n// Note: Claude models also use the same generateContent endpoint, not rawPredict\n// The API accepts Claude model names (e.g., claude-sonnet-4-5) but uses Gemini-style format\nconst ANTIGRAVITY_API_HOST = \"daily-cloudcode-pa.sandbox.googleapis.com\"\nconst ANTIGRAVITY_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:streamGenerateContent?alt=sse`\nconst ANTIGRAVITY_NO_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:generateContent`\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\n// Standard Gemini API endpoints (API Key authentication)\nconst GEMINI_API_HOST = \"generativelanguage.googleapis.com\"\nconst getGeminiStreamUrl = (model: string, apiKey: string) =>\n `https://${GEMINI_API_HOST}/v1beta/models/${model}:streamGenerateContent?alt=sse&key=${apiKey}`\nconst getGeminiNoStreamUrl = (model: string, apiKey: string) =>\n `https://${GEMINI_API_HOST}/v1beta/models/${model}:generateContent?key=${apiKey}`\n\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\"\n content:\n | string\n | Array<{ type: string; text?: string; image_url?: { url: string } }>\n}\n\nexport interface ChatCompletionRequest {\n model: string\n messages: Array<ChatMessage>\n stream?: boolean\n temperature?: number\n max_tokens?: number\n top_p?: number\n top_k?: number\n tools?: Array<unknown>\n}\n\ninterface ConvertedContent {\n contents: Array<unknown>\n systemInstruction?: unknown\n}\n\n/**\n * Convert OpenAI format messages to Antigravity format\n */\nfunction convertMessages(messages: Array<ChatMessage>): ConvertedContent {\n const contents: Array<unknown> = []\n let systemInstruction: unknown\n\n for (const message of messages) {\n if (message.role === \"system\") {\n systemInstruction = buildSystemInstruction(message.content)\n continue\n }\n\n const role = message.role === \"assistant\" ? \"model\" : \"user\"\n const parts = buildMessageParts(message.content)\n contents.push({ role, parts })\n }\n\n return { contents, systemInstruction }\n}\n\n/**\n * Build system instruction from content\n */\nfunction buildSystemInstruction(content: ChatMessage[\"content\"]): {\n parts: Array<{ text: string }>\n} {\n const text =\n typeof content === \"string\" ? content : (\n content.map((c) => c.text || \"\").join(\"\")\n )\n // Antigravity format: parts is an array of Part objects with text field\n return { parts: [{ text }] }\n}\n\n/**\n * Build message parts from content\n */\nfunction buildMessageParts(content: ChatMessage[\"content\"]): Array<unknown> {\n if (typeof content === \"string\") {\n return [{ text: content }]\n }\n\n const parts: Array<unknown> = []\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push({ text: part.text })\n } else if (part.type === \"image_url\" && part.image_url?.url) {\n const imageData = parseBase64Image(part.image_url.url)\n if (imageData) parts.push({ inlineData: imageData })\n }\n }\n return parts\n}\n\n/**\n * Parse base64 image URL\n */\nfunction parseBase64Image(\n url: string,\n): { mimeType: string; data: string } | null {\n if (!url.startsWith(\"data:\")) return null\n const match = url.match(/^data:([^;]+);base64,(.+)$/)\n if (!match) return null\n return { mimeType: match[1], data: match[2] }\n}\n\n// Allowlisted fields for Gemini API Schema\nconst GEMINI_ALLOWED_FIELDS = new Set([\n \"type\",\n \"description\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"nullable\",\n])\n\n/**\n * Convert type value to Gemini format\n * Handles both string and array types (for nullable)\n */\nfunction convertTypeValue(\n value: unknown,\n): { type: string; nullable?: boolean } | null {\n if (typeof value === \"string\") {\n return { type: value.toUpperCase() }\n }\n if (Array.isArray(value)) {\n const nonNullType = value.find(\n (t): t is string => typeof t === \"string\" && t !== \"null\",\n )\n if (nonNullType) {\n return { type: nonNullType.toUpperCase(), nullable: true }\n }\n }\n return null\n}\n\n/**\n * Clean properties object recursively\n */\nfunction cleanProperties(\n props: Record<string, unknown>,\n): Record<string, unknown> {\n const cleanedProps: Record<string, unknown> = {}\n for (const [propKey, propValue] of Object.entries(props)) {\n cleanedProps[propKey] = cleanJsonSchema(propValue)\n }\n return cleanedProps\n}\n\n/**\n * Clean and convert JSON schema to Gemini format\n * - Removes unsupported fields like $schema, additionalProperties\n * - Converts type values to uppercase (string -> STRING)\n * - Ensures properties format is correct for Google API\n */\nfunction cleanJsonSchema(schema: unknown): unknown {\n if (!schema || typeof schema !== \"object\") return schema\n if (Array.isArray(schema)) {\n return schema.map((item) => cleanJsonSchema(item))\n }\n\n const obj = schema as Record<string, unknown>\n const cleaned: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n if (!GEMINI_ALLOWED_FIELDS.has(key)) continue\n\n if (key === \"type\") {\n const result = convertTypeValue(value)\n if (result) {\n cleaned.type = result.type\n if (result.nullable) cleaned.nullable = true\n }\n } else if (key === \"properties\" && typeof value === \"object\" && value) {\n cleaned.properties = cleanProperties(value as Record<string, unknown>)\n } else if (typeof value === \"object\" && value !== null) {\n cleaned[key] = cleanJsonSchema(value)\n } else {\n cleaned[key] = value\n }\n }\n\n return cleaned\n}\n\n/**\n * Convert tools to Antigravity format\n * All tools should be in a single object with functionDeclarations array\n */\nfunction convertTools(tools?: Array<unknown>): Array<unknown> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const functionDeclarations: Array<unknown> = []\n\n for (const tool of tools) {\n const t = tool as {\n type: string\n function?: { name: string; description?: string; parameters?: unknown }\n }\n if (t.type === \"function\" && t.function) {\n functionDeclarations.push({\n name: t.function.name,\n description: t.function.description || \"\",\n parameters: cleanJsonSchema(t.function.parameters) || {},\n })\n }\n }\n\n if (functionDeclarations.length === 0) return undefined\n\n // Return as a single object with all function declarations\n return [{ functionDeclarations }]\n}\n\n/**\n * Build standard Gemini API request body (for API Key authentication)\n */\nfunction buildStandardGeminiRequestBody(\n request: ChatCompletionRequest,\n): Record<string, unknown> {\n const { contents, systemInstruction } = convertMessages(request.messages)\n const tools = convertTools(request.tools)\n\n const body: Record<string, unknown> = {\n contents,\n generationConfig: {\n temperature: request.temperature ?? 1,\n topP: request.top_p ?? 0.85,\n topK: request.top_k ?? 50,\n maxOutputTokens: request.max_tokens ?? 8096,\n },\n }\n\n if (systemInstruction) body.systemInstruction = systemInstruction\n if (tools) body.tools = tools\n\n if (isThinkingModel(request.model)) {\n body.generationConfig = {\n ...(body.generationConfig as Record<string, unknown>),\n thinkingConfig: { includeThoughts: true },\n }\n }\n\n return body\n}\n\n/**\n * Build Antigravity request body\n * The Antigravity API expects a specific nested structure with request object\n */\nfunction buildAntigravityRequestBody(\n request: ChatCompletionRequest,\n): Record<string, unknown> {\n const innerRequest = buildStandardGeminiRequestBody(request)\n\n // Wrap in the Antigravity request structure\n return {\n model: request.model,\n userAgent: \"antigravity\",\n requestId: `agent-${crypto.randomUUID()}`,\n request: innerRequest,\n }\n}\n\n/**\n * Create error response\n */\nfunction createErrorResponse(\n message: string,\n type: string,\n status: number,\n details?: string,\n): Response {\n const error: Record<string, unknown> = { message, type }\n if (details) error.details = details\n return new Response(JSON.stringify({ error }), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Create chat completion with Antigravity or standard Gemini API\n * Priority: API Key > OAuth\n */\nexport async function createAntigravityChatCompletion(\n request: ChatCompletionRequest,\n): Promise<Response> {\n // Try API Key authentication first (simplest)\n const apiKey = getApiKey()\n if (apiKey) {\n return await createWithApiKey(request, apiKey)\n }\n\n // Fall back to OAuth authentication\n const accessToken = await getValidAccessToken()\n if (!accessToken) {\n return createErrorResponse(\n \"No valid authentication available. Please set GEMINI_API_KEY environment variable or run OAuth login.\",\n \"auth_error\",\n 401,\n )\n }\n\n return await createWithOAuth(request, accessToken)\n}\n\n/**\n * Create chat completion using API Key (standard Gemini API)\n */\nasync function createWithApiKey(\n request: ChatCompletionRequest,\n apiKey: string,\n): Promise<Response> {\n const endpoint =\n request.stream ?\n getGeminiStreamUrl(request.model, apiKey)\n : getGeminiNoStreamUrl(request.model, apiKey)\n const body = buildStandardGeminiRequestBody(request)\n\n consola.debug(`Gemini API request with model ${request.model}`)\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return await handleApiError(response)\n }\n\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n } catch (error) {\n consola.error(\"Gemini API request error:\", error)\n return createErrorResponse(\n `Request failed: ${String(error)}`,\n \"request_error\",\n 500,\n )\n }\n}\n\n/**\n * Create chat completion using OAuth (Antigravity private API)\n * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format\n */\nasync function createWithOAuth(\n request: ChatCompletionRequest,\n accessToken: string,\n): Promise<Response> {\n const endpoint =\n request.stream ? ANTIGRAVITY_STREAM_URL : ANTIGRAVITY_NO_STREAM_URL\n const body = buildAntigravityRequestBody(request)\n\n consola.debug(\n `Antigravity request to ${endpoint} with model ${request.model}`,\n )\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Host: ANTIGRAVITY_API_HOST,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return await handleApiError(response)\n }\n\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n } catch (error) {\n consola.error(\"Antigravity request error:\", error)\n return createErrorResponse(\n `Request failed: ${String(error)}`,\n \"request_error\",\n 500,\n )\n }\n}\n\n/**\n * Handle API error response\n */\nasync function handleApiError(response: Response): Promise<Response> {\n const errorText = await response.text()\n consola.error(`Antigravity error: ${response.status} ${errorText}`)\n\n if (response.status === 403) await disableCurrentAccount()\n if (response.status === 429 || response.status === 503) await rotateAccount()\n\n return createErrorResponse(\n `Antigravity API error: ${response.status}`,\n \"api_error\",\n response.status,\n errorText,\n )\n}\n\n/**\n * Generate request ID\n */\nfunction generateRequestId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Transform Antigravity stream response to OpenAI format\n */\nfunction transformStreamResponse(response: Response, model: string): Response {\n const reader = response.body?.getReader()\n if (!reader) return new Response(\"No response body\", { status: 500 })\n\n const encoder = new TextEncoder()\n const decoder = new TextDecoder()\n const requestId = generateRequestId()\n\n const stream = new ReadableStream({\n async start(controller) {\n const state = createStreamState()\n\n try {\n await processOpenAIStream(\n reader as ReadableStreamDefaultReader<Uint8Array>,\n decoder,\n state,\n controller,\n encoder,\n requestId,\n model,\n )\n controller.enqueue(encoder.encode(\"data: [DONE]\\n\\n\"))\n controller.close()\n } catch (error) {\n consola.error(\"Stream transform error:\", error)\n controller.error(error)\n }\n },\n })\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n })\n}\n\n/**\n * Process stream and emit OpenAI format chunks\n */\nasync function processOpenAIStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n decoder: TextDecoder,\n state: StreamState,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n requestId: string,\n model: string,\n): Promise<void> {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n const lines = processChunk(chunk, state)\n\n for (const line of lines) {\n const data = parseSSELine(line)\n if (!data) continue\n\n const { candidates } = extractFromData(data)\n const candidate = candidates[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n const chunkData = buildOpenAIChunk(\n part,\n requestId,\n model,\n candidate?.finishReason,\n )\n if (chunkData) {\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(chunkData)}\\n\\n`),\n )\n }\n }\n }\n }\n}\n\n/**\n * Build OpenAI format chunk from part\n */\nfunction buildOpenAIChunk(\n part: AntigravityPart,\n requestId: string,\n model: string,\n finishReason?: string,\n): unknown | null {\n const baseChunk = {\n id: requestId,\n object: \"chat.completion.chunk\",\n created: Math.floor(Date.now() / 1000),\n model,\n }\n\n // Handle thinking content\n if (part.thought && part.text) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: { reasoning_content: part.text },\n finish_reason: null,\n },\n ],\n }\n }\n\n // Handle regular text\n if (part.text && !part.thought) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: { content: part.text },\n finish_reason: finishReason === \"STOP\" ? \"stop\" : null,\n },\n ],\n }\n }\n\n // Handle function calls\n if (part.functionCall) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [\n {\n index: 0,\n id: `call_${Date.now()}`,\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: JSON.stringify(part.functionCall.args),\n },\n },\n ],\n },\n finish_reason: null,\n },\n ],\n }\n }\n\n return null\n}\n\n/**\n * Transform Antigravity non-stream response to OpenAI format\n */\nasync function transformNonStreamResponse(\n response: Response,\n model: string,\n): Promise<Response> {\n interface AntigravityResponseData {\n candidates?: Array<{\n content?: { parts?: Array<AntigravityPart> }\n finishReason?: string\n }>\n usageMetadata?: {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n }\n }\n\n interface NonStreamData {\n response?: AntigravityResponseData\n candidates?: Array<{\n content?: { parts?: Array<AntigravityPart> }\n finishReason?: string\n }>\n usageMetadata?: {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n }\n }\n\n const rawData = (await response.json()) as NonStreamData\n\n // Handle nested response structure (Antigravity wraps response in a \"response\" object)\n const data = rawData.response ?? rawData\n const candidate = data.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const { content, reasoningContent, toolCalls } =\n extractNonStreamContent(parts)\n\n const message: Record<string, unknown> = {\n role: \"assistant\",\n content: content || null,\n }\n if (reasoningContent) message.reasoning_content = reasoningContent\n if (toolCalls.length > 0) message.tool_calls = toolCalls\n\n const openaiResponse = {\n id: generateRequestId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [{ index: 0, message, finish_reason: \"stop\" }],\n usage: {\n prompt_tokens: data.usageMetadata?.promptTokenCount ?? 0,\n completion_tokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n total_tokens: data.usageMetadata?.totalTokenCount ?? 0,\n },\n }\n\n return new Response(JSON.stringify(openaiResponse), {\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Extract content from non-stream response parts\n */\nfunction extractNonStreamContent(parts: Array<AntigravityPart>): {\n content: string\n reasoningContent: string\n toolCalls: Array<unknown>\n} {\n let content = \"\"\n let reasoningContent = \"\"\n const toolCalls: Array<unknown> = []\n\n for (const part of parts) {\n if (part.thought && part.text) {\n reasoningContent += part.text\n } else if (part.text) {\n content += part.text\n }\n\n if (part.functionCall) {\n toolCalls.push({\n id: `call_${Date.now()}`,\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: JSON.stringify(part.functionCall.args),\n },\n })\n }\n }\n\n return { content, reasoningContent, toolCalls }\n}\n","/**\n * Antigravity Chat Completions Route\n *\n * OpenAI-compatible chat completions endpoint for Antigravity.\n */\n\nimport { Hono } from \"hono\"\n\nimport {\n createAntigravityChatCompletion,\n type ChatCompletionRequest,\n} from \"~/services/antigravity/create-chat-completions\"\n\nconst app = new Hono()\n\napp.post(\"/\", async (c) => {\n const body = await c.req.json<ChatCompletionRequest>()\n\n const response = await createAntigravityChatCompletion(body)\n\n // Copy response headers\n const headers = new Headers(response.headers)\n\n if (body.stream) {\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n return new Response(await response.text(), {\n status: response.status,\n headers,\n })\n})\n\nexport const antigravityChatCompletionsRoute = app\n","/**\n * Request Queue with Concurrency Limit\n *\n * Limits concurrent requests to prevent rate limiting.\n * Allows configurable number of concurrent requests.\n */\n\ntype QueuedRequest<T> = {\n execute: () => Promise<T>\n resolve: (value: T) => void\n reject: (error: unknown) => void\n}\n\nexport class RequestQueue {\n private queue: Array<QueuedRequest<unknown>> = []\n private activeCount = 0\n private maxConcurrent: number\n private minDelayMs: number\n private lastRequestTime = 0\n\n constructor(maxConcurrent = 2, minDelayMs = 300) {\n this.maxConcurrent = maxConcurrent\n this.minDelayMs = minDelayMs\n }\n\n async enqueue<T>(execute: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push({\n execute: execute as () => Promise<unknown>,\n resolve: resolve as (value: unknown) => void,\n reject,\n })\n void this.processQueue()\n })\n }\n\n private async processQueue(): Promise<void> {\n if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {\n return\n }\n\n const request = this.queue.shift()\n if (!request) return\n\n this.activeCount++\n\n // Ensure minimum delay between requests\n const now = Date.now()\n const elapsed = now - this.lastRequestTime\n if (elapsed < this.minDelayMs) {\n await new Promise((r) => setTimeout(r, this.minDelayMs - elapsed))\n }\n this.lastRequestTime = Date.now()\n\n try {\n const result = await request.execute()\n request.resolve(result)\n } catch (error) {\n request.reject(error)\n } finally {\n this.activeCount--\n void this.processQueue()\n }\n }\n}\n\n// Allow 2 concurrent requests with 500ms minimum gap\nexport const antigravityQueue = new RequestQueue(2, 500)\n","/**\n * Anthropic SSE Event Builder\n *\n * Builds Anthropic-compatible SSE events for streaming responses.\n * Extracted for better code organization and reusability.\n */\n\nconst encoder = new TextEncoder()\n\n/**\n * Create message_start event\n */\nexport function createMessageStart(\n messageId: string,\n model: string,\n): Uint8Array {\n const event = {\n type: \"message_start\",\n message: {\n id: messageId,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: 0,\n output_tokens: 0,\n },\n },\n }\n return encoder.encode(\n `event: message_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create message_stop event\n */\nexport function createMessageStop(): Uint8Array {\n const event = { type: \"message_stop\" }\n return encoder.encode(\n `event: message_stop\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for thinking\n */\nexport function createThinkingBlockStart(index: number): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"thinking\",\n thinking: \"\",\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for thinking\n */\nexport function createThinkingDelta(index: number, text: string): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"thinking_delta\",\n thinking: text,\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for text\n */\nexport function createTextBlockStart(index: number): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for text\n */\nexport function createTextDelta(index: number, text: string): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"text_delta\",\n text,\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_stop event\n */\nexport function createBlockStop(index: number): Uint8Array {\n const event = {\n type: \"content_block_stop\",\n index,\n }\n return encoder.encode(\n `event: content_block_stop\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for tool_use\n */\nexport function createToolBlockStart(\n index: number,\n toolId: string,\n name: string,\n): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"tool_use\",\n id: toolId,\n name,\n input: {},\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for tool input\n */\nexport function createToolDelta(index: number, args: unknown): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"input_json_delta\",\n partial_json: JSON.stringify(args),\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create message_delta event with stop reason and usage\n */\nexport function createMessageDelta(\n stopReason: string,\n outputTokens: number,\n): Uint8Array {\n const event = {\n type: \"message_delta\",\n delta: {\n stop_reason: stopReason,\n stop_sequence: null,\n },\n usage: {\n output_tokens: outputTokens,\n },\n }\n return encoder.encode(\n `event: message_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Generate a unique tool ID\n */\nexport function generateToolId(): string {\n return `toolu_${Date.now()}`\n}\n","/**\n * Google Antigravity Messages API\n *\n * Converts Anthropic Messages API format to Antigravity format.\n * This enables Claude Code to use Antigravity as backend.\n *\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n/* eslint-disable default-case */\n\nimport consola from \"consola\"\n\nimport { antigravityQueue } from \"../../lib/request-queue\"\nimport { sleep } from \"../../lib/utils\"\nimport {\n createBlockStop,\n createMessageDelta,\n createMessageStart,\n createMessageStop,\n createTextBlockStart,\n createTextDelta,\n createThinkingBlockStart,\n createThinkingDelta,\n createToolBlockStart,\n createToolDelta,\n generateMessageId,\n generateToolId,\n} from \"./anthropic-events\"\nimport {\n disableCurrentAccount,\n getCurrentProjectId,\n getValidAccessToken,\n rotateAccount,\n} from \"./auth\"\nimport { isThinkingModel } from \"./get-models\"\nimport {\n createStreamState,\n extractFromData,\n handleFinish,\n parseSSELine,\n processChunk,\n processPart,\n type StreamEvent,\n type StreamState,\n} from \"./stream-parser\"\n\n// Antigravity API endpoints with fallback support\n// Note: Claude models also use the same generateContent endpoint, not rawPredict\n// The API accepts Claude model names but uses Gemini-style format\nconst ANTIGRAVITY_ENDPOINTS = [\n \"daily-cloudcode-pa.sandbox.googleapis.com\", // Daily (Sandbox) - Primary\n \"cloudcode-pa.googleapis.com\", // Production - Fallback\n] as const\n\n// Current endpoint index for fallback rotation\nlet currentEndpointIndex = 0\n\nfunction getStreamUrl(host: string): string {\n return `https://${host}/v1internal:streamGenerateContent?alt=sse`\n}\n\nfunction getNoStreamUrl(host: string): string {\n return `https://${host}/v1internal:generateContent`\n}\n\nfunction getCurrentHost(): string {\n return ANTIGRAVITY_ENDPOINTS[currentEndpointIndex]\n}\n\nfunction rotateEndpoint(): void {\n const oldIndex = currentEndpointIndex\n currentEndpointIndex =\n (currentEndpointIndex + 1) % ANTIGRAVITY_ENDPOINTS.length\n consola.info(\n `Rotating endpoint: ${ANTIGRAVITY_ENDPOINTS[oldIndex]} → ${ANTIGRAVITY_ENDPOINTS[currentEndpointIndex]}`,\n )\n}\n\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\n// Rate limit tracking per model family\ninterface RateLimitInfo {\n lastLimitTime: number\n consecutiveErrors: number\n}\n\nconst rateLimitTracker: Record<string, RateLimitInfo> = {}\n\nfunction getModelFamily(model: string): string {\n if (model.includes(\"claude\")) return \"claude\"\n if (model.includes(\"gemini\")) return \"gemini\"\n return \"other\"\n}\n\nfunction trackRateLimit(model: string): void {\n const family = getModelFamily(model)\n if (!rateLimitTracker[family]) {\n rateLimitTracker[family] = { lastLimitTime: 0, consecutiveErrors: 0 }\n }\n rateLimitTracker[family].lastLimitTime = Date.now()\n rateLimitTracker[family].consecutiveErrors++\n}\n\nfunction clearRateLimitTracker(model: string): void {\n const family = getModelFamily(model)\n if (rateLimitTracker[family]) {\n rateLimitTracker[family].consecutiveErrors = 0\n }\n}\n\nfunction getBackoffDelay(model: string, baseDelay: number): number {\n const family = getModelFamily(model)\n const info = rateLimitTracker[family]\n if (!info) return baseDelay\n\n // Exponential backoff: base * 2^(consecutive-1), max 30s\n const multiplier = Math.min(Math.pow(2, info.consecutiveErrors - 1), 60)\n return Math.min(baseDelay * multiplier, 30000)\n}\n\nexport interface AnthropicMessage {\n role: \"user\" | \"assistant\"\n content:\n | string\n | Array<{\n type: string\n text?: string\n source?: { type: string; media_type: string; data: string }\n }>\n}\n\nexport interface AnthropicMessageRequest {\n model: string\n messages: Array<AnthropicMessage>\n system?:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>\n max_tokens: number\n stream?: boolean\n temperature?: number\n top_p?: number\n top_k?: number\n tools?: Array<unknown>\n}\n\ninterface AntigravityContent {\n role: string\n parts: Array<unknown> | { text: string }\n}\n\ninterface ConvertedMessages {\n contents: Array<AntigravityContent>\n systemInstruction?: { parts: Array<{ text: string }> }\n}\n\n/**\n * Extract text from system content (can be string or array)\n */\nfunction extractSystemText(\n system:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>,\n): string {\n if (typeof system === \"string\") {\n return system\n }\n // Extract text from array of content blocks\n return system\n .filter((block) => block.type === \"text\" && block.text)\n .map((block) => block.text)\n .join(\"\\n\\n\")\n}\n\n/**\n * Convert Anthropic messages to Antigravity format\n */\nfunction convertMessages(\n messages: Array<AnthropicMessage>,\n system?:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>,\n): ConvertedMessages {\n const contents: Array<AntigravityContent> = []\n let systemInstruction: { parts: Array<{ text: string }> } | undefined\n\n if (system) {\n const systemText = extractSystemText(system)\n if (systemText) {\n // Antigravity format: parts is an array of Part objects with text field\n systemInstruction = { parts: [{ text: systemText }] }\n }\n }\n\n for (const message of messages) {\n const role = message.role === \"assistant\" ? \"model\" : \"user\"\n const parts = buildParts(message.content)\n if (parts.length > 0) {\n contents.push({ role, parts })\n }\n }\n\n return { contents, systemInstruction }\n}\n\n/**\n * Build parts array from message content\n */\nfunction buildParts(content: AnthropicMessage[\"content\"]): Array<unknown> {\n if (typeof content === \"string\") {\n return [{ text: content }]\n }\n\n const parts: Array<unknown> = []\n for (const block of content) {\n if (block.type === \"text\" && block.text) {\n parts.push({ text: block.text })\n } else if (block.type === \"image\" && block.source) {\n parts.push({\n inlineData: {\n mimeType: block.source.media_type,\n data: block.source.data,\n },\n })\n }\n }\n return parts\n}\n\n// Allowlisted fields for Gemini API Schema\nconst GEMINI_ALLOWED_FIELDS = new Set([\n \"type\",\n \"description\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"nullable\",\n])\n\n/**\n * Convert type value to Gemini format\n * Handles both string and array types (for nullable)\n */\nfunction convertTypeValue(\n value: unknown,\n): { type: string; nullable?: boolean } | null {\n if (typeof value === \"string\") {\n return { type: value.toUpperCase() }\n }\n if (Array.isArray(value)) {\n const nonNullType = value.find(\n (t): t is string => typeof t === \"string\" && t !== \"null\",\n )\n if (nonNullType) {\n return { type: nonNullType.toUpperCase(), nullable: true }\n }\n }\n return null\n}\n\n/**\n * Clean properties object recursively\n */\nfunction cleanProperties(\n props: Record<string, unknown>,\n): Record<string, unknown> {\n const cleanedProps: Record<string, unknown> = {}\n for (const [propKey, propValue] of Object.entries(props)) {\n cleanedProps[propKey] = cleanJsonSchema(propValue)\n }\n return cleanedProps\n}\n\n/**\n * Clean and convert JSON schema to Gemini format\n * - Removes unsupported fields like $schema, additionalProperties\n * - Converts type values to uppercase (string -> STRING)\n * - Ensures properties format is correct for Google API\n */\nfunction cleanJsonSchema(schema: unknown): unknown {\n if (!schema || typeof schema !== \"object\") return schema\n if (Array.isArray(schema)) {\n return schema.map((item) => cleanJsonSchema(item))\n }\n\n const obj = schema as Record<string, unknown>\n const cleaned: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n if (!GEMINI_ALLOWED_FIELDS.has(key)) continue\n\n if (key === \"type\") {\n const result = convertTypeValue(value)\n if (result) {\n cleaned.type = result.type\n if (result.nullable) cleaned.nullable = true\n }\n } else if (key === \"properties\" && typeof value === \"object\" && value) {\n cleaned.properties = cleanProperties(value as Record<string, unknown>)\n } else if (typeof value === \"object\" && value !== null) {\n cleaned[key] = cleanJsonSchema(value)\n } else {\n cleaned[key] = value\n }\n }\n\n return cleaned\n}\n\n/**\n * Convert tools to Antigravity format\n * All tools should be in a single object with functionDeclarations array\n */\nfunction convertTools(tools?: Array<unknown>): Array<unknown> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const functionDeclarations: Array<unknown> = []\n\n for (const tool of tools) {\n const t = tool as {\n name: string\n description?: string\n input_schema?: unknown\n }\n functionDeclarations.push({\n name: t.name,\n description: t.description || \"\",\n parameters: cleanJsonSchema(t.input_schema) || {},\n })\n }\n\n // Return as a single object with all function declarations\n return [{ functionDeclarations }]\n}\n\n/**\n * Build Antigravity request body\n * The Antigravity API expects a specific nested structure with request object\n */\nfunction buildGeminiRequest(\n request: AnthropicMessageRequest,\n projectId?: string | null,\n): Record<string, unknown> {\n const { contents, systemInstruction } = convertMessages(\n request.messages,\n request.system,\n )\n const tools = convertTools(request.tools)\n\n // Build the inner request object\n const innerRequest: Record<string, unknown> = {\n contents,\n generationConfig: {\n temperature: request.temperature ?? 1,\n topP: request.top_p ?? 0.85,\n topK: request.top_k ?? 50,\n maxOutputTokens: request.max_tokens ?? 8096,\n },\n }\n\n if (systemInstruction) innerRequest.systemInstruction = systemInstruction\n if (tools) innerRequest.tools = tools\n\n if (isThinkingModel(request.model)) {\n innerRequest.generationConfig = {\n ...(innerRequest.generationConfig as Record<string, unknown>),\n thinkingConfig: { includeThoughts: true },\n }\n }\n\n // Wrap in the Antigravity request structure\n const result: Record<string, unknown> = {\n model: request.model,\n userAgent: \"antigravity\",\n requestId: `agent-${crypto.randomUUID()}`,\n request: innerRequest,\n }\n\n // Add project ID if available (required by some endpoints)\n if (projectId) {\n result.project = projectId\n }\n\n return result\n}\n\n/**\n * Create error response\n */\nfunction createErrorResponse(\n type: string,\n message: string,\n status: number,\n): Response {\n return new Response(\n JSON.stringify({ type: \"error\", error: { type, message } }),\n { status, headers: { \"Content-Type\": \"application/json\" } },\n )\n}\n\n/**\n * Create Anthropic-compatible message response using Antigravity\n * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format\n *\n * Features:\n * - Endpoint fallback (daily → prod)\n * - Per-model-family rate limit tracking\n * - Exponential backoff for consecutive errors\n * - Smart retry for short delays (≤5s on same endpoint)\n */\nconst MAX_RETRIES = 5\nconst MAX_ENDPOINT_RETRIES = 2 // Try each endpoint up to 2 times before switching\n\nasync function executeAntigravityRequest(\n request: AnthropicMessageRequest,\n): Promise<Response> {\n // Get project ID for the request\n const projectId = await getCurrentProjectId()\n const body = buildGeminiRequest(request, projectId)\n let endpointRetries = 0\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const host = getCurrentHost()\n const endpoint = request.stream ? getStreamUrl(host) : getNoStreamUrl(host)\n\n const accessToken = await getValidAccessToken()\n\n if (!accessToken) {\n return createErrorResponse(\n \"authentication_error\",\n \"No valid Antigravity access token available.\",\n 401,\n )\n }\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Host: host,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify(body),\n })\n\n if (response.ok) {\n // Success - clear rate limit tracker for this model family\n clearRateLimitTracker(request.model)\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n }\n\n const errorResult = await handleApiError(response, request.model)\n\n if (errorResult.shouldRetry && attempt < MAX_RETRIES) {\n // Track rate limit for exponential backoff\n trackRateLimit(request.model)\n\n // Calculate delay with backoff\n const backoffDelay = getBackoffDelay(\n request.model,\n errorResult.retryDelayMs,\n )\n\n // If delay is short (≤5s), retry on same endpoint\n // Otherwise, try switching endpoint\n if (backoffDelay <= 5000 || endpointRetries >= MAX_ENDPOINT_RETRIES) {\n consola.info(\n `Rate limited, retrying in ${backoffDelay}ms (attempt ${attempt + 1}/${MAX_RETRIES})`,\n )\n await sleep(backoffDelay)\n } else {\n // Try switching endpoint\n rotateEndpoint()\n endpointRetries++\n consola.info(\n `Switching endpoint, retrying in ${errorResult.retryDelayMs}ms`,\n )\n await sleep(errorResult.retryDelayMs)\n }\n continue\n }\n\n return errorResult.response\n } catch (error) {\n consola.error(\"Antigravity request error:\", error)\n if (attempt < MAX_RETRIES) {\n // On network error, try switching endpoint\n if (endpointRetries < MAX_ENDPOINT_RETRIES) {\n rotateEndpoint()\n endpointRetries++\n }\n await sleep(500)\n continue\n }\n return createErrorResponse(\n \"api_error\",\n `Request failed: ${String(error)}`,\n 500,\n )\n }\n }\n\n return createErrorResponse(\"api_error\", \"Max retries exceeded\", 429)\n}\n\nexport async function createAntigravityMessages(\n request: AnthropicMessageRequest,\n): Promise<Response> {\n return antigravityQueue.enqueue(() => executeAntigravityRequest(request))\n}\n\ninterface ApiErrorResult {\n shouldRetry: boolean\n retryDelayMs: number\n response: Response\n}\n\n/**\n * Parse retry delay from error response\n * Supports multiple formats:\n * - RetryInfo.retryDelay: \"3.5s\"\n * - quotaResetDelay: \"3000ms\" or \"3s\"\n * - message: \"Your quota will reset after 3s\"\n */\nfunction parseRetryDelay(errorText: string): number {\n try {\n const errorData = JSON.parse(errorText) as {\n error?: {\n message?: string\n details?: Array<{\n \"@type\"?: string\n retryDelay?: string\n quotaResetDelay?: string\n }>\n }\n }\n\n // Check details array first\n const details = errorData.error?.details ?? []\n for (const detail of details) {\n // Check RetryInfo first\n if (detail[\"@type\"]?.includes(\"RetryInfo\") && detail.retryDelay) {\n const match = /(\\d+(?:\\.\\d+)?)s/.exec(detail.retryDelay)\n if (match) return Math.ceil(Number.parseFloat(match[1]) * 1000)\n }\n // Check quotaResetDelay\n if (detail.quotaResetDelay) {\n const match = /(\\d+(?:\\.\\d+)?)(?:ms|s)/.exec(detail.quotaResetDelay)\n if (match) {\n const value = Number.parseFloat(match[1])\n return detail.quotaResetDelay.includes(\"ms\") ?\n Math.ceil(value)\n : Math.ceil(value * 1000)\n }\n }\n }\n\n // Check message for \"Your quota will reset after Xs\" pattern\n const message = errorData.error?.message ?? \"\"\n const resetMatch = /quota will reset after (\\d+(?:\\.\\d+)?)s/i.exec(message)\n if (resetMatch) {\n return Math.ceil(Number.parseFloat(resetMatch[1]) * 1000)\n }\n } catch {\n // Ignore parse errors\n }\n return 500 // Default 500ms retry delay\n}\n\n/**\n * Handle API error response\n */\nasync function handleApiError(\n response: Response,\n _model?: string,\n): Promise<ApiErrorResult> {\n const errorText = await response.text()\n consola.error(`Antigravity error: ${response.status} ${errorText}`)\n\n if (response.status === 403) {\n await disableCurrentAccount()\n }\n\n // Handle rate limit errors with retry\n if (response.status === 429 || response.status === 503) {\n await rotateAccount()\n const retryDelayMs = parseRetryDelay(errorText)\n return {\n shouldRetry: true,\n retryDelayMs,\n response: createErrorResponse(\n \"api_error\",\n `Antigravity API error: ${response.status}`,\n response.status,\n ),\n }\n }\n\n return {\n shouldRetry: false,\n retryDelayMs: 0,\n response: createErrorResponse(\n \"api_error\",\n `Antigravity API error: ${response.status}`,\n response.status,\n ),\n }\n}\n\n/**\n * Emit SSE event to controller based on stream event type\n */\nfunction emitSSEEvent(\n event: StreamEvent,\n controller: ReadableStreamDefaultController<Uint8Array>,\n state: StreamState,\n): void {\n switch (event.type) {\n case \"thinking_start\": {\n controller.enqueue(createThinkingBlockStart(event.index))\n break\n }\n case \"thinking_delta\": {\n controller.enqueue(createThinkingDelta(event.index, event.text))\n break\n }\n case \"thinking_stop\": {\n controller.enqueue(createBlockStop(event.index))\n break\n }\n case \"text_start\": {\n controller.enqueue(createTextBlockStart(event.index))\n break\n }\n case \"text_delta\": {\n controller.enqueue(createTextDelta(event.index, event.text))\n break\n }\n case \"text_stop\": {\n controller.enqueue(createBlockStop(event.index))\n break\n }\n case \"tool_use\": {\n emitToolUseEvents(event, controller)\n break\n }\n case \"usage\": {\n state.inputTokens = event.inputTokens\n state.outputTokens = event.outputTokens\n break\n }\n case \"finish\": {\n controller.enqueue(\n createMessageDelta(event.stopReason, state.outputTokens),\n )\n break\n }\n // No default needed - all cases are handled by the StreamEvent union type\n }\n}\n\n/**\n * Emit tool use events\n */\nfunction emitToolUseEvents(\n event: { type: \"tool_use\"; index: number; name: string; args: unknown },\n controller: ReadableStreamDefaultController<Uint8Array>,\n): void {\n const toolId = generateToolId()\n controller.enqueue(createToolBlockStart(event.index, toolId, event.name))\n controller.enqueue(createToolDelta(event.index, event.args))\n controller.enqueue(createBlockStop(event.index))\n}\n\n/**\n * Transform Antigravity stream response to Anthropic format\n */\nfunction transformStreamResponse(response: Response, model: string): Response {\n const reader = response.body?.getReader()\n if (!reader) {\n return new Response(\"No response body\", { status: 500 })\n }\n\n const decoder = new TextDecoder()\n const messageId = generateMessageId()\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const state = createStreamState()\n controller.enqueue(createMessageStart(messageId, model))\n\n try {\n await processStream(\n reader as ReadableStreamDefaultReader<Uint8Array>,\n decoder,\n state,\n controller,\n )\n controller.enqueue(createMessageStop())\n controller.close()\n } catch (error) {\n consola.error(\"Stream transform error:\", error)\n controller.error(error)\n }\n },\n })\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n })\n}\n\n/**\n * Process candidate parts and handle finish\n */\nfunction processCandidate(\n candidate: { finishReason?: string; content?: { parts?: Array<unknown> } },\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): boolean {\n const parts = (candidate?.content?.parts ?? []) as Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>\n\n for (const part of parts) {\n processPart(part, state, emit)\n }\n\n if (candidate?.finishReason === \"STOP\") {\n handleFinish(state, emit)\n return true\n }\n return false\n}\n\n/**\n * Process the stream and emit events\n */\nasync function processStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n decoder: TextDecoder,\n state: StreamState,\n controller: ReadableStreamDefaultController<Uint8Array>,\n): Promise<void> {\n const emit = (event: StreamEvent) => emitSSEEvent(event, controller, state)\n let finished = false\n\n while (!finished) {\n const { done, value } = await reader.read()\n if (done) break\n\n const lines = processChunk(decoder.decode(value, { stream: true }), state)\n\n for (const line of lines) {\n if (finished) break\n\n const data = parseSSELine(line)\n if (!data) continue\n\n const { candidates, usage } = extractFromData(data)\n if (usage) {\n state.inputTokens = usage.promptTokenCount ?? state.inputTokens\n state.outputTokens = usage.candidatesTokenCount ?? state.outputTokens\n }\n\n if (candidates[0] && processCandidate(candidates[0], state, emit)) {\n finished = true\n break\n }\n }\n }\n}\n\n/**\n * Transform Antigravity non-stream response to Anthropic format\n */\nasync function transformNonStreamResponse(\n response: Response,\n model: string,\n): Promise<Response> {\n interface AntigravityResponseData {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>\n }\n finishReason?: string\n }>\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number }\n }\n\n interface NonStreamData {\n response?: AntigravityResponseData\n candidates?: AntigravityResponseData[\"candidates\"]\n usageMetadata?: AntigravityResponseData[\"usageMetadata\"]\n }\n\n const rawData = (await response.json()) as NonStreamData\n\n // Handle nested response structure (Antigravity wraps response in a \"response\" object)\n const data = rawData.response ?? rawData\n const candidate = data.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const content = buildNonStreamContent(parts)\n\n const anthropicResponse = {\n id: generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content,\n model,\n stop_reason: \"end_turn\",\n stop_sequence: null,\n usage: {\n input_tokens: data.usageMetadata?.promptTokenCount ?? 0,\n output_tokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n },\n }\n\n return new Response(JSON.stringify(anthropicResponse), {\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Build content array for non-stream response\n */\nfunction buildNonStreamContent(\n parts: Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>,\n): Array<unknown> {\n const content: Array<unknown> = []\n\n for (const part of parts) {\n if (part.thought && part.text) {\n content.push({ type: \"thinking\", thinking: part.text })\n } else if (part.text) {\n content.push({ type: \"text\", text: part.text })\n }\n\n if (part.functionCall) {\n content.push({\n type: \"tool_use\",\n id: generateToolId(),\n name: part.functionCall.name,\n input: part.functionCall.args,\n })\n }\n }\n\n return content\n}\n","/**\n * Antigravity Messages Route\n *\n * Anthropic-compatible messages endpoint for Antigravity.\n * This enables Claude Code to use Antigravity as backend.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createAntigravityMessages,\n type AnthropicMessageRequest,\n} from \"~/services/antigravity/create-messages\"\n\nexport const antigravityMessagesRoute = new Hono()\n\nantigravityMessagesRoute.post(\"/\", async (c) => {\n if (!state.antigravityMode) {\n return c.json(\n {\n error:\n \"Antigravity mode is not enabled. Start with --antigravity flag.\",\n },\n 400,\n )\n }\n\n try {\n const body: AnthropicMessageRequest = await c.req.json()\n consola.debug(\"Antigravity message request:\", body.model)\n\n const response = await createAntigravityMessages(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Antigravity message error:\", error)\n return c.json(\n {\n type: \"error\",\n error: {\n type: \"antigravity_error\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * Antigravity Models Route\n *\n * OpenAI-compatible models endpoint for Antigravity.\n */\n\nimport { Hono } from \"hono\"\n\nimport { getAntigravityModels } from \"~/services/antigravity/get-models\"\n\nconst app = new Hono()\n\napp.get(\"/\", async (c) => {\n const models = await getAntigravityModels()\n return c.json(models)\n})\n\nexport const antigravityModelsRoute = app\n","import consola from \"consola\"\n\nimport { HTTPError } from \"./error\"\n\nexport const awaitApproval = async () => {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: \"confirm\",\n })\n\n if (!response)\n throw new HTTPError(\n \"Request rejected\",\n Response.json({ message: \"Request rejected\" }, { status: 403 }),\n )\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import(\"gpt-tokenizer/encoding/o200k_base\"),\n cl100k_base: () => import(\"gpt-tokenizer/encoding/cl100k_base\"),\n p50k_base: () => import(\"gpt-tokenizer/encoding/p50k_base\"),\n p50k_edit: () => import(\"gpt-tokenizer/encoding/p50k_edit\"),\n r50k_base: () => import(\"gpt-tokenizer/encoding/r50k_base\"),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nconst calculateToolCallsTokens = (\n toolCalls: Array<ToolCall>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nconst calculateContentPartsTokens = (\n contentParts: Array<ContentPart>,\n encoder: Encoder,\n): number => {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === \"image_url\") {\n tokens += encoder.encode(part.image_url.url).length + 85\n } else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nconst calculateMessageTokens = (\n message: Message,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\") {\n tokens += encoder.encode(value).length\n }\n if (key === \"name\") {\n tokens += tokensPerName\n }\n if (key === \"tool_calls\") {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === \"content\" && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nconst calculateTokens = (\n messages: Array<Message>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nconst getEncodeChatFunction = async (encoding: string): Promise<Encoder> => {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport const getTokenizerFromModel = (model: Model): string => {\n return model.capabilities.tokenizer || \"o200k_base\"\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nconst getModelConstants = (model: Model) => {\n return model.id === \"gpt-3.5-turbo\" || model.id === \"gpt-4\" ?\n {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nconst calculateParameterTokens = (\n key: string,\n prop: unknown,\n context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n },\n): number => {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== \"object\" || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || \"string\"\n let paramDesc = param.description || \"\"\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith(\".\")) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set([\"type\", \"description\", \"enum\"])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText =\n typeof propertyValue === \"string\" ? propertyValue : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nconst calculateParametersTokens = (\n parameters: unknown,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (!parameters || typeof parameters !== \"object\") {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === \"properties\") {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n } else {\n const paramText =\n typeof value === \"string\" ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nconst calculateToolTokens = (\n tool: Tool,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || \"\"\n if (fDesc.endsWith(\".\")) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = fName + \":\" + fDesc\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === \"object\" // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport const numTokensForTools = (\n tools: Array<Tool>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport const getTokenCount = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<{ input: number; output: number }> => {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const constants = getModelConstants(model)\n\n // All messages in the payload are prompt tokens (the full conversation context).\n // \"Output\" tokens are only the NEW response from the model, not historical assistant turns.\n let inputTokens = calculateTokens(payload.messages, encoder, constants)\n if (payload.tools && payload.tools.length > 0) {\n inputTokens += numTokensForTools(payload.tools, encoder, constants)\n }\n\n return {\n input: inputTokens,\n output: 0,\n }\n}\n","import consola from \"consola\"\n\nimport type {\n ChatCompletionsPayload,\n Message,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\nimport { getTokenCount } from \"./tokenizer\"\n\n/**\n * Get the maximum prompt token limit for a model.\n * Prefers max_prompt_tokens, falls back to max_context_window_tokens minus max_output_tokens.\n */\nconst getMaxPromptTokens = (model: Model): number | undefined => {\n const limits = model.capabilities.limits\n if (limits.max_prompt_tokens) {\n return limits.max_prompt_tokens\n }\n if (limits.max_context_window_tokens) {\n // Reserve space for output tokens\n const outputReserve = limits.max_output_tokens ?? 4096\n return limits.max_context_window_tokens - outputReserve\n }\n return undefined\n}\n\n/**\n * Check if a message is a tool-related message (tool call or tool result).\n * Tool messages must be kept together with their paired assistant message.\n */\nconst isToolMessage = (message: Message): boolean => {\n return message.role === \"tool\"\n}\n\n/**\n * Check if an assistant message contains tool calls.\n */\nconst hasToolCalls = (message: Message): boolean => {\n return (\n message.role === \"assistant\"\n && Array.isArray(message.tool_calls)\n && message.tool_calls.length > 0\n )\n}\n\n/**\n * Group messages into logical units that must be kept together.\n * Tool call sequences (assistant with tool_calls -> tool results) form a single group.\n * System/developer messages are kept as individual groups.\n * Other messages are individual groups.\n */\ninterface MessageGroup {\n messages: Array<Message>\n isSystem: boolean\n isRecent: boolean\n}\n\nconst groupMessages = (messages: Array<Message>): Array<MessageGroup> => {\n const groups: Array<MessageGroup> = []\n let i = 0\n\n while (i < messages.length) {\n const message = messages[i]\n\n // System/developer messages are always their own group\n if (message.role === \"system\" || message.role === \"developer\") {\n groups.push({ messages: [message], isSystem: true, isRecent: false })\n i++\n continue\n }\n\n // Assistant message with tool calls — group with following tool results\n if (hasToolCalls(message)) {\n const group: Array<Message> = [message]\n let j = i + 1\n while (j < messages.length && isToolMessage(messages[j])) {\n group.push(messages[j])\n j++\n }\n groups.push({ messages: group, isSystem: false, isRecent: false })\n i = j\n continue\n }\n\n // Regular message\n groups.push({ messages: [message], isSystem: false, isRecent: false })\n i++\n }\n\n return groups\n}\n\n/**\n * Create a truncation notice message to inform the model that earlier context was removed.\n */\nconst createTruncationNotice = (): Message => ({\n role: \"user\",\n content:\n \"[Note: Earlier conversation history was automatically truncated to fit within the model's context window. The most recent messages have been preserved.]\",\n})\n\n/**\n * Intelligently truncate messages to fit within the model's token limit.\n *\n * Strategy:\n * 1. Always preserve system/developer messages (they contain critical instructions)\n * 2. Always preserve the most recent messages (they contain the current task context)\n * 3. Remove middle conversation messages, oldest first\n * 4. Insert a truncation notice where messages were removed\n * 5. Keep tool call/result pairs together (never split them)\n *\n * Safety margin: keeps 5% below the limit to account for token counting inaccuracies.\n */\nexport const truncateMessages = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<ChatCompletionsPayload> => {\n const maxPromptTokens = getMaxPromptTokens(model)\n if (!maxPromptTokens) {\n consola.debug(\"No token limit found for model, skipping truncation\")\n return payload\n }\n\n // Check current token count\n const tokenCount = await getTokenCount(payload, model)\n // Apply 5% safety margin\n const safeLimit = Math.floor(maxPromptTokens * 0.95)\n\n if (tokenCount.input <= safeLimit) {\n return payload\n }\n\n const groups = groupMessages(payload.messages)\n\n // Separate system groups from conversation groups\n const systemGroups = groups.filter((g) => g.isSystem)\n const conversationGroups = groups.filter((g) => !g.isSystem)\n\n if (conversationGroups.length === 0) {\n consola.warn(\"No conversation messages to truncate, only system messages\")\n return payload\n }\n\n // Binary search approach: find the minimum number of recent conversation groups\n // that, combined with system messages + truncation notice, fit within the limit.\n // We start by trying to keep all conversation groups, then progressively remove from the front.\n\n let truncatedPayload = payload\n let dropCount = 0\n const maxDrop = Math.max(0, conversationGroups.length - 1) // Keep at least the last group\n\n // Start by dropping oldest groups one at a time\n while (dropCount <= maxDrop) {\n const keptConversationGroups = conversationGroups.slice(dropCount)\n const truncationNotice = dropCount > 0 ? [createTruncationNotice()] : []\n\n const newMessages = [\n ...systemGroups.flatMap((g) => g.messages),\n ...truncationNotice,\n ...keptConversationGroups.flatMap((g) => g.messages),\n ]\n\n truncatedPayload = { ...payload, messages: newMessages }\n\n const newTokenCount = await getTokenCount(truncatedPayload, model)\n if (newTokenCount.input <= safeLimit) {\n if (dropCount > 0) {\n const droppedMessages = conversationGroups\n .slice(0, dropCount)\n .reduce((sum, g) => sum + g.messages.length, 0)\n console.log(\n `Truncated: ${tokenCount.input} -> ${newTokenCount.input} tokens (-${droppedMessages} msgs)`,\n )\n }\n return truncatedPayload\n }\n\n dropCount++\n }\n\n // If we still exceed after dropping all but the last conversation group,\n // return what we have — at least we tried our best\n const finalTokenCount = await getTokenCount(truncatedPayload, model)\n consola.warn(\n `Could not reduce tokens below limit even after maximum truncation. `\n + `Current: ${finalTokenCount.input}, limit: ${maxPromptTokens}. `\n + `System messages or the last message may be too large.`,\n )\n\n return truncatedPayload\n}\n","import consola from \"consola\"\n\nimport type { State } from \"./state\"\n\nimport { HTTPError } from \"./error\"\nimport { sleep } from \"./utils\"\n\nexport async function checkRateLimit(state: State) {\n if (state.rateLimitSeconds === undefined) return\n\n const now = Date.now()\n\n if (!state.lastRequestTimestamp) {\n state.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.rateLimitSeconds) {\n state.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds)\n\n if (!state.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n \"Rate limit exceeded\",\n Response.json({ message: \"Rate limit exceeded\" }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n // eslint-disable-next-line require-atomic-updates\n state.lastRequestTimestamp = now\n consola.info(\"Rate limit wait completed, proceeding with request\")\n return\n}\n","import consola from \"consola\"\nimport { events } from \"fetch-event-stream\"\n\nimport { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const createChatCompletions = async (\n payload: ChatCompletionsPayload,\n) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const enableVision = payload.messages.some(\n (x) =>\n typeof x.content !== \"string\"\n && x.content?.some((x) => x.type === \"image_url\"),\n )\n\n // Agent/user check for X-Initiator header\n // Determine if any message is from an agent (\"assistant\" or \"tool\")\n const isAgentCall = payload.messages.some((msg) =>\n [\"assistant\", \"tool\"].includes(msg.role),\n )\n\n // Build headers and add X-Initiator\n const headers: Record<string, string> = {\n ...copilotHeaders(state, enableVision),\n \"X-Initiator\": isAgentCall ? \"agent\" : \"user\",\n }\n\n consola.debug(\"Sending request to Copilot:\", {\n model: payload.model,\n endpoint: `${copilotBaseUrl(state)}/chat/completions`,\n })\n\n const url = `${copilotBaseUrl(state)}/chat/completions`\n\n // Request usage stats in the final stream chunk\n const body =\n payload.stream ?\n { ...payload, stream_options: { include_usage: true } }\n : payload\n\n const fetchOptions: RequestInit = {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n }\n\n // Retry on transient network errors (TLS disconnect, connection reset, etc.)\n const maxRetries = 2\n let lastError: unknown\n let response: Response | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n response = await fetch(url, fetchOptions)\n break\n } catch (error: unknown) {\n lastError = error\n if (attempt < maxRetries) {\n const delay = 1000 * (attempt + 1)\n consola.warn(\n `Network error on attempt ${attempt + 1}/${maxRetries + 1}, retrying in ${delay}ms:`,\n error instanceof Error ? error.message : error,\n )\n await new Promise((r) => setTimeout(r, delay))\n }\n }\n }\n\n if (!response) {\n throw lastError\n }\n\n if (!response.ok) {\n const errorBody = await response.text()\n consola.error(\"Failed to create chat completions\", {\n status: response.status,\n statusText: response.statusText,\n body: errorBody,\n })\n throw new HTTPError(\n `Failed to create chat completions: ${response.status} ${errorBody}`,\n response,\n )\n }\n\n if (payload.stream) {\n return events(response)\n }\n\n return (await response.json()) as ChatCompletionResponse\n}\n\n// Streaming types\n\nexport interface ChatCompletionChunk {\n id: string\n object: \"chat.completion.chunk\"\n created: number\n model: string\n choices: Array<Choice>\n system_fingerprint?: string\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n prompt_tokens_details?: {\n cached_tokens: number\n }\n completion_tokens_details?: {\n accepted_prediction_tokens: number\n rejected_prediction_tokens: number\n }\n }\n}\n\ninterface Delta {\n content?: string | null\n role?: \"user\" | \"assistant\" | \"system\" | \"tool\"\n tool_calls?: Array<{\n index: number\n id?: string\n type?: \"function\"\n function?: {\n name?: string\n arguments?: string\n }\n }>\n}\n\ninterface Choice {\n index: number\n delta: Delta\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n logprobs: object | null\n}\n\n// Non-streaming types\n\nexport interface ChatCompletionResponse {\n id: string\n object: \"chat.completion\"\n created: number\n model: string\n choices: Array<ChoiceNonStreaming>\n system_fingerprint?: string\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n prompt_tokens_details?: {\n cached_tokens: number\n }\n }\n}\n\ninterface ResponseMessage {\n role: \"assistant\"\n content: string | null\n tool_calls?: Array<ToolCall>\n}\n\ninterface ChoiceNonStreaming {\n index: number\n message: ResponseMessage\n logprobs: object | null\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\"\n}\n\n// Payload types\n\nexport interface ChatCompletionsPayload {\n messages: Array<Message>\n model: string\n temperature?: number | null\n top_p?: number | null\n max_tokens?: number | null\n stop?: string | Array<string> | null\n n?: number | null\n stream?: boolean | null\n\n frequency_penalty?: number | null\n presence_penalty?: number | null\n logit_bias?: Record<string, number> | null\n logprobs?: boolean | null\n response_format?: { type: \"json_object\" } | null\n seed?: number | null\n tools?: Array<Tool> | null\n tool_choice?:\n | \"none\"\n | \"auto\"\n | \"required\"\n | { type: \"function\"; function: { name: string } }\n | null\n user?: string | null\n}\n\nexport interface Tool {\n type: \"function\"\n function: {\n name: string\n description?: string\n parameters: Record<string, unknown>\n }\n}\n\nexport interface Message {\n role: \"user\" | \"assistant\" | \"system\" | \"tool\" | \"developer\"\n content: string | Array<ContentPart> | null\n\n name?: string\n tool_calls?: Array<ToolCall>\n tool_call_id?: string\n}\n\nexport interface ToolCall {\n id: string\n type: \"function\"\n function: {\n name: string\n arguments: string\n }\n}\n\nexport type ContentPart = TextPart | ImagePart\n\nexport interface TextPart {\n type: \"text\"\n text: string\n}\n\nexport interface ImagePart {\n type: \"image_url\"\n image_url: {\n url: string\n detail?: \"low\" | \"high\" | \"auto\"\n }\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { streamSSE, type SSEMessage } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { truncateMessages } from \"~/lib/context-compression\"\nimport { setTokenUsage } from \"~/lib/model-logger\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport { findModel, isNullish } from \"~/lib/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n} from \"~/services/copilot/create-chat-completions\"\n\n/**\n * Calculate token count, log it, and auto-truncate if needed.\n *\n * Uses multi-strategy exact matching via findModel() to handle\n * mismatches between requested and available model names.\n */\nasync function processPayloadTokens(\n payload: ChatCompletionsPayload,\n): Promise<ChatCompletionsPayload> {\n const selectedModel = findModel(payload.model)\n\n if (!selectedModel) {\n consola.warn(\"No model selected, skipping token count calculation\")\n return payload\n }\n\n try {\n const tokenCount = await getTokenCount(payload, selectedModel)\n consola.info(\"Current token count:\", tokenCount)\n\n // Auto-truncate if prompt tokens exceed model limit\n const truncated = await truncateMessages(payload, selectedModel)\n\n // Set max_tokens if not provided\n if (isNullish(truncated.max_tokens)) {\n const withMaxTokens = {\n ...truncated,\n max_tokens: selectedModel.capabilities.limits.max_output_tokens,\n }\n consola.debug(\n \"Set max_tokens to:\",\n JSON.stringify(withMaxTokens.max_tokens),\n )\n return withMaxTokens\n }\n\n return truncated\n } catch (error) {\n consola.warn(\"Failed to calculate token count:\", error)\n return payload\n }\n}\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const rawPayload = await c.req.json<ChatCompletionsPayload>()\n consola.debug(\"Request payload:\", JSON.stringify(rawPayload).slice(-400))\n\n const payload = await processPayloadTokens(rawPayload)\n\n if (state.manualApprove) await awaitApproval()\n\n const response = await createChatCompletions(payload)\n\n if (isNonStreaming(response)) {\n consola.debug(\"Non-streaming response:\", JSON.stringify(response))\n if (response.usage) {\n setTokenUsage({\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n cacheReadTokens: response.usage.prompt_tokens_details?.cached_tokens,\n })\n }\n return c.json(response)\n }\n\n consola.debug(\"Streaming response\")\n return streamSSE(c, async (stream) => {\n for await (const chunk of response) {\n consola.debug(\"Streaming chunk:\", JSON.stringify(chunk))\n\n // Extract token usage from stream chunks\n try {\n const sseChunk = chunk as SSEMessage & { data?: string }\n if (sseChunk.data && sseChunk.data !== \"[DONE]\") {\n const parsed = JSON.parse(sseChunk.data) as {\n usage?: {\n prompt_tokens?: number\n completion_tokens?: number\n prompt_tokens_details?: { cached_tokens?: number }\n }\n }\n if (parsed.usage) {\n const usage = {\n inputTokens: parsed.usage.prompt_tokens ?? 0,\n outputTokens: parsed.usage.completion_tokens ?? 0,\n cacheReadTokens:\n parsed.usage.prompt_tokens_details?.cached_tokens,\n }\n setTokenUsage(usage)\n }\n }\n } catch {\n // Ignore parse errors in usage extraction\n }\n\n await stream.writeSSE(chunk as SSEMessage)\n }\n })\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCompletion } from \"./handler\"\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const createEmbeddings = async (payload: EmbeddingRequest) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const response = await fetch(`${copilotBaseUrl(state)}/embeddings`, {\n method: \"POST\",\n headers: copilotHeaders(state),\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to create embeddings\", response)\n\n return (await response.json()) as EmbeddingResponse\n}\n\nexport interface EmbeddingRequest {\n input: string | Array<string>\n model: string\n}\n\nexport interface Embedding {\n object: string\n embedding: Array<number>\n index: number\n}\n\nexport interface EmbeddingResponse {\n object: string\n data: Array<Embedding>\n model: string\n usage: {\n prompt_tokens: number\n total_tokens: number\n }\n}\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport {\n createEmbeddings,\n type EmbeddingRequest,\n} from \"~/services/copilot/create-embeddings\"\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post(\"/\", async (c) => {\n try {\n const paylod = await c.req.json<EmbeddingRequest>()\n const response = await createEmbeddings(paylod)\n\n return c.json(response)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { type AnthropicResponse } from \"./anthropic-types\"\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null,\n): AnthropicResponse[\"stop_reason\"] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: \"end_turn\",\n length: \"max_tokens\",\n tool_calls: \"tool_use\",\n content_filter: \"end_turn\",\n } as const\n return stopReasonMap[finishReason]\n}\n","import { state } from \"~/lib/state\"\nimport {\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n type ContentPart,\n type Message,\n type TextPart,\n type Tool,\n type ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicResponse,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\n// Payload translation\n\nexport function translateToOpenAI(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload {\n return {\n model: translateModelName(payload.model),\n messages: translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),\n }\n}\n\nexport function translateModelName(model: string): string {\n // Claude Code 发送的模型名称可能与 GitHub Copilot 支持的不一致\n // 需要智能匹配到 Copilot 实际支持的模型\n\n const supportedModels = state.models?.data.map((m) => m.id) ?? []\n\n // 1. 直接匹配\n if (supportedModels.includes(model)) {\n return model\n }\n\n // 2. 移除日期后缀后匹配 (claude-opus-4-5-20251101 -> claude-opus-4-5)\n const modelBase = model.replace(/-\\d{8}$/, \"\")\n if (supportedModels.includes(modelBase)) {\n return modelBase\n }\n\n // 3. 尝试 4-5 -> 4.5 格式转换 (claude-opus-4-5 -> claude-opus-4.5)\n const modelWithDot = modelBase.replace(/-(\\d+)-(\\d+)$/, \"-$1.$2\")\n if (supportedModels.includes(modelWithDot)) {\n return modelWithDot\n }\n\n // 4. 尝试 4.5 -> 4-5 格式转换 (claude-opus-4.5 -> claude-opus-4-5)\n const modelWithDash = model.replace(/(\\d+)\\.(\\d+)/, \"$1-$2\")\n if (supportedModels.includes(modelWithDash)) {\n return modelWithDash\n }\n\n // 5. Anthropic 旧格式到 Copilot 新格式映射\n // claude-3-5-sonnet-xxx -> claude-sonnet-4.5\n // claude-3-opus-xxx -> claude-opus-4.5\n // claude-3-5-haiku-xxx -> claude-haiku-4.5\n const oldFormatMapping: Record<string, string> = {\n \"claude-3-5-sonnet\": \"claude-sonnet-4.5\",\n \"claude-3-sonnet\": \"claude-sonnet-4\",\n \"claude-3-5-opus\": \"claude-opus-4.5\",\n \"claude-3-opus\": \"claude-opus-4.5\",\n \"claude-3-5-haiku\": \"claude-haiku-4.5\",\n \"claude-3-haiku\": \"claude-haiku-4.5\",\n }\n\n for (const [oldFormat, newFormat] of Object.entries(oldFormatMapping)) {\n if (\n modelBase.startsWith(oldFormat)\n && supportedModels.includes(newFormat)\n ) {\n return newFormat\n }\n }\n\n // 6. 如果都找不到,返回原始模型名\n return model\n}\n\nfunction translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n const systemMessages = handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap((message) =>\n message.role === \"user\" ?\n handleUserMessage(message)\n : handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n}\n\nfunction handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === \"string\") {\n return [{ role: \"system\", content: system }]\n } else {\n const systemText = system.map((block) => block.text).join(\"\\n\\n\")\n return [{ role: \"system\", content: systemText }]\n }\n}\n\nfunction handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === \"tool_result\",\n )\n const otherBlocks = message.content.filter(\n (block) => block.type !== \"tool_result\",\n )\n\n // Tool results must come first to maintain protocol: tool_use -> tool_result -> user\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: \"tool\",\n tool_call_id: block.tool_use_id,\n content: mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: \"user\",\n content: mapContent(otherBlocks),\n })\n }\n } else {\n newMessages.push({\n role: \"user\",\n content: mapContent(message.content),\n })\n }\n\n return newMessages\n}\n\nfunction handleAssistantMessage(\n message: AnthropicAssistantMessage,\n): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === \"tool_use\",\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === \"text\",\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === \"thinking\",\n )\n\n // Combine text and thinking blocks, as OpenAI doesn't have separate thinking blocks\n const allTextContent = [\n ...textBlocks.map((b) => b.text),\n ...thinkingBlocks.map((b) => b.thinking),\n ].join(\"\\n\\n\")\n\n return toolUseBlocks.length > 0 ?\n [\n {\n role: \"assistant\",\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map((toolUse) => ({\n id: toolUse.id,\n type: \"function\",\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n}\n\nfunction mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n): string | Array<ContentPart> | null {\n if (typeof content === \"string\") {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some((block) => block.type === \"image\")\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === \"text\" || block.type === \"thinking\",\n )\n .map((block) => (block.type === \"text\" ? block.text : block.thinking))\n .join(\"\\n\\n\")\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n contentParts.push({ type: \"text\", text: block.text })\n\n break\n }\n case \"thinking\": {\n contentParts.push({ type: \"text\", text: block.thinking })\n\n break\n }\n case \"image\": {\n contentParts.push({\n type: \"image_url\",\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n\n break\n }\n // No default\n }\n }\n return contentParts\n}\n\nfunction translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map((tool) => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n}\n\nfunction translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload[\"tool_choice\"],\n): ChatCompletionsPayload[\"tool_choice\"] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n if (anthropicToolChoice.name) {\n return {\n type: \"function\",\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return undefined\n }\n }\n}\n\n// Response translation\n\nexport function translateToAnthropic(\n response: ChatCompletionResponse,\n): AnthropicResponse {\n // Merge content from all choices\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null =\n null // default\n stopReason = response.choices[0]?.finish_reason ?? stopReason\n\n // Process all choices to extract text and tool use blocks\n for (const choice of response.choices) {\n const textBlocks = getAnthropicTextBlocks(choice.message.content)\n const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls)\n\n allTextBlocks.push(...textBlocks)\n allToolUseBlocks.push(...toolUseBlocks)\n\n // Use the finish_reason from the first choice, or prioritize tool_calls\n if (choice.finish_reason === \"tool_calls\" || stopReason === \"stop\") {\n stopReason = choice.finish_reason\n }\n }\n\n // Note: GitHub Copilot doesn't generate thinking blocks, so we don't include them in responses\n\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n model: response.model,\n content: [...allTextBlocks, ...allToolUseBlocks],\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n input_tokens:\n (response.usage?.prompt_tokens ?? 0)\n - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(response.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n response.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n }\n}\n\nfunction getAnthropicTextBlocks(\n messageContent: Message[\"content\"],\n): Array<AnthropicTextBlock> {\n if (typeof messageContent === \"string\") {\n return [{ type: \"text\", text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text }))\n }\n\n return []\n}\n\nfunction getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map((toolCall) => ({\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\n\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport { findModel } from \"~/lib/utils\"\n\nimport { type AnthropicMessagesPayload } from \"./anthropic-types\"\nimport { translateModelName, translateToOpenAI } from \"./non-stream-translation\"\n\n/**\n * Handles token counting for Anthropic messages.\n *\n * Uses multi-strategy model matching:\n * 1. findModel(translatedName) — translated Copilot name with format variants\n * 2. findModel(originalName) — original Anthropic name with format variants\n */\nexport async function handleCountTokens(c: Context) {\n try {\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n // Multi-strategy model matching:\n // Try translated name first (most likely to match Copilot model IDs),\n // then fall back to original Anthropic name with format variants\n const translatedModelName = translateModelName(anthropicPayload.model)\n const selectedModel =\n findModel(translatedModelName) ?? findModel(anthropicPayload.model)\n\n if (!selectedModel) {\n consola.warn(\n `Model not found for \"${anthropicPayload.model}\" (translated: \"${translatedModelName}\"), returning default token count`,\n )\n return c.json({\n input_tokens: 1,\n })\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith(\"claude-code\")) {\n mcpToolExist = anthropicPayload.tools.some((tool) =>\n tool.name.startsWith(\"mcp__\"),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith(\"claude\")) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith(\"claude\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.info(\"Token count:\", finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n } catch (error) {\n consola.error(\"Error counting tokens:\", error)\n return c.json({\n input_tokens: 1,\n })\n }\n}\n","import { type ChatCompletionChunk } from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicStreamEventData,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\nfunction isToolBlockOpen(state: AnthropicStreamState): boolean {\n if (!state.contentBlockOpen) {\n return false\n }\n // Check if the current block index corresponds to any known tool call\n return Object.values(state.toolCalls).some(\n (tc) => tc.anthropicBlockIndex === state.contentBlockIndex,\n )\n}\n\n// eslint-disable-next-line max-lines-per-function, complexity\nexport function translateChunkToAnthropicEvents(\n chunk: ChatCompletionChunk,\n state: AnthropicStreamState,\n): Array<AnthropicStreamEventData> {\n const events: Array<AnthropicStreamEventData> = []\n\n if (chunk.choices.length === 0) {\n return events\n }\n\n const choice = chunk.choices[0]\n const { delta } = choice\n\n if (!state.messageStartSent) {\n events.push({\n type: \"message_start\",\n message: {\n id: chunk.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: chunk.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: 0, // Will be updated in message_delta when finished\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n })\n state.messageStartSent = true\n }\n\n if (delta.content) {\n if (isToolBlockOpen(state)) {\n // A tool block was open, so close it before starting a text block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n if (!state.contentBlockOpen) {\n events.push({\n type: \"content_block_start\",\n index: state.contentBlockIndex,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n })\n state.contentBlockOpen = true\n }\n\n events.push({\n type: \"content_block_delta\",\n index: state.contentBlockIndex,\n delta: {\n type: \"text_delta\",\n text: delta.content,\n },\n })\n }\n\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n if (toolCall.id && toolCall.function?.name) {\n // New tool call starting.\n if (state.contentBlockOpen) {\n // Close any previously open block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = state.contentBlockIndex\n state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: \"content_block_start\",\n index: anthropicBlockIndex,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = state.toolCalls[toolCall.index]\n // Tool call can still be empty\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (toolCallInfo) {\n events.push({\n type: \"content_block_delta\",\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n }\n\n if (choice.finish_reason) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockOpen = false\n }\n\n events.push(\n {\n type: \"message_delta\",\n delta: {\n stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),\n stop_sequence: null,\n },\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: chunk.usage?.completion_tokens ?? 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n {\n type: \"message_stop\",\n },\n )\n }\n\n return events\n}\n\nexport function translateErrorToAnthropicErrorEvent(): AnthropicStreamEventData {\n return {\n type: \"error\",\n error: {\n type: \"api_error\",\n message: \"An unexpected error occurred during streaming.\",\n },\n }\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { streamSSE } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { truncateMessages } from \"~/lib/context-compression\"\nimport { setTokenUsage } from \"~/lib/model-logger\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { state } from \"~/lib/state\"\nimport { findModel } from \"~/lib/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicMessagesPayload,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport {\n translateToAnthropic,\n translateToOpenAI,\n} from \"./non-stream-translation\"\nimport { translateChunkToAnthropicEvents } from \"./stream-translation\"\n\n/**\n * Auto-truncate OpenAI payload if prompt tokens exceed model limit.\n *\n * Uses multi-strategy exact matching via findModel() to handle\n * mismatches between Anthropic and Copilot model naming conventions.\n */\nasync function autoTruncatePayload(\n payload: ChatCompletionsPayload,\n): Promise<ChatCompletionsPayload> {\n const selectedModel = findModel(payload.model)\n\n if (!selectedModel) {\n consola.warn(\n \"No model selected for Anthropic endpoint, skipping auto-truncation\",\n )\n return payload\n }\n\n try {\n return await truncateMessages(payload, selectedModel)\n } catch (error) {\n consola.warn(\"Failed to auto-truncate context:\", error)\n return payload\n }\n}\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n const rawOpenAIPayload = translateToOpenAI(anthropicPayload)\n\n // Auto-truncate if prompt tokens exceed model limit\n const openAIPayload = await autoTruncatePayload(rawOpenAIPayload)\n\n if (state.manualApprove) {\n await awaitApproval()\n }\n\n const response = await createChatCompletions(openAIPayload)\n\n if (isNonStreaming(response)) {\n const anthropicResponse = translateToAnthropic(response)\n setTokenUsage({\n inputTokens: anthropicResponse.usage.input_tokens,\n outputTokens: anthropicResponse.usage.output_tokens,\n cacheReadTokens: anthropicResponse.usage.cache_read_input_tokens,\n cacheCreationTokens: anthropicResponse.usage.cache_creation_input_tokens,\n })\n return c.json(anthropicResponse)\n }\n\n return streamSSE(c, async (stream) => {\n const streamState: AnthropicStreamState = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n\n for await (const rawEvent of response) {\n if (rawEvent.data === \"[DONE]\") {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n const events = translateChunkToAnthropicEvents(chunk, streamState)\n\n // Record token usage from the final chunk (which contains usage stats)\n if (chunk.usage) {\n const usage = {\n inputTokens:\n chunk.usage.prompt_tokens\n - (chunk.usage.prompt_tokens_details?.cached_tokens ?? 0),\n outputTokens: chunk.usage.completion_tokens,\n cacheReadTokens: chunk.usage.prompt_tokens_details?.cached_tokens,\n }\n setTokenUsage(usage)\n }\n\n for (const event of events) {\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n })\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCountTokens } from \"./count-tokens-handler\"\nimport { handleCompletion } from \"./handler\"\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n\nmessageRoutes.post(\"/count_tokens\", async (c) => {\n try {\n return await handleCountTokens(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\nimport { cacheModels } from \"~/lib/utils\"\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get(\"/\", async (c) => {\n try {\n if (!state.models) {\n // This should be handled by startup logic, but as a fallback.\n await cacheModels()\n }\n\n const models = state.models?.data.map((model) => ({\n id: model.id,\n object: \"model\",\n type: \"model\",\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n }))\n\n return c.json({\n object: \"list\",\n data: models,\n has_more: false,\n })\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get(\"/\", (c) => {\n try {\n return c.json({\n token: state.copilotToken,\n })\n } catch (error) {\n consola.error(\"Error fetching token:\", error)\n return c.json({ error: \"Failed to fetch token\", token: null }, 500)\n }\n})\n","import consola from \"consola\"\r\nimport { Hono } from \"hono\"\r\n\r\nimport { state } from \"~/lib/state\"\r\nimport { getAntigravityUsage } from \"~/services/antigravity/get-models\"\r\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\r\n\r\nexport const usageRoute = new Hono()\r\n\r\nusageRoute.get(\"/\", async (c) => {\r\n try {\r\n // Handle different modes\r\n if (state.antigravityMode) {\r\n const usage = await getAntigravityUsage()\r\n return c.json(usage)\r\n }\r\n\r\n if (state.zenMode) {\r\n // Zen doesn't have a public usage API\r\n return c.json({\r\n error: \"Usage statistics not available for Zen mode\",\r\n message: \"Please check your usage at https://console.opencode.ai\",\r\n mode: \"zen\",\r\n }, 200)\r\n }\r\n\r\n // Default: Copilot mode\r\n const usage = await getCopilotUsage()\r\n return c.json(usage)\r\n } catch (error) {\r\n consola.error(\"Error fetching usage:\", error)\r\n\r\n // Return mode-specific error messages\r\n if (state.antigravityMode) {\r\n return c.json({ error: \"Failed to fetch Antigravity usage\" }, 500)\r\n }\r\n if (state.zenMode) {\r\n return c.json({ error: \"Failed to fetch Zen usage\" }, 500)\r\n }\r\n return c.json({ error: \"Failed to fetch Copilot usage\" }, 500)\r\n }\r\n})\r\n","/**\n * OpenCode Zen Chat Completions Proxy\n *\n * Proxies chat completion requests to OpenCode Zen API.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenChatCompletionRequest {\n model: string\n messages: Array<{\n role: string\n content:\n | string\n | Array<{ type: string; text?: string; image_url?: { url: string } }>\n }>\n temperature?: number\n max_tokens?: number\n stream?: boolean\n [key: string]: unknown\n}\n\nexport interface ZenChatCompletionResponse {\n id: string\n object: string\n created: number\n model: string\n choices: Array<{\n index: number\n message: {\n role: string\n content: string\n }\n finish_reason: string\n }>\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n }\n}\n\n/**\n * Parse retry delay from error response\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create chat completions via OpenCode Zen\n */\nexport async function createZenChatCompletions(\n request: ZenChatCompletionRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen chat completions request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\n \"https://opencode.ai/zen/v1/chat/completions\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(request),\n signal,\n },\n )\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen API error: ${response.status} ${errorText}`)\n throw new Error(`Zen API error: ${response.status} ${errorText}`)\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Chat Completions Route\n *\n * Proxies OpenAI-format chat completion requests to Zen.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenChatCompletions,\n type ZenChatCompletionRequest,\n} from \"~/services/zen/create-chat-completions\"\n\nexport const zenCompletionRoutes = new Hono()\n\nzenCompletionRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenChatCompletionRequest = await c.req.json()\n consola.debug(\"Zen chat completion request:\", body.model)\n\n const response = await createZenChatCompletions(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen chat completion error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Messages Proxy\n *\n * Proxies Anthropic-format message requests to OpenCode Zen API.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenMessageRequest {\n model: string\n messages: Array<{\n role: string\n content: string | Array<{ type: string; text?: string; source?: unknown }>\n }>\n max_tokens: number\n temperature?: number\n stream?: boolean\n system?: string | Array<{ type: string; text: string }>\n [key: string]: unknown\n}\n\n/**\n * Parse retry delay from error response headers or body\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n // Check Retry-After header\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n // Try to parse from error body\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create messages via OpenCode Zen (Anthropic format)\n */\nexport async function createZenMessages(\n request: ZenMessageRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen messages request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\"https://opencode.ai/zen/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(request),\n signal,\n })\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n // Retry on rate limit or server errors\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen Messages API error: ${response.status} ${errorText}`)\n throw new Error(`Zen Messages API error: ${response.status} ${errorText}`)\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Messages Route\n *\n * Proxies Anthropic-format message requests to Zen.\n * This enables Claude Code to use Zen as backend.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenMessages,\n type ZenMessageRequest,\n} from \"~/services/zen/create-messages\"\n\nexport const zenMessageRoutes = new Hono()\n\nzenMessageRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenMessageRequest = await c.req.json()\n consola.debug(\"Zen message request:\", body.model)\n\n const response = await createZenMessages(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen message error:\", error)\n return c.json(\n {\n type: \"error\",\n error: {\n type: \"zen_error\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Models Route\n *\n * Returns available models from Zen.\n */\n\n/* eslint-disable require-atomic-updates */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const zenModelRoutes = new Hono()\n\nzenModelRoutes.get(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n // Return cached models\n if (state.zenModels) {\n return c.json(state.zenModels)\n }\n\n // Fetch fresh if not cached\n const { getZenModels } = await import(\"~/services/zen/get-models\")\n const models = await getZenModels()\n state.zenModels = models\n return c.json(models)\n } catch (error) {\n consola.error(\"Zen models error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Responses Proxy\n *\n * Proxies OpenAI Responses API requests to OpenCode Zen.\n * Used for GPT-5 series models with stateful, agentic tool-use.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenResponsesRequest {\n model: string\n input: string | Array<{ role: string; content: string }>\n instructions?: string\n tools?: Array<unknown>\n temperature?: number\n max_output_tokens?: number\n stream?: boolean\n [key: string]: unknown\n}\n\n/**\n * Parse retry delay from error response\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create responses via OpenCode Zen (OpenAI Responses API format)\n */\nexport async function createZenResponses(\n request: ZenResponsesRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen responses request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\"https://opencode.ai/zen/v1/responses\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(request),\n signal,\n })\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen Responses API error: ${response.status} ${errorText}`)\n throw new Error(\n `Zen Responses API error: ${response.status} ${errorText}`,\n )\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Responses Route\n *\n * Proxies OpenAI Responses API requests to Zen.\n * Used for GPT-5 series models.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenResponses,\n type ZenResponsesRequest,\n} from \"~/services/zen/create-responses\"\n\nexport const zenResponsesRoutes = new Hono()\n\nzenResponsesRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenResponsesRequest = await c.req.json()\n consola.debug(\"Zen responses request:\", body.model)\n\n const response = await createZenResponses(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen responses error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","import type { Context } from \"hono\"\n\nimport { Hono } from \"hono\"\nimport { cors } from \"hono/cors\"\n\nimport { apiKeyAuthMiddleware } from \"./lib/api-key-auth\"\nimport { modelLogger } from \"./lib/model-logger\"\nimport { state } from \"./lib/state\"\nimport { antigravityChatCompletionsRoute } from \"./routes/antigravity/chat-completions/route\"\nimport { antigravityMessagesRoute } from \"./routes/antigravity/messages/route\"\nimport { antigravityModelsRoute } from \"./routes/antigravity/models/route\"\nimport { completionRoutes } from \"./routes/chat-completions/route\"\nimport { embeddingRoutes } from \"./routes/embeddings/route\"\nimport { messageRoutes } from \"./routes/messages/route\"\nimport { modelRoutes } from \"./routes/models/route\"\nimport { tokenRoute } from \"./routes/token/route\"\nimport { usageRoute } from \"./routes/usage/route\"\nimport { zenCompletionRoutes } from \"./routes/zen/chat-completions/route\"\nimport { zenMessageRoutes } from \"./routes/zen/messages/route\"\nimport { zenModelRoutes } from \"./routes/zen/models/route\"\nimport { zenResponsesRoutes } from \"./routes/zen/responses/route\"\n\nexport const server = new Hono()\n\nserver.use(modelLogger())\nserver.use(cors())\nserver.use(apiKeyAuthMiddleware)\n\nserver.get(\"/\", (c) => c.text(\"Server running\"))\n\n// Helper to create a new request with modified path for sub-routing\nfunction createSubRequest(c: Context, basePath: string): Request {\n const url = new URL(c.req.url)\n // Remove the base path prefix to get the sub-path\n const subPath = url.pathname.slice(basePath.length) || \"/\"\n url.pathname = subPath\n return new Request(url.toString(), c.req.raw)\n}\n\n// Dynamic routing based on mode (Zen / Antigravity / Copilot)\n// Chat completions\nserver.all(\"/chat/completions/*\", async (c) => {\n const req = createSubRequest(c, \"/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\nserver.all(\"/chat/completions\", async (c) => {\n const req = createSubRequest(c, \"/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\n\n// Models\nserver.all(\"/models/*\", async (c) => {\n const req = createSubRequest(c, \"/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\nserver.all(\"/models\", async (c) => {\n const req = createSubRequest(c, \"/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\n\nserver.route(\"/embeddings\", embeddingRoutes)\nserver.route(\"/usage\", usageRoute)\nserver.route(\"/token\", tokenRoute)\n\n// Compatibility with tools that expect v1/ prefix\nserver.all(\"/v1/chat/completions/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/chat/completions\", async (c) => {\n const req = createSubRequest(c, \"/v1/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\n\nserver.all(\"/v1/models/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/models\", async (c) => {\n const req = createSubRequest(c, \"/v1/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\n\nserver.route(\"/v1/embeddings\", embeddingRoutes)\n\n// Anthropic compatible endpoints\nserver.all(\"/v1/messages/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/messages\")\n if (state.zenMode) return zenMessageRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityMessagesRoute.fetch(req, c.env)\n return messageRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/messages\", async (c) => {\n const req = createSubRequest(c, \"/v1/messages\")\n if (state.zenMode) return zenMessageRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityMessagesRoute.fetch(req, c.env)\n return messageRoutes.fetch(req, c.env)\n})\n\n// OpenAI Responses API (Zen only - for GPT-5 models)\nserver.all(\"/v1/responses/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/responses\")\n if (state.zenMode) return zenResponsesRoutes.fetch(req, c.env)\n return c.json({ error: \"Responses API requires Zen mode\" }, 400)\n})\nserver.all(\"/v1/responses\", async (c) => {\n const req = createSubRequest(c, \"/v1/responses\")\n if (state.zenMode) return zenResponsesRoutes.fetch(req, c.env)\n return c.json({ error: \"Responses API requires Zen mode\" }, 400)\n})\n\n// Dedicated Zen routes (always available)\nserver.route(\"/zen/v1/chat/completions\", zenCompletionRoutes)\nserver.route(\"/zen/v1/models\", zenModelRoutes)\nserver.route(\"/zen/v1/messages\", zenMessageRoutes)\nserver.route(\"/zen/v1/responses\", zenResponsesRoutes)\n\n// Dedicated Antigravity routes (always available)\nserver.route(\n \"/antigravity/v1/chat/completions\",\n antigravityChatCompletionsRoute,\n)\nserver.route(\"/antigravity/v1/models\", antigravityModelsRoute)\nserver.route(\"/antigravity/v1/messages\", antigravityMessagesRoute)\n","#!/usr/bin/env node\n\n// Load environment variables from .env file\nimport \"dotenv/config\"\n/* eslint-disable require-atomic-updates */\n/* eslint-disable max-lines-per-function */\n/* eslint-disable complexity */\nimport { defineCommand } from \"citty\"\nimport clipboard from \"clipboardy\"\nimport consola from \"consola\"\nimport { serve, type ServerHandler } from \"srvx\"\nimport invariant from \"tiny-invariant\"\n\nimport { applyProxyConfig } from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { setupCopilotToken, setupGitHubToken } from \"./lib/token\"\nimport { cacheModels, cacheVSCodeVersion } from \"./lib/utils\"\nimport { server } from \"./server\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n apiKeys?: Array<string>\n zen: boolean\n zenApiKey?: string\n antigravity: boolean\n antigravityClientId?: string\n antigravityClientSecret?: string\n}\n\n/**\n * Start and configure the Copilot API server according to the provided options.\n *\n * Configures proxy and logging, initializes global state and credentials, ensures\n * required paths and model data are cached, optionally generates a Claude Code\n * launch command (and attempts to copy it to the clipboard), prints a usage\n * viewer URL, and begins serving HTTP requests on the specified port.\n *\n * @param options - Server startup options:\n * - port: Port number to listen on\n * - verbose: Enable verbose logging\n * - accountType: Account plan to use (\"individual\", \"business\", \"enterprise\")\n * - manual: Require manual approval for requests\n * - rateLimit: Seconds to wait between requests (optional)\n * - rateLimitWait: Wait instead of erroring when rate limit is hit\n * - githubToken: GitHub token to use (optional; if omitted a token setup prompt may run)\n * - claudeCode: Generate a Claude Code environment launch command\n * - showToken: Expose GitHub/Copilot tokens in responses for debugging\n * - proxyEnv: Initialize proxy settings from environment variables\n * - apiKeys: Optional list of API keys to enable API key authentication\n * - zen: Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)\n * - zenApiKey: OpenCode Zen API key (optional; if omitted will prompt for setup)\n * - antigravity: Enable Google Antigravity mode\n * - antigravityClientId: Google OAuth Client ID (optional; overrides env/default)\n * - antigravityClientSecret: Google OAuth Client Secret (optional; overrides env/default)\n */\nexport async function runServer(options: RunServerOptions): Promise<void> {\n // Apply saved proxy configuration first (if any)\n const savedProxyApplied = await applyProxyConfig()\n\n // Then apply --proxy-env if specified (overrides saved config)\n if (options.proxyEnv) {\n initProxyFromEnv()\n } else if (savedProxyApplied) {\n // If saved proxy was applied, initialize the proxy dispatcher\n initProxyFromEnv()\n }\n\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.accountType = options.accountType\n if (options.accountType !== \"individual\") {\n consola.info(`Using ${options.accountType} plan GitHub account`)\n }\n\n state.manualApprove = options.manual\n state.rateLimitSeconds = options.rateLimit\n state.rateLimitWait = options.rateLimitWait\n state.showToken = options.showToken\n state.apiKeys = options.apiKeys\n\n if (state.apiKeys && state.apiKeys.length > 0) {\n consola.info(\n `API key authentication enabled with ${state.apiKeys.length} key(s)`,\n )\n }\n\n await ensurePaths()\n\n // Handle Zen mode\n if (options.zen) {\n consola.info(\"OpenCode Zen mode enabled\")\n state.zenMode = true\n\n // Setup Zen API key\n if (options.zenApiKey) {\n state.zenApiKey = options.zenApiKey\n consola.info(\"Using provided Zen API key\")\n } else {\n const { setupZenApiKey, loadZenAuth } = await import(\n \"~/services/zen/auth\"\n )\n const existingAuth = await loadZenAuth()\n\n if (existingAuth) {\n state.zenApiKey = existingAuth.apiKey\n consola.info(\"Using existing Zen API key\")\n } else {\n const apiKey = await setupZenApiKey()\n state.zenApiKey = apiKey\n }\n }\n\n // Cache Zen models\n const { cacheZenModels } = await import(\"~/services/zen/get-models\")\n await cacheZenModels()\n\n consola.info(\n `Available Zen models: \\n${state.zenModels?.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n } else if (options.antigravity) {\n // Handle Antigravity mode\n consola.info(\"Google Antigravity mode enabled\")\n state.antigravityMode = true\n\n // Import auth module\n const {\n loadAntigravityAuth,\n setupAntigravity,\n getCurrentAccount,\n hasApiKey,\n getApiKey,\n setOAuthCredentials,\n } = await import(\"~/services/antigravity/auth\")\n\n // Set CLI-provided OAuth credentials if available\n if (options.antigravityClientId && options.antigravityClientSecret) {\n setOAuthCredentials(\n options.antigravityClientId,\n options.antigravityClientSecret,\n )\n consola.info(\"Using provided OAuth credentials from CLI\")\n }\n\n // Check for API Key first (simplest authentication)\n if (hasApiKey()) {\n consola.info(\n \"Using Gemini API Key for authentication (from GEMINI_API_KEY)\",\n )\n consola.info(`API Key: ${getApiKey()?.slice(0, 10) ?? \"\"}...`)\n } else {\n // Fall back to OAuth authentication\n const existingAuth = await loadAntigravityAuth()\n\n if (!existingAuth || existingAuth.accounts.length === 0) {\n consola.warn(\"No Antigravity accounts found and no GEMINI_API_KEY set\")\n consola.info(\"\")\n consola.info(\"You can authenticate using one of these methods:\")\n consola.info(\"\")\n consola.info(\"Method 1: API Key (Recommended - Simplest)\")\n consola.info(\" Set environment variable: GEMINI_API_KEY=your_api_key\")\n consola.info(\n \" Get your API key from: https://aistudio.google.com/apikey\",\n )\n consola.info(\"\")\n consola.info(\"Method 2: OAuth (Current setup)\")\n consola.info(\" Will proceed with OAuth login flow...\")\n consola.info(\"\")\n await setupAntigravity()\n } else {\n const enabledCount = existingAuth.accounts.filter(\n (a) => a.enable,\n ).length\n consola.info(\n `Found ${existingAuth.accounts.length} Antigravity accounts (${enabledCount} enabled)`,\n )\n }\n\n const currentAccount = await getCurrentAccount()\n if (!currentAccount && !hasApiKey()) {\n throw new Error(\"No enabled Antigravity accounts available\")\n }\n }\n\n // Get Antigravity models\n const { getAntigravityModels } = await import(\n \"~/services/antigravity/get-models\"\n )\n const models = await getAntigravityModels()\n state.antigravityModels = models\n\n consola.info(\n `Available Antigravity models: \\n${models.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n } else {\n // Standard Copilot mode\n await cacheVSCodeVersion()\n\n if (options.githubToken) {\n state.githubToken = options.githubToken\n consola.info(\"Using provided GitHub token\")\n // Validate the provided token\n try {\n const { getGitHubUser } = await import(\"~/services/github/get-user\")\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n } catch (error) {\n consola.error(\"Provided GitHub token is invalid\")\n throw error\n }\n } else {\n await setupGitHubToken()\n }\n\n try {\n await setupCopilotToken()\n } catch (error) {\n // If getting Copilot token fails with 401, the GitHub token might be invalid\n const { HTTPError } = await import(\"~/lib/error\")\n if (error instanceof HTTPError && error.response.status === 401) {\n consola.error(\n \"Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked\",\n )\n const { clearGithubToken } = await import(\"~/lib/token\")\n await clearGithubToken()\n consola.info(\"Please restart to re-authenticate\")\n }\n throw error\n }\n\n await cacheModels()\n\n consola.info(\n `Available models: \\n${state.models?.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n }\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n // Get model list based on current mode\n // All model responses share the same { data: Array<{ id: string }> } structure\n let modelList: Array<{ id: string }> | undefined\n if (state.zenMode) {\n modelList = state.zenModels?.data\n } else if (state.antigravityMode) {\n modelList = state.antigravityModels?.data\n } else {\n modelList = state.models?.data\n }\n invariant(modelList, \"Models should be loaded by now\")\n\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: modelList.map((model) => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n \"Select a small model to use with Claude Code\",\n {\n type: \"select\",\n options: modelList.map((model) => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n },\n \"claude\",\n )\n\n try {\n clipboard.writeSync(command)\n consola.success(\"Copied Claude Code command to clipboard!\")\n } catch {\n consola.warn(\n \"Failed to copy to clipboard. Here is the Claude Code command:\",\n )\n consola.log(command)\n }\n }\n\n consola.box(\n `🌐 Usage Viewer: https://imbuxiangnan-cyber.github.io/copilot-api-plus?endpoint=${serverUrl}/usage`,\n )\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the Copilot API server\",\n },\n args: {\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port to listen on\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type to use (individual, business, enterprise)\",\n },\n manual: {\n type: \"boolean\",\n default: false,\n description: \"Enable manual request approval\",\n },\n \"rate-limit\": {\n alias: \"r\",\n type: \"string\",\n description: \"Rate limit in seconds between requests\",\n },\n wait: {\n alias: \"w\",\n type: \"boolean\",\n default: false,\n description:\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description:\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\n },\n \"claude-code\": {\n alias: \"c\",\n type: \"boolean\",\n default: false,\n description:\n \"Generate a command to launch Claude Code with Copilot API config\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n \"api-key\": {\n type: \"string\",\n description: \"API keys for authentication\",\n },\n zen: {\n alias: \"z\",\n type: \"boolean\",\n default: false,\n description:\n \"Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)\",\n },\n \"zen-api-key\": {\n type: \"string\",\n description: \"OpenCode Zen API key (get from https://opencode.ai/zen)\",\n },\n antigravity: {\n type: \"boolean\",\n default: false,\n description:\n \"Enable Google Antigravity mode (proxy to Antigravity instead of GitHub Copilot)\",\n },\n \"antigravity-client-id\": {\n type: \"string\",\n description:\n \"Google OAuth Client ID for Antigravity (create at https://console.cloud.google.com/apis/credentials)\",\n },\n \"antigravity-client-secret\": {\n type: \"string\",\n description: \"Google OAuth Client Secret for Antigravity\",\n },\n },\n run({ args }) {\n const rateLimitRaw = args[\"rate-limit\"]\n const rateLimit =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n\n // Handle multiple API keys - citty may pass a string or array\n const apiKeyRaw = args[\"api-key\"]\n let apiKeys: Array<string> | undefined\n if (apiKeyRaw) {\n apiKeys = Array.isArray(apiKeyRaw) ? apiKeyRaw : [apiKeyRaw]\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args[\"account-type\"],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args[\"github-token\"],\n claudeCode: args[\"claude-code\"],\n showToken: args[\"show-token\"],\n proxyEnv: args[\"proxy-env\"],\n apiKeys,\n zen: args.zen,\n zenApiKey: args[\"zen-api-key\"],\n antigravity: args.antigravity,\n antigravityClientId: args[\"antigravity-client-id\"],\n antigravityClientSecret: args[\"antigravity-client-secret\"],\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\"\n\nimport { antigravity } from \"./antigravity\"\nimport { auth } from \"./auth\"\nimport { checkUsage } from \"./check-usage\"\nimport { debug } from \"./debug\"\nimport { logout } from \"./logout\"\nimport { proxy } from \"./proxy-config\"\nimport { start } from \"./start\"\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api-plus\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI/Anthropic compatible. Fork with bug fixes and improvements.\",\n },\n subCommands: {\n antigravity,\n auth,\n start,\n \"check-usage\": checkUsage,\n debug,\n logout,\n proxy,\n },\n})\n\nawait runMain(main)\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.js","names":["fs","path","os","crypto","options","debug","options","config","options","auth","clearAntigravityAuth","options","path","version","options","options","config","newConfig: ProxyConfig","process","commandBlock: string","apiKeyAuthMiddleware: MiddlewareHandler","pendingTokenUsage: TokenUsage | undefined","streamDoneResolve: ((value: void) => void) | undefined","path","model: string | undefined","start","state","ANTIGRAVITY_USER_AGENT","convertMessages","contents: Array<unknown>","systemInstruction: unknown","parts: Array<unknown>","GEMINI_ALLOWED_FIELDS","convertTypeValue","cleanProperties","cleanedProps: Record<string, unknown>","cleanJsonSchema","cleaned: Record<string, unknown>","convertTools","functionDeclarations: Array<unknown>","body: Record<string, unknown>","createErrorResponse","error: Record<string, unknown>","handleApiError","transformStreamResponse","transformNonStreamResponse","encoder","state","message: Record<string, unknown>","toolCalls: Array<unknown>","app","rateLimitTracker: Record<string, RateLimitInfo>","contents: Array<AntigravityContent>","systemInstruction: { parts: Array<{ text: string }> } | undefined","parts: Array<unknown>","cleanedProps: Record<string, unknown>","cleaned: Record<string, unknown>","functionDeclarations: Array<unknown>","innerRequest: Record<string, unknown>","result: Record<string, unknown>","MAX_RETRIES","parseRetryDelay","state","content: Array<unknown>","body: AnthropicMessageRequest","encoder","groups: Array<MessageGroup>","group: Array<Message>","state","x","lastError: unknown","response: Response | undefined","error: unknown","handleCompletion","isNonStreaming","handleCompletion","newMessages: Array<Message>","contentParts: Array<ContentPart>","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null","state","events: Array<AnthropicStreamEventData>","events","streamState: AnthropicStreamState","events","usage","MAX_RETRIES","DEFAULT_RETRY_DELAY","parseRetryDelay","body: ZenChatCompletionRequest","MAX_RETRIES","DEFAULT_RETRY_DELAY","parseRetryDelay","body: ZenMessageRequest","body: ZenResponsesRequest","options","getApiKey","getAntigravityModels","HTTPError","clearGithubToken","modelList: Array<{ id: string }> | undefined","apiKeys: Array<string> | undefined"],"sources":["../node_modules/dotenv/package.json","../node_modules/dotenv/lib/main.js","../node_modules/dotenv/lib/env-options.js","../node_modules/dotenv/lib/cli-options.js","../node_modules/dotenv/config.js","../src/lib/config.ts","../src/lib/proxy.ts","../src/antigravity.ts","../src/auth.ts","../src/services/github/get-copilot-usage.ts","../src/check-usage.ts","../src/debug.ts","../src/logout.ts","../src/proxy-config.ts","../src/lib/shell.ts","../src/lib/api-key-auth.ts","../src/lib/model-logger.ts","../src/services/antigravity/stream-parser.ts","../src/services/antigravity/create-chat-completions.ts","../src/routes/antigravity/chat-completions/route.ts","../src/lib/request-queue.ts","../src/services/antigravity/anthropic-events.ts","../src/services/antigravity/create-messages.ts","../src/routes/antigravity/messages/route.ts","../src/routes/antigravity/models/route.ts","../src/lib/approval.ts","../src/lib/tokenizer.ts","../src/lib/context-compression.ts","../src/lib/rate-limit.ts","../src/services/copilot/create-chat-completions.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/services/copilot/create-embeddings.ts","../src/routes/embeddings/route.ts","../src/routes/messages/utils.ts","../src/routes/messages/non-stream-translation.ts","../src/routes/messages/count-tokens-handler.ts","../src/routes/messages/stream-translation.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/services/zen/create-chat-completions.ts","../src/routes/zen/chat-completions/route.ts","../src/services/zen/create-messages.ts","../src/routes/zen/messages/route.ts","../src/routes/zen/models/route.ts","../src/services/zen/create-responses.ts","../src/routes/zen/responses/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"dotenv\",\n \"version\": \"17.2.3\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\n// Array of tips to display randomly\nconst TIPS = [\n '🔐 encrypt with Dotenvx: https://dotenvx.com',\n '🔐 prevent committing .env to code: https://dotenvx.com/precommit',\n '🔐 prevent building .env in docker: https://dotenvx.com/prebuild',\n '📡 add observability to secrets: https://dotenvx.com/ops',\n '👥 sync secrets across teammates & machines: https://dotenvx.com/ops',\n '🗂️ backup and recover secrets: https://dotenvx.com/ops',\n '✅ audit secrets and track compliance: https://dotenvx.com/ops',\n '🔄 add secrets lifecycle management: https://dotenvx.com/ops',\n '🔑 add access controls to secrets: https://dotenvx.com/ops',\n '🛠️ run anywhere with `dotenvx run -- yourcommand`',\n '⚙️ specify custom .env file path with { path: \\'/custom/path/.env\\' }',\n '⚙️ enable debug logging with { debug: true }',\n '⚙️ override existing env vars with { override: true }',\n '⚙️ suppress all logs with { quiet: true }',\n '⚙️ write to custom object with { processEnv: myObject }',\n '⚙️ load multiple .env files with { path: [\\'.env.local\\', \\'.env\\'] }'\n]\n\n// Get a random tip from the tips array\nfunction _getRandomTip () {\n return TIPS[Math.floor(Math.random() * TIPS.length)]\n}\n\nfunction parseBoolean (value) {\n if (typeof value === 'string') {\n return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())\n }\n return Boolean(value)\n}\n\nfunction supportsAnsi () {\n return process.stdout.isTTY // && process.env.TERM !== 'dumb'\n}\n\nfunction dim (text) {\n return supportsAnsi() ? `\\x1b[2m${text}\\x1b[0m` : text\n}\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.error(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))\n const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))\n let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n const populated = DotenvModule.populate(processEnv, parsedAll, options)\n\n // handle user settings DOTENV_CONFIG_ options inside .env file(s)\n debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)\n quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(populated).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')} ${dim(`-- tip: ${_getRandomTip()}`)}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n const populated = {}\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n populated[key] = parsed[key]\n }\n }\n\n return populated\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","// ../config.js accepts options via environment variables\nconst options = {}\n\nif (process.env.DOTENV_CONFIG_ENCODING != null) {\n options.encoding = process.env.DOTENV_CONFIG_ENCODING\n}\n\nif (process.env.DOTENV_CONFIG_PATH != null) {\n options.path = process.env.DOTENV_CONFIG_PATH\n}\n\nif (process.env.DOTENV_CONFIG_QUIET != null) {\n options.quiet = process.env.DOTENV_CONFIG_QUIET\n}\n\nif (process.env.DOTENV_CONFIG_DEBUG != null) {\n options.debug = process.env.DOTENV_CONFIG_DEBUG\n}\n\nif (process.env.DOTENV_CONFIG_OVERRIDE != null) {\n options.override = process.env.DOTENV_CONFIG_OVERRIDE\n}\n\nif (process.env.DOTENV_CONFIG_DOTENV_KEY != null) {\n options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY\n}\n\nmodule.exports = options\n","const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/\n\nmodule.exports = function optionMatcher (args) {\n const options = args.reduce(function (acc, cur) {\n const matches = cur.match(re)\n if (matches) {\n acc[matches[1]] = matches[2]\n }\n return acc\n }, {})\n\n if (!('quiet' in options)) {\n options.quiet = 'true'\n }\n\n return options\n}\n","(function () {\n require('./lib/main').config(\n Object.assign(\n {},\n require('./lib/env-options'),\n require('./lib/cli-options')(process.argv)\n )\n )\n})()\n","/**\n * Configuration file management\n * Handles persistent configuration storage for proxy settings and other options\n */\n\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport { PATHS } from \"./paths\"\n\nconst CONFIG_FILENAME = \"config.json\"\n\nexport interface ProxyConfig {\n enabled: boolean\n httpProxy?: string\n httpsProxy?: string\n noProxy?: string\n}\n\nexport interface AppConfig {\n proxy?: ProxyConfig\n}\n\n/**\n * Get the path to the config file\n */\nexport function getConfigPath(): string {\n return path.join(PATHS.DATA_DIR, CONFIG_FILENAME)\n}\n\n/**\n * Load configuration from file\n */\nexport async function loadConfig(): Promise<AppConfig> {\n try {\n const configPath = getConfigPath()\n const content = await fs.readFile(configPath)\n // Buffer can be passed to JSON.parse directly (better performance)\n return JSON.parse(content as unknown as string) as AppConfig\n } catch {\n return {}\n }\n}\n\n/**\n * Save configuration to file\n */\nexport async function saveConfig(config: AppConfig): Promise<void> {\n const configPath = getConfigPath()\n await fs.writeFile(configPath, JSON.stringify(config, null, 2), \"utf8\")\n consola.debug(`Configuration saved to ${configPath}`)\n}\n\n/**\n * Get proxy configuration\n */\nexport async function getProxyConfig(): Promise<ProxyConfig | undefined> {\n const config = await loadConfig()\n return config.proxy\n}\n\n/**\n * Save proxy configuration\n */\nexport async function saveProxyConfig(proxyConfig: ProxyConfig): Promise<void> {\n const config = await loadConfig()\n config.proxy = proxyConfig\n await saveConfig(config)\n}\n\n/**\n * Clear proxy configuration\n */\nexport async function clearProxyConfig(): Promise<void> {\n const config = await loadConfig()\n delete config.proxy\n await saveConfig(config)\n}\n\n/**\n * Apply saved proxy configuration to environment variables\n * This should be called at startup to restore proxy settings\n */\nexport async function applyProxyConfig(): Promise<boolean> {\n const proxyConfig = await getProxyConfig()\n\n if (!proxyConfig || !proxyConfig.enabled) {\n return false\n }\n\n if (proxyConfig.httpProxy) {\n process.env.HTTP_PROXY = proxyConfig.httpProxy\n process.env.http_proxy = proxyConfig.httpProxy\n }\n\n if (proxyConfig.httpsProxy) {\n process.env.HTTPS_PROXY = proxyConfig.httpsProxy\n process.env.https_proxy = proxyConfig.httpsProxy\n }\n\n if (proxyConfig.noProxy) {\n process.env.NO_PROXY = proxyConfig.noProxy\n process.env.no_proxy = proxyConfig.noProxy\n }\n\n consola.info(\"Proxy configuration loaded from saved settings\")\n if (proxyConfig.httpProxy) {\n consola.info(` HTTP_PROXY: ${proxyConfig.httpProxy}`)\n }\n if (proxyConfig.httpsProxy) {\n consola.info(` HTTPS_PROXY: ${proxyConfig.httpsProxy}`)\n }\n if (proxyConfig.noProxy) {\n consola.info(` NO_PROXY: ${proxyConfig.noProxy}`)\n }\n\n return true\n}\n","import consola from \"consola\"\nimport { getProxyForUrl } from \"proxy-from-env\"\nimport { Agent, ProxyAgent, setGlobalDispatcher, type Dispatcher } from \"undici\"\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== \"undefined\") return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin =\n typeof options.origin === \"string\" ?\n new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n } catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n } catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug(\"HTTP proxy configured from environment (per-URL)\")\n } catch (err) {\n consola.debug(\"Proxy setup skipped:\", err)\n }\n}\n","#!/usr/bin/env node\n\nimport \"dotenv/config\"\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { applyProxyConfig } from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\n\n/**\n * Add a new Antigravity account via OAuth\n */\nasync function addAccount(): Promise<void> {\n const { setupAntigravity, loadAntigravityAuth } = await import(\n \"~/services/antigravity/auth\"\n )\n\n const existingAuth = await loadAntigravityAuth()\n if (existingAuth && existingAuth.accounts.length > 0) {\n const enabledCount = existingAuth.accounts.filter((a) => a.enable).length\n consola.info(\n `Found ${existingAuth.accounts.length} existing accounts (${enabledCount} enabled)`,\n )\n }\n\n await setupAntigravity()\n}\n\n/**\n * List all Antigravity accounts\n */\nasync function listAccounts(): Promise<void> {\n const { loadAntigravityAuth } = await import(\"~/services/antigravity/auth\")\n\n const auth = await loadAntigravityAuth()\n\n if (!auth || auth.accounts.length === 0) {\n consola.info(\"No Antigravity accounts configured\")\n return\n }\n\n consola.info(`\\nAntigravity Accounts (${auth.accounts.length} total):`)\n consola.info(\"=\".repeat(50))\n\n for (let i = 0; i < auth.accounts.length; i++) {\n const account = auth.accounts[i]\n const isCurrent = i === auth.currentIndex\n const status = account.enable ? \"enabled\" : \"disabled\"\n const marker = isCurrent ? \"→ \" : \" \"\n const projectId = account.project_id || \"unknown\"\n\n consola.info(\n `${marker}[${i}] Project: ${projectId} | Status: ${status}${isCurrent ? \" (current)\" : \"\"}`,\n )\n }\n}\n\n/**\n * Remove an Antigravity account by index\n */\nasync function removeAccount(index: number): Promise<void> {\n const { loadAntigravityAuth, saveAntigravityAuth } = await import(\n \"~/services/antigravity/auth\"\n )\n\n const auth = await loadAntigravityAuth()\n\n if (!auth || auth.accounts.length === 0) {\n consola.error(\"No Antigravity accounts configured\")\n return\n }\n\n if (index < 0 || index >= auth.accounts.length) {\n consola.error(\n `Invalid index. Must be between 0 and ${auth.accounts.length - 1}`,\n )\n return\n }\n\n const removed = auth.accounts.splice(index, 1)[0]\n\n // Adjust current index if needed\n if (auth.currentIndex >= auth.accounts.length) {\n auth.currentIndex = Math.max(0, auth.accounts.length - 1)\n }\n\n await saveAntigravityAuth(auth)\n consola.success(\n `Removed account ${index} (Project: ${removed.project_id || \"unknown\"})`,\n )\n}\n\n/**\n * Clear all Antigravity accounts\n */\nasync function clearAccounts(): Promise<void> {\n const { clearAntigravityAuth } = await import(\"~/services/antigravity/auth\")\n\n const confirm = await consola.prompt(\n \"Are you sure you want to remove all Antigravity accounts?\",\n { type: \"confirm\", initial: false },\n )\n\n if (confirm) {\n await clearAntigravityAuth()\n }\n}\n\nexport const antigravity = defineCommand({\n meta: {\n name: \"antigravity\",\n description: \"Manage Google Antigravity accounts\",\n },\n subCommands: {\n add: defineCommand({\n meta: {\n name: \"add\",\n description: \"Add a new Antigravity account via OAuth\",\n },\n async run() {\n await ensurePaths()\n const savedProxyApplied = await applyProxyConfig()\n if (savedProxyApplied) {\n initProxyFromEnv()\n }\n await addAccount()\n },\n }),\n list: defineCommand({\n meta: {\n name: \"list\",\n description: \"List all Antigravity accounts\",\n },\n async run() {\n await ensurePaths()\n await listAccounts()\n },\n }),\n remove: defineCommand({\n meta: {\n name: \"remove\",\n description: \"Remove an Antigravity account by index\",\n },\n args: {\n index: {\n type: \"positional\",\n description: \"Account index to remove (use 'list' to see indexes)\",\n required: true,\n },\n },\n async run({ args }) {\n await ensurePaths()\n const indexStr = String(args.index)\n const index = Number.parseInt(indexStr, 10)\n if (Number.isNaN(index)) {\n consola.error(\"Index must be a number\")\n return\n }\n await removeAccount(index)\n },\n }),\n clear: defineCommand({\n meta: {\n name: \"clear\",\n description: \"Remove all Antigravity accounts\",\n },\n async run() {\n await ensurePaths()\n await clearAccounts()\n },\n }),\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (): Promise<CopilotUsageResponse> => {\n const response = await fetch(`${GITHUB_API_BASE_URL}/copilot_internal/user`, {\n headers: githubHeaders(state),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\n\nimport { getProxyConfig, type ProxyConfig } from \"./lib/config\"\nimport { PATHS } from \"./lib/paths\"\nimport { getAntigravityAuthPath } from \"./services/antigravity/auth\"\nimport { getZenAuthPath } from \"./services/zen/auth\"\n\ninterface DebugInfo {\n version: string\n runtime: {\n name: string\n version: string\n platform: string\n arch: string\n }\n paths: {\n APP_DIR: string\n GITHUB_TOKEN_PATH: string\n ZEN_AUTH_PATH: string\n ANTIGRAVITY_AUTH_PATH: string\n }\n credentials: {\n github: boolean\n zen: boolean\n antigravity: boolean\n }\n proxy?: ProxyConfig\n}\n\ninterface RunDebugOptions {\n json: boolean\n}\n\nasync function getPackageVersion(): Promise<string> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url).pathname\n // @ts-expect-error https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v59.0.1/docs/rules/prefer-json-parse-buffer.md\n // JSON.parse() can actually parse buffers\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath)) as {\n version: string\n }\n return packageJson.version\n } catch {\n return \"unknown\"\n }\n}\n\nfunction getRuntimeInfo() {\n const isBun = typeof Bun !== \"undefined\"\n\n return {\n name: isBun ? \"bun\" : \"node\",\n version: isBun ? Bun.version : process.version.slice(1),\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nasync function checkTokenExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.GITHUB_TOKEN_PATH)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function checkFileExists(path: string): Promise<boolean> {\n try {\n const stats = await fs.stat(path)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(path, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const zenAuthPath = getZenAuthPath()\n const antigravityAuthPath = getAntigravityAuthPath()\n\n const [version, githubExists, zenExists, antigravityExists, proxyConfig] =\n await Promise.all([\n getPackageVersion(),\n checkTokenExists(),\n checkFileExists(zenAuthPath),\n checkFileExists(antigravityAuthPath),\n getProxyConfig(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,\n ZEN_AUTH_PATH: zenAuthPath,\n ANTIGRAVITY_AUTH_PATH: antigravityAuthPath,\n },\n credentials: {\n github: githubExists,\n zen: zenExists,\n antigravity: antigravityExists,\n },\n proxy: proxyConfig,\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n let proxyStatus = \"Not configured\"\n if (info.proxy) {\n proxyStatus =\n info.proxy.enabled ?\n `Enabled (${info.proxy.httpProxy || info.proxy.httpsProxy})`\n : \"Disabled\"\n }\n\n consola.info(`copilot-api-plus debug\n\nVersion: ${info.version}\nRuntime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})\n\nPaths:\n APP_DIR: ${info.paths.APP_DIR}\n GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}\n ZEN_AUTH_PATH: ${info.paths.ZEN_AUTH_PATH}\n ANTIGRAVITY_AUTH_PATH: ${info.paths.ANTIGRAVITY_AUTH_PATH}\n\nCredentials:\n GitHub Copilot: ${info.credentials.github ? \"✅ Configured\" : \"❌ Not configured\"}\n OpenCode Zen: ${info.credentials.zen ? \"✅ Configured\" : \"❌ Not configured\"}\n Google Antigravity: ${info.credentials.antigravity ? \"✅ Configured\" : \"❌ Not configured\"}\n\nProxy: ${proxyStatus}`)\n}\n\nfunction printDebugInfoJson(info: DebugInfo): void {\n console.log(JSON.stringify(info, null, 2))\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n printDebugInfoJson(debugInfo)\n } else {\n printDebugInfoPlain(debugInfo)\n }\n}\n\nexport const debug = defineCommand({\n meta: {\n name: \"debug\",\n description: \"Print debug information about the application\",\n },\n args: {\n json: {\n type: \"boolean\",\n default: false,\n description: \"Output debug information as JSON\",\n },\n },\n run({ args }) {\n return runDebug({\n json: args.json,\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths, PATHS } from \"./lib/paths\"\nimport { clearGithubToken } from \"./lib/token\"\nimport {\n clearAntigravityAuth,\n getAntigravityAuthPath,\n} from \"./services/antigravity/auth\"\nimport { clearZenAuth, getZenAuthPath } from \"./services/zen/auth\"\n\nexport async function runLogout(options: {\n github?: boolean\n zen?: boolean\n antigravity?: boolean\n all?: boolean\n}): Promise<void> {\n await ensurePaths()\n\n if (options.all) {\n // Clear all credentials\n await clearGithubToken()\n await clearZenAuth()\n await clearAntigravityAuth()\n consola.success(\"Logged out from all services\")\n consola.info(`GitHub token: ${PATHS.GITHUB_TOKEN_PATH}`)\n consola.info(`Zen API key: ${getZenAuthPath()}`)\n consola.info(`Antigravity accounts: ${getAntigravityAuthPath()}`)\n return\n }\n\n if (options.github) {\n // Clear only GitHub token\n await clearGithubToken()\n consola.success(\"Logged out from GitHub Copilot\")\n consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`)\n return\n }\n\n if (options.zen) {\n // Clear only Zen API key\n await clearZenAuth()\n consola.success(\"Logged out from OpenCode Zen\")\n consola.info(`Zen API key location: ${getZenAuthPath()}`)\n return\n }\n\n if (options.antigravity) {\n // Clear only Antigravity accounts\n await clearAntigravityAuth()\n consola.success(\"Logged out from Google Antigravity\")\n consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`)\n return\n }\n\n // Default: show interactive prompt\n const choice = await consola.prompt(\n \"Which credentials do you want to clear?\",\n {\n type: \"select\",\n options: [\n \"GitHub Copilot token\",\n \"OpenCode Zen API key\",\n \"Google Antigravity accounts\",\n \"All credentials\",\n ],\n },\n )\n\n switch (choice) {\n case \"GitHub Copilot token\": {\n await clearGithubToken()\n consola.success(\"Logged out from GitHub Copilot\")\n consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`)\n\n break\n }\n case \"OpenCode Zen API key\": {\n await clearZenAuth()\n consola.success(\"Logged out from OpenCode Zen\")\n consola.info(`Zen API key location: ${getZenAuthPath()}`)\n\n break\n }\n case \"Google Antigravity accounts\": {\n await clearAntigravityAuth()\n consola.success(\"Logged out from Google Antigravity\")\n consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`)\n\n break\n }\n case \"All credentials\": {\n await clearGithubToken()\n await clearZenAuth()\n await clearAntigravityAuth()\n consola.success(\"Logged out from all services\")\n\n break\n }\n // No default\n }\n}\n\nexport const logout = defineCommand({\n meta: {\n name: \"logout\",\n description: \"Clear stored credentials and logout\",\n },\n args: {\n github: {\n alias: \"g\",\n type: \"boolean\",\n default: false,\n description: \"Clear only GitHub Copilot token\",\n },\n zen: {\n alias: \"z\",\n type: \"boolean\",\n default: false,\n description: \"Clear only OpenCode Zen API key\",\n },\n antigravity: {\n type: \"boolean\",\n default: false,\n description: \"Clear only Google Antigravity accounts\",\n },\n all: {\n alias: \"a\",\n type: \"boolean\",\n default: false,\n description: \"Clear all credentials (GitHub, Zen, and Antigravity)\",\n },\n },\n run({ args }) {\n return runLogout({\n github: args.github,\n zen: args.zen,\n antigravity: args.antigravity,\n all: args.all,\n })\n },\n})\n","/**\n * Proxy configuration command\n * Allows users to configure, enable, disable, and view proxy settings\n */\n\n/* eslint-disable max-lines-per-function */\n/* eslint-disable complexity */\n\nimport * as p from \"@clack/prompts\"\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n clearProxyConfig,\n getProxyConfig,\n saveProxyConfig,\n type ProxyConfig,\n} from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\n\nexport const proxy = defineCommand({\n meta: {\n name: \"proxy\",\n description: \"Configure proxy settings (persistent)\",\n },\n args: {\n set: {\n type: \"boolean\",\n default: false,\n description: \"Set proxy configuration interactively\",\n },\n enable: {\n type: \"boolean\",\n default: false,\n description: \"Enable saved proxy configuration\",\n },\n disable: {\n type: \"boolean\",\n default: false,\n description: \"Disable proxy (keep settings)\",\n },\n clear: {\n type: \"boolean\",\n default: false,\n description: \"Clear all proxy settings\",\n },\n show: {\n type: \"boolean\",\n default: false,\n description: \"Show current proxy configuration\",\n },\n \"http-proxy\": {\n type: \"string\",\n description: \"HTTP proxy URL (e.g., http://proxy:8080)\",\n },\n \"https-proxy\": {\n type: \"string\",\n description: \"HTTPS proxy URL (e.g., http://proxy:8080)\",\n },\n \"no-proxy\": {\n type: \"string\",\n description: \"Comma-separated list of hosts to bypass proxy\",\n },\n },\n async run({ args }) {\n await ensurePaths()\n\n // Show current configuration\n if (\n args.show\n || (!args.set\n && !args.enable\n && !args.disable\n && !args.clear\n && !args[\"http-proxy\"]\n && !args[\"https-proxy\"])\n ) {\n const config = await getProxyConfig()\n if (!config) {\n consola.info(\"No proxy configuration saved.\")\n consola.info(\"\")\n consola.info(\"To configure proxy, use one of:\")\n consola.info(\n \" copilot-api-plus proxy --set # Interactive setup\",\n )\n consola.info(\n \" copilot-api-plus proxy --http-proxy http://proxy:8080 # Direct set\",\n )\n return\n }\n\n consola.info(\"Current proxy configuration:\")\n consola.info(` Status: ${config.enabled ? \"✅ Enabled\" : \"❌ Disabled\"}`)\n if (config.httpProxy) {\n consola.info(` HTTP_PROXY: ${config.httpProxy}`)\n }\n if (config.httpsProxy) {\n consola.info(` HTTPS_PROXY: ${config.httpsProxy}`)\n }\n if (config.noProxy) {\n consola.info(` NO_PROXY: ${config.noProxy}`)\n }\n return\n }\n\n // Clear proxy settings\n if (args.clear) {\n await clearProxyConfig()\n consola.success(\"Proxy configuration cleared.\")\n return\n }\n\n // Enable proxy\n if (args.enable) {\n const config = await getProxyConfig()\n if (!config) {\n consola.error(\n \"No proxy configuration saved. Use --set to configure first.\",\n )\n return\n }\n config.enabled = true\n await saveProxyConfig(config)\n consola.success(\"Proxy enabled. It will be used on next server start.\")\n return\n }\n\n // Disable proxy\n if (args.disable) {\n const config = await getProxyConfig()\n if (!config) {\n consola.info(\"No proxy configuration to disable.\")\n return\n }\n config.enabled = false\n await saveProxyConfig(config)\n consola.success(\"Proxy disabled. Settings are preserved.\")\n return\n }\n\n // Direct set via command line args\n if (args[\"http-proxy\"] || args[\"https-proxy\"]) {\n const newConfig: ProxyConfig = {\n enabled: true,\n httpProxy: args[\"http-proxy\"],\n httpsProxy: args[\"https-proxy\"] || args[\"http-proxy\"], // Use HTTP proxy for HTTPS if not specified\n noProxy: args[\"no-proxy\"],\n }\n await saveProxyConfig(newConfig)\n consola.success(\"Proxy configuration saved and enabled.\")\n consola.info(` HTTP_PROXY: ${newConfig.httpProxy || \"(not set)\"}`)\n consola.info(` HTTPS_PROXY: ${newConfig.httpsProxy || \"(not set)\"}`)\n if (newConfig.noProxy) {\n consola.info(` NO_PROXY: ${newConfig.noProxy}`)\n }\n return\n }\n\n // Interactive setup\n if (args.set) {\n p.intro(\"Proxy Configuration\")\n\n const existingConfig = await getProxyConfig()\n\n const httpProxy = await p.text({\n message: \"HTTP Proxy URL\",\n placeholder: \"http://proxy:8080\",\n initialValue: existingConfig?.httpProxy || \"\",\n })\n\n if (p.isCancel(httpProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const httpsProxy = await p.text({\n message: \"HTTPS Proxy URL (leave empty to use HTTP proxy)\",\n placeholder: \"http://proxy:8080\",\n initialValue: existingConfig?.httpsProxy || \"\",\n })\n\n if (p.isCancel(httpsProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const noProxy = await p.text({\n message: \"No Proxy (comma-separated hosts to bypass)\",\n placeholder: \"localhost,127.0.0.1,.local\",\n initialValue: existingConfig?.noProxy || \"\",\n })\n\n if (p.isCancel(noProxy)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const enable = await p.confirm({\n message: \"Enable proxy now?\",\n initialValue: true,\n })\n\n if (p.isCancel(enable)) {\n p.cancel(\"Configuration cancelled.\")\n return\n }\n\n const newConfig: ProxyConfig = {\n enabled: enable,\n httpProxy: httpProxy || undefined,\n httpsProxy: httpsProxy || httpProxy || undefined,\n noProxy: noProxy || undefined,\n }\n\n await saveProxyConfig(newConfig)\n\n p.outro(`Proxy configuration saved${enable ? \" and enabled\" : \"\"}.`)\n }\n },\n})\n","import { execSync } from \"node:child_process\"\nimport process from \"node:process\"\n\ntype ShellName = \"bash\" | \"zsh\" | \"fish\" | \"powershell\" | \"cmd\" | \"sh\"\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === \"win32\") {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: \"pipe\" }).toString()\n\n if (parentProcess.toLowerCase().includes(\"powershell.exe\")) {\n return \"powershell\"\n }\n } catch {\n return \"cmd\"\n }\n\n return \"cmd\"\n } else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith(\"zsh\")) return \"zsh\"\n if (shellPath.endsWith(\"fish\")) return \"fish\"\n if (shellPath.endsWith(\"bash\")) return \"bash\"\n }\n\n return \"sh\"\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = \"\",\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case \"powershell\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join(\"; \")\n break\n }\n case \"cmd\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(\" & \")\n break\n }\n case \"fish\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join(\"; \")\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \")\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : \"\"\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === \"cmd\" ? \" & \" : \" && \"\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from \"hono\"\n\nimport { HTTPException } from \"hono/http-exception\"\n\nimport { state } from \"./state\"\n\n/**\n * Retrieve an API key from the incoming request.\n *\n * Checks common locations where clients supply keys (Authorization Bearer header, `x-api-key` header, or `apiKey` query parameter) and returns the first one found.\n *\n * @returns The extracted API key, or `undefined` if no key is present.\n */\nfunction extractApiKey(c: Context): string | undefined {\n // OpenAI format: Authorization header with Bearer prefix\n const authHeader = c.req.header(\"authorization\")\n if (authHeader?.startsWith(\"Bearer \")) {\n return authHeader.slice(7) // Remove 'Bearer ' prefix\n }\n\n // Anthropic format: x-api-key header\n const anthropicKey = c.req.header(\"x-api-key\")\n if (anthropicKey) {\n return anthropicKey\n }\n\n // Fallback: query parameter, for extra compatibility of `/usage` or `/token` route\n const queryKey = c.req.query(\"apiKey\")\n if (queryKey) {\n return queryKey\n }\n\n return undefined\n}\n\n/**\n * API key authentication middleware\n * Validates that the request contains a valid API key if API keys are configured\n */\nexport const apiKeyAuthMiddleware: MiddlewareHandler = async (c, next) => {\n // If no API keys are configured, skip authentication\n if (!state.apiKeys || state.apiKeys.length === 0) {\n await next()\n return\n }\n\n const providedKey = extractApiKey(c)\n\n // If no API key is provided, return 401\n if (!providedKey) {\n throw new HTTPException(401, {\n message:\n \"API key required. Please provide a valid API key in the Authorization header (Bearer token) or x-api-key header.\",\n })\n }\n\n // Check if the provided key matches any of the configured keys\n const isValidKey = state.apiKeys.includes(providedKey)\n\n if (!isValidKey) {\n throw new HTTPException(401, {\n message: \"Invalid API key. Please provide a valid API key.\",\n })\n }\n\n // Key is valid, continue with the request\n await next()\n}\n","/**\n * Custom logger middleware that displays model name before timestamp\n */\n\nimport type { Context, MiddlewareHandler, Next } from \"hono\"\n\n/**\n * Global token usage store for passing usage info from handlers to logger.\n * Handlers call setTokenUsage() when usage is available,\n * logger reads and clears it after await next().\n *\n * For streaming responses, usage arrives after next() returns.\n * In that case the handler calls signalStreamDone() when the stream ends,\n * and the logger waits for it with a timeout.\n */\nlet pendingTokenUsage: TokenUsage | undefined\n\n// eslint-disable-next-line @typescript-eslint/no-invalid-void-type\nlet streamDoneResolve: ((value: void) => void) | undefined\n\nexport interface TokenUsage {\n inputTokens: number\n outputTokens: number\n cacheReadTokens?: number\n cacheCreationTokens?: number\n}\n\nexport function setTokenUsage(usage: TokenUsage): void {\n pendingTokenUsage = usage\n}\n\n/**\n * Notify the logger that a streaming response has finished sending.\n * Must be called at the end of streamSSE callbacks.\n */\nexport function signalStreamDone(): void {\n streamDoneResolve?.()\n}\n\n/**\n * Get timestamp string in format HH:mm:ss\n */\nfunction getTime(): string {\n return new Date().toLocaleTimeString(\"en-US\", { hour12: false })\n}\n\n/**\n * Format duration in human readable format\n */\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`\n return `${(ms / 1000).toFixed(1)}s`\n}\n\n/**\n * Format token usage for log output\n */\nexport function formatTokenUsage(usage: TokenUsage): string {\n const parts = [`in:${usage.inputTokens}`, `out:${usage.outputTokens}`]\n if (usage.cacheReadTokens) {\n parts.push(`cache_read:${usage.cacheReadTokens}`)\n }\n if (usage.cacheCreationTokens) {\n parts.push(`cache_create:${usage.cacheCreationTokens}`)\n }\n return parts.join(\" \")\n}\n\n/**\n * Extract model name from request body\n */\nasync function extractModel(c: Context): Promise<string | undefined> {\n try {\n // Clone the request to avoid consuming the body\n const clonedReq = c.req.raw.clone()\n const body = (await clonedReq.json()) as { model?: string }\n return body.model\n } catch {\n return undefined\n }\n}\n\n/**\n * Custom logger middleware that shows model name before timestamp\n *\n * Output format:\n * [model] HH:mm:ss <-- METHOD /path\n * [model] HH:mm:ss --> METHOD /path STATUS DURATION [in:N out:N]\n */\nexport function modelLogger(): MiddlewareHandler {\n return async (c: Context, next: Next) => {\n const method = c.req.method\n const path = c.req.path\n const queryString =\n c.req.raw.url.includes(\"?\") ? `?${c.req.raw.url.split(\"?\")[1]}` : \"\"\n const fullPath = `${path}${queryString}`\n\n // Extract model for POST requests with JSON body\n let model: string | undefined\n if (method === \"POST\" && c.req.header(\"content-type\")?.includes(\"json\")) {\n model = await extractModel(c)\n }\n\n const modelPrefix = model ? `[${model}] ` : \"\"\n const startTime = getTime()\n\n // Clear any stale state before handling\n pendingTokenUsage = undefined\n const localStreamDone = new Promise<void>((resolve) => {\n streamDoneResolve = resolve\n })\n\n // Log incoming request\n console.log(`${modelPrefix}${startTime} <-- ${method} ${fullPath}`)\n\n const start = Date.now()\n await next()\n\n // For streaming responses, usage arrives after next() returns.\n // Wait for signalStreamDone() with a generous timeout.\n const isStreaming = c.res.headers\n .get(\"content-type\")\n ?.includes(\"text/event-stream\")\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (isStreaming && !pendingTokenUsage) {\n const timeout = new Promise<void>((resolve) =>\n setTimeout(resolve, 120_000),\n )\n await Promise.race([localStreamDone, timeout])\n }\n\n const duration = Date.now() - start\n const endTime = getTime()\n\n // Read and clear token usage\n const usage = pendingTokenUsage\n pendingTokenUsage = undefined\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n const usageSuffix = usage ? ` [${formatTokenUsage(usage)}]` : \"\"\n\n // Log outgoing response\n console.log(\n `${modelPrefix}${endTime} --> ${method} ${fullPath} ${c.res.status} ${formatDuration(duration)}${usageSuffix}`,\n )\n }\n}\n","/**\n * Antigravity Stream Parser\n *\n * Parses SSE stream responses from Antigravity API and emits events.\n * Extracted for better code organization and reduced complexity.\n */\n\n/** Parsed part from Antigravity response */\nexport interface AntigravityPart {\n text?: string\n thought?: boolean\n functionCall?: {\n name: string\n args: unknown\n }\n}\n\n/** Parsed candidate from Antigravity response */\nexport interface AntigravityCandidate {\n content?: {\n parts?: Array<AntigravityPart>\n }\n finishReason?: string\n}\n\n/** Usage metadata from Antigravity response */\nexport interface AntigravityUsage {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n}\n\n/** Parsed Antigravity SSE data */\nexport interface AntigravityData {\n response?: {\n candidates?: Array<AntigravityCandidate>\n usageMetadata?: AntigravityUsage\n }\n candidates?: Array<AntigravityCandidate>\n usageMetadata?: AntigravityUsage\n}\n\n/** Stream state for tracking parsing progress */\nexport interface StreamState {\n buffer: string\n inputTokens: number\n outputTokens: number\n contentBlockIndex: number\n thinkingBlockStarted: boolean\n textBlockStarted: boolean\n}\n\n/** Events emitted during stream parsing */\nexport type StreamEvent =\n | { type: \"thinking_start\"; index: number }\n | { type: \"thinking_delta\"; index: number; text: string }\n | { type: \"thinking_stop\"; index: number }\n | { type: \"text_start\"; index: number }\n | { type: \"text_delta\"; index: number; text: string }\n | { type: \"text_stop\"; index: number }\n | { type: \"tool_use\"; index: number; name: string; args: unknown }\n | { type: \"usage\"; inputTokens: number; outputTokens: number }\n | { type: \"finish\"; stopReason: string }\n\n/**\n * Create initial stream state\n */\nexport function createStreamState(): StreamState {\n return {\n buffer: \"\",\n inputTokens: 0,\n outputTokens: 0,\n contentBlockIndex: 0,\n thinkingBlockStarted: false,\n textBlockStarted: false,\n }\n}\n\n/**\n * Parse a single SSE line and return the JSON data if valid\n */\nexport function parseSSELine(line: string): AntigravityData | null {\n if (!line.startsWith(\"data: \")) {\n return null\n }\n\n const data = line.slice(6).trim()\n if (data === \"[DONE]\" || data === \"\") {\n return null\n }\n\n try {\n return JSON.parse(data) as AntigravityData\n } catch {\n return null\n }\n}\n\n/**\n * Extract candidates and usage from parsed data\n */\nexport function extractFromData(data: AntigravityData): {\n candidates: Array<AntigravityCandidate>\n usage: AntigravityUsage | undefined\n} {\n const candidates = data.response?.candidates || data.candidates || []\n const usage = data.response?.usageMetadata || data.usageMetadata\n return { candidates, usage }\n}\n\n/**\n * Process a single part and emit events\n */\nexport function processPart(\n part: AntigravityPart,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Handle thinking content\n if (part.thought && part.text) {\n processThinkingPart(part.text, state, emit)\n return\n }\n\n // Handle regular text content\n if (part.text && !part.thought) {\n processTextPart(part.text, state, emit)\n return\n }\n\n // Handle function calls\n if (part.functionCall) {\n processToolPart(part.functionCall, state, emit)\n }\n}\n\n/**\n * Process thinking content\n */\nfunction processThinkingPart(\n text: string,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n if (!state.thinkingBlockStarted) {\n emit({ type: \"thinking_start\", index: state.contentBlockIndex })\n state.thinkingBlockStarted = true\n }\n emit({ type: \"thinking_delta\", index: state.contentBlockIndex, text })\n}\n\n/**\n * Process text content\n */\nfunction processTextPart(\n text: string,\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Close thinking block if open\n if (state.thinkingBlockStarted && !state.textBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.thinkingBlockStarted = false\n }\n\n // Start text block if not started\n if (!state.textBlockStarted) {\n emit({ type: \"text_start\", index: state.contentBlockIndex })\n state.textBlockStarted = true\n }\n\n emit({ type: \"text_delta\", index: state.contentBlockIndex, text })\n}\n\n/**\n * Process tool/function call\n */\nfunction processToolPart(\n functionCall: { name: string; args: unknown },\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n // Close previous block if open\n if (state.textBlockStarted) {\n emit({ type: \"text_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.textBlockStarted = false\n } else if (state.thinkingBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.contentBlockIndex++\n state.thinkingBlockStarted = false\n }\n\n emit({\n type: \"tool_use\",\n index: state.contentBlockIndex,\n name: functionCall.name,\n args: functionCall.args,\n })\n state.contentBlockIndex++\n}\n\n/**\n * Handle finish reason and close open blocks\n */\nexport function handleFinish(\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): void {\n if (state.textBlockStarted) {\n emit({ type: \"text_stop\", index: state.contentBlockIndex })\n state.textBlockStarted = false\n } else if (state.thinkingBlockStarted) {\n emit({ type: \"thinking_stop\", index: state.contentBlockIndex })\n state.thinkingBlockStarted = false\n }\n\n emit({\n type: \"usage\",\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n })\n emit({ type: \"finish\", stopReason: \"end_turn\" })\n}\n\n/**\n * Process chunk and update buffer, returning complete lines\n */\nexport function processChunk(chunk: string, state: StreamState): Array<string> {\n state.buffer += chunk\n const lines = state.buffer.split(\"\\n\")\n state.buffer = lines.pop() || \"\"\n return lines\n}\n","/**\n * Google Antigravity Chat Completions\n *\n * Proxy chat completion requests to Google Antigravity API or standard Gemini API.\n * Supports two authentication methods:\n * - API Key: Uses standard Gemini API (generativelanguage.googleapis.com)\n * - OAuth: Uses Antigravity private API (daily-cloudcode-pa.sandbox.googleapis.com)\n *\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n/* eslint-disable @typescript-eslint/no-redundant-type-constituents */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n\nimport consola from \"consola\"\n\nimport {\n disableCurrentAccount,\n getApiKey,\n getValidAccessToken,\n rotateAccount,\n} from \"./auth\"\nimport { isThinkingModel } from \"./get-models\"\nimport {\n createStreamState,\n extractFromData,\n parseSSELine,\n processChunk,\n type AntigravityPart,\n type StreamState,\n} from \"./stream-parser\"\n\n// Antigravity API endpoints (OAuth authentication)\n// Note: Claude models also use the same generateContent endpoint, not rawPredict\n// The API accepts Claude model names (e.g., claude-sonnet-4-5) but uses Gemini-style format\nconst ANTIGRAVITY_API_HOST = \"daily-cloudcode-pa.sandbox.googleapis.com\"\nconst ANTIGRAVITY_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:streamGenerateContent?alt=sse`\nconst ANTIGRAVITY_NO_STREAM_URL = `https://${ANTIGRAVITY_API_HOST}/v1internal:generateContent`\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\n// Standard Gemini API endpoints (API Key authentication)\nconst GEMINI_API_HOST = \"generativelanguage.googleapis.com\"\nconst getGeminiStreamUrl = (model: string, apiKey: string) =>\n `https://${GEMINI_API_HOST}/v1beta/models/${model}:streamGenerateContent?alt=sse&key=${apiKey}`\nconst getGeminiNoStreamUrl = (model: string, apiKey: string) =>\n `https://${GEMINI_API_HOST}/v1beta/models/${model}:generateContent?key=${apiKey}`\n\nexport interface ChatMessage {\n role: \"system\" | \"user\" | \"assistant\"\n content:\n | string\n | Array<{ type: string; text?: string; image_url?: { url: string } }>\n}\n\nexport interface ChatCompletionRequest {\n model: string\n messages: Array<ChatMessage>\n stream?: boolean\n temperature?: number\n max_tokens?: number\n top_p?: number\n top_k?: number\n tools?: Array<unknown>\n}\n\ninterface ConvertedContent {\n contents: Array<unknown>\n systemInstruction?: unknown\n}\n\n/**\n * Convert OpenAI format messages to Antigravity format\n */\nfunction convertMessages(messages: Array<ChatMessage>): ConvertedContent {\n const contents: Array<unknown> = []\n let systemInstruction: unknown\n\n for (const message of messages) {\n if (message.role === \"system\") {\n systemInstruction = buildSystemInstruction(message.content)\n continue\n }\n\n const role = message.role === \"assistant\" ? \"model\" : \"user\"\n const parts = buildMessageParts(message.content)\n contents.push({ role, parts })\n }\n\n return { contents, systemInstruction }\n}\n\n/**\n * Build system instruction from content\n */\nfunction buildSystemInstruction(content: ChatMessage[\"content\"]): {\n parts: Array<{ text: string }>\n} {\n const text =\n typeof content === \"string\" ? content : (\n content.map((c) => c.text || \"\").join(\"\")\n )\n // Antigravity format: parts is an array of Part objects with text field\n return { parts: [{ text }] }\n}\n\n/**\n * Build message parts from content\n */\nfunction buildMessageParts(content: ChatMessage[\"content\"]): Array<unknown> {\n if (typeof content === \"string\") {\n return [{ text: content }]\n }\n\n const parts: Array<unknown> = []\n for (const part of content) {\n if (part.type === \"text\") {\n parts.push({ text: part.text })\n } else if (part.type === \"image_url\" && part.image_url?.url) {\n const imageData = parseBase64Image(part.image_url.url)\n if (imageData) parts.push({ inlineData: imageData })\n }\n }\n return parts\n}\n\n/**\n * Parse base64 image URL\n */\nfunction parseBase64Image(\n url: string,\n): { mimeType: string; data: string } | null {\n if (!url.startsWith(\"data:\")) return null\n const match = url.match(/^data:([^;]+);base64,(.+)$/)\n if (!match) return null\n return { mimeType: match[1], data: match[2] }\n}\n\n// Allowlisted fields for Gemini API Schema\nconst GEMINI_ALLOWED_FIELDS = new Set([\n \"type\",\n \"description\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"nullable\",\n])\n\n/**\n * Convert type value to Gemini format\n * Handles both string and array types (for nullable)\n */\nfunction convertTypeValue(\n value: unknown,\n): { type: string; nullable?: boolean } | null {\n if (typeof value === \"string\") {\n return { type: value.toUpperCase() }\n }\n if (Array.isArray(value)) {\n const nonNullType = value.find(\n (t): t is string => typeof t === \"string\" && t !== \"null\",\n )\n if (nonNullType) {\n return { type: nonNullType.toUpperCase(), nullable: true }\n }\n }\n return null\n}\n\n/**\n * Clean properties object recursively\n */\nfunction cleanProperties(\n props: Record<string, unknown>,\n): Record<string, unknown> {\n const cleanedProps: Record<string, unknown> = {}\n for (const [propKey, propValue] of Object.entries(props)) {\n cleanedProps[propKey] = cleanJsonSchema(propValue)\n }\n return cleanedProps\n}\n\n/**\n * Clean and convert JSON schema to Gemini format\n * - Removes unsupported fields like $schema, additionalProperties\n * - Converts type values to uppercase (string -> STRING)\n * - Ensures properties format is correct for Google API\n */\nfunction cleanJsonSchema(schema: unknown): unknown {\n if (!schema || typeof schema !== \"object\") return schema\n if (Array.isArray(schema)) {\n return schema.map((item) => cleanJsonSchema(item))\n }\n\n const obj = schema as Record<string, unknown>\n const cleaned: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n if (!GEMINI_ALLOWED_FIELDS.has(key)) continue\n\n if (key === \"type\") {\n const result = convertTypeValue(value)\n if (result) {\n cleaned.type = result.type\n if (result.nullable) cleaned.nullable = true\n }\n } else if (key === \"properties\" && typeof value === \"object\" && value) {\n cleaned.properties = cleanProperties(value as Record<string, unknown>)\n } else if (typeof value === \"object\" && value !== null) {\n cleaned[key] = cleanJsonSchema(value)\n } else {\n cleaned[key] = value\n }\n }\n\n return cleaned\n}\n\n/**\n * Convert tools to Antigravity format\n * All tools should be in a single object with functionDeclarations array\n */\nfunction convertTools(tools?: Array<unknown>): Array<unknown> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const functionDeclarations: Array<unknown> = []\n\n for (const tool of tools) {\n const t = tool as {\n type: string\n function?: { name: string; description?: string; parameters?: unknown }\n }\n if (t.type === \"function\" && t.function) {\n functionDeclarations.push({\n name: t.function.name,\n description: t.function.description || \"\",\n parameters: cleanJsonSchema(t.function.parameters) || {},\n })\n }\n }\n\n if (functionDeclarations.length === 0) return undefined\n\n // Return as a single object with all function declarations\n return [{ functionDeclarations }]\n}\n\n/**\n * Build standard Gemini API request body (for API Key authentication)\n */\nfunction buildStandardGeminiRequestBody(\n request: ChatCompletionRequest,\n): Record<string, unknown> {\n const { contents, systemInstruction } = convertMessages(request.messages)\n const tools = convertTools(request.tools)\n\n const body: Record<string, unknown> = {\n contents,\n generationConfig: {\n temperature: request.temperature ?? 1,\n topP: request.top_p ?? 0.85,\n topK: request.top_k ?? 50,\n maxOutputTokens: request.max_tokens ?? 8096,\n },\n }\n\n if (systemInstruction) body.systemInstruction = systemInstruction\n if (tools) body.tools = tools\n\n if (isThinkingModel(request.model)) {\n body.generationConfig = {\n ...(body.generationConfig as Record<string, unknown>),\n thinkingConfig: { includeThoughts: true },\n }\n }\n\n return body\n}\n\n/**\n * Build Antigravity request body\n * The Antigravity API expects a specific nested structure with request object\n */\nfunction buildAntigravityRequestBody(\n request: ChatCompletionRequest,\n): Record<string, unknown> {\n const innerRequest = buildStandardGeminiRequestBody(request)\n\n // Wrap in the Antigravity request structure\n return {\n model: request.model,\n userAgent: \"antigravity\",\n requestId: `agent-${crypto.randomUUID()}`,\n request: innerRequest,\n }\n}\n\n/**\n * Create error response\n */\nfunction createErrorResponse(\n message: string,\n type: string,\n status: number,\n details?: string,\n): Response {\n const error: Record<string, unknown> = { message, type }\n if (details) error.details = details\n return new Response(JSON.stringify({ error }), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Create chat completion with Antigravity or standard Gemini API\n * Priority: API Key > OAuth\n */\nexport async function createAntigravityChatCompletion(\n request: ChatCompletionRequest,\n): Promise<Response> {\n // Try API Key authentication first (simplest)\n const apiKey = getApiKey()\n if (apiKey) {\n return await createWithApiKey(request, apiKey)\n }\n\n // Fall back to OAuth authentication\n const accessToken = await getValidAccessToken()\n if (!accessToken) {\n return createErrorResponse(\n \"No valid authentication available. Please set GEMINI_API_KEY environment variable or run OAuth login.\",\n \"auth_error\",\n 401,\n )\n }\n\n return await createWithOAuth(request, accessToken)\n}\n\n/**\n * Create chat completion using API Key (standard Gemini API)\n */\nasync function createWithApiKey(\n request: ChatCompletionRequest,\n apiKey: string,\n): Promise<Response> {\n const endpoint =\n request.stream ?\n getGeminiStreamUrl(request.model, apiKey)\n : getGeminiNoStreamUrl(request.model, apiKey)\n const body = buildStandardGeminiRequestBody(request)\n\n consola.debug(`Gemini API request with model ${request.model}`)\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return await handleApiError(response)\n }\n\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n } catch (error) {\n consola.error(\"Gemini API request error:\", error)\n return createErrorResponse(\n `Request failed: ${String(error)}`,\n \"request_error\",\n 500,\n )\n }\n}\n\n/**\n * Create chat completion using OAuth (Antigravity private API)\n * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format\n */\nasync function createWithOAuth(\n request: ChatCompletionRequest,\n accessToken: string,\n): Promise<Response> {\n const endpoint =\n request.stream ? ANTIGRAVITY_STREAM_URL : ANTIGRAVITY_NO_STREAM_URL\n const body = buildAntigravityRequestBody(request)\n\n consola.debug(\n `Antigravity request to ${endpoint} with model ${request.model}`,\n )\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Host: ANTIGRAVITY_API_HOST,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n return await handleApiError(response)\n }\n\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n } catch (error) {\n consola.error(\"Antigravity request error:\", error)\n return createErrorResponse(\n `Request failed: ${String(error)}`,\n \"request_error\",\n 500,\n )\n }\n}\n\n/**\n * Handle API error response\n */\nasync function handleApiError(response: Response): Promise<Response> {\n const errorText = await response.text()\n consola.error(`Antigravity error: ${response.status} ${errorText}`)\n\n if (response.status === 403) await disableCurrentAccount()\n if (response.status === 429 || response.status === 503) await rotateAccount()\n\n return createErrorResponse(\n `Antigravity API error: ${response.status}`,\n \"api_error\",\n response.status,\n errorText,\n )\n}\n\n/**\n * Generate request ID\n */\nfunction generateRequestId(): string {\n return `chatcmpl-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Transform Antigravity stream response to OpenAI format\n */\nfunction transformStreamResponse(response: Response, model: string): Response {\n const reader = response.body?.getReader()\n if (!reader) return new Response(\"No response body\", { status: 500 })\n\n const encoder = new TextEncoder()\n const decoder = new TextDecoder()\n const requestId = generateRequestId()\n\n const stream = new ReadableStream({\n async start(controller) {\n const state = createStreamState()\n\n try {\n await processOpenAIStream(\n reader as ReadableStreamDefaultReader<Uint8Array>,\n decoder,\n state,\n controller,\n encoder,\n requestId,\n model,\n )\n controller.enqueue(encoder.encode(\"data: [DONE]\\n\\n\"))\n controller.close()\n } catch (error) {\n consola.error(\"Stream transform error:\", error)\n controller.error(error)\n }\n },\n })\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n })\n}\n\n/**\n * Process stream and emit OpenAI format chunks\n */\nasync function processOpenAIStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n decoder: TextDecoder,\n state: StreamState,\n controller: ReadableStreamDefaultController<Uint8Array>,\n encoder: TextEncoder,\n requestId: string,\n model: string,\n): Promise<void> {\n while (true) {\n const { done, value } = await reader.read()\n if (done) break\n\n const chunk = decoder.decode(value, { stream: true })\n const lines = processChunk(chunk, state)\n\n for (const line of lines) {\n const data = parseSSELine(line)\n if (!data) continue\n\n const { candidates } = extractFromData(data)\n const candidate = candidates[0]\n const parts = candidate?.content?.parts ?? []\n\n for (const part of parts) {\n const chunkData = buildOpenAIChunk(\n part,\n requestId,\n model,\n candidate?.finishReason,\n )\n if (chunkData) {\n controller.enqueue(\n encoder.encode(`data: ${JSON.stringify(chunkData)}\\n\\n`),\n )\n }\n }\n }\n }\n}\n\n/**\n * Build OpenAI format chunk from part\n */\nfunction buildOpenAIChunk(\n part: AntigravityPart,\n requestId: string,\n model: string,\n finishReason?: string,\n): unknown | null {\n const baseChunk = {\n id: requestId,\n object: \"chat.completion.chunk\",\n created: Math.floor(Date.now() / 1000),\n model,\n }\n\n // Handle thinking content\n if (part.thought && part.text) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: { reasoning_content: part.text },\n finish_reason: null,\n },\n ],\n }\n }\n\n // Handle regular text\n if (part.text && !part.thought) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: { content: part.text },\n finish_reason: finishReason === \"STOP\" ? \"stop\" : null,\n },\n ],\n }\n }\n\n // Handle function calls\n if (part.functionCall) {\n return {\n ...baseChunk,\n choices: [\n {\n index: 0,\n delta: {\n tool_calls: [\n {\n index: 0,\n id: `call_${Date.now()}`,\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: JSON.stringify(part.functionCall.args),\n },\n },\n ],\n },\n finish_reason: null,\n },\n ],\n }\n }\n\n return null\n}\n\n/**\n * Transform Antigravity non-stream response to OpenAI format\n */\nasync function transformNonStreamResponse(\n response: Response,\n model: string,\n): Promise<Response> {\n interface AntigravityResponseData {\n candidates?: Array<{\n content?: { parts?: Array<AntigravityPart> }\n finishReason?: string\n }>\n usageMetadata?: {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n }\n }\n\n interface NonStreamData {\n response?: AntigravityResponseData\n candidates?: Array<{\n content?: { parts?: Array<AntigravityPart> }\n finishReason?: string\n }>\n usageMetadata?: {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n }\n }\n\n const rawData = (await response.json()) as NonStreamData\n\n // Handle nested response structure (Antigravity wraps response in a \"response\" object)\n const data = rawData.response ?? rawData\n const candidate = data.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const { content, reasoningContent, toolCalls } =\n extractNonStreamContent(parts)\n\n const message: Record<string, unknown> = {\n role: \"assistant\",\n content: content || null,\n }\n if (reasoningContent) message.reasoning_content = reasoningContent\n if (toolCalls.length > 0) message.tool_calls = toolCalls\n\n const openaiResponse = {\n id: generateRequestId(),\n object: \"chat.completion\",\n created: Math.floor(Date.now() / 1000),\n model,\n choices: [{ index: 0, message, finish_reason: \"stop\" }],\n usage: {\n prompt_tokens: data.usageMetadata?.promptTokenCount ?? 0,\n completion_tokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n total_tokens: data.usageMetadata?.totalTokenCount ?? 0,\n },\n }\n\n return new Response(JSON.stringify(openaiResponse), {\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Extract content from non-stream response parts\n */\nfunction extractNonStreamContent(parts: Array<AntigravityPart>): {\n content: string\n reasoningContent: string\n toolCalls: Array<unknown>\n} {\n let content = \"\"\n let reasoningContent = \"\"\n const toolCalls: Array<unknown> = []\n\n for (const part of parts) {\n if (part.thought && part.text) {\n reasoningContent += part.text\n } else if (part.text) {\n content += part.text\n }\n\n if (part.functionCall) {\n toolCalls.push({\n id: `call_${Date.now()}`,\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: JSON.stringify(part.functionCall.args),\n },\n })\n }\n }\n\n return { content, reasoningContent, toolCalls }\n}\n","/**\n * Antigravity Chat Completions Route\n *\n * OpenAI-compatible chat completions endpoint for Antigravity.\n */\n\nimport { Hono } from \"hono\"\n\nimport {\n createAntigravityChatCompletion,\n type ChatCompletionRequest,\n} from \"~/services/antigravity/create-chat-completions\"\n\nconst app = new Hono()\n\napp.post(\"/\", async (c) => {\n const body = await c.req.json<ChatCompletionRequest>()\n\n const response = await createAntigravityChatCompletion(body)\n\n // Copy response headers\n const headers = new Headers(response.headers)\n\n if (body.stream) {\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n return new Response(await response.text(), {\n status: response.status,\n headers,\n })\n})\n\nexport const antigravityChatCompletionsRoute = app\n","/**\n * Request Queue with Concurrency Limit\n *\n * Limits concurrent requests to prevent rate limiting.\n * Allows configurable number of concurrent requests.\n */\n\ntype QueuedRequest<T> = {\n execute: () => Promise<T>\n resolve: (value: T) => void\n reject: (error: unknown) => void\n}\n\nexport class RequestQueue {\n private queue: Array<QueuedRequest<unknown>> = []\n private activeCount = 0\n private maxConcurrent: number\n private minDelayMs: number\n private lastRequestTime = 0\n\n constructor(maxConcurrent = 2, minDelayMs = 300) {\n this.maxConcurrent = maxConcurrent\n this.minDelayMs = minDelayMs\n }\n\n async enqueue<T>(execute: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.queue.push({\n execute: execute as () => Promise<unknown>,\n resolve: resolve as (value: unknown) => void,\n reject,\n })\n void this.processQueue()\n })\n }\n\n private async processQueue(): Promise<void> {\n if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {\n return\n }\n\n const request = this.queue.shift()\n if (!request) return\n\n this.activeCount++\n\n // Ensure minimum delay between requests\n const now = Date.now()\n const elapsed = now - this.lastRequestTime\n if (elapsed < this.minDelayMs) {\n await new Promise((r) => setTimeout(r, this.minDelayMs - elapsed))\n }\n this.lastRequestTime = Date.now()\n\n try {\n const result = await request.execute()\n request.resolve(result)\n } catch (error) {\n request.reject(error)\n } finally {\n this.activeCount--\n void this.processQueue()\n }\n }\n}\n\n// Allow 2 concurrent requests with 500ms minimum gap\nexport const antigravityQueue = new RequestQueue(2, 500)\n","/**\n * Anthropic SSE Event Builder\n *\n * Builds Anthropic-compatible SSE events for streaming responses.\n * Extracted for better code organization and reusability.\n */\n\nconst encoder = new TextEncoder()\n\n/**\n * Create message_start event\n */\nexport function createMessageStart(\n messageId: string,\n model: string,\n): Uint8Array {\n const event = {\n type: \"message_start\",\n message: {\n id: messageId,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: 0,\n output_tokens: 0,\n },\n },\n }\n return encoder.encode(\n `event: message_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create message_stop event\n */\nexport function createMessageStop(): Uint8Array {\n const event = { type: \"message_stop\" }\n return encoder.encode(\n `event: message_stop\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for thinking\n */\nexport function createThinkingBlockStart(index: number): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"thinking\",\n thinking: \"\",\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for thinking\n */\nexport function createThinkingDelta(index: number, text: string): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"thinking_delta\",\n thinking: text,\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for text\n */\nexport function createTextBlockStart(index: number): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for text\n */\nexport function createTextDelta(index: number, text: string): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"text_delta\",\n text,\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_stop event\n */\nexport function createBlockStop(index: number): Uint8Array {\n const event = {\n type: \"content_block_stop\",\n index,\n }\n return encoder.encode(\n `event: content_block_stop\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_start event for tool_use\n */\nexport function createToolBlockStart(\n index: number,\n toolId: string,\n name: string,\n): Uint8Array {\n const event = {\n type: \"content_block_start\",\n index,\n content_block: {\n type: \"tool_use\",\n id: toolId,\n name,\n input: {},\n },\n }\n return encoder.encode(\n `event: content_block_start\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create content_block_delta event for tool input\n */\nexport function createToolDelta(index: number, args: unknown): Uint8Array {\n const event = {\n type: \"content_block_delta\",\n index,\n delta: {\n type: \"input_json_delta\",\n partial_json: JSON.stringify(args),\n },\n }\n return encoder.encode(\n `event: content_block_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Create message_delta event with stop reason and usage\n */\nexport function createMessageDelta(\n stopReason: string,\n outputTokens: number,\n): Uint8Array {\n const event = {\n type: \"message_delta\",\n delta: {\n stop_reason: stopReason,\n stop_sequence: null,\n },\n usage: {\n output_tokens: outputTokens,\n },\n }\n return encoder.encode(\n `event: message_delta\\ndata: ${JSON.stringify(event)}\\n\\n`,\n )\n}\n\n/**\n * Generate a unique message ID\n */\nexport function generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`\n}\n\n/**\n * Generate a unique tool ID\n */\nexport function generateToolId(): string {\n return `toolu_${Date.now()}`\n}\n","/**\n * Google Antigravity Messages API\n *\n * Converts Anthropic Messages API format to Antigravity format.\n * This enables Claude Code to use Antigravity as backend.\n *\n * Based on: https://github.com/liuw1535/antigravity2api-nodejs\n */\n\n/* eslint-disable max-params */\n/* eslint-disable @typescript-eslint/no-unnecessary-condition */\n/* eslint-disable default-case */\n\nimport consola from \"consola\"\n\nimport { antigravityQueue } from \"../../lib/request-queue\"\nimport { sleep } from \"../../lib/utils\"\nimport {\n createBlockStop,\n createMessageDelta,\n createMessageStart,\n createMessageStop,\n createTextBlockStart,\n createTextDelta,\n createThinkingBlockStart,\n createThinkingDelta,\n createToolBlockStart,\n createToolDelta,\n generateMessageId,\n generateToolId,\n} from \"./anthropic-events\"\nimport {\n disableCurrentAccount,\n getCurrentProjectId,\n getValidAccessToken,\n rotateAccount,\n} from \"./auth\"\nimport { isThinkingModel } from \"./get-models\"\nimport {\n createStreamState,\n extractFromData,\n handleFinish,\n parseSSELine,\n processChunk,\n processPart,\n type StreamEvent,\n type StreamState,\n} from \"./stream-parser\"\n\n// Antigravity API endpoints with fallback support\n// Note: Claude models also use the same generateContent endpoint, not rawPredict\n// The API accepts Claude model names but uses Gemini-style format\nconst ANTIGRAVITY_ENDPOINTS = [\n \"daily-cloudcode-pa.sandbox.googleapis.com\", // Daily (Sandbox) - Primary\n \"cloudcode-pa.googleapis.com\", // Production - Fallback\n] as const\n\n// Current endpoint index for fallback rotation\nlet currentEndpointIndex = 0\n\nfunction getStreamUrl(host: string): string {\n return `https://${host}/v1internal:streamGenerateContent?alt=sse`\n}\n\nfunction getNoStreamUrl(host: string): string {\n return `https://${host}/v1internal:generateContent`\n}\n\nfunction getCurrentHost(): string {\n return ANTIGRAVITY_ENDPOINTS[currentEndpointIndex]\n}\n\nfunction rotateEndpoint(): void {\n const oldIndex = currentEndpointIndex\n currentEndpointIndex =\n (currentEndpointIndex + 1) % ANTIGRAVITY_ENDPOINTS.length\n consola.info(\n `Rotating endpoint: ${ANTIGRAVITY_ENDPOINTS[oldIndex]} → ${ANTIGRAVITY_ENDPOINTS[currentEndpointIndex]}`,\n )\n}\n\nconst ANTIGRAVITY_USER_AGENT = \"antigravity/1.11.3 windows/amd64\"\n\n// Rate limit tracking per model family\ninterface RateLimitInfo {\n lastLimitTime: number\n consecutiveErrors: number\n}\n\nconst rateLimitTracker: Record<string, RateLimitInfo> = {}\n\nfunction getModelFamily(model: string): string {\n if (model.includes(\"claude\")) return \"claude\"\n if (model.includes(\"gemini\")) return \"gemini\"\n return \"other\"\n}\n\nfunction trackRateLimit(model: string): void {\n const family = getModelFamily(model)\n if (!rateLimitTracker[family]) {\n rateLimitTracker[family] = { lastLimitTime: 0, consecutiveErrors: 0 }\n }\n rateLimitTracker[family].lastLimitTime = Date.now()\n rateLimitTracker[family].consecutiveErrors++\n}\n\nfunction clearRateLimitTracker(model: string): void {\n const family = getModelFamily(model)\n if (rateLimitTracker[family]) {\n rateLimitTracker[family].consecutiveErrors = 0\n }\n}\n\nfunction getBackoffDelay(model: string, baseDelay: number): number {\n const family = getModelFamily(model)\n const info = rateLimitTracker[family]\n if (!info) return baseDelay\n\n // Exponential backoff: base * 2^(consecutive-1), max 30s\n const multiplier = Math.min(Math.pow(2, info.consecutiveErrors - 1), 60)\n return Math.min(baseDelay * multiplier, 30000)\n}\n\nexport interface AnthropicMessage {\n role: \"user\" | \"assistant\"\n content:\n | string\n | Array<{\n type: string\n text?: string\n source?: { type: string; media_type: string; data: string }\n }>\n}\n\nexport interface AnthropicMessageRequest {\n model: string\n messages: Array<AnthropicMessage>\n system?:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>\n max_tokens: number\n stream?: boolean\n temperature?: number\n top_p?: number\n top_k?: number\n tools?: Array<unknown>\n}\n\ninterface AntigravityContent {\n role: string\n parts: Array<unknown> | { text: string }\n}\n\ninterface ConvertedMessages {\n contents: Array<AntigravityContent>\n systemInstruction?: { parts: Array<{ text: string }> }\n}\n\n/**\n * Extract text from system content (can be string or array)\n */\nfunction extractSystemText(\n system:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>,\n): string {\n if (typeof system === \"string\") {\n return system\n }\n // Extract text from array of content blocks\n return system\n .filter((block) => block.type === \"text\" && block.text)\n .map((block) => block.text)\n .join(\"\\n\\n\")\n}\n\n/**\n * Convert Anthropic messages to Antigravity format\n */\nfunction convertMessages(\n messages: Array<AnthropicMessage>,\n system?:\n | string\n | Array<{ type: string; text?: string; cache_control?: unknown }>,\n): ConvertedMessages {\n const contents: Array<AntigravityContent> = []\n let systemInstruction: { parts: Array<{ text: string }> } | undefined\n\n if (system) {\n const systemText = extractSystemText(system)\n if (systemText) {\n // Antigravity format: parts is an array of Part objects with text field\n systemInstruction = { parts: [{ text: systemText }] }\n }\n }\n\n for (const message of messages) {\n const role = message.role === \"assistant\" ? \"model\" : \"user\"\n const parts = buildParts(message.content)\n if (parts.length > 0) {\n contents.push({ role, parts })\n }\n }\n\n return { contents, systemInstruction }\n}\n\n/**\n * Build parts array from message content\n */\nfunction buildParts(content: AnthropicMessage[\"content\"]): Array<unknown> {\n if (typeof content === \"string\") {\n return [{ text: content }]\n }\n\n const parts: Array<unknown> = []\n for (const block of content) {\n if (block.type === \"text\" && block.text) {\n parts.push({ text: block.text })\n } else if (block.type === \"image\" && block.source) {\n parts.push({\n inlineData: {\n mimeType: block.source.media_type,\n data: block.source.data,\n },\n })\n }\n }\n return parts\n}\n\n// Allowlisted fields for Gemini API Schema\nconst GEMINI_ALLOWED_FIELDS = new Set([\n \"type\",\n \"description\",\n \"properties\",\n \"required\",\n \"items\",\n \"enum\",\n \"nullable\",\n])\n\n/**\n * Convert type value to Gemini format\n * Handles both string and array types (for nullable)\n */\nfunction convertTypeValue(\n value: unknown,\n): { type: string; nullable?: boolean } | null {\n if (typeof value === \"string\") {\n return { type: value.toUpperCase() }\n }\n if (Array.isArray(value)) {\n const nonNullType = value.find(\n (t): t is string => typeof t === \"string\" && t !== \"null\",\n )\n if (nonNullType) {\n return { type: nonNullType.toUpperCase(), nullable: true }\n }\n }\n return null\n}\n\n/**\n * Clean properties object recursively\n */\nfunction cleanProperties(\n props: Record<string, unknown>,\n): Record<string, unknown> {\n const cleanedProps: Record<string, unknown> = {}\n for (const [propKey, propValue] of Object.entries(props)) {\n cleanedProps[propKey] = cleanJsonSchema(propValue)\n }\n return cleanedProps\n}\n\n/**\n * Clean and convert JSON schema to Gemini format\n * - Removes unsupported fields like $schema, additionalProperties\n * - Converts type values to uppercase (string -> STRING)\n * - Ensures properties format is correct for Google API\n */\nfunction cleanJsonSchema(schema: unknown): unknown {\n if (!schema || typeof schema !== \"object\") return schema\n if (Array.isArray(schema)) {\n return schema.map((item) => cleanJsonSchema(item))\n }\n\n const obj = schema as Record<string, unknown>\n const cleaned: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n if (!GEMINI_ALLOWED_FIELDS.has(key)) continue\n\n if (key === \"type\") {\n const result = convertTypeValue(value)\n if (result) {\n cleaned.type = result.type\n if (result.nullable) cleaned.nullable = true\n }\n } else if (key === \"properties\" && typeof value === \"object\" && value) {\n cleaned.properties = cleanProperties(value as Record<string, unknown>)\n } else if (typeof value === \"object\" && value !== null) {\n cleaned[key] = cleanJsonSchema(value)\n } else {\n cleaned[key] = value\n }\n }\n\n return cleaned\n}\n\n/**\n * Convert tools to Antigravity format\n * All tools should be in a single object with functionDeclarations array\n */\nfunction convertTools(tools?: Array<unknown>): Array<unknown> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const functionDeclarations: Array<unknown> = []\n\n for (const tool of tools) {\n const t = tool as {\n name: string\n description?: string\n input_schema?: unknown\n }\n functionDeclarations.push({\n name: t.name,\n description: t.description || \"\",\n parameters: cleanJsonSchema(t.input_schema) || {},\n })\n }\n\n // Return as a single object with all function declarations\n return [{ functionDeclarations }]\n}\n\n/**\n * Build Antigravity request body\n * The Antigravity API expects a specific nested structure with request object\n */\nfunction buildGeminiRequest(\n request: AnthropicMessageRequest,\n projectId?: string | null,\n): Record<string, unknown> {\n const { contents, systemInstruction } = convertMessages(\n request.messages,\n request.system,\n )\n const tools = convertTools(request.tools)\n\n // Build the inner request object\n const innerRequest: Record<string, unknown> = {\n contents,\n generationConfig: {\n temperature: request.temperature ?? 1,\n topP: request.top_p ?? 0.85,\n topK: request.top_k ?? 50,\n maxOutputTokens: request.max_tokens ?? 8096,\n },\n }\n\n if (systemInstruction) innerRequest.systemInstruction = systemInstruction\n if (tools) innerRequest.tools = tools\n\n if (isThinkingModel(request.model)) {\n innerRequest.generationConfig = {\n ...(innerRequest.generationConfig as Record<string, unknown>),\n thinkingConfig: { includeThoughts: true },\n }\n }\n\n // Wrap in the Antigravity request structure\n const result: Record<string, unknown> = {\n model: request.model,\n userAgent: \"antigravity\",\n requestId: `agent-${crypto.randomUUID()}`,\n request: innerRequest,\n }\n\n // Add project ID if available (required by some endpoints)\n if (projectId) {\n result.project = projectId\n }\n\n return result\n}\n\n/**\n * Create error response\n */\nfunction createErrorResponse(\n type: string,\n message: string,\n status: number,\n): Response {\n return new Response(\n JSON.stringify({ type: \"error\", error: { type, message } }),\n { status, headers: { \"Content-Type\": \"application/json\" } },\n )\n}\n\n/**\n * Create Anthropic-compatible message response using Antigravity\n * Note: Both Gemini and Claude models use the same endpoint and Gemini-style format\n *\n * Features:\n * - Endpoint fallback (daily → prod)\n * - Per-model-family rate limit tracking\n * - Exponential backoff for consecutive errors\n * - Smart retry for short delays (≤5s on same endpoint)\n */\nconst MAX_RETRIES = 5\nconst MAX_ENDPOINT_RETRIES = 2 // Try each endpoint up to 2 times before switching\n\nasync function executeAntigravityRequest(\n request: AnthropicMessageRequest,\n): Promise<Response> {\n // Get project ID for the request\n const projectId = await getCurrentProjectId()\n const body = buildGeminiRequest(request, projectId)\n let endpointRetries = 0\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const host = getCurrentHost()\n const endpoint = request.stream ? getStreamUrl(host) : getNoStreamUrl(host)\n\n const accessToken = await getValidAccessToken()\n\n if (!accessToken) {\n return createErrorResponse(\n \"authentication_error\",\n \"No valid Antigravity access token available.\",\n 401,\n )\n }\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n Host: host,\n \"User-Agent\": ANTIGRAVITY_USER_AGENT,\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n \"Accept-Encoding\": \"gzip\",\n },\n body: JSON.stringify(body),\n })\n\n if (response.ok) {\n // Success - clear rate limit tracker for this model family\n clearRateLimitTracker(request.model)\n return request.stream ?\n transformStreamResponse(response, request.model)\n : await transformNonStreamResponse(response, request.model)\n }\n\n const errorResult = await handleApiError(response, request.model)\n\n if (errorResult.shouldRetry && attempt < MAX_RETRIES) {\n // Track rate limit for exponential backoff\n trackRateLimit(request.model)\n\n // Calculate delay with backoff\n const backoffDelay = getBackoffDelay(\n request.model,\n errorResult.retryDelayMs,\n )\n\n // If delay is short (≤5s), retry on same endpoint\n // Otherwise, try switching endpoint\n if (backoffDelay <= 5000 || endpointRetries >= MAX_ENDPOINT_RETRIES) {\n consola.info(\n `Rate limited, retrying in ${backoffDelay}ms (attempt ${attempt + 1}/${MAX_RETRIES})`,\n )\n await sleep(backoffDelay)\n } else {\n // Try switching endpoint\n rotateEndpoint()\n endpointRetries++\n consola.info(\n `Switching endpoint, retrying in ${errorResult.retryDelayMs}ms`,\n )\n await sleep(errorResult.retryDelayMs)\n }\n continue\n }\n\n return errorResult.response\n } catch (error) {\n consola.error(\"Antigravity request error:\", error)\n if (attempt < MAX_RETRIES) {\n // On network error, try switching endpoint\n if (endpointRetries < MAX_ENDPOINT_RETRIES) {\n rotateEndpoint()\n endpointRetries++\n }\n await sleep(500)\n continue\n }\n return createErrorResponse(\n \"api_error\",\n `Request failed: ${String(error)}`,\n 500,\n )\n }\n }\n\n return createErrorResponse(\"api_error\", \"Max retries exceeded\", 429)\n}\n\nexport async function createAntigravityMessages(\n request: AnthropicMessageRequest,\n): Promise<Response> {\n return antigravityQueue.enqueue(() => executeAntigravityRequest(request))\n}\n\ninterface ApiErrorResult {\n shouldRetry: boolean\n retryDelayMs: number\n response: Response\n}\n\n/**\n * Parse retry delay from error response\n * Supports multiple formats:\n * - RetryInfo.retryDelay: \"3.5s\"\n * - quotaResetDelay: \"3000ms\" or \"3s\"\n * - message: \"Your quota will reset after 3s\"\n */\nfunction parseRetryDelay(errorText: string): number {\n try {\n const errorData = JSON.parse(errorText) as {\n error?: {\n message?: string\n details?: Array<{\n \"@type\"?: string\n retryDelay?: string\n quotaResetDelay?: string\n }>\n }\n }\n\n // Check details array first\n const details = errorData.error?.details ?? []\n for (const detail of details) {\n // Check RetryInfo first\n if (detail[\"@type\"]?.includes(\"RetryInfo\") && detail.retryDelay) {\n const match = /(\\d+(?:\\.\\d+)?)s/.exec(detail.retryDelay)\n if (match) return Math.ceil(Number.parseFloat(match[1]) * 1000)\n }\n // Check quotaResetDelay\n if (detail.quotaResetDelay) {\n const match = /(\\d+(?:\\.\\d+)?)(?:ms|s)/.exec(detail.quotaResetDelay)\n if (match) {\n const value = Number.parseFloat(match[1])\n return detail.quotaResetDelay.includes(\"ms\") ?\n Math.ceil(value)\n : Math.ceil(value * 1000)\n }\n }\n }\n\n // Check message for \"Your quota will reset after Xs\" pattern\n const message = errorData.error?.message ?? \"\"\n const resetMatch = /quota will reset after (\\d+(?:\\.\\d+)?)s/i.exec(message)\n if (resetMatch) {\n return Math.ceil(Number.parseFloat(resetMatch[1]) * 1000)\n }\n } catch {\n // Ignore parse errors\n }\n return 500 // Default 500ms retry delay\n}\n\n/**\n * Handle API error response\n */\nasync function handleApiError(\n response: Response,\n _model?: string,\n): Promise<ApiErrorResult> {\n const errorText = await response.text()\n consola.error(`Antigravity error: ${response.status} ${errorText}`)\n\n if (response.status === 403) {\n await disableCurrentAccount()\n }\n\n // Handle rate limit errors with retry\n if (response.status === 429 || response.status === 503) {\n await rotateAccount()\n const retryDelayMs = parseRetryDelay(errorText)\n return {\n shouldRetry: true,\n retryDelayMs,\n response: createErrorResponse(\n \"api_error\",\n `Antigravity API error: ${response.status}`,\n response.status,\n ),\n }\n }\n\n return {\n shouldRetry: false,\n retryDelayMs: 0,\n response: createErrorResponse(\n \"api_error\",\n `Antigravity API error: ${response.status}`,\n response.status,\n ),\n }\n}\n\n/**\n * Emit SSE event to controller based on stream event type\n */\nfunction emitSSEEvent(\n event: StreamEvent,\n controller: ReadableStreamDefaultController<Uint8Array>,\n state: StreamState,\n): void {\n switch (event.type) {\n case \"thinking_start\": {\n controller.enqueue(createThinkingBlockStart(event.index))\n break\n }\n case \"thinking_delta\": {\n controller.enqueue(createThinkingDelta(event.index, event.text))\n break\n }\n case \"thinking_stop\": {\n controller.enqueue(createBlockStop(event.index))\n break\n }\n case \"text_start\": {\n controller.enqueue(createTextBlockStart(event.index))\n break\n }\n case \"text_delta\": {\n controller.enqueue(createTextDelta(event.index, event.text))\n break\n }\n case \"text_stop\": {\n controller.enqueue(createBlockStop(event.index))\n break\n }\n case \"tool_use\": {\n emitToolUseEvents(event, controller)\n break\n }\n case \"usage\": {\n state.inputTokens = event.inputTokens\n state.outputTokens = event.outputTokens\n break\n }\n case \"finish\": {\n controller.enqueue(\n createMessageDelta(event.stopReason, state.outputTokens),\n )\n break\n }\n // No default needed - all cases are handled by the StreamEvent union type\n }\n}\n\n/**\n * Emit tool use events\n */\nfunction emitToolUseEvents(\n event: { type: \"tool_use\"; index: number; name: string; args: unknown },\n controller: ReadableStreamDefaultController<Uint8Array>,\n): void {\n const toolId = generateToolId()\n controller.enqueue(createToolBlockStart(event.index, toolId, event.name))\n controller.enqueue(createToolDelta(event.index, event.args))\n controller.enqueue(createBlockStop(event.index))\n}\n\n/**\n * Transform Antigravity stream response to Anthropic format\n */\nfunction transformStreamResponse(response: Response, model: string): Response {\n const reader = response.body?.getReader()\n if (!reader) {\n return new Response(\"No response body\", { status: 500 })\n }\n\n const decoder = new TextDecoder()\n const messageId = generateMessageId()\n\n const stream = new ReadableStream<Uint8Array>({\n async start(controller) {\n const state = createStreamState()\n controller.enqueue(createMessageStart(messageId, model))\n\n try {\n await processStream(\n reader as ReadableStreamDefaultReader<Uint8Array>,\n decoder,\n state,\n controller,\n )\n controller.enqueue(createMessageStop())\n controller.close()\n } catch (error) {\n consola.error(\"Stream transform error:\", error)\n controller.error(error)\n }\n },\n })\n\n return new Response(stream, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n },\n })\n}\n\n/**\n * Process candidate parts and handle finish\n */\nfunction processCandidate(\n candidate: { finishReason?: string; content?: { parts?: Array<unknown> } },\n state: StreamState,\n emit: (event: StreamEvent) => void,\n): boolean {\n const parts = (candidate?.content?.parts ?? []) as Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>\n\n for (const part of parts) {\n processPart(part, state, emit)\n }\n\n if (candidate?.finishReason === \"STOP\") {\n handleFinish(state, emit)\n return true\n }\n return false\n}\n\n/**\n * Process the stream and emit events\n */\nasync function processStream(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n decoder: TextDecoder,\n state: StreamState,\n controller: ReadableStreamDefaultController<Uint8Array>,\n): Promise<void> {\n const emit = (event: StreamEvent) => emitSSEEvent(event, controller, state)\n let finished = false\n\n while (!finished) {\n const { done, value } = await reader.read()\n if (done) break\n\n const lines = processChunk(decoder.decode(value, { stream: true }), state)\n\n for (const line of lines) {\n if (finished) break\n\n const data = parseSSELine(line)\n if (!data) continue\n\n const { candidates, usage } = extractFromData(data)\n if (usage) {\n state.inputTokens = usage.promptTokenCount ?? state.inputTokens\n state.outputTokens = usage.candidatesTokenCount ?? state.outputTokens\n }\n\n if (candidates[0] && processCandidate(candidates[0], state, emit)) {\n finished = true\n break\n }\n }\n }\n}\n\n/**\n * Transform Antigravity non-stream response to Anthropic format\n */\nasync function transformNonStreamResponse(\n response: Response,\n model: string,\n): Promise<Response> {\n interface AntigravityResponseData {\n candidates?: Array<{\n content?: {\n parts?: Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>\n }\n finishReason?: string\n }>\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number }\n }\n\n interface NonStreamData {\n response?: AntigravityResponseData\n candidates?: AntigravityResponseData[\"candidates\"]\n usageMetadata?: AntigravityResponseData[\"usageMetadata\"]\n }\n\n const rawData = (await response.json()) as NonStreamData\n\n // Handle nested response structure (Antigravity wraps response in a \"response\" object)\n const data = rawData.response ?? rawData\n const candidate = data.candidates?.[0]\n const parts = candidate?.content?.parts ?? []\n const content = buildNonStreamContent(parts)\n\n const anthropicResponse = {\n id: generateMessageId(),\n type: \"message\",\n role: \"assistant\",\n content,\n model,\n stop_reason: \"end_turn\",\n stop_sequence: null,\n usage: {\n input_tokens: data.usageMetadata?.promptTokenCount ?? 0,\n output_tokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n },\n }\n\n return new Response(JSON.stringify(anthropicResponse), {\n headers: { \"Content-Type\": \"application/json\" },\n })\n}\n\n/**\n * Build content array for non-stream response\n */\nfunction buildNonStreamContent(\n parts: Array<{\n text?: string\n thought?: boolean\n functionCall?: { name: string; args: unknown }\n }>,\n): Array<unknown> {\n const content: Array<unknown> = []\n\n for (const part of parts) {\n if (part.thought && part.text) {\n content.push({ type: \"thinking\", thinking: part.text })\n } else if (part.text) {\n content.push({ type: \"text\", text: part.text })\n }\n\n if (part.functionCall) {\n content.push({\n type: \"tool_use\",\n id: generateToolId(),\n name: part.functionCall.name,\n input: part.functionCall.args,\n })\n }\n }\n\n return content\n}\n","/**\n * Antigravity Messages Route\n *\n * Anthropic-compatible messages endpoint for Antigravity.\n * This enables Claude Code to use Antigravity as backend.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createAntigravityMessages,\n type AnthropicMessageRequest,\n} from \"~/services/antigravity/create-messages\"\n\nexport const antigravityMessagesRoute = new Hono()\n\nantigravityMessagesRoute.post(\"/\", async (c) => {\n if (!state.antigravityMode) {\n return c.json(\n {\n error:\n \"Antigravity mode is not enabled. Start with --antigravity flag.\",\n },\n 400,\n )\n }\n\n try {\n const body: AnthropicMessageRequest = await c.req.json()\n consola.debug(\"Antigravity message request:\", body.model)\n\n const response = await createAntigravityMessages(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Antigravity message error:\", error)\n return c.json(\n {\n type: \"error\",\n error: {\n type: \"antigravity_error\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * Antigravity Models Route\n *\n * OpenAI-compatible models endpoint for Antigravity.\n */\n\nimport { Hono } from \"hono\"\n\nimport { getAntigravityModels } from \"~/services/antigravity/get-models\"\n\nconst app = new Hono()\n\napp.get(\"/\", async (c) => {\n const models = await getAntigravityModels()\n return c.json(models)\n})\n\nexport const antigravityModelsRoute = app\n","import consola from \"consola\"\n\nimport { HTTPError } from \"./error\"\n\nexport const awaitApproval = async () => {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: \"confirm\",\n })\n\n if (!response)\n throw new HTTPError(\n \"Request rejected\",\n Response.json({ message: \"Request rejected\" }, { status: 403 }),\n )\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import(\"gpt-tokenizer/encoding/o200k_base\"),\n cl100k_base: () => import(\"gpt-tokenizer/encoding/cl100k_base\"),\n p50k_base: () => import(\"gpt-tokenizer/encoding/p50k_base\"),\n p50k_edit: () => import(\"gpt-tokenizer/encoding/p50k_edit\"),\n r50k_base: () => import(\"gpt-tokenizer/encoding/r50k_base\"),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nconst calculateToolCallsTokens = (\n toolCalls: Array<ToolCall>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nconst calculateContentPartsTokens = (\n contentParts: Array<ContentPart>,\n encoder: Encoder,\n): number => {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === \"image_url\") {\n tokens += encoder.encode(part.image_url.url).length + 85\n } else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nconst calculateMessageTokens = (\n message: Message,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\") {\n tokens += encoder.encode(value).length\n }\n if (key === \"name\") {\n tokens += tokensPerName\n }\n if (key === \"tool_calls\") {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === \"content\" && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nconst calculateTokens = (\n messages: Array<Message>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nconst getEncodeChatFunction = async (encoding: string): Promise<Encoder> => {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport const getTokenizerFromModel = (model: Model): string => {\n return model.capabilities.tokenizer || \"o200k_base\"\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nconst getModelConstants = (model: Model) => {\n return model.id === \"gpt-3.5-turbo\" || model.id === \"gpt-4\" ?\n {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nconst calculateParameterTokens = (\n key: string,\n prop: unknown,\n context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n },\n): number => {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== \"object\" || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || \"string\"\n let paramDesc = param.description || \"\"\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith(\".\")) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set([\"type\", \"description\", \"enum\"])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText =\n typeof propertyValue === \"string\" ? propertyValue : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nconst calculateParametersTokens = (\n parameters: unknown,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (!parameters || typeof parameters !== \"object\") {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === \"properties\") {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n } else {\n const paramText =\n typeof value === \"string\" ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nconst calculateToolTokens = (\n tool: Tool,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || \"\"\n if (fDesc.endsWith(\".\")) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = fName + \":\" + fDesc\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === \"object\" // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport const numTokensForTools = (\n tools: Array<Tool>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport const getTokenCount = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<{ input: number; output: number }> => {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const constants = getModelConstants(model)\n\n // All messages in the payload are prompt tokens (the full conversation context).\n // \"Output\" tokens are only the NEW response from the model, not historical assistant turns.\n let inputTokens = calculateTokens(payload.messages, encoder, constants)\n if (payload.tools && payload.tools.length > 0) {\n inputTokens += numTokensForTools(payload.tools, encoder, constants)\n }\n\n return {\n input: inputTokens,\n output: 0,\n }\n}\n","import consola from \"consola\"\n\nimport type {\n ChatCompletionsPayload,\n Message,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\nimport { getTokenCount } from \"./tokenizer\"\n\n/**\n * Get the maximum prompt token limit for a model.\n * Prefers max_prompt_tokens, falls back to max_context_window_tokens minus max_output_tokens.\n */\nconst getMaxPromptTokens = (model: Model): number | undefined => {\n const limits = model.capabilities.limits\n if (limits.max_prompt_tokens) {\n return limits.max_prompt_tokens\n }\n if (limits.max_context_window_tokens) {\n // Reserve space for output tokens\n const outputReserve = limits.max_output_tokens ?? 4096\n return limits.max_context_window_tokens - outputReserve\n }\n return undefined\n}\n\n/**\n * Check if a message is a tool-related message (tool call or tool result).\n * Tool messages must be kept together with their paired assistant message.\n */\nconst isToolMessage = (message: Message): boolean => {\n return message.role === \"tool\"\n}\n\n/**\n * Check if an assistant message contains tool calls.\n */\nconst hasToolCalls = (message: Message): boolean => {\n return (\n message.role === \"assistant\"\n && Array.isArray(message.tool_calls)\n && message.tool_calls.length > 0\n )\n}\n\n/**\n * Group messages into logical units that must be kept together.\n * Tool call sequences (assistant with tool_calls -> tool results) form a single group.\n * System/developer messages are kept as individual groups.\n * Other messages are individual groups.\n */\ninterface MessageGroup {\n messages: Array<Message>\n isSystem: boolean\n isRecent: boolean\n}\n\nconst groupMessages = (messages: Array<Message>): Array<MessageGroup> => {\n const groups: Array<MessageGroup> = []\n let i = 0\n\n while (i < messages.length) {\n const message = messages[i]\n\n // System/developer messages are always their own group\n if (message.role === \"system\" || message.role === \"developer\") {\n groups.push({ messages: [message], isSystem: true, isRecent: false })\n i++\n continue\n }\n\n // Assistant message with tool calls — group with following tool results\n if (hasToolCalls(message)) {\n const group: Array<Message> = [message]\n let j = i + 1\n while (j < messages.length && isToolMessage(messages[j])) {\n group.push(messages[j])\n j++\n }\n groups.push({ messages: group, isSystem: false, isRecent: false })\n i = j\n continue\n }\n\n // Regular message\n groups.push({ messages: [message], isSystem: false, isRecent: false })\n i++\n }\n\n return groups\n}\n\n/**\n * Create a truncation notice message to inform the model that earlier context was removed.\n */\nconst createTruncationNotice = (): Message => ({\n role: \"user\",\n content:\n \"[Note: Earlier conversation history was automatically truncated to fit within the model's context window. The most recent messages have been preserved.]\",\n})\n\n/**\n * Intelligently truncate messages to fit within the model's token limit.\n *\n * Strategy:\n * 1. Always preserve system/developer messages (they contain critical instructions)\n * 2. Always preserve the most recent messages (they contain the current task context)\n * 3. Remove middle conversation messages, oldest first\n * 4. Insert a truncation notice where messages were removed\n * 5. Keep tool call/result pairs together (never split them)\n *\n * Safety margin: keeps 5% below the limit to account for token counting inaccuracies.\n */\nexport const truncateMessages = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<ChatCompletionsPayload> => {\n const maxPromptTokens = getMaxPromptTokens(model)\n if (!maxPromptTokens) {\n consola.debug(\"No token limit found for model, skipping truncation\")\n return payload\n }\n\n // Check current token count\n const tokenCount = await getTokenCount(payload, model)\n // Apply 5% safety margin\n const safeLimit = Math.floor(maxPromptTokens * 0.95)\n\n if (tokenCount.input <= safeLimit) {\n return payload\n }\n\n const groups = groupMessages(payload.messages)\n\n // Separate system groups from conversation groups\n const systemGroups = groups.filter((g) => g.isSystem)\n const conversationGroups = groups.filter((g) => !g.isSystem)\n\n if (conversationGroups.length === 0) {\n consola.warn(\"No conversation messages to truncate, only system messages\")\n return payload\n }\n\n // Binary search approach: find the minimum number of recent conversation groups\n // that, combined with system messages + truncation notice, fit within the limit.\n // We start by trying to keep all conversation groups, then progressively remove from the front.\n\n let truncatedPayload = payload\n let dropCount = 0\n const maxDrop = Math.max(0, conversationGroups.length - 1) // Keep at least the last group\n\n // Start by dropping oldest groups one at a time\n while (dropCount <= maxDrop) {\n const keptConversationGroups = conversationGroups.slice(dropCount)\n const truncationNotice = dropCount > 0 ? [createTruncationNotice()] : []\n\n const newMessages = [\n ...systemGroups.flatMap((g) => g.messages),\n ...truncationNotice,\n ...keptConversationGroups.flatMap((g) => g.messages),\n ]\n\n truncatedPayload = { ...payload, messages: newMessages }\n\n const newTokenCount = await getTokenCount(truncatedPayload, model)\n if (newTokenCount.input <= safeLimit) {\n if (dropCount > 0) {\n const droppedMessages = conversationGroups\n .slice(0, dropCount)\n .reduce((sum, g) => sum + g.messages.length, 0)\n console.log(\n `Truncated: ${tokenCount.input} -> ${newTokenCount.input} tokens (-${droppedMessages} msgs)`,\n )\n }\n return truncatedPayload\n }\n\n dropCount++\n }\n\n // If we still exceed after dropping all but the last conversation group,\n // return what we have — at least we tried our best\n const finalTokenCount = await getTokenCount(truncatedPayload, model)\n consola.warn(\n `Could not reduce tokens below limit even after maximum truncation. `\n + `Current: ${finalTokenCount.input}, limit: ${maxPromptTokens}. `\n + `System messages or the last message may be too large.`,\n )\n\n return truncatedPayload\n}\n","import consola from \"consola\"\n\nimport type { State } from \"./state\"\n\nimport { HTTPError } from \"./error\"\nimport { sleep } from \"./utils\"\n\nexport async function checkRateLimit(state: State) {\n if (state.rateLimitSeconds === undefined) return\n\n const now = Date.now()\n\n if (!state.lastRequestTimestamp) {\n state.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.rateLimitSeconds) {\n state.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds)\n\n if (!state.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n \"Rate limit exceeded\",\n Response.json({ message: \"Rate limit exceeded\" }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n // eslint-disable-next-line require-atomic-updates\n state.lastRequestTimestamp = now\n consola.info(\"Rate limit wait completed, proceeding with request\")\n return\n}\n","import consola from \"consola\"\nimport { events } from \"fetch-event-stream\"\n\nimport { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\nimport { refreshCopilotToken } from \"~/lib/token\"\n\nexport const createChatCompletions = async (\n payload: ChatCompletionsPayload,\n) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const enableVision = payload.messages.some(\n (x) =>\n typeof x.content !== \"string\"\n && x.content?.some((x) => x.type === \"image_url\"),\n )\n\n // Agent/user check for X-Initiator header\n // Determine if any message is from an agent (\"assistant\" or \"tool\")\n const isAgentCall = payload.messages.some((msg) =>\n [\"assistant\", \"tool\"].includes(msg.role),\n )\n\n // Build headers fresh each call (token may be refreshed between attempts)\n const buildHeaders = (): Record<string, string> => ({\n ...copilotHeaders(state, enableVision),\n \"X-Initiator\": isAgentCall ? \"agent\" : \"user\",\n })\n\n consola.debug(\"Sending request to Copilot:\", {\n model: payload.model,\n endpoint: `${copilotBaseUrl(state)}/chat/completions`,\n })\n\n const url = `${copilotBaseUrl(state)}/chat/completions`\n\n // Request usage stats in the final stream chunk\n const body =\n payload.stream ?\n { ...payload, stream_options: { include_usage: true } }\n : payload\n\n const bodyString = JSON.stringify(body)\n\n // Retry on transient network errors (TLS disconnect, connection reset, etc.)\n const maxRetries = 2\n let lastError: unknown\n let response: Response | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(),\n body: bodyString,\n })\n break\n } catch (error: unknown) {\n lastError = error\n if (attempt < maxRetries) {\n const delay = 1000 * (attempt + 1)\n consola.warn(\n `Network error on attempt ${attempt + 1}/${maxRetries + 1}, retrying in ${delay}ms:`,\n error instanceof Error ? error.message : error,\n )\n await new Promise((r) => setTimeout(r, delay))\n }\n }\n }\n\n if (!response) {\n throw lastError\n }\n\n // On 401 (token expired), refresh the Copilot token and retry once\n if (response.status === 401) {\n consola.warn(\"Copilot token expired, refreshing and retrying...\")\n try {\n await refreshCopilotToken()\n response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(),\n body: bodyString,\n })\n } catch (refreshError) {\n consola.error(\"Failed to refresh token:\", refreshError)\n // Fall through to the error handling below\n }\n }\n\n if (!response.ok) {\n const errorBody = await response.text()\n consola.error(\"Failed to create chat completions\", {\n status: response.status,\n statusText: response.statusText,\n body: errorBody,\n })\n throw new HTTPError(\n `Failed to create chat completions: ${response.status} ${errorBody}`,\n response,\n )\n }\n\n if (payload.stream) {\n return events(response)\n }\n\n return (await response.json()) as ChatCompletionResponse\n}\n\n// Streaming types\n\nexport interface ChatCompletionChunk {\n id: string\n object: \"chat.completion.chunk\"\n created: number\n model: string\n choices: Array<Choice>\n system_fingerprint?: string\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n prompt_tokens_details?: {\n cached_tokens: number\n }\n completion_tokens_details?: {\n accepted_prediction_tokens: number\n rejected_prediction_tokens: number\n }\n }\n}\n\ninterface Delta {\n content?: string | null\n role?: \"user\" | \"assistant\" | \"system\" | \"tool\"\n tool_calls?: Array<{\n index: number\n id?: string\n type?: \"function\"\n function?: {\n name?: string\n arguments?: string\n }\n }>\n}\n\ninterface Choice {\n index: number\n delta: Delta\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n logprobs: object | null\n}\n\n// Non-streaming types\n\nexport interface ChatCompletionResponse {\n id: string\n object: \"chat.completion\"\n created: number\n model: string\n choices: Array<ChoiceNonStreaming>\n system_fingerprint?: string\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n prompt_tokens_details?: {\n cached_tokens: number\n }\n }\n}\n\ninterface ResponseMessage {\n role: \"assistant\"\n content: string | null\n tool_calls?: Array<ToolCall>\n}\n\ninterface ChoiceNonStreaming {\n index: number\n message: ResponseMessage\n logprobs: object | null\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\"\n}\n\n// Payload types\n\nexport interface ChatCompletionsPayload {\n messages: Array<Message>\n model: string\n temperature?: number | null\n top_p?: number | null\n max_tokens?: number | null\n stop?: string | Array<string> | null\n n?: number | null\n stream?: boolean | null\n\n frequency_penalty?: number | null\n presence_penalty?: number | null\n logit_bias?: Record<string, number> | null\n logprobs?: boolean | null\n response_format?: { type: \"json_object\" } | null\n seed?: number | null\n tools?: Array<Tool> | null\n tool_choice?:\n | \"none\"\n | \"auto\"\n | \"required\"\n | { type: \"function\"; function: { name: string } }\n | null\n user?: string | null\n}\n\nexport interface Tool {\n type: \"function\"\n function: {\n name: string\n description?: string\n parameters: Record<string, unknown>\n }\n}\n\nexport interface Message {\n role: \"user\" | \"assistant\" | \"system\" | \"tool\" | \"developer\"\n content: string | Array<ContentPart> | null\n\n name?: string\n tool_calls?: Array<ToolCall>\n tool_call_id?: string\n}\n\nexport interface ToolCall {\n id: string\n type: \"function\"\n function: {\n name: string\n arguments: string\n }\n}\n\nexport type ContentPart = TextPart | ImagePart\n\nexport interface TextPart {\n type: \"text\"\n text: string\n}\n\nexport interface ImagePart {\n type: \"image_url\"\n image_url: {\n url: string\n detail?: \"low\" | \"high\" | \"auto\"\n }\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { streamSSE, type SSEMessage } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { truncateMessages } from \"~/lib/context-compression\"\nimport { setTokenUsage, signalStreamDone } from \"~/lib/model-logger\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport { findModel, isNullish } from \"~/lib/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n} from \"~/services/copilot/create-chat-completions\"\n\n/**\n * Calculate token count, log it, and auto-truncate if needed.\n *\n * Uses multi-strategy exact matching via findModel() to handle\n * mismatches between requested and available model names.\n */\nasync function processPayloadTokens(\n payload: ChatCompletionsPayload,\n): Promise<ChatCompletionsPayload> {\n const selectedModel = findModel(payload.model)\n\n if (!selectedModel) {\n consola.warn(\"No model selected, skipping token count calculation\")\n return payload\n }\n\n try {\n const tokenCount = await getTokenCount(payload, selectedModel)\n consola.debug(\"Current token count:\", tokenCount)\n\n // Auto-truncate if prompt tokens exceed model limit\n const truncated = await truncateMessages(payload, selectedModel)\n\n // Set max_tokens if not provided\n if (isNullish(truncated.max_tokens)) {\n const withMaxTokens = {\n ...truncated,\n max_tokens: selectedModel.capabilities.limits.max_output_tokens,\n }\n consola.debug(\n \"Set max_tokens to:\",\n JSON.stringify(withMaxTokens.max_tokens),\n )\n return withMaxTokens\n }\n\n return truncated\n } catch (error) {\n consola.warn(\"Failed to calculate token count:\", error)\n return payload\n }\n}\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const rawPayload = await c.req.json<ChatCompletionsPayload>()\n consola.debug(\"Request payload:\", JSON.stringify(rawPayload).slice(-400))\n\n const payload = await processPayloadTokens(rawPayload)\n\n if (state.manualApprove) await awaitApproval()\n\n const response = await createChatCompletions(payload)\n\n if (isNonStreaming(response)) {\n consola.debug(\"Non-streaming response:\", JSON.stringify(response))\n if (response.usage) {\n setTokenUsage({\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n cacheReadTokens: response.usage.prompt_tokens_details?.cached_tokens,\n })\n }\n return c.json(response)\n }\n\n consola.debug(\"Streaming response\")\n return streamSSE(c, async (stream) => {\n for await (const chunk of response) {\n consola.debug(\"Streaming chunk:\", JSON.stringify(chunk))\n\n // Extract token usage from stream chunks\n try {\n const sseChunk = chunk as SSEMessage & { data?: string }\n if (sseChunk.data && sseChunk.data !== \"[DONE]\") {\n const parsed = JSON.parse(sseChunk.data) as {\n usage?: {\n prompt_tokens?: number\n completion_tokens?: number\n prompt_tokens_details?: { cached_tokens?: number }\n }\n }\n if (parsed.usage) {\n const usage = {\n inputTokens: parsed.usage.prompt_tokens ?? 0,\n outputTokens: parsed.usage.completion_tokens ?? 0,\n cacheReadTokens:\n parsed.usage.prompt_tokens_details?.cached_tokens,\n }\n setTokenUsage(usage)\n }\n }\n } catch {\n // Ignore parse errors in usage extraction\n }\n\n await stream.writeSSE(chunk as SSEMessage)\n }\n signalStreamDone()\n })\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCompletion } from \"./handler\"\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const createEmbeddings = async (payload: EmbeddingRequest) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const response = await fetch(`${copilotBaseUrl(state)}/embeddings`, {\n method: \"POST\",\n headers: copilotHeaders(state),\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to create embeddings\", response)\n\n return (await response.json()) as EmbeddingResponse\n}\n\nexport interface EmbeddingRequest {\n input: string | Array<string>\n model: string\n}\n\nexport interface Embedding {\n object: string\n embedding: Array<number>\n index: number\n}\n\nexport interface EmbeddingResponse {\n object: string\n data: Array<Embedding>\n model: string\n usage: {\n prompt_tokens: number\n total_tokens: number\n }\n}\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport {\n createEmbeddings,\n type EmbeddingRequest,\n} from \"~/services/copilot/create-embeddings\"\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post(\"/\", async (c) => {\n try {\n const paylod = await c.req.json<EmbeddingRequest>()\n const response = await createEmbeddings(paylod)\n\n return c.json(response)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { type AnthropicResponse } from \"./anthropic-types\"\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null,\n): AnthropicResponse[\"stop_reason\"] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: \"end_turn\",\n length: \"max_tokens\",\n tool_calls: \"tool_use\",\n content_filter: \"end_turn\",\n } as const\n return stopReasonMap[finishReason]\n}\n","import { state } from \"~/lib/state\"\nimport {\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n type ContentPart,\n type Message,\n type TextPart,\n type Tool,\n type ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicResponse,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\n// Payload translation\n\nexport function translateToOpenAI(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload {\n return {\n model: translateModelName(payload.model),\n messages: translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),\n }\n}\n\nexport function translateModelName(model: string): string {\n // Claude Code 发送的模型名称可能与 GitHub Copilot 支持的不一致\n // 需要智能匹配到 Copilot 实际支持的模型\n\n const supportedModels = state.models?.data.map((m) => m.id) ?? []\n\n // 1. 直接匹配\n if (supportedModels.includes(model)) {\n return model\n }\n\n // 2. 移除日期后缀后匹配 (claude-opus-4-5-20251101 -> claude-opus-4-5)\n const modelBase = model.replace(/-\\d{8}$/, \"\")\n if (supportedModels.includes(modelBase)) {\n return modelBase\n }\n\n // 3. 尝试 4-5 -> 4.5 格式转换 (claude-opus-4-5 -> claude-opus-4.5)\n const modelWithDot = modelBase.replace(/-(\\d+)-(\\d+)$/, \"-$1.$2\")\n if (supportedModels.includes(modelWithDot)) {\n return modelWithDot\n }\n\n // 4. 尝试 4.5 -> 4-5 格式转换 (claude-opus-4.5 -> claude-opus-4-5)\n const modelWithDash = model.replace(/(\\d+)\\.(\\d+)/, \"$1-$2\")\n if (supportedModels.includes(modelWithDash)) {\n return modelWithDash\n }\n\n // 5. Anthropic 旧格式到 Copilot 新格式映射\n // claude-3-5-sonnet-xxx -> claude-sonnet-4.5\n // claude-3-opus-xxx -> claude-opus-4.5\n // claude-3-5-haiku-xxx -> claude-haiku-4.5\n const oldFormatMapping: Record<string, string> = {\n \"claude-3-5-sonnet\": \"claude-sonnet-4.5\",\n \"claude-3-sonnet\": \"claude-sonnet-4\",\n \"claude-3-5-opus\": \"claude-opus-4.5\",\n \"claude-3-opus\": \"claude-opus-4.5\",\n \"claude-3-5-haiku\": \"claude-haiku-4.5\",\n \"claude-3-haiku\": \"claude-haiku-4.5\",\n }\n\n for (const [oldFormat, newFormat] of Object.entries(oldFormatMapping)) {\n if (\n modelBase.startsWith(oldFormat)\n && supportedModels.includes(newFormat)\n ) {\n return newFormat\n }\n }\n\n // 6. 如果都找不到,返回原始模型名\n return model\n}\n\nfunction translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n const systemMessages = handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap((message) =>\n message.role === \"user\" ?\n handleUserMessage(message)\n : handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n}\n\nfunction handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === \"string\") {\n return [{ role: \"system\", content: system }]\n } else {\n const systemText = system.map((block) => block.text).join(\"\\n\\n\")\n return [{ role: \"system\", content: systemText }]\n }\n}\n\nfunction handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === \"tool_result\",\n )\n const otherBlocks = message.content.filter(\n (block) => block.type !== \"tool_result\",\n )\n\n // Tool results must come first to maintain protocol: tool_use -> tool_result -> user\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: \"tool\",\n tool_call_id: block.tool_use_id,\n content: mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: \"user\",\n content: mapContent(otherBlocks),\n })\n }\n } else {\n newMessages.push({\n role: \"user\",\n content: mapContent(message.content),\n })\n }\n\n return newMessages\n}\n\nfunction handleAssistantMessage(\n message: AnthropicAssistantMessage,\n): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === \"tool_use\",\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === \"text\",\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === \"thinking\",\n )\n\n // Combine text and thinking blocks, as OpenAI doesn't have separate thinking blocks\n const allTextContent = [\n ...textBlocks.map((b) => b.text),\n ...thinkingBlocks.map((b) => b.thinking),\n ].join(\"\\n\\n\")\n\n return toolUseBlocks.length > 0 ?\n [\n {\n role: \"assistant\",\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map((toolUse) => ({\n id: toolUse.id,\n type: \"function\",\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n}\n\nfunction mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n): string | Array<ContentPart> | null {\n if (typeof content === \"string\") {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some((block) => block.type === \"image\")\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === \"text\" || block.type === \"thinking\",\n )\n .map((block) => (block.type === \"text\" ? block.text : block.thinking))\n .join(\"\\n\\n\")\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n contentParts.push({ type: \"text\", text: block.text })\n\n break\n }\n case \"thinking\": {\n contentParts.push({ type: \"text\", text: block.thinking })\n\n break\n }\n case \"image\": {\n contentParts.push({\n type: \"image_url\",\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n\n break\n }\n // No default\n }\n }\n return contentParts\n}\n\nfunction translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map((tool) => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n}\n\nfunction translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload[\"tool_choice\"],\n): ChatCompletionsPayload[\"tool_choice\"] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n if (anthropicToolChoice.name) {\n return {\n type: \"function\",\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return undefined\n }\n }\n}\n\n// Response translation\n\nexport function translateToAnthropic(\n response: ChatCompletionResponse,\n): AnthropicResponse {\n // Merge content from all choices\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null =\n null // default\n stopReason = response.choices[0]?.finish_reason ?? stopReason\n\n // Process all choices to extract text and tool use blocks\n for (const choice of response.choices) {\n const textBlocks = getAnthropicTextBlocks(choice.message.content)\n const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls)\n\n allTextBlocks.push(...textBlocks)\n allToolUseBlocks.push(...toolUseBlocks)\n\n // Use the finish_reason from the first choice, or prioritize tool_calls\n if (choice.finish_reason === \"tool_calls\" || stopReason === \"stop\") {\n stopReason = choice.finish_reason\n }\n }\n\n // Note: GitHub Copilot doesn't generate thinking blocks, so we don't include them in responses\n\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n model: response.model,\n content: [...allTextBlocks, ...allToolUseBlocks],\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n input_tokens:\n (response.usage?.prompt_tokens ?? 0)\n - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(response.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n response.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n }\n}\n\nfunction getAnthropicTextBlocks(\n messageContent: Message[\"content\"],\n): Array<AnthropicTextBlock> {\n if (typeof messageContent === \"string\") {\n return [{ type: \"text\", text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text }))\n }\n\n return []\n}\n\nfunction getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map((toolCall) => ({\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\n\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport { findModel } from \"~/lib/utils\"\n\nimport { type AnthropicMessagesPayload } from \"./anthropic-types\"\nimport { translateModelName, translateToOpenAI } from \"./non-stream-translation\"\n\n/**\n * Handles token counting for Anthropic messages.\n *\n * Uses multi-strategy model matching:\n * 1. findModel(translatedName) — translated Copilot name with format variants\n * 2. findModel(originalName) — original Anthropic name with format variants\n */\nexport async function handleCountTokens(c: Context) {\n try {\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n // Multi-strategy model matching:\n // Try translated name first (most likely to match Copilot model IDs),\n // then fall back to original Anthropic name with format variants\n const translatedModelName = translateModelName(anthropicPayload.model)\n const selectedModel =\n findModel(translatedModelName) ?? findModel(anthropicPayload.model)\n\n if (!selectedModel) {\n consola.warn(\n `Model not found for \"${anthropicPayload.model}\" (translated: \"${translatedModelName}\"), returning default token count`,\n )\n return c.json({\n input_tokens: 1,\n })\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith(\"claude-code\")) {\n mcpToolExist = anthropicPayload.tools.some((tool) =>\n tool.name.startsWith(\"mcp__\"),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith(\"claude\")) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith(\"claude\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.debug(\"Token count:\", finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n } catch (error) {\n consola.error(\"Error counting tokens:\", error)\n return c.json({\n input_tokens: 1,\n })\n }\n}\n","import { type ChatCompletionChunk } from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicStreamEventData,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\nfunction isToolBlockOpen(state: AnthropicStreamState): boolean {\n if (!state.contentBlockOpen) {\n return false\n }\n // Check if the current block index corresponds to any known tool call\n return Object.values(state.toolCalls).some(\n (tc) => tc.anthropicBlockIndex === state.contentBlockIndex,\n )\n}\n\n// eslint-disable-next-line max-lines-per-function, complexity\nexport function translateChunkToAnthropicEvents(\n chunk: ChatCompletionChunk,\n state: AnthropicStreamState,\n): Array<AnthropicStreamEventData> {\n const events: Array<AnthropicStreamEventData> = []\n\n if (chunk.choices.length === 0) {\n return events\n }\n\n const choice = chunk.choices[0]\n const { delta } = choice\n\n if (!state.messageStartSent) {\n events.push({\n type: \"message_start\",\n message: {\n id: chunk.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: chunk.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: 0, // Will be updated in message_delta when finished\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n })\n state.messageStartSent = true\n }\n\n if (delta.content) {\n if (isToolBlockOpen(state)) {\n // A tool block was open, so close it before starting a text block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n if (!state.contentBlockOpen) {\n events.push({\n type: \"content_block_start\",\n index: state.contentBlockIndex,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n })\n state.contentBlockOpen = true\n }\n\n events.push({\n type: \"content_block_delta\",\n index: state.contentBlockIndex,\n delta: {\n type: \"text_delta\",\n text: delta.content,\n },\n })\n }\n\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n if (toolCall.id && toolCall.function?.name) {\n // New tool call starting.\n if (state.contentBlockOpen) {\n // Close any previously open block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = state.contentBlockIndex\n state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: \"content_block_start\",\n index: anthropicBlockIndex,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = state.toolCalls[toolCall.index]\n // Tool call can still be empty\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (toolCallInfo) {\n events.push({\n type: \"content_block_delta\",\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n }\n\n if (choice.finish_reason) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockOpen = false\n }\n\n events.push(\n {\n type: \"message_delta\",\n delta: {\n stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),\n stop_sequence: null,\n },\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: chunk.usage?.completion_tokens ?? 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens\n !== undefined && {\n cache_read_input_tokens:\n chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n {\n type: \"message_stop\",\n },\n )\n }\n\n return events\n}\n\nexport function translateErrorToAnthropicErrorEvent(): AnthropicStreamEventData {\n return {\n type: \"error\",\n error: {\n type: \"api_error\",\n message: \"An unexpected error occurred during streaming.\",\n },\n }\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { streamSSE } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { truncateMessages } from \"~/lib/context-compression\"\nimport { setTokenUsage, signalStreamDone } from \"~/lib/model-logger\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { state } from \"~/lib/state\"\nimport { findModel } from \"~/lib/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicMessagesPayload,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport {\n translateToAnthropic,\n translateToOpenAI,\n} from \"./non-stream-translation\"\nimport { translateChunkToAnthropicEvents } from \"./stream-translation\"\n\n/**\n * Auto-truncate OpenAI payload if prompt tokens exceed model limit.\n *\n * Uses multi-strategy exact matching via findModel() to handle\n * mismatches between Anthropic and Copilot model naming conventions.\n */\nasync function autoTruncatePayload(\n payload: ChatCompletionsPayload,\n): Promise<ChatCompletionsPayload> {\n const selectedModel = findModel(payload.model)\n\n if (!selectedModel) {\n consola.warn(\n \"No model selected for Anthropic endpoint, skipping auto-truncation\",\n )\n return payload\n }\n\n try {\n return await truncateMessages(payload, selectedModel)\n } catch (error) {\n consola.warn(\"Failed to auto-truncate context:\", error)\n return payload\n }\n}\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n const rawOpenAIPayload = translateToOpenAI(anthropicPayload)\n\n // Auto-truncate if prompt tokens exceed model limit\n const openAIPayload = await autoTruncatePayload(rawOpenAIPayload)\n\n if (state.manualApprove) {\n await awaitApproval()\n }\n\n const response = await createChatCompletions(openAIPayload)\n\n if (isNonStreaming(response)) {\n const anthropicResponse = translateToAnthropic(response)\n setTokenUsage({\n inputTokens: anthropicResponse.usage.input_tokens,\n outputTokens: anthropicResponse.usage.output_tokens,\n cacheReadTokens: anthropicResponse.usage.cache_read_input_tokens,\n cacheCreationTokens: anthropicResponse.usage.cache_creation_input_tokens,\n })\n return c.json(anthropicResponse)\n }\n\n return streamSSE(c, async (stream) => {\n const streamState: AnthropicStreamState = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n\n for await (const rawEvent of response) {\n if (rawEvent.data === \"[DONE]\") {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n const events = translateChunkToAnthropicEvents(chunk, streamState)\n\n // Record token usage from the final chunk (which contains usage stats)\n if (chunk.usage) {\n const usage = {\n inputTokens:\n chunk.usage.prompt_tokens\n - (chunk.usage.prompt_tokens_details?.cached_tokens ?? 0),\n outputTokens: chunk.usage.completion_tokens,\n cacheReadTokens: chunk.usage.prompt_tokens_details?.cached_tokens,\n }\n setTokenUsage(usage)\n }\n\n for (const event of events) {\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n signalStreamDone()\n })\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCountTokens } from \"./count-tokens-handler\"\nimport { handleCompletion } from \"./handler\"\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n\nmessageRoutes.post(\"/count_tokens\", async (c) => {\n try {\n return await handleCountTokens(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\nimport { cacheModels } from \"~/lib/utils\"\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get(\"/\", async (c) => {\n try {\n if (!state.models) {\n // This should be handled by startup logic, but as a fallback.\n await cacheModels()\n }\n\n const models = state.models?.data.map((model) => ({\n id: model.id,\n object: \"model\",\n type: \"model\",\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n }))\n\n return c.json({\n object: \"list\",\n data: models,\n has_more: false,\n })\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get(\"/\", (c) => {\n try {\n return c.json({\n token: state.copilotToken,\n })\n } catch (error) {\n consola.error(\"Error fetching token:\", error)\n return c.json({ error: \"Failed to fetch token\", token: null }, 500)\n }\n})\n","import consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport { getAntigravityUsage } from \"~/services/antigravity/get-models\"\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\n\nexport const usageRoute = new Hono()\n\nusageRoute.get(\"/\", async (c) => {\n try {\n // Handle different modes\n if (state.antigravityMode) {\n const usage = await getAntigravityUsage()\n return c.json(usage)\n }\n\n if (state.zenMode) {\n // Zen doesn't have a public usage API\n return c.json(\n {\n error: \"Usage statistics not available for Zen mode\",\n message: \"Please check your usage at https://console.opencode.ai\",\n mode: \"zen\",\n },\n 200,\n )\n }\n\n // Default: Copilot mode\n const usage = await getCopilotUsage()\n return c.json(usage)\n } catch (error) {\n consola.error(\"Error fetching usage:\", error)\n\n // Return mode-specific error messages\n if (state.antigravityMode) {\n return c.json({ error: \"Failed to fetch Antigravity usage\" }, 500)\n }\n if (state.zenMode) {\n return c.json({ error: \"Failed to fetch Zen usage\" }, 500)\n }\n return c.json({ error: \"Failed to fetch Copilot usage\" }, 500)\n }\n})\n","/**\n * OpenCode Zen Chat Completions Proxy\n *\n * Proxies chat completion requests to OpenCode Zen API.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenChatCompletionRequest {\n model: string\n messages: Array<{\n role: string\n content:\n | string\n | Array<{ type: string; text?: string; image_url?: { url: string } }>\n }>\n temperature?: number\n max_tokens?: number\n stream?: boolean\n [key: string]: unknown\n}\n\nexport interface ZenChatCompletionResponse {\n id: string\n object: string\n created: number\n model: string\n choices: Array<{\n index: number\n message: {\n role: string\n content: string\n }\n finish_reason: string\n }>\n usage?: {\n prompt_tokens: number\n completion_tokens: number\n total_tokens: number\n }\n}\n\n/**\n * Parse retry delay from error response\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create chat completions via OpenCode Zen\n */\nexport async function createZenChatCompletions(\n request: ZenChatCompletionRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen chat completions request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\n \"https://opencode.ai/zen/v1/chat/completions\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(request),\n signal,\n },\n )\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen API error: ${response.status} ${errorText}`)\n throw new Error(`Zen API error: ${response.status} ${errorText}`)\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Chat Completions Route\n *\n * Proxies OpenAI-format chat completion requests to Zen.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenChatCompletions,\n type ZenChatCompletionRequest,\n} from \"~/services/zen/create-chat-completions\"\n\nexport const zenCompletionRoutes = new Hono()\n\nzenCompletionRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenChatCompletionRequest = await c.req.json()\n consola.debug(\"Zen chat completion request:\", body.model)\n\n const response = await createZenChatCompletions(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen chat completion error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Messages Proxy\n *\n * Proxies Anthropic-format message requests to OpenCode Zen API.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenMessageRequest {\n model: string\n messages: Array<{\n role: string\n content: string | Array<{ type: string; text?: string; source?: unknown }>\n }>\n max_tokens: number\n temperature?: number\n stream?: boolean\n system?: string | Array<{ type: string; text: string }>\n [key: string]: unknown\n}\n\n/**\n * Parse retry delay from error response headers or body\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n // Check Retry-After header\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n // Try to parse from error body\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create messages via OpenCode Zen (Anthropic format)\n */\nexport async function createZenMessages(\n request: ZenMessageRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen messages request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\"https://opencode.ai/zen/v1/messages\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(request),\n signal,\n })\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n // Retry on rate limit or server errors\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen Messages API error: ${response.status} ${errorText}`)\n throw new Error(`Zen Messages API error: ${response.status} ${errorText}`)\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Messages Route\n *\n * Proxies Anthropic-format message requests to Zen.\n * This enables Claude Code to use Zen as backend.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenMessages,\n type ZenMessageRequest,\n} from \"~/services/zen/create-messages\"\n\nexport const zenMessageRoutes = new Hono()\n\nzenMessageRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenMessageRequest = await c.req.json()\n consola.debug(\"Zen message request:\", body.model)\n\n const response = await createZenMessages(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen message error:\", error)\n return c.json(\n {\n type: \"error\",\n error: {\n type: \"zen_error\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Models Route\n *\n * Returns available models from Zen.\n */\n\n/* eslint-disable require-atomic-updates */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const zenModelRoutes = new Hono()\n\nzenModelRoutes.get(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n // Return cached models\n if (state.zenModels) {\n return c.json(state.zenModels)\n }\n\n // Fetch fresh if not cached\n const { getZenModels } = await import(\"~/services/zen/get-models\")\n const models = await getZenModels()\n state.zenModels = models\n return c.json(models)\n } catch (error) {\n consola.error(\"Zen models error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","/**\n * OpenCode Zen Responses Proxy\n *\n * Proxies OpenAI Responses API requests to OpenCode Zen.\n * Used for GPT-5 series models with stateful, agentic tool-use.\n */\n\nimport consola from \"consola\"\n\nimport { state } from \"~/lib/state\"\nimport { sleep } from \"~/lib/utils\"\n\nconst MAX_RETRIES = 5\nconst DEFAULT_RETRY_DELAY = 500\n\nexport interface ZenResponsesRequest {\n model: string\n input: string | Array<{ role: string; content: string }>\n instructions?: string\n tools?: Array<unknown>\n temperature?: number\n max_output_tokens?: number\n stream?: boolean\n [key: string]: unknown\n}\n\n/**\n * Parse retry delay from error response\n */\nfunction parseRetryDelay(response: Response, errorText: string): number {\n const retryAfter = response.headers.get(\"Retry-After\")\n if (retryAfter) {\n const seconds = Number.parseInt(retryAfter, 10)\n if (!Number.isNaN(seconds)) return seconds * 1000\n }\n\n try {\n const errorData = JSON.parse(errorText) as {\n error?: { retry_after?: number }\n }\n if (errorData.error?.retry_after) {\n return errorData.error.retry_after * 1000\n }\n } catch {\n // Ignore parse errors\n }\n\n return DEFAULT_RETRY_DELAY\n}\n\n/**\n * Create responses via OpenCode Zen (OpenAI Responses API format)\n */\nexport async function createZenResponses(\n request: ZenResponsesRequest,\n signal?: AbortSignal,\n): Promise<Response> {\n const apiKey = state.zenApiKey\n\n if (!apiKey) {\n throw new Error(\"Zen API key not configured\")\n }\n\n consola.debug(`Zen responses request for model: ${request.model}`)\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const response = await fetch(\"https://opencode.ai/zen/v1/responses\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify(request),\n signal,\n })\n\n if (response.ok) {\n return response\n }\n\n const errorText = await response.text()\n\n if (\n (response.status === 429 || response.status >= 500)\n && attempt < MAX_RETRIES\n ) {\n const retryDelay = parseRetryDelay(response, errorText)\n consola.info(\n `Zen rate limited (${response.status}), retrying in ${retryDelay}ms...`,\n )\n await sleep(retryDelay)\n continue\n }\n\n consola.error(`Zen Responses API error: ${response.status} ${errorText}`)\n throw new Error(\n `Zen Responses API error: ${response.status} ${errorText}`,\n )\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw error\n }\n if (attempt < MAX_RETRIES) {\n consola.warn(`Zen request failed, retrying... (${attempt + 1})`)\n await sleep(DEFAULT_RETRY_DELAY)\n continue\n }\n throw error\n }\n }\n\n throw new Error(\"Max retries exceeded\")\n}\n","/**\n * OpenCode Zen Responses Route\n *\n * Proxies OpenAI Responses API requests to Zen.\n * Used for GPT-5 series models.\n */\n\nimport consola from \"consola\"\nimport { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\nimport {\n createZenResponses,\n type ZenResponsesRequest,\n} from \"~/services/zen/create-responses\"\n\nexport const zenResponsesRoutes = new Hono()\n\nzenResponsesRoutes.post(\"/\", async (c) => {\n if (!state.zenMode || !state.zenApiKey) {\n return c.json(\n { error: \"Zen mode is not enabled. Start with --zen flag.\" },\n 400,\n )\n }\n\n try {\n const body: ZenResponsesRequest = await c.req.json()\n consola.debug(\"Zen responses request:\", body.model)\n\n const response = await createZenResponses(body)\n\n // Handle streaming\n if (body.stream) {\n const headers = new Headers()\n headers.set(\"Content-Type\", \"text/event-stream\")\n headers.set(\"Cache-Control\", \"no-cache\")\n headers.set(\"Connection\", \"keep-alive\")\n\n return new Response(response.body, {\n status: response.status,\n headers,\n })\n }\n\n // Non-streaming response\n const data = await response.json()\n return c.json(data)\n } catch (error) {\n consola.error(\"Zen responses error:\", error)\n return c.json(\n {\n error: {\n message: error instanceof Error ? error.message : \"Unknown error\",\n type: \"zen_error\",\n },\n },\n 500,\n )\n }\n})\n","import type { Context } from \"hono\"\n\nimport { Hono } from \"hono\"\nimport { cors } from \"hono/cors\"\n\nimport { apiKeyAuthMiddleware } from \"./lib/api-key-auth\"\nimport { modelLogger } from \"./lib/model-logger\"\nimport { state } from \"./lib/state\"\nimport { antigravityChatCompletionsRoute } from \"./routes/antigravity/chat-completions/route\"\nimport { antigravityMessagesRoute } from \"./routes/antigravity/messages/route\"\nimport { antigravityModelsRoute } from \"./routes/antigravity/models/route\"\nimport { completionRoutes } from \"./routes/chat-completions/route\"\nimport { embeddingRoutes } from \"./routes/embeddings/route\"\nimport { messageRoutes } from \"./routes/messages/route\"\nimport { modelRoutes } from \"./routes/models/route\"\nimport { tokenRoute } from \"./routes/token/route\"\nimport { usageRoute } from \"./routes/usage/route\"\nimport { zenCompletionRoutes } from \"./routes/zen/chat-completions/route\"\nimport { zenMessageRoutes } from \"./routes/zen/messages/route\"\nimport { zenModelRoutes } from \"./routes/zen/models/route\"\nimport { zenResponsesRoutes } from \"./routes/zen/responses/route\"\n\nexport const server = new Hono()\n\nserver.use(modelLogger())\nserver.use(cors())\nserver.use(apiKeyAuthMiddleware)\n\nserver.get(\"/\", (c) => c.text(\"Server running\"))\n\n// Helper to create a new request with modified path for sub-routing\nfunction createSubRequest(c: Context, basePath: string): Request {\n const url = new URL(c.req.url)\n // Remove the base path prefix to get the sub-path\n const subPath = url.pathname.slice(basePath.length) || \"/\"\n url.pathname = subPath\n return new Request(url.toString(), c.req.raw)\n}\n\n// Dynamic routing based on mode (Zen / Antigravity / Copilot)\n// Chat completions\nserver.all(\"/chat/completions/*\", async (c) => {\n const req = createSubRequest(c, \"/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\nserver.all(\"/chat/completions\", async (c) => {\n const req = createSubRequest(c, \"/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\n\n// Models\nserver.all(\"/models/*\", async (c) => {\n const req = createSubRequest(c, \"/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\nserver.all(\"/models\", async (c) => {\n const req = createSubRequest(c, \"/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\n\nserver.route(\"/embeddings\", embeddingRoutes)\nserver.route(\"/usage\", usageRoute)\nserver.route(\"/token\", tokenRoute)\n\n// Compatibility with tools that expect v1/ prefix\nserver.all(\"/v1/chat/completions/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/chat/completions\", async (c) => {\n const req = createSubRequest(c, \"/v1/chat/completions\")\n if (state.zenMode) return zenCompletionRoutes.fetch(req, c.env)\n if (state.antigravityMode)\n return antigravityChatCompletionsRoute.fetch(req, c.env)\n return completionRoutes.fetch(req, c.env)\n})\n\nserver.all(\"/v1/models/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/models\", async (c) => {\n const req = createSubRequest(c, \"/v1/models\")\n if (state.zenMode) return zenModelRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityModelsRoute.fetch(req, c.env)\n return modelRoutes.fetch(req, c.env)\n})\n\nserver.route(\"/v1/embeddings\", embeddingRoutes)\n\n// Anthropic compatible endpoints\nserver.all(\"/v1/messages/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/messages\")\n if (state.zenMode) return zenMessageRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityMessagesRoute.fetch(req, c.env)\n return messageRoutes.fetch(req, c.env)\n})\nserver.all(\"/v1/messages\", async (c) => {\n const req = createSubRequest(c, \"/v1/messages\")\n if (state.zenMode) return zenMessageRoutes.fetch(req, c.env)\n if (state.antigravityMode) return antigravityMessagesRoute.fetch(req, c.env)\n return messageRoutes.fetch(req, c.env)\n})\n\n// OpenAI Responses API (Zen only - for GPT-5 models)\nserver.all(\"/v1/responses/*\", async (c) => {\n const req = createSubRequest(c, \"/v1/responses\")\n if (state.zenMode) return zenResponsesRoutes.fetch(req, c.env)\n return c.json({ error: \"Responses API requires Zen mode\" }, 400)\n})\nserver.all(\"/v1/responses\", async (c) => {\n const req = createSubRequest(c, \"/v1/responses\")\n if (state.zenMode) return zenResponsesRoutes.fetch(req, c.env)\n return c.json({ error: \"Responses API requires Zen mode\" }, 400)\n})\n\n// Dedicated Zen routes (always available)\nserver.route(\"/zen/v1/chat/completions\", zenCompletionRoutes)\nserver.route(\"/zen/v1/models\", zenModelRoutes)\nserver.route(\"/zen/v1/messages\", zenMessageRoutes)\nserver.route(\"/zen/v1/responses\", zenResponsesRoutes)\n\n// Dedicated Antigravity routes (always available)\nserver.route(\n \"/antigravity/v1/chat/completions\",\n antigravityChatCompletionsRoute,\n)\nserver.route(\"/antigravity/v1/models\", antigravityModelsRoute)\nserver.route(\"/antigravity/v1/messages\", antigravityMessagesRoute)\n","#!/usr/bin/env node\n\n// Load environment variables from .env file\nimport \"dotenv/config\"\n/* eslint-disable require-atomic-updates */\n/* eslint-disable max-lines-per-function */\n/* eslint-disable complexity */\nimport { defineCommand } from \"citty\"\nimport clipboard from \"clipboardy\"\nimport consola from \"consola\"\nimport { serve, type ServerHandler } from \"srvx\"\nimport invariant from \"tiny-invariant\"\n\nimport { applyProxyConfig } from \"./lib/config\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { setupCopilotToken, setupGitHubToken } from \"./lib/token\"\nimport { cacheModels, cacheVSCodeVersion } from \"./lib/utils\"\nimport { server } from \"./server\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n apiKeys?: Array<string>\n zen: boolean\n zenApiKey?: string\n antigravity: boolean\n antigravityClientId?: string\n antigravityClientSecret?: string\n}\n\n/**\n * Start and configure the Copilot API server according to the provided options.\n *\n * Configures proxy and logging, initializes global state and credentials, ensures\n * required paths and model data are cached, optionally generates a Claude Code\n * launch command (and attempts to copy it to the clipboard), prints a usage\n * viewer URL, and begins serving HTTP requests on the specified port.\n *\n * @param options - Server startup options:\n * - port: Port number to listen on\n * - verbose: Enable verbose logging\n * - accountType: Account plan to use (\"individual\", \"business\", \"enterprise\")\n * - manual: Require manual approval for requests\n * - rateLimit: Seconds to wait between requests (optional)\n * - rateLimitWait: Wait instead of erroring when rate limit is hit\n * - githubToken: GitHub token to use (optional; if omitted a token setup prompt may run)\n * - claudeCode: Generate a Claude Code environment launch command\n * - showToken: Expose GitHub/Copilot tokens in responses for debugging\n * - proxyEnv: Initialize proxy settings from environment variables\n * - apiKeys: Optional list of API keys to enable API key authentication\n * - zen: Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)\n * - zenApiKey: OpenCode Zen API key (optional; if omitted will prompt for setup)\n * - antigravity: Enable Google Antigravity mode\n * - antigravityClientId: Google OAuth Client ID (optional; overrides env/default)\n * - antigravityClientSecret: Google OAuth Client Secret (optional; overrides env/default)\n */\nexport async function runServer(options: RunServerOptions): Promise<void> {\n // Apply saved proxy configuration first (if any)\n const savedProxyApplied = await applyProxyConfig()\n\n // Then apply --proxy-env if specified (overrides saved config)\n if (options.proxyEnv) {\n initProxyFromEnv()\n } else if (savedProxyApplied) {\n // If saved proxy was applied, initialize the proxy dispatcher\n initProxyFromEnv()\n }\n\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.accountType = options.accountType\n if (options.accountType !== \"individual\") {\n consola.info(`Using ${options.accountType} plan GitHub account`)\n }\n\n state.manualApprove = options.manual\n state.rateLimitSeconds = options.rateLimit\n state.rateLimitWait = options.rateLimitWait\n state.showToken = options.showToken\n state.apiKeys = options.apiKeys\n\n if (state.apiKeys && state.apiKeys.length > 0) {\n consola.info(\n `API key authentication enabled with ${state.apiKeys.length} key(s)`,\n )\n }\n\n await ensurePaths()\n\n // Handle Zen mode\n if (options.zen) {\n consola.info(\"OpenCode Zen mode enabled\")\n state.zenMode = true\n\n // Setup Zen API key\n if (options.zenApiKey) {\n state.zenApiKey = options.zenApiKey\n consola.info(\"Using provided Zen API key\")\n } else {\n const { setupZenApiKey, loadZenAuth } = await import(\n \"~/services/zen/auth\"\n )\n const existingAuth = await loadZenAuth()\n\n if (existingAuth) {\n state.zenApiKey = existingAuth.apiKey\n consola.info(\"Using existing Zen API key\")\n } else {\n const apiKey = await setupZenApiKey()\n state.zenApiKey = apiKey\n }\n }\n\n // Cache Zen models\n const { cacheZenModels } = await import(\"~/services/zen/get-models\")\n await cacheZenModels()\n\n consola.info(\n `Available Zen models: \\n${state.zenModels?.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n } else if (options.antigravity) {\n // Handle Antigravity mode\n consola.info(\"Google Antigravity mode enabled\")\n state.antigravityMode = true\n\n // Import auth module\n const {\n loadAntigravityAuth,\n setupAntigravity,\n getCurrentAccount,\n hasApiKey,\n getApiKey,\n setOAuthCredentials,\n } = await import(\"~/services/antigravity/auth\")\n\n // Set CLI-provided OAuth credentials if available\n if (options.antigravityClientId && options.antigravityClientSecret) {\n setOAuthCredentials(\n options.antigravityClientId,\n options.antigravityClientSecret,\n )\n consola.info(\"Using provided OAuth credentials from CLI\")\n }\n\n // Check for API Key first (simplest authentication)\n if (hasApiKey()) {\n consola.info(\n \"Using Gemini API Key for authentication (from GEMINI_API_KEY)\",\n )\n consola.info(`API Key: ${getApiKey()?.slice(0, 10) ?? \"\"}...`)\n } else {\n // Fall back to OAuth authentication\n const existingAuth = await loadAntigravityAuth()\n\n if (!existingAuth || existingAuth.accounts.length === 0) {\n consola.warn(\"No Antigravity accounts found and no GEMINI_API_KEY set\")\n consola.info(\"\")\n consola.info(\"You can authenticate using one of these methods:\")\n consola.info(\"\")\n consola.info(\"Method 1: API Key (Recommended - Simplest)\")\n consola.info(\" Set environment variable: GEMINI_API_KEY=your_api_key\")\n consola.info(\n \" Get your API key from: https://aistudio.google.com/apikey\",\n )\n consola.info(\"\")\n consola.info(\"Method 2: OAuth (Current setup)\")\n consola.info(\" Will proceed with OAuth login flow...\")\n consola.info(\"\")\n await setupAntigravity()\n } else {\n const enabledCount = existingAuth.accounts.filter(\n (a) => a.enable,\n ).length\n consola.info(\n `Found ${existingAuth.accounts.length} Antigravity accounts (${enabledCount} enabled)`,\n )\n }\n\n const currentAccount = await getCurrentAccount()\n if (!currentAccount && !hasApiKey()) {\n throw new Error(\"No enabled Antigravity accounts available\")\n }\n }\n\n // Get Antigravity models\n const { getAntigravityModels } = await import(\n \"~/services/antigravity/get-models\"\n )\n const models = await getAntigravityModels()\n state.antigravityModels = models\n\n consola.info(\n `Available Antigravity models: \\n${models.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n } else {\n // Standard Copilot mode\n await cacheVSCodeVersion()\n\n if (options.githubToken) {\n state.githubToken = options.githubToken\n consola.info(\"Using provided GitHub token\")\n // Validate the provided token\n try {\n const { getGitHubUser } = await import(\"~/services/github/get-user\")\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n } catch (error) {\n consola.error(\"Provided GitHub token is invalid\")\n throw error\n }\n } else {\n await setupGitHubToken()\n }\n\n try {\n await setupCopilotToken()\n } catch (error) {\n // If getting Copilot token fails with 401, the GitHub token might be invalid\n const { HTTPError } = await import(\"~/lib/error\")\n if (error instanceof HTTPError && error.response.status === 401) {\n consola.error(\n \"Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked\",\n )\n const { clearGithubToken } = await import(\"~/lib/token\")\n await clearGithubToken()\n consola.info(\"Please restart to re-authenticate\")\n }\n throw error\n }\n\n await cacheModels()\n\n consola.info(\n `Available models: \\n${state.models?.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n }\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n // Get model list based on current mode\n // All model responses share the same { data: Array<{ id: string }> } structure\n let modelList: Array<{ id: string }> | undefined\n if (state.zenMode) {\n modelList = state.zenModels?.data\n } else if (state.antigravityMode) {\n modelList = state.antigravityModels?.data\n } else {\n modelList = state.models?.data\n }\n invariant(modelList, \"Models should be loaded by now\")\n\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: modelList.map((model) => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n \"Select a small model to use with Claude Code\",\n {\n type: \"select\",\n options: modelList.map((model) => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n },\n \"claude\",\n )\n\n try {\n clipboard.writeSync(command)\n consola.success(\"Copied Claude Code command to clipboard!\")\n } catch {\n consola.warn(\n \"Failed to copy to clipboard. Here is the Claude Code command:\",\n )\n consola.log(command)\n }\n }\n\n consola.box(\n `🌐 Usage Viewer: https://imbuxiangnan-cyber.github.io/copilot-api-plus?endpoint=${serverUrl}/usage`,\n )\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the Copilot API server\",\n },\n args: {\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port to listen on\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type to use (individual, business, enterprise)\",\n },\n manual: {\n type: \"boolean\",\n default: false,\n description: \"Enable manual request approval\",\n },\n \"rate-limit\": {\n alias: \"r\",\n type: \"string\",\n description: \"Rate limit in seconds between requests\",\n },\n wait: {\n alias: \"w\",\n type: \"boolean\",\n default: false,\n description:\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description:\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\n },\n \"claude-code\": {\n alias: \"c\",\n type: \"boolean\",\n default: false,\n description:\n \"Generate a command to launch Claude Code with Copilot API config\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n \"api-key\": {\n type: \"string\",\n description: \"API keys for authentication\",\n },\n zen: {\n alias: \"z\",\n type: \"boolean\",\n default: false,\n description:\n \"Enable OpenCode Zen mode (proxy to Zen instead of GitHub Copilot)\",\n },\n \"zen-api-key\": {\n type: \"string\",\n description: \"OpenCode Zen API key (get from https://opencode.ai/zen)\",\n },\n antigravity: {\n type: \"boolean\",\n default: false,\n description:\n \"Enable Google Antigravity mode (proxy to Antigravity instead of GitHub Copilot)\",\n },\n \"antigravity-client-id\": {\n type: \"string\",\n description:\n \"Google OAuth Client ID for Antigravity (create at https://console.cloud.google.com/apis/credentials)\",\n },\n \"antigravity-client-secret\": {\n type: \"string\",\n description: \"Google OAuth Client Secret for Antigravity\",\n },\n },\n run({ args }) {\n const rateLimitRaw = args[\"rate-limit\"]\n const rateLimit =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n\n // Handle multiple API keys - citty may pass a string or array\n const apiKeyRaw = args[\"api-key\"]\n let apiKeys: Array<string> | undefined\n if (apiKeyRaw) {\n apiKeys = Array.isArray(apiKeyRaw) ? apiKeyRaw : [apiKeyRaw]\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args[\"account-type\"],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args[\"github-token\"],\n claudeCode: args[\"claude-code\"],\n showToken: args[\"show-token\"],\n proxyEnv: args[\"proxy-env\"],\n apiKeys,\n zen: args.zen,\n zenApiKey: args[\"zen-api-key\"],\n antigravity: args.antigravity,\n antigravityClientId: args[\"antigravity-client-id\"],\n antigravityClientSecret: args[\"antigravity-client-secret\"],\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\"\n\nimport { antigravity } from \"./antigravity\"\nimport { auth } from \"./auth\"\nimport { checkUsage } from \"./check-usage\"\nimport { debug } from \"./debug\"\nimport { logout } from \"./logout\"\nimport { proxy } from \"./proxy-config\"\nimport { start } from \"./start\"\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api-plus\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI/Anthropic compatible. Fork with bug fixes and improvements.\",\n },\n subCommands: {\n antigravity,\n auth,\n start,\n \"check-usage\": checkUsage,\n debug,\n logout,\n proxy,\n },\n})\n\nawait runMain(main)\n"],"x_google_ignoreList":[0,1,2,3,4],"mappings":"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"}
|