betahi-copilot-bridge 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <a href="https://github.com/betahi/copilot-bridge/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/betahi-copilot-bridge.svg" alt="license"></a>
6
6
  </p>
7
7
 
8
- > Use GitHub Copilot as a local OpenAI/Anthropic-compatible API, so [Codex CLI](https://github.com/openai/codex), [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) and Continue can talk to Copilot with minimal configuration.
8
+ > Use GitHub Copilot as a local OpenAI/Anthropic-compatible API, so [Codex CLI](https://developers.openai.com/codex/cli), [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) and Continue can talk to Copilot with minimal configuration.
9
9
 
10
10
  > [!WARNING]
11
11
  > This is a reverse-engineered bridge for the GitHub Copilot API. It is not
@@ -153,12 +153,8 @@ Optional slot-specific:
153
153
 
154
154
  `MODEL_REASONING_EFFORT` (case-insensitive key lookup) is also read from the
155
155
  project-local `.claude/settings.json` and `.claude/settings.local.json` and
156
- applied to Claude requests only when the model supports reasoning.
157
-
158
- For backward compatibility, `COPILOT_REASONING_EFFORT` is accepted as an alias.
159
-
160
- If Claude-side reasoning is not configured, Claude requests fall back to
161
- `medium` (when the target model supports reasoning).
156
+ applied to Claude requests only when the model supports reasoning. If it is not
157
+ configured, Claude requests do not infer or attach a reasoning effort.
162
158
 
163
159
  ## Environment overrides
164
160
 
@@ -168,8 +164,7 @@ If Claude-side reasoning is not configured, Claude requests fall back to
168
164
  | `COPILOT_ACCOUNT_TYPE` | `individual` \| `business` \| `enterprise`. |
169
165
  | `COPILOT_BASE_URL` | Override the upstream Copilot base URL. |
170
166
  | `COPILOT_VSCODE_VERSION` | Override the VS Code version sent upstream. |
171
- | `MODEL_REASONING_EFFORT` | Claude-side default reasoning effort (preferred key). |
172
- | `COPILOT_REASONING_EFFORT` | Alias of `MODEL_REASONING_EFFORT` (backward compatible). |
167
+ | `MODEL_REASONING_EFFORT` | Claude-side reasoning effort override. |
173
168
 
174
169
 
175
170
 
@@ -217,13 +212,11 @@ accepts upstream.
217
212
 
218
213
  ### Reasoning effort
219
214
 
220
- If an unsupported value is sent for a reasoning-capable model, the bridge
221
- falls back to the model's default (`medium` for the GPT-5 / Claude Opus 4.7
222
- families) instead of forwarding an invalid request upstream. Set the default
223
- globally via `MODEL_REASONING_EFFORT` (or `COPILOT_REASONING_EFFORT` alias)
224
- (env, or `env` in
225
- `~/.claude/settings.json`); per-request `reasoning_effort` (or Anthropic
226
- `thinking.budget_tokens`) takes precedence.
215
+ For OpenAI-compatible clients, unsupported reasoning values are clamped to the
216
+ model capability table instead of being forwarded upstream. Claude-side
217
+ reasoning can be set globally via `MODEL_REASONING_EFFORT` (env, or `env` in
218
+ `~/.claude/settings.json`); invalid Claude-side values are ignored, and
219
+ per-request `reasoning_effort` takes precedence.
227
220
 
228
221
  ## Development
229
222
 
package/dist/main.js CHANGED
@@ -808,7 +808,7 @@ var RateLimitError = class extends Error {
808
808
 
809
809
  //#endregion
810
810
  //#region src/services/copilot/responses.ts
811
- const RESPONSES_ONLY_MODEL_PATTERN = /^(?:gpt-5\.3-codex|gpt-5\.4-mini)(?:-|$)/i;
811
+ const RESPONSES_ONLY_MODEL_PATTERN = /^(?:gpt-5\.5|gpt-5\.4-mini|gpt-5\.3-codex|gpt-5\.2-codex)(?:-|$)/i;
812
812
  function shouldUseResponsesApiForModel(model) {
813
813
  return RESPONSES_ONLY_MODEL_PATTERN.test(model);
814
814
  }
@@ -1070,18 +1070,18 @@ const getEnvValueCaseInsensitive = (env, key) => {
1070
1070
  };
1071
1071
  const getConfiguredReasoningEffort = (client, claudeSettingsEnv) => {
1072
1072
  if (client !== "claude") return;
1073
- return process.env.MODEL_REASONING_EFFORT ?? process.env.COPILOT_REASONING_EFFORT ?? getEnvValueCaseInsensitive(claudeSettingsEnv, "MODEL_REASONING_EFFORT") ?? getEnvValueCaseInsensitive(claudeSettingsEnv, "COPILOT_REASONING_EFFORT");
1073
+ return process.env.MODEL_REASONING_EFFORT ?? getEnvValueCaseInsensitive(claudeSettingsEnv, "MODEL_REASONING_EFFORT");
1074
1074
  };
1075
1075
  const getRequestedReasoningEffort = (payload, claudeSettingsEnv, client) => {
1076
1076
  const configuredReasoningEffort = getConfiguredReasoningEffort(client, claudeSettingsEnv);
1077
- const defaultEffort = client === "claude" ? clampReasoningEffort(payload.model, void 0)?.effort : defaultReasoningEffort(payload.model);
1077
+ const defaultEffort = client === "claude" ? void 0 : defaultReasoningEffort(payload.model);
1078
1078
  const requestedReasoningEffort = payload.reasoning_effort ?? normalizeReasoningEffort$1(configuredReasoningEffort);
1079
1079
  return sanitizeReasoningEffortForModel(payload.model, requestedReasoningEffort) ?? defaultEffort;
1080
1080
  };
1081
1081
  const getRequestedClaudeOpus47Effort = (payload, claudeSettingsEnv, client) => {
1082
1082
  if (!isClaudeOpus47Model$1(payload.model)) return;
1083
1083
  const configuredReasoningEffort = getConfiguredReasoningEffort(client, claudeSettingsEnv);
1084
- return payload.output_config?.effort ?? normalizeClaudeOpus47Effort(payload.reasoning_effort) ?? normalizeClaudeOpus47Effort(configuredReasoningEffort) ?? (client === "claude" ? "medium" : void 0);
1084
+ return payload.output_config?.effort ?? normalizeClaudeOpus47Effort(payload.reasoning_effort) ?? normalizeClaudeOpus47Effort(configuredReasoningEffort);
1085
1085
  };
1086
1086
  const sanitizeUserIdentifier = (user) => {
1087
1087
  if (!user) return;
@@ -1422,8 +1422,9 @@ function normalizeReasoningEffort(value) {
1422
1422
  }
1423
1423
  function translateReasoningEffort(payload, settings) {
1424
1424
  const modelId = translateModelName(payload.model, settings);
1425
- if (isClaudeModel(modelId)) return;
1425
+ if (isClaudeOpus47Model(modelId)) return;
1426
1426
  if (payload.reasoning_effort) return sanitizeReasoningEffortForModel(modelId, normalizeReasoningEffort(payload.reasoning_effort));
1427
+ if (isClaudeModel(modelId)) return;
1427
1428
  if (payload.thinking?.type !== "enabled") return;
1428
1429
  const budgetTokens = payload.thinking.budget_tokens;
1429
1430
  if (budgetTokens === void 0) return sanitizeReasoningEffortForModel(modelId, "medium");
@@ -1433,8 +1434,10 @@ function translateReasoningEffort(payload, settings) {
1433
1434
  return sanitizeReasoningEffortForModel(modelId, "xhigh");
1434
1435
  }
1435
1436
  function translateToOpenAI(payload, settings) {
1437
+ const model = translateModelName(payload.model, settings);
1438
+ const tools = translateAnthropicToolsToOpenAI(payload.tools);
1436
1439
  return {
1437
- model: translateModelName(payload.model, settings),
1440
+ model,
1438
1441
  messages: translateAnthropicMessagesToOpenAI(payload.messages, payload.system),
1439
1442
  max_tokens: payload.max_tokens,
1440
1443
  stop: payload.stop_sequences,
@@ -1445,8 +1448,8 @@ function translateToOpenAI(payload, settings) {
1445
1448
  output_config: translateOutputConfig(payload, settings),
1446
1449
  reasoning_effort: translateReasoningEffort(payload, settings),
1447
1450
  user: payload.metadata?.user_id,
1448
- tools: translateAnthropicToolsToOpenAI(payload.tools),
1449
- tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice)
1451
+ tools,
1452
+ tool_choice: tools && tools.length > 0 ? translateAnthropicToolChoiceToOpenAI(payload.tool_choice) : void 0
1450
1453
  };
1451
1454
  }
1452
1455
  function translateAnthropicMessagesToOpenAI(anthropicMessages, system) {
@@ -1538,7 +1541,7 @@ function mapContent(content) {
1538
1541
  return contentParts;
1539
1542
  }
1540
1543
  function translateAnthropicToolsToOpenAI(anthropicTools) {
1541
- if (!anthropicTools) return;
1544
+ if (!anthropicTools || anthropicTools.length === 0) return;
1542
1545
  return anthropicTools.map((tool) => ({
1543
1546
  type: "function",
1544
1547
  function: {
package/dist/main.js.map CHANGED
@@ -1 +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","merged: Record<string, string>","model: string | undefined","parsed: Record<string, unknown>","env: Record<string, unknown>","next: Record<string, unknown>","lines: Array<string>","out: CodexUserConfig","CODEX_DEFAULTS: CodexDefaults","MODEL_CAPABILITIES: ReadonlyArray<ModelCapability>","entries: Array<readonly [string, ModelCapability]>","order: ReadonlyArray<ReasoningEffort>","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/claude-settings.ts","../src/lib/claude-launch.ts","../src/lib/codex-config.ts","../src/lib/defaults.ts","../src/lib/model-capabilities.ts","../src/lib/rate-limit.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 os from \"node:os\"\nimport path from \"node:path\"\n\nimport consola from \"consola\"\n\ninterface ClaudeSettingsFile {\n env?: Record<string, unknown>\n model?: unknown\n}\n\nexport interface ClaudeSettings {\n env: Record<string, string>\n model?: string\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\n/**\n * Read just the `ANTHROPIC_BASE_URL` from a single Claude settings file.\n * Used at startup so the user can pin the bridge port by editing one place\n * instead of passing `--port` every time.\n */\nexport const readClaudeBaseUrl = async (\n configPath: string,\n): Promise<string | undefined> => {\n const settings = await readClaudeSettingsFile(configPath)\n const value = settings?.env?.ANTHROPIC_BASE_URL\n return typeof value === \"string\" ? value : undefined\n}\n\n/**\n * Parse the port from an `ANTHROPIC_BASE_URL`-style string. Returns\n * `undefined` if the URL is malformed or has no explicit port.\n */\nexport const parsePortFromBaseUrl = (\n baseUrl: string | undefined,\n): number | undefined => {\n if (!baseUrl) return undefined\n try {\n const url = new URL(baseUrl)\n if (!url.port) return undefined\n const port = Number.parseInt(url.port, 10)\n return Number.isFinite(port) && port > 0 ? port : undefined\n } catch {\n return undefined\n }\n}\n\nexport const getClaudeSettings = async (): Promise<ClaudeSettings> => {\n const merged: Record<string, string> = {}\n let model: string | undefined\n\n for (const filePath of getClaudeSettingsPaths()) {\n const settings = await readClaudeSettingsFile(filePath)\n\n if (typeof settings?.model === \"string\") {\n model = settings.model\n }\n\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 { env: merged, model }\n}\n\nexport const getClaudeSettingsEnv = async (): Promise<\n Record<string, string>\n> => (await getClaudeSettings()).env\n\ninterface ApplyClaudeConfigInput {\n baseUrl: string\n configPath: string\n}\n\ninterface ApplyClaudeResult {\n configPath: string\n changed: boolean\n created: boolean\n previousBaseUrl?: string\n}\n\n/**\n * Update `~/.claude/settings.json` so its env block points Claude Code at the\n * running bridge. Preserves all unrelated keys (model overrides, plugins,\n * marketplaces, etc.). Sets a dummy auth token only if none is present.\n */\nexport async function applyClaudeConfig(\n input: ApplyClaudeConfigInput,\n): Promise<ApplyClaudeResult> {\n const { configPath, baseUrl } = input\n\n let raw = \"\"\n let created = false\n try {\n raw = await fs.readFile(configPath, \"utf8\")\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n created = true\n } else {\n throw error\n }\n }\n\n let parsed: Record<string, unknown> = {}\n if (raw.trim().length > 0) {\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n parsed = {}\n }\n } catch {\n // Refuse to overwrite a malformed file; bail without changes.\n return { configPath, changed: false, created: false }\n }\n }\n\n const env: Record<string, unknown> =\n typeof parsed.env === \"object\"\n && parsed.env !== null\n && !Array.isArray(parsed.env)\n ? { ...(parsed.env as Record<string, unknown>) }\n : {}\n\n const previousBaseUrl =\n typeof env.ANTHROPIC_BASE_URL === \"string\"\n ? (env.ANTHROPIC_BASE_URL as string)\n : undefined\n\n env.ANTHROPIC_BASE_URL = baseUrl\n if (typeof env.ANTHROPIC_AUTH_TOKEN !== \"string\" || !env.ANTHROPIC_AUTH_TOKEN) {\n env.ANTHROPIC_AUTH_TOKEN = \"dummy\"\n }\n\n const next: Record<string, unknown> = { ...parsed, env }\n const serialized = `${JSON.stringify(next, null, 2)}\\n`\n\n if (serialized === raw) {\n return { configPath, changed: false, created: false, previousBaseUrl }\n }\n\n await fs.mkdir(path.dirname(configPath), { recursive: true })\n await fs.writeFile(configPath, serialized)\n return { configPath, changed: true, created, previousBaseUrl }\n}\n","const shellQuote = (value: string): string => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`\n\nexport interface ClaudeLaunchDefaults {\n model: string\n}\n\nexport interface ClaudeLaunchCommandInput extends ClaudeLaunchDefaults {\n baseUrl: string\n}\n\nexport const pickClaudeLaunchDefaults = (\n availableModels: Array<string>,\n preferredModel?: string,\n): ClaudeLaunchDefaults => {\n const model =\n preferredModel && availableModels.includes(preferredModel) ? preferredModel\n : availableModels.includes(\"gpt-5.3-codex\") ? \"gpt-5.3-codex\"\n : availableModels[0] ?? \"gpt-5.3-codex\"\n\n return { model }\n}\n\nexport const buildClaudeLaunchCommand = (\n input: ClaudeLaunchCommandInput,\n): string => {\n const env = {\n ANTHROPIC_BASE_URL: input.baseUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n }\n\n return `${Object.entries(env)\n .map(([key, value]) => `${key}=${shellQuote(value)}`)\n .join(\" \")} && claude --model ${shellQuote(input.model)}`\n}","import fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CodexDefaults } from \"./defaults\"\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: CodexDefaults\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","import os from \"node:os\"\nimport path from \"node:path\"\n\n/**\n * Static defaults for the bridge. Previously these lived in\n * `~/.config/copilot-bridge/settings.json`, but that file ended up being a\n * silent third source of truth (alongside `~/.codex/config.toml` and\n * `~/.claude/settings.json`) which caused subtle port-mismatch bugs. The\n * bridge now relies on these defaults plus CLI flags only — every other\n * persisted state lives in the consumer config files (codex / claude).\n */\n\nexport interface CodexDefaults {\n providerId: string\n providerName: string\n setAsDefault: boolean\n configPath: string\n}\n\nexport const DEFAULT_HOST = \"127.0.0.1\"\nexport const DEFAULT_PORT = 4142\n\nexport const CODEX_DEFAULTS: CodexDefaults = {\n providerId: \"bridge\",\n providerName: \"Copilot Bridge\",\n setAsDefault: true,\n configPath: path.join(os.homedir(), \".codex\", \"config.toml\"),\n}\n\nexport const CLAUDE_CONFIG_PATH = path.join(\n os.homedir(),\n \".claude\",\n \"settings.json\",\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 type TextVerbosity = \"low\" | \"medium\" | \"high\"\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 textVerbosity?: {\n supported: ReadonlyArray<TextVerbosity>\n default: TextVerbosity\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 textVerbosity: {\n supported: [\"medium\"],\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 const isTextVerbosity = (value: unknown): value is TextVerbosity =>\n value === \"low\" || value === \"medium\" || value === \"high\"\n\nconst normalizeRequestedReasoningEffort = (requested: unknown): unknown =>\n requested === \"minimal\" ? \"low\" : requested\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 const normalizedRequested = normalizeRequestedReasoningEffort(requested)\n\n if (!isReasoningEffort(normalizedRequested)) {\n return {\n effort: defaultEffort,\n changed: true,\n reason: \"unsupported-effort\",\n }\n }\n\n if (supported.includes(normalizedRequested)) {\n return {\n effort: normalizedRequested,\n changed: normalizedRequested !== requested,\n reason:\n normalizedRequested !== requested ? \"unsupported-effort\" : undefined,\n }\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(normalizedRequested)\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 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 { 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 { clampReasoningEffort } from \"~/lib/model-capabilities\"\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.startsWith(\"claude-opus-4.7\")\n\ntype ClaudeOpus47Effort = NonNullable<\n NonNullable<ChatCompletionsPayload[\"output_config\"]>[\"effort\"]\n>\n\ntype ClientKind = \"claude\" | \"codex\" | \"generic\"\n\nconst MAX_USER_LENGTH = 64\n\nconst defaultReasoningEffort = (\n modelId: string,\n): ChatCompletionsPayload[\"reasoning_effort\"] =>\n usesMaxCompletionTokens(modelId) ? \"medium\" : undefined\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 clampReasoningEffort(modelId, reasoningEffort)?.effort\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 getEnvValueCaseInsensitive = (\n env: Record<string, string>,\n key: string,\n): string | undefined => {\n const direct = env[key]\n if (typeof direct === \"string\") {\n return direct\n }\n const lower = key.toLowerCase()\n const matched = Object.entries(env).find(([k]) => k.toLowerCase() === lower)\n return matched?.[1]\n}\n\nconst getConfiguredReasoningEffort = (\n client: ClientKind,\n claudeSettingsEnv: Record<string, string>,\n): string | undefined => {\n if (client !== \"claude\") {\n return undefined\n }\n\n return (\n // Prefer the normalized key name, keep COPILOT_* as a compatibility alias.\n process.env.MODEL_REASONING_EFFORT\n ?? process.env.COPILOT_REASONING_EFFORT\n ?? getEnvValueCaseInsensitive(claudeSettingsEnv, \"MODEL_REASONING_EFFORT\")\n ?? getEnvValueCaseInsensitive(claudeSettingsEnv, \"COPILOT_REASONING_EFFORT\")\n )\n}\n\nconst getRequestedReasoningEffort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n client: ClientKind,\n): ChatCompletionsPayload[\"reasoning_effort\"] => {\n const configuredReasoningEffort = getConfiguredReasoningEffort(\n client,\n claudeSettingsEnv,\n )\n\n const defaultEffort =\n client === \"claude\" ?\n clampReasoningEffort(payload.model, undefined)?.effort\n : defaultReasoningEffort(payload.model)\n\n const requestedReasoningEffort =\n payload.reasoning_effort\n ?? normalizeReasoningEffort(configuredReasoningEffort)\n\n return (\n sanitizeReasoningEffortForModel(payload.model, requestedReasoningEffort)\n ?? defaultEffort\n )\n}\n\nconst getRequestedClaudeOpus47Effort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n client: ClientKind,\n): ClaudeOpus47Effort | undefined => {\n if (!isClaudeOpus47Model(payload.model)) {\n return undefined\n }\n\n const configuredReasoningEffort = getConfiguredReasoningEffort(\n client,\n claudeSettingsEnv,\n )\n\n return (\n payload.output_config?.effort\n ?? normalizeClaudeOpus47Effort(payload.reasoning_effort)\n ?? normalizeClaudeOpus47Effort(configuredReasoningEffort)\n ?? (client === \"claude\" ? \"medium\" : undefined)\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 client: ClientKind,\n): ChatCompletionsRequestPayload => {\n const requestedReasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n client,\n )\n const requestedClaudeOpus47Effort = getRequestedClaudeOpus47Effort(\n payload,\n claudeSettingsEnv,\n client,\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 shouldAttachReasoningEffort = !isClaudeOpus47Model(payload.model)\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 shouldAttachReasoningEffort ? reasoningEffort : undefined,\n user: sanitizeUserIdentifier(payload.user),\n }\n\n return sanitizedPayload\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 options?: { client?: ClientKind },\n) => {\n const provider = getCopilotProviderContext(config)\n const enableVision = messagesIncludeImage(payload.messages)\n const initiator = isAgentInitiator(payload.messages)\n const client = options?.client ?? \"generic\"\n const claudeSettingsEnv =\n client === \"claude\" ? await getClaudeSettingsEnv() : {}\n const requestPayload = buildRequestPayload(payload, claudeSettingsEnv, client)\n\n if (shouldUseResponsesApiForModel(payload.model)) {\n return createResponses(provider, payload, claudeSettingsEnv, client, {\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, client, {\n vision: enableVision,\n initiator,\n })\n }\n\n await logUpstreamError(\"Failed to create chat completions\", response, {\n model: payload.model,\n route: \"/chat/completions\",\n })\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 client: ClientKind,\n options: { vision: boolean; initiator: \"agent\" | \"user\" },\n) {\n const reasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n client,\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 await logUpstreamError(\"Failed to create responses\", response, {\n model: payload.model,\n route: \"/responses\",\n })\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 logUpstreamError(\n message: string,\n response: Response,\n context: { model: string; route: string },\n): Promise<void> {\n const errorBody = await response.clone().text().catch(() => \"\")\n\n consola.error(message, {\n route: context.route,\n model: context.model,\n status: response.status,\n statusText: response.statusText,\n body: errorBody || undefined,\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 client: \"generic\",\n })\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 const claudeSnapshotMatch = id.match(\n /^claude-(opus|sonnet|haiku)-(\\d)-(\\d)(-1m)?(?:-\\d{8})?$/,\n )\n if (claudeSnapshotMatch) {\n const [, family, major, minor, contextWindow = \"\"] = claudeSnapshotMatch\n return `claude-${family}-${major}.${minor}${contextWindow}`\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 canonicalClaudeMatch = canonicalModelId.match(\n /^claude-(opus|sonnet|haiku)-(\\d+)\\.(\\d+)(-1m)?$/,\n )\n if (canonicalClaudeMatch) {\n const [, family, major, minor, contextWindow = \"\"] = canonicalClaudeMatch\n aliases.add(`claude-${family}-${major}-${minor}${contextWindow}`)\n return [...aliases]\n }\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 type { ClaudeSettings } from \"~/lib/claude-settings\"\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 trimmed = model.trim().toLowerCase()\n\n if (trimmed === \"opus[1m]\") {\n return \"claude-opus-4.6-1m\"\n }\n\n const normalized = trimmed.replace(/\\[1m\\]$/, \"\")\n\n if (normalized === \"opus\") {\n return \"claude-opus\"\n }\n\n if (normalized === \"sonnet\") {\n return \"claude-sonnet\"\n }\n\n if (normalized === \"haiku\") {\n return \"claude-haiku\"\n }\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\nconst getConfiguredClaudeDefaultModel = (\n settings: Pick<ClaudeSettings, \"env\" | \"model\"> | undefined,\n): string | undefined => {\n if (!settings) {\n return undefined\n }\n\n const env = settings.env ?? {}\n const topLevelModel = settings.model?.trim()\n const anthropicModel = env.ANTHROPIC_MODEL\n\n if (!topLevelModel) {\n return anthropicModel\n }\n\n switch (topLevelModel.toLowerCase()) {\n case \"opus[1m]\": {\n return env.ANTHROPIC_DEFAULT_OPUS_MODEL ?? topLevelModel\n }\n case \"opus\": {\n return env.ANTHROPIC_DEFAULT_OPUS_MODEL ?? topLevelModel\n }\n case \"sonnet\": {\n return env.ANTHROPIC_DEFAULT_SONNET_MODEL ?? topLevelModel\n }\n case \"haiku\": {\n return (\n env.ANTHROPIC_DEFAULT_HAIKU_MODEL\n ?? env.ANTHROPIC_SMALL_FAST_MODEL\n ?? topLevelModel\n )\n }\n default: {\n return topLevelModel\n }\n }\n}\n\nconst resolveClaudeRequestedModel = (\n model: string,\n settings: Pick<ClaudeSettings, \"env\" | \"model\"> | undefined,\n): string => {\n if (model.trim().toLowerCase() !== \"definitely-not-a-real-model\") {\n return model\n }\n\n return getConfiguredClaudeDefaultModel(settings) ?? model\n}\n\nfunction translateModelName(\n model: string,\n settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): string {\n const requestedModel = resolveClaudeRequestedModel(model, settings)\n return resolveUpstreamModelId(normalizeClaudeModelAlias(requestedModel))\n}\n\nfunction isClaudeModel(modelId: string): boolean {\n return modelId.startsWith(\"claude-\")\n}\n\nfunction isClaudeOpus47Model(modelId: string): boolean {\n return modelId.startsWith(\"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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"thinking\"] {\n const modelId = translateModelName(payload.model, settings)\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"output_config\"] {\n const modelId = translateModelName(payload.model, settings)\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"reasoning_effort\"] {\n const modelId = translateModelName(payload.model, settings)\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload {\n const model = translateModelName(payload.model, settings)\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, settings),\n output_config: translateOutputConfig(payload, settings),\n reasoning_effort: translateReasoningEffort(payload, settings),\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 { getClaudeSettings } from \"~/lib/claude-settings\"\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 claudeSettings = await getClaudeSettings()\n const openAIPayload = translateToOpenAI(anthropicPayload, claudeSettings)\n\n try {\n const response = await createChatCompletions(config, openAIPayload, {\n client: \"claude\",\n })\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 claudeSettings = await getClaudeSettings()\n const openAIPayload = translateToOpenAI(anthropicPayload, claudeSettings)\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 isTextVerbosity,\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\ninterface TextField {\n verbosity?: 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; text?: TextField }\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 const text = isPlainObject(next.text) ? (next.text as TextField) : undefined\n if (text && capability.textVerbosity && \"verbosity\" in text) {\n const { supported, default: defaultVerbosity } = capability.textVerbosity\n const verbosity = text.verbosity\n next.text = {\n ...text,\n verbosity:\n isTextVerbosity(verbosity) && supported.includes(verbosity) ?\n verbosity\n : defaultVerbosity,\n }\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-bridge\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 applyClaudeConfig,\n parsePortFromBaseUrl,\n readClaudeBaseUrl,\n} from \"~/lib/claude-settings\"\nimport {\n buildClaudeLaunchCommand,\n pickClaudeLaunchDefaults,\n} from \"~/lib/claude-launch\"\nimport {\n applyCodexConfig,\n readCodexUserConfigFromDisk,\n} from \"~/lib/codex-config\"\nimport { readBridgeConfig } from \"~/lib/config\"\nimport {\n CLAUDE_CONFIG_PATH,\n CODEX_DEFAULTS,\n DEFAULT_HOST,\n DEFAULT_PORT,\n} from \"~/lib/defaults\"\nimport {\n getModelCapability,\n MODEL_CAPABILITIES,\n} from \"~/lib/model-capabilities\"\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 (default: ${DEFAULT_HOST}).`,\n },\n port: {\n type: \"string\",\n description: `Port to listen on (default: ${DEFAULT_PORT}).`,\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Print GitHub and Copilot tokens during startup.\",\n },\n \"codex-setup\": {\n type: \"boolean\",\n default: true,\n description: \"Skip writing the bridge provider into ~/.codex/config.toml.\",\n },\n \"claude-setup\": {\n type: \"boolean\",\n default: true,\n description:\n \"Skip writing ANTHROPIC_BASE_URL into ~/.claude/settings.json.\",\n },\n \"claude-code\": {\n type: \"boolean\",\n default: false,\n description:\n \"Print a one-shot `export ... && claude` command and do not modify user config files.\",\n },\n \"select-model\": {\n type: \"boolean\",\n default: false,\n description:\n \"Force the model picker even when ~/.codex/config.toml already has a model.\",\n },\n prompt: {\n type: \"boolean\",\n default: true,\n description:\n \"Never prompt; use the existing model from ~/.codex/config.toml 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 // Port resolution priority (high → low):\n // 1. --port CLI flag\n // 2. $PORT environment variable\n // 3. ANTHROPIC_BASE_URL port in ~/.claude/settings.json\n // 4. DEFAULT_PORT\n // Once resolved, the chosen port is written back to BOTH claude\n // settings and codex config so the three sources stay in lockstep.\n const claudeConfigPath = CLAUDE_CONFIG_PATH\n const claudePort = parsePortFromBaseUrl(\n await readClaudeBaseUrl(claudeConfigPath),\n )\n const envPortRaw = process.env.PORT\n const envPort =\n envPortRaw && Number.isFinite(Number(envPortRaw)) ?\n Number(envPortRaw)\n : undefined\n\n const host = args.host ? String(args.host) : DEFAULT_HOST\n const port =\n args.port ? Number(args.port)\n : envPort !== undefined ? envPort\n : claudePort !== undefined ? claudePort\n : DEFAULT_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 baseUrl = `http://${config.host}:${config.port}`\n const codexConfigPath = CODEX_DEFAULTS.configPath\n const isClaudeCodeMode = Boolean(args[\"claude-code\"])\n\n // Sync Claude Code's settings.json and Codex's config.toml *before* any\n // potentially blocking interactive prompt. This guarantees `claude` and\n // `codex` work the moment the server is listening — even if the user\n // never answers the model picker below.\n if (isClaudeCodeMode) {\n consola.info(\n \"--claude-code mode: not modifying ~/.claude/settings.json or ~/.codex/config.toml\",\n )\n }\n\n if (!isClaudeCodeMode && args[\"claude-setup\"]) {\n try {\n const claudeResult = await applyClaudeConfig({\n baseUrl,\n configPath: claudeConfigPath,\n })\n if (claudeResult.changed) {\n consola.success(\n `claude settings ${claudeResult.created ? \"created\" : \"updated\"}: ${claudeResult.configPath}`,\n )\n if (\n claudeResult.previousBaseUrl\n && claudeResult.previousBaseUrl !== baseUrl\n ) {\n consola.info(\n `ANTHROPIC_BASE_URL: ${claudeResult.previousBaseUrl} → ${baseUrl}`,\n )\n }\n } else {\n consola.info(\n `claude settings already up to date: ${claudeResult.configPath}`,\n )\n }\n } catch (error) {\n consola.warn(\n `Could not update claude settings (${claudeConfigPath}):`,\n error,\n )\n }\n }\n\n // Read the user's current codex model so the picker can default to it,\n // and so we can stamp the managed block immediately even if the picker\n // is skipped or interrupted.\n const codexUserConfig = await readCodexUserConfigFromDisk(codexConfigPath)\n let chosenModel: string | undefined = codexUserConfig.model\n let chosenEffort: string | undefined =\n codexUserConfig.modelReasoningEffort\n\n if (chosenModel && !chosenEffort) {\n consola.info(\n `codex model_reasoning_effort not set; using ${chosenModel}'s default reasoning effort`,\n )\n }\n\n if (!isClaudeCodeMode && args[\"codex-setup\"]) {\n try {\n const result = await applyCodexConfig({\n baseUrl: `${baseUrl}/v1`,\n configPath: codexConfigPath,\n settings: CODEX_DEFAULTS,\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 (CODEX_DEFAULTS.setAsDefault) {\n consola.info(\n `codex now defaults to provider \"${CODEX_DEFAULTS.providerId}\". Run \\`codex exec \"...\"\\` directly.`,\n )\n } else {\n consola.info(\n `provider \"${CODEX_DEFAULTS.providerId}\" registered. Use \\`codex -c model_provider=\"${CODEX_DEFAULTS.providerId}\" ...\\``,\n )\n }\n } else {\n consola.info(`codex config already up to date: ${result.configPath}`)\n }\n } catch (error) {\n consola.warn(\n `Could not update codex config (${codexConfigPath}):`,\n error,\n )\n }\n }\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 consola.box(\n [\n `🌐 Usage viewer`,\n ``,\n ` https://betahi.github.io/copilot-bridge?endpoint=${baseUrl}/usage`,\n ].join(\"\\n\"),\n )\n\n const shouldPrompt =\n !isClaudeCodeMode\n &&\n args.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 ${codexConfigPath})`,\n {\n type: \"select\",\n options: finalPickable,\n initial: defaultId,\n },\n )) as string\n if (selected && selected !== chosenModel) {\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 // Re-stamp codex config with the user's freshly picked model.\n if (args[\"codex-setup\"]) {\n try {\n const result = await applyCodexConfig({\n baseUrl: `${baseUrl}/v1`,\n configPath: codexConfigPath,\n settings: CODEX_DEFAULTS,\n model: chosenModel,\n modelReasoningEffort: chosenEffort,\n })\n if (result.changed) {\n consola.success(`codex config updated: ${result.configPath}`)\n }\n } catch (error) {\n consola.warn(\n `Could not update codex config (${codexConfigPath}):`,\n error,\n )\n }\n }\n }\n }\n\n if (isClaudeCodeMode) {\n const defaults = pickClaudeLaunchDefaults(finalPickable, chosenModel)\n let selectedModel = defaults.model\n\n if (args.prompt && finalPickable.length > 0) {\n selectedModel = (await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: finalPickable,\n initial: defaults.model,\n },\n )) as string\n }\n\n const command = buildClaudeLaunchCommand({\n baseUrl,\n model: selectedModel,\n })\n\n consola.box(\n [\n \"Claude one-shot command\",\n \"\",\n ` ${command}`,\n \"\",\n \" The bridge verified this path with explicit --model; current Claude CLI did not reliably honor ANTHROPIC_MODEL env defaults.\",\n ].join(\"\\n\"),\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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"}
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","merged: Record<string, string>","model: string | undefined","parsed: Record<string, unknown>","env: Record<string, unknown>","next: Record<string, unknown>","lines: Array<string>","out: CodexUserConfig","CODEX_DEFAULTS: CodexDefaults","MODEL_CAPABILITIES: ReadonlyArray<ModelCapability>","entries: Array<readonly [string, ModelCapability]>","order: ReadonlyArray<ReasoningEffort>","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/claude-settings.ts","../src/lib/claude-launch.ts","../src/lib/codex-config.ts","../src/lib/defaults.ts","../src/lib/model-capabilities.ts","../src/lib/rate-limit.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 os from \"node:os\"\nimport path from \"node:path\"\n\nimport consola from \"consola\"\n\ninterface ClaudeSettingsFile {\n env?: Record<string, unknown>\n model?: unknown\n}\n\nexport interface ClaudeSettings {\n env: Record<string, string>\n model?: string\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\n/**\n * Read just the `ANTHROPIC_BASE_URL` from a single Claude settings file.\n * Used at startup so the user can pin the bridge port by editing one place\n * instead of passing `--port` every time.\n */\nexport const readClaudeBaseUrl = async (\n configPath: string,\n): Promise<string | undefined> => {\n const settings = await readClaudeSettingsFile(configPath)\n const value = settings?.env?.ANTHROPIC_BASE_URL\n return typeof value === \"string\" ? value : undefined\n}\n\n/**\n * Parse the port from an `ANTHROPIC_BASE_URL`-style string. Returns\n * `undefined` if the URL is malformed or has no explicit port.\n */\nexport const parsePortFromBaseUrl = (\n baseUrl: string | undefined,\n): number | undefined => {\n if (!baseUrl) return undefined\n try {\n const url = new URL(baseUrl)\n if (!url.port) return undefined\n const port = Number.parseInt(url.port, 10)\n return Number.isFinite(port) && port > 0 ? port : undefined\n } catch {\n return undefined\n }\n}\n\nexport const getClaudeSettings = async (): Promise<ClaudeSettings> => {\n const merged: Record<string, string> = {}\n let model: string | undefined\n\n for (const filePath of getClaudeSettingsPaths()) {\n const settings = await readClaudeSettingsFile(filePath)\n\n if (typeof settings?.model === \"string\") {\n model = settings.model\n }\n\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 { env: merged, model }\n}\n\nexport const getClaudeSettingsEnv = async (): Promise<\n Record<string, string>\n> => (await getClaudeSettings()).env\n\ninterface ApplyClaudeConfigInput {\n baseUrl: string\n configPath: string\n}\n\ninterface ApplyClaudeResult {\n configPath: string\n changed: boolean\n created: boolean\n previousBaseUrl?: string\n}\n\n/**\n * Update `~/.claude/settings.json` so its env block points Claude Code at the\n * running bridge. Preserves all unrelated keys (model overrides, plugins,\n * marketplaces, etc.). Sets a dummy auth token only if none is present.\n */\nexport async function applyClaudeConfig(\n input: ApplyClaudeConfigInput,\n): Promise<ApplyClaudeResult> {\n const { configPath, baseUrl } = input\n\n let raw = \"\"\n let created = false\n try {\n raw = await fs.readFile(configPath, \"utf8\")\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n created = true\n } else {\n throw error\n }\n }\n\n let parsed: Record<string, unknown> = {}\n if (raw.trim().length > 0) {\n try {\n parsed = JSON.parse(raw) as Record<string, unknown>\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n parsed = {}\n }\n } catch {\n // Refuse to overwrite a malformed file; bail without changes.\n return { configPath, changed: false, created: false }\n }\n }\n\n const env: Record<string, unknown> =\n typeof parsed.env === \"object\"\n && parsed.env !== null\n && !Array.isArray(parsed.env)\n ? { ...(parsed.env as Record<string, unknown>) }\n : {}\n\n const previousBaseUrl =\n typeof env.ANTHROPIC_BASE_URL === \"string\"\n ? (env.ANTHROPIC_BASE_URL as string)\n : undefined\n\n env.ANTHROPIC_BASE_URL = baseUrl\n if (typeof env.ANTHROPIC_AUTH_TOKEN !== \"string\" || !env.ANTHROPIC_AUTH_TOKEN) {\n env.ANTHROPIC_AUTH_TOKEN = \"dummy\"\n }\n\n const next: Record<string, unknown> = { ...parsed, env }\n const serialized = `${JSON.stringify(next, null, 2)}\\n`\n\n if (serialized === raw) {\n return { configPath, changed: false, created: false, previousBaseUrl }\n }\n\n await fs.mkdir(path.dirname(configPath), { recursive: true })\n await fs.writeFile(configPath, serialized)\n return { configPath, changed: true, created, previousBaseUrl }\n}\n","const shellQuote = (value: string): string => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`\n\nexport interface ClaudeLaunchDefaults {\n model: string\n}\n\nexport interface ClaudeLaunchCommandInput extends ClaudeLaunchDefaults {\n baseUrl: string\n}\n\nexport const pickClaudeLaunchDefaults = (\n availableModels: Array<string>,\n preferredModel?: string,\n): ClaudeLaunchDefaults => {\n const model =\n preferredModel && availableModels.includes(preferredModel) ? preferredModel\n : availableModels.includes(\"gpt-5.3-codex\") ? \"gpt-5.3-codex\"\n : availableModels[0] ?? \"gpt-5.3-codex\"\n\n return { model }\n}\n\nexport const buildClaudeLaunchCommand = (\n input: ClaudeLaunchCommandInput,\n): string => {\n const env = {\n ANTHROPIC_BASE_URL: input.baseUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n }\n\n return `${Object.entries(env)\n .map(([key, value]) => `${key}=${shellQuote(value)}`)\n .join(\" \")} && claude --model ${shellQuote(input.model)}`\n}","import fs from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { CodexDefaults } from \"./defaults\"\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: CodexDefaults\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","import os from \"node:os\"\nimport path from \"node:path\"\n\n/**\n * Static defaults for the bridge. Previously these lived in\n * `~/.config/copilot-bridge/settings.json`, but that file ended up being a\n * silent third source of truth (alongside `~/.codex/config.toml` and\n * `~/.claude/settings.json`) which caused subtle port-mismatch bugs. The\n * bridge now relies on these defaults plus CLI flags only — every other\n * persisted state lives in the consumer config files (codex / claude).\n */\n\nexport interface CodexDefaults {\n providerId: string\n providerName: string\n setAsDefault: boolean\n configPath: string\n}\n\nexport const DEFAULT_HOST = \"127.0.0.1\"\nexport const DEFAULT_PORT = 4142\n\nexport const CODEX_DEFAULTS: CodexDefaults = {\n providerId: \"bridge\",\n providerName: \"Copilot Bridge\",\n setAsDefault: true,\n configPath: path.join(os.homedir(), \".codex\", \"config.toml\"),\n}\n\nexport const CLAUDE_CONFIG_PATH = path.join(\n os.homedir(),\n \".claude\",\n \"settings.json\",\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 type TextVerbosity = \"low\" | \"medium\" | \"high\"\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 textVerbosity?: {\n supported: ReadonlyArray<TextVerbosity>\n default: TextVerbosity\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 textVerbosity: {\n supported: [\"medium\"],\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 const isTextVerbosity = (value: unknown): value is TextVerbosity =>\n value === \"low\" || value === \"medium\" || value === \"high\"\n\nconst normalizeRequestedReasoningEffort = (requested: unknown): unknown =>\n requested === \"minimal\" ? \"low\" : requested\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 const normalizedRequested = normalizeRequestedReasoningEffort(requested)\n\n if (!isReasoningEffort(normalizedRequested)) {\n return {\n effort: defaultEffort,\n changed: true,\n reason: \"unsupported-effort\",\n }\n }\n\n if (supported.includes(normalizedRequested)) {\n return {\n effort: normalizedRequested,\n changed: normalizedRequested !== requested,\n reason:\n normalizedRequested !== requested ? \"unsupported-effort\" : undefined,\n }\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(normalizedRequested)\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 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 { 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 =\n /^(?:gpt-5\\.5|gpt-5\\.4-mini|gpt-5\\.3-codex|gpt-5\\.2-codex)(?:-|$)/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 { clampReasoningEffort } from \"~/lib/model-capabilities\"\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.startsWith(\"claude-opus-4.7\")\n\ntype ClaudeOpus47Effort = NonNullable<\n NonNullable<ChatCompletionsPayload[\"output_config\"]>[\"effort\"]\n>\n\ntype ClientKind = \"claude\" | \"codex\" | \"generic\"\n\nconst MAX_USER_LENGTH = 64\n\nconst defaultReasoningEffort = (\n modelId: string,\n): ChatCompletionsPayload[\"reasoning_effort\"] =>\n usesMaxCompletionTokens(modelId) ? \"medium\" : undefined\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 clampReasoningEffort(modelId, reasoningEffort)?.effort\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 getEnvValueCaseInsensitive = (\n env: Record<string, string>,\n key: string,\n): string | undefined => {\n const direct = env[key]\n if (typeof direct === \"string\") {\n return direct\n }\n const lower = key.toLowerCase()\n const matched = Object.entries(env).find(([k]) => k.toLowerCase() === lower)\n return matched?.[1]\n}\n\nconst getConfiguredReasoningEffort = (\n client: ClientKind,\n claudeSettingsEnv: Record<string, string>,\n): string | undefined => {\n if (client !== \"claude\") {\n return undefined\n }\n\n return (\n process.env.MODEL_REASONING_EFFORT\n ?? getEnvValueCaseInsensitive(claudeSettingsEnv, \"MODEL_REASONING_EFFORT\")\n )\n}\n\nconst getRequestedReasoningEffort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n client: ClientKind,\n): ChatCompletionsPayload[\"reasoning_effort\"] => {\n const configuredReasoningEffort = getConfiguredReasoningEffort(\n client,\n claudeSettingsEnv,\n )\n\n const defaultEffort =\n client === \"claude\" ? undefined : defaultReasoningEffort(payload.model)\n\n const requestedReasoningEffort =\n payload.reasoning_effort\n ?? normalizeReasoningEffort(configuredReasoningEffort)\n\n return (\n sanitizeReasoningEffortForModel(payload.model, requestedReasoningEffort)\n ?? defaultEffort\n )\n}\n\nconst getRequestedClaudeOpus47Effort = (\n payload: ChatCompletionsPayload,\n claudeSettingsEnv: Record<string, string>,\n client: ClientKind,\n): ClaudeOpus47Effort | undefined => {\n if (!isClaudeOpus47Model(payload.model)) {\n return undefined\n }\n\n const configuredReasoningEffort = getConfiguredReasoningEffort(\n client,\n claudeSettingsEnv,\n )\n\n return (\n payload.output_config?.effort\n ?? normalizeClaudeOpus47Effort(payload.reasoning_effort)\n ?? normalizeClaudeOpus47Effort(configuredReasoningEffort)\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 client: ClientKind,\n): ChatCompletionsRequestPayload => {\n const requestedReasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n client,\n )\n const requestedClaudeOpus47Effort = getRequestedClaudeOpus47Effort(\n payload,\n claudeSettingsEnv,\n client,\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 shouldAttachReasoningEffort = !isClaudeOpus47Model(payload.model)\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 shouldAttachReasoningEffort ? reasoningEffort : undefined,\n user: sanitizeUserIdentifier(payload.user),\n }\n\n return sanitizedPayload\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 options?: { client?: ClientKind },\n) => {\n const provider = getCopilotProviderContext(config)\n const enableVision = messagesIncludeImage(payload.messages)\n const initiator = isAgentInitiator(payload.messages)\n const client = options?.client ?? \"generic\"\n const claudeSettingsEnv =\n client === \"claude\" ? await getClaudeSettingsEnv() : {}\n const requestPayload = buildRequestPayload(payload, claudeSettingsEnv, client)\n\n if (shouldUseResponsesApiForModel(payload.model)) {\n return createResponses(provider, payload, claudeSettingsEnv, client, {\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, client, {\n vision: enableVision,\n initiator,\n })\n }\n\n await logUpstreamError(\"Failed to create chat completions\", response, {\n model: payload.model,\n route: \"/chat/completions\",\n })\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 client: ClientKind,\n options: { vision: boolean; initiator: \"agent\" | \"user\" },\n) {\n const reasoningEffort = getRequestedReasoningEffort(\n payload,\n claudeSettingsEnv,\n client,\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 await logUpstreamError(\"Failed to create responses\", response, {\n model: payload.model,\n route: \"/responses\",\n })\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 logUpstreamError(\n message: string,\n response: Response,\n context: { model: string; route: string },\n): Promise<void> {\n const errorBody = await response.clone().text().catch(() => \"\")\n\n consola.error(message, {\n route: context.route,\n model: context.model,\n status: response.status,\n statusText: response.statusText,\n body: errorBody || undefined,\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 client: \"generic\",\n })\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 const claudeSnapshotMatch = id.match(\n /^claude-(opus|sonnet|haiku)-(\\d)-(\\d)(-1m)?(?:-\\d{8})?$/,\n )\n if (claudeSnapshotMatch) {\n const [, family, major, minor, contextWindow = \"\"] = claudeSnapshotMatch\n return `claude-${family}-${major}.${minor}${contextWindow}`\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 canonicalClaudeMatch = canonicalModelId.match(\n /^claude-(opus|sonnet|haiku)-(\\d+)\\.(\\d+)(-1m)?$/,\n )\n if (canonicalClaudeMatch) {\n const [, family, major, minor, contextWindow = \"\"] = canonicalClaudeMatch\n aliases.add(`claude-${family}-${major}-${minor}${contextWindow}`)\n return [...aliases]\n }\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 type { ClaudeSettings } from \"~/lib/claude-settings\"\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 trimmed = model.trim().toLowerCase()\n\n if (trimmed === \"opus[1m]\") {\n return \"claude-opus-4.6-1m\"\n }\n\n const normalized = trimmed.replace(/\\[1m\\]$/, \"\")\n\n if (normalized === \"opus\") {\n return \"claude-opus\"\n }\n\n if (normalized === \"sonnet\") {\n return \"claude-sonnet\"\n }\n\n if (normalized === \"haiku\") {\n return \"claude-haiku\"\n }\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\nconst getConfiguredClaudeDefaultModel = (\n settings: Pick<ClaudeSettings, \"env\" | \"model\"> | undefined,\n): string | undefined => {\n if (!settings) {\n return undefined\n }\n\n const env = settings.env ?? {}\n const topLevelModel = settings.model?.trim()\n const anthropicModel = env.ANTHROPIC_MODEL\n\n if (!topLevelModel) {\n return anthropicModel\n }\n\n switch (topLevelModel.toLowerCase()) {\n case \"opus[1m]\": {\n return env.ANTHROPIC_DEFAULT_OPUS_MODEL ?? topLevelModel\n }\n case \"opus\": {\n return env.ANTHROPIC_DEFAULT_OPUS_MODEL ?? topLevelModel\n }\n case \"sonnet\": {\n return env.ANTHROPIC_DEFAULT_SONNET_MODEL ?? topLevelModel\n }\n case \"haiku\": {\n return (\n env.ANTHROPIC_DEFAULT_HAIKU_MODEL\n ?? env.ANTHROPIC_SMALL_FAST_MODEL\n ?? topLevelModel\n )\n }\n default: {\n return topLevelModel\n }\n }\n}\n\nconst resolveClaudeRequestedModel = (\n model: string,\n settings: Pick<ClaudeSettings, \"env\" | \"model\"> | undefined,\n): string => {\n if (model.trim().toLowerCase() !== \"definitely-not-a-real-model\") {\n return model\n }\n\n return getConfiguredClaudeDefaultModel(settings) ?? model\n}\n\nfunction translateModelName(\n model: string,\n settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): string {\n const requestedModel = resolveClaudeRequestedModel(model, settings)\n return resolveUpstreamModelId(normalizeClaudeModelAlias(requestedModel))\n}\n\nfunction isClaudeModel(modelId: string): boolean {\n return modelId.startsWith(\"claude-\")\n}\n\nfunction isClaudeOpus47Model(modelId: string): boolean {\n return modelId.startsWith(\"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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"thinking\"] {\n const modelId = translateModelName(payload.model, settings)\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"output_config\"] {\n const modelId = translateModelName(payload.model, settings)\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload[\"reasoning_effort\"] {\n const modelId = translateModelName(payload.model, settings)\n\n if (isClaudeOpus47Model(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 (isClaudeModel(modelId)) {\n return undefined\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 settings?: Pick<ClaudeSettings, \"env\" | \"model\">,\n): ChatCompletionsPayload {\n const model = translateModelName(payload.model, settings)\n const tools = translateAnthropicToolsToOpenAI(payload.tools)\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, settings),\n output_config: translateOutputConfig(payload, settings),\n reasoning_effort: translateReasoningEffort(payload, settings),\n user: payload.metadata?.user_id,\n tools,\n tool_choice:\n tools && tools.length > 0 ?\n translateAnthropicToolChoiceToOpenAI(payload.tool_choice)\n : undefined,\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 || anthropicTools.length === 0) {\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 { getClaudeSettings } from \"~/lib/claude-settings\"\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 claudeSettings = await getClaudeSettings()\n const openAIPayload = translateToOpenAI(anthropicPayload, claudeSettings)\n\n try {\n const response = await createChatCompletions(config, openAIPayload, {\n client: \"claude\",\n })\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 claudeSettings = await getClaudeSettings()\n const openAIPayload = translateToOpenAI(anthropicPayload, claudeSettings)\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 isTextVerbosity,\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\ninterface TextField {\n verbosity?: 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; text?: TextField }\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 const text = isPlainObject(next.text) ? (next.text as TextField) : undefined\n if (text && capability.textVerbosity && \"verbosity\" in text) {\n const { supported, default: defaultVerbosity } = capability.textVerbosity\n const verbosity = text.verbosity\n next.text = {\n ...text,\n verbosity:\n isTextVerbosity(verbosity) && supported.includes(verbosity) ?\n verbosity\n : defaultVerbosity,\n }\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-bridge\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 applyClaudeConfig,\n parsePortFromBaseUrl,\n readClaudeBaseUrl,\n} from \"~/lib/claude-settings\"\nimport {\n buildClaudeLaunchCommand,\n pickClaudeLaunchDefaults,\n} from \"~/lib/claude-launch\"\nimport {\n applyCodexConfig,\n readCodexUserConfigFromDisk,\n} from \"~/lib/codex-config\"\nimport { readBridgeConfig } from \"~/lib/config\"\nimport {\n CLAUDE_CONFIG_PATH,\n CODEX_DEFAULTS,\n DEFAULT_HOST,\n DEFAULT_PORT,\n} from \"~/lib/defaults\"\nimport {\n getModelCapability,\n MODEL_CAPABILITIES,\n} from \"~/lib/model-capabilities\"\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 (default: ${DEFAULT_HOST}).`,\n },\n port: {\n type: \"string\",\n description: `Port to listen on (default: ${DEFAULT_PORT}).`,\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Print GitHub and Copilot tokens during startup.\",\n },\n \"codex-setup\": {\n type: \"boolean\",\n default: true,\n description: \"Skip writing the bridge provider into ~/.codex/config.toml.\",\n },\n \"claude-setup\": {\n type: \"boolean\",\n default: true,\n description:\n \"Skip writing ANTHROPIC_BASE_URL into ~/.claude/settings.json.\",\n },\n \"claude-code\": {\n type: \"boolean\",\n default: false,\n description:\n \"Print a one-shot `export ... && claude` command and do not modify user config files.\",\n },\n \"select-model\": {\n type: \"boolean\",\n default: false,\n description:\n \"Force the model picker even when ~/.codex/config.toml already has a model.\",\n },\n prompt: {\n type: \"boolean\",\n default: true,\n description:\n \"Never prompt; use the existing model from ~/.codex/config.toml 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 // Port resolution priority (high → low):\n // 1. --port CLI flag\n // 2. $PORT environment variable\n // 3. ANTHROPIC_BASE_URL port in ~/.claude/settings.json\n // 4. DEFAULT_PORT\n // Once resolved, the chosen port is written back to BOTH claude\n // settings and codex config so the three sources stay in lockstep.\n const claudeConfigPath = CLAUDE_CONFIG_PATH\n const claudePort = parsePortFromBaseUrl(\n await readClaudeBaseUrl(claudeConfigPath),\n )\n const envPortRaw = process.env.PORT\n const envPort =\n envPortRaw && Number.isFinite(Number(envPortRaw)) ?\n Number(envPortRaw)\n : undefined\n\n const host = args.host ? String(args.host) : DEFAULT_HOST\n const port =\n args.port ? Number(args.port)\n : envPort !== undefined ? envPort\n : claudePort !== undefined ? claudePort\n : DEFAULT_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 baseUrl = `http://${config.host}:${config.port}`\n const codexConfigPath = CODEX_DEFAULTS.configPath\n const isClaudeCodeMode = Boolean(args[\"claude-code\"])\n\n // Sync Claude Code's settings.json and Codex's config.toml *before* any\n // potentially blocking interactive prompt. This guarantees `claude` and\n // `codex` work the moment the server is listening — even if the user\n // never answers the model picker below.\n if (isClaudeCodeMode) {\n consola.info(\n \"--claude-code mode: not modifying ~/.claude/settings.json or ~/.codex/config.toml\",\n )\n }\n\n if (!isClaudeCodeMode && args[\"claude-setup\"]) {\n try {\n const claudeResult = await applyClaudeConfig({\n baseUrl,\n configPath: claudeConfigPath,\n })\n if (claudeResult.changed) {\n consola.success(\n `claude settings ${claudeResult.created ? \"created\" : \"updated\"}: ${claudeResult.configPath}`,\n )\n if (\n claudeResult.previousBaseUrl\n && claudeResult.previousBaseUrl !== baseUrl\n ) {\n consola.info(\n `ANTHROPIC_BASE_URL: ${claudeResult.previousBaseUrl} → ${baseUrl}`,\n )\n }\n } else {\n consola.info(\n `claude settings already up to date: ${claudeResult.configPath}`,\n )\n }\n } catch (error) {\n consola.warn(\n `Could not update claude settings (${claudeConfigPath}):`,\n error,\n )\n }\n }\n\n // Read the user's current codex model so the picker can default to it,\n // and so we can stamp the managed block immediately even if the picker\n // is skipped or interrupted.\n const codexUserConfig = await readCodexUserConfigFromDisk(codexConfigPath)\n let chosenModel: string | undefined = codexUserConfig.model\n let chosenEffort: string | undefined =\n codexUserConfig.modelReasoningEffort\n\n if (chosenModel && !chosenEffort) {\n consola.info(\n `codex model_reasoning_effort not set; using ${chosenModel}'s default reasoning effort`,\n )\n }\n\n if (!isClaudeCodeMode && args[\"codex-setup\"]) {\n try {\n const result = await applyCodexConfig({\n baseUrl: `${baseUrl}/v1`,\n configPath: codexConfigPath,\n settings: CODEX_DEFAULTS,\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 (CODEX_DEFAULTS.setAsDefault) {\n consola.info(\n `codex now defaults to provider \"${CODEX_DEFAULTS.providerId}\". Run \\`codex exec \"...\"\\` directly.`,\n )\n } else {\n consola.info(\n `provider \"${CODEX_DEFAULTS.providerId}\" registered. Use \\`codex -c model_provider=\"${CODEX_DEFAULTS.providerId}\" ...\\``,\n )\n }\n } else {\n consola.info(`codex config already up to date: ${result.configPath}`)\n }\n } catch (error) {\n consola.warn(\n `Could not update codex config (${codexConfigPath}):`,\n error,\n )\n }\n }\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 consola.box(\n [\n `🌐 Usage viewer`,\n ``,\n ` https://betahi.github.io/copilot-bridge?endpoint=${baseUrl}/usage`,\n ].join(\"\\n\"),\n )\n\n const shouldPrompt =\n !isClaudeCodeMode\n &&\n args.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 ${codexConfigPath})`,\n {\n type: \"select\",\n options: finalPickable,\n initial: defaultId,\n },\n )) as string\n if (selected && selected !== chosenModel) {\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 // Re-stamp codex config with the user's freshly picked model.\n if (args[\"codex-setup\"]) {\n try {\n const result = await applyCodexConfig({\n baseUrl: `${baseUrl}/v1`,\n configPath: codexConfigPath,\n settings: CODEX_DEFAULTS,\n model: chosenModel,\n modelReasoningEffort: chosenEffort,\n })\n if (result.changed) {\n consola.success(`codex config updated: ${result.configPath}`)\n }\n } catch (error) {\n consola.warn(\n `Could not update codex config (${codexConfigPath}):`,\n error,\n )\n }\n }\n }\n }\n\n if (isClaudeCodeMode) {\n const defaults = pickClaudeLaunchDefaults(finalPickable, chosenModel)\n let selectedModel = defaults.model\n\n if (args.prompt && finalPickable.length > 0) {\n selectedModel = (await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: finalPickable,\n initial: defaults.model,\n },\n )) as string\n }\n\n const command = buildClaudeLaunchCommand({\n baseUrl,\n model: selectedModel,\n })\n\n consola.box(\n [\n \"Claude one-shot command\",\n \"\",\n ` ${command}`,\n \"\",\n \" The bridge verified this path with explicit --model; current Claude CLI did not reliably honor ANTHROPIC_MODEL env defaults.\",\n ].join(\"\\n\"),\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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "betahi-copilot-bridge",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Model-layer bridge for routing Codex CLI, Claude Code, and similar clients to GitHub Copilot.",
5
5
  "keywords": [
6
6
  "github-copilot",