@jeffreycao/copilot-api 1.13.19 → 1.13.21

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.
@@ -1,5 +1,5 @@
1
- import { C as resolveProviderAuthType, E as PATHS, S as resolveMappedModel, a as getExtraPromptForModel, c as getModelResponsesApiCompactThreshold$1, d as getReasoningEffortForModel, f as getSmallModel, g as isResponsesApiWebSocketEnabled, h as isResponsesApiWebSearchEnabled, i as getConfig, l as getProviderConfig, m as isResponsesApiContextManagementEnabled, n as getAnthropicApiKey, o as getMessageApiWebSearchModel, p as isMessagesApiEnabled, r as getClaudeTokenMultiplier, s as getModelMappings, u as getRawProviderConfig, v as listEnabledProviders, w as setModelMappings, x as resolveEffectiveProviderType } from "./config-BeaC6Nhb.js";
2
- import { C as prepareMessageProxyHeaders, E as compactMessageSections, F as createPooledWebSocketStream, I as createWebSocketUrl, L as state, M as generateTraceId, N as requestContext, O as compactSystemPromptStarts, P as resolveTraceId$1, R as HTTPError, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, b as copilotWebSocketHeaders, d as generateRequestIdFromPayload, f as getRootSessionId, g as getCopilotUsage, h as parseUserIdMetadata, j as forwardCodexResponses, m as isNullish, p as getUUID, r as setupCodexToken, v as copilotBaseUrl, x as prepareForCompact, y as copilotHeaders, z as forwardError } from "./token-CXLZYFQQ.js";
1
+ import { C as resolveMappedModel, D as PATHS, S as resolveEffectiveProviderType, T as setModelMappings, _ as isResponsesApiWebSocketEnabled, a as getExtraPromptForModel, c as getModelResponsesApiCompactThreshold$1, d as getReasoningEffortForModel, f as getSmallModel, g as isResponsesApiWebSearchEnabled, h as isMessagesApiEnabled, i as getConfig, l as getProviderConfig, m as isContextManagementEnabledForResponses, n as getAnthropicApiKey, o as getMessageApiWebSearchModel, p as isContextManagementEnabledForMessages, r as getClaudeTokenMultiplier, s as getModelMappings, u as getRawProviderConfig, w as resolveProviderAuthType, y as listEnabledProviders } from "./config-BCyM6AdG.js";
2
+ import { B as HTTPError, C as prepareMessageProxyHeaders, E as compactMessageSections, F as requestContext, I as resolveTraceId$1, L as createPooledWebSocketStream, M as buildCodexRequestHeaders, N as forwardCodexResponses, O as compactSystemPromptStarts, P as generateTraceId, R as createWebSocketUrl, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, V as forwardError, b as copilotWebSocketHeaders, d as generateRequestIdFromPayload, f as getRootSessionId, g as getCopilotUsage, h as parseUserIdMetadata, j as CODEX_API_BASE_URL, m as isNullish, p as getUUID, r as setupCodexToken, v as copilotBaseUrl, x as prepareForCompact, y as copilotHeaders, z as state } from "./token-BHZHMTxp.js";
3
3
  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-OX6iPJ9D.js";
4
4
  import consola from "consola";
5
5
  import { createHash } from "node:crypto";
