@jeffreycao/copilot-api 2.6.23 → 2.6.25
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 +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{auth-DvEHwSn1.js → auth-BM1NSmaY.js} +6 -4
- package/dist/auth-BM1NSmaY.js.map +1 -0
- package/dist/auth-DGt1r0Ik.js +2 -0
- package/dist/{config-B_pC8QXv.js → config-AlcbghlW.js} +24 -370
- package/dist/config-AlcbghlW.js.map +1 -0
- package/dist/config-store--1vrPTFC.js +363 -0
- package/dist/config-store--1vrPTFC.js.map +1 -0
- package/dist/{debug-C4rsL806.js → debug-Cykqg-GL.js} +3 -2
- package/dist/{debug-C4rsL806.js.map → debug-Cykqg-GL.js.map} +1 -1
- package/dist/github-copilot-provider-BWQdEbDy.js +79 -0
- package/dist/github-copilot-provider-BWQdEbDy.js.map +1 -0
- package/dist/main.js +6 -4
- package/dist/main.js.map +1 -1
- package/dist/{models-DNaL0mbS.js → models-DKDMBzWM.js} +2 -2
- package/dist/{models-DNaL0mbS.js.map → models-DKDMBzWM.js.map} +1 -1
- package/dist/provider-C38mrz76.js +36 -0
- package/dist/provider-C38mrz76.js.map +1 -0
- package/dist/provider-management-B8wlMJ5F.js +61 -0
- package/dist/provider-management-B8wlMJ5F.js.map +1 -0
- package/dist/{server-Bn-3LVLI.js → server-ihCUW7FV.js} +144 -27
- package/dist/server-ihCUW7FV.js.map +1 -0
- package/dist/{start-C20b41ZA.js → start-lTEXu1xj.js} +12 -9
- package/dist/{start-C20b41ZA.js.map → start-lTEXu1xj.js.map} +1 -1
- package/dist/{token-Datq4t9R.js → token-CnzxfSWL.js} +60 -74
- package/dist/token-CnzxfSWL.js.map +1 -0
- package/package.json +2 -1
- package/dist/auth-DvEHwSn1.js.map +0 -1
- package/dist/auth-EY18m6_Q.js +0 -2
- package/dist/config-B_pC8QXv.js.map +0 -1
- package/dist/server-Bn-3LVLI.js.map +0 -1
- package/dist/token-Datq4t9R.js.map +0 -1
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Windows x64 (`.exe`), macOS Apple Silicon (`.dmg`), and Linux x64 (`.AppImage`)
|
|
|
91
91
|
| [Installation and Startup](docs/guides/en/getting-started.md) | Prerequisites, project overview, `npx` and source runs, provider-only mode without Copilot, and gateway API key setup |
|
|
92
92
|
| [Claude Code](docs/guides/en/claude-code.md) | The `--claude-code` interactive launcher, `.claude/settings.json` environment variables, opus / sonnet / haiku tier mapping, auto-compact window, and WebSearch behavior |
|
|
93
93
|
| [OpenCode](docs/guides/en/opencode.md) | OpenCode OAuth login, the `@ai-sdk/anthropic` provider in `opencode.json`, `baseURL` conventions, model context limits, and thinking options |
|
|
94
|
-
| [Codex](docs/guides/en/codex.md) | A full `config.toml` provider block, auto-review model mapping, generating `model_catalog.json`, and the merged model picker catalog with protocol adapters |
|
|
94
|
+
| [Codex](docs/guides/en/codex.md) | A full `config.toml` provider block, `GITHUB_COPILOT_API_KEY` environment variable setup, auto-review model mapping, generating `model_catalog.json`, and the merged model picker catalog with protocol adapters |
|
|
95
95
|
| [Docker](docs/guides/en/docker.md) | Docker Compose quick start, the `/data` persistent mount and its ownership repair, supported environment variables, and host interface binding |
|
|
96
96
|
| [Desktop App](docs/guides/en/desktop.md) | Copilot sign-in, Codex OAuth account switching, API-key providers, one-click start / stop, shared model mappings, advanced settings, and per-platform installers |
|
|
97
97
|
| [Plugins and Tool Search](docs/guides/en/integrations.md) | The Responses `tool_search` MCP bridge (not needed on opencode v2, which already defers tools through Code Mode), Claude Code `agent-inject` and `tool-search` marketplace plugins, and the opencode subagent marker plugin |
|
|
@@ -99,6 +99,6 @@ Windows x64 (`.exe`), macOS Apple Silicon (`.dmg`), and Linux x64 (`.AppImage`)
|
|
|
99
99
|
| [CLI Reference](docs/guides/en/cli.md) | Command structure, global options, and the full option sets for the `start`, `auth`, and `debug` subcommands with example usage |
|
|
100
100
|
| [Configuration Reference](docs/guides/en/configuration.md) | Every `config.json` field: gateway and admin API keys, provider definitions, model mappings, WebSocket and HTTP transport, timeouts, and context management |
|
|
101
101
|
| [API and Authentication](docs/guides/en/api.md) | Allowed auth headers and CORS rules, OpenAI, Codex backend, and Anthropic endpoints, usage monitoring routes, and admin configuration endpoints |
|
|
102
|
-
| [Troubleshooting](docs/guides/en/troubleshooting.md) |
|
|
102
|
+
| [Troubleshooting](docs/guides/en/troubleshooting.md) | Fixes for Copilot encrypted output failures and missing Claude models |
|
|
103
103
|
|
|
104
104
|
Before using GitHub Copilot, read the [GitHub Copilot Security Notice](NOTICE.md#github-copilot-security-notice).
|
package/README.zh-CN.md
CHANGED
|
@@ -99,7 +99,7 @@ Windows x64(`.exe`)、macOS Apple Silicon(`.dmg`)和 Linux x64(`.AppIm
|
|
|
99
99
|
| [安装与启动](docs/guides/zh-CN/getting-started.md) | 环境要求、项目概览、npx 与源码运行、无 Copilot 时的 provider-only 模式,以及网关 API Key 配置 |
|
|
100
100
|
| [Claude Code](docs/guides/zh-CN/claude-code.md) | `--claude-code` 交互式启动器、`.claude/settings.json` 环境变量、opus / sonnet / haiku 档位映射、自动压缩窗口与 WebSearch 行为 |
|
|
101
101
|
| [OpenCode](docs/guides/zh-CN/opencode.md) | OpenCode OAuth 登录、`opencode.json` 中的 `@ai-sdk/anthropic` provider、`baseURL` 约定、模型上下文上限与思考选项 |
|
|
102
|
-
| [Codex](docs/guides/zh-CN/codex.md) | 完整的 `config.toml` provider
|
|
102
|
+
| [Codex](docs/guides/zh-CN/codex.md) | 完整的 `config.toml` provider 配置块、`GITHUB_COPILOT_API_KEY` 环境变量设置、自动审核模型映射、生成 `model_catalog.json`,以及合并后的模型选择器目录与协议适配 |
|
|
103
103
|
| [Docker](docs/guides/zh-CN/docker.md) | Docker Compose 快速启动、`/data` 持久化挂载与属主修复、支持的环境变量,以及监听所有网卡地址 |
|
|
104
104
|
| [桌面应用](docs/guides/zh-CN/desktop.md) | Copilot 登录、Codex OAuth 账号切换、API Key provider、一键启停、共享模型映射、高级设置与各平台安装包 |
|
|
105
105
|
| [插件与工具搜索](docs/guides/zh-CN/integrations.md) | Responses `tool_search` MCP 桥接(opencode v2 已通过 Code Mode 延迟加载工具,不需要)、Claude Code 的 `agent-inject` 与 `tool-search` 市场插件,以及 opencode 子代理标记插件 |
|
|
@@ -107,6 +107,6 @@ Windows x64(`.exe`)、macOS Apple Silicon(`.dmg`)和 Linux x64(`.AppIm
|
|
|
107
107
|
| [命令行参考](docs/guides/zh-CN/cli.md) | 命令结构、全局选项,以及 `start`、`auth`、`debug` 子命令的完整参数与使用示例 |
|
|
108
108
|
| [配置参考](docs/guides/zh-CN/configuration.md) | `config.json` 全部配置项:网关与管理 API Key、provider 定义、模型映射、WebSocket 与 HTTP 传输、超时与上下文管理 |
|
|
109
109
|
| [API 与认证](docs/guides/zh-CN/api.md) | 支持的认证请求头与 CORS 规则、OpenAI / Codex 后端 / Anthropic 端点、用量监控接口与管理配置接口 |
|
|
110
|
-
| [故障排查](docs/guides/zh-CN/troubleshooting.md) |
|
|
110
|
+
| [故障排查](docs/guides/zh-CN/troubleshooting.md) | Copilot 加密输出失败与 Claude 模型缺失的处理方法 |
|
|
111
111
|
|
|
112
112
|
使用 GitHub Copilot 前请阅读 [GitHub Copilot 安全提示](NOTICE.md#github-copilot-security-notice)。
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { S as ensurePaths, t as SUPPORTED_PROVIDER_TYPES, x as PATHS, y as setConfiguredApiKeys } from "./config-store--1vrPTFC.js";
|
|
2
|
+
import { a as normalizeProviderBaseUrl, c as setProviderConfig, f as loadModelsDevProviderOptions, n as getRawProviderConfig, r as isSupportedProviderType } from "./config-AlcbghlW.js";
|
|
3
|
+
import { F as getConfiguredApiKeys, L as loginCodex, Z as state, a as selectCodexAccount, c as setupGitHubToken, i as removeCodexAccount, r as persistCodexCredentials, t as getCodexAccounts } from "./token-CnzxfSWL.js";
|
|
3
4
|
import { defineCommand } from "citty";
|
|
4
5
|
import consola from "consola";
|
|
5
6
|
//#region src/lib/quick-providers.ts
|
|
@@ -154,7 +155,7 @@ async function resolveProviderSelection(providerArg) {
|
|
|
154
155
|
function assertCustomProviderName(providerName) {
|
|
155
156
|
if (!providerName) throw new Error("Provider name must be a non-empty string");
|
|
156
157
|
if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(providerName)) throw new Error("Provider name must start with a letter or number and contain only letters, numbers, underscores, or hyphens");
|
|
157
|
-
if (providerName === "copilot" || providerName === "codex") throw new Error(`Provider name '${providerName}' is reserved for a builtin provider`);
|
|
158
|
+
if (providerName === "copilot" || providerName === "github-copilot" || providerName === "codex") throw new Error(`Provider name '${providerName}' is reserved for a builtin provider`);
|
|
158
159
|
}
|
|
159
160
|
async function promptRequiredText(message, fieldName) {
|
|
160
161
|
const value = await prompt(message, { type: "text" });
|
|
@@ -327,6 +328,7 @@ function buildCustomProviderConfig(existingProviderConfig, options) {
|
|
|
327
328
|
apiKey: options.apiKey,
|
|
328
329
|
...options.authType ? { authType: options.authType } : {},
|
|
329
330
|
pricingCurrency: options.pricingCurrency ?? existingProviderConfig.pricingCurrency,
|
|
331
|
+
...existingProviderConfig.codexModels !== void 0 ? { codexModels: existingProviderConfig.codexModels } : {},
|
|
330
332
|
...existingProviderConfig.models ? { models: existingProviderConfig.models } : {}
|
|
331
333
|
};
|
|
332
334
|
}
|
|
@@ -609,4 +611,4 @@ const auth = defineCommand({
|
|
|
609
611
|
//#endregion
|
|
610
612
|
export { runProviderSetup as a, runAuthLogin as i, runAuthCodex as n, runAuthKeys as r, auth as t };
|
|
611
613
|
|
|
612
|
-
//# sourceMappingURL=auth-
|
|
614
|
+
//# sourceMappingURL=auth-BM1NSmaY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-BM1NSmaY.js","names":[],"sources":["../src/lib/quick-providers.ts","../src/lib/interactive-prompt.ts","../src/auth.ts"],"sourcesContent":["import type { ProviderType } from \"./config\"\n\ninterface QuickProviderConfig {\n type: ProviderType\n baseUrl: string\n pricingCurrency: string\n editableType: boolean\n}\n\nexport const QUICK_PROVIDER_CONFIGS = {\n \"opencode-go\": {\n type: \"openai-compatible\",\n baseUrl: \"https://opencode.ai/zen/go\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n kimi: {\n type: \"openai-compatible\",\n baseUrl: \"https://api.kimi.com/coding\",\n pricingCurrency: \"USD\",\n editableType: true,\n },\n deepseek: {\n type: \"anthropic\",\n baseUrl: \"https://api.deepseek.com/anthropic\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n dashscope: {\n type: \"openai-compatible\",\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n openrouter: {\n type: \"anthropic\",\n baseUrl: \"https://openrouter.ai/api\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n} satisfies Record<string, QuickProviderConfig>\n\nexport type QuickProviderName = keyof typeof QUICK_PROVIDER_CONFIGS\n","import consola from \"consola\"\n\ninterface PromptSelectOption {\n label: string\n value: string\n hint?: string\n}\n\ninterface TextPromptOptions {\n type?: \"text\"\n default?: string\n initial?: string\n placeholder?: string\n}\n\ninterface SelectPromptOptions {\n type: \"select\"\n initial?: string\n options: Array<string | PromptSelectOption>\n}\n\nexport type InteractivePromptOptions = SelectPromptOptions | TextPromptOptions\n\ninterface ClackSelectOptions {\n message: string\n initialValue?: string\n options: Array<PromptSelectOption>\n}\n\ninterface ClackTextOptions {\n message: string\n defaultValue?: string\n initialValue?: string\n placeholder?: string\n}\n\nexport interface ClackPromptBackend {\n isCancel(value: unknown): boolean\n select(options: ClackSelectOptions): Promise<string | symbol>\n text(options: ClackTextOptions): Promise<string | symbol>\n}\n\ninterface PromptRuntime {\n bunVersion?: string\n platform: NodeJS.Platform\n stdinIsTTY?: boolean\n stdoutIsTTY?: boolean\n stdoutIsTTYStream?: boolean\n}\n\n// Consola 3.4.2 bundles a prompt implementation that writes keyboard input to\n// tty fd 0. Bun treats that as a real stdin write on Windows and throws EPIPE.\nexport function shouldUseClackPrompt(\n runtime: PromptRuntime = {\n bunVersion: process.versions.bun,\n platform: process.platform,\n stdinIsTTY: process.stdin.isTTY,\n stdoutIsTTY: process.stdout.isTTY,\n stdoutIsTTYStream: typeof process.stdout.getColorDepth === \"function\",\n },\n): boolean {\n return Boolean(\n runtime.platform === \"win32\"\n && runtime.bunVersion\n && runtime.stdinIsTTY\n && runtime.stdoutIsTTY\n && runtime.stdoutIsTTYStream,\n )\n}\n\nfunction getCancelValue(options: InteractivePromptOptions): string | undefined {\n return options.type === \"select\" ?\n options.initial\n : (options.default ?? options.initial)\n}\n\nexport async function promptWithClack(\n message: string,\n options: InteractivePromptOptions,\n backend: ClackPromptBackend,\n): Promise<string | undefined> {\n if (options.type === \"select\") {\n const value = await backend.select({\n message,\n options: options.options.map((option) =>\n typeof option === \"string\" ? { label: option, value: option } : option,\n ),\n initialValue: options.initial,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n }\n\n const value = await backend.text({\n message,\n defaultValue: options.default,\n initialValue: options.initial,\n placeholder: options.placeholder,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n}\n\nexport async function prompt(\n message: string,\n options: InteractivePromptOptions,\n): Promise<string | undefined> {\n if (!shouldUseClackPrompt()) {\n if (options.type === \"select\") {\n const value = await consola.prompt(message, options)\n return typeof value === \"string\" ? value : undefined\n }\n return await consola.prompt(message, options)\n }\n\n const clack = await import(\"@clack/prompts\")\n return await promptWithClack(message, options, clack)\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n getRawProviderConfig,\n isSupportedProviderType,\n normalizeProviderBaseUrl,\n setProviderConfig,\n setConfiguredApiKeys,\n SUPPORTED_PROVIDER_TYPES,\n type ProviderAuthType,\n type ProviderConfig,\n type ProviderType,\n} from \"./lib/config\"\nimport { loginCodex } from \"./lib/oauth/codex\"\nimport {\n loadModelsDevProviderOptions,\n type ModelsDevProviderOption,\n} from \"./lib/models-dev-cache\"\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { getConfiguredApiKeys } from \"./lib/request-auth\"\nimport {\n QUICK_PROVIDER_CONFIGS,\n type QuickProviderName,\n} from \"./lib/quick-providers\"\nimport { prompt } from \"./lib/interactive-prompt\"\nimport { state } from \"./lib/state\"\nimport {\n getCodexAccounts,\n persistCodexCredentials,\n removeCodexAccount,\n selectCodexAccount,\n setupGitHubToken,\n type CodexAccountSummary,\n} from \"./lib/token\"\n\ninterface RunAuthOptions {\n alias?: string\n provider?: string\n verbose: boolean\n showToken: boolean\n}\n\nconst authArgs = {\n provider: {\n type: \"string\",\n description:\n \"Provider to log in with or configure (copilot, codex, opencode-go, kimi, deepseek, dashscope, openrouter, custom)\",\n },\n alias: {\n type: \"string\",\n description: \"Optional alias for a Codex account\",\n },\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 provider access token on auth\",\n },\n} as const\n\nconst BUILTIN_PROVIDER_NAMES = [\"copilot\", \"codex\"] as const\nconst QUICK_PROVIDER_NAMES = Object.keys(\n QUICK_PROVIDER_CONFIGS,\n) as Array<QuickProviderName>\nconst AUTH_PROVIDER_NAMES = [\n ...BUILTIN_PROVIDER_NAMES,\n ...QUICK_PROVIDER_NAMES,\n \"custom\",\n] as const\nconst CUSTOM_PROVIDER_AUTH_TYPE_OPTION = \"__default__\"\nconst QUICK_PROVIDER_DEFAULT_TYPE_OPTION = \"__default__\"\nconst CUSTOM_PROVIDER_AUTH_TYPES = [\"x-api-key\", \"authorization\"] as const\n\ntype BuiltinProviderName = (typeof BUILTIN_PROVIDER_NAMES)[number]\ntype AuthProviderName = (typeof AUTH_PROVIDER_NAMES)[number]\ntype CustomProviderAuthType = (typeof CUSTOM_PROVIDER_AUTH_TYPES)[number]\n\nconst BUILTIN_PROVIDER_LABELS: Record<BuiltinProviderName, string> = {\n copilot: \"GitHub Copilot\",\n codex: \"OpenAI Codex\",\n}\nconst AUTH_PROVIDER_LABELS: Record<AuthProviderName, string> = {\n ...BUILTIN_PROVIDER_LABELS,\n \"opencode-go\": \"OpenCode Go\",\n kimi: \"Kimi\",\n deepseek: \"DeepSeek\",\n dashscope: \"DashScope\",\n openrouter: \"OpenRouter\",\n custom: \"Custom provider\",\n}\n\nfunction isAuthProviderName(\n providerName: string,\n): providerName is AuthProviderName {\n return AUTH_PROVIDER_NAMES.includes(providerName as AuthProviderName)\n}\n\nfunction isCustomProviderAuthType(\n value: string,\n): value is CustomProviderAuthType {\n return CUSTOM_PROVIDER_AUTH_TYPES.includes(value as CustomProviderAuthType)\n}\n\nfunction isQuickProviderName(\n providerName: AuthProviderName,\n): providerName is QuickProviderName {\n return QUICK_PROVIDER_NAMES.includes(providerName as QuickProviderName)\n}\n\nasync function resolveProviderSelection(\n providerArg: string | undefined,\n): Promise<AuthProviderName> {\n const availableProviders = [...AUTH_PROVIDER_NAMES]\n\n if (providerArg !== undefined) {\n const providerName = providerArg.trim()\n if (!isAuthProviderName(providerName)) {\n throw new Error(\n `Unknown provider '${providerArg}'. Expected one of: ${availableProviders.join(\", \")}`,\n )\n }\n return providerName\n }\n\n if (availableProviders.length === 1) {\n return availableProviders[0]\n }\n\n const provider = await prompt(\"Select a provider to log in with\", {\n type: \"select\",\n options: availableProviders.map((providerName) => ({\n label: `${AUTH_PROVIDER_LABELS[providerName]} (${providerName})`,\n value: providerName,\n })),\n })\n\n if (!provider || !isAuthProviderName(provider)) {\n throw new Error(\"No provider selected\")\n }\n\n return provider\n}\n\nfunction assertCustomProviderName(providerName: string): void {\n if (!providerName) {\n throw new Error(\"Provider name must be a non-empty string\")\n }\n\n if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(providerName)) {\n throw new Error(\n \"Provider name must start with a letter or number and contain only letters, numbers, underscores, or hyphens\",\n )\n }\n\n if (\n providerName === \"copilot\"\n || providerName === \"github-copilot\"\n || providerName === \"codex\"\n ) {\n throw new Error(\n `Provider name '${providerName}' is reserved for a builtin provider`,\n )\n }\n}\n\nasync function promptRequiredText(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await prompt(message, { type: \"text\" })\n const normalizedValue = typeof value === \"string\" ? value.trim() : \"\"\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nfunction canUseMaskedPrompt(): boolean {\n return Boolean(\n process.stdin.isTTY\n && process.stdout.isTTY\n && typeof process.stdin.setRawMode === \"function\",\n )\n}\n\nasync function promptMaskedText(message: string): Promise<string> {\n if (!canUseMaskedPrompt()) {\n const value = await prompt(message, { type: \"text\" })\n return typeof value === \"string\" ? value : \"\"\n }\n\n return await new Promise<string>((resolve, reject) => {\n let value = \"\"\n const rawModeWasEnabled = process.stdin.isRaw === true\n\n function cleanup(): void {\n process.stdin.off(\"data\", onData)\n process.stdin.setRawMode(rawModeWasEnabled)\n process.stdin.pause()\n }\n\n function finish(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n resolve(value)\n }\n\n function cancel(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n reject(new Error(\"Prompt cancelled\"))\n }\n\n function onData(chunk: Buffer): void {\n const input = chunk.toString(\"utf8\")\n\n if (input.startsWith(\"\\u001B\")) {\n return\n }\n\n for (const char of input) {\n if (char === \"\\u0003\") {\n cancel()\n return\n }\n\n if (char === \"\\r\" || char === \"\\n\") {\n finish()\n return\n }\n\n if (char === \"\\b\" || char === \"\\u007F\") {\n if (value.length > 0) {\n value = value.slice(0, -1)\n process.stdout.write(\"\\b \\b\")\n }\n continue\n }\n\n if (char >= \" \") {\n value += char\n process.stdout.write(\"*\")\n }\n }\n }\n\n process.stdout.write(`${message}: `)\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on(\"data\", onData)\n })\n}\n\nasync function promptRequiredSecret(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await promptMaskedText(message)\n const normalizedValue = value.trim()\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nasync function promptCustomProviderName(defaultName?: string): Promise<string> {\n const value = await prompt(\"Enter provider name\", {\n type: \"text\",\n ...(defaultName ? { default: defaultName, initial: defaultName } : {}),\n })\n const providerName = (value || defaultName || \"\").trim()\n assertCustomProviderName(providerName)\n return providerName\n}\n\nasync function promptCustomProviderType(\n defaultType?: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\"Select provider type\", {\n type: \"select\",\n initial: defaultType,\n options: SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n })\n\n if (\n typeof providerType !== \"string\"\n || !isSupportedProviderType(providerType)\n ) {\n throw new Error(\"No provider type selected\")\n }\n\n return providerType\n}\n\nasync function promptModelsDevProvider(): Promise<\n ModelsDevProviderOption | undefined\n> {\n const source = await prompt(\"Choose custom provider source\", {\n type: \"select\",\n options: [\n { label: \"Enter manually\", value: \"manual\" },\n { label: \"Choose from models.dev\", value: \"models-dev\" },\n ],\n })\n if (source === \"manual\") return undefined\n if (source !== \"models-dev\") throw new Error(\"No provider source selected\")\n\n const providers = await loadModelsDevProviderOptions()\n const query = (\n (await prompt(\"Search models.dev providers (blank to list all)\", {\n type: \"text\",\n })) ?? \"\"\n )\n .trim()\n .toLowerCase()\n const matches = providers.filter(\n (provider) =>\n provider.id.toLowerCase().includes(query)\n || provider.name.toLowerCase().includes(query),\n )\n if (matches.length === 0) {\n throw new Error(\"No matching models.dev providers with a supported API URL\")\n }\n const selectedId = await prompt(\"Select a models.dev provider\", {\n type: \"select\",\n options: matches.map((provider) => ({\n label: `${provider.name} (${provider.id}) — ${provider.type}`,\n value: provider.id,\n })),\n })\n const selectedProvider = matches.find(\n (provider) => provider.id === selectedId,\n )\n if (!selectedProvider) throw new Error(\"No models.dev provider selected\")\n return selectedProvider\n}\n\nasync function promptQuickProviderType(\n defaultType: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\n `Select provider type (default: ${defaultType})`,\n {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultType})`,\n value: QUICK_PROVIDER_DEFAULT_TYPE_OPTION,\n },\n ...SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n ],\n },\n )\n\n if (providerType === QUICK_PROVIDER_DEFAULT_TYPE_OPTION) {\n return defaultType\n }\n\n if (\n typeof providerType === \"string\"\n && isSupportedProviderType(providerType)\n ) {\n return providerType\n }\n\n throw new Error(\"No provider type selected\")\n}\n\nfunction getDefaultProviderAuthType(\n providerType: ProviderType,\n): ProviderAuthType {\n return providerType === \"anthropic\" ? \"x-api-key\" : \"authorization\"\n}\n\nasync function promptCustomProviderAuthType(\n providerType: ProviderType,\n): Promise<ProviderAuthType | undefined> {\n const defaultAuthType = getDefaultProviderAuthType(providerType)\n const authType = await prompt(\"Select provider auth type\", {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultAuthType})`,\n value: CUSTOM_PROVIDER_AUTH_TYPE_OPTION,\n },\n ...CUSTOM_PROVIDER_AUTH_TYPES.map((value) => ({\n label: value,\n value,\n })),\n ],\n })\n\n if (authType === CUSTOM_PROVIDER_AUTH_TYPE_OPTION) {\n return undefined\n }\n\n if (typeof authType === \"string\" && isCustomProviderAuthType(authType)) {\n return authType\n }\n\n throw new Error(\"No provider auth type selected\")\n}\n\nasync function promptQuickProviderBaseUrl(\n defaultBaseUrl: string,\n): Promise<string> {\n const value = await prompt(\n `Enter provider baseUrl (default: ${defaultBaseUrl})`,\n {\n type: \"text\",\n default: defaultBaseUrl,\n initial: defaultBaseUrl,\n },\n )\n const baseUrl = normalizeProviderBaseUrl(\n typeof value === \"string\" && value.trim() ? value : defaultBaseUrl,\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n return baseUrl\n}\n\nfunction buildCustomProviderConfig(\n existingProviderConfig: ProviderConfig,\n options: {\n apiKey: string\n authType?: ProviderAuthType\n baseUrl: string\n pricingCurrency?: string\n type: ProviderType\n modelsDevProviderId?: string\n },\n): ProviderConfig {\n return {\n type: options.type,\n enabled: true,\n baseUrl: options.baseUrl,\n ...(options.modelsDevProviderId && {\n modelsDevProviderId: options.modelsDevProviderId,\n }),\n apiKey: options.apiKey,\n ...(options.authType ? { authType: options.authType } : {}),\n pricingCurrency:\n options.pricingCurrency ?? existingProviderConfig.pricingCurrency,\n ...(existingProviderConfig.codexModels !== undefined ?\n { codexModels: existingProviderConfig.codexModels }\n : {}),\n ...(existingProviderConfig.models ?\n { models: existingProviderConfig.models }\n : {}),\n }\n}\n\nasync function configureCustomProvider(): Promise<void> {\n const catalogProvider = await promptModelsDevProvider()\n const providerName = await promptCustomProviderName(catalogProvider?.id)\n const type = await promptCustomProviderType(catalogProvider?.type)\n const baseUrl =\n catalogProvider ?\n await promptQuickProviderBaseUrl(catalogProvider.api)\n : normalizeProviderBaseUrl(\n await promptRequiredText(\"Enter provider baseUrl\", \"baseUrl\"),\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n const apiKey = await promptRequiredSecret(\"Enter provider apiKey\", \"apiKey\")\n const authType = await promptCustomProviderAuthType(type)\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n authType,\n baseUrl,\n modelsDevProviderId: catalogProvider?.id,\n type,\n }),\n )\n\n consola.success(\n `Custom provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function configureQuickProvider(\n providerName: QuickProviderName,\n): Promise<void> {\n const defaultProviderConfig = QUICK_PROVIDER_CONFIGS[providerName]\n const apiKey = await promptRequiredSecret(\n `Enter ${providerName} apiKey`,\n \"apiKey\",\n )\n const type =\n defaultProviderConfig.editableType ?\n await promptQuickProviderType(defaultProviderConfig.type)\n : defaultProviderConfig.type\n const baseUrl = await promptQuickProviderBaseUrl(\n defaultProviderConfig.baseUrl,\n )\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n baseUrl,\n pricingCurrency: defaultProviderConfig.pricingCurrency,\n type,\n }),\n )\n\n consola.success(\n `${AUTH_PROVIDER_LABELS[providerName]} provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function loginWithCodex(alias?: string): Promise<void> {\n const credentials = await loginCodex({\n onAuth(info) {\n consola.info(\"Open the following URL to authenticate with Codex:\")\n consola.log(info.url)\n if (info.instructions) {\n consola.info(info.instructions)\n }\n },\n onPrompt(message) {\n return prompt(message, { type: \"text\" }).then((value) => value ?? \"\")\n },\n onProgress(message) {\n consola.debug(message)\n },\n })\n\n await persistCodexCredentials(credentials, {\n activateAccount: true,\n alias,\n enableProvider: true,\n })\n consola.success(\n `Codex provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.CODEX_CREDENTIAL_PATH}`,\n )\n}\n\nasync function loginWithProvider(\n provider: AuthProviderName,\n alias?: string,\n): Promise<void> {\n if (alias !== undefined && provider !== \"codex\") {\n throw new Error(\"--alias is only supported with the codex provider\")\n }\n\n if (provider === \"copilot\") {\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n return\n }\n\n if (provider === \"codex\") {\n await loginWithCodex(alias)\n return\n }\n\n if (isQuickProviderName(provider)) {\n await configureQuickProvider(provider)\n return\n }\n\n await configureCustomProvider()\n}\n\nexport async function runProviderSetup(): Promise<void> {\n const provider = await resolveProviderSelection(undefined)\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider)\n}\n\nexport async function runAuthLogin(options: RunAuthOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\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 const provider = await resolveProviderSelection(options.provider)\n\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider, options.alias)\n}\n\nconst authCodexArgs = {\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List stored Codex accounts\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description:\n \"Remove a Codex account by alias or account id; the account in use cannot be removed\",\n },\n use: {\n alias: \"u\",\n type: \"string\",\n description: \"Select a Codex account by alias or account id\",\n },\n} as const\n\ninterface RunAuthCodexOptions {\n list?: boolean\n remove?: string\n use?: string\n}\n\nfunction formatCodexAccountName(\n account: Pick<CodexAccountSummary, \"accountId\" | \"alias\">,\n): string {\n return account.alias ?\n `${account.alias} (${account.accountId})`\n : account.accountId\n}\n\nfunction formatCodexAccount(account: CodexAccountSummary): string {\n return `${account.active ? \"*\" : \"-\"} ${formatCodexAccountName(account)}`\n}\n\nexport async function runAuthCodex(\n options: RunAuthCodexOptions,\n): Promise<void> {\n await ensurePaths()\n\n const operationCount = [\n options.list === true,\n options.use !== undefined,\n options.remove !== undefined,\n ].filter(Boolean).length\n if (operationCount > 1) {\n throw new Error(\"Use only one of --list, --use, or --remove per invocation\")\n }\n\n if (options.use !== undefined) {\n const account = await selectCodexAccount(options.use)\n consola.success(`Selected Codex account ${formatCodexAccountName(account)}`)\n consola.info(\"Restart the server to use the selected Codex account.\")\n return\n }\n\n if (options.remove !== undefined) {\n const account = await removeCodexAccount(options.remove)\n consola.success(`Removed Codex account ${formatCodexAccountName(account)}`)\n return\n }\n\n const accounts = await getCodexAccounts()\n if (accounts.length === 0) {\n consola.info(\n \"No Codex accounts configured. Run `copilot-api auth login --provider codex` to add one.\",\n )\n return\n }\n\n consola.info(\"Configured Codex accounts:\")\n for (const account of accounts) {\n consola.info(formatCodexAccount(account))\n }\n}\n\nconst authKeysArgs = {\n add: {\n alias: \"a\",\n type: \"string\",\n description: \"Add an API key for gateway authentication\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description: \"Remove an API key\",\n },\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List configured API keys\",\n },\n clear: {\n type: \"boolean\",\n default: false,\n description: \"Remove all configured API keys\",\n },\n} as const\n\ninterface RunAuthKeysOptions {\n add?: string\n remove?: string\n list?: boolean\n clear?: boolean\n}\n\nfunction normalizeAuthKeyValue(value: string): string {\n const normalizedKey = value.trim()\n if (!normalizedKey) {\n throw new Error(\"API key must be a non-empty string\")\n }\n return normalizedKey\n}\n\nexport async function runAuthKeys(options: RunAuthKeysOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n await ensurePaths()\n\n const operations = [\n ...(options.add !== undefined ? [\"add\"] : []),\n ...(options.remove !== undefined ? [\"remove\"] : []),\n ...(options.list ? [\"list\"] : []),\n ...(options.clear ? [\"clear\"] : []),\n ]\n if (operations.length > 1) {\n throw new Error(\n \"Use only one of --add, --remove, --list, or --clear per invocation\",\n )\n }\n\n const operation = operations[0] ?? \"list\"\n\n if (operation === \"add\") {\n const apiKey = normalizeAuthKeyValue(options.add ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.includes(apiKey)) {\n consola.info(\n `API key already configured. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys([...currentKeys, apiKey])\n consola.success(\n `API key added to ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"remove\") {\n const apiKey = normalizeAuthKeyValue(options.remove ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (!currentKeys.includes(apiKey)) {\n consola.info(\n `API key not found. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys(\n currentKeys.filter((key) => key !== apiKey),\n )\n consola.success(\n `API key removed from ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"clear\") {\n setConfiguredApiKeys([])\n consola.success(`Removed all API keys from ${PATHS.CONFIG_PATH}.`)\n return\n }\n\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.length === 0) {\n consola.info(\n \"No API keys configured. Run `npx @jeffreycao/copilot-api@latest auth keys --add <key>` to add one.\",\n )\n return\n }\n consola.info(\"Configured API keys:\")\n for (const key of currentKeys) {\n consola.info(`- ${key}`)\n }\n}\n\nconst authLogin = defineCommand({\n meta: {\n name: \"login\",\n description:\n \"Authenticate or configure a provider without running the server\",\n },\n args: authArgs,\n run({ args }) {\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n\nconst authKeys = defineCommand({\n meta: {\n name: \"keys\",\n description: \"Manage gateway API keys (auth.apiKeys) in the config\",\n },\n args: authKeysArgs,\n run({ args }) {\n return runAuthKeys({\n add: args.add,\n remove: args.remove,\n list: args.list,\n clear: args.clear,\n })\n },\n})\n\nconst authCodex = defineCommand({\n meta: {\n name: \"codex\",\n description: \"List, select, or remove stored Codex accounts\",\n },\n args: authCodexArgs,\n run({ args }) {\n return runAuthCodex({\n list: args.list,\n remove: args.remove,\n use: args.use,\n })\n },\n})\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run authentication flows without running the server\",\n },\n args: authArgs,\n subCommands: {\n codex: authCodex,\n login: authLogin,\n keys: authKeys,\n },\n run({ args }) {\n if ((args._[0] ?? \"\").trim()) {\n return\n }\n\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,357 +1,8 @@
|
|
|
1
|
+
import { _ as readEditableConfigFromDisk, b as writeConfigToDisk, c as getConfig, n as defaultConfig, r as defaultContextManagement, t as SUPPORTED_PROVIDER_TYPES, v as reloadConfig, x as PATHS } from "./config-store--1vrPTFC.js";
|
|
1
2
|
import consola from "consola";
|
|
2
|
-
import { createHash,
|
|
3
|
-
import fs from "node:fs";
|
|
3
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import fs
|
|
6
|
-
import os from "node:os";
|
|
7
|
-
//#region src/lib/atomic-file.ts
|
|
8
|
-
const TEMP_FILE_RANDOM_BYTES = 8;
|
|
9
|
-
const fsyncDirectory = (directory) => {
|
|
10
|
-
if (process.platform === "win32") return;
|
|
11
|
-
let directoryFd;
|
|
12
|
-
try {
|
|
13
|
-
directoryFd = fs.openSync(directory, "r");
|
|
14
|
-
fs.fsyncSync(directoryFd);
|
|
15
|
-
} catch (error) {
|
|
16
|
-
console.warn(`Failed to fsync directory: ${directory}`, error);
|
|
17
|
-
} finally {
|
|
18
|
-
if (directoryFd !== void 0) try {
|
|
19
|
-
fs.closeSync(directoryFd);
|
|
20
|
-
} catch {}
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
function writeFileAtomically(filePath, content) {
|
|
24
|
-
const directory = path.dirname(filePath);
|
|
25
|
-
const tempPath = path.join(directory, `.${path.basename(filePath)}.${process.pid}.${randomBytes(TEMP_FILE_RANDOM_BYTES).toString("hex")}.tmp`);
|
|
26
|
-
fs.mkdirSync(directory, { recursive: true });
|
|
27
|
-
let fileDescriptor;
|
|
28
|
-
let tempFileCreated = false;
|
|
29
|
-
try {
|
|
30
|
-
fileDescriptor = fs.openSync(tempPath, "wx", 384);
|
|
31
|
-
tempFileCreated = true;
|
|
32
|
-
fs.writeFileSync(fileDescriptor, content, "utf8");
|
|
33
|
-
fs.fsyncSync(fileDescriptor);
|
|
34
|
-
fs.closeSync(fileDescriptor);
|
|
35
|
-
fileDescriptor = void 0;
|
|
36
|
-
fs.renameSync(tempPath, filePath);
|
|
37
|
-
tempFileCreated = false;
|
|
38
|
-
fsyncDirectory(directory);
|
|
39
|
-
} catch (error) {
|
|
40
|
-
if (fileDescriptor !== void 0) try {
|
|
41
|
-
fs.closeSync(fileDescriptor);
|
|
42
|
-
} catch {}
|
|
43
|
-
if (tempFileCreated) try {
|
|
44
|
-
fs.rmSync(tempPath, { force: true });
|
|
45
|
-
} catch {}
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/lib/paths.ts
|
|
51
|
-
const AUTH_APP = process.env.COPILOT_API_OAUTH_APP?.trim() || "";
|
|
52
|
-
const ENTERPRISE_PREFIX = process.env.COPILOT_API_ENTERPRISE_URL ? "ent_" : "";
|
|
53
|
-
const DEFAULT_DIR = path.join(os.homedir(), ".local", "share", "copilot-api");
|
|
54
|
-
const APP_DIR = process.env.COPILOT_API_HOME || DEFAULT_DIR;
|
|
55
|
-
const PATHS = {
|
|
56
|
-
APP_DIR,
|
|
57
|
-
GITHUB_TOKEN_PATH: path.join(APP_DIR, AUTH_APP, ENTERPRISE_PREFIX + "github_token"),
|
|
58
|
-
CODEX_CREDENTIAL_PATH: path.join(APP_DIR, "codex_credentials.json"),
|
|
59
|
-
CONFIG_PATH: path.join(APP_DIR, "config.json")
|
|
60
|
-
};
|
|
61
|
-
async function ensurePaths() {
|
|
62
|
-
await fs$1.mkdir(path.join(PATHS.APP_DIR, AUTH_APP), { recursive: true });
|
|
63
|
-
await ensureFile(PATHS.GITHUB_TOKEN_PATH);
|
|
64
|
-
await ensureFile(PATHS.CONFIG_PATH);
|
|
65
|
-
}
|
|
66
|
-
async function ensureFile(filePath) {
|
|
67
|
-
try {
|
|
68
|
-
await fs$1.access(filePath, fs$1.constants.W_OK);
|
|
69
|
-
} catch {
|
|
70
|
-
await fs$1.writeFile(filePath, "");
|
|
71
|
-
await fs$1.chmod(filePath, 384);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
//#endregion
|
|
75
|
-
//#region src/lib/config-store.ts
|
|
76
|
-
const defaultUpstreamTransportConfig = {
|
|
77
|
-
headersTimeoutMs: 3e5,
|
|
78
|
-
streamInactivityTimeoutMs: 3e5,
|
|
79
|
-
websocketMaxBufferedBytes: 8388608,
|
|
80
|
-
websocketMaxBufferedMessages: 1024,
|
|
81
|
-
websocketOpenTimeoutMs: 3e4,
|
|
82
|
-
websocketPoolIdleTimeoutMs: 6e4
|
|
83
|
-
};
|
|
84
|
-
const SUPPORTED_PROVIDER_TYPES = [
|
|
85
|
-
"anthropic",
|
|
86
|
-
"openai-compatible",
|
|
87
|
-
"openai-responses"
|
|
88
|
-
];
|
|
89
|
-
const modelResponsesApiCompactThresholds = {
|
|
90
|
-
"gpt-5.4": 217600,
|
|
91
|
-
"gpt-5.5": 217600
|
|
92
|
-
};
|
|
93
|
-
const defaultContextManagement = {
|
|
94
|
-
messages: true,
|
|
95
|
-
responses: false
|
|
96
|
-
};
|
|
97
|
-
const defaultConfig = {
|
|
98
|
-
auth: { apiKeys: [] },
|
|
99
|
-
providers: {},
|
|
100
|
-
modelMappings: {},
|
|
101
|
-
smallModels: {
|
|
102
|
-
codex: "gpt-6-luna",
|
|
103
|
-
copilot: "gpt-6-luna"
|
|
104
|
-
},
|
|
105
|
-
contextManagement: defaultContextManagement,
|
|
106
|
-
modelResponsesApiCompactThresholds,
|
|
107
|
-
useMessagesApi: true,
|
|
108
|
-
useResponsesApiWebSocket: true,
|
|
109
|
-
upstreamTransport: defaultUpstreamTransportConfig,
|
|
110
|
-
useResponsesApiWebSearch: true,
|
|
111
|
-
alphaSearchCodexPriority: true,
|
|
112
|
-
alphaSearchModel: "gpt-6-luna",
|
|
113
|
-
messageApiWebSearchModel: "gpt-6-luna"
|
|
114
|
-
};
|
|
115
|
-
let cachedConfig = null;
|
|
116
|
-
function normalizeAdminApiKey(adminApiKey) {
|
|
117
|
-
if (typeof adminApiKey !== "string") {
|
|
118
|
-
if (adminApiKey !== void 0) consola.warn("Invalid auth.adminApiKey config. Expected a non-empty string.");
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const normalizedAdminApiKey = adminApiKey.trim();
|
|
122
|
-
if (!normalizedAdminApiKey) {
|
|
123
|
-
consola.warn("Invalid auth.adminApiKey config. Expected a non-empty string.");
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return normalizedAdminApiKey;
|
|
127
|
-
}
|
|
128
|
-
function generateAdminApiKey() {
|
|
129
|
-
return randomBytes(32).toString("hex");
|
|
130
|
-
}
|
|
131
|
-
function isNodeError(error) {
|
|
132
|
-
return error instanceof Error && "code" in error;
|
|
133
|
-
}
|
|
134
|
-
function ensureConfigFile() {
|
|
135
|
-
try {
|
|
136
|
-
fs.accessSync(PATHS.CONFIG_PATH, fs.constants.F_OK);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
if (!isNodeError(error) || error.code !== "ENOENT") throw error;
|
|
139
|
-
writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
function readConfigFromDisk() {
|
|
143
|
-
ensureConfigFile();
|
|
144
|
-
const raw = fs.readFileSync(PATHS.CONFIG_PATH, "utf8");
|
|
145
|
-
if (!raw.trim()) {
|
|
146
|
-
writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`);
|
|
147
|
-
return defaultConfig;
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
return JSON.parse(raw);
|
|
151
|
-
} catch (error) {
|
|
152
|
-
const message = `Config file is not valid JSON: ${PATHS.CONFIG_PATH}. Refusing to start with the default config. Fix the JSON syntax or delete the file to regenerate a fresh config.`;
|
|
153
|
-
consola.error(message, error);
|
|
154
|
-
throw new Error(message, { cause: error });
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function readEditableConfigFromDisk() {
|
|
158
|
-
try {
|
|
159
|
-
const raw = fs.readFileSync(PATHS.CONFIG_PATH, "utf8");
|
|
160
|
-
if (!raw.trim()) return {};
|
|
161
|
-
return JSON.parse(raw);
|
|
162
|
-
} catch (error) {
|
|
163
|
-
if (isNodeError(error) && error.code === "ENOENT") return {};
|
|
164
|
-
if (error instanceof SyntaxError) throw new Error(`Config file is not valid JSON: ${PATHS.CONFIG_PATH}`);
|
|
165
|
-
throw error;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
function writeConfigToDisk(config) {
|
|
169
|
-
writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`);
|
|
170
|
-
}
|
|
171
|
-
function setConfiguredApiKeys(apiKeys) {
|
|
172
|
-
const normalizedKeys = apiKeys.map((key) => key.trim()).filter((key) => key.length > 0);
|
|
173
|
-
const uniqueKeys = [...new Set(normalizedKeys)];
|
|
174
|
-
const editableConfig = readEditableConfigFromDisk();
|
|
175
|
-
writeConfigToDisk({
|
|
176
|
-
...editableConfig,
|
|
177
|
-
auth: {
|
|
178
|
-
...editableConfig.auth,
|
|
179
|
-
apiKeys: uniqueKeys
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
reloadConfig();
|
|
183
|
-
return [...uniqueKeys];
|
|
184
|
-
}
|
|
185
|
-
function mergeDefaultConfig(config) {
|
|
186
|
-
const extraPrompts = config.extraPrompts ?? {};
|
|
187
|
-
const defaultExtraPrompts = defaultConfig.extraPrompts ?? {};
|
|
188
|
-
const responsesApiCompactThresholds = config.modelResponsesApiCompactThresholds ?? {};
|
|
189
|
-
const defaultResponsesApiCompactThresholds = defaultConfig.modelResponsesApiCompactThresholds ?? {};
|
|
190
|
-
const modelReasoningEfforts = config.modelReasoningEfforts ?? {};
|
|
191
|
-
const defaultModelReasoningEfforts = defaultConfig.modelReasoningEfforts ?? {};
|
|
192
|
-
const contextManagement = normalizeContextManagementConfig(config.contextManagement);
|
|
193
|
-
const { changed: upstreamTransportMigrated, migrated: migratedUpstreamTransport } = migrateUpstreamTransportConfig(config);
|
|
194
|
-
const upstreamTransport = normalizeUpstreamTransportConfig(migratedUpstreamTransport);
|
|
195
|
-
const defaultContextManagementConfig = defaultConfig.contextManagement ?? {};
|
|
196
|
-
const missingExtraPromptModels = Object.keys(defaultExtraPrompts).filter((model) => !Object.hasOwn(extraPrompts, model));
|
|
197
|
-
const missingReasoningEffortModels = Object.keys(defaultModelReasoningEfforts).filter((model) => !Object.hasOwn(modelReasoningEfforts, model));
|
|
198
|
-
const missingResponsesApiCompactThresholdModels = Object.keys(defaultResponsesApiCompactThresholds).filter((model) => !Object.hasOwn(responsesApiCompactThresholds, model));
|
|
199
|
-
const missingContextManagementKeys = Object.keys(defaultContextManagementConfig).filter((key) => !Object.hasOwn(contextManagement, key));
|
|
200
|
-
const hasExtraPromptChanges = missingExtraPromptModels.length > 0;
|
|
201
|
-
const hasReasoningEffortChanges = missingReasoningEffortModels.length > 0;
|
|
202
|
-
const hasResponsesApiCompactThresholdChanges = missingResponsesApiCompactThresholdModels.length > 0;
|
|
203
|
-
const hasContextManagementChanges = missingContextManagementKeys.length > 0;
|
|
204
|
-
const hasUpstreamTransportChanges = Object.entries(upstreamTransport).some(([key, value]) => migratedUpstreamTransport[key] !== value);
|
|
205
|
-
if (!hasExtraPromptChanges && !hasReasoningEffortChanges && !hasResponsesApiCompactThresholdChanges && !hasContextManagementChanges && !hasUpstreamTransportChanges && !upstreamTransportMigrated) return {
|
|
206
|
-
mergedConfig: config,
|
|
207
|
-
changed: false
|
|
208
|
-
};
|
|
209
|
-
const { responsesTransport: _legacyResponsesTransport, ...persistedConfig } = config;
|
|
210
|
-
return {
|
|
211
|
-
mergedConfig: {
|
|
212
|
-
...persistedConfig,
|
|
213
|
-
contextManagement: {
|
|
214
|
-
...defaultContextManagementConfig,
|
|
215
|
-
...contextManagement
|
|
216
|
-
},
|
|
217
|
-
extraPrompts: {
|
|
218
|
-
...defaultExtraPrompts,
|
|
219
|
-
...extraPrompts
|
|
220
|
-
},
|
|
221
|
-
modelResponsesApiCompactThresholds: {
|
|
222
|
-
...defaultResponsesApiCompactThresholds,
|
|
223
|
-
...responsesApiCompactThresholds
|
|
224
|
-
},
|
|
225
|
-
modelReasoningEfforts: {
|
|
226
|
-
...defaultModelReasoningEfforts,
|
|
227
|
-
...modelReasoningEfforts
|
|
228
|
-
},
|
|
229
|
-
upstreamTransport
|
|
230
|
-
},
|
|
231
|
-
changed: true
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
function normalizeContextManagementConfig(value) {
|
|
235
|
-
if (!value || typeof value !== "object") return {};
|
|
236
|
-
return {
|
|
237
|
-
...typeof value.messages === "boolean" ? { messages: value.messages } : {},
|
|
238
|
-
...typeof value.responses === "boolean" ? { responses: value.responses } : {}
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
const migrateUpstreamTransportConfig = (config) => {
|
|
242
|
-
const legacyBlock = config.responsesTransport;
|
|
243
|
-
const { headersTimeoutMsV2, ...migrated } = config.upstreamTransport ?? legacyBlock ?? {};
|
|
244
|
-
const hasLegacyBlock = legacyBlock !== void 0;
|
|
245
|
-
const hasLegacyHeadersTimeout = headersTimeoutMsV2 !== void 0;
|
|
246
|
-
if (!hasLegacyBlock && !hasLegacyHeadersTimeout) return {
|
|
247
|
-
changed: false,
|
|
248
|
-
migrated
|
|
249
|
-
};
|
|
250
|
-
consola.info("Migrating deprecated transport config: responsesTransport -> upstreamTransport, headersTimeoutMsV2 -> headersTimeoutMs");
|
|
251
|
-
return {
|
|
252
|
-
changed: true,
|
|
253
|
-
migrated: migrated.headersTimeoutMs === void 0 && hasLegacyHeadersTimeout ? {
|
|
254
|
-
...migrated,
|
|
255
|
-
headersTimeoutMs: headersTimeoutMsV2
|
|
256
|
-
} : migrated
|
|
257
|
-
};
|
|
258
|
-
};
|
|
259
|
-
function ensureAdminApiKey(config) {
|
|
260
|
-
const normalizedAdminApiKey = normalizeAdminApiKey(config.auth?.adminApiKey);
|
|
261
|
-
if (normalizedAdminApiKey) {
|
|
262
|
-
if (config.auth?.adminApiKey === normalizedAdminApiKey) return {
|
|
263
|
-
mergedConfig: config,
|
|
264
|
-
changed: false
|
|
265
|
-
};
|
|
266
|
-
return {
|
|
267
|
-
mergedConfig: {
|
|
268
|
-
...config,
|
|
269
|
-
auth: {
|
|
270
|
-
...config.auth,
|
|
271
|
-
adminApiKey: normalizedAdminApiKey
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
changed: true
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
const editableConfig = readEditableConfigFromDisk();
|
|
278
|
-
const { mergedConfig } = mergeDefaultConfig({
|
|
279
|
-
...editableConfig,
|
|
280
|
-
auth: {
|
|
281
|
-
...editableConfig.auth,
|
|
282
|
-
adminApiKey: generateAdminApiKey()
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
return {
|
|
286
|
-
mergedConfig,
|
|
287
|
-
changed: true
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
function mergeConfigWithDefaults() {
|
|
291
|
-
const { mergedConfig, changed } = mergeDefaultConfig(readConfigFromDisk());
|
|
292
|
-
const { mergedConfig: mergedConfigWithAdminApiKey, changed: adminApiKeyChanged } = ensureAdminApiKey(mergedConfig);
|
|
293
|
-
if (changed || adminApiKeyChanged) try {
|
|
294
|
-
writeConfigToDisk(mergedConfigWithAdminApiKey);
|
|
295
|
-
} catch (writeError) {
|
|
296
|
-
if (adminApiKeyChanged) throw writeError;
|
|
297
|
-
consola.warn("Failed to write merged default config to config file", writeError);
|
|
298
|
-
}
|
|
299
|
-
cachedConfig = mergedConfigWithAdminApiKey;
|
|
300
|
-
return mergedConfigWithAdminApiKey;
|
|
301
|
-
}
|
|
302
|
-
function getConfig() {
|
|
303
|
-
cachedConfig ??= mergeDefaultConfig(readConfigFromDisk()).mergedConfig;
|
|
304
|
-
return cachedConfig;
|
|
305
|
-
}
|
|
306
|
-
function reloadConfig() {
|
|
307
|
-
return mergeConfigWithDefaults();
|
|
308
|
-
}
|
|
309
|
-
function isMessagesApiEnabled() {
|
|
310
|
-
return getConfig().useMessagesApi ?? true;
|
|
311
|
-
}
|
|
312
|
-
function isResponsesApiWebSocketEnabled() {
|
|
313
|
-
return getConfig().useResponsesApiWebSocket ?? true;
|
|
314
|
-
}
|
|
315
|
-
function getUpstreamTransportConfig() {
|
|
316
|
-
return normalizeUpstreamTransportConfig(getConfig().upstreamTransport);
|
|
317
|
-
}
|
|
318
|
-
const normalizeUpstreamTransportConfig = (configured) => ({
|
|
319
|
-
headersTimeoutMs: positiveIntegerOrDefault(configured?.headersTimeoutMs, defaultUpstreamTransportConfig.headersTimeoutMs),
|
|
320
|
-
streamInactivityTimeoutMs: positiveIntegerOrDefault(configured?.streamInactivityTimeoutMs, defaultUpstreamTransportConfig.streamInactivityTimeoutMs),
|
|
321
|
-
websocketMaxBufferedBytes: positiveIntegerOrDefault(configured?.websocketMaxBufferedBytes, defaultUpstreamTransportConfig.websocketMaxBufferedBytes),
|
|
322
|
-
websocketMaxBufferedMessages: positiveIntegerOrDefault(configured?.websocketMaxBufferedMessages, defaultUpstreamTransportConfig.websocketMaxBufferedMessages),
|
|
323
|
-
websocketOpenTimeoutMs: positiveIntegerOrDefault(configured?.websocketOpenTimeoutMs, defaultUpstreamTransportConfig.websocketOpenTimeoutMs),
|
|
324
|
-
websocketPoolIdleTimeoutMs: positiveIntegerOrDefault(configured?.websocketPoolIdleTimeoutMs, defaultUpstreamTransportConfig.websocketPoolIdleTimeoutMs)
|
|
325
|
-
});
|
|
326
|
-
const positiveIntegerOrDefault = (value, fallback) => {
|
|
327
|
-
if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
|
|
328
|
-
const normalized = Math.floor(value);
|
|
329
|
-
return normalized > 0 ? normalized : fallback;
|
|
330
|
-
};
|
|
331
|
-
function getAnthropicApiKey() {
|
|
332
|
-
return getConfig().anthropicApiKey ?? process.env.ANTHROPIC_API_KEY ?? void 0;
|
|
333
|
-
}
|
|
334
|
-
function isResponsesApiWebSearchEnabled() {
|
|
335
|
-
return getConfig().useResponsesApiWebSearch ?? true;
|
|
336
|
-
}
|
|
337
|
-
function isAlphaSearchCodexPriorityEnabled() {
|
|
338
|
-
return getConfig().alphaSearchCodexPriority ?? true;
|
|
339
|
-
}
|
|
340
|
-
function getAlphaSearchModel() {
|
|
341
|
-
return (getConfig().alphaSearchModel ?? "gpt-6-luna").trim() || void 0;
|
|
342
|
-
}
|
|
343
|
-
function getMessageApiWebSearchModel() {
|
|
344
|
-
const model = getConfig().messageApiWebSearchModel ?? "gpt-6-luna";
|
|
345
|
-
return model && model.trim().length > 0 ? model : void 0;
|
|
346
|
-
}
|
|
347
|
-
function getClaudeAutoModel() {
|
|
348
|
-
const model = getConfig().claudeAutoModel;
|
|
349
|
-
return model && model.trim().length > 0 ? model.trim() : void 0;
|
|
350
|
-
}
|
|
351
|
-
function getClaudeTokenMultiplier() {
|
|
352
|
-
return getConfig().claudeTokenMultiplier ?? 1.15;
|
|
353
|
-
}
|
|
354
|
-
//#endregion
|
|
5
|
+
import fs from "node:fs/promises";
|
|
355
6
|
//#region src/lib/model-policy.ts
|
|
356
7
|
const GPT_MODEL_PATTERN = /^gpt-(\d+)(?:\.(\d+))?/;
|
|
357
8
|
function isGpt53OrAbove(model) {
|
|
@@ -413,10 +64,11 @@ function validateModelMappings(modelMappings) {
|
|
|
413
64
|
return validatedMappings;
|
|
414
65
|
}
|
|
415
66
|
function setModelMappings(modelMappings) {
|
|
416
|
-
|
|
67
|
+
const nextConfig = {
|
|
417
68
|
...readEditableConfigFromDisk(),
|
|
418
69
|
modelMappings: validateModelMappings(modelMappings)
|
|
419
|
-
}
|
|
70
|
+
};
|
|
71
|
+
writeConfigToDisk(nextConfig);
|
|
420
72
|
reloadConfig();
|
|
421
73
|
return getModelMappings();
|
|
422
74
|
}
|
|
@@ -704,7 +356,7 @@ async function stopModelsDevRefreshLoop() {
|
|
|
704
356
|
async function loadDiskCache(cachePath) {
|
|
705
357
|
let body;
|
|
706
358
|
try {
|
|
707
|
-
body = await fs
|
|
359
|
+
body = await fs.readFile(cachePath, "utf8");
|
|
708
360
|
installModelsDevCatalog(JSON.parse(body));
|
|
709
361
|
cachedBodyHash = hashBody(body);
|
|
710
362
|
} catch (error) {
|
|
@@ -713,7 +365,7 @@ async function loadDiskCache(cachePath) {
|
|
|
713
365
|
return;
|
|
714
366
|
}
|
|
715
367
|
try {
|
|
716
|
-
const metadata = JSON.parse(await fs
|
|
368
|
+
const metadata = JSON.parse(await fs.readFile(getMetadataPath(cachePath), "utf8"));
|
|
717
369
|
if (isRecord(metadata) && metadata.sha256 === cachedBodyHash) responseValidator = {
|
|
718
370
|
etag: typeof metadata.etag === "string" && metadata.etag.trim() ? metadata.etag : void 0,
|
|
719
371
|
lastModified: typeof metadata.lastModified === "string" && metadata.lastModified.trim() ? metadata.lastModified : void 0
|
|
@@ -727,24 +379,24 @@ async function persistMetadata(cachePath, sha256, validator) {
|
|
|
727
379
|
const metadataPath = getMetadataPath(cachePath);
|
|
728
380
|
const temporaryPath = `${metadataPath}.${randomUUID()}.tmp`;
|
|
729
381
|
try {
|
|
730
|
-
await fs
|
|
382
|
+
await fs.writeFile(temporaryPath, JSON.stringify({
|
|
731
383
|
sha256,
|
|
732
384
|
...validator
|
|
733
385
|
}), { mode: 384 });
|
|
734
|
-
await fs
|
|
386
|
+
await fs.rename(temporaryPath, metadataPath);
|
|
735
387
|
} finally {
|
|
736
|
-
await fs
|
|
388
|
+
await fs.rm(temporaryPath, { force: true });
|
|
737
389
|
}
|
|
738
390
|
}
|
|
739
391
|
async function persistCache(cachePath, body, sha256, validator) {
|
|
740
|
-
await fs
|
|
392
|
+
await fs.mkdir(path.dirname(cachePath), { recursive: true });
|
|
741
393
|
const temporaryPath = `${cachePath}.${randomUUID()}.tmp`;
|
|
742
394
|
try {
|
|
743
|
-
await fs
|
|
744
|
-
await fs
|
|
395
|
+
await fs.writeFile(temporaryPath, body, { mode: 384 });
|
|
396
|
+
await fs.rename(temporaryPath, cachePath);
|
|
745
397
|
await persistMetadata(cachePath, sha256, validator);
|
|
746
398
|
} finally {
|
|
747
|
-
await fs
|
|
399
|
+
await fs.rm(temporaryPath, { force: true });
|
|
748
400
|
}
|
|
749
401
|
}
|
|
750
402
|
async function refreshCatalog(cachePath, fetcher, signal, generation) {
|
|
@@ -864,13 +516,14 @@ function setProviderConfig(name, provider) {
|
|
|
864
516
|
if (!providerName) throw new Error("Provider name must be a non-empty string");
|
|
865
517
|
if (isReservedProviderName(providerName)) throw new Error(`Provider ${providerName} is reserved and cannot be configured in config.providers`);
|
|
866
518
|
const editableConfig = readEditableConfigFromDisk();
|
|
867
|
-
|
|
519
|
+
const nextConfig = {
|
|
868
520
|
...editableConfig,
|
|
869
521
|
providers: {
|
|
870
522
|
...editableConfig.providers,
|
|
871
523
|
[providerName]: provider
|
|
872
524
|
}
|
|
873
|
-
}
|
|
525
|
+
};
|
|
526
|
+
writeConfigToDisk(nextConfig);
|
|
874
527
|
reloadConfig();
|
|
875
528
|
return getRawProviderConfig(providerName) ?? provider;
|
|
876
529
|
}
|
|
@@ -906,7 +559,8 @@ function getProviderConfig(name) {
|
|
|
906
559
|
authType,
|
|
907
560
|
authTypeExplicit: provider.authType !== void 0,
|
|
908
561
|
pricingCurrency: normalizePricingCurrency(provider.pricingCurrency),
|
|
909
|
-
models: provider.models
|
|
562
|
+
models: provider.models,
|
|
563
|
+
codexModels: provider.codexModels
|
|
910
564
|
};
|
|
911
565
|
}
|
|
912
566
|
function resolveEffectiveProviderType(providerConfig, model) {
|
|
@@ -949,12 +603,12 @@ function normalizePricingCurrency(value) {
|
|
|
949
603
|
}
|
|
950
604
|
function listEnabledProviders() {
|
|
951
605
|
const config = getConfig();
|
|
952
|
-
return Object.keys(config.providers ?? {}).filter((name) => getProviderConfig(name) !== null);
|
|
606
|
+
return Object.keys(config.providers ?? {}).filter((name) => !isReservedProviderName(name) && getProviderConfig(name) !== null);
|
|
953
607
|
}
|
|
954
608
|
function isReservedProviderName(name) {
|
|
955
|
-
return name.trim() === "copilot";
|
|
609
|
+
return name.trim() === "copilot" || name.trim() === "github-copilot";
|
|
956
610
|
}
|
|
957
611
|
//#endregion
|
|
958
|
-
export {
|
|
612
|
+
export { resolveMappedModel as C, isGpt56OrAbove as S, getReasoningEffortForModel as _, normalizeProviderBaseUrl as a, isContextManagementEnabledForMessages as b, setProviderConfig as c, getOpencodeGoModelRecords as d, loadModelsDevProviderOptions as f, getModelResponsesApiCompactThreshold as g, getModelMappings as h, listEnabledProviders as i, getOpencodeGoModelConfig as l, getExtraPromptForModel as m, getRawProviderConfig as n, resolveEffectiveProviderType as o, startModelsDevCache as p, isSupportedProviderType as r, resolveProviderConfigForModel as s, getProviderConfig as t, getOpencodeGoModelIds as u, getSmallModel as v, setModelMappings as w, isContextManagementEnabledForResponses as x, getSmallModelForProvider as y };
|
|
959
613
|
|
|
960
|
-
//# sourceMappingURL=config-
|
|
614
|
+
//# sourceMappingURL=config-AlcbghlW.js.map
|