@jeffreycao/copilot-api 2.1.4 → 2.1.6
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 +12 -1
- package/README.zh-CN.md +12 -1
- package/dist/{auth-C0aeKq7k.js → auth-DYaGY4fS.js} +3 -3
- package/dist/{auth-C0aeKq7k.js.map → auth-DYaGY4fS.js.map} +1 -1
- package/dist/auth-t5Gi1JB9.js +2 -0
- package/dist/{config-CoMdcHDW.js → config-DMrKDHiF.js} +32 -4
- package/dist/config-DMrKDHiF.js.map +1 -0
- package/dist/{debug-D2giR-Kj.js → debug-2GkXJBt5.js} +2 -2
- package/dist/{debug-D2giR-Kj.js.map → debug-2GkXJBt5.js.map} +1 -1
- package/dist/main.js +3 -3
- package/dist/{models-DUdPhOBN.js → models-Do0TBzAz.js} +2 -2
- package/dist/{models-DUdPhOBN.js.map → models-Do0TBzAz.js.map} +1 -1
- package/dist/{server-BwT9agIL.js → server-GxC8BArQ.js} +221 -98
- package/dist/server-GxC8BArQ.js.map +1 -0
- package/dist/{start-B5CJA1Cx.js → start-B0MTWFyd.js} +6 -6
- package/dist/{start-B5CJA1Cx.js.map → start-B0MTWFyd.js.map} +1 -1
- package/dist/{token-_ZvkUtOA.js → token-DmNSTe37.js} +466 -86
- package/dist/token-DmNSTe37.js.map +1 -0
- package/package.json +1 -1
- package/dist/auth-DH-ThnhJ.js +0 -2
- package/dist/config-CoMdcHDW.js.map +0 -1
- package/dist/server-BwT9agIL.js.map +0 -1
- package/dist/token-_ZvkUtOA.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { C as getClaudeTokenMultiplier, D as
|
|
2
|
-
import { A as buildCodexRequestHeaders, B as
|
|
1
|
+
import { A as isResponsesApiWebSocketEnabled, C as getClaudeTokenMultiplier, D as isAlphaSearchCodexPriorityEnabled, E as getResponsesTransportConfig, M 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, w as getConfig, x as getAnthropicApiKey } from "./config-DMrKDHiF.js";
|
|
2
|
+
import { A as buildCodexRequestHeaders, B as createPooledWebSocketStream, C as compactAutoContinuePromptStarts, D as compactTextOnlyGuard, E as compactSystemPromptStarts, F as createResponsesHttpEventStream, H as state, I as fetchResponsesWithLifecycle, L as createResponsesSafeStream, M as generateTraceId, N as requestContext, P as resolveTraceId$1, R as encodePoolKeyPart, U as HTTPError, V as createWebSocketUrl, W as forwardError, b as prepareInteractionHeaders, c as getUUID, d as isResponsesStream, f as parseUserIdMetadata, g as copilotHeaders, h as copilotBaseUrl, j as forwardCodexResponses, k as CODEX_API_BASE_URL, l as isAsyncIterable, o as generateRequestIdFromPayload, p as getCopilotUsage, r as setupCodexToken, s as getRootSessionId, u as isNullish, v as copilotWebSocketHeaders, w as compactMessageSections, x as prepareMessageProxyHeaders, y as prepareForCompact, z as isTerminalResponsesStreamChunk } from "./token-DmNSTe37.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-
|
|
4
|
+
import { i as toClientModelId, r as normalizeSdkModelId, t as findEndpointModel } from "./models-Do0TBzAz.js";
|
|
5
5
|
import consola from "consola";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import fs, { readFileSync } from "node:fs";
|
|
8
8
|
import fs$1 from "node:fs/promises";
|
|
9
9
|
import path from "node:path";
|
|
10
|
-
import { events } from "fetch-event-stream";
|
|
11
10
|
import { fetch as fetch$1, getGlobalDispatcher } from "undici";
|
|
11
|
+
import { events } from "fetch-event-stream";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { Hono } from "hono";
|
|
14
14
|
import { cors } from "hono/cors";
|
|
@@ -1951,7 +1951,7 @@ const isCopilotQuotaSnapshot = (value) => {
|
|
|
1951
1951
|
};
|
|
1952
1952
|
//#endregion
|
|
1953
1953
|
//#region src/services/copilot/create-responses.ts
|
|
1954
|
-
const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType, transport = "http" }) => {
|
|
1954
|
+
const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType, transport = "http", signal }) => {
|
|
1955
1955
|
if (!state.copilotToken) throw new Error("Copilot token not found");
|
|
1956
1956
|
const headers = {
|
|
1957
1957
|
...copilotHeaders(state, requestId, vision),
|
|
@@ -1964,22 +1964,28 @@ const createResponses = async (payload, { vision, initiator, subagentMarker, req
|
|
|
1964
1964
|
const effectiveTransport = compactType === 1 ? "http" : transport;
|
|
1965
1965
|
if (payload.stream === true && effectiveTransport === "websocket") return createPooledResponsesWebSocketStream(prepareResponsesWebSocketRequest(payload, headers, {
|
|
1966
1966
|
requestId,
|
|
1967
|
+
signal,
|
|
1967
1968
|
subagentMarker
|
|
1968
1969
|
}));
|
|
1969
|
-
return await createHttpResponses(payload, headers);
|
|
1970
|
+
return await createHttpResponses(payload, headers, signal);
|
|
1970
1971
|
};
|
|
1971
|
-
const createHttpResponses = async (payload, headers) => {
|
|
1972
|
-
const
|
|
1972
|
+
const createHttpResponses = async (payload, headers, signal) => {
|
|
1973
|
+
const transportConfig = getResponsesTransportConfig();
|
|
1974
|
+
const response = await fetchResponsesWithLifecycle(`${copilotBaseUrl(state)}/responses`, {
|
|
1973
1975
|
method: "POST",
|
|
1974
1976
|
headers,
|
|
1975
1977
|
body: JSON.stringify(payload)
|
|
1978
|
+
}, {
|
|
1979
|
+
headersTimeoutMs: transportConfig.headersTimeoutMs,
|
|
1980
|
+
signal,
|
|
1981
|
+
streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
|
|
1976
1982
|
});
|
|
1977
1983
|
logCopilotRateLimits(response.headers);
|
|
1978
1984
|
if (!response.ok) {
|
|
1979
1985
|
consola.error("Failed to create responses", response);
|
|
1980
1986
|
throw new HTTPError("Failed to create responses", response);
|
|
1981
1987
|
}
|
|
1982
|
-
if (payload.stream) return
|
|
1988
|
+
if (payload.stream) return createResponsesSafeStream(createResponsesHttpEventStream(response, signal), { signal });
|
|
1983
1989
|
return await response.json();
|
|
1984
1990
|
};
|
|
1985
1991
|
const prepareResponsesWebSocketRequest = (payload, preparedHeaders, options) => {
|
|
@@ -1988,6 +1994,7 @@ const prepareResponsesWebSocketRequest = (payload, preparedHeaders, options) =>
|
|
|
1988
1994
|
headers: copilotWebSocketHeaders(preparedHeaders),
|
|
1989
1995
|
poolKey: buildResponsesWebSocketPoolKey(payload, options),
|
|
1990
1996
|
payload: buildResponsesWebSocketPayload(payload, initiator),
|
|
1997
|
+
signal: options.signal,
|
|
1991
1998
|
url: buildResponsesWebSocketUrl(copilotBaseUrl(state))
|
|
1992
1999
|
};
|
|
1993
2000
|
};
|
|
@@ -2008,13 +2015,21 @@ const buildResponsesWebSocketPoolKey = (payload, { requestId, subagentMarker })
|
|
|
2008
2015
|
const getResponsesWebSocketInitiator = (preparedHeaders) => {
|
|
2009
2016
|
return getHeaderValue(preparedHeaders, "x-initiator")?.toLowerCase() === "agent" ? "agent" : "user";
|
|
2010
2017
|
};
|
|
2011
|
-
const createPooledResponsesWebSocketStream = (request) =>
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
+
const createPooledResponsesWebSocketStream = (request) => {
|
|
2019
|
+
const transportConfig = getResponsesTransportConfig();
|
|
2020
|
+
return createResponsesSafeStream(createPooledWebSocketStream(request, {
|
|
2021
|
+
createChunk: createResponsesWebSocketStreamChunk,
|
|
2022
|
+
maxBufferedBytes: transportConfig.websocketMaxBufferedBytes,
|
|
2023
|
+
maxBufferedMessages: transportConfig.websocketMaxBufferedMessages,
|
|
2024
|
+
isTerminalChunk: isTerminalResponsesStreamChunk,
|
|
2025
|
+
openErrorMessage: "Failed to create responses websocket",
|
|
2026
|
+
openTimeoutMs: transportConfig.websocketOpenTimeoutMs,
|
|
2027
|
+
poolIdleTimeoutMs: transportConfig.websocketPoolIdleTimeoutMs,
|
|
2028
|
+
streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs,
|
|
2029
|
+
streamErrorMessage: "Responses websocket stream error",
|
|
2030
|
+
terminalChunkMissingMessage: "Responses websocket ended without a terminal response"
|
|
2031
|
+
}), { signal: request.signal });
|
|
2032
|
+
};
|
|
2018
2033
|
const buildResponsesWebSocketPayload = (payload, initiator) => {
|
|
2019
2034
|
const websocketPayload = {
|
|
2020
2035
|
...payload,
|
|
@@ -2127,12 +2142,17 @@ async function forwardProviderChatCompletions(providerConfig, payload, requestHe
|
|
|
2127
2142
|
body: JSON.stringify(payload)
|
|
2128
2143
|
});
|
|
2129
2144
|
}
|
|
2130
|
-
async function forwardProviderResponses(providerConfig, payload, requestHeaders) {
|
|
2145
|
+
async function forwardProviderResponses(providerConfig, payload, requestHeaders, options = {}) {
|
|
2131
2146
|
consola.log(`<-- model: ${payload.model}`);
|
|
2132
|
-
|
|
2147
|
+
const transportConfig = getResponsesTransportConfig();
|
|
2148
|
+
return await fetchResponsesWithLifecycle(`${providerConfig.baseUrl}/v1/responses`, {
|
|
2133
2149
|
method: "POST",
|
|
2134
2150
|
headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
|
|
2135
2151
|
body: JSON.stringify(payload)
|
|
2152
|
+
}, {
|
|
2153
|
+
headersTimeoutMs: transportConfig.headersTimeoutMs,
|
|
2154
|
+
signal: options.signal,
|
|
2155
|
+
streamInactivityTimeoutMs: transportConfig.streamInactivityTimeoutMs
|
|
2136
2156
|
});
|
|
2137
2157
|
}
|
|
2138
2158
|
const PROVIDER_MODELS_TIMEOUT_MS = 15e3;
|
|
@@ -2208,6 +2228,8 @@ const alphaSearchResponsesDependencies = {
|
|
|
2208
2228
|
findEndpointModel,
|
|
2209
2229
|
now: () => Date.now(),
|
|
2210
2230
|
resolveMappedModel,
|
|
2231
|
+
resolveEffectiveProviderType,
|
|
2232
|
+
resolveProviderConfig,
|
|
2211
2233
|
createUsageRecorder: (model, sessionId) => createCopilotTokenUsageRecorder({
|
|
2212
2234
|
endpoint: "responses",
|
|
2213
2235
|
fallbackSessionId: sessionId,
|
|
@@ -2504,12 +2526,12 @@ function shouldExecuteRemoteOperations(request, state) {
|
|
|
2504
2526
|
async function resolveRemoteModel(c, request, provider) {
|
|
2505
2527
|
const model = provider ? request.model : alphaSearchResponsesDependencies.resolveMappedModel(request.model);
|
|
2506
2528
|
if (provider) {
|
|
2507
|
-
const providerConfig = await resolveProviderConfig(provider);
|
|
2529
|
+
const providerConfig = await alphaSearchResponsesDependencies.resolveProviderConfig(provider);
|
|
2508
2530
|
if (!providerConfig) return c.json({ error: {
|
|
2509
2531
|
message: `Provider '${provider}' not found or disabled`,
|
|
2510
2532
|
type: "invalid_request_error"
|
|
2511
2533
|
} }, 404);
|
|
2512
|
-
if (resolveEffectiveProviderType(providerConfig, model) !== "openai-responses") return invalidRequest$1(c, `Provider '${provider}' does not support the /v1/responses endpoint required for alpha search`);
|
|
2534
|
+
if (alphaSearchResponsesDependencies.resolveEffectiveProviderType(providerConfig, model) !== "openai-responses") return invalidRequest$1(c, `Provider '${provider}' does not support the /v1/responses endpoint required for alpha search`);
|
|
2513
2535
|
return {
|
|
2514
2536
|
model,
|
|
2515
2537
|
providerConfig
|
|
@@ -2541,7 +2563,7 @@ async function requestProviderSearch(c, providerConfig, payload, model, sessionI
|
|
|
2541
2563
|
payload,
|
|
2542
2564
|
provider: providerConfig.name
|
|
2543
2565
|
});
|
|
2544
|
-
const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers);
|
|
2566
|
+
const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { signal: c.req.raw.signal });
|
|
2545
2567
|
if (!upstreamResponse.ok) throw new HTTPError(`Failed to create ${providerConfig.name} responses for alpha search`, upstreamResponse);
|
|
2546
2568
|
const result = await upstreamResponse.json();
|
|
2547
2569
|
debugJson(logger$16, "Alpha search provider Responses result:", {
|
|
@@ -2559,14 +2581,15 @@ async function requestProviderSearch(c, providerConfig, payload, model, sessionI
|
|
|
2559
2581
|
})(normalizeResponsesUsage(result.usage));
|
|
2560
2582
|
return result;
|
|
2561
2583
|
}
|
|
2562
|
-
async function requestCopilotSearch(payload, model, requestId, sessionId) {
|
|
2584
|
+
async function requestCopilotSearch(payload, model, requestId, sessionId, signal) {
|
|
2563
2585
|
debugJson(logger$16, "Alpha search Copilot Responses request:", payload);
|
|
2564
2586
|
const result = await alphaSearchResponsesDependencies.createResponses(payload, {
|
|
2565
2587
|
vision: false,
|
|
2566
2588
|
initiator: "agent",
|
|
2567
2589
|
transport: "http",
|
|
2568
2590
|
requestId,
|
|
2569
|
-
sessionId
|
|
2591
|
+
sessionId,
|
|
2592
|
+
signal
|
|
2570
2593
|
});
|
|
2571
2594
|
debugJson(logger$16, "Alpha search Copilot Responses result:", result);
|
|
2572
2595
|
alphaSearchResponsesDependencies.createUsageRecorder(model, sessionId)({
|
|
@@ -2581,7 +2604,7 @@ async function requestRemoteSearch(c, request, state, target) {
|
|
|
2581
2604
|
const requestId = generateRequestIdFromPayload({ messages: `${state.turn.number}:${instruction}` }, sessionId);
|
|
2582
2605
|
const payload = createRemoteResponsesPayload(request, target.model, instruction);
|
|
2583
2606
|
if (target.providerConfig) return await requestProviderSearch(c, target.providerConfig, payload, target.model, sessionId);
|
|
2584
|
-
return await requestCopilotSearch(payload, target.model, requestId, sessionId);
|
|
2607
|
+
return await requestCopilotSearch(payload, target.model, requestId, sessionId, c.req.raw.signal);
|
|
2585
2608
|
}
|
|
2586
2609
|
function getActiveRemoteReferences(session, references) {
|
|
2587
2610
|
return references.filter((reference) => session.referencesById.get(reference.result.ref_id) === reference);
|
|
@@ -2685,6 +2708,16 @@ async function forwardCodexAlphaSearch(request) {
|
|
|
2685
2708
|
//#region src/routes/alpha-search/route.ts
|
|
2686
2709
|
const logger$15 = createHandlerLogger("alpha-search-handler");
|
|
2687
2710
|
const alphaSearchRoutes = new Hono();
|
|
2711
|
+
const alphaSearchRouteDependencies = {
|
|
2712
|
+
findEndpointModel,
|
|
2713
|
+
forwardCodexAlphaSearch,
|
|
2714
|
+
getAlphaSearchModel,
|
|
2715
|
+
handleAlphaSearchResponses,
|
|
2716
|
+
isAlphaSearchCodexPriorityEnabled,
|
|
2717
|
+
resolveEffectiveProviderType,
|
|
2718
|
+
resolveMappedModel,
|
|
2719
|
+
resolveProviderConfig
|
|
2720
|
+
};
|
|
2688
2721
|
function parseDebugBody(body) {
|
|
2689
2722
|
try {
|
|
2690
2723
|
return JSON.parse(body);
|
|
@@ -2694,7 +2727,7 @@ function parseDebugBody(body) {
|
|
|
2694
2727
|
}
|
|
2695
2728
|
async function forwardCodexAlphaSearchRequest(request) {
|
|
2696
2729
|
await debugJsonAsync(logger$15, "alpha_search.codex.request", async () => ({ body: parseDebugBody(await request.clone().text()) }));
|
|
2697
|
-
const upstreamResponse = await forwardCodexAlphaSearch(request);
|
|
2730
|
+
const upstreamResponse = await alphaSearchRouteDependencies.forwardCodexAlphaSearch(request);
|
|
2698
2731
|
await debugJsonAsync(logger$15, "alpha_search.codex.response", async () => ({
|
|
2699
2732
|
body: parseDebugBody(await upstreamResponse.clone().text()),
|
|
2700
2733
|
statusCode: upstreamResponse.status
|
|
@@ -2710,7 +2743,7 @@ function createAlphaSearchRequest(request, payload) {
|
|
|
2710
2743
|
});
|
|
2711
2744
|
}
|
|
2712
2745
|
async function handleCodexRequest(c, request, resolvedProviderConfig) {
|
|
2713
|
-
if (!(resolvedProviderConfig ?? await resolveProviderConfig("codex"))) return c.json({ error: {
|
|
2746
|
+
if (!(resolvedProviderConfig ?? await alphaSearchRouteDependencies.resolveProviderConfig("codex"))) return c.json({ error: {
|
|
2714
2747
|
message: "Provider 'codex' not found or disabled",
|
|
2715
2748
|
type: "invalid_request_error"
|
|
2716
2749
|
} }, 404);
|
|
@@ -2742,7 +2775,7 @@ async function handleAlphaSearchRequest(c, resolvedProviderConfig) {
|
|
|
2742
2775
|
const payload = await parseAlphaSearchBody(c);
|
|
2743
2776
|
if (payload instanceof Response) return payload;
|
|
2744
2777
|
const requestedModel = payload.model;
|
|
2745
|
-
payload.model = resolveMappedModel(requestedModel);
|
|
2778
|
+
payload.model = alphaSearchRouteDependencies.resolveMappedModel(requestedModel);
|
|
2746
2779
|
if (payload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
|
|
2747
2780
|
const resolvedRequestedModel = payload.model;
|
|
2748
2781
|
let providerModelAlias = parseProviderModelAlias(payload.model);
|
|
@@ -2750,17 +2783,17 @@ async function handleAlphaSearchRequest(c, resolvedProviderConfig) {
|
|
|
2750
2783
|
payload.model = providerModelAlias.model;
|
|
2751
2784
|
if (providerModelAlias.provider === "codex") return await handleCodexRequest(c, createAlphaSearchRequest(c.req.raw, payload));
|
|
2752
2785
|
}
|
|
2753
|
-
if (isAlphaSearchCodexPriorityEnabled()) {
|
|
2754
|
-
if (await resolveProviderConfig("codex")) {
|
|
2786
|
+
if (alphaSearchRouteDependencies.isAlphaSearchCodexPriorityEnabled()) {
|
|
2787
|
+
if (await alphaSearchRouteDependencies.resolveProviderConfig("codex")) {
|
|
2755
2788
|
if (!payload.model.startsWith("gpt")) payload.model = "gpt-5.6-luna";
|
|
2756
2789
|
return await forwardCodexAlphaSearchRequest(createAlphaSearchRequest(c.req.raw, payload));
|
|
2757
2790
|
}
|
|
2758
2791
|
}
|
|
2759
2792
|
const messagesBackedModel = await isMessagesBackedModel(resolvedRequestedModel);
|
|
2760
2793
|
if (messagesBackedModel) {
|
|
2761
|
-
const searchModel = getAlphaSearchModel();
|
|
2794
|
+
const searchModel = alphaSearchRouteDependencies.getAlphaSearchModel();
|
|
2762
2795
|
if (!searchModel) return invalidRequest(c, "alphaSearchModel is disabled; Messages-backed Codex models require a native Responses search model");
|
|
2763
|
-
const resolvedSearchModel = resolveMappedModel(searchModel);
|
|
2796
|
+
const resolvedSearchModel = alphaSearchRouteDependencies.resolveMappedModel(searchModel);
|
|
2764
2797
|
if (!await isNativeResponsesModel(resolvedSearchModel)) return invalidRequest(c, `Configured alphaSearchModel '${searchModel}' does not support the Responses endpoint required for alpha search`);
|
|
2765
2798
|
consola.debug(`Redirected alpha search model: ${resolvedRequestedModel} -> ${resolvedSearchModel}`);
|
|
2766
2799
|
payload.model = resolvedSearchModel;
|
|
@@ -2771,11 +2804,11 @@ async function handleAlphaSearchRequest(c, resolvedProviderConfig) {
|
|
|
2771
2804
|
}
|
|
2772
2805
|
}
|
|
2773
2806
|
const fallbackRequestedModel = messagesBackedModel ? payload.model : requestedModel;
|
|
2774
|
-
if (providerModelAlias) return await handleAlphaSearchResponses(c, {
|
|
2807
|
+
if (providerModelAlias) return await alphaSearchRouteDependencies.handleAlphaSearchResponses(c, {
|
|
2775
2808
|
provider: providerModelAlias.provider,
|
|
2776
2809
|
request: payload
|
|
2777
2810
|
});
|
|
2778
|
-
return await handleAlphaSearchResponses(c, { request: {
|
|
2811
|
+
return await alphaSearchRouteDependencies.handleAlphaSearchResponses(c, { request: {
|
|
2779
2812
|
...payload,
|
|
2780
2813
|
model: fallbackRequestedModel
|
|
2781
2814
|
} });
|
|
@@ -2783,21 +2816,21 @@ async function handleAlphaSearchRequest(c, resolvedProviderConfig) {
|
|
|
2783
2816
|
async function isMessagesBackedModel(model) {
|
|
2784
2817
|
const providerAlias = parseProviderModelAlias(model);
|
|
2785
2818
|
if (providerAlias) {
|
|
2786
|
-
const providerConfig = await resolveProviderConfig(providerAlias.provider);
|
|
2819
|
+
const providerConfig = await alphaSearchRouteDependencies.resolveProviderConfig(providerAlias.provider);
|
|
2787
2820
|
if (!providerConfig) return false;
|
|
2788
|
-
const effectiveType = resolveEffectiveProviderType(providerConfig, providerAlias.model);
|
|
2821
|
+
const effectiveType = alphaSearchRouteDependencies.resolveEffectiveProviderType(providerConfig, providerAlias.model);
|
|
2789
2822
|
return effectiveType === "anthropic" || effectiveType === "openai-compatible";
|
|
2790
2823
|
}
|
|
2791
|
-
const endpoints = findEndpointModel(model)?.supported_endpoints ?? [];
|
|
2824
|
+
const endpoints = alphaSearchRouteDependencies.findEndpointModel(model)?.supported_endpoints ?? [];
|
|
2792
2825
|
return (endpoints.includes("/v1/messages") || endpoints.includes("/chat/completions")) && !endpoints.includes("/responses") && !endpoints.includes("ws:/responses");
|
|
2793
2826
|
}
|
|
2794
2827
|
async function isNativeResponsesModel(model) {
|
|
2795
2828
|
const providerAlias = parseProviderModelAlias(model);
|
|
2796
2829
|
if (providerAlias) {
|
|
2797
|
-
const providerConfig = await resolveProviderConfig(providerAlias.provider);
|
|
2798
|
-
return providerConfig !== null && resolveEffectiveProviderType(providerConfig, providerAlias.model) === "openai-responses";
|
|
2830
|
+
const providerConfig = await alphaSearchRouteDependencies.resolveProviderConfig(providerAlias.provider);
|
|
2831
|
+
return providerConfig !== null && alphaSearchRouteDependencies.resolveEffectiveProviderType(providerConfig, providerAlias.model) === "openai-responses";
|
|
2799
2832
|
}
|
|
2800
|
-
const endpoints = findEndpointModel(model)?.supported_endpoints ?? [];
|
|
2833
|
+
const endpoints = alphaSearchRouteDependencies.findEndpointModel(model)?.supported_endpoints ?? [];
|
|
2801
2834
|
return endpoints.includes("/responses") || endpoints.includes("ws:/responses");
|
|
2802
2835
|
}
|
|
2803
2836
|
alphaSearchRoutes.post("/", async (c) => {
|
|
@@ -5844,6 +5877,21 @@ const REDACTED_IMAGE_PLACEHOLDER_DATA_URL = "data:image/png;base64," + [
|
|
|
5844
5877
|
"ucSQ4s8JkKDDIYr3IuR8vEWgqroKP9b1bYKk2wfgeVmqATQLXdXamsXdEKkz3QXEEeTTuWWImMhW6qci94/+hwSVf99HqVoD",
|
|
5845
5878
|
"OAuj2SEAAAAASUVORK5CYII="
|
|
5846
5879
|
].join("");
|
|
5880
|
+
const COPILOT_UNSUPPORTED_INPUT_ITEM_FIELDS = ["internal_chat_message_metadata_passthrough"];
|
|
5881
|
+
const sanitizeUnsupportedInputFields = (payload) => {
|
|
5882
|
+
if (!Array.isArray(payload.input)) return 0;
|
|
5883
|
+
let removedFieldCount = 0;
|
|
5884
|
+
for (const item of payload.input) {
|
|
5885
|
+
if (typeof item !== "object" || item === null) continue;
|
|
5886
|
+
const record = item;
|
|
5887
|
+
for (const field of COPILOT_UNSUPPORTED_INPUT_ITEM_FIELDS) {
|
|
5888
|
+
if (!Object.hasOwn(record, field)) continue;
|
|
5889
|
+
delete record[field];
|
|
5890
|
+
removedFieldCount += 1;
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
return removedFieldCount;
|
|
5894
|
+
};
|
|
5847
5895
|
const sanitizeOversizedInputImages = (payload, maxPromptImageSize) => {
|
|
5848
5896
|
const limit = typeof maxPromptImageSize === "number" && maxPromptImageSize > 0 ? maxPromptImageSize : void 0;
|
|
5849
5897
|
if (limit === void 0 || !Array.isArray(payload.input)) return 0;
|
|
@@ -6143,6 +6191,7 @@ const handleWebSearchViaResponses = async (c, payload, options) => {
|
|
|
6143
6191
|
subagentMarker: options.subagentMarker,
|
|
6144
6192
|
requestId: options.requestId,
|
|
6145
6193
|
sessionId: options.sessionId,
|
|
6194
|
+
signal: c.req?.raw?.signal,
|
|
6146
6195
|
compactType: options.compactType
|
|
6147
6196
|
});
|
|
6148
6197
|
const result = isWebSearchResponsesStream(upstreamResult) ? await collectResponsesStreamResult({
|
|
@@ -6254,49 +6303,101 @@ const CODEX_MODELS = [
|
|
|
6254
6303
|
id: "gpt-5.3-codex-spark",
|
|
6255
6304
|
input: ["text"],
|
|
6256
6305
|
maxTokens: 32e3,
|
|
6257
|
-
name: "GPT-5.3 Codex Spark"
|
|
6306
|
+
name: "GPT-5.3 Codex Spark",
|
|
6307
|
+
reasoningEfforts: [
|
|
6308
|
+
"minimal",
|
|
6309
|
+
"low",
|
|
6310
|
+
"medium",
|
|
6311
|
+
"high",
|
|
6312
|
+
"xhigh"
|
|
6313
|
+
]
|
|
6258
6314
|
},
|
|
6259
6315
|
{
|
|
6260
6316
|
contextWindow: 4e5,
|
|
6261
6317
|
id: "gpt-5.4",
|
|
6262
6318
|
input: ["text", "image"],
|
|
6263
6319
|
maxTokens: 128e3,
|
|
6264
|
-
name: "GPT-5.4"
|
|
6320
|
+
name: "GPT-5.4",
|
|
6321
|
+
reasoningEfforts: [
|
|
6322
|
+
"minimal",
|
|
6323
|
+
"low",
|
|
6324
|
+
"medium",
|
|
6325
|
+
"high",
|
|
6326
|
+
"xhigh"
|
|
6327
|
+
]
|
|
6265
6328
|
},
|
|
6266
6329
|
{
|
|
6267
6330
|
contextWindow: 4e5,
|
|
6268
6331
|
id: "gpt-5.4-mini",
|
|
6269
6332
|
input: ["text", "image"],
|
|
6270
6333
|
maxTokens: 128e3,
|
|
6271
|
-
name: "GPT-5.4 mini"
|
|
6334
|
+
name: "GPT-5.4 mini",
|
|
6335
|
+
reasoningEfforts: [
|
|
6336
|
+
"minimal",
|
|
6337
|
+
"low",
|
|
6338
|
+
"medium",
|
|
6339
|
+
"high",
|
|
6340
|
+
"xhigh"
|
|
6341
|
+
]
|
|
6272
6342
|
},
|
|
6273
6343
|
{
|
|
6274
6344
|
contextWindow: 272e3,
|
|
6275
6345
|
id: "gpt-5.5",
|
|
6276
6346
|
input: ["text", "image"],
|
|
6277
6347
|
maxTokens: 128e3,
|
|
6278
|
-
name: "GPT-5.5"
|
|
6348
|
+
name: "GPT-5.5",
|
|
6349
|
+
reasoningEfforts: [
|
|
6350
|
+
"minimal",
|
|
6351
|
+
"low",
|
|
6352
|
+
"medium",
|
|
6353
|
+
"high",
|
|
6354
|
+
"xhigh"
|
|
6355
|
+
]
|
|
6279
6356
|
},
|
|
6280
6357
|
{
|
|
6281
|
-
contextWindow:
|
|
6358
|
+
contextWindow: 272e3,
|
|
6282
6359
|
id: "gpt-5.6-sol",
|
|
6283
6360
|
input: ["text", "image"],
|
|
6284
6361
|
maxTokens: 128e3,
|
|
6285
|
-
name: "GPT-5.6 Sol"
|
|
6362
|
+
name: "GPT-5.6 Sol",
|
|
6363
|
+
reasoningEfforts: [
|
|
6364
|
+
"none",
|
|
6365
|
+
"low",
|
|
6366
|
+
"medium",
|
|
6367
|
+
"high",
|
|
6368
|
+
"xhigh",
|
|
6369
|
+
"max"
|
|
6370
|
+
]
|
|
6286
6371
|
},
|
|
6287
6372
|
{
|
|
6288
|
-
contextWindow:
|
|
6373
|
+
contextWindow: 272e3,
|
|
6289
6374
|
id: "gpt-5.6-terra",
|
|
6290
6375
|
input: ["text", "image"],
|
|
6291
6376
|
maxTokens: 128e3,
|
|
6292
|
-
name: "GPT-5.6 Terra"
|
|
6377
|
+
name: "GPT-5.6 Terra",
|
|
6378
|
+
reasoningEfforts: [
|
|
6379
|
+
"none",
|
|
6380
|
+
"low",
|
|
6381
|
+
"medium",
|
|
6382
|
+
"high",
|
|
6383
|
+
"xhigh",
|
|
6384
|
+
"max"
|
|
6385
|
+
]
|
|
6293
6386
|
},
|
|
6294
6387
|
{
|
|
6295
|
-
contextWindow:
|
|
6388
|
+
contextWindow: 272e3,
|
|
6296
6389
|
id: "gpt-5.6-luna",
|
|
6297
6390
|
input: ["text", "image"],
|
|
6298
6391
|
maxTokens: 128e3,
|
|
6299
|
-
name: "GPT-5.6 Luna"
|
|
6392
|
+
name: "GPT-5.6 Luna",
|
|
6393
|
+
reasoningEfforts: [
|
|
6394
|
+
"none",
|
|
6395
|
+
"low",
|
|
6396
|
+
"medium",
|
|
6397
|
+
"high",
|
|
6398
|
+
"xhigh",
|
|
6399
|
+
"max"
|
|
6400
|
+
]
|
|
6300
6401
|
}
|
|
6301
6402
|
];
|
|
6302
6403
|
const CODEX_MODELS_URL = `${CODEX_API_BASE_URL}/codex/models`;
|
|
@@ -6329,13 +6430,7 @@ function normalizeCodexModel(model) {
|
|
|
6329
6430
|
supports: {
|
|
6330
6431
|
adaptive_thinking: true,
|
|
6331
6432
|
parallel_tool_calls: true,
|
|
6332
|
-
reasoning_effort:
|
|
6333
|
-
"minimal",
|
|
6334
|
-
"low",
|
|
6335
|
-
"medium",
|
|
6336
|
-
"high",
|
|
6337
|
-
"xhigh"
|
|
6338
|
-
],
|
|
6433
|
+
reasoning_effort: model.reasoningEfforts,
|
|
6339
6434
|
streaming: true,
|
|
6340
6435
|
tool_calls: true,
|
|
6341
6436
|
vision: supportsVision
|
|
@@ -6362,6 +6457,7 @@ function getModels() {
|
|
|
6362
6457
|
//#endregion
|
|
6363
6458
|
//#region src/routes/provider/messages/handler.ts
|
|
6364
6459
|
const logger$10 = createHandlerLogger("provider-messages-handler");
|
|
6460
|
+
const providerMessagesHandlerDependencies = { resolveProviderConfig };
|
|
6365
6461
|
async function handleProviderMessages(c) {
|
|
6366
6462
|
const provider = c.req.param("provider");
|
|
6367
6463
|
const payload = await c.req.json();
|
|
@@ -6377,7 +6473,7 @@ async function handleProviderMessages(c) {
|
|
|
6377
6473
|
}
|
|
6378
6474
|
async function handleProviderMessagesForProvider(c, options) {
|
|
6379
6475
|
const { payload, provider, usageEndpoint } = options;
|
|
6380
|
-
const providerConfig = await resolveProviderConfig(provider);
|
|
6476
|
+
const providerConfig = await providerMessagesHandlerDependencies.resolveProviderConfig(provider);
|
|
6381
6477
|
if (!providerConfig) return c.json({ error: {
|
|
6382
6478
|
message: `Provider '${provider}' not found or disabled`,
|
|
6383
6479
|
type: "invalid_request_error"
|
|
@@ -6468,7 +6564,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
6468
6564
|
provider
|
|
6469
6565
|
});
|
|
6470
6566
|
if (providerConfig.name === "codex") {
|
|
6471
|
-
const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl);
|
|
6567
|
+
const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
|
|
6472
6568
|
if (isResponsesStream(upstreamResponse)) return respondWebSearchProviderMessagesJson(c, {
|
|
6473
6569
|
body: await collectResponsesStreamResult({
|
|
6474
6570
|
errorMessagePrefix: `${provider} web search responses stream`,
|
|
@@ -6491,7 +6587,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
6491
6587
|
usageEndpoint
|
|
6492
6588
|
});
|
|
6493
6589
|
}
|
|
6494
|
-
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
6590
|
+
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { signal: c.req.raw.signal });
|
|
6495
6591
|
if (!upstreamResponse.ok) {
|
|
6496
6592
|
logger$10.error("Failed to create provider web search responses", {
|
|
6497
6593
|
provider,
|
|
@@ -6503,7 +6599,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
6503
6599
|
body: await collectResponsesStreamResult({
|
|
6504
6600
|
errorMessagePrefix: `${provider} web search responses stream`,
|
|
6505
6601
|
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
6506
|
-
upstreamResponse:
|
|
6602
|
+
upstreamResponse: createResponsesHttpEventStream(upstreamResponse, c.req.raw.signal),
|
|
6507
6603
|
logger: logger$10
|
|
6508
6604
|
}),
|
|
6509
6605
|
modelConfig,
|
|
@@ -6533,7 +6629,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
6533
6629
|
provider
|
|
6534
6630
|
});
|
|
6535
6631
|
if (providerConfig.name === "codex") {
|
|
6536
|
-
const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl);
|
|
6632
|
+
const upstreamResponse = await forwardCodexResponses(responsesPayload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
|
|
6537
6633
|
if (isResponsesStream(upstreamResponse)) {
|
|
6538
6634
|
if (wantsStream) return streamResponsesProviderMessages({
|
|
6539
6635
|
c,
|
|
@@ -6570,7 +6666,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
6570
6666
|
usageEndpoint
|
|
6571
6667
|
});
|
|
6572
6668
|
}
|
|
6573
|
-
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
6669
|
+
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers, { signal: c.req.raw.signal });
|
|
6574
6670
|
if (!upstreamResponse.ok) {
|
|
6575
6671
|
logger$10.error("Failed to create provider responses", upstreamResponse);
|
|
6576
6672
|
throw new HTTPError("Failed to create provider responses", upstreamResponse);
|
|
@@ -6582,7 +6678,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
6582
6678
|
pricingCurrency: providerConfig.pricingCurrency,
|
|
6583
6679
|
provider,
|
|
6584
6680
|
providerConfig,
|
|
6585
|
-
upstreamResponse:
|
|
6681
|
+
upstreamResponse: createResponsesSafeStream(createResponsesHttpEventStream(upstreamResponse, c.req.raw.signal), { signal: c.req.raw.signal }),
|
|
6586
6682
|
usageEndpoint
|
|
6587
6683
|
});
|
|
6588
6684
|
return respondResponsesProviderMessagesJson(c, {
|
|
@@ -7102,6 +7198,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
7102
7198
|
const response = await messagesApiFlowDependencies.createResponses(responsesPayload, {
|
|
7103
7199
|
vision,
|
|
7104
7200
|
initiator,
|
|
7201
|
+
signal: c.req?.raw?.signal,
|
|
7105
7202
|
transport,
|
|
7106
7203
|
...requestOptions
|
|
7107
7204
|
});
|
|
@@ -7993,15 +8090,20 @@ function getCopilotCodexCandidates() {
|
|
|
7993
8090
|
function isCopilotCodexCandidate(model) {
|
|
7994
8091
|
return (model.supported_endpoints ?? []).some((endpoint) => endpoint === MESSAGES_ENDPOINT || endpoint === CHAT_COMPLETIONS_ENDPOINT || RESPONSES_ENDPOINTS.has(endpoint)) && model.capabilities.supports.tool_calls !== false;
|
|
7995
8092
|
}
|
|
8093
|
+
function describeCopilotAdapter(model) {
|
|
8094
|
+
const supportsResponses = model.supported_endpoints?.some((endpoint) => RESPONSES_ENDPOINTS.has(endpoint));
|
|
8095
|
+
if (model.id.startsWith("gpt") && supportsResponses) return `${model.name} through the Copilot Responses API.`;
|
|
8096
|
+
if (model.supported_endpoints?.includes(MESSAGES_ENDPOINT)) return `${model.name} through the Copilot Messages adapter.`;
|
|
8097
|
+
if (supportsResponses) return `${model.name} through the Copilot Messages-to-Responses adapter.`;
|
|
8098
|
+
return `${model.name} through the Copilot Messages-to-Chat adapter.`;
|
|
8099
|
+
}
|
|
7996
8100
|
function createCopilotCodexCandidate(model) {
|
|
7997
8101
|
const reasoningEfforts = normalizeReasoningEfforts(model.capabilities.supports.reasoning_effort);
|
|
7998
|
-
const usesNativeResponses = model.supported_endpoints?.some((endpoint) => RESPONSES_ENDPOINTS.has(endpoint));
|
|
7999
|
-
const usesNativeMessages = model.supported_endpoints?.includes(MESSAGES_ENDPOINT);
|
|
8000
8102
|
return {
|
|
8001
8103
|
slug: toClientModelId(model.id),
|
|
8002
8104
|
displayName: model.name,
|
|
8003
|
-
description:
|
|
8004
|
-
contextWindow: positiveNumber(model.capabilities.limits.
|
|
8105
|
+
description: describeCopilotAdapter(model),
|
|
8106
|
+
contextWindow: positiveNumber(model.capabilities.limits.max_prompt_tokens, 256e3),
|
|
8005
8107
|
maxOutputTokens: positiveNumber(model.capabilities.limits.max_output_tokens, 32e3),
|
|
8006
8108
|
inputModalities: model.capabilities.supports.vision ? ["text", "image"] : ["text"],
|
|
8007
8109
|
reasoningEfforts,
|
|
@@ -8080,15 +8182,16 @@ function normalizeInputModalities(value) {
|
|
|
8080
8182
|
if (!Array.isArray(value)) return [];
|
|
8081
8183
|
return [...new Set(value.filter((modality) => modality === "text" || modality === "image"))];
|
|
8082
8184
|
}
|
|
8083
|
-
function
|
|
8084
|
-
if (configuredModalities.length > 0) return configuredModalities;
|
|
8085
|
-
if (providerName === "kimi") {
|
|
8086
|
-
const modalities = remoteModalities.length > 0 ? remoteModalities : builtinModalities.length > 0 ? builtinModalities : ["text"];
|
|
8087
|
-
return [...new Set([...modalities, "image"])];
|
|
8088
|
-
}
|
|
8185
|
+
function fallbackModalities(remoteModalities, builtinModalities) {
|
|
8089
8186
|
if (remoteModalities.length > 0) return remoteModalities;
|
|
8090
8187
|
return builtinModalities.length > 0 ? builtinModalities : ["text"];
|
|
8091
8188
|
}
|
|
8189
|
+
function resolveInputModalities(providerName, configuredModalities, remoteModalities, builtinModalities) {
|
|
8190
|
+
if (configuredModalities.length > 0) return configuredModalities;
|
|
8191
|
+
const modalities = fallbackModalities(remoteModalities, builtinModalities);
|
|
8192
|
+
if (providerName === "kimi") return [...new Set([...modalities, "image"])];
|
|
8193
|
+
return modalities;
|
|
8194
|
+
}
|
|
8092
8195
|
function selectDefaultReasoningEffort(efforts, configured) {
|
|
8093
8196
|
if (configured && efforts.includes(configured)) return configured;
|
|
8094
8197
|
if (efforts.includes("max")) return "max";
|
|
@@ -8128,26 +8231,32 @@ modelRoutes.get("/", async (c) => {
|
|
|
8128
8231
|
//#region src/routes/provider/alpha-search/route.ts
|
|
8129
8232
|
const logger$6 = createHandlerLogger("provider-alpha-search-handler");
|
|
8130
8233
|
const providerAlphaSearchRoutes = new Hono();
|
|
8234
|
+
const providerAlphaSearchRouteDependencies = {
|
|
8235
|
+
createProviderProxyResponse,
|
|
8236
|
+
forwardProviderAlphaSearch,
|
|
8237
|
+
handleAlphaSearchRequest,
|
|
8238
|
+
resolveProviderConfig
|
|
8239
|
+
};
|
|
8131
8240
|
providerAlphaSearchRoutes.post("/", async (c) => {
|
|
8132
8241
|
const provider = c.req.param("provider") ?? "";
|
|
8133
8242
|
try {
|
|
8134
|
-
const providerConfig = await resolveProviderConfig(provider);
|
|
8243
|
+
const providerConfig = await providerAlphaSearchRouteDependencies.resolveProviderConfig(provider);
|
|
8135
8244
|
if (!providerConfig) return c.json({ error: {
|
|
8136
8245
|
message: `Provider '${provider}' not found or disabled`,
|
|
8137
8246
|
type: "invalid_request_error"
|
|
8138
8247
|
} }, 404);
|
|
8139
|
-
if (providerConfig.name === "codex") return await handleAlphaSearchRequest(c, providerConfig);
|
|
8248
|
+
if (providerConfig.name === "codex") return await providerAlphaSearchRouteDependencies.handleAlphaSearchRequest(c, providerConfig);
|
|
8140
8249
|
await debugJsonAsync(logger$6, "provider.alpha_search.request", async () => ({
|
|
8141
8250
|
body: await c.req.raw.clone().text(),
|
|
8142
8251
|
provider
|
|
8143
8252
|
}));
|
|
8144
|
-
const upstreamResponse = await forwardProviderAlphaSearch(providerConfig, c.req.raw);
|
|
8253
|
+
const upstreamResponse = await providerAlphaSearchRouteDependencies.forwardProviderAlphaSearch(providerConfig, c.req.raw);
|
|
8145
8254
|
await debugJsonAsync(logger$6, "provider.alpha_search.response", async () => ({
|
|
8146
8255
|
body: await upstreamResponse.clone().text(),
|
|
8147
8256
|
provider,
|
|
8148
8257
|
statusCode: upstreamResponse.status
|
|
8149
8258
|
}));
|
|
8150
|
-
return createProviderProxyResponse(upstreamResponse);
|
|
8259
|
+
return providerAlphaSearchRouteDependencies.createProviderProxyResponse(upstreamResponse);
|
|
8151
8260
|
} catch (error) {
|
|
8152
8261
|
logger$6.error("provider.alpha_search.error", {
|
|
8153
8262
|
provider,
|
|
@@ -9810,13 +9919,14 @@ function isAnthropicResponse(value) {
|
|
|
9810
9919
|
//#endregion
|
|
9811
9920
|
//#region src/routes/provider/responses/handler.ts
|
|
9812
9921
|
const logger$2 = createHandlerLogger("provider-responses-handler");
|
|
9922
|
+
const providerResponsesHandlerDependencies = { resolveProviderConfig };
|
|
9813
9923
|
async function handleProviderResponsesForProvider(c, options) {
|
|
9814
9924
|
const { payload, provider } = options;
|
|
9815
9925
|
debugJson(logger$2, "Responses request payload:", {
|
|
9816
9926
|
payload,
|
|
9817
9927
|
provider
|
|
9818
9928
|
});
|
|
9819
|
-
const providerConfig = await resolveProviderConfig(provider);
|
|
9929
|
+
const providerConfig = await providerResponsesHandlerDependencies.resolveProviderConfig(provider);
|
|
9820
9930
|
if (!providerConfig) return c.json({ error: {
|
|
9821
9931
|
message: `Provider '${provider}' does not support the /v1/responses endpoint`,
|
|
9822
9932
|
type: "invalid_request_error"
|
|
@@ -9841,7 +9951,7 @@ async function handleProviderResponsesForProvider(c, options) {
|
|
|
9841
9951
|
});
|
|
9842
9952
|
const modelConfig = providerConfig.models?.[payload.model];
|
|
9843
9953
|
if (providerConfig.name === "codex") {
|
|
9844
|
-
const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl);
|
|
9954
|
+
const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl, { signal: c.req.raw.signal });
|
|
9845
9955
|
const recordUsage = createProviderResponsesUsageRecorder(payload, provider, modelConfig, providerConfig.pricingCurrency);
|
|
9846
9956
|
if (payload.stream && isResponsesStream(upstreamResponse)) return streamProviderResponses(c, upstreamResponse, {
|
|
9847
9957
|
normalizeCodex: true,
|
|
@@ -9852,10 +9962,10 @@ async function handleProviderResponsesForProvider(c, options) {
|
|
|
9852
9962
|
recordUsage(normalizeResponsesUsage(responseBody.usage));
|
|
9853
9963
|
return c.json(responseBody);
|
|
9854
9964
|
}
|
|
9855
|
-
const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers);
|
|
9965
|
+
const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers, { signal: c.req.raw.signal });
|
|
9856
9966
|
if (!upstreamResponse.ok) throw new HTTPError(`Failed to create ${provider} responses`, upstreamResponse);
|
|
9857
9967
|
const recordUsage = createProviderResponsesUsageRecorder(payload, provider, modelConfig, providerConfig.pricingCurrency);
|
|
9858
|
-
if (payload.stream) return streamProviderResponses(c, getResponsesEvents(upstreamResponse), {
|
|
9968
|
+
if (payload.stream) return streamProviderResponses(c, getResponsesEvents(upstreamResponse, c.req.raw.signal), {
|
|
9859
9969
|
normalizeCodex: false,
|
|
9860
9970
|
provider,
|
|
9861
9971
|
recordUsage
|
|
@@ -9877,7 +9987,10 @@ const createProviderResponsesUsageRecorder = (payload, provider, modelConfig, pr
|
|
|
9877
9987
|
const streamProviderResponses = async (c, upstreamResponse, options) => {
|
|
9878
9988
|
const iterator = upstreamResponse[Symbol.asyncIterator]();
|
|
9879
9989
|
const firstResult = await iterator.next();
|
|
9880
|
-
if (firstResult.done)
|
|
9990
|
+
if (firstResult.done) {
|
|
9991
|
+
await iterator.return?.();
|
|
9992
|
+
throw new HTTPError(`Empty stream from ${options.provider} responses`, new Response("", { status: 502 }));
|
|
9993
|
+
}
|
|
9881
9994
|
const firstChunk = firstResult.value;
|
|
9882
9995
|
if (firstChunk.data && firstChunk.data !== "[DONE]") {
|
|
9883
9996
|
const event = parseProviderResponsesStreamEvent(firstChunk.data, {
|
|
@@ -9887,6 +10000,7 @@ const streamProviderResponses = async (c, upstreamResponse, options) => {
|
|
|
9887
10000
|
if (event?.type === "error") {
|
|
9888
10001
|
const errorEvent = event;
|
|
9889
10002
|
const statusCode = errorEvent.status_code ?? 500;
|
|
10003
|
+
await iterator.return?.();
|
|
9890
10004
|
return c.json({ error: {
|
|
9891
10005
|
message: errorEvent.message,
|
|
9892
10006
|
...errorEvent.error
|
|
@@ -9923,6 +10037,7 @@ const streamProviderResponses = async (c, upstreamResponse, options) => {
|
|
|
9923
10037
|
await writeChunk(firstChunk);
|
|
9924
10038
|
for await (const chunk of { [Symbol.asyncIterator]: () => iterator }) await writeChunk(chunk);
|
|
9925
10039
|
} finally {
|
|
10040
|
+
await iterator.return?.();
|
|
9926
10041
|
options.recordUsage(usage);
|
|
9927
10042
|
}
|
|
9928
10043
|
});
|
|
@@ -9945,7 +10060,7 @@ const getResponsesStreamEventUsage = (event) => {
|
|
|
9945
10060
|
if (event.type === "response.completed" || event.type === "response.failed" || event.type === "response.incomplete") return normalizeResponsesUsage(event.response.usage);
|
|
9946
10061
|
return null;
|
|
9947
10062
|
};
|
|
9948
|
-
const getResponsesEvents = (response) =>
|
|
10063
|
+
const getResponsesEvents = (response, signal) => createResponsesSafeStream(createResponsesHttpEventStream(response, signal), { signal });
|
|
9949
10064
|
//#endregion
|
|
9950
10065
|
//#region src/routes/provider/responses/route.ts
|
|
9951
10066
|
const providerResponsesRoutes = new Hono();
|
|
@@ -10048,6 +10163,8 @@ const handleResponses = async (c) => {
|
|
|
10048
10163
|
fallbackSessionId,
|
|
10049
10164
|
model: payload.model
|
|
10050
10165
|
});
|
|
10166
|
+
const sanitizedUnsupportedFieldCount = sanitizeUnsupportedInputFields(payload);
|
|
10167
|
+
if (sanitizedUnsupportedFieldCount > 0) logger$1.debug(`Removed ${sanitizedUnsupportedFieldCount} unsupported input field(s) before forwarding to Copilot Responses`);
|
|
10051
10168
|
removeUnsupportedTools(payload);
|
|
10052
10169
|
fillEmptyNamespaceToolDescriptions(payload);
|
|
10053
10170
|
if (!responsesHandlerDependencies.isResponsesApiWebSearchEnabled()) removeWebSearchTool(payload);
|
|
@@ -10067,6 +10184,7 @@ const handleResponses = async (c) => {
|
|
|
10067
10184
|
subagentMarker,
|
|
10068
10185
|
requestId,
|
|
10069
10186
|
sessionId: fallbackSessionId,
|
|
10187
|
+
signal: c.req.raw.signal,
|
|
10070
10188
|
transport: responsesTransport
|
|
10071
10189
|
});
|
|
10072
10190
|
if (isStreamingRequested(payload) && isAsyncIterable(response)) {
|
|
@@ -10074,21 +10192,26 @@ const handleResponses = async (c) => {
|
|
|
10074
10192
|
return streamSSE(c, async (stream) => {
|
|
10075
10193
|
const idTracker = createStreamIdTracker();
|
|
10076
10194
|
let usage = {};
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
const
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10195
|
+
const iterator = response[Symbol.asyncIterator]();
|
|
10196
|
+
try {
|
|
10197
|
+
for await (const chunk of { [Symbol.asyncIterator]: () => iterator }) {
|
|
10198
|
+
debugJson(logger$1, "Responses stream chunk:", chunk);
|
|
10199
|
+
const parsedEvent = parseResponsesStreamEvent(chunk);
|
|
10200
|
+
if (parsedEvent?.type === "response.completed" || parsedEvent?.type === "response.failed" || parsedEvent?.type === "response.incomplete") usage = {
|
|
10201
|
+
...normalizeResponsesUsage(parsedEvent.response.usage),
|
|
10202
|
+
total_nano_aiu: normalizeOptionalToken(parsedEvent.copilot_usage?.total_nano_aiu)
|
|
10203
|
+
};
|
|
10204
|
+
const processedData = fixStreamIds(chunk.data ?? "", chunk.event, idTracker);
|
|
10205
|
+
await stream.writeSSE({
|
|
10206
|
+
id: chunk.id,
|
|
10207
|
+
event: chunk.event,
|
|
10208
|
+
data: processedData
|
|
10209
|
+
});
|
|
10210
|
+
}
|
|
10211
|
+
} finally {
|
|
10212
|
+
await iterator.return?.();
|
|
10213
|
+
recordUsage(usage);
|
|
10090
10214
|
}
|
|
10091
|
-
recordUsage(usage);
|
|
10092
10215
|
});
|
|
10093
10216
|
}
|
|
10094
10217
|
debugJsonTail(logger$1, "Forwarding native Responses result:", {
|
|
@@ -10305,4 +10428,4 @@ server.route("/:provider/images", providerImageRoutes);
|
|
|
10305
10428
|
//#endregion
|
|
10306
10429
|
export { server };
|
|
10307
10430
|
|
|
10308
|
-
//# sourceMappingURL=server-
|
|
10431
|
+
//# sourceMappingURL=server-GxC8BArQ.js.map
|