@nick3/copilot-api 1.9.15 → 1.10.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -7
- package/README.zh-CN.md +55 -6
- package/dist/{account-DjCbqJ2Q.js → account-COtMmvzU.js} +2 -2
- package/dist/{account-DjCbqJ2Q.js.map → account-COtMmvzU.js.map} +1 -1
- package/dist/admin/assets/{index-BRnD4-DB.js → index-DG4TRVMu.js} +36 -36
- package/dist/admin/index.html +1 -1
- package/dist/{auth--I1utaB6.js → auth-B0y-2njL.js} +3 -3
- package/dist/{auth--I1utaB6.js.map → auth-B0y-2njL.js.map} +1 -1
- package/dist/{check-usage-DHvjdha4.js → check-usage-DdevqHE5.js} +3 -3
- package/dist/{check-usage-DHvjdha4.js.map → check-usage-DdevqHE5.js.map} +1 -1
- package/dist/{get-copilot-token-ZbmbVF0I.js → get-copilot-token-8Rm-rVsp.js} +2 -2
- package/dist/{get-copilot-token-ZbmbVF0I.js.map → get-copilot-token-8Rm-rVsp.js.map} +1 -1
- package/dist/main.js +6 -4
- package/dist/main.js.map +1 -1
- package/dist/mcp-9Hgepkc5.js +37 -0
- package/dist/mcp-9Hgepkc5.js.map +1 -0
- package/dist/{poll-access-token-CIPDXrcm.js → poll-access-token-BAgM2-7k.js} +62 -6
- package/dist/poll-access-token-BAgM2-7k.js.map +1 -0
- package/dist/{quota-refresh-scheduler-runtime-XD2fDa2K.js → proxy-YVh74m0I.js} +67 -8
- package/dist/proxy-YVh74m0I.js.map +1 -0
- package/dist/{request-outbound-Cy6huWjK.js → request-outbound-BJjWS_jF.js} +1 -1
- package/dist/{request-outbound-CxvpSkOn.js → request-outbound-Pu1kp2x8.js} +3 -1
- package/dist/request-outbound-Pu1kp2x8.js.map +1 -0
- package/dist/{server-BDCnb3Ao.js → server-DmDAepfa.js} +667 -77
- package/dist/server-DmDAepfa.js.map +1 -0
- package/dist/{start-DkBnp9d8.js → start-D37Bi12h.js} +5 -52
- package/dist/start-D37Bi12h.js.map +1 -0
- package/dist/tool-search-BrN7M0Dd.js +110 -0
- package/dist/tool-search-BrN7M0Dd.js.map +1 -0
- package/package.json +3 -6
- package/dist/poll-access-token-CIPDXrcm.js.map +0 -1
- package/dist/quota-refresh-scheduler-runtime-XD2fDa2K.js.map +0 -1
- package/dist/request-outbound-CxvpSkOn.js.map +0 -1
- package/dist/server-BDCnb3Ao.js.map +0 -1
- package/dist/start-DkBnp9d8.js.map +0 -1
|
@@ -1,60 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { h as saveAccountToken, n as parseAccountType, r as addAccountToRegistry } from "./account-
|
|
1
|
+
import { A as state, F as initOpencodeVersion, a as cacheVsCodeSessionId, h as getDeviceCode, i as cacheVsCodeDeviceId, m as getGitHubUser, n as cacheMacMachineId, r as cacheVSCodeVersion, t as pollAccessToken } from "./poll-access-token-BAgM2-7k.js";
|
|
2
|
+
import { h as saveAccountToken, n as parseAccountType, r as addAccountToRegistry } from "./account-COtMmvzU.js";
|
|
3
3
|
import { r as ensurePaths } from "./paths-CclKwouX.js";
|
|
4
|
-
import {
|
|
4
|
+
import { A as getModelRefreshIntervalMs, P as isAccountAffinityEnabled, V as mergeConfigWithDefaults, a as stopQuotaRefreshScheduler, c as applySharedSessionAffinityRetention, i as startQuotaRefreshSchedulerFromConfig, n as initProxyFromEnv, r as registerQuotaRefreshSchedulerShutdownCleanup, s as accountsManager } from "./proxy-YVh74m0I.js";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
6
6
|
import consola from "consola";
|
|
7
7
|
import { execSync } from "node:child_process";
|
|
8
8
|
import clipboard from "clipboardy";
|
|
9
9
|
import { serve } from "srvx";
|
|
10
|
-
import { getProxyForUrl } from "proxy-from-env";
|
|
11
|
-
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
12
10
|
import process$1 from "node:process";
|
|
13
|
-
//#region src/lib/proxy.ts
|
|
14
|
-
function initProxyFromEnv() {
|
|
15
|
-
if (typeof Bun !== "undefined") return;
|
|
16
|
-
try {
|
|
17
|
-
const direct = new Agent();
|
|
18
|
-
const proxies = /* @__PURE__ */ new Map();
|
|
19
|
-
setGlobalDispatcher({
|
|
20
|
-
dispatch(options, handler) {
|
|
21
|
-
try {
|
|
22
|
-
const origin = typeof options.origin === "string" ? new URL(options.origin) : options.origin;
|
|
23
|
-
const raw = getProxyForUrl(origin.toString());
|
|
24
|
-
const proxyUrl = raw && raw.length > 0 ? raw : void 0;
|
|
25
|
-
if (!proxyUrl) {
|
|
26
|
-
consola.debug(`HTTP proxy bypass: ${origin.hostname}`);
|
|
27
|
-
return direct.dispatch(options, handler);
|
|
28
|
-
}
|
|
29
|
-
let agent = proxies.get(proxyUrl);
|
|
30
|
-
if (!agent) {
|
|
31
|
-
agent = new ProxyAgent(proxyUrl);
|
|
32
|
-
proxies.set(proxyUrl, agent);
|
|
33
|
-
}
|
|
34
|
-
let label = proxyUrl;
|
|
35
|
-
try {
|
|
36
|
-
const u = new URL(proxyUrl);
|
|
37
|
-
label = `${u.protocol}//${u.host}`;
|
|
38
|
-
} catch {}
|
|
39
|
-
consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`);
|
|
40
|
-
return agent.dispatch(options, handler);
|
|
41
|
-
} catch {
|
|
42
|
-
return direct.dispatch(options, handler);
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
close() {
|
|
46
|
-
return direct.close();
|
|
47
|
-
},
|
|
48
|
-
destroy() {
|
|
49
|
-
return direct.destroy();
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
consola.debug("HTTP proxy configured from environment (per-URL)");
|
|
53
|
-
} catch (err) {
|
|
54
|
-
consola.debug("Proxy setup skipped:", err);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
//#endregion
|
|
58
11
|
//#region src/lib/shell.ts
|
|
59
12
|
function getShell() {
|
|
60
13
|
const { platform, ppid, env } = process$1;
|
|
@@ -216,7 +169,7 @@ async function runServer(options) {
|
|
|
216
169
|
await setupClaudeCode(models, serverUrl);
|
|
217
170
|
}
|
|
218
171
|
consola.box(`🌐 Admin UI: ${serverUrl}/admin`);
|
|
219
|
-
const { server } = await import("./server-
|
|
172
|
+
const { server } = await import("./server-DmDAepfa.js");
|
|
220
173
|
serve({
|
|
221
174
|
fetch: server.fetch,
|
|
222
175
|
port: options.port,
|
|
@@ -318,4 +271,4 @@ const start = defineCommand({
|
|
|
318
271
|
//#endregion
|
|
319
272
|
export { start };
|
|
320
273
|
|
|
321
|
-
//# sourceMappingURL=start-
|
|
274
|
+
//# sourceMappingURL=start-D37Bi12h.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-D37Bi12h.js","names":["process"],"sources":["../src/lib/shell.ts","../src/start.ts"],"sourcesContent":["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","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport clipboard from \"clipboardy\"\nimport consola from \"consola\"\nimport { serve } from \"srvx\"\n\nimport {\n registerQuotaRefreshSchedulerShutdownCleanup,\n startQuotaRefreshSchedulerFromConfig,\n stopQuotaRefreshScheduler,\n} from \"~/lib/quota-refresh-scheduler-runtime\"\n\nimport { accountsManager } from \"./lib/accounts-manager\"\nimport { addAccountToRegistry, saveAccountToken } from \"./lib/accounts-registry\"\nimport {\n getModelRefreshIntervalMs,\n isAccountAffinityEnabled,\n mergeConfigWithDefaults,\n} from \"./lib/config\"\nimport { initOpencodeVersion } from \"./lib/opencode\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { applySharedSessionAffinityRetention } from \"./lib/session-affinity-store\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { parseAccountType, type AccountType } from \"./lib/types/account\"\nimport {\n cacheMacMachineId,\n cacheVSCodeVersion,\n cacheVsCodeSessionId,\n cacheVsCodeDeviceId,\n} from \"./lib/utils\"\nimport { getDeviceCode } from \"./services/github/get-device-code\"\nimport { getGitHubUser } from \"./services/github/get-user\"\nimport { pollAccessToken } from \"./services/github/poll-access-token\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: AccountType\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n skipAuth: boolean\n}\n\n/**\n * Run the interactive authentication flow to add a new account.\n * Called automatically when no accounts are found.\n */\nasync function runAuthFlow(accountType: AccountType): Promise<void> {\n consola.warn(\"No accounts found. Starting authentication flow...\")\n\n // Start device code flow\n const deviceResponse = await getDeviceCode()\n consola.info(\n `Please enter the code \"${deviceResponse.user_code}\" at ${deviceResponse.verification_uri}`,\n )\n\n // Poll for access token\n const token = await pollAccessToken(deviceResponse)\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n\n // Get user info to determine account ID\n const user = await getGitHubUser({\n githubToken: token,\n accountType,\n })\n const accountId = user.login\n\n // Save token and add to registry\n await saveAccountToken(accountId, token)\n await addAccountToRegistry({\n id: accountId,\n accountType,\n addedAt: Date.now(),\n })\n\n consola.success(`Account \"${accountId}\" added successfully!`)\n}\n\nfunction logClaudeCodeTip(): void {\n consola.log(\n \"\\n💡 Tip: The --claude-code flag simply generates a clipboard command for launching Claude Code. \\n\"\n + \"All models remain fully accessible without this flag, just configure the model ID directly in your settings.json file.\",\n )\n}\n\ntype AvailableModels = NonNullable<\n ReturnType<typeof accountsManager.getFirstAccountModels>\n>\n\nasync function setupClaudeCode(\n models: AvailableModels,\n serverUrl: string,\n): Promise<void> {\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: models.data.map((model) => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n \"Select a small model to use with Claude Code\",\n {\n type: \"select\",\n options: models.data.map((model) => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n CLAUDE_CODE_ATTRIBUTION_HEADER: \"0\",\n CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: \"false\",\n CLAUDE_CODE_DISABLE_TERMINAL_TITLE: \"true\",\n CLAUDE_CODE_ENABLE_AWAY_SUMMARY: \"0\",\n CLAUDE_PLUGIN_ENABLE_QUESTION_RULES: \"true\",\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\nexport async function runServer(options: RunServerOptions): Promise<void> {\n // Work around unjs/consola#357 until a release includes PR #359.\n consola.options.throttle = 0\n\n // Ensure config is merged with defaults at startup\n mergeConfigWithDefaults()\n accountsManager.setAccountAffinityEnabled(isAccountAffinityEnabled())\n accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs())\n\n await initOpencodeVersion()\n\n if (options.proxyEnv) {\n initProxyFromEnv()\n }\n\n state.verbose = options.verbose\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\n await ensurePaths()\n applySharedSessionAffinityRetention()\n await cacheVSCodeVersion()\n cacheMacMachineId()\n cacheVsCodeSessionId()\n await cacheVsCodeDeviceId()\n\n // Initialize accounts manager with VS Code version\n await accountsManager.initialize(state.vsCodeVersion)\n\n // If --github-token is provided, set it as a temporary (high priority) account\n if (options.githubToken) {\n await accountsManager.setTemporaryAccount(\n options.githubToken,\n options.accountType,\n )\n consola.info(\"Using provided GitHub token as temporary account\")\n }\n\n // Check if we have any accounts, if not, start the auth flow\n if (!accountsManager.hasAccounts()) {\n if (options.skipAuth) {\n consola.warn(\n \"No accounts found. Skipping auth flow (--skip-auth). Add accounts via the Admin UI.\",\n )\n } else {\n try {\n await runAuthFlow(options.accountType)\n\n // Re-initialize accounts manager with the new account\n accountsManager.shutdown()\n stopQuotaRefreshScheduler()\n await accountsManager.initialize(state.vsCodeVersion)\n accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs())\n } catch (error) {\n consola.error(\"Failed to add account:\", error)\n process.exit(1)\n }\n }\n }\n\n startQuotaRefreshSchedulerFromConfig()\n registerQuotaRefreshSchedulerShutdownCleanup()\n\n // Get models from the first available account\n const models = accountsManager.getFirstAccountModels()\n\n consola.info(\n `Available models: \\n${models?.data.map((model) => `- ${model.id}`).join(\"\\n\") ?? \"(no models loaded)\"}`,\n )\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n logClaudeCodeTip()\n if (!models?.data.length) {\n consola.error(\n \"Claude Code requires available models. Add an account via the Admin UI or remove --claude-code.\",\n )\n process.exit(1)\n }\n await setupClaudeCode(models, serverUrl)\n }\n\n consola.box(`🌐 Admin UI: ${serverUrl}/admin`)\n\n const { server } = await import(\"./server\")\n\n serve({\n fetch: server.fetch,\n port: options.port,\n bun: {\n idleTimeout: 0,\n },\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the Copilot API server\",\n },\n args: {\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port to listen on\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type to use (individual, business, enterprise)\",\n },\n manual: {\n type: \"boolean\",\n default: false,\n description: \"Enable manual request approval\",\n },\n \"rate-limit\": {\n alias: \"r\",\n type: \"string\",\n description: \"Rate limit in seconds between requests\",\n },\n wait: {\n alias: \"w\",\n type: \"boolean\",\n default: false,\n description:\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description:\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\n },\n \"claude-code\": {\n alias: \"c\",\n type: \"boolean\",\n default: false,\n description:\n \"Generate a command to launch Claude Code with Copilot API config\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n \"skip-auth\": {\n type: \"boolean\",\n default: false,\n description:\n \"Skip the initial CLI auth flow when no accounts are found. Use this to add accounts via the Admin UI instead.\",\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 let accountType: AccountType\n try {\n accountType = parseAccountType(args[\"account-type\"])\n } catch (error) {\n consola.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType,\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 skipAuth: args[\"skip-auth\"],\n })\n },\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
//#region src/lib/tool-search.ts
|
|
2
|
+
const BRIDGE_TOOL_SEARCH_NAME = "mcp__tool_search__search";
|
|
3
|
+
const BRIDGE_TOOL_SEARCH_ALIASES = [
|
|
4
|
+
BRIDGE_TOOL_SEARCH_NAME,
|
|
5
|
+
"tool_search_search",
|
|
6
|
+
"mcp__plugin_tool-search_tool_search__search"
|
|
7
|
+
];
|
|
8
|
+
const MCP_TOOL_SEARCH_SENTINEL_TYPE = "copilot_api_tool_search";
|
|
9
|
+
const alwaysLoadedToolNameSet = new Set([
|
|
10
|
+
"Agent",
|
|
11
|
+
"AskUserQuestion",
|
|
12
|
+
"Bash",
|
|
13
|
+
"Edit",
|
|
14
|
+
"EnterPlanMode",
|
|
15
|
+
"ExitPlanMode",
|
|
16
|
+
"Glob",
|
|
17
|
+
"Grep",
|
|
18
|
+
"Read",
|
|
19
|
+
"Skill",
|
|
20
|
+
"TodoWrite",
|
|
21
|
+
"ToolSearch",
|
|
22
|
+
"WebFetch",
|
|
23
|
+
"Write",
|
|
24
|
+
"apply_patch",
|
|
25
|
+
"bash",
|
|
26
|
+
"glob",
|
|
27
|
+
"grep",
|
|
28
|
+
"plan_exit",
|
|
29
|
+
"question",
|
|
30
|
+
"read",
|
|
31
|
+
"skill",
|
|
32
|
+
"task",
|
|
33
|
+
"todowrite",
|
|
34
|
+
"webfetch"
|
|
35
|
+
]);
|
|
36
|
+
const bridgeToolSearchNameSet = new Set(BRIDGE_TOOL_SEARCH_ALIASES);
|
|
37
|
+
const isBridgeToolSearchName = (name) => bridgeToolSearchNameSet.has(name);
|
|
38
|
+
const isAlwaysLoadedToolName = (name) => alwaysLoadedToolNameSet.has(name);
|
|
39
|
+
const isDeferredToolName = (name) => !isBridgeToolSearchName(name) && !isAlwaysLoadedToolName(name);
|
|
40
|
+
const supportsResponsesToolSearchModel = (model) => {
|
|
41
|
+
const match = /^gpt-(\d+)(?:\.(\d+))?/iu.exec(model);
|
|
42
|
+
if (!match) return false;
|
|
43
|
+
const major = Number.parseInt(match[1], 10);
|
|
44
|
+
const minor = match[2] ? Number.parseInt(match[2], 10) : 0;
|
|
45
|
+
return major > 5 || major === 5 && minor >= 4;
|
|
46
|
+
};
|
|
47
|
+
const hasBridgeToolSearchTool = (tools) => Array.isArray(tools) && tools.some((tool) => isBridgeToolSearchName(tool.name));
|
|
48
|
+
const hasDeferredToolCandidate = (tools) => Array.isArray(tools) && tools.some((tool) => isDeferredToolName(tool.name));
|
|
49
|
+
const shouldEnableResponsesToolSearch = (params) => supportsResponsesToolSearchModel(params.model) && hasBridgeToolSearchTool(params.tools) && hasDeferredToolCandidate(params.tools);
|
|
50
|
+
const listDeferredToolNames = (tools) => [...new Set(tools.filter((tool) => isDeferredToolName(tool.name)).map((tool) => tool.name))];
|
|
51
|
+
const extractDeferredToolNamesSource = (record) => record.names ?? record.query ?? record.paths;
|
|
52
|
+
const parseDeferredToolNames = (names) => {
|
|
53
|
+
let rawNames = [];
|
|
54
|
+
if (typeof names === "string") rawNames = names.split(",");
|
|
55
|
+
else if (Array.isArray(names)) rawNames = names.flatMap((name) => typeof name === "string" ? name.split(",") : []);
|
|
56
|
+
return [...new Set(rawNames.map((name) => name.trim()).filter((name) => name.length > 0))];
|
|
57
|
+
};
|
|
58
|
+
const createMcpToolSearchSentinel = (names) => JSON.stringify({
|
|
59
|
+
type: MCP_TOOL_SEARCH_SENTINEL_TYPE,
|
|
60
|
+
names: parseDeferredToolNames(names)
|
|
61
|
+
});
|
|
62
|
+
const parseMcpToolSearchSentinel = (text) => {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(text);
|
|
65
|
+
if (!parsed || typeof parsed !== "object") return null;
|
|
66
|
+
const record = parsed;
|
|
67
|
+
if (record.type !== "copilot_api_tool_search") return null;
|
|
68
|
+
const names = parseDeferredToolNames(extractDeferredToolNamesSource(record));
|
|
69
|
+
if (names.length === 0) return null;
|
|
70
|
+
return {
|
|
71
|
+
type: MCP_TOOL_SEARCH_SENTINEL_TYPE,
|
|
72
|
+
names
|
|
73
|
+
};
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const normalizeToolSearchBridgeArguments = (argumentsValue) => {
|
|
79
|
+
if (typeof argumentsValue !== "string") {
|
|
80
|
+
const names = parseDeferredToolNames(extractDeferredToolNamesSource(argumentsValue));
|
|
81
|
+
return names.length > 0 ? { names } : {};
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const parsed = JSON.parse(argumentsValue);
|
|
85
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
86
|
+
const names = parseDeferredToolNames(extractDeferredToolNamesSource(parsed));
|
|
87
|
+
return names.length > 0 ? { names } : {};
|
|
88
|
+
}
|
|
89
|
+
} catch {}
|
|
90
|
+
const names = parseDeferredToolNames(argumentsValue);
|
|
91
|
+
return names.length > 0 ? { names } : {};
|
|
92
|
+
};
|
|
93
|
+
const formatToolSearchBridgeArguments = (argumentsValue) => {
|
|
94
|
+
const names = normalizeToolSearchBridgeArguments(argumentsValue).names;
|
|
95
|
+
if (!Array.isArray(names) || names.length === 0) return {};
|
|
96
|
+
return { names: names.join(",") };
|
|
97
|
+
};
|
|
98
|
+
const selectDeferredToolsByNames = (names, tools) => {
|
|
99
|
+
const requestedNames = parseDeferredToolNames(names);
|
|
100
|
+
if (requestedNames.length === 0) return [];
|
|
101
|
+
const deferredToolByName = new Map(tools.filter((tool) => isDeferredToolName(tool.name)).map((tool) => [tool.name, tool]));
|
|
102
|
+
return requestedNames.flatMap((name) => {
|
|
103
|
+
const tool = deferredToolByName.get(name);
|
|
104
|
+
return tool ? [tool] : [];
|
|
105
|
+
});
|
|
106
|
+
};
|
|
107
|
+
//#endregion
|
|
108
|
+
export { isDeferredToolName as a, parseMcpToolSearchSentinel as c, isBridgeToolSearchName as i, selectDeferredToolsByNames as l, createMcpToolSearchSentinel as n, listDeferredToolNames as o, formatToolSearchBridgeArguments as r, normalizeToolSearchBridgeArguments as s, BRIDGE_TOOL_SEARCH_NAME as t, shouldEnableResponsesToolSearch as u };
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=tool-search-BrN7M0Dd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-search-BrN7M0Dd.js","names":["record"],"sources":["../src/lib/tool-search.ts"],"sourcesContent":["export const BRIDGE_TOOL_SEARCH_NAME = \"mcp__tool_search__search\"\nexport const BRIDGE_TOOL_SEARCH_ALIASES = [\n BRIDGE_TOOL_SEARCH_NAME,\n \"tool_search_search\",\n \"mcp__plugin_tool-search_tool_search__search\",\n] as const\nexport const MCP_TOOL_SEARCH_SENTINEL_TYPE = \"copilot_api_tool_search\"\n\nexport const ALWAYS_LOADED_TOOL_NAMES = [\n \"Agent\",\n \"AskUserQuestion\",\n \"Bash\",\n \"Edit\",\n \"EnterPlanMode\",\n \"ExitPlanMode\",\n \"Glob\",\n \"Grep\",\n \"Read\",\n \"Skill\",\n \"TodoWrite\",\n \"ToolSearch\",\n \"WebFetch\",\n \"Write\",\n \"apply_patch\",\n \"bash\",\n \"glob\",\n \"grep\",\n \"plan_exit\",\n \"question\",\n \"read\",\n \"skill\",\n \"task\",\n \"todowrite\",\n \"webfetch\",\n] as const\n\nconst alwaysLoadedToolNameSet = new Set<string>(ALWAYS_LOADED_TOOL_NAMES)\nconst bridgeToolSearchNameSet = new Set<string>(BRIDGE_TOOL_SEARCH_ALIASES)\n\nexport interface ToolSearchToolLike {\n name: string\n description?: string\n input_schema?: Record<string, unknown>\n defer_loading?: boolean\n}\n\nexport interface McpToolSearchSentinel {\n type: typeof MCP_TOOL_SEARCH_SENTINEL_TYPE\n names: Array<string>\n}\n\nexport const isBridgeToolSearchName = (name: string): boolean =>\n bridgeToolSearchNameSet.has(name)\n\nexport const isAlwaysLoadedToolName = (name: string): boolean =>\n alwaysLoadedToolNameSet.has(name)\n\nexport const isDeferredToolName = (name: string): boolean =>\n !isBridgeToolSearchName(name) && !isAlwaysLoadedToolName(name)\n\nexport const supportsResponsesToolSearchModel = (model: string): boolean => {\n const match = /^gpt-(\\d+)(?:\\.(\\d+))?/iu.exec(model)\n if (!match) {\n return false\n }\n\n const major = Number.parseInt(match[1], 10)\n const minor = match[2] ? Number.parseInt(match[2], 10) : 0\n\n return major > 5 || (major === 5 && minor >= 4)\n}\n\nexport const hasBridgeToolSearchTool = (\n tools: Array<ToolSearchToolLike> | undefined,\n): boolean =>\n Array.isArray(tools)\n && tools.some((tool) => isBridgeToolSearchName(tool.name))\n\nexport const resolveBridgeToolSearchName = (\n tools: Array<ToolSearchToolLike> | undefined,\n): string => {\n if (!Array.isArray(tools)) {\n return BRIDGE_TOOL_SEARCH_NAME\n }\n\n return (\n tools.find((tool) => isBridgeToolSearchName(tool.name))?.name\n ?? BRIDGE_TOOL_SEARCH_NAME\n )\n}\n\nexport const hasDeferredToolCandidate = (\n tools: Array<ToolSearchToolLike> | undefined,\n): boolean =>\n Array.isArray(tools) && tools.some((tool) => isDeferredToolName(tool.name))\n\nexport const shouldEnableResponsesToolSearch = (params: {\n model: string\n tools?: Array<ToolSearchToolLike>\n}): boolean =>\n supportsResponsesToolSearchModel(params.model)\n && hasBridgeToolSearchTool(params.tools)\n && hasDeferredToolCandidate(params.tools)\n\nexport const hasDeferredNamespaceTool = (\n tools: Array<unknown> | null | undefined,\n): boolean =>\n Array.isArray(tools)\n && tools.some((tool) => {\n if (!tool || typeof tool !== \"object\") {\n return false\n }\n\n const record = tool as Record<string, unknown>\n if (record.type !== \"namespace\" || typeof record.name !== \"string\") {\n return false\n }\n\n if (!isDeferredToolName(record.name)) {\n return false\n }\n\n const namespaceTools = record.tools\n return (\n Array.isArray(namespaceTools)\n && namespaceTools.some(\n (entry) =>\n entry\n && typeof entry === \"object\"\n && (entry as Record<string, unknown>).defer_loading === true,\n )\n )\n })\n\nexport const listDeferredToolNames = (\n tools: Array<ToolSearchToolLike>,\n): Array<string> => [\n ...new Set(\n tools\n .filter((tool) => isDeferredToolName(tool.name))\n .map((tool) => tool.name),\n ),\n]\n\nconst extractDeferredToolNamesSource = (\n record: Record<string, unknown>,\n): unknown => record.names ?? record.query ?? record.paths\n\nexport const parseDeferredToolNames = (names: unknown): Array<string> => {\n let rawNames: Array<string> = []\n\n if (typeof names === \"string\") {\n rawNames = names.split(\",\")\n } else if (Array.isArray(names)) {\n rawNames = names.flatMap((name) =>\n typeof name === \"string\" ? name.split(\",\") : [],\n )\n }\n\n return [\n ...new Set(\n rawNames.map((name) => name.trim()).filter((name) => name.length > 0),\n ),\n ]\n}\n\nexport const createMcpToolSearchSentinel = (names: unknown): string =>\n JSON.stringify({\n type: MCP_TOOL_SEARCH_SENTINEL_TYPE,\n names: parseDeferredToolNames(names),\n } satisfies McpToolSearchSentinel)\n\nexport const parseMcpToolSearchSentinel = (\n text: string,\n): McpToolSearchSentinel | null => {\n try {\n const parsed: unknown = JSON.parse(text)\n if (!parsed || typeof parsed !== \"object\") {\n return null\n }\n\n const record = parsed as Record<string, unknown>\n if (record.type !== MCP_TOOL_SEARCH_SENTINEL_TYPE) {\n return null\n }\n\n const names = parseDeferredToolNames(extractDeferredToolNamesSource(record))\n if (names.length === 0) {\n return null\n }\n\n return {\n type: MCP_TOOL_SEARCH_SENTINEL_TYPE,\n names,\n }\n } catch {\n return null\n }\n}\n\nexport const normalizeToolSearchBridgeArguments = (\n argumentsValue: Record<string, unknown> | string,\n): Record<string, unknown> => {\n if (typeof argumentsValue !== \"string\") {\n const names = parseDeferredToolNames(\n extractDeferredToolNamesSource(argumentsValue),\n )\n return names.length > 0 ? { names } : {}\n }\n\n try {\n const parsed: unknown = JSON.parse(argumentsValue)\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const record = parsed as Record<string, unknown>\n const names = parseDeferredToolNames(\n extractDeferredToolNamesSource(record),\n )\n return names.length > 0 ? { names } : {}\n }\n } catch {\n // Treat a raw string as the comma-separated protocol payload.\n }\n\n const names = parseDeferredToolNames(argumentsValue)\n return names.length > 0 ? { names } : {}\n}\n\nexport const formatToolSearchBridgeArguments = (\n argumentsValue: Record<string, unknown> | string,\n): Record<string, unknown> => {\n const normalized = normalizeToolSearchBridgeArguments(argumentsValue)\n const names = normalized.names\n\n if (!Array.isArray(names) || names.length === 0) {\n return {}\n }\n\n return { names: names.join(\",\") }\n}\n\nexport const selectDeferredToolsByNames = (\n names: unknown,\n tools: Array<ToolSearchToolLike>,\n): Array<ToolSearchToolLike> => {\n const requestedNames = parseDeferredToolNames(names)\n if (requestedNames.length === 0) {\n return []\n }\n\n const deferredToolByName = new Map(\n tools\n .filter((tool) => isDeferredToolName(tool.name))\n .map((tool) => [tool.name, tool]),\n )\n\n return requestedNames.flatMap((name) => {\n const tool = deferredToolByName.get(name)\n return tool ? [tool] : []\n })\n}\n\nexport const hasDeferredMcpNamespaceTool = hasDeferredNamespaceTool\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@nick3/copilot-api",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.10.7",
|
|
5
5
|
"description": "OpenAI and Anthropic-compatible gateway for GitHub Copilot or third-party providers.",
|
|
6
6
|
"keywords": [
|
|
7
|
-
"dashboard",
|
|
8
|
-
"multi-provider",
|
|
9
|
-
"github-copilot",
|
|
10
7
|
"ai-gateway",
|
|
11
|
-
"
|
|
12
|
-
"anthropic-compatible"
|
|
8
|
+
"github-copilot"
|
|
13
9
|
],
|
|
14
10
|
"homepage": "https://github.com/nick3/copilot-api",
|
|
15
11
|
"bugs": "https://github.com/nick3/copilot-api/issues",
|
|
@@ -52,6 +48,7 @@
|
|
|
52
48
|
"rolldown": "1.0.0-rc.18"
|
|
53
49
|
},
|
|
54
50
|
"dependencies": {
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
55
52
|
"citty": "^0.1.6",
|
|
56
53
|
"clipboardy": "^5.0.0",
|
|
57
54
|
"consola": "^3.4.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"poll-access-token-CIPDXrcm.js","names":[],"sources":["../src/lib/opencode.ts","../src/lib/request-context.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-usage.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/services/get-vscode-version.ts","../src/lib/deviceid.ts","../src/lib/utils.ts","../src/services/github/poll-access-token.ts"],"sourcesContent":["import consola from \"consola\"\nimport { exec } from \"node:child_process\"\nimport { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nconst execAsync = (command: string): Promise<string> => {\n return new Promise((resolve, reject) => {\n exec(command, (error, stdout) => {\n if (error) {\n reject(error)\n return\n }\n\n resolve(stdout)\n })\n })\n}\n\nlet opencodeVersionCache: string | undefined\n\nconst getGlobalNpmRoot = async (): Promise<string> => {\n const stdout = await execAsync(\"npm root -g\")\n return stdout.trim()\n}\n\nasync function resolveOpencodeVersion(): Promise<void> {\n try {\n const npmRootPath = await getGlobalNpmRoot()\n const opencodePackagePath = path.join(\n npmRootPath,\n \"opencode-ai\",\n \"package.json\",\n )\n const packageJson = await readFile(opencodePackagePath, \"utf8\")\n const { version } = JSON.parse(packageJson) as { version: string }\n opencodeVersionCache = version\n } catch (error) {\n consola.warn(`Failed to resolve opencode version`, error)\n }\n}\n\nexport const initOpencodeVersion = (): Promise<void> => {\n if (process.env.COPILOT_API_OAUTH_APP?.trim() !== \"opencode\") {\n return Promise.resolve()\n }\n return resolveOpencodeVersion()\n}\n\nexport const getCachedOpencodeVersion = (): string | undefined => {\n return opencodeVersionCache\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\"\n\nexport interface OutboundHeadersSnapshot {\n xRequestId?: string\n xAgentTaskId?: string\n xInteractionId?: string\n xInteractionType?: string\n openaiIntent?: string\n userAgent?: string\n}\n\nexport interface RequestContext {\n traceId: string\n startTime: number\n userAgent: string\n sessionAffinity: string | undefined\n parentSessionId: string | undefined\n outboundHeaders?: OutboundHeadersSnapshot\n fetchImpl?: typeof fetch\n}\n\nconst TRACE_ID_MAX_LENGTH = 64\nconst TRACE_ID_PATTERN = /^\\w[\\w.-]*$/\n\nconst asyncLocalStorage = new AsyncLocalStorage<RequestContext>()\n\nexport const requestContext = {\n getStore: () => asyncLocalStorage.getStore(),\n run: <T>(context: RequestContext, callback: () => T) =>\n asyncLocalStorage.run(context, callback),\n}\n\nexport function generateTraceId(): string {\n const timestamp = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${timestamp}-${random}`\n}\n\nfunction buildOutboundHeadersSnapshot(\n headers: Record<string, string>,\n): OutboundHeadersSnapshot {\n const snapshot: OutboundHeadersSnapshot = {\n xRequestId: undefined,\n xAgentTaskId: undefined,\n xInteractionId: undefined,\n xInteractionType: undefined,\n openaiIntent: undefined,\n userAgent: undefined,\n }\n\n for (const [name, value] of Object.entries(headers)) {\n switch (name.toLowerCase()) {\n case \"x-request-id\": {\n snapshot.xRequestId = value\n break\n }\n case \"x-agent-task-id\": {\n snapshot.xAgentTaskId = value\n break\n }\n case \"x-interaction-id\": {\n snapshot.xInteractionId = value\n break\n }\n case \"x-interaction-type\": {\n snapshot.xInteractionType = value\n break\n }\n case \"openai-intent\": {\n snapshot.openaiIntent = value\n break\n }\n case \"user-agent\": {\n snapshot.userAgent = value\n break\n }\n default: {\n break\n }\n }\n }\n\n return snapshot\n}\n\nexport function captureOutboundHeadersSnapshot(\n headers: Record<string, string>,\n): void {\n const store = asyncLocalStorage.getStore()\n if (!store) return\n\n store.outboundHeaders = buildOutboundHeadersSnapshot(headers)\n}\n\nexport function getOutboundHeadersSnapshot():\n | OutboundHeadersSnapshot\n | undefined {\n return asyncLocalStorage.getStore()?.outboundHeaders\n}\n\nexport function consumeOutboundHeadersSnapshot():\n | OutboundHeadersSnapshot\n | undefined {\n const store = asyncLocalStorage.getStore()\n const snapshot = store?.outboundHeaders\n\n if (store) {\n store.outboundHeaders = undefined\n }\n\n return snapshot\n}\n\nexport function resolveTraceId(traceId: string | null | undefined): string {\n const candidate = traceId?.trim()\n\n if (\n !candidate\n || candidate.length > TRACE_ID_MAX_LENGTH\n || !TRACE_ID_PATTERN.test(candidate)\n ) {\n return generateTraceId()\n }\n\n return candidate\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { AccountContext, AccountType } from \"./types/account\"\n\nexport interface State {\n githubToken?: string\n userName?: string\n copilotToken?: string\n\n accountType: AccountType\n vsCodeVersion?: string\n\n macMachineId?: string\n vsCodeSessionId?: string\n vsCodeDeviceId: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n verbose: boolean\n\n copilotApiUrl?: string\n}\n\nexport const state: State = {\n accountType: \"individual\",\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n verbose: false,\n vsCodeDeviceId: randomUUID(),\n}\n\n/**\n * Create an AccountContext from the current global state.\n * This is a compatibility layer for transitioning to multi-account support.\n * @throws Error if githubToken is not set in state\n */\nexport function accountFromState(): AccountContext {\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set in state\")\n }\n return {\n githubToken: state.githubToken,\n copilotToken: state.copilotToken,\n ...(state.copilotApiUrl !== undefined ?\n { copilotApiUrl: state.copilotApiUrl }\n : {}),\n accountType: state.accountType,\n vsCodeVersion: state.vsCodeVersion,\n clientDeviceId: state.vsCodeDeviceId,\n clientMachineId: state.macMachineId,\n clientSessionId: state.vsCodeSessionId,\n }\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { CompactType } from \"./compact\"\nimport type { AccountContext } from \"./types/account\"\n\nimport { getCachedOpencodeVersion } from \"./opencode\"\nimport { requestContext } from \"./request-context\"\nimport { state } from \"./state\"\n\nexport const isOpencodeOauthApp = (): boolean => {\n return process.env.COPILOT_API_OAUTH_APP?.trim() === \"opencode\"\n}\n\nexport const normalizeDomain = (input: string): string => {\n return input\n .trim()\n .replace(/^https?:\\/\\//u, \"\")\n .replace(/\\/+$/u, \"\")\n}\n\nexport const getEnterpriseDomain = (): string | null => {\n const raw = (process.env.COPILOT_API_ENTERPRISE_URL ?? \"\").trim()\n if (!raw) return null\n const normalized = normalizeDomain(raw)\n return normalized || null\n}\n\nexport const getGitHubBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://${resolvedDomain}` : GITHUB_BASE_URL\n}\n\nexport const getGitHubApiBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://api.${resolvedDomain}` : GITHUB_API_BASE_URL\n}\n\nconst getOpencodeOauthHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": getOpencodeVersion(),\n }\n}\n\nconst getOpencodeLLMHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": OPENCODE_LLM_USER_AGENT,\n }\n}\n\nconst normalizeOpencodeUserAgent = (userAgent: string): string => {\n const candidate = userAgent.trim()\n const opencodeProduct = candidate.match(/^opencode\\/[^\\s,]+/u)?.[0]\n\n if (!opencodeProduct || candidate.includes(`, ${opencodeProduct}`)) {\n return candidate\n }\n\n return `${candidate}, ${opencodeProduct}`\n}\n\nexport const getOauthUrls = (): {\n deviceCodeUrl: string\n accessTokenUrl: string\n} => {\n const githubBaseUrl = getGitHubBaseUrl()\n\n return {\n deviceCodeUrl: `${githubBaseUrl}/login/device/code`,\n accessTokenUrl: `${githubBaseUrl}/login/oauth/access_token`,\n }\n}\n\ninterface OauthAppConfig {\n clientId: string\n headers: Record<string, string>\n scope: string\n}\n\nexport const getOauthAppConfig = (): OauthAppConfig => {\n if (isOpencodeOauthApp()) {\n return {\n clientId: OPENCODE_GITHUB_CLIENT_ID,\n headers: getOpencodeOauthHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n }\n\n return {\n clientId: GITHUB_CLIENT_ID,\n headers: standardHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n}\n\nexport const prepareForCompact = (\n headers: Record<string, string>,\n compactType?: CompactType,\n) => {\n if (compactType) {\n headers[\"x-initiator\"] = \"agent\"\n }\n}\n\nexport const prepareInteractionHeaders = (\n sessionId: string | undefined,\n isSubagent: boolean,\n headers: Record<string, string>,\n) => {\n const sendInteractionHeaders = !isOpencodeOauthApp()\n\n if (isSubagent) {\n headers[\"x-initiator\"] = \"agent\"\n if (sendInteractionHeaders) {\n headers[\"x-interaction-type\"] = \"conversation-subagent\"\n }\n }\n\n if (sessionId && sendInteractionHeaders) {\n headers[\"x-interaction-id\"] = sessionId\n }\n}\n\nexport const standardHeaders = () => ({\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n})\n\nexport const getOpencodeVersion = () => {\n const version = getCachedOpencodeVersion()\n if (version) {\n return \"opencode/\" + version\n }\n return OPENCODE_VERSION\n}\n\nconst OPENCODE_VERSION = \"opencode/1.14.29\"\nconst OPENCODE_LLM_USER_AGENT =\n \"opencode/1.14.29 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.13, opencode/1.14.29\"\n\nconst COPILOT_VERSION = \"0.46.0\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst CLAUDE_AGENT_USER_AGENT =\n \"vscode_claude_code/2.1.112 (external, sdk-ts, agent-sdk/0.2.112)\"\n\nconst API_VERSION = \"2025-10-01\"\n\nexport const copilotBaseUrl = (account: AccountContext): string => {\n const enterpriseDomain = getEnterpriseDomain()\n if (enterpriseDomain) {\n return `https://copilot-api.${enterpriseDomain}`\n }\n\n if (isOpencodeOauthApp()) {\n return \"https://api.githubcopilot.com\"\n }\n\n if (account.copilotApiUrl) {\n return account.copilotApiUrl\n }\n\n return account.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${account.accountType}.githubcopilot.com`\n}\n\nexport const prepareMessageProxyHeaders = (headers: Record<string, string>) => {\n if (isOpencodeOauthApp()) {\n return\n }\n\n // vscode copilot claude agent regenerates request id for\n // each request, keeping it consistent\n const requestIdValue = randomUUID()\n headers[\"x-agent-task-id\"] = requestIdValue\n headers[\"x-request-id\"] = requestIdValue\n\n // Consistent with vscode copilot claude agent\n headers[\"x-interaction-type\"] = \"messages-proxy\"\n headers[\"openai-intent\"] = \"messages-proxy\"\n headers[\"user-agent\"] = CLAUDE_AGENT_USER_AGENT\n\n delete headers[\"copilot-integration-id\"]\n}\n\nexport const githubUserHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n\n return {\n accept: \"application/vnd.github+json\",\n authorization: `token ${account.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": \"2022-11-28\",\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const copilotModelsHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n return {\n Authorization: `Bearer ${token}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n const headers = githubCopilotHeaders(account)\n headers[\"x-interaction-type\"] = \"model-access\"\n headers[\"openai-intent\"] = \"model-access\"\n delete headers[\"x-interaction-id\"]\n delete headers[\"content-type\"]\n return headers\n}\n\nexport const copilotHeaders = (\n account: AccountContext,\n vision: boolean = false,\n requestId?: string,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n ...getOpencodeLLMHeaders(),\n \"Openai-Intent\": \"conversation-edits\",\n }\n\n const store = requestContext.getStore()\n const userAgent = store?.userAgent.trim()\n // Real opencode traffic already carries a versioned opencode/* UA,\n // so prefer the inbound header to keep upstream behavior aligned.\n if (userAgent?.startsWith(\"opencode/\")) {\n headers[\"User-Agent\"] = normalizeOpencodeUserAgent(userAgent)\n }\n\n if (store?.sessionAffinity) {\n headers[\"x-session-affinity\"] = store.sessionAffinity\n }\n\n if (store?.parentSessionId) {\n headers[\"x-parent-session-id\"] = store.parentSessionId\n }\n\n if (vision) headers[\"Copilot-Vision-Request\"] = \"true\"\n\n return headers\n }\n\n return githubCopilotHeaders(account, vision, requestId)\n}\n\nconst githubCopilotHeaders = (\n account: AccountContext,\n vision: boolean = false,\n requestId?: string,\n): Record<string, string> => {\n const resolvedRequestId = requestId ?? randomUUID()\n const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId\n const resolvedMachineId = account.clientMachineId ?? state.macMachineId\n const resolvedSessionId = account.clientSessionId ?? state.vsCodeSessionId\n const headers: Record<string, string> = {\n Authorization: `Bearer ${account.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-version\": `vscode/${account.vsCodeVersion}`,\n \"editor-device-id\": resolvedDeviceId,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"openai-intent\": \"conversation-agent\",\n \"x-github-api-version\": API_VERSION,\n \"x-request-id\": resolvedRequestId,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n \"x-agent-task-id\": resolvedRequestId,\n \"x-interaction-type\": \"conversation-agent\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n if (resolvedMachineId) {\n headers[\"vscode-machineid\"] = resolvedMachineId\n }\n\n if (resolvedSessionId) {\n headers[\"vscode-sessionid\"] = resolvedSessionId\n }\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n ...getOpencodeOauthHeaders(),\n }\n }\n\n return {\n authorization: `token ${account.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const GITHUB_BASE_URL = \"https://github.com\"\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\nexport const OPENCODE_GITHUB_CLIENT_ID = \"Ov23li8tweQw6odWQebz\"\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\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport class CancelledError extends Error {}\n\nfunction getFallbackHttpErrorMessage(error: HTTPError): string {\n return error.message || `HTTP ${error.response.status}`\n}\n\nasync function readHttpErrorText(error: HTTPError): Promise<string> {\n try {\n const text = await error.response.text()\n return text || getFallbackHttpErrorMessage(error)\n } catch (readError) {\n consola.warn(\"Failed to read HTTP error response body:\", readError)\n return getFallbackHttpErrorMessage(error)\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message || \"Unknown error\"\n }\n\n if (typeof error === \"string\") {\n return error\n }\n\n if (\n typeof error === \"number\"\n || typeof error === \"boolean\"\n || typeof error === \"bigint\"\n ) {\n return `${error}`\n }\n\n return \"Unknown error\"\n}\n\nexport async function forwardError(\n c: Context,\n error: unknown,\n): Promise<Response> {\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n if (error.response.status === 429) {\n for (const [name, value] of error.response.headers) {\n const lowerName = name.toLowerCase()\n if (lowerName === \"retry-after\" || lowerName.startsWith(\"x-\")) {\n c.header(name, value)\n }\n }\n }\n\n const errorText = await readHttpErrorText(error)\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\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: getErrorMessage(error),\n type: \"error\",\n },\n },\n 500,\n )\n}\n","import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (\n account?: AccountContext,\n): Promise<CopilotUsageResponse> => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/user`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\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 login: string\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 endpoints: {\n api: string\n telemetry: string\n }\n}\n","import { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport interface DeviceCodeOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n}\n\nexport async function getDeviceCode(\n options?: DeviceCodeOptions,\n): Promise<DeviceCodeResponse> {\n const { clientId, headers, scope } = getOauthAppConfig()\n const { deviceCodeUrl } = options?.overrideUrls ?? getOauthUrls()\n\n const response = await fetch(deviceCodeUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n scope,\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 type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubUserHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState, state } from \"~/lib/state\"\n\nconst resolveGitHubUserAccount = (account?: AccountContext): AccountContext => {\n if (account) {\n return account\n }\n\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set\")\n }\n\n return accountFromState()\n}\n\nexport async function getGitHubUser(account?: AccountContext) {\n const resolvedAccount = resolveGitHubUserAccount(account)\n\n const response = await fetch(`${getGitHubApiBaseUrl()}/user`, {\n headers: githubUserHeaders(resolvedAccount),\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\nexport interface GithubUserResponse {\n login: string\n}\n","const FALLBACK = \"1.118.0\"\n\nexport async function getVSCodeVersion() {\n await Promise.resolve()\n return FALLBACK\n}\n","import consola from \"consola\"\nimport { randomUUID } from \"node:crypto\"\nimport path from \"node:path\"\n\nconst WINDOWS_DEVICE_ID_KEY = String.raw`\\SOFTWARE\\Microsoft\\DeveloperTools`\nconst WINDOWS_DEVICE_ID_NAME = \"deviceid\"\n\ntype RegistryArch = \"x86\" | \"x64\"\n\ninterface WinregConstructor {\n new (options: {\n hive: string\n key: string\n arch?: RegistryArch\n }): WinregRegistry\n HKCU: string\n REG_SZ: string\n}\n\ninterface WinregRegistry {\n get(\n name: string,\n callback: (error: RegistryError | null, item: RegistryItem | null) => void,\n ): void\n set(\n name: string,\n type: string,\n value: string,\n callback: (error: RegistryError | null) => void,\n ): void\n}\n\ninterface RegistryItem {\n value?: string\n}\n\ninterface RegistryError extends Error {\n code?: number | string\n}\n\nconst windows64Architectures = new Set([\"AMD64\", \"ARM64\", \"IA64\"])\n\nconst getPosixHomeDir = (): string => {\n if (!process.env.HOME) {\n throw new Error(\"Home directory not found\")\n }\n\n return process.env.HOME\n}\n\nconst getDeviceIdFilePath = (): string => {\n let folder: string\n\n switch (process.platform) {\n case \"darwin\": {\n folder = path.posix.join(\n getPosixHomeDir(),\n \"Library\",\n \"Application Support\",\n )\n break\n }\n case \"linux\": {\n folder =\n process.env.XDG_CACHE_HOME\n ?? path.posix.join(getPosixHomeDir(), \".cache\")\n break\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n\n return path.posix.join(folder, \"Microsoft\", \"DeveloperTools\", \"deviceid\")\n}\n\nconst isMissingFileError = (error: unknown): error is NodeJS.ErrnoException => {\n return error instanceof Error && \"code\" in error && error.code === \"ENOENT\"\n}\n\nconst readStoredDeviceIdFile = async (\n filePath: string,\n): Promise<string | undefined> => {\n const { readFile } = await import(\"node:fs/promises\")\n\n try {\n return await readFile(filePath, \"utf8\")\n } catch (error) {\n if (isMissingFileError(error)) {\n return undefined\n }\n\n throw error\n }\n}\n\nconst writeStoredDeviceIdFile = async (\n filePath: string,\n deviceId: string,\n): Promise<void> => {\n const { mkdir, writeFile } = await import(\"node:fs/promises\")\n\n await mkdir(path.posix.dirname(filePath), { recursive: true })\n await writeFile(filePath, deviceId, \"utf8\")\n}\n\nconst getWindowsRegistryArch = (): RegistryArch | undefined => {\n const architecture = (\n process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE\n )?.toUpperCase()\n\n return architecture && windows64Architectures.has(architecture) ?\n \"x64\"\n : undefined\n}\n\nconst loadWinreg = async (): Promise<WinregConstructor> => {\n const module = await import(\"winreg\")\n const winreg =\n \"default\" in module ? (module.default as unknown) : (module as unknown)\n\n return winreg as WinregConstructor\n}\n\nconst isMissingRegistryError = (error: RegistryError | null): boolean => {\n if (!error) {\n return false\n }\n\n const errorCode = Number(error.code)\n\n return Number.isFinite(errorCode) && errorCode === 1\n}\n\nconst createWindowsRegistry = async (): Promise<{\n registry: WinregRegistry\n regSz: string\n}> => {\n const Winreg = await loadWinreg()\n\n return {\n registry: new Winreg({\n hive: Winreg.HKCU,\n key: WINDOWS_DEVICE_ID_KEY,\n arch: getWindowsRegistryArch(),\n }),\n regSz: Winreg.REG_SZ,\n }\n}\n\nconst readRegistryString = async (\n registry: WinregRegistry,\n name: string,\n): Promise<string | undefined> => {\n return new Promise((resolve, reject) => {\n registry.get(name, (error, item) => {\n if (isMissingRegistryError(error)) {\n resolve(undefined)\n return\n }\n\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve(item?.value)\n })\n })\n}\n\nconst writeRegistryString = async ({\n registry,\n regSz,\n name,\n value,\n}: {\n registry: WinregRegistry\n regSz: string\n name: string\n value: string\n}): Promise<void> => {\n return new Promise((resolve, reject) => {\n registry.set(name, regSz, value, (error) => {\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve()\n })\n })\n}\n\nexport const getStoredVSCodeDeviceId = async (): Promise<\n string | undefined\n> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry } = await createWindowsRegistry()\n\n return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME)\n }\n case \"darwin\":\n case \"linux\": {\n return readStoredDeviceIdFile(getDeviceIdFilePath())\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst setStoredVSCodeDeviceId = async (deviceId: string): Promise<void> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry, regSz } = await createWindowsRegistry()\n\n await writeRegistryString({\n registry,\n regSz,\n name: WINDOWS_DEVICE_ID_NAME,\n value: deviceId,\n })\n return\n }\n case \"darwin\":\n case \"linux\": {\n await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId)\n return\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst createVSCodeDeviceId = (): string => randomUUID().toLowerCase()\n\nexport async function getVSCodeDeviceId(): Promise<string> {\n let deviceId: string | undefined\n\n try {\n deviceId = await getStoredVSCodeDeviceId()\n } catch (error) {\n consola.debug(\"Failed to read VSCode device id\", error)\n }\n\n if (deviceId) {\n return deviceId\n }\n\n const newDeviceId = createVSCodeDeviceId()\n\n try {\n await setStoredVSCodeDeviceId(newDeviceId)\n } catch (error) {\n consola.warn(\n \"Failed to persist VSCode device id, using ephemeral id\",\n error,\n )\n }\n\n return newDeviceId\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { createHash, randomUUID } from \"node:crypto\"\nimport { networkInterfaces } from \"node:os\"\n\nimport type { AnthropicMessagesPayload } from \"~/routes/messages/anthropic-types\"\n\nimport { getVSCodeVersion } from \"~/services/get-vscode-version\"\n\nimport { getVSCodeDeviceId } from \"./deviceid\"\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 const cacheVSCodeVersion = async () => {\n const response = await getVSCodeVersion()\n state.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n\nconst invalidMacAddresses = new Set([\n \"00:00:00:00:00:00\",\n \"ff:ff:ff:ff:ff:ff\",\n \"ac:de:48:00:11:22\",\n])\n\nfunction validateMacAddress(candidate: string): boolean {\n const tempCandidate = candidate.replaceAll(\"-\", \":\").toLowerCase()\n return !invalidMacAddresses.has(tempCandidate)\n}\n\nexport function getMac(): string | null {\n const ifaces = networkInterfaces()\n // eslint-disable-next-line guard-for-in\n for (const name in ifaces) {\n const networkInterface = ifaces[name]\n if (networkInterface) {\n for (const { mac } of networkInterface) {\n if (validateMacAddress(mac)) {\n return mac\n }\n }\n }\n }\n return null\n}\n\nexport const cacheMacMachineId = () => {\n const macAddress = getMac() ?? randomUUID()\n state.macMachineId = createHash(\"sha256\")\n .update(macAddress, \"utf8\")\n .digest(\"hex\")\n consola.debug(`Using machine ID: ${state.macMachineId}`)\n}\n\nexport const cacheVsCodeDeviceId = async () => {\n state.vsCodeDeviceId = await getVSCodeDeviceId()\n consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`)\n}\n\nconst SESSION_REFRESH_BASE_MS = 60 * 60 * 1000\nconst SESSION_REFRESH_JITTER_MS = 20 * 60 * 1000\nlet vsCodeSessionRefreshTimer: ReturnType<typeof setTimeout> | null = null\n\nconst generateSessionId = () => {\n state.vsCodeSessionId = randomUUID() + Date.now().toString()\n consola.debug(`Generated VSCode session ID: ${state.vsCodeSessionId}`)\n}\n\nexport const stopVsCodeSessionRefreshLoop = () => {\n if (vsCodeSessionRefreshTimer) {\n clearTimeout(vsCodeSessionRefreshTimer)\n vsCodeSessionRefreshTimer = null\n }\n}\n\nconst scheduleSessionIdRefresh = () => {\n const randomDelay = Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS)\n const delay = SESSION_REFRESH_BASE_MS + randomDelay\n consola.debug(\n `Scheduling next VSCode session ID refresh in ${Math.round(\n delay / 1000,\n )} seconds`,\n )\n\n stopVsCodeSessionRefreshLoop()\n vsCodeSessionRefreshTimer = setTimeout(() => {\n try {\n generateSessionId()\n } catch (error) {\n consola.error(\"Failed to refresh session ID, rescheduling...\", error)\n } finally {\n scheduleSessionIdRefresh()\n }\n }, delay)\n}\n\nexport const cacheVsCodeSessionId = () => {\n stopVsCodeSessionRefreshLoop()\n generateSessionId()\n scheduleSessionIdRefresh()\n}\n\ninterface PayloadMessage {\n role?: string\n content?: string | Array<{ type?: string; text?: string }> | null\n type?: string\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null\n\nconst getUserIdJsonField = (\n userIdPayload: Record<string, unknown> | null,\n field: string,\n): string | null => {\n const value = userIdPayload?.[field]\n return typeof value === \"string\" && value.length > 0 ? value : null\n}\n\nconst parseJsonUserId = (userId: string): Record<string, unknown> | null => {\n try {\n const parsed: unknown = JSON.parse(userId)\n return isRecord(parsed) ? parsed : null\n } catch {\n return null\n }\n}\n\nexport const parseUserIdMetadata = (\n userId: string | undefined,\n): { safetyIdentifier: string | null; sessionId: string | null } => {\n if (!userId || typeof userId !== \"string\") {\n return { safetyIdentifier: null, sessionId: null }\n }\n\n const legacySafetyIdentifier =\n userId.match(/user_([^_]+)_account/)?.[1] ?? null\n const legacySessionId = userId.match(/_session_(.+)$/)?.[1] ?? null\n\n const parsedUserId =\n legacySafetyIdentifier && legacySessionId ? null : parseJsonUserId(userId)\n\n const safetyIdentifier =\n legacySafetyIdentifier\n ?? getUserIdJsonField(parsedUserId, \"device_id\")\n ?? getUserIdJsonField(parsedUserId, \"account_uuid\")\n const sessionId =\n legacySessionId ?? getUserIdJsonField(parsedUserId, \"session_id\")\n\n return { safetyIdentifier, sessionId }\n}\n\nconst findLastUserContent = (\n messages: Array<PayloadMessage>,\n): string | null => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.role === \"user\" && msg.content) {\n if (typeof msg.content === \"string\") {\n return msg.content\n } else if (Array.isArray(msg.content)) {\n const array = msg.content\n .filter((n) => n.type !== \"tool_result\")\n .map((n) => ({ ...n, cache_control: undefined }))\n if (array.length > 0) {\n return JSON.stringify(array)\n }\n }\n }\n }\n return null\n}\n\nexport const generateRequestIdFromPayload = (\n payload: {\n messages: string | Array<PayloadMessage> | undefined\n },\n sessionId?: string,\n): string => {\n const messages = payload.messages\n if (messages) {\n const lastUserContent =\n typeof messages === \"string\" ? messages : findLastUserContent(messages)\n\n if (lastUserContent) {\n return getUUID((sessionId ?? \"\") + lastUserContent)\n }\n }\n\n return randomUUID()\n}\n\nexport const normalizeStableSessionId = (\n sessionId?: string | null,\n): string | undefined => {\n const trimmedSessionId = sessionId?.trim()\n return trimmedSessionId ? getUUID(trimmedSessionId) : undefined\n}\n\nexport const getRootSessionId = (\n anthropicPayload: AnthropicMessagesPayload,\n c: Context,\n): string | undefined => {\n const userId = anthropicPayload.metadata?.user_id\n const sessionId =\n userId ?\n parseUserIdMetadata(userId).sessionId || undefined\n : c.req.header(\"x-session-id\")\n\n return normalizeStableSessionId(sessionId)\n}\n\nexport const getUUID = (content: string): string => {\n const uuidBytes = createHash(\"sha256\")\n .update(content)\n .digest()\n .subarray(0, 16)\n\n uuidBytes[6] = (uuidBytes[6] & 0x0f) | 0x40\n uuidBytes[8] = (uuidBytes[8] & 0x3f) | 0x80\n\n const uuidHex = uuidBytes.toString(\"hex\")\n\n return `${uuidHex.slice(0, 8)}-${uuidHex.slice(8, 12)}-${uuidHex.slice(12, 16)}-${uuidHex.slice(16, 20)}-${uuidHex.slice(20)}`\n}\n\nexport type AffinityKeySource =\n | \"prompt_cache_key\"\n | \"metadata_session_id\"\n | \"x_session_id\"\n | \"upstream_request_id_fallback\"\n\nexport interface ResolvedAffinityKey {\n requestId: string\n affinityKeyUsed: string\n affinityKeySource: AffinityKeySource\n}\n\n/**\n * Unified affinity key resolution with fixed priority:\n * 1. payload.prompt_cache_key (used as-is)\n * 2. metadata.user_id.session_id (normalized via getUUID)\n * 3. x-session-id header (normalized via getUUID)\n * 4. generateRequestIdFromPayload fallback (used as-is)\n */\nexport const resolveAffinityKey = (params: {\n promptCacheKey?: string | null\n metadataSessionId?: string | null\n headerSessionId?: string | null\n upstreamRequestId: string\n}): ResolvedAffinityKey => {\n const {\n promptCacheKey,\n metadataSessionId,\n headerSessionId,\n upstreamRequestId,\n } = params\n\n if (promptCacheKey) {\n return {\n requestId: promptCacheKey,\n affinityKeyUsed: promptCacheKey,\n affinityKeySource: \"prompt_cache_key\",\n }\n }\n\n if (metadataSessionId) {\n return {\n requestId: getUUID(metadataSessionId),\n affinityKeyUsed: metadataSessionId,\n affinityKeySource: \"metadata_session_id\",\n }\n }\n\n if (headerSessionId) {\n return {\n requestId: getUUID(headerSessionId),\n affinityKeyUsed: headerSessionId,\n affinityKeySource: \"x_session_id\",\n }\n }\n\n return {\n requestId: upstreamRequestId,\n affinityKeyUsed: upstreamRequestId,\n affinityKeySource: \"upstream_request_id_fallback\",\n }\n}\n","import consola from \"consola\"\n\nimport { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { CancelledError } from \"~/lib/error\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport interface PollAccessTokenOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n signal?: AbortSignal\n}\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n options?: PollAccessTokenOptions,\n): Promise<string> {\n const { clientId, headers } = getOauthAppConfig()\n const { accessTokenUrl } = options?.overrideUrls ?? getOauthUrls()\n\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 if (options?.signal?.aborted) {\n throw new CancelledError(\"Authentication cancelled\")\n }\n\n const response = await fetch(accessTokenUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n device_code: deviceCode.device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n signal: options?.signal,\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"],"mappings":"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"}
|