@jeffreycao/copilot-api 1.14.6 → 1.14.8
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 +14 -4
- package/README.zh-CN.md +12 -2
- package/dist/main.js +1 -1
- package/dist/{server-uQjD_RpA.js → server-BayMzJcy.js} +331 -101
- package/dist/server-BayMzJcy.js.map +1 -0
- package/dist/{start-DNPIXvm4.js → start-C-ugrdZG.js} +2 -2
- package/dist/{start-DNPIXvm4.js.map → start-C-ugrdZG.js.map} +1 -1
- package/package.json +1 -1
- package/dist/server-uQjD_RpA.js.map +0 -1
|
@@ -7,6 +7,7 @@ import fs, { readFileSync } from "node:fs";
|
|
|
7
7
|
import fs$1 from "node:fs/promises";
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
import { events } from "fetch-event-stream";
|
|
10
|
+
import { fetch as fetch$1, getGlobalDispatcher } from "undici";
|
|
10
11
|
import { z } from "zod";
|
|
11
12
|
import { Hono } from "hono";
|
|
12
13
|
import { cors } from "hono/cors";
|
|
@@ -299,6 +300,10 @@ const debugLazy = (logger, factory) => {
|
|
|
299
300
|
const debugJson = (logger, label, value) => {
|
|
300
301
|
debugLazy(logger, () => [label, JSON.stringify(value)]);
|
|
301
302
|
};
|
|
303
|
+
const debugJsonAsync = async (logger, label, factory) => {
|
|
304
|
+
if (!state.verbose) return;
|
|
305
|
+
logger.debug(label, JSON.stringify(await factory()));
|
|
306
|
+
};
|
|
302
307
|
const debugJsonTail = (logger, label, { value, tailLength = 400 }) => {
|
|
303
308
|
debugLazy(logger, () => [label, JSON.stringify(value).slice(-tailLength)]);
|
|
304
309
|
};
|
|
@@ -439,25 +444,74 @@ async function forwardProviderModels(providerConfig, requestHeaders) {
|
|
|
439
444
|
headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
|
|
440
445
|
});
|
|
441
446
|
}
|
|
447
|
+
/** Align with Codex images: long-running generation/edits need a generous cap. */
|
|
448
|
+
const PROVIDER_IMAGES_TIMEOUT_MS = 900 * 1e3;
|
|
449
|
+
const providerImagesDispatcher = { dispatch(options, handler) {
|
|
450
|
+
return getGlobalDispatcher().dispatch({
|
|
451
|
+
...options,
|
|
452
|
+
bodyTimeout: PROVIDER_IMAGES_TIMEOUT_MS,
|
|
453
|
+
headersTimeout: PROVIDER_IMAGES_TIMEOUT_MS
|
|
454
|
+
}, handler);
|
|
455
|
+
} };
|
|
456
|
+
function resolveProviderRequestUrl(providerConfig, requestUrl, path) {
|
|
457
|
+
const upstreamUrl = new URL(`${providerConfig.baseUrl}${path}`);
|
|
458
|
+
upstreamUrl.search = new URL(requestUrl, "http://localhost").search;
|
|
459
|
+
return upstreamUrl.toString();
|
|
460
|
+
}
|
|
461
|
+
async function forwardProviderAlphaSearch(providerConfig, request) {
|
|
462
|
+
const headers = buildProviderUpstreamHeaders(providerConfig, request.headers);
|
|
463
|
+
const body = await request.arrayBuffer();
|
|
464
|
+
return await fetch(resolveProviderRequestUrl(providerConfig, request.url, "/v1/alpha/search"), {
|
|
465
|
+
method: "POST",
|
|
466
|
+
headers,
|
|
467
|
+
body
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
async function forwardProviderImages(providerConfig, request, operation) {
|
|
471
|
+
const headers = buildProviderUpstreamHeaders(providerConfig, request.headers);
|
|
472
|
+
const contentType = request.headers.get("content-type");
|
|
473
|
+
if (contentType) headers["content-type"] = contentType;
|
|
474
|
+
else if (operation === "edits") delete headers["content-type"];
|
|
475
|
+
const init = {
|
|
476
|
+
method: "POST",
|
|
477
|
+
headers,
|
|
478
|
+
body: request.body,
|
|
479
|
+
duplex: "half",
|
|
480
|
+
signal: AbortSignal.timeout(PROVIDER_IMAGES_TIMEOUT_MS)
|
|
481
|
+
};
|
|
482
|
+
const upstreamUrl = resolveProviderRequestUrl(providerConfig, request.url, `/v1/images/${operation}`);
|
|
483
|
+
if (typeof Bun !== "undefined") return await fetch(upstreamUrl, init);
|
|
484
|
+
return await fetch$1(upstreamUrl, {
|
|
485
|
+
...init,
|
|
486
|
+
dispatcher: providerImagesDispatcher
|
|
487
|
+
});
|
|
488
|
+
}
|
|
442
489
|
//#endregion
|
|
443
490
|
//#region src/routes/alpha-search/route.ts
|
|
444
|
-
const logger$
|
|
491
|
+
const logger$14 = createHandlerLogger("alpha-search-handler");
|
|
445
492
|
const alphaSearchRoutes = new Hono();
|
|
493
|
+
/**
|
|
494
|
+
* Handles Codex alpha-search proxying. Pass `resolvedProviderConfig` when the
|
|
495
|
+
* caller already resolved the codex provider to avoid a second resolve.
|
|
496
|
+
*/
|
|
497
|
+
async function handleCodexAlphaSearch(c, resolvedProviderConfig) {
|
|
498
|
+
if (!(resolvedProviderConfig ?? await resolveProviderConfig("codex"))) return c.json({ error: {
|
|
499
|
+
message: "Provider 'codex' not found or disabled",
|
|
500
|
+
type: "invalid_request_error"
|
|
501
|
+
} }, 404);
|
|
502
|
+
await debugJsonAsync(logger$14, "alpha_search.codex.request", async () => ({ body: await c.req.raw.clone().text() }));
|
|
503
|
+
const upstreamResponse = await forwardCodexAlphaSearch(c.req.raw);
|
|
504
|
+
await debugJsonAsync(logger$14, "alpha_search.codex.response", async () => ({
|
|
505
|
+
body: await upstreamResponse.clone().text(),
|
|
506
|
+
statusCode: upstreamResponse.status
|
|
507
|
+
}));
|
|
508
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
509
|
+
}
|
|
446
510
|
alphaSearchRoutes.post("/", async (c) => {
|
|
447
511
|
try {
|
|
448
|
-
|
|
449
|
-
message: "Provider 'codex' not found or disabled",
|
|
450
|
-
type: "invalid_request_error"
|
|
451
|
-
} }, 404);
|
|
452
|
-
debugJson(logger$10, "alpha_search.codex.request", { body: await c.req.raw.clone().text() });
|
|
453
|
-
const upstreamResponse = await forwardCodexAlphaSearch(c.req.raw);
|
|
454
|
-
debugJson(logger$10, "alpha_search.codex.response", {
|
|
455
|
-
body: await upstreamResponse.clone().text(),
|
|
456
|
-
statusCode: upstreamResponse.status
|
|
457
|
-
});
|
|
458
|
-
return createProviderProxyResponse(upstreamResponse);
|
|
512
|
+
return await handleCodexAlphaSearch(c);
|
|
459
513
|
} catch (error) {
|
|
460
|
-
logger$
|
|
514
|
+
logger$14.error("alpha_search.codex.error", { error });
|
|
461
515
|
return await forwardError(c, error);
|
|
462
516
|
}
|
|
463
517
|
});
|
|
@@ -1589,7 +1643,7 @@ const setContextCacheControl = (part) => {
|
|
|
1589
1643
|
};
|
|
1590
1644
|
//#endregion
|
|
1591
1645
|
//#region src/routes/provider/chat-completions/handler.ts
|
|
1592
|
-
const logger$
|
|
1646
|
+
const logger$13 = createHandlerLogger("provider-chat-completions-handler");
|
|
1593
1647
|
async function handleProviderChatCompletionsForProvider(c, options) {
|
|
1594
1648
|
const { payload, provider } = options;
|
|
1595
1649
|
const providerConfig = await resolveProviderConfig(provider);
|
|
@@ -1603,13 +1657,13 @@ async function handleProviderChatCompletionsForProvider(c, options) {
|
|
|
1603
1657
|
applyProviderStreamOptions(payload);
|
|
1604
1658
|
applyDashScopePreserveThinkingDefault(payload, providerConfig);
|
|
1605
1659
|
applyProviderContextCache(payload, modelConfig, providerConfig);
|
|
1606
|
-
debugJson(logger$
|
|
1660
|
+
debugJson(logger$13, "provider.chat_completions.request", {
|
|
1607
1661
|
payload,
|
|
1608
1662
|
provider
|
|
1609
1663
|
});
|
|
1610
1664
|
const upstreamResponse = await forwardProviderChatCompletions(providerConfig, payload, c.req.raw.headers);
|
|
1611
1665
|
if (!upstreamResponse.ok) {
|
|
1612
|
-
logger$
|
|
1666
|
+
logger$13.error("Failed to create provider chat completions", {
|
|
1613
1667
|
provider,
|
|
1614
1668
|
statusCode: upstreamResponse.status
|
|
1615
1669
|
});
|
|
@@ -1623,7 +1677,7 @@ async function handleProviderChatCompletionsForProvider(c, options) {
|
|
|
1623
1677
|
});
|
|
1624
1678
|
const responseBody = await upstreamResponse.clone().json();
|
|
1625
1679
|
recordUsage(normalizeOpenAIUsage(responseBody.usage));
|
|
1626
|
-
debugJson(logger$
|
|
1680
|
+
debugJson(logger$13, "provider.chat_completions.response", responseBody);
|
|
1627
1681
|
return createProviderProxyResponse(upstreamResponse);
|
|
1628
1682
|
}
|
|
1629
1683
|
const applyProviderModelDefaults = (payload, modelConfig) => {
|
|
@@ -1653,12 +1707,12 @@ const createProviderChatCompletionsUsageRecorder = (payload, provider, modelConf
|
|
|
1653
1707
|
providerName: provider
|
|
1654
1708
|
});
|
|
1655
1709
|
const streamProviderChatCompletions = (c, upstreamResponse, options) => {
|
|
1656
|
-
logger$
|
|
1710
|
+
logger$13.debug("provider.chat_completions.streaming", { provider: options.provider });
|
|
1657
1711
|
return streamSSE(c, async (stream) => {
|
|
1658
1712
|
let usage = {};
|
|
1659
1713
|
try {
|
|
1660
1714
|
for await (const chunk of events(upstreamResponse)) {
|
|
1661
|
-
debugJson(logger$
|
|
1715
|
+
debugJson(logger$13, "provider.chat_completions.stream_chunk", chunk);
|
|
1662
1716
|
if (chunk.data && chunk.data !== "[DONE]") {
|
|
1663
1717
|
const parsedChunk = parseChatCompletionChunkData(chunk.data);
|
|
1664
1718
|
if (parsedChunk?.usage) usage = normalizeOpenAIUsage(parsedChunk.usage);
|
|
@@ -1785,7 +1839,7 @@ const createChatCompletions = async (payload, options) => {
|
|
|
1785
1839
|
};
|
|
1786
1840
|
//#endregion
|
|
1787
1841
|
//#region src/routes/chat-completions/handler.ts
|
|
1788
|
-
const logger$
|
|
1842
|
+
const logger$12 = createHandlerLogger("chat-completions-handler");
|
|
1789
1843
|
async function handleCompletion$1(c) {
|
|
1790
1844
|
let payload = await c.req.json();
|
|
1791
1845
|
const requestedModel = payload.model;
|
|
@@ -1799,23 +1853,23 @@ async function handleCompletion$1(c) {
|
|
|
1799
1853
|
provider: providerModelAlias.provider
|
|
1800
1854
|
});
|
|
1801
1855
|
}
|
|
1802
|
-
debugJson(logger$
|
|
1856
|
+
debugJson(logger$12, "Request payload:", payload);
|
|
1803
1857
|
const selectedModel = state.models?.data.find((model) => model.id === payload.model);
|
|
1804
1858
|
if (isNullish(payload.max_tokens) && isNullish(payload.max_completion_tokens)) {
|
|
1805
1859
|
payload = {
|
|
1806
1860
|
...payload,
|
|
1807
1861
|
max_tokens: selectedModel?.capabilities.limits.max_output_tokens
|
|
1808
1862
|
};
|
|
1809
|
-
debugJson(logger$
|
|
1863
|
+
debugJson(logger$12, "Set max_tokens to:", payload.max_tokens);
|
|
1810
1864
|
}
|
|
1811
1865
|
if (payload.model.includes("gpt")) {
|
|
1812
1866
|
if (isNullish(payload.max_completion_tokens)) payload.max_completion_tokens = payload.max_tokens;
|
|
1813
1867
|
delete payload.max_tokens;
|
|
1814
1868
|
}
|
|
1815
1869
|
const requestId = generateRequestIdFromPayload(payload);
|
|
1816
|
-
logger$
|
|
1870
|
+
logger$12.debug("Generated request ID:", requestId);
|
|
1817
1871
|
const sessionId = getUUID(requestId);
|
|
1818
|
-
logger$
|
|
1872
|
+
logger$12.debug("Extracted session ID:", sessionId);
|
|
1819
1873
|
const recordUsage = createCopilotTokenUsageRecorder({
|
|
1820
1874
|
endpoint: "chat_completions",
|
|
1821
1875
|
fallbackSessionId: sessionId,
|
|
@@ -1826,18 +1880,18 @@ async function handleCompletion$1(c) {
|
|
|
1826
1880
|
sessionId
|
|
1827
1881
|
});
|
|
1828
1882
|
if (isNonStreaming$1(response)) {
|
|
1829
|
-
debugJson(logger$
|
|
1883
|
+
debugJson(logger$12, "Non-streaming response:", response);
|
|
1830
1884
|
recordUsage({
|
|
1831
1885
|
...normalizeOpenAIUsage(response.usage),
|
|
1832
1886
|
total_nano_aiu: normalizeOptionalToken(response.copilot_usage?.total_nano_aiu)
|
|
1833
1887
|
});
|
|
1834
1888
|
return c.json(response);
|
|
1835
1889
|
}
|
|
1836
|
-
logger$
|
|
1890
|
+
logger$12.debug("Streaming response");
|
|
1837
1891
|
return streamSSE(c, async (stream) => {
|
|
1838
1892
|
let usage = {};
|
|
1839
1893
|
for await (const chunk of response) {
|
|
1840
|
-
debugJson(logger$
|
|
1894
|
+
debugJson(logger$12, "Streaming chunk:", chunk);
|
|
1841
1895
|
const parsedChunk = parseChatCompletionChunk(chunk);
|
|
1842
1896
|
if (parsedChunk?.usage || parsedChunk?.copilot_usage) usage = {
|
|
1843
1897
|
...normalizeOpenAIUsage(parsedChunk.usage),
|
|
@@ -1926,6 +1980,75 @@ embeddingRoutes.post("/", async (c) => {
|
|
|
1926
1980
|
}
|
|
1927
1981
|
});
|
|
1928
1982
|
//#endregion
|
|
1983
|
+
//#region src/services/codex/images.ts
|
|
1984
|
+
const CODEX_IMAGES_TIMEOUT_MS = 900 * 1e3;
|
|
1985
|
+
const codexImagesDispatcher = { dispatch(options, handler) {
|
|
1986
|
+
return getGlobalDispatcher().dispatch({
|
|
1987
|
+
...options,
|
|
1988
|
+
bodyTimeout: CODEX_IMAGES_TIMEOUT_MS,
|
|
1989
|
+
headersTimeout: CODEX_IMAGES_TIMEOUT_MS
|
|
1990
|
+
}, handler);
|
|
1991
|
+
} };
|
|
1992
|
+
function resolveCodexImagesUrl(requestUrl, operation) {
|
|
1993
|
+
const upstreamUrl = new URL(`${CODEX_API_BASE_URL}/codex/images/${operation}`);
|
|
1994
|
+
upstreamUrl.search = new URL(requestUrl, "http://localhost").search;
|
|
1995
|
+
return upstreamUrl.toString();
|
|
1996
|
+
}
|
|
1997
|
+
async function forwardCodexImages(request, operation) {
|
|
1998
|
+
const headers = buildCodexRequestHeaders(request.headers);
|
|
1999
|
+
if (!headers.has("accept")) headers.set("accept", "application/json");
|
|
2000
|
+
if (operation === "generations" && !headers.has("content-type")) headers.set("content-type", "application/json");
|
|
2001
|
+
const init = {
|
|
2002
|
+
method: "POST",
|
|
2003
|
+
headers,
|
|
2004
|
+
body: request.body,
|
|
2005
|
+
duplex: "half",
|
|
2006
|
+
signal: AbortSignal.timeout(CODEX_IMAGES_TIMEOUT_MS)
|
|
2007
|
+
};
|
|
2008
|
+
const upstreamUrl = resolveCodexImagesUrl(request.url, operation);
|
|
2009
|
+
if (typeof Bun !== "undefined") return await fetch(upstreamUrl, init);
|
|
2010
|
+
return await fetch$1(upstreamUrl, {
|
|
2011
|
+
...init,
|
|
2012
|
+
dispatcher: codexImagesDispatcher
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
//#endregion
|
|
2016
|
+
//#region src/routes/images/route.ts
|
|
2017
|
+
const logger$11 = createHandlerLogger("images-handler");
|
|
2018
|
+
const imageRoutes = new Hono();
|
|
2019
|
+
const imageRouteDependencies = { debugJsonAsync };
|
|
2020
|
+
function getContentMetadata$1(headers) {
|
|
2021
|
+
return {
|
|
2022
|
+
contentType: headers.get("content-type"),
|
|
2023
|
+
contentLength: headers.get("content-length")
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Handles Codex images proxying. Pass `resolvedProviderConfig` when the
|
|
2028
|
+
* caller already resolved the codex provider to avoid a second resolve.
|
|
2029
|
+
*/
|
|
2030
|
+
async function handleCodexImages(c, operation, resolvedProviderConfig) {
|
|
2031
|
+
try {
|
|
2032
|
+
if (!(resolvedProviderConfig ?? await resolveProviderConfig("codex"))) return c.json({ error: {
|
|
2033
|
+
message: "Provider 'codex' not found or disabled",
|
|
2034
|
+
type: "invalid_request_error"
|
|
2035
|
+
} }, 404);
|
|
2036
|
+
if (operation === "generations") await imageRouteDependencies.debugJsonAsync(logger$11, "images.generations.codex.request", async () => ({ body: await c.req.raw.clone().text() }));
|
|
2037
|
+
else debugJson(logger$11, "images.edits.codex.request", getContentMetadata$1(c.req.raw.headers));
|
|
2038
|
+
const upstreamResponse = await forwardCodexImages(c.req.raw, operation);
|
|
2039
|
+
debugJson(logger$11, `images.${operation}.codex.response`, {
|
|
2040
|
+
...getContentMetadata$1(upstreamResponse.headers),
|
|
2041
|
+
statusCode: upstreamResponse.status
|
|
2042
|
+
});
|
|
2043
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
2044
|
+
} catch (error) {
|
|
2045
|
+
logger$11.error(`images.${operation}.codex.error`, { error });
|
|
2046
|
+
return await forwardError(c, error);
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
imageRoutes.post("/generations", (c) => handleCodexImages(c, "generations"));
|
|
2050
|
+
imageRoutes.post("/edits", (c) => handleCodexImages(c, "edits"));
|
|
2051
|
+
//#endregion
|
|
1929
2052
|
//#region src/lib/tokenizer.ts
|
|
1930
2053
|
const ENCODING_MAP = {
|
|
1931
2054
|
o200k_base: () => import("gpt-tokenizer/encoding/o200k_base"),
|
|
@@ -2963,7 +3086,7 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
|
|
|
2963
3086
|
};
|
|
2964
3087
|
//#endregion
|
|
2965
3088
|
//#region src/routes/provider/messages/count-tokens-handler.ts
|
|
2966
|
-
const logger$
|
|
3089
|
+
const logger$10 = createHandlerLogger("provider-count-tokens-handler");
|
|
2967
3090
|
async function handleProviderCountTokens(c) {
|
|
2968
3091
|
const provider = c.req.param("provider");
|
|
2969
3092
|
return await handleProviderCountTokensForProvider(c, {
|
|
@@ -2986,7 +3109,7 @@ async function handleProviderCountTokensForProvider(c, options) {
|
|
|
2986
3109
|
toolContentSupportType: modelConfig?.toolContentSupportType ?? []
|
|
2987
3110
|
} : void 0), createFallbackModel(modelId));
|
|
2988
3111
|
const finalTokenCount = tokenCount.input + tokenCount.output;
|
|
2989
|
-
logger$
|
|
3112
|
+
logger$10.debug("provider.count_tokens.success", {
|
|
2990
3113
|
provider,
|
|
2991
3114
|
model: anthropicPayload.model,
|
|
2992
3115
|
input_tokens: finalTokenCount
|
|
@@ -5348,7 +5471,7 @@ function getModels() {
|
|
|
5348
5471
|
}
|
|
5349
5472
|
//#endregion
|
|
5350
5473
|
//#region src/routes/provider/messages/handler.ts
|
|
5351
|
-
const logger$
|
|
5474
|
+
const logger$9 = createHandlerLogger("provider-messages-handler");
|
|
5352
5475
|
async function handleProviderMessages(c) {
|
|
5353
5476
|
const provider = c.req.param("provider");
|
|
5354
5477
|
return await handleProviderMessagesForProvider(c, {
|
|
@@ -5366,7 +5489,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
5366
5489
|
try {
|
|
5367
5490
|
const modelConfig = providerConfig.models?.[payload.model];
|
|
5368
5491
|
const effectiveType = resolveEffectiveProviderType(providerConfig, payload.model);
|
|
5369
|
-
debugJson(logger$
|
|
5492
|
+
debugJson(logger$9, "provider.messages.request", {
|
|
5370
5493
|
payload,
|
|
5371
5494
|
provider
|
|
5372
5495
|
});
|
|
@@ -5399,7 +5522,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
5399
5522
|
});
|
|
5400
5523
|
}
|
|
5401
5524
|
applyMissingExtraBody(payload, { extraBody: modelConfig?.extraBody });
|
|
5402
|
-
debugJson(logger$
|
|
5525
|
+
debugJson(logger$9, "Translated provider.messages.request", {
|
|
5403
5526
|
payload,
|
|
5404
5527
|
provider
|
|
5405
5528
|
});
|
|
@@ -5409,7 +5532,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
5409
5532
|
authType: resolveProviderAuthType(providerConfig.name, void 0, effectiveType)
|
|
5410
5533
|
}, payload, c.req.raw.headers);
|
|
5411
5534
|
if (!upstreamResponse.ok) {
|
|
5412
|
-
logger$
|
|
5535
|
+
logger$9.error("Failed to create responses", upstreamResponse);
|
|
5413
5536
|
throw new HTTPError("Failed to create responses", upstreamResponse);
|
|
5414
5537
|
}
|
|
5415
5538
|
const contentType = upstreamResponse.headers.get("content-type") ?? "";
|
|
@@ -5429,7 +5552,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
5429
5552
|
provider
|
|
5430
5553
|
});
|
|
5431
5554
|
} catch (error) {
|
|
5432
|
-
logger$
|
|
5555
|
+
logger$9.error("provider.messages.error", {
|
|
5433
5556
|
provider,
|
|
5434
5557
|
error
|
|
5435
5558
|
});
|
|
@@ -5439,7 +5562,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
5439
5562
|
const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
5440
5563
|
const { modelConfig, payload, provider, providerConfig } = options;
|
|
5441
5564
|
const responsesPayload = prepareWebSearchResponsesPayload(payload);
|
|
5442
|
-
debugJson(logger$
|
|
5565
|
+
debugJson(logger$9, "provider.messages.responses.web_search.request", {
|
|
5443
5566
|
payload: responsesPayload,
|
|
5444
5567
|
provider
|
|
5445
5568
|
});
|
|
@@ -5450,7 +5573,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
5450
5573
|
errorMessagePrefix: `${provider} web search responses stream`,
|
|
5451
5574
|
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
5452
5575
|
upstreamResponse,
|
|
5453
|
-
logger: logger$
|
|
5576
|
+
logger: logger$9
|
|
5454
5577
|
}),
|
|
5455
5578
|
modelConfig,
|
|
5456
5579
|
payload,
|
|
@@ -5467,7 +5590,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
5467
5590
|
}
|
|
5468
5591
|
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
5469
5592
|
if (!upstreamResponse.ok) {
|
|
5470
|
-
logger$
|
|
5593
|
+
logger$9.error("Failed to create provider web search responses", {
|
|
5471
5594
|
provider,
|
|
5472
5595
|
upstreamResponse
|
|
5473
5596
|
});
|
|
@@ -5478,7 +5601,7 @@ const handleOpenAIResponsesProviderWebSearchMessages = async (c, options) => {
|
|
|
5478
5601
|
errorMessagePrefix: `${provider} web search responses stream`,
|
|
5479
5602
|
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
5480
5603
|
upstreamResponse: events(upstreamResponse),
|
|
5481
|
-
logger: logger$
|
|
5604
|
+
logger: logger$9
|
|
5482
5605
|
}),
|
|
5483
5606
|
modelConfig,
|
|
5484
5607
|
payload,
|
|
@@ -5500,7 +5623,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
5500
5623
|
const responsesPayload = translateAnthropicMessagesToResponsesPayload(payload);
|
|
5501
5624
|
if (providerConfig.name === "codex" && !wantsStream) responsesPayload.stream = true;
|
|
5502
5625
|
if (applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens, { source: "messages" })) compactInputByLatestCompaction(responsesPayload);
|
|
5503
|
-
debugJson(logger$
|
|
5626
|
+
debugJson(logger$9, "provider.messages.responses.request", {
|
|
5504
5627
|
payload: responsesPayload,
|
|
5505
5628
|
provider
|
|
5506
5629
|
});
|
|
@@ -5521,7 +5644,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
5521
5644
|
errorMessagePrefix: `${provider} messages responses stream`,
|
|
5522
5645
|
parseEvent: (data) => parseResponsesProviderStreamChunk(data, providerConfig),
|
|
5523
5646
|
upstreamResponse,
|
|
5524
|
-
logger: logger$
|
|
5647
|
+
logger: logger$9
|
|
5525
5648
|
}),
|
|
5526
5649
|
modelConfig,
|
|
5527
5650
|
payload,
|
|
@@ -5541,7 +5664,7 @@ const handleOpenAIResponsesProviderMessages = async (c, options) => {
|
|
|
5541
5664
|
}
|
|
5542
5665
|
const upstreamResponse = await forwardProviderResponses(providerConfig, responsesPayload, c.req.raw.headers);
|
|
5543
5666
|
if (!upstreamResponse.ok) {
|
|
5544
|
-
logger$
|
|
5667
|
+
logger$9.error("Failed to create provider responses", upstreamResponse);
|
|
5545
5668
|
throw new HTTPError("Failed to create provider responses", upstreamResponse);
|
|
5546
5669
|
}
|
|
5547
5670
|
if (responsesPayload.stream) return streamResponsesProviderMessages({
|
|
@@ -5592,13 +5715,13 @@ const applyOpenAICompatibleExtraBodyThinkingBudget = (payload, options) => {
|
|
|
5592
5715
|
const handleOpenAICompatibleProviderMessages = async (c, options) => {
|
|
5593
5716
|
const { modelConfig, payload, provider, providerConfig } = options;
|
|
5594
5717
|
const openAIPayload = createOpenAICompatiblePayload(payload, modelConfig, providerConfig);
|
|
5595
|
-
debugJson(logger$
|
|
5718
|
+
debugJson(logger$9, "provider.messages.openai_compatible.request", {
|
|
5596
5719
|
payload: openAIPayload,
|
|
5597
5720
|
provider
|
|
5598
5721
|
});
|
|
5599
5722
|
const upstreamResponse = await forwardProviderChatCompletions(providerConfig, openAIPayload, c.req.raw.headers);
|
|
5600
5723
|
if (!upstreamResponse.ok) {
|
|
5601
|
-
logger$
|
|
5724
|
+
logger$9.error("Failed to create openai-compatible responses", upstreamResponse);
|
|
5602
5725
|
throw new HTTPError("Failed to create openai-compatible responses", upstreamResponse);
|
|
5603
5726
|
}
|
|
5604
5727
|
const contentType = upstreamResponse.headers.get("content-type") ?? "";
|
|
@@ -5653,12 +5776,12 @@ const applyOpenAICompatibleRequestOverrides = (payload, options) => {
|
|
|
5653
5776
|
for (const key of allowedKeys) if (Object.hasOwn(options.source, key)) payload[key] = options.source[key];
|
|
5654
5777
|
};
|
|
5655
5778
|
const streamProviderMessages = ({ c, modelConfig, payload, pricingCurrency, provider, upstreamResponse }) => {
|
|
5656
|
-
logger$
|
|
5779
|
+
logger$9.debug("provider.messages.streaming");
|
|
5657
5780
|
const recordUsage = createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency);
|
|
5658
5781
|
return streamSSE(c, async (stream) => {
|
|
5659
5782
|
let usage = {};
|
|
5660
5783
|
for await (const chunk of events(upstreamResponse)) {
|
|
5661
|
-
logger$
|
|
5784
|
+
logger$9.debug("provider.messages.raw_stream_event:", chunk.data);
|
|
5662
5785
|
const eventName = chunk.event;
|
|
5663
5786
|
if (eventName === "ping") {
|
|
5664
5787
|
await stream.writeSSE({
|
|
@@ -5684,7 +5807,7 @@ const streamProviderMessages = ({ c, modelConfig, payload, pricingCurrency, prov
|
|
|
5684
5807
|
});
|
|
5685
5808
|
};
|
|
5686
5809
|
const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, pricingCurrency, provider, upstreamResponse }) => {
|
|
5687
|
-
logger$
|
|
5810
|
+
logger$9.debug("provider.messages.openai_compatible.streaming");
|
|
5688
5811
|
const recordUsage = createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency);
|
|
5689
5812
|
return streamSSE(c, async (stream) => {
|
|
5690
5813
|
let usage = {};
|
|
@@ -5696,7 +5819,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
|
|
|
5696
5819
|
thinkingBlockOpen: false
|
|
5697
5820
|
};
|
|
5698
5821
|
for await (const chunk of events(upstreamResponse)) {
|
|
5699
|
-
logger$
|
|
5822
|
+
logger$9.debug("provider.messages.openai_compatible.raw_stream_event:", chunk.data);
|
|
5700
5823
|
if (chunk.event === "ping") {
|
|
5701
5824
|
await stream.writeSSE({
|
|
5702
5825
|
event: "ping",
|
|
@@ -5714,7 +5837,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
|
|
|
5714
5837
|
const events = translateChunkToAnthropicEvents(parsed, streamState);
|
|
5715
5838
|
for (const event of events) {
|
|
5716
5839
|
const eventData = JSON.stringify(event);
|
|
5717
|
-
debugLazy(logger$
|
|
5840
|
+
debugLazy(logger$9, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
5718
5841
|
await stream.writeSSE({
|
|
5719
5842
|
event: event.type,
|
|
5720
5843
|
data: eventData
|
|
@@ -5723,7 +5846,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
|
|
|
5723
5846
|
}
|
|
5724
5847
|
for (const event of flushPendingAnthropicStreamEvents(streamState)) {
|
|
5725
5848
|
const eventData = JSON.stringify(event);
|
|
5726
|
-
debugLazy(logger$
|
|
5849
|
+
debugLazy(logger$9, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
5727
5850
|
await stream.writeSSE({
|
|
5728
5851
|
event: event.type,
|
|
5729
5852
|
data: eventData
|
|
@@ -5733,13 +5856,13 @@ const streamOpenAICompatibleProviderMessages = ({ c, modelConfig, payload, prici
|
|
|
5733
5856
|
});
|
|
5734
5857
|
};
|
|
5735
5858
|
const streamResponsesProviderMessages = ({ c, modelConfig, payload, pricingCurrency, provider, providerConfig, upstreamResponse }) => {
|
|
5736
|
-
logger$
|
|
5859
|
+
logger$9.debug("provider.messages.responses.streaming", { provider });
|
|
5737
5860
|
const recordUsage = createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency);
|
|
5738
5861
|
return streamSSE(c, async (stream) => {
|
|
5739
5862
|
let usage = {};
|
|
5740
5863
|
const streamState = createResponsesStreamState({ toolSearchName: resolveBridgeToolSearchName(payload.tools) });
|
|
5741
5864
|
for await (const chunk of upstreamResponse) {
|
|
5742
|
-
logger$
|
|
5865
|
+
logger$9.debug("provider.messages.responses.raw_stream_event:", chunk.data);
|
|
5743
5866
|
if (chunk.event === "ping") {
|
|
5744
5867
|
await stream.writeSSE({
|
|
5745
5868
|
event: "ping",
|
|
@@ -5757,7 +5880,7 @@ const streamResponsesProviderMessages = ({ c, modelConfig, payload, pricingCurre
|
|
|
5757
5880
|
const events = translateResponsesStreamEvent(parsed, streamState);
|
|
5758
5881
|
for (const event of events) {
|
|
5759
5882
|
const eventData = JSON.stringify(event);
|
|
5760
|
-
debugLazy(logger$
|
|
5883
|
+
debugLazy(logger$9, () => ["provider.messages.responses.translated_event:", eventData]);
|
|
5761
5884
|
await stream.writeSSE({
|
|
5762
5885
|
event: event.type,
|
|
5763
5886
|
data: eventData
|
|
@@ -5781,7 +5904,7 @@ const parseOpenAICompatibleStreamChunk = (data) => {
|
|
|
5781
5904
|
try {
|
|
5782
5905
|
return JSON.parse(data);
|
|
5783
5906
|
} catch (error) {
|
|
5784
|
-
logger$
|
|
5907
|
+
logger$9.error("provider.messages.openai_compatible.parse_chunk_error", {
|
|
5785
5908
|
data,
|
|
5786
5909
|
error
|
|
5787
5910
|
});
|
|
@@ -5794,7 +5917,7 @@ const parseResponsesProviderStreamChunk = (data, providerConfig) => {
|
|
|
5794
5917
|
if (providerConfig.name === "codex") logCodexRateLimitsEvent(parsed);
|
|
5795
5918
|
return parsed;
|
|
5796
5919
|
} catch (error) {
|
|
5797
|
-
logger$
|
|
5920
|
+
logger$9.error("provider.messages.responses.parse_chunk_error", {
|
|
5798
5921
|
provider: providerConfig.name,
|
|
5799
5922
|
data,
|
|
5800
5923
|
error
|
|
@@ -5819,7 +5942,7 @@ const parseProviderStreamEvent = (data) => {
|
|
|
5819
5942
|
usage: {}
|
|
5820
5943
|
};
|
|
5821
5944
|
} catch (error) {
|
|
5822
|
-
logger$
|
|
5945
|
+
logger$9.error("provider.messages.streaming.adjust_tokens_error", {
|
|
5823
5946
|
error,
|
|
5824
5947
|
originalData: data
|
|
5825
5948
|
});
|
|
@@ -5829,34 +5952,34 @@ const parseProviderStreamEvent = (data) => {
|
|
|
5829
5952
|
const respondProviderMessagesJson = (c, options) => {
|
|
5830
5953
|
const { body, modelConfig, payload, pricingCurrency, provider } = options;
|
|
5831
5954
|
createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency)(normalizeAnthropicUsage(body.usage));
|
|
5832
|
-
debugJson(logger$
|
|
5955
|
+
debugJson(logger$9, "provider.messages.no_stream result:", body);
|
|
5833
5956
|
return c.json(body);
|
|
5834
5957
|
};
|
|
5835
5958
|
const respondOpenAICompatibleProviderMessagesJson = (c, options) => {
|
|
5836
5959
|
const { body, modelConfig, payload, pricingCurrency, provider } = options;
|
|
5837
5960
|
createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency)(normalizeOpenAIUsage(body.usage));
|
|
5838
5961
|
const anthropicResponse = translateToAnthropic(body);
|
|
5839
|
-
debugJson(logger$
|
|
5962
|
+
debugJson(logger$9, "provider.messages.openai_compatible.no_stream result:", anthropicResponse);
|
|
5840
5963
|
return c.json(anthropicResponse);
|
|
5841
5964
|
};
|
|
5842
5965
|
const respondResponsesProviderMessagesJson = (c, options) => {
|
|
5843
5966
|
const { body, modelConfig, payload, pricingCurrency, provider, providerConfig } = options;
|
|
5844
5967
|
createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency)(normalizeResponsesUsage(body.usage));
|
|
5845
5968
|
const anthropicResponse = translateResponsesResultToAnthropic(body, { toolSearchName: resolveBridgeToolSearchName(payload.tools) });
|
|
5846
|
-
debugJson(logger$
|
|
5847
|
-
if (providerConfig.name === "codex") logger$
|
|
5969
|
+
debugJson(logger$9, "provider.messages.responses.no_stream result:", anthropicResponse);
|
|
5970
|
+
if (providerConfig.name === "codex") logger$9.debug("provider.messages.codex.no_stream.result");
|
|
5848
5971
|
return c.json(anthropicResponse);
|
|
5849
5972
|
};
|
|
5850
5973
|
const respondWebSearchProviderMessagesJson = (c, options) => {
|
|
5851
5974
|
const { body, modelConfig, payload, pricingCurrency, provider } = options;
|
|
5852
5975
|
createProviderMessagesUsageRecorder(payload, provider, modelConfig, pricingCurrency)(normalizeResponsesUsage(body.usage));
|
|
5853
5976
|
const { extract, response } = reconstructWebSearchResponse(payload, body, { requestId: body.id || `${provider}:${payload.model}` });
|
|
5854
|
-
debugJson(logger$
|
|
5977
|
+
debugJson(logger$9, `Web search via responses: ${extract.queries.length} quer(y/ies), ${extract.sources.length} source(s)`, body);
|
|
5855
5978
|
if (!payload.stream) return c.json(response);
|
|
5856
5979
|
return streamSSE(c, async (stream) => {
|
|
5857
5980
|
for (const event of buildSyntheticStreamEvents(response)) {
|
|
5858
5981
|
const data = JSON.stringify(event);
|
|
5859
|
-
logger$
|
|
5982
|
+
logger$9.debug(`Web search stream event`, data);
|
|
5860
5983
|
await stream.writeSSE({
|
|
5861
5984
|
event: event.type,
|
|
5862
5985
|
data
|
|
@@ -6215,7 +6338,7 @@ const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
|
6215
6338
|
};
|
|
6216
6339
|
//#endregion
|
|
6217
6340
|
//#region src/routes/messages/handler.ts
|
|
6218
|
-
const logger$
|
|
6341
|
+
const logger$8 = createHandlerLogger("messages-handler");
|
|
6219
6342
|
const messagesFlowHandlers = {
|
|
6220
6343
|
handleWithChatCompletions,
|
|
6221
6344
|
handleWithMessagesApi,
|
|
@@ -6227,7 +6350,7 @@ async function handleCompletion(c) {
|
|
|
6227
6350
|
anthropicPayload.model = resolveMappedModel(anthropicPayload.model);
|
|
6228
6351
|
if (anthropicPayload.model !== requestedModel) consola.debug(`Resolved model mapping: ${requestedModel} -> ${anthropicPayload.model}`);
|
|
6229
6352
|
const webSearchResult = await tryHandleWebSearch(c, anthropicPayload, {
|
|
6230
|
-
logger: logger$
|
|
6353
|
+
logger: logger$8,
|
|
6231
6354
|
forwardToProvider: (ctx, payload, provider) => handleProviderMessagesForProvider(ctx, {
|
|
6232
6355
|
payload,
|
|
6233
6356
|
provider
|
|
@@ -6242,18 +6365,18 @@ async function handleCompletion(c) {
|
|
|
6242
6365
|
provider: providerModelAlias.provider
|
|
6243
6366
|
});
|
|
6244
6367
|
}
|
|
6245
|
-
debugJson(logger$
|
|
6368
|
+
debugJson(logger$8, "Anthropic request payload:", anthropicPayload);
|
|
6246
6369
|
normalizeSystemMessages(anthropicPayload);
|
|
6247
6370
|
sanitizeIdeTools(anthropicPayload);
|
|
6248
6371
|
const subagentMarker = parseSubagentMarkerFromFirstUser(anthropicPayload);
|
|
6249
|
-
if (subagentMarker) debugJson(logger$
|
|
6372
|
+
if (subagentMarker) debugJson(logger$8, "Detected Subagent marker:", subagentMarker);
|
|
6250
6373
|
let sessionId = getRootSessionId(anthropicPayload, c);
|
|
6251
6374
|
const compactType = getCompactType(anthropicPayload);
|
|
6252
6375
|
const anthropicBeta = c.req.header("anthropic-beta");
|
|
6253
|
-
logger$
|
|
6376
|
+
logger$8.debug("Anthropic Beta header:", anthropicBeta);
|
|
6254
6377
|
const noTools = !anthropicPayload.tools || anthropicPayload.tools.length === 0;
|
|
6255
6378
|
if (anthropicBeta && noTools && compactType === 0) anthropicPayload.model = getSmallModel();
|
|
6256
|
-
if (compactType) logger$
|
|
6379
|
+
if (compactType) logger$8.debug("Compact request type:", compactType);
|
|
6257
6380
|
if (!state.tokenBasedBilling) {
|
|
6258
6381
|
const lastMessageCacheControl = getLastMessageContentCacheControl(anthropicPayload.messages.at(-1));
|
|
6259
6382
|
stripToolReferenceTurnBoundary(anthropicPayload);
|
|
@@ -6261,9 +6384,9 @@ async function handleCompletion(c) {
|
|
|
6261
6384
|
applyLastMessageCacheControl(anthropicPayload, lastMessageCacheControl);
|
|
6262
6385
|
}
|
|
6263
6386
|
const requestId = generateRequestIdFromPayload(anthropicPayload, sessionId);
|
|
6264
|
-
logger$
|
|
6387
|
+
logger$8.debug("Generated request ID:", requestId);
|
|
6265
6388
|
if (!sessionId) sessionId = getUUID(requestId);
|
|
6266
|
-
logger$
|
|
6389
|
+
logger$8.debug("Extracted session ID:", sessionId);
|
|
6267
6390
|
const selectedModel = findEndpointModel(anthropicPayload.model);
|
|
6268
6391
|
anthropicPayload.model = selectedModel?.id ?? anthropicPayload.model;
|
|
6269
6392
|
if (shouldUseMessagesApi(selectedModel)) return await messagesFlowHandlers.handleWithMessagesApi(c, anthropicPayload, {
|
|
@@ -6273,7 +6396,7 @@ async function handleCompletion(c) {
|
|
|
6273
6396
|
requestId,
|
|
6274
6397
|
sessionId,
|
|
6275
6398
|
compactType,
|
|
6276
|
-
logger: logger$
|
|
6399
|
+
logger: logger$8
|
|
6277
6400
|
});
|
|
6278
6401
|
if (shouldUseResponsesApi(selectedModel, compactType)) return await messagesFlowHandlers.handleWithResponsesApi(c, anthropicPayload, {
|
|
6279
6402
|
subagentMarker,
|
|
@@ -6281,7 +6404,7 @@ async function handleCompletion(c) {
|
|
|
6281
6404
|
requestId,
|
|
6282
6405
|
sessionId,
|
|
6283
6406
|
compactType,
|
|
6284
|
-
logger: logger$
|
|
6407
|
+
logger: logger$8
|
|
6285
6408
|
});
|
|
6286
6409
|
return await messagesFlowHandlers.handleWithChatCompletions(c, anthropicPayload, {
|
|
6287
6410
|
subagentMarker,
|
|
@@ -6289,7 +6412,7 @@ async function handleCompletion(c) {
|
|
|
6289
6412
|
requestId,
|
|
6290
6413
|
sessionId,
|
|
6291
6414
|
compactType,
|
|
6292
|
-
logger: logger$
|
|
6415
|
+
logger: logger$8
|
|
6293
6416
|
});
|
|
6294
6417
|
}
|
|
6295
6418
|
const MESSAGES_ENDPOINT = "/v1/messages";
|
|
@@ -6318,17 +6441,46 @@ messageRoutes.post("/count_tokens", async (c) => {
|
|
|
6318
6441
|
}
|
|
6319
6442
|
});
|
|
6320
6443
|
//#endregion
|
|
6444
|
+
//#region src/routes/models/codex-models.ts
|
|
6445
|
+
const logger$7 = createHandlerLogger("codex-models-handler");
|
|
6446
|
+
const CODEX_USER_AGENT_PATTERN = /^codex/iu;
|
|
6447
|
+
function isCodexUserAgent(userAgent) {
|
|
6448
|
+
return CODEX_USER_AGENT_PATTERN.test(userAgent?.trim() ?? "");
|
|
6449
|
+
}
|
|
6450
|
+
async function logCodexModelsResponse(response) {
|
|
6451
|
+
try {
|
|
6452
|
+
const responseText = await response.clone().text();
|
|
6453
|
+
debugJson(logger$7, "models.codex.response", {
|
|
6454
|
+
statusCode: response.status,
|
|
6455
|
+
models: responseText
|
|
6456
|
+
});
|
|
6457
|
+
} catch (error) {
|
|
6458
|
+
logger$7.warn("models.codex.response_log_error", { error });
|
|
6459
|
+
}
|
|
6460
|
+
}
|
|
6461
|
+
/**
|
|
6462
|
+
* Proxies a models request to the fixed Codex upstream models endpoint.
|
|
6463
|
+
* Returns a 404 JSON response when the codex provider is unavailable.
|
|
6464
|
+
* Pass `resolvedProviderConfig` when the caller already resolved the codex
|
|
6465
|
+
* provider to avoid a second resolve.
|
|
6466
|
+
*/
|
|
6467
|
+
async function handleCodexModelsProxy(c, resolvedProviderConfig) {
|
|
6468
|
+
if (!(resolvedProviderConfig ?? await resolveProviderConfig("codex"))) return c.json({ error: {
|
|
6469
|
+
message: "Provider 'codex' not found or disabled",
|
|
6470
|
+
type: "invalid_request_error"
|
|
6471
|
+
} }, 404);
|
|
6472
|
+
const upstreamResponse = await forwardCodexModels(c.req.url, c.req.raw.headers);
|
|
6473
|
+
await logCodexModelsResponse(upstreamResponse);
|
|
6474
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
6475
|
+
}
|
|
6476
|
+
//#endregion
|
|
6321
6477
|
//#region src/routes/models/route.ts
|
|
6322
6478
|
const modelRoutes = new Hono();
|
|
6323
|
-
const logger$
|
|
6479
|
+
const logger$6 = createHandlerLogger("models-handler");
|
|
6324
6480
|
const EPOCH_ISO = (/* @__PURE__ */ new Date(0)).toISOString();
|
|
6325
|
-
const CODEX_USER_AGENT_PATTERN = /^codex/iu;
|
|
6326
6481
|
function isRecord(value) {
|
|
6327
6482
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6328
6483
|
}
|
|
6329
|
-
function isCodexUserAgent(userAgent) {
|
|
6330
|
-
return CODEX_USER_AGENT_PATTERN.test(userAgent?.trim() ?? "");
|
|
6331
|
-
}
|
|
6332
6484
|
function normalizeCopilotModel(model) {
|
|
6333
6485
|
const contextWindow = model.capabilities?.limits?.max_context_window_tokens ?? 0;
|
|
6334
6486
|
const clientId = toClientModelId(model.id);
|
|
@@ -6373,7 +6525,7 @@ async function getProviderModels(provider, requestHeaders) {
|
|
|
6373
6525
|
if (providerConfig.name === "codex") return getModels().data.map((model) => normalizeProviderModel(providerConfig.name, model)).filter((model) => model !== null);
|
|
6374
6526
|
const response = await forwardProviderModels(providerConfig, requestHeaders);
|
|
6375
6527
|
if (!response.ok) {
|
|
6376
|
-
logger$
|
|
6528
|
+
logger$6.warn("models.provider.skip_non_ok", {
|
|
6377
6529
|
provider,
|
|
6378
6530
|
statusCode: response.status
|
|
6379
6531
|
});
|
|
@@ -6381,12 +6533,12 @@ async function getProviderModels(provider, requestHeaders) {
|
|
|
6381
6533
|
}
|
|
6382
6534
|
const body = await response.json();
|
|
6383
6535
|
if (!isRecord(body) || !Array.isArray(body.data)) {
|
|
6384
|
-
logger$
|
|
6536
|
+
logger$6.warn("models.provider.skip_invalid_body", { provider });
|
|
6385
6537
|
return [];
|
|
6386
6538
|
}
|
|
6387
6539
|
return body.data.map((model) => normalizeProviderModel(providerConfig.name, model)).filter((model) => model !== null);
|
|
6388
6540
|
} catch (error) {
|
|
6389
|
-
logger$
|
|
6541
|
+
logger$6.warn("models.provider.skip_error", {
|
|
6390
6542
|
provider,
|
|
6391
6543
|
error
|
|
6392
6544
|
});
|
|
@@ -6404,28 +6556,9 @@ async function getAggregatedModels(requestHeaders) {
|
|
|
6404
6556
|
return true;
|
|
6405
6557
|
});
|
|
6406
6558
|
}
|
|
6407
|
-
async function logCodexModelsResponse(response) {
|
|
6408
|
-
try {
|
|
6409
|
-
const responseText = await response.clone().text();
|
|
6410
|
-
debugJson(logger$4, "models.codex.response", {
|
|
6411
|
-
statusCode: response.status,
|
|
6412
|
-
models: responseText
|
|
6413
|
-
});
|
|
6414
|
-
} catch (error) {
|
|
6415
|
-
logger$4.warn("models.codex.response_log_error", { error });
|
|
6416
|
-
}
|
|
6417
|
-
}
|
|
6418
6559
|
modelRoutes.get("/", async (c) => {
|
|
6419
6560
|
try {
|
|
6420
|
-
if (isCodexUserAgent(c.req.header("user-agent")))
|
|
6421
|
-
if (!await resolveProviderConfig("codex")) return c.json({ error: {
|
|
6422
|
-
message: "Provider 'codex' not found or disabled",
|
|
6423
|
-
type: "invalid_request_error"
|
|
6424
|
-
} }, 404);
|
|
6425
|
-
const upstreamResponse = await forwardCodexModels(c.req.url, c.req.raw.headers);
|
|
6426
|
-
await logCodexModelsResponse(upstreamResponse);
|
|
6427
|
-
return createProviderProxyResponse(upstreamResponse);
|
|
6428
|
-
}
|
|
6561
|
+
if (isCodexUserAgent(c.req.header("user-agent"))) return await handleCodexModelsProxy(c);
|
|
6429
6562
|
const models = await getAggregatedModels(c.req.raw.headers);
|
|
6430
6563
|
return c.json({
|
|
6431
6564
|
object: "list",
|
|
@@ -6437,6 +6570,82 @@ modelRoutes.get("/", async (c) => {
|
|
|
6437
6570
|
}
|
|
6438
6571
|
});
|
|
6439
6572
|
//#endregion
|
|
6573
|
+
//#region src/routes/provider/alpha-search/route.ts
|
|
6574
|
+
const logger$5 = createHandlerLogger("provider-alpha-search-handler");
|
|
6575
|
+
const providerAlphaSearchRoutes = new Hono();
|
|
6576
|
+
providerAlphaSearchRoutes.post("/", async (c) => {
|
|
6577
|
+
const provider = c.req.param("provider") ?? "";
|
|
6578
|
+
try {
|
|
6579
|
+
const providerConfig = await resolveProviderConfig(provider);
|
|
6580
|
+
if (!providerConfig) return c.json({ error: {
|
|
6581
|
+
message: `Provider '${provider}' not found or disabled`,
|
|
6582
|
+
type: "invalid_request_error"
|
|
6583
|
+
} }, 404);
|
|
6584
|
+
if (providerConfig.name === "codex") return await handleCodexAlphaSearch(c, providerConfig);
|
|
6585
|
+
await debugJsonAsync(logger$5, "provider.alpha_search.request", async () => ({
|
|
6586
|
+
body: await c.req.raw.clone().text(),
|
|
6587
|
+
provider
|
|
6588
|
+
}));
|
|
6589
|
+
const upstreamResponse = await forwardProviderAlphaSearch(providerConfig, c.req.raw);
|
|
6590
|
+
await debugJsonAsync(logger$5, "provider.alpha_search.response", async () => ({
|
|
6591
|
+
body: await upstreamResponse.clone().text(),
|
|
6592
|
+
provider,
|
|
6593
|
+
statusCode: upstreamResponse.status
|
|
6594
|
+
}));
|
|
6595
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
6596
|
+
} catch (error) {
|
|
6597
|
+
logger$5.error("provider.alpha_search.error", {
|
|
6598
|
+
provider,
|
|
6599
|
+
error
|
|
6600
|
+
});
|
|
6601
|
+
return await forwardError(c, error);
|
|
6602
|
+
}
|
|
6603
|
+
});
|
|
6604
|
+
//#endregion
|
|
6605
|
+
//#region src/routes/provider/images/route.ts
|
|
6606
|
+
const logger$4 = createHandlerLogger("provider-images-handler");
|
|
6607
|
+
const providerImageRoutes = new Hono();
|
|
6608
|
+
function getContentMetadata(headers) {
|
|
6609
|
+
return {
|
|
6610
|
+
contentType: headers.get("content-type"),
|
|
6611
|
+
contentLength: headers.get("content-length")
|
|
6612
|
+
};
|
|
6613
|
+
}
|
|
6614
|
+
async function handleProviderImages(c, operation) {
|
|
6615
|
+
const provider = c.req.param("provider") ?? "";
|
|
6616
|
+
try {
|
|
6617
|
+
const providerConfig = await resolveProviderConfig(provider);
|
|
6618
|
+
if (!providerConfig) return c.json({ error: {
|
|
6619
|
+
message: `Provider '${provider}' not found or disabled`,
|
|
6620
|
+
type: "invalid_request_error"
|
|
6621
|
+
} }, 404);
|
|
6622
|
+
if (providerConfig.name === "codex") return await handleCodexImages(c, operation, providerConfig);
|
|
6623
|
+
if (operation === "generations") await debugJsonAsync(logger$4, "provider.images.generations.request", async () => ({
|
|
6624
|
+
body: await c.req.raw.clone().text(),
|
|
6625
|
+
provider
|
|
6626
|
+
}));
|
|
6627
|
+
else debugJson(logger$4, "provider.images.edits.request", {
|
|
6628
|
+
...getContentMetadata(c.req.raw.headers),
|
|
6629
|
+
provider
|
|
6630
|
+
});
|
|
6631
|
+
const upstreamResponse = await forwardProviderImages(providerConfig, c.req.raw, operation);
|
|
6632
|
+
debugJson(logger$4, `provider.images.${operation}.response`, {
|
|
6633
|
+
...getContentMetadata(upstreamResponse.headers),
|
|
6634
|
+
provider,
|
|
6635
|
+
statusCode: upstreamResponse.status
|
|
6636
|
+
});
|
|
6637
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
6638
|
+
} catch (error) {
|
|
6639
|
+
logger$4.error(`provider.images.${operation}.error`, {
|
|
6640
|
+
provider,
|
|
6641
|
+
error
|
|
6642
|
+
});
|
|
6643
|
+
return await forwardError(c, error);
|
|
6644
|
+
}
|
|
6645
|
+
}
|
|
6646
|
+
providerImageRoutes.post("/generations", (c) => handleProviderImages(c, "generations"));
|
|
6647
|
+
providerImageRoutes.post("/edits", (c) => handleProviderImages(c, "edits"));
|
|
6648
|
+
//#endregion
|
|
6440
6649
|
//#region src/routes/provider/messages/route.ts
|
|
6441
6650
|
const providerMessageRoutes = new Hono();
|
|
6442
6651
|
providerMessageRoutes.post("/", async (c) => {
|
|
@@ -6466,6 +6675,7 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
6466
6675
|
type: "invalid_request_error"
|
|
6467
6676
|
} }, 404);
|
|
6468
6677
|
if (providerConfig.name === "codex") {
|
|
6678
|
+
if (isCodexUserAgent(c.req.header("user-agent"))) return await handleCodexModelsProxy(c, providerConfig);
|
|
6469
6679
|
const models = getModels();
|
|
6470
6680
|
return c.json({
|
|
6471
6681
|
object: "list",
|
|
@@ -6620,6 +6830,20 @@ const isResponsesStream = (value) => {
|
|
|
6620
6830
|
return Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
|
|
6621
6831
|
};
|
|
6622
6832
|
//#endregion
|
|
6833
|
+
//#region src/routes/provider/responses/route.ts
|
|
6834
|
+
const providerResponsesRoutes = new Hono();
|
|
6835
|
+
providerResponsesRoutes.post("/", async (c) => {
|
|
6836
|
+
try {
|
|
6837
|
+
const provider = c.req.param("provider") ?? "";
|
|
6838
|
+
return await handleProviderResponsesForProvider(c, {
|
|
6839
|
+
payload: await c.req.json(),
|
|
6840
|
+
provider
|
|
6841
|
+
});
|
|
6842
|
+
} catch (error) {
|
|
6843
|
+
return await forwardError(c, error);
|
|
6844
|
+
}
|
|
6845
|
+
});
|
|
6846
|
+
//#endregion
|
|
6623
6847
|
//#region src/routes/responses/stream-id-sync.ts
|
|
6624
6848
|
const createStreamIdTracker = () => ({ outputItems: /* @__PURE__ */ new Map() });
|
|
6625
6849
|
const fixStreamIds = (data, event, tracker) => {
|
|
@@ -6910,14 +7134,20 @@ server.route("/token-usage", tokenUsageRoute);
|
|
|
6910
7134
|
server.route("/token", tokenRoute);
|
|
6911
7135
|
server.route("/responses", responsesRoutes);
|
|
6912
7136
|
server.route("/alpha/search", alphaSearchRoutes);
|
|
7137
|
+
server.route("/images", imageRoutes);
|
|
6913
7138
|
server.route("/v1/chat/completions", completionRoutes);
|
|
6914
7139
|
server.route("/v1/models", modelRoutes);
|
|
6915
7140
|
server.route("/v1/embeddings", embeddingRoutes);
|
|
6916
7141
|
server.route("/v1/responses", responsesRoutes);
|
|
7142
|
+
server.route("/v1/alpha/search", alphaSearchRoutes);
|
|
7143
|
+
server.route("/v1/images", imageRoutes);
|
|
6917
7144
|
server.route("/v1/messages", messageRoutes);
|
|
6918
7145
|
server.route("/:provider/v1/messages", providerMessageRoutes);
|
|
6919
7146
|
server.route("/:provider/v1/models", providerModelRoutes);
|
|
7147
|
+
server.route("/:provider/v1/responses", providerResponsesRoutes);
|
|
7148
|
+
server.route("/:provider/v1/alpha/search", providerAlphaSearchRoutes);
|
|
7149
|
+
server.route("/:provider/v1/images", providerImageRoutes);
|
|
6920
7150
|
//#endregion
|
|
6921
7151
|
export { server };
|
|
6922
7152
|
|
|
6923
|
-
//# sourceMappingURL=server-
|
|
7153
|
+
//# sourceMappingURL=server-BayMzJcy.js.map
|