@jeffreycao/copilot-api 1.14.2 → 1.14.5

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
@@ -25,7 +25,7 @@ bindElectronFetch();
25
25
  const { auth } = await import("./auth-DvJ8r_tN.js");
26
26
  const { debug } = await import("./debug-Bb5hamXX.js");
27
27
  const { mcp } = await import("./mcp-BseuqgHR.js");
28
- const { start } = await import("./start-BUCPPobx.js");
28
+ const { start } = await import("./start-Beq7gtGI.js");
29
29
  await runMain(defineCommand({
30
30
  meta: {
31
31
  name: "copilot-api",
@@ -3610,7 +3610,7 @@ const translateAnthropicMessagesToResponsesPayload = (payload, subagentAgentId)
3610
3610
  reasoning: {
3611
3611
  effort: resolveReasoningEffort(payload),
3612
3612
  summary: "detailed",
3613
- context: "all_turns"
3613
+ context: isSupportAllTurns(payload) ? "all_turns" : "auto"
3614
3614
  },
3615
3615
  include: ["reasoning.encrypted_content"]
3616
3616
  };
@@ -4155,6 +4155,10 @@ const convertToolResultContent = (content) => {
4155
4155
  }
4156
4156
  return "";
4157
4157
  };
4158
+ const isSupportAllTurns = (payload) => {
4159
+ if (payload.model === "gpt-5.4" || payload.model === "gpt-5.4-mini" || payload.model === "gpt-5.5") return true;
4160
+ return isGpt56OrAbove(payload.model);
4161
+ };
4158
4162
  //#endregion
4159
4163
  //#region src/routes/messages/responses-stream-translation.ts
4160
4164
  const MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20;
@@ -4623,6 +4627,64 @@ const stringifyToolSearchArguments = (argumentsValue) => {
4623
4627
  return;
4624
4628
  }
4625
4629
  };
4630
+ //#endregion
4631
+ //#region src/routes/messages/responses-stream-collection.ts
4632
+ const collectResponsesStreamResult = async ({ errorMessagePrefix = "Responses stream", parseEvent = parseResponsesStreamEvent$1, upstreamResponse, logger }) => {
4633
+ const state = createResponsesStreamCollection();
4634
+ for await (const chunk of upstreamResponse) {
4635
+ const result = collectResponsesStreamChunk({
4636
+ chunk,
4637
+ errorMessagePrefix,
4638
+ logger,
4639
+ parseEvent,
4640
+ state
4641
+ });
4642
+ if (result) return result;
4643
+ }
4644
+ throw new Error(`${errorMessagePrefix} ended without a terminal event`);
4645
+ };
4646
+ const collectResponsesStreamChunk = ({ chunk, errorMessagePrefix, logger, parseEvent, state }) => {
4647
+ debugJson(logger, "Received responses stream chunk:", chunk);
4648
+ if (chunk.event === "ping" || !chunk.data || chunk.data === "[DONE]") return;
4649
+ const parsed = parseEvent(chunk.data);
4650
+ if (!parsed) return;
4651
+ if (parsed.type === "error") throw new Error(getStreamErrorMessage(parsed) ?? `${errorMessagePrefix} failed`);
4652
+ if (parsed.type === "response.failed") {
4653
+ const response = parsed.response;
4654
+ if (!response) throw new Error("Responses stream ended without a response");
4655
+ throw new Error(response.error?.message ?? `${errorMessagePrefix} failed`);
4656
+ }
4657
+ return collectResponsesStreamEvent(parsed, state);
4658
+ };
4659
+ const parseResponsesStreamEvent$1 = (data) => {
4660
+ try {
4661
+ return JSON.parse(data);
4662
+ } catch {
4663
+ return null;
4664
+ }
4665
+ };
4666
+ const createResponsesStreamCollection = () => ({ outputItemsByIndex: /* @__PURE__ */ new Map() });
4667
+ const collectResponsesStreamEvent = (event, state) => {
4668
+ switch (event.type) {
4669
+ case "response.completed":
4670
+ case "response.incomplete": {
4671
+ const response = event.response;
4672
+ if (!response) throw new Error("Responses stream ended without a response");
4673
+ response.copilot_usage ??= event.copilot_usage;
4674
+ const output = [...state.outputItemsByIndex.entries()].sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([, item]) => item);
4675
+ return {
4676
+ ...response,
4677
+ output: output.length > 0 ? output : response.output
4678
+ };
4679
+ }
4680
+ case "response.output_item.done":
4681
+ state.outputItemsByIndex.set(event.output_index, event.item);
4682
+ break;
4683
+ }
4684
+ };
4685
+ const getStreamErrorMessage = (event) => {
4686
+ return event.error?.message ?? event.message ?? void 0;
4687
+ };
4626
4688
  const DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO = .85;