@@ -4537,7 +4537,8 @@ const stringifyToolSearchArguments = (argumentsValue) => {
4537
4537
  const DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO = .85;
4538
4538
  const responsesUtilsDependencies = {
4539
4539
  getModelResponsesApiCompactThreshold: getModelResponsesApiCompactThreshold$1,
4540
- isResponsesApiContextManagementEnabled,
4540
+ isContextManagementEnabledForMessages,
4541
+ isContextManagementEnabledForResponses,
4541
4542
  isResponsesApiWebSocketEnabled
4542
4543
  };
4543
4544
  const getResponsesRequestOptions = (payload) => {
@@ -4649,11 +4650,16 @@ const createCompactionContextManagement = (compactThreshold) => [{
4649
4650
  type: "compaction",
4650
4651
  compact_threshold: compactThreshold
4651
4652
  }];
4652
- const applyResponsesApiContextManagement = (payload, maxPromptTokens, compactThresholdRatio = DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO) => {
4653
- if (hasTerminalCompactionTrigger(payload)) return;
4654
- if (payload.context_management !== void 0) return;
4655
- if (!responsesUtilsDependencies.isResponsesApiContextManagementEnabled()) return;
4656
- payload.context_management = createCompactionContextManagement(getModelResponsesApiCompactThreshold(payload.model) ?? resolveResponsesCompactThreshold(maxPromptTokens, compactThresholdRatio));
4653
+ const applyResponsesApiContextManagement = (payload, maxPromptTokens, options) => {
4654
+ if (hasTerminalCompactionTrigger(payload)) return isContextManagementEnabledForSource(options.source);
4655
+ if (payload.context_management !== void 0) return true;
4656
+ if (!isContextManagementEnabledForSource(options.source)) return false;
4657
+ payload.context_management = createCompactionContextManagement(getModelResponsesApiCompactThreshold(payload.model) ?? resolveResponsesCompactThreshold(maxPromptTokens, options.compactThresholdRatio ?? .85));
4658
+ return true;
4659
+ };
4660
+ const isContextManagementEnabledForSource = (source) => {
4661
+ if (source === "messages") return responsesUtilsDependencies.isContextManagementEnabledForMessages();
4662
+ return responsesUtilsDependencies.isContextManagementEnabledForResponses();
4657
4663
  };
4658
4664
  const hasTerminalCompactionTrigger = (payload) => {
4659
4665
  const { input } = payload;
@@ -5118,27 +5124,41 @@ const CODEX_MODELS = [
5118
5124
  name: "GPT-5.5"
5119
5125
  },
5120
5126
  {
5121
- contextWindow: 272e3,
5127
+ contextWindow: 372e3,
5122
5128
  id: "gpt-5.6-sol",
5123
5129
  input: ["text", "image"],
5124
5130
  maxTokens: 128e3,
5125
5131
  name: "GPT-5.6 Sol"
5126
5132
  },
5127
5133
  {
5128
- contextWindow: 272e3,
5134
+ contextWindow: 372e3,
5129
5135
  id: "gpt-5.6-terra",
5130
5136
  input: ["text", "image"],
5131
5137
  maxTokens: 128e3,
5132
5138
  name: "GPT-5.6 Terra"
5133
5139
  },
5134
5140
  {
5135
- contextWindow: 272e3,
5141
+ contextWindow: 372e3,
5136
5142
  id: "gpt-5.6-luna",
5137
5143
  input: ["text", "image"],
5138
5144
  maxTokens: 128e3,
5139
5145
  name: "GPT-5.6 Luna"
5140
5146
  }
5141
5147
  ];
5148
+ function resolveCodexModelsUrl(requestUrl, baseUrl = CODEX_API_BASE_URL) {
5149
+ const modelsUrl = `${(baseUrl.trim().replace(/\/+$/u, "") || "https://chatgpt.com/backend-api").replace(/\/codex(?:\/models)?$/u, "")}/codex/models`;
5150
+ const upstreamUrl = new URL(modelsUrl);
5151
+ upstreamUrl.search = new URL(requestUrl, "http://localhost").search;
5152
+ return upstreamUrl.toString();
5153
+ }
5154
+ async function forwardCodexModels(requestUrl, requestHeaders, baseUrl = CODEX_API_BASE_URL) {
5155
+ const headers = buildCodexRequestHeaders(requestHeaders);
5156
+ if (!headers.has("accept")) headers.set("accept", "application/json");
5157
+ return await fetch(resolveCodexModelsUrl(requestUrl, baseUrl), {
5158
+ method: "GET",
5159
+ headers
5160
+ });
5161
+ }
5142
5162
  function normalizeCodexModel(model) {
5143
5163
  const supportsVision = model.input.includes("image");
5144
5164
  return {
@@ -5334,8 +5354,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
5334
5354
  const { modelConfig, payload, provider, providerConfig } = options;
5335
5355
  const selectedModel = providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0;
5336
5356
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(payload);
5337
- applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
5338
- compactInputByLatestCompaction(responsesPayload);
5357
+ if (applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens, { source: "messages" })) compactInputByLatestCompaction(responsesPayload);
5339
5358
  debugJson(logger$6, "provider.messages.responses.request", {
5340
5359
  payload: responsesPayload,
5341
5360
  provider
@@ -5832,8 +5851,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
5832
5851
  model: responsesPayload.model,
5833
5852
  payload: anthropicPayload
5834
5853
  });
5835
- applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
5836
- compactInputByLatestCompaction(responsesPayload);
5854
+ if (applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens, { source: "messages" })) compactInputByLatestCompaction(responsesPayload);
5837
5855
  debugJson(logger, "Translated Responses payload:", responsesPayload);
5838
5856
  const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
5839
5857
  const transport = getResponsesTransportForModel(selectedModel, { compactType: requestOptions.compactType }) ?? "http";
@@ -6144,9 +6162,13 @@ messageRoutes.post("/count_tokens", async (c) => {
6144
6162
  const modelRoutes = new Hono();
6145
6163
  const logger$4 = createHandlerLogger("models-handler");
6146
6164
  const EPOCH_ISO = (/* @__PURE__ */ new Date(0)).toISOString();
6165
+ const CODEX_USER_AGENT_PATTERN = /^codex/iu;
6147
6166
  function isRecord(value) {
6148
6167
  return typeof value === "object" && value !== null && !Array.isArray(value);
6149
6168
  }
6169
+ function isCodexUserAgent(userAgent) {
6170
+ return CODEX_USER_AGENT_PATTERN.test(userAgent?.trim() ?? "");
6171
+ }
6150
6172
  function normalizeCopilotModel(model) {
6151
6173
  const contextWindow = model.capabilities?.limits?.max_context_window_tokens ?? 0;
6152
6174
  const clientId = toClientModelId(model.id);
@@ -6222,8 +6244,29 @@ async function getAggregatedModels(requestHeaders) {
6222
6244
  return true;
6223
6245
  });
6224
6246
  }
6247
+ async function logCodexModelsResponse(response) {
6248
+ try {
6249
+ const responseText = await response.clone().text();
6250
+ logger$4.debug("models.codex.response", {
6251
+ statusCode: response.status,
6252
+ models: responseText
6253
+ });
6254
+ } catch (error) {
6255
+ logger$4.warn("models.codex.response_log_error", { error });
6256
+ }
6257
+ }
6225
6258
  modelRoutes.get("/", async (c) => {
6226
6259
  try {
6260
+ if (isCodexUserAgent(c.req.header("user-agent"))) {
6261
+ const codexProviderConfig = await resolveProviderConfig("codex");
6262
+ if (!codexProviderConfig) return c.json({ error: {
6263
+ message: "Provider 'codex' not found or disabled",
6264
+ type: "invalid_request_error"
6265
+ } }, 404);
6266
+ const upstreamResponse = await forwardCodexModels(c.req.url, c.req.raw.headers, codexProviderConfig.baseUrl);
6267
+ await logCodexModelsResponse(upstreamResponse);
6268
+ return createProviderProxyResponse(upstreamResponse);
6269
+ }
6227
6270
  const models = await getAggregatedModels(c.req.raw.headers);
6228
6271
  return c.json({
6229
6272
  object: "list",
@@ -6299,6 +6342,14 @@ async function handleProviderResponsesForProvider(c, options) {
6299
6342
  message: `Provider '${provider}' does not support the /v1/responses endpoint`,
6300
6343
  type: "invalid_request_error"
6301
6344
  } }, 400);
6345
+ if (applyResponsesApiContextManagement(payload, (providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0)?.capabilities.limits.max_prompt_tokens, {
6346
+ compactThresholdRatio: .8,
6347
+ source: "responses"
6348
+ })) compactInputByLatestCompaction(payload);
6349
+ debugJson(logger$2, "Translated Responses request payload:", {
6350
+ contextManagement: payload.context_management,
6351
+ provider
6352
+ });
6302
6353
  const modelConfig = providerConfig.models?.[payload.model];
6303
6354
  if (providerConfig.name === "codex") {
6304
6355
  const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl);
@@ -6481,7 +6532,6 @@ const handleResponses = async (c) => {
6481
6532
  });
6482
6533
  removeUnsupportedTools(payload);
6483
6534
  if (!responsesHandlerDependencies.isResponsesApiWebSearchEnabled()) removeWebSearchTool(payload);
6484
- compactInputByLatestCompaction(payload);
6485
6535
  const selectedModel = state.models?.data.find((model) => model.id === payload.model);
6486
6536
  const responsesTransport = getResponsesTransportForModel(selectedModel);
6487
6537
  if (!responsesTransport) return c.json({ error: {
@@ -6491,7 +6541,10 @@ const handleResponses = async (c) => {
6491
6541
  const sanitizedImageCount = sanitizeOversizedInputImages(payload, selectedModel?.capabilities.limits.vision?.max_prompt_image_size);
6492
6542
  if (sanitizedImageCount > 0) logger$1.warn(`Omitted ${sanitizedImageCount} oversized input image(s) before forwarding to Copilot Responses`);
6493
6543
  const maxPromptTokens = selectedModel?.capabilities.limits.max_prompt_tokens;
6494
- applyResponsesApiContextManagement(payload, maxPromptTokens, .8);
6544
+ if (applyResponsesApiContextManagement(payload, maxPromptTokens, {
6545
+ compactThresholdRatio: .8,
6546
+ source: "responses"
6547
+ })) compactInputByLatestCompaction(payload);
6495
6548
  debugJson(logger$1, "Translated Responses payload:", payload);
6496
6549
  const { vision, initiator: inferredInitiator } = getResponsesRequestOptions(payload);
6497
6550
  const initiator = subagentMarker ? "agent" : inferredInitiator;
@@ -6704,4 +6757,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
6704
6757
  //#endregion
6705
6758
  export { server };
6706
6759
 
6707
- //# sourceMappingURL=server-BSkcO0zz.js.map
6760
+ //# sourceMappingURL=server-DcNUjirU.js.map