@jeffreycao/copilot-api 2.2.12 → 2.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -30,7 +30,7 @@ if (isMcpFastPath(process.argv)) {
30
30
  const { auth } = await import("./auth-C-RWNXGU.js");
31
31
  const { debug } = await import("./debug-41w6Whae.js");
32
32
  const { mcp } = await import("./mcp-fpSlKZxK.js");
33
- const { start } = await import("./start-CJ6z_8Pn.js");
33
+ const { start } = await import("./start-HHr2HlXT.js");
34
34
  await runMain(defineCommand({
35
35
  meta: {
36
36
  name: "copilot-api",
@@ -374,6 +374,21 @@ async function resolveProviderConfig(providerName) {
374
374
  }
375
375
  return getProviderConfig(normalizedProviderName);
376
376
  }
377
+ /**
378
+ * Returns the parsed "provider/model" alias only when that provider is
379
+ * actually configured, otherwise null so the caller falls through to its
380
+ * default flow. GitHub Copilot enterprise models can ship with namespaced ids
381
+ * such as "org/family/model": without this check the first segment is
382
+ * misrouted to a non-existent provider and surfaced as a 400/404.
383
+ */
384
+ async function ensureConfiguredProviderModelAlias(alias, resolveConfig = resolveProviderConfig) {
385
+ if (!alias) return null;
386
+ return await resolveConfig(alias.provider) ? alias : null;
387
+ }
388
+ /** parseProviderModelAlias + ensureConfiguredProviderModelAlias. */
389
+ async function resolveConfiguredProviderModelAlias(model, resolveConfig = resolveProviderConfig) {
390
+ return ensureConfiguredProviderModelAlias(parseProviderModelAlias(model), resolveConfig);
391
+ }
377
392
  //#endregion
378
393
  //#region src/lib/event-bus.ts
379
394
  var EventBus = class {
@@ -2845,10 +2860,12 @@ async function handleAlphaSearchRequest(c, resolvedProviderConfig) {
2845
2860
  }
2846
2861
  }
2847
2862
  const fallbackRequestedModel = messagesBackedModel ? payload.model : requestedModel;
2848
- if (providerModelAlias) return await alphaSearchRouteDependencies.handleAlphaSearchResponses(c, {
2849
- provider: providerModelAlias.provider,
2850
- request: payload
2851
- });
2863
+ if (providerModelAlias) {
2864
+ if (await ensureConfiguredProviderModelAlias(providerModelAlias, alphaSearchRouteDependencies.resolveProviderConfig)) return await alphaSearchRouteDependencies.handleAlphaSearchResponses(c, {
2865
+ provider: providerModelAlias.provider,
2866
+ request: payload
2867
+ });
2868
+ }
2852
2869
  return await alphaSearchRouteDependencies.handleAlphaSearchResponses(c, { request: {
2853
2870
  ...payload,
2854
2871
  model: fallbackRequestedModel
@@ -2933,8 +2950,8 @@ const setContextCacheControl = (part) => {
2933
2950
  part.cache_control = { ...OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL };
2934
2951
  };
2935
2952
  //#endregion
2936
- //#region src/routes/provider/utils.ts
2937
- const RESPONSES_REASONING_EFFORTS = new Set([
2953
+ //#region src/lib/reasoning-effort.ts
2954
+ const REASONING_EFFORT_LEVELS = [
2938
2955
  "none",
2939
2956
  "minimal",
2940
2957
  "low",
@@ -2942,13 +2959,45 @@ const RESPONSES_REASONING_EFFORTS = new Set([
2942
2959
  "high",
2943
2960
  "xhigh",
2944
2961
  "max"
2945
- ]);
2962
+ ];
2963
+ const KNOWN_REASONING_EFFORTS = new Set(REASONING_EFFORT_LEVELS);
2946
2964
  const REASONING_EFFORT_ALIASES = {
2947
2965
  minimal: "low",
2948
- xhigh: "high",
2949
- max: "high",
2950
- ultra: "high"
2966
+ ultra: "max"
2967
+ };
2968
+ const reasoningEffortRank = (effort) => REASONING_EFFORT_LEVELS.indexOf(effort);
2969
+ /**
2970
+ * Resolves the reasoning effort to send upstream for a requested effort.
2971
+ *
2972
+ * Policy:
2973
+ * - A supported effort passes through unchanged.
2974
+ * - Client-only levels are aliased first ("ultra" -> "max").
2975
+ * - An unsupported request clamps to the highest supported level not above
2976
+ * the request, e.g. "max" against ["low", "medium", "high", "xhigh"]
2977
+ * resolves to "xhigh".
2978
+ * - A request below every supported level resolves to the lowest supported
2979
+ * level, e.g. "none" against ["low", "medium", "high"] resolves to "low".
2980
+ * - Without any known supported levels, valid wire efforts pass through and
2981
+ * client-facing aliases are converted (for example, "ultra" -> "max").
2982
+ * - An unrecognized request is left unresolved so the upstream can validate
2983
+ * it instead of receiving a silently substituted effort.
2984
+ */
2985
+ const resolveSupportedReasoningEffort = (requestedEffort, supportedEfforts) => {
2986
+ const supported = (supportedEfforts ?? []).filter((effort) => KNOWN_REASONING_EFFORTS.has(effort));
2987
+ const requestedWireEffort = KNOWN_REASONING_EFFORTS.has(requestedEffort) ? requestedEffort : void 0;
2988
+ if (supported.length === 0) return requestedWireEffort ?? REASONING_EFFORT_ALIASES[requestedEffort];
2989
+ if (requestedWireEffort && supported.includes(requestedWireEffort)) return requestedWireEffort;
2990
+ const aliasedEffort = REASONING_EFFORT_ALIASES[requestedEffort] ?? requestedWireEffort;
2991
+ if (!aliasedEffort) return;
2992
+ if (supported.includes(aliasedEffort)) return aliasedEffort;
2993
+ const requestedRank = reasoningEffortRank(aliasedEffort);
2994
+ let nearestBelow;
2995
+ for (const effort of supported) if (reasoningEffortRank(effort) <= requestedRank && (nearestBelow === void 0 || reasoningEffortRank(effort) > reasoningEffortRank(nearestBelow))) nearestBelow = effort;
2996
+ if (nearestBelow) return nearestBelow;
2997
+ return supported.reduce((lowest, effort) => reasoningEffortRank(effort) < reasoningEffortRank(lowest) ? effort : lowest);
2951
2998
  };
2999
+ //#endregion
3000
+ //#region src/routes/provider/utils.ts
2952
3001
  const applyModelDefaults = (payload, modelConfig) => {
2953
3002
  payload.temperature ??= modelConfig?.temperature;
2954
3003
  payload.top_p ??= modelConfig?.topP;
@@ -2958,22 +3007,19 @@ const applyMissingExtraBody = (payload, options) => {
2958
3007
  for (const [key, value] of Object.entries(options.extraBody ?? {})) if (!Object.hasOwn(payload, key)) payload[key] = value;
2959
3008
  };
2960
3009
  const normalizeProviderResponsesReasoningEffort = (payload, providerConfig) => {
2961
- const currentEffort = payload.reasoning?.effort;
2962
- if (typeof currentEffort !== "string") return;
3010
+ if (!payload.reasoning || typeof payload.reasoning.effort !== "string") return;
2963
3011
  const modelConfig = providerConfig.models?.[payload.model];
2964
3012
  const builtinModelConfig = builtinProviderModelRegistry.getModelConfig(providerConfig.name, payload.model);
2965
- const configuredEfforts = normalizeResponsesReasoningEfforts(modelConfig?.reasoningEfforts);
2966
- const builtinEfforts = normalizeResponsesReasoningEfforts(builtinModelConfig?.reasoningEfforts);
2967
- const supportedEfforts = configuredEfforts.length > 0 ? configuredEfforts : builtinEfforts;
2968
- if (supportedEfforts.length === 0 || supportedEfforts.includes(currentEffort)) return;
2969
- const aliasedEffort = REASONING_EFFORT_ALIASES[currentEffort];
2970
- const fallbackEffort = aliasedEffort && supportedEfforts.includes(aliasedEffort) ? aliasedEffort : selectSupportedReasoningEffort(supportedEfforts, modelConfig?.defaultReasoningEffort, builtinModelConfig?.defaultReasoningEffort);
2971
- if (payload.reasoning && fallbackEffort) payload.reasoning.effort = fallbackEffort;
2972
- };
2973
- const normalizeResponsesReasoningEfforts = (efforts) => (efforts ?? []).filter((effort) => RESPONSES_REASONING_EFFORTS.has(effort));
2974
- const selectSupportedReasoningEffort = (supportedEfforts, ...defaults) => {
2975
- for (const defaultEffort of defaults) if (defaultEffort && supportedEfforts.includes(defaultEffort)) return defaultEffort;
2976
- return supportedEfforts[0];
3013
+ const configuredEfforts = modelConfig?.reasoningEfforts;
3014
+ const supportedEfforts = configuredEfforts && configuredEfforts.length > 0 ? configuredEfforts : builtinModelConfig?.reasoningEfforts;
3015
+ const resolvedEffort = resolveSupportedReasoningEffort(payload.reasoning.effort, supportedEfforts);
3016
+ if (!resolvedEffort || resolvedEffort === payload.reasoning.effort) return;
3017
+ const requestedEffort = payload.reasoning.effort;
3018
+ payload.reasoning.effort = resolvedEffort;
3019
+ return {
3020
+ from: requestedEffort,
3021
+ to: resolvedEffort
3022
+ };
2977
3023
  };
2978
3024
  //#endregion
2979
3025
  //#region src/routes/provider/chat-completions/handler.ts
@@ -3098,7 +3144,7 @@ async function handleCompletion$1(c) {
3098
3144
  const requestedModel = payload.model;
3099
3145
  payload.model = resolveMappedModel(payload.model);
3100
3146
  if (payload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
3101
- const providerModelAlias = parseProviderModelAlias(payload.model);
3147
+ const providerModelAlias = await resolveConfiguredProviderModelAlias(payload.model);
3102
3148
  if (providerModelAlias) {
3103
3149
  payload.model = providerModelAlias.model;
3104
3150
  return await handleProviderChatCompletionsForProvider(c, {
@@ -4390,7 +4436,7 @@ async function handleCountTokens(c) {
4390
4436
  const anthropicPayload = await c.req.json();
4391
4437
  anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
4392
4438
  normalizeSystemMessages(anthropicPayload);
4393
- const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
4439
+ const providerModelAlias = await resolveConfiguredProviderModelAlias(anthropicPayload.model);
4394
4440
  if (providerModelAlias) {
4395
4441
  anthropicPayload.model = providerModelAlias.model;
4396
4442
  return await handleProviderCountTokensForProvider(c, {
@@ -5910,6 +5956,17 @@ const getStreamErrorMessage = (event) => {
5910
5956
  return event.error?.message ?? event.message ?? void 0;
5911
5957
  };
5912
5958
  const DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO = .85;
5959
+ const normalizeResponsesReasoningEffort = (payload, supportedEfforts) => {
5960
+ if (!payload.reasoning || typeof payload.reasoning.effort !== "string") return;
5961
+ const resolvedEffort = resolveSupportedReasoningEffort(payload.reasoning.effort, supportedEfforts);
5962
+ if (!resolvedEffort || resolvedEffort === payload.reasoning.effort) return;
5963
+ const requestedEffort = payload.reasoning.effort;
5964
+ payload.reasoning.effort = resolvedEffort;
5965
+ return {
5966
+ from: requestedEffort,
5967
+ to: resolvedEffort
5968
+ };
5969
+ };
5913
5970
  const responsesUtilsDependencies = {
5914
5971
  getModelResponsesApiCompactThreshold: getModelResponsesApiCompactThreshold$1,
5915
5972
  isContextManagementEnabledForMessages,
@@ -6104,6 +6161,7 @@ const containsVisionContent = (value) => {
6104
6161
  //#region src/routes/messages/web-search/fulfill.ts
6105
6162
  const webSearchFlowDependencies = {
6106
6163
  createResponses,
6164
+ resolveProviderConfig,
6107
6165
  createUsageRecorder: (payload, sessionId, webSearchModel) => createCopilotTokenUsageRecorder({
6108
6166
  endpoint: "responses",
6109
6167
  fallbackSessionId: sessionId,
@@ -6125,14 +6183,17 @@ const stripWebSearchServerTool = (payload) => {
6125
6183
  if (!Array.isArray(payload.tools)) return;
6126
6184
  payload.tools = payload.tools.filter((tool) => !isWebSearchServerTool(tool));
6127
6185
  };
6128
- const resolveWebSearchRoute = (payload, options) => {
6186
+ const resolveWebSearchRoute = async (payload, options) => {
6129
6187
  const { webSearchModel, responsesWebSearchEnabled } = options;
6130
6188
  if (!webSearchModel || !isWebSearchOnlyRequest(payload)) return { kind: "strip" };
6131
6189
  const alias = parseProviderModelAlias(webSearchModel);
6132
- if (alias) return {
6133
- kind: "provider",
6134
- alias
6135
- };
6190
+ if (alias) {
6191
+ const configuredAlias = await ensureConfiguredProviderModelAlias(alias, options.resolveProviderConfig ?? resolveProviderConfig);
6192
+ return configuredAlias ? {
6193
+ kind: "provider",
6194
+ alias: configuredAlias
6195
+ } : { kind: "strip" };
6196
+ }
6136
6197
  if (responsesWebSearchEnabled) return {
6137
6198
  kind: "responses",
6138
6199
  model: webSearchModel
@@ -6234,9 +6295,10 @@ const createUsageRecorder = (payload, sessionId, webSearchModel) => webSearchFlo
6234
6295
  const tryHandleWebSearch = async (c, payload, options) => {
6235
6296
  if (!hasWebSearchServerTool(payload)) return null;
6236
6297
  normalizeSystemMessages(payload);
6237
- const route = resolveWebSearchRoute(payload, {
6298
+ const route = await resolveWebSearchRoute(payload, {
6238
6299
  webSearchModel: getMessageApiWebSearchModel(),
6239
- responsesWebSearchEnabled: isResponsesApiWebSearchEnabled()
6300
+ responsesWebSearchEnabled: isResponsesApiWebSearchEnabled(),
6301
+ resolveProviderConfig: webSearchFlowDependencies.resolveProviderConfig
6240
6302
  });
6241
6303
  if (route.kind === "provider") {
6242
6304
  payload.model = route.alias.model;
@@ -6651,7 +6713,8 @@ async function handleProviderMessagesForProvider(c, options) {
6651
6713
  const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
6652
6714
  const { modelConfig, payload, provider, providerConfig, usageEndpoint } = options;
6653
6715
  const responsesPayload = prepareWebSearchResponsesPayload(payload);
6654
- normalizeProviderResponsesReasoningEffort(responsesPayload, providerConfig);
6716
+ const normalizedReasoningEffort = normalizeProviderResponsesReasoningEffort(responsesPayload, providerConfig);
6717
+ if (normalizedReasoningEffort) logger$10.debug(`Normalized reasoning effort from ${normalizedReasoningEffort.from} to ${normalizedReasoningEffort.to} based on the provider model configuration`);
6655
6718
  debugJson(logger$10, "provider.messages.responses.web_search.request", {
6656
6719
  payload: responsesPayload,
6657
6720
  provider
@@ -6715,7 +6778,8 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
6715
6778
  const selectedModel = providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0;
6716
6779
  const wantsStream = payload.stream === true;
6717
6780
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(payload);
6718
- normalizeProviderResponsesReasoningEffort(responsesPayload, providerConfig);
6781
+ const normalizedMessagesReasoningEffort = normalizeProviderResponsesReasoningEffort(responsesPayload, providerConfig);
6782
+ if (normalizedMessagesReasoningEffort) logger$10.debug(`Normalized reasoning effort from ${normalizedMessagesReasoningEffort.from} to ${normalizedMessagesReasoningEffort.to} based on the provider model configuration`);
6719
6783
  if (providerConfig.name === "codex" && !wantsStream) responsesPayload.stream = true;
6720
6784
  if (applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens, { source: "messages" })) compactInputByLatestCompaction(responsesPayload);
6721
6785
  debugJson(logger$10, "provider.messages.responses.request", {
@@ -7518,7 +7582,7 @@ async function handleCompletionPayload(c, anthropicPayload, dispatchOptions = {}
7518
7582
  consola.debug(`Claude auto model override: ${anthropicPayload.model} -> ${claudeAutoModel}`);
7519
7583
  anthropicPayload.model = claudeAutoModel;
7520
7584
  }
7521
- const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
7585
+ const providerModelAlias = await resolveConfiguredProviderModelAlias(anthropicPayload.model, providerMessagesHandlerDependencies.resolveProviderConfig);
7522
7586
  if (providerModelAlias) {
7523
7587
  anthropicPayload.model = providerModelAlias.model;
7524
7588
  return await handleProviderMessagesForProvider(c, {
@@ -7641,6 +7705,10 @@ const DEFAULT_REASONING_EFFORTS = [
7641
7705
  "max",
7642
7706
  "ultra"
7643
7707
  ];
7708
+ const addUltraReasoningEffort = (efforts) => {
7709
+ if (efforts.includes("ultra")) return efforts;
7710
+ return [...efforts, "ultra"];
7711
+ };
7644
7712
  const CODEX_ALIAS_PRIORITY_BASE = 1e3;
7645
7713
  const COPILOT_PRIORITY_BASE = 2e3;
7646
7714
  const OPENCODE_GO_PRIORITY_BASE = 3e3;
@@ -7947,7 +8015,7 @@ function createCatalogAlias(model, slug, providerName) {
7947
8015
  };
7948
8016
  }
7949
8017
  function createSyntheticCodexModel(candidate, template, priority) {
7950
- const reasoningEfforts = candidate.reasoningEfforts.length > 0 ? candidate.reasoningEfforts : DEFAULT_REASONING_EFFORTS;
8018
+ const reasoningEfforts = candidate.reasoningEfforts.length > 0 ? addUltraReasoningEffort(candidate.reasoningEfforts) : DEFAULT_REASONING_EFFORTS;
7951
8019
  const defaultReasoningEffort = reasoningEfforts.includes(candidate.defaultReasoningEffort) ? candidate.defaultReasoningEffort : reasoningEfforts[0];
7952
8020
  const supportsReasoning = reasoningEfforts.some((effort) => effort !== "none");
7953
8021
  const inputModalities = [...new Set(candidate.inputModalities)];
@@ -9102,12 +9170,14 @@ function appendUserBlock(messages, block) {
9102
9170
  };
9103
9171
  messages.push(message);
9104
9172
  }
9105
- function parseFunctionArguments(value, path) {
9173
+ function parseFunctionArguments(value, _path) {
9106
9174
  try {
9107
9175
  const parsed = JSON.parse(value);
9108
9176
  if (isRecord(parsed)) return parsed;
9109
- } catch {}
9110
- throw new ResponsesMessagesTranslationError(`${path} must be a JSON object string`);
9177
+ } catch {
9178
+ return {};
9179
+ }
9180
+ return {};
9111
9181
  }
9112
9182
  function parseDataUrl(value) {
9113
9183
  const match = /^data:([^;,]+);base64,(.*)$/su.exec(value);
@@ -10069,7 +10139,8 @@ async function handleProviderResponsesForProvider(c, options) {
10069
10139
  type: "invalid_request_error"
10070
10140
  } }, 400);
10071
10141
  const effectiveType = resolveEffectiveProviderType(providerConfig, payload.model);
10072
- normalizeProviderResponsesReasoningEffort(payload, providerConfig);
10142
+ const normalizedReasoningEffort = normalizeProviderResponsesReasoningEffort(payload, providerConfig);
10143
+ if (normalizedReasoningEffort) logger$2.debug(`Normalized reasoning effort from ${normalizedReasoningEffort.from} to ${normalizedReasoningEffort.to} based on the provider model configuration`);
10073
10144
  if (shouldFallbackToMessages$1(c, payload.model, effectiveType)) return await handleResponsesViaMessages(c, {
10074
10145
  payload,
10075
10146
  publicModel: options.publicModel ?? payload.model,
@@ -10268,7 +10339,7 @@ const handleResponses = async (c) => {
10268
10339
  const requestedModel = payload.model;
10269
10340
  payload.model = responsesHandlerDependencies.resolveMappedModel(payload.model);
10270
10341
  if (payload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
10271
- const providerModelAlias = parseProviderModelAlias(payload.model);
10342
+ const providerModelAlias = await resolveConfiguredProviderModelAlias(payload.model, providerResponsesHandlerDependencies.resolveProviderConfig);
10272
10343
  if (providerModelAlias) {
10273
10344
  payload.model = providerModelAlias.model;
10274
10345
  return await handleProviderResponsesForProvider(c, {
@@ -10288,6 +10359,8 @@ const handleResponses = async (c) => {
10288
10359
  logger$1.debug("Extracted session ID:", fallbackSessionId);
10289
10360
  const selectedModel = responsesHandlerDependencies.findEndpointModel(payload.model);
10290
10361
  payload.model = selectedModel?.id ?? payload.model;
10362
+ const normalizedReasoningEffort = normalizeResponsesReasoningEffort(payload, selectedModel?.capabilities?.supports?.reasoning_effort);
10363
+ if (normalizedReasoningEffort) logger$1.debug(`Normalized reasoning effort from ${normalizedReasoningEffort.from} to ${normalizedReasoningEffort.to} based on the selected model capabilities`);
10291
10364
  const responsesTransport = getResponsesTransportForModel(selectedModel);
10292
10365
  if (shouldFallbackToMessages(c, payload.model, selectedModel, responsesTransport)) return await handleResponsesViaMessages(c, {
10293
10366
  payload,
@@ -10573,4 +10646,4 @@ server.route("/:provider/images", providerImageRoutes);
10573
10646
  //#endregion
10574
10647
  export { server };
10575
10648
 
10576
- //# sourceMappingURL=server-C3DnUZoh.js.map
10649
+ //# sourceMappingURL=server-B3NoF9oG.js.map