4627
4689
  const responsesUtilsDependencies = {
4628
4690
  getModelResponsesApiCompactThreshold: getModelResponsesApiCompactThreshold$1,
@@ -4971,53 +5033,9 @@ const reconstructWebSearchResponse = (payload, result, options) => {
4971
5033
  }
4972
5034
  };
4973
5035
  };
4974
- const collectWebSearchResponsesStreamResult = async ({ errorMessagePrefix = "Web search responses stream", parseEvent = parseResponsesStreamEvent$1, upstreamResponse, logger }) => {
4975
- const state = createWebSearchResponsesStreamCollection();
4976
- for await (const chunk of upstreamResponse) {
4977
- debugJson(logger, "Received web search responses stream chunk:", chunk);
4978
- if (chunk.event === "ping") continue;
4979
- if (!chunk.data || chunk.data === "[DONE]") continue;
4980
- const parsed = parseEvent(chunk.data);
4981
- if (!parsed) continue;
4982
- if (parsed.type === "error") throw new Error(getStreamErrorMessage(parsed) ?? `${errorMessagePrefix} failed`);
4983
- const result = collectResponsesStreamEvent(parsed, state);
4984
- if (result) return result;
4985
- }
4986
- throw new Error(`${errorMessagePrefix} ended without a terminal event`);
4987
- };
4988
- const parseResponsesStreamEvent$1 = (data) => {
4989
- try {
4990
- return JSON.parse(data);
4991
- } catch {
4992
- return null;
4993
- }
4994
- };
4995
5036
  const isWebSearchResponsesStream = (value) => {
4996
5037
  return Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
4997
5038
  };
4998
- const createWebSearchResponsesStreamCollection = () => ({ outputItemsByIndex: /* @__PURE__ */ new Map() });
4999
- const collectResponsesStreamEvent = (event, state) => {
5000
- switch (event.type) {
5001
- case "response.completed":
5002
- case "response.failed":
5003
- case "response.incomplete": {
5004
- event.response.copilot_usage ??= event.copilot_usage;
5005
- const response = event.response;
5006
- if (!response) throw new Error("Web search responses stream ended without a response");
5007
- const output = [...state.outputItemsByIndex.entries()].sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([, item]) => item);
5008
- return {
5009
- ...response,
5010
- output: output.length > 0 ? output : response.output
5011
- };
5012
- }
5013
- case "response.output_item.done":
5014
- state.outputItemsByIndex.set(event.output_index, event.item);
5015
- break;
5016
- }
5017
- };
5018
- const getStreamErrorMessage = (event) => {
5019
- return event.error?.message ?? event.message ?? void 0;
5020
- };
5021
5039
  const createUsageRecorder = (payload, sessionId, webSearchModel) => webSearchFlowDependencies.createUsageRecorder(payload, sessionId, webSearchModel);
