@ashsec/copilot-api 0.9.0 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","names":["state: State","state","headers: Record<string, string>","errorJson: unknown","lastError: Error | undefined","lastResponse: Response | undefined","errorDetails: string","parsed: unknown","token","name","SYSTEM_REPLACEMENTS: Array<ReplacementRule>","userReplacements: Array<ReplacementRule>","rule: ReplacementRule","result","appliedRules: Array<string>","type","name","rule","version","defaultConfig: AppConfig","cachedConfig: AppConfig | null","fs","config","process","commandBlock: string","config","sanitized: Record<string, unknown>","lines: Array<string>","path","tokenParts: Array<string>","state","x","headers: Record<string, string>","handleCompletion","isNonStreaming","handleCompletion","newMessages: Array<Message>","contentParts: Array<ContentPart>","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null","fs","stats: fs.Stats","name","headers: Record<string, string>","input: Array<ResponseInputItem>","items: Array<ResponseInputItem>","pendingContent: Array<ResponseInputContent>","contentBlocks: Array<AnthropicAssistantContentBlock>","segments: Array<string>","parsed: unknown","result: Array<ResponseInputContent>","state","handleOutputItemAdded","handleOutputItemDone","events","blockIndex","name","result: Array<ResponseInputItem>","headers: Record<string, string>","state","events: Array<AnthropicStreamEventData>","events","logger","RESPONSES_ENDPOINT","streamState: AnthropicStreamState","events","isAsyncIterable","toolResults: Array<AnthropicToolResultBlock>","textBlocks: Array<AnthropicTextBlock>","packageJson","packageJson"],"sources":["../package.json","../src/lib/paths.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-token.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/lib/retry-fetch.ts","../src/services/copilot/get-models.ts","../src/services/get-vscode-version.ts","../src/lib/utils.ts","../src/services/github/poll-access-token.ts","../src/lib/token.ts","../src/auth.ts","../src/services/github/get-copilot-usage.ts","../src/check-usage.ts","../src/lib/auto-replace.ts","../src/config.ts","../src/debug.ts","../src/lib/config.ts","../src/lib/proxy.ts","../src/lib/shell.ts","../src/lib/request-auth.ts","../src/lib/request-logger.ts","../src/lib/approval.ts","../src/lib/model-resolver.ts","../src/lib/rate-limit.ts","../src/lib/tokenizer.ts","../src/services/copilot/create-chat-completions.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/services/copilot/create-embeddings.ts","../src/routes/embeddings/route.ts","../src/routes/messages/utils.ts","../src/routes/messages/non-stream-translation.ts","../src/routes/messages/count-tokens-handler.ts","../src/lib/logger.ts","../src/services/copilot/create-responses.ts","../src/routes/messages/responses-translation.ts","../src/routes/messages/responses-stream-translation.ts","../src/routes/responses/utils.ts","../src/services/copilot/create-messages.ts","../src/routes/messages/stream-translation.ts","../src/routes/messages/subagent-marker.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/replacements/route.ts","../src/routes/responses/stream-id-sync.ts","../src/routes/responses/handler.ts","../src/routes/responses/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\r\n \"name\": \"@ashsec/copilot-api\",\r\n \"version\": \"0.9.0\",\r\n \"description\": \"Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code!\",\r\n \"keywords\": [\r\n \"proxy\",\r\n \"github-copilot\",\r\n \"openai-compatible\"\r\n ],\r\n \"homepage\": \"https://github.com/ericc-ch/copilot-api\",\r\n \"bugs\": \"https://github.com/ericc-ch/copilot-api/issues\",\r\n \"repository\": {\r\n \"type\": \"git\",\r\n \"url\": \"git+https://github.com/ericc-ch/copilot-api.git\"\r\n },\r\n \"author\": \"Erick Christian <erickchristian48@gmail.com>\",\r\n \"type\": \"module\",\r\n \"bin\": {\r\n \"copilot-api\": \"./dist/main.js\"\r\n },\r\n \"files\": [\r\n \"dist\"\r\n ],\r\n \"scripts\": {\r\n \"build\": \"tsdown\",\r\n \"dev\": \"bun run --watch ./src/main.ts\",\r\n \"knip\": \"knip-bun\",\r\n \"lint\": \"eslint --cache\",\r\n \"lint:all\": \"eslint --cache .\",\r\n \"prepack\": \"bun run build\",\r\n \"prepare\": \"simple-git-hooks\",\r\n \"release\": \"bumpp && bun publish --access public\",\r\n \"start\": \"NODE_ENV=production bun run ./src/main.ts\",\r\n \"typecheck\": \"tsc\"\r\n },\r\n \"simple-git-hooks\": {\r\n \"pre-commit\": \"bunx lint-staged\"\r\n },\r\n \"lint-staged\": {\r\n \"*\": \"bun run lint --fix\"\r\n },\r\n \"dependencies\": {\r\n \"citty\": \"^0.1.6\",\r\n \"clipboardy\": \"^5.0.0\",\r\n \"consola\": \"^3.4.2\",\r\n \"fetch-event-stream\": \"^0.1.5\",\r\n \"gpt-tokenizer\": \"^3.0.1\",\r\n \"hono\": \"^4.9.9\",\r\n \"ms\": \"^2.1.3\",\r\n \"proxy-from-env\": \"^1.1.0\",\r\n \"srvx\": \"^0.8.9\",\r\n \"tiny-invariant\": \"^1.3.3\",\r\n \"undici\": \"^7.16.0\",\r\n \"zod\": \"^4.1.11\"\r\n },\r\n \"devDependencies\": {\r\n \"@echristian/eslint-config\": \"^0.0.54\",\r\n \"@types/bun\": \"^1.2.23\",\r\n \"@types/proxy-from-env\": \"^1.0.4\",\r\n \"bumpp\": \"^10.2.3\",\r\n \"eslint\": \"^9.37.0\",\r\n \"knip\": \"^5.64.1\",\r\n \"lint-staged\": \"^16.2.3\",\r\n \"prettier-plugin-packagejson\": \"^2.5.19\",\r\n \"simple-git-hooks\": \"^2.13.1\",\r\n \"tsdown\": \"^0.15.6\",\r\n \"typescript\": \"^5.9.3\"\r\n }\r\n}\r\n","import fs from \"node:fs/promises\"\r\nimport os from \"node:os\"\r\nimport path from \"node:path\"\r\n\r\nconst APP_DIR = path.join(os.homedir(), \".local\", \"share\", \"copilot-api\")\r\n\r\nconst GITHUB_TOKEN_PATH = path.join(APP_DIR, \"github_token\")\nconst REPLACEMENTS_CONFIG_PATH = path.join(APP_DIR, \"replacements.json\")\n\nexport const PATHS = {\n APP_DIR,\n CONFIG_PATH: path.join(APP_DIR, \"config.json\"),\n GITHUB_TOKEN_PATH,\n REPLACEMENTS_CONFIG_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\r\nasync function ensureFile(filePath: string): Promise<void> {\r\n try {\r\n await fs.access(filePath, fs.constants.W_OK)\r\n } catch {\r\n await fs.writeFile(filePath, \"\")\r\n await fs.chmod(filePath, 0o600)\r\n }\r\n}\r\n","import type { ModelsResponse } from \"~/services/copilot/get-models\"\n\nexport interface State {\n githubToken?: string\n copilotToken?: string\n\n accountType: string\n models?: ModelsResponse\n vsCodeVersion?: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n debug: boolean\n verbose: boolean\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n}\n\r\nexport const state: State = {\r\n accountType: \"individual\",\r\n manualApprove: false,\r\n rateLimitWait: false,\r\n showToken: false,\r\n debug: false,\r\n verbose: false,\r\n}\r\n","import { randomUUID } from \"node:crypto\"\r\n\r\nimport type { State } from \"./state\"\r\n\r\nexport const standardHeaders = () => ({\r\n \"content-type\": \"application/json\",\r\n accept: \"application/json\",\r\n})\r\n\r\nconst COPILOT_VERSION = \"0.37.6\"\r\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\r\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\r\n\r\nconst API_VERSION = \"2025-10-01\"\r\n\r\nexport const copilotBaseUrl = (state: State) =>\r\n state.accountType === \"individual\" ?\r\n \"https://api.githubcopilot.com\"\r\n : `https://api.${state.accountType}.githubcopilot.com`\r\nexport const copilotHeaders = (state: State, vision: boolean = false) => {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${state.copilotToken}`,\r\n \"content-type\": standardHeaders()[\"content-type\"],\r\n \"copilot-integration-id\": \"vscode-chat\",\r\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\r\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\r\n \"user-agent\": USER_AGENT,\r\n \"openai-intent\": \"conversation-agent\",\r\n \"x-github-api-version\": API_VERSION,\r\n \"x-request-id\": randomUUID(),\r\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\r\n }\r\n\r\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\r\n\r\n return headers\r\n}\r\n\r\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\r\nexport const githubHeaders = (state: State) => ({\r\n ...standardHeaders(),\r\n authorization: `token ${state.githubToken}`,\r\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\r\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\r\n \"user-agent\": USER_AGENT,\r\n \"x-github-api-version\": API_VERSION,\r\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\r\n})\r\n\r\nexport const GITHUB_BASE_URL = \"https://github.com\"\r\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\r\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\r\n","import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n requestPayload?: unknown\n\n constructor(message: string, response: Response, requestPayload?: unknown) {\n super(message)\n this.response = response\n this.requestPayload = requestPayload\n }\n}\n\ninterface ContentFilterError {\n error: {\n code: string\n innererror?: {\n code: string\n content_filter_result?: unknown\n }\n }\n}\n\nfunction isContentFilterError(obj: unknown): obj is ContentFilterError {\n return (\n typeof obj === \"object\"\n && obj !== null\n && \"error\" in obj\n && typeof (obj as ContentFilterError).error === \"object\"\n && (obj as ContentFilterError).error.code === \"content_filter\"\n )\n}\n\nexport async function forwardError(c: Context, error: unknown) {\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n\n // Check for content filter error and log full details\n if (isContentFilterError(errorJson)) {\n consola.box(\"CONTENT FILTER TRIGGERED\")\n consola.error(\"Full error response:\")\n console.log(JSON.stringify(errorJson, null, 2))\n\n if (error.requestPayload) {\n consola.error(\"Request payload that triggered the filter:\")\n console.log(JSON.stringify(error.requestPayload, null, 2))\n }\n }\n\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotToken = async () => {\n const response = await fetch(\n `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(state),\n },\n )\n\n if (!response.ok) throw new HTTPError(\"Failed to get Copilot token\", response)\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n","import {\n GITHUB_APP_SCOPES,\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n standardHeaders,\n} from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport async function getDeviceCode(): 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) throw new HTTPError(\"Failed to get device code\", response)\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n expires_in: number\n interval: number\n}\n","import { GITHUB_API_BASE_URL, standardHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport async function getGitHubUser() {\n const response = await fetch(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${state.githubToken}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GithubUserResponse {\n login: string\n}\n","import consola from \"consola\"\n\nimport { sleep } from \"./utils\"\n\n// Fast retry: 100ms, 200ms, 300ms, then stop (max ~600ms total wait)\nconst RETRY_DELAYS_MS = [100, 200, 300]\n\n/**\n * Check if an error is retryable (transient network error)\n */\nfunction isRetryableError(error: unknown): boolean {\n if (!(error instanceof Error)) return false\n\n const message = error.message.toLowerCase()\n const causeMessage =\n error.cause instanceof Error ? error.cause.message.toLowerCase() : \"\"\n\n // Common transient error patterns\n const retryablePatterns = [\n \"fetch failed\",\n \"other side closed\",\n \"connection reset\",\n \"econnreset\",\n \"socket hang up\",\n \"socket connection was closed unexpectedly\",\n \"etimedout\",\n \"econnrefused\",\n \"network error\",\n \"aborted\",\n \"timeout\",\n ]\n\n return retryablePatterns.some(\n (pattern) => message.includes(pattern) || causeMessage.includes(pattern),\n )\n}\n\n/**\n * Check if an HTTP response status is retryable\n */\nfunction isRetryableStatus(status: number): boolean {\n // 4xx client errors (except 400, 401, 403, 404) and 5xx server errors\n // Retry: 408 Timeout, 429 Rate Limit, and all 5xx\n return status === 408 || status === 429 || (status >= 500 && status <= 599)\n}\n\n/**\n * Fetch with automatic fast retry on transient failures\n * Retries with delays: 100ms, 200ms, 300ms (max ~600ms total wait)\n */\nexport async function fetchWithRetry(\n input: string | URL | Request,\n init?: RequestInit,\n): Promise<Response> {\n const maxAttempts = RETRY_DELAYS_MS.length + 1 // 4 total attempts\n\n let lastError: Error | undefined\n let lastResponse: Response | undefined\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Force a new connection by adding cache-busting and connection headers\n const headers = new Headers(init?.headers)\n\n // Ensure we're not reusing potentially stale connections\n headers.set(\"Connection\", \"close\")\n\n const response = await fetch(input, {\n ...init,\n headers,\n // Disable keep-alive to force fresh connections on each attempt\n keepalive: false,\n })\n\n // Check for retryable HTTP status codes\n if (isRetryableStatus(response.status) && attempt < maxAttempts - 1) {\n lastResponse = response\n const delayMs = RETRY_DELAYS_MS[attempt]\n consola.warn(\n `HTTP ${response.status} (attempt ${attempt + 1}/${maxAttempts}), retrying in ${delayMs}ms`,\n )\n await sleep(delayMs)\n continue\n }\n\n return response\n } catch (error) {\n lastError = error as Error\n\n if (!isRetryableError(error) || attempt === maxAttempts - 1) {\n throw error\n }\n\n const delayMs = RETRY_DELAYS_MS[attempt]\n consola.warn(\n `Fetch failed (attempt ${attempt + 1}/${maxAttempts}), retrying in ${delayMs}ms:`,\n lastError.message,\n )\n await sleep(delayMs)\n }\n }\n\n // If we exhausted retries due to HTTP status, return the last response\n if (lastResponse) {\n return lastResponse\n }\n\n throw lastError\n}\n","import consola from \"consola\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport const getModels = async () => {\r\n const url = `${copilotBaseUrl(state)}/models`\r\n const response = await fetchWithRetry(url, {\r\n headers: copilotHeaders(state),\r\n })\r\n\r\n if (!response.ok) {\r\n const errorBody = await response.text()\r\n let errorDetails: string\r\n try {\r\n const parsed: unknown = JSON.parse(errorBody)\r\n errorDetails = JSON.stringify(parsed, null, 2)\r\n } catch {\r\n errorDetails = errorBody || \"(empty response)\"\r\n }\r\n consola.error(\r\n `Failed to get models from ${url}\\n`\r\n + `Status: ${response.status} ${response.statusText}\\n`\r\n + `Response: ${errorDetails}`,\r\n )\r\n throw new HTTPError(\r\n `Failed to get models: ${response.status} ${response.statusText}`,\r\n response,\r\n )\r\n }\r\n\r\n return (await response.json()) as ModelsResponse\r\n}\r\n\r\nexport interface ModelsResponse {\r\n data: Array<Model>\r\n object: string\r\n}\r\n\r\ninterface ModelLimits {\r\n max_context_window_tokens?: number\r\n max_output_tokens?: number\r\n max_prompt_tokens?: number\r\n max_inputs?: number\r\n}\r\n\r\ninterface ModelSupports {\r\n max_thinking_budget?: number\r\n min_thinking_budget?: number\r\n tool_calls?: boolean\r\n parallel_tool_calls?: boolean\r\n dimensions?: boolean\r\n streaming?: boolean\r\n structured_outputs?: boolean\r\n vision?: boolean\r\n adaptive_thinking?: boolean\r\n}\r\n\r\ninterface ModelCapabilities {\r\n family: string\r\n limits: ModelLimits\r\n object: string\r\n supports: ModelSupports\r\n tokenizer: string\r\n type: string\r\n}\r\n\r\nexport interface Model {\r\n capabilities: ModelCapabilities\r\n id: string\r\n model_picker_enabled: boolean\r\n name: string\r\n object: string\r\n preview: boolean\r\n vendor: string\r\n version: string\r\n policy?: {\r\n state: string\r\n terms: string\r\n }\r\n supported_endpoints?: Array<string>\r\n}\r\n","const FALLBACK = \"1.104.3\"\n\nexport async function getVSCodeVersion() {\n const controller = new AbortController()\n const timeout = setTimeout(() => {\n controller.abort()\n }, 5000)\n\n try {\n const response = await fetch(\n \"https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin\",\n {\n signal: controller.signal,\n },\n )\n\n const pkgbuild = await response.text()\n const pkgverRegex = /pkgver=([0-9.]+)/\n const match = pkgbuild.match(pkgverRegex)\n\n if (match) {\n return match[1]\n }\n\n return FALLBACK\n } catch {\n return FALLBACK\n } finally {\n clearTimeout(timeout)\n }\n}\n\nawait getVSCodeVersion()\n","import consola from \"consola\"\n\nimport { getModels } from \"~/services/copilot/get-models\"\nimport { getVSCodeVersion } from \"~/services/get-vscode-version\"\n\nimport { state } from \"./state\"\n\nexport const sleep = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nexport const isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined\n\nexport async function cacheModels(): Promise<void> {\n try {\n const models = await getModels()\n state.models = models\n } catch (error) {\n consola.error(\"Failed to fetch and cache models. This could be due to:\")\n consola.error(\" - Invalid or expired Copilot token\")\n consola.error(\" - Network connectivity issues\")\n consola.error(\" - GitHub Copilot service unavailable\")\n consola.error(\n \" - Account type mismatch (try --account-type=individual or --account-type=business)\",\n )\n throw error\n }\n}\n\nexport const cacheVSCodeVersion = async () => {\n const response = await getVSCodeVersion()\n state.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n","import consola from \"consola\"\n\nimport {\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n standardHeaders,\n} from \"~/lib/api-config\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n): Promise<string> {\n // Interval is in seconds, we need to multiply by 1000 to get milliseconds\n // I'm also adding another second, just to be safe\n const sleepDuration = (deviceCode.interval + 1) * 1000\n consola.debug(`Polling access token with interval of ${sleepDuration}ms`)\n\n while (true) {\n const response = await fetch(\n `${GITHUB_BASE_URL}/login/oauth/access_token`,\n {\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\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error(\"Failed to poll access token:\", await response.text())\n\n continue\n }\n\n const json = await response.json()\n consola.debug(\"Polling access token response:\", json)\n\n const { access_token } = json as AccessTokenResponse\n\n if (access_token) {\n return access_token\n } else {\n await sleep(sleepDuration)\n }\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n","import consola from \"consola\"\nimport fs from \"node:fs/promises\"\n\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n const refreshInterval = (refresh_in - 60) * 1000\n setInterval(async () => {\n consola.debug(\"Refreshing Copilot token\")\n try {\n const { token } = await getCopilotToken()\n state.copilotToken = token\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n throw error\n }\n }, refreshInterval)\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nasync function logUser() {\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (): Promise<CopilotUsageResponse> => {\n const response = await fetch(`${GITHUB_API_BASE_URL}/copilot_internal/user`, {\n headers: githubHeaders(state),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n","import consola from \"consola\"\nimport fs from \"node:fs/promises\"\n\nimport type { ChatCompletionsPayload } from \"~/services/copilot/create-chat-completions\"\n\nimport { PATHS } from \"./paths\"\n\nexport interface ReplacementRule {\n id: string\n name?: string // Human-readable name/description\n pattern: string\n replacement: string\n isRegex: boolean\n enabled: boolean\n isSystem?: boolean // System rules cannot be deleted by user\n}\n\n// Built-in system replacement that cannot be removed\nconst SYSTEM_REPLACEMENTS: Array<ReplacementRule> = [\n {\n id: \"system-anthropic-billing\",\n name: \"Remove Anthropic billing header\",\n pattern: String.raw`x-anthropic-billing-header:[^\\n]*\\n?`,\n replacement: \"\",\n isRegex: true,\n enabled: true,\n isSystem: true,\n },\n]\n\n// User-configured replacements (loaded from disk)\nlet userReplacements: Array<ReplacementRule> = []\nlet isLoaded = false\n\n/**\n * Load user replacements from disk\n */\nexport async function loadReplacements(): Promise<void> {\n try {\n const data = await fs.readFile(PATHS.REPLACEMENTS_CONFIG_PATH)\n const parsed = JSON.parse(data.toString()) as Array<ReplacementRule>\n userReplacements = parsed.filter((r) => !r.isSystem)\n isLoaded = true\n consola.debug(`Loaded ${userReplacements.length} user replacement rules`)\n } catch {\n // File doesn't exist or is invalid - start with empty array\n userReplacements = []\n isLoaded = true\n }\n}\n\n/**\n * Save user replacements to disk\n */\nexport async function saveReplacements(): Promise<void> {\n try {\n await fs.writeFile(\n PATHS.REPLACEMENTS_CONFIG_PATH,\n JSON.stringify(userReplacements, null, 2),\n \"utf8\",\n )\n consola.debug(`Saved ${userReplacements.length} user replacement rules`)\n } catch (error) {\n consola.error(\"Failed to save replacement rules:\", error)\n throw error\n }\n}\n\n/**\n * Ensure replacements are loaded before accessing\n */\nexport async function ensureLoaded(): Promise<void> {\n if (!isLoaded) {\n await loadReplacements()\n }\n}\n\n/**\n * Get all replacement rules (system + user)\n */\nexport async function getAllReplacements(): Promise<Array<ReplacementRule>> {\n await ensureLoaded()\n return [...SYSTEM_REPLACEMENTS, ...userReplacements]\n}\n\n/**\n * Get only user-configurable replacements\n */\nexport async function getUserReplacements(): Promise<Array<ReplacementRule>> {\n await ensureLoaded()\n return userReplacements\n}\n\n/**\n * Add a new user replacement rule\n */\nexport async function addReplacement(\n pattern: string,\n replacement: string,\n options?: { isRegex?: boolean; name?: string },\n): Promise<ReplacementRule> {\n const { isRegex = false, name } = options ?? {}\n await ensureLoaded()\n const rule: ReplacementRule = {\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n name,\n pattern,\n replacement,\n isRegex,\n enabled: true,\n isSystem: false,\n }\n userReplacements.push(rule)\n await saveReplacements()\n consola.info(`Added replacement rule: \"${pattern}\" -> \"${replacement}\"`)\n return rule\n}\n\n/**\n * Remove a user replacement rule by ID\n */\nexport async function removeReplacement(id: string): Promise<boolean> {\n await ensureLoaded()\n const rule = userReplacements.find((r) => r.id === id)\n if (!rule) {\n return false\n }\n if (rule.isSystem) {\n consola.warn(\"Cannot remove system replacement rule\")\n return false\n }\n userReplacements = userReplacements.filter((r) => r.id !== id)\n await saveReplacements()\n consola.info(`Removed replacement rule: ${id}`)\n return true\n}\n\n/**\n * Update an existing user replacement rule\n */\nexport async function updateReplacement(\n id: string,\n updates: {\n name?: string\n pattern?: string\n replacement?: string\n isRegex?: boolean\n enabled?: boolean\n },\n): Promise<ReplacementRule | null> {\n await ensureLoaded()\n\n const rule = userReplacements.find((r) => r.id === id)\n if (!rule) {\n return null\n }\n\n if (rule.isSystem) {\n consola.warn(\"Cannot update system replacement rule\")\n return null\n }\n\n if (updates.name !== undefined) rule.name = updates.name\n if (updates.pattern !== undefined) rule.pattern = updates.pattern\n if (updates.replacement !== undefined) rule.replacement = updates.replacement\n if (updates.isRegex !== undefined) rule.isRegex = updates.isRegex\n if (updates.enabled !== undefined) rule.enabled = updates.enabled\n\n await saveReplacements()\n consola.info(`Updated replacement rule: ${rule.name || rule.id}`)\n return rule\n}\n\n/**\n * Toggle a replacement rule on/off\n */\nexport async function toggleReplacement(\n id: string,\n): Promise<ReplacementRule | null> {\n await ensureLoaded()\n // Check user replacements first\n const userRule = userReplacements.find((r) => r.id === id)\n if (userRule) {\n userRule.enabled = !userRule.enabled\n await saveReplacements()\n consola.info(\n `Toggled replacement rule ${id}: ${userRule.enabled ? \"enabled\" : \"disabled\"}`,\n )\n return userRule\n }\n\n // System rules cannot be toggled\n const systemRule = SYSTEM_REPLACEMENTS.find((r) => r.id === id)\n if (systemRule) {\n consola.warn(\"Cannot toggle system replacement rule\")\n return null\n }\n\n return null\n}\n\n/**\n * Clear all user replacements\n */\nexport async function clearUserReplacements(): Promise<void> {\n userReplacements = []\n await saveReplacements()\n consola.info(\"Cleared all user replacement rules\")\n}\n\n/**\n * Apply a single replacement rule to text and return info about whether it matched\n */\nfunction applyRule(\n text: string,\n rule: ReplacementRule,\n): { result: string; matched: boolean } {\n if (!rule.enabled) return { result: text, matched: false }\n\n if (rule.isRegex) {\n try {\n const regex = new RegExp(rule.pattern, \"g\")\n const result = text.replace(regex, rule.replacement)\n return { result, matched: result !== text }\n } catch {\n consola.warn(`Invalid regex pattern in rule ${rule.id}: ${rule.pattern}`)\n return { result: text, matched: false }\n }\n }\n\n const result = text.split(rule.pattern).join(rule.replacement)\n return { result, matched: result !== text }\n}\n\n/**\n * Apply all replacement rules to text\n */\nexport async function applyReplacements(text: string): Promise<string> {\n let result = text\n const allRules = await getAllReplacements()\n const appliedRules: Array<string> = []\n\n for (const rule of allRules) {\n const { result: newResult, matched } = applyRule(result, rule)\n if (matched) {\n result = newResult\n appliedRules.push(rule.name || rule.id)\n }\n }\n\n if (appliedRules.length > 0) {\n consola.info(`Replacements applied: ${appliedRules.join(\", \")}`)\n }\n\n return result\n}\n\n/**\n * Apply replacements to a chat completions payload\n * This modifies message content in place\n */\nexport async function applyReplacementsToPayload(\n payload: ChatCompletionsPayload,\n): Promise<ChatCompletionsPayload> {\n const processedMessages = await Promise.all(\n payload.messages.map(async (message) => {\n if (typeof message.content === \"string\") {\n return {\n ...message,\n content: await applyReplacements(message.content),\n }\n }\n\n // Handle array content (multimodal)\n if (Array.isArray(message.content)) {\n return {\n ...message,\n content: await Promise.all(\n message.content.map(async (part) => {\n if (\n typeof part === \"object\"\n && part.type === \"text\"\n && part.text\n ) {\n return {\n ...part,\n text: await applyReplacements(part.text),\n }\n }\n return part\n }),\n ),\n }\n }\n\n return message\n }),\n )\n\n return {\n ...payload,\n messages: processedMessages,\n }\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n addReplacement,\n applyReplacements,\n clearUserReplacements,\n getAllReplacements,\n getUserReplacements,\n removeReplacement,\n toggleReplacement,\n updateReplacement,\n type ReplacementRule,\n} from \"~/lib/auto-replace\"\nimport { ensurePaths, PATHS } from \"~/lib/paths\"\n\ntype MenuAction =\n | \"list\"\n | \"add\"\n | \"edit\"\n | \"remove\"\n | \"toggle\"\n | \"test\"\n | \"clear\"\n | \"exit\"\n\nfunction formatRule(rule: ReplacementRule, index: number): string {\n const status = rule.enabled ? \"✓\" : \"✗\"\n const type = rule.isRegex ? \"regex\" : \"string\"\n const system = rule.isSystem ? \" [system]\" : \"\"\n const name = rule.name ? ` \"${rule.name}\"` : \"\"\n const replacement = rule.replacement || \"(empty)\"\n return `${index + 1}. [${status}] (${type})${system}${name} \"${rule.pattern}\" → \"${replacement}\"`\n}\n\nasync function listReplacements(): Promise<void> {\n const all = await getAllReplacements()\n\n if (all.length === 0) {\n consola.info(\"No replacement rules configured.\")\n return\n }\n\n consola.info(\"\\n📋 Replacement Rules:\\n\")\n for (const [i, element] of all.entries()) {\n console.log(formatRule(element, i))\n }\n console.log()\n}\n\nasync function addNewReplacement(): Promise<void> {\n const name = await consola.prompt(\"Name (optional, short description):\", {\n type: \"text\",\n default: \"\",\n })\n\n if (typeof name === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const matchType = await consola.prompt(\"Match type:\", {\n type: \"select\",\n options: [\n { label: \"String (exact match)\", value: \"string\" },\n { label: \"Regex (regular expression)\", value: \"regex\" },\n ],\n })\n\n if (typeof matchType === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const pattern = await consola.prompt(\"Pattern to match:\", {\n type: \"text\",\n })\n\n if (typeof pattern === \"symbol\" || !pattern) {\n consola.info(\"Cancelled.\")\n return\n }\n\n // Validate regex if needed\n if (matchType === \"regex\") {\n try {\n new RegExp(pattern)\n } catch {\n consola.error(`Invalid regex pattern: ${pattern}`)\n return\n }\n }\n\n const replacement = await consola.prompt(\n \"Replacement text (leave empty to delete matches):\",\n {\n type: \"text\",\n default: \"\",\n },\n )\n\n if (typeof replacement === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = await addReplacement(\n pattern,\n replacement,\n matchType === \"regex\",\n name || undefined,\n )\n\n consola.success(`Added rule: ${rule.name || rule.id}`)\n}\n\nasync function editExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to edit.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to edit:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = userRules.find((r) => r.id === selected)\n if (!rule) {\n consola.error(\"Rule not found.\")\n return\n }\n\n consola.info(`\\nEditing rule: ${rule.name || rule.id}`)\n consola.info(\"Press Enter to keep current value.\\n\")\n\n const name = await consola.prompt(\"Name:\", {\n type: \"text\",\n default: rule.name || \"\",\n })\n\n if (typeof name === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const matchType = await consola.prompt(\"Match type:\", {\n type: \"select\",\n options: [\n { label: \"String (exact match)\", value: \"string\" },\n { label: \"Regex (regular expression)\", value: \"regex\" },\n ],\n initial: rule.isRegex ? \"regex\" : \"string\",\n })\n\n if (typeof matchType === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const pattern = await consola.prompt(\"Pattern to match:\", {\n type: \"text\",\n default: rule.pattern,\n })\n\n if (typeof pattern === \"symbol\" || !pattern) {\n consola.info(\"Cancelled.\")\n return\n }\n\n // Validate regex if needed\n if (matchType === \"regex\") {\n try {\n new RegExp(pattern)\n } catch {\n consola.error(`Invalid regex pattern: ${pattern}`)\n return\n }\n }\n\n const replacement = await consola.prompt(\"Replacement text:\", {\n type: \"text\",\n default: rule.replacement,\n })\n\n if (typeof replacement === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const updated = await updateReplacement(selected, {\n name: name || undefined,\n pattern,\n replacement,\n isRegex: matchType === \"regex\",\n })\n\n if (updated) {\n consola.success(`Updated rule: ${updated.name || updated.id}`)\n } else {\n consola.error(\"Failed to update rule.\")\n }\n}\n\nasync function removeExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to remove.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to remove:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const success = await removeReplacement(selected)\n if (success) {\n consola.success(\"Rule removed.\")\n } else {\n consola.error(\"Failed to remove rule.\")\n }\n}\n\nasync function toggleExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to toggle.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to toggle:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = await toggleReplacement(selected)\n if (rule) {\n consola.success(`Rule ${rule.enabled ? \"enabled\" : \"disabled\"}.`)\n } else {\n consola.error(\"Failed to toggle rule.\")\n }\n}\n\nasync function testReplacements(): Promise<void> {\n const testText = await consola.prompt(\"Enter text to test replacements:\", {\n type: \"text\",\n })\n\n if (typeof testText === \"symbol\" || !testText) {\n consola.info(\"Cancelled.\")\n return\n }\n\n const result = await applyReplacements(testText)\n\n consola.info(\"\\n📝 Original:\")\n console.log(testText)\n consola.info(\"\\n✨ After replacements:\")\n console.log(result)\n console.log()\n}\n\nasync function clearAllReplacements(): Promise<void> {\n const confirm = await consola.prompt(\n \"Are you sure you want to clear all user replacements?\",\n {\n type: \"confirm\",\n initial: false,\n },\n )\n\n if (confirm) {\n await clearUserReplacements()\n consola.success(\"All user replacements cleared.\")\n } else {\n consola.info(\"Cancelled.\")\n }\n}\n\nasync function mainMenu(): Promise<void> {\n consola.info(`\\n🔧 Copilot API - Replacement Configuration`)\n consola.info(`Config file: ${PATHS.REPLACEMENTS_CONFIG_PATH}\\n`)\n\n let running = true\n\n while (running) {\n const action = await consola.prompt(\"What would you like to do?\", {\n type: \"select\",\n options: [\n { label: \"📋 List all rules\", value: \"list\" as MenuAction },\n { label: \"➕ Add new rule\", value: \"add\" as MenuAction },\n { label: \"✏️ Edit rule\", value: \"edit\" as MenuAction },\n { label: \"➖ Remove rule\", value: \"remove\" as MenuAction },\n { label: \"🔄 Toggle rule on/off\", value: \"toggle\" as MenuAction },\n { label: \"🧪 Test replacements\", value: \"test\" as MenuAction },\n { label: \"🗑️ Clear all user rules\", value: \"clear\" as MenuAction },\n { label: \"🚪 Exit\", value: \"exit\" as MenuAction },\n ],\n })\n\n if (typeof action === \"symbol\") {\n break\n }\n\n switch (action) {\n case \"list\": {\n await listReplacements()\n break\n }\n case \"add\": {\n await addNewReplacement()\n break\n }\n case \"edit\": {\n await editExistingReplacement()\n break\n }\n case \"remove\": {\n await removeExistingReplacement()\n break\n }\n case \"toggle\": {\n await toggleExistingReplacement()\n break\n }\n case \"test\": {\n await testReplacements()\n break\n }\n case \"clear\": {\n await clearAllReplacements()\n break\n }\n case \"exit\": {\n running = false\n break\n }\n default: {\n break\n }\n }\n }\n\n consola.info(\"Goodbye! 👋\")\n}\n\nexport const config = defineCommand({\n meta: {\n name: \"config\",\n description: \"Configure replacement rules interactively\",\n },\n run: async () => {\n await ensurePaths()\n await mainMenu()\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\n\nimport { PATHS } from \"./lib/paths\"\n\ninterface DebugInfo {\n version: string\n runtime: {\n name: string\n version: string\n platform: string\n arch: string\n }\n paths: {\n APP_DIR: string\n GITHUB_TOKEN_PATH: string\n }\n tokenExists: boolean\n}\n\ninterface RunDebugOptions {\n json: boolean\n}\n\nasync function getPackageVersion(): Promise<string> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url).pathname\n // @ts-expect-error https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v59.0.1/docs/rules/prefer-json-parse-buffer.md\n // JSON.parse() can actually parse buffers\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath)) as {\n version: string\n }\n return packageJson.version\n } catch {\n return \"unknown\"\n }\n}\n\nfunction getRuntimeInfo() {\n const isBun = typeof Bun !== \"undefined\"\n\n return {\n name: isBun ? \"bun\" : \"node\",\n version: isBun ? Bun.version : process.version.slice(1),\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nasync function checkTokenExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.GITHUB_TOKEN_PATH)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const [version, tokenExists] = await Promise.all([\n getPackageVersion(),\n checkTokenExists(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,\n },\n tokenExists,\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n consola.info(`copilot-api debug\n\nVersion: ${info.version}\nRuntime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})\n\nPaths:\n- APP_DIR: ${info.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${info.tokenExists ? \"Yes\" : \"No\"}`)\n}\n\nfunction printDebugInfoJson(info: DebugInfo): void {\n console.log(JSON.stringify(info, null, 2))\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n printDebugInfoJson(debugInfo)\n } else {\n printDebugInfoPlain(debugInfo)\n }\n}\n\nexport const debug = defineCommand({\n meta: {\n name: \"debug\",\n description: \"Print debug information about the application\",\n },\n args: {\n json: {\n type: \"boolean\",\n default: false,\n description: \"Output debug information as JSON\",\n },\n },\n run({ args }) {\n return runDebug({\n json: args.json,\n })\n },\n})\n","import consola from \"consola\"\r\nimport fs from \"node:fs\"\r\n\r\nimport { PATHS } from \"./paths\"\r\n\r\nexport interface AppConfig {\r\n auth?: {\r\n apiKeys?: Array<string>\r\n }\r\n extraPrompts?: Record<string, string>\r\n smallModel?: string\r\n modelReasoningEfforts?: Record<\r\n string,\r\n \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\"\r\n >\r\n useFunctionApplyPatch?: boolean\r\n compactUseSmallModel?: boolean\r\n}\r\n\r\nconst gpt5ExplorationPrompt = `## Exploration and reading files\r\n- **Think first.** Before any tool call, decide ALL files/resources you will need.\r\n- **Batch everything.** If you need multiple files (even from different places), read them together.\r\n- **multi_tool_use.parallel** Use multi_tool_use.parallel to parallelize tool calls and only this.\r\n- **Only make sequential calls if you truly cannot know the next file without seeing a result first.**\r\n- **Workflow:** (a) plan all needed reads → (b) issue one parallel batch → (c) analyze results → (d) repeat if new, unpredictable reads arise.`\r\n\r\nconst gpt5CommentaryPrompt = `# Working with the user\r\n\r\nYou interact with the user through a terminal. You have 2 ways of communicating with the users:\r\n- Share intermediary updates in \\`commentary\\` channel.\r\n- After you have completed all your work, send a message to the \\`final\\` channel.\r\n\r\n## Intermediary updates\r\n\r\n- Intermediary updates go to the \\`commentary\\` channel.\r\n- User updates are short updates while you are working, they are NOT final answers.\r\n- You use 1-2 sentence user updates to communicate progress and new information to the user as you are doing work.\r\n- Do not begin responses with conversational interjections or meta commentary. Avoid openers such as acknowledgements (\"Done —\", \"Got it\", \"Great question, \") or framing phrases.\r\n- You provide user updates frequently, every 20s.\r\n- Before exploring or doing substantial work, you start with a user update acknowledging the request and explaining your first step. You should include your understanding of the user request and explain what you will do. Avoid commenting on the request or using starters such as \"Got it -\" or \"Understood -\" etc.\r\n- When exploring, e.g. searching, reading files, you provide user updates as you go, every 20s, explaining what context you are gathering and what you've learned. Vary your sentence structure when providing these updates to avoid sounding repetitive - in particular, don't start each sentence the same way.\r\n- After you have sufficient context, and the work is substantial, you provide a longer plan (this is the only user update that may be longer than 2 sentences and can contain formatting).\r\n- Before performing file edits of any kind, you provide updates explaining what edits you are making.\r\n- As you are thinking, you very frequently provide updates even if not taking any actions, informing the user of your progress. You interrupt your thinking and send multiple updates in a row if thinking for more than 100 words.\r\n- Tone of your updates MUST match your personality.`\r\n\r\nconst defaultConfig: AppConfig = {\r\n auth: {\r\n apiKeys: [],\r\n },\r\n extraPrompts: {\r\n \"gpt-5-mini\": gpt5ExplorationPrompt,\r\n \"gpt-5.1-codex-max\": gpt5ExplorationPrompt,\r\n \"gpt-5.3-codex\": gpt5CommentaryPrompt,\r\n },\r\n smallModel: \"gpt-5-mini\",\r\n modelReasoningEfforts: {\r\n \"gpt-5-mini\": \"low\",\r\n },\r\n useFunctionApplyPatch: true,\r\n compactUseSmallModel: true,\r\n}\r\n\r\nlet cachedConfig: AppConfig | null = null\r\n\r\nfunction ensureConfigFile(): void {\r\n try {\r\n fs.accessSync(PATHS.CONFIG_PATH, fs.constants.R_OK | fs.constants.W_OK)\r\n } catch {\r\n fs.mkdirSync(PATHS.APP_DIR, { recursive: true })\r\n fs.writeFileSync(\r\n PATHS.CONFIG_PATH,\r\n `${JSON.stringify(defaultConfig, null, 2)}\\n`,\r\n \"utf8\",\r\n )\r\n try {\r\n fs.chmodSync(PATHS.CONFIG_PATH, 0o600)\r\n } catch {\r\n return\r\n }\r\n }\r\n}\r\n\r\nfunction readConfigFromDisk(): AppConfig {\r\n ensureConfigFile()\r\n try {\r\n const raw = fs.readFileSync(PATHS.CONFIG_PATH, \"utf8\")\r\n if (!raw.trim()) {\r\n fs.writeFileSync(\r\n PATHS.CONFIG_PATH,\r\n `${JSON.stringify(defaultConfig, null, 2)}\\n`,\r\n \"utf8\",\r\n )\r\n return defaultConfig\r\n }\r\n return JSON.parse(raw) as AppConfig\r\n } catch (error) {\r\n consola.error(\"Failed to read config file, using default config\", error)\r\n return defaultConfig\r\n }\r\n}\r\n\r\nfunction mergeDefaultExtraPrompts(config: AppConfig): {\r\n mergedConfig: AppConfig\r\n changed: boolean\r\n} {\r\n const extraPrompts = config.extraPrompts ?? {}\r\n const defaultExtraPrompts = defaultConfig.extraPrompts ?? {}\r\n\r\n const missingExtraPromptModels = Object.keys(defaultExtraPrompts).filter(\r\n (model) => !Object.hasOwn(extraPrompts, model),\r\n )\r\n\r\n if (missingExtraPromptModels.length === 0) {\r\n return { mergedConfig: config, changed: false }\r\n }\r\n\r\n return {\r\n mergedConfig: {\r\n ...config,\r\n extraPrompts: {\r\n ...defaultExtraPrompts,\r\n ...extraPrompts,\r\n },\r\n },\r\n changed: true,\r\n }\r\n}\r\n\r\nexport function mergeConfigWithDefaults(): AppConfig {\r\n const config = readConfigFromDisk()\r\n const { mergedConfig, changed } = mergeDefaultExtraPrompts(config)\r\n\r\n if (changed) {\r\n try {\r\n fs.writeFileSync(\r\n PATHS.CONFIG_PATH,\r\n `${JSON.stringify(mergedConfig, null, 2)}\\n`,\r\n \"utf8\",\r\n )\r\n } catch (writeError) {\r\n consola.warn(\r\n \"Failed to write merged extraPrompts to config file\",\r\n writeError,\r\n )\r\n }\r\n }\r\n\r\n cachedConfig = mergedConfig\r\n return mergedConfig\r\n}\r\n\r\nexport function getConfig(): AppConfig {\r\n cachedConfig ??= readConfigFromDisk()\r\n return cachedConfig\r\n}\r\n\r\nexport function getExtraPromptForModel(model: string): string {\r\n const config = getConfig()\r\n return config.extraPrompts?.[model] ?? \"\"\r\n}\r\n\r\nexport function getSmallModel(): string {\r\n const config = getConfig()\r\n return config.smallModel ?? \"gpt-5-mini\"\r\n}\r\n\r\nexport function getReasoningEffortForModel(\r\n model: string,\r\n): \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" {\r\n const config = getConfig()\r\n return config.modelReasoningEfforts?.[model] ?? \"high\"\r\n}\r\n\r\nexport function shouldCompactUseSmallModel(): boolean {\r\n const config = getConfig()\r\n return config.compactUseSmallModel ?? true\r\n}\r\n","import consola from \"consola\"\nimport { getProxyForUrl } from \"proxy-from-env\"\nimport { Agent, ProxyAgent, setGlobalDispatcher, type Dispatcher } from \"undici\"\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== \"undefined\") return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin =\n typeof options.origin === \"string\" ?\n new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n } catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n } catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug(\"HTTP proxy configured from environment (per-URL)\")\n } catch (err) {\n consola.debug(\"Proxy setup skipped:\", err)\n }\n}\n","import { execSync } from \"node:child_process\"\nimport process from \"node:process\"\n\ntype ShellName = \"bash\" | \"zsh\" | \"fish\" | \"powershell\" | \"cmd\" | \"sh\"\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === \"win32\") {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: \"pipe\" }).toString()\n\n if (parentProcess.toLowerCase().includes(\"powershell.exe\")) {\n return \"powershell\"\n }\n } catch {\n return \"cmd\"\n }\n\n return \"cmd\"\n } else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith(\"zsh\")) return \"zsh\"\n if (shellPath.endsWith(\"fish\")) return \"fish\"\n if (shellPath.endsWith(\"bash\")) return \"bash\"\n }\n\n return \"sh\"\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = \"\",\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case \"powershell\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join(\"; \")\n break\n }\n case \"cmd\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(\" & \")\n break\n }\n case \"fish\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join(\"; \")\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \")\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : \"\"\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === \"cmd\" ? \" & \" : \" && \"\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from \"hono\"\r\n\r\nimport consola from \"consola\"\r\n\r\nimport { getConfig } from \"./config\"\r\n\r\ninterface AuthMiddlewareOptions {\r\n getApiKeys?: () => Array<string>\r\n allowUnauthenticatedPaths?: Array<string>\r\n allowOptionsBypass?: boolean\r\n}\r\n\r\nexport function normalizeApiKeys(apiKeys: unknown): Array<string> {\r\n if (!Array.isArray(apiKeys)) {\r\n if (apiKeys !== undefined) {\r\n consola.warn(\"Invalid auth.apiKeys config. Expected an array of strings.\")\r\n }\r\n return []\r\n }\r\n\r\n const normalizedKeys = apiKeys\r\n .filter((key): key is string => typeof key === \"string\")\r\n .map((key) => key.trim())\r\n .filter((key) => key.length > 0)\r\n\r\n if (normalizedKeys.length !== apiKeys.length) {\r\n consola.warn(\r\n \"Invalid auth.apiKeys entries found. Only non-empty strings are allowed.\",\r\n )\r\n }\r\n\r\n return [...new Set(normalizedKeys)]\r\n}\r\n\r\nexport function getConfiguredApiKeys(): Array<string> {\r\n const config = getConfig()\r\n return normalizeApiKeys(config.auth?.apiKeys)\r\n}\r\n\r\nexport function extractRequestApiKey(c: Context): string | null {\r\n const xApiKey = c.req.header(\"x-api-key\")?.trim()\r\n if (xApiKey) {\r\n return xApiKey\r\n }\r\n\r\n const authorization = c.req.header(\"authorization\")\r\n if (!authorization) {\r\n return null\r\n }\r\n\r\n const [scheme, ...rest] = authorization.trim().split(/\\s+/)\r\n if (scheme.toLowerCase() !== \"bearer\") {\r\n return null\r\n }\r\n\r\n const bearerToken = rest.join(\" \").trim()\r\n return bearerToken || null\r\n}\r\n\r\nfunction createUnauthorizedResponse(c: Context): Response {\r\n c.header(\"WWW-Authenticate\", 'Bearer realm=\"copilot-api\"')\r\n return c.json(\r\n {\r\n error: {\r\n message: \"Unauthorized\",\r\n type: \"authentication_error\",\r\n },\r\n },\r\n 401,\r\n )\r\n}\r\n\r\nexport function createAuthMiddleware(\r\n options: AuthMiddlewareOptions = {},\r\n): MiddlewareHandler {\r\n const getApiKeys = options.getApiKeys ?? getConfiguredApiKeys\r\n const allowUnauthenticatedPaths = options.allowUnauthenticatedPaths ?? [\"/\"]\r\n const allowOptionsBypass = options.allowOptionsBypass ?? true\r\n\r\n return async (c, next) => {\r\n if (allowOptionsBypass && c.req.method === \"OPTIONS\") {\r\n return next()\r\n }\r\n\r\n if (allowUnauthenticatedPaths.includes(c.req.path)) {\r\n return next()\r\n }\r\n\r\n const apiKeys = getApiKeys()\r\n if (apiKeys.length === 0) {\r\n return next()\r\n }\r\n\r\n const requestApiKey = extractRequestApiKey(c)\r\n if (!requestApiKey || !apiKeys.includes(requestApiKey)) {\r\n return createUnauthorizedResponse(c)\r\n }\r\n\r\n return next()\r\n }\r\n}\r\n","import type { Context, Next } from \"hono\"\n\nimport { state } from \"./state\"\n\n/**\n * Request context stored for logging on response\n */\nexport interface RequestContext {\n startTime: number\n model?: string\n inputTokens?: number\n outputTokens?: number\n provider?: \"Copilot\"\n}\n\nconst REQUEST_CONTEXT_KEY = \"requestContext\"\n\n// ANSI color codes\nexport const colors = {\n reset: \"\\x1b[0m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n magenta: \"\\x1b[35m\",\n blue: \"\\x1b[34m\",\n white: \"\\x1b[37m\",\n gray: \"\\x1b[90m\",\n}\n\n/**\n * Get the current time formatted as HH:MM:SS\n */\nfunction getTimeString(): string {\n return new Date().toLocaleTimeString(\"en-US\", {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n })\n}\n\n/**\n * Get status color based on HTTP status code\n */\nfunction getStatusColor(status: number): string {\n if (status >= 500) return colors.red\n if (status >= 400) return colors.yellow\n if (status >= 300) return colors.cyan\n return colors.green\n}\n\n/**\n * Sanitize request body by omitting large message/prompt arrays\n */\nfunction sanitizeRequestBody(\n parsed: Record<string, unknown>,\n): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(parsed)) {\n sanitized[key] =\n key === \"messages\" || key === \"prompt\" ?\n `[${Array.isArray(value) ? value.length : 1} items omitted]`\n : value\n }\n return sanitized\n}\n\n/**\n * Log raw HTTP request details (for debug mode)\n */\nasync function logRawRequest(c: Context): Promise<void> {\n const method = c.req.method\n const url = c.req.url\n const headers = Object.fromEntries(c.req.raw.headers.entries())\n\n const lines: Array<string> = []\n lines.push(\n `${colors.magenta}${colors.bold}[DEBUG] Incoming Request${colors.reset}`,\n `${colors.cyan}${method}${colors.reset} ${url}`,\n `${colors.dim}Headers:${colors.reset}`,\n )\n\n for (const [key, value] of Object.entries(headers)) {\n // Mask authorization headers\n const displayValue =\n key.toLowerCase().includes(\"authorization\") ?\n `${value.slice(0, 20)}...`\n : value\n lines.push(` ${colors.gray}${key}:${colors.reset} ${displayValue}`)\n }\n\n // Try to get body info without consuming it\n if (method !== \"GET\" && method !== \"HEAD\") {\n try {\n const clonedRequest = c.req.raw.clone()\n const body = await clonedRequest.text()\n if (body) {\n // Parse JSON to extract model, omit messages/prompt\n try {\n const parsed = JSON.parse(body) as Record<string, unknown>\n const sanitized = sanitizeRequestBody(parsed)\n\n lines.push(\n `${colors.dim}Body (sanitized):${colors.reset}`,\n ` ${JSON.stringify(sanitized, null, 2).split(\"\\n\").join(\"\\n \")}`,\n )\n } catch {\n // Not JSON, show length\n lines.push(`${colors.dim}Body:${colors.reset} [${body.length} bytes]`)\n }\n }\n } catch {\n lines.push(`${colors.dim}Body:${colors.reset} [unable to read]`)\n }\n }\n\n lines.push(`${colors.dim}${\"─\".repeat(60)}${colors.reset}`)\n console.log(lines.join(\"\\n\"))\n}\n\n/**\n * Set request context for logging\n */\nexport function setRequestContext(\n c: Context,\n ctx: Partial<Omit<RequestContext, \"startTime\">>,\n): void {\n const existing = c.get(REQUEST_CONTEXT_KEY) as RequestContext | undefined\n if (existing) {\n c.set(REQUEST_CONTEXT_KEY, { ...existing, ...ctx })\n }\n}\n\n/**\n * Custom request logger middleware\n */\nexport async function requestLogger(c: Context, next: Next): Promise<void> {\n // Log raw request in debug mode\n if (state.debug) {\n await logRawRequest(c)\n }\n\n const startTime = Date.now()\n const method = c.req.method\n const path =\n c.req.path\n + (c.req.raw.url.includes(\"?\") ? \"?\" + c.req.raw.url.split(\"?\")[1] : \"\")\n\n // Initialize request context\n c.set(REQUEST_CONTEXT_KEY, { startTime } as RequestContext)\n\n await next()\n\n // Get context that may have been set during request handling\n const ctx = c.get(REQUEST_CONTEXT_KEY) as RequestContext | undefined\n const duration = ((Date.now() - startTime) / 1000).toFixed(1)\n const status = c.res.status\n const statusColor = getStatusColor(status)\n\n // Build the log block\n const lines: Array<string> = []\n\n // Separator\n lines.push(`${colors.dim}${\"─\".repeat(60)}${colors.reset}`)\n\n // Main request line: method, path, status, duration\n const statusBadge = `${statusColor}${status}${colors.reset}`\n const durationStr = `${colors.cyan}${duration}s${colors.reset}`\n lines.push(\n `${colors.bold}${method}${colors.reset} ${path} ${statusBadge} ${durationStr}`,\n )\n\n // Provider and model info\n if (ctx?.provider && ctx.model) {\n const providerColor = colors.magenta\n lines.push(\n ` ${colors.gray}Provider:${colors.reset} ${providerColor}${ctx.provider}${colors.reset} ${colors.gray}->${colors.reset} ${colors.white}${ctx.model}${colors.reset}`,\n )\n }\n\n // Token info\n if (ctx?.inputTokens !== undefined || ctx?.outputTokens !== undefined) {\n const tokenParts: Array<string> = []\n if (ctx.inputTokens !== undefined) {\n tokenParts.push(\n `${colors.gray}Input:${colors.reset} ${colors.yellow}${ctx.inputTokens.toLocaleString()}${colors.reset}`,\n )\n }\n if (ctx.outputTokens !== undefined) {\n tokenParts.push(\n `${colors.gray}Output:${colors.reset} ${colors.green}${ctx.outputTokens.toLocaleString()}${colors.reset}`,\n )\n }\n lines.push(` ${tokenParts.join(\" \")}`)\n }\n\n // Timestamp\n lines.push(` ${colors.dim}${getTimeString()}${colors.reset}`)\n\n // Print all lines\n console.log(lines.join(\"\\n\"))\n}\n\n/**\n * Log token usage (for streaming responses where tokens are known after stream completes)\n */\nexport function logTokenUsage(inputTokens: number, outputTokens: number): void {\n const parts: Array<string> = []\n parts.push(\n ` ${colors.gray}Tokens:${colors.reset} ${colors.yellow}${inputTokens.toLocaleString()} in${colors.reset} ${colors.gray}/${colors.reset} ${colors.green}${outputTokens.toLocaleString()} out${colors.reset}`,\n )\n console.log(parts.join(\"\"))\n}\n","import consola from \"consola\"\n\nimport { HTTPError } from \"./error\"\n\nexport const awaitApproval = async () => {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: \"confirm\",\n })\n\n if (!response)\n throw new HTTPError(\n \"Request rejected\",\n Response.json({ message: \"Request rejected\" }, { status: 403 }),\n )\n}\n","/**\n * Normalize a model name by converting dashes to dots between numbers.\n * e.g., \"claude-opus-4-5\" -> \"claude-opus-4.5\"\n * \"gpt-4-1\" -> \"gpt-4.1\"\n * \"gpt-5-1-codex\" -> \"gpt-5.1-codex\"\n */\nexport function normalizeModelName(model: string): string {\n // Replace dash with dot only between two digits: \"4-5\" -> \"4.5\"\n return model.replaceAll(/(\\d)-(\\d)/g, (_, p1, p2) => `${p1}.${p2}`)\n}\n","import consola from \"consola\"\n\nimport type { State } from \"./state\"\n\nimport { HTTPError } from \"./error\"\nimport { sleep } from \"./utils\"\n\nexport async function checkRateLimit(state: State) {\n if (state.rateLimitSeconds === undefined) return\n\n const now = Date.now()\n\n if (!state.lastRequestTimestamp) {\n state.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.rateLimitSeconds) {\n state.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds)\n\n if (!state.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n \"Rate limit exceeded\",\n Response.json({ message: \"Rate limit exceeded\" }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n // eslint-disable-next-line require-atomic-updates\n state.lastRequestTimestamp = now\n consola.info(\"Rate limit wait completed, proceeding with request\")\n return\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import(\"gpt-tokenizer/encoding/o200k_base\"),\n cl100k_base: () => import(\"gpt-tokenizer/encoding/cl100k_base\"),\n p50k_base: () => import(\"gpt-tokenizer/encoding/p50k_base\"),\n p50k_edit: () => import(\"gpt-tokenizer/encoding/p50k_edit\"),\n r50k_base: () => import(\"gpt-tokenizer/encoding/r50k_base\"),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nconst calculateToolCallsTokens = (\n toolCalls: Array<ToolCall>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nconst calculateContentPartsTokens = (\n contentParts: Array<ContentPart>,\n encoder: Encoder,\n): number => {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === \"image_url\") {\n tokens += encoder.encode(part.image_url.url).length + 85\n } else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nconst calculateMessageTokens = (\n message: Message,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\") {\n tokens += encoder.encode(value).length\n }\n if (key === \"name\") {\n tokens += tokensPerName\n }\n if (key === \"tool_calls\") {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === \"content\" && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nconst calculateTokens = (\n messages: Array<Message>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nconst getEncodeChatFunction = async (encoding: string): Promise<Encoder> => {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport const getTokenizerFromModel = (model: Model): string => {\n return model.capabilities.tokenizer || \"o200k_base\"\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nconst getModelConstants = (model: Model) => {\n return model.id === \"gpt-3.5-turbo\" || model.id === \"gpt-4\" ?\n {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nconst calculateParameterTokens = (\n key: string,\n prop: unknown,\n context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n },\n): number => {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== \"object\" || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || \"string\"\n let paramDesc = param.description || \"\"\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith(\".\")) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set([\"type\", \"description\", \"enum\"])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText =\n typeof propertyValue === \"string\" ? propertyValue : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nconst calculateParametersTokens = (\n parameters: unknown,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (!parameters || typeof parameters !== \"object\") {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === \"properties\") {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n } else {\n const paramText =\n typeof value === \"string\" ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nconst calculateToolTokens = (\n tool: Tool,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || \"\"\n if (fDesc.endsWith(\".\")) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = fName + \":\" + fDesc\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === \"object\" // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport const numTokensForTools = (\n tools: Array<Tool>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport const getTokenCount = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<{ input: number; output: number }> => {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const simplifiedMessages = payload.messages\n const inputMessages = simplifiedMessages.filter(\n (msg) => msg.role !== \"assistant\",\n )\n const outputMessages = simplifiedMessages.filter(\n (msg) => msg.role === \"assistant\",\n )\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 {\n input: inputTokens,\n output: outputTokens,\n }\n}\n\n/**\n * Estimate token count for a payload without model info (uses o200k_base encoding)\n * This is a rough estimate used when we don't have model-specific info\n */\nexport const estimateTokenCount = async (\n payload: ChatCompletionsPayload,\n): Promise<number> => {\n const encoder = await getEncodeChatFunction(\"o200k_base\")\n\n // Simple estimation: encode all message content\n let tokens = 0\n for (const message of payload.messages) {\n // 3 tokens per message overhead\n tokens += 3\n\n if (typeof message.content === \"string\") {\n tokens += encoder.encode(message.content).length\n } else if (Array.isArray(message.content)) {\n for (const part of message.content) {\n if (part.type === \"text\" && part.text) {\n tokens += encoder.encode(part.text).length\n } else if (part.type === \"image_url\") {\n // Rough estimate for images\n tokens += 85\n }\n }\n }\n\n // Add role tokens\n if (message.role) {\n tokens += encoder.encode(message.role).length\n }\n\n // Tool calls in messages (assistant responses with tool use)\n if (message.tool_calls) {\n tokens += encoder.encode(JSON.stringify(message.tool_calls)).length\n }\n }\n\n // Add tool definitions if present (but don't double count - use simplified estimate)\n // Tool definitions add overhead but the full JSON stringify overcounts\n if (payload.tools && payload.tools.length > 0) {\n // Estimate ~50 tokens per tool on average for function name + description + params\n tokens += payload.tools.length * 50\n }\n\n // Priming tokens\n tokens += 3\n\n return tokens\n}\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport const createChatCompletions = async (\r\n payload: ChatCompletionsPayload,\r\n options?: {\r\n initiator?: \"agent\" | \"user\"\r\n },\r\n) => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const enableVision = payload.messages.some(\r\n (x) =>\r\n typeof x.content !== \"string\"\r\n && x.content?.some((x) => x.type === \"image_url\"),\r\n )\r\n\r\n // Agent/user check for X-Initiator header\r\n // Check only the last message to prevent false positives in multi-turn conversations\r\n let isAgentCall = false\r\n if (payload.messages.length > 0) {\r\n const lastMessage = payload.messages.at(-1)\r\n if (lastMessage) {\r\n isAgentCall = [\"assistant\", \"tool\"].includes(lastMessage.role)\r\n }\r\n }\r\n\r\n // Build headers and add X-Initiator\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, enableVision),\r\n \"X-Initiator\": options?.initiator ?? (isAgentCall ? \"agent\" : \"user\"),\r\n }\r\n\r\n const response = await fetchWithRetry(\r\n `${copilotBaseUrl(state)}/chat/completions`,\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n },\r\n )\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create chat completions\", response)\r\n throw new HTTPError(\"Failed to create chat completions\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as ChatCompletionResponse\r\n}\r\n\r\n// Streaming types\r\n\r\nexport interface ChatCompletionChunk {\r\n id: string\r\n object: \"chat.completion.chunk\"\r\n created: number\r\n model: string\r\n choices: Array<Choice>\r\n system_fingerprint?: string\r\n usage?: {\r\n prompt_tokens: number\r\n completion_tokens: number\r\n total_tokens: number\r\n prompt_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n completion_tokens_details?: {\r\n accepted_prediction_tokens: number\r\n rejected_prediction_tokens: number\r\n }\r\n }\r\n}\r\n\r\ninterface Delta {\r\n content?: string | null\r\n role?: \"user\" | \"assistant\" | \"system\" | \"tool\"\r\n tool_calls?: Array<{\r\n index: number\r\n id?: string\r\n type?: \"function\"\r\n function?: {\r\n name?: string\r\n arguments?: string\r\n }\r\n }>\r\n}\r\n\r\ninterface Choice {\r\n index: number\r\n delta: Delta\r\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\r\n logprobs: object | null\r\n}\r\n\r\n// Non-streaming types\r\n\r\nexport interface ChatCompletionResponse {\r\n id: string\r\n object: \"chat.completion\"\r\n created: number\r\n model: string\r\n choices: Array<ChoiceNonStreaming>\r\n system_fingerprint?: string\r\n usage?: {\r\n prompt_tokens: number\r\n completion_tokens: number\r\n total_tokens: number\r\n prompt_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n }\r\n}\r\n\r\ninterface ResponseMessage {\r\n role: \"assistant\"\r\n content: string | null\r\n tool_calls?: Array<ToolCall>\r\n}\r\n\r\ninterface ChoiceNonStreaming {\r\n index: number\r\n message: ResponseMessage\r\n logprobs: object | null\r\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\"\r\n}\r\n\r\n// Payload types\r\n\r\nexport interface ChatCompletionsPayload {\r\n messages: Array<Message>\r\n model: string\r\n temperature?: number | null\r\n top_p?: number | null\r\n max_tokens?: number | null\r\n stop?: string | Array<string> | null\r\n n?: number | null\r\n stream?: boolean | null\r\n stream_options?: { include_usage?: boolean } | null\r\n\r\n frequency_penalty?: number | null\r\n presence_penalty?: number | null\r\n logit_bias?: Record<string, number> | null\r\n logprobs?: boolean | null\r\n response_format?: { type: \"json_object\" } | null\r\n seed?: number | null\r\n tools?: Array<Tool> | null\r\n tool_choice?:\r\n | \"none\"\r\n | \"auto\"\r\n | \"required\"\r\n | { type: \"function\"; function: { name: string } }\r\n | null\r\n user?: string | null\r\n}\r\n\r\nexport interface Tool {\r\n type: \"function\"\r\n function: {\r\n name: string\r\n description?: string\r\n parameters: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport interface Message {\r\n role: \"user\" | \"assistant\" | \"system\" | \"tool\" | \"developer\"\r\n content: string | Array<ContentPart> | null\r\n\r\n name?: string\r\n tool_calls?: Array<ToolCall>\r\n tool_call_id?: string\r\n}\r\n\r\nexport interface ToolCall {\r\n id: string\r\n type: \"function\"\r\n function: {\r\n name: string\r\n arguments: string\r\n }\r\n}\r\n\r\nexport type ContentPart = TextPart | ImagePart\r\n\r\nexport interface TextPart {\r\n type: \"text\"\r\n text: string\r\n}\r\n\r\nexport interface ImagePart {\r\n type: \"image_url\"\r\n image_url: {\r\n url: string\r\n detail?: \"low\" | \"high\" | \"auto\"\r\n }\r\n}\r\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { streamSSE, type SSEMessage } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { applyReplacementsToPayload } from \"~/lib/auto-replace\"\nimport { normalizeModelName } from \"~/lib/model-resolver\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { setRequestContext } from \"~/lib/request-logger\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport { isNullish } from \"~/lib/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n} from \"~/services/copilot/create-chat-completions\"\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const rawPayload = await c.req.json<ChatCompletionsPayload>()\n\n // Apply auto-replacements to the payload\n\n let payload = await applyReplacementsToPayload(rawPayload)\n\n // Normalize model name (e.g., claude-opus-4-5 -> claude-opus-4.5)\n payload = {\n ...payload,\n model: normalizeModelName(payload.model),\n }\n\n consola.debug(\"Request payload:\", JSON.stringify(payload).slice(-400))\n\n setRequestContext(c, { provider: \"Copilot\", model: payload.model })\n\n // Find the selected model\n const selectedModel = state.models?.data.find(\n (model) => model.id === payload.model,\n )\n\n // Calculate and display token count\n try {\n if (selectedModel) {\n const tokenCount = await getTokenCount(payload, selectedModel)\n setRequestContext(c, { inputTokens: tokenCount.input })\n }\n } catch (error) {\n consola.warn(\"Failed to calculate token count:\", error)\n }\n\n if (state.manualApprove) await awaitApproval()\n\n if (isNullish(payload.max_tokens)) {\n payload = {\n ...payload,\n max_tokens: selectedModel?.capabilities.limits.max_output_tokens,\n }\n consola.debug(\"Set max_tokens to:\", JSON.stringify(payload.max_tokens))\n }\n\n const response = await createChatCompletions(payload)\n\n if (isNonStreaming(response)) {\n consola.debug(\"Non-streaming response:\", JSON.stringify(response))\n if (response.usage) {\n setRequestContext(c, {\n inputTokens: response.usage.prompt_tokens,\n outputTokens: response.usage.completion_tokens,\n })\n }\n return c.json(response)\n }\n\n consola.debug(\"Streaming response\")\n return streamSSE(c, async (stream) => {\n for await (const chunk of response) {\n consola.debug(\"Streaming chunk:\", JSON.stringify(chunk))\n // Capture usage from final chunk if available\n if (chunk.data && chunk.data !== \"[DONE]\") {\n const parsed = JSON.parse(chunk.data) as ChatCompletionChunk\n if (parsed.usage) {\n setRequestContext(c, {\n inputTokens: parsed.usage.prompt_tokens,\n outputTokens: parsed.usage.completion_tokens,\n })\n }\n }\n await stream.writeSSE(chunk as SSEMessage)\n }\n })\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCompletion } from \"./handler\"\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\nimport { state } from \"~/lib/state\"\n\nexport const createEmbeddings = async (payload: EmbeddingRequest) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const response = await fetchWithRetry(`${copilotBaseUrl(state)}/embeddings`, {\n method: \"POST\",\n headers: copilotHeaders(state),\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to create embeddings\", response)\n\n return (await response.json()) as EmbeddingResponse\n}\n\nexport interface EmbeddingRequest {\n input: string | Array<string>\n model: string\n}\n\nexport interface Embedding {\n object: string\n embedding: Array<number>\n index: number\n}\n\nexport interface EmbeddingResponse {\n object: string\n data: Array<Embedding>\n model: string\n usage: {\n prompt_tokens: number\n total_tokens: number\n }\n}\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport {\n createEmbeddings,\n type EmbeddingRequest,\n} from \"~/services/copilot/create-embeddings\"\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post(\"/\", async (c) => {\n try {\n const paylod = await c.req.json<EmbeddingRequest>()\n const response = await createEmbeddings(paylod)\n\n return c.json(response)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { type AnthropicResponse } from \"./anthropic-types\"\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null,\n): AnthropicResponse[\"stop_reason\"] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: \"end_turn\",\n length: \"max_tokens\",\n tool_calls: \"tool_use\",\n content_filter: \"end_turn\",\n } as const\n return stopReasonMap[finishReason]\n}\n","import {\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n type ContentPart,\n type Message,\n type TextPart,\n type Tool,\n type ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicResponse,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\n// Payload translation\n\nexport function translateToOpenAI(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload {\n return {\n model: translateModelName(payload.model),\n messages: translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),\n }\n}\n\nfunction translateModelName(model: string): string {\n // Subagent requests use a specific dated model which Copilot doesn't support\n // e.g., claude-sonnet-4-20250514 -> claude-sonnet-4\n // But preserve version numbers like claude-opus-4-5 (normalized to claude-opus-4.5 later)\n if (/^claude-sonnet-4-\\d{8}/.test(model)) {\n return \"claude-sonnet-4\"\n } else if (/^claude-opus-4-\\d{8}/.test(model)) {\n return \"claude-opus-4\"\n }\n return model\n}\n\nfunction translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n const systemMessages = handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap((message) =>\n message.role === \"user\" ?\n handleUserMessage(message)\n : handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n}\n\nfunction handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === \"string\") {\n return [{ role: \"system\", content: system }]\n } else {\n const systemText = system.map((block) => block.text).join(\"\\n\\n\")\n return [{ role: \"system\", content: systemText }]\n }\n}\n\nfunction handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === \"tool_result\",\n )\n const otherBlocks = message.content.filter(\n (block) => block.type !== \"tool_result\",\n )\n\n // Tool results must come first to maintain protocol: tool_use -> tool_result -> user\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: \"tool\",\n tool_call_id: block.tool_use_id,\n content: mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: \"user\",\n content: mapContent(otherBlocks),\n })\n }\n } else {\n newMessages.push({\n role: \"user\",\n content: mapContent(message.content),\n })\n }\n\n return newMessages\n}\n\nfunction handleAssistantMessage(\n message: AnthropicAssistantMessage,\n): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === \"tool_use\",\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === \"text\",\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === \"thinking\",\n )\n\n // Combine text and thinking blocks, as OpenAI doesn't have separate thinking blocks\n const allTextContent = [\n ...textBlocks.map((b) => b.text),\n ...thinkingBlocks.map((b) => b.thinking),\n ].join(\"\\n\\n\")\n\n return toolUseBlocks.length > 0 ?\n [\n {\n role: \"assistant\",\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map((toolUse) => ({\n id: toolUse.id,\n type: \"function\",\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n}\n\nfunction mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n): string | Array<ContentPart> | null {\n if (typeof content === \"string\") {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some((block) => block.type === \"image\")\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === \"text\" || block.type === \"thinking\",\n )\n .map((block) => (block.type === \"text\" ? block.text : block.thinking))\n .join(\"\\n\\n\")\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n contentParts.push({ type: \"text\", text: block.text })\n\n break\n }\n case \"thinking\": {\n contentParts.push({ type: \"text\", text: block.thinking })\n\n break\n }\n case \"image\": {\n contentParts.push({\n type: \"image_url\",\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n\n break\n }\n // No default\n }\n }\n return contentParts\n}\n\nfunction translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map((tool) => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n}\n\nfunction translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload[\"tool_choice\"],\n): ChatCompletionsPayload[\"tool_choice\"] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n if (anthropicToolChoice.name) {\n return {\n type: \"function\",\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return undefined\n }\n }\n}\n\n// Response translation\n\nexport function translateToAnthropic(\n response: ChatCompletionResponse,\n originalModel?: string,\n): AnthropicResponse {\n const { contentBlocks, stopReason } = extractContentFromChoices(response)\n return buildAnthropicResponse(response, {\n contentBlocks,\n stopReason,\n originalModel,\n })\n}\n\nfunction extractContentFromChoices(response: ChatCompletionResponse): {\n contentBlocks: Array<AnthropicTextBlock | AnthropicToolUseBlock>\n stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n} {\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null =\n response.choices[0]?.finish_reason ?? null\n\n for (const choice of response.choices) {\n allTextBlocks.push(...getAnthropicTextBlocks(choice.message.content))\n allToolUseBlocks.push(\n ...getAnthropicToolUseBlocks(choice.message.tool_calls),\n )\n\n if (choice.finish_reason === \"tool_calls\" || stopReason === \"stop\") {\n stopReason = choice.finish_reason\n }\n }\n\n return {\n contentBlocks: [...allTextBlocks, ...allToolUseBlocks],\n stopReason,\n }\n}\n\nfunction buildAnthropicResponse(\n response: ChatCompletionResponse,\n options: {\n contentBlocks: Array<AnthropicTextBlock | AnthropicToolUseBlock>\n stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n originalModel?: string\n },\n): AnthropicResponse {\n const { contentBlocks, stopReason, originalModel } = options\n const cachedTokens = response.usage?.prompt_tokens_details?.cached_tokens ?? 0\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n model: originalModel ?? response.model,\n content: contentBlocks,\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n // Anthropic input_tokens = uncached tokens only\n // OpenAI prompt_tokens includes cached, so subtract them\n input_tokens: (response.usage?.prompt_tokens ?? 0) - cachedTokens,\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(cachedTokens > 0 && {\n cache_read_input_tokens: cachedTokens,\n }),\n },\n }\n}\n\nfunction getAnthropicTextBlocks(\n messageContent: Message[\"content\"],\n): Array<AnthropicTextBlock> {\n if (typeof messageContent === \"string\") {\n return [{ type: \"text\", text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text }))\n }\n\n return []\n}\n\nfunction getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map((toolCall) => ({\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\n\nimport { normalizeModelName } from \"~/lib/model-resolver\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\n\nimport { type AnthropicMessagesPayload } from \"./anthropic-types\"\nimport { translateToOpenAI } from \"./non-stream-translation\"\n\n/**\n * Handles token counting for Anthropic messages\n */\nexport async function handleCountTokens(c: Context) {\n try {\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n // Normalize model name (e.g., claude-opus-4-5 -> claude-opus-4.5) before lookup\n const normalizedModel = normalizeModelName(anthropicPayload.model)\n\n const selectedModel = state.models?.data.find(\n (model) => model.id === normalizedModel,\n )\n\n if (!selectedModel) {\n consola.warn(\"Model not found, returning default token count\")\n return c.json({\n input_tokens: 1,\n })\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith(\"claude-code\")) {\n mcpToolExist = anthropicPayload.tools.some((tool) =>\n tool.name.startsWith(\"mcp__\"),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith(\"claude\")) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith(\"claude\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.info(\"Token count:\", finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n } catch (error) {\n consola.error(\"Error counting tokens:\", error)\n return c.json({\n input_tokens: 1,\n })\n }\n}\n","import consola, { type ConsolaInstance } from \"consola\"\r\nimport fs from \"node:fs\"\r\nimport path from \"node:path\"\r\nimport util from \"node:util\"\r\n\r\nimport { PATHS } from \"./paths\"\r\nimport { state } from \"./state\"\r\n\r\nconst LOG_RETENTION_DAYS = 7\r\nconst LOG_RETENTION_MS = LOG_RETENTION_DAYS * 24 * 60 * 60 * 1000\r\nconst CLEANUP_INTERVAL_MS = 24 * 60 * 60 * 1000\r\nconst LOG_DIR = path.join(PATHS.APP_DIR, \"logs\")\r\nconst FLUSH_INTERVAL_MS = 1000\r\nconst MAX_BUFFER_SIZE = 100\r\n\r\nconst logStreams = new Map<string, fs.WriteStream>()\r\nconst logBuffers = new Map<string, Array<string>>()\r\n\r\nconst ensureLogDirectory = () => {\r\n if (!fs.existsSync(LOG_DIR)) {\r\n fs.mkdirSync(LOG_DIR, { recursive: true })\r\n }\r\n}\r\n\r\nconst cleanupOldLogs = () => {\r\n if (!fs.existsSync(LOG_DIR)) {\r\n return\r\n }\r\n\r\n const now = Date.now()\r\n\r\n for (const entry of fs.readdirSync(LOG_DIR)) {\r\n const filePath = path.join(LOG_DIR, entry)\r\n\r\n let stats: fs.Stats\r\n try {\r\n stats = fs.statSync(filePath)\r\n } catch {\r\n continue\r\n }\r\n\r\n if (!stats.isFile()) {\r\n continue\r\n }\r\n\r\n if (now - stats.mtimeMs > LOG_RETENTION_MS) {\r\n try {\r\n fs.rmSync(filePath)\r\n } catch {\r\n continue\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst formatArgs = (args: Array<unknown>) =>\r\n args\r\n .map((arg) =>\r\n typeof arg === \"string\" ? arg : (\r\n util.inspect(arg, { depth: null, colors: false })\r\n ),\r\n )\r\n .join(\" \")\r\n\r\nconst sanitizeName = (name: string) => {\r\n const normalized = name\r\n .toLowerCase()\r\n .replaceAll(/[^a-z0-9]+/g, \"-\")\r\n .replaceAll(/^-+|-+$/g, \"\")\r\n\r\n return normalized === \"\" ? \"handler\" : normalized\r\n}\r\n\r\nconst getLogStream = (filePath: string): fs.WriteStream => {\r\n let stream = logStreams.get(filePath)\r\n if (!stream || stream.destroyed) {\r\n stream = fs.createWriteStream(filePath, { flags: \"a\" })\r\n logStreams.set(filePath, stream)\r\n\r\n stream.on(\"error\", (error: unknown) => {\r\n console.warn(\"Log stream error\", error)\r\n logStreams.delete(filePath)\r\n })\r\n }\r\n return stream\r\n}\r\n\r\nconst flushBuffer = (filePath: string) => {\r\n const buffer = logBuffers.get(filePath)\r\n if (!buffer || buffer.length === 0) {\r\n return\r\n }\r\n\r\n const stream = getLogStream(filePath)\r\n const content = buffer.join(\"\\n\") + \"\\n\"\r\n stream.write(content, (error) => {\r\n if (error) {\r\n console.warn(\"Failed to write handler log\", error)\r\n }\r\n })\r\n\r\n logBuffers.set(filePath, [])\r\n}\r\n\r\nconst flushAllBuffers = () => {\r\n for (const filePath of logBuffers.keys()) {\r\n flushBuffer(filePath)\r\n }\r\n}\r\n\r\nconst appendLine = (filePath: string, line: string) => {\r\n let buffer = logBuffers.get(filePath)\r\n if (!buffer) {\r\n buffer = []\r\n logBuffers.set(filePath, buffer)\r\n }\r\n\r\n buffer.push(line)\r\n\r\n if (buffer.length >= MAX_BUFFER_SIZE) {\r\n flushBuffer(filePath)\r\n }\r\n}\r\n\r\nsetInterval(flushAllBuffers, FLUSH_INTERVAL_MS)\r\n\r\nconst cleanup = () => {\r\n flushAllBuffers()\r\n for (const stream of logStreams.values()) {\r\n stream.end()\r\n }\r\n logStreams.clear()\r\n logBuffers.clear()\r\n}\r\n\r\nprocess.on(\"exit\", cleanup)\r\nprocess.on(\"SIGINT\", () => {\r\n cleanup()\r\n process.exit(0)\r\n})\r\nprocess.on(\"SIGTERM\", () => {\r\n cleanup()\r\n process.exit(0)\r\n})\r\n\r\nlet lastCleanup = 0\r\n\r\nexport const createHandlerLogger = (name: string): ConsolaInstance => {\r\n ensureLogDirectory()\r\n\r\n const sanitizedName = sanitizeName(name)\r\n const instance = consola.withTag(name)\r\n\r\n if (state.verbose) {\r\n instance.level = 5\r\n }\r\n instance.setReporters([])\r\n\r\n instance.addReporter({\r\n log(logObj) {\r\n ensureLogDirectory()\r\n\r\n if (Date.now() - lastCleanup > CLEANUP_INTERVAL_MS) {\r\n cleanupOldLogs()\r\n lastCleanup = Date.now()\r\n }\r\n\r\n const date = logObj.date\r\n const dateKey = date.toLocaleDateString(\"sv-SE\")\r\n const timestamp = date.toLocaleString(\"sv-SE\", { hour12: false })\r\n const filePath = path.join(LOG_DIR, `${sanitizedName}-${dateKey}.log`)\r\n const message = formatArgs(logObj.args as Array<unknown>)\r\n const line = `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${\r\n message ? ` ${message}` : \"\"\r\n }`\r\n\r\n appendLine(filePath, line)\r\n },\r\n })\r\n\r\n return instance\r\n}\r\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport interface ResponsesPayload {\r\n model: string\r\n instructions?: string | null\r\n input?: string | Array<ResponseInputItem>\r\n tools?: Array<Tool> | null\r\n tool_choice?: ToolChoiceOptions | ToolChoiceFunction\r\n temperature?: number | null\r\n top_p?: number | null\r\n max_output_tokens?: number | null\r\n metadata?: Metadata | null\r\n stream?: boolean | null\r\n safety_identifier?: string | null\r\n prompt_cache_key?: string | null\r\n parallel_tool_calls?: boolean | null\r\n store?: boolean | null\r\n reasoning?: Reasoning | null\r\n include?: Array<ResponseIncludable>\r\n service_tier?: string | null // NOTE: Unsupported by GitHub Copilot\r\n [key: string]: unknown\r\n}\r\n\r\nexport type ToolChoiceOptions = \"none\" | \"auto\" | \"required\"\r\n\r\nexport interface ToolChoiceFunction {\r\n name: string\r\n type: \"function\"\r\n}\r\n\r\nexport type Tool = FunctionTool | Record<string, unknown>\r\n\r\nexport interface FunctionTool {\r\n name: string\r\n parameters: { [key: string]: unknown } | null\r\n strict: boolean | null\r\n type: \"function\"\r\n description?: string | null\r\n}\r\n\r\nexport type ResponseIncludable =\r\n | \"file_search_call.results\"\r\n | \"message.input_image.image_url\"\r\n | \"computer_call_output.output.image_url\"\r\n | \"reasoning.encrypted_content\"\r\n | \"code_interpreter_call.outputs\"\r\n\r\nexport interface Reasoning {\r\n effort?: \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | null\r\n summary?: \"auto\" | \"concise\" | \"detailed\" | null\r\n}\r\n\r\nexport interface ResponseInputMessage {\r\n type?: \"message\"\r\n role: \"user\" | \"assistant\" | \"system\" | \"developer\"\r\n content?: string | Array<ResponseInputContent>\r\n status?: string\r\n phase?: \"commentary\" | \"final_answer\"\r\n}\r\n\r\nexport interface ResponseFunctionToolCallItem {\r\n type: \"function_call\"\r\n call_id: string\r\n name: string\r\n arguments: string\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseFunctionCallOutputItem {\r\n type: \"function_call_output\"\r\n call_id: string\r\n output: string | Array<ResponseInputContent>\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseInputReasoning {\r\n id?: string\r\n type: \"reasoning\"\r\n summary: Array<{\r\n type: \"summary_text\"\r\n text: string\r\n }>\r\n encrypted_content: string\r\n}\r\n\r\nexport type ResponseInputItem =\r\n | ResponseInputMessage\r\n | ResponseFunctionToolCallItem\r\n | ResponseFunctionCallOutputItem\r\n | ResponseInputReasoning\r\n | Record<string, unknown>\r\n\r\nexport type ResponseInputContent =\r\n | ResponseInputText\r\n | ResponseInputImage\r\n | Record<string, unknown>\r\n\r\nexport interface ResponseInputText {\r\n type: \"input_text\" | \"output_text\"\r\n text: string\r\n}\r\n\r\nexport interface ResponseInputImage {\r\n type: \"input_image\"\r\n image_url?: string | null\r\n file_id?: string | null\r\n detail: \"low\" | \"high\" | \"auto\"\r\n}\r\n\r\nexport interface ResponsesResult {\r\n id: string\r\n object: \"response\"\r\n created_at: number\r\n model: string\r\n output: Array<ResponseOutputItem>\r\n output_text: string\r\n status: string\r\n usage?: ResponseUsage | null\r\n error: ResponseError | null\r\n incomplete_details: IncompleteDetails | null\r\n instructions: string | null\r\n metadata: Metadata | null\r\n parallel_tool_calls: boolean\r\n temperature: number | null\r\n tool_choice: unknown\r\n tools: Array<Tool>\r\n top_p: number | null\r\n}\r\n\r\nexport type Metadata = { [key: string]: string }\r\n\r\nexport interface IncompleteDetails {\r\n reason?: \"max_output_tokens\" | \"content_filter\"\r\n}\r\n\r\nexport interface ResponseError {\r\n message: string\r\n}\r\n\r\nexport type ResponseOutputItem =\r\n | ResponseOutputMessage\r\n | ResponseOutputReasoning\r\n | ResponseOutputFunctionCall\r\n\r\nexport interface ResponseOutputMessage {\r\n id: string\r\n type: \"message\"\r\n role: \"assistant\"\r\n status: \"completed\" | \"in_progress\" | \"incomplete\"\r\n content?: Array<ResponseOutputContentBlock>\r\n}\r\n\r\nexport interface ResponseOutputReasoning {\r\n id: string\r\n type: \"reasoning\"\r\n summary?: Array<ResponseReasoningBlock>\r\n encrypted_content?: string\r\n status?: \"completed\" | \"in_progress\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseReasoningBlock {\r\n type: string\r\n text?: string\r\n}\r\n\r\nexport interface ResponseOutputFunctionCall {\r\n id?: string\r\n type: \"function_call\"\r\n call_id: string\r\n name: string\r\n arguments: string\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport type ResponseOutputContentBlock =\r\n | ResponseOutputText\r\n | ResponseOutputRefusal\r\n | Record<string, unknown>\r\n\r\nexport interface ResponseOutputText {\r\n type: \"output_text\"\r\n text: string\r\n annotations: Array<unknown>\r\n}\r\n\r\nexport interface ResponseOutputRefusal {\r\n type: \"refusal\"\r\n refusal: string\r\n}\r\n\r\nexport interface ResponseUsage {\r\n input_tokens: number\r\n output_tokens?: number\r\n total_tokens: number\r\n input_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n output_tokens_details?: {\r\n reasoning_tokens: number\r\n }\r\n}\r\n\r\nexport type ResponseStreamEvent =\r\n | ResponseCompletedEvent\r\n | ResponseIncompleteEvent\r\n | ResponseCreatedEvent\r\n | ResponseErrorEvent\r\n | ResponseFunctionCallArgumentsDeltaEvent\r\n | ResponseFunctionCallArgumentsDoneEvent\r\n | ResponseFailedEvent\r\n | ResponseOutputItemAddedEvent\r\n | ResponseOutputItemDoneEvent\r\n | ResponseReasoningSummaryTextDeltaEvent\r\n | ResponseReasoningSummaryTextDoneEvent\r\n | ResponseTextDeltaEvent\r\n | ResponseTextDoneEvent\r\n\r\nexport interface ResponseCompletedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.completed\"\r\n}\r\n\r\nexport interface ResponseIncompleteEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.incomplete\"\r\n}\r\n\r\nexport interface ResponseCreatedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.created\"\r\n}\r\n\r\nexport interface ResponseErrorEvent {\r\n code: string | null\r\n message: string\r\n param: string | null\r\n sequence_number: number\r\n type: \"error\"\r\n}\r\n\r\nexport interface ResponseFunctionCallArgumentsDeltaEvent {\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.function_call_arguments.delta\"\r\n}\r\n\r\nexport interface ResponseFunctionCallArgumentsDoneEvent {\r\n arguments: string\r\n item_id: string\r\n name: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.function_call_arguments.done\"\r\n}\r\n\r\nexport interface ResponseFailedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.failed\"\r\n}\r\n\r\nexport interface ResponseOutputItemAddedEvent {\r\n item: ResponseOutputItem\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_item.added\"\r\n}\r\n\r\nexport interface ResponseOutputItemDoneEvent {\r\n item: ResponseOutputItem\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_item.done\"\r\n}\r\n\r\nexport interface ResponseReasoningSummaryTextDeltaEvent {\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n summary_index: number\r\n type: \"response.reasoning_summary_text.delta\"\r\n}\r\n\r\nexport interface ResponseReasoningSummaryTextDoneEvent {\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n summary_index: number\r\n text: string\r\n type: \"response.reasoning_summary_text.done\"\r\n}\r\n\r\nexport interface ResponseTextDeltaEvent {\r\n content_index: number\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_text.delta\"\r\n}\r\n\r\nexport interface ResponseTextDoneEvent {\r\n content_index: number\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n text: string\r\n type: \"response.output_text.done\"\r\n}\r\n\r\nexport type ResponsesStream = ReturnType<typeof events>\r\nexport type CreateResponsesReturn = ResponsesResult | ResponsesStream\r\n\r\ninterface ResponsesRequestOptions {\r\n vision: boolean\r\n initiator: \"agent\" | \"user\"\r\n}\r\n\r\nexport const createResponses = async (\r\n payload: ResponsesPayload,\r\n { vision, initiator }: ResponsesRequestOptions,\r\n): Promise<CreateResponsesReturn> => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, vision),\r\n \"X-Initiator\": initiator,\r\n }\r\n\r\n // service_tier is not supported by github copilot\r\n payload.service_tier = null\r\n\r\n const response = await fetch(`${copilotBaseUrl(state)}/responses`, {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n })\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create responses\", response)\r\n throw new HTTPError(\"Failed to create responses\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as ResponsesResult\r\n}\r\n","import consola from \"consola\"\r\n\r\nimport {\r\n getExtraPromptForModel,\r\n getReasoningEffortForModel,\r\n} from \"~/lib/config\"\r\nimport {\r\n type ResponsesPayload,\r\n type ResponseInputContent,\r\n type ResponseInputImage,\r\n type ResponseInputItem,\r\n type ResponseInputMessage,\r\n type ResponseInputReasoning,\r\n type ResponseInputText,\r\n type ResponsesResult,\r\n type ResponseOutputContentBlock,\r\n type ResponseOutputFunctionCall,\r\n type ResponseOutputItem,\r\n type ResponseOutputReasoning,\r\n type ResponseReasoningBlock,\r\n type ResponseOutputRefusal,\r\n type ResponseOutputText,\r\n type ResponseFunctionToolCallItem,\r\n type ResponseFunctionCallOutputItem,\r\n type Tool,\r\n type ToolChoiceFunction,\r\n type ToolChoiceOptions,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nimport {\r\n type AnthropicAssistantContentBlock,\r\n type AnthropicAssistantMessage,\r\n type AnthropicResponse,\r\n type AnthropicImageBlock,\r\n type AnthropicMessage,\r\n type AnthropicMessagesPayload,\r\n type AnthropicTextBlock,\r\n type AnthropicThinkingBlock,\r\n type AnthropicTool,\r\n type AnthropicToolResultBlock,\r\n type AnthropicToolUseBlock,\r\n type AnthropicUserContentBlock,\r\n type AnthropicUserMessage,\r\n} from \"./anthropic-types\"\r\n\r\nconst MESSAGE_TYPE = \"message\"\r\nconst CODEX_PHASE_MODEL = \"gpt-5.3-codex\"\r\n\r\nexport const THINKING_TEXT = \"Thinking...\"\r\n\r\nexport const translateAnthropicMessagesToResponsesPayload = (\r\n payload: AnthropicMessagesPayload,\r\n): ResponsesPayload => {\r\n const input: Array<ResponseInputItem> = []\r\n\r\n for (const message of payload.messages) {\r\n input.push(...translateMessage(message, payload.model))\r\n }\r\n\r\n const translatedTools = convertAnthropicTools(payload.tools)\r\n const toolChoice = convertAnthropicToolChoice(payload.tool_choice)\r\n\r\n const { safetyIdentifier, promptCacheKey } = parseUserId(\r\n payload.metadata?.user_id,\r\n )\r\n\r\n const responsesPayload: ResponsesPayload = {\r\n model: payload.model,\r\n input,\r\n instructions: translateSystemPrompt(payload.system, payload.model),\r\n temperature: 1, // reasoning high temperature fixed to 1\r\n top_p: payload.top_p ?? null,\r\n max_output_tokens: Math.max(payload.max_tokens, 12800),\r\n tools: translatedTools,\r\n tool_choice: toolChoice,\r\n metadata: payload.metadata ? { ...payload.metadata } : null,\r\n safety_identifier: safetyIdentifier,\r\n prompt_cache_key: promptCacheKey,\r\n stream: payload.stream ?? null,\r\n store: false,\r\n parallel_tool_calls: true,\r\n reasoning: {\r\n effort: getReasoningEffortForModel(payload.model),\r\n summary: \"detailed\",\r\n },\r\n include: [\"reasoning.encrypted_content\"],\r\n }\r\n\r\n return responsesPayload\r\n}\r\n\r\nconst translateMessage = (\r\n message: AnthropicMessage,\r\n model: string,\r\n): Array<ResponseInputItem> => {\r\n if (message.role === \"user\") {\r\n return translateUserMessage(message)\r\n }\r\n\r\n return translateAssistantMessage(message, model)\r\n}\r\n\r\nconst translateUserMessage = (\r\n message: AnthropicUserMessage,\r\n): Array<ResponseInputItem> => {\r\n if (typeof message.content === \"string\") {\r\n return [createMessage(\"user\", message.content)]\r\n }\r\n\r\n if (!Array.isArray(message.content)) {\r\n return []\r\n }\r\n\r\n const items: Array<ResponseInputItem> = []\r\n const pendingContent: Array<ResponseInputContent> = []\r\n\r\n for (const block of message.content) {\r\n if (block.type === \"tool_result\") {\r\n flushPendingContent(pendingContent, items, { role: \"user\" })\r\n items.push(createFunctionCallOutput(block))\r\n continue\r\n }\r\n\r\n const converted = translateUserContentBlock(block)\r\n if (converted) {\r\n pendingContent.push(converted)\r\n }\r\n }\r\n\r\n flushPendingContent(pendingContent, items, { role: \"user\" })\r\n\r\n return items\r\n}\r\n\r\nconst translateAssistantMessage = (\r\n message: AnthropicAssistantMessage,\r\n model: string,\r\n): Array<ResponseInputItem> => {\r\n const assistantPhase = resolveAssistantPhase(model, message.content)\r\n\r\n if (typeof message.content === \"string\") {\r\n return [createMessage(\"assistant\", message.content, assistantPhase)]\r\n }\r\n\r\n if (!Array.isArray(message.content)) {\r\n return []\r\n }\r\n\r\n const items: Array<ResponseInputItem> = []\r\n const pendingContent: Array<ResponseInputContent> = []\r\n\r\n for (const block of message.content) {\r\n if (block.type === \"tool_use\") {\r\n flushPendingContent(pendingContent, items, {\r\n role: \"assistant\",\r\n phase: assistantPhase,\r\n })\r\n items.push(createFunctionToolCall(block))\r\n continue\r\n }\r\n\r\n if (\r\n block.type === \"thinking\"\r\n && block.signature\r\n && block.signature.includes(\"@\")\r\n ) {\r\n flushPendingContent(pendingContent, items, {\r\n role: \"assistant\",\r\n phase: assistantPhase,\r\n })\r\n items.push(createReasoningContent(block))\r\n continue\r\n }\r\n\r\n const converted = translateAssistantContentBlock(block)\r\n if (converted) {\r\n pendingContent.push(converted)\r\n }\r\n }\r\n\r\n flushPendingContent(pendingContent, items, {\r\n role: \"assistant\",\r\n phase: assistantPhase,\r\n })\r\n\r\n return items\r\n}\r\n\r\nconst translateUserContentBlock = (\r\n block: AnthropicUserContentBlock,\r\n): ResponseInputContent | undefined => {\r\n switch (block.type) {\r\n case \"text\": {\r\n return createTextContent(block.text)\r\n }\r\n case \"image\": {\r\n return createImageContent(block)\r\n }\r\n default: {\r\n return undefined\r\n }\r\n }\r\n}\r\n\r\nconst translateAssistantContentBlock = (\r\n block: AnthropicAssistantContentBlock,\r\n): ResponseInputContent | undefined => {\r\n switch (block.type) {\r\n case \"text\": {\r\n return createOutPutTextContent(block.text)\r\n }\r\n default: {\r\n return undefined\r\n }\r\n }\r\n}\r\n\r\nconst flushPendingContent = (\r\n pendingContent: Array<ResponseInputContent>,\r\n target: Array<ResponseInputItem>,\r\n message: Pick<ResponseInputMessage, \"role\" | \"phase\">,\r\n) => {\r\n if (pendingContent.length === 0) {\r\n return\r\n }\r\n\r\n const messageContent = [...pendingContent]\r\n\r\n target.push(createMessage(message.role, messageContent, message.phase))\r\n pendingContent.length = 0\r\n}\r\n\r\nconst createMessage = (\r\n role: ResponseInputMessage[\"role\"],\r\n content: string | Array<ResponseInputContent>,\r\n phase?: ResponseInputMessage[\"phase\"],\r\n): ResponseInputMessage => ({\r\n type: MESSAGE_TYPE,\r\n role,\r\n content,\r\n ...(role === \"assistant\" && phase ? { phase } : {}),\r\n})\r\n\r\nconst resolveAssistantPhase = (\r\n model: string,\r\n content: AnthropicAssistantMessage[\"content\"],\r\n): ResponseInputMessage[\"phase\"] | undefined => {\r\n if (!shouldApplyCodexPhase(model)) {\r\n return undefined\r\n }\r\n\r\n if (typeof content === \"string\") {\r\n return \"final_answer\"\r\n }\r\n\r\n if (!Array.isArray(content)) {\r\n return undefined\r\n }\r\n\r\n const hasText = content.some((block) => block.type === \"text\")\r\n if (!hasText) {\r\n return undefined\r\n }\r\n\r\n const hasToolUse = content.some((block) => block.type === \"tool_use\")\r\n return hasToolUse ? \"commentary\" : \"final_answer\"\r\n}\r\n\r\nconst shouldApplyCodexPhase = (model: string): boolean =>\r\n model === CODEX_PHASE_MODEL\r\n\r\nconst createTextContent = (text: string): ResponseInputText => ({\r\n type: \"input_text\",\r\n text,\r\n})\r\n\r\nconst createOutPutTextContent = (text: string): ResponseInputText => ({\r\n type: \"output_text\",\r\n text,\r\n})\r\n\r\nconst createImageContent = (\r\n block: AnthropicImageBlock,\r\n): ResponseInputImage => ({\r\n type: \"input_image\",\r\n image_url: `data:${block.source.media_type};base64,${block.source.data}`,\r\n detail: \"auto\",\r\n})\r\n\r\nconst createReasoningContent = (\r\n block: AnthropicThinkingBlock,\r\n): ResponseInputReasoning => {\r\n // align with vscode-copilot-chat extractThinkingData, should add id, otherwise it will cause miss cache occasionally —— the usage input cached tokens to be 0\r\n // https://github.com/microsoft/vscode-copilot-chat/blob/main/src/platform/endpoint/node/responsesApi.ts#L162\r\n // when use in codex cli, reasoning id is empty, so it will cause miss cache occasionally\r\n const array = (block.signature ?? \"\").split(\"@\")\r\n const signature = array[0]\r\n const id = array[1]\r\n const thinking = block.thinking === THINKING_TEXT ? \"\" : block.thinking\r\n return {\r\n id,\r\n type: \"reasoning\",\r\n summary: thinking ? [{ type: \"summary_text\", text: thinking }] : [],\r\n encrypted_content: signature,\r\n }\r\n}\r\n\r\nconst createFunctionToolCall = (\r\n block: AnthropicToolUseBlock,\r\n): ResponseFunctionToolCallItem => ({\r\n type: \"function_call\",\r\n call_id: block.id,\r\n name: block.name,\r\n arguments: JSON.stringify(block.input),\r\n status: \"completed\",\r\n})\r\n\r\nconst createFunctionCallOutput = (\r\n block: AnthropicToolResultBlock,\r\n): ResponseFunctionCallOutputItem => ({\r\n type: \"function_call_output\",\r\n call_id: block.tool_use_id,\r\n output: convertToolResultContent(block.content),\r\n status: block.is_error ? \"incomplete\" : \"completed\",\r\n})\r\n\r\nconst translateSystemPrompt = (\r\n system: string | Array<AnthropicTextBlock> | undefined,\r\n model: string,\r\n): string | null => {\r\n if (!system) {\r\n return null\r\n }\r\n\r\n const extraPrompt = getExtraPromptForModel(model)\r\n\r\n if (typeof system === \"string\") {\r\n return system + extraPrompt\r\n }\r\n\r\n const text = system\r\n .map((block, index) => {\r\n if (index === 0) {\r\n return block.text + extraPrompt\r\n }\r\n return block.text\r\n })\r\n .join(\" \")\r\n return text.length > 0 ? text : null\r\n}\r\n\r\nconst convertAnthropicTools = (\r\n tools: Array<AnthropicTool> | undefined,\r\n): Array<Tool> | null => {\r\n if (!tools || tools.length === 0) {\r\n return null\r\n }\r\n\r\n return tools.map((tool) => ({\r\n type: \"function\",\r\n name: tool.name,\r\n parameters: tool.input_schema,\r\n strict: false,\r\n ...(tool.description ? { description: tool.description } : {}),\r\n }))\r\n}\r\n\r\nconst convertAnthropicToolChoice = (\r\n choice: AnthropicMessagesPayload[\"tool_choice\"],\r\n): ToolChoiceOptions | ToolChoiceFunction => {\r\n if (!choice) {\r\n return \"auto\"\r\n }\r\n\r\n switch (choice.type) {\r\n case \"auto\": {\r\n return \"auto\"\r\n }\r\n case \"any\": {\r\n return \"required\"\r\n }\r\n case \"tool\": {\r\n return choice.name ? { type: \"function\", name: choice.name } : \"auto\"\r\n }\r\n case \"none\": {\r\n return \"none\"\r\n }\r\n default: {\r\n return \"auto\"\r\n }\r\n }\r\n}\r\n\r\nexport const translateResponsesResultToAnthropic = (\r\n response: ResponsesResult,\r\n): AnthropicResponse => {\r\n const contentBlocks = mapOutputToAnthropicContent(response.output)\r\n const usage = mapResponsesUsage(response)\r\n let anthropicContent = fallbackContentBlocks(response.output_text)\r\n if (contentBlocks.length > 0) {\r\n anthropicContent = contentBlocks\r\n }\r\n\r\n const stopReason = mapResponsesStopReason(response)\r\n\r\n return {\r\n id: response.id,\r\n type: \"message\",\r\n role: \"assistant\",\r\n content: anthropicContent,\r\n model: response.model,\r\n stop_reason: stopReason,\r\n stop_sequence: null,\r\n usage,\r\n }\r\n}\r\n\r\nconst mapOutputToAnthropicContent = (\r\n output: Array<ResponseOutputItem>,\r\n): Array<AnthropicAssistantContentBlock> => {\r\n const contentBlocks: Array<AnthropicAssistantContentBlock> = []\r\n\r\n for (const item of output) {\r\n switch (item.type) {\r\n case \"reasoning\": {\r\n const thinkingText = extractReasoningText(item)\r\n if (thinkingText.length > 0) {\r\n contentBlocks.push({\r\n type: \"thinking\",\r\n thinking: thinkingText,\r\n signature: (item.encrypted_content ?? \"\") + \"@\" + item.id,\r\n })\r\n }\r\n break\r\n }\r\n case \"function_call\": {\r\n const toolUseBlock = createToolUseContentBlock(item)\r\n if (toolUseBlock) {\r\n contentBlocks.push(toolUseBlock)\r\n }\r\n break\r\n }\r\n case \"message\": {\r\n const combinedText = combineMessageTextContent(item.content)\r\n if (combinedText.length > 0) {\r\n contentBlocks.push({ type: \"text\", text: combinedText })\r\n }\r\n break\r\n }\r\n default: {\r\n // Future compatibility for unrecognized output item types.\r\n const combinedText = combineMessageTextContent(\r\n (item as { content?: Array<ResponseOutputContentBlock> }).content,\r\n )\r\n if (combinedText.length > 0) {\r\n contentBlocks.push({ type: \"text\", text: combinedText })\r\n }\r\n }\r\n }\r\n }\r\n\r\n return contentBlocks\r\n}\r\n\r\nconst combineMessageTextContent = (\r\n content: Array<ResponseOutputContentBlock> | undefined,\r\n): string => {\r\n if (!Array.isArray(content)) {\r\n return \"\"\r\n }\r\n\r\n let aggregated = \"\"\r\n\r\n for (const block of content) {\r\n if (isResponseOutputText(block)) {\r\n aggregated += block.text\r\n continue\r\n }\r\n\r\n if (isResponseOutputRefusal(block)) {\r\n aggregated += block.refusal\r\n continue\r\n }\r\n\r\n if (typeof (block as { text?: unknown }).text === \"string\") {\r\n aggregated += (block as { text: string }).text\r\n continue\r\n }\r\n\r\n if (typeof (block as { reasoning?: unknown }).reasoning === \"string\") {\r\n aggregated += (block as { reasoning: string }).reasoning\r\n continue\r\n }\r\n }\r\n\r\n return aggregated\r\n}\r\n\r\nconst extractReasoningText = (item: ResponseOutputReasoning): string => {\r\n const segments: Array<string> = []\r\n\r\n const collectFromBlocks = (blocks?: Array<ResponseReasoningBlock>) => {\r\n if (!Array.isArray(blocks)) {\r\n return\r\n }\r\n\r\n for (const block of blocks) {\r\n if (typeof block.text === \"string\") {\r\n segments.push(block.text)\r\n continue\r\n }\r\n }\r\n }\r\n\r\n // Compatible with opencode, it will filter out blocks where the thinking text is empty, so we add a default thinking text here\r\n if (!item.summary || item.summary.length === 0) {\r\n return THINKING_TEXT\r\n }\r\n\r\n collectFromBlocks(item.summary)\r\n\r\n return segments.join(\"\").trim()\r\n}\r\n\r\nconst createToolUseContentBlock = (\r\n call: ResponseOutputFunctionCall,\r\n): AnthropicToolUseBlock | null => {\r\n const toolId = call.call_id\r\n if (!call.name || !toolId) {\r\n return null\r\n }\r\n\r\n const input = parseFunctionCallArguments(call.arguments)\r\n\r\n return {\r\n type: \"tool_use\",\r\n id: toolId,\r\n name: call.name,\r\n input,\r\n }\r\n}\r\n\r\nconst parseFunctionCallArguments = (\r\n rawArguments: string,\r\n): Record<string, unknown> => {\r\n if (typeof rawArguments !== \"string\" || rawArguments.trim().length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n const parsed: unknown = JSON.parse(rawArguments)\r\n\r\n if (Array.isArray(parsed)) {\r\n return { arguments: parsed }\r\n }\r\n\r\n if (parsed && typeof parsed === \"object\") {\r\n return parsed as Record<string, unknown>\r\n }\r\n } catch (error) {\r\n consola.warn(\"Failed to parse function call arguments\", {\r\n error,\r\n rawArguments,\r\n })\r\n }\r\n\r\n return { raw_arguments: rawArguments }\r\n}\r\n\r\nconst fallbackContentBlocks = (\r\n outputText: string,\r\n): Array<AnthropicAssistantContentBlock> => {\r\n if (!outputText) {\r\n return []\r\n }\r\n\r\n return [\r\n {\r\n type: \"text\",\r\n text: outputText,\r\n },\r\n ]\r\n}\r\n\r\nconst mapResponsesStopReason = (\r\n response: ResponsesResult,\r\n): AnthropicResponse[\"stop_reason\"] => {\r\n const { status, incomplete_details: incompleteDetails } = response\r\n\r\n if (status === \"completed\") {\r\n if (response.output.some((item) => item.type === \"function_call\")) {\r\n return \"tool_use\"\r\n }\r\n return \"end_turn\"\r\n }\r\n\r\n if (status === \"incomplete\") {\r\n if (incompleteDetails?.reason === \"max_output_tokens\") {\r\n return \"max_tokens\"\r\n }\r\n if (incompleteDetails?.reason === \"content_filter\") {\r\n return \"end_turn\"\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nconst mapResponsesUsage = (\r\n response: ResponsesResult,\r\n): AnthropicResponse[\"usage\"] => {\r\n const inputTokens = response.usage?.input_tokens ?? 0\r\n const outputTokens = response.usage?.output_tokens ?? 0\r\n const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens\r\n\r\n return {\r\n input_tokens: inputTokens - (inputCachedTokens ?? 0),\r\n output_tokens: outputTokens,\r\n ...(response.usage?.input_tokens_details?.cached_tokens !== undefined && {\r\n cache_read_input_tokens:\r\n response.usage.input_tokens_details.cached_tokens,\r\n }),\r\n }\r\n}\r\n\r\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\r\n typeof value === \"object\" && value !== null\r\n\r\nconst isResponseOutputText = (\r\n block: ResponseOutputContentBlock,\r\n): block is ResponseOutputText =>\r\n isRecord(block)\r\n && \"type\" in block\r\n && (block as { type?: unknown }).type === \"output_text\"\r\n\r\nconst isResponseOutputRefusal = (\r\n block: ResponseOutputContentBlock,\r\n): block is ResponseOutputRefusal =>\r\n isRecord(block)\r\n && \"type\" in block\r\n && (block as { type?: unknown }).type === \"refusal\"\r\n\r\nconst parseUserId = (\r\n userId: string | undefined,\r\n): { safetyIdentifier: string | null; promptCacheKey: string | null } => {\r\n if (!userId || typeof userId !== \"string\") {\r\n return { safetyIdentifier: null, promptCacheKey: null }\r\n }\r\n\r\n // Parse safety_identifier: content between \"user_\" and \"_account\"\r\n const userMatch = userId.match(/user_([^_]+)_account/)\r\n const safetyIdentifier = userMatch ? userMatch[1] : null\r\n\r\n // Parse prompt_cache_key: content after \"_session_\"\r\n const sessionMatch = userId.match(/_session_(.+)$/)\r\n const promptCacheKey = sessionMatch ? sessionMatch[1] : null\r\n\r\n return { safetyIdentifier, promptCacheKey }\r\n}\r\n\r\nconst convertToolResultContent = (\r\n content: string | Array<AnthropicTextBlock | AnthropicImageBlock>,\r\n): string | Array<ResponseInputContent> => {\r\n if (typeof content === \"string\") {\r\n return content\r\n }\r\n\r\n if (Array.isArray(content)) {\r\n const result: Array<ResponseInputContent> = []\r\n for (const block of content) {\r\n switch (block.type) {\r\n case \"text\": {\r\n result.push(createTextContent(block.text))\r\n break\r\n }\r\n case \"image\": {\r\n result.push(createImageContent(block))\r\n break\r\n }\r\n default: {\r\n break\r\n }\r\n }\r\n }\r\n return result\r\n }\r\n\r\n return \"\"\r\n}\r\n","import {\r\n type ResponseCompletedEvent,\r\n type ResponseCreatedEvent,\r\n type ResponseErrorEvent,\r\n type ResponseFailedEvent,\r\n type ResponseFunctionCallArgumentsDeltaEvent,\r\n type ResponseFunctionCallArgumentsDoneEvent,\r\n type ResponseIncompleteEvent,\r\n type ResponseOutputItemAddedEvent,\r\n type ResponseOutputItemDoneEvent,\r\n type ResponseReasoningSummaryTextDeltaEvent,\r\n type ResponseReasoningSummaryTextDoneEvent,\r\n type ResponsesResult,\r\n type ResponseStreamEvent,\r\n type ResponseTextDeltaEvent,\r\n type ResponseTextDoneEvent,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nimport { type AnthropicStreamEventData } from \"./anthropic-types\"\r\nimport {\r\n THINKING_TEXT,\r\n translateResponsesResultToAnthropic,\r\n} from \"./responses-translation\"\r\n\r\nconst MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20\r\n\r\nclass FunctionCallArgumentsValidationError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = \"FunctionCallArgumentsValidationError\"\r\n }\r\n}\r\n\r\nconst updateWhitespaceRunState = (\r\n previousCount: number,\r\n chunk: string,\r\n): {\r\n nextCount: number\r\n exceeded: boolean\r\n} => {\r\n let count = previousCount\r\n\r\n for (const char of chunk) {\r\n if (char === \"\\r\" || char === \"\\n\" || char === \"\\t\") {\r\n count += 1\r\n if (count > MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE) {\r\n return { nextCount: count, exceeded: true }\r\n }\r\n continue\r\n }\r\n\r\n if (char !== \" \") {\r\n count = 0\r\n }\r\n }\r\n\r\n return { nextCount: count, exceeded: false }\r\n}\r\n\r\nexport interface ResponsesStreamState {\r\n messageStartSent: boolean\r\n messageCompleted: boolean\r\n nextContentBlockIndex: number\r\n blockIndexByKey: Map<string, number>\r\n openBlocks: Set<number>\r\n blockHasDelta: Set<number>\r\n functionCallStateByOutputIndex: Map<number, FunctionCallStreamState>\r\n}\r\n\r\ntype FunctionCallStreamState = {\r\n blockIndex: number\r\n toolCallId: string\r\n name: string\r\n consecutiveWhitespaceCount: number\r\n}\r\n\r\nexport const createResponsesStreamState = (): ResponsesStreamState => ({\r\n messageStartSent: false,\r\n messageCompleted: false,\r\n nextContentBlockIndex: 0,\r\n blockIndexByKey: new Map(),\r\n openBlocks: new Set(),\r\n blockHasDelta: new Set(),\r\n functionCallStateByOutputIndex: new Map(),\r\n})\r\n\r\nexport const translateResponsesStreamEvent = (\r\n rawEvent: ResponseStreamEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const eventType = rawEvent.type\r\n switch (eventType) {\r\n case \"response.created\": {\r\n return handleResponseCreated(rawEvent, state)\r\n }\r\n\r\n case \"response.output_item.added\": {\r\n return handleOutputItemAdded(rawEvent, state)\r\n }\r\n\r\n case \"response.reasoning_summary_text.delta\": {\r\n return handleReasoningSummaryTextDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.output_text.delta\": {\r\n return handleOutputTextDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.reasoning_summary_text.done\": {\r\n return handleReasoningSummaryTextDone(rawEvent, state)\r\n }\r\n\r\n case \"response.output_text.done\": {\r\n return handleOutputTextDone(rawEvent, state)\r\n }\r\n case \"response.output_item.done\": {\r\n return handleOutputItemDone(rawEvent, state)\r\n }\r\n\r\n case \"response.function_call_arguments.delta\": {\r\n return handleFunctionCallArgumentsDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.function_call_arguments.done\": {\r\n return handleFunctionCallArgumentsDone(rawEvent, state)\r\n }\r\n\r\n case \"response.completed\":\r\n case \"response.incomplete\": {\r\n return handleResponseCompleted(rawEvent, state)\r\n }\r\n\r\n case \"response.failed\": {\r\n return handleResponseFailed(rawEvent, state)\r\n }\r\n\r\n case \"error\": {\r\n return handleErrorEvent(rawEvent, state)\r\n }\r\n\r\n default: {\r\n return []\r\n }\r\n }\r\n}\r\n\r\n// Helper handlers to keep translateResponsesStreamEvent concise\r\nconst handleResponseCreated = (\r\n rawEvent: ResponseCreatedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n return messageStart(state, rawEvent.response)\r\n}\r\n\r\nconst handleOutputItemAdded = (\r\n rawEvent: ResponseOutputItemAddedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const functionCallDetails = extractFunctionCallDetails(rawEvent)\r\n if (!functionCallDetails) {\r\n return events\r\n }\r\n\r\n const { outputIndex, toolCallId, name, initialArguments } =\r\n functionCallDetails\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n toolCallId,\r\n name,\r\n events,\r\n })\r\n\r\n if (initialArguments !== undefined && initialArguments.length > 0) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: initialArguments,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleOutputItemDone = (\r\n rawEvent: ResponseOutputItemDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const item = rawEvent.item\r\n const itemType = item.type\r\n if (itemType !== \"reasoning\") {\r\n return events\r\n }\r\n\r\n const outputIndex = rawEvent.output_index\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n const signature = (item.encrypted_content ?? \"\") + \"@\" + item.id\r\n if (signature) {\r\n // Compatible with opencode, it will filter out blocks where the thinking text is empty, so we add a default thinking text here\r\n if (!item.summary || item.summary.length === 0) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: THINKING_TEXT,\r\n },\r\n })\r\n }\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"signature_delta\",\r\n signature,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleFunctionCallArgumentsDelta = (\r\n rawEvent: ResponseFunctionCallArgumentsDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const deltaText = rawEvent.delta\r\n\r\n if (!deltaText) {\r\n return events\r\n }\r\n\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n events,\r\n })\r\n\r\n const functionCallState =\r\n state.functionCallStateByOutputIndex.get(outputIndex)\r\n if (!functionCallState) {\r\n return handleFunctionCallArgumentsValidationError(\r\n new FunctionCallArgumentsValidationError(\r\n \"Received function call arguments delta without an open tool call block.\",\r\n ),\r\n state,\r\n events,\r\n )\r\n }\r\n\r\n // fix: copolit function call returning infinite line breaks until max_tokens limit\r\n // \"arguments\": \"{\\\"path\\\":\\\"xxx\\\",\\\"pattern\\\":\\\"**/*.ts\\\",\\\"} }? Wait extra braces. Need correct. I should run? Wait overcame. Need proper JSON with pattern \\\"\\n\\n\\n\\n\\n\\n\\n\\n...\r\n const { nextCount, exceeded } = updateWhitespaceRunState(\r\n functionCallState.consecutiveWhitespaceCount,\r\n deltaText,\r\n )\r\n if (exceeded) {\r\n return handleFunctionCallArgumentsValidationError(\r\n new FunctionCallArgumentsValidationError(\r\n \"Received function call arguments delta containing more than 20 consecutive whitespace characters.\",\r\n ),\r\n state,\r\n events,\r\n )\r\n }\r\n functionCallState.consecutiveWhitespaceCount = nextCount\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleFunctionCallArgumentsDone = (\r\n rawEvent: ResponseFunctionCallArgumentsDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n events,\r\n })\r\n\r\n const finalArguments =\r\n typeof rawEvent.arguments === \"string\" ? rawEvent.arguments : undefined\r\n\r\n if (!state.blockHasDelta.has(blockIndex) && finalArguments) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: finalArguments,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n state.functionCallStateByOutputIndex.delete(outputIndex)\r\n return events\r\n}\r\n\r\nconst handleOutputTextDelta = (\r\n rawEvent: ResponseTextDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const contentIndex = rawEvent.content_index\r\n const deltaText = rawEvent.delta\r\n\r\n if (!deltaText) {\r\n return events\r\n }\r\n\r\n const blockIndex = openTextBlockIfNeeded(state, {\r\n outputIndex,\r\n contentIndex,\r\n events,\r\n })\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"text_delta\",\r\n text: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleReasoningSummaryTextDelta = (\r\n rawEvent: ResponseReasoningSummaryTextDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const outputIndex = rawEvent.output_index\r\n const deltaText = rawEvent.delta\r\n const events = new Array<AnthropicStreamEventData>()\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleReasoningSummaryTextDone = (\r\n rawEvent: ResponseReasoningSummaryTextDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const outputIndex = rawEvent.output_index\r\n const text = rawEvent.text\r\n const events = new Array<AnthropicStreamEventData>()\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n\r\n if (text && !state.blockHasDelta.has(blockIndex)) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: text,\r\n },\r\n })\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleOutputTextDone = (\r\n rawEvent: ResponseTextDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const contentIndex = rawEvent.content_index\r\n const text = rawEvent.text\r\n\r\n const blockIndex = openTextBlockIfNeeded(state, {\r\n outputIndex,\r\n contentIndex,\r\n events,\r\n })\r\n\r\n if (text && !state.blockHasDelta.has(blockIndex)) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"text_delta\",\r\n text,\r\n },\r\n })\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleResponseCompleted = (\r\n rawEvent: ResponseCompletedEvent | ResponseIncompleteEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const response = rawEvent.response\r\n const events = new Array<AnthropicStreamEventData>()\r\n\r\n closeAllOpenBlocks(state, events)\r\n const anthropic = translateResponsesResultToAnthropic(response)\r\n events.push(\r\n {\r\n type: \"message_delta\",\r\n delta: {\r\n stop_reason: anthropic.stop_reason,\r\n stop_sequence: anthropic.stop_sequence,\r\n },\r\n usage: anthropic.usage,\r\n },\r\n { type: \"message_stop\" },\r\n )\r\n state.messageCompleted = true\r\n return events\r\n}\r\n\r\nconst handleResponseFailed = (\r\n rawEvent: ResponseFailedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const response = rawEvent.response\r\n const events = new Array<AnthropicStreamEventData>()\r\n closeAllOpenBlocks(state, events)\r\n\r\n const message =\r\n response.error?.message ?? \"The response failed due to an unknown error.\"\r\n\r\n events.push(buildErrorEvent(message))\r\n state.messageCompleted = true\r\n\r\n return events\r\n}\r\n\r\nconst handleErrorEvent = (\r\n rawEvent: ResponseErrorEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const message =\r\n typeof rawEvent.message === \"string\" ?\r\n rawEvent.message\r\n : \"An unexpected error occurred during streaming.\"\r\n\r\n state.messageCompleted = true\r\n return [buildErrorEvent(message)]\r\n}\r\n\r\nconst handleFunctionCallArgumentsValidationError = (\r\n error: FunctionCallArgumentsValidationError,\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData> = [],\r\n): Array<AnthropicStreamEventData> => {\r\n const reason = error.message\r\n\r\n closeAllOpenBlocks(state, events)\r\n state.messageCompleted = true\r\n\r\n events.push(buildErrorEvent(reason))\r\n\r\n return events\r\n}\r\n\r\nconst messageStart = (\r\n state: ResponsesStreamState,\r\n response: ResponsesResult,\r\n): Array<AnthropicStreamEventData> => {\r\n state.messageStartSent = true\r\n const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens\r\n const inputTokens =\r\n (response.usage?.input_tokens ?? 0) - (inputCachedTokens ?? 0)\r\n return [\r\n {\r\n type: \"message_start\",\r\n message: {\r\n id: response.id,\r\n type: \"message\",\r\n role: \"assistant\",\r\n content: [],\r\n model: response.model,\r\n stop_reason: null,\r\n stop_sequence: null,\r\n usage: {\r\n input_tokens: inputTokens,\r\n output_tokens: 0,\r\n cache_read_input_tokens: inputCachedTokens ?? 0,\r\n },\r\n },\r\n },\r\n ]\r\n}\r\n\r\nconst openTextBlockIfNeeded = (\r\n state: ResponsesStreamState,\r\n params: {\r\n outputIndex: number\r\n contentIndex: number\r\n events: Array<AnthropicStreamEventData>\r\n },\r\n): number => {\r\n const { outputIndex, contentIndex, events } = params\r\n const key = getBlockKey(outputIndex, contentIndex)\r\n let blockIndex = state.blockIndexByKey.get(key)\r\n\r\n if (blockIndex === undefined) {\r\n blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n state.blockIndexByKey.set(key, blockIndex)\r\n }\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"text\",\r\n text: \"\",\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\nconst openThinkingBlockIfNeeded = (\r\n state: ResponsesStreamState,\r\n outputIndex: number,\r\n events: Array<AnthropicStreamEventData>,\r\n): number => {\r\n //thinking blocks has multiple summary_index, should combine into one block\r\n const summaryIndex = 0\r\n const key = getBlockKey(outputIndex, summaryIndex)\r\n let blockIndex = state.blockIndexByKey.get(key)\r\n\r\n if (blockIndex === undefined) {\r\n blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n state.blockIndexByKey.set(key, blockIndex)\r\n }\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"thinking\",\r\n thinking: \"\",\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\nconst closeBlockIfOpen = (\r\n state: ResponsesStreamState,\r\n blockIndex: number,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n if (!state.openBlocks.has(blockIndex)) {\r\n return\r\n }\r\n\r\n events.push({ type: \"content_block_stop\", index: blockIndex })\r\n state.openBlocks.delete(blockIndex)\r\n state.blockHasDelta.delete(blockIndex)\r\n}\r\n\r\nconst closeOpenBlocks = (\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n for (const blockIndex of state.openBlocks) {\r\n closeBlockIfOpen(state, blockIndex, events)\r\n }\r\n}\r\n\r\nconst closeAllOpenBlocks = (\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n closeOpenBlocks(state, events)\r\n\r\n state.functionCallStateByOutputIndex.clear()\r\n}\r\n\r\nexport const buildErrorEvent = (message: string): AnthropicStreamEventData => ({\r\n type: \"error\",\r\n error: {\r\n type: \"api_error\",\r\n message,\r\n },\r\n})\r\n\r\nconst getBlockKey = (outputIndex: number, contentIndex: number): string =>\r\n `${outputIndex}:${contentIndex}`\r\n\r\nconst openFunctionCallBlock = (\r\n state: ResponsesStreamState,\r\n params: {\r\n outputIndex: number\r\n toolCallId?: string\r\n name?: string\r\n events: Array<AnthropicStreamEventData>\r\n },\r\n): number => {\r\n const { outputIndex, toolCallId, name, events } = params\r\n\r\n let functionCallState = state.functionCallStateByOutputIndex.get(outputIndex)\r\n\r\n if (!functionCallState) {\r\n const blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n\r\n const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex}`\r\n const resolvedName = name ?? \"function\"\r\n\r\n functionCallState = {\r\n blockIndex,\r\n toolCallId: resolvedToolCallId,\r\n name: resolvedName,\r\n consecutiveWhitespaceCount: 0,\r\n }\r\n\r\n state.functionCallStateByOutputIndex.set(outputIndex, functionCallState)\r\n }\r\n\r\n const { blockIndex } = functionCallState\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"tool_use\",\r\n id: functionCallState.toolCallId,\r\n name: functionCallState.name,\r\n input: {},\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\ntype FunctionCallDetails = {\r\n outputIndex: number\r\n toolCallId: string\r\n name: string\r\n initialArguments?: string\r\n}\r\n\r\nconst extractFunctionCallDetails = (\r\n rawEvent: ResponseOutputItemAddedEvent,\r\n): FunctionCallDetails | undefined => {\r\n const item = rawEvent.item\r\n const itemType = item.type\r\n if (itemType !== \"function_call\") {\r\n return undefined\r\n }\r\n\r\n const outputIndex = rawEvent.output_index\r\n const toolCallId = item.call_id\r\n const name = item.name\r\n const initialArguments = item.arguments\r\n return {\r\n outputIndex,\r\n toolCallId,\r\n name,\r\n initialArguments,\r\n }\r\n}\r\n","import type {\r\n ResponseInputItem,\r\n ResponsesPayload,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nexport const getResponsesRequestOptions = (\r\n payload: ResponsesPayload,\r\n): { vision: boolean; initiator: \"agent\" | \"user\" } => {\r\n const vision = hasVisionInput(payload)\r\n const initiator = hasAgentInitiator(payload) ? \"agent\" : \"user\"\r\n\r\n return { vision, initiator }\r\n}\r\n\r\nexport const hasAgentInitiator = (payload: ResponsesPayload): boolean => {\r\n // Refactor `isAgentCall` logic to check only the last message in the history rather than any message. This prevents valid user messages from being incorrectly flagged as agent calls due to previous assistant history, ensuring proper credit consumption for multi-turn conversations.\r\n const lastItem = getPayloadItems(payload).at(-1)\r\n if (!lastItem) {\r\n return false\r\n }\r\n if (!(\"role\" in lastItem) || !lastItem.role) {\r\n return true\r\n }\r\n const role =\r\n typeof lastItem.role === \"string\" ? lastItem.role.toLowerCase() : \"\"\r\n return role === \"assistant\"\r\n}\r\n\r\nexport const hasVisionInput = (payload: ResponsesPayload): boolean => {\r\n const values = getPayloadItems(payload)\r\n return values.some((item) => containsVisionContent(item))\r\n}\r\n\r\nconst getPayloadItems = (\r\n payload: ResponsesPayload,\r\n): Array<ResponseInputItem> => {\r\n const result: Array<ResponseInputItem> = []\r\n\r\n const { input } = payload\r\n\r\n if (Array.isArray(input)) {\r\n result.push(...input)\r\n }\r\n\r\n return result\r\n}\r\n\r\nconst containsVisionContent = (value: unknown): boolean => {\r\n if (!value) return false\r\n\r\n if (Array.isArray(value)) {\r\n return value.some((entry) => containsVisionContent(entry))\r\n }\r\n\r\n if (typeof value !== \"object\") {\r\n return false\r\n }\r\n\r\n const record = value as Record<string, unknown>\r\n const type =\r\n typeof record.type === \"string\" ? record.type.toLowerCase() : undefined\r\n\r\n if (type === \"input_image\") {\r\n return true\r\n }\r\n\r\n if (Array.isArray(record.content)) {\r\n return record.content.some((entry) => containsVisionContent(entry))\r\n }\r\n\r\n return false\r\n}\r\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport type {\r\n AnthropicMessagesPayload,\r\n AnthropicResponse,\r\n} from \"~/routes/messages/anthropic-types\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport type MessagesStream = ReturnType<typeof events>\r\nexport type CreateMessagesReturn = AnthropicResponse | MessagesStream\r\n\r\nexport const createMessages = async (\r\n payload: AnthropicMessagesPayload,\r\n anthropicBetaHeader?: string,\r\n options?: {\r\n initiator?: \"agent\" | \"user\"\r\n },\r\n): Promise<CreateMessagesReturn> => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const enableVision = payload.messages.some(\r\n (message) =>\r\n Array.isArray(message.content)\r\n && message.content.some((block) => block.type === \"image\"),\r\n )\r\n\r\n let isInitiateRequest = false\r\n const lastMessage = payload.messages.at(-1)\r\n if (lastMessage?.role === \"user\") {\r\n isInitiateRequest =\r\n Array.isArray(lastMessage.content) ?\r\n lastMessage.content.some((block) => block.type !== \"tool_result\")\r\n : true\r\n }\r\n const initiator = options?.initiator ?? (isInitiateRequest ? \"user\" : \"agent\")\r\n\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, enableVision),\r\n \"X-Initiator\": initiator,\r\n }\r\n\r\n if (anthropicBetaHeader) {\r\n // align with vscode copilot extension anthropic-beta\r\n const filteredBeta = anthropicBetaHeader\r\n .split(\",\")\r\n .map((item) => item.trim())\r\n .filter((item) => item !== \"claude-code-20250219\")\r\n .join(\",\")\r\n if (filteredBeta) {\r\n headers[\"anthropic-beta\"] = filteredBeta\r\n }\r\n } else if (payload.thinking?.budget_tokens) {\r\n headers[\"anthropic-beta\"] = \"interleaved-thinking-2025-05-14\"\r\n }\r\n\r\n const response = await fetch(`${copilotBaseUrl(state)}/v1/messages`, {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n })\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create messages\", response)\r\n throw new HTTPError(\"Failed to create messages\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as AnthropicResponse\r\n}\r\n","import {\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicStreamEventData,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\nfunction isToolBlockOpen(state: AnthropicStreamState): boolean {\n if (!state.contentBlockOpen) {\n return false\n }\n // Check if the current block index corresponds to any known tool call\n return Object.values(state.toolCalls).some(\n (tc) => tc.anthropicBlockIndex === state.contentBlockIndex,\n )\n}\n\n// Helper to create message_delta and message_stop events\nfunction createMessageDeltaEvents(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\",\n usage: {\n prompt_tokens: number\n completion_tokens: number\n cached_tokens: number\n },\n): Array<AnthropicStreamEventData> {\n const stopReason = mapOpenAIStopReasonToAnthropic(finishReason)\n // Anthropic input_tokens = uncached tokens only\n // OpenAI prompt_tokens includes cached, so subtract them\n const inputTokens = usage.prompt_tokens - usage.cached_tokens\n return [\n {\n type: \"message_delta\",\n delta: {\n stop_reason: stopReason,\n stop_sequence: null,\n },\n usage: {\n input_tokens: inputTokens,\n output_tokens: usage.completion_tokens,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cached_tokens,\n },\n },\n {\n type: \"message_stop\",\n },\n ]\n}\n\n// Export for use in handler fallback\nexport function createFallbackMessageDeltaEvents(\n state: AnthropicStreamState,\n): Array<AnthropicStreamEventData> {\n // If message_delta was already sent, return empty\n if (state.messageDeltaSent) {\n return []\n }\n\n // If we have a pending finish_reason, send message_delta with whatever usage we have\n if (state.pendingFinishReason) {\n const usage = state.pendingUsage ?? {\n prompt_tokens: 0,\n completion_tokens: 0,\n cached_tokens: 0,\n }\n return createMessageDeltaEvents(state.pendingFinishReason, usage)\n }\n\n return []\n}\n\n// eslint-disable-next-line max-lines-per-function, complexity\nexport function translateChunkToAnthropicEvents(\n chunk: ChatCompletionChunk,\n state: AnthropicStreamState,\n originalModel?: string,\n): Array<AnthropicStreamEventData> {\n const events: Array<AnthropicStreamEventData> = []\n\n // Capture usage from any chunk that has it (may come before, with, or after finish_reason)\n if (chunk.usage) {\n state.pendingUsage = {\n prompt_tokens: chunk.usage.prompt_tokens,\n completion_tokens: chunk.usage.completion_tokens,\n cached_tokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n\n // If we already saw finish_reason but deferred message_delta, send it now\n if (state.pendingFinishReason && !state.messageDeltaSent) {\n events.push(\n ...createMessageDeltaEvents(\n state.pendingFinishReason,\n state.pendingUsage,\n ),\n )\n state.messageDeltaSent = true\n }\n }\n\n if (chunk.choices.length === 0) {\n // Empty choices chunk - usage already captured above\n return events\n }\n\n const choice = chunk.choices[0]\n const { delta } = choice\n\n if (!state.messageStartSent) {\n // Include usage in message_start for context window display\n // Use pending usage if available (captured from earlier chunks)\n const usage = state.pendingUsage ?? {\n prompt_tokens: 0,\n completion_tokens: 0,\n cached_tokens: 0,\n }\n // Anthropic input_tokens = uncached tokens only\n const inputTokens = usage.prompt_tokens - usage.cached_tokens\n events.push({\n type: \"message_start\",\n message: {\n id: chunk.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n // Use original requested model for cost calculation in Claude Code\n model: originalModel ?? chunk.model,\n stop_reason: null,\n stop_sequence: null,\n // Include usage for context window display\n // Note: output_tokens should be 0 at message_start (final count comes in message_delta)\n usage: {\n input_tokens: inputTokens,\n output_tokens: 0,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cached_tokens,\n },\n },\n })\n state.messageStartSent = true\n }\n\n if (delta.content) {\n if (isToolBlockOpen(state)) {\n // A tool block was open, so close it before starting a text block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n if (!state.contentBlockOpen) {\n events.push({\n type: \"content_block_start\",\n index: state.contentBlockIndex,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n })\n state.contentBlockOpen = true\n }\n\n events.push({\n type: \"content_block_delta\",\n index: state.contentBlockIndex,\n delta: {\n type: \"text_delta\",\n text: delta.content,\n },\n })\n }\n\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n if (toolCall.id && toolCall.function?.name) {\n // New tool call starting.\n if (state.contentBlockOpen) {\n // Close any previously open block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = state.contentBlockIndex\n state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: \"content_block_start\",\n index: anthropicBlockIndex,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = state.toolCalls[toolCall.index]\n // Tool call can still be empty\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (toolCallInfo) {\n events.push({\n type: \"content_block_delta\",\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n }\n\n if (choice.finish_reason) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockOpen = false\n }\n\n // Check if we have usage data (from this chunk or previously captured)\n const hasUsage = chunk.usage || state.pendingUsage\n\n if (hasUsage) {\n // We have usage - send message_delta immediately\n const usage = {\n prompt_tokens:\n chunk.usage?.prompt_tokens ?? state.pendingUsage?.prompt_tokens ?? 0,\n completion_tokens:\n chunk.usage?.completion_tokens\n ?? state.pendingUsage?.completion_tokens\n ?? 0,\n cached_tokens:\n chunk.usage?.prompt_tokens_details?.cached_tokens\n ?? state.pendingUsage?.cached_tokens\n ?? 0,\n }\n\n events.push(...createMessageDeltaEvents(choice.finish_reason, usage))\n state.messageDeltaSent = true\n } else {\n // No usage yet - defer message_delta until we receive usage in a later chunk\n state.pendingFinishReason = choice.finish_reason\n }\n }\n\n return events\n}\n\n/**\n * Convert a complete OpenAI ChatCompletionResponse to Anthropic streaming events.\n * This is used when we fetch non-streaming from upstream but need to simulate\n * streaming to the client with accurate token counts.\n */\nexport function translateResponseToAnthropicEvents(\n response: ChatCompletionResponse,\n originalModel?: string,\n): Array<AnthropicStreamEventData> {\n const choice = response.choices[0]\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive check for empty choices array\n if (!choice) {\n return []\n }\n\n const promptTokens = response.usage?.prompt_tokens ?? 0\n const outputTokens = response.usage?.completion_tokens ?? 0\n const cachedTokens = response.usage?.prompt_tokens_details?.cached_tokens ?? 0\n // Anthropic input_tokens = uncached tokens only\n const inputTokens = promptTokens - cachedTokens\n\n const events: Array<AnthropicStreamEventData> = [\n createMessageStartEvent(response, {\n originalModel,\n inputTokens,\n cachedTokens,\n }),\n ]\n\n let contentBlockIndex = 0\n contentBlockIndex = addTextContentEvents(events, choice, contentBlockIndex)\n addToolCallEvents(events, choice, contentBlockIndex)\n addMessageDeltaAndStopEvents(events, choice, {\n inputTokens,\n outputTokens,\n cachedTokens,\n })\n\n return events\n}\n\ninterface MessageStartEventOptions {\n originalModel: string | undefined\n inputTokens: number\n cachedTokens: number\n}\n\nfunction createMessageStartEvent(\n response: ChatCompletionResponse,\n options: MessageStartEventOptions,\n): AnthropicStreamEventData {\n const { originalModel, inputTokens, cachedTokens } = options\n return {\n type: \"message_start\",\n message: {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: originalModel ?? response.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: inputTokens,\n output_tokens: 0,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: cachedTokens,\n },\n },\n }\n}\n\nfunction addTextContentEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n contentBlockIndex: number,\n): number {\n if (choice.message.content) {\n events.push(\n {\n type: \"content_block_start\",\n index: contentBlockIndex,\n content_block: { type: \"text\", text: \"\" },\n },\n {\n type: \"content_block_delta\",\n index: contentBlockIndex,\n delta: { type: \"text_delta\", text: choice.message.content },\n },\n { type: \"content_block_stop\", index: contentBlockIndex },\n )\n return contentBlockIndex + 1\n }\n return contentBlockIndex\n}\n\nfunction addToolCallEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n startIndex: number,\n): void {\n if (!choice.message.tool_calls) return\n\n let idx = startIndex\n for (const toolCall of choice.message.tool_calls) {\n events.push(\n {\n type: \"content_block_start\",\n index: idx,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n },\n {\n type: \"content_block_delta\",\n index: idx,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n },\n { type: \"content_block_stop\", index: idx },\n )\n idx++\n }\n}\n\ninterface UsageTokens {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n}\n\nfunction addMessageDeltaAndStopEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n usage: UsageTokens,\n): void {\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: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cachedTokens,\n },\n },\n { type: \"message_stop\" },\n )\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 { AnthropicMessagesPayload } from \"./anthropic-types\"\r\n\r\nconst subagentMarkerPrefix = \"__SUBAGENT_MARKER__\"\r\n\r\nexport interface SubagentMarker {\r\n session_id: string\r\n agent_id: string\r\n agent_type: string\r\n}\r\n\r\nexport const parseSubagentMarkerFromFirstUser = (\r\n payload: AnthropicMessagesPayload,\r\n): SubagentMarker | null => {\r\n const firstUserMessage = payload.messages.find((msg) => msg.role === \"user\")\r\n if (!firstUserMessage || !Array.isArray(firstUserMessage.content)) {\r\n return null\r\n }\r\n\r\n for (const block of firstUserMessage.content) {\r\n if (block.type !== \"text\") {\r\n continue\r\n }\r\n\r\n const marker = parseSubagentMarkerFromSystemReminder(block.text)\r\n if (marker) {\r\n return marker\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nconst parseSubagentMarkerFromSystemReminder = (\r\n text: string,\r\n): SubagentMarker | null => {\r\n const startTag = \"<system-reminder>\"\r\n const endTag = \"</system-reminder>\"\r\n let searchFrom = 0\r\n\r\n while (true) {\r\n const reminderStart = text.indexOf(startTag, searchFrom)\r\n if (reminderStart === -1) {\r\n break\r\n }\r\n\r\n const contentStart = reminderStart + startTag.length\r\n const reminderEnd = text.indexOf(endTag, contentStart)\r\n if (reminderEnd === -1) {\r\n break\r\n }\r\n\r\n const reminderContent = text.slice(contentStart, reminderEnd)\r\n const markerIndex = reminderContent.indexOf(subagentMarkerPrefix)\r\n if (markerIndex === -1) {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n\r\n const markerJson = reminderContent\r\n .slice(markerIndex + subagentMarkerPrefix.length)\r\n .trim()\r\n\r\n try {\r\n const parsed = JSON.parse(markerJson) as SubagentMarker\r\n if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n\r\n return parsed\r\n } catch {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n }\r\n\r\n return null\r\n}\r\n","import type { Context } from \"hono\"\r\n\r\nimport { streamSSE } from \"hono/streaming\"\r\n\r\nimport type { Model } from \"~/services/copilot/get-models\"\r\n\r\nimport { awaitApproval } from \"~/lib/approval\"\r\nimport { applyReplacementsToPayload } from \"~/lib/auto-replace\"\r\nimport {\r\n getSmallModel,\r\n shouldCompactUseSmallModel,\r\n getReasoningEffortForModel,\r\n} from \"~/lib/config\"\r\nimport { createHandlerLogger } from \"~/lib/logger\"\r\nimport { normalizeModelName } from \"~/lib/model-resolver\"\r\nimport { checkRateLimit } from \"~/lib/rate-limit\"\r\nimport { state } from \"~/lib/state\"\r\nimport {\n buildErrorEvent,\r\n createResponsesStreamState,\r\n translateResponsesStreamEvent,\r\n} from \"~/routes/messages/responses-stream-translation\"\r\nimport {\r\n translateAnthropicMessagesToResponsesPayload,\r\n translateResponsesResultToAnthropic,\r\n} from \"~/routes/messages/responses-translation\"\r\nimport { getResponsesRequestOptions } from \"~/routes/responses/utils\"\r\nimport {\r\n createChatCompletions,\r\n type ChatCompletionChunk,\r\n type ChatCompletionResponse,\r\n} from \"~/services/copilot/create-chat-completions\"\r\nimport { createMessages } from \"~/services/copilot/create-messages\"\r\nimport {\r\n createResponses,\r\n type ResponsesResult,\r\n type ResponseStreamEvent,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nimport {\r\n type AnthropicMessagesPayload,\r\n type AnthropicStreamState,\r\n type AnthropicTextBlock,\r\n type AnthropicToolResultBlock,\r\n} from \"./anthropic-types\"\r\nimport {\r\n translateToAnthropic,\r\n translateToOpenAI,\r\n} from \"./non-stream-translation\"\r\nimport { translateChunkToAnthropicEvents } from \"./stream-translation\"\r\nimport { parseSubagentMarkerFromFirstUser } from \"./subagent-marker\"\r\n\r\nconst logger = createHandlerLogger(\"messages-handler\")\r\n\r\nconst compactSystemPromptStart =\r\n \"You are a helpful AI assistant tasked with summarizing conversations\"\r\n\r\nexport async function handleCompletion(c: Context) {\r\n await checkRateLimit(state)\r\n\r\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\r\n logger.debug(\"Anthropic request payload:\", JSON.stringify(anthropicPayload))\r\n\r\n const subagentMarker = parseSubagentMarkerFromFirstUser(anthropicPayload)\r\n const initiatorOverride = subagentMarker ? \"agent\" : undefined\r\n if (subagentMarker) {\r\n logger.debug(\"Detected Subagent marker:\", JSON.stringify(subagentMarker))\r\n }\r\n\r\n // claude code and opencode compact request detection\r\n const isCompact = isCompactRequest(anthropicPayload)\r\n\r\n // fix claude code 2.0.28+ warmup request consume premium request, forcing small model if no tools are used\r\n // set \"CLAUDE_CODE_SUBAGENT_MODEL\": \"you small model\" also can avoid this\r\n const anthropicBeta = c.req.header(\"anthropic-beta\")\r\n logger.debug(\"Anthropic Beta header:\", anthropicBeta)\r\n const noTools = !anthropicPayload.tools || anthropicPayload.tools.length === 0\r\n if (anthropicBeta && noTools && !isCompact) {\r\n anthropicPayload.model = getSmallModel()\r\n }\r\n\r\n if (isCompact) {\r\n logger.debug(\"Is compact request:\", isCompact)\r\n if (shouldCompactUseSmallModel()) {\r\n anthropicPayload.model = getSmallModel()\r\n }\r\n } else {\r\n // Merge tool_result and text blocks into tool_result to avoid consuming premium requests\r\n // (caused by skill invocations, edit hooks, plan or to do reminders)\r\n // e.g. {\"role\":\"user\",\"content\":[{\"type\":\"tool_result\",\"content\":\"Launching skill: xxx\"},{\"type\":\"text\",\"text\":\"xxx\"}]}\r\n // not only for claude, but also for opencode\r\n // compact requests are excluded from this processing\r\n mergeToolResultForClaude(anthropicPayload)\r\n }\r\n\r\n if (state.manualApprove) {\r\n await awaitApproval()\r\n }\r\n\r\n const selectedModel = state.models?.data.find(\r\n (m) => m.id === anthropicPayload.model,\r\n )\r\n\r\n if (shouldUseMessagesApi(selectedModel)) {\r\n return await handleWithMessagesApi(c, anthropicPayload, {\r\n anthropicBetaHeader: anthropicBeta,\r\n initiatorOverride,\r\n selectedModel,\r\n })\r\n }\r\n\r\n if (shouldUseResponsesApi(selectedModel)) {\r\n return await handleWithResponsesApi(c, anthropicPayload, initiatorOverride)\r\n }\r\n\r\n return await handleWithChatCompletions(c, anthropicPayload, initiatorOverride)\r\n}\r\n\r\nconst RESPONSES_ENDPOINT = \"/responses\"\r\nconst MESSAGES_ENDPOINT = \"/v1/messages\"\r\n\r\nconst handleWithChatCompletions = async (\r\n c: Context,\r\n anthropicPayload: AnthropicMessagesPayload,\r\n initiatorOverride?: \"agent\" | \"user\",\r\n) => {\r\n const openAIPayload = translateToOpenAI(anthropicPayload)\r\n let finalPayload = await applyReplacementsToPayload(openAIPayload)\r\n finalPayload = { ...finalPayload, model: normalizeModelName(finalPayload.model) }\r\n logger.debug(\r\n \"Translated OpenAI request payload:\",\r\n JSON.stringify(finalPayload),\r\n )\r\n\r\n const response = await createChatCompletions(finalPayload, {\n initiator: initiatorOverride,\n })\n\r\n if (isNonStreaming(response)) {\r\n logger.debug(\r\n \"Non-streaming response from Copilot:\",\r\n JSON.stringify(response).slice(-400),\r\n )\r\n const anthropicResponse = translateToAnthropic(response)\r\n logger.debug(\r\n \"Translated Anthropic response:\",\r\n JSON.stringify(anthropicResponse),\r\n )\r\n return c.json(anthropicResponse)\r\n }\r\n\r\n logger.debug(\"Streaming response from Copilot\")\r\n return streamSSE(c, async (stream) => {\r\n const streamState: AnthropicStreamState = {\r\n messageStartSent: false,\r\n contentBlockIndex: 0,\r\n contentBlockOpen: false,\r\n toolCalls: {},\r\n }\r\n\r\n for await (const rawEvent of response) {\r\n logger.debug(\"Copilot raw stream event:\", JSON.stringify(rawEvent))\r\n if (rawEvent.data === \"[DONE]\") {\r\n break\r\n }\r\n\r\n if (!rawEvent.data) {\r\n continue\r\n }\r\n\r\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\r\n const events = translateChunkToAnthropicEvents(chunk, streamState)\r\n\r\n for (const event of events) {\r\n logger.debug(\"Translated Anthropic event:\", JSON.stringify(event))\r\n await stream.writeSSE({\r\n event: event.type,\r\n data: JSON.stringify(event),\r\n })\r\n }\r\n }\r\n })\r\n}\r\n\r\nconst handleWithResponsesApi = async (\r\n c: Context,\r\n anthropicPayload: AnthropicMessagesPayload,\r\n initiatorOverride?: \"agent\" | \"user\",\r\n) => {\r\n const responsesPayload =\r\n translateAnthropicMessagesToResponsesPayload(anthropicPayload)\r\n logger.debug(\r\n \"Translated Responses payload:\",\r\n JSON.stringify(responsesPayload),\r\n )\r\n\r\n const { vision, initiator } = getResponsesRequestOptions(responsesPayload)\r\n const response = await createResponses(responsesPayload, {\r\n vision,\r\n initiator: initiatorOverride ?? initiator,\r\n })\r\n\r\n if (responsesPayload.stream && isAsyncIterable(response)) {\r\n logger.debug(\"Streaming response from Copilot (Responses API)\")\r\n return streamSSE(c, async (stream) => {\r\n const streamState = createResponsesStreamState()\r\n\r\n for await (const chunk of response) {\r\n const eventName = chunk.event\r\n if (eventName === \"ping\") {\r\n await stream.writeSSE({ event: \"ping\", data: '{\"type\":\"ping\"}' })\r\n continue\r\n }\r\n\r\n const data = chunk.data\r\n if (!data) {\r\n continue\r\n }\r\n\r\n logger.debug(\"Responses raw stream event:\", data)\r\n\r\n const events = translateResponsesStreamEvent(\r\n JSON.parse(data) as ResponseStreamEvent,\r\n streamState,\r\n )\r\n for (const event of events) {\r\n const eventData = JSON.stringify(event)\r\n logger.debug(\"Translated Anthropic event:\", eventData)\r\n await stream.writeSSE({\r\n event: event.type,\r\n data: eventData,\r\n })\r\n }\r\n\r\n if (streamState.messageCompleted) {\r\n logger.debug(\"Message completed, ending stream\")\r\n break\r\n }\r\n }\r\n\r\n if (!streamState.messageCompleted) {\r\n logger.warn(\r\n \"Responses stream ended without completion; sending error event\",\r\n )\r\n const errorEvent = buildErrorEvent(\r\n \"Responses stream ended without completion\",\r\n )\r\n await stream.writeSSE({\r\n event: errorEvent.type,\r\n data: JSON.stringify(errorEvent),\r\n })\r\n }\r\n })\r\n }\r\n\r\n logger.debug(\r\n \"Non-streaming Responses result:\",\r\n JSON.stringify(response).slice(-400),\r\n )\r\n const anthropicResponse = translateResponsesResultToAnthropic(\r\n response as ResponsesResult,\r\n )\r\n logger.debug(\r\n \"Translated Anthropic response:\",\r\n JSON.stringify(anthropicResponse),\r\n )\r\n return c.json(anthropicResponse)\r\n}\r\n\r\nconst handleWithMessagesApi = async (\r\n c: Context,\r\n anthropicPayload: AnthropicMessagesPayload,\r\n options?: {\r\n anthropicBetaHeader?: string\r\n initiatorOverride?: \"agent\" | \"user\"\r\n selectedModel?: Model\r\n },\r\n) => {\r\n const { anthropicBetaHeader, initiatorOverride, selectedModel } =\r\n options ?? {}\r\n // Pre-request processing: filter thinking blocks for Claude models so only\r\n // valid thinking blocks are sent to the Copilot Messages API.\r\n for (const msg of anthropicPayload.messages) {\r\n if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\r\n msg.content = msg.content.filter((block) => {\r\n if (block.type !== \"thinking\") return true\r\n return (\r\n block.thinking\r\n && block.thinking !== \"Thinking...\"\r\n && block.signature\r\n && !block.signature.includes(\"@\")\r\n )\r\n })\r\n }\r\n }\r\n\r\n if (selectedModel?.capabilities.supports.adaptive_thinking) {\r\n anthropicPayload.thinking = {\r\n type: \"adaptive\",\r\n }\r\n anthropicPayload.output_config = {\r\n effort: getAnthropicEffortForModel(anthropicPayload.model),\r\n }\r\n }\r\n\r\n logger.debug(\"Translated Messages payload:\", JSON.stringify(anthropicPayload))\r\n\r\n const response = await createMessages(anthropicPayload, anthropicBetaHeader, {\r\n initiator: initiatorOverride,\r\n })\r\n\r\n if (isAsyncIterable(response)) {\r\n logger.debug(\"Streaming response from Copilot (Messages API)\")\r\n return streamSSE(c, async (stream) => {\r\n for await (const event of response) {\r\n const eventName = event.event\r\n const data = event.data ?? \"\"\r\n logger.debug(\"Messages raw stream event:\", data)\r\n await stream.writeSSE({\r\n event: eventName,\r\n data,\r\n })\r\n }\r\n })\r\n }\r\n\r\n logger.debug(\r\n \"Non-streaming Messages result:\",\r\n JSON.stringify(response).slice(-400),\r\n )\r\n return c.json(response)\r\n}\r\n\r\nconst shouldUseResponsesApi = (selectedModel: Model | undefined): boolean => {\r\n return (\r\n selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false\r\n )\r\n}\r\n\r\nconst shouldUseMessagesApi = (selectedModel: Model | undefined): boolean => {\r\n return (\r\n selectedModel?.supported_endpoints?.includes(MESSAGES_ENDPOINT) ?? false\r\n )\r\n}\r\n\r\nconst isNonStreaming = (\r\n response: Awaited<ReturnType<typeof createChatCompletions>>,\r\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\r\n\r\nconst isAsyncIterable = <T>(value: unknown): value is AsyncIterable<T> =>\r\n Boolean(value)\r\n && typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\r\n\r\nconst getAnthropicEffortForModel = (\r\n model: string,\r\n): \"low\" | \"medium\" | \"high\" | \"max\" => {\r\n const reasoningEffort = getReasoningEffortForModel(model)\r\n\r\n if (reasoningEffort === \"xhigh\") return \"max\"\r\n if (reasoningEffort === \"none\" || reasoningEffort === \"minimal\") return \"low\"\r\n\r\n return reasoningEffort\r\n}\r\n\r\nconst isCompactRequest = (\r\n anthropicPayload: AnthropicMessagesPayload,\r\n): boolean => {\r\n const system = anthropicPayload.system\r\n if (typeof system === \"string\") {\r\n return system.startsWith(compactSystemPromptStart)\r\n }\r\n if (!Array.isArray(system)) return false\r\n\r\n return system.some(\r\n (msg) =>\r\n typeof msg.text === \"string\"\r\n && msg.text.startsWith(compactSystemPromptStart),\r\n )\r\n}\r\n\r\nconst mergeContentWithText = (\r\n tr: AnthropicToolResultBlock,\r\n textBlock: AnthropicTextBlock,\r\n): AnthropicToolResultBlock => {\r\n if (typeof tr.content === \"string\") {\r\n return { ...tr, content: `${tr.content}\\n\\n${textBlock.text}` }\r\n }\r\n return {\r\n ...tr,\r\n content: [...tr.content, textBlock],\r\n }\r\n}\r\n\r\nconst mergeContentWithTexts = (\r\n tr: AnthropicToolResultBlock,\r\n textBlocks: Array<AnthropicTextBlock>,\r\n): AnthropicToolResultBlock => {\r\n if (typeof tr.content === \"string\") {\r\n const appendedTexts = textBlocks.map((tb) => tb.text).join(\"\\n\\n\")\r\n return { ...tr, content: `${tr.content}\\n\\n${appendedTexts}` }\r\n }\r\n return { ...tr, content: [...tr.content, ...textBlocks] }\r\n}\r\n\r\nconst mergeToolResultForClaude = (\r\n anthropicPayload: AnthropicMessagesPayload,\r\n): void => {\r\n for (const msg of anthropicPayload.messages) {\r\n if (msg.role !== \"user\" || !Array.isArray(msg.content)) continue\r\n\r\n const toolResults: Array<AnthropicToolResultBlock> = []\r\n const textBlocks: Array<AnthropicTextBlock> = []\r\n let valid = true\r\n\r\n for (const block of msg.content) {\r\n if (block.type === \"tool_result\") {\r\n toolResults.push(block)\r\n } else if (block.type === \"text\") {\r\n textBlocks.push(block)\r\n } else {\r\n valid = false\r\n break\r\n }\r\n }\r\n\r\n if (!valid || toolResults.length === 0 || textBlocks.length === 0) continue\r\n\r\n msg.content = mergeToolResult(toolResults, textBlocks)\r\n }\r\n}\r\n\r\nconst mergeToolResult = (\r\n toolResults: Array<AnthropicToolResultBlock>,\r\n textBlocks: Array<AnthropicTextBlock>,\r\n): Array<AnthropicToolResultBlock> => {\r\n // equal lengths -> pairwise merge\r\n if (toolResults.length === textBlocks.length) {\r\n return toolResults.map((tr, i) => mergeContentWithText(tr, textBlocks[i]))\r\n }\r\n\r\n // lengths differ -> append all textBlocks to the last tool_result\r\n const lastIndex = toolResults.length - 1\r\n return toolResults.map((tr, i) =>\r\n i === lastIndex ? mergeContentWithTexts(tr, textBlocks) : tr,\r\n )\r\n}\r\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCountTokens } from \"./count-tokens-handler\"\nimport { handleCompletion } from \"./handler\"\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n\nmessageRoutes.post(\"/count_tokens\", async (c) => {\n try {\n return await handleCountTokens(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\nimport { cacheModels } from \"~/lib/utils\"\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get(\"/\", async (c) => {\n try {\n if (!state.models) {\n // This should be handled by startup logic, but as a fallback.\n await cacheModels()\n }\n\n // Copilot models\n const copilotModels =\n state.models?.data.map((model) => ({\n id: model.id,\n object: \"model\",\n type: \"model\",\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n })) ?? []\n\n return c.json({\n object: \"list\",\n data: copilotModels,\n has_more: false,\n })\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport {\n addReplacement,\n clearUserReplacements,\n getAllReplacements,\n getUserReplacements,\n removeReplacement,\n toggleReplacement,\n updateReplacement,\n} from \"~/lib/auto-replace\"\n\nexport const replacementsRoute = new Hono()\n\n// Get all replacement rules\nreplacementsRoute.get(\"/\", async (c) => {\n return c.json({\n all: await getAllReplacements(),\n user: await getUserReplacements(),\n })\n})\n\n// Add a new replacement rule\nreplacementsRoute.post(\"/\", async (c) => {\n const body = await c.req.json<{\n pattern: string\n replacement?: string\n isRegex?: boolean\n name?: string\n }>()\n\n if (!body.pattern) {\n return c.json({ error: \"Pattern is required\" }, 400)\n }\n\n const rule = await addReplacement(\n body.pattern,\n body.replacement ?? \"\",\n body.isRegex ?? false,\n body.name,\n )\n\n return c.json(rule, 201)\n})\n\n// Delete a replacement rule\nreplacementsRoute.delete(\"/:id\", async (c) => {\n const id = c.req.param(\"id\")\n const success = await removeReplacement(id)\n\n if (!success) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json({ success: true })\n})\n\n// Update a replacement rule\nreplacementsRoute.patch(\"/:id\", async (c) => {\n const id = c.req.param(\"id\")\n const body = await c.req.json<{\n name?: string\n pattern?: string\n replacement?: string\n isRegex?: boolean\n enabled?: boolean\n }>()\n\n const rule = await updateReplacement(id, body)\n\n if (!rule) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json(rule)\n})\n\n// Toggle a replacement rule\nreplacementsRoute.patch(\"/:id/toggle\", async (c) => {\n const id = c.req.param(\"id\")\n const rule = await toggleReplacement(id)\n\n if (!rule) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json(rule)\n})\n\n// Clear all user replacements\nreplacementsRoute.delete(\"/\", async (c) => {\n await clearUserReplacements()\n return c.json({ success: true })\n})\n","/**\r\n * Stream ID Synchronization for @ai-sdk/openai compatibility\r\n *\r\n * Problem: GitHub Copilot's Responses API returns different IDs for the same\r\n * item in 'added' vs 'done' events. This breaks @ai-sdk/openai which expects\r\n * consistent IDs across the stream lifecycle.\r\n *\r\n * Errors without this fix:\r\n * - \"activeReasoningPart.summaryParts\" undefined\r\n * - \"text part not found\"\r\n *\r\n * Use case: OpenCode (AI coding assistant) using Codex models (gpt-5.2-codex)\r\n * via @ai-sdk/openai provider requires the Responses API endpoint.\r\n */\r\n\r\nimport type {\r\n ResponseOutputItemAddedEvent,\r\n ResponseOutputItemDoneEvent,\r\n ResponseStreamEvent,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\ninterface StreamIdTracker {\r\n outputItems: Map<number, string>\r\n}\r\n\r\nexport const createStreamIdTracker = (): StreamIdTracker => ({\r\n outputItems: new Map(),\r\n})\r\n\r\nexport const fixStreamIds = (\r\n data: string,\r\n event: string | undefined,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n if (!data) return data\r\n const parsed = JSON.parse(data) as ResponseStreamEvent\r\n switch (event) {\r\n case \"response.output_item.added\": {\r\n return handleOutputItemAdded(\r\n parsed as ResponseOutputItemAddedEvent,\r\n tracker,\r\n )\r\n }\r\n case \"response.output_item.done\": {\r\n return handleOutputItemDone(\r\n parsed as ResponseOutputItemDoneEvent,\r\n tracker,\r\n )\r\n }\r\n default: {\r\n return handleItemId(parsed, tracker)\r\n }\r\n }\r\n}\r\n\r\nconst handleOutputItemAdded = (\r\n parsed: ResponseOutputItemAddedEvent,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n if (!parsed.item.id) {\r\n let randomSuffix = \"\"\r\n while (randomSuffix.length < 16) {\r\n randomSuffix += Math.random().toString(36).slice(2)\r\n }\r\n parsed.item.id = `oi_${parsed.output_index}_${randomSuffix.slice(0, 16)}`\r\n }\r\n\r\n const outputIndex = parsed.output_index\r\n tracker.outputItems.set(outputIndex, parsed.item.id)\r\n return JSON.stringify(parsed)\r\n}\r\n\r\nconst handleOutputItemDone = (\r\n parsed: ResponseOutputItemDoneEvent,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n const outputIndex = parsed.output_index\r\n const originalId = tracker.outputItems.get(outputIndex)\r\n if (originalId) {\r\n parsed.item.id = originalId\r\n }\r\n return JSON.stringify(parsed)\r\n}\r\n\r\nconst handleItemId = (\r\n parsed: ResponseStreamEvent & { output_index?: number; item_id?: string },\r\n tracker: StreamIdTracker,\r\n): string => {\r\n const outputIndex = parsed.output_index\r\n if (outputIndex !== undefined) {\r\n const itemId = tracker.outputItems.get(outputIndex)\r\n if (itemId) {\r\n parsed.item_id = itemId\r\n }\r\n }\r\n return JSON.stringify(parsed)\r\n}\r\n","import type { Context } from \"hono\"\r\n\r\nimport { streamSSE } from \"hono/streaming\"\r\n\r\nimport { awaitApproval } from \"~/lib/approval\"\r\nimport { getConfig } from \"~/lib/config\"\r\nimport { createHandlerLogger } from \"~/lib/logger\"\r\nimport { checkRateLimit } from \"~/lib/rate-limit\"\r\nimport { setRequestContext } from \"~/lib/request-logger\"\r\nimport { state } from \"~/lib/state\"\r\nimport {\r\n createResponses,\r\n type ResponsesPayload,\r\n type ResponsesResult,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nimport { createStreamIdTracker, fixStreamIds } from \"./stream-id-sync\"\r\nimport { getResponsesRequestOptions } from \"./utils\"\r\n\r\nconst logger = createHandlerLogger(\"responses-handler\")\r\n\r\nconst RESPONSES_ENDPOINT = \"/responses\"\r\n\r\nexport const handleResponses = async (c: Context) => {\r\n await checkRateLimit(state)\r\n\r\n const payload = await c.req.json<ResponsesPayload>()\r\n setRequestContext(c, { provider: \"Copilot (Responses)\", model: payload.model })\r\n logger.debug(\"Responses request payload:\", JSON.stringify(payload))\r\n\r\n useFunctionApplyPatch(payload)\r\n\r\n // Remove web_search tool as it's not supported by GitHub Copilot\r\n removeWebSearchTool(payload)\r\n\r\n const selectedModel = state.models?.data.find(\r\n (model) => model.id === payload.model,\r\n )\r\n const supportsResponses =\r\n selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false\r\n\r\n if (!supportsResponses) {\r\n return c.json(\r\n {\r\n error: {\r\n message:\r\n \"This model does not support the responses endpoint. Please choose a different model.\",\r\n type: \"invalid_request_error\",\r\n },\r\n },\r\n 400,\r\n )\r\n }\r\n\r\n const { vision, initiator } = getResponsesRequestOptions(payload)\r\n\r\n if (state.manualApprove) {\r\n await awaitApproval()\r\n }\r\n\r\n const response = await createResponses(payload, { vision, initiator })\r\n\r\n if (isStreamingRequested(payload) && isAsyncIterable(response)) {\r\n logger.debug(\"Forwarding native Responses stream\")\r\n return streamSSE(c, async (stream) => {\r\n const idTracker = createStreamIdTracker()\r\n\r\n for await (const chunk of response) {\r\n logger.debug(\"Responses stream chunk:\", JSON.stringify(chunk))\r\n\r\n const processedData = fixStreamIds(\r\n (chunk as { data?: string }).data ?? \"\",\r\n (chunk as { event?: string }).event,\r\n idTracker,\r\n )\r\n\r\n await stream.writeSSE({\r\n id: (chunk as { id?: string }).id,\r\n event: (chunk as { event?: string }).event,\r\n data: processedData,\r\n })\r\n }\r\n })\r\n }\r\n\r\n logger.debug(\r\n \"Forwarding native Responses result:\",\r\n JSON.stringify(response).slice(-400),\r\n )\r\n return c.json(response as ResponsesResult)\r\n}\r\n\r\nconst isAsyncIterable = <T>(value: unknown): value is AsyncIterable<T> =>\r\n Boolean(value)\r\n && typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\r\n\r\nconst isStreamingRequested = (payload: ResponsesPayload): boolean =>\r\n Boolean(payload.stream)\r\n\r\nconst useFunctionApplyPatch = (payload: ResponsesPayload): void => {\r\n const config = getConfig()\r\n const useFunctionApplyPatch = config.useFunctionApplyPatch ?? true\r\n if (useFunctionApplyPatch) {\r\n logger.debug(\"Using function tool apply_patch for responses\")\r\n if (Array.isArray(payload.tools)) {\r\n const toolsArr = payload.tools\r\n for (let i = 0; i < toolsArr.length; i++) {\r\n const t = toolsArr[i]\r\n if (t.type === \"custom\" && t.name === \"apply_patch\") {\r\n toolsArr[i] = {\r\n type: \"function\",\r\n name: t.name,\r\n description: \"Use the `apply_patch` tool to edit files\",\r\n parameters: {\r\n type: \"object\",\r\n properties: {\r\n input: {\r\n type: \"string\",\r\n description: \"The entire contents of the apply_patch command\",\r\n },\r\n },\r\n required: [\"input\"],\r\n },\r\n strict: false,\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst removeWebSearchTool = (payload: ResponsesPayload): void => {\r\n if (!Array.isArray(payload.tools) || payload.tools.length === 0) return\r\n\r\n payload.tools = payload.tools.filter((t) => {\r\n return t.type !== \"web_search\"\r\n })\r\n}\r\n","import { Hono } from \"hono\"\r\n\r\nimport { forwardError } from \"~/lib/error\"\r\n\r\nimport { handleResponses } from \"./handler\"\r\n\r\nexport const responsesRoutes = new Hono()\r\n\r\nresponsesRoutes.post(\"/\", async (c) => {\r\n try {\r\n return await handleResponses(c)\r\n } catch (error) {\r\n return await forwardError(c, error)\r\n }\r\n})\r\n","import { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get(\"/\", (c) => {\n try {\n return c.json({\n token: state.copilotToken,\n })\n } catch (error) {\n console.error(\"Error fetching token:\", error)\n return c.json({ error: \"Failed to fetch token\", token: null }, 500)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\n\nexport const usageRoute = new Hono()\n\nusageRoute.get(\"/\", async (c) => {\n try {\n const usage = await getCopilotUsage()\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","import { Hono } from \"hono\"\r\nimport { cors } from \"hono/cors\"\r\n\r\nimport { createAuthMiddleware } from \"./lib/request-auth\"\r\nimport { requestLogger } from \"./lib/request-logger\"\r\nimport { completionRoutes } from \"./routes/chat-completions/route\"\r\nimport { embeddingRoutes } from \"./routes/embeddings/route\"\r\nimport { messageRoutes } from \"./routes/messages/route\"\r\nimport { modelRoutes } from \"./routes/models/route\"\r\nimport { replacementsRoute } from \"./routes/replacements/route\"\r\nimport { responsesRoutes } from \"./routes/responses/route\"\r\nimport { tokenRoute } from \"./routes/token/route\"\r\nimport { usageRoute } from \"./routes/usage/route\"\r\n\r\nexport const server = new Hono()\r\n\r\nserver.use(requestLogger)\r\nserver.use(cors())\r\nserver.use(\"*\", createAuthMiddleware())\r\n\r\nserver.get(\"/\", (c) => c.text(\"Server running\"))\r\n\r\nserver.route(\"/chat/completions\", completionRoutes)\r\nserver.route(\"/models\", modelRoutes)\r\nserver.route(\"/embeddings\", embeddingRoutes)\r\nserver.route(\"/usage\", usageRoute)\r\nserver.route(\"/token\", tokenRoute)\r\nserver.route(\"/replacements\", replacementsRoute)\r\nserver.route(\"/responses\", responsesRoutes)\r\n\r\n// Compatibility with tools that expect v1/ prefix\r\nserver.route(\"/v1/chat/completions\", completionRoutes)\r\nserver.route(\"/v1/models\", modelRoutes)\r\nserver.route(\"/v1/embeddings\", embeddingRoutes)\r\nserver.route(\"/v1/responses\", responsesRoutes)\r\n\r\n// Anthropic compatible endpoints\r\nserver.route(\"/v1/messages\", messageRoutes)\r\n","#!/usr/bin/env node\r\n\r\nimport { defineCommand } from \"citty\"\r\nimport clipboard from \"clipboardy\"\r\nimport consola from \"consola\"\r\nimport { serve, type ServerHandler } from \"srvx\"\r\nimport invariant from \"tiny-invariant\"\r\n\r\nimport packageJson from \"../package.json\" with { type: \"json\" }\r\nimport { mergeConfigWithDefaults } from \"./lib/config\"\r\nimport { ensurePaths } from \"./lib/paths\"\r\nimport { initProxyFromEnv } from \"./lib/proxy\"\r\nimport { generateEnvScript } from \"./lib/shell\"\r\nimport { state } from \"./lib/state\"\r\nimport { setupCopilotToken, setupGitHubToken } from \"./lib/token\"\r\nimport { cacheModels, cacheVSCodeVersion } from \"./lib/utils\"\r\nimport { server } from \"./server\"\r\n\r\ninterface RunServerOptions {\r\n port: number\r\n verbose: boolean\r\n accountType: string\r\n manual: boolean\r\n rateLimit?: number\r\n rateLimitWait: boolean\r\n githubToken?: string\r\n claudeCode: boolean\r\n showToken: boolean\r\n proxyEnv: boolean\r\n insecure: boolean\r\n debug: boolean\r\n}\r\n\r\nexport async function runServer(options: RunServerOptions): Promise<void> {\r\n consola.info(`copilot-api v${packageJson.version}`)\r\n\r\n if (options.insecure) {\r\n // Disable SSL certificate verification globally\r\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = \"0\"\r\n consola.warn(\"SSL certificate verification disabled (insecure mode)\")\r\n }\r\n\r\n if (options.proxyEnv) {\r\n initProxyFromEnv()\r\n }\r\n\r\n if (options.verbose) {\r\n consola.level = 5\r\n consola.info(\"Verbose logging enabled\")\r\n }\r\n\r\n state.accountType = options.accountType\r\n if (options.accountType !== \"individual\") {\r\n consola.info(`Using ${options.accountType} plan GitHub account`)\r\n }\r\n\r\n state.manualApprove = options.manual\r\n state.rateLimitSeconds = options.rateLimit\r\n state.rateLimitWait = options.rateLimitWait\r\n state.showToken = options.showToken\r\n state.debug = options.debug\r\n state.verbose = options.verbose\r\n\r\n if (options.debug) {\r\n consola.info(\"Debug mode enabled - raw HTTP requests will be logged\")\r\n }\r\n\r\n await ensurePaths()\r\n mergeConfigWithDefaults()\r\n await cacheVSCodeVersion()\r\n\r\n if (options.githubToken) {\r\n state.githubToken = options.githubToken\r\n consola.info(\"Using provided GitHub token\")\r\n } else {\r\n await setupGitHubToken()\r\n }\r\n\r\n await setupCopilotToken()\r\n await cacheModels()\r\n\r\n const allModelIds = state.models?.data.map((model) => model.id) ?? []\n\r\n consola.info(\r\n `Available models: \\n${allModelIds.map((id) => `- ${id}`).join(\"\\n\")}`,\r\n )\r\n\r\n const serverUrl = `http://localhost:${options.port}`\r\n\r\n if (options.claudeCode) {\r\n invariant(state.models, \"Models should be loaded by now\")\r\n\r\n const selectedModel = await consola.prompt(\r\n \"Select a model to use with Claude Code\",\r\n {\r\n type: \"select\",\r\n options: allModelIds,\r\n },\r\n )\r\n\r\n const selectedSmallModel = await consola.prompt(\r\n \"Select a small model to use with Claude Code\",\r\n {\r\n type: \"select\",\r\n options: allModelIds,\r\n },\r\n )\r\n\r\n const command = generateEnvScript(\r\n {\r\n ANTHROPIC_BASE_URL: serverUrl,\r\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\r\n ANTHROPIC_MODEL: selectedModel,\r\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\r\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\r\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\r\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\r\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\r\n },\r\n \"claude\",\r\n )\r\n\r\n try {\r\n clipboard.writeSync(command)\r\n consola.success(\"Copied Claude Code command to clipboard!\")\r\n } catch {\r\n consola.warn(\r\n \"Failed to copy to clipboard. Here is the Claude Code command:\",\r\n )\r\n consola.log(command)\r\n }\r\n }\r\n\r\n consola.box(\r\n `🌐 Usage Viewer: https://ericc-ch.github.io/copilot-api?endpoint=${serverUrl}/usage`,\r\n )\r\n\r\n serve({\r\n fetch: server.fetch as ServerHandler,\r\n port: options.port,\r\n // Increase idle timeout for long-running requests (e.g. Claude Code compact)\r\n // Bun default is 10s which is too short\r\n bun: {\r\n idleTimeout: 255, // max value in seconds (4m 15s)\r\n },\r\n })\r\n}\r\n\r\nexport const start = defineCommand({\r\n meta: {\r\n name: \"start\",\r\n description: \"Start the Copilot API server\",\r\n },\r\n args: {\r\n port: {\r\n alias: \"p\",\r\n type: \"string\",\r\n default: \"4141\",\r\n description: \"Port to listen on\",\r\n },\r\n verbose: {\r\n alias: \"v\",\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Enable verbose logging\",\r\n },\r\n \"account-type\": {\r\n alias: \"a\",\r\n type: \"string\",\r\n default: \"individual\",\r\n description: \"Account type to use (individual, business, enterprise)\",\r\n },\r\n manual: {\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Enable manual request approval\",\r\n },\r\n \"rate-limit\": {\r\n alias: \"r\",\r\n type: \"string\",\r\n description: \"Rate limit in seconds between requests\",\r\n },\r\n wait: {\r\n alias: \"w\",\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\r\n },\r\n \"github-token\": {\r\n alias: \"g\",\r\n type: \"string\",\r\n description:\r\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\r\n },\r\n \"claude-code\": {\r\n alias: \"c\",\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Generate a command to launch Claude Code with Copilot API config\",\r\n },\r\n \"show-token\": {\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\r\n },\r\n \"proxy-env\": {\r\n type: \"boolean\",\r\n default: false,\r\n description: \"Initialize proxy from environment variables\",\r\n },\r\n insecure: {\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Disable SSL certificate verification (for corporate proxies with self-signed certs)\",\r\n },\r\n debug: {\r\n alias: \"d\",\r\n type: \"boolean\",\r\n default: false,\r\n description:\r\n \"Log raw HTTP requests received by the server (headers, method, path)\",\r\n },\r\n },\r\n run({ args }) {\r\n const rateLimitRaw = args[\"rate-limit\"]\r\n const rateLimit =\r\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\r\n\r\n return runServer({\r\n port: Number.parseInt(args.port, 10),\r\n verbose: args.verbose,\r\n accountType: args[\"account-type\"],\r\n manual: args.manual,\r\n rateLimit,\r\n rateLimitWait: args.wait,\r\n githubToken: args[\"github-token\"],\r\n claudeCode: args[\"claude-code\"],\r\n showToken: args[\"show-token\"],\r\n proxyEnv: args[\"proxy-env\"],\r\n insecure: args.insecure,\r\n debug: args.debug,\r\n })\r\n },\r\n})\r\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\"\n\nimport packageJson from \"../package.json\" with { type: \"json\" }\nimport { auth } from \"./auth\"\nimport { checkUsage } from \"./check-usage\"\nimport { config } from \"./config\"\nimport { debug } from \"./debug\"\nimport { start } from \"./start\"\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api\",\n version: packageJson.version,\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, \"check-usage\": checkUsage, debug, config },\n})\n\nawait runMain(main)\n"],"mappings":"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"}
1
+ {"version":3,"file":"main.js","names":["state: State","state","headers: Record<string, string>","errorJson: unknown","lastError: Error | undefined","lastResponse: Response | undefined","headers: Record<string, string>","errorDetails: string","parsed: unknown","token","name","SYSTEM_REPLACEMENTS: Array<ReplacementRule>","userReplacements: Array<ReplacementRule>","rule: ReplacementRule","result","appliedRules: Array<string>","allAppliedRules: Array<string>","type","name","rule","version","defaultConfig: AppConfig","cachedConfig: AppConfig | null","fs","config","MODEL_REASONING_CONFIG: Partial<Record<string, ModelReasoningConfig>>","config","virtualModels: Array<VirtualModel>","process","commandBlock: string","config","sanitized: Record<string, unknown>","lines: Array<string>","parts: Array<string>","modParts: Array<string>","path","state","x","headers: Record<string, string>","handleCompletion","isNonStreaming","handleCompletion","newMessages: Array<Message>","contentParts: Array<ContentPart>","allTextBlocks: Array<AnthropicTextBlock>","allToolUseBlocks: Array<AnthropicToolUseBlock>","stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null","fs","stats: fs.Stats","name","headers: Record<string, string>","input: Array<ResponseInputItem>","items: Array<ResponseInputItem>","pendingContent: Array<ResponseInputContent>","contentBlocks: Array<AnthropicAssistantContentBlock>","segments: Array<string>","parsed: unknown","result: Array<ResponseInputContent>","state","handleOutputItemAdded","handleOutputItemDone","events","blockIndex","name","result: Array<ResponseInputItem>","headers: Record<string, string>","state","events: Array<AnthropicStreamEventData>","events","logger","RESPONSES_ENDPOINT","streamState: AnthropicStreamState","events","isAsyncIterable","parts: Array<string>","toolResults: Array<AnthropicToolResultBlock>","textBlocks: Array<AnthropicTextBlock>","packageJson","packageJson"],"sources":["../package.json","../src/lib/paths.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-token.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/lib/retry-fetch.ts","../src/services/copilot/get-models.ts","../src/services/get-vscode-version.ts","../src/lib/utils.ts","../src/services/github/poll-access-token.ts","../src/lib/token.ts","../src/auth.ts","../src/services/github/get-copilot-usage.ts","../src/check-usage.ts","../src/lib/auto-replace.ts","../src/config.ts","../src/debug.ts","../src/lib/config.ts","../src/lib/model-suffix.ts","../src/lib/proxy.ts","../src/lib/shell.ts","../src/lib/request-auth.ts","../src/lib/api-key-guard.ts","../src/lib/request-logger.ts","../src/lib/approval.ts","../src/lib/model-resolver.ts","../src/lib/rate-limit.ts","../src/lib/tokenizer.ts","../src/services/copilot/create-chat-completions.ts","../src/routes/chat-completions/handler.ts","../src/routes/chat-completions/route.ts","../src/services/copilot/create-embeddings.ts","../src/routes/embeddings/route.ts","../src/routes/messages/utils.ts","../src/routes/messages/non-stream-translation.ts","../src/routes/messages/count-tokens-handler.ts","../src/lib/logger.ts","../src/services/copilot/create-responses.ts","../src/routes/messages/responses-translation.ts","../src/routes/messages/responses-stream-translation.ts","../src/routes/responses/utils.ts","../src/services/copilot/create-messages.ts","../src/routes/messages/stream-translation.ts","../src/routes/messages/subagent-marker.ts","../src/routes/messages/handler.ts","../src/routes/messages/route.ts","../src/routes/models/route.ts","../src/routes/replacements/route.ts","../src/routes/responses/stream-id-sync.ts","../src/routes/responses/handler.ts","../src/routes/responses/route.ts","../src/routes/token/route.ts","../src/routes/usage/route.ts","../src/server.ts","../src/start.ts","../src/main.ts"],"sourcesContent":["{\n \"name\": \"@ashsec/copilot-api\",\n \"version\": \"0.11.3\",\n \"description\": \"Turn GitHub Copilot into OpenAI/Anthropic API compatible server. Usable with Claude Code!\",\n \"keywords\": [\n \"proxy\",\n \"github-copilot\",\n \"openai-compatible\"\n ],\n \"homepage\": \"https://github.com/ericc-ch/copilot-api\",\n \"bugs\": \"https://github.com/ericc-ch/copilot-api/issues\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/ericc-ch/copilot-api.git\"\n },\n \"author\": \"Erick Christian <erickchristian48@gmail.com>\",\n \"type\": \"module\",\n \"bin\": {\n \"copilot-api\": \"./dist/main.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsdown\",\n \"dev\": \"bun run --watch ./src/main.ts\",\n \"knip\": \"knip-bun\",\n \"lint\": \"eslint --cache\",\n \"lint:all\": \"eslint --cache .\",\n \"prepack\": \"bun run build\",\n \"prepare\": \"simple-git-hooks\",\n \"release\": \"bumpp && bun publish --access public\",\n \"start\": \"NODE_ENV=production bun run ./src/main.ts\",\n \"typecheck\": \"tsc\"\n },\n \"simple-git-hooks\": {\n \"pre-commit\": \"bunx lint-staged\"\n },\n \"lint-staged\": {\n \"*\": \"bun run lint --fix\"\n },\n \"dependencies\": {\n \"citty\": \"^0.1.6\",\n \"clipboardy\": \"^5.0.0\",\n \"consola\": \"^3.4.2\",\n \"fetch-event-stream\": \"^0.1.5\",\n \"gpt-tokenizer\": \"^3.0.1\",\n \"hono\": \"^4.9.9\",\n \"ms\": \"^2.1.3\",\n \"proxy-from-env\": \"^1.1.0\",\n \"srvx\": \"^0.8.9\",\n \"tiny-invariant\": \"^1.3.3\",\n \"undici\": \"^7.16.0\",\n \"zod\": \"^4.1.11\"\n },\n \"devDependencies\": {\n \"@echristian/eslint-config\": \"^0.0.54\",\n \"@types/bun\": \"^1.2.23\",\n \"@types/proxy-from-env\": \"^1.0.4\",\n \"bumpp\": \"^10.2.3\",\n \"eslint\": \"^9.37.0\",\n \"knip\": \"^5.64.1\",\n \"lint-staged\": \"^16.2.3\",\n \"prettier-plugin-packagejson\": \"^2.5.19\",\n \"simple-git-hooks\": \"^2.13.1\",\n \"tsdown\": \"^0.15.6\",\n \"typescript\": \"^5.9.3\"\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-api\")\n\nconst GITHUB_TOKEN_PATH = path.join(APP_DIR, \"github_token\")\nconst REPLACEMENTS_CONFIG_PATH = path.join(APP_DIR, \"replacements.json\")\n\nexport const PATHS = {\n APP_DIR,\n CONFIG_PATH: path.join(APP_DIR, \"config.json\"),\n GITHUB_TOKEN_PATH,\n REPLACEMENTS_CONFIG_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}\n","import type { ModelsResponse } from \"~/services/copilot/get-models\"\n\nexport interface State {\n githubToken?: string\n copilotToken?: string\n\n accountType: string\n models?: ModelsResponse\n vsCodeVersion?: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n debug: boolean\n verbose: boolean\n apiKeyAuth?: string\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n}\n\nexport const state: State = {\n accountType: \"individual\",\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n debug: false,\n verbose: false,\n}\n","import { randomUUID } from \"node:crypto\"\r\n\r\nimport type { State } from \"./state\"\r\n\r\nexport const standardHeaders = () => ({\r\n \"content-type\": \"application/json\",\r\n accept: \"application/json\",\r\n})\r\n\r\nconst COPILOT_VERSION = \"0.37.6\"\r\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\r\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\r\n\r\nconst API_VERSION = \"2025-10-01\"\r\n\r\nexport const copilotBaseUrl = (state: State) =>\r\n state.accountType === \"individual\" ?\r\n \"https://api.githubcopilot.com\"\r\n : `https://api.${state.accountType}.githubcopilot.com`\r\nexport const copilotHeaders = (state: State, vision: boolean = false) => {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bearer ${state.copilotToken}`,\r\n \"content-type\": standardHeaders()[\"content-type\"],\r\n \"copilot-integration-id\": \"vscode-chat\",\r\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\r\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\r\n \"user-agent\": USER_AGENT,\r\n \"openai-intent\": \"conversation-agent\",\r\n \"x-github-api-version\": API_VERSION,\r\n \"x-request-id\": randomUUID(),\r\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\r\n }\r\n\r\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\r\n\r\n return headers\r\n}\r\n\r\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\r\nexport const githubHeaders = (state: State) => ({\r\n ...standardHeaders(),\r\n authorization: `token ${state.githubToken}`,\r\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\r\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\r\n \"user-agent\": USER_AGENT,\r\n \"x-github-api-version\": API_VERSION,\r\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\r\n})\r\n\r\nexport const GITHUB_BASE_URL = \"https://github.com\"\r\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\r\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\r\n","import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n requestPayload?: unknown\n\n constructor(message: string, response: Response, requestPayload?: unknown) {\n super(message)\n this.response = response\n this.requestPayload = requestPayload\n }\n}\n\ninterface ContentFilterError {\n error: {\n code: string\n innererror?: {\n code: string\n content_filter_result?: unknown\n }\n }\n}\n\nfunction isContentFilterError(obj: unknown): obj is ContentFilterError {\n return (\n typeof obj === \"object\"\n && obj !== null\n && \"error\" in obj\n && typeof (obj as ContentFilterError).error === \"object\"\n && (obj as ContentFilterError).error.code === \"content_filter\"\n )\n}\n\nexport async function forwardError(c: Context, error: unknown) {\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n\n // Check for content filter error and log full details\n if (isContentFilterError(errorJson)) {\n consola.box(\"CONTENT FILTER TRIGGERED\")\n consola.error(\"Full error response:\")\n console.log(JSON.stringify(errorJson, null, 2))\n\n if (error.requestPayload) {\n consola.error(\"Request payload that triggered the filter:\")\n console.log(JSON.stringify(error.requestPayload, null, 2))\n }\n }\n\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotToken = async () => {\n const response = await fetch(\n `${GITHUB_API_BASE_URL}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(state),\n },\n )\n\n if (!response.ok) throw new HTTPError(\"Failed to get Copilot token\", response)\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n","import {\n GITHUB_APP_SCOPES,\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n standardHeaders,\n} from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport async function getDeviceCode(): 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) throw new HTTPError(\"Failed to get device code\", response)\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n expires_in: number\n interval: number\n}\n","import { GITHUB_API_BASE_URL, standardHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport async function getGitHubUser() {\n const response = await fetch(`${GITHUB_API_BASE_URL}/user`, {\n headers: {\n authorization: `token ${state.githubToken}`,\n ...standardHeaders(),\n },\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GithubUserResponse {\n login: string\n}\n","import consola from \"consola\"\n\nimport { sleep } from \"./utils\"\n\n// Fast retry: 100ms, 200ms, 300ms, then stop (max ~600ms total wait)\nconst RETRY_DELAYS_MS = [100, 200, 300]\n\n/**\n * Check if an error is retryable (transient network error)\n */\nfunction isRetryableError(error: unknown): boolean {\n if (!(error instanceof Error)) return false\n\n const message = error.message.toLowerCase()\n const causeMessage =\n error.cause instanceof Error ? error.cause.message.toLowerCase() : \"\"\n\n // Common transient error patterns\n const retryablePatterns = [\n \"fetch failed\",\n \"other side closed\",\n \"connection reset\",\n \"econnreset\",\n \"socket hang up\",\n \"socket connection was closed unexpectedly\",\n \"etimedout\",\n \"econnrefused\",\n \"network error\",\n \"aborted\",\n \"timeout\",\n ]\n\n return retryablePatterns.some(\n (pattern) => message.includes(pattern) || causeMessage.includes(pattern),\n )\n}\n\n/**\n * Check if an HTTP response status is retryable\n */\nfunction isRetryableStatus(status: number): boolean {\n // 4xx client errors (except 400, 401, 403, 404) and 5xx server errors\n // Retry: 408 Timeout, 429 Rate Limit, and all 5xx\n return status === 408 || status === 429 || (status >= 500 && status <= 599)\n}\n\n/**\n * Fetch with automatic fast retry on transient failures\n * Retries with delays: 100ms, 200ms, 300ms (max ~600ms total wait)\n */\nexport async function fetchWithRetry(\n input: string | URL | Request,\n init?: RequestInit,\n): Promise<Response> {\n const maxAttempts = RETRY_DELAYS_MS.length + 1 // 4 total attempts\n\n let lastError: Error | undefined\n let lastResponse: Response | undefined\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n // Force a new connection by adding connection-close while preserving\n // caller-provided header casing (tests assert exact header key names).\n const headers = toHeaderRecord(init?.headers)\n headers.Connection = \"close\"\n\n const response = await fetch(input, {\n ...init,\n headers,\n // Disable keep-alive to force fresh connections on each attempt\n keepalive: false,\n })\n\n // Check for retryable HTTP status codes\n if (isRetryableStatus(response.status) && attempt < maxAttempts - 1) {\n lastResponse = response\n const delayMs = RETRY_DELAYS_MS[attempt]\n consola.warn(\n `HTTP ${response.status} (attempt ${attempt + 1}/${maxAttempts}), retrying in ${delayMs}ms`,\n )\n await sleep(delayMs)\n continue\n }\n\n return response\n } catch (error) {\n lastError = error as Error\n\n if (!isRetryableError(error) || attempt === maxAttempts - 1) {\n throw error\n }\n\n const delayMs = RETRY_DELAYS_MS[attempt]\n consola.warn(\n `Fetch failed (attempt ${attempt + 1}/${maxAttempts}), retrying in ${delayMs}ms:`,\n lastError.message,\n )\n await sleep(delayMs)\n }\n }\n\n // If we exhausted retries due to HTTP status, return the last response\n if (lastResponse) {\n return lastResponse\n }\n\n throw lastError ?? new Error(\"Request failed without a captured error\")\n}\n\nfunction toHeaderRecord(\n headersInit: RequestInit[\"headers\"],\n): Record<string, string> {\n const headers: Record<string, string> = {}\n if (!headersInit) return headers\n\n if (headersInit instanceof Headers) {\n for (const [key, value] of headersInit.entries()) {\n headers[key] = value\n }\n return headers\n }\n\n if (Array.isArray(headersInit)) {\n for (const entry of headersInit) {\n if (\n Array.isArray(entry)\n && entry.length === 2\n && typeof entry[0] === \"string\"\n && typeof entry[1] === \"string\"\n ) {\n const [key, value] = entry\n headers[key] = value\n }\n }\n return headers\n }\n\n for (const [key, value] of Object.entries(\n headersInit as Record<string, unknown>,\n )) {\n if (typeof value === \"string\") {\n headers[key] = value\n }\n }\n return headers\n}\n","import consola from \"consola\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport const getModels = async () => {\r\n const url = `${copilotBaseUrl(state)}/models`\r\n const response = await fetchWithRetry(url, {\r\n headers: copilotHeaders(state),\r\n })\r\n\r\n if (!response.ok) {\r\n const errorBody = await response.text()\r\n let errorDetails: string\r\n try {\r\n const parsed: unknown = JSON.parse(errorBody)\r\n errorDetails = JSON.stringify(parsed, null, 2)\r\n } catch {\r\n errorDetails = errorBody || \"(empty response)\"\r\n }\r\n consola.error(\r\n `Failed to get models from ${url}\\n`\r\n + `Status: ${response.status} ${response.statusText}\\n`\r\n + `Response: ${errorDetails}`,\r\n )\r\n throw new HTTPError(\r\n `Failed to get models: ${response.status} ${response.statusText}`,\r\n response,\r\n )\r\n }\r\n\r\n return (await response.json()) as ModelsResponse\r\n}\r\n\r\nexport interface ModelsResponse {\r\n data: Array<Model>\r\n object: string\r\n}\r\n\r\ninterface ModelLimits {\r\n max_context_window_tokens?: number\r\n max_output_tokens?: number\r\n max_prompt_tokens?: number\r\n max_inputs?: number\r\n}\r\n\r\ninterface ModelSupports {\r\n max_thinking_budget?: number\r\n min_thinking_budget?: number\r\n tool_calls?: boolean\r\n parallel_tool_calls?: boolean\r\n dimensions?: boolean\r\n streaming?: boolean\r\n structured_outputs?: boolean\r\n vision?: boolean\r\n adaptive_thinking?: boolean\r\n}\r\n\r\ninterface ModelCapabilities {\r\n family: string\r\n limits: ModelLimits\r\n object: string\r\n supports: ModelSupports\r\n tokenizer: string\r\n type: string\r\n}\r\n\r\nexport interface Model {\r\n capabilities: ModelCapabilities\r\n id: string\r\n model_picker_enabled: boolean\r\n name: string\r\n object: string\r\n preview: boolean\r\n vendor: string\r\n version: string\r\n policy?: {\r\n state: string\r\n terms: string\r\n }\r\n supported_endpoints?: Array<string>\r\n}\r\n","const FALLBACK = \"1.104.3\"\n\nexport async function getVSCodeVersion() {\n const controller = new AbortController()\n const timeout = setTimeout(() => {\n controller.abort()\n }, 5000)\n\n try {\n const response = await fetch(\n \"https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=visual-studio-code-bin\",\n {\n signal: controller.signal,\n },\n )\n\n const pkgbuild = await response.text()\n const pkgverRegex = /pkgver=([0-9.]+)/\n const match = pkgbuild.match(pkgverRegex)\n\n if (match) {\n return match[1]\n }\n\n return FALLBACK\n } catch {\n return FALLBACK\n } finally {\n clearTimeout(timeout)\n }\n}\n\nawait getVSCodeVersion()\n","import consola from \"consola\"\n\nimport { getModels } from \"~/services/copilot/get-models\"\nimport { getVSCodeVersion } from \"~/services/get-vscode-version\"\n\nimport { state } from \"./state\"\n\nexport const sleep = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nexport const isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined\n\nexport async function cacheModels(): Promise<void> {\n try {\n const models = await getModels()\n state.models = models\n } catch (error) {\n consola.error(\"Failed to fetch and cache models. This could be due to:\")\n consola.error(\" - Invalid or expired Copilot token\")\n consola.error(\" - Network connectivity issues\")\n consola.error(\" - GitHub Copilot service unavailable\")\n consola.error(\n \" - Account type mismatch (try --account-type=individual or --account-type=business)\",\n )\n throw error\n }\n}\n\nexport const cacheVSCodeVersion = async () => {\n const response = await getVSCodeVersion()\n state.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n","import consola from \"consola\"\n\nimport {\n GITHUB_BASE_URL,\n GITHUB_CLIENT_ID,\n standardHeaders,\n} from \"~/lib/api-config\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n): Promise<string> {\n // Interval is in seconds, we need to multiply by 1000 to get milliseconds\n // I'm also adding another second, just to be safe\n const sleepDuration = (deviceCode.interval + 1) * 1000\n consola.debug(`Polling access token with interval of ${sleepDuration}ms`)\n\n while (true) {\n const response = await fetch(\n `${GITHUB_BASE_URL}/login/oauth/access_token`,\n {\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\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error(\"Failed to poll access token:\", await response.text())\n\n continue\n }\n\n const json = await response.json()\n consola.debug(\"Polling access token response:\", json)\n\n const { access_token } = json as AccessTokenResponse\n\n if (access_token) {\n return access_token\n } else {\n await sleep(sleepDuration)\n }\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n","import consola from \"consola\"\nimport fs from \"node:fs/promises\"\n\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n const refreshInterval = (refresh_in - 60) * 1000\n setInterval(async () => {\n consola.debug(\"Refreshing Copilot token\")\n try {\n const { token } = await getCopilotToken()\n state.copilotToken = token\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n throw error\n }\n }, refreshInterval)\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nasync function logUser() {\n const user = await getGitHubUser()\n consola.info(`Logged in as ${user.login}`)\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n","import { GITHUB_API_BASE_URL, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (): Promise<CopilotUsageResponse> => {\n const response = await fetch(`${GITHUB_API_BASE_URL}/copilot_internal/user`, {\n headers: githubHeaders(state),\n })\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n}\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n","import consola from \"consola\"\r\nimport fs from \"node:fs/promises\"\r\n\r\nimport type { ChatCompletionsPayload } from \"~/services/copilot/create-chat-completions\"\r\n\r\nimport { PATHS } from \"./paths\"\r\n\r\nexport interface ReplacementRule {\r\n id: string\r\n name?: string // Human-readable name/description\r\n pattern: string\r\n replacement: string\r\n isRegex: boolean\r\n enabled: boolean\r\n isSystem?: boolean // System rules cannot be deleted by user\r\n}\r\n\r\n// Built-in system replacement that cannot be removed\r\nconst SYSTEM_REPLACEMENTS: Array<ReplacementRule> = [\r\n {\r\n id: \"system-anthropic-billing\",\r\n name: \"Remove Anthropic billing header\",\r\n pattern: String.raw`x-anthropic-billing-header:[^\\n]*\\n?`,\r\n replacement: \"\",\r\n isRegex: true,\r\n enabled: true,\r\n isSystem: true,\r\n },\r\n]\r\n\r\n// User-configured replacements (loaded from disk)\r\nlet userReplacements: Array<ReplacementRule> = []\r\nlet isLoaded = false\r\n\r\n/**\r\n * Load user replacements from disk\r\n */\r\nexport async function loadReplacements(): Promise<void> {\r\n try {\r\n const data = await fs.readFile(PATHS.REPLACEMENTS_CONFIG_PATH)\r\n const parsed = JSON.parse(data.toString()) as Array<ReplacementRule>\r\n userReplacements = parsed.filter((r) => !r.isSystem)\r\n isLoaded = true\r\n consola.debug(`Loaded ${userReplacements.length} user replacement rules`)\r\n } catch {\r\n // File doesn't exist or is invalid - start with empty array\r\n userReplacements = []\r\n isLoaded = true\r\n }\r\n}\r\n\r\n/**\r\n * Save user replacements to disk\r\n */\r\nexport async function saveReplacements(): Promise<void> {\r\n try {\r\n await fs.writeFile(\r\n PATHS.REPLACEMENTS_CONFIG_PATH,\r\n JSON.stringify(userReplacements, null, 2),\r\n \"utf8\",\r\n )\r\n consola.debug(`Saved ${userReplacements.length} user replacement rules`)\r\n } catch (error) {\r\n consola.error(\"Failed to save replacement rules:\", error)\r\n throw error\r\n }\r\n}\r\n\r\n/**\r\n * Ensure replacements are loaded before accessing\r\n */\r\nexport async function ensureLoaded(): Promise<void> {\r\n if (!isLoaded) {\r\n await loadReplacements()\r\n }\r\n}\r\n\r\n/**\r\n * Get all replacement rules (system + user)\r\n */\r\nexport async function getAllReplacements(): Promise<Array<ReplacementRule>> {\r\n await ensureLoaded()\r\n return [...SYSTEM_REPLACEMENTS, ...userReplacements]\r\n}\r\n\r\n/**\r\n * Get only user-configurable replacements\r\n */\r\nexport async function getUserReplacements(): Promise<Array<ReplacementRule>> {\r\n await ensureLoaded()\r\n return userReplacements\r\n}\r\n\r\n/**\r\n * Add a new user replacement rule\r\n */\r\nexport async function addReplacement(\r\n pattern: string,\r\n replacement: string,\r\n options?: { isRegex?: boolean; name?: string },\r\n): Promise<ReplacementRule> {\r\n const { isRegex = false, name } = options ?? {}\r\n await ensureLoaded()\r\n const rule: ReplacementRule = {\r\n id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\r\n name,\r\n pattern,\r\n replacement,\r\n isRegex,\r\n enabled: true,\r\n isSystem: false,\r\n }\r\n userReplacements.push(rule)\r\n await saveReplacements()\r\n consola.info(`Added replacement rule: \"${pattern}\" -> \"${replacement}\"`)\r\n return rule\r\n}\r\n\r\n/**\r\n * Remove a user replacement rule by ID\r\n */\r\nexport async function removeReplacement(id: string): Promise<boolean> {\r\n await ensureLoaded()\r\n const rule = userReplacements.find((r) => r.id === id)\r\n if (!rule) {\r\n return false\r\n }\r\n if (rule.isSystem) {\r\n consola.warn(\"Cannot remove system replacement rule\")\r\n return false\r\n }\r\n userReplacements = userReplacements.filter((r) => r.id !== id)\r\n await saveReplacements()\r\n consola.info(`Removed replacement rule: ${id}`)\r\n return true\r\n}\r\n\r\n/**\r\n * Update an existing user replacement rule\r\n */\r\nexport async function updateReplacement(\r\n id: string,\r\n updates: {\r\n name?: string\r\n pattern?: string\r\n replacement?: string\r\n isRegex?: boolean\r\n enabled?: boolean\r\n },\r\n): Promise<ReplacementRule | null> {\r\n await ensureLoaded()\r\n\r\n const rule = userReplacements.find((r) => r.id === id)\r\n if (!rule) {\r\n return null\r\n }\r\n\r\n if (rule.isSystem) {\r\n consola.warn(\"Cannot update system replacement rule\")\r\n return null\r\n }\r\n\r\n if (updates.name !== undefined) rule.name = updates.name\r\n if (updates.pattern !== undefined) rule.pattern = updates.pattern\r\n if (updates.replacement !== undefined) rule.replacement = updates.replacement\r\n if (updates.isRegex !== undefined) rule.isRegex = updates.isRegex\r\n if (updates.enabled !== undefined) rule.enabled = updates.enabled\r\n\r\n await saveReplacements()\r\n consola.info(`Updated replacement rule: ${rule.name || rule.id}`)\r\n return rule\r\n}\r\n\r\n/**\r\n * Toggle a replacement rule on/off\r\n */\r\nexport async function toggleReplacement(\r\n id: string,\r\n): Promise<ReplacementRule | null> {\r\n await ensureLoaded()\r\n // Check user replacements first\r\n const userRule = userReplacements.find((r) => r.id === id)\r\n if (userRule) {\r\n userRule.enabled = !userRule.enabled\r\n await saveReplacements()\r\n consola.info(\r\n `Toggled replacement rule ${id}: ${userRule.enabled ? \"enabled\" : \"disabled\"}`,\r\n )\r\n return userRule\r\n }\r\n\r\n // System rules cannot be toggled\r\n const systemRule = SYSTEM_REPLACEMENTS.find((r) => r.id === id)\r\n if (systemRule) {\r\n consola.warn(\"Cannot toggle system replacement rule\")\r\n return null\r\n }\r\n\r\n return null\r\n}\r\n\r\n/**\r\n * Clear all user replacements\r\n */\r\nexport async function clearUserReplacements(): Promise<void> {\r\n userReplacements = []\r\n await saveReplacements()\r\n consola.info(\"Cleared all user replacement rules\")\r\n}\r\n\r\n/**\r\n * Apply a single replacement rule to text and return info about whether it matched\r\n */\r\nfunction applyRule(\r\n text: string,\r\n rule: ReplacementRule,\r\n): { result: string; matched: boolean } {\r\n if (!rule.enabled) return { result: text, matched: false }\r\n\r\n if (rule.isRegex) {\r\n try {\r\n const regex = new RegExp(rule.pattern, \"g\")\r\n const result = text.replace(regex, rule.replacement)\r\n return { result, matched: result !== text }\r\n } catch {\r\n consola.warn(`Invalid regex pattern in rule ${rule.id}: ${rule.pattern}`)\r\n return { result: text, matched: false }\r\n }\r\n }\r\n\r\n const result = text.split(rule.pattern).join(rule.replacement)\r\n return { result, matched: result !== text }\r\n}\r\n\r\nexport interface ReplacementResult {\r\n text: string\r\n appliedRules: Array<string>\r\n}\r\n\r\n/**\r\n * Apply all replacement rules to text\r\n */\r\nexport async function applyReplacements(\r\n text: string,\r\n): Promise<ReplacementResult> {\r\n let result = text\r\n const allRules = await getAllReplacements()\r\n const appliedRules: Array<string> = []\r\n\r\n for (const rule of allRules) {\r\n const { result: newResult, matched } = applyRule(result, rule)\r\n if (matched) {\r\n result = newResult\r\n appliedRules.push(rule.name || rule.id)\r\n }\r\n }\r\n\r\n return { text: result, appliedRules }\r\n}\r\n\r\nexport interface PayloadReplacementResult {\r\n payload: ChatCompletionsPayload\r\n appliedRules: Array<string>\r\n}\r\n\r\n/**\r\n * Apply replacements to a chat completions payload\r\n * This modifies message content in place\r\n */\r\nexport async function applyReplacementsToPayload(\r\n payload: ChatCompletionsPayload,\r\n): Promise<PayloadReplacementResult> {\r\n const allAppliedRules: Array<string> = []\r\n\r\n const processedMessages = await Promise.all(\r\n payload.messages.map(async (message) => {\r\n if (typeof message.content === \"string\") {\r\n const { text, appliedRules } = await applyReplacements(message.content)\r\n allAppliedRules.push(...appliedRules)\r\n return { ...message, content: text }\r\n }\r\n\r\n // Handle array content (multimodal)\r\n if (Array.isArray(message.content)) {\r\n return {\r\n ...message,\r\n content: await Promise.all(\r\n message.content.map(async (part) => {\r\n if (\r\n typeof part === \"object\"\r\n && part.type === \"text\"\r\n && part.text\r\n ) {\r\n const { text, appliedRules } = await applyReplacements(\r\n part.text,\r\n )\r\n allAppliedRules.push(...appliedRules)\r\n return { ...part, text }\r\n }\r\n return part\r\n }),\r\n ),\r\n }\r\n }\r\n\r\n return message\r\n }),\r\n )\r\n\r\n // Deduplicate rule names\r\n const uniqueRules = [...new Set(allAppliedRules)]\r\n\r\n return {\r\n payload: { ...payload, messages: processedMessages },\r\n appliedRules: uniqueRules,\r\n }\r\n}\r\n","import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n addReplacement,\n applyReplacements,\n clearUserReplacements,\n getAllReplacements,\n getUserReplacements,\n removeReplacement,\n toggleReplacement,\n updateReplacement,\n type ReplacementRule,\n} from \"~/lib/auto-replace\"\nimport { ensurePaths, PATHS } from \"~/lib/paths\"\n\ntype MenuAction =\n | \"list\"\n | \"add\"\n | \"edit\"\n | \"remove\"\n | \"toggle\"\n | \"test\"\n | \"clear\"\n | \"exit\"\n\nfunction formatRule(rule: ReplacementRule, index: number): string {\n const status = rule.enabled ? \"✓\" : \"✗\"\n const type = rule.isRegex ? \"regex\" : \"string\"\n const system = rule.isSystem ? \" [system]\" : \"\"\n const name = rule.name ? ` \"${rule.name}\"` : \"\"\n const replacement = rule.replacement || \"(empty)\"\n return `${index + 1}. [${status}] (${type})${system}${name} \"${rule.pattern}\" → \"${replacement}\"`\n}\n\nfunction isValidPatternForMatchType(\n pattern: string,\n matchType: \"string\" | \"regex\",\n): boolean {\n if (matchType !== \"regex\") return true\n try {\n new RegExp(pattern)\n return true\n } catch {\n return false\n }\n}\n\nasync function listReplacements(): Promise<void> {\n const all = await getAllReplacements()\n\n if (all.length === 0) {\n consola.info(\"No replacement rules configured.\")\n return\n }\n\n consola.info(\"\\n📋 Replacement Rules:\\n\")\n for (const [i, element] of all.entries()) {\n console.log(formatRule(element, i))\n }\n console.log()\n}\n\nasync function addNewReplacement(): Promise<void> {\n const name = await consola.prompt(\"Name (optional, short description):\", {\n type: \"text\",\n default: \"\",\n })\n\n if (typeof name === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const matchType = await consola.prompt(\"Match type:\", {\n type: \"select\",\n options: [\n { label: \"String (exact match)\", value: \"string\" },\n { label: \"Regex (regular expression)\", value: \"regex\" },\n ],\n })\n\n if (typeof matchType === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const pattern = await consola.prompt(\"Pattern to match:\", {\n type: \"text\",\n })\n\n if (typeof pattern === \"symbol\" || !pattern) {\n consola.info(\"Cancelled.\")\n return\n }\n\n if (!isValidPatternForMatchType(pattern, matchType as \"string\" | \"regex\")) {\n consola.error(`Invalid regex pattern: ${pattern}`)\n return\n }\n\n const replacement = await consola.prompt(\n \"Replacement text (leave empty to delete matches):\",\n {\n type: \"text\",\n default: \"\",\n },\n )\n\n if (typeof replacement === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = await addReplacement(pattern, replacement, {\n isRegex: matchType === \"regex\",\n name: name || undefined,\n })\n\n consola.success(`Added rule: ${rule.name || rule.id}`)\n}\n\nasync function editExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to edit.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to edit:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = userRules.find((r) => r.id === selected)\n if (!rule) {\n consola.error(\"Rule not found.\")\n return\n }\n\n consola.info(`\\nEditing rule: ${rule.name || rule.id}`)\n consola.info(\"Press Enter to keep current value.\\n\")\n\n const name = await consola.prompt(\"Name:\", {\n type: \"text\",\n default: rule.name || \"\",\n })\n\n if (typeof name === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const matchType = await consola.prompt(\"Match type:\", {\n type: \"select\",\n options: [\n { label: \"String (exact match)\", value: \"string\" },\n { label: \"Regex (regular expression)\", value: \"regex\" },\n ],\n initial: rule.isRegex ? \"regex\" : \"string\",\n })\n\n if (typeof matchType === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const pattern = await consola.prompt(\"Pattern to match:\", {\n type: \"text\",\n default: rule.pattern,\n })\n\n if (typeof pattern === \"symbol\" || !pattern) {\n consola.info(\"Cancelled.\")\n return\n }\n\n if (!isValidPatternForMatchType(pattern, matchType as \"string\" | \"regex\")) {\n consola.error(`Invalid regex pattern: ${pattern}`)\n return\n }\n\n const replacement = await consola.prompt(\"Replacement text:\", {\n type: \"text\",\n default: rule.replacement,\n })\n\n if (typeof replacement === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const updated = await updateReplacement(selected, {\n name: name || undefined,\n pattern,\n replacement,\n isRegex: matchType === \"regex\",\n })\n\n if (updated) {\n consola.success(`Updated rule: ${updated.name || updated.id}`)\n } else {\n consola.error(\"Failed to update rule.\")\n }\n}\n\nasync function removeExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to remove.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to remove:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const success = await removeReplacement(selected)\n if (success) {\n consola.success(\"Rule removed.\")\n } else {\n consola.error(\"Failed to remove rule.\")\n }\n}\n\nasync function toggleExistingReplacement(): Promise<void> {\n const userRules = await getUserReplacements()\n\n if (userRules.length === 0) {\n consola.info(\"No user rules to toggle.\")\n return\n }\n\n const options = userRules.map((rule, i) => ({\n label: formatRule(rule, i),\n value: rule.id,\n }))\n\n const selected = await consola.prompt(\"Select rule to toggle:\", {\n type: \"select\",\n options,\n })\n\n if (typeof selected === \"symbol\") {\n consola.info(\"Cancelled.\")\n return\n }\n\n const rule = await toggleReplacement(selected)\n if (rule) {\n consola.success(`Rule ${rule.enabled ? \"enabled\" : \"disabled\"}.`)\n } else {\n consola.error(\"Failed to toggle rule.\")\n }\n}\n\nasync function testReplacements(): Promise<void> {\n const testText = await consola.prompt(\"Enter text to test replacements:\", {\n type: \"text\",\n })\n\n if (typeof testText === \"symbol\" || !testText) {\n consola.info(\"Cancelled.\")\n return\n }\n\n const { text: result } = await applyReplacements(testText)\n\n consola.info(\"\\n📝 Original:\")\n console.log(testText)\n consola.info(\"\\n✨ After replacements:\")\n console.log(result)\n console.log()\n}\n\nasync function clearAllReplacements(): Promise<void> {\n const confirm = await consola.prompt(\n \"Are you sure you want to clear all user replacements?\",\n {\n type: \"confirm\",\n initial: false,\n },\n )\n\n if (confirm) {\n await clearUserReplacements()\n consola.success(\"All user replacements cleared.\")\n } else {\n consola.info(\"Cancelled.\")\n }\n}\n\nasync function mainMenu(): Promise<void> {\n consola.info(`\\n🔧 Copilot API - Replacement Configuration`)\n consola.info(`Config file: ${PATHS.REPLACEMENTS_CONFIG_PATH}\\n`)\n\n let running = true\n\n while (running) {\n const action = await consola.prompt(\"What would you like to do?\", {\n type: \"select\",\n options: [\n { label: \"📋 List all rules\", value: \"list\" as MenuAction },\n { label: \"➕ Add new rule\", value: \"add\" as MenuAction },\n { label: \"✏️ Edit rule\", value: \"edit\" as MenuAction },\n { label: \"➖ Remove rule\", value: \"remove\" as MenuAction },\n { label: \"🔄 Toggle rule on/off\", value: \"toggle\" as MenuAction },\n { label: \"🧪 Test replacements\", value: \"test\" as MenuAction },\n { label: \"🗑️ Clear all user rules\", value: \"clear\" as MenuAction },\n { label: \"🚪 Exit\", value: \"exit\" as MenuAction },\n ],\n })\n\n if (typeof action === \"symbol\") {\n break\n }\n\n switch (action) {\n case \"list\": {\n await listReplacements()\n break\n }\n case \"add\": {\n await addNewReplacement()\n break\n }\n case \"edit\": {\n await editExistingReplacement()\n break\n }\n case \"remove\": {\n await removeExistingReplacement()\n break\n }\n case \"toggle\": {\n await toggleExistingReplacement()\n break\n }\n case \"test\": {\n await testReplacements()\n break\n }\n case \"clear\": {\n await clearAllReplacements()\n break\n }\n case \"exit\": {\n running = false\n break\n }\n default: {\n break\n }\n }\n }\n\n consola.info(\"Goodbye! 👋\")\n}\n\nexport const config = defineCommand({\n meta: {\n name: \"config\",\n description: \"Configure replacement rules interactively\",\n },\n run: async () => {\n await ensurePaths()\n await mainMenu()\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport os from \"node:os\"\n\nimport { PATHS } from \"./lib/paths\"\n\ninterface DebugInfo {\n version: string\n runtime: {\n name: string\n version: string\n platform: string\n arch: string\n }\n paths: {\n APP_DIR: string\n GITHUB_TOKEN_PATH: string\n }\n tokenExists: boolean\n}\n\ninterface RunDebugOptions {\n json: boolean\n}\n\nasync function getPackageVersion(): Promise<string> {\n try {\n const packageJsonPath = new URL(\"../package.json\", import.meta.url).pathname\n // @ts-expect-error https://github.com/sindresorhus/eslint-plugin-unicorn/blob/v59.0.1/docs/rules/prefer-json-parse-buffer.md\n // JSON.parse() can actually parse buffers\n const packageJson = JSON.parse(await fs.readFile(packageJsonPath)) as {\n version: string\n }\n return packageJson.version\n } catch {\n return \"unknown\"\n }\n}\n\nfunction getRuntimeInfo() {\n const isBun = typeof Bun !== \"undefined\"\n\n return {\n name: isBun ? \"bun\" : \"node\",\n version: isBun ? Bun.version : process.version.slice(1),\n platform: os.platform(),\n arch: os.arch(),\n }\n}\n\nasync function checkTokenExists(): Promise<boolean> {\n try {\n const stats = await fs.stat(PATHS.GITHUB_TOKEN_PATH)\n if (!stats.isFile()) return false\n\n const content = await fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n return content.trim().length > 0\n } catch {\n return false\n }\n}\n\nasync function getDebugInfo(): Promise<DebugInfo> {\n const [version, tokenExists] = await Promise.all([\n getPackageVersion(),\n checkTokenExists(),\n ])\n\n return {\n version,\n runtime: getRuntimeInfo(),\n paths: {\n APP_DIR: PATHS.APP_DIR,\n GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,\n },\n tokenExists,\n }\n}\n\nfunction printDebugInfoPlain(info: DebugInfo): void {\n consola.info(`copilot-api debug\n\nVersion: ${info.version}\nRuntime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})\n\nPaths:\n- APP_DIR: ${info.paths.APP_DIR}\n- GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}\n\nToken exists: ${info.tokenExists ? \"Yes\" : \"No\"}`)\n}\n\nfunction printDebugInfoJson(info: DebugInfo): void {\n console.log(JSON.stringify(info, null, 2))\n}\n\nexport async function runDebug(options: RunDebugOptions): Promise<void> {\n const debugInfo = await getDebugInfo()\n\n if (options.json) {\n printDebugInfoJson(debugInfo)\n } else {\n printDebugInfoPlain(debugInfo)\n }\n}\n\nexport const debug = defineCommand({\n meta: {\n name: \"debug\",\n description: \"Print debug information about the application\",\n },\n args: {\n json: {\n type: \"boolean\",\n default: false,\n description: \"Output debug information as JSON\",\n },\n },\n run({ args }) {\n return runDebug({\n json: args.json,\n })\n },\n})\n","import consola from \"consola\"\nimport fs from \"node:fs\"\n\nimport { PATHS } from \"./paths\"\n\nexport interface AppConfig {\n auth?: {\n apiKeys?: Array<string>\n }\n extraPrompts?: Record<string, string>\n smallModel?: string\n modelReasoningEfforts?: Record<\n string,\n \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\"\n >\n useFunctionApplyPatch?: boolean\n compactUseSmallModel?: boolean\n}\n\nconst gpt5ExplorationPrompt = `## Exploration and reading files\n- **Think first.** Before any tool call, decide ALL files/resources you will need.\n- **Batch everything.** If you need multiple files (even from different places), read them together.\n- **multi_tool_use.parallel** Use multi_tool_use.parallel to parallelize tool calls and only this.\n- **Only make sequential calls if you truly cannot know the next file without seeing a result first.**\n- **Workflow:** (a) plan all needed reads → (b) issue one parallel batch → (c) analyze results → (d) repeat if new, unpredictable reads arise.`\n\nconst gpt5CommentaryPrompt = `# Working with the user\n\nYou interact with the user through a terminal. You have 2 ways of communicating with the users:\n- Share intermediary updates in \\`commentary\\` channel.\n- After you have completed all your work, send a message to the \\`final\\` channel.\n\n## Intermediary updates\n\n- Intermediary updates go to the \\`commentary\\` channel.\n- User updates are short updates while you are working, they are NOT final answers.\n- You use 1-2 sentence user updates to communicate progress and new information to the user as you are doing work.\n- Do not begin responses with conversational interjections or meta commentary. Avoid openers such as acknowledgements (\"Done —\", \"Got it\", \"Great question, \") or framing phrases.\n- You provide user updates frequently, every 20s.\n- Before exploring or doing substantial work, you start with a user update acknowledging the request and explaining your first step. You should include your understanding of the user request and explain what you will do. Avoid commenting on the request or using starters such as \"Got it -\" or \"Understood -\" etc.\n- When exploring, e.g. searching, reading files, you provide user updates as you go, every 20s, explaining what context you are gathering and what you've learned. Vary your sentence structure when providing these updates to avoid sounding repetitive - in particular, don't start each sentence the same way.\n- After you have sufficient context, and the work is substantial, you provide a longer plan (this is the only user update that may be longer than 2 sentences and can contain formatting).\n- Before performing file edits of any kind, you provide updates explaining what edits you are making.\n- As you are thinking, you very frequently provide updates even if not taking any actions, informing the user of your progress. You interrupt your thinking and send multiple updates in a row if thinking for more than 100 words.\n- Tone of your updates MUST match your personality.`\n\nconst defaultConfig: AppConfig = {\n auth: {\n apiKeys: [],\n },\n extraPrompts: {\n \"gpt-5-mini\": gpt5ExplorationPrompt,\n \"gpt-5.1-codex-max\": gpt5ExplorationPrompt,\n \"gpt-5.3-codex\": gpt5CommentaryPrompt,\n },\n smallModel: \"gpt-5-mini\",\n modelReasoningEfforts: {\n \"gpt-5-mini\": \"low\",\n },\n useFunctionApplyPatch: true,\n compactUseSmallModel: true,\n}\n\nlet cachedConfig: AppConfig | null = null\n\nfunction ensureConfigFile(): void {\n try {\n fs.accessSync(PATHS.CONFIG_PATH, fs.constants.R_OK | fs.constants.W_OK)\n } catch {\n fs.mkdirSync(PATHS.APP_DIR, { recursive: true })\n fs.writeFileSync(\n PATHS.CONFIG_PATH,\n `${JSON.stringify(defaultConfig, null, 2)}\\n`,\n \"utf8\",\n )\n try {\n fs.chmodSync(PATHS.CONFIG_PATH, 0o600)\n } catch {\n return\n }\n }\n}\n\nfunction readConfigFromDisk(): AppConfig {\n ensureConfigFile()\n try {\n const raw = fs.readFileSync(PATHS.CONFIG_PATH, \"utf8\")\n if (!raw.trim()) {\n fs.writeFileSync(\n PATHS.CONFIG_PATH,\n `${JSON.stringify(defaultConfig, null, 2)}\\n`,\n \"utf8\",\n )\n return defaultConfig\n }\n return JSON.parse(raw) as AppConfig\n } catch (error) {\n consola.error(\"Failed to read config file, using default config\", error)\n return defaultConfig\n }\n}\n\nfunction mergeDefaultExtraPrompts(config: AppConfig): {\n mergedConfig: AppConfig\n changed: boolean\n} {\n const extraPrompts = config.extraPrompts ?? {}\n const defaultExtraPrompts = defaultConfig.extraPrompts ?? {}\n\n const missingExtraPromptModels = Object.keys(defaultExtraPrompts).filter(\n (model) => !Object.hasOwn(extraPrompts, model),\n )\n\n if (missingExtraPromptModels.length === 0) {\n return { mergedConfig: config, changed: false }\n }\n\n return {\n mergedConfig: {\n ...config,\n extraPrompts: {\n ...defaultExtraPrompts,\n ...extraPrompts,\n },\n },\n changed: true,\n }\n}\n\nexport function mergeConfigWithDefaults(): AppConfig {\n const config = readConfigFromDisk()\n const { mergedConfig, changed } = mergeDefaultExtraPrompts(config)\n\n if (changed) {\n try {\n fs.writeFileSync(\n PATHS.CONFIG_PATH,\n `${JSON.stringify(mergedConfig, null, 2)}\\n`,\n \"utf8\",\n )\n } catch (writeError) {\n consola.warn(\n \"Failed to write merged extraPrompts to config file\",\n writeError,\n )\n }\n }\n\n cachedConfig = mergedConfig\n return mergedConfig\n}\n\nexport function getConfig(): AppConfig {\n cachedConfig ??= readConfigFromDisk()\n return cachedConfig\n}\n\nexport function getExtraPromptForModel(model: string): string {\n const config = getConfig()\n return config.extraPrompts?.[model] ?? \"\"\n}\n\nexport function getSmallModel(): string {\n const config = getConfig()\n return config.smallModel ?? \"gpt-5-mini\"\n}\n\nexport function getReasoningEffortForModel(\n model: string,\n override?: \"low\" | \"medium\" | \"high\" | \"xhigh\",\n): \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" {\n if (override) return override\n const config = getConfig()\n return config.modelReasoningEfforts?.[model] ?? \"high\"\n}\n\nexport function shouldCompactUseSmallModel(): boolean {\n const config = getConfig()\n return config.compactUseSmallModel ?? true\n}\n","import type { Model } from \"~/services/copilot/get-models\"\n\nexport type ReasoningEffort = \"low\" | \"medium\" | \"high\" | \"xhigh\"\n\ninterface ModelReasoningConfig {\n supportedEfforts: Array<ReasoningEffort>\n defaultEffort: ReasoningEffort\n}\n\n/**\n * Hardcoded reasoning config per model, derived from Copilot CLI v0.0.414.\n * Models not in this map do not support per-request reasoning effort control.\n */\nconst MODEL_REASONING_CONFIG: Partial<Record<string, ModelReasoningConfig>> = {\n \"claude-sonnet-4.6\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"claude-opus-4.6\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"high\",\n },\n \"claude-opus-4.6-fast\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"high\",\n },\n \"claude-opus-4.6-1m\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"high\",\n },\n \"gpt-5.3-codex\": {\n supportedEfforts: [\"low\", \"medium\", \"high\", \"xhigh\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5.2-codex\": {\n supportedEfforts: [\"low\", \"medium\", \"high\", \"xhigh\"],\n defaultEffort: \"high\",\n },\n \"gpt-5.2\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5.1-codex\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5.1-codex-max\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5.1\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5.1-codex-mini\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n \"gpt-5-mini\": {\n supportedEfforts: [\"low\", \"medium\", \"high\"],\n defaultEffort: \"medium\",\n },\n}\n\nconst VALID_EFFORTS = new Set<string>([\"low\", \"medium\", \"high\", \"xhigh\"])\n\nexport interface ParsedModel {\n baseModel: string\n reasoningEffort?: ReasoningEffort\n}\n\n/**\n * Parse a model string that may contain a reasoning effort suffix.\n * Format: \"model-name:effort\" (e.g. \"claude-sonnet-4.6:high\")\n *\n * If the suffix is not a valid effort level or the model doesn't support it,\n * the suffix is ignored and the full string is treated as the model name.\n */\nexport function parseModelSuffix(model: string): ParsedModel {\n const colonIndex = model.lastIndexOf(\":\")\n if (colonIndex === -1) {\n return { baseModel: model }\n }\n\n const potentialBase = model.slice(0, colonIndex)\n const potentialEffort = model.slice(colonIndex + 1)\n\n if (!VALID_EFFORTS.has(potentialEffort)) {\n return { baseModel: model }\n }\n\n const effort = potentialEffort as ReasoningEffort\n const config = MODEL_REASONING_CONFIG[potentialBase]\n\n if (!config) {\n // Model not in our reasoning config — treat suffix as part of model name\n return { baseModel: model }\n }\n\n if (!config.supportedEfforts.includes(effort)) {\n // Effort not supported for this model — use default for that model\n return { baseModel: potentialBase, reasoningEffort: config.defaultEffort }\n }\n\n return { baseModel: potentialBase, reasoningEffort: effort }\n}\n\n/**\n * Get the reasoning config for a model, if it supports reasoning effort.\n */\nexport function getModelReasoningConfig(\n model: string,\n): ModelReasoningConfig | undefined {\n return MODEL_REASONING_CONFIG[model]\n}\n\ninterface VirtualModel {\n id: string\n object: string\n type: string\n created: number\n created_at: string\n owned_by: string\n display_name: string\n}\n\n/**\n * Generate virtual model entries for models that support reasoning effort.\n * Each supported effort level gets its own virtual model entry.\n */\nexport function generateVirtualModels(\n models: Array<Model>,\n): Array<VirtualModel> {\n const virtualModels: Array<VirtualModel> = []\n\n for (const model of models) {\n const config = MODEL_REASONING_CONFIG[model.id]\n if (!config) continue\n\n for (const effort of config.supportedEfforts) {\n virtualModels.push({\n id: `${model.id}:${effort}`,\n object: \"model\",\n type: \"model\",\n created: 0,\n created_at: new Date(0).toISOString(),\n owned_by: model.vendor,\n display_name: `${model.name} (${effort} thinking)`,\n })\n }\n }\n\n return virtualModels\n}\n","import consola from \"consola\"\nimport { getProxyForUrl } from \"proxy-from-env\"\nimport { Agent, ProxyAgent, setGlobalDispatcher, type Dispatcher } from \"undici\"\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== \"undefined\") return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin =\n typeof options.origin === \"string\" ?\n new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n } catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n } catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug(\"HTTP proxy configured from environment (per-URL)\")\n } catch (err) {\n consola.debug(\"Proxy setup skipped:\", err)\n }\n}\n","import { execSync } from \"node:child_process\"\nimport process from \"node:process\"\n\ntype ShellName = \"bash\" | \"zsh\" | \"fish\" | \"powershell\" | \"cmd\" | \"sh\"\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === \"win32\") {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: \"pipe\" }).toString()\n\n if (parentProcess.toLowerCase().includes(\"powershell.exe\")) {\n return \"powershell\"\n }\n } catch {\n return \"cmd\"\n }\n\n return \"cmd\"\n } else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith(\"zsh\")) return \"zsh\"\n if (shellPath.endsWith(\"fish\")) return \"fish\"\n if (shellPath.endsWith(\"bash\")) return \"bash\"\n }\n\n return \"sh\"\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = \"\",\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case \"powershell\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join(\"; \")\n break\n }\n case \"cmd\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(\" & \")\n break\n }\n case \"fish\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join(\"; \")\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \")\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : \"\"\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === \"cmd\" ? \" & \" : \" && \"\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","import type { Context, MiddlewareHandler } from \"hono\"\r\n\r\nimport consola from \"consola\"\r\n\r\nimport { getConfig } from \"./config\"\r\n\r\ninterface AuthMiddlewareOptions {\r\n getApiKeys?: () => Array<string>\r\n allowUnauthenticatedPaths?: Array<string>\r\n allowOptionsBypass?: boolean\r\n}\r\n\r\nexport function normalizeApiKeys(apiKeys: unknown): Array<string> {\r\n if (!Array.isArray(apiKeys)) {\r\n if (apiKeys !== undefined) {\r\n consola.warn(\"Invalid auth.apiKeys config. Expected an array of strings.\")\r\n }\r\n return []\r\n }\r\n\r\n const normalizedKeys = apiKeys\r\n .filter((key): key is string => typeof key === \"string\")\r\n .map((key) => key.trim())\r\n .filter((key) => key.length > 0)\r\n\r\n if (normalizedKeys.length !== apiKeys.length) {\r\n consola.warn(\r\n \"Invalid auth.apiKeys entries found. Only non-empty strings are allowed.\",\r\n )\r\n }\r\n\r\n return [...new Set(normalizedKeys)]\r\n}\r\n\r\nexport function getConfiguredApiKeys(): Array<string> {\r\n const config = getConfig()\r\n return normalizeApiKeys(config.auth?.apiKeys)\r\n}\r\n\r\nexport function extractRequestApiKey(c: Context): string | null {\r\n const xApiKey = c.req.header(\"x-api-key\")?.trim()\r\n if (xApiKey) {\r\n return xApiKey\r\n }\r\n\r\n const authorization = c.req.header(\"authorization\")\r\n if (!authorization) {\r\n return null\r\n }\r\n\r\n const [scheme, ...rest] = authorization.trim().split(/\\s+/)\r\n if (scheme.toLowerCase() !== \"bearer\") {\r\n return null\r\n }\r\n\r\n const bearerToken = rest.join(\" \").trim()\r\n return bearerToken || null\r\n}\r\n\r\nfunction createUnauthorizedResponse(c: Context): Response {\r\n c.header(\"WWW-Authenticate\", 'Bearer realm=\"copilot-api\"')\r\n return c.json(\r\n {\r\n error: {\r\n message: \"Unauthorized\",\r\n type: \"authentication_error\",\r\n },\r\n },\r\n 401,\r\n )\r\n}\r\n\r\nexport function createAuthMiddleware(\r\n options: AuthMiddlewareOptions = {},\r\n): MiddlewareHandler {\r\n const getApiKeys = options.getApiKeys ?? getConfiguredApiKeys\r\n const allowUnauthenticatedPaths = options.allowUnauthenticatedPaths ?? [\"/\"]\r\n const allowOptionsBypass = options.allowOptionsBypass ?? true\r\n\r\n return async (c, next) => {\r\n if (allowOptionsBypass && c.req.method === \"OPTIONS\") {\r\n return next()\r\n }\r\n\r\n if (allowUnauthenticatedPaths.includes(c.req.path)) {\r\n return next()\r\n }\r\n\r\n const apiKeys = getApiKeys()\r\n if (apiKeys.length === 0) {\r\n return next()\r\n }\r\n\r\n const requestApiKey = extractRequestApiKey(c)\r\n if (!requestApiKey || !apiKeys.includes(requestApiKey)) {\r\n return createUnauthorizedResponse(c)\r\n }\r\n\r\n return next()\r\n }\r\n}\r\n","import type { Context, Next } from \"hono\"\n\nimport { extractRequestApiKey } from \"./request-auth\"\nimport { state } from \"./state\"\n\n/**\n * API key guard middleware that silently drops connections when the API key\n * doesn't match the expected value. Unauthorized requests get NO response.\n *\n * Only active when state.apiKeyAuth is set (via --api-key-auth CLI flag).\n */\nexport async function apiKeyGuard(c: Context, next: Next): Promise<void> {\n if (!state.apiKeyAuth) {\n await next()\n return\n }\n\n const requestApiKey = extractRequestApiKey(c)\n\n if (requestApiKey === state.apiKeyAuth) {\n await next()\n return\n }\n\n // Silent drop: never resolves, client gets no response\n await new Promise(() => {})\n}\n","import type { Context, Next } from \"hono\"\n\nimport { state } from \"./state\"\n\n/**\n * Request context stored for logging on response\n */\nexport interface RequestContext {\n startTime: number\n requestedModel?: string\n model?: string\n inputLength?: number\n inputTokens?: number\n outputTokens?: number\n provider?: string\n replacements?: Array<string>\n reasoningEffort?: string\n}\n\nconst REQUEST_CONTEXT_KEY = \"requestContext\"\n\n// ANSI color codes\nexport const colors = {\n reset: \"\\x1b[0m\",\n dim: \"\\x1b[2m\",\n bold: \"\\x1b[1m\",\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n magenta: \"\\x1b[35m\",\n blue: \"\\x1b[34m\",\n white: \"\\x1b[37m\",\n gray: \"\\x1b[90m\",\n}\n\n/**\n * Get the current time formatted as HH:MM:SS\n */\nfunction getTimeString(): string {\n return new Date().toLocaleTimeString(\"en-US\", {\n hour12: false,\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n })\n}\n\n/**\n * Get status color based on HTTP status code\n */\nfunction getStatusColor(status: number): string {\n if (status >= 500) return colors.red\n if (status >= 400) return colors.yellow\n if (status >= 300) return colors.cyan\n return colors.green\n}\n\n/**\n * Sanitize request body by omitting large message/prompt arrays\n */\nfunction sanitizeRequestBody(\n parsed: Record<string, unknown>,\n): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(parsed)) {\n sanitized[key] =\n key === \"messages\" || key === \"prompt\" ?\n `[${Array.isArray(value) ? value.length : 1} items omitted]`\n : value\n }\n return sanitized\n}\n\n/**\n * Log raw HTTP request details (for debug mode)\n */\nasync function logRawRequest(c: Context): Promise<void> {\n const method = c.req.method\n const url = c.req.url\n const headers = Object.fromEntries(c.req.raw.headers.entries())\n\n const lines: Array<string> = []\n lines.push(\n `${colors.magenta}${colors.bold}[DEBUG] Incoming Request${colors.reset}`,\n `${colors.cyan}${method}${colors.reset} ${url}`,\n `${colors.dim}Headers:${colors.reset}`,\n )\n\n for (const [key, value] of Object.entries(headers)) {\n // Mask authorization headers\n const displayValue =\n key.toLowerCase().includes(\"authorization\") ?\n `${value.slice(0, 20)}...`\n : value\n lines.push(` ${colors.gray}${key}:${colors.reset} ${displayValue}`)\n }\n\n // Try to get body info without consuming it\n if (method !== \"GET\" && method !== \"HEAD\") {\n try {\n const clonedRequest = c.req.raw.clone()\n const body = await clonedRequest.text()\n if (body) {\n // Parse JSON to extract model, omit messages/prompt\n try {\n const parsed = JSON.parse(body) as Record<string, unknown>\n const sanitized = sanitizeRequestBody(parsed)\n\n lines.push(\n `${colors.dim}Body (sanitized):${colors.reset}`,\n ` ${JSON.stringify(sanitized, null, 2).split(\"\\n\").join(\"\\n \")}`,\n )\n } catch {\n // Not JSON, show length\n lines.push(`${colors.dim}Body:${colors.reset} [${body.length} bytes]`)\n }\n }\n } catch {\n lines.push(`${colors.dim}Body:${colors.reset} [unable to read]`)\n }\n }\n\n lines.push(`${colors.dim}${\"─\".repeat(60)}${colors.reset}`)\n console.log(lines.join(\"\\n\"))\n}\n\n/**\n * Set request context for logging\n */\nexport function setRequestContext(\n c: Context,\n ctx: Partial<Omit<RequestContext, \"startTime\">>,\n): void {\n const existing = c.get(REQUEST_CONTEXT_KEY) as RequestContext | undefined\n if (existing) {\n c.set(REQUEST_CONTEXT_KEY, { ...existing, ...ctx })\n }\n}\n\n/**\n * Format the input size for display\n */\nfunction formatInputSize(bytes: number): string {\n return bytes >= 1024 ? `${(bytes / 1024).toFixed(1)}KB` : `${bytes}B`\n}\n\n/**\n * Build the model routing log line\n */\nfunction buildModelLine(ctx: RequestContext): string {\n const parts: Array<string> = []\n\n // Model name(s)\n if (ctx.requestedModel && ctx.requestedModel !== ctx.model) {\n parts.push(\n `${colors.gray}${ctx.requestedModel}${colors.reset} ${colors.dim}→${colors.reset} ${colors.white}${ctx.model}${colors.reset}`,\n )\n } else {\n parts.push(`${colors.white}${ctx.model}${colors.reset}`)\n }\n\n // API type from provider\n if (ctx.provider) {\n parts.push(\n `${colors.dim}via${colors.reset} ${colors.magenta}${ctx.provider}${colors.reset}`,\n )\n }\n\n // Input size\n if (ctx.inputLength !== undefined) {\n parts.push(\n `${colors.dim}·${colors.reset} ${colors.yellow}${formatInputSize(ctx.inputLength)}${colors.reset}`,\n )\n }\n\n return ` ${parts.join(\" \")}`\n}\n\n/**\n * Build the modifications log line (effort, replacements, tokens)\n */\nfunction buildModificationsLine(ctx: RequestContext): string | undefined {\n const modParts: Array<string> = []\n\n if (ctx.reasoningEffort) {\n modParts.push(`${colors.blue}effort=${ctx.reasoningEffort}${colors.reset}`)\n }\n\n if (ctx.replacements && ctx.replacements.length > 0) {\n modParts.push(\n `${colors.green}replace: ${ctx.replacements.join(\", \")}${colors.reset}`,\n )\n }\n\n if (ctx.inputTokens !== undefined) {\n modParts.push(\n `${colors.yellow}${ctx.inputTokens.toLocaleString()} tokens${colors.reset}`,\n )\n }\n\n if (modParts.length === 0) return undefined\n return ` ${modParts.join(` ${colors.dim}·${colors.reset} `)}`\n}\n\n/**\n * Custom request logger middleware\n */\nexport async function requestLogger(c: Context, next: Next): Promise<void> {\n // Log raw request in debug mode\n if (state.debug) {\n await logRawRequest(c)\n }\n\n const startTime = Date.now()\n const method = c.req.method\n const path =\n c.req.path\n + (c.req.raw.url.includes(\"?\") ? \"?\" + c.req.raw.url.split(\"?\")[1] : \"\")\n\n // Initialize request context\n const contentLength = c.req.header(\"content-length\")\n c.set(REQUEST_CONTEXT_KEY, {\n startTime,\n inputLength: contentLength ? Number(contentLength) : undefined,\n } as RequestContext)\n\n await next()\n\n // Get context that may have been set during request handling\n const ctx = c.get(REQUEST_CONTEXT_KEY) as RequestContext | undefined\n const duration = ((Date.now() - startTime) / 1000).toFixed(1)\n const status = c.res.status\n const statusColor = getStatusColor(status)\n\n // Build the log block\n const lines: Array<string> = []\n\n // Separator\n lines.push(`${colors.dim}${\"─\".repeat(60)}${colors.reset}`)\n\n // Main request line: method, path, status, duration\n const statusBadge = `${statusColor}${status}${colors.reset}`\n const durationStr = `${colors.cyan}${duration}s${colors.reset}`\n lines.push(\n `${colors.bold}${method}${colors.reset} ${path} ${statusBadge} ${durationStr}`,\n )\n\n // Model routing line\n if (ctx?.model) {\n lines.push(buildModelLine(ctx))\n }\n\n // Applied modifications line\n if (ctx) {\n const modsLine = buildModificationsLine(ctx)\n if (modsLine) lines.push(modsLine)\n }\n\n // Timestamp\n lines.push(` ${colors.dim}${getTimeString()}${colors.reset}`)\n\n // Print all lines\n console.log(lines.join(\"\\n\"))\n}\n\n/**\n * Log token usage (for streaming responses where tokens are known after stream completes)\n */\nexport function logTokenUsage(inputTokens: number, outputTokens: number): void {\n const parts: Array<string> = []\n parts.push(\n ` ${colors.gray}Tokens:${colors.reset} ${colors.yellow}${inputTokens.toLocaleString()} in${colors.reset} ${colors.gray}/${colors.reset} ${colors.green}${outputTokens.toLocaleString()} out${colors.reset}`,\n )\n console.log(parts.join(\"\"))\n}\n","import consola from \"consola\"\n\nimport { HTTPError } from \"./error\"\n\nexport const awaitApproval = async () => {\n const response = await consola.prompt(`Accept incoming request?`, {\n type: \"confirm\",\n })\n\n if (!response)\n throw new HTTPError(\n \"Request rejected\",\n Response.json({ message: \"Request rejected\" }, { status: 403 }),\n )\n}\n","/**\n * Normalize a model name by converting dashes to dots between numbers\n * and converting Anthropic's [1m] suffix to Copilot's -1m suffix.\n * e.g., \"claude-opus-4-5\" -> \"claude-opus-4.5\"\n * \"claude-opus-4-6[1m]\" -> \"claude-opus-4.6-1m\"\n * \"gpt-4-1\" -> \"gpt-4.1\"\n * \"gpt-5-1-codex\" -> \"gpt-5.1-codex\"\n */\nexport function normalizeModelName(model: string): string {\n // Convert Anthropic's [1m] context suffix to Copilot's -1m format\n let normalized = model.replace(\"[1m]\", \"-1m\")\n\n // Strip Anthropic date suffixes (e.g., \"-20251001\") — Copilot doesn't support them\n normalized = normalized.replace(/-\\d{8}$/, \"\")\n\n // Replace dash with dot only between two digits: \"4-5\" -> \"4.5\"\n normalized = normalized.replaceAll(/(\\d)-(\\d)/g, (_, p1, p2) => `${p1}.${p2}`)\n\n return normalized\n}\n","import consola from \"consola\"\n\nimport type { State } from \"./state\"\n\nimport { HTTPError } from \"./error\"\nimport { sleep } from \"./utils\"\n\nexport async function checkRateLimit(state: State) {\n if (state.rateLimitSeconds === undefined) return\n\n const now = Date.now()\n\n if (!state.lastRequestTimestamp) {\n state.lastRequestTimestamp = now\n return\n }\n\n const elapsedSeconds = (now - state.lastRequestTimestamp) / 1000\n\n if (elapsedSeconds > state.rateLimitSeconds) {\n state.lastRequestTimestamp = now\n return\n }\n\n const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds)\n\n if (!state.rateLimitWait) {\n consola.warn(\n `Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`,\n )\n throw new HTTPError(\n \"Rate limit exceeded\",\n Response.json({ message: \"Rate limit exceeded\" }, { status: 429 }),\n )\n }\n\n const waitTimeMs = waitTimeSeconds * 1000\n consola.warn(\n `Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`,\n )\n await sleep(waitTimeMs)\n // eslint-disable-next-line require-atomic-updates\n state.lastRequestTimestamp = now\n consola.info(\"Rate limit wait completed, proceeding with request\")\n return\n}\n","import type {\n ChatCompletionsPayload,\n ContentPart,\n Message,\n Tool,\n ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\nimport type { Model } from \"~/services/copilot/get-models\"\n\n// Encoder type mapping\nconst ENCODING_MAP = {\n o200k_base: () => import(\"gpt-tokenizer/encoding/o200k_base\"),\n cl100k_base: () => import(\"gpt-tokenizer/encoding/cl100k_base\"),\n p50k_base: () => import(\"gpt-tokenizer/encoding/p50k_base\"),\n p50k_edit: () => import(\"gpt-tokenizer/encoding/p50k_edit\"),\n r50k_base: () => import(\"gpt-tokenizer/encoding/r50k_base\"),\n} as const\n\ntype SupportedEncoding = keyof typeof ENCODING_MAP\n\n// Define encoder interface\ninterface Encoder {\n encode: (text: string) => Array<number>\n}\n\n// Cache loaded encoders to avoid repeated imports\nconst encodingCache = new Map<string, Encoder>()\n\n/**\n * Calculate tokens for tool calls\n */\nconst calculateToolCallsTokens = (\n toolCalls: Array<ToolCall>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = 0\n for (const toolCall of toolCalls) {\n tokens += constants.funcInit\n tokens += encoder.encode(JSON.stringify(toolCall)).length\n }\n tokens += constants.funcEnd\n return tokens\n}\n\n/**\n * Calculate tokens for content parts\n */\nconst calculateContentPartsTokens = (\n contentParts: Array<ContentPart>,\n encoder: Encoder,\n): number => {\n let tokens = 0\n for (const part of contentParts) {\n if (part.type === \"image_url\") {\n tokens += encoder.encode(part.image_url.url).length + 85\n } else if (part.text) {\n tokens += encoder.encode(part.text).length\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens for a single message\n */\nconst calculateMessageTokens = (\n message: Message,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n const tokensPerMessage = 3\n const tokensPerName = 1\n let tokens = tokensPerMessage\n for (const [key, value] of Object.entries(message)) {\n if (typeof value === \"string\") {\n tokens += encoder.encode(value).length\n }\n if (key === \"name\") {\n tokens += tokensPerName\n }\n if (key === \"tool_calls\") {\n tokens += calculateToolCallsTokens(\n value as Array<ToolCall>,\n encoder,\n constants,\n )\n }\n if (key === \"content\" && Array.isArray(value)) {\n tokens += calculateContentPartsTokens(\n value as Array<ContentPart>,\n encoder,\n )\n }\n }\n return tokens\n}\n\n/**\n * Calculate tokens using custom algorithm\n */\nconst calculateTokens = (\n messages: Array<Message>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (messages.length === 0) {\n return 0\n }\n let numTokens = 0\n for (const message of messages) {\n numTokens += calculateMessageTokens(message, encoder, constants)\n }\n // every reply is primed with <|start|>assistant<|message|>\n numTokens += 3\n return numTokens\n}\n\n/**\n * Get the corresponding encoder module based on encoding type\n */\nconst getEncodeChatFunction = async (encoding: string): Promise<Encoder> => {\n if (encodingCache.has(encoding)) {\n const cached = encodingCache.get(encoding)\n if (cached) {\n return cached\n }\n }\n\n const supportedEncoding = encoding as SupportedEncoding\n if (!(supportedEncoding in ENCODING_MAP)) {\n const fallbackModule = (await ENCODING_MAP.o200k_base()) as Encoder\n encodingCache.set(encoding, fallbackModule)\n return fallbackModule\n }\n\n const encodingModule = (await ENCODING_MAP[supportedEncoding]()) as Encoder\n encodingCache.set(encoding, encodingModule)\n return encodingModule\n}\n\n/**\n * Get tokenizer type from model information\n */\nexport const getTokenizerFromModel = (model: Model): string => {\n return model.capabilities.tokenizer || \"o200k_base\"\n}\n\n/**\n * Get model-specific constants for token calculation\n */\nconst getModelConstants = (model: Model) => {\n return model.id === \"gpt-3.5-turbo\" || model.id === \"gpt-4\" ?\n {\n funcInit: 10,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n : {\n funcInit: 7,\n propInit: 3,\n propKey: 3,\n enumInit: -3,\n enumItem: 3,\n funcEnd: 12,\n }\n}\n\n/**\n * Calculate tokens for a single parameter\n */\nconst calculateParameterTokens = (\n key: string,\n prop: unknown,\n context: {\n encoder: Encoder\n constants: ReturnType<typeof getModelConstants>\n },\n): number => {\n const { encoder, constants } = context\n let tokens = constants.propKey\n\n // Early return if prop is not an object\n if (typeof prop !== \"object\" || prop === null) {\n return tokens\n }\n\n // Type assertion for parameter properties\n const param = prop as {\n type?: string\n description?: string\n enum?: Array<unknown>\n [key: string]: unknown\n }\n\n const paramName = key\n const paramType = param.type || \"string\"\n let paramDesc = param.description || \"\"\n\n // Handle enum values\n if (param.enum && Array.isArray(param.enum)) {\n tokens += constants.enumInit\n for (const item of param.enum) {\n tokens += constants.enumItem\n tokens += encoder.encode(String(item)).length\n }\n }\n\n // Clean up description\n if (paramDesc.endsWith(\".\")) {\n paramDesc = paramDesc.slice(0, -1)\n }\n\n // Encode the main parameter line\n const line = `${paramName}:${paramType}:${paramDesc}`\n tokens += encoder.encode(line).length\n\n // Handle additional properties (excluding standard ones)\n const excludedKeys = new Set([\"type\", \"description\", \"enum\"])\n for (const propertyName of Object.keys(param)) {\n if (!excludedKeys.has(propertyName)) {\n const propertyValue = param[propertyName]\n const propertyText =\n typeof propertyValue === \"string\" ? propertyValue : (\n JSON.stringify(propertyValue)\n )\n tokens += encoder.encode(`${propertyName}:${propertyText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for function parameters\n */\nconst calculateParametersTokens = (\n parameters: unknown,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n if (!parameters || typeof parameters !== \"object\") {\n return 0\n }\n\n const params = parameters as Record<string, unknown>\n let tokens = 0\n\n for (const [key, value] of Object.entries(params)) {\n if (key === \"properties\") {\n const properties = value as Record<string, unknown>\n if (Object.keys(properties).length > 0) {\n tokens += constants.propInit\n for (const propKey of Object.keys(properties)) {\n tokens += calculateParameterTokens(propKey, properties[propKey], {\n encoder,\n constants,\n })\n }\n }\n } else {\n const paramText =\n typeof value === \"string\" ? value : JSON.stringify(value)\n tokens += encoder.encode(`${key}:${paramText}`).length\n }\n }\n\n return tokens\n}\n\n/**\n * Calculate tokens for a single tool\n */\nconst calculateToolTokens = (\n tool: Tool,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let tokens = constants.funcInit\n const func = tool.function\n const fName = func.name\n let fDesc = func.description || \"\"\n if (fDesc.endsWith(\".\")) {\n fDesc = fDesc.slice(0, -1)\n }\n const line = fName + \":\" + fDesc\n tokens += encoder.encode(line).length\n if (\n typeof func.parameters === \"object\" // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n && func.parameters !== null\n ) {\n tokens += calculateParametersTokens(func.parameters, encoder, constants)\n }\n return tokens\n}\n\n/**\n * Calculate token count for tools based on model\n */\nexport const numTokensForTools = (\n tools: Array<Tool>,\n encoder: Encoder,\n constants: ReturnType<typeof getModelConstants>,\n): number => {\n let funcTokenCount = 0\n for (const tool of tools) {\n funcTokenCount += calculateToolTokens(tool, encoder, constants)\n }\n funcTokenCount += constants.funcEnd\n return funcTokenCount\n}\n\n/**\n * Calculate the token count of messages, supporting multiple GPT encoders\n */\nexport const getTokenCount = async (\n payload: ChatCompletionsPayload,\n model: Model,\n): Promise<{ input: number; output: number }> => {\n // Get tokenizer string\n const tokenizer = getTokenizerFromModel(model)\n\n // Get corresponding encoder module\n const encoder = await getEncodeChatFunction(tokenizer)\n\n const simplifiedMessages = payload.messages\n const inputMessages = simplifiedMessages.filter(\n (msg) => msg.role !== \"assistant\",\n )\n const outputMessages = simplifiedMessages.filter(\n (msg) => msg.role === \"assistant\",\n )\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 {\n input: inputTokens,\n output: outputTokens,\n }\n}\n\n/**\n * Estimate token count for a payload without model info (uses o200k_base encoding)\n * This is a rough estimate used when we don't have model-specific info\n */\nexport const estimateTokenCount = async (\n payload: ChatCompletionsPayload,\n): Promise<number> => {\n const encoder = await getEncodeChatFunction(\"o200k_base\")\n\n // Simple estimation: encode all message content\n let tokens = 0\n for (const message of payload.messages) {\n // 3 tokens per message overhead\n tokens += 3\n\n if (typeof message.content === \"string\") {\n tokens += encoder.encode(message.content).length\n } else if (Array.isArray(message.content)) {\n for (const part of message.content) {\n if (part.type === \"text\" && part.text) {\n tokens += encoder.encode(part.text).length\n } else if (part.type === \"image_url\") {\n // Rough estimate for images\n tokens += 85\n }\n }\n }\n\n // Add role tokens\n tokens += encoder.encode(message.role).length\n\n // Tool calls in messages (assistant responses with tool use)\n if (message.tool_calls) {\n tokens += encoder.encode(JSON.stringify(message.tool_calls)).length\n }\n }\n\n // Add tool definitions if present (but don't double count - use simplified estimate)\n // Tool definitions add overhead but the full JSON stringify overcounts\n if (payload.tools && payload.tools.length > 0) {\n // Estimate ~50 tokens per tool on average for function name + description + params\n tokens += payload.tools.length * 50\n }\n\n // Priming tokens\n tokens += 3\n\n return tokens\n}\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport const createChatCompletions = async (\r\n payload: ChatCompletionsPayload,\r\n options?: {\r\n initiator?: \"agent\" | \"user\"\r\n },\r\n) => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const enableVision = payload.messages.some(\r\n (x) =>\r\n typeof x.content !== \"string\"\r\n && x.content?.some((x) => x.type === \"image_url\"),\r\n )\r\n\r\n // Agent/user check for X-Initiator header\r\n // Check only the last message to prevent false positives in multi-turn conversations\r\n let isAgentCall = false\r\n if (payload.messages.length > 0) {\r\n const lastMessage = payload.messages.at(-1)\r\n if (lastMessage) {\r\n isAgentCall = [\"assistant\", \"tool\"].includes(lastMessage.role)\r\n }\r\n }\r\n\r\n // Build headers and add X-Initiator\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, enableVision),\r\n \"X-Initiator\": options?.initiator ?? (isAgentCall ? \"agent\" : \"user\"),\r\n }\r\n\r\n const response = await fetchWithRetry(\r\n `${copilotBaseUrl(state)}/chat/completions`,\r\n {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n },\r\n )\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create chat completions\", response)\r\n throw new HTTPError(\"Failed to create chat completions\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as ChatCompletionResponse\r\n}\r\n\r\n// Streaming types\r\n\r\nexport interface ChatCompletionChunk {\r\n id: string\r\n object: \"chat.completion.chunk\"\r\n created: number\r\n model: string\r\n choices: Array<Choice>\r\n system_fingerprint?: string\r\n usage?: {\r\n prompt_tokens: number\r\n completion_tokens: number\r\n total_tokens: number\r\n prompt_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n completion_tokens_details?: {\r\n accepted_prediction_tokens: number\r\n rejected_prediction_tokens: number\r\n }\r\n }\r\n}\r\n\r\ninterface Delta {\r\n content?: string | null\r\n role?: \"user\" | \"assistant\" | \"system\" | \"tool\"\r\n tool_calls?: Array<{\r\n index: number\r\n id?: string\r\n type?: \"function\"\r\n function?: {\r\n name?: string\r\n arguments?: string\r\n }\r\n }>\r\n}\r\n\r\ninterface Choice {\r\n index: number\r\n delta: Delta\r\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\r\n logprobs: object | null\r\n}\r\n\r\n// Non-streaming types\r\n\r\nexport interface ChatCompletionResponse {\r\n id: string\r\n object: \"chat.completion\"\r\n created: number\r\n model: string\r\n choices: Array<ChoiceNonStreaming>\r\n system_fingerprint?: string\r\n usage?: {\r\n prompt_tokens: number\r\n completion_tokens: number\r\n total_tokens: number\r\n prompt_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n }\r\n}\r\n\r\ninterface ResponseMessage {\r\n role: \"assistant\"\r\n content: string | null\r\n tool_calls?: Array<ToolCall>\r\n}\r\n\r\ninterface ChoiceNonStreaming {\r\n index: number\r\n message: ResponseMessage\r\n logprobs: object | null\r\n finish_reason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\"\r\n}\r\n\r\n// Payload types\r\n\r\nexport interface ChatCompletionsPayload {\r\n messages: Array<Message>\r\n model: string\r\n temperature?: number | null\r\n top_p?: number | null\r\n max_tokens?: number | null\r\n stop?: string | Array<string> | null\r\n n?: number | null\r\n stream?: boolean | null\r\n stream_options?: { include_usage?: boolean } | null\r\n\r\n frequency_penalty?: number | null\r\n presence_penalty?: number | null\r\n logit_bias?: Record<string, number> | null\r\n logprobs?: boolean | null\r\n response_format?: { type: \"json_object\" } | null\r\n seed?: number | null\r\n tools?: Array<Tool> | null\r\n tool_choice?:\r\n | \"none\"\r\n | \"auto\"\r\n | \"required\"\r\n | { type: \"function\"; function: { name: string } }\r\n | null\r\n user?: string | null\r\n}\r\n\r\nexport interface Tool {\r\n type: \"function\"\r\n function: {\r\n name: string\r\n description?: string\r\n parameters: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport interface Message {\r\n role: \"user\" | \"assistant\" | \"system\" | \"tool\" | \"developer\"\r\n content: string | Array<ContentPart> | null\r\n\r\n name?: string\r\n tool_calls?: Array<ToolCall>\r\n tool_call_id?: string\r\n}\r\n\r\nexport interface ToolCall {\r\n id: string\r\n type: \"function\"\r\n function: {\r\n name: string\r\n arguments: string\r\n }\r\n}\r\n\r\nexport type ContentPart = TextPart | ImagePart\r\n\r\nexport interface TextPart {\r\n type: \"text\"\r\n text: string\r\n}\r\n\r\nexport interface ImagePart {\r\n type: \"image_url\"\r\n image_url: {\r\n url: string\r\n detail?: \"low\" | \"high\" | \"auto\"\r\n }\r\n}\r\n","import type { Context } from \"hono\"\r\n\r\nimport consola from \"consola\"\r\nimport { streamSSE, type SSEMessage } from \"hono/streaming\"\r\n\r\nimport { awaitApproval } from \"~/lib/approval\"\r\nimport { applyReplacementsToPayload } from \"~/lib/auto-replace\"\r\nimport { normalizeModelName } from \"~/lib/model-resolver\"\r\nimport { parseModelSuffix } from \"~/lib/model-suffix\"\r\nimport { checkRateLimit } from \"~/lib/rate-limit\"\r\nimport { setRequestContext } from \"~/lib/request-logger\"\r\nimport { state } from \"~/lib/state\"\r\nimport { getTokenCount } from \"~/lib/tokenizer\"\r\nimport { isNullish } from \"~/lib/utils\"\r\nimport {\r\n createChatCompletions,\r\n type ChatCompletionChunk,\r\n type ChatCompletionResponse,\r\n type ChatCompletionsPayload,\r\n} from \"~/services/copilot/create-chat-completions\"\r\n\r\nexport async function handleCompletion(c: Context) {\r\n await checkRateLimit(state)\r\n\r\n const rawPayload = await c.req.json<ChatCompletionsPayload>()\r\n\r\n // Capture the originally requested model before any manipulation\r\n const requestedModel = rawPayload.model\r\n\r\n // Parse model suffix to strip reasoning effort suffix (e.g. \"gpt-5.3-codex:high\" -> \"gpt-5.3-codex\")\r\n const { baseModel, reasoningEffort } = parseModelSuffix(rawPayload.model)\r\n rawPayload.model = baseModel\r\n\r\n // Apply auto-replacements to the payload\r\n const { payload: replacedPayload, appliedRules } =\r\n await applyReplacementsToPayload(rawPayload)\r\n\r\n // Normalize model name (e.g., claude-opus-4-5 -> claude-opus-4.5)\r\n let payload = {\r\n ...replacedPayload,\r\n model: normalizeModelName(replacedPayload.model),\r\n }\r\n\r\n consola.debug(\"Request payload:\", JSON.stringify(payload).slice(-400))\r\n\r\n setRequestContext(c, {\r\n requestedModel,\r\n provider: \"ChatCompletions\",\r\n model: payload.model,\r\n replacements: appliedRules,\r\n reasoningEffort,\r\n })\r\n\r\n // Find the selected model\r\n const selectedModel = state.models?.data.find(\r\n (model) => model.id === payload.model,\r\n )\r\n\r\n // Calculate and display token count\r\n try {\r\n if (selectedModel) {\r\n const tokenCount = await getTokenCount(payload, selectedModel)\r\n setRequestContext(c, { inputTokens: tokenCount.input })\r\n }\r\n } catch (error) {\r\n consola.warn(\"Failed to calculate token count:\", error)\r\n }\r\n\r\n if (state.manualApprove) await awaitApproval()\r\n\r\n if (isNullish(payload.max_tokens)) {\r\n payload = {\r\n ...payload,\r\n max_tokens: selectedModel?.capabilities.limits.max_output_tokens,\r\n }\r\n consola.debug(\"Set max_tokens to:\", JSON.stringify(payload.max_tokens))\r\n }\r\n\r\n const response = await createChatCompletions(payload)\r\n\r\n if (isNonStreaming(response)) {\r\n consola.debug(\"Non-streaming response:\", JSON.stringify(response))\r\n if (response.usage) {\r\n setRequestContext(c, {\r\n inputTokens: response.usage.prompt_tokens,\r\n outputTokens: response.usage.completion_tokens,\r\n })\r\n }\r\n return c.json(response)\r\n }\r\n\r\n consola.debug(\"Streaming response\")\r\n return streamSSE(c, async (stream) => {\r\n for await (const chunk of response) {\r\n consola.debug(\"Streaming chunk:\", JSON.stringify(chunk))\r\n // Capture usage from final chunk if available\r\n if (chunk.data && chunk.data !== \"[DONE]\") {\r\n const parsed = JSON.parse(chunk.data) as ChatCompletionChunk\r\n if (parsed.usage) {\r\n setRequestContext(c, {\r\n inputTokens: parsed.usage.prompt_tokens,\r\n outputTokens: parsed.usage.completion_tokens,\r\n })\r\n }\r\n }\r\n await stream.writeSSE(chunk as SSEMessage)\r\n }\r\n })\r\n}\r\n\r\nconst isNonStreaming = (\r\n response: Awaited<ReturnType<typeof createChatCompletions>>,\r\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\r\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCompletion } from \"./handler\"\n\nexport const completionRoutes = new Hono()\n\ncompletionRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { copilotHeaders, copilotBaseUrl } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { fetchWithRetry } from \"~/lib/retry-fetch\"\nimport { state } from \"~/lib/state\"\n\nexport const createEmbeddings = async (payload: EmbeddingRequest) => {\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\n\n const response = await fetchWithRetry(`${copilotBaseUrl(state)}/embeddings`, {\n method: \"POST\",\n headers: copilotHeaders(state),\n body: JSON.stringify(payload),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to create embeddings\", response)\n\n return (await response.json()) as EmbeddingResponse\n}\n\nexport interface EmbeddingRequest {\n input: string | Array<string>\n model: string\n}\n\nexport interface Embedding {\n object: string\n embedding: Array<number>\n index: number\n}\n\nexport interface EmbeddingResponse {\n object: string\n data: Array<Embedding>\n model: string\n usage: {\n prompt_tokens: number\n total_tokens: number\n }\n}\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport {\n createEmbeddings,\n type EmbeddingRequest,\n} from \"~/services/copilot/create-embeddings\"\n\nexport const embeddingRoutes = new Hono()\n\nembeddingRoutes.post(\"/\", async (c) => {\n try {\n const paylod = await c.req.json<EmbeddingRequest>()\n const response = await createEmbeddings(paylod)\n\n return c.json(response)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { type AnthropicResponse } from \"./anthropic-types\"\n\nexport function mapOpenAIStopReasonToAnthropic(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null,\n): AnthropicResponse[\"stop_reason\"] {\n if (finishReason === null) {\n return null\n }\n const stopReasonMap = {\n stop: \"end_turn\",\n length: \"max_tokens\",\n tool_calls: \"tool_use\",\n content_filter: \"end_turn\",\n } as const\n return stopReasonMap[finishReason]\n}\n","import {\n type ChatCompletionResponse,\n type ChatCompletionsPayload,\n type ContentPart,\n type Message,\n type TextPart,\n type Tool,\n type ToolCall,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicResponse,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\n// Payload translation\n\nexport function translateToOpenAI(\n payload: AnthropicMessagesPayload,\n): ChatCompletionsPayload {\n return {\n model: translateModelName(payload.model),\n messages: translateAnthropicMessagesToOpenAI(\n payload.messages,\n payload.system,\n ),\n max_tokens: payload.max_tokens,\n stop: payload.stop_sequences,\n stream: payload.stream,\n temperature: payload.temperature,\n top_p: payload.top_p,\n user: payload.metadata?.user_id,\n tools: translateAnthropicToolsToOpenAI(payload.tools),\n tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),\n }\n}\n\nfunction translateModelName(model: string): string {\n // Subagent requests use a specific dated model which Copilot doesn't support\n // e.g., claude-sonnet-4-20250514 -> claude-sonnet-4\n // But preserve version numbers like claude-opus-4-5 (normalized to claude-opus-4.5 later)\n if (/^claude-sonnet-4-\\d{8}/.test(model)) {\n return \"claude-sonnet-4\"\n } else if (/^claude-opus-4-\\d{8}/.test(model)) {\n return \"claude-opus-4\"\n }\n return model\n}\n\nfunction translateAnthropicMessagesToOpenAI(\n anthropicMessages: Array<AnthropicMessage>,\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n const systemMessages = handleSystemPrompt(system)\n\n const otherMessages = anthropicMessages.flatMap((message) =>\n message.role === \"user\" ?\n handleUserMessage(message)\n : handleAssistantMessage(message),\n )\n\n return [...systemMessages, ...otherMessages]\n}\n\nfunction handleSystemPrompt(\n system: string | Array<AnthropicTextBlock> | undefined,\n): Array<Message> {\n if (!system) {\n return []\n }\n\n if (typeof system === \"string\") {\n return [{ role: \"system\", content: system }]\n } else {\n const systemText = system.map((block) => block.text).join(\"\\n\\n\")\n return [{ role: \"system\", content: systemText }]\n }\n}\n\nfunction handleUserMessage(message: AnthropicUserMessage): Array<Message> {\n const newMessages: Array<Message> = []\n\n if (Array.isArray(message.content)) {\n const toolResultBlocks = message.content.filter(\n (block): block is AnthropicToolResultBlock =>\n block.type === \"tool_result\",\n )\n const otherBlocks = message.content.filter(\n (block) => block.type !== \"tool_result\",\n )\n\n // Tool results must come first to maintain protocol: tool_use -> tool_result -> user\n for (const block of toolResultBlocks) {\n newMessages.push({\n role: \"tool\",\n tool_call_id: block.tool_use_id,\n content: mapContent(block.content),\n })\n }\n\n if (otherBlocks.length > 0) {\n newMessages.push({\n role: \"user\",\n content: mapContent(otherBlocks),\n })\n }\n } else {\n newMessages.push({\n role: \"user\",\n content: mapContent(message.content),\n })\n }\n\n return newMessages\n}\n\nfunction handleAssistantMessage(\n message: AnthropicAssistantMessage,\n): Array<Message> {\n if (!Array.isArray(message.content)) {\n return [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n }\n\n const toolUseBlocks = message.content.filter(\n (block): block is AnthropicToolUseBlock => block.type === \"tool_use\",\n )\n\n const textBlocks = message.content.filter(\n (block): block is AnthropicTextBlock => block.type === \"text\",\n )\n\n const thinkingBlocks = message.content.filter(\n (block): block is AnthropicThinkingBlock => block.type === \"thinking\",\n )\n\n // Combine text and thinking blocks, as OpenAI doesn't have separate thinking blocks\n const allTextContent = [\n ...textBlocks.map((b) => b.text),\n ...thinkingBlocks.map((b) => b.thinking),\n ].join(\"\\n\\n\")\n\n return toolUseBlocks.length > 0 ?\n [\n {\n role: \"assistant\",\n content: allTextContent || null,\n tool_calls: toolUseBlocks.map((toolUse) => ({\n id: toolUse.id,\n type: \"function\",\n function: {\n name: toolUse.name,\n arguments: JSON.stringify(toolUse.input),\n },\n })),\n },\n ]\n : [\n {\n role: \"assistant\",\n content: mapContent(message.content),\n },\n ]\n}\n\nfunction mapContent(\n content:\n | string\n | Array<AnthropicUserContentBlock | AnthropicAssistantContentBlock>,\n): string | Array<ContentPart> | null {\n if (typeof content === \"string\") {\n return content\n }\n if (!Array.isArray(content)) {\n return null\n }\n\n const hasImage = content.some((block) => block.type === \"image\")\n if (!hasImage) {\n return content\n .filter(\n (block): block is AnthropicTextBlock | AnthropicThinkingBlock =>\n block.type === \"text\" || block.type === \"thinking\",\n )\n .map((block) => (block.type === \"text\" ? block.text : block.thinking))\n .join(\"\\n\\n\")\n }\n\n const contentParts: Array<ContentPart> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n contentParts.push({ type: \"text\", text: block.text })\n\n break\n }\n case \"thinking\": {\n contentParts.push({ type: \"text\", text: block.thinking })\n\n break\n }\n case \"image\": {\n contentParts.push({\n type: \"image_url\",\n image_url: {\n url: `data:${block.source.media_type};base64,${block.source.data}`,\n },\n })\n\n break\n }\n // No default\n }\n }\n return contentParts\n}\n\nfunction translateAnthropicToolsToOpenAI(\n anthropicTools: Array<AnthropicTool> | undefined,\n): Array<Tool> | undefined {\n if (!anthropicTools) {\n return undefined\n }\n return anthropicTools.map((tool) => ({\n type: \"function\",\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.input_schema,\n },\n }))\n}\n\nfunction translateAnthropicToolChoiceToOpenAI(\n anthropicToolChoice: AnthropicMessagesPayload[\"tool_choice\"],\n): ChatCompletionsPayload[\"tool_choice\"] {\n if (!anthropicToolChoice) {\n return undefined\n }\n\n switch (anthropicToolChoice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n if (anthropicToolChoice.name) {\n return {\n type: \"function\",\n function: { name: anthropicToolChoice.name },\n }\n }\n return undefined\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return undefined\n }\n }\n}\n\n// Response translation\n\nexport function translateToAnthropic(\n response: ChatCompletionResponse,\n originalModel?: string,\n): AnthropicResponse {\n const { contentBlocks, stopReason } = extractContentFromChoices(response)\n return buildAnthropicResponse(response, {\n contentBlocks,\n stopReason,\n originalModel,\n })\n}\n\nfunction extractContentFromChoices(response: ChatCompletionResponse): {\n contentBlocks: Array<AnthropicTextBlock | AnthropicToolUseBlock>\n stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n} {\n const allTextBlocks: Array<AnthropicTextBlock> = []\n const allToolUseBlocks: Array<AnthropicToolUseBlock> = []\n let stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null =\n response.choices[0]?.finish_reason ?? null\n\n for (const choice of response.choices) {\n allTextBlocks.push(...getAnthropicTextBlocks(choice.message.content))\n allToolUseBlocks.push(\n ...getAnthropicToolUseBlocks(choice.message.tool_calls),\n )\n\n if (choice.finish_reason === \"tool_calls\" || stopReason === \"stop\") {\n stopReason = choice.finish_reason\n }\n }\n\n return {\n contentBlocks: [...allTextBlocks, ...allToolUseBlocks],\n stopReason,\n }\n}\n\nfunction buildAnthropicResponse(\n response: ChatCompletionResponse,\n options: {\n contentBlocks: Array<AnthropicTextBlock | AnthropicToolUseBlock>\n stopReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\" | null\n originalModel?: string\n },\n): AnthropicResponse {\n const { contentBlocks, stopReason, originalModel } = options\n const cachedTokens = response.usage?.prompt_tokens_details?.cached_tokens ?? 0\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n model: originalModel ?? response.model,\n content: contentBlocks,\n stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),\n stop_sequence: null,\n usage: {\n // Anthropic input_tokens = uncached tokens only\n // OpenAI prompt_tokens includes cached, so subtract them\n input_tokens: (response.usage?.prompt_tokens ?? 0) - cachedTokens,\n output_tokens: response.usage?.completion_tokens ?? 0,\n ...(cachedTokens > 0 && {\n cache_read_input_tokens: cachedTokens,\n }),\n },\n }\n}\n\nfunction getAnthropicTextBlocks(\n messageContent: Message[\"content\"],\n): Array<AnthropicTextBlock> {\n if (typeof messageContent === \"string\") {\n return [{ type: \"text\", text: messageContent }]\n }\n\n if (Array.isArray(messageContent)) {\n return messageContent\n .filter((part): part is TextPart => part.type === \"text\")\n .map((part) => ({ type: \"text\", text: part.text }))\n }\n\n return []\n}\n\nfunction getAnthropicToolUseBlocks(\n toolCalls: Array<ToolCall> | undefined,\n): Array<AnthropicToolUseBlock> {\n if (!toolCalls) {\n return []\n }\n return toolCalls.map((toolCall) => ({\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: JSON.parse(toolCall.function.arguments) as Record<string, unknown>,\n }))\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\n\nimport { normalizeModelName } from \"~/lib/model-resolver\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\n\nimport { type AnthropicMessagesPayload } from \"./anthropic-types\"\nimport { translateToOpenAI } from \"./non-stream-translation\"\n\n/**\n * Handles token counting for Anthropic messages\n */\nexport async function handleCountTokens(c: Context) {\n try {\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n\n const openAIPayload = translateToOpenAI(anthropicPayload)\n\n // Normalize model name (e.g., claude-opus-4-5 -> claude-opus-4.5) before lookup\n const normalizedModel = normalizeModelName(anthropicPayload.model)\n\n const selectedModel = state.models?.data.find(\n (model) => model.id === normalizedModel,\n )\n\n if (!selectedModel) {\n consola.warn(\"Model not found, returning default token count\")\n return c.json({\n input_tokens: 1,\n })\n }\n\n const tokenCount = await getTokenCount(openAIPayload, selectedModel)\n\n if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {\n let mcpToolExist = false\n if (anthropicBeta?.startsWith(\"claude-code\")) {\n mcpToolExist = anthropicPayload.tools.some((tool) =>\n tool.name.startsWith(\"mcp__\"),\n )\n }\n if (!mcpToolExist) {\n if (anthropicPayload.model.startsWith(\"claude\")) {\n // https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview#pricing\n tokenCount.input = tokenCount.input + 346\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n tokenCount.input = tokenCount.input + 480\n }\n }\n }\n\n let finalTokenCount = tokenCount.input + tokenCount.output\n if (anthropicPayload.model.startsWith(\"claude\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.15)\n } else if (anthropicPayload.model.startsWith(\"grok\")) {\n finalTokenCount = Math.round(finalTokenCount * 1.03)\n }\n\n consola.info(\"Token count:\", finalTokenCount)\n\n return c.json({\n input_tokens: finalTokenCount,\n })\n } catch (error) {\n consola.error(\"Error counting tokens:\", error)\n return c.json({\n input_tokens: 1,\n })\n }\n}\n","import consola, { type ConsolaInstance } from \"consola\"\r\nimport fs from \"node:fs\"\r\nimport path from \"node:path\"\r\nimport util from \"node:util\"\r\n\r\nimport { PATHS } from \"./paths\"\r\nimport { state } from \"./state\"\r\n\r\nconst LOG_RETENTION_DAYS = 7\r\nconst LOG_RETENTION_MS = LOG_RETENTION_DAYS * 24 * 60 * 60 * 1000\r\nconst CLEANUP_INTERVAL_MS = 24 * 60 * 60 * 1000\r\nconst LOG_DIR = path.join(PATHS.APP_DIR, \"logs\")\r\nconst FLUSH_INTERVAL_MS = 1000\r\nconst MAX_BUFFER_SIZE = 100\r\n\r\nconst logStreams = new Map<string, fs.WriteStream>()\r\nconst logBuffers = new Map<string, Array<string>>()\r\n\r\nconst ensureLogDirectory = () => {\r\n if (!fs.existsSync(LOG_DIR)) {\r\n fs.mkdirSync(LOG_DIR, { recursive: true })\r\n }\r\n}\r\n\r\nconst cleanupOldLogs = () => {\r\n if (!fs.existsSync(LOG_DIR)) {\r\n return\r\n }\r\n\r\n const now = Date.now()\r\n\r\n for (const entry of fs.readdirSync(LOG_DIR)) {\r\n const filePath = path.join(LOG_DIR, entry)\r\n\r\n let stats: fs.Stats\r\n try {\r\n stats = fs.statSync(filePath)\r\n } catch {\r\n continue\r\n }\r\n\r\n if (!stats.isFile()) {\r\n continue\r\n }\r\n\r\n if (now - stats.mtimeMs > LOG_RETENTION_MS) {\r\n try {\r\n fs.rmSync(filePath)\r\n } catch {\r\n continue\r\n }\r\n }\r\n }\r\n}\r\n\r\nconst formatArgs = (args: Array<unknown>) =>\r\n args\r\n .map((arg) =>\r\n typeof arg === \"string\" ? arg : (\r\n util.inspect(arg, { depth: null, colors: false })\r\n ),\r\n )\r\n .join(\" \")\r\n\r\nconst sanitizeName = (name: string) => {\r\n const normalized = name\r\n .toLowerCase()\r\n .replaceAll(/[^a-z0-9]+/g, \"-\")\r\n .replaceAll(/^-+|-+$/g, \"\")\r\n\r\n return normalized === \"\" ? \"handler\" : normalized\r\n}\r\n\r\nconst getLogStream = (filePath: string): fs.WriteStream => {\r\n let stream = logStreams.get(filePath)\r\n if (!stream || stream.destroyed) {\r\n stream = fs.createWriteStream(filePath, { flags: \"a\" })\r\n logStreams.set(filePath, stream)\r\n\r\n stream.on(\"error\", (error: unknown) => {\r\n console.warn(\"Log stream error\", error)\r\n logStreams.delete(filePath)\r\n })\r\n }\r\n return stream\r\n}\r\n\r\nconst flushBuffer = (filePath: string) => {\r\n const buffer = logBuffers.get(filePath)\r\n if (!buffer || buffer.length === 0) {\r\n return\r\n }\r\n\r\n const stream = getLogStream(filePath)\r\n const content = buffer.join(\"\\n\") + \"\\n\"\r\n stream.write(content, (error) => {\r\n if (error) {\r\n console.warn(\"Failed to write handler log\", error)\r\n }\r\n })\r\n\r\n logBuffers.set(filePath, [])\r\n}\r\n\r\nconst flushAllBuffers = () => {\r\n for (const filePath of logBuffers.keys()) {\r\n flushBuffer(filePath)\r\n }\r\n}\r\n\r\nconst appendLine = (filePath: string, line: string) => {\r\n let buffer = logBuffers.get(filePath)\r\n if (!buffer) {\r\n buffer = []\r\n logBuffers.set(filePath, buffer)\r\n }\r\n\r\n buffer.push(line)\r\n\r\n if (buffer.length >= MAX_BUFFER_SIZE) {\r\n flushBuffer(filePath)\r\n }\r\n}\r\n\r\nsetInterval(flushAllBuffers, FLUSH_INTERVAL_MS)\r\n\r\nconst cleanup = () => {\r\n flushAllBuffers()\r\n for (const stream of logStreams.values()) {\r\n stream.end()\r\n }\r\n logStreams.clear()\r\n logBuffers.clear()\r\n}\r\n\r\nprocess.on(\"exit\", cleanup)\r\nprocess.on(\"SIGINT\", () => {\r\n cleanup()\r\n process.exit(0)\r\n})\r\nprocess.on(\"SIGTERM\", () => {\r\n cleanup()\r\n process.exit(0)\r\n})\r\n\r\nlet lastCleanup = 0\r\n\r\nexport const createHandlerLogger = (name: string): ConsolaInstance => {\r\n ensureLogDirectory()\r\n\r\n const sanitizedName = sanitizeName(name)\r\n const instance = consola.withTag(name)\r\n\r\n if (state.verbose) {\r\n instance.level = 5\r\n }\r\n instance.setReporters([])\r\n\r\n instance.addReporter({\r\n log(logObj) {\r\n ensureLogDirectory()\r\n\r\n if (Date.now() - lastCleanup > CLEANUP_INTERVAL_MS) {\r\n cleanupOldLogs()\r\n lastCleanup = Date.now()\r\n }\r\n\r\n const date = logObj.date\r\n const dateKey = date.toLocaleDateString(\"sv-SE\")\r\n const timestamp = date.toLocaleString(\"sv-SE\", { hour12: false })\r\n const filePath = path.join(LOG_DIR, `${sanitizedName}-${dateKey}.log`)\r\n const message = formatArgs(logObj.args as Array<unknown>)\r\n const line = `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${\r\n message ? ` ${message}` : \"\"\r\n }`\r\n\r\n appendLine(filePath, line)\r\n },\r\n })\r\n\r\n return instance\r\n}\r\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport interface ResponsesPayload {\r\n model: string\r\n instructions?: string | null\r\n input?: string | Array<ResponseInputItem>\r\n tools?: Array<Tool> | null\r\n tool_choice?: ToolChoiceOptions | ToolChoiceFunction\r\n temperature?: number | null\r\n top_p?: number | null\r\n max_output_tokens?: number | null\r\n metadata?: Metadata | null\r\n stream?: boolean | null\r\n safety_identifier?: string | null\r\n prompt_cache_key?: string | null\r\n parallel_tool_calls?: boolean | null\r\n store?: boolean | null\r\n reasoning?: Reasoning | null\r\n include?: Array<ResponseIncludable>\r\n service_tier?: string | null // NOTE: Unsupported by GitHub Copilot\r\n [key: string]: unknown\r\n}\r\n\r\nexport type ToolChoiceOptions = \"none\" | \"auto\" | \"required\"\r\n\r\nexport interface ToolChoiceFunction {\r\n name: string\r\n type: \"function\"\r\n}\r\n\r\nexport type Tool = FunctionTool | Record<string, unknown>\r\n\r\nexport interface FunctionTool {\r\n name: string\r\n parameters: { [key: string]: unknown } | null\r\n strict: boolean | null\r\n type: \"function\"\r\n description?: string | null\r\n}\r\n\r\nexport type ResponseIncludable =\r\n | \"file_search_call.results\"\r\n | \"message.input_image.image_url\"\r\n | \"computer_call_output.output.image_url\"\r\n | \"reasoning.encrypted_content\"\r\n | \"code_interpreter_call.outputs\"\r\n\r\nexport interface Reasoning {\r\n effort?: \"none\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\" | null\r\n summary?: \"auto\" | \"concise\" | \"detailed\" | null\r\n}\r\n\r\nexport interface ResponseInputMessage {\r\n type?: \"message\"\r\n role: \"user\" | \"assistant\" | \"system\" | \"developer\"\r\n content?: string | Array<ResponseInputContent>\r\n status?: string\r\n phase?: \"commentary\" | \"final_answer\"\r\n}\r\n\r\nexport interface ResponseFunctionToolCallItem {\r\n type: \"function_call\"\r\n call_id: string\r\n name: string\r\n arguments: string\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseFunctionCallOutputItem {\r\n type: \"function_call_output\"\r\n call_id: string\r\n output: string | Array<ResponseInputContent>\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseInputReasoning {\r\n id?: string\r\n type: \"reasoning\"\r\n summary: Array<{\r\n type: \"summary_text\"\r\n text: string\r\n }>\r\n encrypted_content: string\r\n}\r\n\r\nexport type ResponseInputItem =\r\n | ResponseInputMessage\r\n | ResponseFunctionToolCallItem\r\n | ResponseFunctionCallOutputItem\r\n | ResponseInputReasoning\r\n | Record<string, unknown>\r\n\r\nexport type ResponseInputContent =\r\n | ResponseInputText\r\n | ResponseInputImage\r\n | Record<string, unknown>\r\n\r\nexport interface ResponseInputText {\r\n type: \"input_text\" | \"output_text\"\r\n text: string\r\n}\r\n\r\nexport interface ResponseInputImage {\r\n type: \"input_image\"\r\n image_url?: string | null\r\n file_id?: string | null\r\n detail: \"low\" | \"high\" | \"auto\"\r\n}\r\n\r\nexport interface ResponsesResult {\r\n id: string\r\n object: \"response\"\r\n created_at: number\r\n model: string\r\n output: Array<ResponseOutputItem>\r\n output_text: string\r\n status: string\r\n usage?: ResponseUsage | null\r\n error: ResponseError | null\r\n incomplete_details: IncompleteDetails | null\r\n instructions: string | null\r\n metadata: Metadata | null\r\n parallel_tool_calls: boolean\r\n temperature: number | null\r\n tool_choice: unknown\r\n tools: Array<Tool>\r\n top_p: number | null\r\n}\r\n\r\nexport type Metadata = { [key: string]: string }\r\n\r\nexport interface IncompleteDetails {\r\n reason?: \"max_output_tokens\" | \"content_filter\"\r\n}\r\n\r\nexport interface ResponseError {\r\n message: string\r\n}\r\n\r\nexport type ResponseOutputItem =\r\n | ResponseOutputMessage\r\n | ResponseOutputReasoning\r\n | ResponseOutputFunctionCall\r\n\r\nexport interface ResponseOutputMessage {\r\n id: string\r\n type: \"message\"\r\n role: \"assistant\"\r\n status: \"completed\" | \"in_progress\" | \"incomplete\"\r\n content?: Array<ResponseOutputContentBlock>\r\n}\r\n\r\nexport interface ResponseOutputReasoning {\r\n id: string\r\n type: \"reasoning\"\r\n summary?: Array<ResponseReasoningBlock>\r\n encrypted_content?: string\r\n status?: \"completed\" | \"in_progress\" | \"incomplete\"\r\n}\r\n\r\nexport interface ResponseReasoningBlock {\r\n type: string\r\n text?: string\r\n}\r\n\r\nexport interface ResponseOutputFunctionCall {\r\n id?: string\r\n type: \"function_call\"\r\n call_id: string\r\n name: string\r\n arguments: string\r\n status?: \"in_progress\" | \"completed\" | \"incomplete\"\r\n}\r\n\r\nexport type ResponseOutputContentBlock =\r\n | ResponseOutputText\r\n | ResponseOutputRefusal\r\n | Record<string, unknown>\r\n\r\nexport interface ResponseOutputText {\r\n type: \"output_text\"\r\n text: string\r\n annotations: Array<unknown>\r\n}\r\n\r\nexport interface ResponseOutputRefusal {\r\n type: \"refusal\"\r\n refusal: string\r\n}\r\n\r\nexport interface ResponseUsage {\r\n input_tokens: number\r\n output_tokens?: number\r\n total_tokens: number\r\n input_tokens_details?: {\r\n cached_tokens: number\r\n }\r\n output_tokens_details?: {\r\n reasoning_tokens: number\r\n }\r\n}\r\n\r\nexport type ResponseStreamEvent =\r\n | ResponseCompletedEvent\r\n | ResponseIncompleteEvent\r\n | ResponseCreatedEvent\r\n | ResponseErrorEvent\r\n | ResponseFunctionCallArgumentsDeltaEvent\r\n | ResponseFunctionCallArgumentsDoneEvent\r\n | ResponseFailedEvent\r\n | ResponseOutputItemAddedEvent\r\n | ResponseOutputItemDoneEvent\r\n | ResponseReasoningSummaryTextDeltaEvent\r\n | ResponseReasoningSummaryTextDoneEvent\r\n | ResponseTextDeltaEvent\r\n | ResponseTextDoneEvent\r\n\r\nexport interface ResponseCompletedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.completed\"\r\n}\r\n\r\nexport interface ResponseIncompleteEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.incomplete\"\r\n}\r\n\r\nexport interface ResponseCreatedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.created\"\r\n}\r\n\r\nexport interface ResponseErrorEvent {\r\n code: string | null\r\n message: string\r\n param: string | null\r\n sequence_number: number\r\n type: \"error\"\r\n}\r\n\r\nexport interface ResponseFunctionCallArgumentsDeltaEvent {\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.function_call_arguments.delta\"\r\n}\r\n\r\nexport interface ResponseFunctionCallArgumentsDoneEvent {\r\n arguments: string\r\n item_id: string\r\n name: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.function_call_arguments.done\"\r\n}\r\n\r\nexport interface ResponseFailedEvent {\r\n response: ResponsesResult\r\n sequence_number: number\r\n type: \"response.failed\"\r\n}\r\n\r\nexport interface ResponseOutputItemAddedEvent {\r\n item: ResponseOutputItem\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_item.added\"\r\n}\r\n\r\nexport interface ResponseOutputItemDoneEvent {\r\n item: ResponseOutputItem\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_item.done\"\r\n}\r\n\r\nexport interface ResponseReasoningSummaryTextDeltaEvent {\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n summary_index: number\r\n type: \"response.reasoning_summary_text.delta\"\r\n}\r\n\r\nexport interface ResponseReasoningSummaryTextDoneEvent {\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n summary_index: number\r\n text: string\r\n type: \"response.reasoning_summary_text.done\"\r\n}\r\n\r\nexport interface ResponseTextDeltaEvent {\r\n content_index: number\r\n delta: string\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n type: \"response.output_text.delta\"\r\n}\r\n\r\nexport interface ResponseTextDoneEvent {\r\n content_index: number\r\n item_id: string\r\n output_index: number\r\n sequence_number: number\r\n text: string\r\n type: \"response.output_text.done\"\r\n}\r\n\r\nexport type ResponsesStream = ReturnType<typeof events>\r\nexport type CreateResponsesReturn = ResponsesResult | ResponsesStream\r\n\r\ninterface ResponsesRequestOptions {\r\n vision: boolean\r\n initiator: \"agent\" | \"user\"\r\n}\r\n\r\nexport const createResponses = async (\r\n payload: ResponsesPayload,\r\n { vision, initiator }: ResponsesRequestOptions,\r\n): Promise<CreateResponsesReturn> => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, vision),\r\n \"X-Initiator\": initiator,\r\n }\r\n\r\n // service_tier is not supported by github copilot\r\n payload.service_tier = null\r\n\r\n const response = await fetch(`${copilotBaseUrl(state)}/responses`, {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n })\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create responses\", response)\r\n throw new HTTPError(\"Failed to create responses\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as ResponsesResult\r\n}\r\n","import consola from \"consola\"\n\nimport {\n getExtraPromptForModel,\n getReasoningEffortForModel,\n} from \"~/lib/config\"\nimport {\n type ResponsesPayload,\n type ResponseInputContent,\n type ResponseInputImage,\n type ResponseInputItem,\n type ResponseInputMessage,\n type ResponseInputReasoning,\n type ResponseInputText,\n type ResponsesResult,\n type ResponseOutputContentBlock,\n type ResponseOutputFunctionCall,\n type ResponseOutputItem,\n type ResponseOutputReasoning,\n type ResponseReasoningBlock,\n type ResponseOutputRefusal,\n type ResponseOutputText,\n type ResponseFunctionToolCallItem,\n type ResponseFunctionCallOutputItem,\n type Tool,\n type ToolChoiceFunction,\n type ToolChoiceOptions,\n} from \"~/services/copilot/create-responses\"\n\nimport {\n type AnthropicAssistantContentBlock,\n type AnthropicAssistantMessage,\n type AnthropicResponse,\n type AnthropicImageBlock,\n type AnthropicMessage,\n type AnthropicMessagesPayload,\n type AnthropicTextBlock,\n type AnthropicThinkingBlock,\n type AnthropicTool,\n type AnthropicToolResultBlock,\n type AnthropicToolUseBlock,\n type AnthropicUserContentBlock,\n type AnthropicUserMessage,\n} from \"./anthropic-types\"\n\nconst MESSAGE_TYPE = \"message\"\nconst CODEX_PHASE_MODEL = \"gpt-5.3-codex\"\n\nexport const THINKING_TEXT = \"Thinking...\"\n\nexport const translateAnthropicMessagesToResponsesPayload = (\n payload: AnthropicMessagesPayload,\n effortOverride?: \"low\" | \"medium\" | \"high\" | \"xhigh\",\n): ResponsesPayload => {\n const input: Array<ResponseInputItem> = []\n\n for (const message of payload.messages) {\n input.push(...translateMessage(message, payload.model))\n }\n\n const translatedTools = convertAnthropicTools(payload.tools)\n const toolChoice = convertAnthropicToolChoice(payload.tool_choice)\n\n const { safetyIdentifier, promptCacheKey } = parseUserId(\n payload.metadata?.user_id,\n )\n\n const responsesPayload: ResponsesPayload = {\n model: payload.model,\n input,\n instructions: translateSystemPrompt(payload.system, payload.model),\n temperature: 1, // reasoning high temperature fixed to 1\n top_p: payload.top_p ?? null,\n max_output_tokens: Math.max(payload.max_tokens, 12800),\n tools: translatedTools,\n tool_choice: toolChoice,\n metadata: payload.metadata ? { ...payload.metadata } : null,\n safety_identifier: safetyIdentifier,\n prompt_cache_key: promptCacheKey,\n stream: payload.stream ?? null,\n store: false,\n parallel_tool_calls: true,\n reasoning: {\n effort: getReasoningEffortForModel(payload.model, effortOverride),\n summary: \"detailed\",\n },\n include: [\"reasoning.encrypted_content\"],\n }\n\n return responsesPayload\n}\n\nconst translateMessage = (\n message: AnthropicMessage,\n model: string,\n): Array<ResponseInputItem> => {\n if (message.role === \"user\") {\n return translateUserMessage(message)\n }\n\n return translateAssistantMessage(message, model)\n}\n\nconst translateUserMessage = (\n message: AnthropicUserMessage,\n): Array<ResponseInputItem> => {\n if (typeof message.content === \"string\") {\n return [createMessage(\"user\", message.content)]\n }\n\n if (!Array.isArray(message.content)) {\n return []\n }\n\n const items: Array<ResponseInputItem> = []\n const pendingContent: Array<ResponseInputContent> = []\n\n for (const block of message.content) {\n if (block.type === \"tool_result\") {\n flushPendingContent(pendingContent, items, { role: \"user\" })\n items.push(createFunctionCallOutput(block))\n continue\n }\n\n const converted = translateUserContentBlock(block)\n if (converted) {\n pendingContent.push(converted)\n }\n }\n\n flushPendingContent(pendingContent, items, { role: \"user\" })\n\n return items\n}\n\nconst translateAssistantMessage = (\n message: AnthropicAssistantMessage,\n model: string,\n): Array<ResponseInputItem> => {\n const assistantPhase = resolveAssistantPhase(model, message.content)\n\n if (typeof message.content === \"string\") {\n return [createMessage(\"assistant\", message.content, assistantPhase)]\n }\n\n if (!Array.isArray(message.content)) {\n return []\n }\n\n const items: Array<ResponseInputItem> = []\n const pendingContent: Array<ResponseInputContent> = []\n\n for (const block of message.content) {\n if (block.type === \"tool_use\") {\n flushPendingContent(pendingContent, items, {\n role: \"assistant\",\n phase: assistantPhase,\n })\n items.push(createFunctionToolCall(block))\n continue\n }\n\n if (\n block.type === \"thinking\"\n && block.signature\n && block.signature.includes(\"@\")\n ) {\n flushPendingContent(pendingContent, items, {\n role: \"assistant\",\n phase: assistantPhase,\n })\n items.push(createReasoningContent(block))\n continue\n }\n\n const converted = translateAssistantContentBlock(block)\n if (converted) {\n pendingContent.push(converted)\n }\n }\n\n flushPendingContent(pendingContent, items, {\n role: \"assistant\",\n phase: assistantPhase,\n })\n\n return items\n}\n\nconst translateUserContentBlock = (\n block: AnthropicUserContentBlock,\n): ResponseInputContent | undefined => {\n switch (block.type) {\n case \"text\": {\n return createTextContent(block.text)\n }\n case \"image\": {\n return createImageContent(block)\n }\n default: {\n return undefined\n }\n }\n}\n\nconst translateAssistantContentBlock = (\n block: AnthropicAssistantContentBlock,\n): ResponseInputContent | undefined => {\n switch (block.type) {\n case \"text\": {\n return createOutPutTextContent(block.text)\n }\n default: {\n return undefined\n }\n }\n}\n\nconst flushPendingContent = (\n pendingContent: Array<ResponseInputContent>,\n target: Array<ResponseInputItem>,\n message: Pick<ResponseInputMessage, \"role\" | \"phase\">,\n) => {\n if (pendingContent.length === 0) {\n return\n }\n\n const messageContent = [...pendingContent]\n\n target.push(createMessage(message.role, messageContent, message.phase))\n pendingContent.length = 0\n}\n\nconst createMessage = (\n role: ResponseInputMessage[\"role\"],\n content: string | Array<ResponseInputContent>,\n phase?: ResponseInputMessage[\"phase\"],\n): ResponseInputMessage => ({\n type: MESSAGE_TYPE,\n role,\n content,\n ...(role === \"assistant\" && phase ? { phase } : {}),\n})\n\nconst resolveAssistantPhase = (\n model: string,\n content: AnthropicAssistantMessage[\"content\"],\n): ResponseInputMessage[\"phase\"] | undefined => {\n if (!shouldApplyCodexPhase(model)) {\n return undefined\n }\n\n if (typeof content === \"string\") {\n return \"final_answer\"\n }\n\n if (!Array.isArray(content)) {\n return undefined\n }\n\n const hasText = content.some((block) => block.type === \"text\")\n if (!hasText) {\n return undefined\n }\n\n const hasToolUse = content.some((block) => block.type === \"tool_use\")\n return hasToolUse ? \"commentary\" : \"final_answer\"\n}\n\nconst shouldApplyCodexPhase = (model: string): boolean =>\n model === CODEX_PHASE_MODEL\n\nconst createTextContent = (text: string): ResponseInputText => ({\n type: \"input_text\",\n text,\n})\n\nconst createOutPutTextContent = (text: string): ResponseInputText => ({\n type: \"output_text\",\n text,\n})\n\nconst createImageContent = (\n block: AnthropicImageBlock,\n): ResponseInputImage => ({\n type: \"input_image\",\n image_url: `data:${block.source.media_type};base64,${block.source.data}`,\n detail: \"auto\",\n})\n\nconst createReasoningContent = (\n block: AnthropicThinkingBlock,\n): ResponseInputReasoning => {\n // align with vscode-copilot-chat extractThinkingData, should add id, otherwise it will cause miss cache occasionally —— the usage input cached tokens to be 0\n // https://github.com/microsoft/vscode-copilot-chat/blob/main/src/platform/endpoint/node/responsesApi.ts#L162\n // when use in codex cli, reasoning id is empty, so it will cause miss cache occasionally\n const array = (block.signature ?? \"\").split(\"@\")\n const signature = array[0]\n const id = array[1]\n const thinking = block.thinking === THINKING_TEXT ? \"\" : block.thinking\n return {\n id,\n type: \"reasoning\",\n summary: thinking ? [{ type: \"summary_text\", text: thinking }] : [],\n encrypted_content: signature,\n }\n}\n\nconst createFunctionToolCall = (\n block: AnthropicToolUseBlock,\n): ResponseFunctionToolCallItem => ({\n type: \"function_call\",\n call_id: block.id,\n name: block.name,\n arguments: JSON.stringify(block.input),\n status: \"completed\",\n})\n\nconst createFunctionCallOutput = (\n block: AnthropicToolResultBlock,\n): ResponseFunctionCallOutputItem => ({\n type: \"function_call_output\",\n call_id: block.tool_use_id,\n output: convertToolResultContent(block.content),\n status: block.is_error ? \"incomplete\" : \"completed\",\n})\n\nconst translateSystemPrompt = (\n system: string | Array<AnthropicTextBlock> | undefined,\n model: string,\n): string | null => {\n if (!system) {\n return null\n }\n\n const extraPrompt = getExtraPromptForModel(model)\n\n if (typeof system === \"string\") {\n return system + extraPrompt\n }\n\n const text = system\n .map((block, index) => {\n if (index === 0) {\n return block.text + extraPrompt\n }\n return block.text\n })\n .join(\" \")\n return text.length > 0 ? text : null\n}\n\nconst convertAnthropicTools = (\n tools: Array<AnthropicTool> | undefined,\n): Array<Tool> | null => {\n if (!tools || tools.length === 0) {\n return null\n }\n\n return tools.map((tool) => ({\n type: \"function\",\n name: tool.name,\n parameters: tool.input_schema,\n strict: false,\n ...(tool.description ? { description: tool.description } : {}),\n }))\n}\n\nconst convertAnthropicToolChoice = (\n choice: AnthropicMessagesPayload[\"tool_choice\"],\n): ToolChoiceOptions | ToolChoiceFunction => {\n if (!choice) {\n return \"auto\"\n }\n\n switch (choice.type) {\n case \"auto\": {\n return \"auto\"\n }\n case \"any\": {\n return \"required\"\n }\n case \"tool\": {\n return choice.name ? { type: \"function\", name: choice.name } : \"auto\"\n }\n case \"none\": {\n return \"none\"\n }\n default: {\n return \"auto\"\n }\n }\n}\n\nexport const translateResponsesResultToAnthropic = (\n response: ResponsesResult,\n): AnthropicResponse => {\n const contentBlocks = mapOutputToAnthropicContent(response.output)\n const usage = mapResponsesUsage(response)\n let anthropicContent = fallbackContentBlocks(response.output_text)\n if (contentBlocks.length > 0) {\n anthropicContent = contentBlocks\n }\n\n const stopReason = mapResponsesStopReason(response)\n\n return {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n content: anthropicContent,\n model: response.model,\n stop_reason: stopReason,\n stop_sequence: null,\n usage,\n }\n}\n\nconst mapOutputToAnthropicContent = (\n output: Array<ResponseOutputItem>,\n): Array<AnthropicAssistantContentBlock> => {\n const contentBlocks: Array<AnthropicAssistantContentBlock> = []\n\n for (const item of output) {\n switch (item.type) {\n case \"reasoning\": {\n const thinkingText = extractReasoningText(item)\n if (thinkingText.length > 0) {\n contentBlocks.push({\n type: \"thinking\",\n thinking: thinkingText,\n signature: (item.encrypted_content ?? \"\") + \"@\" + item.id,\n })\n }\n break\n }\n case \"function_call\": {\n const toolUseBlock = createToolUseContentBlock(item)\n if (toolUseBlock) {\n contentBlocks.push(toolUseBlock)\n }\n break\n }\n case \"message\": {\n const combinedText = combineMessageTextContent(item.content)\n if (combinedText.length > 0) {\n contentBlocks.push({ type: \"text\", text: combinedText })\n }\n break\n }\n default: {\n // Future compatibility for unrecognized output item types.\n const combinedText = combineMessageTextContent(\n (item as { content?: Array<ResponseOutputContentBlock> }).content,\n )\n if (combinedText.length > 0) {\n contentBlocks.push({ type: \"text\", text: combinedText })\n }\n }\n }\n }\n\n return contentBlocks\n}\n\nconst combineMessageTextContent = (\n content: Array<ResponseOutputContentBlock> | undefined,\n): string => {\n if (!Array.isArray(content)) {\n return \"\"\n }\n\n let aggregated = \"\"\n\n for (const block of content) {\n if (isResponseOutputText(block)) {\n aggregated += block.text\n continue\n }\n\n if (isResponseOutputRefusal(block)) {\n aggregated += block.refusal\n continue\n }\n\n if (typeof (block as { text?: unknown }).text === \"string\") {\n aggregated += (block as { text: string }).text\n continue\n }\n\n if (typeof (block as { reasoning?: unknown }).reasoning === \"string\") {\n aggregated += (block as { reasoning: string }).reasoning\n continue\n }\n }\n\n return aggregated\n}\n\nconst extractReasoningText = (item: ResponseOutputReasoning): string => {\n const segments: Array<string> = []\n\n const collectFromBlocks = (blocks?: Array<ResponseReasoningBlock>) => {\n if (!Array.isArray(blocks)) {\n return\n }\n\n for (const block of blocks) {\n if (typeof block.text === \"string\") {\n segments.push(block.text)\n continue\n }\n }\n }\n\n // Compatible with opencode, it will filter out blocks where the thinking text is empty, so we add a default thinking text here\n if (!item.summary || item.summary.length === 0) {\n return THINKING_TEXT\n }\n\n collectFromBlocks(item.summary)\n\n return segments.join(\"\").trim()\n}\n\nconst createToolUseContentBlock = (\n call: ResponseOutputFunctionCall,\n): AnthropicToolUseBlock | null => {\n const toolId = call.call_id\n if (!call.name || !toolId) {\n return null\n }\n\n const input = parseFunctionCallArguments(call.arguments)\n\n return {\n type: \"tool_use\",\n id: toolId,\n name: call.name,\n input,\n }\n}\n\nconst parseFunctionCallArguments = (\n rawArguments: string,\n): Record<string, unknown> => {\n if (typeof rawArguments !== \"string\" || rawArguments.trim().length === 0) {\n return {}\n }\n\n try {\n const parsed: unknown = JSON.parse(rawArguments)\n\n if (Array.isArray(parsed)) {\n return { arguments: parsed }\n }\n\n if (parsed && typeof parsed === \"object\") {\n return parsed as Record<string, unknown>\n }\n } catch (error) {\n consola.warn(\"Failed to parse function call arguments\", {\n error,\n rawArguments,\n })\n }\n\n return { raw_arguments: rawArguments }\n}\n\nconst fallbackContentBlocks = (\n outputText: string,\n): Array<AnthropicAssistantContentBlock> => {\n if (!outputText) {\n return []\n }\n\n return [\n {\n type: \"text\",\n text: outputText,\n },\n ]\n}\n\nconst mapResponsesStopReason = (\n response: ResponsesResult,\n): AnthropicResponse[\"stop_reason\"] => {\n const { status, incomplete_details: incompleteDetails } = response\n\n if (status === \"completed\") {\n if (response.output.some((item) => item.type === \"function_call\")) {\n return \"tool_use\"\n }\n return \"end_turn\"\n }\n\n if (status === \"incomplete\") {\n if (incompleteDetails?.reason === \"max_output_tokens\") {\n return \"max_tokens\"\n }\n if (incompleteDetails?.reason === \"content_filter\") {\n return \"end_turn\"\n }\n }\n\n return null\n}\n\nconst mapResponsesUsage = (\n response: ResponsesResult,\n): AnthropicResponse[\"usage\"] => {\n const inputTokens = response.usage?.input_tokens ?? 0\n const outputTokens = response.usage?.output_tokens ?? 0\n const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens\n\n return {\n input_tokens: inputTokens - (inputCachedTokens ?? 0),\n output_tokens: outputTokens,\n ...(response.usage?.input_tokens_details?.cached_tokens !== undefined && {\n cache_read_input_tokens:\n response.usage.input_tokens_details.cached_tokens,\n }),\n }\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null\n\nconst isResponseOutputText = (\n block: ResponseOutputContentBlock,\n): block is ResponseOutputText =>\n isRecord(block)\n && \"type\" in block\n && (block as { type?: unknown }).type === \"output_text\"\n\nconst isResponseOutputRefusal = (\n block: ResponseOutputContentBlock,\n): block is ResponseOutputRefusal =>\n isRecord(block)\n && \"type\" in block\n && (block as { type?: unknown }).type === \"refusal\"\n\nconst parseUserId = (\n userId: string | undefined,\n): { safetyIdentifier: string | null; promptCacheKey: string | null } => {\n if (!userId || typeof userId !== \"string\") {\n return { safetyIdentifier: null, promptCacheKey: null }\n }\n\n // Parse safety_identifier: content between \"user_\" and \"_account\"\n const userMatch = userId.match(/user_([^_]+)_account/)\n const safetyIdentifier = userMatch ? userMatch[1] : null\n\n // Parse prompt_cache_key: content after \"_session_\"\n const sessionMatch = userId.match(/_session_(.+)$/)\n const promptCacheKey = sessionMatch ? sessionMatch[1] : null\n\n return { safetyIdentifier, promptCacheKey }\n}\n\nconst convertToolResultContent = (\n content: string | Array<AnthropicTextBlock | AnthropicImageBlock>,\n): string | Array<ResponseInputContent> => {\n if (typeof content === \"string\") {\n return content\n }\n\n if (Array.isArray(content)) {\n const result: Array<ResponseInputContent> = []\n for (const block of content) {\n switch (block.type) {\n case \"text\": {\n result.push(createTextContent(block.text))\n break\n }\n case \"image\": {\n result.push(createImageContent(block))\n break\n }\n default: {\n break\n }\n }\n }\n return result\n }\n\n return \"\"\n}\n","import {\r\n type ResponseCompletedEvent,\r\n type ResponseCreatedEvent,\r\n type ResponseErrorEvent,\r\n type ResponseFailedEvent,\r\n type ResponseFunctionCallArgumentsDeltaEvent,\r\n type ResponseFunctionCallArgumentsDoneEvent,\r\n type ResponseIncompleteEvent,\r\n type ResponseOutputItemAddedEvent,\r\n type ResponseOutputItemDoneEvent,\r\n type ResponseReasoningSummaryTextDeltaEvent,\r\n type ResponseReasoningSummaryTextDoneEvent,\r\n type ResponsesResult,\r\n type ResponseStreamEvent,\r\n type ResponseTextDeltaEvent,\r\n type ResponseTextDoneEvent,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nimport { type AnthropicStreamEventData } from \"./anthropic-types\"\r\nimport {\r\n THINKING_TEXT,\r\n translateResponsesResultToAnthropic,\r\n} from \"./responses-translation\"\r\n\r\nconst MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20\r\n\r\nclass FunctionCallArgumentsValidationError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = \"FunctionCallArgumentsValidationError\"\r\n }\r\n}\r\n\r\nconst updateWhitespaceRunState = (\r\n previousCount: number,\r\n chunk: string,\r\n): {\r\n nextCount: number\r\n exceeded: boolean\r\n} => {\r\n let count = previousCount\r\n\r\n for (const char of chunk) {\r\n if (char === \"\\r\" || char === \"\\n\" || char === \"\\t\") {\r\n count += 1\r\n if (count > MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE) {\r\n return { nextCount: count, exceeded: true }\r\n }\r\n continue\r\n }\r\n\r\n if (char !== \" \") {\r\n count = 0\r\n }\r\n }\r\n\r\n return { nextCount: count, exceeded: false }\r\n}\r\n\r\nexport interface ResponsesStreamState {\r\n messageStartSent: boolean\r\n messageCompleted: boolean\r\n nextContentBlockIndex: number\r\n blockIndexByKey: Map<string, number>\r\n openBlocks: Set<number>\r\n blockHasDelta: Set<number>\r\n functionCallStateByOutputIndex: Map<number, FunctionCallStreamState>\r\n}\r\n\r\ntype FunctionCallStreamState = {\r\n blockIndex: number\r\n toolCallId: string\r\n name: string\r\n consecutiveWhitespaceCount: number\r\n}\r\n\r\nexport const createResponsesStreamState = (): ResponsesStreamState => ({\r\n messageStartSent: false,\r\n messageCompleted: false,\r\n nextContentBlockIndex: 0,\r\n blockIndexByKey: new Map(),\r\n openBlocks: new Set(),\r\n blockHasDelta: new Set(),\r\n functionCallStateByOutputIndex: new Map(),\r\n})\r\n\r\nexport const translateResponsesStreamEvent = (\r\n rawEvent: ResponseStreamEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const eventType = rawEvent.type\r\n switch (eventType) {\r\n case \"response.created\": {\r\n return handleResponseCreated(rawEvent, state)\r\n }\r\n\r\n case \"response.output_item.added\": {\r\n return handleOutputItemAdded(rawEvent, state)\r\n }\r\n\r\n case \"response.reasoning_summary_text.delta\": {\r\n return handleReasoningSummaryTextDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.output_text.delta\": {\r\n return handleOutputTextDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.reasoning_summary_text.done\": {\r\n return handleReasoningSummaryTextDone(rawEvent, state)\r\n }\r\n\r\n case \"response.output_text.done\": {\r\n return handleOutputTextDone(rawEvent, state)\r\n }\r\n case \"response.output_item.done\": {\r\n return handleOutputItemDone(rawEvent, state)\r\n }\r\n\r\n case \"response.function_call_arguments.delta\": {\r\n return handleFunctionCallArgumentsDelta(rawEvent, state)\r\n }\r\n\r\n case \"response.function_call_arguments.done\": {\r\n return handleFunctionCallArgumentsDone(rawEvent, state)\r\n }\r\n\r\n case \"response.completed\":\r\n case \"response.incomplete\": {\r\n return handleResponseCompleted(rawEvent, state)\r\n }\r\n\r\n case \"response.failed\": {\r\n return handleResponseFailed(rawEvent, state)\r\n }\r\n\r\n case \"error\": {\r\n return handleErrorEvent(rawEvent, state)\r\n }\r\n\r\n default: {\r\n return []\r\n }\r\n }\r\n}\r\n\r\n// Helper handlers to keep translateResponsesStreamEvent concise\r\nconst handleResponseCreated = (\r\n rawEvent: ResponseCreatedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n return messageStart(state, rawEvent.response)\r\n}\r\n\r\nconst handleOutputItemAdded = (\r\n rawEvent: ResponseOutputItemAddedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const functionCallDetails = extractFunctionCallDetails(rawEvent)\r\n if (!functionCallDetails) {\r\n return events\r\n }\r\n\r\n const { outputIndex, toolCallId, name, initialArguments } =\r\n functionCallDetails\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n toolCallId,\r\n name,\r\n events,\r\n })\r\n\r\n if (initialArguments !== undefined && initialArguments.length > 0) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: initialArguments,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleOutputItemDone = (\r\n rawEvent: ResponseOutputItemDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const item = rawEvent.item\r\n const itemType = item.type\r\n if (itemType !== \"reasoning\") {\r\n return events\r\n }\r\n\r\n const outputIndex = rawEvent.output_index\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n const signature = (item.encrypted_content ?? \"\") + \"@\" + item.id\r\n if (signature) {\r\n // Compatible with opencode, it will filter out blocks where the thinking text is empty, so we add a default thinking text here\r\n if (!item.summary || item.summary.length === 0) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: THINKING_TEXT,\r\n },\r\n })\r\n }\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"signature_delta\",\r\n signature,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleFunctionCallArgumentsDelta = (\r\n rawEvent: ResponseFunctionCallArgumentsDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const deltaText = rawEvent.delta\r\n\r\n if (!deltaText) {\r\n return events\r\n }\r\n\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n events,\r\n })\r\n\r\n const functionCallState =\r\n state.functionCallStateByOutputIndex.get(outputIndex)\r\n if (!functionCallState) {\r\n return handleFunctionCallArgumentsValidationError(\r\n new FunctionCallArgumentsValidationError(\r\n \"Received function call arguments delta without an open tool call block.\",\r\n ),\r\n state,\r\n events,\r\n )\r\n }\r\n\r\n // fix: copolit function call returning infinite line breaks until max_tokens limit\r\n // \"arguments\": \"{\\\"path\\\":\\\"xxx\\\",\\\"pattern\\\":\\\"**/*.ts\\\",\\\"} }? Wait extra braces. Need correct. I should run? Wait overcame. Need proper JSON with pattern \\\"\\n\\n\\n\\n\\n\\n\\n\\n...\r\n const { nextCount, exceeded } = updateWhitespaceRunState(\r\n functionCallState.consecutiveWhitespaceCount,\r\n deltaText,\r\n )\r\n if (exceeded) {\r\n return handleFunctionCallArgumentsValidationError(\r\n new FunctionCallArgumentsValidationError(\r\n \"Received function call arguments delta containing more than 20 consecutive whitespace characters.\",\r\n ),\r\n state,\r\n events,\r\n )\r\n }\r\n functionCallState.consecutiveWhitespaceCount = nextCount\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleFunctionCallArgumentsDone = (\r\n rawEvent: ResponseFunctionCallArgumentsDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const blockIndex = openFunctionCallBlock(state, {\r\n outputIndex,\r\n events,\r\n })\r\n\r\n const finalArguments =\r\n typeof rawEvent.arguments === \"string\" ? rawEvent.arguments : undefined\r\n\r\n if (!state.blockHasDelta.has(blockIndex) && finalArguments) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"input_json_delta\",\r\n partial_json: finalArguments,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n }\r\n\r\n state.functionCallStateByOutputIndex.delete(outputIndex)\r\n return events\r\n}\r\n\r\nconst handleOutputTextDelta = (\r\n rawEvent: ResponseTextDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const contentIndex = rawEvent.content_index\r\n const deltaText = rawEvent.delta\r\n\r\n if (!deltaText) {\r\n return events\r\n }\r\n\r\n const blockIndex = openTextBlockIfNeeded(state, {\r\n outputIndex,\r\n contentIndex,\r\n events,\r\n })\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"text_delta\",\r\n text: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleReasoningSummaryTextDelta = (\r\n rawEvent: ResponseReasoningSummaryTextDeltaEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const outputIndex = rawEvent.output_index\r\n const deltaText = rawEvent.delta\r\n const events = new Array<AnthropicStreamEventData>()\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: deltaText,\r\n },\r\n })\r\n state.blockHasDelta.add(blockIndex)\r\n\r\n return events\r\n}\r\n\r\nconst handleReasoningSummaryTextDone = (\r\n rawEvent: ResponseReasoningSummaryTextDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const outputIndex = rawEvent.output_index\r\n const text = rawEvent.text\r\n const events = new Array<AnthropicStreamEventData>()\r\n const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events)\r\n\r\n if (text && !state.blockHasDelta.has(blockIndex)) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"thinking_delta\",\r\n thinking: text,\r\n },\r\n })\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleOutputTextDone = (\r\n rawEvent: ResponseTextDoneEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const events = new Array<AnthropicStreamEventData>()\r\n const outputIndex = rawEvent.output_index\r\n const contentIndex = rawEvent.content_index\r\n const text = rawEvent.text\r\n\r\n const blockIndex = openTextBlockIfNeeded(state, {\r\n outputIndex,\r\n contentIndex,\r\n events,\r\n })\r\n\r\n if (text && !state.blockHasDelta.has(blockIndex)) {\r\n events.push({\r\n type: \"content_block_delta\",\r\n index: blockIndex,\r\n delta: {\r\n type: \"text_delta\",\r\n text,\r\n },\r\n })\r\n }\r\n\r\n return events\r\n}\r\n\r\nconst handleResponseCompleted = (\r\n rawEvent: ResponseCompletedEvent | ResponseIncompleteEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const response = rawEvent.response\r\n const events = new Array<AnthropicStreamEventData>()\r\n\r\n closeAllOpenBlocks(state, events)\r\n const anthropic = translateResponsesResultToAnthropic(response)\r\n events.push(\r\n {\r\n type: \"message_delta\",\r\n delta: {\r\n stop_reason: anthropic.stop_reason,\r\n stop_sequence: anthropic.stop_sequence,\r\n },\r\n usage: anthropic.usage,\r\n },\r\n { type: \"message_stop\" },\r\n )\r\n state.messageCompleted = true\r\n return events\r\n}\r\n\r\nconst handleResponseFailed = (\r\n rawEvent: ResponseFailedEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const response = rawEvent.response\r\n const events = new Array<AnthropicStreamEventData>()\r\n closeAllOpenBlocks(state, events)\r\n\r\n const message =\r\n response.error?.message ?? \"The response failed due to an unknown error.\"\r\n\r\n events.push(buildErrorEvent(message))\r\n state.messageCompleted = true\r\n\r\n return events\r\n}\r\n\r\nconst handleErrorEvent = (\r\n rawEvent: ResponseErrorEvent,\r\n state: ResponsesStreamState,\r\n): Array<AnthropicStreamEventData> => {\r\n const message =\r\n typeof rawEvent.message === \"string\" ?\r\n rawEvent.message\r\n : \"An unexpected error occurred during streaming.\"\r\n\r\n state.messageCompleted = true\r\n return [buildErrorEvent(message)]\r\n}\r\n\r\nconst handleFunctionCallArgumentsValidationError = (\r\n error: FunctionCallArgumentsValidationError,\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData> = [],\r\n): Array<AnthropicStreamEventData> => {\r\n const reason = error.message\r\n\r\n closeAllOpenBlocks(state, events)\r\n state.messageCompleted = true\r\n\r\n events.push(buildErrorEvent(reason))\r\n\r\n return events\r\n}\r\n\r\nconst messageStart = (\r\n state: ResponsesStreamState,\r\n response: ResponsesResult,\r\n): Array<AnthropicStreamEventData> => {\r\n state.messageStartSent = true\r\n const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens\r\n const inputTokens =\r\n (response.usage?.input_tokens ?? 0) - (inputCachedTokens ?? 0)\r\n return [\r\n {\r\n type: \"message_start\",\r\n message: {\r\n id: response.id,\r\n type: \"message\",\r\n role: \"assistant\",\r\n content: [],\r\n model: response.model,\r\n stop_reason: null,\r\n stop_sequence: null,\r\n usage: {\r\n input_tokens: inputTokens,\r\n output_tokens: 0,\r\n cache_read_input_tokens: inputCachedTokens ?? 0,\r\n },\r\n },\r\n },\r\n ]\r\n}\r\n\r\nconst openTextBlockIfNeeded = (\r\n state: ResponsesStreamState,\r\n params: {\r\n outputIndex: number\r\n contentIndex: number\r\n events: Array<AnthropicStreamEventData>\r\n },\r\n): number => {\r\n const { outputIndex, contentIndex, events } = params\r\n const key = getBlockKey(outputIndex, contentIndex)\r\n let blockIndex = state.blockIndexByKey.get(key)\r\n\r\n if (blockIndex === undefined) {\r\n blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n state.blockIndexByKey.set(key, blockIndex)\r\n }\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"text\",\r\n text: \"\",\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\nconst openThinkingBlockIfNeeded = (\r\n state: ResponsesStreamState,\r\n outputIndex: number,\r\n events: Array<AnthropicStreamEventData>,\r\n): number => {\r\n //thinking blocks has multiple summary_index, should combine into one block\r\n const summaryIndex = 0\r\n const key = getBlockKey(outputIndex, summaryIndex)\r\n let blockIndex = state.blockIndexByKey.get(key)\r\n\r\n if (blockIndex === undefined) {\r\n blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n state.blockIndexByKey.set(key, blockIndex)\r\n }\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"thinking\",\r\n thinking: \"\",\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\nconst closeBlockIfOpen = (\r\n state: ResponsesStreamState,\r\n blockIndex: number,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n if (!state.openBlocks.has(blockIndex)) {\r\n return\r\n }\r\n\r\n events.push({ type: \"content_block_stop\", index: blockIndex })\r\n state.openBlocks.delete(blockIndex)\r\n state.blockHasDelta.delete(blockIndex)\r\n}\r\n\r\nconst closeOpenBlocks = (\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n for (const blockIndex of state.openBlocks) {\r\n closeBlockIfOpen(state, blockIndex, events)\r\n }\r\n}\r\n\r\nconst closeAllOpenBlocks = (\r\n state: ResponsesStreamState,\r\n events: Array<AnthropicStreamEventData>,\r\n) => {\r\n closeOpenBlocks(state, events)\r\n\r\n state.functionCallStateByOutputIndex.clear()\r\n}\r\n\r\nexport const buildErrorEvent = (message: string): AnthropicStreamEventData => ({\r\n type: \"error\",\r\n error: {\r\n type: \"api_error\",\r\n message,\r\n },\r\n})\r\n\r\nconst getBlockKey = (outputIndex: number, contentIndex: number): string =>\r\n `${outputIndex}:${contentIndex}`\r\n\r\nconst openFunctionCallBlock = (\r\n state: ResponsesStreamState,\r\n params: {\r\n outputIndex: number\r\n toolCallId?: string\r\n name?: string\r\n events: Array<AnthropicStreamEventData>\r\n },\r\n): number => {\r\n const { outputIndex, toolCallId, name, events } = params\r\n\r\n let functionCallState = state.functionCallStateByOutputIndex.get(outputIndex)\r\n\r\n if (!functionCallState) {\r\n const blockIndex = state.nextContentBlockIndex\r\n state.nextContentBlockIndex += 1\r\n\r\n const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex}`\r\n const resolvedName = name ?? \"function\"\r\n\r\n functionCallState = {\r\n blockIndex,\r\n toolCallId: resolvedToolCallId,\r\n name: resolvedName,\r\n consecutiveWhitespaceCount: 0,\r\n }\r\n\r\n state.functionCallStateByOutputIndex.set(outputIndex, functionCallState)\r\n }\r\n\r\n const { blockIndex } = functionCallState\r\n\r\n if (!state.openBlocks.has(blockIndex)) {\r\n closeOpenBlocks(state, events)\r\n events.push({\r\n type: \"content_block_start\",\r\n index: blockIndex,\r\n content_block: {\r\n type: \"tool_use\",\r\n id: functionCallState.toolCallId,\r\n name: functionCallState.name,\r\n input: {},\r\n },\r\n })\r\n state.openBlocks.add(blockIndex)\r\n }\r\n\r\n return blockIndex\r\n}\r\n\r\ntype FunctionCallDetails = {\r\n outputIndex: number\r\n toolCallId: string\r\n name: string\r\n initialArguments?: string\r\n}\r\n\r\nconst extractFunctionCallDetails = (\r\n rawEvent: ResponseOutputItemAddedEvent,\r\n): FunctionCallDetails | undefined => {\r\n const item = rawEvent.item\r\n const itemType = item.type\r\n if (itemType !== \"function_call\") {\r\n return undefined\r\n }\r\n\r\n const outputIndex = rawEvent.output_index\r\n const toolCallId = item.call_id\r\n const name = item.name\r\n const initialArguments = item.arguments\r\n return {\r\n outputIndex,\r\n toolCallId,\r\n name,\r\n initialArguments,\r\n }\r\n}\r\n","import type {\r\n ResponseInputItem,\r\n ResponsesPayload,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\nexport const getResponsesRequestOptions = (\r\n payload: ResponsesPayload,\r\n): { vision: boolean; initiator: \"agent\" | \"user\" } => {\r\n const vision = hasVisionInput(payload)\r\n const initiator = hasAgentInitiator(payload) ? \"agent\" : \"user\"\r\n\r\n return { vision, initiator }\r\n}\r\n\r\nexport const hasAgentInitiator = (payload: ResponsesPayload): boolean => {\r\n // Refactor `isAgentCall` logic to check only the last message in the history rather than any message. This prevents valid user messages from being incorrectly flagged as agent calls due to previous assistant history, ensuring proper credit consumption for multi-turn conversations.\r\n const lastItem = getPayloadItems(payload).at(-1)\r\n if (!lastItem) {\r\n return false\r\n }\r\n if (!(\"role\" in lastItem) || !lastItem.role) {\r\n return true\r\n }\r\n const role =\r\n typeof lastItem.role === \"string\" ? lastItem.role.toLowerCase() : \"\"\r\n return role === \"assistant\"\r\n}\r\n\r\nexport const hasVisionInput = (payload: ResponsesPayload): boolean => {\r\n const values = getPayloadItems(payload)\r\n return values.some((item) => containsVisionContent(item))\r\n}\r\n\r\nconst getPayloadItems = (\r\n payload: ResponsesPayload,\r\n): Array<ResponseInputItem> => {\r\n const result: Array<ResponseInputItem> = []\r\n\r\n const { input } = payload\r\n\r\n if (Array.isArray(input)) {\r\n result.push(...input)\r\n }\r\n\r\n return result\r\n}\r\n\r\nconst containsVisionContent = (value: unknown): boolean => {\r\n if (!value) return false\r\n\r\n if (Array.isArray(value)) {\r\n return value.some((entry) => containsVisionContent(entry))\r\n }\r\n\r\n if (typeof value !== \"object\") {\r\n return false\r\n }\r\n\r\n const record = value as Record<string, unknown>\r\n const type =\r\n typeof record.type === \"string\" ? record.type.toLowerCase() : undefined\r\n\r\n if (type === \"input_image\") {\r\n return true\r\n }\r\n\r\n if (Array.isArray(record.content)) {\r\n return record.content.some((entry) => containsVisionContent(entry))\r\n }\r\n\r\n return false\r\n}\r\n","import consola from \"consola\"\r\nimport { events } from \"fetch-event-stream\"\r\n\r\nimport type {\r\n AnthropicMessagesPayload,\r\n AnthropicResponse,\r\n} from \"~/routes/messages/anthropic-types\"\r\n\r\nimport { copilotBaseUrl, copilotHeaders } from \"~/lib/api-config\"\r\nimport { HTTPError } from \"~/lib/error\"\r\nimport { state } from \"~/lib/state\"\r\n\r\nexport type MessagesStream = ReturnType<typeof events>\r\nexport type CreateMessagesReturn = AnthropicResponse | MessagesStream\r\n\r\nexport const createMessages = async (\r\n payload: AnthropicMessagesPayload,\r\n anthropicBetaHeader?: string,\r\n options?: {\r\n initiator?: \"agent\" | \"user\"\r\n },\r\n): Promise<CreateMessagesReturn> => {\r\n if (!state.copilotToken) throw new Error(\"Copilot token not found\")\r\n\r\n const enableVision = payload.messages.some(\r\n (message) =>\r\n Array.isArray(message.content)\r\n && message.content.some((block) => block.type === \"image\"),\r\n )\r\n\r\n let isInitiateRequest = false\r\n const lastMessage = payload.messages.at(-1)\r\n if (lastMessage?.role === \"user\") {\r\n isInitiateRequest =\r\n Array.isArray(lastMessage.content) ?\r\n lastMessage.content.some((block) => block.type !== \"tool_result\")\r\n : true\r\n }\r\n const initiator = options?.initiator ?? (isInitiateRequest ? \"user\" : \"agent\")\r\n\r\n const headers: Record<string, string> = {\r\n ...copilotHeaders(state, enableVision),\r\n \"X-Initiator\": initiator,\r\n }\r\n\r\n if (anthropicBetaHeader) {\r\n // Strip beta flags unsupported by Copilot API\r\n const unsupportedBetas = new Set([\r\n \"claude-code-20250219\",\r\n \"context-1m-2025-08-07\",\r\n ])\r\n const filteredBeta = anthropicBetaHeader\r\n .split(\",\")\r\n .map((item) => item.trim())\r\n .filter((item) => !unsupportedBetas.has(item))\r\n .join(\",\")\r\n if (filteredBeta) {\r\n headers[\"anthropic-beta\"] = filteredBeta\r\n }\r\n } else if (payload.thinking?.budget_tokens) {\r\n headers[\"anthropic-beta\"] = \"interleaved-thinking-2025-05-14\"\r\n }\r\n\r\n const response = await fetch(`${copilotBaseUrl(state)}/v1/messages`, {\r\n method: \"POST\",\r\n headers,\r\n body: JSON.stringify(payload),\r\n })\r\n\r\n if (!response.ok) {\r\n consola.error(\"Failed to create messages\", response)\r\n throw new HTTPError(\"Failed to create messages\", response)\r\n }\r\n\r\n if (payload.stream) {\r\n return events(response)\r\n }\r\n\r\n return (await response.json()) as AnthropicResponse\r\n}\r\n","import {\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n} from \"~/services/copilot/create-chat-completions\"\n\nimport {\n type AnthropicStreamEventData,\n type AnthropicStreamState,\n} from \"./anthropic-types\"\nimport { mapOpenAIStopReasonToAnthropic } from \"./utils\"\n\nfunction isToolBlockOpen(state: AnthropicStreamState): boolean {\n if (!state.contentBlockOpen) {\n return false\n }\n // Check if the current block index corresponds to any known tool call\n return Object.values(state.toolCalls).some(\n (tc) => tc.anthropicBlockIndex === state.contentBlockIndex,\n )\n}\n\n// Helper to create message_delta and message_stop events\nfunction createMessageDeltaEvents(\n finishReason: \"stop\" | \"length\" | \"tool_calls\" | \"content_filter\",\n usage: {\n prompt_tokens: number\n completion_tokens: number\n cached_tokens: number\n },\n): Array<AnthropicStreamEventData> {\n const stopReason = mapOpenAIStopReasonToAnthropic(finishReason)\n // Anthropic input_tokens = uncached tokens only\n // OpenAI prompt_tokens includes cached, so subtract them\n const inputTokens = usage.prompt_tokens - usage.cached_tokens\n return [\n {\n type: \"message_delta\",\n delta: {\n stop_reason: stopReason,\n stop_sequence: null,\n },\n usage: {\n input_tokens: inputTokens,\n output_tokens: usage.completion_tokens,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cached_tokens,\n },\n },\n {\n type: \"message_stop\",\n },\n ]\n}\n\n// Export for use in handler fallback\nexport function createFallbackMessageDeltaEvents(\n state: AnthropicStreamState,\n): Array<AnthropicStreamEventData> {\n // If message_delta was already sent, return empty\n if (state.messageDeltaSent) {\n return []\n }\n\n // If we have a pending finish_reason, send message_delta with whatever usage we have\n if (state.pendingFinishReason) {\n const usage = state.pendingUsage ?? {\n prompt_tokens: 0,\n completion_tokens: 0,\n cached_tokens: 0,\n }\n return createMessageDeltaEvents(state.pendingFinishReason, usage)\n }\n\n return []\n}\n\n// eslint-disable-next-line max-lines-per-function, complexity\nexport function translateChunkToAnthropicEvents(\n chunk: ChatCompletionChunk,\n state: AnthropicStreamState,\n originalModel?: string,\n): Array<AnthropicStreamEventData> {\n const events: Array<AnthropicStreamEventData> = []\n\n // Capture usage from any chunk that has it (may come before, with, or after finish_reason)\n if (chunk.usage) {\n state.pendingUsage = {\n prompt_tokens: chunk.usage.prompt_tokens,\n completion_tokens: chunk.usage.completion_tokens,\n cached_tokens: chunk.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n\n // If we already saw finish_reason but deferred message_delta, send it now\n if (state.pendingFinishReason && !state.messageDeltaSent) {\n events.push(\n ...createMessageDeltaEvents(\n state.pendingFinishReason,\n state.pendingUsage,\n ),\n )\n state.messageDeltaSent = true\n }\n }\n\n if (chunk.choices.length === 0) {\n // Empty choices chunk - usage already captured above\n return events\n }\n\n const choice = chunk.choices[0]\n const { delta } = choice\n\n if (!state.messageStartSent) {\n // Include usage in message_start for context window display\n // Use pending usage if available (captured from earlier chunks)\n const usage = state.pendingUsage ?? {\n prompt_tokens: 0,\n completion_tokens: 0,\n cached_tokens: 0,\n }\n // Anthropic input_tokens = uncached tokens only\n const inputTokens = usage.prompt_tokens - usage.cached_tokens\n events.push({\n type: \"message_start\",\n message: {\n id: chunk.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n // Use original requested model for cost calculation in Claude Code\n model: originalModel ?? chunk.model,\n stop_reason: null,\n stop_sequence: null,\n // Include usage for context window display\n // Note: output_tokens should be 0 at message_start (final count comes in message_delta)\n usage: {\n input_tokens: inputTokens,\n output_tokens: 0,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cached_tokens,\n },\n },\n })\n state.messageStartSent = true\n }\n\n if (delta.content) {\n if (isToolBlockOpen(state)) {\n // A tool block was open, so close it before starting a text block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n if (!state.contentBlockOpen) {\n events.push({\n type: \"content_block_start\",\n index: state.contentBlockIndex,\n content_block: {\n type: \"text\",\n text: \"\",\n },\n })\n state.contentBlockOpen = true\n }\n\n events.push({\n type: \"content_block_delta\",\n index: state.contentBlockIndex,\n delta: {\n type: \"text_delta\",\n text: delta.content,\n },\n })\n }\n\n if (delta.tool_calls) {\n for (const toolCall of delta.tool_calls) {\n if (toolCall.id && toolCall.function?.name) {\n // New tool call starting.\n if (state.contentBlockOpen) {\n // Close any previously open block.\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockIndex++\n state.contentBlockOpen = false\n }\n\n const anthropicBlockIndex = state.contentBlockIndex\n state.toolCalls[toolCall.index] = {\n id: toolCall.id,\n name: toolCall.function.name,\n anthropicBlockIndex,\n }\n\n events.push({\n type: \"content_block_start\",\n index: anthropicBlockIndex,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n })\n state.contentBlockOpen = true\n }\n\n if (toolCall.function?.arguments) {\n const toolCallInfo = state.toolCalls[toolCall.index]\n // Tool call can still be empty\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (toolCallInfo) {\n events.push({\n type: \"content_block_delta\",\n index: toolCallInfo.anthropicBlockIndex,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n })\n }\n }\n }\n }\n\n if (choice.finish_reason) {\n if (state.contentBlockOpen) {\n events.push({\n type: \"content_block_stop\",\n index: state.contentBlockIndex,\n })\n state.contentBlockOpen = false\n }\n\n // Check if we have usage data (from this chunk or previously captured)\n const hasUsage = chunk.usage || state.pendingUsage\n\n if (hasUsage) {\n // We have usage - send message_delta immediately\n const usage = {\n prompt_tokens:\n chunk.usage?.prompt_tokens ?? state.pendingUsage?.prompt_tokens ?? 0,\n completion_tokens:\n chunk.usage?.completion_tokens\n ?? state.pendingUsage?.completion_tokens\n ?? 0,\n cached_tokens:\n chunk.usage?.prompt_tokens_details?.cached_tokens\n ?? state.pendingUsage?.cached_tokens\n ?? 0,\n }\n\n events.push(...createMessageDeltaEvents(choice.finish_reason, usage))\n state.messageDeltaSent = true\n } else {\n // No usage yet - defer message_delta until we receive usage in a later chunk\n state.pendingFinishReason = choice.finish_reason\n }\n }\n\n return events\n}\n\n/**\n * Convert a complete OpenAI ChatCompletionResponse to Anthropic streaming events.\n * This is used when we fetch non-streaming from upstream but need to simulate\n * streaming to the client with accurate token counts.\n */\nexport function translateResponseToAnthropicEvents(\n response: ChatCompletionResponse,\n originalModel?: string,\n): Array<AnthropicStreamEventData> {\n const choice = response.choices[0]\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive check for empty choices array\n if (!choice) {\n return []\n }\n\n const promptTokens = response.usage?.prompt_tokens ?? 0\n const outputTokens = response.usage?.completion_tokens ?? 0\n const cachedTokens = response.usage?.prompt_tokens_details?.cached_tokens ?? 0\n // Anthropic input_tokens = uncached tokens only\n const inputTokens = promptTokens - cachedTokens\n\n const events: Array<AnthropicStreamEventData> = [\n createMessageStartEvent(response, {\n originalModel,\n inputTokens,\n cachedTokens,\n }),\n ]\n\n let contentBlockIndex = 0\n contentBlockIndex = addTextContentEvents(events, choice, contentBlockIndex)\n addToolCallEvents(events, choice, contentBlockIndex)\n addMessageDeltaAndStopEvents(events, choice, {\n inputTokens,\n outputTokens,\n cachedTokens,\n })\n\n return events\n}\n\ninterface MessageStartEventOptions {\n originalModel: string | undefined\n inputTokens: number\n cachedTokens: number\n}\n\nfunction createMessageStartEvent(\n response: ChatCompletionResponse,\n options: MessageStartEventOptions,\n): AnthropicStreamEventData {\n const { originalModel, inputTokens, cachedTokens } = options\n return {\n type: \"message_start\",\n message: {\n id: response.id,\n type: \"message\",\n role: \"assistant\",\n content: [],\n model: originalModel ?? response.model,\n stop_reason: null,\n stop_sequence: null,\n usage: {\n input_tokens: inputTokens,\n output_tokens: 0,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: cachedTokens,\n },\n },\n }\n}\n\nfunction addTextContentEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n contentBlockIndex: number,\n): number {\n if (choice.message.content) {\n events.push(\n {\n type: \"content_block_start\",\n index: contentBlockIndex,\n content_block: { type: \"text\", text: \"\" },\n },\n {\n type: \"content_block_delta\",\n index: contentBlockIndex,\n delta: { type: \"text_delta\", text: choice.message.content },\n },\n { type: \"content_block_stop\", index: contentBlockIndex },\n )\n return contentBlockIndex + 1\n }\n return contentBlockIndex\n}\n\nfunction addToolCallEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n startIndex: number,\n): void {\n if (!choice.message.tool_calls) return\n\n let idx = startIndex\n for (const toolCall of choice.message.tool_calls) {\n events.push(\n {\n type: \"content_block_start\",\n index: idx,\n content_block: {\n type: \"tool_use\",\n id: toolCall.id,\n name: toolCall.function.name,\n input: {},\n },\n },\n {\n type: \"content_block_delta\",\n index: idx,\n delta: {\n type: \"input_json_delta\",\n partial_json: toolCall.function.arguments,\n },\n },\n { type: \"content_block_stop\", index: idx },\n )\n idx++\n }\n}\n\ninterface UsageTokens {\n inputTokens: number\n outputTokens: number\n cachedTokens: number\n}\n\nfunction addMessageDeltaAndStopEvents(\n events: Array<AnthropicStreamEventData>,\n choice: ChatCompletionResponse[\"choices\"][0],\n usage: UsageTokens,\n): void {\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: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_creation_input_tokens: 0,\n cache_read_input_tokens: usage.cachedTokens,\n },\n },\n { type: \"message_stop\" },\n )\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 { AnthropicMessagesPayload } from \"./anthropic-types\"\r\n\r\nconst subagentMarkerPrefix = \"__SUBAGENT_MARKER__\"\r\n\r\nexport interface SubagentMarker {\r\n session_id: string\r\n agent_id: string\r\n agent_type: string\r\n}\r\n\r\nexport const parseSubagentMarkerFromFirstUser = (\r\n payload: AnthropicMessagesPayload,\r\n): SubagentMarker | null => {\r\n const firstUserMessage = payload.messages.find((msg) => msg.role === \"user\")\r\n if (!firstUserMessage || !Array.isArray(firstUserMessage.content)) {\r\n return null\r\n }\r\n\r\n for (const block of firstUserMessage.content) {\r\n if (block.type !== \"text\") {\r\n continue\r\n }\r\n\r\n const marker = parseSubagentMarkerFromSystemReminder(block.text)\r\n if (marker) {\r\n return marker\r\n }\r\n }\r\n\r\n return null\r\n}\r\n\r\nconst parseSubagentMarkerFromSystemReminder = (\r\n text: string,\r\n): SubagentMarker | null => {\r\n const startTag = \"<system-reminder>\"\r\n const endTag = \"</system-reminder>\"\r\n let searchFrom = 0\r\n\r\n while (true) {\r\n const reminderStart = text.indexOf(startTag, searchFrom)\r\n if (reminderStart === -1) {\r\n break\r\n }\r\n\r\n const contentStart = reminderStart + startTag.length\r\n const reminderEnd = text.indexOf(endTag, contentStart)\r\n if (reminderEnd === -1) {\r\n break\r\n }\r\n\r\n const reminderContent = text.slice(contentStart, reminderEnd)\r\n const markerIndex = reminderContent.indexOf(subagentMarkerPrefix)\r\n if (markerIndex === -1) {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n\r\n const markerJson = reminderContent\r\n .slice(markerIndex + subagentMarkerPrefix.length)\r\n .trim()\r\n\r\n try {\r\n const parsed = JSON.parse(markerJson) as SubagentMarker\r\n if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n\r\n return parsed\r\n } catch {\r\n searchFrom = reminderEnd + endTag.length\r\n continue\r\n }\r\n }\r\n\r\n return null\r\n}\r\n","import type { Context } from \"hono\"\n\nimport { streamSSE } from \"hono/streaming\"\n\nimport type { Model } from \"~/services/copilot/get-models\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { applyReplacementsToPayload } from \"~/lib/auto-replace\"\nimport { getReasoningEffortForModel } from \"~/lib/config\"\nimport { createHandlerLogger } from \"~/lib/logger\"\nimport { normalizeModelName } from \"~/lib/model-resolver\"\nimport { parseModelSuffix } from \"~/lib/model-suffix\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { setRequestContext } from \"~/lib/request-logger\"\nimport { state } from \"~/lib/state\"\nimport { getTokenCount } from \"~/lib/tokenizer\"\nimport {\n buildErrorEvent,\n createResponsesStreamState,\n translateResponsesStreamEvent,\n} from \"~/routes/messages/responses-stream-translation\"\nimport {\n translateAnthropicMessagesToResponsesPayload,\n translateResponsesResultToAnthropic,\n} from \"~/routes/messages/responses-translation\"\nimport { getResponsesRequestOptions } from \"~/routes/responses/utils\"\nimport {\n createChatCompletions,\n type ChatCompletionChunk,\n type ChatCompletionResponse,\n} from \"~/services/copilot/create-chat-completions\"\nimport { createMessages } from \"~/services/copilot/create-messages\"\nimport {\n createResponses,\n type ResponsesResult,\n type ResponseStreamEvent,\n} from \"~/services/copilot/create-responses\"\n\nimport {\n type AnthropicMessagesPayload,\n type AnthropicStreamState,\n type AnthropicTextBlock,\n type AnthropicToolResultBlock,\n} from \"./anthropic-types\"\nimport {\n translateToAnthropic,\n translateToOpenAI,\n} from \"./non-stream-translation\"\nimport { translateChunkToAnthropicEvents } from \"./stream-translation\"\nimport { parseSubagentMarkerFromFirstUser } from \"./subagent-marker\"\n\nconst logger = createHandlerLogger(\"messages-handler\")\n\nconst compactSystemPromptStart =\n \"You are a helpful AI assistant tasked with summarizing conversations\"\n\nexport async function handleCompletion(c: Context) {\n await checkRateLimit(state)\n\n const anthropicPayload = await c.req.json<AnthropicMessagesPayload>()\n logger.debug(\"Anthropic request payload:\", JSON.stringify(anthropicPayload))\n\n // Capture the originally requested model before any manipulation\n const requestedModel = anthropicPayload.model\n\n // Parse model suffix for reasoning effort override (e.g. \"claude-sonnet-4.6:high\")\n const { baseModel, reasoningEffort: suffixEffort } = parseModelSuffix(\n anthropicPayload.model,\n )\n // Normalize model name (e.g. \"claude-opus-4-6[1m]\" → \"claude-opus-4.6-1m\")\n anthropicPayload.model = normalizeModelName(baseModel)\n\n const subagentMarker = parseSubagentMarkerFromFirstUser(anthropicPayload)\n const initiatorOverride = subagentMarker ? \"agent\" : undefined\n if (subagentMarker) {\n logger.debug(\"Detected Subagent marker:\", JSON.stringify(subagentMarker))\n }\n\n // claude code and opencode compact request detection\n const isCompact = isCompactRequest(anthropicPayload)\n\n const anthropicBeta = c.req.header(\"anthropic-beta\")\n logger.debug(\"Anthropic Beta header:\", anthropicBeta)\n\n // Route to model variants based on client signals\n applyModelVariantRouting(anthropicPayload, anthropicBeta)\n\n if (isCompact) {\n logger.debug(\"Is compact request:\", isCompact)\n } else {\n // Merge tool_result and text blocks into tool_result to avoid consuming premium requests\n // (caused by skill invocations, edit hooks, plan or to do reminders)\n // e.g. {\"role\":\"user\",\"content\":[{\"type\":\"tool_result\",\"content\":\"Launching skill: xxx\"},{\"type\":\"text\",\"text\":\"xxx\"}]}\n // not only for claude, but also for opencode\n // compact requests are excluded from this processing\n mergeToolResultForClaude(anthropicPayload)\n }\n\n if (state.manualApprove) {\n await awaitApproval()\n }\n\n const selectedModel = state.models?.data.find(\n (m) => m.id === anthropicPayload.model,\n )\n\n // Log the requested vs routed model\n let apiType = \"ChatCompletions\"\n if (shouldUseMessagesApi(selectedModel)) {\n apiType = \"Messages\"\n } else if (shouldUseResponsesApi(selectedModel)) {\n apiType = \"Responses\"\n }\n\n // Determine effective reasoning effort for logging\n // Priority: suffix > body thinking config\n const bodyEffort = getBodyReasoningEffort(anthropicPayload)\n const effectiveEffort = suffixEffort ?? bodyEffort\n\n setRequestContext(c, {\n requestedModel,\n model: anthropicPayload.model,\n provider: apiType,\n reasoningEffort: effectiveEffort,\n })\n\n if (shouldUseMessagesApi(selectedModel)) {\n return await handleWithMessagesApi(c, anthropicPayload, {\n anthropicBetaHeader: anthropicBeta,\n initiatorOverride,\n selectedModel,\n effortOverride: suffixEffort,\n })\n }\n\n if (shouldUseResponsesApi(selectedModel)) {\n return await handleWithResponsesApi(c, anthropicPayload, {\n initiatorOverride,\n effortOverride: suffixEffort,\n })\n }\n\n return await handleWithChatCompletions(c, anthropicPayload, initiatorOverride)\n}\n\nconst RESPONSES_ENDPOINT = \"/responses\"\nconst MESSAGES_ENDPOINT = \"/v1/messages\"\n\nconst handleWithChatCompletions = async (\n c: Context,\n anthropicPayload: AnthropicMessagesPayload,\n initiatorOverride?: \"agent\" | \"user\",\n) => {\n const openAIPayload = translateToOpenAI(anthropicPayload)\n const { payload: replacedPayload, appliedRules } =\n await applyReplacementsToPayload(openAIPayload)\n const finalPayload = {\n ...replacedPayload,\n model: normalizeModelName(replacedPayload.model),\n }\n\n if (appliedRules.length > 0) {\n setRequestContext(c, { replacements: appliedRules })\n }\n\n // Calculate token count for the translated payload\n try {\n const selectedModel = state.models?.data.find(\n (m) => m.id === finalPayload.model,\n )\n if (selectedModel) {\n const tokenCount = await getTokenCount(finalPayload, selectedModel)\n setRequestContext(c, { inputTokens: tokenCount.input })\n }\n } catch {\n // Token counting is best-effort, don't fail the request\n }\n\n logger.debug(\n \"Translated OpenAI request payload:\",\n JSON.stringify(finalPayload),\n )\n\n const response = await createChatCompletions(finalPayload, {\n initiator: initiatorOverride,\n })\n\n if (isNonStreaming(response)) {\n logger.debug(\n \"Non-streaming response from Copilot:\",\n JSON.stringify(response).slice(-400),\n )\n const anthropicResponse = translateToAnthropic(response)\n logger.debug(\n \"Translated Anthropic response:\",\n JSON.stringify(anthropicResponse),\n )\n return c.json(anthropicResponse)\n }\n\n logger.debug(\"Streaming response from Copilot\")\n return streamSSE(c, async (stream) => {\n const streamState: AnthropicStreamState = {\n messageStartSent: false,\n contentBlockIndex: 0,\n contentBlockOpen: false,\n toolCalls: {},\n }\n\n for await (const rawEvent of response) {\n logger.debug(\"Copilot raw stream event:\", JSON.stringify(rawEvent))\n if (rawEvent.data === \"[DONE]\") {\n break\n }\n\n if (!rawEvent.data) {\n continue\n }\n\n const chunk = JSON.parse(rawEvent.data) as ChatCompletionChunk\n const events = translateChunkToAnthropicEvents(chunk, streamState)\n\n for (const event of events) {\n logger.debug(\"Translated Anthropic event:\", JSON.stringify(event))\n await stream.writeSSE({\n event: event.type,\n data: JSON.stringify(event),\n })\n }\n }\n })\n}\n\nconst handleWithResponsesApi = async (\n c: Context,\n anthropicPayload: AnthropicMessagesPayload,\n options?: {\n initiatorOverride?: \"agent\" | \"user\"\n effortOverride?: \"low\" | \"medium\" | \"high\" | \"xhigh\"\n },\n) => {\n const { initiatorOverride, effortOverride } = options ?? {}\n const responsesPayload = translateAnthropicMessagesToResponsesPayload(\n anthropicPayload,\n effortOverride,\n )\n logger.debug(\n \"Translated Responses payload:\",\n JSON.stringify(responsesPayload),\n )\n\n const { vision, initiator } = getResponsesRequestOptions(responsesPayload)\n const response = await createResponses(responsesPayload, {\n vision,\n initiator: initiatorOverride ?? initiator,\n })\n\n if (responsesPayload.stream && isAsyncIterable(response)) {\n logger.debug(\"Streaming response from Copilot (Responses API)\")\n return streamSSE(c, async (stream) => {\n const streamState = createResponsesStreamState()\n\n for await (const chunk of response) {\n const eventName = chunk.event\n if (eventName === \"ping\") {\n await stream.writeSSE({ event: \"ping\", data: '{\"type\":\"ping\"}' })\n continue\n }\n\n const data = chunk.data\n if (!data) {\n continue\n }\n\n logger.debug(\"Responses raw stream event:\", data)\n\n const events = translateResponsesStreamEvent(\n JSON.parse(data) as ResponseStreamEvent,\n streamState,\n )\n for (const event of events) {\n const eventData = JSON.stringify(event)\n logger.debug(\"Translated Anthropic event:\", eventData)\n await stream.writeSSE({\n event: event.type,\n data: eventData,\n })\n }\n\n if (streamState.messageCompleted) {\n logger.debug(\"Message completed, ending stream\")\n break\n }\n }\n\n if (!streamState.messageCompleted) {\n logger.warn(\n \"Responses stream ended without completion; sending error event\",\n )\n const errorEvent = buildErrorEvent(\n \"Responses stream ended without completion\",\n )\n await stream.writeSSE({\n event: errorEvent.type,\n data: JSON.stringify(errorEvent),\n })\n }\n })\n }\n\n logger.debug(\n \"Non-streaming Responses result:\",\n JSON.stringify(response).slice(-400),\n )\n const anthropicResponse = translateResponsesResultToAnthropic(\n response as ResponsesResult,\n )\n logger.debug(\n \"Translated Anthropic response:\",\n JSON.stringify(anthropicResponse),\n )\n return c.json(anthropicResponse)\n}\n\nconst handleWithMessagesApi = async (\n c: Context,\n anthropicPayload: AnthropicMessagesPayload,\n options?: {\n anthropicBetaHeader?: string\n initiatorOverride?: \"agent\" | \"user\"\n selectedModel?: Model\n effortOverride?: \"low\" | \"medium\" | \"high\" | \"xhigh\"\n },\n) => {\n const {\n anthropicBetaHeader,\n initiatorOverride,\n selectedModel,\n effortOverride,\n } = options ?? {}\n // Pre-request processing: filter thinking blocks for Claude models so only\n // valid thinking blocks are sent to the Copilot Messages API.\n for (const msg of anthropicPayload.messages) {\n if (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n msg.content = msg.content.filter((block) => {\n if (block.type !== \"thinking\") return true\n return (\n block.thinking\n && block.thinking !== \"Thinking...\"\n && block.signature\n && !block.signature.includes(\"@\")\n )\n })\n }\n }\n\n if (selectedModel?.capabilities.supports.adaptive_thinking) {\n // Only set thinking if client didn't already provide it\n if (!anthropicPayload.thinking) {\n anthropicPayload.thinking = {\n type: \"adaptive\",\n }\n }\n // Priority: suffix override > client body > config default\n const clientEffort = anthropicPayload.output_config?.effort\n anthropicPayload.output_config = {\n effort:\n effortOverride ?\n getAnthropicEffortForModel(anthropicPayload.model, effortOverride)\n : (clientEffort ?? getAnthropicEffortForModel(anthropicPayload.model)),\n }\n }\n\n logger.debug(\"Translated Messages payload:\", JSON.stringify(anthropicPayload))\n\n const response = await createMessages(anthropicPayload, anthropicBetaHeader, {\n initiator: initiatorOverride,\n })\n\n if (isAsyncIterable(response)) {\n logger.debug(\"Streaming response from Copilot (Messages API)\")\n return streamSSE(c, async (stream) => {\n for await (const event of response) {\n const eventName = event.event\n const data = event.data ?? \"\"\n logger.debug(\"Messages raw stream event:\", data)\n await stream.writeSSE({\n event: eventName,\n data,\n })\n }\n })\n }\n\n logger.debug(\n \"Non-streaming Messages result:\",\n JSON.stringify(response).slice(-400),\n )\n return c.json(response)\n}\n\n/**\n * Route to model variants based on client signals (1m context, fast mode).\n * Mutates the payload in place.\n */\nfunction applyModelVariantRouting(\n payload: AnthropicMessagesPayload,\n anthropicBeta: string | undefined,\n): void {\n // 1M context via beta header → route to -1m model variant\n if (anthropicBeta?.includes(\"context-1m\")) {\n const candidate = `${payload.model}-1m`\n if (state.models?.data.some((m) => m.id === candidate)) {\n payload.model = candidate\n }\n }\n\n // Fast mode → route to -fast model variant, strip unsupported field\n if (payload.speed === \"fast\") {\n const candidate = `${payload.model}-fast`\n if (state.models?.data.some((m) => m.id === candidate)) {\n payload.model = candidate\n }\n delete payload.speed\n }\n}\n\nconst shouldUseResponsesApi = (selectedModel: Model | undefined): boolean => {\n return (\n selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false\n )\n}\n\nconst shouldUseMessagesApi = (selectedModel: Model | undefined): boolean => {\n return (\n selectedModel?.supported_endpoints?.includes(MESSAGES_ENDPOINT) ?? false\n )\n}\n\nconst isNonStreaming = (\n response: Awaited<ReturnType<typeof createChatCompletions>>,\n): response is ChatCompletionResponse => Object.hasOwn(response, \"choices\")\n\nconst isAsyncIterable = <T>(value: unknown): value is AsyncIterable<T> =>\n Boolean(value)\n && typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n\n/**\n * Extract reasoning effort info from the Anthropic request body for logging.\n * Claude Code sends effort as `output_config.effort` (low/medium/high/max)\n * and thinking mode as `thinking.type` (enabled/adaptive).\n * When effort is \"high\" (the default), Claude Code omits output_config.effort entirely.\n */\nfunction getBodyReasoningEffort(\n payload: AnthropicMessagesPayload,\n): string | undefined {\n // No thinking config at all — no effort to report\n if (!payload.thinking && !payload.output_config?.effort) return undefined\n\n const parts: Array<string> = []\n\n // output_config.effort is the actual effort level (low/medium/high/max)\n // Claude Code omits this field when effort is \"high\" (the API default)\n const effort =\n payload.output_config?.effort ?? (payload.thinking ? \"high\" : undefined)\n if (effort) {\n parts.push(effort)\n }\n\n // thinking.type indicates the thinking mode (enabled/adaptive)\n if (payload.thinking) {\n parts.push(payload.thinking.type)\n if (payload.thinking.budget_tokens) {\n parts.push(`${payload.thinking.budget_tokens.toLocaleString()} budget`)\n }\n }\n\n return parts.length > 0 ? parts.join(\", \") : undefined\n}\n\nconst getAnthropicEffortForModel = (\n model: string,\n override?: \"low\" | \"medium\" | \"high\" | \"xhigh\",\n): \"low\" | \"medium\" | \"high\" | \"max\" => {\n const reasoningEffort = getReasoningEffortForModel(model, override)\n\n if (reasoningEffort === \"xhigh\") return \"max\"\n if (reasoningEffort === \"none\" || reasoningEffort === \"minimal\") return \"low\"\n\n return reasoningEffort\n}\n\nconst isCompactRequest = (\n anthropicPayload: AnthropicMessagesPayload,\n): boolean => {\n const system = anthropicPayload.system\n if (typeof system === \"string\") {\n return system.startsWith(compactSystemPromptStart)\n }\n if (!Array.isArray(system)) return false\n\n return system.some(\n (msg) =>\n typeof msg.text === \"string\"\n && msg.text.startsWith(compactSystemPromptStart),\n )\n}\n\nconst mergeContentWithText = (\n tr: AnthropicToolResultBlock,\n textBlock: AnthropicTextBlock,\n): AnthropicToolResultBlock => {\n if (typeof tr.content === \"string\") {\n return { ...tr, content: `${tr.content}\\n\\n${textBlock.text}` }\n }\n return {\n ...tr,\n content: [...tr.content, textBlock],\n }\n}\n\nconst mergeContentWithTexts = (\n tr: AnthropicToolResultBlock,\n textBlocks: Array<AnthropicTextBlock>,\n): AnthropicToolResultBlock => {\n if (typeof tr.content === \"string\") {\n const appendedTexts = textBlocks.map((tb) => tb.text).join(\"\\n\\n\")\n return { ...tr, content: `${tr.content}\\n\\n${appendedTexts}` }\n }\n return { ...tr, content: [...tr.content, ...textBlocks] }\n}\n\nconst mergeToolResultForClaude = (\n anthropicPayload: AnthropicMessagesPayload,\n): void => {\n for (const msg of anthropicPayload.messages) {\n if (msg.role !== \"user\" || !Array.isArray(msg.content)) continue\n\n const toolResults: Array<AnthropicToolResultBlock> = []\n const textBlocks: Array<AnthropicTextBlock> = []\n let valid = true\n\n for (const block of msg.content) {\n if (block.type === \"tool_result\") {\n toolResults.push(block)\n } else if (block.type === \"text\") {\n textBlocks.push(block)\n } else {\n valid = false\n break\n }\n }\n\n if (!valid || toolResults.length === 0 || textBlocks.length === 0) continue\n\n msg.content = mergeToolResult(toolResults, textBlocks)\n }\n}\n\nconst mergeToolResult = (\n toolResults: Array<AnthropicToolResultBlock>,\n textBlocks: Array<AnthropicTextBlock>,\n): Array<AnthropicToolResultBlock> => {\n // equal lengths -> pairwise merge\n if (toolResults.length === textBlocks.length) {\n return toolResults.map((tr, i) => mergeContentWithText(tr, textBlocks[i]))\n }\n\n // lengths differ -> append all textBlocks to the last tool_result\n const lastIndex = toolResults.length - 1\n return toolResults.map((tr, i) =>\n i === lastIndex ? mergeContentWithTexts(tr, textBlocks) : tr,\n )\n}\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\n\nimport { handleCountTokens } from \"./count-tokens-handler\"\nimport { handleCompletion } from \"./handler\"\n\nexport const messageRoutes = new Hono()\n\nmessageRoutes.post(\"/\", async (c) => {\n try {\n return await handleCompletion(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n\nmessageRoutes.post(\"/count_tokens\", async (c) => {\n try {\n return await handleCountTokens(c)\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { forwardError } from \"~/lib/error\"\nimport { generateVirtualModels } from \"~/lib/model-suffix\"\nimport { state } from \"~/lib/state\"\nimport { cacheModels } from \"~/lib/utils\"\n\nexport const modelRoutes = new Hono()\n\nmodelRoutes.get(\"/\", async (c) => {\n try {\n if (!state.models) {\n // This should be handled by startup logic, but as a fallback.\n await cacheModels()\n }\n\n // Copilot models\n const copilotModels =\n state.models?.data.map((model) => ({\n id: model.id,\n object: \"model\",\n type: \"model\",\n created: 0, // No date available from source\n created_at: new Date(0).toISOString(), // No date available from source\n owned_by: model.vendor,\n display_name: model.name,\n })) ?? []\n\n // Virtual models for reasoning effort variants (e.g. \"claude-sonnet-4.6:high\")\n const virtualModels =\n state.models ? generateVirtualModels(state.models.data) : []\n\n return c.json({\n object: \"list\",\n data: [...copilotModels, ...virtualModels],\n has_more: false,\n })\n } catch (error) {\n return await forwardError(c, error)\n }\n})\n","import { Hono } from \"hono\"\n\nimport {\n addReplacement,\n clearUserReplacements,\n getAllReplacements,\n getUserReplacements,\n removeReplacement,\n toggleReplacement,\n updateReplacement,\n} from \"~/lib/auto-replace\"\n\nexport const replacementsRoute = new Hono()\n\n// Get all replacement rules\nreplacementsRoute.get(\"/\", async (c) => {\n return c.json({\n all: await getAllReplacements(),\n user: await getUserReplacements(),\n })\n})\n\n// Add a new replacement rule\nreplacementsRoute.post(\"/\", async (c) => {\n const body = await c.req.json<{\n pattern: string\n replacement?: string\n isRegex?: boolean\n name?: string\n }>()\n\n if (!body.pattern) {\n return c.json({ error: \"Pattern is required\" }, 400)\n }\n\n const rule = await addReplacement(body.pattern, body.replacement ?? \"\", {\n isRegex: body.isRegex ?? false,\n name: body.name,\n })\n\n return c.json(rule, 201)\n})\n\n// Delete a replacement rule\nreplacementsRoute.delete(\"/:id\", async (c) => {\n const id = c.req.param(\"id\")\n const success = await removeReplacement(id)\n\n if (!success) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json({ success: true })\n})\n\n// Update a replacement rule\nreplacementsRoute.patch(\"/:id\", async (c) => {\n const id = c.req.param(\"id\")\n const body = await c.req.json<{\n name?: string\n pattern?: string\n replacement?: string\n isRegex?: boolean\n enabled?: boolean\n }>()\n\n const rule = await updateReplacement(id, body)\n\n if (!rule) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json(rule)\n})\n\n// Toggle a replacement rule\nreplacementsRoute.patch(\"/:id/toggle\", async (c) => {\n const id = c.req.param(\"id\")\n const rule = await toggleReplacement(id)\n\n if (!rule) {\n return c.json({ error: \"Replacement not found or is a system rule\" }, 404)\n }\n\n return c.json(rule)\n})\n\n// Clear all user replacements\nreplacementsRoute.delete(\"/\", async (c) => {\n await clearUserReplacements()\n return c.json({ success: true })\n})\n","/**\r\n * Stream ID Synchronization for @ai-sdk/openai compatibility\r\n *\r\n * Problem: GitHub Copilot's Responses API returns different IDs for the same\r\n * item in 'added' vs 'done' events. This breaks @ai-sdk/openai which expects\r\n * consistent IDs across the stream lifecycle.\r\n *\r\n * Errors without this fix:\r\n * - \"activeReasoningPart.summaryParts\" undefined\r\n * - \"text part not found\"\r\n *\r\n * Use case: OpenCode (AI coding assistant) using Codex models (gpt-5.2-codex)\r\n * via @ai-sdk/openai provider requires the Responses API endpoint.\r\n */\r\n\r\nimport type {\r\n ResponseOutputItemAddedEvent,\r\n ResponseOutputItemDoneEvent,\r\n ResponseStreamEvent,\r\n} from \"~/services/copilot/create-responses\"\r\n\r\ninterface StreamIdTracker {\r\n outputItems: Map<number, string>\r\n}\r\n\r\nexport const createStreamIdTracker = (): StreamIdTracker => ({\r\n outputItems: new Map(),\r\n})\r\n\r\nexport const fixStreamIds = (\r\n data: string,\r\n event: string | undefined,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n if (!data) return data\r\n const parsed = JSON.parse(data) as ResponseStreamEvent\r\n switch (event) {\r\n case \"response.output_item.added\": {\r\n return handleOutputItemAdded(\r\n parsed as ResponseOutputItemAddedEvent,\r\n tracker,\r\n )\r\n }\r\n case \"response.output_item.done\": {\r\n return handleOutputItemDone(\r\n parsed as ResponseOutputItemDoneEvent,\r\n tracker,\r\n )\r\n }\r\n default: {\r\n return handleItemId(parsed, tracker)\r\n }\r\n }\r\n}\r\n\r\nconst handleOutputItemAdded = (\r\n parsed: ResponseOutputItemAddedEvent,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n if (!parsed.item.id) {\r\n let randomSuffix = \"\"\r\n while (randomSuffix.length < 16) {\r\n randomSuffix += Math.random().toString(36).slice(2)\r\n }\r\n parsed.item.id = `oi_${parsed.output_index}_${randomSuffix.slice(0, 16)}`\r\n }\r\n\r\n const outputIndex = parsed.output_index\r\n tracker.outputItems.set(outputIndex, parsed.item.id)\r\n return JSON.stringify(parsed)\r\n}\r\n\r\nconst handleOutputItemDone = (\r\n parsed: ResponseOutputItemDoneEvent,\r\n tracker: StreamIdTracker,\r\n): string => {\r\n const outputIndex = parsed.output_index\r\n const originalId = tracker.outputItems.get(outputIndex)\r\n if (originalId) {\r\n parsed.item.id = originalId\r\n }\r\n return JSON.stringify(parsed)\r\n}\r\n\r\nconst handleItemId = (\r\n parsed: ResponseStreamEvent & { output_index?: number; item_id?: string },\r\n tracker: StreamIdTracker,\r\n): string => {\r\n const outputIndex = parsed.output_index\r\n if (outputIndex !== undefined) {\r\n const itemId = tracker.outputItems.get(outputIndex)\r\n if (itemId) {\r\n parsed.item_id = itemId\r\n }\r\n }\r\n return JSON.stringify(parsed)\r\n}\r\n","import type { Context } from \"hono\"\n\nimport { streamSSE } from \"hono/streaming\"\n\nimport { awaitApproval } from \"~/lib/approval\"\nimport { getConfig } from \"~/lib/config\"\nimport { createHandlerLogger } from \"~/lib/logger\"\nimport { parseModelSuffix } from \"~/lib/model-suffix\"\nimport { checkRateLimit } from \"~/lib/rate-limit\"\nimport { setRequestContext } from \"~/lib/request-logger\"\nimport { state } from \"~/lib/state\"\nimport {\n createResponses,\n type ResponsesPayload,\n type ResponsesResult,\n} from \"~/services/copilot/create-responses\"\n\nimport { createStreamIdTracker, fixStreamIds } from \"./stream-id-sync\"\nimport { getResponsesRequestOptions } from \"./utils\"\n\nconst logger = createHandlerLogger(\"responses-handler\")\n\nconst RESPONSES_ENDPOINT = \"/responses\"\n\ntype ResponsesReasoningEffort = NonNullable<\n NonNullable<ResponsesPayload[\"reasoning\"]>[\"effort\"]\n>\n\nfunction isResponsesReasoningEffort(\n value: unknown,\n): value is ResponsesReasoningEffort {\n return (\n value === \"none\"\n || value === \"minimal\"\n || value === \"low\"\n || value === \"medium\"\n || value === \"high\"\n || value === \"xhigh\"\n )\n}\n\nfunction normalizeResponsesReasoning(\n payload: ResponsesPayload,\n suffixEffort?: \"low\" | \"medium\" | \"high\" | \"xhigh\",\n): ResponsesReasoningEffort | undefined {\n // Accept OpenAI-compatible top-level aliases and normalize to reasoning.effort\n const topLevelEffortRaw = payload.reasoningEffort ?? payload.reasoning_effort\n const topLevelEffort =\n isResponsesReasoningEffort(topLevelEffortRaw) ? topLevelEffortRaw : (\n undefined\n )\n\n if (topLevelEffort) {\n payload.reasoning =\n payload.reasoning ?\n {\n ...payload.reasoning,\n effort: payload.reasoning.effort ?? topLevelEffort,\n }\n : { effort: topLevelEffort }\n }\n delete payload.reasoningEffort\n delete payload.reasoning_effort\n\n if (suffixEffort) {\n payload.reasoning =\n payload.reasoning ?\n {\n ...payload.reasoning,\n effort: suffixEffort,\n }\n : { effort: suffixEffort }\n }\n\n return payload.reasoning?.effort ?? undefined\n}\n\nexport const handleResponses = async (c: Context) => {\n await checkRateLimit(state)\n\n const payload = await c.req.json<ResponsesPayload>()\n\n // Capture the originally requested model before any manipulation\n const requestedModel = payload.model\n\n // Parse model suffix and apply reasoning effort override (e.g. \"gpt-5.3-codex:high\")\n const { baseModel, reasoningEffort: suffixEffort } = parseModelSuffix(\n payload.model,\n )\n payload.model = baseModel\n const effectiveEffort = normalizeResponsesReasoning(payload, suffixEffort)\n\n setRequestContext(c, {\n requestedModel,\n provider: \"Responses\",\n model: payload.model,\n reasoningEffort: effectiveEffort,\n })\n logger.debug(\"Responses request payload:\", JSON.stringify(payload))\n\n useFunctionApplyPatch(payload)\n\n // Remove web_search tool as it's not supported by GitHub Copilot\n removeWebSearchTool(payload)\n\n const selectedModel = state.models?.data.find(\n (model) => model.id === payload.model,\n )\n const supportsResponses =\n selectedModel?.supported_endpoints?.includes(RESPONSES_ENDPOINT) ?? false\n\n if (!supportsResponses) {\n return c.json(\n {\n error: {\n message:\n \"This model does not support the responses endpoint. Please choose a different model.\",\n type: \"invalid_request_error\",\n },\n },\n 400,\n )\n }\n\n const { vision, initiator } = getResponsesRequestOptions(payload)\n\n if (state.manualApprove) {\n await awaitApproval()\n }\n\n const response = await createResponses(payload, { vision, initiator })\n\n if (isStreamingRequested(payload) && isAsyncIterable(response)) {\n logger.debug(\"Forwarding native Responses stream\")\n return streamSSE(c, async (stream) => {\n const idTracker = createStreamIdTracker()\n\n for await (const chunk of response) {\n logger.debug(\"Responses stream chunk:\", JSON.stringify(chunk))\n\n const processedData = fixStreamIds(\n (chunk as { data?: string }).data ?? \"\",\n (chunk as { event?: string }).event,\n idTracker,\n )\n\n await stream.writeSSE({\n id: (chunk as { id?: string }).id,\n event: (chunk as { event?: string }).event,\n data: processedData,\n })\n }\n })\n }\n\n logger.debug(\n \"Forwarding native Responses result:\",\n JSON.stringify(response).slice(-400),\n )\n return c.json(response as ResponsesResult)\n}\n\nconst isAsyncIterable = <T>(value: unknown): value is AsyncIterable<T> =>\n Boolean(value)\n && typeof (value as AsyncIterable<T>)[Symbol.asyncIterator] === \"function\"\n\nconst isStreamingRequested = (payload: ResponsesPayload): boolean =>\n Boolean(payload.stream)\n\nconst useFunctionApplyPatch = (payload: ResponsesPayload): void => {\n const config = getConfig()\n const useFunctionApplyPatch = config.useFunctionApplyPatch ?? true\n if (useFunctionApplyPatch) {\n logger.debug(\"Using function tool apply_patch for responses\")\n if (Array.isArray(payload.tools)) {\n const toolsArr = payload.tools\n for (let i = 0; i < toolsArr.length; i++) {\n const t = toolsArr[i]\n if (t.type === \"custom\" && t.name === \"apply_patch\") {\n toolsArr[i] = {\n type: \"function\",\n name: t.name,\n description: \"Use the `apply_patch` tool to edit files\",\n parameters: {\n type: \"object\",\n properties: {\n input: {\n type: \"string\",\n description: \"The entire contents of the apply_patch command\",\n },\n },\n required: [\"input\"],\n },\n strict: false,\n }\n }\n }\n }\n }\n}\n\nconst removeWebSearchTool = (payload: ResponsesPayload): void => {\n if (!Array.isArray(payload.tools) || payload.tools.length === 0) return\n\n payload.tools = payload.tools.filter((t) => {\n return t.type !== \"web_search\"\n })\n}\n","import { Hono } from \"hono\"\r\n\r\nimport { forwardError } from \"~/lib/error\"\r\n\r\nimport { handleResponses } from \"./handler\"\r\n\r\nexport const responsesRoutes = new Hono()\r\n\r\nresponsesRoutes.post(\"/\", async (c) => {\r\n try {\r\n return await handleResponses(c)\r\n } catch (error) {\r\n return await forwardError(c, error)\r\n }\r\n})\r\n","import { Hono } from \"hono\"\n\nimport { state } from \"~/lib/state\"\n\nexport const tokenRoute = new Hono()\n\ntokenRoute.get(\"/\", (c) => {\n try {\n return c.json({\n token: state.copilotToken,\n })\n } catch (error) {\n console.error(\"Error fetching token:\", error)\n return c.json({ error: \"Failed to fetch token\", token: null }, 500)\n }\n})\n","import { Hono } from \"hono\"\n\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\n\nexport const usageRoute = new Hono()\n\nusageRoute.get(\"/\", async (c) => {\n try {\n const usage = await getCopilotUsage()\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","import { Hono } from \"hono\"\nimport { cors } from \"hono/cors\"\n\nimport { apiKeyGuard } from \"./lib/api-key-guard\"\nimport { createAuthMiddleware } from \"./lib/request-auth\"\nimport { requestLogger } from \"./lib/request-logger\"\nimport { completionRoutes } from \"./routes/chat-completions/route\"\nimport { embeddingRoutes } from \"./routes/embeddings/route\"\nimport { messageRoutes } from \"./routes/messages/route\"\nimport { modelRoutes } from \"./routes/models/route\"\nimport { replacementsRoute } from \"./routes/replacements/route\"\nimport { responsesRoutes } from \"./routes/responses/route\"\nimport { tokenRoute } from \"./routes/token/route\"\nimport { usageRoute } from \"./routes/usage/route\"\n\nexport const server = new Hono()\n\nserver.use(apiKeyGuard)\nserver.use(requestLogger)\nserver.use(cors())\nserver.use(\"*\", createAuthMiddleware())\n\nserver.get(\"/\", (c) => c.text(\"Server running\"))\n\nserver.route(\"/chat/completions\", completionRoutes)\nserver.route(\"/models\", modelRoutes)\nserver.route(\"/embeddings\", embeddingRoutes)\nserver.route(\"/usage\", usageRoute)\nserver.route(\"/token\", tokenRoute)\nserver.route(\"/replacements\", replacementsRoute)\nserver.route(\"/responses\", responsesRoutes)\n\n// Compatibility with tools that expect v1/ prefix\nserver.route(\"/v1/chat/completions\", completionRoutes)\nserver.route(\"/v1/models\", modelRoutes)\nserver.route(\"/v1/embeddings\", embeddingRoutes)\nserver.route(\"/v1/responses\", responsesRoutes)\n\n// Anthropic compatible endpoints\nserver.route(\"/v1/messages\", messageRoutes)\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport clipboard from \"clipboardy\"\nimport consola from \"consola\"\nimport { serve, type ServerHandler } from \"srvx\"\nimport invariant from \"tiny-invariant\"\n\nimport packageJson from \"../package.json\" with { type: \"json\" }\nimport { mergeConfigWithDefaults } from \"./lib/config\"\nimport { generateVirtualModels } from \"./lib/model-suffix\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { setupCopilotToken, setupGitHubToken } from \"./lib/token\"\nimport { cacheModels, cacheVSCodeVersion } from \"./lib/utils\"\nimport { server } from \"./server\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n insecure: boolean\n debug: boolean\n apiKeyAuth?: string\n host?: string\n}\n\nfunction getAllModelIds(): Array<string> {\n const baseModelIds = state.models?.data.map((model) => model.id) ?? []\n const virtualModelIds =\n state.models ?\n generateVirtualModels(state.models.data).map((model) => model.id)\n : []\n return [...baseModelIds, ...virtualModelIds]\n}\n\nexport async function runServer(options: RunServerOptions): Promise<void> {\n consola.info(`copilot-api v${packageJson.version}`)\n\n if (options.insecure) {\n // Disable SSL certificate verification globally\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = \"0\"\n consola.warn(\"SSL certificate verification disabled (insecure mode)\")\n }\n\n if (options.proxyEnv) {\n initProxyFromEnv()\n }\n\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.accountType = options.accountType\n if (options.accountType !== \"individual\") {\n consola.info(`Using ${options.accountType} plan GitHub account`)\n }\n\n state.manualApprove = options.manual\n state.rateLimitSeconds = options.rateLimit\n state.rateLimitWait = options.rateLimitWait\n state.showToken = options.showToken\n state.debug = options.debug\n state.verbose = options.verbose\n state.apiKeyAuth = options.apiKeyAuth\n\n if (options.apiKeyAuth)\n consola.info(\n \"API key authentication enabled - unauthorized requests will be silently dropped\",\n )\n if (options.host) consola.info(`Binding to host: ${options.host}`)\n\n if (options.debug) {\n consola.info(\"Debug mode enabled - raw HTTP requests will be logged\")\n }\n\n await ensurePaths()\n mergeConfigWithDefaults()\n await cacheVSCodeVersion()\n\n if (options.githubToken) {\n state.githubToken = options.githubToken\n consola.info(\"Using provided GitHub token\")\n } else {\n await setupGitHubToken()\n }\n\n await setupCopilotToken()\n await cacheModels()\n\n const allModelIds = getAllModelIds()\n\n consola.info(\n `Available models: \\n${allModelIds.map((id) => `- ${id}`).join(\"\\n\")}`,\n )\n\n const serverUrl = `http://${options.host ?? \"localhost\"}:${options.port}`\n\n if (options.claudeCode) {\n invariant(state.models, \"Models should be loaded by now\")\n\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: allModelIds,\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n \"Select a small model to use with Claude Code\",\n {\n type: \"select\",\n options: allModelIds,\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n },\n \"claude\",\n )\n\n try {\n clipboard.writeSync(command)\n consola.success(\"Copied Claude Code command to clipboard!\")\n } catch {\n consola.warn(\n \"Failed to copy to clipboard. Here is the Claude Code command:\",\n )\n consola.log(command)\n }\n }\n\n consola.box(\n `🌐 Usage Viewer: https://ericc-ch.github.io/copilot-api?endpoint=${serverUrl}/usage`,\n )\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n hostname: options.host,\n // Increase idle timeout for long-running requests (e.g. Claude Code compact)\n // Bun default is 10s which is too short\n bun: {\n idleTimeout: 255, // max value in seconds (4m 15s)\n },\n })\n}\n\n/**\n * Resolve --api-key-auth value: use provided value, fall back to env, or error if flag used without value.\n */\nfunction resolveApiKeyAuth(cliValue: string | undefined): string | undefined {\n if (cliValue === undefined) return undefined\n\n // If a non-empty value was provided via CLI, use it\n if (cliValue !== \"\" && cliValue !== \"true\") return cliValue\n\n // Flag was provided but no value — fall back to env\n const envValue = process.env.COPILOT_API_KEY_AUTH\n if (envValue) return envValue\n\n consola.error(\n \"--api-key-auth requires a value or COPILOT_API_KEY_AUTH environment variable\",\n )\n process.exit(1)\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the Copilot API server\",\n },\n args: {\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port to listen on\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type to use (individual, business, enterprise)\",\n },\n manual: {\n type: \"boolean\",\n default: false,\n description: \"Enable manual request approval\",\n },\n \"rate-limit\": {\n alias: \"r\",\n type: \"string\",\n description: \"Rate limit in seconds between requests\",\n },\n wait: {\n alias: \"w\",\n type: \"boolean\",\n default: false,\n description:\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description:\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\n },\n \"claude-code\": {\n alias: \"c\",\n type: \"boolean\",\n default: false,\n description:\n \"Generate a command to launch Claude Code with Copilot API config\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n insecure: {\n type: \"boolean\",\n default: false,\n description:\n \"Disable SSL certificate verification (for corporate proxies with self-signed certs)\",\n },\n debug: {\n alias: \"d\",\n type: \"boolean\",\n default: false,\n description:\n \"Log raw HTTP requests received by the server (headers, method, path)\",\n },\n \"api-key-auth\": {\n type: \"string\",\n description:\n \"API key for incoming request authentication. Requests with mismatched keys are silently dropped.\",\n },\n host: {\n type: \"string\",\n description:\n \"Hostname/IP to bind the server to (e.g., 0.0.0.0 for all interfaces)\",\n },\n },\n run({ args }) {\n const rateLimitRaw = args[\"rate-limit\"]\n const rateLimit =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args[\"account-type\"],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args[\"github-token\"],\n claudeCode: args[\"claude-code\"],\n showToken: args[\"show-token\"],\n proxyEnv: args[\"proxy-env\"],\n insecure: args.insecure,\n debug: args.debug,\n apiKeyAuth: resolveApiKeyAuth(args[\"api-key-auth\"]),\n host: args.host,\n })\n },\n})\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain } from \"citty\"\n\nimport packageJson from \"../package.json\" with { type: \"json\" }\nimport { auth } from \"./auth\"\nimport { checkUsage } from \"./check-usage\"\nimport { config } from \"./config\"\nimport { debug } from \"./debug\"\nimport { start } from \"./start\"\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api\",\n version: packageJson.version,\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, \"check-usage\": checkUsage, debug, config },\n})\n\nawait runMain(main)\n"],"mappings":"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"}