@openhoo/hoopilot 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/cli.js +234 -67
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +203 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +203 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/auth-store.ts","../src/auth.ts","../src/copilot.ts","../src/github-device.ts","../src/logger.ts","../src/openai.ts","../src/anthropic.ts","../src/metrics.ts","../src/server.ts","../src/update.ts","../src/update-core.ts","../src/version.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { CopilotAuthError, DEFAULT_COPILOT_API_BASE_URL } from \"./auth\";\nimport { authStorePath, writeStoredCopilotAuth } from \"./auth-store\";\nimport { main as codexxMain } from \"./codexx\";\nimport { applyCopilotHeaders, CopilotClient, normalizeCopilotUsage } from \"./copilot\";\nimport { githubCopilotDeviceLogin } from \"./github-device\";\nimport { createHoopilotLogger, noopLogger, parseLogFormat, parseLogLevel } from \"./logger\";\nimport { startHoopilotServer } from \"./server\";\nimport type {\n CopilotAccess,\n CopilotQuota,\n CopilotUsage,\n FetchLike,\n HoopilotLogger,\n HoopilotServerOptions,\n} from \"./types\";\nimport { cleanupOldBinary, maybeNotifyUpdate, runUpdate } from \"./update\";\nimport {\n asRecord,\n envValue,\n isTrustedTokenBaseUrl,\n trimTrailingSlash,\n truncatedResponseText,\n} from \"./util\";\nimport { getVersion, IS_STANDALONE_BINARY } from \"./version\";\n\ninterface ParsedArgs extends HoopilotServerOptions {\n help?: boolean;\n noUpdateCheck?: boolean;\n version?: boolean;\n}\n\ninterface VerifyCopilotOAuthTokenOptions {\n copilotApiBaseUrl?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n}\n\nconst ALLOWED_COPILOT_API_HOSTS = [\"api.githubcopilot.com\"] as const;\n\nexport async function main(argv = Bun.argv.slice(2)): Promise<void> {\n // Clear any leftover \".old\" binary from a prior Windows self-update.\n cleanupOldBinary();\n\n const command = argv[0];\n if (command === \"update\" || command === \"upgrade\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n const logger = commandLogger(args, command);\n await runUpdate(await getVersion(), logger);\n return;\n }\n if (command === \"codexx\") {\n await codexxMain(argv.slice(1), process.env);\n return;\n }\n if (command === \"login\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"login\");\n await runLogin(args);\n return;\n }\n if (command === \"models\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"models\");\n await runModels(args);\n return;\n }\n if (command === \"usage\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"usage\");\n await runUsage(args);\n return;\n }\n\n const args = withRuntimeEnv(parseArgs(argv));\n if (await printMetaOption(args)) {\n return;\n }\n\n const logger = commandLogger(args, \"serve\");\n args.logger = logger;\n const started = startHoopilotServer(args);\n logger.info(\n {\n baseUrl: `${started.url}/v1`,\n event: \"server.started\",\n url: started.url,\n },\n \"hoopilot server started\",\n );\n\n if (!args.noUpdateCheck) {\n // Non-blocking: prints a notice from the previous check and refreshes the\n // cache in the background. The running server keeps the refresh alive.\n // Env-based disabling (HOOPILOT_NO_UPDATE_CHECK, NO_UPDATE_NOTIFIER, CI, …)\n // is handled centrally by isUpdateCheckDisabled inside maybeNotifyUpdate.\n void maybeNotifyUpdate(\n await getVersion(),\n IS_STANDALONE_BINARY ? \"binary\" : \"npm\",\n logger.child({ component: \"update\" }),\n );\n }\n}\n\nasync function printMetaOption(args: ParsedArgs): Promise<boolean> {\n if (args.help) {\n console.log(helpText(await getVersion()));\n return true;\n }\n if (args.version) {\n console.log(await getVersion());\n return true;\n }\n return false;\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const args: ParsedArgs = {};\n const rest = [...argv];\n if (rest[0] === \"serve\") {\n rest.shift();\n }\n\n while (rest.length > 0) {\n const arg = rest.shift();\n if (!arg) {\n continue;\n }\n if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n continue;\n }\n if (arg === \"--version\" || arg === \"-v\") {\n args.version = true;\n continue;\n }\n if (arg === \"--allow-unauthenticated\") {\n args.allowUnauthenticated = true;\n continue;\n }\n if (arg === \"--no-update-check\") {\n args.noUpdateCheck = true;\n continue;\n }\n\n if (!arg.startsWith(\"-\")) {\n throw new Error(`Unknown argument: ${arg}.`);\n }\n\n const [name, inlineValue] = splitOption(arg);\n switch (name) {\n case \"--api-key\":\n args.apiKey = optionValue(name, inlineValue, rest);\n break;\n case \"--api-key-file\":\n args.apiKey = readApiKeyFile(optionValue(name, inlineValue, rest));\n break;\n case \"--auth-file\":\n args.authStorePath = optionValue(name, inlineValue, rest);\n break;\n case \"--copilot-api-base-url\":\n args.copilotApiBaseUrl = optionValue(name, inlineValue, rest);\n break;\n case \"--log-format\":\n args.logFormat = parseLogFormat(optionValue(name, inlineValue, rest));\n break;\n case \"--log-level\":\n args.logLevel = parseLogLevel(optionValue(name, inlineValue, rest));\n break;\n case \"--host\":\n args.host = optionValue(name, inlineValue, rest);\n break;\n case \"--port\":\n case \"-p\": {\n const value = optionValue(name, inlineValue, rest);\n args.port = Number(value);\n if (!Number.isInteger(args.port) || args.port <= 0 || args.port > 65_535) {\n throw new Error(`Invalid port: ${value}.`);\n }\n break;\n }\n default:\n throw new Error(`Unknown option: ${name}.`);\n }\n }\n\n return args;\n}\n\nfunction optionValue(name: string, inlineValue: string | undefined, rest: string[]): string {\n const value = inlineValue ?? rest.shift();\n if (!value) {\n throw new Error(`Missing value for ${name}.`);\n }\n return value;\n}\n\nfunction splitOption(arg: string): [string, string | undefined] {\n const separator = arg.indexOf(\"=\");\n if (separator === -1) {\n return [arg, undefined];\n }\n return [arg.slice(0, separator), arg.slice(separator + 1)];\n}\n\nfunction readApiKeyFile(path: string): string {\n const value = readFileSync(path, \"utf8\").trim();\n if (!value) {\n throw new Error(`API key file is empty: ${path}.`);\n }\n return value;\n}\n\nasync function runLogin(options: HoopilotServerOptions = {}): Promise<void> {\n const logger = options.logger?.child({ component: \"auth\" }) ?? noopLogger;\n logger.debug({ event: \"auth.login.started\" }, \"starting github copilot browser login\");\n console.log(\"Starting GitHub Copilot browser login...\");\n const login = await githubCopilotDeviceLogin({\n env: options.env,\n logger: console,\n openBrowser: openBrowserBestEffort,\n });\n\n console.log(\"Checking GitHub Copilot access...\");\n const access = await verifyCopilotOAuthToken(login.token, options);\n logger.debug(\n { apiBaseUrl: access.apiBaseUrl, event: \"auth.login.verified\" },\n \"github copilot oauth token verified\",\n );\n const path = options.authStorePath ?? authStorePath(options.env);\n writeStoredCopilotAuth(\n {\n apiBaseUrl: access.apiBaseUrl,\n githubDomain: login.domain,\n source: \"github-device-oauth\",\n token: login.token,\n },\n path,\n );\n logger.debug({ authStorePath: path, event: \"auth.login.stored\" }, \"copilot credential stored\");\n console.log(`Copilot OAuth credential stored at ${path}`);\n console.log(\"Copilot authentication ready.\");\n}\n\nexport async function runModels(options: HoopilotServerOptions = {}): Promise<string[]> {\n const logger = options.logger?.child({ component: \"models\" }) ?? noopLogger;\n logger.debug({ event: \"models.list.started\" }, \"fetching github copilot models\");\n\n const response = await new CopilotClient(options).models();\n if (!response.ok) {\n const message = `GitHub Copilot API model list failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n const ids = modelIdsFromResponse(await response.json().catch(() => undefined));\n if (ids.length === 0) {\n throw new Error(\"GitHub Copilot API returned no model IDs.\");\n }\n\n logger.debug(\n { count: ids.length, event: \"models.list.succeeded\" },\n \"github copilot models fetched\",\n );\n for (const id of ids) {\n console.log(id);\n }\n return ids;\n}\n\nexport async function runUsage(options: HoopilotServerOptions = {}): Promise<CopilotUsage> {\n const logger = options.logger?.child({ component: \"usage\" }) ?? noopLogger;\n logger.debug({ event: \"usage.fetch.started\" }, \"fetching github copilot quota\");\n\n const response = await new CopilotClient(options).usage();\n if (!response.ok) {\n const message = `GitHub Copilot usage request failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n const usage = normalizeCopilotUsage(await response.json().catch(() => ({})));\n logger.debug(\n { event: \"usage.fetch.succeeded\", plan: usage.plan },\n \"github copilot quota fetched\",\n );\n for (const line of formatCopilotUsage(usage)) {\n console.log(line);\n }\n return usage;\n}\n\nfunction formatCopilotUsage(usage: CopilotUsage): string[] {\n const lines: string[] = [];\n if (usage.plan) {\n lines.push(`Plan: ${usage.plan}`);\n }\n if (usage.quotaResetDate) {\n lines.push(`Quota resets: ${usage.quotaResetDate}`);\n }\n\n const order = [\"premium_interactions\", \"chat\", \"completions\"];\n const names = Object.keys(usage.quotas).sort(\n (a, b) => quotaRank(order, a) - quotaRank(order, b) || a.localeCompare(b),\n );\n for (const name of names) {\n const quota = usage.quotas[name];\n if (quota) {\n lines.push(`${quotaLabel(name)}: ${formatQuota(quota)}`);\n }\n }\n if (lines.length === 0) {\n lines.push(\"No GitHub Copilot quota information available for this account.\");\n }\n return lines;\n}\n\nfunction quotaRank(order: string[], name: string): number {\n const index = order.indexOf(name);\n return index === -1 ? order.length : index;\n}\n\nfunction quotaLabel(name: string): string {\n switch (name) {\n case \"premium_interactions\":\n return \"Premium requests\";\n case \"chat\":\n return \"Chat\";\n case \"completions\":\n return \"Completions\";\n default:\n return name;\n }\n}\n\nfunction formatQuota(quota: CopilotQuota): string {\n if (quota.unlimited) {\n return \"unlimited\";\n }\n const parts: string[] = [];\n if (quota.used !== undefined && quota.entitlement !== undefined) {\n parts.push(`${roundQuota(quota.used)}/${roundQuota(quota.entitlement)} used`);\n } else if (quota.remaining !== undefined) {\n parts.push(`${roundQuota(quota.remaining)} remaining`);\n }\n if (quota.percentRemaining !== undefined) {\n parts.push(`${roundQuota(quota.percentRemaining)}% remaining`);\n }\n if (quota.overageCount) {\n parts.push(`${roundQuota(quota.overageCount)} overage`);\n }\n return parts.length > 0 ? parts.join(\", \") : \"n/a\";\n}\n\nfunction roundQuota(value: number): number {\n return Number.isInteger(value) ? value : Math.round(value * 10) / 10;\n}\n\nexport async function verifyCopilotOAuthToken(\n token: string,\n options: VerifyCopilotOAuthTokenOptions = {},\n): Promise<CopilotAccess> {\n const apiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ??\n envValue(options.env?.COPILOT_API_BASE_URL) ??\n DEFAULT_COPILOT_API_BASE_URL,\n );\n const allowUnsafeUpstream = envValue(options.env?.HOOPILOT_ALLOW_UNSAFE_UPSTREAM) === \"1\";\n if (!isTrustedTokenBaseUrl(apiBaseUrl, ALLOWED_COPILOT_API_HOSTS, allowUnsafeUpstream)) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted Copilot API host: ${apiBaseUrl}`,\n );\n }\n const fetcher = options.fetch ?? fetch;\n const response = await fetcher(`${apiBaseUrl}/models`, {\n headers: applyCopilotHeaders(new Headers(), token),\n method: \"GET\",\n });\n\n if (!response.ok) {\n const message = `GitHub Copilot API verification failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n return {\n apiBaseUrl,\n expiresAtMs: Date.now() + 10 * 60_000,\n source: \"github-copilot-oauth\",\n token,\n };\n}\n\nfunction openBrowserBestEffort(url: string): void {\n const platform = process.platform;\n const command = platform === \"win32\" ? \"cmd\" : platform === \"darwin\" ? \"open\" : \"xdg-open\";\n const args = platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n try {\n const child = spawn(command, args, {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n // The device login code and URL were already printed.\n }\n}\n\nfunction modelIdsFromResponse(body: unknown): string[] {\n const record = asRecord(body);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(body) ? body : [];\n const seen = new Set<string>();\n const ids: string[] = [];\n for (const model of data) {\n const id = asRecord(model).id;\n if (typeof id !== \"string\" || id.length === 0 || seen.has(id)) {\n continue;\n }\n seen.add(id);\n ids.push(id);\n }\n return ids;\n}\n\nfunction withRuntimeEnv(args: ParsedArgs): ParsedArgs {\n return { ...args, env: process.env };\n}\n\nfunction commandLogger(args: ParsedArgs, command: string): HoopilotLogger {\n return createHoopilotLogger({\n env: args.env,\n format: args.logFormat,\n level: args.logLevel,\n }).child({ command, component: \"cli\" });\n}\n\nfunction helpText(version: string): string {\n return `hoopilot ${version}\n\nOpenAI-compatible proxy for GitHub Copilot.\n\nUsage:\n hoopilot [serve] [options]\n hoopilot codexx [codex options] [prompt]\n hoopilot login [options]\n hoopilot models [options]\n hoopilot usage [options]\n hoopilot update\n npx @openhoo/hoopilot [options]\n\nCommands:\n serve Start the proxy server (default)\n codexx Run Codex through the local Hoopilot server\n login Sign in through GitHub OAuth in a browser and verify Copilot access\n models List available GitHub Copilot model IDs\n usage Show GitHub Copilot quota and premium-request usage\n update, upgrade Update hoopilot to the latest release\n\nWhile the server runs, GET /metrics exposes Prometheus metrics (request counts,\ntoken usage, latency) and GET /v1/usage returns those metrics plus live Copilot\nquota as JSON.\n\nOptions:\n -p, --port <port> Port to listen on. Default: 4141\n --host <host> Host to listen on. Default: 127.0.0.1\n --api-key <key> Require clients to send Authorization: Bearer <key> or x-api-key: <key>\n --api-key-file <path> Read the local API key from a file instead of argv\n --auth-file <path> OAuth credential store path\n --copilot-api-base-url <url> Copilot API base URL override\n --log-level <level> trace, debug, info, warn, error, fatal, or silent\n --log-format <format> json or pretty. Default: pretty\n --no-update-check Do not check GitHub for a newer release\n --allow-unauthenticated Allow non-loopback bind without --api-key\n -h, --help Show help\n -v, --version Show version\n\nEnvironment:\n HOOPILOT_API_KEY\n HOOPILOT_AUTH_FILE\n HOOPILOT_GITHUB_CLIENT_ID\n HOOPILOT_GITHUB_DOMAIN\n HOOPILOT_LOG_FORMAT json or pretty. Default: pretty\n HOOPILOT_LOG_LEVEL trace, debug, info, warn, error, fatal, or silent\n COPILOT_API_BASE_URL\n HOOPILOT_GITHUB_API_BASE_URL GitHub REST base for the usage/quota lookup. Default: https://api.github.com\n HOOPILOT_ALLOW_UNSAFE_UPSTREAM Set to 1 to allow nonstandard HTTPS token hosts\n HOOPILOT_NO_UPDATE_CHECK Set to disable update checks (also NO_UPDATE_NOTIFIER)\n`;\n}\n\nif (import.meta.main) {\n main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n });\n}\n","import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { envValue } from \"./util\";\n\nexport class StoredCopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StoredCopilotAuthError\";\n }\n}\n\nexport interface StoredCopilotAuth {\n apiBaseUrl?: string;\n createdAt?: string;\n githubDomain?: string;\n source?: string;\n token: string;\n}\n\nexport function authStorePath(env: NodeJS.ProcessEnv = process.env): string {\n const explicit = envValue(env.HOOPILOT_AUTH_FILE);\n if (explicit) {\n return explicit;\n }\n\n const xdg = envValue(env.XDG_CONFIG_HOME);\n if (xdg) {\n return join(xdg, \"hoopilot\", \"auth.json\");\n }\n const appdata = envValue(env.APPDATA);\n if (appdata) {\n return join(appdata, \"hoopilot\", \"auth.json\");\n }\n const home = envValue(env.HOME);\n if (!home) {\n throw new StoredCopilotAuthError(\n \"Cannot resolve Hoopilot auth file path without HOOPILOT_AUTH_FILE, XDG_CONFIG_HOME, APPDATA, or HOME.\",\n );\n }\n const base = join(home, \".config\");\n return join(base, \"hoopilot\", \"auth.json\");\n}\n\nexport function readStoredCopilotAuth(path = authStorePath()): StoredCopilotAuth | undefined {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw new StoredCopilotAuthError(`Could not read Hoopilot auth file at ${path}.`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new StoredCopilotAuthError(\n `Hoopilot auth file at ${path} is not valid JSON. Run \\`hoopilot login\\` to replace it.`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new StoredCopilotAuthError(`Hoopilot auth file at ${path} must contain a JSON object.`);\n }\n const record = parsed as Record<string, unknown>;\n const token = typeof record.token === \"string\" ? record.token.trim() : \"\";\n if (!token) {\n throw new StoredCopilotAuthError(`Hoopilot auth file at ${path} does not contain a token.`);\n }\n return {\n apiBaseUrl: typeof record.apiBaseUrl === \"string\" ? record.apiBaseUrl : undefined,\n createdAt: typeof record.createdAt === \"string\" ? record.createdAt : undefined,\n githubDomain: typeof record.githubDomain === \"string\" ? record.githubDomain : undefined,\n source: typeof record.source === \"string\" ? record.source : undefined,\n token,\n };\n}\n\nexport function writeStoredCopilotAuth(auth: StoredCopilotAuth, path = authStorePath()): void {\n mkdirSync(dirname(path), { recursive: true });\n const data = `${JSON.stringify(\n {\n ...auth,\n createdAt: auth.createdAt ?? new Date().toISOString(),\n },\n null,\n 2,\n )}\\n`;\n // Write to a sibling temp file, then rename into place so a crash or full\n // disk mid-write can never leave a truncated credential file behind.\n const tmpPath = `${path}.${process.pid}.tmp`;\n writeFileSync(tmpPath, data, { mode: 0o600 });\n renameSync(tmpPath, path);\n try {\n chmodSync(path, 0o600);\n } catch {\n // chmod is best-effort on Windows.\n }\n}\n","import {\n readStoredCopilotAuth,\n type StoredCopilotAuth,\n StoredCopilotAuthError,\n} from \"./auth-store\";\nimport type { CopilotAccess, CopilotAuthOptions } from \"./types\";\nimport { envValue, trimTrailingSlash } from \"./util\";\n\nexport const DEFAULT_COPILOT_API_BASE_URL = \"https://api.githubcopilot.com\";\nconst REFRESH_SKEW_MS = 60_000;\nconst STORED_TOKEN_TTL_MS = 10 * 60_000;\n\nexport class CopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CopilotAuthError\";\n }\n}\n\nexport class CopilotAuth {\n readonly #authStorePath?: string;\n readonly #copilotApiBaseUrl: string;\n readonly #hasCopilotApiBaseUrlOverride: boolean;\n #cachedAccess?: CopilotAccess;\n\n constructor(options: CopilotAuthOptions = {}) {\n const envAuthStorePath = envValue(options.env?.HOOPILOT_AUTH_FILE);\n const envCopilotApiBaseUrl = envValue(options.env?.COPILOT_API_BASE_URL);\n this.#authStorePath = options.authStorePath ?? envAuthStorePath;\n this.#hasCopilotApiBaseUrlOverride = Boolean(options.copilotApiBaseUrl ?? envCopilotApiBaseUrl);\n this.#copilotApiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ?? envCopilotApiBaseUrl ?? DEFAULT_COPILOT_API_BASE_URL,\n );\n }\n\n async getAccess(): Promise<CopilotAccess> {\n if (this.#cachedAccess && this.#cachedAccess.expiresAtMs - REFRESH_SKEW_MS > Date.now()) {\n return this.#cachedAccess;\n }\n\n let stored: StoredCopilotAuth | undefined;\n try {\n stored = readStoredCopilotAuth(this.#authStorePath);\n } catch (error) {\n if (error instanceof StoredCopilotAuthError) {\n throw new CopilotAuthError(error.message);\n }\n throw error;\n }\n if (stored) {\n return this.#cacheAccess({\n apiBaseUrl: trimTrailingSlash(\n this.#hasCopilotApiBaseUrlOverride\n ? this.#copilotApiBaseUrl\n : (stored.apiBaseUrl ?? this.#copilotApiBaseUrl),\n ),\n expiresAtMs: Date.now() + STORED_TOKEN_TTL_MS,\n source: \"github-copilot-oauth\",\n token: stored.token,\n });\n }\n\n throw new CopilotAuthError(\n \"No GitHub Copilot OAuth credential found. Run `hoopilot login` to sign in through your browser.\",\n );\n }\n\n #cacheAccess(access: CopilotAccess): CopilotAccess {\n this.#cachedAccess = access;\n return access;\n }\n}\n","import { CopilotAuth } from \"./auth\";\nimport type {\n CopilotAuthOptions,\n CopilotQuota,\n CopilotUsage,\n FetchLike,\n JsonObject,\n} from \"./types\";\nimport { asRecord, envValue, isTrustedTokenBaseUrl, trimTrailingSlash } from \"./util\";\n\n/** Default GitHub REST host that serves the `copilot_internal/user` quota route. */\nexport const DEFAULT_GITHUB_API_BASE_URL = \"https://api.github.com\";\nconst ALLOWED_COPILOT_API_HOSTS = [\"api.githubcopilot.com\"] as const;\nconst ALLOWED_GITHUB_API_HOSTS = [\"api.github.com\"] as const;\n\n/**\n * API version sent to the GitHub `copilot_internal` endpoints. This is a\n * different surface from the Copilot completions API (`x-github-api-version`\n * `2026-06-01`), so it is pinned separately and bumped independently.\n */\nexport const COPILOT_USAGE_API_VERSION = \"2025-04-01\";\n\n/**\n * Set the GitHub Copilot API request headers on `headers`, leaving any\n * caller-provided `accept` intact. Single source of truth for the pinned\n * integration id, editor/plugin versions, and API version so the proxy client\n * and the login-time verification call cannot drift apart.\n */\nexport function applyCopilotHeaders(headers: Headers, token: string): Headers {\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `Bearer ${token}`);\n headers.set(\"copilot-integration-id\", \"vscode-chat\");\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"openai-intent\", \"conversation-panel\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", \"2026-06-01\");\n return headers;\n}\n\n/**\n * Set headers for the GitHub REST `copilot_internal/user` quota call. This host\n * is `api.github.com` (not the Copilot API host) and expects the `token` auth\n * scheme with the raw stored OAuth token — not the `Bearer` scheme used by the\n * Copilot completion endpoints.\n */\nexport function applyGithubApiHeaders(headers: Headers, token: string): Headers {\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `token ${token}`);\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", COPILOT_USAGE_API_VERSION);\n return headers;\n}\n\nexport class CopilotClient {\n readonly #auth: CopilotAuth;\n readonly #allowUnsafeUpstream: boolean;\n readonly #fetch: FetchLike;\n readonly #githubApiBaseUrl: string;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#auth = new CopilotAuth(options);\n this.#allowUnsafeUpstream = envValue(options.env?.HOOPILOT_ALLOW_UNSAFE_UPSTREAM) === \"1\";\n this.#fetch = options.fetch ?? fetch;\n this.#githubApiBaseUrl = trimTrailingSlash(\n options.githubApiBaseUrl ??\n envValue(options.env?.HOOPILOT_GITHUB_API_BASE_URL) ??\n DEFAULT_GITHUB_API_BASE_URL,\n );\n }\n\n /**\n * Fetch the Copilot account's quota / premium-request usage from the GitHub\n * REST `copilot_internal/user` endpoint. The stored device-flow OAuth token is\n * accepted directly here — no Copilot token exchange is required to read quota.\n */\n async usage(signal?: AbortSignal): Promise<Response> {\n // The quota call sends the raw, long-lived OAuth token. Never transmit it\n // over plaintext to a non-loopback host, so a misconfigured base URL cannot\n // exfiltrate the credential.\n if (\n !isTrustedTokenBaseUrl(\n this.#githubApiBaseUrl,\n ALLOWED_GITHUB_API_HOSTS,\n this.#allowUnsafeUpstream,\n )\n ) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted GitHub API host: ${this.#githubApiBaseUrl}`,\n );\n }\n const access = await this.#auth.getAccess();\n const headers = applyGithubApiHeaders(new Headers(), access.token);\n return this.#fetch(`${this.#githubApiBaseUrl}/copilot_internal/user`, {\n headers,\n method: \"GET\",\n signal,\n });\n }\n\n async chatCompletions(body: JsonObject, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body: JSON.stringify(body),\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async responses(body: string, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/responses\", {\n body,\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async models(signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/models\", {\n headers: {\n accept: \"application/json\",\n },\n method: \"GET\",\n signal,\n });\n }\n\n async fetchCopilot(path: string, init: RequestInit): Promise<Response> {\n const access = await this.#auth.getAccess();\n if (\n !isTrustedTokenBaseUrl(\n access.apiBaseUrl,\n ALLOWED_COPILOT_API_HOSTS,\n this.#allowUnsafeUpstream,\n )\n ) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted Copilot API host: ${access.apiBaseUrl}`,\n );\n }\n const headers = applyCopilotHeaders(new Headers(init.headers), access.token);\n\n return this.#fetch(`${access.apiBaseUrl}${path}`, {\n ...init,\n headers,\n });\n }\n}\n\n/**\n * Normalize a `copilot_internal/user` response into {@link CopilotUsage}. Handles\n * both the paid-plan shape (`quota_snapshots.{chat,completions,premium_interactions}`)\n * and the free-plan shape (`limited_user_quotas` remaining + `monthly_quotas`\n * allowance). `remaining` may be fractional and negative under permitted overage,\n * so `used` is derived as `max(0, entitlement - remaining)`.\n */\nexport function normalizeCopilotUsage(body: unknown): CopilotUsage {\n const record = asRecord(body);\n const quotas: Record<string, CopilotQuota> = {};\n\n const snapshots = asRecord(record.quota_snapshots);\n for (const [category, detail] of Object.entries(snapshots)) {\n quotas[category] = normalizeQuotaDetail(asRecord(detail));\n }\n\n if (Object.keys(quotas).length === 0) {\n const remaining = asRecord(record.limited_user_quotas);\n const monthly = asRecord(record.monthly_quotas);\n for (const category of new Set([...Object.keys(remaining), ...Object.keys(monthly)])) {\n const entitlement = numberOrUndefined(monthly[category]);\n const left = numberOrUndefined(remaining[category]);\n quotas[category] = removeUndefinedQuota({\n entitlement,\n percentRemaining:\n entitlement !== undefined && entitlement > 0 && left !== undefined\n ? (left / entitlement) * 100\n : undefined,\n remaining: left,\n used: usedFrom(entitlement, left),\n });\n }\n }\n\n return removeUndefinedUsage({\n accessTypeSku: stringOrUndefined(record.access_type_sku),\n chatEnabled: typeof record.chat_enabled === \"boolean\" ? record.chat_enabled : undefined,\n plan: stringOrUndefined(record.copilot_plan),\n quotaResetDate:\n stringOrUndefined(record.quota_reset_date) ??\n stringOrUndefined(record.quota_reset_date_utc) ??\n stringOrUndefined(record.limited_user_reset_date),\n quotas,\n });\n}\n\nfunction normalizeQuotaDetail(detail: JsonObject): CopilotQuota {\n const entitlement = numberOrUndefined(detail.entitlement);\n const overageCount = numberOrUndefined(detail.overage_count);\n const remaining =\n numberOrUndefined(detail.remaining) ?? numberOrUndefined(detail.quota_remaining);\n return removeUndefinedQuota({\n entitlement,\n hasQuota: typeof detail.has_quota === \"boolean\" ? detail.has_quota : undefined,\n overageCount,\n overageEntitlement: numberOrUndefined(detail.overage_entitlement),\n overagePermitted:\n typeof detail.overage_permitted === \"boolean\" ? detail.overage_permitted : undefined,\n percentRemaining: numberOrUndefined(detail.percent_remaining),\n quotaId: stringOrUndefined(detail.quota_id),\n quotaResetAt: stringOrUndefined(detail.quota_reset_at),\n remaining,\n timestampUtc: stringOrUndefined(detail.timestamp_utc),\n tokenBasedBilling:\n typeof detail.token_based_billing === \"boolean\" ? detail.token_based_billing : undefined,\n unlimited: typeof detail.unlimited === \"boolean\" ? detail.unlimited : undefined,\n used: usedFrom(entitlement, remaining, overageCount),\n });\n}\n\nfunction usedFrom(\n entitlement: number | undefined,\n remaining: number | undefined,\n overageCount?: number,\n): number | undefined {\n if (entitlement === undefined || remaining === undefined) {\n return undefined;\n }\n const base = entitlement - remaining;\n const overage = remaining === 0 ? (overageCount ?? 0) : 0;\n return Math.max(0, base + overage);\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction removeUndefinedQuota(quota: CopilotQuota): CopilotQuota {\n return Object.fromEntries(\n Object.entries(quota).filter(([, value]) => value !== undefined),\n ) as CopilotQuota;\n}\n\nfunction removeUndefinedUsage(usage: CopilotUsage): CopilotUsage {\n const entries = Object.entries(usage).filter(([, value]) => value !== undefined);\n return Object.fromEntries(entries) as unknown as CopilotUsage;\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\nimport type { FetchLike, Logger } from \"./types\";\nimport { envValue, truncatedResponseText } from \"./util\";\n\nexport const DEFAULT_GITHUB_COPILOT_CLIENT_ID = \"Ov23li8tweQw6odWQebz\";\nconst DEFAULT_GITHUB_DOMAIN = \"github.com\";\nconst DEVICE_GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\nconst POLLING_SAFETY_MARGIN_MS = 3_000;\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport interface GithubCopilotDeviceLoginOptions {\n clientId?: string;\n domain?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n logger?: Logger;\n openBrowser?: (url: string) => void | Promise<void>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport interface GithubCopilotDeviceLoginResult {\n domain: string;\n token: string;\n}\n\ninterface DeviceCodeResponse {\n device_code?: string;\n expires_in?: number;\n interval?: number;\n user_code?: string;\n verification_uri?: string;\n}\n\ninterface DeviceTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\nexport async function githubCopilotDeviceLogin(\n options: GithubCopilotDeviceLoginOptions = {},\n): Promise<GithubCopilotDeviceLoginResult> {\n const env = options.env ?? process.env;\n const fetcher = options.fetch ?? fetch;\n const sleeper = options.sleep ?? sleep;\n const domain = normalizeDomain(\n options.domain ?? envValue(env.HOOPILOT_GITHUB_DOMAIN) ?? DEFAULT_GITHUB_DOMAIN,\n );\n const clientId =\n options.clientId ??\n envValue(env.HOOPILOT_GITHUB_CLIENT_ID) ??\n envValue(env.COPILOT_GITHUB_CLIENT_ID) ??\n DEFAULT_GITHUB_COPILOT_CLIENT_ID;\n\n const device = await requestDeviceCode(fetcher, domain, clientId);\n const verificationUrl = device.verification_uri;\n const userCode = device.user_code;\n const deviceCode = device.device_code;\n if (!verificationUrl || !userCode || !deviceCode) {\n throw new Error(\"GitHub device authorization response is missing required fields.\");\n }\n\n options.logger?.info(`First copy your one-time code: ${userCode}`);\n options.logger?.info(`Open ${verificationUrl} in your browser to authorize Hoopilot.`);\n await options.openBrowser?.(verificationUrl);\n\n return {\n domain,\n token: await pollForAccessToken(fetcher, sleeper, domain, clientId, {\n deviceCode,\n expiresIn: positiveSeconds(device.expires_in, 900),\n interval: positiveSeconds(device.interval, 5),\n }),\n };\n}\n\nasync function requestDeviceCode(\n fetcher: FetchLike,\n domain: string,\n clientId: string,\n): Promise<DeviceCodeResponse> {\n const response = await fetcher(`https://${domain}/login/device/code`, {\n body: JSON.stringify({\n client_id: clientId,\n scope: \"read:user\",\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (!response.ok) {\n throw new Error(\n `GitHub device authorization failed with ${response.status}: ${await truncatedResponseText(\n response,\n )}`,\n );\n }\n return parseJsonResponse<DeviceCodeResponse>(\n response,\n \"GitHub device authorization response was not valid JSON\",\n );\n}\n\nasync function pollForAccessToken(\n fetcher: FetchLike,\n sleeper: (ms: number) => Promise<void>,\n domain: string,\n clientId: string,\n device: { deviceCode: string; expiresIn: number; interval: number },\n): Promise<string> {\n let intervalMs = device.interval * 1000 + POLLING_SAFETY_MARGIN_MS;\n const deadline = Date.now() + device.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await sleeper(intervalMs);\n const response = await fetcher(`https://${domain}/login/oauth/access_token`, {\n body: JSON.stringify({\n client_id: clientId,\n device_code: device.deviceCode,\n grant_type: DEVICE_GRANT_TYPE,\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub device token exchange failed with ${response.status}: ${await truncatedResponseText(\n response,\n )}`,\n );\n }\n\n const data = await parseJsonResponse<DeviceTokenResponse>(\n response,\n \"GitHub device token response was not valid JSON\",\n );\n if (data.access_token) {\n return data.access_token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n if (data.error === \"slow_down\") {\n intervalMs =\n positiveSeconds(data.interval, device.interval + 5) * 1000 + POLLING_SAFETY_MARGIN_MS;\n continue;\n }\n if (data.error === \"expired_token\") {\n throw new Error(\"GitHub device login expired. Run `hoopilot login` again.\");\n }\n if (data.error === \"access_denied\") {\n throw new Error(\"GitHub device login was cancelled.\");\n }\n if (data.error) {\n throw new Error(data.error_description || `GitHub device login failed: ${data.error}`);\n }\n }\n\n throw new Error(\"GitHub device login timed out. Run `hoopilot login` again.\");\n}\n\nfunction oauthHeaders(): Headers {\n const headers = new Headers();\n headers.set(\"accept\", \"application/json\");\n headers.set(\"content-type\", \"application/json\");\n headers.set(\"user-agent\", \"hoopilot\");\n return headers;\n}\n\nfunction normalizeDomain(value: string): string {\n const raw = value.trim();\n const withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `https://${raw}`;\n let url: URL;\n try {\n url = new URL(withScheme);\n } catch {\n throw new Error(`Invalid GitHub domain: ${value}.`);\n }\n if (\n (url.protocol !== \"https:\" && url.protocol !== \"http:\") ||\n url.username ||\n url.password ||\n !url.hostname ||\n (url.pathname !== \"\" && url.pathname !== \"/\") ||\n url.search ||\n url.hash\n ) {\n throw new Error(`Invalid GitHub domain: ${value}. Provide only a hostname.`);\n }\n return url.host;\n}\n\nfunction positiveSeconds(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nasync function parseJsonResponse<T>(response: Response, context: string): Promise<T> {\n const text = await response.text();\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new Error(`${context}: ${text.slice(0, 500)}`);\n }\n}\n","import pino from \"pino\";\nimport pretty from \"pino-pretty\";\nimport type {\n HoopilotLogger,\n HoopilotLoggerOptions,\n LogFields,\n LogFormat,\n LogLevel,\n} from \"./types\";\nimport { envValue } from \"./util\";\n\nexport const DEFAULT_LOG_FORMAT: LogFormat = \"pretty\";\nexport const DEFAULT_LOG_LEVEL: LogLevel = \"info\";\n\nconst LOG_FORMATS = [\"json\", \"pretty\"] as const;\nconst LOG_LEVELS = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", \"silent\"] as const;\nconst REDACT_PATHS = [\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"headers.authorization\",\n \"headers.Authorization\",\n \"headers.cookie\",\n \"headers.Cookie\",\n \"headers.x-api-key\",\n \"headers.X-Api-Key\",\n \"token\",\n \"*.apiKey\",\n \"*.authorization\",\n \"*.cookie\",\n \"*.token\",\n \"*.headers.authorization\",\n \"*.headers.Authorization\",\n \"*.headers.cookie\",\n \"*.headers.Cookie\",\n \"*.headers.x-api-key\",\n \"*.headers.X-Api-Key\",\n];\n\nexport const noopLogger: HoopilotLogger = {\n child: () => noopLogger,\n debug: () => {},\n error: () => {},\n fatal: () => {},\n info: () => {},\n trace: () => {},\n warn: () => {},\n};\n\nexport function createHoopilotLogger(options: HoopilotLoggerOptions = {}): HoopilotLogger {\n const env = options.env ?? process.env;\n const level = parseLogLevel(options.level ?? envValue(env.HOOPILOT_LOG_LEVEL));\n const format = parseLogFormat(options.format ?? envValue(env.HOOPILOT_LOG_FORMAT));\n const pinoOptions: pino.LoggerOptions = {\n base: {\n service: \"hoopilot\",\n ...options.base,\n },\n level,\n redact: {\n censor: \"[Redacted]\",\n paths: REDACT_PATHS,\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n };\n\n if (format === \"pretty\") {\n return pino(\n pinoOptions,\n pretty({\n colorize: options.colorize ?? process.stderr.isTTY,\n destination: options.stream ?? 1,\n ignore: \"pid,hostname\",\n singleLine: true,\n translateTime: \"SYS:standard\",\n }),\n ) as HoopilotLogger;\n }\n\n if (options.stream) {\n return pino(pinoOptions, options.stream as pino.DestinationStream) as HoopilotLogger;\n }\n return pino(pinoOptions) as HoopilotLogger;\n}\n\nexport function parseLogFormat(value: string | undefined): LogFormat {\n if (!value) {\n return DEFAULT_LOG_FORMAT;\n }\n if (isLogFormat(value)) {\n return value;\n }\n throw new Error(`Invalid log format: ${value}. Expected one of: ${LOG_FORMATS.join(\", \")}.`);\n}\n\nexport function parseLogLevel(value: string | undefined): LogLevel {\n if (!value) {\n return DEFAULT_LOG_LEVEL;\n }\n if (isLogLevel(value)) {\n return value;\n }\n throw new Error(`Invalid log level: ${value}. Expected one of: ${LOG_LEVELS.join(\", \")}.`);\n}\n\nexport function shouldCreateLogger(options: {\n env?: NodeJS.ProcessEnv;\n logFormat?: string;\n logger?: HoopilotLogger;\n logLevel?: string;\n}): boolean {\n return Boolean(\n options.logger ||\n options.logFormat ||\n options.logLevel ||\n envValue(options.env?.HOOPILOT_LOG_FORMAT) ||\n envValue(options.env?.HOOPILOT_LOG_LEVEL),\n );\n}\n\n/** Build structured log fields describing an error, for the `err` log key. */\nexport function errorDetails(error: unknown): LogFields {\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n stack: error.stack,\n };\n }\n return { message: String(error) };\n}\n\nfunction isLogFormat(value: string): value is LogFormat {\n return (LOG_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isLogLevel(value: string): value is LogLevel {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","import type { JsonObject, TokenUsage } from \"./types\";\nimport { asRecord } from \"./util\";\n\nexport const DEFAULT_MODEL = \"gpt-4.1\";\n\ninterface ResponseStreamOptions {\n model: string;\n responseId?: string;\n}\n\ninterface AccumulatedToolCall {\n arguments: string;\n id: string;\n index: number;\n itemId?: string;\n name: string;\n outputIndex?: number;\n}\n\nexport class OpenAICompatibilityError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenAICompatibilityError\";\n }\n}\n\nexport function responsesRequestToChatCompletion(request: JsonObject): JsonObject {\n const messages: unknown[] = [];\n const instructions = contentToText(request.instructions);\n if (instructions) {\n messages.push({ content: instructions, role: \"system\" });\n }\n\n for (const message of inputToMessages(request.input)) {\n messages.push(message);\n }\n\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n max_tokens: request.max_output_tokens ?? request.max_tokens,\n messages,\n metadata: request.metadata,\n model: normalizeRequestedModel(request.model),\n presence_penalty: request.presence_penalty,\n reasoning_effort: asRecord(request.reasoning).effort,\n response_format: asRecord(request.text).format,\n seed: request.seed,\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: chatToolChoice(request.tool_choice),\n tools: chatTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function normalizeChatCompletionRequest(request: JsonObject): JsonObject {\n return removeUndefined({\n ...request,\n model: normalizeRequestedModel(request.model),\n });\n}\n\nexport function completionsRequestToChatCompletion(request: JsonObject): JsonObject {\n assertSupportedLegacyCompletionRequest(request);\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n logit_bias: request.logit_bias,\n max_tokens: request.max_tokens,\n messages: [{ content: legacyPromptToText(request.prompt), role: \"user\" }],\n model: normalizeRequestedModel(request.model),\n n: request.n,\n presence_penalty: request.presence_penalty,\n seed: request.seed,\n stop: request.stop,\n stream: request.stream === true,\n stream_options: request.stream_options,\n temperature: request.temperature,\n top_p: request.top_p,\n user: request.user,\n });\n}\n\nexport function normalizeRequestedModel(model: unknown): string {\n const requested = contentToText(model).trim();\n return requested || DEFAULT_MODEL;\n}\n\nexport function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject {\n const id = responseId ?? `resp_${randomId()}`;\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n const model = contentToText(completion.model) || DEFAULT_MODEL;\n const output = outputItemsFromMessage(message);\n const usage = responseUsage(completion.usage);\n\n return removeUndefined({\n created_at: epochSeconds(),\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n output_text: outputText(output),\n parallel_tool_calls: true,\n status: \"completed\",\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n usage,\n });\n}\n\nexport function chatCompletionToCompletion(completion: JsonObject): JsonObject {\n return removeUndefined({\n choices: completionChoices(completion).map((choice, index) => {\n const message = asRecord(choice.message);\n return {\n finish_reason: choice.finish_reason ?? \"stop\",\n index: typeof choice.index === \"number\" ? choice.index : index,\n logprobs: choice.logprobs ?? null,\n text: contentToText(choice.text) || contentToText(message.content),\n };\n }),\n created: completion.created ?? epochSeconds(),\n id: completion.id ?? `cmpl_${randomId()}`,\n model: completion.model ?? DEFAULT_MODEL,\n object: \"text_completion\",\n system_fingerprint: completion.system_fingerprint,\n usage: completion.usage,\n });\n}\n\nexport function completionStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let sawTerminalEvent = false;\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (data: JsonObject | \"[DONE]\") => {\n controller.enqueue(encoder.encode(encodeDataSse(data)));\n };\n const markTerminal = () => {\n sawTerminalEvent = true;\n };\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const blocks = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = blocks.pop() ?? \"\";\n for (const block of blocks) {\n processCompletionSseBlock(block, enqueue, markTerminal);\n }\n }\n const tail = `${buffer}${decoder.decode()}`;\n if (tail.trim()) {\n processCompletionSseBlock(tail, enqueue, markTerminal);\n }\n if (!sawTerminalEvent) {\n enqueue(\"[DONE]\");\n }\n controller.close();\n } catch (error) {\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nexport function normalizeModelsResponse(upstream: unknown): JsonObject {\n const record = asRecord(upstream);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(upstream) ? upstream : [];\n const models = data\n .map((model) => asRecord(model))\n .filter((model) => typeof model.id === \"string\")\n .map((model) => ({\n created: model.created ?? 0,\n id: model.id,\n object: \"model\",\n owned_by: model.owned_by ?? \"github-copilot\",\n }));\n\n return {\n data: models.length > 0 ? models : fallbackModels(),\n object: \"list\",\n };\n}\n\nexport function fallbackModels(): Array<JsonObject> {\n return [\n {\n created: 0,\n id: DEFAULT_MODEL,\n object: \"model\",\n owned_by: \"github-copilot\",\n },\n ];\n}\n\nexport function responsesStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n options: ResponseStreamOptions,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const responseId = options.responseId ?? `resp_${randomId()}`;\n const messageId = `msg_${randomId()}`;\n const createdAt = epochSeconds();\n let buffer = \"\";\n let text = \"\";\n let messageOutputIndex: number | undefined;\n let nextOutputIndex = 0;\n let sequenceNumber = 0;\n const tools = new Map<number, AccumulatedToolCall>();\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject | \"[DONE]\") => {\n controller.enqueue(\n encoder.encode(\n encodeSse(\n event,\n data === \"[DONE]\" ? data : { ...data, sequence_number: sequenceNumber++ },\n ),\n ),\n );\n };\n\n enqueue(\"response.created\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"in_progress\", []),\n type: \"response.created\",\n });\n\n const ensureMessageStarted = () => {\n if (messageOutputIndex !== undefined) {\n return;\n }\n messageOutputIndex = nextOutputIndex++;\n enqueue(\"response.output_item.added\", {\n item: {\n content: [],\n id: messageId,\n role: \"assistant\",\n status: \"in_progress\",\n type: \"message\",\n },\n output_index: messageOutputIndex,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.content_part.added\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n part: {\n annotations: [],\n text: \"\",\n type: \"output_text\",\n },\n type: \"response.content_part.added\",\n });\n };\n\n const appendText = (delta: string) => {\n ensureMessageStarted();\n text += delta;\n enqueue(\"response.output_text.delta\", {\n content_index: 0,\n delta,\n item_id: messageId,\n output_index: messageOutputIndex ?? 0,\n type: \"response.output_text.delta\",\n });\n };\n\n const appendToolCall = (toolCall: JsonObject) => {\n const fn = asRecord(toolCall.function);\n const index = typeof toolCall.index === \"number\" ? toolCall.index : tools.size;\n let existing = tools.get(index);\n const isNew = !existing;\n existing ??= {\n arguments: \"\",\n id: contentToText(toolCall.id) || `call_${randomId()}`,\n index,\n itemId: `fc_${randomId()}`,\n name: \"\",\n outputIndex: nextOutputIndex++,\n };\n existing.id = contentToText(toolCall.id) || existing.id;\n existing.name += contentToText(fn.name);\n tools.set(index, existing);\n\n if (isNew) {\n enqueue(\"response.output_item.added\", {\n item: functionCallItem(existing, \"in_progress\"),\n output_index: existing.outputIndex ?? 0,\n type: \"response.output_item.added\",\n });\n }\n\n const argumentDelta = contentToText(fn.arguments);\n if (argumentDelta) {\n existing.arguments += argumentDelta;\n enqueue(\"response.function_call_arguments.delta\", {\n delta: argumentDelta,\n item_id: existing.itemId,\n output_index: existing.outputIndex ?? 0,\n type: \"response.function_call_arguments.delta\",\n });\n }\n };\n\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n processChatSseLine(line, { appendText, appendToolCall });\n }\n }\n if (buffer) {\n processChatSseLine(buffer, { appendText, appendToolCall });\n }\n\n // Build the output items once so the ids emitted in the per-tool stream\n // events match the ids embedded in the final response.completed payload.\n const outputEntries: Array<[number, JsonObject]> = [];\n if (messageOutputIndex !== undefined) {\n const item = messageOutputItem(text, messageId);\n outputEntries.push([messageOutputIndex, item]);\n enqueue(\"response.output_text.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n text,\n type: \"response.output_text.done\",\n });\n enqueue(\"response.content_part.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n part: {\n annotations: [],\n text,\n type: \"output_text\",\n },\n type: \"response.content_part.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: messageOutputIndex,\n type: \"response.output_item.done\",\n });\n }\n\n for (const tool of [...tools.values()].sort(\n (a, b) => (a.outputIndex ?? 0) - (b.outputIndex ?? 0),\n )) {\n const item = functionCallItem(tool);\n const outputIndex = tool.outputIndex ?? 0;\n outputEntries.push([outputIndex, item]);\n enqueue(\"response.function_call_arguments.done\", {\n arguments: tool.arguments,\n item_id: item.id,\n output_index: outputIndex,\n type: \"response.function_call_arguments.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.done\",\n });\n }\n\n const output = outputEntries\n .sort(([left], [right]) => left - right)\n .map(([, item]) => item);\n\n enqueue(\"response.completed\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"completed\", output),\n type: \"response.completed\",\n });\n enqueue(\"done\", \"[DONE]\");\n controller.close();\n } catch (error) {\n // Tear down the upstream body so an output-side error/abort cannot leak it.\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nfunction inputToMessages(input: unknown): unknown[] {\n if (typeof input === \"string\") {\n return [{ content: input, role: \"user\" }];\n }\n if (!Array.isArray(input)) {\n return [];\n }\n\n const messages: unknown[] = [];\n for (const item of input) {\n const record = asRecord(item);\n const type = contentToText(record.type);\n if (type === \"function_call_output\") {\n messages.push({\n content: contentToText(record.output),\n role: \"tool\",\n tool_call_id: contentToText(record.call_id),\n });\n continue;\n }\n if (type === \"function_call\") {\n messages.push({\n role: \"assistant\",\n tool_calls: [\n {\n function: {\n arguments: contentToText(record.arguments),\n name: contentToText(record.name),\n },\n id: contentToText(record.call_id) || contentToText(record.id),\n type: \"function\",\n },\n ],\n });\n continue;\n }\n if (type && type !== \"message\") {\n unsupportedResponsesFeature(`input item type \"${type}\"`);\n }\n const role = responsesRoleToChatRole(contentToText(record.role));\n const content = chatMessageContent(record.content);\n if (role && content !== undefined) {\n messages.push({ content, role });\n }\n }\n return messages;\n}\n\nfunction chatMessageContent(content: unknown): string | Array<JsonObject> | undefined {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n if (content === undefined || content === null) {\n return undefined;\n }\n unsupportedResponsesFeature(\"non-array message content objects\");\n }\n\n const parts: JsonObject[] = [];\n for (const part of content) {\n const record = asRecord(part);\n const type = contentToText(record.type);\n if (type === \"input_text\" || type === \"output_text\" || type === \"text\") {\n parts.push({ text: contentToText(record.text), type: \"text\" });\n continue;\n }\n if (type === \"input_image\") {\n if (contentToText(record.file_id)) {\n unsupportedResponsesFeature(\"input_image file_id parts\");\n }\n const imageUrl = contentToText(record.image_url);\n if (!imageUrl) {\n unsupportedResponsesFeature(\"input_image parts without image_url\");\n }\n const image: JsonObject = { url: imageUrl };\n const detail = contentToText(record.detail);\n if (detail) {\n image.detail = detail;\n }\n parts.push({ image_url: image, type: \"image_url\" });\n continue;\n }\n if (type === \"input_file\") {\n unsupportedResponsesFeature(\"input_file parts\");\n }\n if (type === \"input_audio\") {\n unsupportedResponsesFeature(\"input_audio parts\");\n }\n unsupportedResponsesFeature(`content part type \"${type || \"unknown\"}\"`);\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n if (parts.every((part) => part.type === \"text\")) {\n return parts.map((part) => contentToText(part.text)).join(\"\\n\");\n }\n return parts;\n}\n\nfunction legacyPromptToText(prompt: unknown): string {\n if (typeof prompt === \"string\") {\n return prompt;\n }\n if (Array.isArray(prompt) && prompt.length === 1 && typeof prompt[0] === \"string\") {\n return prompt[0];\n }\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility supports exactly one string prompt per request.\",\n );\n}\n\nfunction assertSupportedLegacyCompletionRequest(request: JsonObject): void {\n if (request.echo === true) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support echo=true.\",\n );\n }\n if (typeof request.best_of === \"number\" && request.best_of > 1) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support best_of greater than 1.\",\n );\n }\n if (typeof request.logprobs === \"number\" && request.logprobs > 0) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support legacy logprobs.\",\n );\n }\n if (contentToText(request.suffix)) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support suffix.\",\n );\n }\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (typeof content === \"number\" || typeof content === \"boolean\") {\n return String(content);\n }\n if (Array.isArray(content)) {\n return content\n .map((item) => contentToText(item))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content && typeof content === \"object\") {\n const record = content as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n if (typeof record.output_text === \"string\") {\n return record.output_text;\n }\n return JSON.stringify(content);\n }\n return \"\";\n}\n\nfunction responsesRoleToChatRole(role: string): string | undefined {\n if (!role) {\n return \"user\";\n }\n if (\n role === \"assistant\" ||\n role === \"developer\" ||\n role === \"system\" ||\n role === \"tool\" ||\n role === \"user\"\n ) {\n return role === \"developer\" ? \"system\" : role;\n }\n unsupportedResponsesFeature(`message role \"${role}\"`);\n}\n\nfunction chatTools(tools: unknown): unknown[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools.map((tool) => {\n const record = asRecord(tool);\n const type = contentToText(record.type);\n if (type !== \"function\") {\n unsupportedResponsesFeature(`tool type \"${type || \"unknown\"}\"`);\n }\n return {\n function: removeUndefined({\n description: record.description,\n name: record.name,\n parameters: record.parameters,\n strict: record.strict,\n }),\n type: \"function\",\n };\n });\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction chatToolChoice(toolChoice: unknown): unknown {\n if (typeof toolChoice === \"string\" || toolChoice === undefined) {\n return toolChoice;\n }\n const record = asRecord(toolChoice);\n const type = contentToText(record.type);\n if (type === \"function\" && typeof record.name === \"string\") {\n return { function: { name: record.name }, type: \"function\" };\n }\n unsupportedResponsesFeature(`tool_choice type \"${type || \"unknown\"}\"`);\n}\n\nfunction unsupportedResponsesFeature(feature: string): never {\n throw new OpenAICompatibilityError(\n `Hoopilot Responses-to-chat compatibility does not support ${feature}.`,\n );\n}\n\nfunction outputItemsFromMessage(message: Record<string, unknown>): JsonObject[] {\n const output: JsonObject[] = [];\n const text = contentToText(message.content);\n if (text) {\n output.push(messageOutputItem(text));\n }\n const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n output.push(\n functionCallItem({\n arguments: contentToText(fn.arguments),\n id: contentToText(record.id) || `call_${randomId()}`,\n index: output.length,\n name: contentToText(fn.name),\n }),\n );\n }\n return output;\n}\n\nfunction messageOutputItem(text: string, id = `msg_${randomId()}`): JsonObject {\n return {\n content: [\n {\n annotations: [],\n text,\n type: \"output_text\",\n },\n ],\n id,\n role: \"assistant\",\n status: \"completed\",\n type: \"message\",\n };\n}\n\nfunction functionCallItem(\n tool: AccumulatedToolCall,\n status: \"in_progress\" | \"completed\" = \"completed\",\n): JsonObject {\n return {\n arguments: tool.arguments,\n call_id: tool.id,\n id: tool.itemId ?? `fc_${randomId()}`,\n name: tool.name,\n status,\n type: \"function_call\",\n };\n}\n\nfunction outputText(output: JsonObject[]): string {\n return output\n .flatMap((item) => {\n const content = item.content;\n return Array.isArray(content) ? content : [];\n })\n .map((part) => contentToText(asRecord(part).text))\n .filter(Boolean)\n .join(\"\");\n}\n\nfunction responseUsage(usage: unknown): JsonObject | null {\n const record = asRecord(usage);\n if (Object.keys(record).length === 0) {\n return null;\n }\n const inputTokens = record.prompt_tokens;\n const outputTokens = record.completion_tokens;\n return removeUndefined({\n input_tokens: inputTokens,\n input_tokens_details: responseUsageDetails(record.prompt_tokens_details, inputTokens, {\n cached_tokens: 0,\n }),\n output_tokens: outputTokens,\n output_tokens_details: responseUsageDetails(record.completion_tokens_details, outputTokens, {\n reasoning_tokens: 0,\n }),\n total_tokens: record.total_tokens,\n });\n}\n\nfunction responseUsageDetails(\n value: unknown,\n tokenCount: unknown,\n fallback: JsonObject,\n): JsonObject | undefined {\n const record = asRecord(value);\n if (Object.keys(record).length > 0) {\n return record;\n }\n return typeof tokenCount === \"number\" && Number.isFinite(tokenCount) ? fallback : undefined;\n}\n\n/**\n * Normalize an upstream `usage` object into {@link TokenUsage}. Accepts both the\n * Chat Completions shape (`prompt_tokens`/`completion_tokens`) and the Responses\n * shape (`input_tokens`/`output_tokens`), and pulls nested reasoning/cached\n * details when present. Returns undefined when no token counts are available so\n * callers can distinguish \"no usage reported\" from \"zero tokens\".\n */\nexport function extractTokenUsage(usage: unknown): TokenUsage | undefined {\n const record = asRecord(usage);\n const prompt = firstNumber(record.prompt_tokens, record.input_tokens);\n const completion = firstNumber(record.completion_tokens, record.output_tokens);\n const total = firstNumber(record.total_tokens);\n if (prompt === undefined && completion === undefined && total === undefined) {\n return undefined;\n }\n const promptTokens = prompt ?? 0;\n const completionTokens = completion ?? 0;\n const reasoning = firstNumber(\n asRecord(record.completion_tokens_details).reasoning_tokens,\n asRecord(record.output_tokens_details).reasoning_tokens,\n );\n const cached = firstNumber(\n asRecord(record.prompt_tokens_details).cached_tokens,\n asRecord(record.input_tokens_details).cached_tokens,\n );\n return removeUndefined({\n cachedTokens: cached,\n completionTokens,\n promptTokens,\n reasoningTokens: reasoning,\n totalTokens: total ?? promptTokens + completionTokens,\n }) as unknown as TokenUsage;\n}\n\nfunction firstNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction firstChoice(completion: JsonObject): Record<string, unknown> {\n return completionChoices(completion)[0] ?? {};\n}\n\nfunction completionChoices(completion: JsonObject): Array<Record<string, unknown>> {\n const choices = Array.isArray(completion.choices) ? completion.choices : [];\n return choices.map((choice) => asRecord(choice));\n}\n\nfunction processCompletionSseBlock(\n block: string,\n enqueue: (data: JsonObject | \"[DONE]\") => void,\n markTerminal: () => void,\n): void {\n let event = \"message\";\n const dataLines: string[] = [];\n for (const line of block.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"event:\")) {\n event = trimmed.slice(\"event:\".length).trim() || event;\n } else if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(\"data:\".length).trim());\n }\n }\n const data = dataLines.join(\"\\n\");\n if (!data) {\n return;\n }\n if (data === \"[DONE]\") {\n markTerminal();\n enqueue(\"[DONE]\");\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const error = completionStreamError(event, parsed);\n if (error) {\n markTerminal();\n enqueue({ error });\n return;\n }\n const choices = completionChoices(parsed)\n .map((choice, index) => {\n const delta = asRecord(choice.delta);\n const text = contentToText(delta.content);\n const finishReason = choice.finish_reason ?? null;\n if (!text && finishReason === null) {\n return undefined;\n }\n return {\n finish_reason: finishReason,\n index: typeof choice.index === \"number\" ? choice.index : index,\n logprobs: choice.logprobs ?? null,\n text,\n };\n })\n .filter((choice) => choice !== undefined);\n const usage = asRecord(parsed.usage);\n const hasUsage = Object.keys(usage).length > 0;\n if (choices.length === 0 && !hasUsage) {\n return;\n }\n\n enqueue(\n removeUndefined({\n choices,\n created: typeof parsed.created === \"number\" ? parsed.created : epochSeconds(),\n id: contentToText(parsed.id) || `cmpl_${randomId()}`,\n model: contentToText(parsed.model) || DEFAULT_MODEL,\n object: \"text_completion\",\n usage: hasUsage ? usage : undefined,\n }),\n );\n}\n\nfunction completionStreamError(event: string, parsed: JsonObject): JsonObject | undefined {\n const responseError = asRecord(asRecord(parsed.response).error);\n const directError = asRecord(parsed.error);\n const error =\n Object.keys(directError).length > 0\n ? directError\n : Object.keys(responseError).length > 0\n ? responseError\n : undefined;\n if (error) {\n return error;\n }\n if (event === \"error\" || parsed.type === \"response.failed\") {\n return removeUndefined({\n code: contentToText(parsed.code) || undefined,\n message: contentToText(parsed.message) || \"Upstream streaming request failed.\",\n type: contentToText(parsed.type) || \"upstream_stream_error\",\n });\n }\n return undefined;\n}\n\nfunction processChatSseLine(\n line: string,\n handlers: {\n appendText: (delta: string) => void;\n appendToolCall: (toolCall: JsonObject) => void;\n },\n): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const choice = firstChoice(parsed);\n const delta = asRecord(choice.delta);\n const content = contentToText(delta.content);\n if (content) {\n handlers.appendText(content);\n }\n\n const toolCalls = Array.isArray(delta.tool_calls) ? delta.tool_calls : [];\n for (const toolCall of toolCalls) {\n handlers.appendToolCall(asRecord(toolCall));\n }\n}\n\nfunction baseStreamResponse(\n id: string,\n model: string,\n createdAt: number,\n status: \"in_progress\" | \"completed\",\n output: JsonObject[],\n): JsonObject {\n return {\n created_at: createdAt,\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n parallel_tool_calls: true,\n status,\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n };\n}\n\nfunction encodeSse(event: string, data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction encodeDataSse(data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `data: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction parseJson(data: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(data));\n } catch {\n return undefined;\n }\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n\nfunction epochSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { normalizeRequestedModel } from \"./openai\";\nimport type { JsonObject } from \"./types\";\nimport { asRecord } from \"./util\";\n\ninterface AnthropicStreamOptions {\n model: string;\n messageId?: string;\n}\n\ninterface StreamBlock {\n index: number;\n sentText: string;\n stopped: boolean;\n type: \"text\" | \"tool_use\";\n}\n\ninterface AnthropicStreamState {\n blocks: Map<string, StreamBlock>;\n completed: boolean;\n messageId: string;\n model: string;\n nextBlockIndex: number;\n sawToolUse: boolean;\n started: boolean;\n usage: JsonObject;\n}\n\nexport class AnthropicCompatibilityError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AnthropicCompatibilityError\";\n }\n}\n\nexport function anthropicMessagesToResponsesRequest(request: JsonObject): JsonObject {\n return removeUndefined({\n input: anthropicMessagesToResponsesInput(request.messages),\n instructions: anthropicSystemToInstructions(request.system),\n max_output_tokens:\n typeof request.max_tokens === \"number\" && Number.isFinite(request.max_tokens)\n ? request.max_tokens\n : undefined,\n metadata: request.metadata,\n model: normalizeRequestedModel(request.model),\n parallel_tool_calls: true,\n reasoning: anthropicThinkingToReasoning(request.thinking),\n stop: anthropicStopSequences(request.stop_sequences),\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: anthropicToolChoice(request.tool_choice),\n tools: anthropicTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function responsesResponseToAnthropicMessage(\n response: JsonObject,\n fallbackModel: string,\n): JsonObject {\n const content = anthropicContentFromResponsesOutput(response);\n const usage = anthropicUsage(response.usage);\n return {\n content,\n id: textValue(response.id) || `msg_${randomId()}`,\n model: textValue(response.model) || fallbackModel,\n role: \"assistant\",\n stop_reason: anthropicStopReason(response, content),\n stop_sequence: null,\n type: \"message\",\n usage,\n };\n}\n\nexport function responsesStreamToAnthropicStream(\n stream: ReadableStream<Uint8Array>,\n options: AnthropicStreamOptions,\n): ReadableStream<Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = \"\";\n const state: AnthropicStreamState = {\n blocks: new Map(),\n completed: false,\n messageId: options.messageId ?? `msg_${randomId()}`,\n model: options.model,\n nextBlockIndex: 0,\n sawToolUse: false,\n started: false,\n usage: anthropicUsage(undefined),\n };\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject) => {\n controller.enqueue(encoder.encode(encodeSse(event, data)));\n };\n const reader = stream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const blocks = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = blocks.pop() ?? \"\";\n for (const block of blocks) {\n processResponsesSseBlock(block, state, enqueue);\n }\n }\n const tail = `${buffer}${decoder.decode()}`;\n if (tail.trim()) {\n processResponsesSseBlock(tail, state, enqueue);\n }\n finishAnthropicStream(state, enqueue);\n controller.close();\n } catch (error) {\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nexport function estimateAnthropicMessageTokens(request: JsonObject): JsonObject {\n const chars =\n estimatedTextSize(request.system) +\n estimatedTextSize(request.messages) +\n estimatedTextSize(request.tools) +\n estimatedTextSize(request.tool_choice) +\n estimatedTextSize(request.thinking);\n const messageCount = Array.isArray(request.messages) ? request.messages.length : 1;\n const toolCount = Array.isArray(request.tools) ? request.tools.length : 0;\n const inputTokens = Math.max(1, Math.ceil(chars / 4) + messageCount * 4 + toolCount * 16);\n return {\n input_tokens: inputTokens,\n total_tokens: inputTokens,\n };\n}\n\nfunction anthropicMessagesToResponsesInput(messages: unknown): JsonObject[] {\n if (!Array.isArray(messages)) {\n throw new AnthropicCompatibilityError(\"Anthropic Messages requests require messages[].\");\n }\n\n const input: JsonObject[] = [];\n for (const message of messages) {\n const record = asRecord(message);\n const role = anthropicRole(record.role);\n const parts = anthropicContentParts(record.content);\n const messageParts: JsonObject[] = [];\n const flushMessage = () => {\n if (messageParts.length === 0) {\n return;\n }\n input.push({\n content: [...messageParts],\n role,\n type: \"message\",\n });\n messageParts.length = 0;\n };\n\n for (const part of parts) {\n const type = textValue(part.type) || \"text\";\n if (type === \"text\") {\n const text = textValue(part.text);\n if (text) {\n messageParts.push({\n text,\n type: role === \"assistant\" ? \"output_text\" : \"input_text\",\n });\n }\n continue;\n }\n if (type === \"image\") {\n if (role !== \"user\") {\n throw new AnthropicCompatibilityError(\n \"Anthropic image content is only supported for user messages.\",\n );\n }\n messageParts.push(anthropicImageToResponsesPart(part));\n continue;\n }\n if (type === \"tool_use\") {\n flushMessage();\n input.push({\n arguments: JSON.stringify(asRecord(part.input)),\n call_id: textValue(part.id) || `call_${randomId()}`,\n name: textValue(part.name),\n type: \"function_call\",\n });\n continue;\n }\n if (type === \"tool_result\") {\n flushMessage();\n input.push({\n call_id: textValue(part.tool_use_id),\n output: anthropicToolResultOutput(part.content),\n type: \"function_call_output\",\n });\n continue;\n }\n if (type === \"thinking\" || type === \"redacted_thinking\") {\n continue;\n }\n throw new AnthropicCompatibilityError(\n `Anthropic content block type \"${type}\" is not supported.`,\n );\n }\n flushMessage();\n }\n return input;\n}\n\nfunction anthropicRole(value: unknown): \"assistant\" | \"user\" {\n const role = textValue(value);\n if (role === \"assistant\" || role === \"user\") {\n return role;\n }\n if (!role) {\n return \"user\";\n }\n throw new AnthropicCompatibilityError(`Anthropic message role \"${role}\" is not supported.`);\n}\n\nfunction anthropicContentParts(content: unknown): JsonObject[] {\n if (typeof content === \"string\") {\n return [{ text: content, type: \"text\" }];\n }\n if (Array.isArray(content)) {\n return content.map((part) =>\n typeof part === \"string\" ? { text: part, type: \"text\" } : asRecord(part),\n );\n }\n if (content === undefined || content === null) {\n return [];\n }\n return [asRecord(content)];\n}\n\nfunction anthropicImageToResponsesPart(part: JsonObject): JsonObject {\n const source = asRecord(part.source);\n const sourceType = textValue(source.type);\n if (sourceType === \"base64\") {\n const mediaType = textValue(source.media_type) || \"image/png\";\n const data = textValue(source.data);\n if (!data) {\n throw new AnthropicCompatibilityError(\"Anthropic base64 image content requires source.data.\");\n }\n return {\n detail: \"auto\",\n image_url: `data:${mediaType};base64,${data}`,\n type: \"input_image\",\n };\n }\n if (sourceType === \"url\") {\n const url = textValue(source.url);\n if (!url) {\n throw new AnthropicCompatibilityError(\"Anthropic URL image content requires source.url.\");\n }\n return {\n detail: \"auto\",\n image_url: url,\n type: \"input_image\",\n };\n }\n throw new AnthropicCompatibilityError(\n `Anthropic image source type \"${sourceType || \"unknown\"}\" is not supported.`,\n );\n}\n\nfunction anthropicToolResultOutput(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n const record = asRecord(part);\n return textValue(record.text) || textValue(record.content) || JSON.stringify(part);\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content === undefined || content === null) {\n return \"\";\n }\n return typeof content === \"object\" ? JSON.stringify(content) : String(content);\n}\n\nfunction anthropicSystemToInstructions(system: unknown): string | undefined {\n if (typeof system === \"string\") {\n return system || undefined;\n }\n if (!Array.isArray(system)) {\n return undefined;\n }\n const text = system\n .map((part) => textValue(asRecord(part).text) || textValue(part))\n .filter(Boolean)\n .join(\"\\n\");\n return text || undefined;\n}\n\nfunction anthropicTools(tools: unknown): JsonObject[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools.map((tool) => {\n const record = asRecord(tool);\n return removeUndefined({\n description: record.description,\n name: record.name,\n parameters: record.input_schema,\n strict: record.strict,\n type: \"function\",\n });\n });\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction anthropicToolChoice(toolChoice: unknown): unknown {\n if (toolChoice === undefined || toolChoice === null) {\n return undefined;\n }\n const record = asRecord(toolChoice);\n const type = textValue(record.type);\n if (type === \"auto\") {\n return \"auto\";\n }\n if (type === \"any\") {\n return \"required\";\n }\n if (type === \"none\") {\n return \"none\";\n }\n if (type === \"tool\") {\n return { name: textValue(record.name), type: \"function\" };\n }\n throw new AnthropicCompatibilityError(\n `Anthropic tool_choice type \"${type || \"unknown\"}\" is not supported.`,\n );\n}\n\nfunction anthropicThinkingToReasoning(thinking: unknown): JsonObject | undefined {\n const record = asRecord(thinking);\n if (Object.keys(record).length === 0) {\n return undefined;\n }\n const type = textValue(record.type);\n if (type && type !== \"enabled\") {\n return undefined;\n }\n const budget = typeof record.budget_tokens === \"number\" ? record.budget_tokens : 0;\n return {\n effort: budget >= 16_000 ? \"high\" : budget >= 4_000 ? \"medium\" : \"low\",\n };\n}\n\nfunction anthropicStopSequences(stopSequences: unknown): unknown {\n if (!Array.isArray(stopSequences) || stopSequences.length === 0) {\n return undefined;\n }\n return stopSequences.map((sequence) => textValue(sequence)).filter(Boolean);\n}\n\nfunction anthropicContentFromResponsesOutput(response: JsonObject): JsonObject[] {\n const content: JsonObject[] = [];\n const output = Array.isArray(response.output) ? response.output : [];\n for (const item of output) {\n const record = asRecord(item);\n const type = textValue(record.type);\n if (type === \"message\") {\n const parts = Array.isArray(record.content) ? record.content : [];\n for (const part of parts) {\n const partRecord = asRecord(part);\n const text = textValue(partRecord.text) || textValue(partRecord.output_text);\n if (text) {\n content.push({ text, type: \"text\" });\n }\n }\n continue;\n }\n if (type === \"function_call\") {\n content.push({\n id: textValue(record.call_id) || textValue(record.id) || `call_${randomId()}`,\n input: parseToolInput(textValue(record.arguments)),\n name: textValue(record.name),\n type: \"tool_use\",\n });\n }\n }\n\n if (content.length === 0) {\n const outputText = textValue(response.output_text);\n if (outputText) {\n content.push({ text: outputText, type: \"text\" });\n }\n }\n return content;\n}\n\nfunction anthropicStopReason(response: JsonObject, content: JsonObject[]): string {\n if (content.some((part) => part.type === \"tool_use\")) {\n return \"tool_use\";\n }\n const incompleteReason = textValue(asRecord(response.incomplete_details).reason);\n if (textValue(response.status) === \"incomplete\" || incompleteReason === \"max_output_tokens\") {\n return \"max_tokens\";\n }\n return \"end_turn\";\n}\n\nfunction anthropicUsage(usage: unknown): JsonObject {\n const record = asRecord(usage);\n const inputTokens = firstNumber(record.input_tokens, record.prompt_tokens) ?? 0;\n const outputTokens = firstNumber(record.output_tokens, record.completion_tokens) ?? 0;\n const details = asRecord(record.input_tokens_details);\n return removeUndefined({\n cache_creation_input_tokens: firstNumber(record.cache_creation_input_tokens),\n cache_read_input_tokens:\n firstNumber(record.cache_read_input_tokens, details.cached_tokens) ?? undefined,\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n });\n}\n\nfunction processResponsesSseBlock(\n block: string,\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n const { data, event } = parseSseBlock(block);\n if (!data || data === \"[DONE]\") {\n return;\n }\n const parsed = parseJsonObject(data);\n if (!parsed) {\n return;\n }\n const type = textValue(parsed.type) || event;\n if (type === \"response.created\") {\n const response = asRecord(parsed.response);\n state.messageId = textValue(response.id) || state.messageId;\n state.model = textValue(response.model) || state.model;\n startAnthropicMessage(state, enqueue);\n return;\n }\n if (type === \"response.output_item.added\") {\n const item = asRecord(parsed.item);\n if (textValue(item.type) === \"function_call\") {\n ensureToolBlock(state, parsed, item, enqueue);\n }\n return;\n }\n if (type === \"response.output_text.delta\") {\n const blockState = ensureTextBlock(state, parsed, enqueue);\n const delta = textValue(parsed.delta);\n if (delta) {\n blockState.sentText += delta;\n enqueue(\"content_block_delta\", {\n delta: { text: delta, type: \"text_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n return;\n }\n if (type === \"response.output_text.done\" || type === \"response.content_part.done\") {\n const blockState = ensureTextBlock(state, parsed, enqueue);\n const text = textValue(parsed.text) || textValue(asRecord(parsed.part).text);\n if (text && !blockState.sentText) {\n blockState.sentText = text;\n enqueue(\"content_block_delta\", {\n delta: { text, type: \"text_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n return;\n }\n if (type === \"response.function_call_arguments.delta\") {\n const blockState = ensureToolBlock(state, parsed, {}, enqueue);\n const delta = textValue(parsed.delta);\n if (delta) {\n blockState.sentText += delta;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: delta, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n return;\n }\n if (type === \"response.function_call_arguments.done\") {\n const blockState = ensureToolBlock(state, parsed, {}, enqueue);\n const args = textValue(parsed.arguments);\n if (args && !blockState.sentText) {\n blockState.sentText = args;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: args, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n return;\n }\n if (type === \"response.output_item.done\") {\n const item = asRecord(parsed.item);\n if (textValue(item.type) === \"function_call\") {\n const blockState = ensureToolBlock(state, parsed, item, enqueue);\n const args = textValue(item.arguments);\n if (args && !blockState.sentText) {\n blockState.sentText = args;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: args, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n }\n return;\n }\n if (type === \"response.completed\") {\n const response = asRecord(parsed.response);\n state.model = textValue(response.model) || state.model;\n state.usage = anthropicUsage(response.usage);\n finishAnthropicStream(state, enqueue);\n return;\n }\n if (type === \"response.failed\" || event === \"error\") {\n const error = asRecord(asRecord(parsed.response).error);\n enqueue(\"error\", {\n error: {\n message: textValue(error.message) || textValue(parsed.message) || \"Upstream stream failed.\",\n type: textValue(error.type) || \"api_error\",\n },\n type: \"error\",\n });\n state.completed = true;\n }\n}\n\nfunction startAnthropicMessage(\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n if (state.started) {\n return;\n }\n state.started = true;\n enqueue(\"message_start\", {\n message: {\n content: [],\n id: state.messageId,\n model: state.model,\n role: \"assistant\",\n stop_reason: null,\n stop_sequence: null,\n type: \"message\",\n usage: anthropicUsage(undefined),\n },\n type: \"message_start\",\n });\n}\n\nfunction finishAnthropicStream(\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n if (state.completed) {\n return;\n }\n startAnthropicMessage(state, enqueue);\n for (const block of [...state.blocks.values()].sort((left, right) => left.index - right.index)) {\n stopBlock(block, enqueue);\n }\n enqueue(\"message_delta\", {\n delta: {\n stop_reason: state.sawToolUse ? \"tool_use\" : \"end_turn\",\n stop_sequence: null,\n },\n type: \"message_delta\",\n usage: state.usage,\n });\n enqueue(\"message_stop\", { type: \"message_stop\" });\n state.completed = true;\n}\n\nfunction ensureTextBlock(\n state: AnthropicStreamState,\n payload: JsonObject,\n enqueue: (event: string, data: JsonObject) => void,\n): StreamBlock {\n startAnthropicMessage(state, enqueue);\n const key = `text:${indexValue(payload.output_index)}:${indexValue(payload.content_index)}`;\n let block = state.blocks.get(key);\n if (!block) {\n block = { index: state.nextBlockIndex++, sentText: \"\", stopped: false, type: \"text\" };\n state.blocks.set(key, block);\n enqueue(\"content_block_start\", {\n content_block: { text: \"\", type: \"text\" },\n index: block.index,\n type: \"content_block_start\",\n });\n }\n return block;\n}\n\nfunction ensureToolBlock(\n state: AnthropicStreamState,\n payload: JsonObject,\n item: JsonObject,\n enqueue: (event: string, data: JsonObject) => void,\n): StreamBlock {\n startAnthropicMessage(state, enqueue);\n state.sawToolUse = true;\n const key = `tool:${indexValue(payload.output_index)}`;\n let block = state.blocks.get(key);\n if (!block) {\n block = { index: state.nextBlockIndex++, sentText: \"\", stopped: false, type: \"tool_use\" };\n state.blocks.set(key, block);\n enqueue(\"content_block_start\", {\n content_block: {\n id: textValue(item.call_id) || textValue(item.id) || `call_${randomId()}`,\n input: {},\n name: textValue(item.name),\n type: \"tool_use\",\n },\n index: block.index,\n type: \"content_block_start\",\n });\n }\n return block;\n}\n\nfunction stopBlock(block: StreamBlock, enqueue: (event: string, data: JsonObject) => void): void {\n if (block.stopped) {\n return;\n }\n block.stopped = true;\n enqueue(\"content_block_stop\", {\n index: block.index,\n type: \"content_block_stop\",\n });\n}\n\nfunction parseSseBlock(block: string): { data: string; event: string } {\n let event = \"message\";\n const data: string[] = [];\n for (const line of block.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"event:\")) {\n event = trimmed.slice(\"event:\".length).trim() || event;\n } else if (trimmed.startsWith(\"data:\")) {\n data.push(trimmed.slice(\"data:\".length).trim());\n }\n }\n return { data: data.join(\"\\n\"), event };\n}\n\nfunction parseJsonObject(text: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(text));\n } catch {\n return undefined;\n }\n}\n\nfunction parseToolInput(argumentsText: string): JsonObject {\n const parsed = parseJsonObject(argumentsText);\n return parsed ?? {};\n}\n\nfunction estimatedTextSize(value: unknown): number {\n if (value === undefined || value === null) {\n return 0;\n }\n if (typeof value === \"string\") {\n return value.length;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value).length;\n }\n if (Array.isArray(value)) {\n return value.reduce((sum, item) => sum + estimatedTextSize(item), 0);\n }\n if (typeof value === \"object\") {\n return Object.values(value).reduce((sum, item) => sum + estimatedTextSize(item), 0);\n }\n return 0;\n}\n\nfunction textValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return \"\";\n}\n\nfunction firstNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction indexValue(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction encodeSse(event: string, data: JsonObject): string {\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n","import { extractTokenUsage } from \"./openai\";\nimport type {\n CopilotUsage,\n MetricsSnapshot,\n ModelTokenTotals,\n RequestObservation,\n TokenUsage,\n} from \"./types\";\nimport { asRecord } from \"./util\";\n\n/** Content-Type for the Prometheus text exposition format (version 0.0.4). */\nexport const PROMETHEUS_CONTENT_TYPE = \"text/plain; version=0.0.4; charset=utf-8\";\n\n/** Upper bounds (seconds) for the request-duration histogram buckets. */\nconst DURATION_BUCKETS_SECONDS = [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60] as const;\n\n/** Cap on bytes buffered or scanned while extracting usage from a response body. */\nconst USAGE_BUFFER_LIMIT_BYTES = 16 * 1024 * 1024;\n\n/** Bound the distinct model labels so a hostile client cannot blow up cardinality. */\nconst MAX_TRACKED_MODELS = 200;\nconst MAX_MODEL_LABEL_LENGTH = 200;\n\n// Unit separator (ASCII 0x1f): joins label parts; cannot collide with a label value.\nconst LABEL_SEPARATOR = \"\\u001f\";\nconst UNKNOWN_MODEL = \"unknown\";\n\ninterface RouteDuration {\n buckets: number[];\n count: number;\n sum: number;\n}\n\nfunction emptyModelTotals(): ModelTokenTotals {\n return { cached: 0, completion: 0, prompt: 0, reasoning: 0, requests: 0, total: 0 };\n}\n\n/**\n * In-process metrics for the running proxy. Counters are monotonic for the life\n * of the process and reset on restart, which Prometheus handles natively. The\n * registry is intentionally allocation-light and synchronous; the single-\n * threaded event loop makes its mutations atomic with respect to each request.\n */\nexport class MetricsRegistry {\n readonly #startedAtMs: number;\n #inFlight = 0;\n #requests = new Map<string, number>();\n #durations = new Map<string, RouteDuration>();\n #tokens = new Map<string, ModelTokenTotals>();\n #upstream = new Map<string, number>();\n #copilotQuota?: CopilotUsage;\n\n constructor(options: { now?: () => number } = {}) {\n this.#startedAtMs = (options.now ?? Date.now)();\n }\n\n /** Mark a request as started; pair with exactly one {@link observe}. */\n startRequest(): void {\n this.#inFlight += 1;\n }\n\n /** Record a completed request and clear its in-flight slot. */\n observe(observation: RequestObservation): void {\n if (this.#inFlight > 0) {\n this.#inFlight -= 1;\n }\n const key = labelKey(observation.route, observation.method, String(observation.status));\n this.#requests.set(key, (this.#requests.get(key) ?? 0) + 1);\n this.#observeDuration(observation.route, observation.durationMs / 1000);\n }\n\n /** Accumulate token counts for a model from one upstream completion. */\n recordTokens(model: string, usage: TokenUsage): void {\n const name = this.#modelLabel(model);\n const totals = this.#tokens.get(name) ?? emptyModelTotals();\n totals.requests += 1;\n totals.prompt += nonNegative(usage.promptTokens);\n totals.completion += nonNegative(usage.completionTokens);\n totals.total += nonNegative(usage.totalTokens);\n totals.reasoning += nonNegative(usage.reasoningTokens ?? 0);\n totals.cached += nonNegative(usage.cachedTokens ?? 0);\n this.#tokens.set(name, totals);\n }\n\n /** Record one upstream Copilot call and whether it succeeded. */\n recordUpstream(path: string, ok: boolean): void {\n const key = labelKey(path, ok ? \"ok\" : \"error\");\n this.#upstream.set(key, (this.#upstream.get(key) ?? 0) + 1);\n }\n\n /** Store the latest Copilot quota so /metrics can expose it as gauges. */\n recordCopilotQuota(usage: CopilotUsage): void {\n this.#copilotQuota = usage;\n }\n\n // Sanitize the model into a bounded, control-char-free label. The model can\n // originate from a client request, so cap its length, strip characters that\n // would corrupt the exposition format, and fold overflow past the cardinality\n // limit into UNKNOWN_MODEL to keep the series count bounded.\n #modelLabel(model: string): string {\n const cleaned =\n model\n // biome-ignore lint/suspicious/noControlCharactersInRegex: stripping control chars is the intent.\n .replace(/[\\u0000-\\u001f\\u007f]/g, \"\")\n .trim()\n .slice(0, MAX_MODEL_LABEL_LENGTH) || UNKNOWN_MODEL;\n if (!this.#tokens.has(cleaned) && this.#tokens.size >= MAX_TRACKED_MODELS) {\n return UNKNOWN_MODEL;\n }\n return cleaned;\n }\n\n #observeDuration(route: string, seconds: number): void {\n const value = Number.isFinite(seconds) && seconds >= 0 ? seconds : 0;\n const entry = this.#durations.get(route) ?? {\n buckets: new Array(DURATION_BUCKETS_SECONDS.length).fill(0),\n count: 0,\n sum: 0,\n };\n entry.count += 1;\n entry.sum += value;\n // Values larger than the last bucket bound only appear in the +Inf bucket,\n // which renderPrometheus derives from entry.count.\n const index = DURATION_BUCKETS_SECONDS.findIndex((bound) => value <= bound);\n if (index !== -1) {\n entry.buckets[index] = (entry.buckets[index] ?? 0) + 1;\n }\n this.#durations.set(route, entry);\n }\n\n /** A JSON-friendly view of the current counters. */\n snapshot(now: () => number = Date.now): MetricsSnapshot {\n const byRoute: Record<string, number> = {};\n const byStatus: Record<string, number> = {};\n let requestsTotal = 0;\n for (const [key, count] of this.#requests) {\n const [route = \"\", , status = \"\"] = key.split(LABEL_SEPARATOR);\n byRoute[route] = (byRoute[route] ?? 0) + count;\n byStatus[status] = (byStatus[status] ?? 0) + count;\n requestsTotal += count;\n }\n\n const byModel: Record<string, ModelTokenTotals> = {};\n const tokenTotals = { cached: 0, completion: 0, prompt: 0, reasoning: 0, total: 0 };\n for (const [model, totals] of this.#tokens) {\n byModel[model] = { ...totals };\n tokenTotals.prompt += totals.prompt;\n tokenTotals.completion += totals.completion;\n tokenTotals.total += totals.total;\n tokenTotals.reasoning += totals.reasoning;\n tokenTotals.cached += totals.cached;\n }\n\n let upstreamTotal = 0;\n let upstreamErrors = 0;\n for (const [key, count] of this.#upstream) {\n upstreamTotal += count;\n if (key.endsWith(`${LABEL_SEPARATOR}error`)) {\n upstreamErrors += count;\n }\n }\n\n return {\n inFlight: this.#inFlight,\n requests: { byRoute, byStatus, total: requestsTotal },\n startedAt: new Date(this.#startedAtMs).toISOString(),\n tokens: { byModel, ...tokenTotals },\n upstream: { errors: upstreamErrors, total: upstreamTotal },\n uptimeSeconds: Math.max(0, Math.round((now() - this.#startedAtMs) / 1000)),\n };\n }\n\n /** Render the Prometheus text exposition format (version 0.0.4). */\n renderPrometheus(now: () => number = Date.now): string {\n const lines: string[] = [];\n\n lines.push(\"# HELP hoopilot_process_start_time_seconds Unix epoch when the proxy started.\");\n lines.push(\"# TYPE hoopilot_process_start_time_seconds gauge\");\n lines.push(`hoopilot_process_start_time_seconds ${this.#startedAtMs / 1000}`);\n\n lines.push(\"# HELP hoopilot_uptime_seconds Seconds since the proxy started.\");\n lines.push(\"# TYPE hoopilot_uptime_seconds gauge\");\n lines.push(`hoopilot_uptime_seconds ${Math.max(0, (now() - this.#startedAtMs) / 1000)}`);\n\n lines.push(\"# HELP hoopilot_requests_in_flight Requests currently being served.\");\n lines.push(\"# TYPE hoopilot_requests_in_flight gauge\");\n lines.push(`hoopilot_requests_in_flight ${this.#inFlight}`);\n\n lines.push(\"# HELP hoopilot_requests_total Completed requests by route, method, and status.\");\n lines.push(\"# TYPE hoopilot_requests_total counter\");\n for (const [key, count] of this.#requests) {\n const [route = \"\", method = \"\", status = \"\"] = key.split(LABEL_SEPARATOR);\n lines.push(`hoopilot_requests_total${labels({ method, route, status })} ${count}`);\n }\n\n lines.push(\n \"# HELP hoopilot_upstream_requests_total Copilot upstream calls by path and outcome.\",\n );\n lines.push(\"# TYPE hoopilot_upstream_requests_total counter\");\n for (const [key, count] of this.#upstream) {\n const [path = \"\", outcome = \"\"] = key.split(LABEL_SEPARATOR);\n lines.push(`hoopilot_upstream_requests_total${labels({ outcome, path })} ${count}`);\n }\n\n lines.push(\n \"# HELP hoopilot_tokens_total Tokens reported by upstream usage, by model and type.\",\n );\n lines.push(\"# TYPE hoopilot_tokens_total counter\");\n for (const [model, totals] of this.#tokens) {\n lines.push(`hoopilot_tokens_total${labels({ model, type: \"prompt\" })} ${totals.prompt}`);\n lines.push(\n `hoopilot_tokens_total${labels({ model, type: \"completion\" })} ${totals.completion}`,\n );\n lines.push(\n `hoopilot_tokens_total${labels({ model, type: \"reasoning\" })} ${totals.reasoning}`,\n );\n lines.push(`hoopilot_tokens_total${labels({ model, type: \"cached\" })} ${totals.cached}`);\n }\n\n lines.push(\"# HELP hoopilot_model_requests_total Completions with usage observed, by model.\");\n lines.push(\"# TYPE hoopilot_model_requests_total counter\");\n for (const [model, totals] of this.#tokens) {\n lines.push(`hoopilot_model_requests_total${labels({ model })} ${totals.requests}`);\n }\n\n lines.push(\"# HELP hoopilot_request_duration_seconds Request duration by route.\");\n lines.push(\"# TYPE hoopilot_request_duration_seconds histogram\");\n for (const [route, entry] of this.#durations) {\n let cumulative = 0;\n for (let i = 0; i < DURATION_BUCKETS_SECONDS.length; i += 1) {\n cumulative += entry.buckets[i] ?? 0;\n const le = formatNumber(DURATION_BUCKETS_SECONDS[i] ?? 0);\n lines.push(\n `hoopilot_request_duration_seconds_bucket${labels({ le, route })} ${cumulative}`,\n );\n }\n lines.push(\n `hoopilot_request_duration_seconds_bucket${labels({ le: \"+Inf\", route })} ${entry.count}`,\n );\n lines.push(`hoopilot_request_duration_seconds_sum${labels({ route })} ${entry.sum}`);\n lines.push(`hoopilot_request_duration_seconds_count${labels({ route })} ${entry.count}`);\n }\n\n this.#renderCopilotQuota(lines);\n\n return `${lines.join(\"\\n\")}\\n`;\n }\n\n #renderCopilotQuota(lines: string[]): void {\n const usage = this.#copilotQuota;\n if (!usage) {\n return;\n }\n const categories = Object.entries(usage.quotas);\n\n const gauge = (\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => number | undefined,\n ): void => {\n const present = categories.filter(([, quota]) => pick(quota) !== undefined);\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, quota] of present) {\n lines.push(`hoopilot_copilot_quota_${suffix}${labels({ category })} ${pick(quota)}`);\n }\n };\n\n gauge(\"remaining\", \"Remaining quota for the Copilot category.\", (q) => q.remaining);\n gauge(\"entitlement\", \"Quota entitlement for the Copilot category.\", (q) => q.entitlement);\n gauge(\"used\", \"Used quota (entitlement minus remaining) for the category.\", (q) => q.used);\n gauge(\"overage_count\", \"Overage count for the Copilot category.\", (q) => q.overageCount);\n gauge(\n \"overage_entitlement\",\n \"Overage entitlement for the Copilot category.\",\n (q) => q.overageEntitlement,\n );\n gauge(\n \"percent_remaining\",\n \"Percent of quota remaining for the Copilot category.\",\n (q) => q.percentRemaining,\n );\n booleanGauge(\n \"unlimited\",\n \"Whether the Copilot quota category is unlimited.\",\n (q) => q.unlimited,\n );\n booleanGauge(\n \"overage_permitted\",\n \"Whether overage is permitted for the Copilot category.\",\n (q) => q.overagePermitted,\n );\n booleanGauge(\"has_quota\", \"Whether the Copilot quota category has a quota.\", (q) => q.hasQuota);\n booleanGauge(\n \"token_based_billing\",\n \"Whether the Copilot quota category uses token-based billing.\",\n (q) => q.tokenBasedBilling,\n );\n dateGauge(\n \"category_reset_timestamp_seconds\",\n \"Unix epoch of the Copilot category-specific quota reset.\",\n (q) => q.quotaResetAt,\n );\n dateGauge(\n \"category_snapshot_timestamp_seconds\",\n \"Unix epoch of the Copilot category quota snapshot.\",\n (q) => q.timestampUtc,\n );\n\n const resetMs = usage.quotaResetDate ? Date.parse(usage.quotaResetDate) : Number.NaN;\n if (Number.isFinite(resetMs)) {\n lines.push(\n \"# HELP hoopilot_copilot_quota_reset_timestamp_seconds Unix epoch of the next reset.\",\n );\n lines.push(\"# TYPE hoopilot_copilot_quota_reset_timestamp_seconds gauge\");\n lines.push(`hoopilot_copilot_quota_reset_timestamp_seconds ${resetMs / 1000}`);\n }\n\n if (usage.plan || usage.accessTypeSku) {\n lines.push(\"# HELP hoopilot_copilot_info Copilot plan metadata as a constant-1 info gauge.\");\n lines.push(\"# TYPE hoopilot_copilot_info gauge\");\n lines.push(\n `hoopilot_copilot_info${labels({\n access_type_sku: usage.accessTypeSku ?? \"\",\n plan: usage.plan ?? \"\",\n })} 1`,\n );\n }\n\n function booleanGauge(\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => boolean | undefined,\n ): void {\n const present = categories.filter(([, quota]) => pick(quota) !== undefined);\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, quota] of present) {\n lines.push(\n `hoopilot_copilot_quota_${suffix}${labels({ category })} ${pick(quota) ? 1 : 0}`,\n );\n }\n }\n\n function dateGauge(\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => string | undefined,\n ): void {\n const present = categories\n .map(([category, quota]) => [category, Date.parse(pick(quota) ?? \"\")] as const)\n .filter(([, timestamp]) => Number.isFinite(timestamp));\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, timestamp] of present) {\n lines.push(`hoopilot_copilot_quota_${suffix}${labels({ category })} ${timestamp / 1000}`);\n }\n }\n }\n}\n\n/**\n * Tee `response`'s body so the client receives an unchanged copy while a\n * background reader extracts token usage. Returns a new Response carrying the\n * client-facing branch and the original status/headers. Usage extraction never\n * throws into the client stream: a parse failure or an aborted client simply\n * yields no usage. When the body is absent the response is returned untouched.\n *\n * Pass the request's `signal` so a client disconnect cancels the observer\n * branch; combined with the runtime cancelling the client branch, that releases\n * the shared upstream connection instead of draining it in the background.\n */\nexport function observeResponseUsage(\n response: Response,\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n signal?: AbortSignal,\n): Response {\n const body = response.body;\n if (!body) {\n return response;\n }\n const [clientBranch, observerBranch] = body.tee();\n const isSse = response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n void consumeUsage(observerBranch, isSse, fallbackModel, onUsage, signal).catch(() => {});\n return new Response(clientBranch, {\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\nasync function consumeUsage(\n stream: ReadableStream<Uint8Array>,\n isSse: boolean,\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n signal?: AbortSignal,\n): Promise<void> {\n const reader = stream.getReader();\n const onAbort = () => {\n reader.cancel().catch(() => {});\n };\n if (signal?.aborted) {\n reader.cancel().catch(() => {});\n } else {\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const decoder = new TextDecoder();\n let model = fallbackModel;\n let usage: TokenUsage | undefined;\n let buffer = \"\";\n let bufferedBytes = 0;\n let overflowed = false;\n\n const consider = (payload: unknown): void => {\n const record = asRecord(payload);\n const found =\n extractTokenUsage(record.usage) ?? extractTokenUsage(asRecord(record.response).usage);\n if (found) {\n usage = found;\n }\n const candidateModel = modelText(record.model) || modelText(asRecord(record.response).model);\n if (candidateModel) {\n model = candidateModel;\n }\n };\n\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n const chunk = decoder.decode(result.value, { stream: true });\n if (isSse) {\n buffer += chunk;\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n considerSseLine(line, consider);\n }\n // Drop a pathologically long newline-less line so the buffer stays bounded.\n if (buffer.length > USAGE_BUFFER_LIMIT_BYTES) {\n buffer = \"\";\n }\n } else if (!overflowed) {\n bufferedBytes += result.value.byteLength;\n if (bufferedBytes > USAGE_BUFFER_LIMIT_BYTES) {\n overflowed = true;\n buffer = \"\";\n } else {\n buffer += chunk;\n }\n }\n }\n // Flush any trailing bytes the streaming decoder is still holding.\n const finalBuffer = buffer + decoder.decode();\n if (isSse) {\n if (finalBuffer) {\n considerSseLine(finalBuffer, consider);\n }\n } else if (!overflowed && finalBuffer) {\n const parsed = safeParse(finalBuffer);\n if (parsed !== undefined) {\n consider(parsed);\n }\n }\n } finally {\n signal?.removeEventListener(\"abort\", onAbort);\n reader.releaseLock();\n }\n\n if (usage) {\n onUsage(model, usage);\n }\n}\n\nfunction considerSseLine(line: string, consider: (payload: unknown) => void): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n const parsed = safeParse(data);\n if (parsed !== undefined) {\n consider(parsed);\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction modelText(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction nonNegative(value: number): number {\n return Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction labelKey(...parts: string[]): string {\n return parts.join(LABEL_SEPARATOR);\n}\n\nfunction labels(pairs: Record<string, string>): string {\n const entries = Object.entries(pairs);\n if (entries.length === 0) {\n return \"\";\n }\n const rendered = entries.map(([name, value]) => `${name}=\"${escapeLabelValue(value)}\"`);\n return `{${rendered.join(\",\")}}`;\n}\n\nfunction escapeLabelValue(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\");\n}\n\nfunction formatNumber(value: number): string {\n return Number.isInteger(value) ? value.toString() : String(value);\n}\n","import {\n AnthropicCompatibilityError,\n anthropicMessagesToResponsesRequest,\n estimateAnthropicMessageTokens,\n responsesResponseToAnthropicMessage,\n responsesStreamToAnthropicStream,\n} from \"./anthropic\";\nimport { CopilotAuthError } from \"./auth\";\nimport { CopilotClient, normalizeCopilotUsage } from \"./copilot\";\nimport { createHoopilotLogger, errorDetails, noopLogger, shouldCreateLogger } from \"./logger\";\nimport { MetricsRegistry, observeResponseUsage, PROMETHEUS_CONTENT_TYPE } from \"./metrics\";\nimport {\n chatCompletionToCompletion,\n completionStreamFromChatStream,\n completionsRequestToChatCompletion,\n extractTokenUsage,\n fallbackModels,\n normalizeChatCompletionRequest,\n normalizeModelsResponse,\n normalizeRequestedModel,\n OpenAICompatibilityError,\n} from \"./openai\";\nimport type {\n CopilotUsage,\n HoopilotLogger,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n StartedHoopilotServer,\n TokenUsage,\n} from \"./types\";\nimport { asRecord, envValue } from \"./util\";\n\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_PORT = 4141;\nconst FORBIDDEN_BROWSER_ORIGIN_MESSAGE =\n \"Browser-origin requests require HOOPILOT_API_KEY unless the Origin is loopback.\";\nconst INVALID_JSON_MESSAGE = \"Request body must be valid JSON.\";\nconst JSON_OBJECT_MESSAGE = \"Request body must be a JSON object.\";\nconst MAX_REQUEST_BODY_BYTES = 16 * 1024 * 1024;\nconst REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;\nconst REQUEST_TOO_LARGE_MESSAGE = `Request body must be ${MAX_REQUEST_BODY_BYTES} bytes or smaller.`;\nconst USAGE_CACHE_TTL_MS = 60_000;\n\ninterface UsageReadResult {\n copilot?: CopilotUsage;\n error?: string;\n}\n\ntype UsageReader = (signal?: AbortSignal) => Promise<UsageReadResult>;\ntype TokenRecorder = (model: string, usage: TokenUsage) => void;\n\nclass RequestBodyTooLargeError extends Error {\n constructor() {\n super(REQUEST_TOO_LARGE_MESSAGE);\n this.name = \"RequestBodyTooLargeError\";\n }\n}\n\nexport function createHoopilotHandler(\n options: HoopilotServerOptions = {},\n): (request: Request) => Promise<Response> {\n const client = new CopilotClient(options);\n const apiKey = options.apiKey ?? envValue(options.env?.HOOPILOT_API_KEY);\n const logger = serverLogger(options);\n const metrics = options.metrics ?? new MetricsRegistry();\n const readUsage = createUsageReader(client, metrics);\n const recordTokens: TokenRecorder = (model, usage) => metrics.recordTokens(model, usage);\n\n return async (request: Request): Promise<Response> => {\n const startedAt = performance.now();\n const url = new URL(request.url);\n const apiPath = canonicalApiPath(url.pathname);\n const requestId = requestIdFor(request);\n const route = routeFor(request.method, apiPath);\n const requestLogger = logger.child({\n method: request.method,\n path: url.pathname,\n requestId,\n route,\n });\n metrics.startRequest();\n const finish = (response: Response): Response =>\n finishResponse(response, {\n logger: requestLogger,\n method: request.method,\n metrics,\n requestId,\n route,\n startedAt,\n });\n\n const browserOrigin = forbiddenBrowserOrigin(request, apiKey);\n if (browserOrigin) {\n requestLogger.warn(\n { event: \"http.request.forbidden_origin\", origin: browserOrigin },\n \"blocked unauthenticated browser-origin request\",\n );\n return finish(jsonError(403, \"forbidden_origin\", FORBIDDEN_BROWSER_ORIGIN_MESSAGE));\n }\n\n if (request.method === \"OPTIONS\") {\n return finish(new Response(null, { headers: corsHeaders() }));\n }\n\n if (!isAuthorized(request, apiKey)) {\n requestLogger.warn({ event: \"http.request.unauthorized\" }, \"invalid hoopilot api key\");\n return finish(jsonError(401, \"invalid_api_key\", \"Invalid or missing Hoopilot API key.\"));\n }\n\n try {\n if (request.method === \"GET\" && (apiPath === \"/\" || apiPath === \"/healthz\")) {\n return finish(jsonResponse({ name: \"hoopilot\", object: \"health\", status: \"ok\" }));\n }\n if (request.method === \"GET\" && apiPath === \"/metrics\") {\n return finish(metricsResponse(metrics));\n }\n if (request.method === \"GET\" && apiPath === \"/v1/usage\") {\n return finish(await handleUsage(metrics, readUsage, request.signal));\n }\n if (request.method === \"GET\" && apiPath === \"/v1/responses\") {\n return finish(websocketUnsupportedResponse());\n }\n if (request.method === \"GET\" && apiPath === \"/v1/models\") {\n return finish(await handleModels(client, metrics, request.signal, requestLogger));\n }\n if (request.method === \"POST\" && apiPath === \"/v1/messages\") {\n return finish(\n await handleAnthropicMessages(client, metrics, recordTokens, request, requestLogger),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/messages/count_tokens\") {\n return finish(handleAnthropicCountTokens(await readJson(request)));\n }\n if (request.method === \"POST\" && apiPath === \"/v1/chat/completions\") {\n return finish(\n await handleChatCompletions(client, metrics, recordTokens, request, requestLogger),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/completions\") {\n return finish(\n await handleCompletions(client, metrics, recordTokens, request, requestLogger),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/responses\") {\n return finish(await handleResponses(client, metrics, recordTokens, request, requestLogger));\n }\n return finish(jsonError(404, \"not_found\", `No route for ${request.method} ${url.pathname}.`));\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"copilot.auth.missing\" },\n \"copilot auth failed\",\n );\n return finish(jsonError(401, \"copilot_auth_error\", error.message));\n }\n const message = errorMessage(error);\n if (message === INVALID_JSON_MESSAGE || message === JSON_OBJECT_MESSAGE) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body was not usable json\",\n );\n return finish(jsonError(400, \"invalid_request_error\", message));\n } else if (\n error instanceof OpenAICompatibilityError ||\n error instanceof AnthropicCompatibilityError\n ) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body used unsupported compatibility fields\",\n );\n return finish(jsonError(400, \"invalid_request_error\", message));\n } else if (error instanceof RequestBodyTooLargeError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body exceeded size limit\",\n );\n return finish(jsonError(413, \"request_too_large\", message));\n } else {\n requestLogger.error(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request failed\",\n );\n }\n return finish(jsonError(500, \"internal_error\", message));\n }\n };\n}\n\nexport function startHoopilotServer(options: HoopilotServerOptions = {}): StartedHoopilotServer {\n const host = options.host ?? envValue(options.env?.HOST) ?? DEFAULT_HOST;\n const port = normalizeServerPort(options.port ?? envValue(options.env?.PORT) ?? DEFAULT_PORT);\n const apiKey = options.apiKey ?? envValue(options.env?.HOOPILOT_API_KEY);\n const allowUnauthenticated =\n options.allowUnauthenticated ?? envValue(options.env?.HOOPILOT_ALLOW_UNAUTHENTICATED) === \"1\";\n\n if (!isLoopbackHost(host) && !apiKey && !allowUnauthenticated) {\n throw new Error(\n \"Refusing to listen on a non-loopback host without HOOPILOT_API_KEY. Set an API key or pass --allow-unauthenticated.\",\n );\n }\n\n const server = Bun.serve({\n fetch: createHoopilotHandler({\n ...options,\n apiKey,\n host,\n port,\n }),\n hostname: host,\n port,\n });\n\n return {\n server,\n url: `http://${urlHost(host)}:${server.port}`,\n };\n}\n\nasync function handleAnthropicMessages(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const anthropicRequest = await readJson(request);\n const responsesRequest = anthropicMessagesToResponsesRequest(anthropicRequest);\n const upstream = await client.responses(JSON.stringify(responsesRequest), request.signal);\n metrics.recordUpstream(\"/responses\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/responses\", upstream.status);\n const model = normalizeRequestedModel(responsesRequest.model);\n\n if (isStreamingResponse(upstream) && upstream.body) {\n const observed = observeResponseUsage(upstream, model, recordTokens, request.signal);\n if (!observed.body) {\n return proxyResponse(observed);\n }\n return proxyResponse(\n new Response(responsesStreamToAnthropicStream(observed.body, { model }), {\n headers: observed.headers,\n status: observed.status,\n statusText: observed.statusText,\n }),\n );\n }\n\n const body = asRecord(await upstream.json());\n const usage = extractTokenUsage(body.usage);\n if (usage) {\n const responseModel = typeof body.model === \"string\" ? body.model.trim() : \"\";\n recordTokens(responseModel || model, usage);\n }\n return jsonResponse(responsesResponseToAnthropicMessage(body, model));\n}\n\nfunction handleAnthropicCountTokens(body: JsonObject): Response {\n return jsonResponse(estimateAnthropicMessageTokens(body));\n}\n\nasync function handleModels(\n client: CopilotClient,\n metrics: MetricsRegistry,\n signal: AbortSignal,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.models(signal);\n metrics.recordUpstream(\"/models\", upstream.ok);\n if (!upstream.ok) {\n if (isUpstreamAuthStatus(upstream.status)) {\n return proxyError(upstream, logger);\n }\n logger.warn(\n {\n event: \"copilot.models.fallback\",\n upstreamPath: \"/models\",\n upstreamStatus: upstream.status,\n },\n \"falling back to built-in model list\",\n );\n return jsonResponse({ data: fallbackModels(), object: \"list\" });\n }\n logUpstreamSuccess(logger, \"/models\", upstream.status);\n return jsonResponse(normalizeModelsResponse(await upstream.json()));\n}\n\nasync function handleChatCompletions(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const chatRequest = normalizeChatCompletionRequest(await readJson(request));\n const upstream = await client.chatCompletions(chatRequest, request.signal);\n metrics.recordUpstream(\"/chat/completions\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n const model = normalizeRequestedModel(chatRequest.model);\n return proxyResponse(observeResponseUsage(upstream, model, recordTokens, request.signal));\n}\n\nasync function handleCompletions(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJson(request);\n const upstream = await client.chatCompletions(\n completionsRequestToChatCompletion(body),\n request.signal,\n );\n metrics.recordUpstream(\"/chat/completions\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n const model = normalizeRequestedModel(body.model);\n // A streaming request yields chat-completion SSE; convert each chunk to the\n // legacy completions stream shape instead of calling .json() on the body.\n if (isStreamingResponse(upstream) && upstream.body) {\n return proxyResponse(\n observeResponseUsage(\n new Response(completionStreamFromChatStream(upstream.body), {\n headers: upstream.headers,\n status: upstream.status,\n statusText: upstream.statusText,\n }),\n model,\n recordTokens,\n request.signal,\n ),\n );\n }\n const completion = asRecord(await upstream.json());\n const usage = extractTokenUsage(completion.usage);\n if (usage) {\n const responseModel = typeof completion.model === \"string\" ? completion.model.trim() : \"\";\n recordTokens(responseModel || model, usage);\n }\n return jsonResponse(chatCompletionToCompletion(completion));\n}\n\nasync function handleResponses(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n): Promise<Response> {\n const body = await readJsonText(request);\n const upstream = await client.responses(body, request.signal);\n metrics.recordUpstream(\"/responses\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/responses\", upstream.status);\n const model = normalizeRequestedModel(asRecord(safeParseJson(body)).model);\n return proxyResponse(observeResponseUsage(upstream, model, recordTokens, request.signal));\n}\n\nasync function proxyError(upstream: Response, logger: HoopilotLogger): Promise<Response> {\n const text = await upstream.text();\n if (isUpstreamAuthStatus(upstream.status)) {\n logger.warn(\n { event: \"copilot.auth.rejected\", upstreamStatus: upstream.status },\n \"copilot rejected credential or account access\",\n );\n return jsonError(401, \"copilot_auth_error\", upstreamAuthMessage(text || upstream.statusText));\n }\n logger.warn(\n { event: \"copilot.request.failed\", upstreamStatus: upstream.status },\n \"copilot upstream request failed\",\n );\n return upstreamErrorResponse(upstream.status, text || upstream.statusText);\n}\n\nfunction proxyResponse(upstream: Response): Response {\n const headers = new Headers(upstream.headers);\n headers.delete(\"content-encoding\");\n headers.delete(\"content-length\");\n headers.delete(\"transfer-encoding\");\n for (const [key, value] of Object.entries(corsHeaders())) {\n headers.set(key, value);\n }\n return new Response(upstream.body, {\n headers,\n status: upstream.status,\n statusText: upstream.statusText,\n });\n}\n\nasync function readJson(request: Request): Promise<JsonObject> {\n const text = await readRequestText(request);\n return parseJsonObject(text);\n}\n\nfunction parseJsonObject(text: string): JsonObject {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new Error(INVALID_JSON_MESSAGE);\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(JSON_OBJECT_MESSAGE);\n }\n return parsed as JsonObject;\n}\n\nasync function readJsonText(request: Request): Promise<string> {\n const text = await readRequestText(request);\n parseJsonObject(text);\n return text;\n}\n\nasync function readRequestText(request: Request): Promise<string> {\n const contentLength = request.headers.get(\"content-length\");\n if (contentLength) {\n const declaredBytes = Number(contentLength);\n if (Number.isFinite(declaredBytes) && declaredBytes > MAX_REQUEST_BODY_BYTES) {\n throw new RequestBodyTooLargeError();\n }\n }\n\n const body = request.body;\n if (!body) {\n return \"\";\n }\n\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let bytes = 0;\n let text = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n return `${text}${decoder.decode()}`;\n }\n bytes += value.byteLength;\n if (bytes > MAX_REQUEST_BODY_BYTES) {\n await reader.cancel().catch(() => {});\n throw new RequestBodyTooLargeError();\n }\n text += decoder.decode(value, { stream: true });\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction jsonResponse(body: JsonObject, status = 200): Response {\n return new Response(JSON.stringify(body), {\n headers: {\n ...corsHeaders(),\n \"content-type\": \"application/json; charset=utf-8\",\n },\n status,\n });\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return jsonResponse(\n {\n error: {\n code,\n message,\n type: code,\n },\n },\n status,\n );\n}\n\nfunction upstreamErrorResponse(status: number, text: string): Response {\n const parsedError = asRecord(asRecord(safeParseJson(text)).error);\n if (Object.keys(parsedError).length > 0) {\n return jsonResponse({ error: parsedError }, status);\n }\n return jsonError(status, \"copilot_error\", text);\n}\n\nfunction websocketUnsupportedResponse(): Response {\n const response = jsonError(\n 426,\n \"websocket_not_supported\",\n \"Hoopilot does not support Responses WebSocket transport; retry with HTTP Responses API.\",\n );\n response.headers.set(\"upgrade\", \"websocket\");\n return response;\n}\n\nfunction corsHeaders(): Record<string, string> {\n return {\n \"access-control-allow-headers\":\n \"anthropic-beta, anthropic-dangerous-direct-browser-access, anthropic-version, authorization, content-type, x-api-key, x-request-id\",\n \"access-control-allow-methods\": \"GET, POST, OPTIONS\",\n \"access-control-allow-origin\": \"*\",\n \"access-control-expose-headers\": \"x-request-id\",\n };\n}\n\nfunction isAuthorized(request: Request, apiKey: string | undefined): boolean {\n if (!apiKey) {\n return true;\n }\n const authorization = request.headers.get(\"authorization\") ?? \"\";\n const bearer = authorization.match(/^Bearer\\s+(.+)$/i)?.[1];\n return bearer === apiKey || request.headers.get(\"x-api-key\") === apiKey;\n}\n\nfunction forbiddenBrowserOrigin(request: Request, apiKey: string | undefined): string | undefined {\n if (apiKey) {\n return undefined;\n }\n\n const origin = request.headers.get(\"origin\")?.trim();\n if (origin) {\n return isLoopbackOrigin(origin) ? undefined : origin;\n }\n\n const fetchSite = request.headers.get(\"sec-fetch-site\")?.toLowerCase();\n return fetchSite === \"cross-site\" ? \"cross-site\" : undefined;\n}\n\nfunction isUpstreamAuthStatus(status: number): boolean {\n return status === 401 || status === 403;\n}\n\nfunction upstreamAuthMessage(message: string): string {\n return `GitHub Copilot rejected the credential or account access: ${message}`;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"::1\" || host === \"[::1]\";\n}\n\nfunction urlHost(host: string): string {\n return host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host;\n}\n\nfunction isLoopbackOrigin(origin: string): boolean {\n try {\n return isLoopbackHost(new URL(origin).hostname.toLowerCase());\n } catch {\n return false;\n }\n}\n\nfunction normalizeServerPort(value: number | string): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n throw new Error(`Invalid port: ${value}.`);\n }\n return port;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction serverLogger(options: HoopilotServerOptions): HoopilotLogger {\n if (options.logger) {\n return options.logger.child({ component: \"server\" });\n }\n if (shouldCreateLogger(options)) {\n return createHoopilotLogger({\n env: options.env,\n format: options.logFormat,\n level: options.logLevel,\n }).child({ component: \"server\" });\n }\n return noopLogger;\n}\n\nfunction finishResponse(\n response: Response,\n options: {\n logger: HoopilotLogger;\n method: string;\n metrics: MetricsRegistry;\n requestId: string;\n route: string;\n startedAt: number;\n },\n): Response {\n const withRequestId = responseWithRequestId(response, options.requestId);\n const stream = isStreamingResponse(withRequestId);\n const status = withRequestId.status;\n // Record metrics and log when the response is truly done. For a streamed body\n // that is when the client finishes receiving (or aborts) — so the in-flight\n // gauge and duration histogram reflect the full serving lifetime, not just the\n // time to upstream headers.\n const complete = (): void => {\n const durationMs = Math.round((performance.now() - options.startedAt) * 100) / 100;\n options.metrics.observe({ durationMs, method: options.method, route: options.route, status });\n logRequestCompleted(options.logger, status, stream, durationMs);\n };\n\n if (stream && withRequestId.body) {\n return new Response(trackStreamCompletion(withRequestId.body, complete), {\n headers: withRequestId.headers,\n status,\n statusText: withRequestId.statusText,\n });\n }\n complete();\n return withRequestId;\n}\n\nfunction responseWithRequestId(response: Response, requestId: string): Response {\n const headers = new Headers(response.headers);\n headers.set(\"x-request-id\", requestId);\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\n// Re-stream `body`, invoking `onComplete` exactly once when the stream finishes,\n// is cancelled (client disconnect), or errors — so callers can measure the true\n// end of a streamed response.\nfunction trackStreamCompletion(\n body: ReadableStream<Uint8Array>,\n onComplete: () => void,\n): ReadableStream<Uint8Array> {\n const reader = body.getReader();\n let fired = false;\n const fire = (): void => {\n if (!fired) {\n fired = true;\n onComplete();\n }\n };\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const { done, value } = await reader.read();\n if (done) {\n controller.close();\n fire();\n return;\n }\n controller.enqueue(value);\n } catch (error) {\n fire();\n controller.error(error);\n }\n },\n cancel(reason) {\n fire();\n return reader.cancel(reason);\n },\n });\n}\n\nfunction logRequestCompleted(\n logger: HoopilotLogger,\n status: number,\n stream: boolean,\n durationMs: number,\n): void {\n const fields: LogFields = {\n durationMs,\n event: \"http.request.completed\",\n status,\n stream,\n };\n if (status >= 500) {\n logger.error(fields, \"request completed with server error\");\n return;\n }\n if (status >= 400) {\n logger.warn(fields, \"request completed with client error\");\n return;\n }\n logger.info(fields, \"request completed\");\n}\n\nfunction requestIdFor(request: Request): string {\n const existing = request.headers.get(\"x-request-id\")?.trim();\n return existing && REQUEST_ID_PATTERN.test(existing) ? existing : crypto.randomUUID();\n}\n\nfunction canonicalApiPath(path: string): string {\n const withoutTrailingSlash = path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n switch (withoutTrailingSlash) {\n case \"/models\":\n return \"/v1/models\";\n case \"/chat/completions\":\n return \"/v1/chat/completions\";\n case \"/completions\":\n return \"/v1/completions\";\n case \"/messages\":\n return \"/v1/messages\";\n case \"/messages/count_tokens\":\n return \"/v1/messages/count_tokens\";\n case \"/responses\":\n return \"/v1/responses\";\n case \"/usage\":\n return \"/v1/usage\";\n default:\n return withoutTrailingSlash;\n }\n}\n\nfunction routeFor(method: string, path: string): string {\n if (method === \"OPTIONS\") {\n return \"cors.preflight\";\n }\n if (method === \"GET\" && (path === \"/\" || path === \"/healthz\")) {\n return \"health\";\n }\n if (method === \"GET\" && path === \"/metrics\") {\n return \"metrics\";\n }\n if (method === \"GET\" && path === \"/v1/usage\") {\n return \"usage\";\n }\n if (method === \"GET\" && path === \"/v1/models\") {\n return \"models\";\n }\n if (method === \"POST\" && path === \"/v1/messages\") {\n return \"anthropic_messages\";\n }\n if (method === \"POST\" && path === \"/v1/messages/count_tokens\") {\n return \"anthropic_count_tokens\";\n }\n if (method === \"POST\" && path === \"/v1/chat/completions\") {\n return \"chat_completions\";\n }\n if (method === \"POST\" && path === \"/v1/completions\") {\n return \"completions\";\n }\n if (method === \"POST\" && path === \"/v1/responses\") {\n return \"responses\";\n }\n if (method === \"GET\" && path === \"/v1/responses\") {\n return \"responses_websocket\";\n }\n return \"not_found\";\n}\n\nfunction isStreamingResponse(response: Response): boolean {\n return response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n}\n\nfunction logUpstreamSuccess(logger: HoopilotLogger, upstreamPath: string, status: number): void {\n logger.debug(\n {\n event: \"copilot.request.completed\",\n upstreamPath,\n upstreamStatus: status,\n },\n \"copilot upstream request completed\",\n );\n}\n\nfunction metricsResponse(metrics: MetricsRegistry): Response {\n return new Response(metrics.renderPrometheus(), {\n headers: {\n ...corsHeaders(),\n \"content-type\": PROMETHEUS_CONTENT_TYPE,\n },\n status: 200,\n });\n}\n\nasync function handleUsage(\n metrics: MetricsRegistry,\n readUsage: UsageReader,\n signal: AbortSignal,\n): Promise<Response> {\n const { copilot, error } = await readUsage(signal);\n const proxy = metrics.snapshot();\n const body: JsonObject = { copilot: copilot ?? null, object: \"usage\", proxy };\n if (error) {\n body.copilot_error = error;\n }\n return jsonResponse(body);\n}\n\n/**\n * Build a memoizing reader for the Copilot quota. The result is cached for\n * {@link USAGE_CACHE_TTL_MS} so repeated `/v1/usage` scrapes do not hammer\n * GitHub's REST rate limit, and missing credentials or upstream errors surface\n * as an `error` string rather than failing the whole response.\n */\nexport function createUsageReader(\n client: CopilotClient,\n metrics: MetricsRegistry,\n now: () => number = Date.now,\n ttlMs = USAGE_CACHE_TTL_MS,\n): UsageReader {\n const usagePath = \"/copilot_internal/user\";\n let cache: { atMs: number; value: CopilotUsage } | undefined;\n return async (signal) => {\n if (cache && now() - cache.atMs < ttlMs) {\n return { copilot: cache.value };\n }\n try {\n const upstream = await client.usage(signal);\n metrics.recordUpstream(usagePath, upstream.ok);\n if (!upstream.ok) {\n return { error: `GitHub Copilot usage request failed with ${upstream.status}.` };\n }\n const value = normalizeCopilotUsage(await upstream.json().catch(() => ({})));\n cache = { atMs: now(), value };\n metrics.recordCopilotQuota(value);\n return { copilot: value };\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n return { error: error.message };\n }\n metrics.recordUpstream(usagePath, false);\n return { error: errorMessage(error) };\n }\n };\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n","// Self-update and update-notification orchestration. The pure decision logic\n// lives in update-core.ts; this module performs the network and filesystem I/O.\nimport { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n realpathSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { errorDetails } from \"./logger\";\nimport type { HoopilotLogger } from \"./types\";\nimport {\n assetNameFor,\n assetSuffixFor,\n checksumFor,\n codexxShimFiles,\n formatUpdateNotice,\n type InstallKind,\n isOutdated,\n isUpdateCheckDisabled,\n type LatestRelease,\n latestReleaseApiUrl,\n parseLatestRelease,\n parseState,\n resolveCacheDir,\n shouldCleanupOldBinary,\n shouldRefresh,\n type UpdateState,\n upgradeCommandFor,\n} from \"./update-core\";\nimport { BAKED_TARGET, IS_STANDALONE_BINARY } from \"./version\";\n\nconst REQUEST_TIMEOUT_MS = 8_000;\nconst SHA256SUMS = \"SHA256SUMS\";\n\nfunction userAgent(version: string): string {\n return `hoopilot/${version}`;\n}\n\nfunction cacheDir(): string {\n return resolveCacheDir(process.env, process.platform, homedir(), join);\n}\n\nfunction stateFilePath(): string {\n return join(cacheDir(), \"update-check.json\");\n}\n\nasync function readStateSafe(): Promise<UpdateState> {\n try {\n return parseState(await readFile(stateFilePath(), \"utf8\"));\n } catch {\n return { lastCheck: 0, latestVersion: null, etag: null };\n }\n}\n\nasync function writeStateSafe(state: UpdateState): Promise<void> {\n try {\n mkdirSync(cacheDir(), { recursive: true });\n await writeFile(stateFilePath(), JSON.stringify(state), \"utf8\");\n } catch {\n // best effort: a read-only cache dir must never break the CLI\n }\n}\n\ninterface FetchResult {\n status: number;\n etag: string | null;\n release: LatestRelease | null;\n}\n\nasync function fetchLatest(version: string, etag?: string | null): Promise<FetchResult | null> {\n try {\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": userAgent(version),\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n };\n if (etag) {\n headers[\"If-None-Match\"] = etag;\n }\n const response = await fetch(latestReleaseApiUrl(), {\n headers,\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (response.status === 304) {\n return { status: 304, etag: etag ?? null, release: null };\n }\n if (!response.ok) {\n return { status: response.status, etag: null, release: null };\n }\n return {\n status: response.status,\n etag: response.headers.get(\"etag\"),\n release: parseLatestRelease(await response.json()),\n };\n } catch {\n return null; // offline / timeout: caller leaves state untouched\n }\n}\n\n/**\n * Print a notice if a previously-cached check found a newer release, then kick\n * off a throttled background refresh. Never blocks on the network and never\n * throws. Intended to be called (unawaited is fine) from the serve path.\n */\nexport async function maybeNotifyUpdate(\n currentVersion: string,\n kind: InstallKind,\n logger?: HoopilotLogger,\n): Promise<void> {\n if (isUpdateCheckDisabled(process.env, Boolean(process.stderr.isTTY))) {\n logger?.debug({ event: \"update.check.skipped\" }, \"update check skipped\");\n return;\n }\n const state = await readStateSafe();\n if (state.latestVersion && isOutdated(currentVersion, state.latestVersion)) {\n logger?.debug(\n {\n currentVersion,\n event: \"update.notice.cached\",\n installKind: kind,\n latestVersion: state.latestVersion,\n },\n \"showing cached update notice\",\n );\n process.stderr.write(formatUpdateNotice(currentVersion, state.latestVersion, kind));\n }\n if (shouldRefresh(state.lastCheck, Date.now())) {\n logger?.debug({ event: \"update.check.refresh_queued\" }, \"queued update check refresh\");\n void refreshState(currentVersion, state.etag ?? null, logger).catch((error: unknown) => {\n logger?.debug(\n { err: errorDetails(error), event: \"update.check.refresh_failed\" },\n \"update check refresh failed\",\n );\n });\n }\n}\n\nasync function refreshState(\n currentVersion: string,\n etag: string | null,\n logger?: HoopilotLogger,\n): Promise<void> {\n const result = await fetchLatest(currentVersion, etag);\n if (!result) {\n logger?.debug({ event: \"update.check.unavailable\" }, \"update check unavailable\");\n return; // network error: keep prior state\n }\n if (result.status === 304) {\n const prev = await readStateSafe();\n await writeStateSafe({ ...prev, lastCheck: Date.now() });\n logger?.debug({ event: \"update.check.not_modified\" }, \"latest release unchanged\");\n return;\n }\n if (result.release) {\n await writeStateSafe({\n lastCheck: Date.now(),\n latestVersion: result.release.version,\n etag: result.etag,\n });\n logger?.debug(\n { event: \"update.check.updated\", latestVersion: result.release.version },\n \"updated cached latest release state\",\n );\n }\n}\n\nfunction detectInstallKind(): InstallKind {\n return IS_STANDALONE_BINARY ? \"binary\" : \"npm\";\n}\n\nfunction detectMusl(): boolean {\n if (process.platform !== \"linux\") {\n return false;\n }\n try {\n const report = process.report?.getReport?.() as\n | { header?: Record<string, unknown> }\n | undefined;\n if (report?.header && \"glibcVersionRuntime\" in report.header) {\n return !report.header.glibcVersionRuntime;\n }\n } catch {\n // fall through to file-based detection\n }\n try {\n if (existsSync(\"/etc/alpine-release\")) {\n return true;\n }\n const ldd = execFileSync(\"ldd\", [\"--version\"], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 2_000,\n });\n return /musl/i.test(ldd);\n } catch {\n return false;\n }\n}\n\nasync function downloadToFile(url: string, dest: string, version: string): Promise<void> {\n const response = await fetch(url, {\n headers: { \"User-Agent\": userAgent(version) },\n redirect: \"follow\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS * 10),\n });\n if (!response.ok || !response.body) {\n throw new Error(`Download failed (${response.status}) for ${url}`);\n }\n await writeFile(dest, new Uint8Array(await response.arrayBuffer()));\n}\n\nasync function sha256File(path: string): Promise<string> {\n return createHash(\"sha256\")\n .update(await readFile(path))\n .digest(\"hex\");\n}\n\nasync function verifyChecksum(\n release: LatestRelease,\n assetName: string,\n file: string,\n version: string,\n): Promise<void> {\n const sums = release.assets.find((asset) => asset.name === SHA256SUMS);\n if (!sums) {\n // Fail closed: never overwrite the running binary with an unverified download.\n throw new Error(\n `Release ${release.tag} has no ${SHA256SUMS}; refusing to install an unverified binary.`,\n );\n }\n const response = await fetch(sums.url, {\n headers: { \"User-Agent\": userAgent(version) },\n redirect: \"follow\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (!response.ok) {\n throw new Error(`Could not download ${SHA256SUMS} (${response.status}).`);\n }\n const expected = checksumFor(await response.text(), assetName);\n if (!expected) {\n throw new Error(`No checksum for ${assetName} in ${SHA256SUMS}.`);\n }\n const actual = await sha256File(file);\n if (actual.toLowerCase() !== expected) {\n throw new Error(`Checksum mismatch for ${assetName}: expected ${expected}, got ${actual}.`);\n }\n}\n\nfunction swapBinary(tmpFile: string, exePath: string): void {\n if (process.platform === \"win32\") {\n // A running .exe cannot be overwritten, but it can be renamed aside.\n const oldExe = `${exePath}.old`;\n try {\n rmSync(oldExe, { force: true });\n } catch {\n // a previous .old may still be locked; the new name still wins below\n }\n renameSync(exePath, oldExe);\n const restore = () => {\n try {\n renameSync(oldExe, exePath); // put the working binary back\n } catch {\n // nothing more we can do\n }\n };\n try {\n renameSync(tmpFile, exePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EXDEV\") {\n try {\n copyFileSync(tmpFile, exePath);\n } catch (copyError) {\n restore();\n throw copyError;\n }\n } else {\n restore();\n throw error;\n }\n }\n return;\n }\n // Unix: atomic rename over the running file; the old inode stays mapped until exit.\n try {\n renameSync(tmpFile, exePath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"EXDEV\") {\n copyFileSync(tmpFile, exePath);\n chmodSync(exePath, 0o755);\n } else if (code === \"EACCES\" || code === \"EPERM\") {\n throw new Error(\n `No permission to update ${exePath}. Re-run with sudo, or reinstall to a writable directory.`,\n );\n } else {\n throw error;\n }\n }\n}\n\nfunction refreshCodexxShim(dir: string, logger?: HoopilotLogger): void {\n try {\n for (const file of codexxShimFiles(process.platform)) {\n const path = join(dir, file.name);\n writeFileSync(path, file.content, \"utf8\");\n if (file.executable) {\n chmodSync(path, 0o755);\n }\n }\n } catch (error) {\n logger?.warn(\n { err: errorDetails(error), event: \"update.codexx_shim_failed\" },\n \"could not refresh codexx shim\",\n );\n console.warn(`Updated hoopilot, but could not refresh the codexx shim: ${errorMessage(error)}`);\n }\n}\n\n/** Remove the leftover \".old\" binary from a prior Windows self-update. */\nexport function cleanupOldBinary(): void {\n if (!shouldCleanupOldBinary(process.platform, IS_STANDALONE_BINARY)) {\n return;\n }\n try {\n rmSync(`${realpathSync(process.execPath)}.old`, { force: true });\n } catch {\n // still locked or already gone\n }\n}\n\n/** Implements the `hoopilot update` command. */\nexport async function runUpdate(currentVersion: string, logger?: HoopilotLogger): Promise<void> {\n cleanupOldBinary();\n const kind = detectInstallKind();\n logger?.debug({ currentVersion, event: \"update.started\", installKind: kind }, \"update started\");\n\n if (kind !== \"binary\") {\n console.log(`hoopilot ${currentVersion} was installed via npm.`);\n console.log(`Update with: ${upgradeCommandFor(\"npm\")}`);\n return;\n }\n\n console.log(`hoopilot ${currentVersion} — checking for updates...`);\n const result = await fetchLatest(currentVersion);\n const release = result?.release ?? null;\n if (!release) {\n throw new Error(\"Could not reach GitHub to check for the latest release.\");\n }\n if (!isOutdated(currentVersion, release.version)) {\n logger?.debug(\n { currentVersion, event: \"update.already_current\", latestVersion: release.version },\n \"hoopilot is already up to date\",\n );\n console.log(`Already up to date (latest: ${release.version}).`);\n return;\n }\n\n const suffix = BAKED_TARGET ?? assetSuffixFor(process.platform, process.arch, detectMusl());\n const assetName = assetNameFor(suffix);\n const asset = release.assets.find((entry) => entry.name === assetName);\n if (!asset) {\n const available = release.assets.map((entry) => entry.name).join(\", \") || \"none\";\n throw new Error(`Release ${release.tag} has no asset \"${assetName}\". Available: ${available}.`);\n }\n\n console.log(`Updating ${currentVersion} → ${release.version} (${assetName})...`);\n logger?.debug(\n {\n assetName,\n currentVersion,\n event: \"update.installing\",\n latestVersion: release.version,\n },\n \"installing update\",\n );\n const exePath = realpathSync(process.execPath);\n const tmpFile = join(dirname(exePath), `.hoopilot-update-${process.pid}.tmp`);\n try {\n await downloadToFile(asset.url, tmpFile, currentVersion);\n await verifyChecksum(release, assetName, tmpFile, currentVersion);\n if (process.platform !== \"win32\") {\n chmodSync(tmpFile, 0o755);\n }\n swapBinary(tmpFile, exePath);\n refreshCodexxShim(dirname(exePath), logger);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"EACCES\" || code === \"EPERM\") {\n throw new Error(\n `No permission to update ${exePath}. Re-run with sudo, or reinstall to a writable directory (e.g. set HOOPILOT_INSTALL_DIR).`,\n );\n }\n throw error;\n } finally {\n try {\n rmSync(tmpFile, { force: true });\n } catch {\n // already moved into place or never created\n }\n }\n\n console.log(`Updated hoopilot to ${release.version}.`);\n logger?.debug(\n { currentVersion, event: \"update.completed\", latestVersion: release.version },\n \"update completed\",\n );\n if (process.platform === \"win32\") {\n console.log(\"Restart hoopilot to run the new version.\");\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","// Pure, dependency-free logic for version checks and self-update decisions.\n// Everything here is side-effect free so it can be unit tested without network\n// or filesystem access; the I/O orchestration lives in update.ts.\n\nconst REPO_OWNER = \"openhoo\";\nconst REPO_NAME = \"hoopilot\";\nexport const REPO = `${REPO_OWNER}/${REPO_NAME}`;\nexport const NPM_PACKAGE = \"@openhoo/hoopilot\";\n\n/** How a copy of hoopilot was installed. */\nexport type InstallKind = \"binary\" | \"npm\";\n\n/** How often the background update check is allowed to hit GitHub. */\nexport const UPDATE_CHECK_INTERVAL_MS = 1000 * 60 * 60 * 24; // 24h\n\n/** Persisted state for the throttled update check. */\nexport interface UpdateState {\n lastCheck: number;\n latestVersion: string | null;\n etag?: string | null;\n}\n\nexport interface CodexxShimFile {\n content: string;\n executable: boolean;\n name: string;\n}\n\ninterface SemVer {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n}\n\nfunction parseSemver(input: string): SemVer | null {\n const value = String(input)\n .trim()\n .replace(/^[v=]+/, \"\");\n const match = value.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/);\n if (!match) {\n return null;\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n // Build metadata (everything after \"+\") is intentionally dropped.\n prerelease: match[4] ? match[4].split(\".\") : [],\n };\n}\n\nfunction comparePrerelease(a: string[], b: string[]): -1 | 0 | 1 {\n if (a.length === 0 && b.length === 0) {\n return 0;\n }\n // A release outranks an otherwise-equal prerelease.\n if (a.length === 0) {\n return 1;\n }\n if (b.length === 0) {\n return -1;\n }\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n const x = a[i];\n const y = b[i];\n // The version with more prerelease fields has higher precedence.\n if (x === undefined) {\n return -1;\n }\n if (y === undefined) {\n return 1;\n }\n const xNumeric = /^\\d+$/.test(x);\n const yNumeric = /^\\d+$/.test(y);\n if (xNumeric && yNumeric) {\n const diff = Number(x) - Number(y);\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n } else if (xNumeric) {\n return -1; // numeric identifiers sort lower than alphanumeric\n } else if (yNumeric) {\n return 1;\n } else if (x !== y) {\n return x < y ? -1 : 1; // ASCII lexical\n }\n }\n return 0;\n}\n\n/**\n * Compare two semantic versions. Returns -1 if a < b, 0 if equal, 1 if a > b.\n * Tolerates a leading \"v\"/\"=\", ignores build metadata, honors prerelease\n * precedence, and sorts unparseable input low so a bad value never throws.\n */\nexport function compareSemver(a: string, b: string): -1 | 0 | 1 {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n if (!pa || !pb) {\n if (!pa && !pb) {\n return 0;\n }\n return pa ? 1 : -1;\n }\n if (pa.major !== pb.major) {\n return pa.major < pb.major ? -1 : 1;\n }\n if (pa.minor !== pb.minor) {\n return pa.minor < pb.minor ? -1 : 1;\n }\n if (pa.patch !== pb.patch) {\n return pa.patch < pb.patch ? -1 : 1;\n }\n return comparePrerelease(pa.prerelease, pb.prerelease);\n}\n\n/** True when `latest` is a strictly newer release than `current`. */\nexport function isOutdated(current: string, latest: string): boolean {\n return compareSemver(current, latest) < 0;\n}\n\n/** Strip a leading \"v\" from a git tag to get a bare version string. */\nexport function versionFromTag(tag: string): string {\n return tag.trim().replace(/^v/, \"\");\n}\n\n/**\n * Compute the release asset suffix for a platform/arch, e.g. \"linux-x64-musl\",\n * \"darwin-arm64\", \"windows-x64\". `platform`/`arch` use Node's process values.\n */\nexport function assetSuffixFor(platform: string, arch: string, isMusl: boolean): string {\n const os = platform === \"win32\" ? \"windows\" : platform === \"darwin\" ? \"darwin\" : \"linux\";\n const cpu = arch === \"arm64\" || arch === \"aarch64\" ? \"arm64\" : \"x64\";\n const libc = os === \"linux\" && isMusl ? \"-musl\" : \"\";\n return `${os}-${cpu}${libc}`;\n}\n\n/** Full release asset file name for a suffix (adds .exe for Windows). */\nexport function assetNameFor(suffix: string): string {\n const name = `hoopilot-${suffix}`;\n return suffix.startsWith(\"windows-\") ? `${name}.exe` : name;\n}\n\n/** Whether automatic update checks should be skipped, per env + TTY. */\nexport function isUpdateCheckDisabled(\n env: Record<string, string | undefined>,\n isTty: boolean,\n): boolean {\n if (env.HOOPILOT_NO_UPDATE_CHECK || env.NO_UPDATE_NOTIFIER) {\n return true;\n }\n if (env.NODE_ENV === \"test\") {\n return true;\n }\n if (!isTty) {\n return true; // piped / non-interactive output\n }\n if (\n (env.CI && env.CI !== \"false\") ||\n env.CONTINUOUS_INTEGRATION ||\n env.GITHUB_ACTIONS ||\n env.BUILD_NUMBER ||\n env.RUN_ID\n ) {\n return true;\n }\n return false;\n}\n\n/** Whether the background check is due again given the last check time. */\nexport function shouldRefresh(\n lastCheck: number,\n now: number,\n intervalMs = UPDATE_CHECK_INTERVAL_MS,\n): boolean {\n return now - lastCheck >= intervalMs;\n}\n\n/** The command a user runs to upgrade, depending on how they installed. */\nexport function upgradeCommandFor(kind: InstallKind): string {\n return kind === \"binary\"\n ? \"hoopilot update\"\n : `npm install -g ${NPM_PACKAGE}@latest (or: bun add -g ${NPM_PACKAGE})`;\n}\n\n/** Whether it is safe to remove a leftover Windows self-update backup. */\nexport function shouldCleanupOldBinary(platform: string, isStandaloneBinary: boolean): boolean {\n return platform === \"win32\" && isStandaloneBinary;\n}\n\n/** Files that expose the standalone `codexx` command next to the `hoopilot` binary. */\nexport function codexxShimFiles(platform: string): CodexxShimFile[] {\n if (platform === \"win32\") {\n return [\n {\n content: `$ErrorActionPreference = 'Stop'\n$hoopilot = Join-Path $PSScriptRoot 'hoopilot.exe'\n& $hoopilot codexx @args\nexit $LASTEXITCODE\n`,\n executable: false,\n name: \"codexx.ps1\",\n },\n {\n content: `@echo off\nsetlocal\nwhere pwsh >nul 2>nul\nif %ERRORLEVEL% EQU 0 (\n pwsh -NoProfile -ExecutionPolicy Bypass -File \"%~dp0codexx.ps1\" %*\n) else (\n powershell -NoProfile -ExecutionPolicy Bypass -File \"%~dp0codexx.ps1\" %*\n)\nexit /b %ERRORLEVEL%\n`,\n executable: false,\n name: \"codexx.cmd\",\n },\n ];\n }\n return [\n {\n content: `#!/bin/sh\nset -eu\nscript_dir=$(CDPATH= cd \"$(dirname \"$0\")\" && pwd)\nexec \"$script_dir/hoopilot\" codexx \"$@\"\n`,\n executable: true,\n name: \"codexx\",\n },\n ];\n}\n\n/** Render the \"update available\" notice printed to stderr. */\nexport function formatUpdateNotice(current: string, latest: string, kind: InstallKind): string {\n return (\n `\\nUpdate available for hoopilot: ${current} → ${latest}\\n` +\n `Run: ${upgradeCommandFor(kind)}\\n\\n`\n );\n}\n\n/** Parse the persisted update-check state, tolerating any malformed input. */\nexport function parseState(text: string): UpdateState {\n try {\n const data = JSON.parse(text) as Partial<UpdateState>;\n return {\n lastCheck: typeof data.lastCheck === \"number\" ? data.lastCheck : 0,\n latestVersion: typeof data.latestVersion === \"string\" ? data.latestVersion : null,\n etag: typeof data.etag === \"string\" ? data.etag : null,\n };\n } catch {\n return { lastCheck: 0, latestVersion: null, etag: null };\n }\n}\n\nexport interface LatestRelease {\n version: string;\n tag: string;\n assets: Array<{ name: string; url: string }>;\n}\n\n/** Parse the GitHub `releases/latest` response into the fields we need. */\nexport function parseLatestRelease(json: unknown): LatestRelease | null {\n if (!json || typeof json !== \"object\") {\n return null;\n }\n const record = json as Record<string, unknown>;\n const tag = typeof record.tag_name === \"string\" ? record.tag_name : undefined;\n if (!tag) {\n return null;\n }\n const assets: Array<{ name: string; url: string }> = [];\n if (Array.isArray(record.assets)) {\n for (const item of record.assets) {\n if (item && typeof item === \"object\") {\n const asset = item as Record<string, unknown>;\n if (typeof asset.name === \"string\" && typeof asset.browser_download_url === \"string\") {\n assets.push({ name: asset.name, url: asset.browser_download_url });\n }\n }\n }\n }\n return { version: versionFromTag(tag), tag, assets };\n}\n\n/** Find a checksum line for `fileName` in a `sha256sum`-style SHA256SUMS file. */\nexport function checksumFor(sumsText: string, fileName: string): string | undefined {\n for (const line of sumsText.split(/\\r?\\n/)) {\n const match = line.trim().match(/^([0-9a-fA-F]{64})\\s+\\*?(.+)$/);\n if (match?.[1] && match[2]?.trim() === fileName) {\n return match[1].toLowerCase();\n }\n }\n return undefined;\n}\n\n/**\n * Resolve the per-OS cache directory (no deps). Mirrors env-paths conventions:\n * Windows -> %LOCALAPPDATA%, macOS -> ~/Library/Caches, else $XDG_CACHE_HOME||~/.cache.\n */\nexport function resolveCacheDir(\n env: Record<string, string | undefined>,\n platform: string,\n homedir: string,\n join: (...parts: string[]) => string,\n): string {\n if (platform === \"win32\") {\n const base = env.LOCALAPPDATA || join(homedir, \"AppData\", \"Local\");\n return join(base, \"hoopilot\");\n }\n if (platform === \"darwin\") {\n return join(homedir, \"Library\", \"Caches\", \"hoopilot\");\n }\n const base = env.XDG_CACHE_HOME || join(homedir, \".cache\");\n return join(base, \"hoopilot\");\n}\n\n/** Stable redirect URL that downloads an asset from the latest release. */\nexport function latestDownloadUrl(asset: string): string {\n return `https://github.com/${REPO}/releases/latest/download/${asset}`;\n}\n\n/** GitHub REST endpoint for the latest release. */\nexport function latestReleaseApiUrl(): string {\n return `https://api.github.com/repos/${REPO}/releases/latest`;\n}\n","// Build-time constants. For standalone binaries these identifiers are replaced\n// at compile time via `bun build --compile --define 'HOOPILOT_VERSION=\"x.y.z\"'`\n// (see scripts/build-binaries.sh). In dev runs and the npm package they are not\n// defined, so `typeof` is \"undefined\" and we fall back to reading package.json.\ndeclare const HOOPILOT_VERSION: string;\ndeclare const HOOPILOT_TARGET: string;\n\n/** Version baked into a standalone binary, or undefined for npm/dev installs. */\nexport const BAKED_VERSION: string | undefined =\n typeof HOOPILOT_VERSION !== \"undefined\" ? HOOPILOT_VERSION : undefined;\n\n/**\n * Release asset suffix baked into a standalone binary (e.g. \"linux-x64-musl\",\n * \"windows-x64\", \"darwin-arm64\"), or undefined for npm/dev installs. Lets the\n * self-updater fetch the exact asset variant it was built from.\n */\nexport const BAKED_TARGET: string | undefined =\n typeof HOOPILOT_TARGET !== \"undefined\" ? HOOPILOT_TARGET : undefined;\n\n/** True when running as a `bun build --compile` standalone executable. */\nexport const IS_STANDALONE_BINARY: boolean = BAKED_VERSION !== undefined;\n\nlet cachedVersion: string | undefined;\n\n/** Resolve the running version, preferring the baked value for binaries. */\nexport async function getVersion(): Promise<string> {\n if (cachedVersion !== undefined) {\n return cachedVersion;\n }\n let resolved: string;\n if (BAKED_VERSION) {\n resolved = BAKED_VERSION;\n } else {\n try {\n const manifest = await Bun.file(new URL(\"../package.json\", import.meta.url)).json();\n resolved = typeof manifest.version === \"string\" ? manifest.version : \"0.0.0\";\n } catch {\n resolved = \"0.0.0\";\n }\n }\n cachedVersion = resolved;\n return resolved;\n}\n"],"mappings":"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","names":["readFileSync","removeUndefined","randomId","firstNumber","parseJsonObject","chmodSync","mkdirSync","renameSync","writeFileSync","dirname","join","homedir","join","base","REQUEST_TIMEOUT_MS","join","mkdirSync","renameSync","chmodSync","writeFileSync","errorMessage","dirname","ALLOWED_COPILOT_API_HOSTS","main","args","logger","readFileSync"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/auth-store.ts","../src/auth.ts","../src/copilot.ts","../src/github-device.ts","../src/logger.ts","../src/openai.ts","../src/anthropic.ts","../src/metrics.ts","../src/version.ts","../src/server.ts","../src/update.ts","../src/update-core.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { CopilotAuthError, DEFAULT_COPILOT_API_BASE_URL } from \"./auth\";\nimport { authStorePath, writeStoredCopilotAuth } from \"./auth-store\";\nimport { main as codexxMain } from \"./codexx\";\nimport { applyCopilotHeaders, CopilotClient, normalizeCopilotUsage } from \"./copilot\";\nimport { githubCopilotDeviceLogin } from \"./github-device\";\nimport { createHoopilotLogger, noopLogger, parseLogFormat, parseLogLevel } from \"./logger\";\nimport { startHoopilotServer } from \"./server\";\nimport type {\n CopilotAccess,\n CopilotQuota,\n CopilotUsage,\n FetchLike,\n HoopilotLogger,\n HoopilotServerOptions,\n} from \"./types\";\nimport { cleanupOldBinary, maybeNotifyUpdate, runUpdate } from \"./update\";\nimport {\n asRecord,\n envValue,\n isTrustedTokenBaseUrl,\n trimTrailingSlash,\n truncatedResponseText,\n} from \"./util\";\nimport { getVersion, IS_STANDALONE_BINARY } from \"./version\";\n\ninterface ParsedArgs extends HoopilotServerOptions {\n help?: boolean;\n noUpdateCheck?: boolean;\n version?: boolean;\n}\n\ninterface VerifyCopilotOAuthTokenOptions {\n copilotApiBaseUrl?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n}\n\nconst ALLOWED_COPILOT_API_HOSTS = [\"api.githubcopilot.com\"] as const;\n\nexport async function main(argv = Bun.argv.slice(2)): Promise<void> {\n // Clear any leftover \".old\" binary from a prior Windows self-update.\n cleanupOldBinary();\n\n const command = argv[0];\n if (command === \"update\" || command === \"upgrade\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n const logger = commandLogger(args, command);\n await runUpdate(await getVersion(), logger);\n return;\n }\n if (command === \"codexx\") {\n await codexxMain(argv.slice(1), process.env);\n return;\n }\n if (command === \"login\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"login\");\n await runLogin(args);\n return;\n }\n if (command === \"models\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"models\");\n await runModels(args);\n return;\n }\n if (command === \"usage\") {\n const args = withRuntimeEnv(parseArgs(argv.slice(1)));\n if (await printMetaOption(args)) {\n return;\n }\n args.logger = commandLogger(args, \"usage\");\n await runUsage(args);\n return;\n }\n\n const args = withRuntimeEnv(parseArgs(argv));\n if (await printMetaOption(args)) {\n return;\n }\n\n const logger = commandLogger(args, \"serve\");\n args.logger = logger;\n const started = startHoopilotServer(args);\n logger.info(\n {\n baseUrl: `${started.url}/v1`,\n event: \"server.started\",\n url: started.url,\n },\n \"hoopilot server started\",\n );\n\n if (!args.noUpdateCheck) {\n // Non-blocking: prints a notice from the previous check and refreshes the\n // cache in the background. The running server keeps the refresh alive.\n // Env-based disabling (HOOPILOT_NO_UPDATE_CHECK, NO_UPDATE_NOTIFIER, CI, …)\n // is handled centrally by isUpdateCheckDisabled inside maybeNotifyUpdate.\n void maybeNotifyUpdate(\n await getVersion(),\n IS_STANDALONE_BINARY ? \"binary\" : \"npm\",\n logger.child({ component: \"update\" }),\n );\n }\n}\n\nasync function printMetaOption(args: ParsedArgs): Promise<boolean> {\n if (args.help) {\n console.log(helpText(await getVersion()));\n return true;\n }\n if (args.version) {\n console.log(await getVersion());\n return true;\n }\n return false;\n}\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const args: ParsedArgs = {};\n const rest = [...argv];\n if (rest[0] === \"serve\") {\n rest.shift();\n }\n\n while (rest.length > 0) {\n const arg = rest.shift();\n if (!arg) {\n continue;\n }\n if (arg === \"--help\" || arg === \"-h\") {\n args.help = true;\n continue;\n }\n if (arg === \"--version\" || arg === \"-v\") {\n args.version = true;\n continue;\n }\n if (arg === \"--allow-unauthenticated\") {\n args.allowUnauthenticated = true;\n continue;\n }\n if (arg === \"--no-update-check\") {\n args.noUpdateCheck = true;\n continue;\n }\n\n if (!arg.startsWith(\"-\")) {\n throw new Error(`Unknown argument: ${arg}.`);\n }\n\n const [name, inlineValue] = splitOption(arg);\n switch (name) {\n case \"--api-key\":\n args.apiKey = optionValue(name, inlineValue, rest);\n break;\n case \"--api-key-file\":\n args.apiKey = readApiKeyFile(optionValue(name, inlineValue, rest));\n break;\n case \"--auth-file\":\n args.authStorePath = optionValue(name, inlineValue, rest);\n break;\n case \"--copilot-api-base-url\":\n args.copilotApiBaseUrl = optionValue(name, inlineValue, rest);\n break;\n case \"--log-format\":\n args.logFormat = parseLogFormat(optionValue(name, inlineValue, rest));\n break;\n case \"--log-level\":\n args.logLevel = parseLogLevel(optionValue(name, inlineValue, rest));\n break;\n case \"--stream-mode\":\n args.streamingProxyMode = parseStreamMode(optionValue(name, inlineValue, rest));\n break;\n case \"--host\":\n args.host = optionValue(name, inlineValue, rest);\n break;\n case \"--port\":\n case \"-p\": {\n const value = optionValue(name, inlineValue, rest);\n args.port = Number(value);\n if (!Number.isInteger(args.port) || args.port <= 0 || args.port > 65_535) {\n throw new Error(`Invalid port: ${value}.`);\n }\n break;\n }\n default:\n throw new Error(`Unknown option: ${name}.`);\n }\n }\n\n return args;\n}\n\nfunction parseStreamMode(value: string): \"auto\" | \"buffer\" | \"live\" {\n if (value === \"auto\" || value === \"buffer\" || value === \"live\") {\n return value;\n }\n throw new Error(`Invalid stream mode: ${value}. Expected auto, live, or buffer.`);\n}\n\nfunction optionValue(name: string, inlineValue: string | undefined, rest: string[]): string {\n const value = inlineValue ?? rest.shift();\n if (!value) {\n throw new Error(`Missing value for ${name}.`);\n }\n return value;\n}\n\nfunction splitOption(arg: string): [string, string | undefined] {\n const separator = arg.indexOf(\"=\");\n if (separator === -1) {\n return [arg, undefined];\n }\n return [arg.slice(0, separator), arg.slice(separator + 1)];\n}\n\nfunction readApiKeyFile(path: string): string {\n const value = readFileSync(path, \"utf8\").trim();\n if (!value) {\n throw new Error(`API key file is empty: ${path}.`);\n }\n return value;\n}\n\nasync function runLogin(options: HoopilotServerOptions = {}): Promise<void> {\n const logger = options.logger?.child({ component: \"auth\" }) ?? noopLogger;\n logger.debug({ event: \"auth.login.started\" }, \"starting github copilot browser login\");\n console.log(\"Starting GitHub Copilot browser login...\");\n const login = await githubCopilotDeviceLogin({\n env: options.env,\n logger: console,\n openBrowser: openBrowserBestEffort,\n });\n\n console.log(\"Checking GitHub Copilot access...\");\n const access = await verifyCopilotOAuthToken(login.token, options);\n logger.debug(\n { apiBaseUrl: access.apiBaseUrl, event: \"auth.login.verified\" },\n \"github copilot oauth token verified\",\n );\n const path = options.authStorePath ?? authStorePath(options.env);\n writeStoredCopilotAuth(\n {\n apiBaseUrl: access.apiBaseUrl,\n githubDomain: login.domain,\n source: \"github-device-oauth\",\n token: login.token,\n },\n path,\n );\n logger.debug({ authStorePath: path, event: \"auth.login.stored\" }, \"copilot credential stored\");\n console.log(`Copilot OAuth credential stored at ${path}`);\n console.log(\"Copilot authentication ready.\");\n}\n\nexport async function runModels(options: HoopilotServerOptions = {}): Promise<string[]> {\n const logger = options.logger?.child({ component: \"models\" }) ?? noopLogger;\n logger.debug({ event: \"models.list.started\" }, \"fetching github copilot models\");\n\n const response = await new CopilotClient(options).models();\n if (!response.ok) {\n const message = `GitHub Copilot API model list failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n const ids = modelIdsFromResponse(await response.json().catch(() => undefined));\n if (ids.length === 0) {\n throw new Error(\"GitHub Copilot API returned no model IDs.\");\n }\n\n logger.debug(\n { count: ids.length, event: \"models.list.succeeded\" },\n \"github copilot models fetched\",\n );\n for (const id of ids) {\n console.log(id);\n }\n return ids;\n}\n\nexport async function runUsage(options: HoopilotServerOptions = {}): Promise<CopilotUsage> {\n const logger = options.logger?.child({ component: \"usage\" }) ?? noopLogger;\n logger.debug({ event: \"usage.fetch.started\" }, \"fetching github copilot quota\");\n\n const response = await new CopilotClient(options).usage();\n if (!response.ok) {\n const message = `GitHub Copilot usage request failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n const usage = normalizeCopilotUsage(await response.json().catch(() => ({})));\n logger.debug(\n { event: \"usage.fetch.succeeded\", plan: usage.plan },\n \"github copilot quota fetched\",\n );\n for (const line of formatCopilotUsage(usage)) {\n console.log(line);\n }\n return usage;\n}\n\nfunction formatCopilotUsage(usage: CopilotUsage): string[] {\n const lines: string[] = [];\n if (usage.plan) {\n lines.push(`Plan: ${usage.plan}`);\n }\n if (usage.quotaResetDate) {\n lines.push(`Quota resets: ${usage.quotaResetDate}`);\n }\n\n const order = [\"premium_interactions\", \"chat\", \"completions\"];\n const names = Object.keys(usage.quotas).sort(\n (a, b) => quotaRank(order, a) - quotaRank(order, b) || a.localeCompare(b),\n );\n for (const name of names) {\n const quota = usage.quotas[name];\n if (quota) {\n lines.push(`${quotaLabel(name)}: ${formatQuota(quota)}`);\n }\n }\n if (lines.length === 0) {\n lines.push(\"No GitHub Copilot quota information available for this account.\");\n }\n return lines;\n}\n\nfunction quotaRank(order: string[], name: string): number {\n const index = order.indexOf(name);\n return index === -1 ? order.length : index;\n}\n\nfunction quotaLabel(name: string): string {\n switch (name) {\n case \"premium_interactions\":\n return \"Premium requests\";\n case \"chat\":\n return \"Chat\";\n case \"completions\":\n return \"Completions\";\n default:\n return name;\n }\n}\n\nfunction formatQuota(quota: CopilotQuota): string {\n if (quota.unlimited) {\n return \"unlimited\";\n }\n const parts: string[] = [];\n if (quota.used !== undefined && quota.entitlement !== undefined) {\n parts.push(`${roundQuota(quota.used)}/${roundQuota(quota.entitlement)} used`);\n } else if (quota.remaining !== undefined) {\n parts.push(`${roundQuota(quota.remaining)} remaining`);\n }\n if (quota.percentRemaining !== undefined) {\n parts.push(`${roundQuota(quota.percentRemaining)}% remaining`);\n }\n if (quota.overageCount) {\n parts.push(`${roundQuota(quota.overageCount)} overage`);\n }\n return parts.length > 0 ? parts.join(\", \") : \"n/a\";\n}\n\nfunction roundQuota(value: number): number {\n return Number.isInteger(value) ? value : Math.round(value * 10) / 10;\n}\n\nexport async function verifyCopilotOAuthToken(\n token: string,\n options: VerifyCopilotOAuthTokenOptions = {},\n): Promise<CopilotAccess> {\n const apiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ??\n envValue(options.env?.COPILOT_API_BASE_URL) ??\n DEFAULT_COPILOT_API_BASE_URL,\n );\n const allowUnsafeUpstream = envValue(options.env?.HOOPILOT_ALLOW_UNSAFE_UPSTREAM) === \"1\";\n if (!isTrustedTokenBaseUrl(apiBaseUrl, ALLOWED_COPILOT_API_HOSTS, allowUnsafeUpstream)) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted Copilot API host: ${apiBaseUrl}`,\n );\n }\n const fetcher = options.fetch ?? fetch;\n const response = await fetcher(`${apiBaseUrl}/models`, {\n headers: applyCopilotHeaders(new Headers(), token),\n method: \"GET\",\n });\n\n if (!response.ok) {\n const message = `GitHub Copilot API verification failed with ${\n response.status\n }: ${await truncatedResponseText(response)}`;\n if (response.status === 401 || response.status === 403) {\n throw new CopilotAuthError(message);\n }\n throw new Error(message);\n }\n\n return {\n apiBaseUrl,\n expiresAtMs: Date.now() + 10 * 60_000,\n source: \"github-copilot-oauth\",\n token,\n };\n}\n\nfunction openBrowserBestEffort(url: string): void {\n const platform = process.platform;\n const command = platform === \"win32\" ? \"cmd\" : platform === \"darwin\" ? \"open\" : \"xdg-open\";\n const args = platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n try {\n const child = spawn(command, args, {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n // The device login code and URL were already printed.\n }\n}\n\nfunction modelIdsFromResponse(body: unknown): string[] {\n const record = asRecord(body);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(body) ? body : [];\n const seen = new Set<string>();\n const ids: string[] = [];\n for (const model of data) {\n const id = asRecord(model).id;\n if (typeof id !== \"string\" || id.length === 0 || seen.has(id)) {\n continue;\n }\n seen.add(id);\n ids.push(id);\n }\n return ids;\n}\n\nfunction withRuntimeEnv(args: ParsedArgs): ParsedArgs {\n return { ...args, env: process.env };\n}\n\nfunction commandLogger(args: ParsedArgs, command: string): HoopilotLogger {\n return createHoopilotLogger({\n env: args.env,\n format: args.logFormat,\n level: args.logLevel,\n }).child({ command, component: \"cli\" });\n}\n\nfunction helpText(version: string): string {\n return `hoopilot ${version}\n\nOpenAI-compatible proxy for GitHub Copilot.\n\nUsage:\n hoopilot [serve] [options]\n hoopilot codexx [codex options] [prompt]\n hoopilot login [options]\n hoopilot models [options]\n hoopilot usage [options]\n hoopilot update\n npx @openhoo/hoopilot [options]\n\nCommands:\n serve Start the proxy server (default)\n codexx Run Codex through the local Hoopilot server\n login Sign in through GitHub OAuth in a browser and verify Copilot access\n models List available GitHub Copilot model IDs\n usage Show GitHub Copilot quota and premium-request usage\n update, upgrade Update hoopilot to the latest release\n\nWhile the server runs, GET /metrics exposes Prometheus metrics (request counts,\ntoken usage, latency) and GET /v1/usage returns those metrics plus live Copilot\nquota as JSON.\n\nOptions:\n -p, --port <port> Port to listen on. Default: 4141\n --host <host> Host to listen on. Default: 127.0.0.1\n --api-key <key> Require clients to send Authorization: Bearer <key> or x-api-key: <key>\n --api-key-file <path> Read the local API key from a file instead of argv\n --auth-file <path> OAuth credential store path\n --copilot-api-base-url <url> Copilot API base URL override\n --log-level <level> trace, debug, info, warn, error, fatal, or silent\n --log-format <format> json or pretty. Default: pretty\n --stream-mode <mode> auto, live, or buffer. Auto buffers Windows standalone streams.\n --no-update-check Do not check GitHub for a newer release\n --allow-unauthenticated Allow non-loopback bind without --api-key\n -h, --help Show help\n -v, --version Show version\n\nEnvironment:\n HOOPILOT_API_KEY\n HOOPILOT_AUTH_FILE\n HOOPILOT_GITHUB_CLIENT_ID\n HOOPILOT_GITHUB_DOMAIN\n HOOPILOT_LOG_FORMAT json or pretty. Default: pretty\n HOOPILOT_LOG_LEVEL trace, debug, info, warn, error, fatal, or silent\n HOOPILOT_STREAM_MODE auto, live, or buffer\n COPILOT_API_BASE_URL\n HOOPILOT_GITHUB_API_BASE_URL GitHub REST base for the usage/quota lookup. Default: https://api.github.com\n HOOPILOT_ALLOW_UNSAFE_UPSTREAM Set to 1 to allow nonstandard HTTPS token hosts\n HOOPILOT_NO_UPDATE_CHECK Set to disable update checks (also NO_UPDATE_NOTIFIER)\n`;\n}\n\nif (import.meta.main) {\n main().catch((error: unknown) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exit(1);\n });\n}\n","import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { envValue } from \"./util\";\n\nexport class StoredCopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StoredCopilotAuthError\";\n }\n}\n\nexport interface StoredCopilotAuth {\n apiBaseUrl?: string;\n createdAt?: string;\n githubDomain?: string;\n source?: string;\n token: string;\n}\n\nexport function authStorePath(env: NodeJS.ProcessEnv = process.env): string {\n const explicit = envValue(env.HOOPILOT_AUTH_FILE);\n if (explicit) {\n return explicit;\n }\n\n const xdg = envValue(env.XDG_CONFIG_HOME);\n if (xdg) {\n return join(xdg, \"hoopilot\", \"auth.json\");\n }\n const appdata = envValue(env.APPDATA);\n if (appdata) {\n return join(appdata, \"hoopilot\", \"auth.json\");\n }\n const home = envValue(env.HOME);\n if (!home) {\n throw new StoredCopilotAuthError(\n \"Cannot resolve Hoopilot auth file path without HOOPILOT_AUTH_FILE, XDG_CONFIG_HOME, APPDATA, or HOME.\",\n );\n }\n const base = join(home, \".config\");\n return join(base, \"hoopilot\", \"auth.json\");\n}\n\nexport function readStoredCopilotAuth(path = authStorePath()): StoredCopilotAuth | undefined {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined;\n }\n throw new StoredCopilotAuthError(`Could not read Hoopilot auth file at ${path}.`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new StoredCopilotAuthError(\n `Hoopilot auth file at ${path} is not valid JSON. Run \\`hoopilot login\\` to replace it.`,\n );\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new StoredCopilotAuthError(`Hoopilot auth file at ${path} must contain a JSON object.`);\n }\n const record = parsed as Record<string, unknown>;\n const token = typeof record.token === \"string\" ? record.token.trim() : \"\";\n if (!token) {\n throw new StoredCopilotAuthError(`Hoopilot auth file at ${path} does not contain a token.`);\n }\n return {\n apiBaseUrl: typeof record.apiBaseUrl === \"string\" ? record.apiBaseUrl : undefined,\n createdAt: typeof record.createdAt === \"string\" ? record.createdAt : undefined,\n githubDomain: typeof record.githubDomain === \"string\" ? record.githubDomain : undefined,\n source: typeof record.source === \"string\" ? record.source : undefined,\n token,\n };\n}\n\nexport function writeStoredCopilotAuth(auth: StoredCopilotAuth, path = authStorePath()): void {\n mkdirSync(dirname(path), { recursive: true });\n const data = `${JSON.stringify(\n {\n ...auth,\n createdAt: auth.createdAt ?? new Date().toISOString(),\n },\n null,\n 2,\n )}\\n`;\n // Write to a sibling temp file, then rename into place so a crash or full\n // disk mid-write can never leave a truncated credential file behind.\n const tmpPath = `${path}.${process.pid}.tmp`;\n writeFileSync(tmpPath, data, { mode: 0o600 });\n renameSync(tmpPath, path);\n try {\n chmodSync(path, 0o600);\n } catch {\n // chmod is best-effort on Windows.\n }\n}\n","import {\n readStoredCopilotAuth,\n type StoredCopilotAuth,\n StoredCopilotAuthError,\n} from \"./auth-store\";\nimport type { CopilotAccess, CopilotAuthOptions } from \"./types\";\nimport { envValue, trimTrailingSlash } from \"./util\";\n\nexport const DEFAULT_COPILOT_API_BASE_URL = \"https://api.githubcopilot.com\";\nconst REFRESH_SKEW_MS = 60_000;\nconst STORED_TOKEN_TTL_MS = 10 * 60_000;\n\nexport class CopilotAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"CopilotAuthError\";\n }\n}\n\nexport class CopilotAuth {\n readonly #authStorePath?: string;\n readonly #copilotApiBaseUrl: string;\n readonly #hasCopilotApiBaseUrlOverride: boolean;\n #cachedAccess?: CopilotAccess;\n\n constructor(options: CopilotAuthOptions = {}) {\n const envAuthStorePath = envValue(options.env?.HOOPILOT_AUTH_FILE);\n const envCopilotApiBaseUrl = envValue(options.env?.COPILOT_API_BASE_URL);\n this.#authStorePath = options.authStorePath ?? envAuthStorePath;\n this.#hasCopilotApiBaseUrlOverride = Boolean(options.copilotApiBaseUrl ?? envCopilotApiBaseUrl);\n this.#copilotApiBaseUrl = trimTrailingSlash(\n options.copilotApiBaseUrl ?? envCopilotApiBaseUrl ?? DEFAULT_COPILOT_API_BASE_URL,\n );\n }\n\n async getAccess(): Promise<CopilotAccess> {\n if (this.#cachedAccess && this.#cachedAccess.expiresAtMs - REFRESH_SKEW_MS > Date.now()) {\n return this.#cachedAccess;\n }\n\n let stored: StoredCopilotAuth | undefined;\n try {\n stored = readStoredCopilotAuth(this.#authStorePath);\n } catch (error) {\n if (error instanceof StoredCopilotAuthError) {\n throw new CopilotAuthError(error.message);\n }\n throw error;\n }\n if (stored) {\n return this.#cacheAccess({\n apiBaseUrl: trimTrailingSlash(\n this.#hasCopilotApiBaseUrlOverride\n ? this.#copilotApiBaseUrl\n : (stored.apiBaseUrl ?? this.#copilotApiBaseUrl),\n ),\n expiresAtMs: Date.now() + STORED_TOKEN_TTL_MS,\n source: \"github-copilot-oauth\",\n token: stored.token,\n });\n }\n\n throw new CopilotAuthError(\n \"No GitHub Copilot OAuth credential found. Run `hoopilot login` to sign in through your browser.\",\n );\n }\n\n #cacheAccess(access: CopilotAccess): CopilotAccess {\n this.#cachedAccess = access;\n return access;\n }\n}\n","import { CopilotAuth } from \"./auth\";\nimport type {\n CopilotAuthOptions,\n CopilotQuota,\n CopilotUsage,\n FetchLike,\n JsonObject,\n} from \"./types\";\nimport { asRecord, envValue, isTrustedTokenBaseUrl, trimTrailingSlash } from \"./util\";\n\n/** Default GitHub REST host that serves the `copilot_internal/user` quota route. */\nexport const DEFAULT_GITHUB_API_BASE_URL = \"https://api.github.com\";\nconst ALLOWED_COPILOT_API_HOSTS = [\"api.githubcopilot.com\"] as const;\nconst ALLOWED_GITHUB_API_HOSTS = [\"api.github.com\"] as const;\n\n/**\n * API version sent to the GitHub `copilot_internal` endpoints. This is a\n * different surface from the Copilot completions API (`x-github-api-version`\n * `2026-06-01`), so it is pinned separately and bumped independently.\n */\nexport const COPILOT_USAGE_API_VERSION = \"2025-04-01\";\n\n/**\n * Set the GitHub Copilot API request headers on `headers`, leaving any\n * caller-provided `accept` intact. Single source of truth for the pinned\n * integration id, editor/plugin versions, and API version so the proxy client\n * and the login-time verification call cannot drift apart.\n */\nexport function applyCopilotHeaders(headers: Headers, token: string): Headers {\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `Bearer ${token}`);\n headers.set(\"copilot-integration-id\", \"vscode-chat\");\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"openai-intent\", \"conversation-panel\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", \"2026-06-01\");\n return headers;\n}\n\n/**\n * Set headers for the GitHub REST `copilot_internal/user` quota call. This host\n * is `api.github.com` (not the Copilot API host) and expects the `token` auth\n * scheme with the raw stored OAuth token — not the `Bearer` scheme used by the\n * Copilot completion endpoints.\n */\nexport function applyGithubApiHeaders(headers: Headers, token: string): Headers {\n headers.set(\"accept\", headers.get(\"accept\") ?? \"application/json\");\n headers.set(\"authorization\", `token ${token}`);\n headers.set(\"editor-plugin-version\", \"hoopilot/0.1.0\");\n headers.set(\"editor-version\", \"Hoopilot/0.1.0\");\n headers.set(\"user-agent\", \"hoopilot/0.1.0\");\n headers.set(\"x-github-api-version\", COPILOT_USAGE_API_VERSION);\n return headers;\n}\n\nexport class CopilotClient {\n readonly #auth: CopilotAuth;\n readonly #allowUnsafeUpstream: boolean;\n readonly #fetch: FetchLike;\n readonly #githubApiBaseUrl: string;\n\n constructor(options: CopilotAuthOptions = {}) {\n this.#auth = new CopilotAuth(options);\n this.#allowUnsafeUpstream = envValue(options.env?.HOOPILOT_ALLOW_UNSAFE_UPSTREAM) === \"1\";\n this.#fetch = options.fetch ?? fetch;\n this.#githubApiBaseUrl = trimTrailingSlash(\n options.githubApiBaseUrl ??\n envValue(options.env?.HOOPILOT_GITHUB_API_BASE_URL) ??\n DEFAULT_GITHUB_API_BASE_URL,\n );\n }\n\n /**\n * Fetch the Copilot account's quota / premium-request usage from the GitHub\n * REST `copilot_internal/user` endpoint. The stored device-flow OAuth token is\n * accepted directly here — no Copilot token exchange is required to read quota.\n */\n async usage(signal?: AbortSignal): Promise<Response> {\n // The quota call sends the raw, long-lived OAuth token. Never transmit it\n // over plaintext to a non-loopback host, so a misconfigured base URL cannot\n // exfiltrate the credential.\n if (\n !isTrustedTokenBaseUrl(\n this.#githubApiBaseUrl,\n ALLOWED_GITHUB_API_HOSTS,\n this.#allowUnsafeUpstream,\n )\n ) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted GitHub API host: ${this.#githubApiBaseUrl}`,\n );\n }\n const access = await this.#auth.getAccess();\n const headers = applyGithubApiHeaders(new Headers(), access.token);\n return this.#fetch(`${this.#githubApiBaseUrl}/copilot_internal/user`, {\n headers,\n method: \"GET\",\n signal,\n });\n }\n\n async chatCompletions(body: JsonObject, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/chat/completions\", {\n body: JSON.stringify(body),\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async responses(body: string, signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/responses\", {\n body,\n headers: {\n \"content-type\": \"application/json\",\n },\n method: \"POST\",\n signal,\n });\n }\n\n async models(signal?: AbortSignal): Promise<Response> {\n return this.fetchCopilot(\"/models\", {\n headers: {\n accept: \"application/json\",\n },\n method: \"GET\",\n signal,\n });\n }\n\n async fetchCopilot(path: string, init: RequestInit): Promise<Response> {\n const access = await this.#auth.getAccess();\n if (\n !isTrustedTokenBaseUrl(\n access.apiBaseUrl,\n ALLOWED_COPILOT_API_HOSTS,\n this.#allowUnsafeUpstream,\n )\n ) {\n throw new Error(\n `Refusing to send the GitHub OAuth token to an untrusted Copilot API host: ${access.apiBaseUrl}`,\n );\n }\n const headers = applyCopilotHeaders(new Headers(init.headers), access.token);\n\n return this.#fetch(`${access.apiBaseUrl}${path}`, {\n ...init,\n headers,\n });\n }\n}\n\n/**\n * Normalize a `copilot_internal/user` response into {@link CopilotUsage}. Handles\n * both the paid-plan shape (`quota_snapshots.{chat,completions,premium_interactions}`)\n * and the free-plan shape (`limited_user_quotas` remaining + `monthly_quotas`\n * allowance). `remaining` may be fractional and negative under permitted overage,\n * so `used` is derived as `max(0, entitlement - remaining)`.\n */\nexport function normalizeCopilotUsage(body: unknown): CopilotUsage {\n const record = asRecord(body);\n const quotas: Record<string, CopilotQuota> = {};\n\n const snapshots = asRecord(record.quota_snapshots);\n for (const [category, detail] of Object.entries(snapshots)) {\n quotas[category] = normalizeQuotaDetail(asRecord(detail));\n }\n\n if (Object.keys(quotas).length === 0) {\n const remaining = asRecord(record.limited_user_quotas);\n const monthly = asRecord(record.monthly_quotas);\n for (const category of new Set([...Object.keys(remaining), ...Object.keys(monthly)])) {\n const entitlement = numberOrUndefined(monthly[category]);\n const left = numberOrUndefined(remaining[category]);\n quotas[category] = removeUndefinedQuota({\n entitlement,\n percentRemaining:\n entitlement !== undefined && entitlement > 0 && left !== undefined\n ? (left / entitlement) * 100\n : undefined,\n remaining: left,\n used: usedFrom(entitlement, left),\n });\n }\n }\n\n return removeUndefinedUsage({\n accessTypeSku: stringOrUndefined(record.access_type_sku),\n chatEnabled: typeof record.chat_enabled === \"boolean\" ? record.chat_enabled : undefined,\n plan: stringOrUndefined(record.copilot_plan),\n quotaResetDate:\n stringOrUndefined(record.quota_reset_date) ??\n stringOrUndefined(record.quota_reset_date_utc) ??\n stringOrUndefined(record.limited_user_reset_date),\n quotas,\n });\n}\n\nfunction normalizeQuotaDetail(detail: JsonObject): CopilotQuota {\n const entitlement = numberOrUndefined(detail.entitlement);\n const overageCount = numberOrUndefined(detail.overage_count);\n const remaining =\n numberOrUndefined(detail.remaining) ?? numberOrUndefined(detail.quota_remaining);\n return removeUndefinedQuota({\n entitlement,\n hasQuota: typeof detail.has_quota === \"boolean\" ? detail.has_quota : undefined,\n overageCount,\n overageEntitlement: numberOrUndefined(detail.overage_entitlement),\n overagePermitted:\n typeof detail.overage_permitted === \"boolean\" ? detail.overage_permitted : undefined,\n percentRemaining: numberOrUndefined(detail.percent_remaining),\n quotaId: stringOrUndefined(detail.quota_id),\n quotaResetAt: stringOrUndefined(detail.quota_reset_at),\n remaining,\n timestampUtc: stringOrUndefined(detail.timestamp_utc),\n tokenBasedBilling:\n typeof detail.token_based_billing === \"boolean\" ? detail.token_based_billing : undefined,\n unlimited: typeof detail.unlimited === \"boolean\" ? detail.unlimited : undefined,\n used: usedFrom(entitlement, remaining, overageCount),\n });\n}\n\nfunction usedFrom(\n entitlement: number | undefined,\n remaining: number | undefined,\n overageCount?: number,\n): number | undefined {\n if (entitlement === undefined || remaining === undefined) {\n return undefined;\n }\n const base = entitlement - remaining;\n const overage = remaining === 0 ? (overageCount ?? 0) : 0;\n return Math.max(0, base + overage);\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction removeUndefinedQuota(quota: CopilotQuota): CopilotQuota {\n return Object.fromEntries(\n Object.entries(quota).filter(([, value]) => value !== undefined),\n ) as CopilotQuota;\n}\n\nfunction removeUndefinedUsage(usage: CopilotUsage): CopilotUsage {\n const entries = Object.entries(usage).filter(([, value]) => value !== undefined);\n return Object.fromEntries(entries) as unknown as CopilotUsage;\n}\n","import { setTimeout as sleep } from \"node:timers/promises\";\nimport type { FetchLike, Logger } from \"./types\";\nimport { envValue, truncatedResponseText } from \"./util\";\n\nexport const DEFAULT_GITHUB_COPILOT_CLIENT_ID = \"Ov23li8tweQw6odWQebz\";\nconst DEFAULT_GITHUB_DOMAIN = \"github.com\";\nconst DEVICE_GRANT_TYPE = \"urn:ietf:params:oauth:grant-type:device_code\";\nconst POLLING_SAFETY_MARGIN_MS = 3_000;\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport interface GithubCopilotDeviceLoginOptions {\n clientId?: string;\n domain?: string;\n env?: NodeJS.ProcessEnv;\n fetch?: FetchLike;\n logger?: Logger;\n openBrowser?: (url: string) => void | Promise<void>;\n sleep?: (ms: number) => Promise<void>;\n}\n\nexport interface GithubCopilotDeviceLoginResult {\n domain: string;\n token: string;\n}\n\ninterface DeviceCodeResponse {\n device_code?: string;\n expires_in?: number;\n interval?: number;\n user_code?: string;\n verification_uri?: string;\n}\n\ninterface DeviceTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n interval?: number;\n}\n\nexport async function githubCopilotDeviceLogin(\n options: GithubCopilotDeviceLoginOptions = {},\n): Promise<GithubCopilotDeviceLoginResult> {\n const env = options.env ?? process.env;\n const fetcher = options.fetch ?? fetch;\n const sleeper = options.sleep ?? sleep;\n const domain = normalizeDomain(\n options.domain ?? envValue(env.HOOPILOT_GITHUB_DOMAIN) ?? DEFAULT_GITHUB_DOMAIN,\n );\n const clientId =\n options.clientId ??\n envValue(env.HOOPILOT_GITHUB_CLIENT_ID) ??\n envValue(env.COPILOT_GITHUB_CLIENT_ID) ??\n DEFAULT_GITHUB_COPILOT_CLIENT_ID;\n\n const device = await requestDeviceCode(fetcher, domain, clientId);\n const verificationUrl = device.verification_uri;\n const userCode = device.user_code;\n const deviceCode = device.device_code;\n if (!verificationUrl || !userCode || !deviceCode) {\n throw new Error(\"GitHub device authorization response is missing required fields.\");\n }\n\n options.logger?.info(`First copy your one-time code: ${userCode}`);\n options.logger?.info(`Open ${verificationUrl} in your browser to authorize Hoopilot.`);\n await options.openBrowser?.(verificationUrl);\n\n return {\n domain,\n token: await pollForAccessToken(fetcher, sleeper, domain, clientId, {\n deviceCode,\n expiresIn: positiveSeconds(device.expires_in, 900),\n interval: positiveSeconds(device.interval, 5),\n }),\n };\n}\n\nasync function requestDeviceCode(\n fetcher: FetchLike,\n domain: string,\n clientId: string,\n): Promise<DeviceCodeResponse> {\n const response = await fetcher(`https://${domain}/login/device/code`, {\n body: JSON.stringify({\n client_id: clientId,\n scope: \"read:user\",\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (!response.ok) {\n throw new Error(\n `GitHub device authorization failed with ${response.status}: ${await truncatedResponseText(\n response,\n )}`,\n );\n }\n return parseJsonResponse<DeviceCodeResponse>(\n response,\n \"GitHub device authorization response was not valid JSON\",\n );\n}\n\nasync function pollForAccessToken(\n fetcher: FetchLike,\n sleeper: (ms: number) => Promise<void>,\n domain: string,\n clientId: string,\n device: { deviceCode: string; expiresIn: number; interval: number },\n): Promise<string> {\n let intervalMs = device.interval * 1000 + POLLING_SAFETY_MARGIN_MS;\n const deadline = Date.now() + device.expiresIn * 1000;\n\n while (Date.now() < deadline) {\n await sleeper(intervalMs);\n const response = await fetcher(`https://${domain}/login/oauth/access_token`, {\n body: JSON.stringify({\n client_id: clientId,\n device_code: device.deviceCode,\n grant_type: DEVICE_GRANT_TYPE,\n }),\n headers: oauthHeaders(),\n method: \"POST\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n throw new Error(\n `GitHub device token exchange failed with ${response.status}: ${await truncatedResponseText(\n response,\n )}`,\n );\n }\n\n const data = await parseJsonResponse<DeviceTokenResponse>(\n response,\n \"GitHub device token response was not valid JSON\",\n );\n if (data.access_token) {\n return data.access_token;\n }\n\n if (data.error === \"authorization_pending\") {\n continue;\n }\n if (data.error === \"slow_down\") {\n intervalMs =\n positiveSeconds(data.interval, device.interval + 5) * 1000 + POLLING_SAFETY_MARGIN_MS;\n continue;\n }\n if (data.error === \"expired_token\") {\n throw new Error(\"GitHub device login expired. Run `hoopilot login` again.\");\n }\n if (data.error === \"access_denied\") {\n throw new Error(\"GitHub device login was cancelled.\");\n }\n if (data.error) {\n throw new Error(data.error_description || `GitHub device login failed: ${data.error}`);\n }\n }\n\n throw new Error(\"GitHub device login timed out. Run `hoopilot login` again.\");\n}\n\nfunction oauthHeaders(): Headers {\n const headers = new Headers();\n headers.set(\"accept\", \"application/json\");\n headers.set(\"content-type\", \"application/json\");\n headers.set(\"user-agent\", \"hoopilot\");\n return headers;\n}\n\nfunction normalizeDomain(value: string): string {\n const raw = value.trim();\n const withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(raw) ? raw : `https://${raw}`;\n let url: URL;\n try {\n url = new URL(withScheme);\n } catch {\n throw new Error(`Invalid GitHub domain: ${value}.`);\n }\n if (\n (url.protocol !== \"https:\" && url.protocol !== \"http:\") ||\n url.username ||\n url.password ||\n !url.hostname ||\n (url.pathname !== \"\" && url.pathname !== \"/\") ||\n url.search ||\n url.hash\n ) {\n throw new Error(`Invalid GitHub domain: ${value}. Provide only a hostname.`);\n }\n return url.host;\n}\n\nfunction positiveSeconds(value: unknown, fallback: number): number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 ? value : fallback;\n}\n\nasync function parseJsonResponse<T>(response: Response, context: string): Promise<T> {\n const text = await response.text();\n try {\n return JSON.parse(text) as T;\n } catch {\n throw new Error(`${context}: ${text.slice(0, 500)}`);\n }\n}\n","import pino from \"pino\";\nimport pretty from \"pino-pretty\";\nimport type {\n HoopilotLogger,\n HoopilotLoggerOptions,\n LogFields,\n LogFormat,\n LogLevel,\n} from \"./types\";\nimport { envValue } from \"./util\";\n\nexport const DEFAULT_LOG_FORMAT: LogFormat = \"pretty\";\nexport const DEFAULT_LOG_LEVEL: LogLevel = \"info\";\n\nconst LOG_FORMATS = [\"json\", \"pretty\"] as const;\nconst LOG_LEVELS = [\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\", \"silent\"] as const;\nconst REDACT_PATHS = [\n \"apiKey\",\n \"authorization\",\n \"cookie\",\n \"headers.authorization\",\n \"headers.Authorization\",\n \"headers.cookie\",\n \"headers.Cookie\",\n \"headers.x-api-key\",\n \"headers.X-Api-Key\",\n \"token\",\n \"*.apiKey\",\n \"*.authorization\",\n \"*.cookie\",\n \"*.token\",\n \"*.headers.authorization\",\n \"*.headers.Authorization\",\n \"*.headers.cookie\",\n \"*.headers.Cookie\",\n \"*.headers.x-api-key\",\n \"*.headers.X-Api-Key\",\n];\n\nexport const noopLogger: HoopilotLogger = {\n child: () => noopLogger,\n debug: () => {},\n error: () => {},\n fatal: () => {},\n info: () => {},\n trace: () => {},\n warn: () => {},\n};\n\nexport function createHoopilotLogger(options: HoopilotLoggerOptions = {}): HoopilotLogger {\n const env = options.env ?? process.env;\n const level = parseLogLevel(options.level ?? envValue(env.HOOPILOT_LOG_LEVEL));\n const format = parseLogFormat(options.format ?? envValue(env.HOOPILOT_LOG_FORMAT));\n const pinoOptions: pino.LoggerOptions = {\n base: {\n service: \"hoopilot\",\n ...options.base,\n },\n level,\n redact: {\n censor: \"[Redacted]\",\n paths: REDACT_PATHS,\n },\n timestamp: pino.stdTimeFunctions.isoTime,\n };\n\n if (format === \"pretty\") {\n return pino(\n pinoOptions,\n pretty({\n colorize: options.colorize ?? process.stderr.isTTY,\n destination: options.stream ?? 1,\n ignore: \"pid,hostname\",\n singleLine: true,\n translateTime: \"SYS:standard\",\n }),\n ) as HoopilotLogger;\n }\n\n if (options.stream) {\n return pino(pinoOptions, options.stream as pino.DestinationStream) as HoopilotLogger;\n }\n return pino(pinoOptions) as HoopilotLogger;\n}\n\nexport function parseLogFormat(value: string | undefined): LogFormat {\n if (!value) {\n return DEFAULT_LOG_FORMAT;\n }\n if (isLogFormat(value)) {\n return value;\n }\n throw new Error(`Invalid log format: ${value}. Expected one of: ${LOG_FORMATS.join(\", \")}.`);\n}\n\nexport function parseLogLevel(value: string | undefined): LogLevel {\n if (!value) {\n return DEFAULT_LOG_LEVEL;\n }\n if (isLogLevel(value)) {\n return value;\n }\n throw new Error(`Invalid log level: ${value}. Expected one of: ${LOG_LEVELS.join(\", \")}.`);\n}\n\nexport function shouldCreateLogger(options: {\n env?: NodeJS.ProcessEnv;\n logFormat?: string;\n logger?: HoopilotLogger;\n logLevel?: string;\n}): boolean {\n return Boolean(\n options.logger ||\n options.logFormat ||\n options.logLevel ||\n envValue(options.env?.HOOPILOT_LOG_FORMAT) ||\n envValue(options.env?.HOOPILOT_LOG_LEVEL),\n );\n}\n\n/** Build structured log fields describing an error, for the `err` log key. */\nexport function errorDetails(error: unknown): LogFields {\n if (error instanceof Error) {\n return {\n message: error.message,\n name: error.name,\n stack: error.stack,\n };\n }\n return { message: String(error) };\n}\n\nfunction isLogFormat(value: string): value is LogFormat {\n return (LOG_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isLogLevel(value: string): value is LogLevel {\n return (LOG_LEVELS as readonly string[]).includes(value);\n}\n","import type { JsonObject, TokenUsage } from \"./types\";\nimport { asRecord } from \"./util\";\n\nexport const DEFAULT_MODEL = \"gpt-4.1\";\n\ninterface ResponseStreamOptions {\n model: string;\n responseId?: string;\n}\n\ninterface AccumulatedToolCall {\n arguments: string;\n id: string;\n index: number;\n itemId?: string;\n name: string;\n outputIndex?: number;\n}\n\nexport class OpenAICompatibilityError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenAICompatibilityError\";\n }\n}\n\nexport function responsesRequestToChatCompletion(request: JsonObject): JsonObject {\n const messages: unknown[] = [];\n const instructions = contentToText(request.instructions);\n if (instructions) {\n messages.push({ content: instructions, role: \"system\" });\n }\n\n for (const message of inputToMessages(request.input)) {\n messages.push(message);\n }\n\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n max_tokens: request.max_output_tokens ?? request.max_tokens,\n messages,\n metadata: request.metadata,\n model: normalizeRequestedModel(request.model),\n presence_penalty: request.presence_penalty,\n reasoning_effort: asRecord(request.reasoning).effort,\n response_format: asRecord(request.text).format,\n seed: request.seed,\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: chatToolChoice(request.tool_choice),\n tools: chatTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function normalizeChatCompletionRequest(request: JsonObject): JsonObject {\n return removeUndefined({\n ...request,\n model: normalizeRequestedModel(request.model),\n });\n}\n\nexport function completionsRequestToChatCompletion(request: JsonObject): JsonObject {\n assertSupportedLegacyCompletionRequest(request);\n return removeUndefined({\n frequency_penalty: request.frequency_penalty,\n logit_bias: request.logit_bias,\n max_tokens: request.max_tokens,\n messages: [{ content: legacyPromptToText(request.prompt), role: \"user\" }],\n model: normalizeRequestedModel(request.model),\n n: request.n,\n presence_penalty: request.presence_penalty,\n seed: request.seed,\n stop: request.stop,\n stream: request.stream === true,\n stream_options: request.stream_options,\n temperature: request.temperature,\n top_p: request.top_p,\n user: request.user,\n });\n}\n\nexport function normalizeRequestedModel(model: unknown): string {\n const requested = contentToText(model).trim();\n return requested || DEFAULT_MODEL;\n}\n\nexport function chatCompletionToResponse(completion: JsonObject, responseId?: string): JsonObject {\n const id = responseId ?? `resp_${randomId()}`;\n const choice = firstChoice(completion);\n const message = asRecord(choice.message);\n const model = contentToText(completion.model) || DEFAULT_MODEL;\n const output = outputItemsFromMessage(message);\n const usage = responseUsage(completion.usage);\n\n return removeUndefined({\n created_at: epochSeconds(),\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n output_text: outputText(output),\n parallel_tool_calls: true,\n status: \"completed\",\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n usage,\n });\n}\n\nexport function chatCompletionToCompletion(completion: JsonObject): JsonObject {\n return removeUndefined({\n choices: completionChoices(completion).map((choice, index) => {\n const message = asRecord(choice.message);\n return {\n finish_reason: choice.finish_reason ?? \"stop\",\n index: typeof choice.index === \"number\" ? choice.index : index,\n logprobs: choice.logprobs ?? null,\n text: contentToText(choice.text) || contentToText(message.content),\n };\n }),\n created: completion.created ?? epochSeconds(),\n id: completion.id ?? `cmpl_${randomId()}`,\n model: completion.model ?? DEFAULT_MODEL,\n object: \"text_completion\",\n system_fingerprint: completion.system_fingerprint,\n usage: completion.usage,\n });\n}\n\nexport function completionStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let sawTerminalEvent = false;\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (data: JsonObject | \"[DONE]\") => {\n controller.enqueue(encoder.encode(encodeDataSse(data)));\n };\n const markTerminal = () => {\n sawTerminalEvent = true;\n };\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const blocks = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = blocks.pop() ?? \"\";\n for (const block of blocks) {\n processCompletionSseBlock(block, enqueue, markTerminal);\n }\n }\n const tail = `${buffer}${decoder.decode()}`;\n if (tail.trim()) {\n processCompletionSseBlock(tail, enqueue, markTerminal);\n }\n if (!sawTerminalEvent) {\n enqueue(\"[DONE]\");\n }\n controller.close();\n } catch (error) {\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nexport function completionSseTextFromChatSseText(text: string): string {\n const chunks: string[] = [];\n let sawTerminalEvent = false;\n const enqueue = (data: JsonObject | \"[DONE]\") => {\n chunks.push(encodeDataSse(data));\n };\n const markTerminal = () => {\n sawTerminalEvent = true;\n };\n\n for (const block of text.split(/\\r?\\n\\r?\\n/)) {\n if (block.trim()) {\n processCompletionSseBlock(block, enqueue, markTerminal);\n }\n }\n if (!sawTerminalEvent) {\n enqueue(\"[DONE]\");\n }\n return chunks.join(\"\");\n}\n\nexport function normalizeModelsResponse(upstream: unknown): JsonObject {\n const record = asRecord(upstream);\n const data = Array.isArray(record.data) ? record.data : Array.isArray(upstream) ? upstream : [];\n const models = data\n .map((model) => asRecord(model))\n .filter((model) => typeof model.id === \"string\")\n .map((model) => ({\n created: model.created ?? 0,\n id: model.id,\n object: \"model\",\n owned_by: model.owned_by ?? \"github-copilot\",\n }));\n\n return {\n data: models.length > 0 ? models : fallbackModels(),\n object: \"list\",\n };\n}\n\nexport function fallbackModels(): Array<JsonObject> {\n return [\n {\n created: 0,\n id: DEFAULT_MODEL,\n object: \"model\",\n owned_by: \"github-copilot\",\n },\n ];\n}\n\nexport function responsesStreamFromChatStream(\n chatStream: ReadableStream<Uint8Array>,\n options: ResponseStreamOptions,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const decoder = new TextDecoder();\n const responseId = options.responseId ?? `resp_${randomId()}`;\n const messageId = `msg_${randomId()}`;\n const createdAt = epochSeconds();\n let buffer = \"\";\n let text = \"\";\n let messageOutputIndex: number | undefined;\n let nextOutputIndex = 0;\n let sequenceNumber = 0;\n const tools = new Map<number, AccumulatedToolCall>();\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject | \"[DONE]\") => {\n controller.enqueue(\n encoder.encode(\n encodeSse(\n event,\n data === \"[DONE]\" ? data : { ...data, sequence_number: sequenceNumber++ },\n ),\n ),\n );\n };\n\n enqueue(\"response.created\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"in_progress\", []),\n type: \"response.created\",\n });\n\n const ensureMessageStarted = () => {\n if (messageOutputIndex !== undefined) {\n return;\n }\n messageOutputIndex = nextOutputIndex++;\n enqueue(\"response.output_item.added\", {\n item: {\n content: [],\n id: messageId,\n role: \"assistant\",\n status: \"in_progress\",\n type: \"message\",\n },\n output_index: messageOutputIndex,\n type: \"response.output_item.added\",\n });\n enqueue(\"response.content_part.added\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n part: {\n annotations: [],\n text: \"\",\n type: \"output_text\",\n },\n type: \"response.content_part.added\",\n });\n };\n\n const appendText = (delta: string) => {\n ensureMessageStarted();\n text += delta;\n enqueue(\"response.output_text.delta\", {\n content_index: 0,\n delta,\n item_id: messageId,\n output_index: messageOutputIndex ?? 0,\n type: \"response.output_text.delta\",\n });\n };\n\n const appendToolCall = (toolCall: JsonObject) => {\n const fn = asRecord(toolCall.function);\n const index = typeof toolCall.index === \"number\" ? toolCall.index : tools.size;\n let existing = tools.get(index);\n const isNew = !existing;\n existing ??= {\n arguments: \"\",\n id: contentToText(toolCall.id) || `call_${randomId()}`,\n index,\n itemId: `fc_${randomId()}`,\n name: \"\",\n outputIndex: nextOutputIndex++,\n };\n existing.id = contentToText(toolCall.id) || existing.id;\n existing.name += contentToText(fn.name);\n tools.set(index, existing);\n\n if (isNew) {\n enqueue(\"response.output_item.added\", {\n item: functionCallItem(existing, \"in_progress\"),\n output_index: existing.outputIndex ?? 0,\n type: \"response.output_item.added\",\n });\n }\n\n const argumentDelta = contentToText(fn.arguments);\n if (argumentDelta) {\n existing.arguments += argumentDelta;\n enqueue(\"response.function_call_arguments.delta\", {\n delta: argumentDelta,\n item_id: existing.itemId,\n output_index: existing.outputIndex ?? 0,\n type: \"response.function_call_arguments.delta\",\n });\n }\n };\n\n const reader = chatStream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n processChatSseLine(line, { appendText, appendToolCall });\n }\n }\n if (buffer) {\n processChatSseLine(buffer, { appendText, appendToolCall });\n }\n\n // Build the output items once so the ids emitted in the per-tool stream\n // events match the ids embedded in the final response.completed payload.\n const outputEntries: Array<[number, JsonObject]> = [];\n if (messageOutputIndex !== undefined) {\n const item = messageOutputItem(text, messageId);\n outputEntries.push([messageOutputIndex, item]);\n enqueue(\"response.output_text.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n text,\n type: \"response.output_text.done\",\n });\n enqueue(\"response.content_part.done\", {\n content_index: 0,\n item_id: messageId,\n output_index: messageOutputIndex,\n part: {\n annotations: [],\n text,\n type: \"output_text\",\n },\n type: \"response.content_part.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: messageOutputIndex,\n type: \"response.output_item.done\",\n });\n }\n\n for (const tool of [...tools.values()].sort(\n (a, b) => (a.outputIndex ?? 0) - (b.outputIndex ?? 0),\n )) {\n const item = functionCallItem(tool);\n const outputIndex = tool.outputIndex ?? 0;\n outputEntries.push([outputIndex, item]);\n enqueue(\"response.function_call_arguments.done\", {\n arguments: tool.arguments,\n item_id: item.id,\n output_index: outputIndex,\n type: \"response.function_call_arguments.done\",\n });\n enqueue(\"response.output_item.done\", {\n item,\n output_index: outputIndex,\n type: \"response.output_item.done\",\n });\n }\n\n const output = outputEntries\n .sort(([left], [right]) => left - right)\n .map(([, item]) => item);\n\n enqueue(\"response.completed\", {\n response: baseStreamResponse(responseId, options.model, createdAt, \"completed\", output),\n type: \"response.completed\",\n });\n enqueue(\"done\", \"[DONE]\");\n controller.close();\n } catch (error) {\n // Tear down the upstream body so an output-side error/abort cannot leak it.\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nfunction inputToMessages(input: unknown): unknown[] {\n if (typeof input === \"string\") {\n return [{ content: input, role: \"user\" }];\n }\n if (!Array.isArray(input)) {\n return [];\n }\n\n const messages: unknown[] = [];\n for (const item of input) {\n const record = asRecord(item);\n const type = contentToText(record.type);\n if (type === \"function_call_output\") {\n messages.push({\n content: contentToText(record.output),\n role: \"tool\",\n tool_call_id: contentToText(record.call_id),\n });\n continue;\n }\n if (type === \"function_call\") {\n messages.push({\n role: \"assistant\",\n tool_calls: [\n {\n function: {\n arguments: contentToText(record.arguments),\n name: contentToText(record.name),\n },\n id: contentToText(record.call_id) || contentToText(record.id),\n type: \"function\",\n },\n ],\n });\n continue;\n }\n if (type && type !== \"message\") {\n unsupportedResponsesFeature(`input item type \"${type}\"`);\n }\n const role = responsesRoleToChatRole(contentToText(record.role));\n const content = chatMessageContent(record.content);\n if (role && content !== undefined) {\n messages.push({ content, role });\n }\n }\n return messages;\n}\n\nfunction chatMessageContent(content: unknown): string | Array<JsonObject> | undefined {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n if (content === undefined || content === null) {\n return undefined;\n }\n unsupportedResponsesFeature(\"non-array message content objects\");\n }\n\n const parts: JsonObject[] = [];\n for (const part of content) {\n const record = asRecord(part);\n const type = contentToText(record.type);\n if (type === \"input_text\" || type === \"output_text\" || type === \"text\") {\n parts.push({ text: contentToText(record.text), type: \"text\" });\n continue;\n }\n if (type === \"input_image\") {\n if (contentToText(record.file_id)) {\n unsupportedResponsesFeature(\"input_image file_id parts\");\n }\n const imageUrl = contentToText(record.image_url);\n if (!imageUrl) {\n unsupportedResponsesFeature(\"input_image parts without image_url\");\n }\n const image: JsonObject = { url: imageUrl };\n const detail = contentToText(record.detail);\n if (detail) {\n image.detail = detail;\n }\n parts.push({ image_url: image, type: \"image_url\" });\n continue;\n }\n if (type === \"input_file\") {\n unsupportedResponsesFeature(\"input_file parts\");\n }\n if (type === \"input_audio\") {\n unsupportedResponsesFeature(\"input_audio parts\");\n }\n unsupportedResponsesFeature(`content part type \"${type || \"unknown\"}\"`);\n }\n\n if (parts.length === 0) {\n return undefined;\n }\n if (parts.every((part) => part.type === \"text\")) {\n return parts.map((part) => contentToText(part.text)).join(\"\\n\");\n }\n return parts;\n}\n\nfunction legacyPromptToText(prompt: unknown): string {\n if (typeof prompt === \"string\") {\n return prompt;\n }\n if (Array.isArray(prompt) && prompt.length === 1 && typeof prompt[0] === \"string\") {\n return prompt[0];\n }\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility supports exactly one string prompt per request.\",\n );\n}\n\nfunction assertSupportedLegacyCompletionRequest(request: JsonObject): void {\n if (request.echo === true) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support echo=true.\",\n );\n }\n if (typeof request.best_of === \"number\" && request.best_of > 1) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support best_of greater than 1.\",\n );\n }\n if (typeof request.logprobs === \"number\" && request.logprobs > 0) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support legacy logprobs.\",\n );\n }\n if (contentToText(request.suffix)) {\n throw new OpenAICompatibilityError(\n \"Hoopilot legacy completions compatibility does not support suffix.\",\n );\n }\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (typeof content === \"number\" || typeof content === \"boolean\") {\n return String(content);\n }\n if (Array.isArray(content)) {\n return content\n .map((item) => contentToText(item))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content && typeof content === \"object\") {\n const record = content as Record<string, unknown>;\n if (typeof record.text === \"string\") {\n return record.text;\n }\n if (typeof record.output_text === \"string\") {\n return record.output_text;\n }\n return JSON.stringify(content);\n }\n return \"\";\n}\n\nfunction responsesRoleToChatRole(role: string): string | undefined {\n if (!role) {\n return \"user\";\n }\n if (\n role === \"assistant\" ||\n role === \"developer\" ||\n role === \"system\" ||\n role === \"tool\" ||\n role === \"user\"\n ) {\n return role === \"developer\" ? \"system\" : role;\n }\n unsupportedResponsesFeature(`message role \"${role}\"`);\n}\n\nfunction chatTools(tools: unknown): unknown[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools.map((tool) => {\n const record = asRecord(tool);\n const type = contentToText(record.type);\n if (type !== \"function\") {\n unsupportedResponsesFeature(`tool type \"${type || \"unknown\"}\"`);\n }\n return {\n function: removeUndefined({\n description: record.description,\n name: record.name,\n parameters: record.parameters,\n strict: record.strict,\n }),\n type: \"function\",\n };\n });\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction chatToolChoice(toolChoice: unknown): unknown {\n if (typeof toolChoice === \"string\" || toolChoice === undefined) {\n return toolChoice;\n }\n const record = asRecord(toolChoice);\n const type = contentToText(record.type);\n if (type === \"function\" && typeof record.name === \"string\") {\n return { function: { name: record.name }, type: \"function\" };\n }\n unsupportedResponsesFeature(`tool_choice type \"${type || \"unknown\"}\"`);\n}\n\nfunction unsupportedResponsesFeature(feature: string): never {\n throw new OpenAICompatibilityError(\n `Hoopilot Responses-to-chat compatibility does not support ${feature}.`,\n );\n}\n\nfunction outputItemsFromMessage(message: Record<string, unknown>): JsonObject[] {\n const output: JsonObject[] = [];\n const text = contentToText(message.content);\n if (text) {\n output.push(messageOutputItem(text));\n }\n const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];\n for (const toolCall of toolCalls) {\n const record = asRecord(toolCall);\n const fn = asRecord(record.function);\n output.push(\n functionCallItem({\n arguments: contentToText(fn.arguments),\n id: contentToText(record.id) || `call_${randomId()}`,\n index: output.length,\n name: contentToText(fn.name),\n }),\n );\n }\n return output;\n}\n\nfunction messageOutputItem(text: string, id = `msg_${randomId()}`): JsonObject {\n return {\n content: [\n {\n annotations: [],\n text,\n type: \"output_text\",\n },\n ],\n id,\n role: \"assistant\",\n status: \"completed\",\n type: \"message\",\n };\n}\n\nfunction functionCallItem(\n tool: AccumulatedToolCall,\n status: \"in_progress\" | \"completed\" = \"completed\",\n): JsonObject {\n return {\n arguments: tool.arguments,\n call_id: tool.id,\n id: tool.itemId ?? `fc_${randomId()}`,\n name: tool.name,\n status,\n type: \"function_call\",\n };\n}\n\nfunction outputText(output: JsonObject[]): string {\n return output\n .flatMap((item) => {\n const content = item.content;\n return Array.isArray(content) ? content : [];\n })\n .map((part) => contentToText(asRecord(part).text))\n .filter(Boolean)\n .join(\"\");\n}\n\nfunction responseUsage(usage: unknown): JsonObject | null {\n const record = asRecord(usage);\n if (Object.keys(record).length === 0) {\n return null;\n }\n const inputTokens = record.prompt_tokens;\n const outputTokens = record.completion_tokens;\n return removeUndefined({\n input_tokens: inputTokens,\n input_tokens_details: responseUsageDetails(record.prompt_tokens_details, inputTokens, {\n cached_tokens: 0,\n }),\n output_tokens: outputTokens,\n output_tokens_details: responseUsageDetails(record.completion_tokens_details, outputTokens, {\n reasoning_tokens: 0,\n }),\n total_tokens: record.total_tokens,\n });\n}\n\nfunction responseUsageDetails(\n value: unknown,\n tokenCount: unknown,\n fallback: JsonObject,\n): JsonObject | undefined {\n const record = asRecord(value);\n if (Object.keys(record).length > 0) {\n return record;\n }\n return typeof tokenCount === \"number\" && Number.isFinite(tokenCount) ? fallback : undefined;\n}\n\n/**\n * Normalize an upstream `usage` object into {@link TokenUsage}. Accepts both the\n * Chat Completions shape (`prompt_tokens`/`completion_tokens`) and the Responses\n * shape (`input_tokens`/`output_tokens`), and pulls nested reasoning/cached\n * details when present. Returns undefined when no token counts are available so\n * callers can distinguish \"no usage reported\" from \"zero tokens\".\n */\nexport function extractTokenUsage(usage: unknown): TokenUsage | undefined {\n const record = asRecord(usage);\n const prompt = firstNumber(record.prompt_tokens, record.input_tokens);\n const completion = firstNumber(record.completion_tokens, record.output_tokens);\n const total = firstNumber(record.total_tokens);\n if (prompt === undefined && completion === undefined && total === undefined) {\n return undefined;\n }\n const promptTokens = prompt ?? 0;\n const completionTokens = completion ?? 0;\n const reasoning = firstNumber(\n asRecord(record.completion_tokens_details).reasoning_tokens,\n asRecord(record.output_tokens_details).reasoning_tokens,\n );\n const cached = firstNumber(\n asRecord(record.prompt_tokens_details).cached_tokens,\n asRecord(record.input_tokens_details).cached_tokens,\n );\n return removeUndefined({\n cachedTokens: cached,\n completionTokens,\n promptTokens,\n reasoningTokens: reasoning,\n totalTokens: total ?? promptTokens + completionTokens,\n }) as unknown as TokenUsage;\n}\n\nfunction firstNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction firstChoice(completion: JsonObject): Record<string, unknown> {\n return completionChoices(completion)[0] ?? {};\n}\n\nfunction completionChoices(completion: JsonObject): Array<Record<string, unknown>> {\n const choices = Array.isArray(completion.choices) ? completion.choices : [];\n return choices.map((choice) => asRecord(choice));\n}\n\nfunction processCompletionSseBlock(\n block: string,\n enqueue: (data: JsonObject | \"[DONE]\") => void,\n markTerminal: () => void,\n): void {\n let event = \"message\";\n const dataLines: string[] = [];\n for (const line of block.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"event:\")) {\n event = trimmed.slice(\"event:\".length).trim() || event;\n } else if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(\"data:\".length).trim());\n }\n }\n const data = dataLines.join(\"\\n\");\n if (!data) {\n return;\n }\n if (data === \"[DONE]\") {\n markTerminal();\n enqueue(\"[DONE]\");\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const error = completionStreamError(event, parsed);\n if (error) {\n markTerminal();\n enqueue({ error });\n return;\n }\n const choices = completionChoices(parsed)\n .map((choice, index) => {\n const delta = asRecord(choice.delta);\n const text = contentToText(delta.content);\n const finishReason = choice.finish_reason ?? null;\n if (!text && finishReason === null) {\n return undefined;\n }\n return {\n finish_reason: finishReason,\n index: typeof choice.index === \"number\" ? choice.index : index,\n logprobs: choice.logprobs ?? null,\n text,\n };\n })\n .filter((choice) => choice !== undefined);\n const usage = asRecord(parsed.usage);\n const hasUsage = Object.keys(usage).length > 0;\n if (choices.length === 0 && !hasUsage) {\n return;\n }\n\n enqueue(\n removeUndefined({\n choices,\n created: typeof parsed.created === \"number\" ? parsed.created : epochSeconds(),\n id: contentToText(parsed.id) || `cmpl_${randomId()}`,\n model: contentToText(parsed.model) || DEFAULT_MODEL,\n object: \"text_completion\",\n usage: hasUsage ? usage : undefined,\n }),\n );\n}\n\nfunction completionStreamError(event: string, parsed: JsonObject): JsonObject | undefined {\n const responseError = asRecord(asRecord(parsed.response).error);\n const directError = asRecord(parsed.error);\n const error =\n Object.keys(directError).length > 0\n ? directError\n : Object.keys(responseError).length > 0\n ? responseError\n : undefined;\n if (error) {\n return error;\n }\n if (event === \"error\" || parsed.type === \"response.failed\") {\n return removeUndefined({\n code: contentToText(parsed.code) || undefined,\n message: contentToText(parsed.message) || \"Upstream streaming request failed.\",\n type: contentToText(parsed.type) || \"upstream_stream_error\",\n });\n }\n return undefined;\n}\n\nfunction processChatSseLine(\n line: string,\n handlers: {\n appendText: (delta: string) => void;\n appendToolCall: (toolCall: JsonObject) => void;\n },\n): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n\n const parsed = parseJson(data);\n if (!parsed) {\n return;\n }\n const choice = firstChoice(parsed);\n const delta = asRecord(choice.delta);\n const content = contentToText(delta.content);\n if (content) {\n handlers.appendText(content);\n }\n\n const toolCalls = Array.isArray(delta.tool_calls) ? delta.tool_calls : [];\n for (const toolCall of toolCalls) {\n handlers.appendToolCall(asRecord(toolCall));\n }\n}\n\nfunction baseStreamResponse(\n id: string,\n model: string,\n createdAt: number,\n status: \"in_progress\" | \"completed\",\n output: JsonObject[],\n): JsonObject {\n return {\n created_at: createdAt,\n error: null,\n id,\n incomplete_details: null,\n instructions: null,\n max_output_tokens: null,\n metadata: {},\n model,\n object: \"response\",\n output,\n parallel_tool_calls: true,\n status,\n temperature: null,\n tool_choice: \"auto\",\n tools: [],\n top_p: null,\n };\n}\n\nfunction encodeSse(event: string, data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction encodeDataSse(data: JsonObject | \"[DONE]\"): string {\n if (data === \"[DONE]\") {\n return \"data: [DONE]\\n\\n\";\n }\n return `data: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction parseJson(data: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(data));\n } catch {\n return undefined;\n }\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n\nfunction epochSeconds(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import { normalizeRequestedModel } from \"./openai\";\nimport type { JsonObject } from \"./types\";\nimport { asRecord } from \"./util\";\n\ninterface AnthropicStreamOptions {\n model: string;\n messageId?: string;\n}\n\ninterface StreamBlock {\n index: number;\n sentText: string;\n stopped: boolean;\n type: \"text\" | \"tool_use\";\n}\n\ninterface AnthropicStreamState {\n blocks: Map<string, StreamBlock>;\n completed: boolean;\n messageId: string;\n model: string;\n nextBlockIndex: number;\n sawToolUse: boolean;\n started: boolean;\n usage: JsonObject;\n}\n\nexport class AnthropicCompatibilityError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"AnthropicCompatibilityError\";\n }\n}\n\nexport function anthropicMessagesToResponsesRequest(request: JsonObject): JsonObject {\n return removeUndefined({\n input: anthropicMessagesToResponsesInput(request.messages),\n instructions: anthropicSystemToInstructions(request.system),\n max_output_tokens:\n typeof request.max_tokens === \"number\" && Number.isFinite(request.max_tokens)\n ? request.max_tokens\n : undefined,\n metadata: request.metadata,\n model: normalizeRequestedModel(request.model),\n parallel_tool_calls: true,\n reasoning: anthropicThinkingToReasoning(request.thinking),\n stop: anthropicStopSequences(request.stop_sequences),\n stream: request.stream === true,\n temperature: request.temperature,\n tool_choice: anthropicToolChoice(request.tool_choice),\n tools: anthropicTools(request.tools),\n top_p: request.top_p,\n });\n}\n\nexport function responsesResponseToAnthropicMessage(\n response: JsonObject,\n fallbackModel: string,\n): JsonObject {\n const content = anthropicContentFromResponsesOutput(response);\n const usage = anthropicUsage(response.usage);\n return {\n content,\n id: textValue(response.id) || `msg_${randomId()}`,\n model: textValue(response.model) || fallbackModel,\n role: \"assistant\",\n stop_reason: anthropicStopReason(response, content),\n stop_sequence: null,\n type: \"message\",\n usage,\n };\n}\n\nexport function responsesStreamToAnthropicStream(\n stream: ReadableStream<Uint8Array>,\n options: AnthropicStreamOptions,\n): ReadableStream<Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let buffer = \"\";\n const state = createAnthropicStreamState(options);\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const enqueue = (event: string, data: JsonObject) => {\n controller.enqueue(encoder.encode(encodeSse(event, data)));\n };\n const reader = stream.getReader();\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n buffer += decoder.decode(result.value, { stream: true });\n const blocks = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = blocks.pop() ?? \"\";\n for (const block of blocks) {\n processResponsesSseBlock(block, state, enqueue);\n }\n }\n const tail = `${buffer}${decoder.decode()}`;\n if (tail.trim()) {\n processResponsesSseBlock(tail, state, enqueue);\n }\n finishAnthropicStream(state, enqueue);\n controller.close();\n } catch (error) {\n await reader.cancel(error).catch(() => {});\n controller.error(error);\n } finally {\n reader.releaseLock();\n }\n },\n });\n}\n\nexport function responsesSseTextToAnthropicSseText(\n text: string,\n options: AnthropicStreamOptions,\n): string {\n const chunks: string[] = [];\n const state = createAnthropicStreamState(options);\n const enqueue = (event: string, data: JsonObject) => {\n chunks.push(encodeSse(event, data));\n };\n\n for (const block of text.split(/\\r?\\n\\r?\\n/)) {\n if (block.trim()) {\n processResponsesSseBlock(block, state, enqueue);\n }\n }\n finishAnthropicStream(state, enqueue);\n return chunks.join(\"\");\n}\n\nexport function estimateAnthropicMessageTokens(request: JsonObject): JsonObject {\n const chars =\n estimatedTextSize(request.system) +\n estimatedTextSize(request.messages) +\n estimatedTextSize(request.tools) +\n estimatedTextSize(request.tool_choice) +\n estimatedTextSize(request.thinking);\n const messageCount = Array.isArray(request.messages) ? request.messages.length : 1;\n const toolCount = Array.isArray(request.tools) ? request.tools.length : 0;\n const inputTokens = Math.max(1, Math.ceil(chars / 4) + messageCount * 4 + toolCount * 16);\n return {\n input_tokens: inputTokens,\n total_tokens: inputTokens,\n };\n}\n\nfunction createAnthropicStreamState(options: AnthropicStreamOptions): AnthropicStreamState {\n return {\n blocks: new Map(),\n completed: false,\n messageId: options.messageId ?? `msg_${randomId()}`,\n model: options.model,\n nextBlockIndex: 0,\n sawToolUse: false,\n started: false,\n usage: anthropicUsage(undefined),\n };\n}\n\nfunction anthropicMessagesToResponsesInput(messages: unknown): JsonObject[] {\n if (!Array.isArray(messages)) {\n throw new AnthropicCompatibilityError(\"Anthropic Messages requests require messages[].\");\n }\n\n const input: JsonObject[] = [];\n for (const message of messages) {\n const record = asRecord(message);\n const role = anthropicRole(record.role);\n const parts = anthropicContentParts(record.content);\n const messageParts: JsonObject[] = [];\n const flushMessage = () => {\n if (messageParts.length === 0) {\n return;\n }\n input.push({\n content: [...messageParts],\n role,\n type: \"message\",\n });\n messageParts.length = 0;\n };\n\n for (const part of parts) {\n const type = textValue(part.type) || \"text\";\n if (type === \"text\") {\n const text = textValue(part.text);\n if (text) {\n messageParts.push({\n text,\n type: role === \"assistant\" ? \"output_text\" : \"input_text\",\n });\n }\n continue;\n }\n if (type === \"image\") {\n if (role !== \"user\") {\n throw new AnthropicCompatibilityError(\n \"Anthropic image content is only supported for user messages.\",\n );\n }\n messageParts.push(anthropicImageToResponsesPart(part));\n continue;\n }\n if (type === \"tool_use\") {\n flushMessage();\n input.push({\n arguments: JSON.stringify(asRecord(part.input)),\n call_id: textValue(part.id) || `call_${randomId()}`,\n name: textValue(part.name),\n type: \"function_call\",\n });\n continue;\n }\n if (type === \"tool_result\") {\n flushMessage();\n input.push({\n call_id: textValue(part.tool_use_id),\n output: anthropicToolResultOutput(part.content),\n type: \"function_call_output\",\n });\n continue;\n }\n if (type === \"thinking\" || type === \"redacted_thinking\") {\n continue;\n }\n throw new AnthropicCompatibilityError(\n `Anthropic content block type \"${type}\" is not supported.`,\n );\n }\n flushMessage();\n }\n return input;\n}\n\nfunction anthropicRole(value: unknown): \"assistant\" | \"user\" {\n const role = textValue(value);\n if (role === \"assistant\" || role === \"user\") {\n return role;\n }\n if (!role) {\n return \"user\";\n }\n throw new AnthropicCompatibilityError(`Anthropic message role \"${role}\" is not supported.`);\n}\n\nfunction anthropicContentParts(content: unknown): JsonObject[] {\n if (typeof content === \"string\") {\n return [{ text: content, type: \"text\" }];\n }\n if (Array.isArray(content)) {\n return content.map((part) =>\n typeof part === \"string\" ? { text: part, type: \"text\" } : asRecord(part),\n );\n }\n if (content === undefined || content === null) {\n return [];\n }\n return [asRecord(content)];\n}\n\nfunction anthropicImageToResponsesPart(part: JsonObject): JsonObject {\n const source = asRecord(part.source);\n const sourceType = textValue(source.type);\n if (sourceType === \"base64\") {\n const mediaType = textValue(source.media_type) || \"image/png\";\n const data = textValue(source.data);\n if (!data) {\n throw new AnthropicCompatibilityError(\"Anthropic base64 image content requires source.data.\");\n }\n return {\n detail: \"auto\",\n image_url: `data:${mediaType};base64,${data}`,\n type: \"input_image\",\n };\n }\n if (sourceType === \"url\") {\n const url = textValue(source.url);\n if (!url) {\n throw new AnthropicCompatibilityError(\"Anthropic URL image content requires source.url.\");\n }\n return {\n detail: \"auto\",\n image_url: url,\n type: \"input_image\",\n };\n }\n throw new AnthropicCompatibilityError(\n `Anthropic image source type \"${sourceType || \"unknown\"}\" is not supported.`,\n );\n}\n\nfunction anthropicToolResultOutput(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n const record = asRecord(part);\n return textValue(record.text) || textValue(record.content) || JSON.stringify(part);\n })\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (content === undefined || content === null) {\n return \"\";\n }\n return typeof content === \"object\" ? JSON.stringify(content) : String(content);\n}\n\nfunction anthropicSystemToInstructions(system: unknown): string | undefined {\n if (typeof system === \"string\") {\n return system || undefined;\n }\n if (!Array.isArray(system)) {\n return undefined;\n }\n const text = system\n .map((part) => textValue(asRecord(part).text) || textValue(part))\n .filter(Boolean)\n .join(\"\\n\");\n return text || undefined;\n}\n\nfunction anthropicTools(tools: unknown): JsonObject[] | undefined {\n if (!Array.isArray(tools)) {\n return undefined;\n }\n const converted = tools.map((tool) => {\n const record = asRecord(tool);\n return removeUndefined({\n description: record.description,\n name: record.name,\n parameters: record.input_schema,\n strict: record.strict,\n type: \"function\",\n });\n });\n return converted.length > 0 ? converted : undefined;\n}\n\nfunction anthropicToolChoice(toolChoice: unknown): unknown {\n if (toolChoice === undefined || toolChoice === null) {\n return undefined;\n }\n const record = asRecord(toolChoice);\n const type = textValue(record.type);\n if (type === \"auto\") {\n return \"auto\";\n }\n if (type === \"any\") {\n return \"required\";\n }\n if (type === \"none\") {\n return \"none\";\n }\n if (type === \"tool\") {\n return { name: textValue(record.name), type: \"function\" };\n }\n throw new AnthropicCompatibilityError(\n `Anthropic tool_choice type \"${type || \"unknown\"}\" is not supported.`,\n );\n}\n\nfunction anthropicThinkingToReasoning(thinking: unknown): JsonObject | undefined {\n const record = asRecord(thinking);\n if (Object.keys(record).length === 0) {\n return undefined;\n }\n const type = textValue(record.type);\n if (type && type !== \"enabled\") {\n return undefined;\n }\n const budget = typeof record.budget_tokens === \"number\" ? record.budget_tokens : 0;\n return {\n effort: budget >= 16_000 ? \"high\" : budget >= 4_000 ? \"medium\" : \"low\",\n };\n}\n\nfunction anthropicStopSequences(stopSequences: unknown): unknown {\n if (!Array.isArray(stopSequences) || stopSequences.length === 0) {\n return undefined;\n }\n return stopSequences.map((sequence) => textValue(sequence)).filter(Boolean);\n}\n\nfunction anthropicContentFromResponsesOutput(response: JsonObject): JsonObject[] {\n const content: JsonObject[] = [];\n const output = Array.isArray(response.output) ? response.output : [];\n for (const item of output) {\n const record = asRecord(item);\n const type = textValue(record.type);\n if (type === \"message\") {\n const parts = Array.isArray(record.content) ? record.content : [];\n for (const part of parts) {\n const partRecord = asRecord(part);\n const text = textValue(partRecord.text) || textValue(partRecord.output_text);\n if (text) {\n content.push({ text, type: \"text\" });\n }\n }\n continue;\n }\n if (type === \"function_call\") {\n content.push({\n id: textValue(record.call_id) || textValue(record.id) || `call_${randomId()}`,\n input: parseToolInput(textValue(record.arguments)),\n name: textValue(record.name),\n type: \"tool_use\",\n });\n }\n }\n\n if (content.length === 0) {\n const outputText = textValue(response.output_text);\n if (outputText) {\n content.push({ text: outputText, type: \"text\" });\n }\n }\n return content;\n}\n\nfunction anthropicStopReason(response: JsonObject, content: JsonObject[]): string {\n if (content.some((part) => part.type === \"tool_use\")) {\n return \"tool_use\";\n }\n const incompleteReason = textValue(asRecord(response.incomplete_details).reason);\n if (textValue(response.status) === \"incomplete\" || incompleteReason === \"max_output_tokens\") {\n return \"max_tokens\";\n }\n return \"end_turn\";\n}\n\nfunction anthropicUsage(usage: unknown): JsonObject {\n const record = asRecord(usage);\n const inputTokens = firstNumber(record.input_tokens, record.prompt_tokens) ?? 0;\n const outputTokens = firstNumber(record.output_tokens, record.completion_tokens) ?? 0;\n const details = asRecord(record.input_tokens_details);\n return removeUndefined({\n cache_creation_input_tokens: firstNumber(record.cache_creation_input_tokens),\n cache_read_input_tokens:\n firstNumber(record.cache_read_input_tokens, details.cached_tokens) ?? undefined,\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n });\n}\n\nfunction processResponsesSseBlock(\n block: string,\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n const { data, event } = parseSseBlock(block);\n if (!data || data === \"[DONE]\") {\n return;\n }\n const parsed = parseJsonObject(data);\n if (!parsed) {\n return;\n }\n const type = textValue(parsed.type) || event;\n if (type === \"response.created\") {\n const response = asRecord(parsed.response);\n state.messageId = textValue(response.id) || state.messageId;\n state.model = textValue(response.model) || state.model;\n startAnthropicMessage(state, enqueue);\n return;\n }\n if (type === \"response.output_item.added\") {\n const item = asRecord(parsed.item);\n if (textValue(item.type) === \"function_call\") {\n ensureToolBlock(state, parsed, item, enqueue);\n }\n return;\n }\n if (type === \"response.output_text.delta\") {\n const blockState = ensureTextBlock(state, parsed, enqueue);\n const delta = textValue(parsed.delta);\n if (delta) {\n blockState.sentText += delta;\n enqueue(\"content_block_delta\", {\n delta: { text: delta, type: \"text_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n return;\n }\n if (type === \"response.output_text.done\" || type === \"response.content_part.done\") {\n const blockState = ensureTextBlock(state, parsed, enqueue);\n const text = textValue(parsed.text) || textValue(asRecord(parsed.part).text);\n if (text && !blockState.sentText) {\n blockState.sentText = text;\n enqueue(\"content_block_delta\", {\n delta: { text, type: \"text_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n return;\n }\n if (type === \"response.function_call_arguments.delta\") {\n const blockState = ensureToolBlock(state, parsed, {}, enqueue);\n const delta = textValue(parsed.delta);\n if (delta) {\n blockState.sentText += delta;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: delta, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n return;\n }\n if (type === \"response.function_call_arguments.done\") {\n const blockState = ensureToolBlock(state, parsed, {}, enqueue);\n const args = textValue(parsed.arguments);\n if (args && !blockState.sentText) {\n blockState.sentText = args;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: args, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n return;\n }\n if (type === \"response.output_item.done\") {\n const item = asRecord(parsed.item);\n if (textValue(item.type) === \"function_call\") {\n const blockState = ensureToolBlock(state, parsed, item, enqueue);\n const args = textValue(item.arguments);\n if (args && !blockState.sentText) {\n blockState.sentText = args;\n enqueue(\"content_block_delta\", {\n delta: { partial_json: args, type: \"input_json_delta\" },\n index: blockState.index,\n type: \"content_block_delta\",\n });\n }\n stopBlock(blockState, enqueue);\n }\n return;\n }\n if (type === \"response.completed\") {\n const response = asRecord(parsed.response);\n state.model = textValue(response.model) || state.model;\n state.usage = anthropicUsage(response.usage);\n finishAnthropicStream(state, enqueue);\n return;\n }\n if (type === \"response.failed\" || event === \"error\") {\n const error = asRecord(asRecord(parsed.response).error);\n enqueue(\"error\", {\n error: {\n message: textValue(error.message) || textValue(parsed.message) || \"Upstream stream failed.\",\n type: textValue(error.type) || \"api_error\",\n },\n type: \"error\",\n });\n state.completed = true;\n }\n}\n\nfunction startAnthropicMessage(\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n if (state.started) {\n return;\n }\n state.started = true;\n enqueue(\"message_start\", {\n message: {\n content: [],\n id: state.messageId,\n model: state.model,\n role: \"assistant\",\n stop_reason: null,\n stop_sequence: null,\n type: \"message\",\n usage: anthropicUsage(undefined),\n },\n type: \"message_start\",\n });\n}\n\nfunction finishAnthropicStream(\n state: AnthropicStreamState,\n enqueue: (event: string, data: JsonObject) => void,\n): void {\n if (state.completed) {\n return;\n }\n startAnthropicMessage(state, enqueue);\n for (const block of [...state.blocks.values()].sort((left, right) => left.index - right.index)) {\n stopBlock(block, enqueue);\n }\n enqueue(\"message_delta\", {\n delta: {\n stop_reason: state.sawToolUse ? \"tool_use\" : \"end_turn\",\n stop_sequence: null,\n },\n type: \"message_delta\",\n usage: state.usage,\n });\n enqueue(\"message_stop\", { type: \"message_stop\" });\n state.completed = true;\n}\n\nfunction ensureTextBlock(\n state: AnthropicStreamState,\n payload: JsonObject,\n enqueue: (event: string, data: JsonObject) => void,\n): StreamBlock {\n startAnthropicMessage(state, enqueue);\n const key = `text:${indexValue(payload.output_index)}:${indexValue(payload.content_index)}`;\n let block = state.blocks.get(key);\n if (!block) {\n block = { index: state.nextBlockIndex++, sentText: \"\", stopped: false, type: \"text\" };\n state.blocks.set(key, block);\n enqueue(\"content_block_start\", {\n content_block: { text: \"\", type: \"text\" },\n index: block.index,\n type: \"content_block_start\",\n });\n }\n return block;\n}\n\nfunction ensureToolBlock(\n state: AnthropicStreamState,\n payload: JsonObject,\n item: JsonObject,\n enqueue: (event: string, data: JsonObject) => void,\n): StreamBlock {\n startAnthropicMessage(state, enqueue);\n state.sawToolUse = true;\n const key = `tool:${indexValue(payload.output_index)}`;\n let block = state.blocks.get(key);\n if (!block) {\n block = { index: state.nextBlockIndex++, sentText: \"\", stopped: false, type: \"tool_use\" };\n state.blocks.set(key, block);\n enqueue(\"content_block_start\", {\n content_block: {\n id: textValue(item.call_id) || textValue(item.id) || `call_${randomId()}`,\n input: {},\n name: textValue(item.name),\n type: \"tool_use\",\n },\n index: block.index,\n type: \"content_block_start\",\n });\n }\n return block;\n}\n\nfunction stopBlock(block: StreamBlock, enqueue: (event: string, data: JsonObject) => void): void {\n if (block.stopped) {\n return;\n }\n block.stopped = true;\n enqueue(\"content_block_stop\", {\n index: block.index,\n type: \"content_block_stop\",\n });\n}\n\nfunction parseSseBlock(block: string): { data: string; event: string } {\n let event = \"message\";\n const data: string[] = [];\n for (const line of block.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"event:\")) {\n event = trimmed.slice(\"event:\".length).trim() || event;\n } else if (trimmed.startsWith(\"data:\")) {\n data.push(trimmed.slice(\"data:\".length).trim());\n }\n }\n return { data: data.join(\"\\n\"), event };\n}\n\nfunction parseJsonObject(text: string): JsonObject | undefined {\n try {\n return asRecord(JSON.parse(text));\n } catch {\n return undefined;\n }\n}\n\nfunction parseToolInput(argumentsText: string): JsonObject {\n const parsed = parseJsonObject(argumentsText);\n return parsed ?? {};\n}\n\nfunction estimatedTextSize(value: unknown): number {\n if (value === undefined || value === null) {\n return 0;\n }\n if (typeof value === \"string\") {\n return value.length;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value).length;\n }\n if (Array.isArray(value)) {\n return value.reduce((sum, item) => sum + estimatedTextSize(item), 0);\n }\n if (typeof value === \"object\") {\n return Object.values(value).reduce((sum, item) => sum + estimatedTextSize(item), 0);\n }\n return 0;\n}\n\nfunction textValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return \"\";\n}\n\nfunction firstNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n }\n return undefined;\n}\n\nfunction indexValue(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n\nfunction removeUndefined(record: JsonObject): JsonObject {\n return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));\n}\n\nfunction encodeSse(event: string, data: JsonObject): string {\n return `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n}\n\nfunction randomId(): string {\n return crypto.randomUUID().replaceAll(\"-\", \"\");\n}\n","import { extractTokenUsage } from \"./openai\";\nimport type {\n CopilotUsage,\n MetricsSnapshot,\n ModelTokenTotals,\n RequestObservation,\n TokenUsage,\n} from \"./types\";\nimport { asRecord } from \"./util\";\n\n/** Content-Type for the Prometheus text exposition format (version 0.0.4). */\nexport const PROMETHEUS_CONTENT_TYPE = \"text/plain; version=0.0.4; charset=utf-8\";\n\n/** Upper bounds (seconds) for the request-duration histogram buckets. */\nconst DURATION_BUCKETS_SECONDS = [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60] as const;\n\n/** Cap on bytes buffered or scanned while extracting usage from a response body. */\nconst USAGE_BUFFER_LIMIT_BYTES = 16 * 1024 * 1024;\n\n/** Bound the distinct model labels so a hostile client cannot blow up cardinality. */\nconst MAX_TRACKED_MODELS = 200;\nconst MAX_MODEL_LABEL_LENGTH = 200;\n\n// Unit separator (ASCII 0x1f): joins label parts; cannot collide with a label value.\nconst LABEL_SEPARATOR = \"\\u001f\";\nconst UNKNOWN_MODEL = \"unknown\";\n\ninterface RouteDuration {\n buckets: number[];\n count: number;\n sum: number;\n}\n\nfunction emptyModelTotals(): ModelTokenTotals {\n return { cached: 0, completion: 0, prompt: 0, reasoning: 0, requests: 0, total: 0 };\n}\n\n/**\n * In-process metrics for the running proxy. Counters are monotonic for the life\n * of the process and reset on restart, which Prometheus handles natively. The\n * registry is intentionally allocation-light and synchronous; the single-\n * threaded event loop makes its mutations atomic with respect to each request.\n */\nexport class MetricsRegistry {\n readonly #startedAtMs: number;\n #inFlight = 0;\n #requests = new Map<string, number>();\n #durations = new Map<string, RouteDuration>();\n #tokens = new Map<string, ModelTokenTotals>();\n #upstream = new Map<string, number>();\n #copilotQuota?: CopilotUsage;\n\n constructor(options: { now?: () => number } = {}) {\n this.#startedAtMs = (options.now ?? Date.now)();\n }\n\n /** Mark a request as started; pair with exactly one {@link observe}. */\n startRequest(): void {\n this.#inFlight += 1;\n }\n\n /** Record a completed request and clear its in-flight slot. */\n observe(observation: RequestObservation): void {\n if (this.#inFlight > 0) {\n this.#inFlight -= 1;\n }\n const key = labelKey(observation.route, observation.method, String(observation.status));\n this.#requests.set(key, (this.#requests.get(key) ?? 0) + 1);\n this.#observeDuration(observation.route, observation.durationMs / 1000);\n }\n\n /** Accumulate token counts for a model from one upstream completion. */\n recordTokens(model: string, usage: TokenUsage): void {\n const name = this.#modelLabel(model);\n const totals = this.#tokens.get(name) ?? emptyModelTotals();\n totals.requests += 1;\n totals.prompt += nonNegative(usage.promptTokens);\n totals.completion += nonNegative(usage.completionTokens);\n totals.total += nonNegative(usage.totalTokens);\n totals.reasoning += nonNegative(usage.reasoningTokens ?? 0);\n totals.cached += nonNegative(usage.cachedTokens ?? 0);\n this.#tokens.set(name, totals);\n }\n\n /** Record one upstream Copilot call and whether it succeeded. */\n recordUpstream(path: string, ok: boolean): void {\n const key = labelKey(path, ok ? \"ok\" : \"error\");\n this.#upstream.set(key, (this.#upstream.get(key) ?? 0) + 1);\n }\n\n /** Store the latest Copilot quota so /metrics can expose it as gauges. */\n recordCopilotQuota(usage: CopilotUsage): void {\n this.#copilotQuota = usage;\n }\n\n // Sanitize the model into a bounded, control-char-free label. The model can\n // originate from a client request, so cap its length, strip characters that\n // would corrupt the exposition format, and fold overflow past the cardinality\n // limit into UNKNOWN_MODEL to keep the series count bounded.\n #modelLabel(model: string): string {\n const cleaned =\n model\n // biome-ignore lint/suspicious/noControlCharactersInRegex: stripping control chars is the intent.\n .replace(/[\\u0000-\\u001f\\u007f]/g, \"\")\n .trim()\n .slice(0, MAX_MODEL_LABEL_LENGTH) || UNKNOWN_MODEL;\n if (!this.#tokens.has(cleaned) && this.#tokens.size >= MAX_TRACKED_MODELS) {\n return UNKNOWN_MODEL;\n }\n return cleaned;\n }\n\n #observeDuration(route: string, seconds: number): void {\n const value = Number.isFinite(seconds) && seconds >= 0 ? seconds : 0;\n const entry = this.#durations.get(route) ?? {\n buckets: new Array(DURATION_BUCKETS_SECONDS.length).fill(0),\n count: 0,\n sum: 0,\n };\n entry.count += 1;\n entry.sum += value;\n // Values larger than the last bucket bound only appear in the +Inf bucket,\n // which renderPrometheus derives from entry.count.\n const index = DURATION_BUCKETS_SECONDS.findIndex((bound) => value <= bound);\n if (index !== -1) {\n entry.buckets[index] = (entry.buckets[index] ?? 0) + 1;\n }\n this.#durations.set(route, entry);\n }\n\n /** A JSON-friendly view of the current counters. */\n snapshot(now: () => number = Date.now): MetricsSnapshot {\n const byRoute: Record<string, number> = {};\n const byStatus: Record<string, number> = {};\n let requestsTotal = 0;\n for (const [key, count] of this.#requests) {\n const [route = \"\", , status = \"\"] = key.split(LABEL_SEPARATOR);\n byRoute[route] = (byRoute[route] ?? 0) + count;\n byStatus[status] = (byStatus[status] ?? 0) + count;\n requestsTotal += count;\n }\n\n const byModel: Record<string, ModelTokenTotals> = {};\n const tokenTotals = { cached: 0, completion: 0, prompt: 0, reasoning: 0, total: 0 };\n for (const [model, totals] of this.#tokens) {\n byModel[model] = { ...totals };\n tokenTotals.prompt += totals.prompt;\n tokenTotals.completion += totals.completion;\n tokenTotals.total += totals.total;\n tokenTotals.reasoning += totals.reasoning;\n tokenTotals.cached += totals.cached;\n }\n\n let upstreamTotal = 0;\n let upstreamErrors = 0;\n for (const [key, count] of this.#upstream) {\n upstreamTotal += count;\n if (key.endsWith(`${LABEL_SEPARATOR}error`)) {\n upstreamErrors += count;\n }\n }\n\n return {\n inFlight: this.#inFlight,\n requests: { byRoute, byStatus, total: requestsTotal },\n startedAt: new Date(this.#startedAtMs).toISOString(),\n tokens: { byModel, ...tokenTotals },\n upstream: { errors: upstreamErrors, total: upstreamTotal },\n uptimeSeconds: Math.max(0, Math.round((now() - this.#startedAtMs) / 1000)),\n };\n }\n\n /** Render the Prometheus text exposition format (version 0.0.4). */\n renderPrometheus(now: () => number = Date.now): string {\n const lines: string[] = [];\n\n lines.push(\"# HELP hoopilot_process_start_time_seconds Unix epoch when the proxy started.\");\n lines.push(\"# TYPE hoopilot_process_start_time_seconds gauge\");\n lines.push(`hoopilot_process_start_time_seconds ${this.#startedAtMs / 1000}`);\n\n lines.push(\"# HELP hoopilot_uptime_seconds Seconds since the proxy started.\");\n lines.push(\"# TYPE hoopilot_uptime_seconds gauge\");\n lines.push(`hoopilot_uptime_seconds ${Math.max(0, (now() - this.#startedAtMs) / 1000)}`);\n\n lines.push(\"# HELP hoopilot_requests_in_flight Requests currently being served.\");\n lines.push(\"# TYPE hoopilot_requests_in_flight gauge\");\n lines.push(`hoopilot_requests_in_flight ${this.#inFlight}`);\n\n lines.push(\"# HELP hoopilot_requests_total Completed requests by route, method, and status.\");\n lines.push(\"# TYPE hoopilot_requests_total counter\");\n for (const [key, count] of this.#requests) {\n const [route = \"\", method = \"\", status = \"\"] = key.split(LABEL_SEPARATOR);\n lines.push(`hoopilot_requests_total${labels({ method, route, status })} ${count}`);\n }\n\n lines.push(\n \"# HELP hoopilot_upstream_requests_total Copilot upstream calls by path and outcome.\",\n );\n lines.push(\"# TYPE hoopilot_upstream_requests_total counter\");\n for (const [key, count] of this.#upstream) {\n const [path = \"\", outcome = \"\"] = key.split(LABEL_SEPARATOR);\n lines.push(`hoopilot_upstream_requests_total${labels({ outcome, path })} ${count}`);\n }\n\n lines.push(\n \"# HELP hoopilot_tokens_total Tokens reported by upstream usage, by model and type.\",\n );\n lines.push(\"# TYPE hoopilot_tokens_total counter\");\n for (const [model, totals] of this.#tokens) {\n lines.push(`hoopilot_tokens_total${labels({ model, type: \"prompt\" })} ${totals.prompt}`);\n lines.push(\n `hoopilot_tokens_total${labels({ model, type: \"completion\" })} ${totals.completion}`,\n );\n lines.push(\n `hoopilot_tokens_total${labels({ model, type: \"reasoning\" })} ${totals.reasoning}`,\n );\n lines.push(`hoopilot_tokens_total${labels({ model, type: \"cached\" })} ${totals.cached}`);\n }\n\n lines.push(\"# HELP hoopilot_model_requests_total Completions with usage observed, by model.\");\n lines.push(\"# TYPE hoopilot_model_requests_total counter\");\n for (const [model, totals] of this.#tokens) {\n lines.push(`hoopilot_model_requests_total${labels({ model })} ${totals.requests}`);\n }\n\n lines.push(\"# HELP hoopilot_request_duration_seconds Request duration by route.\");\n lines.push(\"# TYPE hoopilot_request_duration_seconds histogram\");\n for (const [route, entry] of this.#durations) {\n let cumulative = 0;\n for (let i = 0; i < DURATION_BUCKETS_SECONDS.length; i += 1) {\n cumulative += entry.buckets[i] ?? 0;\n const le = formatNumber(DURATION_BUCKETS_SECONDS[i] ?? 0);\n lines.push(\n `hoopilot_request_duration_seconds_bucket${labels({ le, route })} ${cumulative}`,\n );\n }\n lines.push(\n `hoopilot_request_duration_seconds_bucket${labels({ le: \"+Inf\", route })} ${entry.count}`,\n );\n lines.push(`hoopilot_request_duration_seconds_sum${labels({ route })} ${entry.sum}`);\n lines.push(`hoopilot_request_duration_seconds_count${labels({ route })} ${entry.count}`);\n }\n\n this.#renderCopilotQuota(lines);\n\n return `${lines.join(\"\\n\")}\\n`;\n }\n\n #renderCopilotQuota(lines: string[]): void {\n const usage = this.#copilotQuota;\n if (!usage) {\n return;\n }\n const categories = Object.entries(usage.quotas);\n\n const gauge = (\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => number | undefined,\n ): void => {\n const present = categories.filter(([, quota]) => pick(quota) !== undefined);\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, quota] of present) {\n lines.push(`hoopilot_copilot_quota_${suffix}${labels({ category })} ${pick(quota)}`);\n }\n };\n\n gauge(\"remaining\", \"Remaining quota for the Copilot category.\", (q) => q.remaining);\n gauge(\"entitlement\", \"Quota entitlement for the Copilot category.\", (q) => q.entitlement);\n gauge(\"used\", \"Used quota (entitlement minus remaining) for the category.\", (q) => q.used);\n gauge(\"overage_count\", \"Overage count for the Copilot category.\", (q) => q.overageCount);\n gauge(\n \"overage_entitlement\",\n \"Overage entitlement for the Copilot category.\",\n (q) => q.overageEntitlement,\n );\n gauge(\n \"percent_remaining\",\n \"Percent of quota remaining for the Copilot category.\",\n (q) => q.percentRemaining,\n );\n booleanGauge(\n \"unlimited\",\n \"Whether the Copilot quota category is unlimited.\",\n (q) => q.unlimited,\n );\n booleanGauge(\n \"overage_permitted\",\n \"Whether overage is permitted for the Copilot category.\",\n (q) => q.overagePermitted,\n );\n booleanGauge(\"has_quota\", \"Whether the Copilot quota category has a quota.\", (q) => q.hasQuota);\n booleanGauge(\n \"token_based_billing\",\n \"Whether the Copilot quota category uses token-based billing.\",\n (q) => q.tokenBasedBilling,\n );\n dateGauge(\n \"category_reset_timestamp_seconds\",\n \"Unix epoch of the Copilot category-specific quota reset.\",\n (q) => q.quotaResetAt,\n );\n dateGauge(\n \"category_snapshot_timestamp_seconds\",\n \"Unix epoch of the Copilot category quota snapshot.\",\n (q) => q.timestampUtc,\n );\n\n const resetMs = usage.quotaResetDate ? Date.parse(usage.quotaResetDate) : Number.NaN;\n if (Number.isFinite(resetMs)) {\n lines.push(\n \"# HELP hoopilot_copilot_quota_reset_timestamp_seconds Unix epoch of the next reset.\",\n );\n lines.push(\"# TYPE hoopilot_copilot_quota_reset_timestamp_seconds gauge\");\n lines.push(`hoopilot_copilot_quota_reset_timestamp_seconds ${resetMs / 1000}`);\n }\n\n if (usage.plan || usage.accessTypeSku) {\n lines.push(\"# HELP hoopilot_copilot_info Copilot plan metadata as a constant-1 info gauge.\");\n lines.push(\"# TYPE hoopilot_copilot_info gauge\");\n lines.push(\n `hoopilot_copilot_info${labels({\n access_type_sku: usage.accessTypeSku ?? \"\",\n plan: usage.plan ?? \"\",\n })} 1`,\n );\n }\n\n function booleanGauge(\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => boolean | undefined,\n ): void {\n const present = categories.filter(([, quota]) => pick(quota) !== undefined);\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, quota] of present) {\n lines.push(\n `hoopilot_copilot_quota_${suffix}${labels({ category })} ${pick(quota) ? 1 : 0}`,\n );\n }\n }\n\n function dateGauge(\n suffix: string,\n help: string,\n pick: (quota: (typeof categories)[number][1]) => string | undefined,\n ): void {\n const present = categories\n .map(([category, quota]) => [category, Date.parse(pick(quota) ?? \"\")] as const)\n .filter(([, timestamp]) => Number.isFinite(timestamp));\n if (present.length === 0) {\n return;\n }\n lines.push(`# HELP hoopilot_copilot_quota_${suffix} ${help}`);\n lines.push(`# TYPE hoopilot_copilot_quota_${suffix} gauge`);\n for (const [category, timestamp] of present) {\n lines.push(`hoopilot_copilot_quota_${suffix}${labels({ category })} ${timestamp / 1000}`);\n }\n }\n }\n}\n\n/**\n * Tee `response`'s body so the client receives an unchanged copy while a\n * background reader extracts token usage. Returns a new Response carrying the\n * client-facing branch and the original status/headers. Usage extraction never\n * throws into the client stream: a parse failure or an aborted client simply\n * yields no usage. When the body is absent the response is returned untouched.\n *\n * Pass the request's `signal` so a client disconnect cancels the observer\n * branch; combined with the runtime cancelling the client branch, that releases\n * the shared upstream connection instead of draining it in the background.\n */\nexport function observeResponseUsage(\n response: Response,\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n signal?: AbortSignal,\n): Response {\n const body = response.body;\n if (!body) {\n return response;\n }\n const [clientBranch, observerBranch] = body.tee();\n const isSse = response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n void consumeUsage(observerBranch, isSse, fallbackModel, onUsage, signal).catch(() => {});\n return new Response(clientBranch, {\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\n/** Extract and record token usage from an already-buffered response body. */\nexport function recordResponseTextUsage(\n text: string,\n isSse: boolean,\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n): void {\n const accumulator = createUsageAccumulator(fallbackModel, onUsage);\n if (isSse) {\n for (const line of text.split(/\\r?\\n/)) {\n considerSseLine(line, accumulator.consider);\n }\n } else {\n const parsed = safeParse(text);\n if (parsed !== undefined) {\n accumulator.consider(parsed);\n }\n }\n accumulator.finish();\n}\n\nasync function consumeUsage(\n stream: ReadableStream<Uint8Array>,\n isSse: boolean,\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n signal?: AbortSignal,\n): Promise<void> {\n const reader = stream.getReader();\n const onAbort = () => {\n reader.cancel().catch(() => {});\n };\n if (signal?.aborted) {\n reader.cancel().catch(() => {});\n } else {\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n }\n\n const decoder = new TextDecoder();\n const accumulator = createUsageAccumulator(fallbackModel, onUsage);\n let buffer = \"\";\n let bufferedBytes = 0;\n let overflowed = false;\n\n try {\n while (true) {\n const result = await reader.read();\n if (result.done) {\n break;\n }\n const chunk = decoder.decode(result.value, { stream: true });\n if (isSse) {\n buffer += chunk;\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n for (const line of lines) {\n considerSseLine(line, accumulator.consider);\n }\n // Drop a pathologically long newline-less line so the buffer stays bounded.\n if (buffer.length > USAGE_BUFFER_LIMIT_BYTES) {\n buffer = \"\";\n }\n } else if (!overflowed) {\n bufferedBytes += result.value.byteLength;\n if (bufferedBytes > USAGE_BUFFER_LIMIT_BYTES) {\n overflowed = true;\n buffer = \"\";\n } else {\n buffer += chunk;\n }\n }\n }\n // Flush any trailing bytes the streaming decoder is still holding.\n const finalBuffer = buffer + decoder.decode();\n if (isSse) {\n if (finalBuffer) {\n considerSseLine(finalBuffer, accumulator.consider);\n }\n } else if (!overflowed && finalBuffer) {\n const parsed = safeParse(finalBuffer);\n if (parsed !== undefined) {\n accumulator.consider(parsed);\n }\n }\n } finally {\n signal?.removeEventListener(\"abort\", onAbort);\n reader.releaseLock();\n }\n\n accumulator.finish();\n}\n\nfunction createUsageAccumulator(\n fallbackModel: string,\n onUsage: (model: string, usage: TokenUsage) => void,\n): { consider: (payload: unknown) => void; finish: () => void } {\n let model = fallbackModel;\n let usage: TokenUsage | undefined;\n return {\n consider(payload) {\n const record = asRecord(payload);\n const found =\n extractTokenUsage(record.usage) ?? extractTokenUsage(asRecord(record.response).usage);\n if (found) {\n usage = found;\n }\n const candidateModel = modelText(record.model) || modelText(asRecord(record.response).model);\n if (candidateModel) {\n model = candidateModel;\n }\n },\n finish() {\n if (usage) {\n onUsage(model, usage);\n }\n },\n };\n}\n\nfunction considerSseLine(line: string, consider: (payload: unknown) => void): void {\n const trimmed = line.trim();\n if (!trimmed.startsWith(\"data:\")) {\n return;\n }\n const data = trimmed.slice(\"data:\".length).trim();\n if (!data || data === \"[DONE]\") {\n return;\n }\n const parsed = safeParse(data);\n if (parsed !== undefined) {\n consider(parsed);\n }\n}\n\nfunction safeParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction modelText(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction nonNegative(value: number): number {\n return Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction labelKey(...parts: string[]): string {\n return parts.join(LABEL_SEPARATOR);\n}\n\nfunction labels(pairs: Record<string, string>): string {\n const entries = Object.entries(pairs);\n if (entries.length === 0) {\n return \"\";\n }\n const rendered = entries.map(([name, value]) => `${name}=\"${escapeLabelValue(value)}\"`);\n return `{${rendered.join(\",\")}}`;\n}\n\nfunction escapeLabelValue(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\");\n}\n\nfunction formatNumber(value: number): string {\n return Number.isInteger(value) ? value.toString() : String(value);\n}\n","// Build-time constants. For standalone binaries these identifiers are replaced\n// at compile time via `bun build --compile --define 'HOOPILOT_VERSION=\"x.y.z\"'`\n// (see scripts/build-binaries.sh). In dev runs and the npm package they are not\n// defined, so `typeof` is \"undefined\" and we fall back to reading package.json.\ndeclare const HOOPILOT_VERSION: string;\ndeclare const HOOPILOT_TARGET: string;\n\n/** Version baked into a standalone binary, or undefined for npm/dev installs. */\nexport const BAKED_VERSION: string | undefined =\n typeof HOOPILOT_VERSION !== \"undefined\" ? HOOPILOT_VERSION : undefined;\n\n/**\n * Release asset suffix baked into a standalone binary (e.g. \"linux-x64-musl\",\n * \"windows-x64\", \"darwin-arm64\"), or undefined for npm/dev installs. Lets the\n * self-updater fetch the exact asset variant it was built from.\n */\nexport const BAKED_TARGET: string | undefined =\n typeof HOOPILOT_TARGET !== \"undefined\" ? HOOPILOT_TARGET : undefined;\n\n/** True when running as a `bun build --compile` standalone executable. */\nexport const IS_STANDALONE_BINARY: boolean = BAKED_VERSION !== undefined;\n\nlet cachedVersion: string | undefined;\n\n/** Resolve the running version, preferring the baked value for binaries. */\nexport async function getVersion(): Promise<string> {\n if (cachedVersion !== undefined) {\n return cachedVersion;\n }\n let resolved: string;\n if (BAKED_VERSION) {\n resolved = BAKED_VERSION;\n } else {\n try {\n const manifest = await Bun.file(new URL(\"../package.json\", import.meta.url)).json();\n resolved = typeof manifest.version === \"string\" ? manifest.version : \"0.0.0\";\n } catch {\n resolved = \"0.0.0\";\n }\n }\n cachedVersion = resolved;\n return resolved;\n}\n","import {\n AnthropicCompatibilityError,\n anthropicMessagesToResponsesRequest,\n estimateAnthropicMessageTokens,\n responsesResponseToAnthropicMessage,\n responsesSseTextToAnthropicSseText,\n responsesStreamToAnthropicStream,\n} from \"./anthropic\";\nimport { CopilotAuthError } from \"./auth\";\nimport { CopilotClient, normalizeCopilotUsage } from \"./copilot\";\nimport { createHoopilotLogger, errorDetails, noopLogger, shouldCreateLogger } from \"./logger\";\nimport {\n MetricsRegistry,\n observeResponseUsage,\n PROMETHEUS_CONTENT_TYPE,\n recordResponseTextUsage,\n} from \"./metrics\";\nimport {\n chatCompletionToCompletion,\n completionSseTextFromChatSseText,\n completionStreamFromChatStream,\n completionsRequestToChatCompletion,\n extractTokenUsage,\n fallbackModels,\n normalizeChatCompletionRequest,\n normalizeModelsResponse,\n normalizeRequestedModel,\n OpenAICompatibilityError,\n} from \"./openai\";\nimport type {\n CopilotUsage,\n HoopilotLogger,\n HoopilotServerOptions,\n JsonObject,\n LogFields,\n StartedHoopilotServer,\n StreamingProxyMode,\n TokenUsage,\n} from \"./types\";\nimport { asRecord, envValue } from \"./util\";\nimport { IS_STANDALONE_BINARY } from \"./version\";\n\nconst DEFAULT_HOST = \"127.0.0.1\";\nconst DEFAULT_PORT = 4141;\nconst FORBIDDEN_BROWSER_ORIGIN_MESSAGE =\n \"Browser-origin requests require HOOPILOT_API_KEY unless the Origin is loopback.\";\nconst INVALID_JSON_MESSAGE = \"Request body must be valid JSON.\";\nconst JSON_OBJECT_MESSAGE = \"Request body must be a JSON object.\";\nconst MAX_REQUEST_BODY_BYTES = 16 * 1024 * 1024;\nconst REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;\nconst REQUEST_TOO_LARGE_MESSAGE = `Request body must be ${MAX_REQUEST_BODY_BYTES} bytes or smaller.`;\nconst USAGE_CACHE_TTL_MS = 60_000;\n\ninterface UsageReadResult {\n copilot?: CopilotUsage;\n error?: string;\n}\n\ntype UsageReader = (signal?: AbortSignal) => Promise<UsageReadResult>;\ntype TokenRecorder = (model: string, usage: TokenUsage) => void;\n\nclass RequestBodyTooLargeError extends Error {\n constructor() {\n super(REQUEST_TOO_LARGE_MESSAGE);\n this.name = \"RequestBodyTooLargeError\";\n }\n}\n\nexport function createHoopilotHandler(\n options: HoopilotServerOptions = {},\n): (request: Request) => Promise<Response> {\n const client = new CopilotClient(options);\n const apiKey = options.apiKey ?? envValue(options.env?.HOOPILOT_API_KEY);\n const logger = serverLogger(options);\n const metrics = options.metrics ?? new MetricsRegistry();\n const readUsage = createUsageReader(client, metrics);\n const recordTokens: TokenRecorder = (model, usage) => metrics.recordTokens(model, usage);\n const streamingProxyMode = resolveStreamingProxyMode(options);\n const bufferProxyBodies = shouldBufferProxyBodies(streamingProxyMode);\n\n return async (request: Request): Promise<Response> => {\n const startedAt = performance.now();\n const url = new URL(request.url);\n const apiPath = canonicalApiPath(url.pathname);\n const requestId = requestIdFor(request);\n const route = routeFor(request.method, apiPath);\n const requestLogger = logger.child({\n method: request.method,\n path: url.pathname,\n requestId,\n route,\n });\n metrics.startRequest();\n const finish = (response: Response): Response =>\n finishResponse(response, {\n logger: requestLogger,\n method: request.method,\n metrics,\n requestId,\n route,\n startedAt,\n closeConnection: bufferProxyBodies,\n trackStreamingBody: !bufferProxyBodies,\n });\n\n const browserOrigin = forbiddenBrowserOrigin(request, apiKey);\n if (browserOrigin) {\n requestLogger.warn(\n { event: \"http.request.forbidden_origin\", origin: browserOrigin },\n \"blocked unauthenticated browser-origin request\",\n );\n return finish(jsonError(403, \"forbidden_origin\", FORBIDDEN_BROWSER_ORIGIN_MESSAGE));\n }\n\n if (request.method === \"OPTIONS\") {\n return finish(new Response(null, { headers: corsHeaders() }));\n }\n\n if (!isAuthorized(request, apiKey)) {\n requestLogger.warn({ event: \"http.request.unauthorized\" }, \"invalid hoopilot api key\");\n return finish(jsonError(401, \"invalid_api_key\", \"Invalid or missing Hoopilot API key.\"));\n }\n\n try {\n if (request.method === \"GET\" && (apiPath === \"/\" || apiPath === \"/healthz\")) {\n return finish(jsonResponse({ name: \"hoopilot\", object: \"health\", status: \"ok\" }));\n }\n if (request.method === \"GET\" && apiPath === \"/metrics\") {\n return finish(metricsResponse(metrics));\n }\n if (request.method === \"GET\" && apiPath === \"/v1/usage\") {\n return finish(await handleUsage(metrics, readUsage, request.signal));\n }\n if (request.method === \"GET\" && apiPath === \"/v1/responses\") {\n return finish(websocketUnsupportedResponse());\n }\n if (request.method === \"GET\" && apiPath === \"/v1/models\") {\n return finish(await handleModels(client, metrics, request.signal, requestLogger));\n }\n if (request.method === \"POST\" && apiPath === \"/v1/messages\") {\n return finish(\n await handleAnthropicMessages(\n client,\n metrics,\n recordTokens,\n request,\n requestLogger,\n bufferProxyBodies,\n ),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/messages/count_tokens\") {\n return finish(handleAnthropicCountTokens(await readJson(request)));\n }\n if (request.method === \"POST\" && apiPath === \"/v1/chat/completions\") {\n return finish(\n await handleChatCompletions(\n client,\n metrics,\n recordTokens,\n request,\n requestLogger,\n bufferProxyBodies,\n ),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/completions\") {\n return finish(\n await handleCompletions(\n client,\n metrics,\n recordTokens,\n request,\n requestLogger,\n bufferProxyBodies,\n ),\n );\n }\n if (request.method === \"POST\" && apiPath === \"/v1/responses\") {\n return finish(\n await handleResponses(\n client,\n metrics,\n recordTokens,\n request,\n requestLogger,\n bufferProxyBodies,\n ),\n );\n }\n return finish(jsonError(404, \"not_found\", `No route for ${request.method} ${url.pathname}.`));\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"copilot.auth.missing\" },\n \"copilot auth failed\",\n );\n return finish(jsonError(401, \"copilot_auth_error\", error.message));\n }\n const message = errorMessage(error);\n if (message === INVALID_JSON_MESSAGE || message === JSON_OBJECT_MESSAGE) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body was not usable json\",\n );\n return finish(jsonError(400, \"invalid_request_error\", message));\n } else if (\n error instanceof OpenAICompatibilityError ||\n error instanceof AnthropicCompatibilityError\n ) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body used unsupported compatibility fields\",\n );\n return finish(jsonError(400, \"invalid_request_error\", message));\n } else if (error instanceof RequestBodyTooLargeError) {\n requestLogger.warn(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request body exceeded size limit\",\n );\n return finish(jsonError(413, \"request_too_large\", message));\n } else {\n requestLogger.error(\n { err: errorDetails(error), event: \"http.request.failed\" },\n \"request failed\",\n );\n }\n return finish(jsonError(500, \"internal_error\", message));\n }\n };\n}\n\nexport function startHoopilotServer(options: HoopilotServerOptions = {}): StartedHoopilotServer {\n const host = options.host ?? envValue(options.env?.HOST) ?? DEFAULT_HOST;\n const port = normalizeServerPort(options.port ?? envValue(options.env?.PORT) ?? DEFAULT_PORT);\n const apiKey = options.apiKey ?? envValue(options.env?.HOOPILOT_API_KEY);\n const allowUnauthenticated =\n options.allowUnauthenticated ?? envValue(options.env?.HOOPILOT_ALLOW_UNAUTHENTICATED) === \"1\";\n\n if (!isLoopbackHost(host) && !apiKey && !allowUnauthenticated) {\n throw new Error(\n \"Refusing to listen on a non-loopback host without HOOPILOT_API_KEY. Set an API key or pass --allow-unauthenticated.\",\n );\n }\n\n const server = Bun.serve({\n fetch: createHoopilotHandler({\n ...options,\n apiKey,\n host,\n port,\n }),\n hostname: host,\n port,\n });\n\n return {\n server,\n url: `http://${urlHost(host)}:${server.port}`,\n };\n}\n\nasync function handleAnthropicMessages(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n bufferProxyBodies: boolean,\n): Promise<Response> {\n const anthropicRequest = await readJson(request);\n const responsesRequest = anthropicMessagesToResponsesRequest(anthropicRequest);\n const upstream = await client.responses(JSON.stringify(responsesRequest), request.signal);\n metrics.recordUpstream(\"/responses\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/responses\", upstream.status);\n const model = normalizeRequestedModel(responsesRequest.model);\n\n if (isStreamingResponse(upstream) && upstream.body) {\n if (bufferProxyBodies) {\n const text = await upstream.text();\n recordResponseTextUsage(text, true, model, recordTokens);\n return proxyResponse(\n responseFromText(upstream, responsesSseTextToAnthropicSseText(text, { model })),\n );\n }\n const observed = observeResponseUsage(upstream, model, recordTokens, request.signal);\n if (!observed.body) {\n return proxyResponse(observed);\n }\n return proxyResponse(\n new Response(responsesStreamToAnthropicStream(observed.body, { model }), {\n headers: observed.headers,\n status: observed.status,\n statusText: observed.statusText,\n }),\n );\n }\n\n const body = asRecord(await upstream.json());\n const usage = extractTokenUsage(body.usage);\n if (usage) {\n const responseModel = typeof body.model === \"string\" ? body.model.trim() : \"\";\n recordTokens(responseModel || model, usage);\n }\n return jsonResponse(responsesResponseToAnthropicMessage(body, model));\n}\n\nfunction handleAnthropicCountTokens(body: JsonObject): Response {\n return jsonResponse(estimateAnthropicMessageTokens(body));\n}\n\nasync function handleModels(\n client: CopilotClient,\n metrics: MetricsRegistry,\n signal: AbortSignal,\n logger: HoopilotLogger,\n): Promise<Response> {\n const upstream = await client.models(signal);\n metrics.recordUpstream(\"/models\", upstream.ok);\n if (!upstream.ok) {\n if (isUpstreamAuthStatus(upstream.status)) {\n return proxyError(upstream, logger);\n }\n logger.warn(\n {\n event: \"copilot.models.fallback\",\n upstreamPath: \"/models\",\n upstreamStatus: upstream.status,\n },\n \"falling back to built-in model list\",\n );\n return jsonResponse({ data: fallbackModels(), object: \"list\" });\n }\n logUpstreamSuccess(logger, \"/models\", upstream.status);\n return jsonResponse(normalizeModelsResponse(await upstream.json()));\n}\n\nasync function handleChatCompletions(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n bufferProxyBodies: boolean,\n): Promise<Response> {\n const chatRequest = normalizeChatCompletionRequest(await readJson(request));\n const upstream = await client.chatCompletions(chatRequest, request.signal);\n metrics.recordUpstream(\"/chat/completions\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n const model = normalizeRequestedModel(chatRequest.model);\n return proxyResponse(\n await responseWithObservedUsage(\n upstream,\n model,\n recordTokens,\n request.signal,\n bufferProxyBodies,\n ),\n );\n}\n\nasync function handleCompletions(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n bufferProxyBodies: boolean,\n): Promise<Response> {\n const body = await readJson(request);\n const upstream = await client.chatCompletions(\n completionsRequestToChatCompletion(body),\n request.signal,\n );\n metrics.recordUpstream(\"/chat/completions\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/chat/completions\", upstream.status);\n const model = normalizeRequestedModel(body.model);\n // A streaming request yields chat-completion SSE; convert each chunk to the\n // legacy completions stream shape instead of calling .json() on the body.\n if (isStreamingResponse(upstream) && upstream.body) {\n if (bufferProxyBodies) {\n const upstreamText = await upstream.text();\n recordResponseTextUsage(upstreamText, true, model, recordTokens);\n const text = completionSseTextFromChatSseText(upstreamText);\n return proxyResponse(responseFromText(upstream, text));\n }\n return proxyResponse(\n observeResponseUsage(\n new Response(completionStreamFromChatStream(upstream.body), {\n headers: upstream.headers,\n status: upstream.status,\n statusText: upstream.statusText,\n }),\n model,\n recordTokens,\n request.signal,\n ),\n );\n }\n const completion = asRecord(await upstream.json());\n const usage = extractTokenUsage(completion.usage);\n if (usage) {\n const responseModel = typeof completion.model === \"string\" ? completion.model.trim() : \"\";\n recordTokens(responseModel || model, usage);\n }\n return jsonResponse(chatCompletionToCompletion(completion));\n}\n\nasync function handleResponses(\n client: CopilotClient,\n metrics: MetricsRegistry,\n recordTokens: TokenRecorder,\n request: Request,\n logger: HoopilotLogger,\n bufferProxyBodies: boolean,\n): Promise<Response> {\n const body = await readJsonText(request);\n const upstream = await client.responses(body, request.signal);\n metrics.recordUpstream(\"/responses\", upstream.ok);\n if (!upstream.ok) {\n return proxyError(upstream, logger);\n }\n logUpstreamSuccess(logger, \"/responses\", upstream.status);\n const model = normalizeRequestedModel(asRecord(safeParseJson(body)).model);\n return proxyResponse(\n await responseWithObservedUsage(\n upstream,\n model,\n recordTokens,\n request.signal,\n bufferProxyBodies,\n ),\n );\n}\n\nasync function responseWithObservedUsage(\n response: Response,\n fallbackModel: string,\n recordTokens: TokenRecorder,\n signal: AbortSignal,\n bufferBody: boolean,\n): Promise<Response> {\n const isSse = isStreamingResponse(response);\n if (bufferBody && response.body) {\n const text = await response.text();\n recordResponseTextUsage(text, isSse, fallbackModel, recordTokens);\n return responseFromText(response, text);\n }\n return observeResponseUsage(response, fallbackModel, recordTokens, signal);\n}\n\nfunction responseFromText(source: Response, text: string): Response {\n return new Response(text, {\n headers: source.headers,\n status: source.status,\n statusText: source.statusText,\n });\n}\n\nasync function proxyError(upstream: Response, logger: HoopilotLogger): Promise<Response> {\n const text = await upstream.text();\n if (isUpstreamAuthStatus(upstream.status)) {\n logger.warn(\n { event: \"copilot.auth.rejected\", upstreamStatus: upstream.status },\n \"copilot rejected credential or account access\",\n );\n return jsonError(401, \"copilot_auth_error\", upstreamAuthMessage(text || upstream.statusText));\n }\n logger.warn(\n { event: \"copilot.request.failed\", upstreamStatus: upstream.status },\n \"copilot upstream request failed\",\n );\n return upstreamErrorResponse(upstream.status, text || upstream.statusText);\n}\n\nfunction proxyResponse(upstream: Response): Response {\n const headers = new Headers(upstream.headers);\n headers.delete(\"content-encoding\");\n headers.delete(\"content-length\");\n headers.delete(\"transfer-encoding\");\n for (const [key, value] of Object.entries(corsHeaders())) {\n headers.set(key, value);\n }\n return new Response(upstream.body, {\n headers,\n status: upstream.status,\n statusText: upstream.statusText,\n });\n}\n\nasync function readJson(request: Request): Promise<JsonObject> {\n const text = await readRequestText(request);\n return parseJsonObject(text);\n}\n\nfunction parseJsonObject(text: string): JsonObject {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new Error(INVALID_JSON_MESSAGE);\n }\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n throw new Error(JSON_OBJECT_MESSAGE);\n }\n return parsed as JsonObject;\n}\n\nasync function readJsonText(request: Request): Promise<string> {\n const text = await readRequestText(request);\n parseJsonObject(text);\n return text;\n}\n\nasync function readRequestText(request: Request): Promise<string> {\n const contentLength = request.headers.get(\"content-length\");\n if (contentLength) {\n const declaredBytes = Number(contentLength);\n if (Number.isFinite(declaredBytes) && declaredBytes > MAX_REQUEST_BODY_BYTES) {\n throw new RequestBodyTooLargeError();\n }\n }\n\n const body = request.body;\n if (!body) {\n return \"\";\n }\n\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let bytes = 0;\n let text = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n return `${text}${decoder.decode()}`;\n }\n bytes += value.byteLength;\n if (bytes > MAX_REQUEST_BODY_BYTES) {\n await reader.cancel().catch(() => {});\n throw new RequestBodyTooLargeError();\n }\n text += decoder.decode(value, { stream: true });\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction jsonResponse(body: JsonObject, status = 200): Response {\n return new Response(JSON.stringify(body), {\n headers: {\n ...corsHeaders(),\n \"content-type\": \"application/json; charset=utf-8\",\n },\n status,\n });\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return jsonResponse(\n {\n error: {\n code,\n message,\n type: code,\n },\n },\n status,\n );\n}\n\nfunction upstreamErrorResponse(status: number, text: string): Response {\n const parsedError = asRecord(asRecord(safeParseJson(text)).error);\n if (Object.keys(parsedError).length > 0) {\n return jsonResponse({ error: parsedError }, status);\n }\n return jsonError(status, \"copilot_error\", text);\n}\n\nfunction websocketUnsupportedResponse(): Response {\n const response = jsonError(\n 426,\n \"websocket_not_supported\",\n \"Hoopilot does not support Responses WebSocket transport; retry with HTTP Responses API.\",\n );\n response.headers.set(\"upgrade\", \"websocket\");\n return response;\n}\n\nfunction corsHeaders(): Record<string, string> {\n return {\n \"access-control-allow-headers\":\n \"anthropic-beta, anthropic-dangerous-direct-browser-access, anthropic-version, authorization, content-type, x-api-key, x-request-id\",\n \"access-control-allow-methods\": \"GET, POST, OPTIONS\",\n \"access-control-allow-origin\": \"*\",\n \"access-control-expose-headers\": \"x-request-id\",\n };\n}\n\nfunction isAuthorized(request: Request, apiKey: string | undefined): boolean {\n if (!apiKey) {\n return true;\n }\n const authorization = request.headers.get(\"authorization\") ?? \"\";\n const bearer = authorization.match(/^Bearer\\s+(.+)$/i)?.[1];\n return bearer === apiKey || request.headers.get(\"x-api-key\") === apiKey;\n}\n\nfunction forbiddenBrowserOrigin(request: Request, apiKey: string | undefined): string | undefined {\n if (apiKey) {\n return undefined;\n }\n\n const origin = request.headers.get(\"origin\")?.trim();\n if (origin) {\n return isLoopbackOrigin(origin) ? undefined : origin;\n }\n\n const fetchSite = request.headers.get(\"sec-fetch-site\")?.toLowerCase();\n return fetchSite === \"cross-site\" ? \"cross-site\" : undefined;\n}\n\nfunction isUpstreamAuthStatus(status: number): boolean {\n return status === 401 || status === 403;\n}\n\nfunction upstreamAuthMessage(message: string): string {\n return `GitHub Copilot rejected the credential or account access: ${message}`;\n}\n\nfunction isLoopbackHost(host: string): boolean {\n return host === \"localhost\" || host === \"127.0.0.1\" || host === \"::1\" || host === \"[::1]\";\n}\n\nfunction urlHost(host: string): string {\n return host.includes(\":\") && !host.startsWith(\"[\") ? `[${host}]` : host;\n}\n\nfunction isLoopbackOrigin(origin: string): boolean {\n try {\n return isLoopbackHost(new URL(origin).hostname.toLowerCase());\n } catch {\n return false;\n }\n}\n\nfunction normalizeServerPort(value: number | string): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 0 || port > 65_535) {\n throw new Error(`Invalid port: ${value}.`);\n }\n return port;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction serverLogger(options: HoopilotServerOptions): HoopilotLogger {\n if (options.logger) {\n return options.logger.child({ component: \"server\" });\n }\n if (shouldCreateLogger(options)) {\n return createHoopilotLogger({\n env: options.env,\n format: options.logFormat,\n level: options.logLevel,\n }).child({ component: \"server\" });\n }\n return noopLogger;\n}\n\nfunction resolveStreamingProxyMode(options: HoopilotServerOptions): StreamingProxyMode {\n const value =\n options.streamingProxyMode ??\n envValue(options.env?.HOOPILOT_STREAM_MODE) ??\n envValue(options.env?.HOOPILOT_STREAMING_PROXY_MODE) ??\n \"auto\";\n if (value === \"auto\" || value === \"buffer\" || value === \"live\") {\n return value;\n }\n throw new Error(`Invalid stream mode: ${value}. Expected auto, live, or buffer.`);\n}\n\nfunction shouldBufferProxyBodies(mode: StreamingProxyMode): boolean {\n if (mode === \"buffer\") {\n return true;\n }\n if (mode === \"live\") {\n return false;\n }\n return process.platform === \"win32\" && IS_STANDALONE_BINARY;\n}\n\nfunction finishResponse(\n response: Response,\n options: {\n closeConnection: boolean;\n logger: HoopilotLogger;\n method: string;\n metrics: MetricsRegistry;\n requestId: string;\n route: string;\n startedAt: number;\n trackStreamingBody: boolean;\n },\n): Response {\n const withRequestId = responseWithRequestId(response, options.requestId, options.closeConnection);\n const stream = isStreamingResponse(withRequestId);\n const status = withRequestId.status;\n // Record metrics and log when the response is truly done. For a streamed body\n // that is when the client finishes receiving (or aborts) — so the in-flight\n // gauge and duration histogram reflect the full serving lifetime, not just the\n // time to upstream headers.\n const complete = (): void => {\n const durationMs = Math.round((performance.now() - options.startedAt) * 100) / 100;\n options.metrics.observe({ durationMs, method: options.method, route: options.route, status });\n logRequestCompleted(options.logger, status, stream, durationMs);\n };\n\n if (stream && withRequestId.body && options.trackStreamingBody) {\n return new Response(trackStreamCompletion(withRequestId.body, complete), {\n headers: withRequestId.headers,\n status,\n statusText: withRequestId.statusText,\n });\n }\n complete();\n return withRequestId;\n}\n\nfunction responseWithRequestId(\n response: Response,\n requestId: string,\n closeConnection: boolean,\n): Response {\n const headers = new Headers(response.headers);\n headers.set(\"x-request-id\", requestId);\n if (closeConnection) {\n headers.set(\"connection\", \"close\");\n }\n return new Response(response.body, {\n headers,\n status: response.status,\n statusText: response.statusText,\n });\n}\n\n// Re-stream `body`, invoking `onComplete` exactly once when the stream finishes,\n// is cancelled (client disconnect), or errors — so callers can measure the true\n// end of a streamed response.\nfunction trackStreamCompletion(\n body: ReadableStream<Uint8Array>,\n onComplete: () => void,\n): ReadableStream<Uint8Array> {\n const reader = body.getReader();\n let fired = false;\n const fire = (): void => {\n if (!fired) {\n fired = true;\n onComplete();\n }\n };\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n const { done, value } = await reader.read();\n if (done) {\n controller.close();\n fire();\n return;\n }\n controller.enqueue(value);\n } catch (error) {\n fire();\n controller.error(error);\n }\n },\n cancel(reason) {\n fire();\n return reader.cancel(reason);\n },\n });\n}\n\nfunction logRequestCompleted(\n logger: HoopilotLogger,\n status: number,\n stream: boolean,\n durationMs: number,\n): void {\n const fields: LogFields = {\n durationMs,\n event: \"http.request.completed\",\n status,\n stream,\n };\n if (status >= 500) {\n logger.error(fields, \"request completed with server error\");\n return;\n }\n if (status >= 400) {\n logger.warn(fields, \"request completed with client error\");\n return;\n }\n logger.info(fields, \"request completed\");\n}\n\nfunction requestIdFor(request: Request): string {\n const existing = request.headers.get(\"x-request-id\")?.trim();\n return existing && REQUEST_ID_PATTERN.test(existing) ? existing : crypto.randomUUID();\n}\n\nfunction canonicalApiPath(path: string): string {\n const withoutTrailingSlash = path.length > 1 ? path.replace(/\\/+$/, \"\") : path;\n switch (withoutTrailingSlash) {\n case \"/models\":\n return \"/v1/models\";\n case \"/chat/completions\":\n return \"/v1/chat/completions\";\n case \"/completions\":\n return \"/v1/completions\";\n case \"/messages\":\n return \"/v1/messages\";\n case \"/messages/count_tokens\":\n return \"/v1/messages/count_tokens\";\n case \"/responses\":\n return \"/v1/responses\";\n case \"/usage\":\n return \"/v1/usage\";\n default:\n return withoutTrailingSlash;\n }\n}\n\nfunction routeFor(method: string, path: string): string {\n if (method === \"OPTIONS\") {\n return \"cors.preflight\";\n }\n if (method === \"GET\" && (path === \"/\" || path === \"/healthz\")) {\n return \"health\";\n }\n if (method === \"GET\" && path === \"/metrics\") {\n return \"metrics\";\n }\n if (method === \"GET\" && path === \"/v1/usage\") {\n return \"usage\";\n }\n if (method === \"GET\" && path === \"/v1/models\") {\n return \"models\";\n }\n if (method === \"POST\" && path === \"/v1/messages\") {\n return \"anthropic_messages\";\n }\n if (method === \"POST\" && path === \"/v1/messages/count_tokens\") {\n return \"anthropic_count_tokens\";\n }\n if (method === \"POST\" && path === \"/v1/chat/completions\") {\n return \"chat_completions\";\n }\n if (method === \"POST\" && path === \"/v1/completions\") {\n return \"completions\";\n }\n if (method === \"POST\" && path === \"/v1/responses\") {\n return \"responses\";\n }\n if (method === \"GET\" && path === \"/v1/responses\") {\n return \"responses_websocket\";\n }\n return \"not_found\";\n}\n\nfunction isStreamingResponse(response: Response): boolean {\n return response.headers.get(\"content-type\")?.includes(\"text/event-stream\") ?? false;\n}\n\nfunction logUpstreamSuccess(logger: HoopilotLogger, upstreamPath: string, status: number): void {\n logger.debug(\n {\n event: \"copilot.request.completed\",\n upstreamPath,\n upstreamStatus: status,\n },\n \"copilot upstream request completed\",\n );\n}\n\nfunction metricsResponse(metrics: MetricsRegistry): Response {\n return new Response(metrics.renderPrometheus(), {\n headers: {\n ...corsHeaders(),\n \"content-type\": PROMETHEUS_CONTENT_TYPE,\n },\n status: 200,\n });\n}\n\nasync function handleUsage(\n metrics: MetricsRegistry,\n readUsage: UsageReader,\n signal: AbortSignal,\n): Promise<Response> {\n const { copilot, error } = await readUsage(signal);\n const proxy = metrics.snapshot();\n const body: JsonObject = { copilot: copilot ?? null, object: \"usage\", proxy };\n if (error) {\n body.copilot_error = error;\n }\n return jsonResponse(body);\n}\n\n/**\n * Build a memoizing reader for the Copilot quota. The result is cached for\n * {@link USAGE_CACHE_TTL_MS} so repeated `/v1/usage` scrapes do not hammer\n * GitHub's REST rate limit, and missing credentials or upstream errors surface\n * as an `error` string rather than failing the whole response.\n */\nexport function createUsageReader(\n client: CopilotClient,\n metrics: MetricsRegistry,\n now: () => number = Date.now,\n ttlMs = USAGE_CACHE_TTL_MS,\n): UsageReader {\n const usagePath = \"/copilot_internal/user\";\n let cache: { atMs: number; value: CopilotUsage } | undefined;\n return async (signal) => {\n if (cache && now() - cache.atMs < ttlMs) {\n return { copilot: cache.value };\n }\n try {\n const upstream = await client.usage(signal);\n metrics.recordUpstream(usagePath, upstream.ok);\n if (!upstream.ok) {\n return { error: `GitHub Copilot usage request failed with ${upstream.status}.` };\n }\n const value = normalizeCopilotUsage(await upstream.json().catch(() => ({})));\n cache = { atMs: now(), value };\n metrics.recordCopilotQuota(value);\n return { copilot: value };\n } catch (error) {\n if (error instanceof CopilotAuthError) {\n return { error: error.message };\n }\n metrics.recordUpstream(usagePath, false);\n return { error: errorMessage(error) };\n }\n };\n}\n\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n","// Self-update and update-notification orchestration. The pure decision logic\n// lives in update-core.ts; this module performs the network and filesystem I/O.\nimport { execFileSync } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport {\n chmodSync,\n copyFileSync,\n existsSync,\n mkdirSync,\n realpathSync,\n renameSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { errorDetails } from \"./logger\";\nimport type { HoopilotLogger } from \"./types\";\nimport {\n assetNameFor,\n assetSuffixFor,\n checksumFor,\n codexxShimFiles,\n formatUpdateNotice,\n type InstallKind,\n isOutdated,\n isUpdateCheckDisabled,\n type LatestRelease,\n latestReleaseApiUrl,\n parseLatestRelease,\n parseState,\n resolveCacheDir,\n shouldCleanupOldBinary,\n shouldRefresh,\n type UpdateState,\n upgradeCommandFor,\n} from \"./update-core\";\nimport { BAKED_TARGET, IS_STANDALONE_BINARY } from \"./version\";\n\nconst REQUEST_TIMEOUT_MS = 8_000;\nconst SHA256SUMS = \"SHA256SUMS\";\n\nfunction userAgent(version: string): string {\n return `hoopilot/${version}`;\n}\n\nfunction cacheDir(): string {\n return resolveCacheDir(process.env, process.platform, homedir(), join);\n}\n\nfunction stateFilePath(): string {\n return join(cacheDir(), \"update-check.json\");\n}\n\nasync function readStateSafe(): Promise<UpdateState> {\n try {\n return parseState(await readFile(stateFilePath(), \"utf8\"));\n } catch {\n return { lastCheck: 0, latestVersion: null, etag: null };\n }\n}\n\nasync function writeStateSafe(state: UpdateState): Promise<void> {\n try {\n mkdirSync(cacheDir(), { recursive: true });\n await writeFile(stateFilePath(), JSON.stringify(state), \"utf8\");\n } catch {\n // best effort: a read-only cache dir must never break the CLI\n }\n}\n\ninterface FetchResult {\n status: number;\n etag: string | null;\n release: LatestRelease | null;\n}\n\nasync function fetchLatest(version: string, etag?: string | null): Promise<FetchResult | null> {\n try {\n const headers: Record<string, string> = {\n Accept: \"application/vnd.github+json\",\n \"User-Agent\": userAgent(version),\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n };\n if (etag) {\n headers[\"If-None-Match\"] = etag;\n }\n const response = await fetch(latestReleaseApiUrl(), {\n headers,\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (response.status === 304) {\n return { status: 304, etag: etag ?? null, release: null };\n }\n if (!response.ok) {\n return { status: response.status, etag: null, release: null };\n }\n return {\n status: response.status,\n etag: response.headers.get(\"etag\"),\n release: parseLatestRelease(await response.json()),\n };\n } catch {\n return null; // offline / timeout: caller leaves state untouched\n }\n}\n\n/**\n * Print a notice if a previously-cached check found a newer release, then kick\n * off a throttled background refresh. Never blocks on the network and never\n * throws. Intended to be called (unawaited is fine) from the serve path.\n */\nexport async function maybeNotifyUpdate(\n currentVersion: string,\n kind: InstallKind,\n logger?: HoopilotLogger,\n): Promise<void> {\n if (isUpdateCheckDisabled(process.env, Boolean(process.stderr.isTTY))) {\n logger?.debug({ event: \"update.check.skipped\" }, \"update check skipped\");\n return;\n }\n const state = await readStateSafe();\n if (state.latestVersion && isOutdated(currentVersion, state.latestVersion)) {\n logger?.debug(\n {\n currentVersion,\n event: \"update.notice.cached\",\n installKind: kind,\n latestVersion: state.latestVersion,\n },\n \"showing cached update notice\",\n );\n process.stderr.write(formatUpdateNotice(currentVersion, state.latestVersion, kind));\n }\n if (shouldRefresh(state.lastCheck, Date.now())) {\n logger?.debug({ event: \"update.check.refresh_queued\" }, \"queued update check refresh\");\n void refreshState(currentVersion, state.etag ?? null, logger).catch((error: unknown) => {\n logger?.debug(\n { err: errorDetails(error), event: \"update.check.refresh_failed\" },\n \"update check refresh failed\",\n );\n });\n }\n}\n\nasync function refreshState(\n currentVersion: string,\n etag: string | null,\n logger?: HoopilotLogger,\n): Promise<void> {\n const result = await fetchLatest(currentVersion, etag);\n if (!result) {\n logger?.debug({ event: \"update.check.unavailable\" }, \"update check unavailable\");\n return; // network error: keep prior state\n }\n if (result.status === 304) {\n const prev = await readStateSafe();\n await writeStateSafe({ ...prev, lastCheck: Date.now() });\n logger?.debug({ event: \"update.check.not_modified\" }, \"latest release unchanged\");\n return;\n }\n if (result.release) {\n await writeStateSafe({\n lastCheck: Date.now(),\n latestVersion: result.release.version,\n etag: result.etag,\n });\n logger?.debug(\n { event: \"update.check.updated\", latestVersion: result.release.version },\n \"updated cached latest release state\",\n );\n }\n}\n\nfunction detectInstallKind(): InstallKind {\n return IS_STANDALONE_BINARY ? \"binary\" : \"npm\";\n}\n\nfunction detectMusl(): boolean {\n if (process.platform !== \"linux\") {\n return false;\n }\n try {\n const report = process.report?.getReport?.() as\n | { header?: Record<string, unknown> }\n | undefined;\n if (report?.header && \"glibcVersionRuntime\" in report.header) {\n return !report.header.glibcVersionRuntime;\n }\n } catch {\n // fall through to file-based detection\n }\n try {\n if (existsSync(\"/etc/alpine-release\")) {\n return true;\n }\n const ldd = execFileSync(\"ldd\", [\"--version\"], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n timeout: 2_000,\n });\n return /musl/i.test(ldd);\n } catch {\n return false;\n }\n}\n\nasync function downloadToFile(url: string, dest: string, version: string): Promise<void> {\n const response = await fetch(url, {\n headers: { \"User-Agent\": userAgent(version) },\n redirect: \"follow\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS * 10),\n });\n if (!response.ok || !response.body) {\n throw new Error(`Download failed (${response.status}) for ${url}`);\n }\n await writeFile(dest, new Uint8Array(await response.arrayBuffer()));\n}\n\nasync function sha256File(path: string): Promise<string> {\n return createHash(\"sha256\")\n .update(await readFile(path))\n .digest(\"hex\");\n}\n\nasync function verifyChecksum(\n release: LatestRelease,\n assetName: string,\n file: string,\n version: string,\n): Promise<void> {\n const sums = release.assets.find((asset) => asset.name === SHA256SUMS);\n if (!sums) {\n // Fail closed: never overwrite the running binary with an unverified download.\n throw new Error(\n `Release ${release.tag} has no ${SHA256SUMS}; refusing to install an unverified binary.`,\n );\n }\n const response = await fetch(sums.url, {\n headers: { \"User-Agent\": userAgent(version) },\n redirect: \"follow\",\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n if (!response.ok) {\n throw new Error(`Could not download ${SHA256SUMS} (${response.status}).`);\n }\n const expected = checksumFor(await response.text(), assetName);\n if (!expected) {\n throw new Error(`No checksum for ${assetName} in ${SHA256SUMS}.`);\n }\n const actual = await sha256File(file);\n if (actual.toLowerCase() !== expected) {\n throw new Error(`Checksum mismatch for ${assetName}: expected ${expected}, got ${actual}.`);\n }\n}\n\nfunction swapBinary(tmpFile: string, exePath: string): void {\n if (process.platform === \"win32\") {\n // A running .exe cannot be overwritten, but it can be renamed aside.\n const oldExe = `${exePath}.old`;\n try {\n rmSync(oldExe, { force: true });\n } catch {\n // a previous .old may still be locked; the new name still wins below\n }\n renameSync(exePath, oldExe);\n const restore = () => {\n try {\n renameSync(oldExe, exePath); // put the working binary back\n } catch {\n // nothing more we can do\n }\n };\n try {\n renameSync(tmpFile, exePath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"EXDEV\") {\n try {\n copyFileSync(tmpFile, exePath);\n } catch (copyError) {\n restore();\n throw copyError;\n }\n } else {\n restore();\n throw error;\n }\n }\n return;\n }\n // Unix: atomic rename over the running file; the old inode stays mapped until exit.\n try {\n renameSync(tmpFile, exePath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"EXDEV\") {\n copyFileSync(tmpFile, exePath);\n chmodSync(exePath, 0o755);\n } else if (code === \"EACCES\" || code === \"EPERM\") {\n throw new Error(\n `No permission to update ${exePath}. Re-run with sudo, or reinstall to a writable directory.`,\n );\n } else {\n throw error;\n }\n }\n}\n\nfunction refreshCodexxShim(dir: string, logger?: HoopilotLogger): void {\n try {\n for (const file of codexxShimFiles(process.platform)) {\n const path = join(dir, file.name);\n writeFileSync(path, file.content, \"utf8\");\n if (file.executable) {\n chmodSync(path, 0o755);\n }\n }\n } catch (error) {\n logger?.warn(\n { err: errorDetails(error), event: \"update.codexx_shim_failed\" },\n \"could not refresh codexx shim\",\n );\n console.warn(`Updated hoopilot, but could not refresh the codexx shim: ${errorMessage(error)}`);\n }\n}\n\n/** Remove the leftover \".old\" binary from a prior Windows self-update. */\nexport function cleanupOldBinary(): void {\n if (!shouldCleanupOldBinary(process.platform, IS_STANDALONE_BINARY)) {\n return;\n }\n try {\n rmSync(`${realpathSync(process.execPath)}.old`, { force: true });\n } catch {\n // still locked or already gone\n }\n}\n\n/** Implements the `hoopilot update` command. */\nexport async function runUpdate(currentVersion: string, logger?: HoopilotLogger): Promise<void> {\n cleanupOldBinary();\n const kind = detectInstallKind();\n logger?.debug({ currentVersion, event: \"update.started\", installKind: kind }, \"update started\");\n\n if (kind !== \"binary\") {\n console.log(`hoopilot ${currentVersion} was installed via npm.`);\n console.log(`Update with: ${upgradeCommandFor(\"npm\")}`);\n return;\n }\n\n console.log(`hoopilot ${currentVersion} — checking for updates...`);\n const result = await fetchLatest(currentVersion);\n const release = result?.release ?? null;\n if (!release) {\n throw new Error(\"Could not reach GitHub to check for the latest release.\");\n }\n if (!isOutdated(currentVersion, release.version)) {\n logger?.debug(\n { currentVersion, event: \"update.already_current\", latestVersion: release.version },\n \"hoopilot is already up to date\",\n );\n console.log(`Already up to date (latest: ${release.version}).`);\n return;\n }\n\n const suffix = BAKED_TARGET ?? assetSuffixFor(process.platform, process.arch, detectMusl());\n const assetName = assetNameFor(suffix);\n const asset = release.assets.find((entry) => entry.name === assetName);\n if (!asset) {\n const available = release.assets.map((entry) => entry.name).join(\", \") || \"none\";\n throw new Error(`Release ${release.tag} has no asset \"${assetName}\". Available: ${available}.`);\n }\n\n console.log(`Updating ${currentVersion} → ${release.version} (${assetName})...`);\n logger?.debug(\n {\n assetName,\n currentVersion,\n event: \"update.installing\",\n latestVersion: release.version,\n },\n \"installing update\",\n );\n const exePath = realpathSync(process.execPath);\n const tmpFile = join(dirname(exePath), `.hoopilot-update-${process.pid}.tmp`);\n try {\n await downloadToFile(asset.url, tmpFile, currentVersion);\n await verifyChecksum(release, assetName, tmpFile, currentVersion);\n if (process.platform !== \"win32\") {\n chmodSync(tmpFile, 0o755);\n }\n swapBinary(tmpFile, exePath);\n refreshCodexxShim(dirname(exePath), logger);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"EACCES\" || code === \"EPERM\") {\n throw new Error(\n `No permission to update ${exePath}. Re-run with sudo, or reinstall to a writable directory (e.g. set HOOPILOT_INSTALL_DIR).`,\n );\n }\n throw error;\n } finally {\n try {\n rmSync(tmpFile, { force: true });\n } catch {\n // already moved into place or never created\n }\n }\n\n console.log(`Updated hoopilot to ${release.version}.`);\n logger?.debug(\n { currentVersion, event: \"update.completed\", latestVersion: release.version },\n \"update completed\",\n );\n if (process.platform === \"win32\") {\n console.log(\"Restart hoopilot to run the new version.\");\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","// Pure, dependency-free logic for version checks and self-update decisions.\n// Everything here is side-effect free so it can be unit tested without network\n// or filesystem access; the I/O orchestration lives in update.ts.\n\nconst REPO_OWNER = \"openhoo\";\nconst REPO_NAME = \"hoopilot\";\nexport const REPO = `${REPO_OWNER}/${REPO_NAME}`;\nexport const NPM_PACKAGE = \"@openhoo/hoopilot\";\n\n/** How a copy of hoopilot was installed. */\nexport type InstallKind = \"binary\" | \"npm\";\n\n/** How often the background update check is allowed to hit GitHub. */\nexport const UPDATE_CHECK_INTERVAL_MS = 1000 * 60 * 60 * 24; // 24h\n\n/** Persisted state for the throttled update check. */\nexport interface UpdateState {\n lastCheck: number;\n latestVersion: string | null;\n etag?: string | null;\n}\n\nexport interface CodexxShimFile {\n content: string;\n executable: boolean;\n name: string;\n}\n\ninterface SemVer {\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n}\n\nfunction parseSemver(input: string): SemVer | null {\n const value = String(input)\n .trim()\n .replace(/^[v=]+/, \"\");\n const match = value.match(/^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/);\n if (!match) {\n return null;\n }\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n // Build metadata (everything after \"+\") is intentionally dropped.\n prerelease: match[4] ? match[4].split(\".\") : [],\n };\n}\n\nfunction comparePrerelease(a: string[], b: string[]): -1 | 0 | 1 {\n if (a.length === 0 && b.length === 0) {\n return 0;\n }\n // A release outranks an otherwise-equal prerelease.\n if (a.length === 0) {\n return 1;\n }\n if (b.length === 0) {\n return -1;\n }\n const len = Math.max(a.length, b.length);\n for (let i = 0; i < len; i++) {\n const x = a[i];\n const y = b[i];\n // The version with more prerelease fields has higher precedence.\n if (x === undefined) {\n return -1;\n }\n if (y === undefined) {\n return 1;\n }\n const xNumeric = /^\\d+$/.test(x);\n const yNumeric = /^\\d+$/.test(y);\n if (xNumeric && yNumeric) {\n const diff = Number(x) - Number(y);\n if (diff !== 0) {\n return diff < 0 ? -1 : 1;\n }\n } else if (xNumeric) {\n return -1; // numeric identifiers sort lower than alphanumeric\n } else if (yNumeric) {\n return 1;\n } else if (x !== y) {\n return x < y ? -1 : 1; // ASCII lexical\n }\n }\n return 0;\n}\n\n/**\n * Compare two semantic versions. Returns -1 if a < b, 0 if equal, 1 if a > b.\n * Tolerates a leading \"v\"/\"=\", ignores build metadata, honors prerelease\n * precedence, and sorts unparseable input low so a bad value never throws.\n */\nexport function compareSemver(a: string, b: string): -1 | 0 | 1 {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n if (!pa || !pb) {\n if (!pa && !pb) {\n return 0;\n }\n return pa ? 1 : -1;\n }\n if (pa.major !== pb.major) {\n return pa.major < pb.major ? -1 : 1;\n }\n if (pa.minor !== pb.minor) {\n return pa.minor < pb.minor ? -1 : 1;\n }\n if (pa.patch !== pb.patch) {\n return pa.patch < pb.patch ? -1 : 1;\n }\n return comparePrerelease(pa.prerelease, pb.prerelease);\n}\n\n/** True when `latest` is a strictly newer release than `current`. */\nexport function isOutdated(current: string, latest: string): boolean {\n return compareSemver(current, latest) < 0;\n}\n\n/** Strip a leading \"v\" from a git tag to get a bare version string. */\nexport function versionFromTag(tag: string): string {\n return tag.trim().replace(/^v/, \"\");\n}\n\n/**\n * Compute the release asset suffix for a platform/arch, e.g. \"linux-x64-musl\",\n * \"darwin-arm64\", \"windows-x64\". `platform`/`arch` use Node's process values.\n */\nexport function assetSuffixFor(platform: string, arch: string, isMusl: boolean): string {\n const os = platform === \"win32\" ? \"windows\" : platform === \"darwin\" ? \"darwin\" : \"linux\";\n const cpu = arch === \"arm64\" || arch === \"aarch64\" ? \"arm64\" : \"x64\";\n const libc = os === \"linux\" && isMusl ? \"-musl\" : \"\";\n return `${os}-${cpu}${libc}`;\n}\n\n/** Full release asset file name for a suffix (adds .exe for Windows). */\nexport function assetNameFor(suffix: string): string {\n const name = `hoopilot-${suffix}`;\n return suffix.startsWith(\"windows-\") ? `${name}.exe` : name;\n}\n\n/** Whether automatic update checks should be skipped, per env + TTY. */\nexport function isUpdateCheckDisabled(\n env: Record<string, string | undefined>,\n isTty: boolean,\n): boolean {\n if (env.HOOPILOT_NO_UPDATE_CHECK || env.NO_UPDATE_NOTIFIER) {\n return true;\n }\n if (env.NODE_ENV === \"test\") {\n return true;\n }\n if (!isTty) {\n return true; // piped / non-interactive output\n }\n if (\n (env.CI && env.CI !== \"false\") ||\n env.CONTINUOUS_INTEGRATION ||\n env.GITHUB_ACTIONS ||\n env.BUILD_NUMBER ||\n env.RUN_ID\n ) {\n return true;\n }\n return false;\n}\n\n/** Whether the background check is due again given the last check time. */\nexport function shouldRefresh(\n lastCheck: number,\n now: number,\n intervalMs = UPDATE_CHECK_INTERVAL_MS,\n): boolean {\n return now - lastCheck >= intervalMs;\n}\n\n/** The command a user runs to upgrade, depending on how they installed. */\nexport function upgradeCommandFor(kind: InstallKind): string {\n return kind === \"binary\"\n ? \"hoopilot update\"\n : `npm install -g ${NPM_PACKAGE}@latest (or: bun add -g ${NPM_PACKAGE})`;\n}\n\n/** Whether it is safe to remove a leftover Windows self-update backup. */\nexport function shouldCleanupOldBinary(platform: string, isStandaloneBinary: boolean): boolean {\n return platform === \"win32\" && isStandaloneBinary;\n}\n\n/** Files that expose the standalone `codexx` command next to the `hoopilot` binary. */\nexport function codexxShimFiles(platform: string): CodexxShimFile[] {\n if (platform === \"win32\") {\n return [\n {\n content: `$ErrorActionPreference = 'Stop'\n$hoopilot = Join-Path $PSScriptRoot 'hoopilot.exe'\n& $hoopilot codexx @args\nexit $LASTEXITCODE\n`,\n executable: false,\n name: \"codexx.ps1\",\n },\n {\n content: `@echo off\nsetlocal\nwhere pwsh >nul 2>nul\nif %ERRORLEVEL% EQU 0 (\n pwsh -NoProfile -ExecutionPolicy Bypass -File \"%~dp0codexx.ps1\" %*\n) else (\n powershell -NoProfile -ExecutionPolicy Bypass -File \"%~dp0codexx.ps1\" %*\n)\nexit /b %ERRORLEVEL%\n`,\n executable: false,\n name: \"codexx.cmd\",\n },\n ];\n }\n return [\n {\n content: `#!/bin/sh\nset -eu\nscript_dir=$(CDPATH= cd \"$(dirname \"$0\")\" && pwd)\nexec \"$script_dir/hoopilot\" codexx \"$@\"\n`,\n executable: true,\n name: \"codexx\",\n },\n ];\n}\n\n/** Render the \"update available\" notice printed to stderr. */\nexport function formatUpdateNotice(current: string, latest: string, kind: InstallKind): string {\n return (\n `\\nUpdate available for hoopilot: ${current} → ${latest}\\n` +\n `Run: ${upgradeCommandFor(kind)}\\n\\n`\n );\n}\n\n/** Parse the persisted update-check state, tolerating any malformed input. */\nexport function parseState(text: string): UpdateState {\n try {\n const data = JSON.parse(text) as Partial<UpdateState>;\n return {\n lastCheck: typeof data.lastCheck === \"number\" ? data.lastCheck : 0,\n latestVersion: typeof data.latestVersion === \"string\" ? data.latestVersion : null,\n etag: typeof data.etag === \"string\" ? data.etag : null,\n };\n } catch {\n return { lastCheck: 0, latestVersion: null, etag: null };\n }\n}\n\nexport interface LatestRelease {\n version: string;\n tag: string;\n assets: Array<{ name: string; url: string }>;\n}\n\n/** Parse the GitHub `releases/latest` response into the fields we need. */\nexport function parseLatestRelease(json: unknown): LatestRelease | null {\n if (!json || typeof json !== \"object\") {\n return null;\n }\n const record = json as Record<string, unknown>;\n const tag = typeof record.tag_name === \"string\" ? record.tag_name : undefined;\n if (!tag) {\n return null;\n }\n const assets: Array<{ name: string; url: string }> = [];\n if (Array.isArray(record.assets)) {\n for (const item of record.assets) {\n if (item && typeof item === \"object\") {\n const asset = item as Record<string, unknown>;\n if (typeof asset.name === \"string\" && typeof asset.browser_download_url === \"string\") {\n assets.push({ name: asset.name, url: asset.browser_download_url });\n }\n }\n }\n }\n return { version: versionFromTag(tag), tag, assets };\n}\n\n/** Find a checksum line for `fileName` in a `sha256sum`-style SHA256SUMS file. */\nexport function checksumFor(sumsText: string, fileName: string): string | undefined {\n for (const line of sumsText.split(/\\r?\\n/)) {\n const match = line.trim().match(/^([0-9a-fA-F]{64})\\s+\\*?(.+)$/);\n if (match?.[1] && match[2]?.trim() === fileName) {\n return match[1].toLowerCase();\n }\n }\n return undefined;\n}\n\n/**\n * Resolve the per-OS cache directory (no deps). Mirrors env-paths conventions:\n * Windows -> %LOCALAPPDATA%, macOS -> ~/Library/Caches, else $XDG_CACHE_HOME||~/.cache.\n */\nexport function resolveCacheDir(\n env: Record<string, string | undefined>,\n platform: string,\n homedir: string,\n join: (...parts: string[]) => string,\n): string {\n if (platform === \"win32\") {\n const base = env.LOCALAPPDATA || join(homedir, \"AppData\", \"Local\");\n return join(base, \"hoopilot\");\n }\n if (platform === \"darwin\") {\n return join(homedir, \"Library\", \"Caches\", \"hoopilot\");\n }\n const base = env.XDG_CACHE_HOME || join(homedir, \".cache\");\n return join(base, \"hoopilot\");\n}\n\n/** Stable redirect URL that downloads an asset from the latest release. */\nexport function latestDownloadUrl(asset: string): string {\n return `https://github.com/${REPO}/releases/latest/download/${asset}`;\n}\n\n/** GitHub REST endpoint for the latest release. */\nexport function latestReleaseApiUrl(): string {\n return `https://api.github.com/repos/${REPO}/releases/latest`;\n}\n"],"mappings":"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","names":["readFileSync","removeUndefined","randomId","firstNumber","parseJsonObject","chmodSync","mkdirSync","renameSync","writeFileSync","dirname","join","homedir","join","base","REQUEST_TIMEOUT_MS","join","mkdirSync","renameSync","chmodSync","writeFileSync","errorMessage","dirname","ALLOWED_COPILOT_API_HOSTS","main","args","logger","readFileSync"]}
|