5022
5040
  /**
5023
5041
  * Entry point for web-search detection and routing on /v1/messages.
@@ -5082,7 +5100,7 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
5082
5100
  sessionId: options.sessionId,
5083
5101
  compactType: options.compactType
5084
5102
  });
5085
- const result = isWebSearchResponsesStream(upstreamResult) ? await collectWebSearchResponsesStreamResult({
5103
+ const result = isWebSearchResponsesStream(upstreamResult) ? await collectResponsesStreamResult({
5086
5104
  errorMessagePrefix: "Web search responses stream",
5087
5105
  upstreamResponse: upstreamResult,
5088
5106
  logger
@@ -5394,7 +5412,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
5394
5412
  if (providerConfig.name === "codex") {
5395
5413
  const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl);
5396
5414
  if (isResponsesStream$1(upstreamResponse)) return respondWebSearchProviderMessagesJson(c, {
5397
- body: await collectWebSearchResponsesStreamResult({
5415
+ body: await collectResponsesStreamResult({
5398
5416
  errorMessagePrefix: `${provider} web search responses stream`,
5399
5417
  parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
5400
5418
  upstreamResponse,
@@ -5422,7 +5440,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
5422
5440
  throw new HTTPError("Failed to create provider web search responses", upstreamResponse);
5423
5441
  }
5424
5442
  if ((upstreamResponse.headers.get("content-type") ?? "").includes("text/event-stream")) return respondWebSearchProviderMessagesJson(c, {
5425
- body: await collectWebSearchResponsesStreamResult({
5443
+ body: await collectResponsesStreamResult({
5426
5444
  errorMessagePrefix: `${provider} web search responses stream`,
5427
5445
  parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
5428
5446
  upstreamResponse: events(upstreamResponse),
@@ -5444,7 +5462,9 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
5444
5462
  const handleOpenAIResponsesProviderMessages = async (c, options) => {
5445
5463
  const { modelConfig, payload, provider, providerConfig } = options;
5446
5464
  const selectedModel = providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0;
5465
+ const wantsStream = payload.stream === true;
5447
5466
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(payload);
5467
+ if (providerConfig.name === "codex" && !wantsStream) responsesPayload.stream = true;
5448
5468
  if (applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens, { source: "messages" })) compactInputByLatestCompaction(responsesPayload);
5449
5469
  debugJson(logger$6, "provider.messages.responses.request", {
5450
5470
  payload: responsesPayload,
@@ -5452,15 +5472,30 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
5452
5472
  });
5453
5473
  if (providerConfig.name === "codex") {
5454
5474
  const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl);
5455
- if (responsesPayload.stream && isResponsesStream$1(upstreamResponse)) return streamResponsesProviderMessages({
5456
- c,
5457
- modelConfig,
5458
- payload,
5459
- pricingCurrency: providerConfig.pricingCurrency,
5460
- provider,
5461
- providerConfig,
5462
- upstreamResponse
5463
- });
5475
+ if (isResponsesStream$1(upstreamResponse)) {
5476
+ if (wantsStream) return streamResponsesProviderMessages({
5477
+ c,
5478
+ modelConfig,
5479
+ payload,
5480
+ pricingCurrency: providerConfig.pricingCurrency,
5481
+ provider,
5482
+ providerConfig,
5483
+ upstreamResponse
5484
+ });
5485
+ return respondResponsesProviderMessagesJson(c, {
5486
+ body: await collectResponsesStreamResult({
5487
+ errorMessagePrefix: `${provider} messages responses stream`,
5488
+ parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
5489
+ upstreamResponse,
5490
+ logger: logger$6
5491
+ }),
5492
+ modelConfig,
5493
+ payload,
5494
+ pricingCurrency: providerConfig.pricingCurrency,
5495
+ provider,
5496
+ providerConfig
5497
+ });
5498
+ }
5464
5499
  return respondResponsesProviderMessagesJson(c, {
5465
5500
  body: upstreamResponse,
5466
5501
  modelConfig,
@@ -6851,4 +6886,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
6851
6886
  //#endregion
6852
6887
  export { server };
6853
6888
 
6854
- //# sourceMappingURL=server-HvdtsRfY.js.map
6889
+ //# sourceMappingURL=server-CmynIOAW.js.map