@jeffreycao/copilot-api 2.7.2 → 2.7.4
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 +7 -7
- package/README.zh-CN.md +7 -7
- package/dist/{auth-DC-EO-eb.js → auth-D1czv5AK.js} +5 -5
- package/dist/auth-D1czv5AK.js.map +1 -0
- package/dist/auth-DZZzrMnx.js +2 -0
- package/dist/{config-DIDLVXMU.js → config-D1F-TyTn.js} +3 -3
- package/dist/{config-DIDLVXMU.js.map → config-D1F-TyTn.js.map} +1 -1
- package/dist/{config-store-CMgB1mCV.js → config-store-Bgmf82i_.js} +29 -5
- package/dist/config-store-Bgmf82i_.js.map +1 -0
- package/dist/{copilot-runtime-CRTYwDWy.js → copilot-runtime-BCf245Y5.js} +4 -90
- package/dist/copilot-runtime-BCf245Y5.js.map +1 -0
- package/dist/{debug-B0URJ4gT.js → debug-EkODckEE.js} +3 -3
- package/dist/{debug-B0URJ4gT.js.map → debug-EkODckEE.js.map} +1 -1
- package/dist/{github-copilot-provider-CLEAHyT-.js → github-copilot-provider-Cx4Afaco.js} +2 -2
- package/dist/{github-copilot-provider-CLEAHyT-.js.map → github-copilot-provider-Cx4Afaco.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{provider-C2Hs8Dua.js → provider-DXivPd6W.js} +2 -2
- package/dist/{provider-C2Hs8Dua.js.map → provider-DXivPd6W.js.map} +1 -1
- package/dist/{provider-management-BjU3aJnC.js → provider-management-DiQ92JMT.js} +12 -12
- package/dist/provider-management-DiQ92JMT.js.map +1 -0
- package/dist/{server-DbkseGH6.js → server-BmGSx45N.js} +226 -39
- package/dist/server-BmGSx45N.js.map +1 -0
- package/dist/{start-C_Svr70X.js → start-CaNs870A.js} +13 -111
- package/dist/start-CaNs870A.js.map +1 -0
- package/dist/{token-BjzzuPSb.js → token-CBDlQufZ.js} +6 -6
- package/dist/token-CBDlQufZ.js.map +1 -0
- package/package.json +1 -2
- package/dist/auth-C3_rHdk6.js +0 -2
- package/dist/auth-DC-EO-eb.js.map +0 -1
- package/dist/config-store-CMgB1mCV.js.map +0 -1
- package/dist/copilot-runtime-CRTYwDWy.js.map +0 -1
- package/dist/provider-management-BjU3aJnC.js.map +0 -1
- package/dist/server-DbkseGH6.js.map +0 -1
- package/dist/start-C_Svr70X.js.map +0 -1
- package/dist/token-BjzzuPSb.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { a as getAnthropicApiKey, c as getConfig, f as isAlphaSearchCodexPriorityEnabled, h as isResponsesApiWebSocketEnabled, i as getAlphaSearchModel, l as getMessageApiWebSearchModel, m as isResponsesApiWebSearchEnabled, o as getClaudeAutoModel, p as isMessagesApiEnabled, s as getClaudeTokenMultiplier, u as getUpstreamTransportConfig, v as reloadConfig, x as PATHS } from "./config-store-
|
|
2
|
-
import { C as isGpt56OrAbove, S as isContextManagementEnabledForResponses, T as setModelMappings, _ as getModelResponsesApiCompactThreshold$1, b as getSmallModelForProvider, d as getOpencodeGoModelIds, f as getOpencodeGoModelRecords, g as getModelMappings, h as getExtraPromptForModel, i as listEnabledProviders, l as getModelsDevModelMaxOutputTokens, n as getRawProviderConfig, o as resolveEffectiveProviderType, s as resolveProviderConfigForModel, t as getProviderConfig, u as getOpencodeGoModelConfig, v as getReasoningEffortForModel, w as resolveMappedModel, x as isContextManagementEnabledForMessages, y as getSmallModel } from "./config-
|
|
3
|
-
import { i as HTTPError, r as isGitHubCopilotEnabled, s as forwardError } from "./github-copilot-provider-
|
|
4
|
-
import { $ as
|
|
1
|
+
import { a as getAnthropicApiKey, c as getConfig, f as isAlphaSearchCodexPriorityEnabled, h as isResponsesApiWebSocketEnabled, i as getAlphaSearchModel, l as getMessageApiWebSearchModel, m as isResponsesApiWebSearchEnabled, o as getClaudeAutoModel, p as isMessagesApiEnabled, s as getClaudeTokenMultiplier, u as getUpstreamTransportConfig, v as reloadConfig, x as PATHS } from "./config-store-Bgmf82i_.js";
|
|
2
|
+
import { C as isGpt56OrAbove, S as isContextManagementEnabledForResponses, T as setModelMappings, _ as getModelResponsesApiCompactThreshold$1, b as getSmallModelForProvider, d as getOpencodeGoModelIds, f as getOpencodeGoModelRecords, g as getModelMappings, h as getExtraPromptForModel, i as listEnabledProviders, l as getModelsDevModelMaxOutputTokens, n as getRawProviderConfig, o as resolveEffectiveProviderType, s as resolveProviderConfigForModel, t as getProviderConfig, u as getOpencodeGoModelConfig, v as getReasoningEffortForModel, w as resolveMappedModel, x as isContextManagementEnabledForMessages, y as getSmallModel } from "./config-D1F-TyTn.js";
|
|
3
|
+
import { i as HTTPError, r as isGitHubCopilotEnabled, s as forwardError, t as GITHUB_COPILOT_PROVIDER } from "./github-copilot-provider-Cx4Afaco.js";
|
|
4
|
+
import { $ as fetchUpstreamWithLifecycle, A as compactSystemPromptStarts, C as prepareForCompact, D as compactAutoContinuePromptStarts, H as readGitHubToken, I as getXaiAccessToken, J as buildCodexRequestHeaders, M as createAuthMiddleware, N as getConfiguredAdminApiKeys, O as compactMessageSections, Q as resolveTraceId$1, S as copilotWebSocketHeaders, T as prepareMessageProxyHeaders, U as readGitHubTokenFromEnv, W as XAI_API_BASE_URL, X as generateTraceId, Y as forwardCodexResponses, Z as requestContext, _ as parseUserIdMetadata, at as createWebSocketUrl, b as copilotHeaders, ct as stripInternalRequestHeaders, d as generateRequestIdFromPayload, et as createResponsesHttpEventStream, f as getRootSessionId, g as isResponsesStream, h as isNullish, it as createPooledWebSocketStream, j as compactTextOnlyGuard, m as isAsyncIterable, n as invalidateCodexRuntime, nt as encodePoolKeyPart, ot as state, p as getUUID, q as CODEX_API_BASE_URL, rt as getResponsesStreamTerminalDisposition, s as setupCodexToken, tt as createResponsesSafeStream, u as stopCopilotRefreshLoop, v as getCopilotUsage, w as prepareInteractionHeaders, y as copilotBaseUrl } from "./token-CBDlQufZ.js";
|
|
5
5
|
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-BgFcDbNQ.js";
|
|
6
|
-
import { n as
|
|
7
|
-
import {
|
|
6
|
+
import { n as isProviderAgentModelVisible, t as getProviderAgentModels } from "./provider-management-DiQ92JMT.js";
|
|
7
|
+
import { n as stopModelsRefreshLoop, t as setupCopilotRuntime } from "./copilot-runtime-BCf245Y5.js";
|
|
8
8
|
import consola from "consola";
|
|
9
|
-
import { createHash } from "node:crypto";
|
|
9
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
10
10
|
import fs, { createWriteStream, readFileSync, rmSync } from "node:fs";
|
|
11
11
|
import path, { join } from "node:path";
|
|
12
12
|
import fs$1, { mkdtemp, rm } from "node:fs/promises";
|
|
@@ -275,6 +275,68 @@ const createHandlerLogger = (name) => {
|
|
|
275
275
|
return instance;
|
|
276
276
|
};
|
|
277
277
|
//#endregion
|
|
278
|
+
//#region src/lib/models.ts
|
|
279
|
+
/**
|
|
280
|
+
* Converts a Copilot upstream model ID to a client-friendly ID that Claude Code
|
|
281
|
+
* and Claude Desktop recognize (dots in version replaced with hyphens).
|
|
282
|
+
* e.g. "claude-sonnet-4.6" -> "claude-sonnet-4-6"
|
|
283
|
+
* Non-Claude models are returned unchanged.
|
|
284
|
+
*/
|
|
285
|
+
const toClientModelId = (modelId) => {
|
|
286
|
+
const normalized = normalizeSdkModelId(modelId);
|
|
287
|
+
if (!normalized) return modelId;
|
|
288
|
+
const versionHyphenated = normalized.version.replaceAll(".", "-");
|
|
289
|
+
return `claude-${normalized.family}-${versionHyphenated}`;
|
|
290
|
+
};
|
|
291
|
+
const findEndpointModel = (sdkModelId) => {
|
|
292
|
+
const models = state.models?.data ?? [];
|
|
293
|
+
const exactMatch = models.find((m) => m.id === sdkModelId);
|
|
294
|
+
if (exactMatch) return exactMatch;
|
|
295
|
+
const normalized = normalizeSdkModelId(sdkModelId);
|
|
296
|
+
if (!normalized) return;
|
|
297
|
+
const modelName = `claude-${normalized.family}-${normalized.version}`;
|
|
298
|
+
const model = models.find((m) => m.id === modelName);
|
|
299
|
+
if (model) return model;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Normalizes an SDK model ID to extract the model family and version.
|
|
303
|
+
* this method from github copilot extension
|
|
304
|
+
* Examples:
|
|
305
|
+
* - "claude-opus-4-5-20251101" -> { family: "opus", version: "4.5" }
|
|
306
|
+
* - "claude-3-5-sonnet-20241022" -> { family: "sonnet", version: "3.5" }
|
|
307
|
+
* - "claude-sonnet-4-20250514" -> { family: "sonnet", version: "4" }
|
|
308
|
+
* - "claude-haiku-3-5-20250514" -> { family: "haiku", version: "3.5" }
|
|
309
|
+
* - "claude-haiku-4.5" -> { family: "haiku", version: "4.5" }
|
|
310
|
+
*/
|
|
311
|
+
const normalizeSdkModelId = (sdkModelId) => {
|
|
312
|
+
const withoutDate = sdkModelId.toLowerCase().replace(/-\d{8}$/, "");
|
|
313
|
+
const pattern1 = withoutDate.match(/^claude-(\w+)-(\d+)\.(\d+)$/);
|
|
314
|
+
if (pattern1) return {
|
|
315
|
+
family: pattern1[1],
|
|
316
|
+
version: `${pattern1[2]}.${pattern1[3]}`
|
|
317
|
+
};
|
|
318
|
+
const pattern2 = withoutDate.match(/^claude-(\w+)-(\d+)-(\d+)$/);
|
|
319
|
+
if (pattern2) return {
|
|
320
|
+
family: pattern2[1],
|
|
321
|
+
version: `${pattern2[2]}.${pattern2[3]}`
|
|
322
|
+
};
|
|
323
|
+
const pattern3 = withoutDate.match(/^claude-(\d+)-(\d+)-(\w+)$/);
|
|
324
|
+
if (pattern3) return {
|
|
325
|
+
family: pattern3[3],
|
|
326
|
+
version: `${pattern3[1]}.${pattern3[2]}`
|
|
327
|
+
};
|
|
328
|
+
const pattern4 = withoutDate.match(/^claude-(\w+)-(\d+)$/);
|
|
329
|
+
if (pattern4) return {
|
|
330
|
+
family: pattern4[1],
|
|
331
|
+
version: pattern4[2]
|
|
332
|
+
};
|
|
333
|
+
const pattern5 = withoutDate.match(/^claude-(\d+)-(\w+)$/);
|
|
334
|
+
if (pattern5) return {
|
|
335
|
+
family: pattern5[2],
|
|
336
|
+
version: pattern5[1]
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
//#endregion
|
|
278
340
|
//#region src/lib/provider-model.ts
|
|
279
341
|
const parseProviderModelAlias = (model) => {
|
|
280
342
|
const separatorIndex = model.indexOf("/");
|
|
@@ -355,6 +417,7 @@ async function resolveProviderConfig(providerName, getAzureAccessToken = getDefa
|
|
|
355
417
|
const accessToken = await getXaiAccessToken();
|
|
356
418
|
return accessToken ? {
|
|
357
419
|
...providerConfig,
|
|
420
|
+
baseUrl: providerConfig.baseUrl === "https://api.x.ai" ? XAI_API_BASE_URL : providerConfig.baseUrl,
|
|
358
421
|
apiKey: accessToken
|
|
359
422
|
} : null;
|
|
360
423
|
}
|
|
@@ -2173,6 +2236,36 @@ const createResponsesWebSocketStreamChunk = (data) => {
|
|
|
2173
2236
|
}
|
|
2174
2237
|
};
|
|
2175
2238
|
//#endregion
|
|
2239
|
+
//#region src/lib/grok-build.ts
|
|
2240
|
+
const VERSION_URL = "https://x.ai/cli/stable";
|
|
2241
|
+
const VERSION_CACHE_MS = 864e5;
|
|
2242
|
+
const VERSION_RETRY_MS = 3e5;
|
|
2243
|
+
let cachedVersion = "1.0.46";
|
|
2244
|
+
let nextVersionCheck = 0;
|
|
2245
|
+
let versionInFlight;
|
|
2246
|
+
async function refreshGrokBuildVersion() {
|
|
2247
|
+
nextVersionCheck = Date.now() + VERSION_RETRY_MS;
|
|
2248
|
+
try {
|
|
2249
|
+
const response = await fetch(VERSION_URL, { signal: AbortSignal.timeout(3e3) });
|
|
2250
|
+
if (response.ok) {
|
|
2251
|
+
const version = (await response.text()).trim();
|
|
2252
|
+
if (/^\d+\.\d+\.\d+$/u.test(version)) {
|
|
2253
|
+
cachedVersion = version;
|
|
2254
|
+
nextVersionCheck = Date.now() + VERSION_CACHE_MS;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
} catch {}
|
|
2258
|
+
return cachedVersion;
|
|
2259
|
+
}
|
|
2260
|
+
async function getGrokBuildVersion() {
|
|
2261
|
+
if (versionInFlight) return await versionInFlight;
|
|
2262
|
+
if (Date.now() < nextVersionCheck) return cachedVersion;
|
|
2263
|
+
versionInFlight = refreshGrokBuildVersion().finally(() => {
|
|
2264
|
+
versionInFlight = void 0;
|
|
2265
|
+
});
|
|
2266
|
+
return await versionInFlight;
|
|
2267
|
+
}
|
|
2268
|
+
//#endregion
|
|
2176
2269
|
//#region src/lib/timeout-dispatcher.ts
|
|
2177
2270
|
/**
|
|
2178
2271
|
* Node's global fetch keeps Undici's shorter default headers/body timeouts.
|
|
@@ -2240,6 +2333,21 @@ const applyOpencodeSessionHeader = (providerConfig, headers, session) => {
|
|
|
2240
2333
|
if (providerConfig.name !== OPENCODE_GO_PROVIDER_NAME || !session) return;
|
|
2241
2334
|
headers[OPENCODE_SESSION_HEADER] = session;
|
|
2242
2335
|
};
|
|
2336
|
+
async function applyXaiGrokBuildHeaders(providerConfig, headers, payload) {
|
|
2337
|
+
if (providerConfig.name !== "xai" || providerConfig.authType !== "oauth2" || new URL(providerConfig.baseUrl).origin !== "https://cli-chat-proxy.grok.com") return;
|
|
2338
|
+
const cacheKey = payload.prompt_cache_key;
|
|
2339
|
+
const sessionId = cacheKey?.trim() ? cacheKey : requestContext.getStore()?.sessionAffinity?.trim();
|
|
2340
|
+
if (!sessionId) throw new Error("xAI OAuth Responses requests require prompt_cache_key or session affinity");
|
|
2341
|
+
headers["x-xai-token-auth"] = "xai-grok-cli";
|
|
2342
|
+
headers["x-authenticateresponse"] = "authenticate-response";
|
|
2343
|
+
headers["x-grok-client-version"] = await getGrokBuildVersion();
|
|
2344
|
+
headers["x-grok-client-identifier"] = "grok-shell";
|
|
2345
|
+
headers["x-grok-client-mode"] = "headless";
|
|
2346
|
+
headers["x-grok-model-override"] = payload.model;
|
|
2347
|
+
headers["x-grok-conv-id"] = sessionId;
|
|
2348
|
+
headers["x-grok-session-id"] = sessionId;
|
|
2349
|
+
headers["x-grok-req-id"] = randomUUID();
|
|
2350
|
+
}
|
|
2243
2351
|
function createProviderProxyResponse(upstreamResponse, body) {
|
|
2244
2352
|
return new Response(body ?? upstreamResponse.body, {
|
|
2245
2353
|
headers: createProviderProxyResponseHeaders(upstreamResponse.headers),
|
|
@@ -2287,6 +2395,7 @@ async function forwardProviderResponses(providerConfig, payload, requestHeaders,
|
|
|
2287
2395
|
const transportConfig = getUpstreamTransportConfig();
|
|
2288
2396
|
const headers = buildProviderUpstreamHeaders(providerConfig, requestHeaders);
|
|
2289
2397
|
applyOpencodeSessionHeader(providerConfig, headers, payload.prompt_cache_key?.trim() || void 0);
|
|
2398
|
+
await applyXaiGrokBuildHeaders(providerConfig, headers, payload);
|
|
2290
2399
|
return await fetchUpstreamWithLifecycle(resolveProviderEndpointUrl(providerConfig, "responses"), {
|
|
2291
2400
|
method: "POST",
|
|
2292
2401
|
headers,
|
|
@@ -3943,6 +4052,33 @@ const imageRoutes = new Hono();
|
|
|
3943
4052
|
imageRoutes.post("/generations", handleImagesGenerations);
|
|
3944
4053
|
imageRoutes.post("/edits", handleImagesEdits);
|
|
3945
4054
|
//#endregion
|
|
4055
|
+
//#region src/lib/claude-models.ts
|
|
4056
|
+
const DISCOVERY_MODEL_PREFIX = "my-claude-";
|
|
4057
|
+
const DISCOVERY_MODEL_SUFFIX = "[1m]";
|
|
4058
|
+
function isClaudeUserAgent(userAgent) {
|
|
4059
|
+
return userAgent?.toLowerCase().includes("claude") ?? false;
|
|
4060
|
+
}
|
|
4061
|
+
/** Advertise every discovery ID with [1m], keeping its provider namespace. */
|
|
4062
|
+
function toClaudeDiscoveryModelId(modelId) {
|
|
4063
|
+
const discoveryId = `${stripDiscoveryModelSuffix(modelId)}${DISCOVERY_MODEL_SUFFIX}`;
|
|
4064
|
+
if (discoveryId.toLowerCase().includes("claude")) return discoveryId;
|
|
4065
|
+
const modelStart = discoveryId.indexOf("/") + 1;
|
|
4066
|
+
const model = discoveryId.slice(modelStart);
|
|
4067
|
+
return `${discoveryId.slice(0, modelStart)}${DISCOVERY_MODEL_PREFIX}${model}`;
|
|
4068
|
+
}
|
|
4069
|
+
/** Restore the upstream ID before model mappings and provider resolution. */
|
|
4070
|
+
function fromClaudeDiscoveryModelId(modelId) {
|
|
4071
|
+
const upstreamId = stripDiscoveryModelSuffix(modelId);
|
|
4072
|
+
if (upstreamId.startsWith(DISCOVERY_MODEL_PREFIX)) return upstreamId.slice(10);
|
|
4073
|
+
const modelStart = upstreamId.indexOf("/") + 1;
|
|
4074
|
+
const model = upstreamId.slice(modelStart);
|
|
4075
|
+
if (!model.startsWith(DISCOVERY_MODEL_PREFIX)) return upstreamId;
|
|
4076
|
+
return `${upstreamId.slice(0, modelStart)}${model.slice(10)}`;
|
|
4077
|
+
}
|
|
4078
|
+
function stripDiscoveryModelSuffix(modelId) {
|
|
4079
|
+
return modelId.endsWith(DISCOVERY_MODEL_SUFFIX) ? modelId.slice(0, -4) : modelId;
|
|
4080
|
+
}
|
|
4081
|
+
//#endregion
|
|
3946
4082
|
//#region src/lib/tokenizer.ts
|
|
3947
4083
|
const ENCODING_MAP = {
|
|
3948
4084
|
o200k_base: () => import("gpt-tokenizer/encoding/o200k_base"),
|
|
@@ -4963,8 +5099,10 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
|
|
|
4963
5099
|
const logger$11 = createHandlerLogger("provider-count-tokens-handler");
|
|
4964
5100
|
async function handleProviderCountTokens(c) {
|
|
4965
5101
|
const provider = c.req.param("provider");
|
|
5102
|
+
const payload = await c.req.json();
|
|
5103
|
+
payload.model = fromClaudeDiscoveryModelId(payload.model);
|
|
4966
5104
|
return await handleProviderCountTokensForProvider(c, {
|
|
4967
|
-
payload
|
|
5105
|
+
payload,
|
|
4968
5106
|
provider
|
|
4969
5107
|
});
|
|
4970
5108
|
}
|
|
@@ -5044,7 +5182,7 @@ async function countTokensViaAnthropic(c, payload) {
|
|
|
5044
5182
|
*/
|
|
5045
5183
|
async function handleCountTokens(c) {
|
|
5046
5184
|
const anthropicPayload = await c.req.json();
|
|
5047
|
-
anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
|
|
5185
|
+
anthropicPayload.model = resolveMappedModel(fromClaudeDiscoveryModelId(anthropicPayload.model));
|
|
5048
5186
|
normalizeSystemMessages(anthropicPayload);
|
|
5049
5187
|
const providerModelAlias = await resolveConfiguredProviderModelAlias(anthropicPayload.model);
|
|
5050
5188
|
if (providerModelAlias) {
|
|
@@ -8024,6 +8162,7 @@ const providerMessagesHandlerDependencies = { resolveProviderConfig };
|
|
|
8024
8162
|
async function handleProviderMessages(c) {
|
|
8025
8163
|
const provider = c.req.param("provider");
|
|
8026
8164
|
const payload = await c.req.json();
|
|
8165
|
+
payload.model = fromClaudeDiscoveryModelId(payload.model);
|
|
8027
8166
|
const claudeAutoModel = getClaudeAutoModel();
|
|
8028
8167
|
if (claudeAutoModel && isClaudeAutoModelRequest(payload)) {
|
|
8029
8168
|
consola.debug(`Claude auto model override (${provider}): ${payload.model} -> ${claudeAutoModel}`);
|
|
@@ -9076,7 +9215,9 @@ const messagesFlowHandlers = {
|
|
|
9076
9215
|
handleWithResponsesApi
|
|
9077
9216
|
};
|
|
9078
9217
|
async function handleCompletion(c) {
|
|
9079
|
-
|
|
9218
|
+
const anthropicPayload = await c.req.json();
|
|
9219
|
+
anthropicPayload.model = fromClaudeDiscoveryModelId(anthropicPayload.model);
|
|
9220
|
+
return await handleCompletionPayload(c, anthropicPayload);
|
|
9080
9221
|
}
|
|
9081
9222
|
async function handleCompletionPayload(c, anthropicPayload, dispatchOptions = {}) {
|
|
9082
9223
|
const requestedModel = anthropicPayload.model;
|
|
@@ -9192,6 +9333,22 @@ messageRoutes.post("/count_tokens", async (c) => {
|
|
|
9192
9333
|
return await forwardError(c, error);
|
|
9193
9334
|
}
|
|
9194
9335
|
});
|
|
9336
|
+
//#endregion
|
|
9337
|
+
//#region src/lib/model-display-name.ts
|
|
9338
|
+
/** Keep upstream labels as the base and identify their gateway provider. */
|
|
9339
|
+
function withModelDisplayName(model, provider) {
|
|
9340
|
+
if (typeof model !== "object" || model === null || Array.isArray(model)) return model;
|
|
9341
|
+
const fields = model;
|
|
9342
|
+
const hasDisplayName = Object.hasOwn(model, "display_name");
|
|
9343
|
+
let displayName = hasDisplayName ? fields.display_name : typeof fields.name === "string" && fields.name.trim() ? fields.name : fields.id;
|
|
9344
|
+
const providerName = provider?.trim();
|
|
9345
|
+
if (providerName && typeof displayName === "string" && displayName.trim() && !displayName.startsWith(`${providerName} `) && !displayName.endsWith(` (${providerName})`)) displayName = `${displayName} (${providerName})`;
|
|
9346
|
+
if (hasDisplayName && displayName === fields.display_name) return model;
|
|
9347
|
+
return {
|
|
9348
|
+
...model,
|
|
9349
|
+
display_name: displayName
|
|
9350
|
+
};
|
|
9351
|
+
}
|
|
9195
9352
|
const DEFAULT_EXCLUSION_THRESHOLD = 20;
|
|
9196
9353
|
const DEFAULT_EXCLUDED_MODELS = /* @__PURE__ */ new Set([
|
|
9197
9354
|
"gpt-5.6-sol",
|
|
@@ -10837,8 +10994,8 @@ async function handleCodexModelsProxy(c, resolvedProviderConfig) {
|
|
|
10837
10994
|
const providerConfig = getRawProviderConfig("codex");
|
|
10838
10995
|
return createCodexCatalogResponse(c, {
|
|
10839
10996
|
...catalog,
|
|
10840
|
-
models: catalog.models.filter((model) =>
|
|
10841
|
-
}, new Set(
|
|
10997
|
+
models: catalog.models.filter((model) => isProviderAgentModelVisible(providerConfig, model.slug))
|
|
10998
|
+
}, new Set(getProviderAgentModels(providerConfig)), FALLBACK_CODEX_MODELS[0].model_messages);
|
|
10842
10999
|
}
|
|
10843
11000
|
async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
|
|
10844
11001
|
const [upstreamCatalogResult, candidates] = await Promise.all([tryGetCodexCatalog(c), Promise.resolve(candidatesRequest).catch((error) => {
|
|
@@ -10851,9 +11008,9 @@ async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
|
|
|
10851
11008
|
const catalogModelsBySlug = new Map(upstreamModels.map((model) => [model.slug, model]));
|
|
10852
11009
|
const codexConfig = getRawProviderConfig("codex");
|
|
10853
11010
|
const copilotConfig = getRawProviderConfig("github-copilot");
|
|
10854
|
-
const visibleUpstreamModels = upstreamModels.filter((model) =>
|
|
11011
|
+
const visibleUpstreamModels = upstreamModels.filter((model) => isProviderAgentModelVisible(codexConfig, model.slug) && (upstreamCatalog !== void 0 || codexConfig !== null || isProviderAgentModelVisible(copilotConfig, model.slug)));
|
|
10855
11012
|
const explicitSlugs = /* @__PURE__ */ new Set();
|
|
10856
|
-
const codexSelection =
|
|
11013
|
+
const codexSelection = getProviderAgentModels(codexConfig);
|
|
10857
11014
|
for (const model of visibleUpstreamModels) if (codexSelection?.includes(model.slug)) {
|
|
10858
11015
|
explicitSlugs.add(model.slug);
|
|
10859
11016
|
explicitSlugs.add(`codex/${model.slug}`);
|
|
@@ -10862,9 +11019,9 @@ async function handleMergedCodexModels(c, candidatesRequest, options = {}) {
|
|
|
10862
11019
|
const providerName = candidate.providerName ?? "github-copilot";
|
|
10863
11020
|
const modelId = candidate.catalogSlug ?? (candidate.providerName ? candidate.slug.slice(providerName.length + 1) : candidate.slug);
|
|
10864
11021
|
const config = getRawProviderConfig(providerName);
|
|
10865
|
-
const selectedModels =
|
|
11022
|
+
const selectedModels = getProviderAgentModels(config);
|
|
10866
11023
|
const selectionId = providerName === "github-copilot" && selectedModels?.includes(candidate.slug) ? candidate.slug : modelId;
|
|
10867
|
-
if (!
|
|
11024
|
+
if (!isProviderAgentModelVisible(config, selectionId)) return false;
|
|
10868
11025
|
if (selectedModels?.includes(selectionId)) explicitSlugs.add(candidate.slug);
|
|
10869
11026
|
return true;
|
|
10870
11027
|
});
|
|
@@ -11038,18 +11195,16 @@ function isRecord(value) {
|
|
|
11038
11195
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11039
11196
|
}
|
|
11040
11197
|
function normalizeCopilotModel(model) {
|
|
11041
|
-
const contextWindow = model.capabilities?.limits?.max_context_window_tokens ?? 0;
|
|
11042
11198
|
const clientId = toClientModelId(model.id);
|
|
11043
11199
|
return {
|
|
11044
|
-
claude_model_id:
|
|
11045
|
-
...model,
|
|
11200
|
+
claude_model_id: `${clientId}[1m]`,
|
|
11201
|
+
...withModelDisplayName(model, GITHUB_COPILOT_PROVIDER),
|
|
11046
11202
|
id: clientId,
|
|
11047
11203
|
object: "model",
|
|
11048
11204
|
type: "model",
|
|
11049
11205
|
created: 0,
|
|
11050
11206
|
created_at: EPOCH_ISO,
|
|
11051
|
-
owned_by: model.vendor
|
|
11052
|
-
display_name: model.name
|
|
11207
|
+
owned_by: model.vendor
|
|
11053
11208
|
};
|
|
11054
11209
|
}
|
|
11055
11210
|
function getStringField(model, field) {
|
|
@@ -11070,17 +11225,15 @@ function normalizeProviderModel(provider, model) {
|
|
|
11070
11225
|
const rawId = getStringField(model, "id");
|
|
11071
11226
|
if (!rawId) return null;
|
|
11072
11227
|
const id = `${provider}/${rawId}`;
|
|
11073
|
-
const name = getStringField(model, "display_name") ?? getStringField(model, "name") ?? rawId;
|
|
11074
11228
|
const ownedBy = getStringField(model, "owned_by") ?? getStringField(model, "vendor") ?? provider;
|
|
11075
11229
|
return {
|
|
11076
|
-
...model,
|
|
11230
|
+
...withModelDisplayName(model, provider),
|
|
11077
11231
|
id,
|
|
11078
11232
|
object: getStringField(model, "object") ?? "model",
|
|
11079
11233
|
type: getStringField(model, "type") ?? "model",
|
|
11080
11234
|
created: typeof model.created === "number" ? model.created : 0,
|
|
11081
11235
|
created_at: getStringField(model, "created_at") ?? EPOCH_ISO,
|
|
11082
|
-
owned_by: ownedBy
|
|
11083
|
-
display_name: name
|
|
11236
|
+
owned_by: ownedBy
|
|
11084
11237
|
};
|
|
11085
11238
|
}
|
|
11086
11239
|
function normalizeProviderModels(provider, models) {
|
|
@@ -11099,13 +11252,12 @@ async function getProviderModelRecords(providerConfig, requestHeaders) {
|
|
|
11099
11252
|
return getFallbackProviderModelRecords(providerConfig.name, "error", { error });
|
|
11100
11253
|
}
|
|
11101
11254
|
}
|
|
11102
|
-
async function getProviderModels(provider, requestHeaders) {
|
|
11255
|
+
async function getProviderModels(provider, requestHeaders, claudeClient) {
|
|
11103
11256
|
try {
|
|
11104
11257
|
const providerConfig = await resolveProviderConfig(provider);
|
|
11105
11258
|
if (!providerConfig) return [];
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
return normalizeProviderModels(providerConfig.name, models);
|
|
11259
|
+
const models = providerConfig.name === "codex" ? getModels().data : await getProviderModelRecords(providerConfig, requestHeaders);
|
|
11260
|
+
return normalizeProviderModels(providerConfig.name, claudeClient ? selectClaudeProviderModels(providerConfig, models) : models);
|
|
11109
11261
|
} catch (error) {
|
|
11110
11262
|
if (provider === "codex") {
|
|
11111
11263
|
logger$7.warn("models.provider.skip_error", {
|
|
@@ -11114,12 +11266,24 @@ async function getProviderModels(provider, requestHeaders) {
|
|
|
11114
11266
|
});
|
|
11115
11267
|
return [];
|
|
11116
11268
|
}
|
|
11117
|
-
|
|
11269
|
+
const fallbackModels = getFallbackProviderModelRecords(provider, "error", { error });
|
|
11270
|
+
return normalizeProviderModels(provider, claudeClient ? selectClaudeProviderModels(getRawProviderConfig(provider), fallbackModels) : fallbackModels);
|
|
11118
11271
|
}
|
|
11119
11272
|
}
|
|
11120
|
-
|
|
11121
|
-
const
|
|
11122
|
-
|
|
11273
|
+
function selectClaudeProviderModels(providerConfig, models) {
|
|
11274
|
+
const selection = getProviderAgentModels(providerConfig);
|
|
11275
|
+
if (selection === void 0) return models;
|
|
11276
|
+
const modelsById = new Map(models.flatMap((model) => {
|
|
11277
|
+
if (!isRecord(model)) return [];
|
|
11278
|
+
const id = getStringField(model, "id");
|
|
11279
|
+
return id ? [[id, model]] : [];
|
|
11280
|
+
}));
|
|
11281
|
+
return selection.map((id) => modelsById.get(id) ?? { id });
|
|
11282
|
+
}
|
|
11283
|
+
async function getAggregatedModels(requestHeaders, claudeClient) {
|
|
11284
|
+
const copilotSelection = claudeClient ? getProviderAgentModels(getRawProviderConfig("github-copilot")) : void 0;
|
|
11285
|
+
const copilotModels = isGitHubCopilotEnabled() ? state.models?.data.filter((model) => copilotSelection === void 0 || copilotSelection.includes(model.id) || copilotSelection.includes(toClientModelId(model.id))).map(normalizeCopilotModel) ?? [] : [];
|
|
11286
|
+
const providerModelsByProvider = await Promise.all(listEnabledProviders().map((provider) => getProviderModels(provider, requestHeaders, claudeClient)));
|
|
11123
11287
|
const models = [...copilotModels, ...providerModelsByProvider.flat()];
|
|
11124
11288
|
const seenModelIds = /* @__PURE__ */ new Set();
|
|
11125
11289
|
return models.filter((model) => {
|
|
@@ -11304,10 +11468,16 @@ modelRoutes.get("/", async (c) => {
|
|
|
11304
11468
|
codexProviderName
|
|
11305
11469
|
});
|
|
11306
11470
|
}
|
|
11307
|
-
const
|
|
11471
|
+
const claudeClient = isClaudeUserAgent(c.req.header("user-agent"));
|
|
11472
|
+
const models = await getAggregatedModels(stripInternalRequestHeaders(c.req.raw.headers), claudeClient);
|
|
11473
|
+
const clientModels = claudeClient ? models.map((model) => ({
|
|
11474
|
+
...model,
|
|
11475
|
+
id: toClaudeDiscoveryModelId(model.id),
|
|
11476
|
+
...typeof model.claude_model_id === "string" ? { claude_model_id: toClaudeDiscoveryModelId(model.claude_model_id) } : {}
|
|
11477
|
+
})) : models;
|
|
11308
11478
|
return c.json({
|
|
11309
11479
|
object: "list",
|
|
11310
|
-
data:
|
|
11480
|
+
data: clientModels,
|
|
11311
11481
|
has_more: false
|
|
11312
11482
|
});
|
|
11313
11483
|
} catch (error) {
|
|
@@ -11413,7 +11583,7 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
11413
11583
|
const models = getModels();
|
|
11414
11584
|
return c.json({
|
|
11415
11585
|
object: "list",
|
|
11416
|
-
data: models.data,
|
|
11586
|
+
data: models.data.map((model) => withModelDisplayName(model, providerConfig.name)),
|
|
11417
11587
|
has_more: false
|
|
11418
11588
|
});
|
|
11419
11589
|
}
|
|
@@ -11425,13 +11595,13 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
11425
11595
|
} }, 503);
|
|
11426
11596
|
return c.json({
|
|
11427
11597
|
object: "list",
|
|
11428
|
-
data: models,
|
|
11598
|
+
data: models.map((model) => withModelDisplayName(model, providerConfig.name)),
|
|
11429
11599
|
has_more: false
|
|
11430
11600
|
});
|
|
11431
11601
|
}
|
|
11432
11602
|
if (providerConfig.name === "xai" && providerConfig.authType === "oauth2") return c.json({
|
|
11433
11603
|
object: "list",
|
|
11434
|
-
data: getBuiltinProviderModelRecords("xai"),
|
|
11604
|
+
data: getBuiltinProviderModelRecords("xai").map((model) => withModelDisplayName(model, providerConfig.name)),
|
|
11435
11605
|
has_more: false
|
|
11436
11606
|
});
|
|
11437
11607
|
const upstreamResponse = await forwardProviderModels(providerConfig, c.req.raw.headers);
|
|
@@ -11439,6 +11609,23 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
11439
11609
|
provider,
|
|
11440
11610
|
statusCode: upstreamResponse.status
|
|
11441
11611
|
});
|
|
11612
|
+
if (upstreamResponse.ok) {
|
|
11613
|
+
const body = await upstreamResponse.clone().json().catch(() => null);
|
|
11614
|
+
if (typeof body === "object" && body !== null && "data" in body && Array.isArray(body.data)) {
|
|
11615
|
+
const upstreamModels = body.data;
|
|
11616
|
+
const data = upstreamModels.map((model) => withModelDisplayName(model, providerConfig.name));
|
|
11617
|
+
if (data.every((model, index) => model === upstreamModels[index])) return createProviderProxyResponse(upstreamResponse);
|
|
11618
|
+
const headers = createProviderProxyResponseHeaders(upstreamResponse.headers);
|
|
11619
|
+
headers.delete("etag");
|
|
11620
|
+
return Response.json({
|
|
11621
|
+
...body,
|
|
11622
|
+
data
|
|
11623
|
+
}, {
|
|
11624
|
+
status: upstreamResponse.status,
|
|
11625
|
+
headers
|
|
11626
|
+
});
|
|
11627
|
+
}
|
|
11628
|
+
}
|
|
11442
11629
|
return createProviderProxyResponse(upstreamResponse);
|
|
11443
11630
|
} catch (error) {
|
|
11444
11631
|
logger$4.error("provider.models.error", {
|
|
@@ -12950,4 +13137,4 @@ createServer();
|
|
|
12950
13137
|
//#endregion
|
|
12951
13138
|
export { createServer };
|
|
12952
13139
|
|
|
12953
|
-
//# sourceMappingURL=server-
|
|
13140
|
+
//# sourceMappingURL=server-BmGSx45N.js.map
|