@jeffreycao/copilot-api 2.5.1 → 2.5.2

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,7 +1,7 @@
1
- import { A as isResponsesApiWebSocketEnabled, C as getClaudeTokenMultiplier, D as isAlphaSearchCodexPriorityEnabled, E as getResponsesTransportConfig, N as PATHS, O as isMessagesApiEnabled, S as getClaudeAutoModel, T as getMessageApiWebSearchModel, _ as resolveMappedModel, b as getAlphaSearchModel, d as getModelResponsesApiCompactThreshold$1, f as getReasoningEffortForModel, g as isGpt56OrAbove, h as isContextManagementEnabledForResponses, i as listEnabledProviders, k as isResponsesApiWebSearchEnabled, l as getExtraPromptForModel, m as isContextManagementEnabledForMessages, n as getRawProviderConfig, o as resolveEffectiveProviderType, p as getSmallModel, s as resolveProviderAuthType, t as getProviderConfig, u as getModelMappings, v as setModelMappings, x as getAnthropicApiKey } from "./config-Cb0atQ6i.js";
2
- import { B as fetchResponsesWithLifecycle, C as compactAutoContinuePromptStarts, D as compactTextOnlyGuard, E as compactSystemPromptStarts, F as forwardCodexResponses, G as createWebSocketUrl, H as encodePoolKeyPart, I as generateTraceId, J as forwardError, K as state, L as requestContext, N as CODEX_API_BASE_URL, O as createAuthMiddleware, P as buildCodexRequestHeaders, R as resolveTraceId$1, U as isTerminalResponsesStreamChunk, V as createResponsesSafeStream, W as createPooledWebSocketStream, b as prepareInteractionHeaders, c as getUUID, d as isResponsesStream, f as parseUserIdMetadata, g as copilotHeaders, h as copilotBaseUrl, k as getConfiguredAdminApiKeys, l as isAsyncIterable, o as generateRequestIdFromPayload, p as getCopilotUsage, q as HTTPError, r as setupCodexToken, s as getRootSessionId, u as isNullish, v as copilotWebSocketHeaders, w as compactMessageSections, x as prepareMessageProxyHeaders, y as prepareForCompact, z as createResponsesHttpEventStream } from "./token-DYqRXNhu.js";
1
+ import { A as isResponsesApiWebSocketEnabled, C as getClaudeTokenMultiplier, D as isAlphaSearchCodexPriorityEnabled, E as getUpstreamTransportConfig, N as PATHS, O as isMessagesApiEnabled, S as getClaudeAutoModel, T as getMessageApiWebSearchModel, _ as resolveMappedModel, b as getAlphaSearchModel, d as getModelResponsesApiCompactThreshold$1, f as getReasoningEffortForModel, g as isGpt56OrAbove, h as isContextManagementEnabledForResponses, i as listEnabledProviders, k as isResponsesApiWebSearchEnabled, l as getExtraPromptForModel, m as isContextManagementEnabledForMessages, n as getRawProviderConfig, o as resolveEffectiveProviderType, p as getSmallModel, s as resolveProviderAuthType, t as getProviderConfig, u as getModelMappings, v as setModelMappings, x as getAnthropicApiKey } from "./config-Dj2ZvQuL.js";
2
+ import { A as createAuthMiddleware, B as resolveTraceId$1, C as prepareMessageProxyHeaders, E as compactMessageSections, F as CODEX_API_BASE_URL, G as isTerminalResponsesStreamChunk, H as createResponsesHttpEventStream, I as buildCodexRequestHeaders, J as state, K as createPooledWebSocketStream, L as forwardCodexResponses, O as compactSystemPromptStarts, R as generateTraceId, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, U as createResponsesSafeStream, V as fetchUpstreamWithLifecycle, W as encodePoolKeyPart, X as forwardError, Y as HTTPError, _ as copilotBaseUrl, b as copilotWebSocketHeaders, c as getUUID, d as isResponsesStream, f as parseUserIdMetadata, j as getConfiguredAdminApiKeys, k as compactTextOnlyGuard, l as isAsyncIterable, o as generateRequestIdFromPayload, p as getCopilotUsage, q as createWebSocketUrl, r as setupCodexToken, s as getRootSessionId, u as isNullish, v as copilotHeaders, x as prepareForCompact, z as requestContext } from "./token-CaFzyRJX.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-Ds1vbmGG.js";
4
- import { i as toClientModelId, r as normalizeSdkModelId, t as findEndpointModel } from "./models-DvNveb2V.js";
4
+ import { i as toClientModelId, r as normalizeSdkModelId, t as findEndpointModel } from "./models-12Y1nB8k.js";
5
5
  import consola from "consola";
6
6
  import { createHash } from "node:crypto";
7
7
  import fs, { createWriteStream, readFileSync, rmSync } from "node:fs";
@@ -2156,7 +2156,7 @@ const isCopilotQuotaSnapshot = (value) => {
2156
2156
  };
2157
2157
  //#endregion
2158
2158
  //#region src/services/copilot/create-responses.ts
