@jeffreycao/copilot-api 1.9.11 → 1.9.12
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-XuNjMVc6.js} +340 -417
- package/dist/server-XuNjMVc6.js.map +1 -0
- package/dist/{start-D2K2jpHF.js → start-C88Fy8qw.js} +12 -17
- package/dist/start-C88Fy8qw.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,55 @@ 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
|
+
state.pendingMessageDelta = {
|
|
1828
1793
|
type: "message_delta",
|
|
1829
1794
|
delta: {
|
|
1830
1795
|
stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
|
|
@@ -1832,7 +1797,7 @@ function handleFinish(choice, state$1, context) {
|
|
|
1832
1797
|
},
|
|
1833
1798
|
usage: getAnthropicUsageFromOpenAIChunk(chunk)
|
|
1834
1799
|
};
|
|
1835
|
-
if (chunk.usage) completePendingMessage(state
|
|
1800
|
+
if (chunk.usage) completePendingMessage(state, events, chunk);
|
|
1836
1801
|
}
|
|
1837
1802
|
}
|
|
1838
1803
|
function getAnthropicUsageFromOpenAIChunk(chunk) {
|
|
@@ -1854,27 +1819,27 @@ function getOpenAIChunkUsageTokens(chunk) {
|
|
|
1854
1819
|
inputTokens: Math.max(0, promptTokens - cachedTokens - cacheCreationTokens)
|
|
1855
1820
|
};
|
|
1856
1821
|
}
|
|
1857
|
-
function handleToolCalls(delta, state
|
|
1822
|
+
function handleToolCalls(delta, state, events) {
|
|
1858
1823
|
if (delta.tool_calls && delta.tool_calls.length > 0) {
|
|
1859
|
-
closeThinkingBlockIfOpen(state
|
|
1860
|
-
handleReasoningOpaqueInToolCalls(state
|
|
1824
|
+
closeThinkingBlockIfOpen(state, events);
|
|
1825
|
+
handleReasoningOpaqueInToolCalls(state, events, delta);
|
|
1861
1826
|
for (const toolCall of delta.tool_calls) {
|
|
1862
1827
|
if (toolCall.id && toolCall.function?.name) {
|
|
1863
|
-
if (state
|
|
1864
|
-
events
|
|
1828
|
+
if (state.contentBlockOpen) {
|
|
1829
|
+
events.push({
|
|
1865
1830
|
type: "content_block_stop",
|
|
1866
|
-
index: state
|
|
1831
|
+
index: state.contentBlockIndex
|
|
1867
1832
|
});
|
|
1868
|
-
state
|
|
1869
|
-
state
|
|
1833
|
+
state.contentBlockIndex++;
|
|
1834
|
+
state.contentBlockOpen = false;
|
|
1870
1835
|
}
|
|
1871
|
-
const anthropicBlockIndex = state
|
|
1872
|
-
state
|
|
1836
|
+
const anthropicBlockIndex = state.contentBlockIndex;
|
|
1837
|
+
state.toolCalls[toolCall.index] = {
|
|
1873
1838
|
id: toolCall.id,
|
|
1874
1839
|
name: toolCall.function.name,
|
|
1875
1840
|
anthropicBlockIndex
|
|
1876
1841
|
};
|
|
1877
|
-
events
|
|
1842
|
+
events.push({
|
|
1878
1843
|
type: "content_block_start",
|
|
1879
1844
|
index: anthropicBlockIndex,
|
|
1880
1845
|
content_block: {
|
|
@@ -1884,11 +1849,11 @@ function handleToolCalls(delta, state$1, events$1) {
|
|
|
1884
1849
|
input: {}
|
|
1885
1850
|
}
|
|
1886
1851
|
});
|
|
1887
|
-
state
|
|
1852
|
+
state.contentBlockOpen = true;
|
|
1888
1853
|
}
|
|
1889
1854
|
if (toolCall.function?.arguments) {
|
|
1890
|
-
const toolCallInfo = state
|
|
1891
|
-
if (toolCallInfo) events
|
|
1855
|
+
const toolCallInfo = state.toolCalls[toolCall.index];
|
|
1856
|
+
if (toolCallInfo) events.push({
|
|
1892
1857
|
type: "content_block_delta",
|
|
1893
1858
|
index: toolCallInfo.anthropicBlockIndex,
|
|
1894
1859
|
delta: {
|
|
@@ -1900,68 +1865,68 @@ function handleToolCalls(delta, state$1, events$1) {
|
|
|
1900
1865
|
}
|
|
1901
1866
|
}
|
|
1902
1867
|
}
|
|
1903
|
-
function handleReasoningOpaqueInToolCalls(state
|
|
1904
|
-
if (state
|
|
1905
|
-
events
|
|
1868
|
+
function handleReasoningOpaqueInToolCalls(state, events, delta) {
|
|
1869
|
+
if (state.contentBlockOpen && !isToolBlockOpen(state)) {
|
|
1870
|
+
events.push({
|
|
1906
1871
|
type: "content_block_stop",
|
|
1907
|
-
index: state
|
|
1872
|
+
index: state.contentBlockIndex
|
|
1908
1873
|
});
|
|
1909
|
-
state
|
|
1910
|
-
state
|
|
1874
|
+
state.contentBlockIndex++;
|
|
1875
|
+
state.contentBlockOpen = false;
|
|
1911
1876
|
}
|
|
1912
|
-
handleReasoningOpaque(delta, events
|
|
1877
|
+
handleReasoningOpaque(delta, events, state);
|
|
1913
1878
|
}
|
|
1914
|
-
function handleContent(delta, state
|
|
1879
|
+
function handleContent(delta, state, events) {
|
|
1915
1880
|
if (delta.content && delta.content.length > 0) {
|
|
1916
|
-
closeThinkingBlockIfOpen(state
|
|
1917
|
-
if (isToolBlockOpen(state
|
|
1918
|
-
events
|
|
1881
|
+
closeThinkingBlockIfOpen(state, events);
|
|
1882
|
+
if (isToolBlockOpen(state)) {
|
|
1883
|
+
events.push({
|
|
1919
1884
|
type: "content_block_stop",
|
|
1920
|
-
index: state
|
|
1885
|
+
index: state.contentBlockIndex
|
|
1921
1886
|
});
|
|
1922
|
-
state
|
|
1923
|
-
state
|
|
1887
|
+
state.contentBlockIndex++;
|
|
1888
|
+
state.contentBlockOpen = false;
|
|
1924
1889
|
}
|
|
1925
|
-
if (!state
|
|
1926
|
-
events
|
|
1890
|
+
if (!state.contentBlockOpen) {
|
|
1891
|
+
events.push({
|
|
1927
1892
|
type: "content_block_start",
|
|
1928
|
-
index: state
|
|
1893
|
+
index: state.contentBlockIndex,
|
|
1929
1894
|
content_block: {
|
|
1930
1895
|
type: "text",
|
|
1931
1896
|
text: ""
|
|
1932
1897
|
}
|
|
1933
1898
|
});
|
|
1934
|
-
state
|
|
1899
|
+
state.contentBlockOpen = true;
|
|
1935
1900
|
}
|
|
1936
|
-
events
|
|
1901
|
+
events.push({
|
|
1937
1902
|
type: "content_block_delta",
|
|
1938
|
-
index: state
|
|
1903
|
+
index: state.contentBlockIndex,
|
|
1939
1904
|
delta: {
|
|
1940
1905
|
type: "text_delta",
|
|
1941
1906
|
text: delta.content
|
|
1942
1907
|
}
|
|
1943
1908
|
});
|
|
1944
1909
|
}
|
|
1945
|
-
if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state
|
|
1946
|
-
events
|
|
1910
|
+
if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state.thinkingBlockOpen) {
|
|
1911
|
+
events.push({
|
|
1947
1912
|
type: "content_block_delta",
|
|
1948
|
-
index: state
|
|
1913
|
+
index: state.contentBlockIndex,
|
|
1949
1914
|
delta: {
|
|
1950
1915
|
type: "signature_delta",
|
|
1951
1916
|
signature: delta.reasoning_opaque
|
|
1952
1917
|
}
|
|
1953
1918
|
}, {
|
|
1954
1919
|
type: "content_block_stop",
|
|
1955
|
-
index: state
|
|
1920
|
+
index: state.contentBlockIndex
|
|
1956
1921
|
});
|
|
1957
|
-
state
|
|
1958
|
-
state
|
|
1922
|
+
state.contentBlockIndex++;
|
|
1923
|
+
state.thinkingBlockOpen = false;
|
|
1959
1924
|
}
|
|
1960
1925
|
}
|
|
1961
|
-
function handleMessageStart(state
|
|
1962
|
-
if (!state
|
|
1926
|
+
function handleMessageStart(state, events, chunk) {
|
|
1927
|
+
if (!state.messageStartSent) {
|
|
1963
1928
|
const { cachedTokens, cacheCreationTokens, inputTokens } = getOpenAIChunkUsageTokens(chunk);
|
|
1964
|
-
events
|
|
1929
|
+
events.push({
|
|
1965
1930
|
type: "message_start",
|
|
1966
1931
|
message: {
|
|
1967
1932
|
id: chunk.id,
|
|
@@ -1979,62 +1944,62 @@ function handleMessageStart(state$1, events$1, chunk) {
|
|
|
1979
1944
|
}
|
|
1980
1945
|
}
|
|
1981
1946
|
});
|
|
1982
|
-
state
|
|
1947
|
+
state.messageStartSent = true;
|
|
1983
1948
|
}
|
|
1984
1949
|
}
|
|
1985
|
-
function handleReasoningOpaque(delta, events
|
|
1950
|
+
function handleReasoningOpaque(delta, events, state) {
|
|
1986
1951
|
if (delta.reasoning_opaque && delta.reasoning_opaque.length > 0) {
|
|
1987
|
-
events
|
|
1952
|
+
events.push({
|
|
1988
1953
|
type: "content_block_start",
|
|
1989
|
-
index: state
|
|
1954
|
+
index: state.contentBlockIndex,
|
|
1990
1955
|
content_block: {
|
|
1991
1956
|
type: "thinking",
|
|
1992
1957
|
thinking: ""
|
|
1993
1958
|
}
|
|
1994
1959
|
}, {
|
|
1995
1960
|
type: "content_block_delta",
|
|
1996
|
-
index: state
|
|
1961
|
+
index: state.contentBlockIndex,
|
|
1997
1962
|
delta: {
|
|
1998
1963
|
type: "thinking_delta",
|
|
1999
1964
|
thinking: THINKING_TEXT$1
|
|
2000
1965
|
}
|
|
2001
1966
|
}, {
|
|
2002
1967
|
type: "content_block_delta",
|
|
2003
|
-
index: state
|
|
1968
|
+
index: state.contentBlockIndex,
|
|
2004
1969
|
delta: {
|
|
2005
1970
|
type: "signature_delta",
|
|
2006
1971
|
signature: delta.reasoning_opaque
|
|
2007
1972
|
}
|
|
2008
1973
|
}, {
|
|
2009
1974
|
type: "content_block_stop",
|
|
2010
|
-
index: state
|
|
1975
|
+
index: state.contentBlockIndex
|
|
2011
1976
|
});
|
|
2012
|
-
state
|
|
1977
|
+
state.contentBlockIndex++;
|
|
2013
1978
|
}
|
|
2014
1979
|
}
|
|
2015
|
-
function handleThinkingText(delta, state
|
|
1980
|
+
function handleThinkingText(delta, state, events) {
|
|
2016
1981
|
const reasoningText = delta.reasoning_text ?? delta.reasoning_content;
|
|
2017
1982
|
if (reasoningText && reasoningText.length > 0) {
|
|
2018
|
-
if (state
|
|
1983
|
+
if (state.contentBlockOpen) {
|
|
2019
1984
|
delta.content = reasoningText;
|
|
2020
1985
|
delta.reasoning_text = void 0;
|
|
2021
1986
|
delta.reasoning_content = void 0;
|
|
2022
1987
|
return;
|
|
2023
1988
|
}
|
|
2024
|
-
if (!state
|
|
2025
|
-
events
|
|
1989
|
+
if (!state.thinkingBlockOpen) {
|
|
1990
|
+
events.push({
|
|
2026
1991
|
type: "content_block_start",
|
|
2027
|
-
index: state
|
|
1992
|
+
index: state.contentBlockIndex,
|
|
2028
1993
|
content_block: {
|
|
2029
1994
|
type: "thinking",
|
|
2030
1995
|
thinking: ""
|
|
2031
1996
|
}
|
|
2032
1997
|
});
|
|
2033
|
-
state
|
|
1998
|
+
state.thinkingBlockOpen = true;
|
|
2034
1999
|
}
|
|
2035
|
-
events
|
|
2000
|
+
events.push({
|
|
2036
2001
|
type: "content_block_delta",
|
|
2037
|
-
index: state
|
|
2002
|
+
index: state.contentBlockIndex,
|
|
2038
2003
|
delta: {
|
|
2039
2004
|
type: "thinking_delta",
|
|
2040
2005
|
thinking: reasoningText
|
|
@@ -2042,24 +2007,23 @@ function handleThinkingText(delta, state$1, events$1) {
|
|
|
2042
2007
|
});
|
|
2043
2008
|
}
|
|
2044
2009
|
}
|
|
2045
|
-
function closeThinkingBlockIfOpen(state
|
|
2046
|
-
if (state
|
|
2047
|
-
events
|
|
2010
|
+
function closeThinkingBlockIfOpen(state, events) {
|
|
2011
|
+
if (state.thinkingBlockOpen) {
|
|
2012
|
+
events.push({
|
|
2048
2013
|
type: "content_block_delta",
|
|
2049
|
-
index: state
|
|
2014
|
+
index: state.contentBlockIndex,
|
|
2050
2015
|
delta: {
|
|
2051
2016
|
type: "signature_delta",
|
|
2052
2017
|
signature: ""
|
|
2053
2018
|
}
|
|
2054
2019
|
}, {
|
|
2055
2020
|
type: "content_block_stop",
|
|
2056
|
-
index: state
|
|
2021
|
+
index: state.contentBlockIndex
|
|
2057
2022
|
});
|
|
2058
|
-
state
|
|
2059
|
-
state
|
|
2023
|
+
state.contentBlockIndex++;
|
|
2024
|
+
state.thinkingBlockOpen = false;
|
|
2060
2025
|
}
|
|
2061
2026
|
}
|
|
2062
|
-
|
|
2063
2027
|
//#endregion
|
|
2064
2028
|
//#region src/services/providers/anthropic-proxy.ts
|
|
2065
2029
|
const SHARED_FORWARDABLE_HEADERS = ["accept", "user-agent"];
|
|
@@ -2125,7 +2089,6 @@ async function forwardProviderModels(providerConfig, requestHeaders) {
|
|
|
2125
2089
|
headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
|
|
2126
2090
|
});
|
|
2127
2091
|
}
|
|
2128
|
-
|
|
2129
2092
|
//#endregion
|
|
2130
2093
|
//#region src/routes/provider/messages/handler.ts
|
|
2131
2094
|
const logger$4 = createHandlerLogger("provider-messages-handler");
|
|
@@ -2139,9 +2102,8 @@ const OPENAI_COMPATIBLE_CONTEXT_CACHE_ROLES = new Set([
|
|
|
2139
2102
|
]);
|
|
2140
2103
|
async function handleProviderMessages(c) {
|
|
2141
2104
|
const provider = c.req.param("provider");
|
|
2142
|
-
const payload = await c.req.json();
|
|
2143
2105
|
return await handleProviderMessagesForProvider(c, {
|
|
2144
|
-
payload,
|
|
2106
|
+
payload: await c.req.json(),
|
|
2145
2107
|
provider
|
|
2146
2108
|
});
|
|
2147
2109
|
}
|
|
@@ -2179,9 +2141,8 @@ async function handleProviderMessagesForProvider(c, options) {
|
|
|
2179
2141
|
providerConfig,
|
|
2180
2142
|
upstreamResponse
|
|
2181
2143
|
});
|
|
2182
|
-
const jsonBody = await upstreamResponse.json();
|
|
2183
2144
|
return respondProviderMessagesJson(c, {
|
|
2184
|
-
body:
|
|
2145
|
+
body: await upstreamResponse.json(),
|
|
2185
2146
|
payload,
|
|
2186
2147
|
provider,
|
|
2187
2148
|
providerConfig
|
|
@@ -2221,9 +2182,8 @@ const handleOpenAICompatibleProviderMessages = async (c, options) => {
|
|
|
2221
2182
|
provider,
|
|
2222
2183
|
upstreamResponse
|
|
2223
2184
|
});
|
|
2224
|
-
const jsonBody = await upstreamResponse.json();
|
|
2225
2185
|
return respondOpenAICompatibleProviderMessagesJson(c, {
|
|
2226
|
-
body:
|
|
2186
|
+
body: await upstreamResponse.json(),
|
|
2227
2187
|
payload,
|
|
2228
2188
|
provider
|
|
2229
2189
|
});
|
|
@@ -2350,8 +2310,8 @@ const streamOpenAICompatibleProviderMessages = ({ c, payload, provider, upstream
|
|
|
2350
2310
|
const parsed = parseOpenAICompatibleStreamChunk(chunk.data);
|
|
2351
2311
|
if (!parsed) continue;
|
|
2352
2312
|
if (parsed.usage) usage = normalizeOpenAIUsage(parsed.usage);
|
|
2353
|
-
const events
|
|
2354
|
-
for (const event of events
|
|
2313
|
+
const events = translateChunkToAnthropicEvents(parsed, streamState);
|
|
2314
|
+
for (const event of events) {
|
|
2355
2315
|
const eventData = JSON.stringify(event);
|
|
2356
2316
|
debugLazy(logger$4, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
|
|
2357
2317
|
await stream.writeSSE({
|
|
@@ -2438,7 +2398,6 @@ const adjustInputTokens = (providerConfig, usage) => {
|
|
|
2438
2398
|
usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
|
|
2439
2399
|
debugJson(logger$4, "provider.messages.adjusted_usage:", usage);
|
|
2440
2400
|
};
|
|
2441
|
-
|
|
2442
2401
|
//#endregion
|
|
2443
2402
|
//#region src/services/copilot/create-responses.ts
|
|
2444
2403
|
const createResponses = async (payload, { vision, initiator, subagentMarker, requestId, sessionId, compactType }) => {
|
|
@@ -2464,7 +2423,6 @@ const createResponses = async (payload, { vision, initiator, subagentMarker, req
|
|
|
2464
2423
|
if (payload.stream) return events(response);
|
|
2465
2424
|
return await response.json();
|
|
2466
2425
|
};
|
|
2467
|
-
|
|
2468
2426
|
//#endregion
|
|
2469
2427
|
//#region src/routes/messages/responses-translation.ts
|
|
2470
2428
|
const MESSAGE_TYPE = "message";
|
|
@@ -2636,7 +2594,7 @@ const createFileContent = (block) => ({
|
|
|
2636
2594
|
});
|
|
2637
2595
|
const createReasoningContent = (block) => {
|
|
2638
2596
|
const { encryptedContent, id } = parseReasoningSignature(block.signature);
|
|
2639
|
-
const thinking = block.thinking ===
|
|
2597
|
+
const thinking = block.thinking === "Thinking..." ? "" : block.thinking;
|
|
2640
2598
|
return {
|
|
2641
2599
|
id,
|
|
2642
2600
|
type: "reasoning",
|
|
@@ -2864,9 +2822,8 @@ const mapResponsesStopReason = (response) => {
|
|
|
2864
2822
|
const mapResponsesUsage = (response) => {
|
|
2865
2823
|
const inputTokens = response.usage?.input_tokens ?? 0;
|
|
2866
2824
|
const outputTokens = response.usage?.output_tokens ?? 0;
|
|
2867
|
-
const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
|
|
2868
2825
|
return {
|
|
2869
|
-
input_tokens: inputTokens - (
|
|
2826
|
+
input_tokens: inputTokens - (response.usage?.input_tokens_details?.cached_tokens ?? 0),
|
|
2870
2827
|
output_tokens: outputTokens,
|
|
2871
2828
|
...response.usage?.input_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.input_tokens_details.cached_tokens }
|
|
2872
2829
|
};
|
|
@@ -2897,7 +2854,6 @@ const convertToolResultContent = (content) => {
|
|
|
2897
2854
|
}
|
|
2898
2855
|
return "";
|
|
2899
2856
|
};
|
|
2900
|
-
|
|
2901
2857
|
//#endregion
|
|
2902
2858
|
//#region src/routes/messages/responses-stream-translation.ts
|
|
2903
2859
|
const MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20;
|
|
@@ -2934,40 +2890,40 @@ const createResponsesStreamState = () => ({
|
|
|
2934
2890
|
blockHasDelta: /* @__PURE__ */ new Set(),
|
|
2935
2891
|
functionCallStateByOutputIndex: /* @__PURE__ */ new Map()
|
|
2936
2892
|
});
|
|
2937
|
-
const translateResponsesStreamEvent = (rawEvent, state
|
|
2893
|
+
const translateResponsesStreamEvent = (rawEvent, state) => {
|
|
2938
2894
|
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
|
|
2895
|
+
case "response.created": return handleResponseCreated(rawEvent, state);
|
|
2896
|
+
case "response.output_item.added": return handleOutputItemAdded$1(rawEvent, state);
|
|
2897
|
+
case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state);
|
|
2898
|
+
case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state);
|
|
2899
|
+
case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state);
|
|
2900
|
+
case "response.output_text.done": return handleOutputTextDone(rawEvent, state);
|
|
2901
|
+
case "response.output_item.done": return handleOutputItemDone$1(rawEvent, state);
|
|
2902
|
+
case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state);
|
|
2903
|
+
case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state);
|
|
2948
2904
|
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
|
|
2905
|
+
case "response.incomplete": return handleResponseCompleted(rawEvent, state);
|
|
2906
|
+
case "response.failed": return handleResponseFailed(rawEvent, state);
|
|
2907
|
+
case "error": return handleErrorEvent(rawEvent, state);
|
|
2952
2908
|
default: return [];
|
|
2953
2909
|
}
|
|
2954
2910
|
};
|
|
2955
|
-
const handleResponseCreated = (rawEvent, state
|
|
2956
|
-
return messageStart(state
|
|
2911
|
+
const handleResponseCreated = (rawEvent, state) => {
|
|
2912
|
+
return messageStart(state, rawEvent.response);
|
|
2957
2913
|
};
|
|
2958
|
-
const handleOutputItemAdded$1 = (rawEvent, state
|
|
2959
|
-
const events
|
|
2914
|
+
const handleOutputItemAdded$1 = (rawEvent, state) => {
|
|
2915
|
+
const events = new Array();
|
|
2960
2916
|
const functionCallDetails = extractFunctionCallDetails(rawEvent);
|
|
2961
|
-
if (!functionCallDetails) return events
|
|
2917
|
+
if (!functionCallDetails) return events;
|
|
2962
2918
|
const { outputIndex, toolCallId, name, initialArguments } = functionCallDetails;
|
|
2963
|
-
const blockIndex = openFunctionCallBlock(state
|
|
2919
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
2964
2920
|
outputIndex,
|
|
2965
2921
|
toolCallId,
|
|
2966
2922
|
name,
|
|
2967
|
-
events
|
|
2923
|
+
events
|
|
2968
2924
|
});
|
|
2969
2925
|
if (initialArguments !== void 0 && initialArguments.length > 0) {
|
|
2970
|
-
events
|
|
2926
|
+
events.push({
|
|
2971
2927
|
type: "content_block_delta",
|
|
2972
2928
|
index: blockIndex,
|
|
2973
2929
|
delta: {
|
|
@@ -2975,29 +2931,29 @@ const handleOutputItemAdded$1 = (rawEvent, state$1) => {
|
|
|
2975
2931
|
partial_json: initialArguments
|
|
2976
2932
|
}
|
|
2977
2933
|
});
|
|
2978
|
-
state
|
|
2934
|
+
state.blockHasDelta.add(blockIndex);
|
|
2979
2935
|
}
|
|
2980
|
-
return events
|
|
2936
|
+
return events;
|
|
2981
2937
|
};
|
|
2982
|
-
const handleOutputItemDone$1 = (rawEvent, state
|
|
2983
|
-
const events
|
|
2938
|
+
const handleOutputItemDone$1 = (rawEvent, state) => {
|
|
2939
|
+
const events = new Array();
|
|
2984
2940
|
const item = rawEvent.item;
|
|
2985
2941
|
const itemType = item.type;
|
|
2986
2942
|
const outputIndex = rawEvent.output_index;
|
|
2987
2943
|
if (itemType === "compaction") {
|
|
2988
|
-
if (!item.id || !item.encrypted_content) return events
|
|
2989
|
-
const blockIndex
|
|
2990
|
-
if (!state
|
|
2944
|
+
if (!item.id || !item.encrypted_content) return events;
|
|
2945
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
2946
|
+
if (!state.blockHasDelta.has(blockIndex)) events.push({
|
|
2991
2947
|
type: "content_block_delta",
|
|
2992
|
-
index: blockIndex
|
|
2948
|
+
index: blockIndex,
|
|
2993
2949
|
delta: {
|
|
2994
2950
|
type: "thinking_delta",
|
|
2995
2951
|
thinking: THINKING_TEXT
|
|
2996
2952
|
}
|
|
2997
2953
|
});
|
|
2998
|
-
events
|
|
2954
|
+
events.push({
|
|
2999
2955
|
type: "content_block_delta",
|
|
3000
|
-
index: blockIndex
|
|
2956
|
+
index: blockIndex,
|
|
3001
2957
|
delta: {
|
|
3002
2958
|
type: "signature_delta",
|
|
3003
2959
|
signature: encodeCompactionCarrierSignature({
|
|
@@ -3006,14 +2962,14 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3006
2962
|
})
|
|
3007
2963
|
}
|
|
3008
2964
|
});
|
|
3009
|
-
state
|
|
3010
|
-
return events
|
|
2965
|
+
state.blockHasDelta.add(blockIndex);
|
|
2966
|
+
return events;
|
|
3011
2967
|
}
|
|
3012
|
-
if (itemType !== "reasoning") return events
|
|
3013
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
2968
|
+
if (itemType !== "reasoning") return events;
|
|
2969
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3014
2970
|
const signature = (item.encrypted_content ?? "") + "@" + item.id;
|
|
3015
2971
|
if (signature) {
|
|
3016
|
-
if (!item.summary || item.summary.length === 0) events
|
|
2972
|
+
if (!item.summary || item.summary.length === 0) events.push({
|
|
3017
2973
|
type: "content_block_delta",
|
|
3018
2974
|
index: blockIndex,
|
|
3019
2975
|
delta: {
|
|
@@ -3021,7 +2977,7 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3021
2977
|
thinking: THINKING_TEXT
|
|
3022
2978
|
}
|
|
3023
2979
|
});
|
|
3024
|
-
events
|
|
2980
|
+
events.push({
|
|
3025
2981
|
type: "content_block_delta",
|
|
3026
2982
|
index: blockIndex,
|
|
3027
2983
|
delta: {
|
|
@@ -3029,25 +2985,25 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
|
|
|
3029
2985
|
signature
|
|
3030
2986
|
}
|
|
3031
2987
|
});
|
|
3032
|
-
state
|
|
2988
|
+
state.blockHasDelta.add(blockIndex);
|
|
3033
2989
|
}
|
|
3034
|
-
return events
|
|
2990
|
+
return events;
|
|
3035
2991
|
};
|
|
3036
|
-
const handleFunctionCallArgumentsDelta = (rawEvent, state
|
|
3037
|
-
const events
|
|
2992
|
+
const handleFunctionCallArgumentsDelta = (rawEvent, state) => {
|
|
2993
|
+
const events = new Array();
|
|
3038
2994
|
const outputIndex = rawEvent.output_index;
|
|
3039
2995
|
const deltaText = rawEvent.delta;
|
|
3040
|
-
if (!deltaText) return events
|
|
3041
|
-
const blockIndex = openFunctionCallBlock(state
|
|
2996
|
+
if (!deltaText) return events;
|
|
2997
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
3042
2998
|
outputIndex,
|
|
3043
|
-
events
|
|
2999
|
+
events
|
|
3044
3000
|
});
|
|
3045
|
-
const functionCallState = state
|
|
3046
|
-
if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state
|
|
3001
|
+
const functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
|
|
3002
|
+
if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state, events);
|
|
3047
3003
|
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
|
|
3004
|
+
if (exceeded) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta containing more than 20 consecutive whitespace characters."), state, events);
|
|
3049
3005
|
functionCallState.consecutiveWhitespaceCount = nextCount;
|
|
3050
|
-
events
|
|
3006
|
+
events.push({
|
|
3051
3007
|
type: "content_block_delta",
|
|
3052
3008
|
index: blockIndex,
|
|
3053
3009
|
delta: {
|
|
@@ -3055,19 +3011,19 @@ const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
|
|
|
3055
3011
|
partial_json: deltaText
|
|
3056
3012
|
}
|
|
3057
3013
|
});
|
|
3058
|
-
state
|
|
3059
|
-
return events
|
|
3014
|
+
state.blockHasDelta.add(blockIndex);
|
|
3015
|
+
return events;
|
|
3060
3016
|
};
|
|
3061
|
-
const handleFunctionCallArgumentsDone = (rawEvent, state
|
|
3062
|
-
const events
|
|
3017
|
+
const handleFunctionCallArgumentsDone = (rawEvent, state) => {
|
|
3018
|
+
const events = new Array();
|
|
3063
3019
|
const outputIndex = rawEvent.output_index;
|
|
3064
|
-
const blockIndex = openFunctionCallBlock(state
|
|
3020
|
+
const blockIndex = openFunctionCallBlock(state, {
|
|
3065
3021
|
outputIndex,
|
|
3066
|
-
events
|
|
3022
|
+
events
|
|
3067
3023
|
});
|
|
3068
3024
|
const finalArguments = typeof rawEvent.arguments === "string" ? rawEvent.arguments : void 0;
|
|
3069
|
-
if (!state
|
|
3070
|
-
events
|
|
3025
|
+
if (!state.blockHasDelta.has(blockIndex) && finalArguments) {
|
|
3026
|
+
events.push({
|
|
3071
3027
|
type: "content_block_delta",
|
|
3072
3028
|
index: blockIndex,
|
|
3073
3029
|
delta: {
|
|
@@ -3075,23 +3031,23 @@ const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
|
|
|
3075
3031
|
partial_json: finalArguments
|
|
3076
3032
|
}
|
|
3077
3033
|
});
|
|
3078
|
-
state
|
|
3034
|
+
state.blockHasDelta.add(blockIndex);
|
|
3079
3035
|
}
|
|
3080
|
-
state
|
|
3081
|
-
return events
|
|
3036
|
+
state.functionCallStateByOutputIndex.delete(outputIndex);
|
|
3037
|
+
return events;
|
|
3082
3038
|
};
|
|
3083
|
-
const handleOutputTextDelta = (rawEvent, state
|
|
3084
|
-
const events
|
|
3039
|
+
const handleOutputTextDelta = (rawEvent, state) => {
|
|
3040
|
+
const events = new Array();
|
|
3085
3041
|
const outputIndex = rawEvent.output_index;
|
|
3086
3042
|
const contentIndex = rawEvent.content_index;
|
|
3087
3043
|
const deltaText = rawEvent.delta;
|
|
3088
|
-
if (!deltaText) return events
|
|
3089
|
-
const blockIndex = openTextBlockIfNeeded(state
|
|
3044
|
+
if (!deltaText) return events;
|
|
3045
|
+
const blockIndex = openTextBlockIfNeeded(state, {
|
|
3090
3046
|
outputIndex,
|
|
3091
3047
|
contentIndex,
|
|
3092
|
-
events
|
|
3048
|
+
events
|
|
3093
3049
|
});
|
|
3094
|
-
events
|
|
3050
|
+
events.push({
|
|
3095
3051
|
type: "content_block_delta",
|
|
3096
3052
|
index: blockIndex,
|
|
3097
3053
|
delta: {
|
|
@@ -3099,15 +3055,15 @@ const handleOutputTextDelta = (rawEvent, state$1) => {
|
|
|
3099
3055
|
text: deltaText
|
|
3100
3056
|
}
|
|
3101
3057
|
});
|
|
3102
|
-
state
|
|
3103
|
-
return events
|
|
3058
|
+
state.blockHasDelta.add(blockIndex);
|
|
3059
|
+
return events;
|
|
3104
3060
|
};
|
|
3105
|
-
const handleReasoningSummaryTextDelta = (rawEvent, state
|
|
3061
|
+
const handleReasoningSummaryTextDelta = (rawEvent, state) => {
|
|
3106
3062
|
const outputIndex = rawEvent.output_index;
|
|
3107
3063
|
const deltaText = rawEvent.delta;
|
|
3108
|
-
const events
|
|
3109
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
3110
|
-
events
|
|
3064
|
+
const events = new Array();
|
|
3065
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3066
|
+
events.push({
|
|
3111
3067
|
type: "content_block_delta",
|
|
3112
3068
|
index: blockIndex,
|
|
3113
3069
|
delta: {
|
|
@@ -3115,15 +3071,15 @@ const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
|
|
|
3115
3071
|
thinking: deltaText
|
|
3116
3072
|
}
|
|
3117
3073
|
});
|
|
3118
|
-
state
|
|
3119
|
-
return events
|
|
3074
|
+
state.blockHasDelta.add(blockIndex);
|
|
3075
|
+
return events;
|
|
3120
3076
|
};
|
|
3121
|
-
const handleReasoningSummaryTextDone = (rawEvent, state
|
|
3077
|
+
const handleReasoningSummaryTextDone = (rawEvent, state) => {
|
|
3122
3078
|
const outputIndex = rawEvent.output_index;
|
|
3123
3079
|
const text = rawEvent.text;
|
|
3124
|
-
const events
|
|
3125
|
-
const blockIndex = openThinkingBlockIfNeeded(state
|
|
3126
|
-
if (text && !state
|
|
3080
|
+
const events = new Array();
|
|
3081
|
+
const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
|
|
3082
|
+
if (text && !state.blockHasDelta.has(blockIndex)) events.push({
|
|
3127
3083
|
type: "content_block_delta",
|
|
3128
3084
|
index: blockIndex,
|
|
3129
3085
|
delta: {
|
|
@@ -3131,19 +3087,19 @@ const handleReasoningSummaryTextDone = (rawEvent, state$1) => {
|
|
|
3131
3087
|
thinking: text
|
|
3132
3088
|
}
|
|
3133
3089
|
});
|
|
3134
|
-
return events
|
|
3090
|
+
return events;
|
|
3135
3091
|
};
|
|
3136
|
-
const handleOutputTextDone = (rawEvent, state
|
|
3137
|
-
const events
|
|
3092
|
+
const handleOutputTextDone = (rawEvent, state) => {
|
|
3093
|
+
const events = new Array();
|
|
3138
3094
|
const outputIndex = rawEvent.output_index;
|
|
3139
3095
|
const contentIndex = rawEvent.content_index;
|
|
3140
3096
|
const text = rawEvent.text;
|
|
3141
|
-
const blockIndex = openTextBlockIfNeeded(state
|
|
3097
|
+
const blockIndex = openTextBlockIfNeeded(state, {
|
|
3142
3098
|
outputIndex,
|
|
3143
3099
|
contentIndex,
|
|
3144
|
-
events
|
|
3100
|
+
events
|
|
3145
3101
|
});
|
|
3146
|
-
if (text && !state
|
|
3102
|
+
if (text && !state.blockHasDelta.has(blockIndex)) events.push({
|
|
3147
3103
|
type: "content_block_delta",
|
|
3148
3104
|
index: blockIndex,
|
|
3149
3105
|
delta: {
|
|
@@ -3151,14 +3107,14 @@ const handleOutputTextDone = (rawEvent, state$1) => {
|
|
|
3151
3107
|
text
|
|
3152
3108
|
}
|
|
3153
3109
|
});
|
|
3154
|
-
return events
|
|
3110
|
+
return events;
|
|
3155
3111
|
};
|
|
3156
|
-
const handleResponseCompleted = (rawEvent, state
|
|
3112
|
+
const handleResponseCompleted = (rawEvent, state) => {
|
|
3157
3113
|
const response = rawEvent.response;
|
|
3158
|
-
const events
|
|
3159
|
-
closeAllOpenBlocks(state
|
|
3114
|
+
const events = new Array();
|
|
3115
|
+
closeAllOpenBlocks(state, events);
|
|
3160
3116
|
const anthropic = translateResponsesResultToAnthropic(response);
|
|
3161
|
-
events
|
|
3117
|
+
events.push({
|
|
3162
3118
|
type: "message_delta",
|
|
3163
3119
|
delta: {
|
|
3164
3120
|
stop_reason: anthropic.stop_reason,
|
|
@@ -3166,32 +3122,32 @@ const handleResponseCompleted = (rawEvent, state$1) => {
|
|
|
3166
3122
|
},
|
|
3167
3123
|
usage: anthropic.usage
|
|
3168
3124
|
}, { type: "message_stop" });
|
|
3169
|
-
state
|
|
3170
|
-
return events
|
|
3125
|
+
state.messageCompleted = true;
|
|
3126
|
+
return events;
|
|
3171
3127
|
};
|
|
3172
|
-
const handleResponseFailed = (rawEvent, state
|
|
3128
|
+
const handleResponseFailed = (rawEvent, state) => {
|
|
3173
3129
|
const response = rawEvent.response;
|
|
3174
|
-
const events
|
|
3175
|
-
closeAllOpenBlocks(state
|
|
3130
|
+
const events = new Array();
|
|
3131
|
+
closeAllOpenBlocks(state, events);
|
|
3176
3132
|
const message = response.error?.message ?? "The response failed due to an unknown error.";
|
|
3177
|
-
events
|
|
3178
|
-
state
|
|
3179
|
-
return events
|
|
3133
|
+
events.push(buildErrorEvent(message));
|
|
3134
|
+
state.messageCompleted = true;
|
|
3135
|
+
return events;
|
|
3180
3136
|
};
|
|
3181
|
-
const handleErrorEvent = (rawEvent, state
|
|
3137
|
+
const handleErrorEvent = (rawEvent, state) => {
|
|
3182
3138
|
const message = typeof rawEvent.message === "string" ? rawEvent.message : "An unexpected error occurred during streaming.";
|
|
3183
|
-
state
|
|
3139
|
+
state.messageCompleted = true;
|
|
3184
3140
|
return [buildErrorEvent(message)];
|
|
3185
3141
|
};
|
|
3186
|
-
const handleFunctionCallArgumentsValidationError = (error, state
|
|
3142
|
+
const handleFunctionCallArgumentsValidationError = (error, state, events = []) => {
|
|
3187
3143
|
const reason = error.message;
|
|
3188
|
-
closeAllOpenBlocks(state
|
|
3189
|
-
state
|
|
3190
|
-
events
|
|
3191
|
-
return events
|
|
3144
|
+
closeAllOpenBlocks(state, events);
|
|
3145
|
+
state.messageCompleted = true;
|
|
3146
|
+
events.push(buildErrorEvent(reason));
|
|
3147
|
+
return events;
|
|
3192
3148
|
};
|
|
3193
|
-
const messageStart = (state
|
|
3194
|
-
state
|
|
3149
|
+
const messageStart = (state, response) => {
|
|
3150
|
+
state.messageStartSent = true;
|
|
3195
3151
|
const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
|
|
3196
3152
|
const inputTokens = (response.usage?.input_tokens ?? 0) - (inputCachedTokens ?? 0);
|
|
3197
3153
|
return [{
|
|
@@ -3212,18 +3168,18 @@ const messageStart = (state$1, response) => {
|
|
|
3212
3168
|
}
|
|
3213
3169
|
}];
|
|
3214
3170
|
};
|
|
3215
|
-
const openTextBlockIfNeeded = (state
|
|
3216
|
-
const { outputIndex, contentIndex, events
|
|
3171
|
+
const openTextBlockIfNeeded = (state, params) => {
|
|
3172
|
+
const { outputIndex, contentIndex, events } = params;
|
|
3217
3173
|
const key = getBlockKey(outputIndex, contentIndex);
|
|
3218
|
-
let blockIndex = state
|
|
3174
|
+
let blockIndex = state.blockIndexByKey.get(key);
|
|
3219
3175
|
if (blockIndex === void 0) {
|
|
3220
|
-
blockIndex = state
|
|
3221
|
-
state
|
|
3222
|
-
state
|
|
3176
|
+
blockIndex = state.nextContentBlockIndex;
|
|
3177
|
+
state.nextContentBlockIndex += 1;
|
|
3178
|
+
state.blockIndexByKey.set(key, blockIndex);
|
|
3223
3179
|
}
|
|
3224
|
-
if (!state
|
|
3225
|
-
closeOpenBlocks(state
|
|
3226
|
-
events
|
|
3180
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3181
|
+
closeOpenBlocks(state, events);
|
|
3182
|
+
events.push({
|
|
3227
3183
|
type: "content_block_start",
|
|
3228
3184
|
index: blockIndex,
|
|
3229
3185
|
content_block: {
|
|
@@ -3231,21 +3187,21 @@ const openTextBlockIfNeeded = (state$1, params) => {
|
|
|
3231
3187
|
text: ""
|
|
3232
3188
|
}
|
|
3233
3189
|
});
|
|
3234
|
-
state
|
|
3190
|
+
state.openBlocks.add(blockIndex);
|
|
3235
3191
|
}
|
|
3236
3192
|
return blockIndex;
|
|
3237
3193
|
};
|
|
3238
|
-
const openThinkingBlockIfNeeded = (state
|
|
3194
|
+
const openThinkingBlockIfNeeded = (state, outputIndex, events) => {
|
|
3239
3195
|
const key = getBlockKey(outputIndex, 0);
|
|
3240
|
-
let blockIndex = state
|
|
3196
|
+
let blockIndex = state.blockIndexByKey.get(key);
|
|
3241
3197
|
if (blockIndex === void 0) {
|
|
3242
|
-
blockIndex = state
|
|
3243
|
-
state
|
|
3244
|
-
state
|
|
3198
|
+
blockIndex = state.nextContentBlockIndex;
|
|
3199
|
+
state.nextContentBlockIndex += 1;
|
|
3200
|
+
state.blockIndexByKey.set(key, blockIndex);
|
|
3245
3201
|
}
|
|
3246
|
-
if (!state
|
|
3247
|
-
closeOpenBlocks(state
|
|
3248
|
-
events
|
|
3202
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3203
|
+
closeOpenBlocks(state, events);
|
|
3204
|
+
events.push({
|
|
3249
3205
|
type: "content_block_start",
|
|
3250
3206
|
index: blockIndex,
|
|
3251
3207
|
content_block: {
|
|
@@ -3253,25 +3209,25 @@ const openThinkingBlockIfNeeded = (state$1, outputIndex, events$1) => {
|
|
|
3253
3209
|
thinking: ""
|
|
3254
3210
|
}
|
|
3255
3211
|
});
|
|
3256
|
-
state
|
|
3212
|
+
state.openBlocks.add(blockIndex);
|
|
3257
3213
|
}
|
|
3258
3214
|
return blockIndex;
|
|
3259
3215
|
};
|
|
3260
|
-
const closeBlockIfOpen = (state
|
|
3261
|
-
if (!state
|
|
3262
|
-
events
|
|
3216
|
+
const closeBlockIfOpen = (state, blockIndex, events) => {
|
|
3217
|
+
if (!state.openBlocks.has(blockIndex)) return;
|
|
3218
|
+
events.push({
|
|
3263
3219
|
type: "content_block_stop",
|
|
3264
3220
|
index: blockIndex
|
|
3265
3221
|
});
|
|
3266
|
-
state
|
|
3267
|
-
state
|
|
3222
|
+
state.openBlocks.delete(blockIndex);
|
|
3223
|
+
state.blockHasDelta.delete(blockIndex);
|
|
3268
3224
|
};
|
|
3269
|
-
const closeOpenBlocks = (state
|
|
3270
|
-
for (const blockIndex of state
|
|
3225
|
+
const closeOpenBlocks = (state, events) => {
|
|
3226
|
+
for (const blockIndex of state.openBlocks) closeBlockIfOpen(state, blockIndex, events);
|
|
3271
3227
|
};
|
|
3272
|
-
const closeAllOpenBlocks = (state
|
|
3273
|
-
closeOpenBlocks(state
|
|
3274
|
-
state
|
|
3228
|
+
const closeAllOpenBlocks = (state, events) => {
|
|
3229
|
+
closeOpenBlocks(state, events);
|
|
3230
|
+
state.functionCallStateByOutputIndex.clear();
|
|
3275
3231
|
};
|
|
3276
3232
|
const buildErrorEvent = (message) => ({
|
|
3277
3233
|
type: "error",
|
|
@@ -3281,25 +3237,24 @@ const buildErrorEvent = (message) => ({
|
|
|
3281
3237
|
}
|
|
3282
3238
|
});
|
|
3283
3239
|
const getBlockKey = (outputIndex, contentIndex) => `${outputIndex}:${contentIndex}`;
|
|
3284
|
-
const openFunctionCallBlock = (state
|
|
3285
|
-
const { outputIndex, toolCallId, name, events
|
|
3286
|
-
let functionCallState = state
|
|
3240
|
+
const openFunctionCallBlock = (state, params) => {
|
|
3241
|
+
const { outputIndex, toolCallId, name, events } = params;
|
|
3242
|
+
let functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
|
|
3287
3243
|
if (!functionCallState) {
|
|
3288
|
-
const blockIndex
|
|
3289
|
-
state
|
|
3290
|
-
const resolvedToolCallId = toolCallId ?? `tool_call_${blockIndex$1}`;
|
|
3244
|
+
const blockIndex = state.nextContentBlockIndex;
|
|
3245
|
+
state.nextContentBlockIndex += 1;
|
|
3291
3246
|
functionCallState = {
|
|
3292
|
-
blockIndex
|
|
3293
|
-
toolCallId:
|
|
3247
|
+
blockIndex,
|
|
3248
|
+
toolCallId: toolCallId ?? `tool_call_${blockIndex}`,
|
|
3294
3249
|
name: name ?? "function",
|
|
3295
3250
|
consecutiveWhitespaceCount: 0
|
|
3296
3251
|
};
|
|
3297
|
-
state
|
|
3252
|
+
state.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
|
|
3298
3253
|
}
|
|
3299
3254
|
const { blockIndex } = functionCallState;
|
|
3300
|
-
if (!state
|
|
3301
|
-
closeOpenBlocks(state
|
|
3302
|
-
events
|
|
3255
|
+
if (!state.openBlocks.has(blockIndex)) {
|
|
3256
|
+
closeOpenBlocks(state, events);
|
|
3257
|
+
events.push({
|
|
3303
3258
|
type: "content_block_start",
|
|
3304
3259
|
index: blockIndex,
|
|
3305
3260
|
content_block: {
|
|
@@ -3309,33 +3264,26 @@ const openFunctionCallBlock = (state$1, params) => {
|
|
|
3309
3264
|
input: {}
|
|
3310
3265
|
}
|
|
3311
3266
|
});
|
|
3312
|
-
state
|
|
3267
|
+
state.openBlocks.add(blockIndex);
|
|
3313
3268
|
}
|
|
3314
3269
|
return blockIndex;
|
|
3315
3270
|
};
|
|
3316
3271
|
const extractFunctionCallDetails = (rawEvent) => {
|
|
3317
3272
|
const item = rawEvent.item;
|
|
3318
3273
|
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
3274
|
return {
|
|
3324
|
-
outputIndex,
|
|
3325
|
-
toolCallId,
|
|
3326
|
-
name,
|
|
3327
|
-
initialArguments
|
|
3275
|
+
outputIndex: rawEvent.output_index,
|
|
3276
|
+
toolCallId: item.call_id,
|
|
3277
|
+
name: item.name,
|
|
3278
|
+
initialArguments: item.arguments
|
|
3328
3279
|
};
|
|
3329
3280
|
};
|
|
3330
|
-
|
|
3331
3281
|
//#endregion
|
|
3332
3282
|
//#region src/routes/responses/utils.ts
|
|
3333
3283
|
const getResponsesRequestOptions = (payload) => {
|
|
3334
|
-
const vision = hasVisionInput(payload);
|
|
3335
|
-
const initiator = hasAgentInitiator(payload) ? "agent" : "user";
|
|
3336
3284
|
return {
|
|
3337
|
-
vision,
|
|
3338
|
-
initiator
|
|
3285
|
+
vision: hasVisionInput(payload),
|
|
3286
|
+
initiator: hasAgentInitiator(payload) ? "agent" : "user"
|
|
3339
3287
|
};
|
|
3340
3288
|
};
|
|
3341
3289
|
const hasAgentInitiator = (payload) => {
|
|
@@ -3387,7 +3335,6 @@ const containsVisionContent = (value) => {
|
|
|
3387
3335
|
if (Array.isArray(record.content)) return record.content.some((entry) => containsVisionContent(entry));
|
|
3388
3336
|
return false;
|
|
3389
3337
|
};
|
|
3390
|
-
|
|
3391
3338
|
//#endregion
|
|
3392
3339
|
//#region src/services/copilot/create-messages.ts
|
|
3393
3340
|
const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
@@ -3438,10 +3385,6 @@ const createMessages = async (payload, anthropicBetaHeader, options) => {
|
|
|
3438
3385
|
if (payload.stream) return events(response);
|
|
3439
3386
|
return await response.json();
|
|
3440
3387
|
};
|
|
3441
|
-
|
|
3442
|
-
//#endregion
|
|
3443
|
-
//#region src/routes/messages/preprocess.ts
|
|
3444
|
-
const TOOL_REFERENCE_TURN_BOUNDARY = "Tool loaded.";
|
|
3445
3388
|
const IDE_EXECUTE_CODE_TOOL = "mcp__ide__executeCode";
|
|
3446
3389
|
const IDE_GET_DIAGNOSTICS_TOOL = "mcp__ide__getDiagnostics";
|
|
3447
3390
|
const IDE_GET_DIAGNOSTICS_DESCRIPTION = "Get language diagnostics from VS Code. Returns errors, warnings, information, and hints for files in the workspace.";
|
|
@@ -3454,7 +3397,7 @@ const getCompactCandidateText = (message) => {
|
|
|
3454
3397
|
const isCompactMessage = (lastMessage) => {
|
|
3455
3398
|
const text = getCompactCandidateText(lastMessage);
|
|
3456
3399
|
if (!text) return false;
|
|
3457
|
-
return text.includes(
|
|
3400
|
+
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
3401
|
};
|
|
3459
3402
|
const isCompactAutoContinueMessage = (lastMessage) => {
|
|
3460
3403
|
const text = getCompactCandidateText(lastMessage);
|
|
@@ -3462,12 +3405,12 @@ const isCompactAutoContinueMessage = (lastMessage) => {
|
|
|
3462
3405
|
};
|
|
3463
3406
|
const getCompactType = (anthropicPayload) => {
|
|
3464
3407
|
const lastMessage = anthropicPayload.messages.at(-1);
|
|
3465
|
-
if (lastMessage && isCompactMessage(lastMessage)) return
|
|
3466
|
-
if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return
|
|
3408
|
+
if (lastMessage && isCompactMessage(lastMessage)) return 1;
|
|
3409
|
+
if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return 2;
|
|
3467
3410
|
const system = anthropicPayload.system;
|
|
3468
|
-
if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ?
|
|
3411
|
+
if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ? 1 : 0;
|
|
3469
3412
|
if (!Array.isArray(system)) return 0;
|
|
3470
|
-
if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return
|
|
3413
|
+
if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return 1;
|
|
3471
3414
|
return 0;
|
|
3472
3415
|
};
|
|
3473
3416
|
const mergeContentWithText = (tr, textBlock) => {
|
|
@@ -3519,8 +3462,7 @@ const mergeAttachmentsIntoToolResults = (toolResults, attachmentsByToolResultInd
|
|
|
3519
3462
|
return toolResults.map((block, index) => {
|
|
3520
3463
|
const matchedAttachments = attachmentsByToolResultIndex.get(index);
|
|
3521
3464
|
if (!matchedAttachments) return block;
|
|
3522
|
-
|
|
3523
|
-
return mergeContentWithAttachments(block, orderedAttachments);
|
|
3465
|
+
return mergeContentWithAttachments(block, [...matchedAttachments].sort((left, right) => left.order - right.order).map(({ attachment }) => attachment));
|
|
3524
3466
|
});
|
|
3525
3467
|
};
|
|
3526
3468
|
const assignAttachmentsToToolResults = (target, attachments, options) => {
|
|
@@ -3529,9 +3471,9 @@ const assignAttachmentsToToolResults = (target, attachments, options) => {
|
|
|
3529
3471
|
if (attachments.length === 0) return;
|
|
3530
3472
|
if (toolResultIndices.length > 0 && toolResultIndices.length === attachments.length) {
|
|
3531
3473
|
for (const [index, toolResultIndex] of toolResultIndices.entries()) {
|
|
3532
|
-
const currentAttachments
|
|
3533
|
-
if (currentAttachments
|
|
3534
|
-
currentAttachments
|
|
3474
|
+
const currentAttachments = target.get(toolResultIndex);
|
|
3475
|
+
if (currentAttachments) {
|
|
3476
|
+
currentAttachments.push(attachments[index]);
|
|
3535
3477
|
continue;
|
|
3536
3478
|
}
|
|
3537
3479
|
target.set(toolResultIndex, [attachments[index]]);
|
|
@@ -3612,8 +3554,7 @@ const mergeUserMessageContent = (content) => {
|
|
|
3612
3554
|
if (!mergeableContent) return null;
|
|
3613
3555
|
const { toolResults, textBlocks, attachments } = mergeableContent;
|
|
3614
3556
|
if (toolResults.length === 0 || textBlocks.length === 0 && attachments.length === 0) return null;
|
|
3615
|
-
|
|
3616
|
-
return mergeAttachmentsForToolResults(mergedToolResults, attachments);
|
|
3557
|
+
return mergeAttachmentsForToolResults(textBlocks.length === 0 ? toolResults : mergeToolResult(toolResults, textBlocks), attachments);
|
|
3617
3558
|
};
|
|
3618
3559
|
const mergeToolResult = (toolResults, textBlocks) => {
|
|
3619
3560
|
if (toolResults.length === textBlocks.length) return toolResults.map((tr, i) => mergeContentWithText(tr, textBlocks[i]));
|
|
@@ -3624,7 +3565,7 @@ const stripToolReferenceTurnBoundary = (anthropicPayload) => {
|
|
|
3624
3565
|
for (const msg of anthropicPayload.messages) {
|
|
3625
3566
|
if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
|
|
3626
3567
|
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() !==
|
|
3568
|
+
msg.content = msg.content.filter((block) => block.type !== "text" || block.text.trim() !== "Tool loaded.");
|
|
3628
3569
|
}
|
|
3629
3570
|
};
|
|
3630
3571
|
const mergeToolResultForClaude = (anthropicPayload, options) => {
|
|
@@ -3655,7 +3596,7 @@ const stripCacheControl = (payload) => {
|
|
|
3655
3596
|
const systemBlock = block;
|
|
3656
3597
|
const cacheControl = systemBlock.cache_control;
|
|
3657
3598
|
if (cacheControl && typeof cacheControl === "object") {
|
|
3658
|
-
const { scope
|
|
3599
|
+
const { scope, ...rest } = cacheControl;
|
|
3659
3600
|
systemBlock.cache_control = rest;
|
|
3660
3601
|
}
|
|
3661
3602
|
}
|
|
@@ -3683,14 +3624,13 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
|
|
|
3683
3624
|
payload.output_config = { effort };
|
|
3684
3625
|
}
|
|
3685
3626
|
};
|
|
3686
|
-
|
|
3687
3627
|
//#endregion
|
|
3688
3628
|
//#region src/routes/messages/api-flows.ts
|
|
3689
3629
|
const COPILOT_CONTEXT_CACHE_SYSTEM_MARKER_LIMIT = 2;
|
|
3690
3630
|
const COPILOT_CONTEXT_CACHE_NON_SYSTEM_MARKER_LIMIT = 2;
|
|
3691
3631
|
const COPILOT_CONTEXT_CACHE_CONTROL = { type: "ephemeral" };
|
|
3692
3632
|
const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
3693
|
-
const { logger
|
|
3633
|
+
const { logger, subagentMarker, requestId, sessionId, compactType } = options;
|
|
3694
3634
|
const openAIPayload = translateToOpenAI(anthropicPayload);
|
|
3695
3635
|
prepareCopilotChatCompletionsPayload(openAIPayload);
|
|
3696
3636
|
const recordUsage = createCopilotUsageRecorder({
|
|
@@ -3699,7 +3639,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3699
3639
|
model: openAIPayload.model,
|
|
3700
3640
|
payload: anthropicPayload
|
|
3701
3641
|
});
|
|
3702
|
-
debugJson(logger
|
|
3642
|
+
debugJson(logger, "Translated OpenAI request payload:", openAIPayload);
|
|
3703
3643
|
const response = await createChatCompletions(openAIPayload, {
|
|
3704
3644
|
subagentMarker,
|
|
3705
3645
|
requestId,
|
|
@@ -3707,13 +3647,13 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3707
3647
|
compactType
|
|
3708
3648
|
});
|
|
3709
3649
|
if (isNonStreaming(response)) {
|
|
3710
|
-
debugJson(logger
|
|
3650
|
+
debugJson(logger, "Non-streaming response from Copilot:", response);
|
|
3711
3651
|
recordUsage(normalizeOpenAIUsage(response.usage));
|
|
3712
3652
|
const anthropicResponse = translateToAnthropic(response);
|
|
3713
|
-
debugJson(logger
|
|
3653
|
+
debugJson(logger, "Translated Anthropic response:", anthropicResponse);
|
|
3714
3654
|
return c.json(anthropicResponse);
|
|
3715
3655
|
}
|
|
3716
|
-
logger
|
|
3656
|
+
logger.debug("Streaming response from Copilot");
|
|
3717
3657
|
return streamSSE(c, async (stream) => {
|
|
3718
3658
|
let usage = {};
|
|
3719
3659
|
const streamState = {
|
|
@@ -3724,15 +3664,15 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3724
3664
|
thinkingBlockOpen: false
|
|
3725
3665
|
};
|
|
3726
3666
|
for await (const rawEvent of response) {
|
|
3727
|
-
debugJson(logger
|
|
3667
|
+
debugJson(logger, "Copilot raw stream event:", rawEvent);
|
|
3728
3668
|
if (rawEvent.data === "[DONE]") break;
|
|
3729
3669
|
if (!rawEvent.data) continue;
|
|
3730
3670
|
const chunk = JSON.parse(rawEvent.data);
|
|
3731
3671
|
if (chunk.usage) usage = normalizeOpenAIUsage(chunk.usage);
|
|
3732
|
-
const events
|
|
3733
|
-
for (const event of events
|
|
3672
|
+
const events = translateChunkToAnthropicEvents(chunk, streamState);
|
|
3673
|
+
for (const event of events) {
|
|
3734
3674
|
const eventData = JSON.stringify(event);
|
|
3735
|
-
debugLazy(logger
|
|
3675
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3736
3676
|
await stream.writeSSE({
|
|
3737
3677
|
event: event.type,
|
|
3738
3678
|
data: eventData
|
|
@@ -3741,7 +3681,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3741
3681
|
}
|
|
3742
3682
|
for (const event of flushPendingAnthropicStreamEvents(streamState)) {
|
|
3743
3683
|
const eventData = JSON.stringify(event);
|
|
3744
|
-
debugLazy(logger
|
|
3684
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3745
3685
|
await stream.writeSSE({
|
|
3746
3686
|
event: event.type,
|
|
3747
3687
|
data: eventData
|
|
@@ -3751,7 +3691,7 @@ const handleWithChatCompletions = async (c, anthropicPayload, options) => {
|
|
|
3751
3691
|
});
|
|
3752
3692
|
};
|
|
3753
3693
|
const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
3754
|
-
const { logger
|
|
3694
|
+
const { logger, selectedModel, ...requestOptions } = options;
|
|
3755
3695
|
const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload);
|
|
3756
3696
|
const recordUsage = createCopilotUsageRecorder({
|
|
3757
3697
|
endpoint: "responses",
|
|
@@ -3761,7 +3701,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3761
3701
|
});
|
|
3762
3702
|
applyResponsesApiContextManagement(responsesPayload, selectedModel?.capabilities.limits.max_prompt_tokens);
|
|
3763
3703
|
compactInputByLatestCompaction(responsesPayload);
|
|
3764
|
-
debugJson(logger
|
|
3704
|
+
debugJson(logger, "Translated Responses payload:", responsesPayload);
|
|
3765
3705
|
const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
|
|
3766
3706
|
const response = await createResponses(responsesPayload, {
|
|
3767
3707
|
vision,
|
|
@@ -3769,7 +3709,7 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3769
3709
|
...requestOptions
|
|
3770
3710
|
});
|
|
3771
3711
|
if (responsesPayload.stream && isAsyncIterable$1(response)) {
|
|
3772
|
-
logger
|
|
3712
|
+
logger.debug("Streaming response from Copilot (Responses API)");
|
|
3773
3713
|
return streamSSE(c, async (stream) => {
|
|
3774
3714
|
const streamState = createResponsesStreamState();
|
|
3775
3715
|
let usage = {};
|
|
@@ -3783,25 +3723,25 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3783
3723
|
}
|
|
3784
3724
|
const data = chunk.data;
|
|
3785
3725
|
if (!data) continue;
|
|
3786
|
-
debugLazy(logger
|
|
3726
|
+
debugLazy(logger, () => ["Responses raw stream event:", data]);
|
|
3787
3727
|
const responseEvent = JSON.parse(data);
|
|
3788
3728
|
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
|
|
3729
|
+
const events = translateResponsesStreamEvent(responseEvent, streamState);
|
|
3730
|
+
for (const event of events) {
|
|
3791
3731
|
const eventData = JSON.stringify(event);
|
|
3792
|
-
debugLazy(logger
|
|
3732
|
+
debugLazy(logger, () => ["Translated Anthropic event:", eventData]);
|
|
3793
3733
|
await stream.writeSSE({
|
|
3794
3734
|
event: event.type,
|
|
3795
3735
|
data: eventData
|
|
3796
3736
|
});
|
|
3797
3737
|
}
|
|
3798
3738
|
if (streamState.messageCompleted) {
|
|
3799
|
-
logger
|
|
3739
|
+
logger.debug("Message completed, ending stream");
|
|
3800
3740
|
break;
|
|
3801
3741
|
}
|
|
3802
3742
|
}
|
|
3803
3743
|
if (!streamState.messageCompleted) {
|
|
3804
|
-
logger
|
|
3744
|
+
logger.warn("Responses stream ended without completion; sending error event");
|
|
3805
3745
|
const errorEvent = buildErrorEvent("Responses stream ended without completion");
|
|
3806
3746
|
await stream.writeSSE({
|
|
3807
3747
|
event: errorEvent.type,
|
|
@@ -3811,17 +3751,17 @@ const handleWithResponsesApi = async (c, anthropicPayload, options) => {
|
|
|
3811
3751
|
recordUsage(usage);
|
|
3812
3752
|
});
|
|
3813
3753
|
}
|
|
3814
|
-
debugJsonTail(logger
|
|
3754
|
+
debugJsonTail(logger, "Non-streaming Responses result:", {
|
|
3815
3755
|
value: response,
|
|
3816
3756
|
tailLength: 400
|
|
3817
3757
|
});
|
|
3818
3758
|
const anthropicResponse = translateResponsesResultToAnthropic(response);
|
|
3819
3759
|
recordUsage(normalizeResponsesUsage(response.usage));
|
|
3820
|
-
debugJson(logger
|
|
3760
|
+
debugJson(logger, "Translated Anthropic response:", anthropicResponse);
|
|
3821
3761
|
return c.json(anthropicResponse);
|
|
3822
3762
|
};
|
|
3823
3763
|
const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
3824
|
-
const { logger
|
|
3764
|
+
const { logger, anthropicBetaHeader, subagentMarker, selectedModel, requestId, sessionId, compactType } = options;
|
|
3825
3765
|
prepareMessagesApiPayload(anthropicPayload, selectedModel);
|
|
3826
3766
|
const recordUsage = createCopilotUsageRecorder({
|
|
3827
3767
|
endpoint: "messages",
|
|
@@ -3829,7 +3769,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3829
3769
|
model: anthropicPayload.model,
|
|
3830
3770
|
payload: anthropicPayload
|
|
3831
3771
|
});
|
|
3832
|
-
debugJson(logger
|
|
3772
|
+
debugJson(logger, "Translated Messages payload:", anthropicPayload);
|
|
3833
3773
|
const response = await createMessages(anthropicPayload, anthropicBetaHeader, {
|
|
3834
3774
|
subagentMarker,
|
|
3835
3775
|
requestId,
|
|
@@ -3837,7 +3777,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3837
3777
|
compactType
|
|
3838
3778
|
});
|
|
3839
3779
|
if (isAsyncIterable$1(response)) {
|
|
3840
|
-
logger
|
|
3780
|
+
logger.debug("Streaming response from Copilot (Messages API)");
|
|
3841
3781
|
return streamSSE(c, async (stream) => {
|
|
3842
3782
|
let usage = {};
|
|
3843
3783
|
for await (const event of response) {
|
|
@@ -3845,7 +3785,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3845
3785
|
const data = event.data ?? "";
|
|
3846
3786
|
if (data === "[DONE]") break;
|
|
3847
3787
|
if (!data) continue;
|
|
3848
|
-
debugLazy(logger
|
|
3788
|
+
debugLazy(logger, () => ["Messages raw stream event:", data]);
|
|
3849
3789
|
const parsedEvent = parseAnthropicStreamEvent(data);
|
|
3850
3790
|
if (parsedEvent?.type === "message_start") usage = mergeAnthropicUsage(usage, normalizeAnthropicUsage(parsedEvent.message.usage));
|
|
3851
3791
|
else if (parsedEvent?.type === "message_delta") usage = mergeAnthropicUsage(usage, normalizeAnthropicUsage(parsedEvent.usage));
|
|
@@ -3857,7 +3797,7 @@ const handleWithMessagesApi = async (c, anthropicPayload, options) => {
|
|
|
3857
3797
|
recordUsage(usage);
|
|
3858
3798
|
});
|
|
3859
3799
|
}
|
|
3860
|
-
debugJsonTail(logger
|
|
3800
|
+
debugJsonTail(logger, "Non-streaming Messages result:", {
|
|
3861
3801
|
value: response,
|
|
3862
3802
|
tailLength: 400
|
|
3863
3803
|
});
|
|
@@ -3900,11 +3840,9 @@ const parseAnthropicStreamEvent = (data) => {
|
|
|
3900
3840
|
return null;
|
|
3901
3841
|
}
|
|
3902
3842
|
};
|
|
3903
|
-
|
|
3904
3843
|
//#endregion
|
|
3905
3844
|
//#region src/lib/subagent.ts
|
|
3906
3845
|
const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
|
|
3907
|
-
|
|
3908
3846
|
//#endregion
|
|
3909
3847
|
//#region src/routes/messages/subagent-marker.ts
|
|
3910
3848
|
const parseSubagentMarkerFromFirstUser = (payload) => {
|
|
@@ -3933,7 +3871,7 @@ const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
|
3933
3871
|
searchFrom = reminderEnd + 18;
|
|
3934
3872
|
continue;
|
|
3935
3873
|
}
|
|
3936
|
-
const markerJson = reminderContent.slice(markerIndex +
|
|
3874
|
+
const markerJson = reminderContent.slice(markerIndex + 19).trim();
|
|
3937
3875
|
try {
|
|
3938
3876
|
const parsed = JSON.parse(markerJson);
|
|
3939
3877
|
if (!parsed.session_id || !parsed.agent_id || !parsed.agent_type) {
|
|
@@ -3948,7 +3886,6 @@ const parseSubagentMarkerFromSystemReminder = (text) => {
|
|
|
3948
3886
|
}
|
|
3949
3887
|
return null;
|
|
3950
3888
|
};
|
|
3951
|
-
|
|
3952
3889
|
//#endregion
|
|
3953
3890
|
//#region src/routes/messages/handler.ts
|
|
3954
3891
|
const logger$3 = createHandlerLogger("messages-handler");
|
|
@@ -3981,7 +3918,7 @@ async function handleCompletion(c) {
|
|
|
3981
3918
|
if (anthropicBeta && noTools && compactType === 0) anthropicPayload.model = getSmallModel();
|
|
3982
3919
|
if (compactType) logger$3.debug("Compact request type:", compactType);
|
|
3983
3920
|
stripToolReferenceTurnBoundary(anthropicPayload);
|
|
3984
|
-
mergeToolResultForClaude(anthropicPayload, { skipLastMessage: compactType ===
|
|
3921
|
+
mergeToolResultForClaude(anthropicPayload, { skipLastMessage: compactType === 1 });
|
|
3985
3922
|
const requestId = generateRequestIdFromPayload(anthropicPayload, sessionId);
|
|
3986
3923
|
logger$3.debug("Generated request ID:", requestId);
|
|
3987
3924
|
if (state.manualApprove) await awaitApproval();
|
|
@@ -4021,7 +3958,6 @@ const shouldUseMessagesApi = (selectedModel) => {
|
|
|
4021
3958
|
if (!isMessagesApiEnabled()) return false;
|
|
4022
3959
|
return selectedModel?.supported_endpoints?.includes(MESSAGES_ENDPOINT) ?? false;
|
|
4023
3960
|
};
|
|
4024
|
-
|
|
4025
3961
|
//#endregion
|
|
4026
3962
|
//#region src/routes/messages/route.ts
|
|
4027
3963
|
const messageRoutes = new Hono();
|
|
@@ -4039,7 +3975,6 @@ messageRoutes.post("/count_tokens", async (c) => {
|
|
|
4039
3975
|
return await forwardError(c, error);
|
|
4040
3976
|
}
|
|
4041
3977
|
});
|
|
4042
|
-
|
|
4043
3978
|
//#endregion
|
|
4044
3979
|
//#region src/routes/models/route.ts
|
|
4045
3980
|
const modelRoutes = new Hono();
|
|
@@ -4068,7 +4003,6 @@ modelRoutes.get("/", async (c) => {
|
|
|
4068
4003
|
return await forwardError(c, error);
|
|
4069
4004
|
}
|
|
4070
4005
|
});
|
|
4071
|
-
|
|
4072
4006
|
//#endregion
|
|
4073
4007
|
//#region src/routes/provider/messages/route.ts
|
|
4074
4008
|
const providerMessageRoutes = new Hono();
|
|
@@ -4086,7 +4020,6 @@ providerMessageRoutes.post("/count_tokens", async (c) => {
|
|
|
4086
4020
|
return await forwardError(c, error);
|
|
4087
4021
|
}
|
|
4088
4022
|
});
|
|
4089
|
-
|
|
4090
4023
|
//#endregion
|
|
4091
4024
|
//#region src/routes/provider/models/route.ts
|
|
4092
4025
|
const logger$2 = createHandlerLogger("provider-models-handler");
|
|
@@ -4113,7 +4046,6 @@ providerModelRoutes.get("/", async (c) => {
|
|
|
4113
4046
|
return await forwardError(c, error);
|
|
4114
4047
|
}
|
|
4115
4048
|
});
|
|
4116
|
-
|
|
4117
4049
|
//#endregion
|
|
4118
4050
|
//#region src/routes/responses/stream-id-sync.ts
|
|
4119
4051
|
const createStreamIdTracker = () => ({ outputItems: /* @__PURE__ */ new Map() });
|
|
@@ -4150,7 +4082,6 @@ const handleItemId = (parsed, tracker) => {
|
|
|
4150
4082
|
}
|
|
4151
4083
|
return JSON.stringify(parsed);
|
|
4152
4084
|
};
|
|
4153
|
-
|
|
4154
4085
|
//#endregion
|
|
4155
4086
|
//#region src/routes/responses/handler.ts
|
|
4156
4087
|
const logger$1 = createHandlerLogger("responses-handler");
|
|
@@ -4269,7 +4200,6 @@ const removeUnsupportedTools = (payload) => {
|
|
|
4269
4200
|
});
|
|
4270
4201
|
if (dropped.length > 0) logger$1.debug("Removed unsupported tools:", dropped);
|
|
4271
4202
|
};
|
|
4272
|
-
|
|
4273
4203
|
//#endregion
|
|
4274
4204
|
//#region src/routes/responses/route.ts
|
|
4275
4205
|
const responsesRoutes = new Hono();
|
|
@@ -4280,7 +4210,6 @@ responsesRoutes.post("/", async (c) => {
|
|
|
4280
4210
|
return await forwardError(c, error);
|
|
4281
4211
|
}
|
|
4282
4212
|
});
|
|
4283
|
-
|
|
4284
4213
|
//#endregion
|
|
4285
4214
|
//#region src/routes/token-usage/route.ts
|
|
4286
4215
|
const tokenUsageRoute = new Hono();
|
|
@@ -4298,22 +4227,18 @@ function parsePositiveInt(value, fallback) {
|
|
|
4298
4227
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
4299
4228
|
}
|
|
4300
4229
|
tokenUsageRoute.get("/", async (c) => {
|
|
4301
|
-
const
|
|
4302
|
-
const summary = await getTokenUsageSummary(period);
|
|
4230
|
+
const summary = await getTokenUsageSummary(parsePeriod(c.req.query("period")));
|
|
4303
4231
|
return c.json(summary);
|
|
4304
4232
|
});
|
|
4305
4233
|
tokenUsageRoute.get("/events", async (c) => {
|
|
4306
4234
|
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
4235
|
const eventsPage = await getTokenUsageEventsPage({
|
|
4310
|
-
page,
|
|
4311
|
-
pageSize,
|
|
4236
|
+
page: parsePositiveInt(c.req.query("page"), 1),
|
|
4237
|
+
pageSize: parsePositiveInt(c.req.query("page_size"), DEFAULT_EVENTS_PAGE_SIZE),
|
|
4312
4238
|
period
|
|
4313
4239
|
});
|
|
4314
4240
|
return c.json(eventsPage);
|
|
4315
4241
|
});
|
|
4316
|
-
|
|
4317
4242
|
//#endregion
|
|
4318
4243
|
//#region src/routes/token/route.ts
|
|
4319
4244
|
const tokenRoute = new Hono();
|
|
@@ -4328,7 +4253,6 @@ tokenRoute.get("/", (c) => {
|
|
|
4328
4253
|
}, 500);
|
|
4329
4254
|
}
|
|
4330
4255
|
});
|
|
4331
|
-
|
|
4332
4256
|
//#endregion
|
|
4333
4257
|
//#region src/routes/usage/route.ts
|
|
4334
4258
|
const usageRoute = new Hono();
|
|
@@ -4341,7 +4265,6 @@ usageRoute.get("/", async (c) => {
|
|
|
4341
4265
|
return c.json({ error: "Failed to fetch Copilot usage" }, 500);
|
|
4342
4266
|
}
|
|
4343
4267
|
});
|
|
4344
|
-
|
|
4345
4268
|
//#endregion
|
|
4346
4269
|
//#region src/server.ts
|
|
4347
4270
|
const server = new Hono();
|
|
@@ -4373,7 +4296,7 @@ server.route("/v1/responses", responsesRoutes);
|
|
|
4373
4296
|
server.route("/v1/messages", messageRoutes);
|
|
4374
4297
|
server.route("/:provider/v1/messages", providerMessageRoutes);
|
|
4375
4298
|
server.route("/:provider/v1/models", providerModelRoutes);
|
|
4376
|
-
|
|
4377
4299
|
//#endregion
|
|
4378
4300
|
export { server };
|
|
4379
|
-
|
|
4301
|
+
|
|
4302
|
+
//# sourceMappingURL=server-XuNjMVc6.js.map
|