@nick3/copilot-api 1.10.29 → 1.10.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/assets/{index-BAh4eOwM.js → index-BGmG-ckX.js} +34 -34
- package/dist/admin/index.html +1 -1
- package/dist/{auth-nO-eHeO_.js → auth-CnwhQOu6.js} +2 -2
- package/dist/{auth-nO-eHeO_.js.map → auth-CnwhQOu6.js.map} +1 -1
- package/dist/{check-usage-ZifYvA3w.js → check-usage-CseltoFJ.js} +2 -2
- package/dist/{check-usage-ZifYvA3w.js.map → check-usage-CseltoFJ.js.map} +1 -1
- package/dist/{config-CmhIPHn_.js → config-XZv75uoU.js} +15 -2
- package/dist/{config-CmhIPHn_.js.map → config-XZv75uoU.js.map} +1 -1
- package/dist/{debug-DvpksqEL.js → debug-D8xHblDV.js} +2 -2
- package/dist/{debug-DvpksqEL.js.map → debug-D8xHblDV.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{responses-bridge-registry-BJ5Sbh6-.js → responses-bridge-registry-JjUvTCST.js} +14 -7
- package/dist/responses-bridge-registry-JjUvTCST.js.map +1 -0
- package/dist/{server-DJ3_UGc4.js → server-BYKxAFro.js} +371 -90
- package/dist/server-BYKxAFro.js.map +1 -0
- package/dist/{start-DaB0AcjZ.js → start-DVlCJ0Ma.js} +4 -4
- package/dist/{start-DaB0AcjZ.js.map → start-DVlCJ0Ma.js.map} +1 -1
- package/dist/token-9O2KJcF5.js +946 -0
- package/dist/token-9O2KJcF5.js.map +1 -0
- package/package.json +2 -2
- package/dist/responses-bridge-registry-BJ5Sbh6-.js.map +0 -1
- package/dist/server-DJ3_UGc4.js.map +0 -1
- package/dist/token-DrFDLVxa.js +0 -365
- package/dist/token-DrFDLVxa.js.map +0 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { A as accountFromState, B as compactSystemPromptStarts, C as copilotHeaders, D as prepareForCompact, E as normalizeDomain, F as resolveTraceId, L as compactAutoContinuePromptStarts, M as captureOutboundHeadersSnapshot, O as prepareInteractionHeaders, P as requestContext, R as compactMessageSections, S as copilotBaseUrl, T as copilotWebSocketHeaders, b as HTTPError, c as getUUID, d as parseUserIdMetadata, f as resolveAffinityKey, g as getCopilotUsage, h as getDeviceCode, j as state, k as prepareMessageProxyHeaders, l as isNullish, m as getGitHubUser, o as generateRequestIdFromPayload, p as sleep, s as getRootSessionId, t as pollAccessToken, u as normalizeStableSessionId, v as getProxyEnvDispatcher, x as forwardError } from "./poll-access-token-GzVkiTH8.js";
|
|
2
2
|
import { a as getAccountClientIdentityByLoginAndApp, b as getCurrentIdentityEnvironment, d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, p as removeAccountFromRegistry, r as addAccountToRegistry, t as isAccountType } from "./account-DpW8RaT6.js";
|
|
3
3
|
import { r as ensurePaths, t as PATHS } from "./paths-Bpsb62LK.js";
|
|
4
|
-
import { C as isResponsesApiWebSocketEnabled,
|
|
4
|
+
import { C as isResponsesApiWebSocketEnabled, D as resolveModelAlias, E as resolveMappedModel, S as isResponsesApiWebSearchEnabled, T as mergeConfigWithDefaults, _ as isAccountAffinityEnabled, a as getConfig, b as isMessagesApiEnabled, c as getModelAliases, d as getProviderConfig, g as getSmallModel, i as getClaudeTokenMultiplier, k as shouldCompactUseSmallModel, l as getModelAliasesInfo, m as getReasoningEffortForModel, n as getAliasTargetSet, o as getExtraPromptForModel, p as getRawProviderConfig, r as getAnthropicApiKey, s as getLogLevel, t as PROVIDER_TYPE_ANTHROPIC, u as getModelRefreshIntervalMs, v as isForceAgentEnabled, x as isResponsesApiContextManagementEnabled, y as isMessageStartInputTokensFallbackEnabled } from "./config-XZv75uoU.js";
|
|
5
|
+
import { a as forwardCodexResponses, n as setupCodexToken } from "./token-9O2KJcF5.js";
|
|
5
6
|
import { i as getRequestOutboundStore, r as getRedactedHeaderKeys } from "./request-outbound-DZTxxtcx.js";
|
|
6
7
|
import { i as isMcpHttpEnabledFromEnv, n as DEFAULT_MCP_HTTP_PATH } from "./mcp-http-config-DMdUDz1D.js";
|
|
7
8
|
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, i as isBridgeToolSearchName, l as selectDeferredToolsByNames, n as BRIDGE_TOOL_SEARCH_NAME, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, u as shouldEnableResponsesToolSearch } from "./mcp-server-DEqHrXFq.js";
|
|
8
9
|
import { n as handleStreamableHttpMcpRequest, r as mcpHttpCorsOptions } from "./mcp-http-DI4Vz01p.js";
|
|
9
|
-
import {
|
|
10
|
+
import { C as createAuthMiddleware, S as isDevModeEnabled, _ as normalizeMessagesUsage, b as copilotFetch, c as accountsManager, d as extractResponsesUsageFromStreamEvent, f as getClientIpInfo, g as normalizeEmbeddingsUsage, h as normalizeChatCompletionsUsage, l as applySharedSessionAffinityRetention, m as getStatsStore, p as getRequestHistoryStore, s as updateQuotaRefreshSchedulerFromConfig, t as closeResponsesBridge, u as extractResponsesUsageFromResult, v as normalizeResponsesUsage, x as flushPendingCapture, y as toLocalDateString } from "./responses-bridge-registry-JjUvTCST.js";
|
|
10
11
|
import consola from "consola";
|
|
11
12
|
import fs, { readFile } from "node:fs/promises";
|
|
12
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -2499,13 +2500,22 @@ adminApiRoutes.get("/accounts", async (c) => {
|
|
|
2499
2500
|
unlimited: s.unlimited,
|
|
2500
2501
|
failed: s.failed,
|
|
2501
2502
|
failureReason: s.failureReason,
|
|
2502
|
-
enabled: s.enabled
|
|
2503
|
+
enabled: s.enabled,
|
|
2504
|
+
lastModelsFetch: s.lastModelsFetch,
|
|
2505
|
+
isRefreshingModels: s.isRefreshingModels
|
|
2503
2506
|
},
|
|
2504
2507
|
stats
|
|
2505
2508
|
};
|
|
2506
2509
|
});
|
|
2507
2510
|
return c.json({ items });
|
|
2508
2511
|
});
|
|
2512
|
+
adminApiRoutes.post("/accounts/models/refresh", async (c) => {
|
|
2513
|
+
const { failedCount } = await accountsManager.refreshAllModelsNow();
|
|
2514
|
+
return c.json({
|
|
2515
|
+
ok: true,
|
|
2516
|
+
failedCount
|
|
2517
|
+
});
|
|
2518
|
+
});
|
|
2509
2519
|
adminApiRoutes.get("/requests", (c) => {
|
|
2510
2520
|
const p = new URL(c.req.url, "http://local").searchParams;
|
|
2511
2521
|
const limit = parseFiniteNumber(p.get("limit")) ?? 50;
|
|
@@ -3870,7 +3880,7 @@ function selectionFailureResponse$2(c, params) {
|
|
|
3870
3880
|
}
|
|
3871
3881
|
//#endregion
|
|
3872
3882
|
//#region src/routes/chat-completions/handler.ts
|
|
3873
|
-
const logger$
|
|
3883
|
+
const logger$7 = createHandlerLogger("chat-completions-handler");
|
|
3874
3884
|
function buildChatCompletionCandidates(clientModel) {
|
|
3875
3885
|
return [{
|
|
3876
3886
|
modelId: clientModel,
|
|
@@ -4007,12 +4017,12 @@ async function writeChatCompletionsStreamError(stream, message) {
|
|
|
4007
4017
|
} }) });
|
|
4008
4018
|
await stream.writeSSE({ data: "[DONE]" });
|
|
4009
4019
|
} catch (streamError) {
|
|
4010
|
-
logger$
|
|
4020
|
+
logger$7.warn("Failed to write chat completions stream error event:", streamError);
|
|
4011
4021
|
}
|
|
4012
4022
|
}
|
|
4013
4023
|
async function selectChatCompletionAccount(params) {
|
|
4014
4024
|
const { c, store, request, payload, clientModel, streamRequested, normalizedPromptCacheKey } = params;
|
|
4015
|
-
debugJsonTail(logger$
|
|
4025
|
+
debugJsonTail(logger$7, "Request payload:", {
|
|
4016
4026
|
value: payload,
|
|
4017
4027
|
tailLength: 400
|
|
4018
4028
|
});
|
|
@@ -4047,9 +4057,9 @@ async function selectChatCompletionAccount(params) {
|
|
|
4047
4057
|
async function logTokenCountForRequest(params) {
|
|
4048
4058
|
try {
|
|
4049
4059
|
const tokenCount = await getTokenCount(params.payload, params.selectedModel);
|
|
4050
|
-
logger$
|
|
4060
|
+
logger$7.info("Current token count:", tokenCount);
|
|
4051
4061
|
} catch (error) {
|
|
4052
|
-
logger$
|
|
4062
|
+
logger$7.warn("Failed to calculate token count:", error);
|
|
4053
4063
|
}
|
|
4054
4064
|
}
|
|
4055
4065
|
function applyDefaultMaxTokens(payload, selectedModel) {
|
|
@@ -4058,7 +4068,7 @@ function applyDefaultMaxTokens(payload, selectedModel) {
|
|
|
4058
4068
|
...payload,
|
|
4059
4069
|
max_tokens: selectedModel.capabilities.limits.max_output_tokens
|
|
4060
4070
|
};
|
|
4061
|
-
debugJson(logger$
|
|
4071
|
+
debugJson(logger$7, "Set max_tokens to:", updated.max_tokens);
|
|
4062
4072
|
return updated;
|
|
4063
4073
|
}
|
|
4064
4074
|
async function handleStreamingRequest(params) {
|
|
@@ -4092,7 +4102,7 @@ async function handleStreamingRequest(params) {
|
|
|
4092
4102
|
premiumUnlimitedBefore,
|
|
4093
4103
|
response
|
|
4094
4104
|
});
|
|
4095
|
-
logger$
|
|
4105
|
+
logger$7.debug("Streaming response");
|
|
4096
4106
|
return streamSSE(c, (stream) => streamChatCompletionsAndLog$1({
|
|
4097
4107
|
stream,
|
|
4098
4108
|
response,
|
|
@@ -4147,7 +4157,7 @@ async function handleNonStreamingUpstreamResponse(params) {
|
|
|
4147
4157
|
let upstreamErrorMessageRaw;
|
|
4148
4158
|
const finishedAtMs = Date.now();
|
|
4149
4159
|
try {
|
|
4150
|
-
debugJson(logger$
|
|
4160
|
+
debugJson(logger$7, "Non-streaming response:", response);
|
|
4151
4161
|
return c.json(response);
|
|
4152
4162
|
} catch (error) {
|
|
4153
4163
|
const details = await extractErrorObservability(error);
|
|
@@ -4200,7 +4210,7 @@ async function streamChatCompletionsAndLog$1(params) {
|
|
|
4200
4210
|
if (ttfbMs === void 0) ttfbMs = Date.now() - request.startedAtMs;
|
|
4201
4211
|
const usage = await extractUsageFromChunk(chunk);
|
|
4202
4212
|
if (usage) lastUsage = usage;
|
|
4203
|
-
debugJson(logger$
|
|
4213
|
+
debugJson(logger$7, "Streaming chunk:", chunk);
|
|
4204
4214
|
await stream.writeSSE(chunk);
|
|
4205
4215
|
}
|
|
4206
4216
|
} catch (error) {
|
|
@@ -4209,7 +4219,7 @@ async function streamChatCompletionsAndLog$1(params) {
|
|
|
4209
4219
|
errorStatus = details.errorStatus;
|
|
4210
4220
|
errorMessage = details.errorMessage;
|
|
4211
4221
|
upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
|
|
4212
|
-
logger$
|
|
4222
|
+
logger$7.warn("Streaming error:", error);
|
|
4213
4223
|
if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(account.id, "Unauthorized (401)");
|
|
4214
4224
|
await writeChatCompletionsStreamError(stream, getUserVisibleErrorMessage(details));
|
|
4215
4225
|
} finally {
|
|
@@ -4247,7 +4257,7 @@ async function extractUsageFromChunk(chunk) {
|
|
|
4247
4257
|
try {
|
|
4248
4258
|
data = typeof chunk.data === "string" ? chunk.data : await chunk.data;
|
|
4249
4259
|
} catch (error) {
|
|
4250
|
-
logger$
|
|
4260
|
+
logger$7.warn("Failed to read chat completions usage chunk:", error);
|
|
4251
4261
|
return;
|
|
4252
4262
|
}
|
|
4253
4263
|
if (!data || data === "[DONE]") return;
|
|
@@ -4256,7 +4266,7 @@ async function extractUsageFromChunk(chunk) {
|
|
|
4256
4266
|
if (!parsed.usage) return void 0;
|
|
4257
4267
|
return normalizeChatCompletionsUsage(parsed.usage);
|
|
4258
4268
|
} catch (error) {
|
|
4259
|
-
logger$
|
|
4269
|
+
logger$7.warn("Failed to parse chat completions usage chunk:", {
|
|
4260
4270
|
error,
|
|
4261
4271
|
data
|
|
4262
4272
|
});
|
|
@@ -4283,7 +4293,7 @@ async function handleNonStreamingRequest(params) {
|
|
|
4283
4293
|
selection.confirmAffinity?.();
|
|
4284
4294
|
finishedAtMs = Date.now();
|
|
4285
4295
|
usage = normalizeChatCompletionsUsage(response.usage);
|
|
4286
|
-
debugJson(logger$
|
|
4296
|
+
debugJson(logger$7, "Non-streaming response:", response);
|
|
4287
4297
|
return c.json(response);
|
|
4288
4298
|
} catch (error) {
|
|
4289
4299
|
finishedAtMs = Date.now();
|
|
@@ -4541,8 +4551,8 @@ const createFallbackModel = (modelId) => ({
|
|
|
4541
4551
|
});
|
|
4542
4552
|
//#endregion
|
|
4543
4553
|
//#region src/routes/provider/messages/count-tokens-handler.ts
|
|
4544
|
-
const logger$
|
|
4545
|
-
const resolveProviderConfig$
|
|
4554
|
+
const logger$6 = createHandlerLogger("provider-count-tokens-handler");
|
|
4555
|
+
const resolveProviderConfig$3 = (c, provider) => {
|
|
4546
4556
|
return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
|
|
4547
4557
|
};
|
|
4548
4558
|
async function handleProviderCountTokens(c) {
|
|
@@ -4555,7 +4565,7 @@ async function handleProviderCountTokens(c) {
|
|
|
4555
4565
|
async function handleProviderCountTokensForProvider(c, options) {
|
|
4556
4566
|
const { payload: anthropicPayload, provider } = options;
|
|
4557
4567
|
normalizeSystemMessages(anthropicPayload);
|
|
4558
|
-
const providerConfig = resolveProviderConfig$
|
|
4568
|
+
const providerConfig = resolveProviderConfig$3(c, provider);
|
|
4559
4569
|
if (!providerConfig) return c.json({ error: {
|
|
4560
4570
|
message: `Provider '${provider}' not found or disabled`,
|
|
4561
4571
|
type: "invalid_request_error"
|
|
@@ -4573,14 +4583,14 @@ async function handleProviderCountTokensForProvider(c, options) {
|
|
|
4573
4583
|
try {
|
|
4574
4584
|
const tokenCount = await getTokenCount(translateToOpenAI(anthropicPayload, translationOptions), findEndpointModel(modelId) ?? createFallbackModel(modelId));
|
|
4575
4585
|
const finalTokenCount = tokenCount.input + tokenCount.output;
|
|
4576
|
-
logger$
|
|
4586
|
+
logger$6.debug("provider.count_tokens.success", {
|
|
4577
4587
|
provider,
|
|
4578
4588
|
model: anthropicPayload.model,
|
|
4579
4589
|
input_tokens: finalTokenCount
|
|
4580
4590
|
});
|
|
4581
4591
|
return c.json({ input_tokens: finalTokenCount });
|
|
4582
4592
|
} catch (error) {
|
|
4583
|
-
logger$
|
|
4593
|
+
logger$6.error("provider.count_tokens.error", {
|
|
4584
4594
|
provider,
|
|
4585
4595
|
error
|
|
4586
4596
|
});
|
|
@@ -6073,6 +6083,13 @@ async function forwardProviderChatCompletions(providerConfig, payload, requestHe
|
|
|
6073
6083
|
body: JSON.stringify(payload)
|
|
6074
6084
|
});
|
|
6075
6085
|
}
|
|
6086
|
+
async function forwardProviderResponses(providerConfig, payload, requestHeaders) {
|
|
6087
|
+
return await fetch(`${providerConfig.baseUrl}/v1/responses`, {
|
|
6088
|
+
method: "POST",
|
|
6089
|
+
headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
|
|
6090
|
+
body: JSON.stringify(payload)
|
|
6091
|
+
});
|
|
6092
|
+
}
|
|
6076
6093
|
async function forwardProviderModels(providerConfig, requestHeaders, fetchImpl = fetch) {
|
|
6077
6094
|
return await fetchImpl(`${providerConfig.baseUrl}/v1/models`, {
|
|
6078
6095
|
method: "GET",
|
|
@@ -6081,9 +6098,9 @@ async function forwardProviderModels(providerConfig, requestHeaders, fetchImpl =
|
|
|
6081
6098
|
}
|
|
6082
6099
|
//#endregion
|
|
6083
6100
|
//#region src/routes/provider/messages/handler.ts
|
|
6084
|
-
const logger$
|
|
6101
|
+
const logger$5 = createHandlerLogger("provider-messages-handler");
|
|
6085
6102
|
const getProviderFetch$1 = (c) => c.get("providerFetch") ?? fetch;
|
|
6086
|
-
const resolveProviderConfig$
|
|
6103
|
+
const resolveProviderConfig$2 = (c, provider) => {
|
|
6087
6104
|
return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
|
|
6088
6105
|
};
|
|
6089
6106
|
const OPENAI_COMPATIBLE_CONTEXT_CACHE_MARKER_LIMIT = 4;
|
|
@@ -6107,7 +6124,7 @@ const writeProviderStreamError = async (stream, message) => {
|
|
|
6107
6124
|
})
|
|
6108
6125
|
});
|
|
6109
6126
|
} catch (error) {
|
|
6110
|
-
logger$
|
|
6127
|
+
logger$5.warn("Failed to write provider stream error event", error);
|
|
6111
6128
|
}
|
|
6112
6129
|
};
|
|
6113
6130
|
async function handleProviderMessages(c) {
|
|
@@ -6119,7 +6136,7 @@ async function handleProviderMessages(c) {
|
|
|
6119
6136
|
}
|
|
6120
6137
|
async function handleProviderMessagesForProvider(c, options) {
|
|
6121
6138
|
const { instrumentation, payload, provider } = options;
|
|
6122
|
-
const providerConfig = resolveProviderConfig$
|
|
6139
|
+
const providerConfig = resolveProviderConfig$2(c, provider);
|
|
6123
6140
|
if (!providerConfig) {
|
|
6124
6141
|
const message = `Provider '${provider}' not found or disabled`;
|
|
6125
6142
|
instrumentation?.onError?.({
|
|
@@ -6136,7 +6153,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
6136
6153
|
try {
|
|
6137
6154
|
const modelConfig = providerConfig.models?.[payload.model];
|
|
6138
6155
|
applyModelDefaults(payload, modelConfig);
|
|
6139
|
-
debugJson(logger$
|
|
6156
|
+
debugJson(logger$5, "provider.messages.request", {
|
|
6140
6157
|
payload,
|
|
6141
6158
|
provider
|
|
6142
6159
|
});
|
|
@@ -6150,7 +6167,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
6150
6167
|
applyMissingExtraBody(payload, { extraBody: modelConfig?.extraBody });
|
|
6151
6168
|
const upstreamResponse = await forwardProviderMessages(providerConfig, payload, c.req.raw.headers, getProviderFetch$1(c));
|
|
6152
6169
|
if (!upstreamResponse.ok) {
|
|
6153
|
-
logger$
|
|
6170
|
+
logger$5.error("Failed to create responses", upstreamResponse);
|
|
6154
6171
|
throw new HTTPError("Failed to create responses", upstreamResponse);
|
|
6155
6172
|
}
|
|
6156
6173
|
const contentType = upstreamResponse.headers.get("content-type") ?? "";
|
|
@@ -6170,7 +6187,7 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
6170
6187
|
providerConfig
|
|
6171
6188
|
});
|
|
6172
6189
|
} catch (error) {
|
|
6173
|
-
logger$
|
|
6190
|
+
logger$5.error("provider.messages.error", {
|
|
6174
6191
|
provider,
|
|
6175
6192
|
error
|
|
6176
6193
|
});
|
|
@@ -6207,13 +6224,13 @@ const applyOpenAICompatibleExtraBodyThinkingBudget = (payload, options) => {
|
|
|
6207
6224
|
const handleOpenAICompatibleProviderMessages = async (c, options) => {
|
|
6208
6225
|
const { instrumentation, modelConfig, payload, provider, providerConfig } = options;
|
|
6209
6226
|
const openAIPayload = createOpenAICompatiblePayload(payload, modelConfig);
|
|
6210
|
-
debugJson(logger$
|
|
6227
|
+
debugJson(logger$5, "provider.messages.openai_compatible.request", {
|
|
6211
6228
|
payload: openAIPayload,
|
|
6212
6229
|
provider
|
|
6213
6230
|
});
|
|
6214
6231
|
const upstreamResponse = await forwardProviderChatCompletions(providerConfig, openAIPayload, c.req.raw.headers, getProviderFetch$1(c));
|
|
6215
6232
|
if (!upstreamResponse.ok) {
|
|
6216
|
-
logger$
|
|
6233
|
+
logger$5.error("Failed to create openai-compatible responses", upstreamResponse);
|
|
6217
6234
|
throw new HTTPError("Failed to create openai-compatible responses", upstreamResponse);
|
|
6218
6235
|
}
|
|
6219
6236
|
const contentType = upstreamResponse.headers.get("content-type") ?? "";
|
|
@@ -6297,13 +6314,13 @@ const setContextCacheControl = (part) => {
|
|
|
6297
6314
|
part.cache_control = { ...OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL };
|
|
6298
6315
|
};
|
|
6299
6316
|
const streamProviderMessages = ({ c, instrumentation, providerConfig, upstreamResponse }) => {
|
|
6300
|
-
logger$
|
|
6317
|
+
logger$5.debug("provider.messages.streaming");
|
|
6301
6318
|
return streamSSE(c, async (stream) => {
|
|
6302
6319
|
let usage = {};
|
|
6303
6320
|
try {
|
|
6304
6321
|
let completed = false;
|
|
6305
6322
|
for await (const chunk of events(upstreamResponse)) {
|
|
6306
|
-
logger$
|
|
6323
|
+
logger$5.debug("provider.messages.raw_stream_event:", chunk.data);
|
|
6307
6324
|
const eventName = chunk.event;
|
|
6308
6325
|
if (eventName === "ping") {
|
|
6309
6326
|
await stream.writeSSE({
|
|
@@ -6339,14 +6356,14 @@ const streamProviderMessages = ({ c, instrumentation, providerConfig, upstreamRe
|
|
|
6339
6356
|
instrumentation?.onComplete?.(usage);
|
|
6340
6357
|
} catch (error) {
|
|
6341
6358
|
const details = await extractErrorObservability(error);
|
|
6342
|
-
logger$
|
|
6359
|
+
logger$5.warn("provider.messages.streaming.error", error);
|
|
6343
6360
|
instrumentation?.onError?.(details);
|
|
6344
6361
|
await writeProviderStreamError(stream, getUserVisibleErrorMessage(details));
|
|
6345
6362
|
}
|
|
6346
6363
|
});
|
|
6347
6364
|
};
|
|
6348
6365
|
const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamResponse }) => {
|
|
6349
|
-
logger$
|
|
6366
|
+
logger$5.debug("provider.messages.openai_compatible.streaming");
|
|
6350
6367
|
return streamSSE(c, async (stream) => {
|
|
6351
6368
|
let usage = {};
|
|
6352
6369
|
const streamState = {
|
|
@@ -6359,7 +6376,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamRe
|
|
|
6359
6376
|
try {
|
|
6360
6377
|
let completed = false;
|
|
6361
6378
|
for await (const chunk of events(upstreamResponse)) {
|
|
6362
|
-
logger$
|
|
6379
|
+
logger$5.debug("provider.messages.openai_compatible.raw_stream_event:", chunk.data);
|
|
6363
6380
|
if (chunk.event === "ping") {
|
|
6364
6381
|
await stream.writeSSE({
|
|
6365
6382
|
event: "ping",
|
|
@@ -6377,7 +6394,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamRe
|
|
|
6377
6394
|
const events = translateChunkToAnthropicEvents(parsed, streamState);
|
|
6378
6395
|
for (const event of events) {
|
|
6379
6396
|
const eventData = JSON.stringify(event);
|
|
6380
|
-
debugLazy(logger$
|
|
6397
|
+
debugLazy(logger$5, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
6381
6398
|
await stream.writeSSE({
|
|
6382
6399
|
event: event.type,
|
|
6383
6400
|
data: eventData
|
|
@@ -6387,7 +6404,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamRe
|
|
|
6387
6404
|
}
|
|
6388
6405
|
for (const event of flushPendingAnthropicStreamEvents(streamState)) {
|
|
6389
6406
|
const eventData = JSON.stringify(event);
|
|
6390
|
-
debugLazy(logger$
|
|
6407
|
+
debugLazy(logger$5, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
6391
6408
|
await stream.writeSSE({
|
|
6392
6409
|
event: event.type,
|
|
6393
6410
|
data: eventData
|
|
@@ -6398,7 +6415,7 @@ const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamRe
|
|
|
6398
6415
|
instrumentation?.onComplete?.(usage);
|
|
6399
6416
|
} catch (error) {
|
|
6400
6417
|
const details = await extractErrorObservability(error);
|
|
6401
|
-
logger$
|
|
6418
|
+
logger$5.warn("provider.messages.openai_compatible.streaming.error", error);
|
|
6402
6419
|
instrumentation?.onError?.(details);
|
|
6403
6420
|
await writeProviderStreamError(stream, getUserVisibleErrorMessage(details));
|
|
6404
6421
|
}
|
|
@@ -6409,7 +6426,7 @@ const parseOpenAICompatibleStreamChunk = (data) => {
|
|
|
6409
6426
|
try {
|
|
6410
6427
|
parsed = JSON.parse(data);
|
|
6411
6428
|
} catch (error) {
|
|
6412
|
-
logger$
|
|
6429
|
+
logger$5.error("provider.messages.openai_compatible.parse_chunk_error", {
|
|
6413
6430
|
data,
|
|
6414
6431
|
error
|
|
6415
6432
|
});
|
|
@@ -6466,7 +6483,7 @@ const parseProviderStreamEvent = (data, providerConfig) => {
|
|
|
6466
6483
|
usage: {}
|
|
6467
6484
|
};
|
|
6468
6485
|
} catch (error) {
|
|
6469
|
-
logger$
|
|
6486
|
+
logger$5.error("provider.messages.streaming.adjust_tokens_error", {
|
|
6470
6487
|
error,
|
|
6471
6488
|
originalData: data
|
|
6472
6489
|
});
|
|
@@ -6476,7 +6493,7 @@ const parseProviderStreamEvent = (data, providerConfig) => {
|
|
|
6476
6493
|
const respondProviderMessagesJson = (c, options) => {
|
|
6477
6494
|
const { body, instrumentation, providerConfig } = options;
|
|
6478
6495
|
adjustInputTokens(providerConfig, body.usage);
|
|
6479
|
-
debugJson(logger$
|
|
6496
|
+
debugJson(logger$5, "provider.messages.no_stream result:", body);
|
|
6480
6497
|
const response = c.json(body);
|
|
6481
6498
|
instrumentation?.onComplete?.(normalizeAnthropicUsage(body.usage));
|
|
6482
6499
|
return response;
|
|
@@ -6484,7 +6501,7 @@ const respondProviderMessagesJson = (c, options) => {
|
|
|
6484
6501
|
const respondOpenAICompatibleProviderMessagesJson = (c, options) => {
|
|
6485
6502
|
const { body, instrumentation } = options;
|
|
6486
6503
|
const anthropicResponse = translateToAnthropic(body);
|
|
6487
|
-
debugJson(logger$
|
|
6504
|
+
debugJson(logger$5, "provider.messages.openai_compatible.no_stream result:", anthropicResponse);
|
|
6488
6505
|
const response = c.json(anthropicResponse);
|
|
6489
6506
|
instrumentation?.onComplete?.(normalizeOpenAIUsage(body.usage));
|
|
6490
6507
|
return response;
|
|
@@ -6514,7 +6531,7 @@ const mergeAnthropicUsage = (current, next) => ({
|
|
|
6514
6531
|
const adjustInputTokens = (providerConfig, usage) => {
|
|
6515
6532
|
if (!providerConfig.adjustInputTokens || !usage) return;
|
|
6516
6533
|
usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
|
|
6517
|
-
debugJson(logger$
|
|
6534
|
+
debugJson(logger$5, "provider.messages.adjusted_usage:", usage);
|
|
6518
6535
|
};
|
|
6519
6536
|
//#endregion
|
|
6520
6537
|
//#region src/routes/messages/responses-stream-translation.ts
|
|
@@ -7021,7 +7038,8 @@ const isAgentRole = (item) => {
|
|
|
7021
7038
|
const hasVisionInput$1 = (payload) => {
|
|
7022
7039
|
return getPayloadItems(payload).some((item) => containsVisionContent(item));
|
|
7023
7040
|
};
|
|
7024
|
-
""
|
|
7041
|
+
const DATA_URL_PREFIX = "data:";
|
|
7042
|
+
const REDACTED_IMAGE_PLACEHOLDER_DATA_URL = "data:image/png;base64," + [
|
|
7025
7043
|
"iVBORw0KGgoAAAANSUhEUgAAAGAAAAAgCAMAAADaHo1mAAADAFBMVEX///8fKTfR1dsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
|
7026
7044
|
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
|
7027
7045
|
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
|
@@ -7038,6 +7056,62 @@ const hasVisionInput$1 = (payload) => {
|
|
|
7038
7056
|
"ucSQ4s8JkKDDIYr3IuR8vEWgqroKP9b1bYKk2wfgeVmqATQLXdXamsXdEKkz3QXEEeTTuWWImMhW6qci94/+hwSVf99HqVoD",
|
|
7039
7057
|
"OAuj2SEAAAAASUVORK5CYII="
|
|
7040
7058
|
].join("");
|
|
7059
|
+
const sanitizeOversizedInputImages = (payload, maxPromptImageSize) => {
|
|
7060
|
+
const limit = typeof maxPromptImageSize === "number" && maxPromptImageSize > 0 ? maxPromptImageSize : void 0;
|
|
7061
|
+
if (limit === void 0 || !Array.isArray(payload.input)) return 0;
|
|
7062
|
+
return sanitizeInputImages(payload.input, (image) => image.decodedBytes > limit);
|
|
7063
|
+
};
|
|
7064
|
+
const sanitizeInputImages = (input, shouldReplace) => {
|
|
7065
|
+
let count = 0;
|
|
7066
|
+
for (const image of collectInputImageDataUrls(input)) {
|
|
7067
|
+
if (!shouldReplace(image)) continue;
|
|
7068
|
+
replaceInputImageWithPlaceholder(image);
|
|
7069
|
+
count += 1;
|
|
7070
|
+
}
|
|
7071
|
+
return count;
|
|
7072
|
+
};
|
|
7073
|
+
const collectInputImageDataUrls = (input, images = []) => {
|
|
7074
|
+
for (const item of input) collectInputItemImageDataUrls(item, images);
|
|
7075
|
+
return images;
|
|
7076
|
+
};
|
|
7077
|
+
const collectInputItemImageDataUrls = (item, images) => {
|
|
7078
|
+
if (isResponseInputMessage(item)) collectContentImageDataUrls(item.content, images);
|
|
7079
|
+
else if (isResponseFunctionCallOutputItem(item)) collectContentImageDataUrls(item.output, images);
|
|
7080
|
+
};
|
|
7081
|
+
const collectContentImageDataUrls = (content, images) => {
|
|
7082
|
+
if (!Array.isArray(content)) return;
|
|
7083
|
+
for (const block of content) {
|
|
7084
|
+
const image = getInputImageDataUrl(block);
|
|
7085
|
+
if (image) images.push(image);
|
|
7086
|
+
}
|
|
7087
|
+
};
|
|
7088
|
+
const getInputImageDataUrl = (content) => {
|
|
7089
|
+
if (!isResponseInputImage(content) || typeof content.image_url !== "string") return null;
|
|
7090
|
+
const imageUrl = content.image_url;
|
|
7091
|
+
if (!imageUrl.startsWith(DATA_URL_PREFIX)) return null;
|
|
7092
|
+
return {
|
|
7093
|
+
decodedBytes: estimateDataUrlByteLength(imageUrl),
|
|
7094
|
+
record: content
|
|
7095
|
+
};
|
|
7096
|
+
};
|
|
7097
|
+
const estimateDataUrlByteLength = (value) => {
|
|
7098
|
+
return Math.max(0, Math.floor(value.length * 3 / 4));
|
|
7099
|
+
};
|
|
7100
|
+
const replaceInputImageWithPlaceholder = (image) => {
|
|
7101
|
+
image.record.type = "input_image";
|
|
7102
|
+
image.record.image_url = REDACTED_IMAGE_PLACEHOLDER_DATA_URL;
|
|
7103
|
+
image.record.detail = "low";
|
|
7104
|
+
delete image.record.file_id;
|
|
7105
|
+
};
|
|
7106
|
+
const isResponseInputMessage = (item) => {
|
|
7107
|
+
return typeof item === "object" && item !== null && "role" in item && typeof item.role === "string";
|
|
7108
|
+
};
|
|
7109
|
+
const isResponseFunctionCallOutputItem = (item) => {
|
|
7110
|
+
return typeof item === "object" && item !== null && "type" in item && item.type === "function_call_output";
|
|
7111
|
+
};
|
|
7112
|
+
const isResponseInputImage = (content) => {
|
|
7113
|
+
return typeof content === "object" && content !== null && "type" in content && content.type === "input_image";
|
|
7114
|
+
};
|
|
7041
7115
|
const resolveResponsesCompactThreshold = (maxPromptTokens, compactThresholdRatio = DEFAULT_RESPONSES_COMPACT_THRESHOLD_RATIO) => {
|
|
7042
7116
|
if (typeof maxPromptTokens === "number" && maxPromptTokens > 0) return Math.floor(maxPromptTokens * compactThresholdRatio);
|
|
7043
7117
|
return 2e5 * compactThresholdRatio;
|
|
@@ -7291,7 +7365,7 @@ const extractBalancedJson = (text) => {
|
|
|
7291
7365
|
};
|
|
7292
7366
|
//#endregion
|
|
7293
7367
|
//#region src/routes/messages/handler.ts
|
|
7294
|
-
const logger$
|
|
7368
|
+
const logger$4 = createHandlerLogger("messages-handler");
|
|
7295
7369
|
const CHAT_COMPLETIONS_ENDPOINT = "/chat/completions";
|
|
7296
7370
|
const RESPONSES_ENDPOINT$1 = "/responses";
|
|
7297
7371
|
const MESSAGES_ENDPOINT = "/v1/messages";
|
|
@@ -7337,7 +7411,7 @@ async function handleProviderAliasCompletion(c, options) {
|
|
|
7337
7411
|
let requestRecorded = false;
|
|
7338
7412
|
const insertProviderAliasLog = (record) => {
|
|
7339
7413
|
if (requestRecorded) {
|
|
7340
|
-
logger$
|
|
7414
|
+
logger$4.warn("provider alias request already recorded", { requestId });
|
|
7341
7415
|
return;
|
|
7342
7416
|
}
|
|
7343
7417
|
requestRecorded = true;
|
|
@@ -7412,14 +7486,14 @@ async function handleCompletion(c) {
|
|
|
7412
7486
|
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
7413
7487
|
normalizeSystemMessages(anthropicPayload);
|
|
7414
7488
|
sanitizeIdeTools(anthropicPayload);
|
|
7415
|
-
debugJson(logger$
|
|
7489
|
+
debugJson(logger$4, "Anthropic request payload:", anthropicPayload);
|
|
7416
7490
|
const markerInspection = inspectSubagentMarkerFromFirstUser(anthropicPayload);
|
|
7417
7491
|
const subagentMarker = markerInspection.kind === "valid" ? markerInspection.marker : null;
|
|
7418
7492
|
const isSubagentRequest = subagentMarker !== null;
|
|
7419
7493
|
const invalidSubagentMarkerSelectionReason = markerInspection.kind === "invalid" ? "subagent_marker_invalid_fallback" : void 0;
|
|
7420
|
-
if (subagentMarker) debugJson(logger$
|
|
7494
|
+
if (subagentMarker) debugJson(logger$4, "Detected Subagent marker:", subagentMarker);
|
|
7421
7495
|
const sessionId = getRootSessionId(anthropicPayload, c);
|
|
7422
|
-
logger$
|
|
7496
|
+
logger$4.debug("Extracted session ID:", sessionId);
|
|
7423
7497
|
const ownershipLookupSessionId = markerInspection.kind === "valid" ? normalizeStableSessionId(markerInspection.marker.session_id) : void 0;
|
|
7424
7498
|
const ownershipWriteSessionId = markerInspection.kind === "none" ? sessionId : void 0;
|
|
7425
7499
|
const anthropicBeta = c.req.header("anthropic-beta");
|
|
@@ -7427,7 +7501,7 @@ async function handleCompletion(c) {
|
|
|
7427
7501
|
const isCompact = compactType !== 0;
|
|
7428
7502
|
const originalRequestModel = anthropicPayload.model;
|
|
7429
7503
|
if (anthropicBeta && isWarmupProbeRequest(anthropicPayload)) anthropicPayload.model = getSmallModel();
|
|
7430
|
-
if (compactType !== 0) logger$
|
|
7504
|
+
if (compactType !== 0) logger$4.debug("Compact request type:", compactType);
|
|
7431
7505
|
const lastMessageCacheControl = getLastMessageContentCacheControl(anthropicPayload.messages.at(-1));
|
|
7432
7506
|
if (compactType === 1 && shouldCompactUseSmallModel()) anthropicPayload.model = getSmallModel();
|
|
7433
7507
|
if (compactType === 0) {
|
|
@@ -7436,7 +7510,7 @@ async function handleCompletion(c) {
|
|
|
7436
7510
|
}
|
|
7437
7511
|
applyLastMessageCacheControl(anthropicPayload, lastMessageCacheControl);
|
|
7438
7512
|
const upstreamRequestId = generateRequestIdFromPayload(anthropicPayload, sessionId);
|
|
7439
|
-
logger$
|
|
7513
|
+
logger$4.debug("Generated request ID:", upstreamRequestId);
|
|
7440
7514
|
const clientModel = anthropicPayload.model;
|
|
7441
7515
|
anthropicPayload.model = resolveModelAlias(anthropicPayload.model);
|
|
7442
7516
|
const routingModel = anthropicPayload.model;
|
|
@@ -7593,7 +7667,7 @@ async function handleCompletion(c) {
|
|
|
7593
7667
|
}
|
|
7594
7668
|
const handleWithChatCompletions = async (params) => {
|
|
7595
7669
|
const { c, openAIPayload, subagentMarker, sessionId, selectedModel, instr, compactType } = params;
|
|
7596
|
-
debugJson(logger$
|
|
7670
|
+
debugJson(logger$4, "Translated OpenAI request payload:", openAIPayload);
|
|
7597
7671
|
const ctx = toAccountContext(instr.account);
|
|
7598
7672
|
const effectiveInitiator = resolveEffectiveInitiator(getChatInitiator(openAIPayload.messages), {
|
|
7599
7673
|
isCompact: compactType !== 0,
|
|
@@ -7624,9 +7698,9 @@ const handleWithChatCompletions = async (params) => {
|
|
|
7624
7698
|
response,
|
|
7625
7699
|
instr
|
|
7626
7700
|
});
|
|
7627
|
-
logger$
|
|
7701
|
+
logger$4.debug("Streaming response from Copilot");
|
|
7628
7702
|
const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
|
|
7629
|
-
const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$
|
|
7703
|
+
const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$4) : void 0;
|
|
7630
7704
|
const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
|
|
7631
7705
|
promptCacheKey: instr.promptCacheKey,
|
|
7632
7706
|
safetyIdentifier: instr.safetyIdentifier,
|
|
@@ -7648,7 +7722,7 @@ const handleWithResponsesApi = async (params) => {
|
|
|
7648
7722
|
});
|
|
7649
7723
|
applyResponsesApiContextManagement(responsesPayload, selectedModel.capabilities.limits.max_prompt_tokens);
|
|
7650
7724
|
compactInputByLatestCompaction(responsesPayload);
|
|
7651
|
-
debugJson(logger$
|
|
7725
|
+
debugJson(logger$4, "Translated Responses payload:", responsesPayload);
|
|
7652
7726
|
const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
|
|
7653
7727
|
const transport = getResponsesTransportForModel(selectedModel, { compactType }) ?? "http";
|
|
7654
7728
|
const effectiveInitiator = resolveEffectiveInitiator(initiator, {
|
|
@@ -7679,9 +7753,9 @@ const handleWithResponsesApi = async (params) => {
|
|
|
7679
7753
|
});
|
|
7680
7754
|
}
|
|
7681
7755
|
if (responsesPayload.stream && isAsyncIterable(response)) {
|
|
7682
|
-
logger$
|
|
7756
|
+
logger$4.debug("Streaming response from Copilot (Responses API)");
|
|
7683
7757
|
const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
|
|
7684
|
-
const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$
|
|
7758
|
+
const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$4) : void 0;
|
|
7685
7759
|
const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
|
|
7686
7760
|
promptCacheKey: instr.promptCacheKey,
|
|
7687
7761
|
safetyIdentifier: instr.safetyIdentifier,
|
|
@@ -7779,9 +7853,9 @@ async function handleChatCompletionsNonStreaming(params) {
|
|
|
7779
7853
|
let upstreamErrorMessageRaw;
|
|
7780
7854
|
const finishedAtMs = Date.now();
|
|
7781
7855
|
try {
|
|
7782
|
-
logger$
|
|
7856
|
+
logger$4.debug("Non-streaming response from Copilot:", JSON.stringify(response));
|
|
7783
7857
|
const anthropicResponse = translateToAnthropic(response);
|
|
7784
|
-
debugJson(logger$
|
|
7858
|
+
debugJson(logger$4, "Translated Anthropic response:", anthropicResponse);
|
|
7785
7859
|
return c.json(anthropicResponse);
|
|
7786
7860
|
} catch (error) {
|
|
7787
7861
|
const details = await extractErrorObservability(error);
|
|
@@ -7832,7 +7906,7 @@ async function streamChatCompletionsAndLog(params) {
|
|
|
7832
7906
|
try {
|
|
7833
7907
|
for await (const rawEvent of response) {
|
|
7834
7908
|
if (ttfbMs === void 0) ttfbMs = Date.now() - instr.startedAtMs;
|
|
7835
|
-
logger$
|
|
7909
|
+
logger$4.debug("Copilot raw stream event:", JSON.stringify(rawEvent));
|
|
7836
7910
|
const { data: rawData } = rawEvent;
|
|
7837
7911
|
const data = typeof rawData === "string" ? rawData : await rawData;
|
|
7838
7912
|
if (data === "[DONE]") break;
|
|
@@ -7841,7 +7915,7 @@ async function streamChatCompletionsAndLog(params) {
|
|
|
7841
7915
|
if (chunk.usage) lastUsage = normalizeChatCompletionsUsage(chunk.usage);
|
|
7842
7916
|
const events = translateChunkToAnthropicEvents(chunk, streamState);
|
|
7843
7917
|
for (const event of events) {
|
|
7844
|
-
logger$
|
|
7918
|
+
logger$4.debug("Translated Anthropic event:", JSON.stringify(event));
|
|
7845
7919
|
await stream.writeSSE({
|
|
7846
7920
|
event: event.type,
|
|
7847
7921
|
data: JSON.stringify(event)
|
|
@@ -7854,7 +7928,7 @@ async function streamChatCompletionsAndLog(params) {
|
|
|
7854
7928
|
errorStatus = details.errorStatus;
|
|
7855
7929
|
errorMessage = details.errorMessage;
|
|
7856
7930
|
upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
|
|
7857
|
-
logger$
|
|
7931
|
+
logger$4.warn("Streaming error:", error);
|
|
7858
7932
|
if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
|
|
7859
7933
|
await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
|
|
7860
7934
|
} finally {
|
|
@@ -7915,9 +7989,9 @@ async function handleResponsesNonStreaming(params) {
|
|
|
7915
7989
|
usage = extractResponsesUsageFromResult(result);
|
|
7916
7990
|
const responseOwnerKeys = extractResponsesResultOwnerKeys(result);
|
|
7917
7991
|
instr.responsesItemOwnerRecordedKeys = responseOwnerKeys;
|
|
7918
|
-
logger$
|
|
7992
|
+
logger$4.debug("Non-streaming Responses result:", JSON.stringify(result).slice(-400));
|
|
7919
7993
|
const anthropicResponse = translateResponsesResultToAnthropic(result);
|
|
7920
|
-
debugJson(logger$
|
|
7994
|
+
debugJson(logger$4, "Translated Anthropic response:", anthropicResponse);
|
|
7921
7995
|
const response = c.json(anthropicResponse);
|
|
7922
7996
|
if (result.status === "completed") accountsManager.recordResponsesItemOwnership(responseOwnerKeys, instr.account.id);
|
|
7923
7997
|
return response;
|
|
@@ -7951,7 +8025,7 @@ async function handleResponsesNonStreaming(params) {
|
|
|
7951
8025
|
async function ensureResponsesStreamCompleted(params) {
|
|
7952
8026
|
const { stream, streamState, setStreamError } = params;
|
|
7953
8027
|
if (streamState.messageCompleted) return;
|
|
7954
|
-
logger$
|
|
8028
|
+
logger$4.warn("Responses stream ended without completion; sending error event");
|
|
7955
8029
|
const msg = "Responses stream ended without completion";
|
|
7956
8030
|
const errorEvent = buildErrorEvent(msg);
|
|
7957
8031
|
setStreamError("StreamIncomplete", msg);
|
|
@@ -7968,7 +8042,7 @@ async function writeAnthropicStreamError(stream, message) {
|
|
|
7968
8042
|
data: JSON.stringify(errorEvent)
|
|
7969
8043
|
});
|
|
7970
8044
|
} catch (streamError) {
|
|
7971
|
-
logger$
|
|
8045
|
+
logger$4.warn("Failed to write Anthropic stream error event:", streamError);
|
|
7972
8046
|
}
|
|
7973
8047
|
}
|
|
7974
8048
|
function collectResponsesStreamOwnerKeys(event, responseOwnerKeys) {
|
|
@@ -8011,7 +8085,7 @@ function getResponsesStreamEventError(event) {
|
|
|
8011
8085
|
async function writeTranslatedAnthropicStreamEvents(stream, events) {
|
|
8012
8086
|
for (const event of events) {
|
|
8013
8087
|
const eventData = JSON.stringify(event);
|
|
8014
|
-
logger$
|
|
8088
|
+
logger$4.debug("Translated Anthropic event:", eventData);
|
|
8015
8089
|
await stream.writeSSE({
|
|
8016
8090
|
event: event.type,
|
|
8017
8091
|
data: eventData
|
|
@@ -8040,7 +8114,7 @@ async function streamResponsesAndLog$1(params) {
|
|
|
8040
8114
|
}
|
|
8041
8115
|
const data = chunk.data;
|
|
8042
8116
|
if (!data) continue;
|
|
8043
|
-
logger$
|
|
8117
|
+
logger$4.debug("Responses raw stream event:", data);
|
|
8044
8118
|
const parsed = JSON.parse(data);
|
|
8045
8119
|
const streamEventError = getResponsesStreamEventError(parsed);
|
|
8046
8120
|
if (streamEventError) {
|
|
@@ -8054,7 +8128,7 @@ async function streamResponsesAndLog$1(params) {
|
|
|
8054
8128
|
if (u.usageJson) lastUsage = u;
|
|
8055
8129
|
await writeTranslatedAnthropicStreamEvents(stream, translateResponsesStreamEvent(parsed, streamState));
|
|
8056
8130
|
if (streamState.messageCompleted) {
|
|
8057
|
-
logger$
|
|
8131
|
+
logger$4.debug("Message completed, ending stream");
|
|
8058
8132
|
break;
|
|
8059
8133
|
}
|
|
8060
8134
|
}
|
|
@@ -8073,7 +8147,7 @@ async function streamResponsesAndLog$1(params) {
|
|
|
8073
8147
|
errorStatus = details.errorStatus;
|
|
8074
8148
|
errorMessage = details.errorMessage;
|
|
8075
8149
|
upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
|
|
8076
|
-
logger$
|
|
8150
|
+
logger$4.warn("Streaming error:", error);
|
|
8077
8151
|
invalidateAffinityOnOwnershipMismatch(details.ownershipMismatch, instr);
|
|
8078
8152
|
if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
|
|
8079
8153
|
await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
|
|
@@ -8128,7 +8202,7 @@ async function handleMessagesNonStreaming(params) {
|
|
|
8128
8202
|
let upstreamErrorMessageRaw;
|
|
8129
8203
|
const finishedAtMs = Date.now();
|
|
8130
8204
|
try {
|
|
8131
|
-
logger$
|
|
8205
|
+
logger$4.debug("Non-streaming Messages result:", JSON.stringify(response).slice(-400));
|
|
8132
8206
|
return c.json(response);
|
|
8133
8207
|
} catch (error) {
|
|
8134
8208
|
const details = await extractErrorObservability(error);
|
|
@@ -8165,7 +8239,7 @@ const parseMessagesStreamUsage = (data) => {
|
|
|
8165
8239
|
if (parsed.type !== "message_delta" || !parsed.usage) return null;
|
|
8166
8240
|
return normalizeMessagesUsage(parsed.usage);
|
|
8167
8241
|
} catch (error) {
|
|
8168
|
-
logger$
|
|
8242
|
+
logger$4.warn("Failed to parse messages stream event", error);
|
|
8169
8243
|
throw new Error("Failed to parse messages stream event", { cause: error });
|
|
8170
8244
|
}
|
|
8171
8245
|
};
|
|
@@ -8183,7 +8257,7 @@ async function streamMessagesAndLog(params) {
|
|
|
8183
8257
|
const eventNameRaw = rawEvent.event;
|
|
8184
8258
|
const eventName = typeof eventNameRaw === "string" && eventNameRaw.length > 0 ? eventNameRaw : "message";
|
|
8185
8259
|
const data = rawEvent.data ?? "";
|
|
8186
|
-
logger$
|
|
8260
|
+
logger$4.debug("Messages raw stream event:", data);
|
|
8187
8261
|
const usage = parseMessagesStreamUsage(data);
|
|
8188
8262
|
if (usage) lastUsage = usage;
|
|
8189
8263
|
await stream.writeSSE({
|
|
@@ -8197,7 +8271,7 @@ async function streamMessagesAndLog(params) {
|
|
|
8197
8271
|
errorStatus = details.errorStatus;
|
|
8198
8272
|
errorMessage = details.errorMessage;
|
|
8199
8273
|
upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
|
|
8200
|
-
logger$
|
|
8274
|
+
logger$4.warn("Streaming error:", error);
|
|
8201
8275
|
if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
|
|
8202
8276
|
await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
|
|
8203
8277
|
} finally {
|
|
@@ -8223,7 +8297,7 @@ async function streamMessagesAndLog(params) {
|
|
|
8223
8297
|
const handleWithMessagesApi = async (params) => {
|
|
8224
8298
|
const { c, anthropicPayload, anthropicBetaHeader, subagentMarker, sessionId, instr, selectedModel, compactType } = params;
|
|
8225
8299
|
prepareMessagesApiPayload(anthropicPayload, selectedModel);
|
|
8226
|
-
debugJson(logger$
|
|
8300
|
+
debugJson(logger$4, "Translated Messages payload:", anthropicPayload);
|
|
8227
8301
|
const ctx = toAccountContext(instr.account);
|
|
8228
8302
|
const effectiveInitiator = resolveEffectiveInitiator(getMessagesInitiator(anthropicPayload), {
|
|
8229
8303
|
isCompact: compactType !== 0,
|
|
@@ -8251,7 +8325,7 @@ const handleWithMessagesApi = async (params) => {
|
|
|
8251
8325
|
});
|
|
8252
8326
|
}
|
|
8253
8327
|
if (isAsyncIterable(response)) {
|
|
8254
|
-
logger$
|
|
8328
|
+
logger$4.debug("Streaming response from Copilot (Messages API)");
|
|
8255
8329
|
return streamSSE(c, (stream) => streamMessagesAndLog({
|
|
8256
8330
|
stream,
|
|
8257
8331
|
response,
|
|
@@ -8416,16 +8490,16 @@ function getModels() {
|
|
|
8416
8490
|
}
|
|
8417
8491
|
//#endregion
|
|
8418
8492
|
//#region src/routes/provider/models/route.ts
|
|
8419
|
-
const logger$
|
|
8493
|
+
const logger$3 = createHandlerLogger("provider-models-handler");
|
|
8420
8494
|
const getProviderFetch = (c) => c.get("providerFetch") ?? fetch;
|
|
8421
|
-
const resolveProviderConfig = (c, provider) => {
|
|
8495
|
+
const resolveProviderConfig$1 = (c, provider) => {
|
|
8422
8496
|
return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
|
|
8423
8497
|
};
|
|
8424
8498
|
const providerModelRoutes = new Hono();
|
|
8425
8499
|
providerModelRoutes.get("/", async (c) => {
|
|
8426
8500
|
const provider = c.req.param("provider") ?? "";
|
|
8427
8501
|
try {
|
|
8428
|
-
const providerConfig = resolveProviderConfig(c, provider);
|
|
8502
|
+
const providerConfig = resolveProviderConfig$1(c, provider);
|
|
8429
8503
|
if (!providerConfig) return c.json({ error: {
|
|
8430
8504
|
message: `Provider '${provider}' not found or disabled`,
|
|
8431
8505
|
type: "invalid_request_error"
|
|
@@ -8439,13 +8513,13 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
8439
8513
|
});
|
|
8440
8514
|
}
|
|
8441
8515
|
const upstreamResponse = await forwardProviderModels(providerConfig, c.req.raw.headers, getProviderFetch(c));
|
|
8442
|
-
logger$
|
|
8516
|
+
logger$3.debug("provider.models.response", {
|
|
8443
8517
|
provider,
|
|
8444
8518
|
statusCode: upstreamResponse.status
|
|
8445
8519
|
});
|
|
8446
8520
|
return createProviderProxyResponse(upstreamResponse);
|
|
8447
8521
|
} catch (error) {
|
|
8448
|
-
logger$
|
|
8522
|
+
logger$3.error("provider.models.error", {
|
|
8449
8523
|
provider,
|
|
8450
8524
|
error
|
|
8451
8525
|
});
|
|
@@ -8453,6 +8527,166 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
8453
8527
|
}
|
|
8454
8528
|
});
|
|
8455
8529
|
//#endregion
|
|
8530
|
+
//#region src/lib/codex-rate-limit.ts
|
|
8531
|
+
const codexRateLimitScopes = ["primary", "secondary"];
|
|
8532
|
+
const formatCodexRateLimitResetAt = (resetAt) => {
|
|
8533
|
+
const date = /* @__PURE__ */ new Date(resetAt * 1e3);
|
|
8534
|
+
return Number.isNaN(date.getTime()) ? String(resetAt) : date.toLocaleString();
|
|
8535
|
+
};
|
|
8536
|
+
const logCodexRateLimitsEvent = (event) => {
|
|
8537
|
+
if (!event || typeof event !== "object") return;
|
|
8538
|
+
const eventRecord = event;
|
|
8539
|
+
if (eventRecord.type !== "codex.rate_limits") return;
|
|
8540
|
+
const rateLimits = eventRecord.rate_limits;
|
|
8541
|
+
if (!rateLimits || typeof rateLimits !== "object") return;
|
|
8542
|
+
const planType = typeof eventRecord.plan_type === "string" ? eventRecord.plan_type : null;
|
|
8543
|
+
const rateLimitRecord = rateLimits;
|
|
8544
|
+
const allowed = typeof rateLimitRecord.allowed === "boolean" ? rateLimitRecord.allowed : null;
|
|
8545
|
+
const limitReached = typeof rateLimitRecord.limit_reached === "boolean" ? rateLimitRecord.limit_reached : null;
|
|
8546
|
+
for (const scope of codexRateLimitScopes) {
|
|
8547
|
+
const window = rateLimitRecord[scope];
|
|
8548
|
+
if (!isCodexRateLimitWindow(window)) continue;
|
|
8549
|
+
const summary = [];
|
|
8550
|
+
if (allowed !== null) summary.push(`allowed=${allowed}`);
|
|
8551
|
+
if (limitReached !== null) summary.push(`limit_reached=${limitReached}`);
|
|
8552
|
+
summary.push(`used=${window.used_percent}%`, `reset_at=${formatCodexRateLimitResetAt(window.reset_at)}`);
|
|
8553
|
+
const label = planType ? `Codex ${scope} rate limit (${planType})` : `Codex ${scope} rate limit`;
|
|
8554
|
+
consola.log(`${label}: ${summary.join(", ")}`);
|
|
8555
|
+
}
|
|
8556
|
+
};
|
|
8557
|
+
const isCodexRateLimitWindow = (value) => {
|
|
8558
|
+
if (!value || typeof value !== "object") return false;
|
|
8559
|
+
const record = value;
|
|
8560
|
+
return typeof record.reset_after_seconds === "number" && typeof record.reset_at === "number" && typeof record.used_percent === "number" && typeof record.window_minutes === "number";
|
|
8561
|
+
};
|
|
8562
|
+
//#endregion
|
|
8563
|
+
//#region src/lib/provider-resolver.ts
|
|
8564
|
+
function isMissingCodexCredentialsError(error) {
|
|
8565
|
+
return error instanceof Error && error.message === "Codex credentials not found. Run `copilot-api auth login --provider codex` first.";
|
|
8566
|
+
}
|
|
8567
|
+
async function resolveProviderConfig(providerName) {
|
|
8568
|
+
const normalizedProviderName = providerName.trim();
|
|
8569
|
+
if (!normalizedProviderName) return null;
|
|
8570
|
+
if (normalizedProviderName === "codex") {
|
|
8571
|
+
if (getRawProviderConfig(normalizedProviderName)?.enabled === false) return null;
|
|
8572
|
+
try {
|
|
8573
|
+
await setupCodexToken();
|
|
8574
|
+
} catch (error) {
|
|
8575
|
+
if (isMissingCodexCredentialsError(error)) return null;
|
|
8576
|
+
throw error;
|
|
8577
|
+
}
|
|
8578
|
+
const providerConfig = getProviderConfig(normalizedProviderName);
|
|
8579
|
+
if (!providerConfig) return null;
|
|
8580
|
+
return {
|
|
8581
|
+
...providerConfig,
|
|
8582
|
+
apiKey: state.codexAccessToken ?? providerConfig.apiKey
|
|
8583
|
+
};
|
|
8584
|
+
}
|
|
8585
|
+
return getProviderConfig(normalizedProviderName);
|
|
8586
|
+
}
|
|
8587
|
+
//#endregion
|
|
8588
|
+
//#region src/routes/provider/responses/handler.ts
|
|
8589
|
+
const logger$2 = createHandlerLogger("provider-responses-handler");
|
|
8590
|
+
async function handleProviderResponsesForProvider(c, options) {
|
|
8591
|
+
const { payload, provider } = options;
|
|
8592
|
+
debugJson(logger$2, "Responses request payload:", {
|
|
8593
|
+
payload,
|
|
8594
|
+
provider
|
|
8595
|
+
});
|
|
8596
|
+
const providerConfig = await resolveProviderConfig(provider);
|
|
8597
|
+
if (providerConfig?.type !== "openai-responses") return c.json({ error: {
|
|
8598
|
+
message: `Provider '${provider}' does not support the /v1/responses endpoint`,
|
|
8599
|
+
type: "invalid_request_error"
|
|
8600
|
+
} }, 400);
|
|
8601
|
+
applyResponsesApiContextManagement(payload, (providerConfig.name === "codex" ? getModels().data.find((model) => model.id === payload.model) : void 0)?.capabilities.limits.max_prompt_tokens ?? 0, .8);
|
|
8602
|
+
const contextManagement = payload.context_management;
|
|
8603
|
+
debugJson(logger$2, "Translated Responses request payload:", {
|
|
8604
|
+
contextManagement,
|
|
8605
|
+
provider
|
|
8606
|
+
});
|
|
8607
|
+
compactInputByLatestCompaction(payload);
|
|
8608
|
+
if (providerConfig.name === "codex") {
|
|
8609
|
+
const upstreamResponse = await forwardCodexResponses(payload, c.req.raw.headers, providerConfig.baseUrl);
|
|
8610
|
+
const recordUsage = createProviderResponsesUsageRecorder(payload, provider);
|
|
8611
|
+
if (payload.stream && isResponsesStream(upstreamResponse)) return streamProviderResponses(c, upstreamResponse, {
|
|
8612
|
+
normalizeCodex: true,
|
|
8613
|
+
provider,
|
|
8614
|
+
recordUsage
|
|
8615
|
+
});
|
|
8616
|
+
const responseBody = upstreamResponse;
|
|
8617
|
+
recordUsage(normalizeResponsesUsage(responseBody.usage));
|
|
8618
|
+
return c.json(responseBody);
|
|
8619
|
+
}
|
|
8620
|
+
const upstreamResponse = await forwardProviderResponses(providerConfig, payload, c.req.raw.headers);
|
|
8621
|
+
if (!upstreamResponse.ok) throw new HTTPError(`Failed to create ${provider} responses`, upstreamResponse);
|
|
8622
|
+
const recordUsage = createProviderResponsesUsageRecorder(payload, provider);
|
|
8623
|
+
if (payload.stream) return streamProviderResponses(c, getResponsesEvents(upstreamResponse), {
|
|
8624
|
+
normalizeCodex: false,
|
|
8625
|
+
provider,
|
|
8626
|
+
recordUsage
|
|
8627
|
+
});
|
|
8628
|
+
recordUsage(normalizeResponsesUsage((await upstreamResponse.clone().json()).usage));
|
|
8629
|
+
return createProviderProxyResponse(upstreamResponse);
|
|
8630
|
+
}
|
|
8631
|
+
const createProviderResponsesUsageRecorder = (_payload, _provider) => {
|
|
8632
|
+
return (_usage) => {};
|
|
8633
|
+
};
|
|
8634
|
+
const streamProviderResponses = (c, upstreamResponse, options) => {
|
|
8635
|
+
return streamSSE(c, async (stream) => {
|
|
8636
|
+
let usage = {};
|
|
8637
|
+
try {
|
|
8638
|
+
for await (const chunk of upstreamResponse) {
|
|
8639
|
+
debugJson(logger$2, "Responses stream chunk:", chunk);
|
|
8640
|
+
let responseChunk = chunk;
|
|
8641
|
+
let event = null;
|
|
8642
|
+
if (chunk.data && chunk.data !== "[DONE]") {
|
|
8643
|
+
event = parseProviderResponsesStreamEvent(chunk.data, {
|
|
8644
|
+
normalizeCodex: options.normalizeCodex,
|
|
8645
|
+
provider: options.provider
|
|
8646
|
+
});
|
|
8647
|
+
if (event && options.normalizeCodex) responseChunk = {
|
|
8648
|
+
...chunk,
|
|
8649
|
+
data: JSON.stringify(event),
|
|
8650
|
+
event: event.type
|
|
8651
|
+
};
|
|
8652
|
+
}
|
|
8653
|
+
if (event) {
|
|
8654
|
+
const nextUsage = getResponsesStreamEventUsage(event);
|
|
8655
|
+
if (nextUsage) usage = nextUsage;
|
|
8656
|
+
}
|
|
8657
|
+
await stream.writeSSE({
|
|
8658
|
+
data: responseChunk.data ?? "",
|
|
8659
|
+
event: responseChunk.event
|
|
8660
|
+
});
|
|
8661
|
+
}
|
|
8662
|
+
} finally {
|
|
8663
|
+
options.recordUsage(usage);
|
|
8664
|
+
}
|
|
8665
|
+
});
|
|
8666
|
+
};
|
|
8667
|
+
const parseProviderResponsesStreamEvent = (data, options) => {
|
|
8668
|
+
try {
|
|
8669
|
+
const parsed = JSON.parse(data);
|
|
8670
|
+
if (options.normalizeCodex) logCodexRateLimitsEvent(parsed);
|
|
8671
|
+
return parsed;
|
|
8672
|
+
} catch (error) {
|
|
8673
|
+
logger$2.error("provider.responses.parse_chunk_error", {
|
|
8674
|
+
provider: options.provider,
|
|
8675
|
+
data,
|
|
8676
|
+
error
|
|
8677
|
+
});
|
|
8678
|
+
return null;
|
|
8679
|
+
}
|
|
8680
|
+
};
|
|
8681
|
+
const getResponsesStreamEventUsage = (event) => {
|
|
8682
|
+
if (event.type === "response.completed" || event.type === "response.failed" || event.type === "response.incomplete") return normalizeResponsesUsage(event.response.usage);
|
|
8683
|
+
return null;
|
|
8684
|
+
};
|
|
8685
|
+
const getResponsesEvents = (response) => events(response);
|
|
8686
|
+
const isResponsesStream = (value) => {
|
|
8687
|
+
return Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
|
|
8688
|
+
};
|
|
8689
|
+
//#endregion
|
|
8456
8690
|
//#region src/routes/responses/stream-id-sync.ts
|
|
8457
8691
|
const createStreamIdTracker = () => ({ outputItems: /* @__PURE__ */ new Map() });
|
|
8458
8692
|
const fixStreamIds = (data, event, tracker) => {
|
|
@@ -8493,16 +8727,31 @@ const handleItemId = (parsed, tracker) => {
|
|
|
8493
8727
|
const logger$1 = createHandlerLogger("responses-handler");
|
|
8494
8728
|
const RESPONSES_ENDPOINT = "/responses";
|
|
8495
8729
|
const handleResponses = async (c) => {
|
|
8730
|
+
const payload = await c.req.json();
|
|
8731
|
+
debugJson(logger$1, "Responses request payload:", payload);
|
|
8732
|
+
const requestedModel = payload.model;
|
|
8733
|
+
payload.model = resolveMappedModel(payload.model);
|
|
8734
|
+
if (payload.model !== requestedModel) logger$1.debug(`Resolved model mapping: ${requestedModel} -> ${payload.model}`);
|
|
8735
|
+
const providerModelAlias = parseProviderModelAlias(payload.model);
|
|
8736
|
+
if (providerModelAlias) {
|
|
8737
|
+
payload.model = providerModelAlias.model;
|
|
8738
|
+
return await handleProviderResponsesForProvider(c, {
|
|
8739
|
+
payload,
|
|
8740
|
+
provider: providerModelAlias.provider
|
|
8741
|
+
});
|
|
8742
|
+
}
|
|
8743
|
+
const subagentMarker = getCodexResponsesSubagentMarker(c);
|
|
8744
|
+
if (subagentMarker) debugJson(logger$1, "Detected Codex subagent headers:", subagentMarker);
|
|
8745
|
+
const incomingSessionId = subagentMarker ? getIncomingResponsesSessionId(c) : void 0;
|
|
8496
8746
|
await checkRateLimit(state);
|
|
8497
8747
|
const store = getRequestHistoryStore();
|
|
8498
8748
|
const request = buildRequestContext(c);
|
|
8499
|
-
const payload = await c.req.json();
|
|
8500
8749
|
const clientModel = payload.model;
|
|
8501
|
-
debugJson(logger$1, "Responses request payload:", payload);
|
|
8502
8750
|
if (!isResponsesApiWebSearchEnabled()) removeWebSearchTool(payload);
|
|
8503
8751
|
compactInputByLatestCompaction(payload);
|
|
8504
8752
|
const streamRequested = Boolean(payload.stream);
|
|
8505
|
-
const { initiator:
|
|
8753
|
+
const { initiator: inferredInitiator } = getResponsesRequestOptions(payload);
|
|
8754
|
+
const initialInitiator = subagentMarker ? "agent" : inferredInitiator;
|
|
8506
8755
|
const userId = payload.metadata?.user_id;
|
|
8507
8756
|
const requestBodyPromptCacheKey = typeof payload.prompt_cache_key === "string" ? payload.prompt_cache_key : null;
|
|
8508
8757
|
const { safetyIdentifier, sessionId: metadataSessionId } = parseUserIdMetadata(userId);
|
|
@@ -8524,8 +8773,8 @@ const handleResponses = async (c) => {
|
|
|
8524
8773
|
message: "This model is only available via an alias. Please use the alias model name."
|
|
8525
8774
|
});
|
|
8526
8775
|
}
|
|
8527
|
-
const upstreamRequestId = generateRequestIdFromPayload({ messages: payload.input }, normalizedPromptCacheKey);
|
|
8528
8776
|
const headerSessionId = c.req.header("x-session-id") ?? null;
|
|
8777
|
+
const upstreamRequestId = generateRequestIdFromPayload({ messages: payload.input }, incomingSessionId ?? normalizedPromptCacheKey);
|
|
8529
8778
|
const affinityKey = resolveAffinityKey({
|
|
8530
8779
|
promptCacheKey: requestBodyPromptCacheKey,
|
|
8531
8780
|
metadataSessionId,
|
|
@@ -8556,16 +8805,19 @@ const handleResponses = async (c) => {
|
|
|
8556
8805
|
model: selectedModel.id
|
|
8557
8806
|
};
|
|
8558
8807
|
removeUnsupportedTools(upstreamPayload);
|
|
8808
|
+
const sanitizedImageCount = sanitizeOversizedInputImages(upstreamPayload, selectedModel.capabilities.limits.vision?.max_prompt_image_size);
|
|
8809
|
+
if (sanitizedImageCount > 0) logger$1.warn(`Omitted ${sanitizedImageCount} oversized input image(s) before forwarding to Copilot Responses`);
|
|
8559
8810
|
applyResponsesApiContextManagement(upstreamPayload, selectedModel.capabilities.limits.max_prompt_tokens);
|
|
8560
8811
|
compactInputByLatestCompaction(upstreamPayload);
|
|
8561
8812
|
const premiumRemainingBefore = account.premiumRemaining;
|
|
8562
8813
|
const premiumUnlimitedBefore = account.unlimited;
|
|
8563
8814
|
const transport = getResponsesTransportForModel(selectedModel) ?? "http";
|
|
8564
|
-
const { vision, initiator } = getResponsesRequestOptions(upstreamPayload);
|
|
8815
|
+
const { vision, initiator: inferredUpstreamInitiator } = getResponsesRequestOptions(upstreamPayload);
|
|
8816
|
+
const initiator = subagentMarker ? "agent" : inferredUpstreamInitiator;
|
|
8565
8817
|
request.initiator = initiator;
|
|
8566
8818
|
if (state.manualApprove) await awaitApproval();
|
|
8567
8819
|
const accountCtx = toAccountContext(account);
|
|
8568
|
-
const upstreamSessionId = getUUID(normalizedPromptCacheKey ?? headerSessionId ?? upstreamRequestId);
|
|
8820
|
+
const upstreamSessionId = getUUID(incomingSessionId ?? normalizedPromptCacheKey ?? headerSessionId ?? upstreamRequestId);
|
|
8569
8821
|
request.upstreamRequestId = upstreamRequestId;
|
|
8570
8822
|
request.upstreamSessionId = upstreamSessionId;
|
|
8571
8823
|
const bridgeId = c.req.header("x-responses-bridge-id") ?? void 0;
|
|
@@ -8579,6 +8831,7 @@ const handleResponses = async (c) => {
|
|
|
8579
8831
|
accountCtx,
|
|
8580
8832
|
vision,
|
|
8581
8833
|
initiator,
|
|
8834
|
+
subagentMarker,
|
|
8582
8835
|
premiumRemainingBefore,
|
|
8583
8836
|
premiumUnlimitedBefore,
|
|
8584
8837
|
transport,
|
|
@@ -8594,6 +8847,7 @@ const handleResponses = async (c) => {
|
|
|
8594
8847
|
accountCtx,
|
|
8595
8848
|
vision,
|
|
8596
8849
|
initiator,
|
|
8850
|
+
subagentMarker,
|
|
8597
8851
|
premiumRemainingBefore,
|
|
8598
8852
|
premiumUnlimitedBefore,
|
|
8599
8853
|
transport,
|
|
@@ -8705,12 +8959,13 @@ function extractUsageFromChunkData(data) {
|
|
|
8705
8959
|
}
|
|
8706
8960
|
}
|
|
8707
8961
|
async function handleStreamingResponses(params) {
|
|
8708
|
-
const { c, store, request, payload, selection, clientModel, accountCtx, vision, initiator, premiumRemainingBefore, premiumUnlimitedBefore, transport, bridgeId } = params;
|
|
8962
|
+
const { c, store, request, payload, selection, clientModel, accountCtx, vision, initiator, subagentMarker, premiumRemainingBefore, premiumUnlimitedBefore, transport, bridgeId } = params;
|
|
8709
8963
|
let response;
|
|
8710
8964
|
try {
|
|
8711
8965
|
response = await createResponses(payload, {
|
|
8712
8966
|
vision,
|
|
8713
8967
|
initiator,
|
|
8968
|
+
subagentMarker,
|
|
8714
8969
|
upstreamRequestId: request.upstreamRequestId,
|
|
8715
8970
|
sessionId: request.upstreamSessionId,
|
|
8716
8971
|
requestId: request.requestId,
|
|
@@ -8903,7 +9158,7 @@ async function streamResponsesAndLog(params) {
|
|
|
8903
9158
|
}
|
|
8904
9159
|
}
|
|
8905
9160
|
async function handleNonStreamingResponses(params) {
|
|
8906
|
-
const { c, store, request, payload, selection, clientModel, accountCtx, vision, initiator, premiumRemainingBefore, premiumUnlimitedBefore, transport, bridgeId } = params;
|
|
9161
|
+
const { c, store, request, payload, selection, clientModel, accountCtx, vision, initiator, subagentMarker, premiumRemainingBefore, premiumUnlimitedBefore, transport, bridgeId } = params;
|
|
8907
9162
|
const { account, reservation, selectedModel, endpoint, costUnits } = selection;
|
|
8908
9163
|
let usage = {};
|
|
8909
9164
|
let errorState = { httpStatus: 200 };
|
|
@@ -8912,6 +9167,7 @@ async function handleNonStreamingResponses(params) {
|
|
|
8912
9167
|
const response = await createResponses(payload, {
|
|
8913
9168
|
vision,
|
|
8914
9169
|
initiator,
|
|
9170
|
+
subagentMarker,
|
|
8915
9171
|
upstreamRequestId: request.upstreamRequestId,
|
|
8916
9172
|
sessionId: request.upstreamSessionId,
|
|
8917
9173
|
requestId: request.requestId,
|
|
@@ -8978,6 +9234,31 @@ const removeUnsupportedTools = (payload) => {
|
|
|
8978
9234
|
});
|
|
8979
9235
|
if (dropped.length > 0) logger$1.debug("Removed unsupported tools:", dropped);
|
|
8980
9236
|
};
|
|
9237
|
+
const getTrimmedHeader = (c, name) => {
|
|
9238
|
+
const value = c.req.header(name)?.trim();
|
|
9239
|
+
return value ? value : void 0;
|
|
9240
|
+
};
|
|
9241
|
+
const getIncomingResponsesSessionId = (c) => getTrimmedHeader(c, "session-id") ?? getTrimmedHeader(c, "x-session-id");
|
|
9242
|
+
const codexSubagentHeaderValues = new Set([
|
|
9243
|
+
"collab_spawn",
|
|
9244
|
+
"compact",
|
|
9245
|
+
"memory_consolidation",
|
|
9246
|
+
"review"
|
|
9247
|
+
]);
|
|
9248
|
+
const getCodexResponsesSubagentMarker = (c) => {
|
|
9249
|
+
const agentType = getTrimmedHeader(c, "x-openai-subagent");
|
|
9250
|
+
if (!agentType || !codexSubagentHeaderValues.has(agentType)) return null;
|
|
9251
|
+
const threadId = getTrimmedHeader(c, "thread-id");
|
|
9252
|
+
const rootSessionId = getIncomingResponsesSessionId(c);
|
|
9253
|
+
const parentThreadId = getTrimmedHeader(c, "x-codex-parent-thread-id");
|
|
9254
|
+
if (!threadId && !rootSessionId && !parentThreadId) return null;
|
|
9255
|
+
const agentId = threadId ?? parentThreadId ?? rootSessionId;
|
|
9256
|
+
return {
|
|
9257
|
+
agent_id: agentId,
|
|
9258
|
+
agent_type: agentType,
|
|
9259
|
+
session_id: threadId ?? rootSessionId ?? agentId
|
|
9260
|
+
};
|
|
9261
|
+
};
|
|
8981
9262
|
//#endregion
|
|
8982
9263
|
//#region src/routes/responses/route.ts
|
|
8983
9264
|
const responsesRoutes = new Hono();
|
|
@@ -9079,4 +9360,4 @@ createServer();
|
|
|
9079
9360
|
//#endregion
|
|
9080
9361
|
export { createServer };
|
|
9081
9362
|
|
|
9082
|
-
//# sourceMappingURL=server-
|
|
9363
|
+
//# sourceMappingURL=server-BYKxAFro.js.map
|