2159
- const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType, transport = "http", signal }) => {
2159
+ const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType, transport = "http", clientSignal }) => {
2160
2160
  if (!state.copilotToken) throw new Error("Copilot token not found");
2161
2161
  const headers = {
2162
2162
  ...copilotHeaders(state, requestId, vision),
@@ -2167,22 +2167,24 @@ const createResponses = async (payload, { vision, initiator, subagentMarker, req
2167
2167
  payload.service_tier = void 0;
2168
2168
  consola.log(`<-- model: ${payload.model}`);
2169
2169
  const effectiveTransport = compactType === 1 ? "http" : transport;
2170
- if (payload.stream === true && effectiveTransport === "websocket") return createPooledResponsesWebSocketStream(prepareResponsesWebSocketRequest(payload, headers, {
2171
- requestId,
2172
- signal,
2173
- subagentMarker
2174
- }));
2175
- return await createHttpResponses(payload, headers, signal);
2170
+ if (payload.stream === true && effectiveTransport === "websocket") {
2171
+ clientSignal?.throwIfAborted();
2172
+ return createPooledResponsesWebSocketStream(prepareResponsesWebSocketRequest(payload, headers, {
2173
+ requestId,
2174
+ subagentMarker
2175
+ }), clientSignal);
2176
+ }
2177
+ return await createHttpResponses(payload, headers, clientSignal);
2176
2178
  };
2177
- const createHttpResponses = async (payload, headers, signal) => {
2178
- const transportConfig = getResponsesTransportConfig();
2179
- const response = await fetchResponsesWithLifecycle(`${copilotBaseUrl(state)}/responses`, {
2179
+ const createHttpResponses = async (payload, headers, clientSignal) => {
2180
+ const transportConfig = getUpstreamTransportConfig();
2181
+ const response = await fetchUpstreamWithLifecycle(`${copilotBaseUrl(state)}/responses`, {
2180
2182
  method: "POST",
2181
2183
  headers,
2182
2184
  body: JSON.stringify(payload)
2183
2185
  }, {
2186
+ clientSignal,
2184
2187
  headersTimeoutMs: transportConfig.headersTimeoutMs,
2185
- signal,
2186
2188
  streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
2187
2189
  });
2188
2190
  logCopilotRateLimits(response.headers);
@@ -2190,7 +2192,7 @@ const createHttpResponses = async (payload, headers, signal) => {
2190
2192
  consola.error("Failed to create responses", response);
2191
2193
  throw new HTTPError("Failed to create responses", response);
2192
2194
  }
2193
- if (payload.stream) return createResponsesSafeStream(createResponsesHttpEventStream(response, signal), { signal });
2195
+ if (payload.stream) return createResponsesSafeStream(createResponsesHttpEventStream(response));
2194
2196
  return await response.json();
2195
2197
  };
2196
2198
  const prepareResponsesWebSocketRequest = (payload, preparedHeaders, options) => {
@@ -2199,7 +2201,6 @@ const prepareResponsesWebSocketRequest = (payload, preparedHeaders, options) =>
2199
2201
  headers: copilotWebSocketHeaders(preparedHeaders),
2200
2202
  poolKey: buildResponsesWebSocketPoolKey(payload, options),
2201
2203
  payload: buildResponsesWebSocketPayload(payload, initiator),
2202
- signal: options.signal,
2203
2204
  url: buildResponsesWebSocketUrl(copilotBaseUrl(state))
2204
2205
  };
2205
2206
  };
@@ -2220,9 +2221,10 @@ const buildResponsesWebSocketPoolKey = (payload, { requestId, subagentMarker })
2220
2221
  const getResponsesWebSocketInitiator = (preparedHeaders) => {
2221
2222
  return getHeaderValue(preparedHeaders, "x-initiator")?.toLowerCase() === "agent" ? "agent" : "user";
2222
2223
  };
2223
- const createPooledResponsesWebSocketStream = (request) => {
2224
- const transportConfig = getResponsesTransportConfig();
2225
- return createResponsesSafeStream(createPooledWebSocketStream(request, {
2224
+ const createPooledResponsesWebSocketStream = (request, clientSignal) => createResponsesSafeStream(createClientPreflightStream(createPooledWebSocketStream(request, { ...getResponsesWebSocketOptions() }), clientSignal));
2225
+ const getResponsesWebSocketOptions = () => {
2226
+ const transportConfig = getUpstreamTransportConfig();
2227
+ return {
2226
2228
  createChunk: createResponsesWebSocketStreamChunk,
2227
2229
  maxBufferedBytes: transportConfig.websocketMaxBufferedBytes,
2228
2230
  maxBufferedMessages: transportConfig.websocketMaxBufferedMessages,
@@ -2233,7 +2235,11 @@ const createPooledResponsesWebSocketStream = (request) => {
2233
2235
  streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs,
2234
2236
  streamErrorMessage: "Upstream connection lost, Responses websocket stream error",
2235
2237
  terminalChunkMissingMessage: "Responses websocket ended without a terminal response, retry your request."
2236
- }), { signal: request.signal });
2238
+ };
2239
+ };
2240
+ const createClientPreflightStream = async function* (source, clientSignal) {
2241
+ if (clientSignal?.aborted) return;
2242
+ yield* source;
2237
2243
  };
2238
2244
  const buildResponsesWebSocketPayload = (payload, initiator) => {
2239
2245
  const websocketPayload = {
@@ -2345,38 +2351,48 @@ function createProviderProxyResponse(upstreamResponse, body) {
2345
2351
  statusText: upstreamResponse.statusText
2346
2352
  });
2347
2353
  }
2348
- async function forwardProviderMessages(providerConfig, payload, requestHeaders) {
2354
+ async function forwardProviderMessages(providerConfig, payload, requestHeaders, options = {}) {
2349
2355
  consola.log(`<-- model: ${payload.model}`);
2350
2356
  const headers = buildProviderUpstreamHeaders(providerConfig, requestHeaders);
2351
2357
  applyOpencodeSessionHeader(providerConfig, headers, resolveOpencodeMessagesSession(payload));
2352
- return await fetch(`${providerConfig.baseUrl}/v1/messages`, {
2358
+ const transportConfig = getUpstreamTransportConfig();
2359
+ return await fetchUpstreamWithLifecycle(`${providerConfig.baseUrl}/v1/messages`, {
2353
2360
  method: "POST",
2354
2361
  headers,
2355
2362
  body: JSON.stringify(payload)
2363
+ }, {
2364
+ clientSignal: options.clientSignal,
2365
+ headersTimeoutMs: transportConfig.headersTimeoutMs,
2366
+ streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
2356
2367
  });
2357
2368
  }
2358
- async function forwardProviderChatCompletions(providerConfig, payload, requestHeaders) {
2369
+ async function forwardProviderChatCompletions(providerConfig, payload, requestHeaders, options = {}) {
2359
2370
  consola.log(`<-- model: ${payload.model}`);
2360
2371
  const headers = buildProviderUpstreamHeaders(providerConfig, requestHeaders);
2361
2372
  applyOpencodeSessionHeader(providerConfig, headers, payload.prompt_cache_key?.trim() || void 0);
2362
- return await fetch(`${providerConfig.baseUrl}/v1/chat/completions`, {
2373
+ const transportConfig = getUpstreamTransportConfig();
2374
+ return await fetchUpstreamWithLifecycle(`${providerConfig.baseUrl}/v1/chat/completions`, {
2363
2375
  method: "POST",
2364
2376
  headers,
2365
2377
  body: JSON.stringify(payload)
2378
+ }, {
2379
+ clientSignal: options.clientSignal,
2380
+ headersTimeoutMs: transportConfig.headersTimeoutMs,
2381
+ streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
2366
2382
  });
2367
2383
  }
2368
2384
  async function forwardProviderResponses(providerConfig, payload, requestHeaders, options = {}) {
2369
2385
  consola.log(`<-- model: ${payload.model}`);
2370
- const transportConfig = getResponsesTransportConfig();
2386
+ const transportConfig = getUpstreamTransportConfig();
2371
2387
  const headers = buildProviderUpstreamHeaders(providerConfig, requestHeaders);
2372
2388
  applyOpencodeSessionHeader(providerConfig, headers, payload.prompt_cache_key?.trim() || void 0);
2373
- return await fetchResponsesWithLifecycle(`${providerConfig.baseUrl}/v1/responses`, {
2389
+ return await fetchUpstreamWithLifecycle(`${providerConfig.baseUrl}/v1/responses`, {
2374
2390
  method: "POST",
2375
2391
  headers,
2376
2392
  body: JSON.stringify(payload)
2377
2393
  }, {
2378
2394
  headersTimeoutMs: transportConfig.headersTimeoutMs,
2379
- signal: options.signal,
2395
+ clientSignal: options.clientSignal,
2380
2396
  streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
2381
2397
  });
2382
2398
  }
@@ -2396,13 +2412,18 @@ function resolveProviderRequestUrl(providerConfig, requestUrl, path) {
2396
2412
  upstreamUrl.search = new URL(requestUrl, "http://localhost").search;
2397
2413
  return upstreamUrl.toString();
2398
2414
  }
2399
- async function forwardProviderAlphaSearch(providerConfig, request) {
2415
+ async function forwardProviderAlphaSearch(providerConfig, request, options = {}) {
2400
2416
  const headers = buildProviderUpstreamHeaders(providerConfig, request.headers);
2401
2417
  const body = await request.arrayBuffer();
2402
- return await fetch(resolveProviderRequestUrl(providerConfig, request.url, "/v1/alpha/search"), {
2418
+ const transportConfig = getUpstreamTransportConfig();
2419
+ return await fetchUpstreamWithLifecycle(resolveProviderRequestUrl(providerConfig, request.url, "/v1/alpha/search"), {
2403
2420
  method: "POST",
2404
2421
  headers,
2405
2422
  body
2423
+ }, {
2424
+ clientSignal: options.clientSignal,
2425
+ headersTimeoutMs: transportConfig.headersTimeoutMs,
2426
+ streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
2406
2427
  });
2407
2428
  }
2408
2429
  async function forwardProviderImages(providerConfig, request, operation) {
@@ -2788,7 +2809,7 @@ async function requestProviderSearch(c, providerConfig, payload, model, sessionI
2788
2809
  payload,
2789
2810
  provider: providerConfig.name
2790
2811
  });
2791
- const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { signal: c.req.raw.signal });
2812
+ const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
2792
2813
  if (!upstreamResponse.ok) throw new HTTPError(`Failed to create ${providerConfig.name} responses for alpha search`, upstreamResponse);
2793
2814
  const result = await upstreamResponse.json();
2794
2815
  debugJson(logger$17, "Alpha search provider Responses result:", {
@@ -2806,7 +2827,7 @@ async function requestProviderSearch(c, providerConfig, payload, model, sessionI
2806
2827
  })(normalizeResponsesUsage(result.usage));
2807
2828
  return result;
2808
2829
  }
2809
- async function requestCopilotSearch(payload, model, requestId, sessionId, signal) {
2830
+ async function requestCopilotSearch(payload, model, requestId, sessionId, clientSignal) {
2810
2831
  debugJson(logger$17, "Alpha search Copilot Responses request:", payload);
2811
2832
  const result = await alphaSearchResponsesDependencies.createResponses(payload, {
2812
2833
  vision: false,
@@ -2814,7 +2835,7 @@ async function requestCopilotSearch(payload, model, requestId, sessionId, signal
2814
2835
  transport: "http",
2815
2836
  requestId,
2816
2837
  sessionId,
2817
- signal
2838
+ clientSignal
2818
2839
  });
2819
2840
  debugJson(logger$17, "Alpha search Copilot Responses result:", result);
2820
2841
  alphaSearchResponsesDependencies.createUsageRecorder(model, sessionId)({
@@ -3069,6 +3090,18 @@ alphaSearchRoutes.post("/", async (c) => {
3069
3090
  }
3070
3091
  });
3071
3092
  //#endregion
3093
+ //#region src/lib/sse.ts
3094
+ async function writeSSEIfConnected(stream, message) {
3095
+ if (stream.aborted) return false;
3096
+ try {
3097
+ await stream.writeSSE(message);
3098
+ return true;
3099
+ } catch (error) {
3100
+ if (stream.aborted) return false;
3101
+ throw error;
3102
+ }
3103
+ }
3104
+ //#endregion
3072
3105
  //#region src/lib/dashscope.ts
3073
3106
  const OPENAI_COMPATIBLE_CONTEXT_CACHE_MARKER_LIMIT = 4;
3074
3107
  const OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL = { type: "ephemeral" };
@@ -3210,7 +3243,7 @@ async function handleProviderChatCompletionsForProvider(c, options) {
3210
3243
  payload,
3211
3244
  provider
3212
3245
  });
3213
- const upstreamResponse = await forwardProviderChatCompletions(providerConfig, payload, c.req.raw.headers);
3246
+ const upstreamResponse = await forwardProviderChatCompletions(providerConfig, payload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
3214
3247
  if (!upstreamResponse.ok) {
3215
3248
  logger$15.error("Failed to create provider chat completions", {
3216
3249
  provider,
@@ -3258,7 +3291,7 @@ const streamProviderChatCompletions = (c, upstreamResponse, options) => {
3258
3291
  const parsedChunk = parseChatCompletionChunkData(chunk.data);
3259
3292
  if (parsedChunk?.usage) usage = normalizeOpenAIUsage(parsedChunk.usage);
3260
3293
  }
3261
- await stream.writeSSE({
3294
+ await writeSSEIfConnected(stream, {
3262
3295
  event: chunk.event,
3263
3296
  data: chunk.data ?? ""
3264
3297
  });
@@ -3292,10 +3325,15 @@ const createChatCompletions = async (payload, options) => {
3292
3325
  prepareInteractionHeaders(options.sessionId, Boolean(options.subagentMarker), headers);
3293
3326
  prepareForCompact(headers, options.compactType);
3294
3327
  consola.log(`<-- model: ${payload.model}`);
3295
- const response = await fetch(`${copilotBaseUrl(state)}/chat/completions`, {
3328
+ const transportConfig = getUpstreamTransportConfig();
3329
+ const response = await fetchUpstreamWithLifecycle(`${copilotBaseUrl(state)}/chat/completions`, {
3296
3330
  method: "POST",
3297
3331
  headers,
3298
3332
  body: JSON.stringify(payload)
3333
+ }, {
3334
+ clientSignal: options.clientSignal,
3335
+ headersTimeoutMs: transportConfig.headersTimeoutMs,
3336
+ streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
3299
3337
  });
3300
3338
  logCopilotRateLimits(response.headers);
3301
3339
  if (!response.ok) {
@@ -3345,6 +3383,7 @@ async function handleCompletion$1(c) {
3345
3383
  model: payload.model
3346
3384
  });
3347
3385
  const response = await createChatCompletions(payload, {
3386
+ clientSignal: c.req.raw.signal,
3348
3387
  requestId,
3349
3388
  sessionId
3350
3389
  });
@@ -3366,7 +3405,7 @@ async function handleCompletion$1(c) {
3366
3405
  ...normalizeOpenAIUsage(parsedChunk.usage),
3367
3406
  total_nano_aiu: normalizeOptionalToken(parsedChunk.copilot_usage?.total_nano_aiu)
3368
3407
  };
3369
- await stream.writeSSE(chunk);
3408
+ await writeSSEIfConnected(stream, chunk);
3370
3409
  }
3371
3410
  recordUsage(usage);
3372
3411
  });
@@ -6579,7 +6618,8 @@ const MESSAGES_TOOL_CALL_TIPS = [
6579
6618
  "- Construct all tools.exec_command(...) arguments strictly according to its tool definition, and use OS/shell-compatible commands for Windows, Linux, and macOS.",
6580
6619
  "- Always assign the awaited tools.exec_command(...) call to a variable and forward the full result with text(JSON.stringify(r)); unforwarded output is silently dropped and makes results look empty.",
6581
6620
  "- Yielded execution is not truncated output. Resume a running `cell_id` with `functions.wait`, and a live `session_id` with `tools.write_stdin`, until the command reaches a terminal result.",
6582
- "- Read files with the OS-native command (Get-Content/Test-Path on Windows PowerShell, cat/ls on POSIX), quote paths containing spaces, and verify the forwarded output is non-empty before concluding a file was read."
6621
+ "- Read files with the OS-native command (Get-Content/Test-Path on Windows PowerShell, cat/ls on POSIX), quote paths containing spaces, and verify the forwarded output is non-empty before concluding a file was read.",
6622
+ "- For long-running commands, keep the returned `session_id` and poll it with `tools.write_stdin` until the command finishes; do not redirect output to a temp file and read it back in a second call."
6583
6623
  ].join("\n");
6584
6624
  const COMPACTION_REPLAY_PROMPT = "The previous conversation was compacted. Continue from this handoff summary:\n\n";
6585
6625
  const MAX_DEVELOPER_PROMPTS = 5;
@@ -7667,7 +7707,7 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
7667
7707
  subagentMarker: options.subagentMarker,
7668
7708
  requestId: options.requestId,
7669
7709
  sessionId: options.sessionId,
7670
- signal: c.req?.raw?.signal,
7710
+ clientSignal: c.req?.raw?.signal,
7671
7711
  compactType: options.compactType
7672
7712
  });
7673
7713
  const result = isWebSearchResponsesStream(upstreamResult) ? await collectResponsesStreamResult({
@@ -7686,7 +7726,7 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
7686
7726
  for (const event of buildSyntheticStreamEvents(response)) {
7687
7727
  const data = JSON.stringify(event);
7688
7728
  logger.debug(`Web search stream event`, data);
7689
- await stream.writeSSE({
7729
+ await writeSSEIfConnected(stream, {
7690
7730
  event: event.type,
7691
7731
  data
7692
7732
  });
@@ -8005,7 +8045,7 @@ async function handleProviderMessagesForProvider(c, options) {
8005
8045
  ...providerConfig,
8006
8046
  type: effectiveType,
8007
8047
  authType: resolveOverrideProviderAuthType(providerConfig, effectiveType)
8008
- }, payload, c.req.raw.headers);
8048
+ }, payload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
8009
8049
  if (!upstreamResponse.ok) {
8010
8050
  logger$10.error("Failed to create responses", upstreamResponse);
8011
8051
  throw new HTTPError("Failed to create responses", upstreamResponse);
@@ -8046,7 +8086,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
8046
8086
  provider
8047
8087
  });
8048
8088
  if (providerConfig.name === "codex") {
8049
- const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
8089
+ const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { clientSignal: c.req.raw.signal });
8050
8090
  if (isResponsesStream(upstreamResponse)) return respondWebSearchProviderMessagesJson(c, {
8051
8091
  body: await collectResponsesStreamResult({
8052
8092
  errorMessagePrefix: `${provider} web search responses stream`,
@@ -8069,7 +8109,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
8069
8109
  usageEndpoint
8070
8110
  });
8071
8111
  }
8072
- const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { signal: c.req.raw.signal });
8112
+ const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
8073
8113
  if (!upstreamResponse.ok) {
8074
8114
  logger$10.error("Failed to create provider web search responses", {
8075
8115
  provider,
@@ -8081,7 +8121,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
8081
8121
  body: await collectResponsesStreamResult({
8082
8122
  errorMessagePrefix: `${provider} web search responses stream`,
8083
8123
  parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
8084
- upstreamResponse: createResponsesHttpEventStream(upstreamResponse, c.req.raw.signal),
8124
+ upstreamResponse: createResponsesHttpEventStream(upstreamResponse),
8085
8125
  logger: logger$10
8086
8126
  }),
8087
8127
  modelConfig,
@@ -8113,7 +8153,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
8113
8153
  provider
8114
8154
  });
8115
8155
  if (providerConfig.name === "codex") {
8116
- const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
8156
+ const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { clientSignal: c.req.raw.signal });
8117
8157
  if (isResponsesStream(upstreamResponse)) {
8118
8158
  if (wantsStream) return streamResponsesProviderMessages({
8119
8159
  c,
@@ -8150,7 +8190,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
8150
8190
  usageEndpoint
8151
8191
  });
8152
8192
  }
8153
- const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { signal: c.req.raw.signal });
8193
+ const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
8154
8194
  if (!upstreamResponse.ok) {
8155
8195
  logger$10.error("Failed to create provider responses", upstreamResponse);
8156
8196
  throw new HTTPError("Failed to create provider responses", upstreamResponse);
@@ -8162,7 +8202,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
8162
8202
  pricingCurrency: providerConfig.pricingCurrency,
8163
8203
  provider,
8164
8204
  providerConfig,
8165
- upstreamResponse: createResponsesSafeStream(createResponsesHttpEventStream(upstreamResponse, c.req.raw.signal), { signal: c.req.raw.signal }),
8205
+ upstreamResponse: createResponsesSafeStream(createResponsesHttpEventStream(upstreamResponse)),
8166
8206
  usageEndpoint
8167
8207
  });
8168
8208
  return respondResponsesProviderMessagesJson(c, {
@@ -8201,7 +8241,7 @@ const handleOpenAICompatibleProviderMessages = async (c, options) => {
8201
8241
  payload: openAIPayload,
8202
8242
  provider
8203
8243
  });
8204
- const upstreamResponse = await forwardProviderChatCompletions(providerConfig, openAIPayload, c.req.raw.headers);
8244
+ const upstreamResponse = await forwardProviderChatCompletions(providerConfig, openAIPayload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
8205
8245
  if (!upstreamResponse.ok) {
8206
8246
  logger$10.error("Failed to create openai-compatible responses", upstreamResponse);
8207
8247
  throw new HTTPError("Failed to create openai-compatible responses", upstreamResponse);
@@ -8283,7 +8323,7 @@ const streamProviderMessages = ({ c, modelConfig, payload, pricingCurrency, prov
8283
8323
  logger$10.debug("provider.messages.raw_stream_event:", chunk.data);
8284
8324
  const eventName = chunk.event;
8285
8325
  if (eventName === "ping") {
8286
- await stream.writeSSE({
8326
+ await writeSSEIfConnected(stream, {
8287
8327
  event: "ping",
8288
8328
  data: "{\"type\":\"ping\"}"
8289
8329
  });
@@ -8303,7 +8343,7 @@ const streamProviderMessages = ({ c, modelConfig, payload, pricingCurrency, prov
8303
8343
  data,
8304
8344
  event: eventName
8305
8345
  }];
8306
- for (const streamEvent of streamEvents) await stream.writeSSE({
8346
+ for (const streamEvent of streamEvents) await writeSSEIfConnected(stream, {
8307
8347
  event: streamEvent.event,
8308
8348
  data: streamEvent.data
8309
8349
  });
@@ -8317,7 +8357,7 @@ const streamProviderMessages = ({ c, modelConfig, payload, pricingCurrency, prov
8317
8357
  if (!messageStopSeen && !errorSeen) {
8318
8358
  logger$10.warn("provider.messages.stream_incomplete:", { provider });
8319
8359
  const errorEvent = translateErrorToAnthropicErrorEvent();
8320
- await stream.writeSSE({
8360
+ await writeSSEIfConnected(stream, {
8321
8361
  event: errorEvent.type,
8322
8362
  data: JSON.stringify(errorEvent)
8323
8363
  });
@@ -8342,7 +8382,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
8342
8382
  for await (const chunk of events(upstreamResponse)) {
8343
8383
  logger$10.debug("provider.messages.openai_compatible.raw_stream_event:", chunk.data);
8344
8384
  if (chunk.event === "ping") {
8345
- await stream.writeSSE({
8385
+ await writeSSEIfConnected(stream, {
8346
8386
  event: "ping",
8347
8387
  data: "{\"type\":\"ping\"}"
8348
8388
  });
@@ -8359,7 +8399,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
8359
8399
  for (const event of events) {
8360
8400
  const eventData = JSON.stringify(event);
8361
8401
  debugLazy(logger$10, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
8362
- await stream.writeSSE({
8402
+ await writeSSEIfConnected(stream, {
8363
8403
  event: event.type,
8364
8404
  data: eventData
8365
8405
  });
@@ -8374,7 +8414,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
8374
8414
  for (const event of flushPendingAnthropicStreamEvents(streamState)) {
8375
8415
  const eventData = JSON.stringify(event);
8376
8416
  debugLazy(logger$10, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
8377
- await stream.writeSSE({
8417
+ await writeSSEIfConnected(stream, {
8378
8418
  event: event.type,
8379
8419
  data: eventData
8380
8420
  });
@@ -8382,7 +8422,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
8382
8422
  if (!streamState.messageCompleted) {
8383
8423
  logger$10.warn("provider.messages.openai_compatible.stream_incomplete:", { provider });
8384
8424
  const errorEvent = translateErrorToAnthropicErrorEvent();
8385
- await stream.writeSSE({
8425
+ await writeSSEIfConnected(stream, {
8386
8426
  event: errorEvent.type,
8387
8427
  data: JSON.stringify(errorEvent)
8388
8428
  });
@@ -8399,7 +8439,7 @@ const streamResponsesProviderMessages = ({ c, modelConfig, payload, pricingCurre
8399
8439
  for await (const chunk of upstreamResponse) {
8400
8440
  logger$10.debug("provider.messages.responses.raw_stream_event:", chunk.data);
8401
8441
  if (chunk.event === "ping") {
8402
- await stream.writeSSE({
8442
+ await writeSSEIfConnected(stream, {
8403
8443
  event: "ping",
8404
8444
  data: "{\"type\":\"ping\"}"
8405
8445
  });
@@ -8416,7 +8456,7 @@ const streamResponsesProviderMessages = ({ c, modelConfig, payload, pricingCurre
8416
8456
  for (const event of events) {
8417
8457
  const eventData = JSON.stringify(event);
8418
8458
  debugLazy(logger$10, () => ["provider.messages.responses.translated_event:", eventData]);
8419
- await stream.writeSSE({
8459
+ await writeSSEIfConnected(stream, {
8420
8460
  event: event.type,
8421
8461
  data: eventData
8422
8462
  });
@@ -8424,7 +8464,7 @@ const streamResponsesProviderMessages = ({ c, modelConfig, payload, pricingCurre
8424
8464
  }
8425
8465
  if (!streamState.messageCompleted) {
8426
8466
  const errorEvent = buildErrorEvent(`${provider} stream ended without a completion event, retry your request.`);
8427
- await stream.writeSSE({
8467
+ await writeSSEIfConnected(stream, {
8428
8468
  event: errorEvent.type,
8429
8469
  data: JSON.stringify(errorEvent)
8430
8470
  });
@@ -8567,7 +8607,7 @@ const respondWebSearchProviderMessagesJson = (c, options) => {
8567
8607
  for (const event of buildSyntheticStreamEvents(response)) {
8568
8608
  const data = JSON.stringify(event);
8569
8609
  logger$10.debug(`Web search stream event`, data);
8570
- await stream.writeSSE({
8610
+ await writeSSEIfConnected(stream, {
8571
8611
  event: event.type,
8572
8612
  data
8573
8613
  });
@@ -8619,10 +8659,15 @@ const createMessages = async (payload, anthropicBetaHeader, options) => {
8619
8659
  const anthropicBeta = buildAnthropicBetaHeader(anthropicBetaHeader, payload.thinking, payload.model);
8620
8660
  if (anthropicBeta) headers["anthropic-beta"] = anthropicBeta;
8621
8661
  consola.log(`<-- model: ${payload.model}`);
8622
- const response = await fetch(`${copilotBaseUrl(state)}/v1/messages`, {
8662
+ const transportConfig = getUpstreamTransportConfig();
8663
+ const response = await fetchUpstreamWithLifecycle(`${copilotBaseUrl(state)}/v1/messages`, {
8623
8664
  method: "POST",
8624
8665
  headers,
8625
8666
  body: JSON.stringify(payload)
8667
+ }, {
8668
+ clientSignal: options.clientSignal,
8669
+ headersTimeoutMs: transportConfig.headersTimeoutMs,
8670
+ streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
8626
8671
  });
8627
8672
  logCopilotRateLimits(response.headers);
8628
8673
  if (!response.ok) {
@@ -8657,6 +8702,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
8657
8702
  });
8658
8703
  debugJson(logger, "Translated OpenAI request payload:", openAIPayload);
8659
8704
  const response = await messagesApiFlowDependencies.createChatCompletions(openAIPayload, {
8705
+ clientSignal: c.req?.raw?.signal,
8660
8706
  subagentMarker,
8661
8707
  requestId,
8662
8708
  sessionId,
@@ -8697,7 +8743,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
8697
8743
  for (const event of events) {
8698
8744
  const eventData = JSON.stringify(event);
8699
8745
  debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
8700
- await stream.writeSSE({
8746
+ await writeSSEIfConnected(stream, {
8701
8747
  event: event.type,
8702
8748
  data: eventData
8703
8749
  });
@@ -8709,7 +8755,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
8709
8755
  for (const event of flushPendingAnthropicStreamEvents(streamState)) {
8710
8756
  const eventData = JSON.stringify(event);
8711
8757
  debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
8712
- await stream.writeSSE({
8758
+ await writeSSEIfConnected(stream, {
8713
8759
  event: event.type,
8714
8760
  data: eventData
8715
8761
  });
@@ -8717,7 +8763,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
8717
8763
  if (!streamState.messageCompleted) {
8718
8764
  logger.warn("Chat completions stream ended without completion; sending error event");
8719
8765
  const errorEvent = translateErrorToAnthropicErrorEvent();
8720
- await stream.writeSSE({
8766
+ await writeSSEIfConnected(stream, {
8721
8767
  event: errorEvent.type,
8722
8768
  data: JSON.stringify(errorEvent)
8723
8769
  });
@@ -8741,7 +8787,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
8741
8787
  const response = await messagesApiFlowDependencies.createResponses(responsesPayload, {
8742
8788
  vision,
8743
8789
  initiator,
8744
- signal: c.req?.raw?.signal,
8790
+ clientSignal: c.req?.raw?.signal,
8745
8791
  transport,
8746
8792
  ...requestOptions
8747
8793
  });
@@ -8752,7 +8798,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
8752
8798
  let usage = {};
8753
8799
  for await (const chunk of response) {
8754
8800
  if (chunk.event === "ping") {
8755
- await stream.writeSSE({
8801
+ await writeSSEIfConnected(stream, {
8756
8802
  event: "ping",
8757
8803
  data: "{\"type\":\"ping\"}"
8758
8804
  });
@@ -8770,7 +8816,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
8770
8816
  for (const event of events) {
8771
8817
  const eventData = JSON.stringify(event);
8772
8818
  debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
8773
- await stream.writeSSE({
8819
+ await writeSSEIfConnected(stream, {
8774
8820
  event: event.type,
8775
8821
  data: eventData
8776
8822
  });
@@ -8783,7 +8829,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
8783
8829
  if (!streamState.messageCompleted) {
8784
8830
  logger.warn("Responses stream ended without completion; sending error event");
8785
8831
  const errorEvent = buildErrorEvent("Responses stream ended without completion, retry your request.");
8786
- await stream.writeSSE({
8832
+ await writeSSEIfConnected(stream, {
8787
8833
  event: errorEvent.type,
8788
8834
  data: JSON.stringify(errorEvent)
8789
8835
  });
@@ -8812,6 +8858,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
8812
8858
  });
8813
8859
  debugJson(logger, "Translated Messages payload:", anthropicPayload);
8814
8860
  const response = await messagesApiFlowDependencies.createMessages(anthropicPayload, anthropicBetaHeader, {
8861
+ clientSignal: c.req?.raw?.signal,
8815
8862
  subagentMarker,
8816
8863
  requestId,
8817
8864
  sessionId,
@@ -8841,7 +8888,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
8841
8888
  });
8842
8889
  if (parsedEvent?.type === "message_stop" || eventName === "message_stop") messageStopSeen = true;
8843
8890
  else if (parsedEvent?.type === "error" || eventName === "error") errorSeen = true;
8844
- await stream.writeSSE({
8891
+ await writeSSEIfConnected(stream, {
8845
8892
  event: eventName,
8846
8893
  data
8847
8894
  });
@@ -8852,7 +8899,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
8852
8899
  if (!messageStopSeen && !errorSeen) {
8853
8900
  logger.warn("Messages stream ended without completion; sending error event");
8854
8901
  const errorEvent = translateErrorToAnthropicErrorEvent();
8855
- await stream.writeSSE({
8902
+ await writeSSEIfConnected(stream, {
8856
8903
  event: errorEvent.type,
8857
8904
  data: JSON.stringify(errorEvent)
8858
8905
  });
@@ -10875,7 +10922,7 @@ providerAlphaSearchRoutes.post("/", async (c) => {
10875
10922
  body: await c.req.raw.clone().text(),
10876
10923
  provider
10877
10924
  }));
10878
- const upstreamResponse = await providerAlphaSearchRouteDependencies.forwardProviderAlphaSearch(providerConfig, c.req.raw);
10925
+ const upstreamResponse = await providerAlphaSearchRouteDependencies.forwardProviderAlphaSearch(providerConfig, c.req.raw, { clientSignal: c.req.raw.signal });
10879
10926
  await debugJsonAsync(logger$6, "provider.alpha_search.response", async () => ({
10880
10927
  body: await upstreamResponse.clone().text(),
10881
10928
  provider,
@@ -11875,7 +11922,7 @@ async function handleResponsesViaMessages(c, options) {
11875
11922
  debugJson(logger$3, "Translated Responses result:", result);
11876
11923
  if (!translation.messagesPayload.stream) return c.json(result);
11877
11924
  return streamSSE(c, async (stream) => {
11878
- for (const event of responsesResultToStreamEvents(result)) await stream.writeSSE({
11925
+ for (const event of responsesResultToStreamEvents(result)) await writeSSEIfConnected(stream, {
11879
11926
  event: event.type,
11880
11927
  data: JSON.stringify(event)
11881
11928
  });
@@ -11892,7 +11939,7 @@ function streamTranslatedMessagesEvents(c, response, context) {
11892
11939
  return streamSSE(c, async (stream) => {
11893
11940
  for await (const event of translateMessagesStream(events(response), context)) {
11894
11941
  debugJson(logger$3, "Translated Responses stream event:", event);
11895
- await stream.writeSSE({
11942
+ await writeSSEIfConnected(stream, {
11896
11943
  event: event.type,
11897
11944
  data: JSON.stringify(event)
11898
11945
  });
@@ -11943,7 +11990,7 @@ async function handleProviderResponsesForProvider(c, options) {
11943
11990
  });
11944
11991
  const modelConfig = providerConfig.models?.[payload.model];
11945
11992
  if (providerConfig.name === "codex") {
11946
- const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
11993
+ const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl, { clientSignal: c.req.raw.signal });
11947
11994
  const recordUsage = createProviderResponsesUsageRecorder(payload, provider, modelConfig, providerConfig.pricingCurrency);
11948
11995
  if (payload.stream && isResponsesStream(upstreamResponse)) return streamProviderResponses(c, upstreamResponse, {
11949
11996
  normalizeCodex: true,
@@ -11954,10 +12001,10 @@ async function handleProviderResponsesForProvider(c, options) {
11954
12001
  recordUsage(normalizeResponsesUsage(responseBody.usage));
11955
12002
  return c.json(responseBody);
11956
12003
  }
11957
- const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { signal: c.req.raw.signal });
12004
+ const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { clientSignal: c.req.raw.signal });
11958
12005
  if (!upstreamResponse.ok) throw new HTTPError(`Failed to create ${provider} responses`, upstreamResponse);
11959
12006
  const recordUsage = createProviderResponsesUsageRecorder(payload, provider, modelConfig, providerConfig.pricingCurrency);
11960
- if (payload.stream) return streamProviderResponses(c, getResponsesEvents(upstreamResponse, c.req.raw.signal), {
12007
+ if (payload.stream) return streamProviderResponses(c, getResponsesEvents(upstreamResponse), {
11961
12008
  normalizeCodex: false,
11962
12009
  provider,
11963
12010
  recordUsage
@@ -12025,7 +12072,7 @@ const streamProviderResponses = async (c, upstreamResponse, options) => {
12025
12072
  const nextUsage = getResponsesStreamEventUsage(event);
12026
12073
  if (nextUsage) usage = nextUsage;
12027
12074
  }
12028
- await stream.writeSSE({
12075
+ await writeSSEIfConnected(stream, {
12029
12076
  data: responseChunk.data ?? "",
12030
12077
  event: responseChunk.event
12031
12078
  });
@@ -12057,7 +12104,7 @@ const getResponsesStreamEventUsage = (event) => {
12057
12104
  if (event.type === "response.completed" || event.type === "response.failed" || event.type === "response.incomplete") return normalizeResponsesUsage(event.response.usage);
12058
12105
  return null;
12059
12106
  };
12060
- const getResponsesEvents = (response, signal) => createResponsesSafeStream(createResponsesHttpEventStream(response, signal), { signal });
12107
+ const getResponsesEvents = (response) => createResponsesSafeStream(createResponsesHttpEventStream(response));
12061
12108
  //#endregion
12062
12109
  //#region src/routes/provider/responses/route.ts
12063
12110
  const providerResponsesRoutes = new Hono();
@@ -12190,7 +12237,7 @@ const handleResponses = async (c) => {
12190
12237
  subagentMarker,
12191
12238
  requestId,
12192
12239
  sessionId: fallbackSessionId,
12193
- signal: c.req.raw.signal,
12240
+ clientSignal: c.req.raw.signal,
12194
12241
  transport: responsesTransport
12195
12242
  });
12196
12243
  if (isStreamingRequested(payload) && isAsyncIterable(response)) {
@@ -12208,7 +12255,7 @@ const handleResponses = async (c) => {
12208
12255
  total_nano_aiu: normalizeOptionalToken(parsedEvent.copilot_usage?.total_nano_aiu)
12209
12256
  };
12210
12257
  const processedData = fixStreamIds(chunk.data ?? "", chunk.event, idTracker);
12211
- await stream.writeSSE({
12258
+ await writeSSEIfConnected(stream, {
12212
12259
  id: chunk.id,
12213
12260
  event: chunk.event,
12214
12261
  data: processedData
@@ -12443,4 +12490,4 @@ createServer();
12443
12490
  //#endregion
12444
12491
  export { createServer };
12445
12492
 
12446
- //# sourceMappingURL=server-D5XuGc4z.js.map
12493
+ //# sourceMappingURL=server-B4-mT5EU.js.map