betahi-copilot-bridge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","names":["runtimeState: RuntimeState","COPILOT_VERSION","EDITOR_PLUGIN_VERSION","USER_AGENT","path","COPILOT_VERSION","EDITOR_PLUGIN_VERSION","USER_AGENT","GITHUB_API_VERSION","GITHUB_API_BASE_URL","sleep","readGitHubToken","lines: Array<string>","out: CodexUserConfig","MODEL_CAPABILITIES: ReadonlyArray<ModelCapability>","entries: Array<readonly [string, ModelCapability]>","order: ReadonlyArray<ReasoningEffort>","DEFAULT_SETTINGS: BridgeSettings","out: Record<string, unknown>","merged: Record<string, string>","state: ResponseTranslationState","translated: Array<ResponsesInputItem>","isClaudeOpus47Model","normalizeReasoningEffort","matches: Array<Model>","newMessages: Array<Message>","contentParts: Array<ContentPart>","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null","events: Array<AnthropicStreamEventData>","events","streamState: AnthropicStreamState","chunk: ChatCompletionChunk","events","parts: Array<ChatContentPart>","messages: Array<ChatMessage>","inputItems: Array<ResponsesInputItem>","role: ChatRole","tools: Array<ChatTool> | undefined","payload: ChatRequestPayload","output: ResponsesApiResult[\"output\"]","event: ResponsesStreamEvent","stableResponse: StableResponseMetadata","incoming: ReasoningField | undefined","upstream","chosenModel: string | undefined","chosenEffort: string | undefined"],"sources":["../src/lib/error.ts","../src/lib/paths.ts","../src/lib/state.ts","../src/providers/copilot/client.ts","../src/providers/copilot/get-models.ts","../src/lib/auth.ts","../src/lib/config.ts","../src/auth.ts","../src/lib/codex-config.ts","../src/lib/model-capabilities.ts","../src/lib/settings.ts","../src/lib/rate-limit.ts","../src/lib/claude-settings.ts","../src/services/copilot/responses.ts","../src/services/copilot/create-chat-completions.ts","../src/routes/chat-completions.ts","../src/providers/copilot/create-embeddings.ts","../src/routes/embeddings.ts","../src/lib/models-resolver.ts","../src/bridges/claude/utils.ts","../src/bridges/claude/non-stream-translation.ts","../src/bridges/claude/stream-translation.ts","../src/lib/tokenizer.ts","../src/routes/messages.ts","../src/routes/models.ts","../src/bridges/codex/chat-fallback.ts","../src/bridges/codex/normalize-stream.ts","../src/bridges/codex/responses.ts","../src/routes/responses.ts","../src/providers/github/get-copilot-usage.ts","../src/routes/usage.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["export class BridgeNotImplementedError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"BridgeNotImplementedError\"\n }\n}\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.name = \"HTTPError\"\n this.response = response\n }\n}\n","import fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nconst APP_DIR = path.join(os.homedir(), \".local\", \"share\", \"copilot-bridge\")\n\nconst GITHUB_TOKEN_PATH = path.join(APP_DIR, \"github_token\")\n\nexport const PATHS = {\n APP_DIR,\n GITHUB_TOKEN_PATH,\n}\n\nexport async function ensurePaths(): Promise<void> {\n await fs.mkdir(PATHS.APP_DIR, { recursive: true })\n await ensureFile(PATHS.GITHUB_TOKEN_PATH)\n}\n\nasync function ensureFile(filePath: string): Promise<void> {\n try {\n await fs.access(filePath, fs.constants.W_OK)\n } catch {\n await fs.writeFile(filePath, \"\")\n await fs.chmod(filePath, 0o600)\n }\n}","import type { ModelsResponse } from \"~/providers/copilot/get-models\"\n\nexport interface RuntimeState {\n models?: ModelsResponse\n rateLimitSeconds?: number\n rateLimitWait?: boolean\n lastRequestTimestamp?: number\n}\n\nexport const runtimeState: RuntimeState = {}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { BridgeConfig } from \"~/lib/config\"\nimport { BridgeNotImplementedError } from \"~/lib/error\"\n\nconst COPILOT_VERSION = \"0.26.7\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst API_VERSION = \"2025-04-01\"\n\nexport interface CopilotProviderContext {\n baseUrl: string\n token: string | undefined\n vsCodeVersion: string\n}\n\nexport const getCopilotProviderContext = (\n config: BridgeConfig,\n): CopilotProviderContext => ({\n baseUrl: config.copilotBaseUrl,\n token: config.copilotToken,\n vsCodeVersion: config.vsCodeVersion,\n})\n\nexport interface FetchCopilotOptions {\n vision?: boolean\n initiator?: \"agent\" | \"user\"\n}\n\nexport const fetchCopilot = async (\n provider: CopilotProviderContext,\n path: string,\n init: RequestInit,\n options: FetchCopilotOptions = {},\n) => {\n if (!provider.token) {\n throw new BridgeNotImplementedError(\n \"COPILOT_TOKEN is not configured for copilot-bridge.\",\n )\n }\n\n const headers = new Headers(init.headers)\n\n headers.set(\"authorization\", `Bearer ${provider.token}`)\n headers.set(\"copilot-integration-id\", \"vscode-chat\")\n headers.set(\"editor-version\", `vscode/${provider.vsCodeVersion}`)\n headers.set(\"editor-plugin-version\", EDITOR_PLUGIN_VERSION)\n headers.set(\"user-agent\", USER_AGENT)\n headers.set(\"openai-intent\", \"conversation-panel\")\n headers.set(\"x-github-api-version\", API_VERSION)\n headers.set(\"x-request-id\", randomUUID())\n headers.set(\"x-vscode-user-agent-library-version\", \"electron-fetch\")\n\n if (options.vision) {\n headers.set(\"copilot-vision-request\", \"true\")\n }\n\n if (options.initiator) {\n headers.set(\"x-initiator\", options.initiator)\n }\n\n if (!headers.has(\"content-type\") && init.body !== undefined) {\n headers.set(\"content-type\", \"application/json\")\n }\n\n if (!headers.has(\"accept\")) {\n headers.set(\"accept\", \"application/json\")\n }\n\n return fetch(`${provider.baseUrl}${path}`, {\n ...init,\n headers,\n })\n}\n","import type { BridgeConfig } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\n\nimport { fetchCopilot, getCopilotProviderContext } from \"./client\"\n\nexport const getModels = async (\n config: BridgeConfig,\n): Promise<ModelsResponse> => {\n const provider = getCopilotProviderContext(config)\n const response = await fetchCopilot(provider, \"/models\", {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get models\", response)\n\n return (await response.json()) as ModelsResponse\n}\n\nexport interface ModelsResponse {\n data: Array<Model>\n object: string\n}\n\ninterface ModelLimits {\n max_context_window_tokens?: number\n max_output_tokens?: number\n max_prompt_tokens?: number\n max_inputs?: number\n}\n\ninterface ModelSupports {\n tool_calls?: boolean\n parallel_tool_calls?: boolean\n dimensions?: boolean\n}\n\ninterface ModelCapabilities {\n family: string\n limits: ModelLimits\n object: string\n supports: ModelSupports\n tokenizer: string\n type: string\n}\n\nexport interface Model {\n capabilities: ModelCapabilities\n id: string\n model_picker_enabled: boolean\n name: string\n object: string\n preview: boolean\n vendor: string\n version: string\n policy?: {\n state: string\n terms: string\n }\n}\n","import fs from \"node:fs/promises\"\n\nimport consola from \"consola\"\n\nimport type { BridgeConfig } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { PATHS, ensurePaths } from \"~/lib/paths\"\nimport { runtimeState } from \"~/lib/state\"\nimport { getModels } from \"~/providers/copilot/get-models\"\n\nconst COPILOT_VERSION = \"0.26.7\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst GITHUB_API_VERSION = \"2022-11-28\"\n\nconst GITHUB_API_BASE_URL = \"https://api.github.com\"\nconst GITHUB_BASE_URL = \"https://github.com\"\nconst GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nconst GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\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 AccessTokenResponse {\n access_token?: string\n}\n\ninterface CopilotTokenResponse {\n refresh_in: number\n token: string\n}\n\ninterface GitHubUserResponse {\n login: string\n}\n\ninterface AuthOptions {\n force?: boolean\n showToken?: boolean\n}\n\nconst standardHeaders = () => ({\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n})\n\nconst sleep = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nconst readGitHubToken = async () => {\n const token = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return token.trim()\n}\n\nconst writeGitHubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, `${token.trim()}\\n`, { mode: 0o600 })\n\nconst githubHeaders = (githubToken: string, vsCodeVersion: string) => ({\n ...standardHeaders(),\n authorization: `token ${githubToken}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"editor-version\": `vscode/${vsCodeVersion}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": GITHUB_API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n})\n\nconst getDeviceCode = async (): Promise<DeviceCodeResponse> => {\n const response = await fetch(`${GITHUB_BASE_URL}/login/device/code`, {\n method: \"POST\",\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n scope: GITHUB_APP_SCOPES,\n }),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get device code\", response)\n }\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nconst pollAccessToken = async (\n deviceCode: DeviceCodeResponse,\n): Promise<string> => {\n const sleepDuration = (deviceCode.interval + 1) * 1000\n\n while (true) {\n const response = await fetch(`${GITHUB_BASE_URL}/login/oauth/access_token`, {\n method: \"POST\",\n headers: standardHeaders(),\n body: JSON.stringify({\n client_id: GITHUB_CLIENT_ID,\n device_code: deviceCode.device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n })\n\n if (!response.ok) {\n await sleep(sleepDuration)\n continue\n }\n\n const json = (await response.json()) as AccessTokenResponse\n if (json.access_token) {\n return json.access_token\n }\n\n await sleep(sleepDuration)\n }\n}\n\nconst getGitHubUser = async (\n githubToken: string,\n vsCodeVersion: string,\n): Promise<GitHubUserResponse> => {\n const response = await fetch(`${GITHUB_API_BASE_URL}/user`, {\n headers: githubHeaders(githubToken, vsCodeVersion),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get GitHub user\", response)\n }\n\n return (await response.json()) as GitHubUserResponse\n}\n\nconst getCopilotToken = async (\n githubToken: string,\n vsCodeVersion: string,\n): Promise<CopilotTokenResponse> => {\n const response = await fetch(\n `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(githubToken, vsCodeVersion),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot token\", response)\n }\n\n return (await response.json()) as CopilotTokenResponse\n}\n\nconst ensureGitHubToken = async (\n config: BridgeConfig,\n options: AuthOptions = {},\n) => {\n await ensurePaths()\n\n const existingToken = options.force ? \"\" : await readGitHubToken()\n if (existingToken) {\n return existingToken\n }\n\n const deviceCode = await getDeviceCode()\n consola.info(\n `Open ${deviceCode.verification_uri} and enter code ${deviceCode.user_code}`,\n )\n\n const githubToken = await pollAccessToken(deviceCode)\n await writeGitHubToken(githubToken)\n\n if (options.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n\n const user = await getGitHubUser(githubToken, config.vsCodeVersion)\n consola.success(`Logged in as ${user.login}`)\n\n return githubToken\n}\n\nexport const setupBridgeAuth = async (\n config: BridgeConfig,\n options: AuthOptions = {},\n) => {\n if (config.copilotToken) {\n if (options.showToken) {\n consola.info(\"Using COPILOT_TOKEN from environment\")\n }\n await loadModels(config)\n return\n }\n\n const githubToken = await ensureGitHubToken(config, options)\n const applyCopilotToken = async () => {\n const { refresh_in, token } = await getCopilotToken(\n githubToken,\n config.vsCodeVersion,\n )\n\n config.copilotToken = token\n if (options.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n return refresh_in\n }\n\n const refreshIn = await applyCopilotToken()\n const refreshInterval = Math.max(refreshIn - 60, 60) * 1000\n\n setInterval(async () => {\n try {\n await applyCopilotToken()\n consola.debug(\"Refreshed Copilot token\")\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n }\n }, refreshInterval)\n\n await loadModels(config)\n}\n\nconst loadModels = async (config: BridgeConfig) => {\n try {\n runtimeState.models = await getModels(config)\n consola.success(\n `Loaded ${runtimeState.models.data.length} Copilot models`,\n )\n } catch (error) {\n consola.warn(\"Failed to load Copilot models:\", error)\n }\n}\n\nexport const runBridgeAuth = async (\n config: BridgeConfig,\n options: AuthOptions = {},\n) => {\n const githubToken = await ensureGitHubToken(config, {\n ...options,\n force: true,\n })\n\n const user = await getGitHubUser(githubToken, config.vsCodeVersion)\n consola.success(`GitHub token written to ${PATHS.GITHUB_TOKEN_PATH}`)\n consola.info(`Logged in as ${user.login}`)\n}","import { z } from \"zod\"\n\nconst accountTypeSchema = z.enum([\"individual\", \"business\", \"enterprise\"])\n\nconst inputSchema = z.object({\n host: z.string().min(1),\n port: z.number().int().min(1).max(65535),\n})\n\nexport interface BridgeConfig {\n host: string\n port: number\n accountType: \"individual\" | \"business\" | \"enterprise\"\n copilotBaseUrl: string\n copilotToken: string | undefined\n vsCodeVersion: string\n}\n\nexport interface BridgeEnv {\n Variables: {\n config: BridgeConfig\n }\n}\n\nexport const readBridgeConfig = (input: {\n host: string\n port: number\n}): BridgeConfig => {\n const parsedInput = inputSchema.parse(input)\n const accountType = accountTypeSchema.parse(\n process.env.COPILOT_ACCOUNT_TYPE ?? \"individual\",\n )\n const copilotBaseUrl =\n process.env.COPILOT_BASE_URL\n ?? (\n accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${accountType}.githubcopilot.com`\n )\n\n return {\n host: parsedInput.host,\n port: parsedInput.port,\n accountType,\n copilotBaseUrl,\n copilotToken: process.env.COPILOT_TOKEN,\n vsCodeVersion: process.env.COPILOT_VSCODE_VERSION ?? \"1.99.3\",\n }\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { setupBridgeAuth } from \"~/lib/auth\"\nimport { readBridgeConfig } from \"~/lib/config\"\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub device auth and cache credentials for copilot-bridge.\",\n },\n args: {\n host: {\n type: \"string\",\n default: \"127.0.0.1\",\n description: \"Host used for config initialization.\",\n },\n port: {\n type: \"string\",\n default: \"4142\",\n description: \"Port used for config initialization.\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Print GitHub and Copilot tokens during auth.\",\n },\n },\n async run({ args }) {\n const config = readBridgeConfig({\n host: String(args.host),\n port: Number(args.port),\n })\n\n config.copilotToken = undefined\n\n await setupBridgeAuth(config, {\n force: true,\n showToken: args[\"show-token\"],\n })\n\n consola.success(\"copilot-bridge auth completed\")\n },\n})","import fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CodexSettings } from \"./settings\"\n\nconst BEGIN_MARK =\n \"# >>> copilot-bridge managed block — auto-generated, do not edit between markers >>>\"\nconst END_MARK =\n \"# <<< copilot-bridge managed block — edits outside this block are preserved <<<\"\n\n// Legacy markers from earlier releases. We still recognize and strip them so\n// upgrading users do not end up with duplicate managed blocks.\nconst LEGACY_BEGIN_MARK = \"# >>> copilot-bridge managed (do not edit) >>>\"\nconst LEGACY_END_MARK = \"# <<< copilot-bridge managed (do not edit) <<<\"\n\n// Top-level keys that the user (or codex itself) is the owner of.\n// We never put these in our managed block to avoid TOML duplicate-key errors.\nconst USER_OWNED_SCALARS = [\"model\", \"model_reasoning_effort\"] as const\ntype UserScalar = (typeof USER_OWNED_SCALARS)[number]\n\ninterface ApplyCodexConfigInput {\n baseUrl: string\n settings: CodexSettings\n /** Optional model to write into the user-owned area of the file. */\n model?: string\n /** Optional reasoning effort to write into the user-owned area. */\n modelReasoningEffort?: string\n}\n\ninterface ApplyResult {\n configPath: string\n changed: boolean\n created: boolean\n}\n\nexport interface CodexUserConfig {\n model?: string\n modelReasoningEffort?: string\n}\n\nfunction tomlEscape(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"')\n}\n\nfunction buildManagedBlock(input: ApplyCodexConfigInput): string {\n const { baseUrl, settings } = input\n const lines: Array<string> = []\n lines.push(BEGIN_MARK)\n if (settings.setAsDefault) {\n lines.push(`model_provider = \"${tomlEscape(settings.providerId)}\"`)\n }\n lines.push(\"\")\n lines.push(`[model_providers.${settings.providerId}]`)\n lines.push(`name = \"${tomlEscape(settings.providerName)}\"`)\n lines.push(`base_url = \"${tomlEscape(baseUrl)}\"`)\n lines.push(`wire_api = \"responses\"`)\n lines.push(`prefer_websockets = false`)\n lines.push(`requires_openai_auth = false`)\n lines.push(END_MARK)\n return lines.join(\"\\n\")\n}\n\nfunction stripManagedBlock(content: string): string {\n let next = content\n for (const [begin, end] of [\n [BEGIN_MARK, END_MARK],\n [LEGACY_BEGIN_MARK, LEGACY_END_MARK],\n ]) {\n while (true) {\n const beginIdx = next.indexOf(begin)\n if (beginIdx === -1) break\n const endIdx = next.indexOf(end, beginIdx)\n if (endIdx === -1) break\n const before = next.slice(0, beginIdx).replace(/\\n*$/, \"\")\n const after = next.slice(endIdx + end.length).replace(/^\\n+/, \"\")\n if (before.length === 0) next = after\n else if (after.length === 0) next = `${before}\\n`\n else next = `${before}\\n\\n${after}`\n }\n }\n return next\n}\n\n// Lines belonging to the first (top-level) TOML section: from the start of\n// the file up to the first line that begins with `[`. This is where\n// codex's own `model = ...` and `model_reasoning_effort = ...` live.\nfunction splitTopSection(content: string): {\n top: string\n rest: string\n} {\n const lines = content.split(\"\\n\")\n let cut = lines.length\n for (let i = 0; i < lines.length; i++) {\n if (/^\\s*\\[/.test(lines[i])) {\n cut = i\n break\n }\n }\n return {\n top: lines.slice(0, cut).join(\"\\n\"),\n rest: lines.slice(cut).join(\"\\n\"),\n }\n}\n\nconst scalarRegex = (key: string) =>\n new RegExp(`^\\\\s*${key}\\\\s*=\\\\s*\"((?:[^\"\\\\\\\\]|\\\\\\\\.)*)\"\\\\s*$`, \"m\")\n\nexport function readCodexUserConfig(content: string): CodexUserConfig {\n const stripped = stripManagedBlock(content)\n const { top } = splitTopSection(stripped)\n const out: CodexUserConfig = {}\n const m = top.match(scalarRegex(\"model\"))\n if (m) out.model = m[1]\n const e = top.match(scalarRegex(\"model_reasoning_effort\"))\n if (e) out.modelReasoningEffort = e[1]\n return out\n}\n\nfunction setTopScalar(\n topSection: string,\n key: UserScalar,\n value: string | undefined,\n): string {\n const re = scalarRegex(key)\n if (value === undefined) {\n // Leave the existing value as-is when caller did not provide one.\n return topSection\n }\n const line = `${key} = \"${tomlEscape(value)}\"`\n if (re.test(topSection)) {\n return topSection.replace(re, line)\n }\n // Insert at the very top of the file, before any existing content.\n if (topSection.length === 0) return `${line}\\n`\n // Keep a single blank line between our inserted scalars and existing content.\n return `${line}\\n${topSection.startsWith(\"\\n\") ? \"\" : \"\"}${topSection}`\n}\n\nfunction applyUserScalars(\n content: string,\n input: ApplyCodexConfigInput,\n): string {\n const { top, rest } = splitTopSection(content)\n let nextTop = top\n nextTop = setTopScalar(nextTop, \"model\", input.model)\n nextTop = setTopScalar(\n nextTop,\n \"model_reasoning_effort\",\n input.modelReasoningEffort,\n )\n if (nextTop === top) return content\n if (rest.length === 0) {\n return nextTop.endsWith(\"\\n\") ? nextTop : `${nextTop}\\n`\n }\n const sep = nextTop.endsWith(\"\\n\") ? \"\" : \"\\n\"\n return `${nextTop}${sep}${rest}`\n}\n\nexport async function applyCodexConfig(\n input: ApplyCodexConfigInput & { configPath: string },\n): Promise<ApplyResult> {\n const { configPath } = input\n let existing = \"\"\n let created = false\n try {\n existing = await fs.readFile(configPath, \"utf8\")\n } catch {\n created = true\n }\n\n let stripped = stripManagedBlock(existing)\n stripped = applyUserScalars(stripped, input)\n const block = buildManagedBlock(input)\n const trimmed = stripped.replace(/\\n+$/, \"\")\n const next =\n trimmed.length === 0 ? `${block}\\n` : `${trimmed}\\n\\n${block}\\n`\n\n if (next === existing) {\n return { configPath, changed: false, created: false }\n }\n\n await fs.mkdir(path.dirname(configPath), { recursive: true })\n await fs.writeFile(configPath, next)\n return { configPath, changed: true, created }\n}\n\nexport async function readCodexUserConfigFromDisk(\n configPath: string,\n): Promise<CodexUserConfig> {\n try {\n const content = await fs.readFile(configPath, \"utf8\")\n return readCodexUserConfig(content)\n } catch {\n return {}\n }\n}\n","// Model capability registry for copilot-bridge.\n// Source: GitHub Copilot Responses API model + reasoning_effort matrix.\n// Keep this tightly scoped to what we use to validate / clamp requests.\n\nexport type ReasoningEffort =\n | \"none\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"xhigh\"\n | \"max\"\n\nexport interface ModelCapability {\n id: string\n // Optional aliases that resolve to this canonical id (e.g. trimming a\n // \"-preview\" suffix). Requests using an alias get their model rewritten\n // to the canonical id before being forwarded upstream.\n aliases?: ReadonlyArray<string>\n // If undefined, the model does not accept a reasoning parameter at all\n // and the bridge will strip any reasoning.* fields from the request.\n reasoning?: {\n supported: ReadonlyArray<ReasoningEffort>\n default: ReasoningEffort\n }\n // When set, /v1/responses requests for this model are translated to\n // upstream /v1/chat/completions because Copilot does not expose the\n // Responses API for this model.\n fallback?: \"chat-completions\"\n // Where to place the reasoning effort on the upstream chat payload.\n // - \"reasoning_effort\" (default for gpt-5 family / most claude)\n // - \"output_config.effort\" (claude-opus-4.7 family)\n // Has no effect when reasoning is undefined.\n reasoningField?: \"reasoning_effort\" | \"output_config.effort\"\n}\n\nexport const MODEL_CAPABILITIES: ReadonlyArray<ModelCapability> = [\n {\n id: \"gpt-5.5\",\n reasoning: {\n supported: [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5.4\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\", \"xhigh\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5.4-mini\",\n reasoning: {\n supported: [\"none\", \"low\", \"medium\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5.3-codex\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\", \"xhigh\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5.2\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\", \"xhigh\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5.2-codex\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\", \"xhigh\"],\n default: \"medium\",\n },\n },\n {\n id: \"gpt-5-mini\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\"],\n default: \"medium\",\n },\n },\n // Claude family — Copilot does not expose /v1/responses for Claude, so we\n // translate to /v1/chat/completions. Only opus-4.7 places effort under\n // output_config.effort; the others use the standard reasoning_effort.\n {\n id: \"claude-opus-4.7\",\n fallback: \"chat-completions\",\n reasoningField: \"output_config.effort\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\", \"xhigh\", \"max\"],\n default: \"medium\",\n },\n },\n {\n id: \"claude-opus-4.6\",\n fallback: \"chat-completions\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\"],\n default: \"medium\",\n },\n },\n {\n id: \"claude-opus-4.6-1m\",\n fallback: \"chat-completions\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\"],\n default: \"medium\",\n },\n },\n {\n id: \"claude-opus-4.5\",\n fallback: \"chat-completions\",\n },\n {\n id: \"claude-sonnet-4.6\",\n fallback: \"chat-completions\",\n reasoning: {\n supported: [\"low\", \"medium\", \"high\"],\n default: \"medium\",\n },\n },\n {\n id: \"claude-sonnet-4.5\",\n fallback: \"chat-completions\",\n },\n {\n id: \"claude-sonnet-4\",\n fallback: \"chat-completions\",\n },\n {\n id: \"claude-haiku-4.5\",\n fallback: \"chat-completions\",\n },\n // Gemini family currently does not accept a reasoning parameter on the\n // Copilot Responses endpoint — bridge strips reasoning.* before forwarding.\n {\n id: \"gemini-3.1-pro-preview\",\n fallback: \"chat-completions\",\n aliases: [\"gemini-3.1-pro\"],\n },\n {\n id: \"gemini-3-flash-preview\",\n fallback: \"chat-completions\",\n aliases: [\"gemini-3-flash\"],\n },\n {\n id: \"gemini-2.5-pro\",\n fallback: \"chat-completions\",\n },\n // Legacy GPT-4.x — chat-only upstream, no reasoning parameter accepted.\n {\n id: \"gpt-4.1\",\n fallback: \"chat-completions\",\n },\n {\n id: \"gpt-4o\",\n fallback: \"chat-completions\",\n },\n]\n\nconst CAPABILITY_BY_ID = new Map(\n MODEL_CAPABILITIES.flatMap((m) => {\n const entries: Array<readonly [string, ModelCapability]> = [[m.id, m]]\n for (const alias of m.aliases ?? []) entries.push([alias, m])\n return entries\n }),\n)\n\n// Resolve any alias to the canonical upstream id. Returns the input\n// unchanged when no mapping is found.\nexport const resolveModelId = (modelId: string): string =>\n CAPABILITY_BY_ID.get(modelId)?.id ?? modelId\n\nexport const getModelCapability = (\n modelId: string,\n): ModelCapability | undefined => CAPABILITY_BY_ID.get(modelId)\n\nexport const isReasoningEffort = (value: unknown): value is ReasoningEffort =>\n value === \"none\"\n || value === \"low\"\n || value === \"medium\"\n || value === \"high\"\n || value === \"xhigh\"\n || value === \"max\"\n\nexport interface NormalizedReasoning {\n effort: ReasoningEffort\n changed: boolean\n reason?: \"unsupported-model\" | \"unsupported-effort\"\n}\n\n// Clamp a requested effort to what the model supports. Returns undefined\n// when the model does not accept reasoning at all (caller should strip it).\nexport const clampReasoningEffort = (\n modelId: string,\n requested: unknown,\n): NormalizedReasoning | undefined => {\n const capability = getModelCapability(modelId)\n if (!capability?.reasoning) return undefined\n\n const { supported, default: defaultEffort } = capability.reasoning\n\n if (requested === undefined || requested === null) {\n return { effort: defaultEffort, changed: false }\n }\n\n if (!isReasoningEffort(requested)) {\n return {\n effort: defaultEffort,\n changed: true,\n reason: \"unsupported-effort\",\n }\n }\n\n if (supported.includes(requested)) {\n return { effort: requested, changed: false }\n }\n\n // Pick the closest supported value by ordering low<medium<high<xhigh<max,\n // treat 'none' as below 'low'. If requested exceeds max supported, fall to\n // the highest supported; if below the lowest, fall to the lowest.\n const order: ReadonlyArray<ReasoningEffort> = [\n \"none\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n ]\n const reqIdx = order.indexOf(requested)\n const supportedSorted = [...supported].sort(\n (a, b) => order.indexOf(a) - order.indexOf(b),\n )\n const lowest = supportedSorted[0]\n const highest = supportedSorted[supportedSorted.length - 1]\n const fallback =\n reqIdx > order.indexOf(highest) ? highest\n : reqIdx < order.indexOf(lowest) ? lowest\n : (supportedSorted.find((e) => order.indexOf(e) >= reqIdx) ?? defaultEffort)\n\n return { effort: fallback, changed: true, reason: \"unsupported-effort\" }\n}\n","import fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nconst SETTINGS_DIR = path.join(os.homedir(), \".config\", \"copilot-bridge\")\nconst SETTINGS_FILE = path.join(SETTINGS_DIR, \"settings.json\")\n\nexport interface CodexSettings {\n enabled: boolean\n providerId: string\n providerName: string\n setAsDefault: boolean\n configPath: string\n}\n\nexport interface BridgeSettings {\n host: string\n port: number\n codex: CodexSettings\n}\n\nconst DEFAULT_SETTINGS: BridgeSettings = {\n host: \"127.0.0.1\",\n port: 4142,\n codex: {\n enabled: true,\n providerId: \"bridge\",\n providerName: \"Copilot Bridge\",\n setAsDefault: true,\n configPath: path.join(os.homedir(), \".codex\", \"config.toml\"),\n },\n}\n\nexport const SETTINGS_PATHS = { SETTINGS_DIR, SETTINGS_FILE }\n\nfunction deepMerge<T>(base: T, override: unknown): T {\n if (\n typeof base !== \"object\"\n || base === null\n || Array.isArray(base)\n || typeof override !== \"object\"\n || override === null\n || Array.isArray(override)\n ) {\n return (override ?? base) as T\n }\n const out: Record<string, unknown> = { ...(base as Record<string, unknown>) }\n for (const [key, value] of Object.entries(override as Record<string, unknown>)) {\n out[key] = deepMerge((base as Record<string, unknown>)[key], value)\n }\n return out as T\n}\n\nexport async function loadSettings(): Promise<BridgeSettings> {\n try {\n const raw = await fs.readFile(SETTINGS_FILE, \"utf8\")\n const parsed = JSON.parse(raw) as unknown\n return deepMerge(DEFAULT_SETTINGS, parsed)\n } catch {\n return { ...DEFAULT_SETTINGS, codex: { ...DEFAULT_SETTINGS.codex } }\n }\n}\n\nexport async function ensureSettingsFile(): Promise<BridgeSettings> {\n const settings = await loadSettings()\n try {\n await fs.access(SETTINGS_FILE)\n } catch {\n await fs.mkdir(SETTINGS_DIR, { recursive: true })\n await fs.writeFile(SETTINGS_FILE, `${JSON.stringify(settings, null, 2)}\\n`)\n }\n return settings\n}\n\nexport async function saveSettings(settings: BridgeSettings): Promise<void> {\n await fs.mkdir(SETTINGS_DIR, { recursive: true })\n await fs.writeFile(SETTINGS_FILE, `${JSON.stringify(settings, null, 2)}\\n`)\n}\n","import consola from \"consola\"\n\nimport { runtimeState } from \"./state\"\n\nconst sleep = (ms: number) =>\n new Promise<void>((resolve) => {\n setTimeout(resolve, ms)\n })\n\n/**\n * Enforces the configured rate limit window between mutating upstream calls.\n *\n * - Resolves silently if no rate limit is configured or enough time has passed.\n * - Throws a Response (HTTP 429) when the window has not elapsed and `wait` is\n * disabled, so route handlers can `c.json` it directly.\n * - When `wait` is enabled, sleeps until the window elapses, then resolves.\n */\nexport const checkRateLimit = async (): Promise<void> => {\n const { rateLimitSeconds, rateLimitWait } = runtimeState\n if (rateLimitSeconds === undefined) return\n\n const now = Date.now()\n if (!runtimeState.lastRequestTimestamp) {\n runtimeState.lastRequestTimestamp = now\n return\n }\n\n const elapsed = (now - runtimeState.lastRequestTimestamp) / 1000\n if (elapsed > rateLimitSeconds) {\n runtimeState.lastRequestTimestamp = now\n return\n }\n\n const waitSeconds = Math.ceil(rateLimitSeconds - elapsed)\n\n if (!rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitSeconds} more seconds.`,\n )\n throw new RateLimitError(waitSeconds)\n }\n\n consola.warn(\n `Rate limit reached. Waiting ${waitSeconds}s before proceeding...`,\n )\n await sleep(waitSeconds * 1000)\n runtimeState.lastRequestTimestamp = Date.now()\n}\n\nexport class RateLimitError extends Error {\n readonly waitSeconds: number\n\n constructor(waitSeconds: number) {\n super(`Rate limit exceeded. Try again in ${waitSeconds}s.`)\n this.name = \"RateLimitError\"\n this.waitSeconds = waitSeconds\n }\n}\n","import fs from \"node:fs/promises\"\nimport os from \"node:os\"\nimport path from \"node:path\"\n\nimport consola from \"consola\"\n\ninterface ClaudeSettingsFile {\n env?: Record<string, unknown>\n}\n\nconst getClaudeSettingsPaths = (): Array<string> => {\n const cwd = process.cwd()\n const home = process.env.HOME ?? os.homedir()\n\n return [\n path.join(home, \".claude\", \"settings.json\"),\n path.join(cwd, \".claude\", \"settings.json\"),\n path.join(cwd, \".claude\", \"settings.local.json\"),\n ]\n}\n\nconst readClaudeSettingsFile = async (\n filePath: string,\n): Promise<ClaudeSettingsFile | undefined> => {\n try {\n const content = await fs.readFile(filePath, \"utf8\")\n return JSON.parse(content) as ClaudeSettingsFile\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return undefined\n }\n consola.warn(`Failed to read Claude settings from ${filePath}:`, error)\n return undefined\n }\n}\n\nexport const getClaudeSettingsEnv = async (): Promise<\n Record<string, string>\n> => {\n const merged: Record<string, string> = {}\n\n for (const filePath of getClaudeSettingsPaths()) {\n const settings = await readClaudeSettingsFile(filePath)\n if (!settings?.env) continue\n\n for (const [key, value] of Object.entries(settings.env)) {\n if (typeof value === \"string\") merged[key] = value\n }\n }\n\n return merged\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type {\n ChatCompletionChunk,\n ChatCompletionResponse,\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n} from \"~/providers/copilot/chat-types\"\n\nimport { sanitizeUserIdentifier } from \"./create-chat-completions\"\n\nexport interface ResponseStreamEventMessage {\n data?: string\n event?: string\n}\n\nexport interface ResponsesApiResponse {\n id: string\n created_at: number\n model: string\n output: Array<ResponsesOutputItem>\n usage?: {\n input_tokens: number\n input_tokens_details?: {\n cached_tokens?: number\n }\n output_tokens: number\n output_tokens_details?: {\n reasoning_tokens?: number\n }\n total_tokens: number\n }\n incomplete_details?: {\n reason?: string | null\n } | null\n}\n\nexport type ResponsesReasoningEffort =\n | \"none\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"max\"\n | \"xhigh\"\n\ntype ResponsesInput = string | Array<ResponsesInputItem>\n\ntype ResponsesInputItem =\n | ResponsesMessageInput\n | ResponsesFunctionCallInput\n | ResponsesFunctionCallOutputInput\n\ntype ResponsesMessageInput = {\n role: \"user\" | \"assistant\" | \"system\" | \"developer\"\n content: string | Array<ResponsesInputContentPart>\n}\n\ntype ResponsesInputContentPart =\n | {\n type: \"input_text\"\n text: string\n }\n | {\n type: \"input_image\"\n image_url: string\n detail: \"low\" | \"high\" | \"auto\"\n }\n\ntype ResponsesFunctionCallInput = {\n type: \"function_call\"\n call_id: string\n name: string\n arguments: string\n}\n\ntype ResponsesFunctionCallOutputInput = {\n type: \"function_call_output\"\n call_id: string\n output: string\n}\n\ntype ResponsesToolChoice =\n | \"none\"\n | \"auto\"\n | \"required\"\n | { type: \"function\"; name: string }\n\nexport interface ResponsesRequestPayload {\n model: string\n input: ResponsesInput\n stream?: boolean | null\n max_output_tokens?: number | null\n temperature?: number | null\n top_p?: number | null\n user?: string | null\n reasoning?: {\n effort: ResponsesReasoningEffort\n }\n tools?: Array<ResponsesTool>\n tool_choice?: ResponsesToolChoice | null\n text?: {\n format: {\n type: \"json_object\"\n }\n }\n}\n\ninterface ResponsesTool {\n type: \"function\"\n name: string\n description?: string\n parameters: Record<string, unknown>\n}\n\ntype ResponsesOutputItem =\n | ResponsesMessageOutputItem\n | ResponsesFunctionCallOutputItem\n | ResponsesReasoningOutputItem\n\ninterface ResponsesMessageOutputItem {\n type: \"message\"\n role: \"assistant\"\n content: Array<ResponsesMessageContentPart>\n}\n\ninterface ResponsesMessageContentPart {\n type: \"output_text\"\n text: string\n}\n\ninterface ResponsesFunctionCallOutputItem {\n type: \"function_call\"\n call_id: string\n name: string\n arguments: string\n}\n\ninterface ResponsesReasoningOutputItem {\n type: \"reasoning\"\n}\n\ninterface ResponsesStreamEnvelope {\n type: string\n response?: {\n id: string\n created_at: number\n model: string\n usage?: ResponsesApiResponse[\"usage\"]\n output?: Array<ResponsesOutputItem>\n incomplete_details?: ResponsesApiResponse[\"incomplete_details\"]\n }\n item?:\n | Partial<ResponsesMessageOutputItem>\n | Partial<ResponsesFunctionCallOutputItem>\n output_index?: number\n delta?: string\n}\n\ninterface ResponseTranslationState {\n responseId: string\n createdAt: number\n model: string\n started: boolean\n}\n\ninterface CreateChunkOptions {\n delta: ChatCompletionChunk[\"choices\"][0][\"delta\"]\n finishReason?: ChatCompletionChunk[\"choices\"][0][\"finish_reason\"]\n usage?: ChatCompletionChunk[\"usage\"]\n}\n\nconst RESPONSES_ONLY_MODEL_PATTERN = /^(?:gpt-5\\.3-codex|gpt-5\\.4-mini)(?:-|$)/i\n\nexport function shouldUseResponsesApiForModel(model: string): boolean {\n return RESPONSES_ONLY_MODEL_PATTERN.test(model)\n}\n\nexport function buildResponsesRequestPayload(\n payload: ChatCompletionsPayload,\n reasoningEffort: ResponsesReasoningEffort | undefined,\n): ResponsesRequestPayload {\n return {\n model: payload.model,\n input: translateMessagesToResponsesInput(payload.messages),\n stream: payload.stream,\n max_output_tokens: payload.max_tokens,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: sanitizeUserIdentifier(payload.user),\n tools: translateTools(payload.tools),\n tool_choice: translateToolChoice(payload.tool_choice),\n reasoning: reasoningEffort ? { effort: reasoningEffort } : undefined,\n text:\n payload.response_format?.type === \"json_object\" ?\n { format: { type: \"json_object\" } }\n : undefined,\n }\n}\n\nexport function translateResponsesToChatCompletion(\n response: ResponsesApiResponse,\n): ChatCompletionResponse {\n const assistantMessages = response.output.filter(\n (item): item is ResponsesMessageOutputItem => item.type === \"message\",\n )\n const functionCalls = response.output.filter(\n (item): item is ResponsesFunctionCallOutputItem =>\n item.type === \"function_call\",\n )\n\n const content = assistantMessages\n .flatMap((item) => item.content)\n .map((part) => part.text)\n .join(\"\")\n\n return {\n id: response.id,\n object: \"chat.completion\",\n created: response.created_at,\n model: response.model,\n choices: [\n {\n index: 0,\n message: {\n role: \"assistant\",\n content: content || null,\n ...(functionCalls.length > 0 && {\n tool_calls: functionCalls.map((toolCall) => ({\n id: toolCall.call_id,\n type: \"function\" as const,\n function: {\n name: toolCall.name,\n arguments: toolCall.arguments,\n },\n })),\n }),\n },\n logprobs: null,\n finish_reason: getFinishReason(response, functionCalls.length > 0),\n },\n ],\n usage: translateUsage(response.usage),\n }\n}\n\nexport async function* translateResponsesStreamToChatCompletionStream(\n responseStream: AsyncIterable<ResponseStreamEventMessage>,\n): AsyncGenerator<ResponseStreamEventMessage> {\n const state: ResponseTranslationState = {\n responseId: randomUUID(),\n createdAt: Math.floor(Date.now() / 1000),\n model: \"\",\n started: false,\n }\n\n for await (const rawEvent of responseStream) {\n if (!rawEvent.data || rawEvent.data === \"[DONE]\") {\n continue\n }\n\n const event = JSON.parse(rawEvent.data) as ResponsesStreamEnvelope\n\n if (event.response) {\n state.responseId = event.response.id\n state.createdAt = event.response.created_at\n state.model = event.response.model\n }\n\n if (event.type === \"response.output_item.added\") {\n const chunk = handleOutputItemAdded(state, event)\n if (chunk) {\n yield chunk\n }\n continue\n }\n\n if (event.type === \"response.output_text.delta\") {\n yield createRoleChunk(state)\n yield createChunk(state, { delta: { content: event.delta } })\n continue\n }\n\n if (event.type === \"response.function_call_arguments.delta\") {\n if (event.output_index === undefined) {\n continue\n }\n\n yield createRoleChunk(state)\n yield createChunk(state, {\n delta: {\n tool_calls: [\n {\n index: event.output_index,\n type: \"function\",\n function: {\n arguments: event.delta ?? \"\",\n },\n },\n ],\n },\n })\n continue\n }\n\n if (event.type === \"response.completed\") {\n if (!event.response) {\n continue\n }\n\n yield createChunk(\n {\n ...state,\n responseId: event.response.id,\n createdAt: event.response.created_at,\n model: event.response.model,\n },\n {\n delta: {},\n finishReason: getFinishReason(\n {\n output: event.response.output ?? [],\n incomplete_details: event.response.incomplete_details,\n },\n (event.response.output ?? []).some(\n (item) => item.type === \"function_call\",\n ),\n ),\n usage: translateUsage(event.response.usage),\n },\n )\n yield { data: \"[DONE]\" }\n return\n }\n }\n}\n\nfunction handleOutputItemAdded(\n state: ResponseTranslationState,\n event: ResponsesStreamEnvelope,\n): ResponseStreamEventMessage | undefined {\n if (event.item?.type === \"message\") {\n return createRoleChunk(state)\n }\n\n if (\n event.item?.type === \"function_call\"\n && event.output_index !== undefined\n ) {\n state.started = true\n return createChunk(state, {\n delta: {\n role: \"assistant\",\n tool_calls: [\n {\n index: event.output_index,\n id: event.item.call_id,\n type: \"function\",\n function: {\n name: event.item.name,\n arguments: event.item.arguments ?? \"\",\n },\n },\n ],\n },\n })\n }\n\n return undefined\n}\n\nfunction createRoleChunk(\n state: ResponseTranslationState,\n): ResponseStreamEventMessage {\n if (state.started) {\n return { data: \"\" }\n }\n\n state.started = true\n return createChunk(state, { delta: { role: \"assistant\" } })\n}\n\nfunction createChunk(\n state: ResponseTranslationState,\n { delta, finishReason = null, usage }: CreateChunkOptions,\n): ResponseStreamEventMessage {\n return {\n data: JSON.stringify({\n id: state.responseId,\n object: \"chat.completion.chunk\",\n created: state.createdAt,\n model: state.model,\n choices: [\n {\n index: 0,\n delta,\n finish_reason: finishReason,\n logprobs: null,\n },\n ],\n usage,\n } satisfies ChatCompletionChunk),\n }\n}\n\nfunction translateMessagesToResponsesInput(\n messages: Array<Message>,\n): ResponsesInput {\n const items = messages.flatMap((message) => translateMessage(message))\n\n if (\n items.length === 1\n && \"role\" in items[0]\n && items[0].role === \"user\"\n && typeof items[0].content === \"string\"\n ) {\n return items[0].content\n }\n\n return items\n}\n\nfunction translateMessage(message: Message): Array<ResponsesInputItem> {\n if (message.role === \"tool\") {\n return [\n {\n type: \"function_call_output\",\n call_id: message.tool_call_id ?? \"\",\n output: stringifyToolOutput(message.content),\n },\n ]\n }\n\n const translated: Array<ResponsesInputItem> = []\n\n if (hasContent(message.content)) {\n translated.push({\n role: message.role,\n content: translateContent(message.content),\n })\n }\n\n if (message.role === \"assistant\" && message.tool_calls) {\n translated.push(\n ...message.tool_calls.map((toolCall) => ({\n type: \"function_call\" as const,\n call_id: toolCall.id,\n name: toolCall.function.name,\n arguments: toolCall.function.arguments,\n })),\n )\n }\n\n return translated\n}\n\nfunction hasContent(content: Message[\"content\"]): boolean {\n if (content === null) {\n return false\n }\n\n if (typeof content === \"string\") {\n return content.length > 0\n }\n\n return content.length > 0\n}\n\nfunction translateContent(\n content: Message[\"content\"],\n): ResponsesMessageInput[\"content\"] {\n if (typeof content === \"string\") {\n return content\n }\n\n if (!content || content.length === 0) {\n return \"\"\n }\n\n return content.map((part) => translateContentPart(part))\n}\n\nfunction translateContentPart(part: ContentPart): ResponsesInputContentPart {\n if (part.type === \"text\") {\n return {\n type: \"input_text\",\n text: part.text,\n }\n }\n\n return {\n type: \"input_image\",\n image_url: part.image_url.url,\n detail: part.image_url.detail ?? \"auto\",\n }\n}\n\nfunction stringifyToolOutput(content: Message[\"content\"]): string {\n if (typeof content === \"string\") {\n return content\n }\n\n if (!content) {\n return \"\"\n }\n\n const text = content\n .filter(\n (part): part is Extract<ContentPart, { type: \"text\" }> =>\n part.type === \"text\",\n )\n .map((part) => part.text)\n .join(\"\\n\\n\")\n\n return text || JSON.stringify(content)\n}\n\nfunction translateTools(\n tools: Array<Tool> | null | undefined,\n): Array<ResponsesTool> | undefined {\n if (!tools) {\n return undefined\n }\n\n return tools.map((tool) => ({\n type: \"function\",\n name: tool.function.name,\n description: tool.function.description,\n parameters: tool.function.parameters,\n }))\n}\n\nfunction translateToolChoice(\n toolChoice: ChatCompletionsPayload[\"tool_choice\"],\n): ResponsesToolChoice | undefined {\n if (!toolChoice) {\n return undefined\n }\n\n if (typeof toolChoice === \"string\") {\n return toolChoice\n }\n\n return {\n type: \"function\",\n name: toolChoice.function.name,\n }\n}\n\nfunction translateUsage(\n usage: ResponsesApiResponse[\"usage\"] | undefined,\n): ChatCompletionResponse[\"usage\"] | undefined {\n if (!usage) {\n return undefined\n }\n\n return {\n prompt_tokens: usage.input_tokens,\n completion_tokens: usage.output_tokens,\n total_tokens: usage.total_tokens,\n ...(usage.input_tokens_details?.cached_tokens !== undefined && {\n prompt_tokens_details: {\n cached_tokens: usage.input_tokens_details.cached_tokens,\n },\n }),\n }\n}\n\nfunction getFinishReason(\n response: Pick<ResponsesApiResponse, \"output\" | \"incomplete_details\">,\n hasFunctionCalls: boolean,\n): \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" {\n if (hasFunctionCalls) {\n return \"tool_calls\"\n }\n\n if (response.incomplete_details?.reason?.includes(\"max_output_tokens\")) {\n return \"length\"\n }\n\n return \"stop\"\n}\n","import consola from \"consola\"\nimport { events } from \"fetch-event-stream\"\n\nimport type { BridgeConfig } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { getClaudeSettingsEnv } from \"~/lib/claude-settings\"\nimport { fetchCopilot, getCopilotProviderContext } from \"~/providers/copilot/client\"\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n} from \"~/providers/copilot/chat-types\"\n\nimport {\n buildResponsesRequestPayload,\n shouldUseResponsesApiForModel,\n translateResponsesStreamToChatCompletionStream,\n translateResponsesToChatCompletion,\n type ResponsesApiResponse,\n type ResponsesReasoningEffort,\n} from \"./responses\"\n\nconst usesMaxCompletionTokens = (modelId: string): boolean =>\n modelId.startsWith(\"gpt-5\")\n\nconst isClaudeOpus47Model = (modelId: string): boolean =>\n modelId === \"claude-opus-4.7\"\n\ntype ClaudeOpus47Effort = NonNullable<\n NonNullable<ChatCompletionsPayload[\"output_config\"]>[\"effort\"]\n>\n\nconst MAX_USER_LENGTH = 64\n\nconst defaultReasoningEffort = (\n modelId: string,\n): ChatCompletionsPayload[\"reasoning_effort\"] =>\n usesMaxCompletionTokens(modelId) ? \"medium\" : undefined\n\nconst getAllowedReasoningEfforts = (\n modelId: string,\n): Array<\n Exclude<ChatCompletionsPayload[\"reasoning_effort\"], null | undefined>\n> => {\n if (modelId.startsWith(\"gpt-5.5\")) {\n return [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"]\n }\n\n if (modelId.startsWith(\"gpt-5.4-mini\")) {\n return [\"none\", \"low\", \"medium\"]\n }\n\n if (modelId.startsWith(\"gpt-5.4\") || modelId.startsWith(\"gpt-5.3-codex\")) {\n return [\"low\", \"medium\", \"high\", \"xhigh\"]\n }\n\n if (usesMaxCompletionTokens(modelId)) {\n return [\"low\", \"medium\", \"high\", \"xhigh\"]\n }\n\n return []\n}\n\nexport const sanitizeReasoningEffortForModel = (\n modelId: string,\n reasoningEffort: ChatCompletionsPayload[\"reasoning_effort\"],\n): ChatCompletionsPayload[\"reasoning_effort\"] => {\n if (!reasoningEffort) {\n return undefined\n }\n\n return getAllowedReasoningEfforts(modelId).includes(reasoningEffort) ?\n reasoningEffort\n : undefined\n}\n\nconst normalizeReasoningEffort = (\n value: string | undefined | null,\n): ChatCompletionsPayload[\"reasoning_effort\"] => {\n switch (value?.toLowerCase()) {\n case \"none\": {\n return \"none\"\n }\n case \"low\": {\n return \"low\"\n }\n case \"medium\": {\n return \"medium\"\n }\n case \"high\": {\n return \"high\"\n }\n case \"xhigh\": {\n return \"xhigh\"\n }\n case \"max\": {\n return \"max\"\n }\n default: {\n return undefined\n }\n }\n}\n\nconst normalizeClaudeOpus47Effort = (\n value: string | undefined | null,\n): ClaudeOpus47Effort | undefined => {\n switch (value?.toLowerCase()) {\n case \"low\": {\n return \"low\"\n }\n case \"medium\": {\n return \"medium\"\n }\n case \"high\": {\n return \"high\"\n }\n case \"xhigh\": {\n return \"xhigh\"\n }\n case \"max\": {\n return \"max\"\n }\n default: {\n return undefined\n }\n }\n}\n\nconst getRequestedReasoningEffort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n): ChatCompletionsPayload[\"reasoning_effort\"] => {\n const requestedReasoningEffort =\n payload.reasoning_effort\n ?? normalizeReasoningEffort(process.env.COPILOT_REASONING_EFFORT)\n ?? normalizeReasoningEffort(claudeSettingsEnv.COPILOT_REASONING_EFFORT)\n\n return (\n sanitizeReasoningEffortForModel(payload.model, requestedReasoningEffort)\n ?? defaultReasoningEffort(payload.model)\n )\n}\n\nconst getRequestedClaudeOpus47Effort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n): ClaudeOpus47Effort | undefined => {\n if (!isClaudeOpus47Model(payload.model)) {\n return undefined\n }\n\n return (\n payload.output_config?.effort\n ?? normalizeClaudeOpus47Effort(payload.reasoning_effort)\n ?? normalizeClaudeOpus47Effort(process.env.COPILOT_REASONING_EFFORT)\n ?? normalizeClaudeOpus47Effort(claudeSettingsEnv.COPILOT_REASONING_EFFORT)\n )\n}\n\nexport const sanitizeUserIdentifier = (\n user: string | null | undefined,\n): string | undefined => {\n if (!user) {\n return undefined\n }\n\n return user.slice(0, MAX_USER_LENGTH)\n}\n\ntype ChatCompletionsRequestPayload = Omit<\n ChatCompletionsPayload,\n \"max_tokens\"\n> & {\n max_tokens?: number | null\n max_completion_tokens?: number | null\n}\n\nconst buildRequestPayload = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n): ChatCompletionsRequestPayload => {\n const requestedReasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n )\n const requestedClaudeOpus47Effort = getRequestedClaudeOpus47Effort(\n payload,\n claudeSettingsEnv,\n )\n\n const reasoningEffort =\n (\n usesMaxCompletionTokens(payload.model)\n && payload.tools !== null\n && payload.tools !== undefined\n && payload.tools.length > 0\n ) ?\n undefined\n : requestedReasoningEffort\n\n if (\n !usesMaxCompletionTokens(payload.model)\n || payload.max_tokens === null\n || payload.max_tokens === undefined\n ) {\n const sanitizedPayload = {\n ...payload,\n output_config:\n requestedClaudeOpus47Effort ?\n {\n ...payload.output_config,\n effort: requestedClaudeOpus47Effort,\n }\n : payload.output_config,\n reasoning_effort:\n isClaudeOpus47Model(payload.model) ? undefined : (\n payload.reasoning_effort\n ),\n user: sanitizeUserIdentifier(payload.user),\n }\n\n return reasoningEffort === null || reasoningEffort === undefined ?\n sanitizedPayload\n : { ...sanitizedPayload, reasoning_effort: reasoningEffort }\n }\n\n return {\n ...payload,\n max_tokens: undefined,\n max_completion_tokens: payload.max_tokens,\n reasoning_effort: reasoningEffort,\n user: sanitizeUserIdentifier(payload.user),\n }\n}\n\nconst isAgentInitiator = (\n messages: ChatCompletionsPayload[\"messages\"],\n): \"agent\" | \"user\" =>\n messages.some((msg) => msg.role === \"assistant\" || msg.role === \"tool\") ?\n \"agent\"\n : \"user\"\n\nconst messagesIncludeImage = (\n messages: ChatCompletionsPayload[\"messages\"],\n): boolean =>\n messages.some(\n (msg) =>\n typeof msg.content !== \"string\"\n && msg.content?.some((part) => part.type === \"image_url\"),\n )\n\nexport const createChatCompletions = async (\n config: BridgeConfig,\n payload: ChatCompletionsPayload,\n) => {\n const provider = getCopilotProviderContext(config)\n const enableVision = messagesIncludeImage(payload.messages)\n const initiator = isAgentInitiator(payload.messages)\n const claudeSettingsEnv = await getClaudeSettingsEnv()\n const requestPayload = buildRequestPayload(payload, claudeSettingsEnv)\n\n if (shouldUseResponsesApiForModel(payload.model)) {\n return createResponses(provider, payload, claudeSettingsEnv, {\n vision: enableVision,\n initiator,\n })\n }\n\n const response = await fetchCopilot(\n provider,\n \"/chat/completions\",\n {\n method: \"POST\",\n headers: {\n accept: payload.stream ? \"text/event-stream\" : \"application/json\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(requestPayload),\n },\n { vision: enableVision, initiator },\n )\n\n if (!response.ok) {\n if (await shouldRetryWithResponses(response)) {\n return createResponses(provider, payload, claudeSettingsEnv, {\n vision: enableVision,\n initiator,\n })\n }\n\n consola.error(\"Failed to create chat completions\", response)\n throw new HTTPError(\"Failed to create chat completions\", response)\n }\n\n if (payload.stream) {\n return events(response)\n }\n\n return (await response.json()) as ChatCompletionResponse\n}\n\nasync function createResponses(\n provider: ReturnType<typeof getCopilotProviderContext>,\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n options: { vision: boolean; initiator: \"agent\" | \"user\" },\n) {\n const reasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n ) as ResponsesReasoningEffort | undefined\n\n const response = await fetchCopilot(\n provider,\n \"/responses\",\n {\n method: \"POST\",\n headers: {\n accept: payload.stream ? \"text/event-stream\" : \"application/json\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(\n buildResponsesRequestPayload(payload, reasoningEffort),\n ),\n },\n { vision: options.vision, initiator: options.initiator },\n )\n\n if (!response.ok) {\n consola.error(\"Failed to create responses\", response)\n throw new HTTPError(\"Failed to create responses\", response)\n }\n\n if (payload.stream) {\n return translateResponsesStreamToChatCompletionStream(events(response))\n }\n\n return translateResponsesToChatCompletion(\n (await response.json()) as ResponsesApiResponse,\n )\n}\n\nasync function shouldRetryWithResponses(response: Response): Promise<boolean> {\n try {\n const errorBody = (await response.clone().json()) as {\n error?: {\n code?: string\n }\n }\n\n return errorBody.error?.code === \"unsupported_api_for_model\"\n } catch {\n return false\n }\n}\n","import { Hono } from \"hono\"\nimport { streamSSE, type SSEMessage } from \"hono/streaming\"\n\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { BridgeNotImplementedError, HTTPError } from \"~/lib/error\"\nimport { checkRateLimit, RateLimitError } from \"~/lib/rate-limit\"\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n} from \"~/providers/copilot/chat-types\"\nimport { createChatCompletions } from \"~/services/copilot/create-chat-completions\"\n\nexport const chatCompletionRoutes = new Hono<BridgeEnv>()\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse =>\n typeof response === \"object\"\n && response !== null\n && Object.hasOwn(response, \"choices\")\n\nchatCompletionRoutes.post(\"/\", async (c) => {\n try {\n await checkRateLimit()\n const payload = await c.req.json<ChatCompletionsPayload>()\n const response = await createChatCompletions(c.var.config, payload)\n\n if (isNonStreaming(response)) {\n return c.json(response)\n }\n\n return streamSSE(c, async (stream) => {\n for await (const chunk of response) {\n await stream.writeSSE(chunk as SSEMessage)\n }\n })\n } catch (error) {\n if (error instanceof RateLimitError) {\n return c.json({ error: { message: error.message } }, 429)\n }\n if (error instanceof BridgeNotImplementedError) {\n return c.json(\n { error: { type: error.name, message: error.message } },\n 501,\n )\n }\n if (error instanceof HTTPError) {\n const text = await error.response.text().catch(() => \"\")\n return new Response(text, {\n status: error.response.status,\n headers: {\n \"content-type\":\n error.response.headers.get(\"content-type\") ?? \"application/json\",\n },\n })\n }\n throw error\n }\n})\n","import type { BridgeConfig } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { fetchCopilot, getCopilotProviderContext } from \"./client\"\n\nexport interface EmbeddingRequest {\n input: string | Array<string>\n model: string\n}\n\nexport interface Embedding {\n object: string\n embedding: Array<number>\n index: number\n}\n\nexport interface EmbeddingResponse {\n object: string\n data: Array<Embedding>\n model: string\n usage: {\n prompt_tokens: number\n total_tokens: number\n }\n}\n\nexport const createEmbeddings = async (\n config: BridgeConfig,\n payload: EmbeddingRequest,\n): Promise<EmbeddingResponse> => {\n const provider = getCopilotProviderContext(config)\n const response = await fetchCopilot(provider, \"/embeddings\", {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to create embeddings\", response)\n }\n\n return (await response.json()) as EmbeddingResponse\n}\n","import { Hono } from \"hono\"\n\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { checkRateLimit, RateLimitError } from \"~/lib/rate-limit\"\nimport {\n createEmbeddings,\n type EmbeddingRequest,\n} from \"~/providers/copilot/create-embeddings\"\n\nexport const embeddingRoutes = new Hono<BridgeEnv>()\n\nembeddingRoutes.post(\"/\", async (c) => {\n try {\n await checkRateLimit()\n const payload = await c.req.json<EmbeddingRequest>()\n const response = await createEmbeddings(c.var.config, payload)\n return c.json(response)\n } catch (error) {\n if (error instanceof RateLimitError) {\n return c.json({ error: { message: error.message } }, 429)\n }\n if (error instanceof HTTPError) {\n const text = await error.response.text().catch(() => \"\")\n return new Response(text, {\n status: error.response.status,\n headers: {\n \"content-type\":\n error.response.headers.get(\"content-type\") ?? \"application/json\",\n },\n })\n }\n throw error\n }\n})\n","import type { Model } from \"~/providers/copilot/get-models\"\n\nimport { runtimeState } from \"./state\"\n\nconst normalizeModelId = (modelId: string): string =>\n modelId.trim().toLowerCase().replaceAll(/[\\s._-]+/g, \"\")\n\nconst stripSnapshotSuffix = (modelId: string): string => {\n const id = modelId.trim().toLowerCase().replace(/\\[1m\\]$/, \"\")\n\n if (id.startsWith(\"claude-sonnet-4-\")) {\n return \"claude-sonnet-4\"\n }\n\n if (/^claude-opus-4-7-\\d{8}$/.test(id)) {\n return \"claude-opus-4.7\"\n }\n\n if (id.startsWith(\"claude-opus-4-\")) {\n return \"claude-opus-4\"\n }\n\n return id\n}\n\nconst getAliasCandidates = (modelId: string): Array<string> => {\n const canonicalModelId = stripSnapshotSuffix(modelId)\n const aliases = new Set<string>([canonicalModelId])\n\n const familyMatch = canonicalModelId.match(\n /^[a-z]+(?:-[a-z]+)*-\\d+(?:\\.\\d+)?/,\n )\n if (familyMatch) {\n aliases.add(familyMatch[0])\n aliases.add(familyMatch[0].replace(/\\.\\d+$/, \"\"))\n }\n\n if (/^gpt-5(?:[.-]\\d+)?$/i.test(canonicalModelId)) {\n aliases.add(\"gpt-5\")\n }\n\n return [...aliases]\n}\n\nconst scoreModelCandidate = (model: Model): number => {\n let score = 0\n\n if (model.model_picker_enabled) {\n score += 20\n }\n\n if (!model.preview) {\n score += 10\n }\n\n if (/mini|nano|fast|flash|haiku/i.test(model.id)) {\n score -= 15\n }\n\n return score - model.id.length / 1000\n}\n\nconst pickBestModel = (models: Array<Model>): Model | undefined =>\n [...models].sort(\n (left, right) => scoreModelCandidate(right) - scoreModelCandidate(left),\n )[0]\n\nconst getBestPrefixMatches = (\n models: Array<Model>,\n aliasCandidates: Array<string>,\n): Array<Model> => {\n let bestMatchLength = 0\n const matches: Array<Model> = []\n\n for (const model of models) {\n const normalizedModelId = normalizeModelId(model.id)\n const matchedAliasLength = Math.max(\n 0,\n ...aliasCandidates.map((candidate) => {\n const normalizedCandidate = normalizeModelId(candidate)\n return normalizedCandidate.length >= 4\n && normalizedModelId.startsWith(normalizedCandidate)\n ? normalizedCandidate.length\n : 0\n }),\n )\n\n if (matchedAliasLength === 0) continue\n\n if (matchedAliasLength > bestMatchLength) {\n bestMatchLength = matchedAliasLength\n matches.length = 0\n matches.push(model)\n continue\n }\n\n if (matchedAliasLength === bestMatchLength) {\n matches.push(model)\n }\n }\n\n return matches\n}\n\nexport const resolveModel = (\n requestedModelId: string,\n models: Array<Model> | undefined = runtimeState.models?.data,\n): Model | undefined => {\n if (!models || models.length === 0) {\n return undefined\n }\n\n const exactMatch = models.find((model) => model.id === requestedModelId)\n if (exactMatch) return exactMatch\n\n const aliasCandidates = getAliasCandidates(requestedModelId)\n const normalizedAliases = new Set(\n aliasCandidates.map((candidate) => normalizeModelId(candidate)),\n )\n\n const normalizedExactMatches = models.filter((model) =>\n normalizedAliases.has(normalizeModelId(model.id)),\n )\n if (normalizedExactMatches.length > 0) {\n return pickBestModel(normalizedExactMatches)\n }\n\n const familyPrefixMatches = getBestPrefixMatches(models, aliasCandidates)\n return pickBestModel(familyPrefixMatches)\n}\n\nexport const resolveUpstreamModelId = (\n requestedModelId: string,\n models: Array<Model> | undefined = runtimeState.models?.data,\n): string =>\n resolveModel(requestedModelId, models)?.id ?? stripSnapshotSuffix(requestedModelId)\n","import type { AnthropicResponse } from \"~/bridges/claude/anthropic-types\"\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null,\n): AnthropicResponse[\"stop_reason\"] {\n if (finishReason === null) {\n return null\n }\n\n const stopReasonMap = {\n stop: \"end_turn\",\n length: \"max_tokens\",\n tool_calls: \"tool_use\",\n content_filter: \"end_turn\",\n } as const\n\n return stopReasonMap[finishReason]\n}\n","import { resolveUpstreamModelId } from \"~/lib/models-resolver\"\nimport { sanitizeReasoningEffortForModel } from \"~/services/copilot/create-chat-completions\"\nimport type {\n ChatCompletionResponse,\n ChatCompletionsPayload,\n ContentPart,\n Message,\n TextPart,\n Tool,\n ToolCall,\n} from \"~/providers/copilot/chat-types\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicResponse,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"~/bridges/claude/anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"~/bridges/claude/utils\"\n\nconst normalizeClaudeModelAlias = (model: string): string => {\n const normalized = model.trim().toLowerCase().replace(/\\[1m\\]$/, \"\")\n\n if (/^claude-(opus|sonnet|haiku)-\\d-\\d(?:-1m)?$/.test(normalized)) {\n return normalized.replace(\n /^claude-(opus|sonnet|haiku)-(\\d)-(\\d)(-1m)?$/,\n \"claude-$1-$2.$3$4\",\n )\n }\n\n if (/^claude-opus-4-7-\\d{8}$/.test(normalized)) {\n return \"claude-opus-4.7\"\n }\n\n return normalized\n}\n\nfunction translateModelName(model: string): string {\n return resolveUpstreamModelId(normalizeClaudeModelAlias(model))\n}\n\nfunction isClaudeModel(modelId: string): boolean {\n return modelId.startsWith(\"claude-\")\n}\n\nfunction isClaudeOpus47Model(modelId: string): boolean {\n return modelId === \"claude-opus-4.7\"\n}\n\ntype ClaudeOpus47Effort = NonNullable<\n NonNullable<ChatCompletionsPayload[\"output_config\"]>[\"effort\"]\n>\n\nfunction normalizeClaudeEffort(\n value: string | undefined,\n): ClaudeOpus47Effort | undefined {\n switch (value?.toLowerCase()) {\n case \"low\": {\n return \"low\"\n }\n case \"medium\": {\n return \"medium\"\n }\n case \"high\": {\n return \"high\"\n }\n case \"xhigh\": {\n return \"xhigh\"\n }\n case \"max\": {\n return \"max\"\n }\n default: {\n return undefined\n }\n }\n}\n\nfunction getClaudeOpus47Effort(\n payload: AnthropicMessagesPayload,\n): ClaudeOpus47Effort | undefined {\n const explicitEffort = normalizeClaudeEffort(payload.reasoning_effort)\n if (explicitEffort) {\n return explicitEffort\n }\n\n if (payload.thinking?.type !== \"enabled\") {\n return undefined\n }\n\n const budgetTokens = payload.thinking.budget_tokens\n if (budgetTokens === undefined) {\n return \"medium\"\n }\n\n if (budgetTokens <= 2_048) {\n return \"low\"\n }\n\n if (budgetTokens <= 8_192) {\n return \"medium\"\n }\n\n if (budgetTokens <= 24_576) {\n return \"high\"\n }\n\n return \"xhigh\"\n}\n\nfunction translateThinking(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload[\"thinking\"] {\n const modelId = translateModelName(payload.model)\n\n if (!isClaudeOpus47Model(modelId)) {\n return undefined\n }\n\n if (payload.thinking?.type === \"adaptive\") {\n return { type: \"adaptive\" }\n }\n\n return payload.thinking?.type === \"enabled\" ? { type: \"adaptive\" } : undefined\n}\n\nfunction translateOutputConfig(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload[\"output_config\"] {\n const modelId = translateModelName(payload.model)\n\n if (!isClaudeOpus47Model(modelId)) {\n return undefined\n }\n\n const effort = getClaudeOpus47Effort(payload)\n\n return effort ? { effort } : undefined\n}\n\nfunction normalizeReasoningEffort(\n value: string,\n): ChatCompletionsPayload[\"reasoning_effort\"] {\n switch (value.toLowerCase()) {\n case \"none\": {\n return \"none\"\n }\n case \"low\": {\n return \"low\"\n }\n case \"medium\": {\n return \"medium\"\n }\n case \"high\": {\n return \"high\"\n }\n case \"xhigh\": {\n return \"xhigh\"\n }\n case \"max\": {\n return \"max\"\n }\n default: {\n return undefined\n }\n }\n}\n\nfunction translateReasoningEffort(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload[\"reasoning_effort\"] {\n const modelId = translateModelName(payload.model)\n\n if (isClaudeModel(modelId)) {\n return undefined\n }\n\n if (payload.reasoning_effort) {\n const requested = normalizeReasoningEffort(payload.reasoning_effort)\n return sanitizeReasoningEffortForModel(modelId, requested)\n }\n\n if (payload.thinking?.type !== \"enabled\") {\n return undefined\n }\n\n const budgetTokens = payload.thinking.budget_tokens\n if (budgetTokens === undefined) {\n return sanitizeReasoningEffortForModel(modelId, \"medium\")\n }\n\n if (budgetTokens <= 2_048) {\n return sanitizeReasoningEffortForModel(modelId, \"low\")\n }\n\n if (budgetTokens <= 8_192) {\n return sanitizeReasoningEffortForModel(modelId, \"medium\")\n }\n\n if (budgetTokens <= 24_576) {\n return sanitizeReasoningEffortForModel(modelId, \"high\")\n }\n\n return sanitizeReasoningEffortForModel(modelId, \"xhigh\")\n}\n\nexport function translateToOpenAI(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload {\n const model = translateModelName(payload.model)\n\n return {\n model,\n messages: translateAnthropicMessagesToOpenAI(payload.messages, payload.system),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n thinking: translateThinking(payload),\n output_config: translateOutputConfig(payload),\n reasoning_effort: translateReasoningEffort(payload),\n user: payload.metadata?.user_id,\n tools: translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),\n }\n}\n\nfunction translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n const systemMessages = handleSystemPrompt(system)\n const otherMessages = anthropicMessages.flatMap((message) =>\n message.role === \"user\" ? handleUserMessage(message) : handleAssistantMessage(message),\n )\n return [...systemMessages, ...otherMessages]\n}\n\nfunction handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === \"string\") {\n return [{ role: \"system\", content: system }]\n }\n\n return [{ role: \"system\", content: system.map((block) => block.text).join(\"\\n\\n\") }]\n}\n\nfunction handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock => block.type === \"tool_result\",\n )\n const otherBlocks = message.content.filter((block) => block.type !== \"tool_result\")\n\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: \"tool\",\n tool_call_id: block.tool_use_id,\n content: mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: \"user\",\n content: mapContent(otherBlocks),\n })\n }\n } else {\n newMessages.push({\n role: \"user\",\n content: mapContent(message.content),\n })\n }\n\n return newMessages\n}\n\nfunction handleAssistantMessage(message: AnthropicAssistantMessage): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [{ role: \"assistant\", content: mapContent(message.content) }]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === \"tool_use\",\n )\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === \"text\",\n )\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === \"thinking\",\n )\n\n const allTextContent = [\n ...textBlocks.map((b) => b.text),\n ...thinkingBlocks.map((b) => b.thinking),\n ].join(\"\\n\\n\")\n\n return toolUseBlocks.length > 0\n ? [\n {\n role: \"assistant\",\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map((toolUse) => ({\n id: toolUse.id,\n type: \"function\",\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [{ role: \"assistant\", content: mapContent(message.content) }]\n}\n\nfunction mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n): string | Array<ContentPart> | null {\n if (typeof content === \"string\") {\n return content\n }\n\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some((block) => block.type === \"image\")\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === \"text\" || block.type === \"thinking\",\n )\n .map((block) => (block.type === \"text\" ? block.text : block.thinking))\n .join(\"\\n\\n\")\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n contentParts.push({ type: \"text\", text: block.text })\n break\n }\n case \"thinking\": {\n contentParts.push({ type: \"text\", text: block.thinking })\n break\n }\n case \"image\": {\n contentParts.push({\n type: \"image_url\",\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n break\n }\n }\n }\n\n return contentParts\n}\n\nfunction translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n\n return anthropicTools.map((tool) => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n}\n\nfunction translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload[\"tool_choice\"],\n): ChatCompletionsPayload[\"tool_choice\"] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n if (anthropicToolChoice.name) {\n return {\n type: \"function\",\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return undefined\n }\n }\n}\n\nexport function translateToAnthropic(\n response: ChatCompletionResponse,\n): AnthropicResponse {\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null = null\n\n stopReason = response.choices[0]?.finish_reason ?? stopReason\n\n for (const choice of response.choices) {\n allTextBlocks.push(...getAnthropicTextBlocks(choice.message.content))\n allToolUseBlocks.push(...getAnthropicToolUseBlocks(choice.message.tool_calls))\n\n if (choice.finish_reason === \"tool_calls\" || stopReason === \"stop\") {\n stopReason = choice.finish_reason\n }\n }\n\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n model: response.model,\n content: [...allTextBlocks, ...allToolUseBlocks],\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n input_tokens:\n (response.usage?.prompt_tokens ?? 0)\n - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(response.usage?.prompt_tokens_details?.cached_tokens !== undefined && {\n cache_read_input_tokens: response.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n }\n}\n\nfunction getAnthropicTextBlocks(\n messageContent: Message[\"content\"],\n): Array<AnthropicTextBlock> {\n if (typeof messageContent === \"string\") {\n return [{ type: \"text\", text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text }))\n }\n\n return []\n}\n\nfunction getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n\n return toolCalls.map((toolCall) => ({\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: safeJsonParse(toolCall.function.arguments),\n }))\n}\n\nfunction safeJsonParse(input: string): Record<string, unknown> {\n try {\n return JSON.parse(input) as Record<string, unknown>\n } catch {\n return { raw: input }\n }\n}\n","import type {\n AnthropicStreamEventData,\n AnthropicStreamState,\n} from \"~/bridges/claude/anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"~/bridges/claude/utils\"\nimport type { ChatCompletionChunk } from \"~/providers/copilot/chat-types\"\n\nfunction isToolBlockOpen(state: AnthropicStreamState): boolean {\n if (!state.contentBlockOpen) {\n return false\n }\n\n return Object.values(state.toolCalls).some(\n (tc) => tc.anthropicBlockIndex === state.contentBlockIndex,\n )\n}\n\nexport function translateChunkToAnthropicEvents(\n chunk: ChatCompletionChunk,\n state: AnthropicStreamState,\n): Array<AnthropicStreamEventData> {\n const events: Array<AnthropicStreamEventData> = []\n\n if (chunk.choices.length === 0) {\n return events\n }\n\n const choice = chunk.choices[0]\n const { delta } = choice\n\n if (!state.messageStartSent) {\n events.push({\n type: \"message_start\",\n message: {\n id: chunk.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: chunk.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens !== undefined && {\n cache_read_input_tokens: chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n })\n state.messageStartSent = true\n }\n\n if (delta.content) {\n if (isToolBlockOpen(state)) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n if (!state.contentBlockOpen) {\n events.push({\n type: \"content_block_start\",\n index: state.contentBlockIndex,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n })\n state.contentBlockOpen = true\n }\n\n events.push({\n type: \"content_block_delta\",\n index: state.contentBlockIndex,\n delta: {\n type: \"text_delta\",\n text: delta.content,\n },\n })\n }\n\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n if (toolCall.id && toolCall.function?.name) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = state.contentBlockIndex\n state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: \"content_block_start\",\n index: anthropicBlockIndex,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = state.toolCalls[toolCall.index]\n if (toolCallInfo) {\n events.push({\n type: \"content_block_delta\",\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n }\n\n if (choice.finish_reason) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockOpen = false\n }\n\n events.push(\n {\n type: \"message_delta\",\n delta: {\n stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),\n stop_sequence: null,\n },\n usage: {\n input_tokens:\n (chunk.usage?.prompt_tokens ?? 0)\n - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),\n output_tokens: chunk.usage?.completion_tokens ?? 0,\n ...(chunk.usage?.prompt_tokens_details?.cached_tokens !== undefined && {\n cache_read_input_tokens: chunk.usage.prompt_tokens_details.cached_tokens,\n }),\n },\n },\n {\n type: \"message_stop\",\n },\n )\n }\n\n return events\n}\n\nexport function translateErrorToAnthropicErrorEvent(): AnthropicStreamEventData {\n return {\n type: \"error\",\n error: {\n type: \"api_error\",\n message: \"An unexpected error occurred during streaming.\",\n },\n }\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n ToolCall,\n} from \"~/providers/copilot/chat-types\"\nimport type { Model } from \"~/providers/copilot/get-models\"\n\nconst ENCODING_MAP = {\n o200k_base: () => import(\"gpt-tokenizer/encoding/o200k_base\"),\n cl100k_base: () => import(\"gpt-tokenizer/encoding/cl100k_base\"),\n p50k_base: () => import(\"gpt-tokenizer/encoding/p50k_base\"),\n p50k_edit: () => import(\"gpt-tokenizer/encoding/p50k_edit\"),\n r50k_base: () => import(\"gpt-tokenizer/encoding/r50k_base\"),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\nconst encodingCache = new Map<string, Encoder>()\n\nconst calculateToolCallsTokens = (\n toolCalls: Array<ToolCall>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\nconst calculateContentPartsTokens = (\n contentParts: Array<ContentPart>,\n encoder: Encoder,\n): number => {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === \"image_url\") {\n tokens += encoder.encode(part.image_url.url).length + 85\n } else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\nconst calculateMessageTokens = (\n message: Message,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\") {\n tokens += encoder.encode(value).length\n }\n if (key === \"name\") tokens += tokensPerName\n if (key === \"tool_calls\") {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === \"content\" && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\nconst calculateTokens = (\n messages: Array<Message>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (messages.length === 0) return 0\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n numTokens += 3\n return numTokens\n}\n\nconst getEncodeChatFunction = async (encoding: string): Promise<Encoder> => {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) return cached\n }\n\n const supported = encoding as SupportedEncoding\n if (!(supported in ENCODING_MAP)) {\n const fallback = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallback)\n return fallback\n }\n\n const mod = (await ENCODING_MAP[supported]()) as Encoder\n encodingCache.set(encoding, mod)\n return mod\n}\n\nexport const getTokenizerFromModel = (model: Model): string =>\n model.capabilities.tokenizer || \"o200k_base\"\n\nconst getModelConstants = (model: Model) =>\n model.id === \"gpt-3.5-turbo\" || model.id === \"gpt-4\"\n ? {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n\nconst calculateParameterTokens = (\n key: string,\n prop: unknown,\n context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n },\n): number => {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n if (typeof prop !== \"object\" || prop === null) return tokens\n\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || \"string\"\n let paramDesc = param.description || \"\"\n\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n if (paramDesc.endsWith(\".\")) paramDesc = paramDesc.slice(0, -1)\n\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n const excludedKeys = new Set([\"type\", \"description\", \"enum\"])\n for (const propertyName of Object.keys(param)) {\n if (excludedKeys.has(propertyName)) continue\n const propertyValue = param[propertyName]\n const propertyText =\n typeof propertyValue === \"string\"\n ? propertyValue\n : JSON.stringify(propertyValue)\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n\n return tokens\n}\n\nconst calculateParametersTokens = (\n parameters: unknown,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (!parameters || typeof parameters !== \"object\") return 0\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === \"properties\") {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n } else {\n const paramText =\n typeof value === \"string\" ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\nconst calculateToolTokens = (\n tool: Tool,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || \"\"\n if (fDesc.endsWith(\".\")) fDesc = fDesc.slice(0, -1)\n tokens += encoder.encode(`${fName}:${fDesc}`).length\n if (typeof func.parameters === \"object\" && func.parameters !== null) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\nexport const numTokensForTools = (\n tools: Array<Tool>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\nexport const getTokenCount = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<{ input: number; output: number }> => {\n const tokenizer = getTokenizerFromModel(model)\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const inputMessages = payload.messages.filter((msg) => msg.role !== \"assistant\")\n const outputMessages = payload.messages.filter((msg) => msg.role === \"assistant\")\n\n const constants = getModelConstants(model)\n let inputTokens = calculateTokens(inputMessages, encoder, constants)\n if (payload.tools && payload.tools.length > 0) {\n inputTokens += numTokensForTools(payload.tools, encoder, constants)\n }\n const outputTokens = calculateTokens(outputMessages, encoder, constants)\n\n return { input: inputTokens, output: outputTokens }\n}\n","import consola from \"consola\"\nimport { Hono } from \"hono\"\nimport { streamSSE } from \"hono/streaming\"\n\nimport {\n type AnthropicMessagesPayload,\n type AnthropicStreamState,\n} from \"~/bridges/claude/anthropic-types\"\nimport {\n translateToAnthropic,\n translateToOpenAI,\n} from \"~/bridges/claude/non-stream-translation\"\nimport {\n translateChunkToAnthropicEvents,\n translateErrorToAnthropicErrorEvent,\n} from \"~/bridges/claude/stream-translation\"\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { BridgeNotImplementedError, HTTPError } from \"~/lib/error\"\nimport { checkRateLimit, RateLimitError } from \"~/lib/rate-limit\"\nimport { resolveModel } from \"~/lib/models-resolver\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport type {\n ChatCompletionChunk,\n ChatCompletionResponse,\n} from \"~/providers/copilot/chat-types\"\nimport { createChatCompletions } from \"~/services/copilot/create-chat-completions\"\n\nexport const messageRoutes = new Hono<BridgeEnv>()\n\nconst isNonStreamingResponse = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse =>\n typeof response === \"object\"\n && response !== null\n && Object.hasOwn(response, \"choices\")\n\nmessageRoutes.post(\"/\", async (c) => {\n const config = c.get(\"config\")\n try {\n await checkRateLimit()\n } catch (error) {\n if (error instanceof RateLimitError) {\n return c.json({ error: { message: error.message } }, 429)\n }\n throw error\n }\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n try {\n const response = await createChatCompletions(config, openAIPayload)\n\n if (isNonStreamingResponse(response)) {\n return c.json(translateToAnthropic(response))\n }\n\n return streamSSE(c, async (stream) => {\n const streamState: AnthropicStreamState = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n\n try {\n for await (const rawEvent of response) {\n if (rawEvent.data === \"[DONE]\") {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n let chunk: ChatCompletionChunk\n try {\n chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n } catch {\n continue\n }\n\n const events = translateChunkToAnthropicEvents(chunk, streamState)\n for (const event of events) {\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n } catch (error) {\n consola.error(\"Error during Anthropic stream translation:\", error)\n const errorEvent = translateErrorToAnthropicErrorEvent()\n await stream.writeSSE({\n event: errorEvent.type,\n data: JSON.stringify(errorEvent),\n })\n }\n })\n } catch (error) {\n if (error instanceof BridgeNotImplementedError) {\n return c.json(\n { error: { type: error.name, message: error.message } },\n 501,\n )\n }\n\n if (error instanceof HTTPError) {\n const text = await error.response.text().catch(() => \"\")\n return new Response(text, {\n status: error.response.status,\n headers: {\n \"content-type\":\n error.response.headers.get(\"content-type\") ?? \"application/json\",\n },\n })\n }\n\n throw error\n }\n})\n\nmessageRoutes.post(\"/count_tokens\", async (c) => {\n try {\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n const selectedModel = resolveModel(openAIPayload.model)\n\n if (!selectedModel) {\n consola.warn(\n `Model ${openAIPayload.model} not found in registry, returning fallback token count`,\n )\n return c.json({ input_tokens: 1 })\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n const effectiveModelId = selectedModel.id\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith(\"claude-code\")) {\n mcpToolExist = anthropicPayload.tools.some((tool) =>\n tool.name.startsWith(\"mcp__\"),\n )\n }\n if (!mcpToolExist) {\n if (effectiveModelId.startsWith(\"claude\")) {\n tokenCount.input += 346\n } else if (effectiveModelId.startsWith(\"grok\")) {\n tokenCount.input += 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (effectiveModelId.startsWith(\"claude\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n } else if (effectiveModelId.startsWith(\"grok\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n return c.json({ input_tokens: Math.max(1, finalTokenCount) })\n } catch (error) {\n consola.error(\"Error counting tokens:\", error)\n return c.json({ input_tokens: 1 })\n }\n})\n","import { Hono } from \"hono\"\n\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { BridgeNotImplementedError } from \"~/lib/error\"\nimport {\n fetchCopilot,\n getCopilotProviderContext,\n} from \"~/providers/copilot/client\"\n\nexport const modelRoutes = new Hono<BridgeEnv>()\n\nmodelRoutes.get(\"/\", async (c) => {\n const config = c.get(\"config\")\n const provider = getCopilotProviderContext(config)\n const search = new URL(c.req.url).search\n\n try {\n const upstream = await fetchCopilot(provider, `/models${search}`, {\n method: \"GET\",\n headers: {\n accept: c.req.header(\"accept\") ?? \"application/json\",\n },\n })\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: upstream.headers,\n })\n } catch (error) {\n if (error instanceof BridgeNotImplementedError) {\n return c.json(\n {\n error: {\n type: error.name,\n message: error.message,\n },\n },\n 500,\n )\n }\n\n throw error\n }\n})\n","// Translation layer: Codex /v1/responses ⇄ Copilot /v1/chat/completions.\n// Used for models that do not implement the Responses API upstream\n// (claude-*, gemini-*).\n//\n// Strategy:\n// - Translate the Responses request to a Chat Completions request.\n// - Force upstream to non-stream (stream: false) so we get a single JSON.\n// - Translate that JSON to a Responses API JSON.\n// - If the original request asked for stream:true, synthesize a tiny\n// sequence of SSE events (response.created → output_item.added →\n// content_part.added → output_text.delta → ... → response.completed)\n// so codex's bookkeeping still works.\n\nimport { randomUUID } from \"node:crypto\"\n\nimport type { ModelCapability, ReasoningEffort } from \"~/lib/model-capabilities\"\n\n// ---------- Responses (input) types — only what we read ----------\n\ninterface ResponsesInputMessage {\n type?: \"message\"\n role: \"user\" | \"assistant\" | \"system\" | \"developer\"\n content: string | Array<ResponsesInputContentPart>\n}\n\ninterface ResponsesInputContentPart {\n type:\n | \"input_text\"\n | \"output_text\"\n | \"input_image\"\n | \"text\"\n text?: string\n image_url?: string | { url: string }\n detail?: \"low\" | \"high\" | \"auto\"\n}\n\ninterface ResponsesFunctionCallInput {\n type: \"function_call\"\n call_id: string\n name: string\n arguments: string\n}\n\ninterface ResponsesFunctionCallOutputInput {\n type: \"function_call_output\"\n call_id: string\n output: string\n}\n\ntype ResponsesInputItem =\n | ResponsesInputMessage\n | ResponsesFunctionCallInput\n | ResponsesFunctionCallOutputInput\n\ninterface ResponsesTool {\n type: \"function\"\n name?: string\n description?: string\n parameters?: Record<string, unknown>\n function?: {\n name: string\n description?: string\n parameters?: Record<string, unknown>\n }\n}\n\nexport interface ResponsesRequestLike {\n model: string\n input?: string | Array<ResponsesInputItem>\n instructions?: string\n stream?: boolean\n max_output_tokens?: number\n temperature?: number\n top_p?: number\n user?: string\n tools?: Array<ResponsesTool>\n tool_choice?:\n | \"auto\"\n | \"none\"\n | \"required\"\n | { type: \"function\"; name: string }\n reasoning?: { effort?: ReasoningEffort; [k: string]: unknown }\n [key: string]: unknown\n}\n\n// ---------- Chat completion types — only what we send/read ----------\n\ntype ChatRole = \"system\" | \"user\" | \"assistant\" | \"tool\"\n\ninterface ChatContentPart {\n type: \"text\" | \"image_url\"\n text?: string\n image_url?: { url: string; detail?: \"low\" | \"high\" | \"auto\" }\n}\n\ninterface ChatToolCall {\n id: string\n type: \"function\"\n function: { name: string; arguments: string }\n}\n\ninterface ChatMessage {\n role: ChatRole\n content?: string | Array<ChatContentPart> | null\n name?: string\n tool_call_id?: string\n tool_calls?: Array<ChatToolCall>\n}\n\ninterface ChatTool {\n type: \"function\"\n function: {\n name: string\n description?: string\n parameters?: Record<string, unknown>\n }\n}\n\ninterface ChatRequestPayload {\n model: string\n messages: Array<ChatMessage>\n stream: boolean\n max_tokens?: number\n temperature?: number\n top_p?: number\n user?: string\n tools?: Array<ChatTool>\n tool_choice?: unknown\n reasoning_effort?: ReasoningEffort\n output_config?: { effort?: ReasoningEffort }\n}\n\ninterface ChatCompletionResponse {\n id?: string\n created?: number\n model?: string\n choices: Array<{\n index?: number\n message: ChatMessage & { role: \"assistant\" }\n finish_reason?: string | null\n }>\n usage?: {\n prompt_tokens?: number\n completion_tokens?: number\n total_tokens?: number\n }\n}\n\n// ---------- Helpers ----------\n\nconst collectText = (\n content: string | Array<ResponsesInputContentPart> | undefined,\n): { text: string; parts: Array<ChatContentPart> } => {\n if (typeof content === \"string\") {\n return { text: content, parts: [{ type: \"text\", text: content }] }\n }\n const parts: Array<ChatContentPart> = []\n let textBuf = \"\"\n for (const p of content ?? []) {\n if (p.type === \"input_text\" || p.type === \"output_text\" || p.type === \"text\") {\n const t = p.text ?? \"\"\n textBuf += t\n parts.push({ type: \"text\", text: t })\n } else if (p.type === \"input_image\") {\n const url =\n typeof p.image_url === \"string\" ?\n p.image_url\n : (p.image_url?.url ?? \"\")\n if (url) parts.push({ type: \"image_url\", image_url: { url, detail: p.detail } })\n }\n }\n return { text: textBuf, parts }\n}\n\nconst placeReasoning = (\n payload: ChatRequestPayload,\n capability: ModelCapability,\n effort: ReasoningEffort | undefined,\n) => {\n if (!effort || !capability.reasoning) return\n if (capability.reasoningField === \"output_config.effort\") {\n payload.output_config = { ...(payload.output_config ?? {}), effort }\n } else {\n payload.reasoning_effort = effort\n }\n}\n\n// ---------- Public: translate request ----------\n\nexport const responsesPayloadToChatPayload = (\n request: ResponsesRequestLike,\n capability: ModelCapability,\n): ChatRequestPayload => {\n const messages: Array<ChatMessage> = []\n\n if (request.instructions) {\n messages.push({ role: \"system\", content: request.instructions })\n }\n\n const inputItems: Array<ResponsesInputItem> =\n typeof request.input === \"string\" ?\n [{ role: \"user\", content: request.input } as ResponsesInputMessage]\n : (request.input ?? [])\n\n for (const item of inputItems) {\n if (\"role\" in item && (item.type === undefined || item.type === \"message\")) {\n const { text, parts } = collectText(item.content)\n const role: ChatRole =\n item.role === \"developer\" ? \"system\"\n : item.role === \"system\" ? \"system\"\n : item.role === \"assistant\" ? \"assistant\"\n : \"user\"\n // Use string content when single text part for simplicity.\n const useStringContent =\n parts.length <= 1 && parts.every((p) => p.type === \"text\")\n messages.push({\n role,\n content: useStringContent ? text : parts,\n })\n } else if (item.type === \"function_call\") {\n messages.push({\n role: \"assistant\",\n content: null,\n tool_calls: [\n {\n id: item.call_id,\n type: \"function\",\n function: { name: item.name, arguments: item.arguments },\n },\n ],\n })\n } else if (item.type === \"function_call_output\") {\n messages.push({\n role: \"tool\",\n tool_call_id: item.call_id,\n content: item.output,\n })\n }\n }\n\n const tools: Array<ChatTool> | undefined = request.tools\n ?.filter((t) => {\n const name = t.function?.name ?? t.name\n return t.type === \"function\" && typeof name === \"string\" && name.length > 0\n })\n .map((t) => ({\n type: \"function\",\n function: {\n name: t.function?.name ?? t.name ?? \"\",\n description: t.function?.description ?? t.description,\n parameters: t.function?.parameters ?? t.parameters,\n },\n }))\n\n const payload: ChatRequestPayload = {\n model: capability.id,\n messages,\n stream: false, // always non-stream upstream; we synthesize SSE later\n max_tokens: request.max_output_tokens,\n temperature: request.temperature,\n top_p: request.top_p,\n user: request.user,\n tools: tools && tools.length > 0 ? tools : undefined,\n tool_choice:\n tools && tools.length > 0 ? request.tool_choice : undefined,\n }\n\n placeReasoning(payload, capability, request.reasoning?.effort)\n\n return payload\n}\n\n// ---------- Public: translate non-stream response ----------\n\ninterface ResponsesApiResult {\n id: string\n object: \"response\"\n status: \"completed\" | \"incomplete\"\n created_at: number\n model: string\n output: Array<\n | {\n id: string\n type: \"message\"\n role: \"assistant\"\n status: \"completed\"\n content: Array<{ type: \"output_text\"; text: string; annotations: [] }>\n }\n | {\n id: string\n type: \"function_call\"\n status: \"completed\"\n call_id: string\n name: string\n arguments: string\n }\n >\n usage?: {\n input_tokens: number\n output_tokens: number\n total_tokens: number\n }\n}\n\nconst buildResponsesResult = (\n request: ResponsesRequestLike,\n chat: ChatCompletionResponse,\n): ResponsesApiResult => {\n const choice = chat.choices[0]\n const message = choice?.message\n const text =\n typeof message?.content === \"string\" ?\n message.content\n : Array.isArray(message?.content) ?\n message.content\n .filter((p): p is ChatContentPart => p.type === \"text\")\n .map((p) => p.text ?? \"\")\n .join(\"\")\n : \"\"\n\n const output: ResponsesApiResult[\"output\"] = []\n if (text.length > 0) {\n output.push({\n id: `msg_${randomUUID()}`,\n type: \"message\",\n role: \"assistant\",\n status: \"completed\",\n content: [{ type: \"output_text\", text, annotations: [] }],\n })\n }\n for (const tc of message?.tool_calls ?? []) {\n output.push({\n id: `fc_${randomUUID()}`,\n type: \"function_call\",\n status: \"completed\",\n call_id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n })\n }\n\n return {\n id: chat.id ?? `resp_${randomUUID()}`,\n object: \"response\",\n status: \"completed\",\n created_at: chat.created ?? Math.floor(Date.now() / 1000),\n model: chat.model ?? request.model,\n output,\n usage:\n chat.usage ?\n {\n input_tokens: chat.usage.prompt_tokens ?? 0,\n output_tokens: chat.usage.completion_tokens ?? 0,\n total_tokens: chat.usage.total_tokens ?? 0,\n }\n : undefined,\n }\n}\n\nexport const chatResponseToResponsesJson = buildResponsesResult\n\n// ---------- Public: synthesize SSE stream ----------\n\nconst sse = (event: string, data: unknown) =>\n `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`\n\nexport const synthesizeResponsesSseFromChat = (\n request: ResponsesRequestLike,\n chat: ChatCompletionResponse,\n): ReadableStream<Uint8Array> => {\n const result = buildResponsesResult(request, chat)\n const encoder = new TextEncoder()\n const baseResponse = {\n id: result.id,\n object: \"response\",\n created_at: result.created_at,\n model: result.model,\n status: \"in_progress\",\n output: [] as unknown[],\n }\n\n return new ReadableStream<Uint8Array>({\n start(controller) {\n const push = (event: string, data: unknown) =>\n controller.enqueue(encoder.encode(sse(event, data)))\n\n push(\"response.created\", { type: \"response.created\", response: baseResponse })\n push(\"response.in_progress\", {\n type: \"response.in_progress\",\n response: baseResponse,\n })\n\n result.output.forEach((item, index) => {\n push(\"response.output_item.added\", {\n type: \"response.output_item.added\",\n output_index: index,\n item,\n })\n\n if (item.type === \"message\") {\n const text = item.content[0]?.text ?? \"\"\n const part = { type: \"output_text\", text: \"\", annotations: [] }\n push(\"response.content_part.added\", {\n type: \"response.content_part.added\",\n item_id: item.id,\n output_index: index,\n content_index: 0,\n part,\n })\n if (text) {\n push(\"response.output_text.delta\", {\n type: \"response.output_text.delta\",\n item_id: item.id,\n output_index: index,\n content_index: 0,\n delta: text,\n })\n }\n push(\"response.output_text.done\", {\n type: \"response.output_text.done\",\n item_id: item.id,\n output_index: index,\n content_index: 0,\n text,\n })\n push(\"response.content_part.done\", {\n type: \"response.content_part.done\",\n item_id: item.id,\n output_index: index,\n content_index: 0,\n part: { ...part, text },\n })\n } else if (item.type === \"function_call\") {\n if (item.arguments) {\n push(\"response.function_call_arguments.delta\", {\n type: \"response.function_call_arguments.delta\",\n item_id: item.id,\n output_index: index,\n delta: item.arguments,\n })\n }\n push(\"response.function_call_arguments.done\", {\n type: \"response.function_call_arguments.done\",\n item_id: item.id,\n output_index: index,\n arguments: item.arguments,\n })\n }\n\n push(\"response.output_item.done\", {\n type: \"response.output_item.done\",\n output_index: index,\n item,\n })\n })\n\n push(\"response.completed\", {\n type: \"response.completed\",\n response: { ...result, status: \"completed\" },\n })\n controller.close()\n },\n })\n}\n","interface ResponseMetadata {\n created_at?: number\n id?: string\n model?: string\n}\n\ninterface ResponsesStreamEvent {\n response?: ResponseMetadata\n type?: string\n [key: string]: unknown\n}\n\ninterface StableResponseMetadata {\n created_at: number\n id: string\n initialized: boolean\n model: string\n}\n\nconst normalizeEventPayload = (\n rawData: string,\n stableResponse: StableResponseMetadata,\n): string => {\n let event: ResponsesStreamEvent\n try {\n event = JSON.parse(rawData) as ResponsesStreamEvent\n } catch {\n return rawData\n }\n\n if (event.response && typeof event.response === \"object\") {\n const incoming = event.response\n if (!stableResponse.initialized) {\n if (incoming.id) stableResponse.id = incoming.id\n if (typeof incoming.created_at === \"number\")\n stableResponse.created_at = incoming.created_at\n if (incoming.model) stableResponse.model = incoming.model\n stableResponse.initialized = true\n }\n\n event.response = {\n ...incoming,\n ...(stableResponse.id ? { id: stableResponse.id } : {}),\n ...(stableResponse.created_at\n ? { created_at: stableResponse.created_at }\n : {}),\n ...(stableResponse.model ? { model: stableResponse.model } : {}),\n }\n }\n\n return JSON.stringify(event)\n}\n\nconst transformSseChunk = (\n chunk: string,\n stableResponse: StableResponseMetadata,\n): string => {\n const lines = chunk.split(\"\\n\")\n\n return lines\n .map((line) => {\n if (!line.startsWith(\"data: \")) {\n return line\n }\n\n const rawData = line.slice(6)\n if (!rawData || rawData === \"[DONE]\") {\n return line\n }\n\n return `data: ${normalizeEventPayload(rawData, stableResponse)}`\n })\n .join(\"\\n\")\n}\n\nexport const normalizeResponsesSseStream = (\n upstreamBody: ReadableStream<Uint8Array>,\n) => {\n const stableResponse: StableResponseMetadata = {\n created_at: 0,\n id: \"\",\n initialized: false,\n model: \"\",\n }\n\n const decoder = new TextDecoder()\n const encoder = new TextEncoder()\n let buffer = \"\"\n\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n const reader = upstreamBody.getReader()\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n\n if (done) {\n break\n }\n\n buffer += decoder.decode(value, { stream: true })\n\n let separatorIndex = buffer.indexOf(\"\\n\\n\")\n\n while (separatorIndex !== -1) {\n const rawEvent = buffer.slice(0, separatorIndex)\n buffer = buffer.slice(separatorIndex + 2)\n\n const transformed = transformSseChunk(rawEvent, stableResponse)\n controller.enqueue(encoder.encode(`${transformed}\\n\\n`))\n\n separatorIndex = buffer.indexOf(\"\\n\\n\")\n }\n }\n\n if (buffer.length > 0) {\n const transformed = transformSseChunk(buffer, stableResponse)\n controller.enqueue(encoder.encode(transformed))\n }\n } finally {\n reader.releaseLock()\n }\n\n controller.close()\n },\n })\n}\n","import { z } from \"zod\"\n\nimport {\n clampReasoningEffort,\n getModelCapability,\n resolveModelId,\n} from \"~/lib/model-capabilities\"\n\nconst codexResponsesRequestSchema = z\n .object({\n model: z.string().min(1),\n stream: z.boolean().optional(),\n })\n .passthrough()\n\nexport type CodexResponsesRequest = z.infer<typeof codexResponsesRequestSchema>\n\ninterface ReasoningField {\n effort?: unknown\n [key: string]: unknown\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nexport const normalizeCodexResponsesRequest = (\n payload: CodexResponsesRequest,\n): CodexResponsesRequest => {\n const parsed = codexResponsesRequestSchema.parse(payload) as CodexResponsesRequest\n & { reasoning?: ReasoningField }\n\n const canonical = resolveModelId(parsed.model)\n const capability = getModelCapability(canonical)\n if (!capability) return parsed\n\n const next = { ...parsed, model: canonical } as typeof parsed\n\n if (!capability.reasoning) {\n if (\"reasoning\" in next) {\n delete (next as Record<string, unknown>).reasoning\n }\n return next\n }\n\n const incoming: ReasoningField | undefined =\n isPlainObject(next.reasoning) ? (next.reasoning as ReasoningField) : undefined\n const clamped = clampReasoningEffort(canonical, incoming?.effort)\n if (clamped) {\n next.reasoning = { ...(incoming ?? {}), effort: clamped.effort }\n }\n\n return next\n}\n","import { Hono } from \"hono\"\n\nimport {\n chatResponseToResponsesJson,\n responsesPayloadToChatPayload,\n synthesizeResponsesSseFromChat,\n type ResponsesRequestLike,\n} from \"~/bridges/codex/chat-fallback\"\nimport { normalizeResponsesSseStream } from \"~/bridges/codex/normalize-stream\"\nimport { normalizeCodexResponsesRequest } from \"~/bridges/codex/responses\"\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { BridgeNotImplementedError } from \"~/lib/error\"\nimport { getModelCapability } from \"~/lib/model-capabilities\"\nimport { checkRateLimit, RateLimitError } from \"~/lib/rate-limit\"\nimport {\n fetchCopilot,\n getCopilotProviderContext,\n} from \"~/providers/copilot/client\"\n\nexport const responsesRoutes = new Hono<BridgeEnv>()\n\nresponsesRoutes.post(\"/\", async (c) => {\n try {\n await checkRateLimit()\n } catch (error) {\n if (error instanceof RateLimitError) {\n return c.json({ error: { message: error.message } }, 429)\n }\n throw error\n }\n const rawPayload = (await c.req.json()) as ResponsesRequestLike\n const payload = normalizeCodexResponsesRequest(\n rawPayload as unknown as Parameters<typeof normalizeCodexResponsesRequest>[0],\n ) as unknown as ResponsesRequestLike\n const config = c.get(\"config\")\n const provider = getCopilotProviderContext(config)\n const search = new URL(c.req.url).search\n\n const capability = getModelCapability(payload.model)\n\n try {\n if (capability?.fallback === \"chat-completions\") {\n const chatPayload = responsesPayloadToChatPayload(payload, capability)\n const upstream = await fetchCopilot(provider, `/chat/completions${search}`, {\n method: \"POST\",\n headers: { accept: \"application/json\", \"content-type\": \"application/json\" },\n body: JSON.stringify(chatPayload),\n })\n\n if (!upstream.ok) {\n const text = await upstream.text()\n return new Response(text, {\n status: upstream.status,\n headers: { \"content-type\": upstream.headers.get(\"content-type\") ?? \"application/json\" },\n })\n }\n\n const chatJson = (await upstream.json()) as Parameters<\n typeof chatResponseToResponsesJson\n >[1]\n\n if (payload.stream) {\n const stream = synthesizeResponsesSseFromChat(payload, chatJson)\n return new Response(stream, {\n status: 200,\n headers: {\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache\",\n connection: \"keep-alive\",\n },\n })\n }\n\n const responsesJson = chatResponseToResponsesJson(payload, chatJson)\n return new Response(JSON.stringify(responsesJson), {\n status: 200,\n headers: { \"content-type\": \"application/json\" },\n })\n }\n\n const upstream = await fetchCopilot(provider, `/responses${search}`, {\n method: \"POST\",\n headers: {\n accept: c.req.header(\"accept\") ?? \"application/json\",\n \"content-type\": c.req.header(\"content-type\") ?? \"application/json\",\n },\n body: JSON.stringify(payload),\n })\n\n const contentType = upstream.headers.get(\"content-type\") ?? \"\"\n\n if (payload.stream && upstream.body && contentType.includes(\"text/event-stream\")) {\n return new Response(normalizeResponsesSseStream(upstream.body), {\n status: upstream.status,\n headers: upstream.headers,\n })\n }\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: upstream.headers,\n })\n } catch (error) {\n if (error instanceof BridgeNotImplementedError) {\n return c.json(\n {\n error: {\n type: error.name,\n message: error.message,\n },\n },\n 501,\n )\n }\n\n throw error\n }\n})","import fs from \"node:fs/promises\"\n\nimport type { BridgeConfig } from \"~/lib/config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { PATHS } from \"~/lib/paths\"\n\nconst COPILOT_VERSION = \"0.26.7\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst GITHUB_API_VERSION = \"2022-11-28\"\nconst GITHUB_API_BASE_URL = \"https://api.github.com\"\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\nexport interface CopilotUsageResponse {\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n }\n}\n\nconst readGitHubToken = async (): Promise<string> => {\n const token = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return token.trim()\n}\n\nexport const getCopilotUsage = async (\n config: BridgeConfig,\n): Promise<CopilotUsageResponse> => {\n const githubToken = await readGitHubToken()\n const response = await fetch(\n `${GITHUB_API_BASE_URL}/copilot_internal/user`,\n {\n headers: {\n accept: \"application/json\",\n authorization: `token ${githubToken}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"editor-version\": `vscode/${config.vsCodeVersion}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": GITHUB_API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n },\n },\n )\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n","import { Hono } from \"hono\"\n\nimport type { BridgeEnv } from \"~/lib/config\"\nimport { getCopilotUsage } from \"~/providers/github/get-copilot-usage\"\n\nexport const usageRoutes = new Hono<BridgeEnv>()\n\nusageRoutes.get(\"/\", async (c) => {\n // Allow the static usage viewer at https://betahi.github.io/copilot-api\n // (and local dev) to call this endpoint cross-origin.\n c.header(\"access-control-allow-origin\", \"*\")\n c.header(\"access-control-allow-methods\", \"GET, OPTIONS\")\n c.header(\"access-control-allow-headers\", \"*\")\n\n try {\n const usage = await getCopilotUsage(c.var.config)\n return c.json(usage)\n } catch (error) {\n console.error(\"Error fetching Copilot usage:\", error)\n return c.json({ error: \"Failed to fetch Copilot usage\" }, 500)\n }\n})\n\nusageRoutes.options(\"/\", (c) => {\n c.header(\"access-control-allow-origin\", \"*\")\n c.header(\"access-control-allow-methods\", \"GET, OPTIONS\")\n c.header(\"access-control-allow-headers\", \"*\")\n return c.body(null, 204)\n})\n","import { serve } from \"@hono/node-server\"\nimport { Hono } from \"hono\"\nimport { cors } from \"hono/cors\"\nimport { logger } from \"hono/logger\"\n\nimport type { BridgeConfig, BridgeEnv } from \"~/lib/config\"\nimport { chatCompletionRoutes } from \"~/routes/chat-completions\"\nimport { embeddingRoutes } from \"~/routes/embeddings\"\nimport { messageRoutes } from \"~/routes/messages\"\nimport { modelRoutes } from \"~/routes/models\"\nimport { responsesRoutes } from \"~/routes/responses\"\nimport { usageRoutes } from \"~/routes/usage\"\n\nexport const createServer = (config: BridgeConfig) => {\n const app = new Hono<BridgeEnv>()\n\n app.use(logger())\n app.use(\"*\", cors())\n app.use(\"*\", async (c, next) => {\n c.set(\"config\", config)\n await next()\n })\n\n app.get(\"/\", (c) =>\n c.json({\n name: \"copilot-bridge\",\n status: \"ok\",\n }),\n )\n\n app.get(\"/healthz\", (c) => c.json({ ok: true }))\n app.route(\"/v1/models\", modelRoutes)\n app.route(\"/v1/responses\", responsesRoutes)\n app.route(\"/v1/messages\", messageRoutes)\n app.route(\"/v1/chat/completions\", chatCompletionRoutes)\n app.route(\"/v1/embeddings\", embeddingRoutes)\n app.route(\"/usage\", usageRoutes)\n\n return app\n}\n\nexport const startServer = (config: BridgeConfig) =>\n serve({\n fetch: createServer(config).fetch,\n hostname: config.host,\n port: config.port,\n })\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { setupBridgeAuth } from \"~/lib/auth\"\nimport {\n applyCodexConfig,\n readCodexUserConfigFromDisk,\n} from \"~/lib/codex-config\"\nimport { readBridgeConfig } from \"~/lib/config\"\nimport {\n getModelCapability,\n MODEL_CAPABILITIES,\n} from \"~/lib/model-capabilities\"\nimport { ensureSettingsFile } from \"~/lib/settings\"\nimport { runtimeState } from \"~/lib/state\"\nimport {\n fetchCopilot,\n getCopilotProviderContext,\n} from \"~/providers/copilot/client\"\nimport { startServer } from \"~/server\"\n\ninterface CopilotModel {\n id: string\n}\n\ninterface CopilotModelsResponse {\n data?: Array<CopilotModel>\n}\n\nconst fetchAvailableModels = async (\n config: ReturnType<typeof readBridgeConfig>,\n): Promise<Array<string>> => {\n try {\n const provider = getCopilotProviderContext(config)\n const response = await fetchCopilot(provider, \"/models\", {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n })\n if (!response.ok) return []\n const payload = (await response.json()) as CopilotModelsResponse\n return (payload.data ?? []).map((m) => m.id).filter(Boolean)\n } catch {\n return []\n }\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the copilot-bridge HTTP server.\",\n },\n args: {\n host: {\n type: \"string\",\n description: \"Host to bind (overrides settings.json).\",\n },\n port: {\n type: \"string\",\n description: \"Port to listen on (overrides settings.json).\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Print GitHub and Copilot tokens during startup.\",\n },\n \"no-codex-setup\": {\n type: \"boolean\",\n default: false,\n description: \"Skip writing the bridge provider into ~/.codex/config.toml.\",\n },\n \"select-model\": {\n type: \"boolean\",\n default: false,\n description: \"Force the model picker even when codex.model is set.\",\n },\n \"no-prompt\": {\n type: \"boolean\",\n default: false,\n description: \"Never prompt; use codex.model from settings.json as-is.\",\n },\n \"rate-limit\": {\n type: \"string\",\n description:\n \"Minimum seconds between upstream requests (anti-abuse throttle).\",\n },\n wait: {\n type: \"boolean\",\n default: false,\n description:\n \"When --rate-limit is set, wait instead of returning HTTP 429.\",\n },\n },\n async run({ args }) {\n const settings = await ensureSettingsFile()\n\n const host = args.host ? String(args.host) : settings.host\n const port = args.port ? Number(args.port) : settings.port\n\n const config = readBridgeConfig({ host, port })\n\n const rateLimitRaw = args[\"rate-limit\"]\n if (rateLimitRaw !== undefined) {\n const parsed = Number.parseInt(String(rateLimitRaw), 10)\n if (!Number.isFinite(parsed) || parsed <= 0) {\n consola.error(`Invalid --rate-limit value: ${rateLimitRaw}`)\n process.exit(1)\n }\n runtimeState.rateLimitSeconds = parsed\n runtimeState.rateLimitWait = Boolean(args.wait)\n consola.info(\n `Rate limit: ${parsed}s between requests (${runtimeState.rateLimitWait ? \"wait\" : \"reject\"} on overflow)`,\n )\n }\n\n await setupBridgeAuth(config, {\n showToken: args[\"show-token\"],\n })\n\n const server = startServer(config)\n\n consola.success(\n `copilot-bridge listening on http://${config.host}:${config.port}`,\n )\n consola.info(`copilot base url: ${config.copilotBaseUrl}`)\n\n const models = await fetchAvailableModels(config)\n const supportedIds = new Set(MODEL_CAPABILITIES.map((m) => m.id))\n const pickable =\n models.length > 0 ?\n models.filter((id) => supportedIds.has(id))\n : MODEL_CAPABILITIES.map((m) => m.id)\n const finalPickable =\n pickable.length > 0 ? pickable : MODEL_CAPABILITIES.map((m) => m.id)\n if (models.length > 0) {\n consola.info(\n `Available models:\\n${models\n .map((id) => `- ${id}${supportedIds.has(id) ? \" (bridge-supported)\" : \"\"}`)\n .join(\"\\n\")}`,\n )\n } else {\n consola.warn(\"Could not fetch model list from upstream Copilot API\")\n }\n\n const codexUserConfig = await readCodexUserConfigFromDisk(\n settings.codex.configPath,\n )\n let chosenModel: string | undefined = codexUserConfig.model\n let chosenEffort: string | undefined =\n codexUserConfig.modelReasoningEffort\n\n const shouldPrompt =\n !args[\"no-prompt\"]\n && finalPickable.length > 0\n && (args[\"select-model\"] || !chosenModel)\n\n if (shouldPrompt) {\n const defaultId =\n chosenModel && finalPickable.includes(chosenModel) ? chosenModel\n : finalPickable.includes(\"gpt-5.3-codex\") ? \"gpt-5.3-codex\"\n : finalPickable[0]\n const selected = (await consola.prompt(\n `Select a model for codex (writes to ${settings.codex.configPath})`,\n {\n type: \"select\",\n options: finalPickable,\n initial: defaultId,\n },\n )) as string\n if (selected) {\n chosenModel = selected\n // If the previously stored effort is no longer supported by the\n // newly chosen model, drop it so codex falls back to its default.\n const cap = getModelCapability(selected)\n const supported = cap?.reasoning?.supported\n if (\n chosenEffort\n && supported\n && !supported.includes(chosenEffort as never)\n ) {\n chosenEffort = undefined\n }\n }\n }\n\n const baseUrl = `http://${config.host}:${config.port}`\n consola.box(\n [\n `🌐 Usage viewer`,\n ``,\n ` https://betahi.github.io/copilot-api?endpoint=${baseUrl}/usage`,\n ].join(\"\\n\"),\n )\n\n if (settings.codex.enabled && !args[\"no-codex-setup\"]) {\n const codexBaseUrl = `${baseUrl}/v1`\n const result = await applyCodexConfig({\n baseUrl: codexBaseUrl,\n configPath: settings.codex.configPath,\n settings: settings.codex,\n model: chosenModel,\n modelReasoningEffort: chosenEffort,\n })\n if (result.changed) {\n consola.success(\n `codex config ${result.created ? \"created\" : \"updated\"}: ${result.configPath}`,\n )\n if (settings.codex.setAsDefault) {\n consola.info(\n `codex now defaults to provider \"${settings.codex.providerId}\". Run \\`codex exec \"...\"\\` directly.`,\n )\n } else {\n consola.info(\n `provider \"${settings.codex.providerId}\" registered. Use \\`codex -c model_provider=\"${settings.codex.providerId}\" ...\\``,\n )\n }\n } else {\n consola.info(`codex config already up to date: ${result.configPath}`)\n }\n }\n\n await new Promise<void>((resolve, reject) => {\n server.on(\"close\", resolve)\n server.on(\"error\", reject)\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\"\n\nimport { auth } from \"./auth\"\nimport { start } from \"./start\"\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-bridge\",\n description:\n \"Model-layer bridge for routing Codex CLI, Claude Code, and similar clients to GitHub Copilot.\",\n },\n subCommands: { auth, start },\n})\n\nawait runMain(main)\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "betahi-copilot-bridge",
3
+ "version": "0.1.0",
4
+ "description": "Model-layer bridge for routing Codex CLI, Claude Code, and similar clients to GitHub Copilot.",
5
+ "keywords": [
6
+ "github-copilot",
7
+ "proxy",
8
+ "bridge",
9
+ "codex",
10
+ "claude"
11
+ ],
12
+ "homepage": "https://github.com/betaHi/copilot-bridge#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/betaHi/copilot-bridge/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/betaHi/copilot-bridge.git"
19
+ },
20
+ "license": "MIT",
21
+ "author": "betaHi",
22
+ "type": "module",
23
+ "bin": {
24
+ "copilot-bridge": "./dist/main.js",
25
+ "betahi-copilot-bridge": "./dist/main.js"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "scripts": {
34
+ "build": "tsdown",
35
+ "dev": "bun run --watch ./src/main.ts",
36
+ "prepack": "bun run build",
37
+ "start": "NODE_ENV=production bun run ./src/main.ts",
38
+ "test": "bun test",
39
+ "typecheck": "tsc"
40
+ },
41
+ "dependencies": {
42
+ "@hono/node-server": "^1.14.4",
43
+ "citty": "^0.1.6",
44
+ "consola": "^3.4.2",
45
+ "fetch-event-stream": "^0.1.6",
46
+ "gpt-tokenizer": "^3.4.0",
47
+ "hono": "^4.9.9",
48
+ "zod": "^4.1.11"
49
+ },
50
+ "devDependencies": {
51
+ "@types/bun": "^1.2.23",
52
+ "tsdown": "^0.15.6",
53
+ "typescript": "^5.9.3"
54
+ }
55
+ }