@jeffreycao/copilot-api 1.9.11 → 1.9.13
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/{auth-CWEhhJYn.js → auth-DEUCqXMV.js} +5 -6
- package/dist/{auth-CWEhhJYn.js.map → auth-DEUCqXMV.js.map} +1 -1
- package/dist/{check-usage-B5yr4fpk.js → check-usage-OcW_3tEg.js} +5 -6
- package/dist/{check-usage-B5yr4fpk.js.map → check-usage-OcW_3tEg.js.map} +1 -1
- package/dist/{config-BJt9unC0.js → config-DrfmMOO-.js} +5 -7
- package/dist/config-DrfmMOO-.js.map +1 -0
- package/dist/{debug-DcC7ZPH0.js → debug-CIXXx_bq.js} +3 -4
- package/dist/{debug-DcC7ZPH0.js.map → debug-CIXXx_bq.js.map} +1 -1
- package/dist/main.js +8 -11
- package/dist/main.js.map +1 -1
- package/dist/{paths-Cla6y5eD.js → paths-DC-mqCY3.js} +5 -8
- package/dist/{paths-Cla6y5eD.js.map → paths-DC-mqCY3.js.map} +1 -1
- package/dist/{server-D4pg54e1.js → server-DkUKa2I6.js} +370 -419
- package/dist/server-DkUKa2I6.js.map +1 -0
- package/dist/{start-D2K2jpHF.js → start-DFJynp4A.js} +12 -17
- package/dist/start-DFJynp4A.js.map +1 -0
- package/dist/{token-rgdB2YWP.js → token-BOwQe3TO.js} +5 -10
- package/dist/token-BOwQe3TO.js.map +1 -0
- package/dist/{utils-DEJvF68W.js → utils-Cj-ToKA6.js} +36 -62
- package/dist/utils-Cj-ToKA6.js.map +1 -0
- package/package.json +11 -5
- package/dist/config-BJt9unC0.js.map +0 -1
- package/dist/server-D4pg54e1.js.map +0 -1
- package/dist/start-D2K2jpHF.js.map +0 -1
- package/dist/token-rgdB2YWP.js.map +0 -1
- package/dist/utils-DEJvF68W.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { PATHS } from "./paths-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { t as PATHS } from "./paths-DC-mqCY3.js";
|
|
2
|
+
import { A as compactAutoContinuePromptStarts, C as prepareForCompact, D as requestContext, E as generateTraceId, F as state, N as compactSystemPromptStarts, O as resolveTraceId$1, T as prepareMessageProxyHeaders, c as getUUID, d as sleep, f as getCopilotUsage, g as copilotHeaders, h as copilotBaseUrl, j as compactMessageSections, l as isNullish, m as forwardError, n as cacheModels, o as generateRequestIdFromPayload, p as HTTPError, s as getRootSessionId, u as parseUserIdMetadata, w as prepareInteractionHeaders } from "./utils-Cj-ToKA6.js";
|
|
3
|
+
import { a as getProviderConfig, c as isMessagesApiEnabled, i as getExtraPromptForModel, l as isResponsesApiContextManagementModel, n as getClaudeTokenMultiplier, o as getReasoningEffortForModel, r as getConfig, s as getSmallModel, t as getAnthropicApiKey, u as isResponsesApiWebSearchEnabled } from "./config-DrfmMOO-.js";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import path from "node:path";
|
|
@@ -11,7 +11,6 @@ import fs$1, { readFileSync } from "node:fs";
|
|
|
11
11
|
import { streamSSE } from "hono/streaming";
|
|
12
12
|
import util from "node:util";
|
|
13
13
|
import { events } from "fetch-event-stream";
|
|
14
|
-
|
|
15
14
|
//#region src/lib/request-auth.ts
|
|
16
15
|
function normalizeApiKeys(apiKeys) {
|
|
17
16
|
if (!Array.isArray(apiKeys)) {
|
|
@@ -23,8 +22,7 @@ function normalizeApiKeys(apiKeys) {
|
|
|
23
22
|
return [...new Set(normalizedKeys)];
|
|
24
23
|
}
|
|
25
24
|
function getConfiguredApiKeys() {
|
|
26
|
-
|
|
27
|
-
return normalizeApiKeys(config.auth?.apiKeys);
|
|
25
|
+
return normalizeApiKeys(getConfig().auth?.apiKeys);
|
|
28
26
|
}
|
|
29
27
|
function extractRequestApiKey(c) {
|
|
30
28
|
const xApiKey = c.req.header("x-api-key")?.trim();
|
|
@@ -56,7 +54,6 @@ function createAuthMiddleware(options = {}) {
|
|
|
56
54
|
return next();
|
|
57
55
|
};
|
|
58
56
|
}
|
|
59
|
-
|
|
60
57
|
//#endregion
|
|
61
58
|
//#region src/lib/trace.ts
|
|
62
59
|
const traceIdMiddleware = async (c, next) => {
|
|
@@ -73,13 +70,11 @@ const traceIdMiddleware = async (c, next) => {
|
|
|
73
70
|
await next();
|
|
74
71
|
});
|
|
75
72
|
};
|
|
76
|
-
|
|
77
73
|
//#endregion
|
|
78
74
|
//#region src/lib/approval.ts
|
|
79
75
|
const awaitApproval = async () => {
|
|
80
76
|
if (!await consola.prompt(`Accept incoming request?`, { type: "confirm" })) throw new HTTPError("Request rejected", Response.json({ message: "Request rejected" }, { status: 403 }));
|
|
81
77
|
};
|
|
82
|
-
|
|
83
78
|
//#endregion
|
|
84
79
|
//#region src/lib/process-cleanup.ts
|
|
85
80
|
const cleanupHandlers = /* @__PURE__ */ new Set();
|
|
@@ -131,7 +126,6 @@ function registerProcessCleanup(handler) {
|
|
|
131
126
|
cleanupHandlers.delete(handler);
|
|
132
127
|
};
|
|
133
128
|
}
|
|
134
|
-
|
|
135
129
|
//#endregion
|
|
136
130
|
//#region src/lib/logger.ts
|
|
137
131
|
const LOG_RETENTION_MS = 10080 * 60 * 1e3;
|
|
@@ -237,15 +231,15 @@ const appendLine = (filePath, line) => {
|
|
|
237
231
|
buffer.push(line);
|
|
238
232
|
if (buffer.length >= MAX_BUFFER_SIZE) flushBuffer(filePath);
|
|
239
233
|
};
|
|
240
|
-
const debugLazy = (logger
|
|
234
|
+
const debugLazy = (logger, factory) => {
|
|
241
235
|
if (!state.verbose) return;
|
|
242
|
-
logger
|
|
236
|
+
logger.debug(...factory());
|
|
243
237
|
};
|
|
244
|
-
const debugJson = (logger
|
|
245
|
-
debugLazy(logger
|
|
238
|
+
const debugJson = (logger, label, value) => {
|
|
239
|
+
debugLazy(logger, () => [label, JSON.stringify(value)]);
|
|
246
240
|
};
|
|
247
|
-
const debugJsonTail = (logger
|
|
248
|
-
debugLazy(logger
|
|
241
|
+
const debugJsonTail = (logger, label, { value, tailLength = 400 }) => {
|
|
242
|
+
debugLazy(logger, () => [label, JSON.stringify(value).slice(-tailLength)]);
|
|
249
243
|
};
|
|
250
244
|
const createHandlerLogger = (name) => {
|
|
251
245
|
const sanitizedName = sanitizeName(name);
|
|
@@ -261,38 +255,35 @@ const createHandlerLogger = (name) => {
|
|
|
261
255
|
const filePath = path.join(LOG_DIR, `${sanitizedName}-${dateKey}.log`);
|
|
262
256
|
const message = formatArgs(logObj.args);
|
|
263
257
|
const traceIdStr = traceId ? ` [${traceId}]` : "";
|
|
264
|
-
|
|
265
|
-
appendLine(filePath, line);
|
|
258
|
+
appendLine(filePath, `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${traceIdStr}${message ? ` ${message}` : ""}`);
|
|
266
259
|
} });
|
|
267
260
|
return instance;
|
|
268
261
|
};
|
|
269
|
-
|
|
270
262
|
//#endregion
|
|
271
263
|
//#region src/lib/rate-limit.ts
|
|
272
|
-
async function checkRateLimit(state
|
|
273
|
-
if (state
|
|
264
|
+
async function checkRateLimit(state) {
|
|
265
|
+
if (state.rateLimitSeconds === void 0) return;
|
|
274
266
|
const now = Date.now();
|
|
275
|
-
if (!state
|
|
276
|
-
state
|
|
267
|
+
if (!state.lastRequestTimestamp) {
|
|
268
|
+
state.lastRequestTimestamp = now;
|
|
277
269
|
return;
|
|
278
270
|
}
|
|
279
|
-
const elapsedSeconds = (now - state
|
|
280
|
-
if (elapsedSeconds > state
|
|
281
|
-
state
|
|
271
|
+
const elapsedSeconds = (now - state.lastRequestTimestamp) / 1e3;
|
|
272
|
+
if (elapsedSeconds > state.rateLimitSeconds) {
|
|
273
|
+
state.lastRequestTimestamp = now;
|
|
282
274
|
return;
|
|
283
275
|
}
|
|
284
|
-
const waitTimeSeconds = Math.ceil(state
|
|
285
|
-
if (!state
|
|
276
|
+
const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds);
|
|
277
|
+
if (!state.rateLimitWait) {
|
|
286
278
|
consola.warn(`Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`);
|
|
287
279
|
throw new HTTPError("Rate limit exceeded", Response.json({ message: "Rate limit exceeded" }, { status: 429 }));
|
|
288
280
|
}
|
|
289
281
|
const waitTimeMs = waitTimeSeconds * 1e3;
|
|
290
282
|
consola.warn(`Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`);
|
|
291
283
|
await sleep(waitTimeMs);
|
|
292
|
-
state
|
|
284
|
+
state.lastRequestTimestamp = now;
|
|
293
285
|
consola.info("Rate limit wait completed, proceeding with request");
|
|
294
286
|
}
|
|
295
|
-
|
|
296
287
|
//#endregion
|
|
297
288
|
//#region src/lib/event-bus.ts
|
|
298
289
|
var EventBus = class {
|
|
@@ -316,7 +307,6 @@ var EventBus = class {
|
|
|
316
307
|
};
|
|
317
308
|
}
|
|
318
309
|
};
|
|
319
|
-
|
|
320
310
|
//#endregion
|
|
321
311
|
//#region src/lib/sqlite.ts
|
|
322
312
|
const MINIMUM_NODE_SQLITE_VERSION = "22.13.0";
|
|
@@ -395,7 +385,6 @@ var SqliteDbStore = class {
|
|
|
395
385
|
return db;
|
|
396
386
|
}
|
|
397
387
|
};
|
|
398
|
-
|
|
399
388
|
//#endregion
|
|
400
389
|
//#region src/lib/token-usage/store.ts
|
|
401
390
|
const DB_PATH_ENV = "COPILOT_API_SQLITE_DB_PATH";
|
|
@@ -573,12 +562,10 @@ function createEmptySummary(period) {
|
|
|
573
562
|
}
|
|
574
563
|
function createEmptyEventsPage(input) {
|
|
575
564
|
const range = getPeriodRange(input.period);
|
|
576
|
-
const page = Math.max(1, Math.floor(input.page));
|
|
577
|
-
const pageSize = Math.min(100, Math.max(1, Math.floor(input.pageSize)));
|
|
578
565
|
return {
|
|
579
566
|
items: [],
|
|
580
|
-
page,
|
|
581
|
-
page_size: pageSize,
|
|
567
|
+
page: Math.max(1, Math.floor(input.page)),
|
|
568
|
+
page_size: Math.min(100, Math.max(1, Math.floor(input.pageSize))),
|
|
582
569
|
period: input.period,
|
|
583
570
|
range: {
|
|
584
571
|
end_ms: range.endMs,
|
|
@@ -738,7 +725,6 @@ async function closeUsageStore() {
|
|
|
738
725
|
writeQueue = Promise.resolve();
|
|
739
726
|
}
|
|
740
727
|
registerProcessCleanup(closeUsageStore);
|
|
741
|
-
|
|
742
728
|
//#endregion
|
|
743
729
|
//#region src/lib/token-usage/index.ts
|
|
744
730
|
const tokenUsageEventBus = new EventBus();
|
|
@@ -838,7 +824,6 @@ function mergeAnthropicUsage(current, next) {
|
|
|
838
824
|
total_tokens: next.total_tokens ?? current.total_tokens
|
|
839
825
|
};
|
|
840
826
|
}
|
|
841
|
-
|
|
842
827
|
//#endregion
|
|
843
828
|
//#region src/lib/copilot-rate-limit.ts
|
|
844
829
|
const copilotRateLimitTypes = ["session", "weekly"];
|
|
@@ -884,12 +869,11 @@ const logCopilotRateLimits = (headers) => {
|
|
|
884
869
|
consola.info(`Copilot ${usage.type} quota remaining: ${usage.remaining}, resets at: ${dateStr}`);
|
|
885
870
|
}
|
|
886
871
|
};
|
|
887
|
-
|
|
888
872
|
//#endregion
|
|
889
873
|
//#region src/services/copilot/create-chat-completions.ts
|
|
890
874
|
const createChatCompletions = async (payload, options) => {
|
|
891
875
|
if (!state.copilotToken) throw new Error("Copilot token not found");
|
|
892
|
-
const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x
|
|
876
|
+
const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x) => x.type === "image_url"));
|
|
893
877
|
let isAgentCall = false;
|
|
894
878
|
if (payload.messages.length > 0) {
|
|
895
879
|
const lastMessage = payload.messages.at(-1);
|
|
@@ -915,7 +899,6 @@ const createChatCompletions = async (payload, options) => {
|
|
|
915
899
|
if (payload.stream) return events(response);
|
|
916
900
|
return await response.json();
|
|
917
901
|
};
|
|
918
|
-
|
|
919
902
|
//#endregion
|
|
920
903
|
//#region src/routes/chat-completions/handler.ts
|
|
921
904
|
const logger$6 = createHandlerLogger("chat-completions-handler");
|
|
@@ -979,7 +962,6 @@ const parseChatCompletionChunk = (chunk) => {
|
|
|
979
962
|
return null;
|
|
980
963
|
}
|
|
981
964
|
};
|
|
982
|
-
|
|
983
965
|
//#endregion
|
|
984
966
|
//#region src/routes/chat-completions/route.ts
|
|
985
967
|
const completionRoutes = new Hono();
|
|
@@ -990,7 +972,6 @@ completionRoutes.post("/", async (c) => {
|
|
|
990
972
|
return await forwardError(c, error);
|
|
991
973
|
}
|
|
992
974
|
});
|
|
993
|
-
|
|
994
975
|
//#endregion
|
|
995
976
|
//#region src/services/copilot/create-embeddings.ts
|
|
996
977
|
const createEmbeddings = async (payload) => {
|
|
@@ -1003,7 +984,6 @@ const createEmbeddings = async (payload) => {
|
|
|
1003
984
|
if (!response.ok) throw new HTTPError("Failed to create embeddings", response);
|
|
1004
985
|
return await response.json();
|
|
1005
986
|
};
|
|
1006
|
-
|
|
1007
987
|
//#endregion
|
|
1008
988
|
//#region src/routes/embeddings/route.ts
|
|
1009
989
|
const embeddingRoutes = new Hono();
|
|
@@ -1023,7 +1003,6 @@ embeddingRoutes.post("/", async (c) => {
|
|
|
1023
1003
|
return await forwardError(c, error);
|
|
1024
1004
|
}
|
|
1025
1005
|
});
|
|
1026
|
-
|
|
1027
1006
|
//#endregion
|
|
1028
1007
|
//#region src/lib/provider-model.ts
|
|
1029
1008
|
const parseProviderModelAlias = (model) => {
|
|
@@ -1054,7 +1033,6 @@ const createFallbackModel = (modelId) => ({
|
|
|
1054
1033
|
vendor: "provider",
|
|
1055
1034
|
version: "unknown"
|
|
1056
1035
|
});
|
|
1057
|
-
|
|
1058
1036
|
//#endregion
|
|
1059
1037
|
//#region src/lib/tokenizer.ts
|
|
1060
1038
|
const ENCODING_MAP = {
|
|
@@ -1259,8 +1237,7 @@ const numTokensForTools = (tools, encoder, constants) => {
|
|
|
1259
1237
|
* Calculate the token count of messages, supporting multiple GPT encoders
|
|
1260
1238
|
*/
|
|
1261
1239
|
const getTokenCount = async (payload, model) => {
|
|
1262
|
-
const
|
|
1263
|
-
const encoder = await getEncodeChatFunction(tokenizer);
|
|
1240
|
+
const encoder = await getEncodeChatFunction(getTokenizerFromModel(model));
|
|
1264
1241
|
const simplifiedMessages = payload.messages;
|
|
1265
1242
|
const inputMessages = simplifiedMessages.filter((msg) => msg.role !== "assistant");
|
|
1266
1243
|
const outputMessages = simplifiedMessages.filter((msg) => msg.role === "assistant");
|
|
@@ -1273,7 +1250,6 @@ const getTokenCount = async (payload, model) => {
|
|
|
1273
1250
|
output: outputTokens
|
|
1274
1251
|
};
|
|
1275
1252
|
};
|
|
1276
|
-
|
|
1277
1253
|
//#endregion
|
|
1278
1254
|
//#region src/routes/messages/utils.ts
|
|
1279
1255
|
function mapOpenAIStopReasonToAnthropic(finishReason) {
|
|
@@ -1285,23 +1261,20 @@ function mapOpenAIStopReasonToAnthropic(finishReason) {
|
|
|
1285
1261
|
content_filter: "end_turn"
|
|
1286
1262
|
}[finishReason];
|
|
1287
1263
|
}
|
|
1288
|
-
|
|
1289
1264
|
//#endregion
|
|
1290
1265
|
//#region src/routes/messages/non-stream-translation.ts
|
|
1291
1266
|
const THINKING_TEXT$1 = "Thinking...";
|
|
1292
|
-
const RICH_TOOL_RESULT_MOVED_TEXT = "Rich tool result content was moved to a user message because this upstream does not support it in tool messages.";
|
|
1293
1267
|
const COPILOT_TOOL_CONTENT_SUPPORT_TYPE = ["array", "image"];
|
|
1294
1268
|
function translateToOpenAI(payload, options = {}) {
|
|
1295
1269
|
const modelId = payload.model;
|
|
1296
1270
|
const model = state.models?.data.find((m) => m.id === modelId);
|
|
1297
1271
|
const thinkingBudget = getThinkingBudget(payload, model);
|
|
1298
|
-
const capabilities = {
|
|
1299
|
-
supportPdf: options.supportPdf ?? false,
|
|
1300
|
-
toolContentSupportType: options.toolContentSupportType ?? COPILOT_TOOL_CONTENT_SUPPORT_TYPE
|
|
1301
|
-
};
|
|
1302
1272
|
return {
|
|
1303
1273
|
model: modelId,
|
|
1304
|
-
messages: translateAnthropicMessagesToOpenAI(payload, modelId,
|
|
1274
|
+
messages: translateAnthropicMessagesToOpenAI(payload, modelId, {
|
|
1275
|
+
supportPdf: options.supportPdf ?? false,
|
|
1276
|
+
toolContentSupportType: options.toolContentSupportType ?? COPILOT_TOOL_CONTENT_SUPPORT_TYPE
|
|
1277
|
+
}),
|
|
1305
1278
|
max_tokens: payload.max_tokens,
|
|
1306
1279
|
stop: payload.stop_sequences,
|
|
1307
1280
|
stream: payload.stream,
|
|
@@ -1368,15 +1341,15 @@ function handleToolResultBlock(block, capabilities) {
|
|
|
1368
1341
|
if (typeof block.content === "string") return { toolMessage: createToolMessage(block.tool_use_id, block.content) };
|
|
1369
1342
|
if (!Array.isArray(block.content)) return { toolMessage: createToolMessage(block.tool_use_id, "") };
|
|
1370
1343
|
const support = getToolContentSupport(capabilities);
|
|
1371
|
-
const hasImage = block.content.some((block
|
|
1372
|
-
const hasDocument = block.content.some((block
|
|
1344
|
+
const hasImage = block.content.some((block) => block.type === "image");
|
|
1345
|
+
const hasDocument = block.content.some((block) => block.type === "document");
|
|
1373
1346
|
const content = mapContent(block.content, { supportPdf: capabilities.supportPdf });
|
|
1374
1347
|
const hasPdfFile = hasDocument && capabilities.supportPdf;
|
|
1375
1348
|
const shouldMoveImageToUserMessage = hasImage && !support.image;
|
|
1376
1349
|
const shouldMovePdfToUserMessage = hasPdfFile && !support.pdf;
|
|
1377
1350
|
if (shouldMoveImageToUserMessage || shouldMovePdfToUserMessage) return {
|
|
1378
1351
|
movedUserMessage: createToolResultUserMessage(block, capabilities.supportPdf),
|
|
1379
|
-
toolMessage: createToolMessage(block.tool_use_id, getTextToolContent(content) ||
|
|
1352
|
+
toolMessage: createToolMessage(block.tool_use_id, getTextToolContent(content) || "Rich tool result content was moved to a user message because this upstream does not support it in tool messages.")
|
|
1380
1353
|
};
|
|
1381
1354
|
const hasRichContent = hasImage || hasPdfFile;
|
|
1382
1355
|
if (support.array || hasRichContent) return { toolMessage: createToolMessage(block.tool_use_id, content) };
|
|
@@ -1425,8 +1398,8 @@ function handleAssistantMessage(message, modelId, capabilities) {
|
|
|
1425
1398
|
}];
|
|
1426
1399
|
const toolUseBlocks = message.content.filter((block) => block.type === "tool_use");
|
|
1427
1400
|
let thinkingBlocks = message.content.filter((block) => block.type === "thinking");
|
|
1428
|
-
if (modelId.startsWith("claude")) thinkingBlocks = thinkingBlocks.filter((b) => b.thinking && b.thinking !==
|
|
1429
|
-
const thinkingContents = thinkingBlocks.filter((b) => b.thinking && b.thinking !==
|
|
1401
|
+
if (modelId.startsWith("claude")) thinkingBlocks = thinkingBlocks.filter((b) => b.thinking && b.thinking !== "Thinking..." && b.signature && !b.signature.includes("@"));
|
|
1402
|
+
const thinkingContents = thinkingBlocks.filter((b) => b.thinking && b.thinking !== "Thinking...").map((b) => b.thinking);
|
|
1430
1403
|
const allThinkingContent = thinkingContents.length > 0 ? thinkingContents.join("\n\n") : void 0;
|
|
1431
1404
|
const signature = thinkingBlocks.find((b) => b.signature)?.signature;
|
|
1432
1405
|
return toolUseBlocks.length > 0 ? [{
|
|
@@ -1601,15 +1574,13 @@ function getAnthropicToolUseBlocks(toolCalls) {
|
|
|
1601
1574
|
input: JSON.parse(toolCall.function.arguments)
|
|
1602
1575
|
}));
|
|
1603
1576
|
}
|
|
1604
|
-
|
|
1605
1577
|
//#endregion
|
|
1606
1578
|
//#region src/routes/provider/messages/count-tokens-handler.ts
|
|
1607
1579
|
const logger$5 = createHandlerLogger("provider-count-tokens-handler");
|
|
1608
1580
|
async function handleProviderCountTokens(c) {
|
|
1609
1581
|
const provider = c.req.param("provider");
|
|
1610
|
-
const payload = await c.req.json();
|
|
1611
1582
|
return await handleProviderCountTokensForProvider(c, {
|
|
1612
|
-
payload,
|
|
1583
|
+
payload: await c.req.json(),
|
|
1613
1584
|
provider
|
|
1614
1585
|
});
|
|
1615
1586
|
}
|
|
@@ -1622,13 +1593,10 @@ async function handleProviderCountTokensForProvider(c, options) {
|
|
|
1622
1593
|
type: "invalid_request_error"
|
|
1623
1594
|
} }, 404);
|
|
1624
1595
|
const modelConfig = providerConfig.models?.[modelId];
|
|
1625
|
-
const
|
|
1596
|
+
const tokenCount = await getTokenCount(translateToOpenAI(anthropicPayload, providerConfig.type === "openai-compatible" ? {
|
|
1626
1597
|
supportPdf: modelConfig?.supportPdf,
|
|
1627
1598
|
toolContentSupportType: modelConfig?.toolContentSupportType ?? []
|
|
1628
|
-
} : void 0;
|
|
1629
|
-
const openAIPayload = translateToOpenAI(anthropicPayload, translationOptions);
|
|
1630
|
-
const selectedModel = createFallbackModel(modelId);
|
|
1631
|
-
const tokenCount = await getTokenCount(openAIPayload, selectedModel);
|
|
1599
|
+
} : void 0), createFallbackModel(modelId));
|
|
1632
1600
|
const finalTokenCount = tokenCount.input + tokenCount.output;
|
|
1633
1601
|
logger$5.debug("provider.count_tokens.success", {
|
|
1634
1602
|
provider,
|
|
@@ -1637,7 +1605,6 @@ async function handleProviderCountTokensForProvider(c, options) {
|
|
|
1637
1605
|
});
|
|
1638
1606
|
return c.json({ input_tokens: finalTokenCount });
|
|
1639
1607
|
}
|
|
1640
|
-
|
|
1641
1608
|
//#endregion
|
|
1642
1609
|
//#region src/lib/models.ts
|
|
1643
1610
|
const findEndpointModel = (sdkModelId) => {
|
|
@@ -1688,7 +1655,6 @@ const _normalizeSdkModelId = (sdkModelId) => {
|
|
|
1688
1655
|
version: pattern5[1]
|
|
1689
1656
|
};
|
|
1690
1657
|
};
|
|
1691
|
-
|
|
1692
1658
|
//#endregion
|
|
1693
1659
|
//#region src/routes/messages/count-tokens-handler.ts
|
|
1694
1660
|
const resolveCountTokensModel = (modelId, findModel = findEndpointModel) => {
|
|
@@ -1775,56 +1741,56 @@ async function handleCountTokens(c) {
|
|
|
1775
1741
|
consola.info("Token count:", finalTokenCount);
|
|
1776
1742
|
return c.json({ input_tokens: finalTokenCount });
|
|
1777
1743
|
}
|
|
1778
|
-
|
|
1779
1744
|
//#endregion
|
|
1780
1745
|
//#region src/routes/messages/stream-translation.ts
|
|
1781
|
-
function isToolBlockOpen(state
|
|
1782
|
-
if (!state
|
|
1783
|
-
return Object.values(state
|
|
1746
|
+
function isToolBlockOpen(state) {
|
|
1747
|
+
if (!state.contentBlockOpen) return false;
|
|
1748
|
+
return Object.values(state.toolCalls).some((tc) => tc.anthropicBlockIndex === state.contentBlockIndex);
|
|
1784
1749
|
}
|
|
1785
|
-
function translateChunkToAnthropicEvents(chunk, state
|
|
1786
|
-
const events
|
|
1750
|
+
function translateChunkToAnthropicEvents(chunk, state) {
|
|
1751
|
+
const events = [];
|
|
1787
1752
|
if (chunk.choices.length === 0) {
|
|
1788
|
-
completePendingMessage(state
|
|
1789
|
-
return events
|
|
1753
|
+
completePendingMessage(state, events, chunk);
|
|
1754
|
+
return events;
|
|
1790
1755
|
}
|
|
1791
1756
|
const choice = chunk.choices[0];
|
|
1792
1757
|
const { delta } = choice;
|
|
1793
|
-
handleMessageStart(state
|
|
1794
|
-
handleThinkingText(delta, state
|
|
1795
|
-
handleContent(delta, state
|
|
1796
|
-
handleToolCalls(delta, state
|
|
1797
|
-
handleFinish(choice, state
|
|
1798
|
-
events
|
|
1758
|
+
handleMessageStart(state, events, chunk);
|
|
1759
|
+
handleThinkingText(delta, state, events);
|
|
1760
|
+
handleContent(delta, state, events);
|
|
1761
|
+
handleToolCalls(delta, state, events);
|
|
1762
|
+
handleFinish(choice, state, {
|
|
1763
|
+
events,
|
|
1799
1764
|
chunk
|
|
1800
1765
|
});
|
|
1801
|
-
return events
|
|
1766
|
+
return events;
|
|
1802
1767
|
}
|
|
1803
|
-
function flushPendingAnthropicStreamEvents(state
|
|
1804
|
-
const events
|
|
1805
|
-
completePendingMessage(state
|
|
1806
|
-
return events
|
|
1768
|
+
function flushPendingAnthropicStreamEvents(state) {
|
|
1769
|
+
const events = [];
|
|
1770
|
+
completePendingMessage(state, events);
|
|
1771
|
+
return events;
|
|
1807
1772
|
}
|
|
1808
|
-
function completePendingMessage(state
|
|
1809
|
-
if (!state
|
|
1810
|
-
if (chunk?.usage) state
|
|
1811
|
-
events
|
|
1812
|
-
state
|
|
1773
|
+
function completePendingMessage(state, events, chunk) {
|
|
1774
|
+
if (!state.pendingMessageDelta) return;
|
|
1775
|
+
if (chunk?.usage) state.pendingMessageDelta.usage = getAnthropicUsageFromOpenAIChunk(chunk);
|
|
1776
|
+
events.push(state.pendingMessageDelta, { type: "message_stop" });
|
|
1777
|
+
state.pendingMessageDelta = void 0;
|
|
1813
1778
|
}
|
|
1814
|
-
function handleFinish(choice, state
|
|
1815
|
-
const { events
|
|
1779
|
+
function handleFinish(choice, state, context) {
|
|
1780
|
+
const { events, chunk } = context;
|
|
1816
1781
|
if (choice.finish_reason && choice.finish_reason.length > 0) {
|
|
1817
|
-
if (state
|
|
1818
|
-
const toolBlockOpen = isToolBlockOpen(state
|
|
1782
|
+
if (state.contentBlockOpen) {
|
|
1783
|
+
const toolBlockOpen = isToolBlockOpen(state);
|
|
1819
1784
|
context.events.push({
|
|
1820
1785
|
type: "content_block_stop",
|
|
1821
|
-
index: state
|
|
1786
|
+
index: state.contentBlockIndex
|
|
1822
1787
|
});
|
|
1823
|
-
state
|
|
1824
|
-
state
|
|
1825
|
-
if (!toolBlockOpen) handleReasoningOpaque(choice.delta, events
|
|
1788
|
+
state.contentBlockOpen = false;
|
|
1789
|
+
state.contentBlockIndex++;
|
|
1790
|
+
if (!toolBlockOpen) handleReasoningOpaque(choice.delta, events, state);
|
|
1826
1791
|
}
|
|
1827
|
-
state
|
|
1792
|
+
flushDeferredContent(state, events);
|
|
1793
|
+
state.pendingMessageDelta = {
|
|
1828
1794
|
type: "message_delta",
|
|
1829
1795
|
delta: {
|
|
1830
1796
|
stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
|
|
@@ -1832,7 +1798,7 @@ function handleFinish(choice, state$1, context) {
|
|
|
1832
1798
|
},
|
|
1833
1799
|
usage: getAnthropicUsageFromOpenAIChunk(chunk)
|
|
1834
1800
|
};
|
|
1835
|
-
if (chunk.usage) completePendingMessage(state
|
|
1801
|
+
if (chunk.usage) completePendingMessage(state, events, chunk);
|
|
1836
1802
|
}
|
|
1837
1803
|
}
|
|
1838
1804
|
function getAnthropicUsageFromOpenAIChunk(chunk) {
|
|
@@ -1854,27 +1820,27 @@ function getOpenAIChunkUsageTokens(chunk) {
|
|
|
1854
1820
|
inputTokens: Math.max(0, promptTokens - cachedTokens - cacheCreationTokens)
|
|
1855
1821
|
};
|
|
1856
1822
|
}
|
|
1857
|
-
function handleToolCalls(delta, state
|
|
1823
|
+
function handleToolCalls(delta, state, events) {
|
|
1858
1824
|
if (delta.tool_calls && delta.tool_calls.length > 0) {
|
|
1859
|
-
closeThinkingBlockIfOpen(state
|
|
1860
|
-
handleReasoningOpaqueInToolCalls(state
|
|
1825
|
+
closeThinkingBlockIfOpen(state, events);
|
|
1826
|
+
handleReasoningOpaqueInToolCalls(state, events, delta);
|
|
1861
1827
|
for (const toolCall of delta.tool_calls) {
|
|
1862
1828
|
if (toolCall.id && toolCall.function?.name) {
|
|
1863
|
-
if (state
|
|
1864
|
-
events
|
|
1829
|
+
if (state.contentBlockOpen) {
|
|
1830
|
+
events.push({
|
|
1865
1831
|
type: "content_block_stop",
|
|
1866
|
-
index: state
|
|
1832
|
+
index: state.contentBlockIndex
|
|
1867
1833
|
});
|
|
1868
|
-
state
|
|
1869
|
-
state
|
|
1834
|
+
state.contentBlockIndex++;
|
|
1835
|
+
state.contentBlockOpen = false;
|
|
1870
1836
|
}
|
|
1871
|
-
const anthropicBlockIndex = state
|
|
1872
|
-
state
|
|
1837
|
+
const anthropicBlockIndex = state.contentBlockIndex;
|
|
1838
|
+
state.toolCalls[toolCall.index] = {
|
|
1873
1839
|
id: toolCall.id,
|
|
1874
1840
|
name: toolCall.function.name,
|
|
1875
1841
|
anthropicBlockIndex
|
|
1876
1842
|
};
|
|
1877
|
-
events
|
|
1843
|
+
events.push({
|
|
1878
1844
|
type: "content_block_start",
|
|
1879
1845
|
index: anthropicBlockIndex,
|
|
1880
1846
|
content_block: {
|
|
@@ -1884,11 +1850,11 @@ function handleToolCalls(delta, state$1, events$1) {
|
|
|
1884
1850
|
input: {}
|
|
1885
1851
|
}
|
|
1886
1852
|
});
|
|
1887
|
-
state
|
|
1853
|
+
state.contentBlockOpen = true;
|
|
1888
1854
|
}
|
|
1889
1855
|
if (toolCall.function?.arguments) {
|
|
1890
|
-
const toolCallInfo = state
|
|
1891
|
-
if (toolCallInfo) events
|
|
1856
|
+
const toolCallInfo = state.toolCalls[toolCall.index];
|
|
1857
|
+
if (toolCallInfo) events.push({
|
|
1892
1858
|
type: "content_block_delta",
|
|
1893
1859
|
index: toolCallInfo.anthropicBlockIndex,
|
|
1894
1860
|
delta: {
|
|
@@ -1900,68 +1866,95 @@ function handleToolCalls(delta, state$1, events$1) {
|
|
|
1900
1866
|
}
|
|
1901
1867
|
}
|
|
1902
1868
|
}
|
|
1903
|
-
function handleReasoningOpaqueInToolCalls(state
|
|
1904
|
-
if (state
|
|
1905
|
-
events
|
|
1869
|
+
function handleReasoningOpaqueInToolCalls(state, events, delta) {
|
|
1870
|
+
if (state.contentBlockOpen && !isToolBlockOpen(state)) {
|
|
1871
|
+
events.push({
|
|
1906
1872
|
type: "content_block_stop",
|
|
1907
|
-
index: state
|
|
1873
|
+
index: state.contentBlockIndex
|
|
1908
1874
|
});
|
|
1909
|
-
state
|
|
1910
|
-
state
|
|
1875
|
+
state.contentBlockIndex++;
|
|
1876
|
+
state.contentBlockOpen = false;
|
|
1911
1877
|
}
|
|
1912
|
-
handleReasoningOpaque(delta, events
|
|
1878
|
+
handleReasoningOpaque(delta, events, state);
|
|
1913
1879
|
}
|
|
1914
|
-
function handleContent(delta, state
|
|
1880
|
+
function handleContent(delta, state, events) {
|
|
1915
1881
|
if (delta.content && delta.content.length > 0) {
|
|
1916
|
-
closeThinkingBlockIfOpen(state
|
|
1917
|
-
if (isToolBlockOpen(state
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
index: state$1.contentBlockIndex
|
|
1921
|
-
});
|
|
1922
|
-
state$1.contentBlockIndex++;
|
|
1923
|
-
state$1.contentBlockOpen = false;
|
|
1882
|
+
closeThinkingBlockIfOpen(state, events);
|
|
1883
|
+
if (isToolBlockOpen(state) || hasToolCallDelta(delta)) {
|
|
1884
|
+
state.deferredContent = `${state.deferredContent ?? ""}${delta.content}`;
|
|
1885
|
+
return;
|
|
1924
1886
|
}
|
|
1925
|
-
if (!state
|
|
1926
|
-
events
|
|
1887
|
+
if (!state.contentBlockOpen) {
|
|
1888
|
+
events.push({
|
|
1927
1889
|
type: "content_block_start",
|
|
1928
|
-
index: state
|
|
1890
|
+
index: state.contentBlockIndex,
|
|
1929
1891
|
content_block: {
|
|
1930
1892
|
type: "text",
|
|
1931
1893
|
text: ""
|
|
1932
1894
|
}
|
|
1933
1895
|
});
|
|
1934
|
-
state
|
|
1896
|
+
state.contentBlockOpen = true;
|
|
1935
1897
|
}
|
|
1936
|
-
events
|
|
1898
|
+
events.push({
|
|
1937
1899
|
type: "content_block_delta",
|
|
1938
|
-
index: state
|
|
1900
|
+
index: state.contentBlockIndex,
|
|
1939
1901
|
delta: {
|
|
1940
1902
|
type: "text_delta",
|
|
1941
1903
|
text: delta.content
|
|
1942
1904
|
}
|
|
1943
1905
|
});
|
|
1944
1906
|
}
|
|
1945
|
-
if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state
|
|
1946
|
-
events
|
|
1907
|
+
if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state.thinkingBlockOpen) {
|
|
1908
|
+
events.push({
|
|
1947
1909
|
type: "content_block_delta",
|
|
1948
|
-
index: state
|
|
1910
|
+
index: state.contentBlockIndex,
|
|
1949
1911
|
delta: {
|
|
1950
1912
|
type: "signature_delta",
|
|
1951
1913
|
signature: delta.reasoning_opaque
|
|
1952
1914
|
}
|
|
1953
1915
|
}, {
|
|
1954
1916
|
type: "content_block_stop",
|
|
1955
|
-
index: state
|
|
1917
|
+
index: state.contentBlockIndex
|
|
1918
|
+
});
|
|
1919
|
+
state.contentBlockIndex++;
|
|
1920
|
+
state.thinkingBlockOpen = false;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
function hasToolCallDelta(delta) {
|
|
1924
|
+
return Boolean(delta.tool_calls && delta.tool_calls.length > 0);
|
|
1925
|
+
}
|
|
1926
|
+
function flushDeferredContent(state, events) {
|
|
1927
|
+
if (!state.deferredContent) return;
|
|
1928
|
+
if (!state.contentBlockOpen) {
|
|
1929
|
+
events.push({
|
|
1930
|
+
type: "content_block_start",
|
|
1931
|
+
index: state.contentBlockIndex,
|
|
1932
|
+
content_block: {
|
|
1933
|
+
type: "text",
|
|
1934
|
+
text: ""
|
|
1935
|
+
}
|
|
1956
1936
|
});
|
|
1957
|
-
state
|
|
1958
|
-
state$1.thinkingBlockOpen = false;
|
|
1937
|
+
state.contentBlockOpen = true;
|
|
1959
1938
|
}
|
|
1939
|
+
events.push({
|
|
1940
|
+
type: "content_block_delta",
|
|
1941
|
+
index: state.contentBlockIndex,
|
|
1942
|
+
delta: {
|
|
1943
|
+
type: "text_delta",
|
|
1944
|
+
text: state.deferredContent
|
|
1945
|
+
}
|
|
1946
|
+
}, {
|
|
1947
|
+
type: "content_block_stop",
|
|
1948
|
+
index: state.contentBlockIndex
|
|
1949
|
+
});
|
|
1950
|
+
state.deferredContent = void 0;
|
|
1951
|
+
state.contentBlockOpen = false;
|
|
1952
|
+
state.contentBlockIndex++;
|
|
1960
1953
|
}
|
|
1961
|
-
function handleMessageStart(state
|
|
1962
|
-
if (!state
|
|
1954
|
+
function handleMessageStart(state, events, chunk) {
|
|
1955
|
+
if (!state.messageStartSent) {
|
|
1963
1956
|
const { cachedTokens, cacheCreationTokens, inputTokens } = getOpenAIChunkUsageTokens(chunk);
|
|
1964
|
-
events
|
|
1957
|
+
events.push({
|
|
1965
1958
|
type: "message_start",
|
|
1966
1959
|
message: {
|
|
1967
1960
|
id: chunk.id,
|
|
@@ -1979,62 +1972,62 @@ function handleMessageStart(state$1, events$1, chunk) {
|
|
|
1979
1972
|
}
|
|
1980
1973
|
}
|
|
1981
1974
|
});
|
|
1982
|
-
state
|
|
1975
|
+
state.messageStartSent = true;
|
|
1983
1976
|
}
|
|
1984
1977
|
}
|
|
1985
|
-
function handleReasoningOpaque(delta, events
|
|
1978
|
+
function handleReasoningOpaque(delta, events, state) {
|
|
1986
1979
|
if (delta.reasoning_opaque && delta.reasoning_opaque.length > 0) {
|
|
1987
|
-
events
|
|
1980
|
+
events.push({
|
|
1988
1981
|
type: "content_block_start",
|
|
1989
|
-
index: state
|
|
1982
|
+
index: state.contentBlockIndex,
|
|
1990
1983
|
content_block: {
|
|
1991
1984
|
type: "thinking",
|
|
1992
1985
|
thinking: ""
|
|
1993
1986
|
}
|
|
1994
1987
|
}, {
|
|
1995
1988
|
type: "content_block_delta",
|
|
1996
|
-
index: state
|
|
1989
|
+
index: state.contentBlockIndex,
|
|
1997
1990
|
delta: {
|
|
1998
1991
|
type: "thinking_delta",
|
|
1999
1992
|
thinking: THINKING_TEXT$1
|
|
2000
1993
|
}
|
|
2001
1994
|
}, {
|
|
2002
1995
|
type: "content_block_delta",
|
|
2003
|
-
index: state
|
|
1996
|
+
index: state.contentBlockIndex,
|
|
2004
1997
|
delta: {
|
|
2005
1998
|
type: "signature_delta",
|
|
2006
1999
|
signature: delta.reasoning_opaque
|
|
2007
2000
|
}
|
|
2008
2001
|
}, {
|
|
2009
2002
|
type: "content_block_stop",
|
|
2010
|
-
index: state
|
|
2003
|
+
index: state.contentBlockIndex
|
|
2011
2004
|
});
|
|
2012
|
-
state
|
|
2005
|
+
state.contentBlockIndex++;
|
|
2013
2006
|
}
|
|
2014
2007
|
}
|
|
2015
|
-
function handleThinkingText(delta, state
|
|
2008
|
+
function handleThinkingText(delta, state, events) {
|
|
2016
2009
|
const reasoningText = delta.reasoning_text ?? delta.reasoning_content;
|
|
2017
2010
|
if (reasoningText && reasoningText.length > 0) {
|
|
2018
|
-
if (state
|
|
2011
|
+
if (state.contentBlockOpen) {
|
|
2019
2012
|
delta.content = reasoningText;
|
|
2020
2013
|
delta.reasoning_text = void 0;
|
|
2021
2014
|
delta.reasoning_content = void 0;
|
|
2022
2015
|
return;
|
|
2023
2016
|
}
|
|
2024
|
-
if (!state
|
|
2025
|
-
events
|
|
2017
|
+
if (!state.thinkingBlockOpen) {
|
|
2018
|
+
events.push({
|
|
2026
2019
|
type: "content_block_start",
|
|
2027
|
-
index: state
|
|
2020
|
+
index: state.contentBlockIndex,
|
|
2028
2021
|
content_block: {
|
|
2029
2022
|
type: "thinking",
|
|
2030
2023
|
thinking: ""
|
|
2031
2024
|
}
|
|
2032
2025
|
});
|
|
2033
|
-
state
|
|
2026
|
+
state.thinkingBlockOpen = true;
|
|
2034
2027
|
}
|
|
2035
|
-
events
|
|
2028
|
+
events.push({
|
|
2036
2029
|
type: "content_block_delta",
|
|
2037
|
-
index: state
|
|
2030
|
+
index: state.contentBlockIndex,
|
|
2038
2031
|
delta: {
|
|
2039
2032
|
type: "thinking_delta",
|
|
2040
2033
|
thinking: reasoningText
|
|
@@ -2042,24 +2035,23 @@ function handleThinkingText(delta, state$1, events$1) {
|
|
|
2042
2035
|
});
|
|
2043
2036
|
}
|
|
2044
2037
|
}
|
|
2045
|
-
function closeThinkingBlockIfOpen(state
|
|
2046
|
-
if (state
|
|
2047
|
-
events
|
|
2038
|
+
function closeThinkingBlockIfOpen(state, events) {
|
|
2039
|
+
if (state.thinkingBlockOpen) {
|
|
2040
|
+
events.push({
|
|
2048
2041
|
type: "content_block_delta",
|
|
2049
|
-
index: state
|
|
2042
|
+
index: state.contentBlockIndex,
|
|
2050
2043
|
delta: {
|
|
2051
2044
|
type: "signature_delta",
|
|
2052
2045
|
signature: ""
|
|
2053
2046
|
}
|
|
2054
2047
|
}, {
|
|
2055
2048
|
type: "content_block_stop",
|
|
2056
|
-
index: state
|
|
2049
|
+
index: state.contentBlockIndex
|
|
2057
2050
|
});
|
|
2058
|
-
state
|
|
2059
|
-
state
|
|
2051
|
+
state.contentBlockIndex++;
|
|
2052
|
+
state.thinkingBlockOpen = false;
|
|
2060
2053
|
}
|
|
2061
2054
|
}
|
|
2062
|
-
|
|
2063
2055
|
//#endregion
|
|
2064
2056
|
//#region src/services/providers/anthropic-proxy.ts
|
|
2065
2057
|
const SHARED_FORWARDABLE_HEADERS = ["accept", "user-agent"];
|
|
@@ -2125,7 +2117,6 @@ async function forwardProviderModels(providerConfig, requestHeaders) {
|
|
|
2125
2117
|
headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
|
|
2126
2118
|
});
|
|
2127
2119
|
}
|
|
2128
|
-
|
|
2129
2120
|
//#endregion
|
|
2130
2121
|
//#region src/routes/provider/messages/handler.ts
|
|
2131
2122
|
const logger$4 = createHandlerLogger("provider-messages-handler");
|
|
@@ -2139,9 +2130,8 @@ const OPENAI_COMPATIBLE_CONTEXT_CACHE_ROLES = new Set([
|
|
|
2139
2130
|
]);
|
|
2140
2131
|
async function handleProviderMessages(c) {
|
|
2141
2132
|
const provider = c.req.param("provider");
|
|
2142
|
-
const payload = await c.req.json();
|
|
2143
2133
|
return await handleProviderMessagesForProvider(c, {
|
|
2144
|
-
payload,
|
|
2134
|
+
payload: await c.req.json(),
|
|
2145
2135
|
provider
|
|
2146
2136
|
});
|
|
2147
2137
|
}
|
|
@@ -2179,9 +2169,8 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
2179
2169
|
providerConfig,
|
|
2180
2170
|
upstreamResponse
|
|
2181
2171
|
});
|
|
2182
|
-
const jsonBody = await upstreamResponse.json();
|
|
2183
2172
|
return respondProviderMessagesJson(c, {
|
|
2184
|
-
body:
|
|
2173
|
+
body: await upstreamResponse.json(),
|
|
2185
2174
|
payload,
|
|
2186
2175
|
provider,
|
|
2187
2176
|
providerConfig
|
|
@@ -2221,9 +2210,8 @@ const handleOpenAICompatibleProviderMessages = async (c, options) => {
|
|
|
2221
2210
|
provider,
|
|
2222
2211
|
upstreamResponse
|
|
2223
2212
|
});
|
|
2224
|
-
const jsonBody = await upstreamResponse.json();
|
|
2225
2213
|
return respondOpenAICompatibleProviderMessagesJson(c, {
|
|
2226
|
-
body:
|
|
2214
|
+
body: await upstreamResponse.json(),
|
|
2227
2215
|
payload,
|
|
2228
2216
|
provider
|
|
2229
2217
|
});
|
|
@@ -2350,8 +2338,8 @@ const streamOpenAICompatibleProviderMessages = ({ c, payload, provider, upstream
|
|
|
2350
2338
|
const parsed = parseOpenAICompatibleStreamChunk(chunk.data);
|
|
2351
2339
|
if (!parsed) continue;
|
|
2352
2340
|
if (parsed.usage) usage = normalizeOpenAIUsage(parsed.usage);
|
|
2353
|
-
const events
|
|
2354
|
-
for (const event of events
|
|
2341
|
+
const events = translateChunkToAnthropicEvents(parsed, streamState);
|
|
2342
|
+
for (const event of events) {
|
|
2355
2343
|
const eventData = JSON.stringify(event);
|
|
2356
2344
|
debugLazy(logger$4, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
2357
2345
|
await stream.writeSSE({
|
|
@@ -2438,7 +2426,6 @@ const adjustInputTokens = (providerConfig, usage) => {
|
|
|
2438
2426
|
usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
|
|
2439
2427
|
debugJson(logger$4, "provider.messages.adjusted_usage:", usage);
|
|
2440
2428
|
};
|
|
2441
|
-
|
|
2442
2429
|
//#endregion
|
|
2443
2430
|
//#region src/services/copilot/create-responses.ts
|
|
2444
2431
|
const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType }) => {
|
|
@@ -2464,7 +2451,6 @@ const createResponses = async (payload, { vision, initiator, subagentMarker, req
|
|
|
2464
2451
|
if (payload.stream) return events(response);
|
|
2465
2452
|
return await response.json();
|
|
2466
2453
|
};
|
|
2467
|
-
|
|
2468
2454
|
//#endregion
|
|
2469
2455
|
//#region src/routes/messages/responses-translation.ts
|
|
2470
2456
|
const MESSAGE_TYPE = "message";
|
|
@@ -2636,7 +2622,7 @@ const createFileContent = (block) => ({
|
|
|
2636
2622
|
});
|
|
2637
2623
|
const createReasoningContent = (block) => {
|
|
2638
2624
|
const { encryptedContent, id } = parseReasoningSignature(block.signature);
|
|
2639
|
-
const thinking = block.thinking ===
|
|
2625
|
+
const thinking = block.thinking === "Thinking..." ? "" : block.thinking;
|
|
2640
2626
|
return {
|
|
2641
2627
|
id,
|
|
2642
2628
|
type: "reasoning",
|
|
@@ -2864,9 +2850,8 @@ const mapResponsesStopReason = (response) => {
|
|
|
2864
2850
|
const mapResponsesUsage = (response) => {
|
|
2865
2851
|
const inputTokens = response.usage?.input_tokens ?? 0;
|
|
2866
2852
|
const outputTokens = response.usage?.output_tokens ?? 0;
|
|
2867
|
-
const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
|
|
2868
2853
|
return {
|
|
2869
|
-
input_tokens: inputTokens - (
|
|
2854
|
+
input_tokens: inputTokens - (response.usage?.input_tokens_details?.cached_tokens ?? 0),
|
|
2870
2855
|
output_tokens: outputTokens,
|
|
2871
2856
|
...response.usage?.input_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.input_tokens_details.cached_tokens }
|
|
2872
2857
|
};
|
|
@@ -2897,7 +2882,6 @@ const convertToolResultContent = (content) => {
|
|
|
2897
2882
|
}
|
|
2898
2883
|
return "";
|
|
2899
2884
|
};
|
|
2900
|
-
|
|
2901
2885
|
//#endregion
|
|
2902
2886
|
//#region src/routes/messages/responses-stream-translation.ts
|
|
2903
2887
|
const MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20;
|
|
@@ -2934,40 +2918,40 @@ const createResponsesStreamState = () => ({
|
|
|
2934
2918
|
blockHasDelta: /* @__PURE__ */ new Set(),
|
|
2935
2919
|
functionCallStateByOutputIndex: /* @__PURE__ */ new Map()
|
|
2936
2920
|
});
|
|
2937
|
-
const translateResponsesStreamEvent = (rawEvent, state
|
|
2921
|
+
const translateResponsesStreamEvent = (rawEvent, state) => {
|
|
2938
2922
|
switch (rawEvent.type) {
|
|
2939
|
-
case "response.created": return handleResponseCreated(rawEvent, state
|
|
2940
|
-
case "response.output_item.added": return handleOutputItemAdded$1(rawEvent, state
|
|
2941
|
-
case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state
|
|
2942
|
-
case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state
|
|
2943
|
-
case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state
|
|
2944
|
-
case "response.output_text.done": return handleOutputTextDone(rawEvent, state
|
|
2945
|
-
case "response.output_item.done": return handleOutputItemDone$1(rawEvent, state
|
|
2946
|
-
case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state
|
|
2947
|
-
case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state
|
|
2923
|
+
case "response.created": return handleResponseCreated(rawEvent, state);
|
|
2924
|
+
case "response.output_item.added": return handleOutputItemAdded$1(rawEvent, state);
|
|
2925
|
+
case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state);
|
|
2926
|
+
case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state);
|
|
2927
|
+
case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state);
|
|
2928
|
+
case "response.output_text.done": return handleOutputTextDone(rawEvent, state);
|
|
2929
|
+
case "response.output_item.done": return handleOutputItemDone$1(rawEvent, state);
|
|
2930
|
+
case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state);
|
|
2931
|
+
case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state);
|
|
2948
2932
|
case "response.completed":
|
|
2949
|
-
case "response.incomplete": return handleResponseCompleted(rawEvent, state
|
|
2950
|
-
case "response.failed": return handleResponseFailed(rawEvent, state
|
|
2951
|
-
case "error": return handleErrorEvent(rawEvent, state
|
|
2933
|
+
case "response.incomplete": return handleResponseCompleted(rawEvent, state);
|
|
2934
|
+
case "response.failed": return handleResponseFailed(rawEvent, state);
|
|
2935
|
+
case "error": return handleErrorEvent(rawEvent, state);
|
|
2952
2936
|
default: return [];
|
|
2953
2937
|
}
|
|
2954
2938
|
};
|
|
2955
|
-
const handleResponseCreated = (rawEvent, state
|
|
2956
|
-
return messageStart(state
|
|
2939
|
+
const handleResponseCreated = (rawEvent, state) => {
|
|
2940
|
+
return messageStart(state, rawEvent.response);
|
|
2957
2941
|
};
|
|
2958
|
-
const handleOutputItemAdded$1 = (rawEvent, state
|
|
2959
|
-
const events
|
|
2942
|
+
const handleOutputItemAdded$1 = (rawEvent, state) => {
|
|
2943
|
+
const events = new Array();
|
|
2960
2944
|
const functionCallDetails = extractFunctionCallDetails(rawEvent);
|
|
2961
|
-
if (!functionCallDetails) return events
|
|
2945
|
+
if (!functionCallDetails) return events;
|
|
2962
2946
|
const { outputIndex, toolCallId, name, initialArguments } = functionCallDetails;
|
|
2963
|
-
const blockIndex = openFunctionCallBlock(state
|
|
2947
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
2964
2948
|
outputIndex,
|
|
2965
2949
|
toolCallId,
|
|
2966
2950
|
name,
|
|
2967
|
-
events
|
|
2951
|
+
events
|
|
2968
2952
|
});
|
|
2969
2953
|
if (initialArguments !== void 0 && initialArguments.length > 0) {
|
|
2970
|
-
events
|
|
2954
|
+
events.push({
|
|
2971
2955
|
type: "content_block_delta",
|
|
2972
2956
|
index: blockIndex,
|
|
2973
2957
|
delta: {
|
|
@@ -2975,29 +2959,29 @@ const handleOutputItemAdded$1 = (rawEvent, state$1) => {
|
|
|
2975
2959
|
partial_json: initialArguments
|
|
2976
2960
|
}
|
|
2977
2961
|
});
|
|
2978
|
-
state
|
|
2962
|
+
state.blockHasDelta.add(blockIndex);
|
|
2979
2963
|
}
|
|
2980
|
-
return events
|
|
2964
|
+
return events;
|
|
2981
2965
|
};
|
|
2982
|
-
const handleOutputItemDone$1 = (rawEvent, state
|
|
2983
|
-
const events
|
|
2966
|
+
const handleOutputItemDone$1 = (rawEvent, state) => {
|
|
2967
|
+
const events = new Array();
|
|
2984
2968
|
const item = rawEvent.item;
|
|
2985
2969
|
const itemType = item.type;
|
|
2986
2970
|
const outputIndex = rawEvent.output_index;
|
|
2987
2971
|
if (itemType === "compaction") {
|
|
2988
|
-
if (!item.id || !item.encrypted_content) return events
|
|
2989
|
-
const blockIndex
|
|
2990
|
-
if (!state
|
|
2972
|
+
if (!item.id || !item.encrypted_content) return events;
|
|
2973
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
2974
|
+
if (!state.blockHasDelta.has(blockIndex)) events.push({
|
|
2991
2975
|
type: "content_block_delta",
|
|
2992
|
-
index: blockIndex
|
|
2976
|
+
index: blockIndex,
|
|
2993
2977
|
delta: {
|
|
2994
2978
|
type: "thinking_delta",
|
|
2995
2979
|
thinking: THINKING_TEXT
|
|
2996
2980
|
}
|
|
2997
2981
|
});
|
|
2998
|
-
events
|
|
2982
|
+
events.push({
|
|
2999
2983
|
type: "content_block_delta",
|
|
3000
|
-
index: blockIndex
|
|
2984
|
+
index: blockIndex,
|
|
3001
2985
|
delta: {
|
|
3002
2986
|
type: "signature_delta",
|
|
3003
2987
|
signature: encodeCompactionCarrierSignature({
|
|
@@ -3006,14 +2990,14 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3006
2990
|
})
|
|
3007
2991
|
}
|
|
3008
2992
|
});
|
|
3009
|
-
state
|
|
3010
|
-
return events
|
|
2993
|
+
state.blockHasDelta.add(blockIndex);
|
|
2994
|
+
return events;
|
|
3011
2995
|
}
|
|
3012
|
-
if (itemType !== "reasoning") return events
|
|
3013
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
2996
|
+
if (itemType !== "reasoning") return events;
|
|
2997
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3014
2998
|
const signature = (item.encrypted_content ?? "") + "@" + item.id;
|
|
3015
2999
|
if (signature) {
|
|
3016
|
-
if (!item.summary || item.summary.length === 0) events
|
|
3000
|
+
if (!item.summary || item.summary.length === 0) events.push({
|
|
3017
3001
|
type: "content_block_delta",
|
|
3018
3002
|
index: blockIndex,
|
|
3019
3003
|
delta: {
|
|
@@ -3021,7 +3005,7 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3021
3005
|
thinking: THINKING_TEXT
|
|
3022
3006
|
}
|
|
3023
3007
|
});
|
|
3024
|
-
events
|
|
3008
|
+
events.push({
|
|
3025
3009
|
type: "content_block_delta",
|
|
3026
3010
|
index: blockIndex,
|
|
3027
3011
|
delta: {
|
|
@@ -3029,25 +3013,25 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3029
3013
|
signature
|
|
3030
3014
|
}
|
|
3031
3015
|
});
|
|
3032
|
-
state
|
|
3016
|
+
state.blockHasDelta.add(blockIndex);
|
|
3033
3017
|
}
|
|
3034
|
-
return events
|
|
3018
|
+
return events;
|
|
3035
3019
|
};
|
|
3036
|
-
const handleFunctionCallArgumentsDelta = (rawEvent, state
|
|
3037
|
-
const events
|
|
3020
|
+
const handleFunctionCallArgumentsDelta = (rawEvent, state) => {
|
|
3021
|
+
const events = new Array();
|
|
3038
3022
|
const outputIndex = rawEvent.output_index;
|
|
3039
3023
|
const deltaText = rawEvent.delta;
|
|
3040
|
-
if (!deltaText) return events
|
|
3041
|
-
const blockIndex = openFunctionCallBlock(state
|
|
3024
|
+
if (!deltaText) return events;
|
|
3025
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
3042
3026
|
outputIndex,
|
|
3043
|
-
events
|
|
3027
|
+
events
|
|
3044
3028
|
});
|
|
3045
|
-
const functionCallState = state
|
|
3046
|
-
if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state
|
|
3029
|
+
const functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
|
|
3030
|
+
if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state, events);
|
|
3047
3031
|
const { nextCount, exceeded } = updateWhitespaceRunState(functionCallState.consecutiveWhitespaceCount, deltaText);
|
|
3048
|
-
if (exceeded) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta containing more than 20 consecutive whitespace characters."), state
|
|
3032
|
+
if (exceeded) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta containing more than 20 consecutive whitespace characters."), state, events);
|
|
3049
3033
|
functionCallState.consecutiveWhitespaceCount = nextCount;
|
|
3050
|
-
events
|
|
3034
|
+
events.push({
|
|
3051
3035
|
type: "content_block_delta",
|
|
3052
3036
|
index: blockIndex,
|
|
3053
3037
|
delta: {
|
|
@@ -3055,19 +3039,19 @@ const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
|
|
|
3055
3039
|
partial_json: deltaText
|
|
3056
3040
|
}
|
|
3057
3041
|
});
|
|
3058
|
-
state
|
|
3059
|
-
return events
|
|
3042
|
+
state.blockHasDelta.add(blockIndex);
|
|
3043
|
+
return events;
|
|
3060
3044
|
};
|
|
3061
|
-
const handleFunctionCallArgumentsDone = (rawEvent, state
|
|
3062
|
-
const events
|
|
3045
|
+
const handleFunctionCallArgumentsDone = (rawEvent, state) => {
|
|
3046
|
+
const events = new Array();
|
|
3063
3047
|
const outputIndex = rawEvent.output_index;
|
|
3064
|
-
const blockIndex = openFunctionCallBlock(state
|
|
3048
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
3065
3049
|
outputIndex,
|
|
3066
|
-
events
|
|
3050
|
+
events
|
|
3067
3051
|
});
|
|
3068
3052
|
const finalArguments = typeof rawEvent.arguments === "string" ? rawEvent.arguments : void 0;
|
|
3069
|
-
if (!state
|
|
3070
|
-
events
|
|
3053
|
+
if (!state.blockHasDelta.has(blockIndex) && finalArguments) {
|
|
3054
|
+
events.push({
|
|
3071
3055
|
type: "content_block_delta",
|
|
3072
3056
|
index: blockIndex,
|
|
3073
3057
|
delta: {
|
|
@@ -3075,23 +3059,23 @@ const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
|
|
|
3075
3059
|
partial_json: finalArguments
|
|
3076
3060
|
}
|
|
3077
3061
|
});
|
|
3078
|
-
state
|
|
3062
|
+
state.blockHasDelta.add(blockIndex);
|
|
3079
3063
|
}
|
|
3080
|
-
state
|
|
3081
|
-
return events
|
|
3064
|
+
state.functionCallStateByOutputIndex.delete(outputIndex);
|
|
3065
|
+
return events;
|
|
3082
3066
|
};
|
|
3083
|
-
const handleOutputTextDelta = (rawEvent, state
|
|
3084
|
-
const events
|
|
3067
|
+
const handleOutputTextDelta = (rawEvent, state) => {
|
|
3068
|
+
const events = new Array();
|
|
3085
3069
|
const outputIndex = rawEvent.output_index;
|
|
3086
3070
|
const contentIndex = rawEvent.content_index;
|
|
3087
3071
|
const deltaText = rawEvent.delta;
|
|
3088
|
-
if (!deltaText) return events
|
|
3089
|
-
const blockIndex = openTextBlockIfNeeded(state
|
|
3072
|
+
if (!deltaText) return events;
|
|
3073
|
+
const blockIndex = openTextBlockIfNeeded(state, {
|
|
3090
3074
|
outputIndex,
|
|
3091
3075
|
contentIndex,
|
|
3092
|
-
events
|
|
3076
|
+
events
|
|
3093
3077
|
});
|
|
3094
|
-
events
|
|
3078
|
+
events.push({
|
|
3095
3079
|
type: "content_block_delta",
|
|
3096
3080
|
index: blockIndex,
|
|
3097
3081
|
delta: {
|
|
@@ -3099,15 +3083,15 @@ const handleOutputTextDelta = (rawEvent, state$1) => {
|
|
|
3099
3083
|
text: deltaText
|
|
3100
3084
|
}
|
|
3101
3085
|
});
|
|
3102
|
-
state
|
|
3103
|
-
return events
|
|
3086
|
+
state.blockHasDelta.add(blockIndex);
|
|
3087
|
+
return events;
|
|
3104
3088
|
};
|
|
3105
|
-
const handleReasoningSummaryTextDelta = (rawEvent, state
|
|
3089
|
+
const handleReasoningSummaryTextDelta = (rawEvent, state) => {
|
|
3106
3090
|
const outputIndex = rawEvent.output_index;
|
|
3107
3091
|
const deltaText = rawEvent.delta;
|
|
3108
|
-
const events
|
|
3109
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
3110
|
-
events
|
|
3092
|
+
const events = new Array();
|
|
3093
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3094
|
+
events.push({
|
|
3111
3095
|
type: "content_block_delta",
|
|
3112
3096
|
index: blockIndex,
|
|
3113
3097
|
delta: {
|
|
@@ -3115,15 +3099,15 @@ const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
|
|
|
3115
3099
|
thinking: deltaText
|
|
3116
3100
|
}
|
|
3117
3101
|
});
|
|
3118
|
-
state
|
|
3119
|
-
return events
|
|
3102
|
+
state.blockHasDelta.add(blockIndex);
|
|
3103
|
+
return events;
|
|
3120
3104
|
};
|
|
3121
|
-
const handleReasoningSummaryTextDone = (rawEvent, state
|
|
3105
|
+
const handleReasoningSummaryTextDone = (rawEvent, state) => {
|
|
3122
3106
|
const outputIndex = rawEvent.output_index;
|
|
3123
3107
|
const text = rawEvent.text;
|
|
3124
|
-
const events
|
|
3125
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
3126
|
-
if (text && !state
|
|
3108
|
+
const events = new Array();
|
|
3109
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3110
|
+
if (text && !state.blockHasDelta.has(blockIndex)) events.push({
|
|
3127
3111
|
type: "content_block_delta",
|
|
3128
3112
|
index: blockIndex,
|
|
3129
3113
|
delta: {
|
|
@@ -3131,19 +3115,19 @@ const handleReasoningSummaryTextDone = (rawEvent, state$1) => {
|
|
|
3131
3115
|
thinking: text
|
|
3132
3116
|
}
|
|
3133
3117
|
});
|
|
3134
|
-
return events
|
|
3118
|
+
return events;
|
|
3135
3119
|
};
|
|
3136
|
-
const handleOutputTextDone = (rawEvent, state
|
|
3137
|
-
const events
|
|
3120
|
+
const handleOutputTextDone = (rawEvent, state) => {
|
|
3121
|
+
const events = new Array();
|
|
3138
3122
|
const outputIndex = rawEvent.output_index;
|
|
3139
3123
|
const contentIndex = rawEvent.content_index;
|
|
3140
3124
|
const text = rawEvent.text;
|
|
3141
|
-
const blockIndex = openTextBlockIfNeeded(state
|
|
3125
|
+
const blockIndex = openTextBlockIfNeeded(state, {
|
|
3142
3126
|
outputIndex,
|
|
3143
3127
|
contentIndex,
|
|
3144
|
-
events
|
|
3128
|
+
events
|
|
3145
3129
|
});
|
|
3146
|
-
if (text && !state
|
|
3130
|
+
if (text && !state.blockHasDelta.has(blockIndex)) events.push({
|
|
3147
3131
|
type: "content_block_delta",
|
|
3148
3132
|
index: blockIndex,
|
|
3149
3133
|
delta: {
|
|
@@ -3151,14 +3135,14 @@ const handleOutputTextDone = (rawEvent, state$1) => {
|
|
|
3151
3135
|
text
|
|
3152
3136
|
}
|
|
3153
3137
|
});
|
|
3154
|
-
return events
|
|
3138
|
+
return events;
|
|
3155
3139
|
};
|
|
3156
|
-
const handleResponseCompleted = (rawEvent, state
|
|
3140
|
+
const handleResponseCompleted = (rawEvent, state) => {
|
|
3157
3141
|
const response = rawEvent.response;
|
|
3158
|
-
const events
|
|
3159
|
-
closeAllOpenBlocks(state
|
|
3142
|
+
const events = new Array();
|
|
3143
|
+
closeAllOpenBlocks(state, events);
|
|
3160
3144
|
const anthropic = translateResponsesResultToAnthropic(response);
|
|
3161
|
-
events
|
|
3145
|
+
events.push({
|
|
3162
3146
|
type: "message_delta",
|
|
3163
3147
|
delta: {
|
|
3164
3148
|
stop_reason: anthropic.stop_reason,
|
|
@@ -3166,32 +3150,32 @@ const handleResponseCompleted = (rawEvent, state$1) => {
|
|
|
3166
3150
|
},
|
|
3167
3151
|
usage: anthropic.usage
|
|
3168
3152
|
}, { type: "message_stop" });
|
|
3169
|
-
state
|
|
3170
|
-
return events
|
|
3153
|
+
state.messageCompleted = true;
|
|
3154
|
+
return events;
|
|
3171
3155
|
};
|
|
3172
|
-
const handleResponseFailed = (rawEvent, state
|
|
3156
|
+
const handleResponseFailed = (rawEvent, state) => {
|
|
3173
3157
|
const response = rawEvent.response;
|
|
3174
|
-
const events
|
|
3175
|
-
closeAllOpenBlocks(state
|
|
3158
|
+
const events = new Array();
|
|
3159
|
+
closeAllOpenBlocks(state, events);
|
|
3176
3160
|
const message = response.error?.message ?? "The response failed due to an unknown error.";
|
|
3177
|
-
events
|
|
3178
|
-
state
|
|
3179
|
-
return events
|
|
3161
|
+
events.push(buildErrorEvent(message));
|
|
3162
|
+
state.messageCompleted = true;
|
|
3163
|
+
return events;
|
|
3180
3164
|
};
|
|
3181
|
-
const handleErrorEvent = (rawEvent, state
|
|
3165
|
+
const handleErrorEvent = (rawEvent, state) => {
|
|
3182
3166
|
const message = typeof rawEvent.message === "string" ? rawEvent.message : "An unexpected error occurred during streaming.";
|
|
3183
|
-
state
|
|
3167
|
+
state.messageCompleted = true;
|
|
3184
3168
|
return [buildErrorEvent(message)];
|
|
3185
3169
|
};
|
|
3186
|
-
const handleFunctionCallArgumentsValidationError = (error, state
|
|
3170
|
+
const handleFunctionCallArgumentsValidationError = (error, state, events = []) => {
|
|
3187
3171
|
const reason = error.message;
|
|
3188
|
-
closeAllOpenBlocks(state
|
|
3189
|
-
state
|
|
3190
|
-
events
|
|
3191
|
-
return events
|
|
3172
|
+
closeAllOpenBlocks(state, events);
|
|
3173
|
+
state.messageCompleted = true;
|
|
3174
|
+
events.push(buildErrorEvent(reason));
|
|
3175
|
+
return events;
|
|
3192
3176
|
};
|
|
3193
|
-
const messageStart = (state
|
|
3194
|
-
state
|
|
3177
|
+
const messageStart = (state, response) => {
|
|
3178
|
+
state.messageStartSent = true;
|
|
3195
3179
|
const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
|
|
3196
3180
|
const inputTokens = (response.usage?.input_tokens ?? 0) - (inputCachedTokens ?? 0);
|
|
3197
3181
|
return [{
|
|
@@ -3212,18 +3196,18 @@ const messageStart = (state$1, response) => {
|
|
|
3212
3196
|
}
|
|
3213
3197
|
}];
|
|
3214
3198
|
};
|
|
3215
|
-
const openTextBlockIfNeeded = (state
|
|
3216
|
-
const { outputIndex, contentIndex, events
|
|
3199
|
+
const openTextBlockIfNeeded = (state, params) => {
|
|
3200
|
+
const { outputIndex, contentIndex, events } = params;
|
|
3217
3201
|
const key = getBlockKey(outputIndex, contentIndex);
|
|
3218
|
-
let blockIndex = state
|
|
3202
|
+
let blockIndex = state.blockIndexByKey.get(key);
|
|
3219
3203
|
if (blockIndex === void 0) {
|
|
3220
|
-
blockIndex = state
|
|
3221
|
-
state
|
|
3222
|
-
state
|
|
3204
|
+
blockIndex = state.nextContentBlockIndex;
|
|
3205
|
+
state.nextContentBlockIndex += 1;
|
|
3206
|
+
state.blockIndexByKey.set(key, blockIndex);
|
|
3223
3207
|
}
|
|
3224
|
-
if (!state
|
|
3225
|
-
closeOpenBlocks(state
|
|
3226
|
-
events
|
|
3208
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3209
|
+
closeOpenBlocks(state, events);
|
|
3210
|
+
events.push({
|
|
3227
3211
|
type: "content_block_start",
|
|
3228
3212
|
index: blockIndex,
|
|
3229
3213
|
content_block: {
|
|
@@ -3231,21 +3215,21 @@ const openTextBlockIfNeeded = (state$1, params) => {
|
|
|
3231
3215
|
text: ""
|
|
3232
3216
|
}
|
|
3233
3217
|
});
|
|
3234
|
-
state
|
|
3218
|
+
state.openBlocks.add(blockIndex);
|
|
3235
3219
|
}
|
|
3236
3220
|
return blockIndex;
|
|
3237
3221
|
};
|
|
3238
|
-
const openThinkingBlockIfNeeded = (state
|
|
3222
|
+
const openThinkingBlockIfNeeded = (state, outputIndex, events) => {
|
|
3239
3223
|
const key = getBlockKey(outputIndex, 0);
|
|
3240
|
-
let blockIndex = state
|
|
3224
|
+
let blockIndex = state.blockIndexByKey.get(key);
|
|
3241
3225
|
if (blockIndex === void 0) {
|
|
3242
|
-
blockIndex = state
|
|
3243
|
-
state
|
|
3244
|
-
state
|
|
3226
|
+
blockIndex = state.nextContentBlockIndex;
|
|
3227
|
+
state.nextContentBlockIndex += 1;
|
|
3228
|
+
state.blockIndexByKey.set(key, blockIndex);
|
|
3245
3229
|
}
|
|
3246
|
-
if (!state
|
|
3247
|
-
closeOpenBlocks(state
|
|
3248
|
-
events
|
|
3230
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3231
|
+
closeOpenBlocks(state, events);
|
|
3232
|
+
events.push({
|
|
3249
3233
|
type: "content_block_start",
|
|
3250
3234
|
index: blockIndex,
|
|
3251
3235
|
content_block: {
|
|
@@ -3253,25 +3237,25 @@ const openThinkingBlockIfNeeded = (state$1, outputIndex, events$1) => {
|
|
|
3253
3237
|
thinking: ""
|
|
3254
3238
|
}
|
|
3255
3239
|
});
|
|
3256
|
-
state
|
|
3240
|
+
state.openBlocks.add(blockIndex);
|
|
3257
3241
|
}
|
|
3258
3242
|
return blockIndex;
|
|
3259
3243
|
};
|
|
3260
|
-
const closeBlockIfOpen = (state
|
|
3261
|
-
if (!state
|
|
3262
|
-
events
|
|
3244
|
+
const closeBlockIfOpen = (state, blockIndex, events) => {
|
|
3245
|
+
if (!state.openBlocks.has(blockIndex)) return;
|
|
3246
|
+
events.push({
|
|
3263
3247
|
type: "content_block_stop",
|
|
3264
3248
|
index: blockIndex
|
|
3265
3249
|
});
|
|
3266
|
-
state
|
|
3267
|
-
state
|
|
3250
|
+
state.openBlocks.delete(blockIndex);
|
|
3251
|
+
state.blockHasDelta.delete(blockIndex);
|
|
3268
3252
|
};
|
|
3269
|
-
const closeOpenBlocks = (state
|
|
3270
|
-
for (const blockIndex of state
|
|
3253
|
+
const closeOpenBlocks = (state, events) => {
|
|
3254
|
+
for (const blockIndex of state.openBlocks) closeBlockIfOpen(state, blockIndex, events);
|
|
3271
3255
|
};
|
|
3272
|
-
const closeAllOpenBlocks = (state
|
|
3273
|
-
closeOpenBlocks(state
|
|
3274
|
-
state
|
|
3256
|
+
const closeAllOpenBlocks = (state, events) => {
|
|
3257
|
+
closeOpenBlocks(state, events);
|
|
3258
|
+
state.functionCallStateByOutputIndex.clear();
|
|
3275
3259
|
};
|
|
3276
3260
|
const buildErrorEvent = (message) => ({
|
|
3277
3261
|
type: "error",
|
|
@@ -3281,25 +3265,24 @@ const buildErrorEvent = (message) => ({
|
|
|
3281
3265
|
}
|
|
3282
3266
|
});
|
|
3283
3267
|
const getBlockKey = (outputIndex, contentIndex) => `${outputIndex}:${contentIndex}`;
|
|
3284
|
-
const openFunctionCallBlock = (state
|
|
3285
|
-
const { outputIndex, toolCallId, name, events
|
|
3286
|
-
let functionCallState = state
|
|
3268
|
+
const openFunctionCallBlock = (state, params) => {
|
|
3269
|
+
const { outputIndex, toolCallId, name, events } = params;
|
|
3270
|
+
let functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
|
|
3287
3271
|
if (!functionCallState) {
|
|
3288
|
-
const blockIndex
|
|
3289
|
-
state
|
|
3290
|
-
const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex$1}`;
|
|
3272
|
+
const blockIndex = state.nextContentBlockIndex;
|
|
3273
|
+
state.nextContentBlockIndex += 1;
|
|
3291
3274
|
functionCallState = {
|
|
3292
|
-
blockIndex
|
|
3293
|
-
toolCallId:
|
|
3275
|
+
blockIndex,
|
|
3276
|
+
toolCallId: toolCallId ?? `tool_call_${blockIndex}`,
|
|
3294
3277
|
name: name ?? "function",
|
|
3295
3278
|
consecutiveWhitespaceCount: 0
|
|
3296
3279
|
};
|
|
3297
|
-
state
|
|
3280
|
+
state.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
|
|
3298
3281
|
}
|
|
3299
3282
|
const { blockIndex } = functionCallState;
|
|
3300
|
-
if (!state
|
|
3301
|
-
closeOpenBlocks(state
|
|
3302
|
-
events
|
|
3283
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3284
|
+
closeOpenBlocks(state, events);
|
|
3285
|
+
events.push({
|
|
3303
3286
|
type: "content_block_start",
|
|
3304
3287
|
index: blockIndex,
|
|
3305
3288
|
content_block: {
|
|
@@ -3309,33 +3292,26 @@ const openFunctionCallBlock = (state$1, params) => {
|
|
|
3309
3292
|
input: {}
|
|
3310
3293
|
}
|
|
3311
3294
|
});
|
|
3312
|
-
state
|
|
3295
|
+
state.openBlocks.add(blockIndex);
|
|
3313
3296
|
}
|
|
3314
3297
|
return blockIndex;
|
|
3315
3298
|
};
|
|
3316
3299
|
const extractFunctionCallDetails = (rawEvent) => {
|
|
3317
3300
|
const item = rawEvent.item;
|
|
3318
3301
|
if (item.type !== "function_call") return;
|
|
3319
|
-
const outputIndex = rawEvent.output_index;
|
|
3320
|
-
const toolCallId = item.call_id;
|
|
3321
|
-
const name = item.name;
|
|
3322
|
-
const initialArguments = item.arguments;
|
|
3323
3302
|
return {
|
|
3324
|
-
outputIndex,
|
|
3325
|
-
toolCallId,
|
|
3326
|
-
name,
|
|
3327
|
-
initialArguments
|
|
3303
|
+
outputIndex: rawEvent.output_index,
|
|
3304
|
+
toolCallId: item.call_id,
|
|
3305
|
+
name: item.name,
|
|
3306
|
+
initialArguments: item.arguments
|
|
3328
3307
|
};
|
|
3329
3308
|
};
|
|
3330
|
-
|
|
3331
3309
|
//#endregion
|
|
3332
3310
|
//#region src/routes/responses/utils.ts
|
|
3333
3311
|
const getResponsesRequestOptions = (payload) => {
|
|
3334
|
-
const vision = hasVisionInput(payload);
|
|
3335
|
-
const initiator = hasAgentInitiator(payload) ? "agent" : "user";
|
|
3336
3312
|
return {
|
|
3337
|
-
vision,
|
|
3338
|
-
initiator
|
|
3313
|
+
vision: hasVisionInput(payload),
|
|
3314
|
+
initiator: hasAgentInitiator(payload) ? "agent" : "user"
|
|
3339
3315
|
};
|
|
3340
3316
|
};
|
|
3341
3317
|
const hasAgentInitiator = (payload) => {
|
|
@@ -3387,7 +3363,6 @@ const containsVisionContent = (value) => {
|
|
|
3387
3363
|
if (Array.isArray(record.content)) return record.content.some((entry) => containsVisionContent(entry));
|
|
3388
3364
|
return false;
|
|
3389
3365
|
};
|
|
3390
|
-
|
|
3391
3366
|
//#endregion
|
|
3392
3367
|
//#region src/services/copilot/create-messages.ts
|
|
3393
3368
|
const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
@@ -3438,10 +3413,6 @@ const createMessages = async (payload, anthropicBetaHeader, options) => {
|
|
|
3438
3413
|
if (payload.stream) return events(response);
|
|
3439
3414
|
return await response.json();
|
|
3440
3415
|
};
|
|
3441
|
-
|
|
3442
|
-
//#endregion
|
|
3443
|
-
//#region src/routes/messages/preprocess.ts
|
|
3444
|
-
const TOOL_REFERENCE_TURN_BOUNDARY = "Tool loaded.";
|
|
3445
3416
|
const IDE_EXECUTE_CODE_TOOL = "mcp__ide__executeCode";
|
|
3446
3417
|
const IDE_GET_DIAGNOSTICS_TOOL = "mcp__ide__getDiagnostics";
|
|
3447
3418
|
const IDE_GET_DIAGNOSTICS_DESCRIPTION = "Get language diagnostics from VS Code. Returns errors, warnings, information, and hints for files in the workspace.";
|
|
@@ -3454,7 +3425,7 @@ const getCompactCandidateText = (message) => {
|
|
|
3454
3425
|
const isCompactMessage = (lastMessage) => {
|
|
3455
3426
|
const text = getCompactCandidateText(lastMessage);
|
|
3456
3427
|
if (!text) return false;
|
|
3457
|
-
return text.includes(
|
|
3428
|
+
return text.includes("CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.") && text.includes("Your task is to create a detailed summary of the conversation so far") && compactMessageSections.some((section) => text.includes(section));
|
|
3458
3429
|
};
|
|
3459
3430
|
const isCompactAutoContinueMessage = (lastMessage) => {
|
|
3460
3431
|
const text = getCompactCandidateText(lastMessage);
|
|
@@ -3462,12 +3433,12 @@ const isCompactAutoContinueMessage = (lastMessage) => {
|
|
|
3462
3433
|
};
|
|
3463
3434
|
const getCompactType = (anthropicPayload) => {
|
|
3464
3435
|
const lastMessage = anthropicPayload.messages.at(-1);
|
|
3465
|
-
if (lastMessage && isCompactMessage(lastMessage)) return
|
|
3466
|
-
if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return
|
|
3436
|
+
if (lastMessage && isCompactMessage(lastMessage)) return 1;
|
|
3437
|
+
if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return 2;
|
|
3467
3438
|
const system = anthropicPayload.system;
|
|
3468
|
-
if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ?
|
|
3439
|
+
if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ? 1 : 0;
|
|
3469
3440
|
if (!Array.isArray(system)) return 0;
|
|
3470
|
-
if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return
|
|
3441
|
+
if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return 1;
|
|
3471
3442
|
return 0;
|
|
3472
3443
|
};
|
|
3473
3444
|
const mergeContentWithText = (tr, textBlock) => {
|
|
@@ -3519,8 +3490,7 @@ const mergeAttachmentsIntoToolResults = (toolResults, attachmentsByToolResultInd
|
|
|
3519
3490
|
return toolResults.map((block, index) => {
|
|
3520
3491
|
const matchedAttachments = attachmentsByToolResultIndex.get(index);
|
|
3521
3492
|
if (!matchedAttachments) return block;
|
|
3522
|
-
|
|
3523
|
-
return mergeContentWithAttachments(block, orderedAttachments);
|
|
3493
|
+
return mergeContentWithAttachments(block, [...matchedAttachments].sort((left, right) => left.order - right.order).map(({ attachment }) => attachment));
|
|
3524
3494
|
});
|
|
3525
3495
|
};
|
|
3526
3496
|
const assignAttachmentsToToolResults = (target, attachments, options) => {
|
|
@@ -3529,9 +3499,9 @@ const assignAttachmentsToToolResults = (target, attachments, options) => {
|
|
|
3529
3499
|
if (attachments.length === 0) return;
|
|
3530
3500
|
if (toolResultIndices.length > 0 && toolResultIndices.length === attachments.length) {
|
|
3531
3501
|
for (const [index, toolResultIndex] of toolResultIndices.entries()) {
|
|
3532
|
-
const currentAttachments
|
|
3533
|
-
if (currentAttachments
|
|
3534
|
-
currentAttachments
|
|
3502
|
+
const currentAttachments = target.get(toolResultIndex);
|
|
3503
|
+
if (currentAttachments) {
|
|
3504
|
+
currentAttachments.push(attachments[index]);
|
|
3535
3505
|
continue;
|
|
3536
3506
|
}
|
|
3537
3507
|
target.set(toolResultIndex, [attachments[index]]);
|
|
@@ -3612,8 +3582,7 @@ const mergeUserMessageContent = (content) => {
|
|
|
3612
3582
|
if (!mergeableContent) return null;
|
|
3613
3583
|
const { toolResults, textBlocks, attachments } = mergeableContent;
|
|
3614
3584
|
if (toolResults.length === 0 || textBlocks.length === 0 && attachments.length === 0) return null;
|
|
3615
|
-
|
|
3616
|
-
return mergeAttachmentsForToolResults(mergedToolResults, attachments);
|
|
3585
|
+
return mergeAttachmentsForToolResults(textBlocks.length === 0 ? toolResults : mergeToolResult(toolResults, textBlocks), attachments);
|
|
3617
3586
|
};
|
|
3618
3587
|
const mergeToolResult = (toolResults, textBlocks) => {
|
|
3619
3588
|
if (toolResults.length === textBlocks.length) return toolResults.map((tr, i) => mergeContentWithText(tr, textBlocks[i]));
|
|
@@ -3624,7 +3593,7 @@ const stripToolReferenceTurnBoundary = (anthropicPayload) => {
|
|
|
3624
3593
|
for (const msg of anthropicPayload.messages) {
|
|
3625
3594
|
if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
|
|
3626
3595
|
if (!msg.content.some((block) => block.type === "tool_result" && hasToolRef(block))) continue;
|
|
3627
|
-
msg.content = msg.content.filter((block) => block.type !== "text" || block.text.trim() !==
|
|
3596
|
+
msg.content = msg.content.filter((block) => block.type !== "text" || block.text.trim() !== "Tool loaded.");
|
|
3628
3597
|
}
|
|
3629
3598
|
};
|
|
3630
3599
|
const mergeToolResultForClaude = (anthropicPayload, options) => {
|
|
@@ -3655,7 +3624,7 @@ const stripCacheControl = (payload) => {
|
|
|
3655
3624
|
const systemBlock = block;
|
|
3656
3625
|
const cacheControl = systemBlock.cache_control;
|
|
3657
3626
|
if (cacheControl && typeof cacheControl === "object") {
|
|
3658
|
-
const { scope
|
|
3627
|
+
const { scope, ...rest } = cacheControl;
|
|
3659
3628
|
systemBlock.cache_control = rest;
|
|
3660
3629
|
}
|
|
3661
3630
|
}
|
|
@@ -3683,14 +3652,13 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
|
|
|
3683
3652
|
payload.output_config = { effort };
|
|
3684
3653
|
}
|
|
3685
3654
|
};
|
|
3686
|
-
|
|
3687
3655
|
//#endregion
|
|
3688
3656
|
//#region src/routes/messages/api-flows.ts
|
|
3689
3657
|
const COPILOT_CONTEXT_CACHE_SYSTEM_MARKER_LIMIT = 2;
|
|
3690
3658
|
const COPILOT_CONTEXT_CACHE_NON_SYSTEM_MARKER_LIMIT = 2;
|
|
3691
3659
|
const COPILOT_CONTEXT_CACHE_CONTROL = { type: "ephemeral" };
|
|
3692
3660
|
const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
3693
|
-
const { logger
|
|
3661
|
+
const { logger, subagentMarker, requestId, sessionId, compactType } = options;
|
|
3694
3662
|
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
3695
3663
|
prepareCopilotChatCompletionsPayload(openAIPayload);
|
|
3696
3664
|
const recordUsage = createCopilotUsageRecorder({
|
|
@@ -3699,7 +3667,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3699
3667
|
model: openAIPayload.model,
|
|
3700
3668
|
payload: anthropicPayload
|
|
3701
3669
|
});
|
|
3702
|
-
debugJson(logger
|
|
3670
|
+
debugJson(logger, "Translated OpenAI request payload:", openAIPayload);
|
|
3703
3671
|
const response = await createChatCompletions(openAIPayload, {
|
|
3704
3672
|
subagentMarker,
|
|
3705
3673
|
requestId,
|
|
@@ -3707,13 +3675,13 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3707
3675
|
compactType
|
|
3708
3676
|
});
|
|
3709
3677
|
if (isNonStreaming(response)) {
|
|
3710
|
-
debugJson(logger
|
|
3678
|
+
debugJson(logger, "Non-streaming response from Copilot:", response);
|
|
3711
3679
|
recordUsage(normalizeOpenAIUsage(response.usage));
|
|
3712
3680
|
const anthropicResponse = translateToAnthropic(response);
|
|
3713
|
-
debugJson(logger
|
|
3681
|
+
debugJson(logger, "Translated Anthropic response:", anthropicResponse);
|
|
3714
3682
|
return c.json(anthropicResponse);
|
|
3715
3683
|
}
|
|
3716
|
-
logger
|
|
3684
|
+
logger.debug("Streaming response from Copilot");
|
|
3717
3685
|
return streamSSE(c, async (stream) => {
|
|
3718
3686
|
let usage = {};
|
|
3719
3687
|
const streamState = {
|
|
@@ -3724,15 +3692,15 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3724
3692
|
thinkingBlockOpen: false
|
|
3725
3693
|
};
|
|
3726
3694
|
for await (const rawEvent of response) {
|
|
3727
|
-
debugJson(logger
|
|
3695
|
+
debugJson(logger, "Copilot raw stream event:", rawEvent);
|
|
3728
3696
|
if (rawEvent.data === "[DONE]") break;
|
|
3729
3697
|
if (!rawEvent.data) continue;
|
|
3730
3698
|
const chunk = JSON.parse(rawEvent.data);
|
|
3731
3699
|
if (chunk.usage) usage = normalizeOpenAIUsage(chunk.usage);
|
|
3732
|
-
const events
|
|
3733
|
-
for (const event of events
|
|
3700
|
+
const events = translateChunkToAnthropicEvents(chunk, streamState);
|
|
3701
|
+
for (const event of events) {
|
|
3734
3702
|
const eventData = JSON.stringify(event);
|
|
3735
|
-
debugLazy(logger
|
|
3703
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3736
3704
|
await stream.writeSSE({
|
|
3737
3705
|
event: event.type,
|
|
3738
3706
|
data: eventData
|
|
@@ -3741,7 +3709,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3741
3709
|
}
|
|
3742
3710
|
for (const event of flushPendingAnthropicStreamEvents(streamState)) {
|
|
3743
3711
|
const eventData = JSON.stringify(event);
|
|
3744
|
-
debugLazy(logger
|
|
3712
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3745
3713
|
await stream.writeSSE({
|
|
3746
3714
|
event: event.type,
|
|
3747
3715
|
data: eventData
|
|
@@ -3751,7 +3719,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3751
3719
|
});
|
|
3752
3720
|
};
|
|
3753
3721
|
const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
3754
|
-
const { logger
|
|
3722
|
+
const { logger, selectedModel, ...requestOptions } = options;
|
|
3755
3723
|
const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload);
|
|
3756
3724
|
const recordUsage = createCopilotUsageRecorder({
|
|
3757
3725
|
endpoint: "responses",
|
|
@@ -3761,7 +3729,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3761
3729
|
});
|
|
3762
3730
|
applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
|
|
3763
3731
|
compactInputByLatestCompaction(responsesPayload);
|
|
3764
|
-
debugJson(logger
|
|
3732
|
+
debugJson(logger, "Translated Responses payload:", responsesPayload);
|
|
3765
3733
|
const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
|
|
3766
3734
|
const response = await createResponses(responsesPayload, {
|
|
3767
3735
|
vision,
|
|
@@ -3769,7 +3737,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3769
3737
|
...requestOptions
|
|
3770
3738
|
});
|
|
3771
3739
|
if (responsesPayload.stream && isAsyncIterable$1(response)) {
|
|
3772
|
-
logger
|
|
3740
|
+
logger.debug("Streaming response from Copilot (Responses API)");
|
|
3773
3741
|
return streamSSE(c, async (stream) => {
|
|
3774
3742
|
const streamState = createResponsesStreamState();
|
|
3775
3743
|
let usage = {};
|
|
@@ -3783,25 +3751,25 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3783
3751
|
}
|
|
3784
3752
|
const data = chunk.data;
|
|
3785
3753
|
if (!data) continue;
|
|
3786
|
-
debugLazy(logger
|
|
3754
|
+
debugLazy(logger, () => ["Responses raw stream event:", data]);
|
|
3787
3755
|
const responseEvent = JSON.parse(data);
|
|
3788
3756
|
if (responseEvent.type === "response.completed" || responseEvent.type === "response.failed" || responseEvent.type === "response.incomplete") usage = normalizeResponsesUsage(responseEvent.response.usage);
|
|
3789
|
-
const events
|
|
3790
|
-
for (const event of events
|
|
3757
|
+
const events = translateResponsesStreamEvent(responseEvent, streamState);
|
|
3758
|
+
for (const event of events) {
|
|
3791
3759
|
const eventData = JSON.stringify(event);
|
|
3792
|
-
debugLazy(logger
|
|
3760
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3793
3761
|
await stream.writeSSE({
|
|
3794
3762
|
event: event.type,
|
|
3795
3763
|
data: eventData
|
|
3796
3764
|
});
|
|
3797
3765
|
}
|
|
3798
3766
|
if (streamState.messageCompleted) {
|
|
3799
|
-
logger
|
|
3767
|
+
logger.debug("Message completed, ending stream");
|
|
3800
3768
|
break;
|
|
3801
3769
|
}
|
|
3802
3770
|
}
|
|
3803
3771
|
if (!streamState.messageCompleted) {
|
|
3804
|
-
logger
|
|
3772
|
+
logger.warn("Responses stream ended without completion; sending error event");
|
|
3805
3773
|
const errorEvent = buildErrorEvent("Responses stream ended without completion");
|
|
3806
3774
|
await stream.writeSSE({
|
|
3807
3775
|
event: errorEvent.type,
|
|
@@ -3811,17 +3779,17 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3811
3779
|
recordUsage(usage);
|
|
3812
3780
|
});
|
|
3813
3781
|
}
|
|
3814
|
-
debugJsonTail(logger
|
|
3782
|
+
debugJsonTail(logger, "Non-streaming Responses result:", {
|
|
3815
3783
|
value: response,
|
|
3816
3784
|
tailLength: 400
|
|
3817
3785
|
});
|
|
3818
3786
|
const anthropicResponse = translateResponsesResultToAnthropic(response);
|
|
3819
3787
|
recordUsage(normalizeResponsesUsage(response.usage));
|
|
3820
|
-
debugJson(logger
|
|
3788
|
+
debugJson(logger, "Translated Anthropic response:", anthropicResponse);
|
|
3821
3789
|
return c.json(anthropicResponse);
|
|
3822
3790
|
};
|
|
3823
3791
|
const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
3824
|
-
const { logger
|
|
3792
|
+
const { logger, anthropicBetaHeader, subagentMarker, selectedModel, requestId, sessionId, compactType } = options;
|
|
3825
3793
|
prepareMessagesApiPayload(anthropicPayload, selectedModel);
|
|
3826
3794
|
const recordUsage = createCopilotUsageRecorder({
|
|
3827
3795
|
endpoint: "messages",
|
|
@@ -3829,7 +3797,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3829
3797
|
model: anthropicPayload.model,
|
|
3830
3798
|
payload: anthropicPayload
|
|
3831
3799
|
});
|
|
3832
|
-
debugJson(logger
|
|
3800
|
+
debugJson(logger, "Translated Messages payload:", anthropicPayload);
|
|
3833
3801
|
const response = await createMessages(anthropicPayload, anthropicBetaHeader, {
|
|
3834
3802
|
subagentMarker,
|
|
3835
3803
|
requestId,
|
|
@@ -3837,7 +3805,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3837
3805
|
compactType
|
|
3838
3806
|
});
|
|
3839
3807
|
if (isAsyncIterable$1(response)) {
|
|
3840
|
-
logger
|
|
3808
|
+
logger.debug("Streaming response from Copilot (Messages API)");
|
|
3841
3809
|
return streamSSE(c, async (stream) => {
|
|
3842
3810
|
let usage = {};
|
|
3843
3811
|
for await (const event of response) {
|
|
@@ -3845,7 +3813,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3845
3813
|
const data = event.data ?? "";
|
|
3846
3814
|
if (data === "[DONE]") break;
|
|
3847
3815
|
if (!data) continue;
|
|
3848
|
-
debugLazy(logger
|
|
3816
|
+
debugLazy(logger, () => ["Messages raw stream event:", data]);
|
|
3849
3817
|
const parsedEvent = parseAnthropicStreamEvent(data);
|
|
3850
3818
|
if (parsedEvent?.type === "message_start") usage = mergeAnthropicUsage(usage, normalizeAnthropicUsage(parsedEvent.message.usage));
|
|
3851
3819
|
else if (parsedEvent?.type === "message_delta") usage = mergeAnthropicUsage(usage, normalizeAnthropicUsage(parsedEvent.usage));
|
|
@@ -3857,7 +3825,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3857
3825
|
recordUsage(usage);
|
|
3858
3826
|
});
|
|
3859
3827
|
}
|
|
3860
|
-
debugJsonTail(logger
|
|
3828
|
+
debugJsonTail(logger, "Non-streaming Messages result:", {
|
|
3861
3829
|
value: response,
|
|
3862
3830
|
tailLength: 400
|
|
3863
3831
|
});
|
|
@@ -3900,11 +3868,9 @@ const parseAnthropicStreamEvent = (data) => {
|
|
|
3900
3868
|
return null;
|
|
3901
3869
|
}
|
|
3902
3870
|
};
|
|
3903
|
-
|
|
3904
3871
|
//#endregion
|
|
3905
3872
|
//#region src/lib/subagent.ts
|
|
3906
3873
|
const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
|
|
3907
|
-
|
|
3908
3874
|
//#endregion
|
|
3909
3875
|
//#region src/routes/messages/subagent-marker.ts
|
|
3910
3876
|
const parseSubagentMarkerFromFirstUser = (payload) => {
|
|
@@ -3933,7 +3899,7 @@ const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
|
3933
3899
|
searchFrom = reminderEnd + 18;
|
|
3934
3900
|
continue;
|
|
3935
3901
|
}
|
|
3936
|
-
const markerJson = reminderContent.slice(markerIndex +
|
|
3902
|
+
const markerJson = reminderContent.slice(markerIndex + 19).trim();
|
|
3937
3903
|
try {
|
|
3938
3904
|
const parsed = JSON.parse(markerJson);
|
|
3939
3905
|
if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {
|
|
@@ -3948,7 +3914,6 @@ const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
|
3948
3914
|
}
|
|
3949
3915
|
return null;
|
|
3950
3916
|
};
|
|
3951
|
-
|
|
3952
3917
|
//#endregion
|
|
3953
3918
|
//#region src/routes/messages/handler.ts
|
|
3954
3919
|
const logger$3 = createHandlerLogger("messages-handler");
|
|
@@ -3981,7 +3946,7 @@ async function handleCompletion(c) {
|
|
|
3981
3946
|
if (anthropicBeta && noTools && compactType === 0) anthropicPayload.model = getSmallModel();
|
|
3982
3947
|
if (compactType) logger$3.debug("Compact request type:", compactType);
|
|
3983
3948
|
stripToolReferenceTurnBoundary(anthropicPayload);
|
|
3984
|
-
mergeToolResultForClaude(anthropicPayload, { skipLastMessage: compactType ===
|
|
3949
|
+
mergeToolResultForClaude(anthropicPayload, { skipLastMessage: compactType === 1 });
|
|
3985
3950
|
const requestId = generateRequestIdFromPayload(anthropicPayload, sessionId);
|
|
3986
3951
|
logger$3.debug("Generated request ID:", requestId);
|
|
3987
3952
|
if (state.manualApprove) await awaitApproval();
|
|
@@ -4021,7 +3986,6 @@ const shouldUseMessagesApi = (selectedModel) => {
|
|
|
4021
3986
|
if (!isMessagesApiEnabled()) return false;
|
|
4022
3987
|
return selectedModel?.supported_endpoints?.includes(MESSAGES_ENDPOINT) ?? false;
|
|
4023
3988
|
};
|
|
4024
|
-
|
|
4025
3989
|
//#endregion
|
|
4026
3990
|
//#region src/routes/messages/route.ts
|
|
4027
3991
|
const messageRoutes = new Hono();
|
|
@@ -4039,7 +4003,6 @@ messageRoutes.post("/count_tokens", async (c) => {
|
|
|
4039
4003
|
return await forwardError(c, error);
|
|
4040
4004
|
}
|
|
4041
4005
|
});
|
|
4042
|
-
|
|
4043
4006
|
//#endregion
|
|
4044
4007
|
//#region src/routes/models/route.ts
|
|
4045
4008
|
const modelRoutes = new Hono();
|
|
@@ -4068,7 +4031,6 @@ modelRoutes.get("/", async (c) => {
|
|
|
4068
4031
|
return await forwardError(c, error);
|
|
4069
4032
|
}
|
|
4070
4033
|
});
|
|
4071
|
-
|
|
4072
4034
|
//#endregion
|
|
4073
4035
|
//#region src/routes/provider/messages/route.ts
|
|
4074
4036
|
const providerMessageRoutes = new Hono();
|
|
@@ -4086,7 +4048,6 @@ providerMessageRoutes.post("/count_tokens", async (c) => {
|
|
|
4086
4048
|
return await forwardError(c, error);
|
|
4087
4049
|
}
|
|
4088
4050
|
});
|
|
4089
|
-
|
|
4090
4051
|
//#endregion
|
|
4091
4052
|
//#region src/routes/provider/models/route.ts
|
|
4092
4053
|
const logger$2 = createHandlerLogger("provider-models-handler");
|
|
@@ -4113,7 +4074,6 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
4113
4074
|
return await forwardError(c, error);
|
|
4114
4075
|
}
|
|
4115
4076
|
});
|
|
4116
|
-
|
|
4117
4077
|
//#endregion
|
|
4118
4078
|
//#region src/routes/responses/stream-id-sync.ts
|
|
4119
4079
|
const createStreamIdTracker = () => ({ outputItems: /* @__PURE__ */ new Map() });
|
|
@@ -4150,7 +4110,6 @@ const handleItemId = (parsed, tracker) => {
|
|
|
4150
4110
|
}
|
|
4151
4111
|
return JSON.stringify(parsed);
|
|
4152
4112
|
};
|
|
4153
|
-
|
|
4154
4113
|
//#endregion
|
|
4155
4114
|
//#region src/routes/responses/handler.ts
|
|
4156
4115
|
const logger$1 = createHandlerLogger("responses-handler");
|
|
@@ -4269,7 +4228,6 @@ const removeUnsupportedTools = (payload) => {
|
|
|
4269
4228
|
});
|
|
4270
4229
|
if (dropped.length > 0) logger$1.debug("Removed unsupported tools:", dropped);
|
|
4271
4230
|
};
|
|
4272
|
-
|
|
4273
4231
|
//#endregion
|
|
4274
4232
|
//#region src/routes/responses/route.ts
|
|
4275
4233
|
const responsesRoutes = new Hono();
|
|
@@ -4280,7 +4238,6 @@ responsesRoutes.post("/", async (c) => {
|
|
|
4280
4238
|
return await forwardError(c, error);
|
|
4281
4239
|
}
|
|
4282
4240
|
});
|
|
4283
|
-
|
|
4284
4241
|
//#endregion
|
|
4285
4242
|
//#region src/routes/token-usage/route.ts
|
|
4286
4243
|
const tokenUsageRoute = new Hono();
|
|
@@ -4298,22 +4255,18 @@ function parsePositiveInt(value, fallback) {
|
|
|
4298
4255
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
4299
4256
|
}
|
|
4300
4257
|
tokenUsageRoute.get("/", async (c) => {
|
|
4301
|
-
const
|
|
4302
|
-
const summary = await getTokenUsageSummary(period);
|
|
4258
|
+
const summary = await getTokenUsageSummary(parsePeriod(c.req.query("period")));
|
|
4303
4259
|
return c.json(summary);
|
|
4304
4260
|
});
|
|
4305
4261
|
tokenUsageRoute.get("/events", async (c) => {
|
|
4306
4262
|
const period = parsePeriod(c.req.query("period"));
|
|
4307
|
-
const page = parsePositiveInt(c.req.query("page"), 1);
|
|
4308
|
-
const pageSize = parsePositiveInt(c.req.query("page_size"), DEFAULT_EVENTS_PAGE_SIZE);
|
|
4309
4263
|
const eventsPage = await getTokenUsageEventsPage({
|
|
4310
|
-
page,
|
|
4311
|
-
pageSize,
|
|
4264
|
+
page: parsePositiveInt(c.req.query("page"), 1),
|
|
4265
|
+
pageSize: parsePositiveInt(c.req.query("page_size"), DEFAULT_EVENTS_PAGE_SIZE),
|
|
4312
4266
|
period
|
|
4313
4267
|
});
|
|
4314
4268
|
return c.json(eventsPage);
|
|
4315
4269
|
});
|
|
4316
|
-
|
|
4317
4270
|
//#endregion
|
|
4318
4271
|
//#region src/routes/token/route.ts
|
|
4319
4272
|
const tokenRoute = new Hono();
|
|
@@ -4328,7 +4281,6 @@ tokenRoute.get("/", (c) => {
|
|
|
4328
4281
|
}, 500);
|
|
4329
4282
|
}
|
|
4330
4283
|
});
|
|
4331
|
-
|
|
4332
4284
|
//#endregion
|
|
4333
4285
|
//#region src/routes/usage/route.ts
|
|
4334
4286
|
const usageRoute = new Hono();
|
|
@@ -4341,7 +4293,6 @@ usageRoute.get("/", async (c) => {
|
|
|
4341
4293
|
return c.json({ error: "Failed to fetch Copilot usage" }, 500);
|
|
4342
4294
|
}
|
|
4343
4295
|
});
|
|
4344
|
-
|
|
4345
4296
|
//#endregion
|
|
4346
4297
|
//#region src/server.ts
|
|
4347
4298
|
const server = new Hono();
|
|
@@ -4373,7 +4324,7 @@ server.route("/v1/responses", responsesRoutes);
|
|
|
4373
4324
|
server.route("/v1/messages", messageRoutes);
|
|
4374
4325
|
server.route("/:provider/v1/messages", providerMessageRoutes);
|
|
4375
4326
|
server.route("/:provider/v1/models", providerModelRoutes);
|
|
4376
|
-
|
|
4377
4327
|
//#endregion
|
|
4378
4328
|
export { server };
|
|
4379
|
-
|
|
4329
|
+
|
|
4330
|
+
//# sourceMappingURL=server-DkUKa2I6.js.map
|