ghc-proxy 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -10
- package/dist/main.mjs +1005 -67
- package/dist/main.mjs.map +1 -1
- package/package.json +2 -1
package/dist/main.mjs
CHANGED
|
@@ -5378,7 +5378,11 @@ const configFileSchema = object({
|
|
|
5378
5378
|
smallModel: string().optional(),
|
|
5379
5379
|
compactUseSmallModel: boolean().optional(),
|
|
5380
5380
|
useFunctionApplyPatch: boolean().optional(),
|
|
5381
|
+
responsesApiAutoCompactInput: boolean().optional(),
|
|
5382
|
+
responsesApiAutoContextManagement: boolean().optional(),
|
|
5381
5383
|
responsesApiContextManagementModels: array(string()).optional(),
|
|
5384
|
+
responsesOfficialEmulator: boolean().optional(),
|
|
5385
|
+
responsesOfficialEmulatorTtlSeconds: number().int().positive().optional(),
|
|
5382
5386
|
modelReasoningEfforts: record(string(), reasoningEffortSchema).optional(),
|
|
5383
5387
|
modelRewrites: array(object({
|
|
5384
5388
|
from: string(),
|
|
@@ -5392,6 +5396,10 @@ let cachedConfig = {};
|
|
|
5392
5396
|
const DEFAULT_REASONING_EFFORT = "high";
|
|
5393
5397
|
const DEFAULT_USE_FUNCTION_APPLY_PATCH = true;
|
|
5394
5398
|
const DEFAULT_COMPACT_USE_SMALL_MODEL = false;
|
|
5399
|
+
const DEFAULT_RESPONSES_API_AUTO_COMPACT_INPUT = false;
|
|
5400
|
+
const DEFAULT_RESPONSES_API_AUTO_CONTEXT_MANAGEMENT = false;
|
|
5401
|
+
const DEFAULT_RESPONSES_OFFICIAL_EMULATOR = false;
|
|
5402
|
+
const DEFAULT_RESPONSES_OFFICIAL_EMULATOR_TTL_SECONDS = 14400;
|
|
5395
5403
|
const DEFAULT_CONTEXT_UPGRADE = true;
|
|
5396
5404
|
const DEFAULT_CONTEXT_UPGRADE_TOKEN_THRESHOLD = 16e4;
|
|
5397
5405
|
async function readConfig() {
|
|
@@ -5439,9 +5447,19 @@ function shouldCompactUseSmallModel() {
|
|
|
5439
5447
|
function shouldUseFunctionApplyPatch() {
|
|
5440
5448
|
return cachedConfig.useFunctionApplyPatch ?? DEFAULT_USE_FUNCTION_APPLY_PATCH;
|
|
5441
5449
|
}
|
|
5450
|
+
function shouldAutoCompactResponsesInput() {
|
|
5451
|
+
return cachedConfig.responsesApiAutoCompactInput ?? DEFAULT_RESPONSES_API_AUTO_COMPACT_INPUT;
|
|
5452
|
+
}
|
|
5442
5453
|
function isResponsesApiContextManagementModel(model) {
|
|
5454
|
+
if (!(cachedConfig.responsesApiAutoContextManagement ?? DEFAULT_RESPONSES_API_AUTO_CONTEXT_MANAGEMENT)) return false;
|
|
5443
5455
|
return cachedConfig.responsesApiContextManagementModels?.includes(model) ?? false;
|
|
5444
5456
|
}
|
|
5457
|
+
function shouldUseResponsesOfficialEmulator() {
|
|
5458
|
+
return cachedConfig.responsesOfficialEmulator ?? DEFAULT_RESPONSES_OFFICIAL_EMULATOR;
|
|
5459
|
+
}
|
|
5460
|
+
function getResponsesOfficialEmulatorTtlSeconds() {
|
|
5461
|
+
return cachedConfig.responsesOfficialEmulatorTtlSeconds ?? DEFAULT_RESPONSES_OFFICIAL_EMULATOR_TTL_SECONDS;
|
|
5462
|
+
}
|
|
5445
5463
|
function shouldContextUpgrade() {
|
|
5446
5464
|
return cachedConfig.contextUpgrade ?? DEFAULT_CONTEXT_UPGRADE;
|
|
5447
5465
|
}
|
|
@@ -5698,6 +5716,9 @@ function fromTranslationFailure(failure) {
|
|
|
5698
5716
|
type: "translation_error"
|
|
5699
5717
|
} });
|
|
5700
5718
|
}
|
|
5719
|
+
function previewBody(text, maxLength = 500) {
|
|
5720
|
+
return text.length > maxLength ? `${text.slice(0, maxLength)}…` : text;
|
|
5721
|
+
}
|
|
5701
5722
|
function isStructuredErrorPayload(value) {
|
|
5702
5723
|
return typeof value === "object" && value !== null && "error" in value && typeof value.error === "object" && value.error !== null;
|
|
5703
5724
|
}
|
|
@@ -5706,12 +5727,13 @@ function isStructuredErrorPayload(value) {
|
|
|
5706
5727
|
* Used by CopilotClient when upstream returns a non-OK response.
|
|
5707
5728
|
*/
|
|
5708
5729
|
async function throwUpstreamError(message, response) {
|
|
5730
|
+
let rawText = "";
|
|
5709
5731
|
let body;
|
|
5710
5732
|
try {
|
|
5711
|
-
|
|
5712
|
-
const json = JSON.parse(
|
|
5733
|
+
rawText = await response.text();
|
|
5734
|
+
const json = JSON.parse(rawText);
|
|
5713
5735
|
body = isStructuredErrorPayload(json) ? json : { error: {
|
|
5714
|
-
message:
|
|
5736
|
+
message: rawText,
|
|
5715
5737
|
type: "upstream_error"
|
|
5716
5738
|
} };
|
|
5717
5739
|
} catch {
|
|
@@ -5720,7 +5742,13 @@ async function throwUpstreamError(message, response) {
|
|
|
5720
5742
|
type: "upstream_error"
|
|
5721
5743
|
} };
|
|
5722
5744
|
}
|
|
5723
|
-
consola.error("Upstream error:",
|
|
5745
|
+
consola.error("Upstream error:", {
|
|
5746
|
+
status: response.status,
|
|
5747
|
+
statusText: response.statusText,
|
|
5748
|
+
url: response.url,
|
|
5749
|
+
body,
|
|
5750
|
+
rawBody: rawText ? previewBody(rawText) : "<empty>"
|
|
5751
|
+
});
|
|
5724
5752
|
throw new HTTPError(response.status, body);
|
|
5725
5753
|
}
|
|
5726
5754
|
|
|
@@ -5751,10 +5779,7 @@ var CopilotClient = class {
|
|
|
5751
5779
|
body: options.body,
|
|
5752
5780
|
signal: options.signal
|
|
5753
5781
|
});
|
|
5754
|
-
if (!response.ok)
|
|
5755
|
-
consola.error(errorMessage, response);
|
|
5756
|
-
await throwUpstreamError(errorMessage, response);
|
|
5757
|
-
}
|
|
5782
|
+
if (!response.ok) await throwUpstreamError(errorMessage, response);
|
|
5758
5783
|
return response;
|
|
5759
5784
|
}
|
|
5760
5785
|
/** Fetch and parse JSON response */
|
|
@@ -6022,6 +6047,221 @@ async function getVSCodeVersion() {
|
|
|
6022
6047
|
return remoteVersion ?? localVersion ?? FALLBACK;
|
|
6023
6048
|
}
|
|
6024
6049
|
|
|
6050
|
+
//#endregion
|
|
6051
|
+
//#region src/lib/responses-emulator-state.ts
|
|
6052
|
+
function cloneValue$1(value) {
|
|
6053
|
+
if (typeof globalThis.structuredClone === "function") return globalThis.structuredClone(value);
|
|
6054
|
+
return JSON.parse(JSON.stringify(value));
|
|
6055
|
+
}
|
|
6056
|
+
function currentTime() {
|
|
6057
|
+
return Date.now();
|
|
6058
|
+
}
|
|
6059
|
+
function resolveTtlSeconds(ttlSeconds) {
|
|
6060
|
+
const resolved = ttlSeconds ?? getResponsesOfficialEmulatorTtlSeconds();
|
|
6061
|
+
if (!Number.isFinite(resolved) || resolved <= 0) return getResponsesOfficialEmulatorTtlSeconds();
|
|
6062
|
+
return Math.floor(resolved);
|
|
6063
|
+
}
|
|
6064
|
+
function toExpiresAt(ttlSeconds, at = currentTime()) {
|
|
6065
|
+
return at + resolveTtlSeconds(ttlSeconds) * 1e3;
|
|
6066
|
+
}
|
|
6067
|
+
function responseKeyFromConversation(conversation) {
|
|
6068
|
+
return typeof conversation === "string" ? conversation : conversation.id;
|
|
6069
|
+
}
|
|
6070
|
+
function createResponsesEmulatorState() {
|
|
6071
|
+
const responseRecords = /* @__PURE__ */ new Map();
|
|
6072
|
+
const conversationRecords = /* @__PURE__ */ new Map();
|
|
6073
|
+
const conversationHeadRecords = /* @__PURE__ */ new Map();
|
|
6074
|
+
const inputItemRecords = /* @__PURE__ */ new Map();
|
|
6075
|
+
const responseDeletionFlags = /* @__PURE__ */ new Map();
|
|
6076
|
+
const conversationDeletionFlags = /* @__PURE__ */ new Map();
|
|
6077
|
+
const inputItemDeletionFlags = /* @__PURE__ */ new Map();
|
|
6078
|
+
function pruneMap(map, at = currentTime()) {
|
|
6079
|
+
for (const [key, entry] of map) if (entry.expiresAt <= at) map.delete(key);
|
|
6080
|
+
}
|
|
6081
|
+
function readMap(map, key, at = currentTime()) {
|
|
6082
|
+
const entry = map.get(key);
|
|
6083
|
+
if (!entry) return;
|
|
6084
|
+
if (entry.expiresAt <= at) {
|
|
6085
|
+
map.delete(key);
|
|
6086
|
+
return;
|
|
6087
|
+
}
|
|
6088
|
+
return cloneValue$1(entry.value);
|
|
6089
|
+
}
|
|
6090
|
+
function writeMap(map, key, value, ttlSeconds, at = currentTime()) {
|
|
6091
|
+
const cloned = cloneValue$1(value);
|
|
6092
|
+
map.set(key, {
|
|
6093
|
+
expiresAt: toExpiresAt(ttlSeconds, at),
|
|
6094
|
+
value: cloned
|
|
6095
|
+
});
|
|
6096
|
+
return cloneValue$1(cloned);
|
|
6097
|
+
}
|
|
6098
|
+
function deleteMapEntry(map, key) {
|
|
6099
|
+
return map.delete(key);
|
|
6100
|
+
}
|
|
6101
|
+
function putDeletionFlag(map, id, ttlSeconds, at = currentTime()) {
|
|
6102
|
+
const flag = {
|
|
6103
|
+
deleted: true,
|
|
6104
|
+
deletedAt: at,
|
|
6105
|
+
expiresAt: toExpiresAt(ttlSeconds, at)
|
|
6106
|
+
};
|
|
6107
|
+
map.set(id, {
|
|
6108
|
+
expiresAt: flag.expiresAt,
|
|
6109
|
+
value: flag
|
|
6110
|
+
});
|
|
6111
|
+
return cloneValue$1(flag);
|
|
6112
|
+
}
|
|
6113
|
+
function readDeletionFlag(map, id, at = currentTime()) {
|
|
6114
|
+
return readMap(map, id, at);
|
|
6115
|
+
}
|
|
6116
|
+
function removeDeletionFlag(map, id) {
|
|
6117
|
+
map.delete(id);
|
|
6118
|
+
}
|
|
6119
|
+
function deletionMap(kind) {
|
|
6120
|
+
switch (kind) {
|
|
6121
|
+
case "response": return responseDeletionFlags;
|
|
6122
|
+
case "conversation": return conversationDeletionFlags;
|
|
6123
|
+
case "input_items": return inputItemDeletionFlags;
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
function pruneExpiredRecords(at = currentTime()) {
|
|
6127
|
+
pruneMap(responseRecords, at);
|
|
6128
|
+
pruneMap(conversationRecords, at);
|
|
6129
|
+
pruneMap(conversationHeadRecords, at);
|
|
6130
|
+
pruneMap(inputItemRecords, at);
|
|
6131
|
+
pruneMap(responseDeletionFlags, at);
|
|
6132
|
+
pruneMap(conversationDeletionFlags, at);
|
|
6133
|
+
pruneMap(inputItemDeletionFlags, at);
|
|
6134
|
+
}
|
|
6135
|
+
return {
|
|
6136
|
+
isEnabled() {
|
|
6137
|
+
return shouldUseResponsesOfficialEmulator();
|
|
6138
|
+
},
|
|
6139
|
+
getDefaultTtlSeconds() {
|
|
6140
|
+
return getResponsesOfficialEmulatorTtlSeconds();
|
|
6141
|
+
},
|
|
6142
|
+
clear() {
|
|
6143
|
+
responseRecords.clear();
|
|
6144
|
+
conversationRecords.clear();
|
|
6145
|
+
conversationHeadRecords.clear();
|
|
6146
|
+
inputItemRecords.clear();
|
|
6147
|
+
responseDeletionFlags.clear();
|
|
6148
|
+
conversationDeletionFlags.clear();
|
|
6149
|
+
inputItemDeletionFlags.clear();
|
|
6150
|
+
},
|
|
6151
|
+
pruneExpired(nowValue) {
|
|
6152
|
+
pruneExpiredRecords(nowValue ?? currentTime());
|
|
6153
|
+
},
|
|
6154
|
+
snapshot(nowValue) {
|
|
6155
|
+
pruneExpiredRecords(nowValue ?? currentTime());
|
|
6156
|
+
return {
|
|
6157
|
+
responses: responseRecords.size,
|
|
6158
|
+
conversations: conversationRecords.size,
|
|
6159
|
+
conversationHeads: conversationHeadRecords.size,
|
|
6160
|
+
inputItems: inputItemRecords.size,
|
|
6161
|
+
deletions: responseDeletionFlags.size + conversationDeletionFlags.size + inputItemDeletionFlags.size
|
|
6162
|
+
};
|
|
6163
|
+
},
|
|
6164
|
+
setResponse(response, options) {
|
|
6165
|
+
pruneExpiredRecords();
|
|
6166
|
+
removeDeletionFlag(responseDeletionFlags, response.id);
|
|
6167
|
+
if (response.conversation !== void 0 && response.conversation !== null) {
|
|
6168
|
+
const conversationId = responseKeyFromConversation(response.conversation);
|
|
6169
|
+
writeMap(conversationRecords, conversationId, response.conversation, options?.ttlSeconds);
|
|
6170
|
+
writeMap(conversationHeadRecords, conversationId, response.id, options?.ttlSeconds);
|
|
6171
|
+
removeDeletionFlag(conversationDeletionFlags, conversationId);
|
|
6172
|
+
}
|
|
6173
|
+
return writeMap(responseRecords, response.id, response, options?.ttlSeconds);
|
|
6174
|
+
},
|
|
6175
|
+
getResponse(responseId) {
|
|
6176
|
+
pruneExpiredRecords();
|
|
6177
|
+
if (readDeletionFlag(responseDeletionFlags, responseId)) return;
|
|
6178
|
+
return readMap(responseRecords, responseId);
|
|
6179
|
+
},
|
|
6180
|
+
deleteResponse(responseId, options) {
|
|
6181
|
+
pruneExpiredRecords();
|
|
6182
|
+
const existing = readMap(responseRecords, responseId);
|
|
6183
|
+
deleteMapEntry(responseRecords, responseId);
|
|
6184
|
+
deleteMapEntry(inputItemRecords, responseId);
|
|
6185
|
+
putDeletionFlag(responseDeletionFlags, responseId, options?.ttlSeconds);
|
|
6186
|
+
putDeletionFlag(inputItemDeletionFlags, responseId, options?.ttlSeconds);
|
|
6187
|
+
if (existing?.conversation) {
|
|
6188
|
+
const conversationId = responseKeyFromConversation(existing.conversation);
|
|
6189
|
+
if (readMap(conversationHeadRecords, conversationId) === responseId) deleteMapEntry(conversationHeadRecords, conversationId);
|
|
6190
|
+
}
|
|
6191
|
+
return {
|
|
6192
|
+
id: responseId,
|
|
6193
|
+
object: "response.deleted",
|
|
6194
|
+
deleted: true
|
|
6195
|
+
};
|
|
6196
|
+
},
|
|
6197
|
+
setConversation(conversation, options) {
|
|
6198
|
+
pruneExpiredRecords();
|
|
6199
|
+
const conversationId = responseKeyFromConversation(conversation);
|
|
6200
|
+
removeDeletionFlag(conversationDeletionFlags, conversationId);
|
|
6201
|
+
return writeMap(conversationRecords, conversationId, conversation, options?.ttlSeconds);
|
|
6202
|
+
},
|
|
6203
|
+
getConversation(conversationId) {
|
|
6204
|
+
pruneExpiredRecords();
|
|
6205
|
+
if (readDeletionFlag(conversationDeletionFlags, conversationId)) return;
|
|
6206
|
+
return readMap(conversationRecords, conversationId);
|
|
6207
|
+
},
|
|
6208
|
+
deleteConversation(conversationId, options) {
|
|
6209
|
+
pruneExpiredRecords();
|
|
6210
|
+
deleteMapEntry(conversationRecords, conversationId);
|
|
6211
|
+
deleteMapEntry(conversationHeadRecords, conversationId);
|
|
6212
|
+
putDeletionFlag(conversationDeletionFlags, conversationId, options?.ttlSeconds);
|
|
6213
|
+
return {
|
|
6214
|
+
id: conversationId,
|
|
6215
|
+
object: "conversation.deleted",
|
|
6216
|
+
deleted: true
|
|
6217
|
+
};
|
|
6218
|
+
},
|
|
6219
|
+
setConversationHead(conversationId, responseId, options) {
|
|
6220
|
+
pruneExpiredRecords();
|
|
6221
|
+
return writeMap(conversationHeadRecords, conversationId, responseId, options?.ttlSeconds);
|
|
6222
|
+
},
|
|
6223
|
+
getConversationHead(conversationId) {
|
|
6224
|
+
pruneExpiredRecords();
|
|
6225
|
+
return readMap(conversationHeadRecords, conversationId);
|
|
6226
|
+
},
|
|
6227
|
+
clearConversationHead(conversationId) {
|
|
6228
|
+
deleteMapEntry(conversationHeadRecords, conversationId);
|
|
6229
|
+
},
|
|
6230
|
+
setInputItems(responseId, inputItems, options) {
|
|
6231
|
+
pruneExpiredRecords();
|
|
6232
|
+
removeDeletionFlag(inputItemDeletionFlags, responseId);
|
|
6233
|
+
return writeMap(inputItemRecords, responseId, inputItems, options?.ttlSeconds);
|
|
6234
|
+
},
|
|
6235
|
+
getInputItems(responseId) {
|
|
6236
|
+
pruneExpiredRecords();
|
|
6237
|
+
if (readDeletionFlag(inputItemDeletionFlags, responseId)) return;
|
|
6238
|
+
return readMap(inputItemRecords, responseId);
|
|
6239
|
+
},
|
|
6240
|
+
deleteInputItems(responseId, options) {
|
|
6241
|
+
pruneExpiredRecords();
|
|
6242
|
+
deleteMapEntry(inputItemRecords, responseId);
|
|
6243
|
+
putDeletionFlag(inputItemDeletionFlags, responseId, options?.ttlSeconds);
|
|
6244
|
+
return {
|
|
6245
|
+
id: responseId,
|
|
6246
|
+
object: "response.input_items.deleted",
|
|
6247
|
+
deleted: true
|
|
6248
|
+
};
|
|
6249
|
+
},
|
|
6250
|
+
setDeletionFlag(kind, id, options) {
|
|
6251
|
+
pruneExpiredRecords();
|
|
6252
|
+
return putDeletionFlag(deletionMap(kind), id, options?.ttlSeconds);
|
|
6253
|
+
},
|
|
6254
|
+
getDeletionFlag(kind, id) {
|
|
6255
|
+
pruneExpiredRecords();
|
|
6256
|
+
return readDeletionFlag(deletionMap(kind), id);
|
|
6257
|
+
},
|
|
6258
|
+
clearDeletionFlag(kind, id) {
|
|
6259
|
+
removeDeletionFlag(deletionMap(kind), id);
|
|
6260
|
+
}
|
|
6261
|
+
};
|
|
6262
|
+
}
|
|
6263
|
+
const responsesEmulatorState = createResponsesEmulatorState();
|
|
6264
|
+
|
|
6025
6265
|
//#endregion
|
|
6026
6266
|
//#region src/lib/state.ts
|
|
6027
6267
|
const state = {
|
|
@@ -6033,7 +6273,8 @@ const state = {
|
|
|
6033
6273
|
showToken: false
|
|
6034
6274
|
},
|
|
6035
6275
|
cache: {},
|
|
6036
|
-
rateLimit: {}
|
|
6276
|
+
rateLimit: {},
|
|
6277
|
+
responsesEmulator: responsesEmulatorState
|
|
6037
6278
|
};
|
|
6038
6279
|
function getClientConfig() {
|
|
6039
6280
|
return {
|
|
@@ -6225,7 +6466,7 @@ const checkUsage = defineCommand({
|
|
|
6225
6466
|
|
|
6226
6467
|
//#endregion
|
|
6227
6468
|
//#region src/lib/version.ts
|
|
6228
|
-
const VERSION = "0.5.
|
|
6469
|
+
const VERSION = "0.5.3";
|
|
6229
6470
|
|
|
6230
6471
|
//#endregion
|
|
6231
6472
|
//#region src/debug.ts
|
|
@@ -46711,8 +46952,8 @@ function inferModelFamily(model) {
|
|
|
46711
46952
|
const baseProfile = {
|
|
46712
46953
|
id: "base",
|
|
46713
46954
|
family: "other",
|
|
46714
|
-
enableCacheControl:
|
|
46715
|
-
includeUsageOnStream:
|
|
46955
|
+
enableCacheControl: true,
|
|
46956
|
+
includeUsageOnStream: true,
|
|
46716
46957
|
applyThinking(request) {
|
|
46717
46958
|
const thinking = request.thinking;
|
|
46718
46959
|
if (!thinking || thinking.type === "disabled") return {};
|
|
@@ -46740,6 +46981,9 @@ function selectCapiProfile(model) {
|
|
|
46740
46981
|
|
|
46741
46982
|
//#endregion
|
|
46742
46983
|
//#region src/core/capi/request-context.ts
|
|
46984
|
+
const SUBAGENT_MARKER_PREFIX = "__SUBAGENT_MARKER__";
|
|
46985
|
+
const SYSTEM_REMINDER_OPEN_TAG = "<system-reminder>";
|
|
46986
|
+
const SYSTEM_REMINDER_CLOSE_TAG = "</system-reminder>";
|
|
46743
46987
|
function readHeader(headers, name) {
|
|
46744
46988
|
return headers.get(name) ?? void 0;
|
|
46745
46989
|
}
|
|
@@ -46751,11 +46995,20 @@ function readCapiRequestContext(headers) {
|
|
|
46751
46995
|
interactionType: readHeader(headers, "x-interaction-type"),
|
|
46752
46996
|
agentTaskId: readHeader(headers, "x-agent-task-id"),
|
|
46753
46997
|
parentAgentTaskId: readHeader(headers, "x-parent-agent-id"),
|
|
46754
|
-
clientSessionId: readHeader(headers, "x-client-session-id"),
|
|
46998
|
+
clientSessionId: readHeader(headers, "x-client-session-id") ?? readHeader(headers, "x-session-id"),
|
|
46755
46999
|
interactionId: readHeader(headers, "x-interaction-id"),
|
|
46756
47000
|
clientMachineId: readHeader(headers, "x-client-machine-id")
|
|
46757
47001
|
};
|
|
46758
47002
|
}
|
|
47003
|
+
function resolveInitiator(defaultInitiator, requestContext) {
|
|
47004
|
+
switch (requestContext?.interactionType) {
|
|
47005
|
+
case "conversation-agent":
|
|
47006
|
+
case "conversation-subagent":
|
|
47007
|
+
case "conversation-background": return "agent";
|
|
47008
|
+
case "conversation-user": return "user";
|
|
47009
|
+
default: return defaultInitiator;
|
|
47010
|
+
}
|
|
47011
|
+
}
|
|
46759
47012
|
function buildCapiRequestContext(initiator, overrides = {}) {
|
|
46760
47013
|
return {
|
|
46761
47014
|
interactionType: overrides.interactionType ?? (initiator === "agent" ? "conversation-agent" : "conversation-user"),
|
|
@@ -46766,6 +47019,269 @@ function buildCapiRequestContext(initiator, overrides = {}) {
|
|
|
46766
47019
|
clientMachineId: overrides.clientMachineId
|
|
46767
47020
|
};
|
|
46768
47021
|
}
|
|
47022
|
+
function normalizeAnthropicRequestContext(payload, headers) {
|
|
47023
|
+
return withSubagentMarker(readCapiRequestContext(headers), headers, stripSubagentMarkerFromAnthropicPayload(payload));
|
|
47024
|
+
}
|
|
47025
|
+
function normalizeChatRequestContext(payload, headers) {
|
|
47026
|
+
return withSubagentMarker(readCapiRequestContext(headers), headers, stripSubagentMarkerFromChatPayload(payload));
|
|
47027
|
+
}
|
|
47028
|
+
function normalizeResponsesRequestContext(payload, headers) {
|
|
47029
|
+
return withSubagentMarker(readCapiRequestContext(headers), headers, stripSubagentMarkerFromResponsesPayload(payload));
|
|
47030
|
+
}
|
|
47031
|
+
function withSubagentMarker(baseContext, headers, marker) {
|
|
47032
|
+
if (!marker) return baseContext;
|
|
47033
|
+
const rootSessionId = readHeader(headers, "x-session-id") ?? baseContext.clientSessionId;
|
|
47034
|
+
return {
|
|
47035
|
+
...baseContext,
|
|
47036
|
+
interactionType: baseContext.interactionType && baseContext.interactionType !== "conversation-user" ? baseContext.interactionType : "conversation-subagent",
|
|
47037
|
+
agentTaskId: baseContext.agentTaskId ?? marker.agent_id ?? marker.session_id,
|
|
47038
|
+
clientSessionId: baseContext.clientSessionId ?? rootSessionId ?? marker.session_id
|
|
47039
|
+
};
|
|
47040
|
+
}
|
|
47041
|
+
function stripSubagentMarkerFromAnthropicPayload(payload) {
|
|
47042
|
+
let marker;
|
|
47043
|
+
if (typeof payload.system === "string") {
|
|
47044
|
+
const result = stripSubagentMarkerFromText(payload.system);
|
|
47045
|
+
payload.system = result.text || void 0;
|
|
47046
|
+
marker ??= result.marker;
|
|
47047
|
+
} else if (Array.isArray(payload.system)) {
|
|
47048
|
+
payload.system = payload.system.map((block) => {
|
|
47049
|
+
const result = stripSubagentMarkerFromText(block.text);
|
|
47050
|
+
marker ??= result.marker;
|
|
47051
|
+
return result.text ? {
|
|
47052
|
+
...block,
|
|
47053
|
+
text: result.text
|
|
47054
|
+
} : void 0;
|
|
47055
|
+
}).filter((block) => block !== void 0);
|
|
47056
|
+
if (payload.system.length === 0) payload.system = void 0;
|
|
47057
|
+
}
|
|
47058
|
+
payload.messages = payload.messages.map((message) => {
|
|
47059
|
+
const sanitized = sanitizeAnthropicMessage(message);
|
|
47060
|
+
marker ??= sanitized.marker;
|
|
47061
|
+
return sanitized.message;
|
|
47062
|
+
}).filter((message) => message !== void 0);
|
|
47063
|
+
return marker;
|
|
47064
|
+
}
|
|
47065
|
+
function sanitizeAnthropicMessage(message) {
|
|
47066
|
+
if (typeof message.content === "string") {
|
|
47067
|
+
const result = stripSubagentMarkerFromText(message.content);
|
|
47068
|
+
return {
|
|
47069
|
+
marker: result.marker,
|
|
47070
|
+
message: result.text ? {
|
|
47071
|
+
...message,
|
|
47072
|
+
content: result.text
|
|
47073
|
+
} : void 0
|
|
47074
|
+
};
|
|
47075
|
+
}
|
|
47076
|
+
if (message.role === "user") {
|
|
47077
|
+
let marker;
|
|
47078
|
+
const content = message.content.map((block) => {
|
|
47079
|
+
if (block.type !== "text") return block;
|
|
47080
|
+
const result = stripSubagentMarkerFromText(block.text);
|
|
47081
|
+
marker ??= result.marker;
|
|
47082
|
+
return result.text ? {
|
|
47083
|
+
...block,
|
|
47084
|
+
text: result.text
|
|
47085
|
+
} : void 0;
|
|
47086
|
+
}).filter((block) => block !== void 0);
|
|
47087
|
+
return {
|
|
47088
|
+
marker,
|
|
47089
|
+
message: content.length > 0 ? {
|
|
47090
|
+
...message,
|
|
47091
|
+
content
|
|
47092
|
+
} : void 0
|
|
47093
|
+
};
|
|
47094
|
+
}
|
|
47095
|
+
let marker;
|
|
47096
|
+
const content = message.content.map((block) => {
|
|
47097
|
+
if (block.type !== "text") return block;
|
|
47098
|
+
const result = stripSubagentMarkerFromText(block.text);
|
|
47099
|
+
marker ??= result.marker;
|
|
47100
|
+
return result.text ? {
|
|
47101
|
+
...block,
|
|
47102
|
+
text: result.text
|
|
47103
|
+
} : void 0;
|
|
47104
|
+
}).filter((block) => block !== void 0);
|
|
47105
|
+
return {
|
|
47106
|
+
marker,
|
|
47107
|
+
message: content.length > 0 ? {
|
|
47108
|
+
...message,
|
|
47109
|
+
content
|
|
47110
|
+
} : void 0
|
|
47111
|
+
};
|
|
47112
|
+
}
|
|
47113
|
+
function stripSubagentMarkerFromChatPayload(payload) {
|
|
47114
|
+
let marker;
|
|
47115
|
+
payload.messages = payload.messages.map((message) => {
|
|
47116
|
+
const sanitized = sanitizeChatMessage(message);
|
|
47117
|
+
marker ??= sanitized.marker;
|
|
47118
|
+
return sanitized.message;
|
|
47119
|
+
}).filter((message) => message !== void 0);
|
|
47120
|
+
return marker;
|
|
47121
|
+
}
|
|
47122
|
+
function sanitizeChatMessage(message) {
|
|
47123
|
+
if (typeof message.content === "string") {
|
|
47124
|
+
const result = stripSubagentMarkerFromText(message.content);
|
|
47125
|
+
return {
|
|
47126
|
+
marker: result.marker,
|
|
47127
|
+
message: result.text || message.tool_calls?.length ? {
|
|
47128
|
+
...message,
|
|
47129
|
+
content: result.text
|
|
47130
|
+
} : void 0
|
|
47131
|
+
};
|
|
47132
|
+
}
|
|
47133
|
+
if (message.content === null) return { message };
|
|
47134
|
+
let marker;
|
|
47135
|
+
const content = message.content.map((part) => {
|
|
47136
|
+
if (part.type !== "text") return part;
|
|
47137
|
+
const result = stripSubagentMarkerFromText(part.text);
|
|
47138
|
+
marker ??= result.marker;
|
|
47139
|
+
return result.text ? {
|
|
47140
|
+
...part,
|
|
47141
|
+
text: result.text
|
|
47142
|
+
} : void 0;
|
|
47143
|
+
}).filter((part) => part !== void 0);
|
|
47144
|
+
return {
|
|
47145
|
+
marker,
|
|
47146
|
+
message: content.length > 0 || message.tool_calls?.length ? {
|
|
47147
|
+
...message,
|
|
47148
|
+
content
|
|
47149
|
+
} : void 0
|
|
47150
|
+
};
|
|
47151
|
+
}
|
|
47152
|
+
function stripSubagentMarkerFromResponsesPayload(payload) {
|
|
47153
|
+
let marker;
|
|
47154
|
+
if (typeof payload.instructions === "string") {
|
|
47155
|
+
const result = stripSubagentMarkerFromText(payload.instructions);
|
|
47156
|
+
payload.instructions = result.text || void 0;
|
|
47157
|
+
marker ??= result.marker;
|
|
47158
|
+
}
|
|
47159
|
+
if (typeof payload.input === "string") {
|
|
47160
|
+
const result = stripSubagentMarkerFromText(payload.input);
|
|
47161
|
+
payload.input = result.text || null;
|
|
47162
|
+
marker ??= result.marker;
|
|
47163
|
+
return marker;
|
|
47164
|
+
}
|
|
47165
|
+
if (!Array.isArray(payload.input)) return marker;
|
|
47166
|
+
payload.input = payload.input.map((item) => {
|
|
47167
|
+
const sanitized = sanitizeResponsesInputItem(item);
|
|
47168
|
+
marker ??= sanitized.marker;
|
|
47169
|
+
return sanitized.item;
|
|
47170
|
+
}).filter((item) => item !== void 0);
|
|
47171
|
+
return marker;
|
|
47172
|
+
}
|
|
47173
|
+
function sanitizeResponsesInputItem(item) {
|
|
47174
|
+
if (!("type" in item) || item.type !== "message") return { item };
|
|
47175
|
+
if (typeof item.content === "string") {
|
|
47176
|
+
const result = stripSubagentMarkerFromText(item.content);
|
|
47177
|
+
return {
|
|
47178
|
+
marker: result.marker,
|
|
47179
|
+
item: result.text ? {
|
|
47180
|
+
...item,
|
|
47181
|
+
content: result.text
|
|
47182
|
+
} : void 0
|
|
47183
|
+
};
|
|
47184
|
+
}
|
|
47185
|
+
if (!Array.isArray(item.content)) return { item };
|
|
47186
|
+
let marker;
|
|
47187
|
+
const content = item.content.map((part) => {
|
|
47188
|
+
const sanitized = sanitizeResponsesInputContent(part);
|
|
47189
|
+
marker ??= sanitized.marker;
|
|
47190
|
+
return sanitized.content;
|
|
47191
|
+
}).filter((part) => part !== void 0);
|
|
47192
|
+
return {
|
|
47193
|
+
marker,
|
|
47194
|
+
item: content.length > 0 ? {
|
|
47195
|
+
...item,
|
|
47196
|
+
content
|
|
47197
|
+
} : void 0
|
|
47198
|
+
};
|
|
47199
|
+
}
|
|
47200
|
+
function sanitizeResponsesInputContent(content) {
|
|
47201
|
+
if (!("type" in content)) return { content };
|
|
47202
|
+
if (content.type !== "input_text" && content.type !== "output_text") return { content };
|
|
47203
|
+
if (typeof content.text !== "string") return { content };
|
|
47204
|
+
const result = stripSubagentMarkerFromText(content.text);
|
|
47205
|
+
return {
|
|
47206
|
+
marker: result.marker,
|
|
47207
|
+
content: result.text ? {
|
|
47208
|
+
...content,
|
|
47209
|
+
text: result.text
|
|
47210
|
+
} : void 0
|
|
47211
|
+
};
|
|
47212
|
+
}
|
|
47213
|
+
function stripSubagentMarkerFromText(text) {
|
|
47214
|
+
const markerMatch = findSubagentMarker(text);
|
|
47215
|
+
if (!markerMatch) return { text };
|
|
47216
|
+
const removalRange = findReminderRange(text, markerMatch.start, markerMatch.end);
|
|
47217
|
+
const before = text.slice(0, removalRange.start).trimEnd();
|
|
47218
|
+
const after = text.slice(removalRange.end).trimStart();
|
|
47219
|
+
return {
|
|
47220
|
+
marker: markerMatch.marker,
|
|
47221
|
+
text: before && after ? `${before}\n${after}` : `${before}${after}`
|
|
47222
|
+
};
|
|
47223
|
+
}
|
|
47224
|
+
function findSubagentMarker(text) {
|
|
47225
|
+
const markerIndex = text.indexOf(SUBAGENT_MARKER_PREFIX);
|
|
47226
|
+
if (markerIndex < 0) return;
|
|
47227
|
+
const jsonStart = text.indexOf("{", markerIndex + 19);
|
|
47228
|
+
if (jsonStart < 0) return;
|
|
47229
|
+
const jsonEnd = findJsonObjectEnd(text, jsonStart);
|
|
47230
|
+
if (jsonEnd < 0) return;
|
|
47231
|
+
try {
|
|
47232
|
+
const parsed = JSON.parse(text.slice(jsonStart, jsonEnd));
|
|
47233
|
+
if (!parsed || typeof parsed !== "object") return;
|
|
47234
|
+
return {
|
|
47235
|
+
marker: parsed,
|
|
47236
|
+
start: markerIndex,
|
|
47237
|
+
end: jsonEnd
|
|
47238
|
+
};
|
|
47239
|
+
} catch {
|
|
47240
|
+
return;
|
|
47241
|
+
}
|
|
47242
|
+
}
|
|
47243
|
+
function findReminderRange(text, markerStart, markerEnd) {
|
|
47244
|
+
const reminderStart = text.lastIndexOf(SYSTEM_REMINDER_OPEN_TAG, markerStart);
|
|
47245
|
+
const reminderEnd = text.indexOf(SYSTEM_REMINDER_CLOSE_TAG, markerEnd);
|
|
47246
|
+
if (reminderStart >= 0 && reminderEnd >= 0) return {
|
|
47247
|
+
start: reminderStart,
|
|
47248
|
+
end: reminderEnd + 18
|
|
47249
|
+
};
|
|
47250
|
+
return {
|
|
47251
|
+
start: markerStart,
|
|
47252
|
+
end: markerEnd
|
|
47253
|
+
};
|
|
47254
|
+
}
|
|
47255
|
+
function findJsonObjectEnd(text, start) {
|
|
47256
|
+
let depth = 0;
|
|
47257
|
+
let inString = false;
|
|
47258
|
+
let escaped = false;
|
|
47259
|
+
for (let index = start; index < text.length; index++) {
|
|
47260
|
+
const char = text[index];
|
|
47261
|
+
if (escaped) {
|
|
47262
|
+
escaped = false;
|
|
47263
|
+
continue;
|
|
47264
|
+
}
|
|
47265
|
+
if (char === "\\") {
|
|
47266
|
+
escaped = true;
|
|
47267
|
+
continue;
|
|
47268
|
+
}
|
|
47269
|
+
if (char === "\"") {
|
|
47270
|
+
inString = !inString;
|
|
47271
|
+
continue;
|
|
47272
|
+
}
|
|
47273
|
+
if (inString) continue;
|
|
47274
|
+
if (char === "{") {
|
|
47275
|
+
depth++;
|
|
47276
|
+
continue;
|
|
47277
|
+
}
|
|
47278
|
+
if (char === "}") {
|
|
47279
|
+
depth--;
|
|
47280
|
+
if (depth === 0) return index + 1;
|
|
47281
|
+
}
|
|
47282
|
+
}
|
|
47283
|
+
return -1;
|
|
47284
|
+
}
|
|
46769
47285
|
|
|
46770
47286
|
//#endregion
|
|
46771
47287
|
//#region src/core/capi/plan-builder.ts
|
|
@@ -46944,7 +47460,7 @@ function stripTransportFields(payload) {
|
|
|
46944
47460
|
function buildCapiExecutionPlan(request, options = {}) {
|
|
46945
47461
|
const resolvedModel = options.resolveModel?.(request.model) ?? request.model;
|
|
46946
47462
|
const profile = selectCapiProfile(resolvedModel);
|
|
46947
|
-
const initiator = inferInitiator(request.turns);
|
|
47463
|
+
const initiator = resolveInitiator(inferInitiator(request.turns), options.requestContext);
|
|
46948
47464
|
const payload = {
|
|
46949
47465
|
model: resolvedModel,
|
|
46950
47466
|
messages: serializeTurns(request.turns),
|
|
@@ -48262,6 +48778,9 @@ async function getTokenCount(payload, model) {
|
|
|
48262
48778
|
output: outputTokens
|
|
48263
48779
|
};
|
|
48264
48780
|
}
|
|
48781
|
+
async function estimateResponsesInputTokens(inputItems, model) {
|
|
48782
|
+
return (await getEncoder(getTokenizerFromModel(model))).encode(JSON.stringify(inputItems)).length;
|
|
48783
|
+
}
|
|
48265
48784
|
/**
|
|
48266
48785
|
* Fast character-based token estimate for Anthropic payloads.
|
|
48267
48786
|
* Uses ~3.5 chars/token ratio (conservative for Claude's tokenizer).
|
|
@@ -48467,7 +48986,10 @@ function parseAnthropicCountTokensPayload(payload) {
|
|
|
48467
48986
|
//#region src/lib/validation/embeddings.ts
|
|
48468
48987
|
const embeddingRequestSchema = object({
|
|
48469
48988
|
input: union([string(), array(string())]),
|
|
48470
|
-
model: string().min(1)
|
|
48989
|
+
model: string().min(1),
|
|
48990
|
+
dimensions: nonNegativeIntegerSchema.optional(),
|
|
48991
|
+
encoding_format: _enum(["float", "base64"]).optional(),
|
|
48992
|
+
user: string().min(1).optional()
|
|
48471
48993
|
}).loose();
|
|
48472
48994
|
function parseEmbeddingRequest(payload) {
|
|
48473
48995
|
return parsePayload(embeddingRequestSchema, "openai.embeddings", payload);
|
|
@@ -48725,7 +49247,7 @@ const responsesFunctionToolSchema = object({
|
|
|
48725
49247
|
type: literal("function"),
|
|
48726
49248
|
name: string().min(1),
|
|
48727
49249
|
parameters: jsonObjectSchema.nullable().optional(),
|
|
48728
|
-
strict: boolean().
|
|
49250
|
+
strict: boolean().optional(),
|
|
48729
49251
|
description: string().nullable().optional()
|
|
48730
49252
|
}).loose();
|
|
48731
49253
|
const responsesUnknownToolSchema = object({ type: string().min(1) }).catchall(unknown()).superRefine((tool, ctx) => {
|
|
@@ -48739,9 +49261,33 @@ const responsesToolChoiceSchema = union([
|
|
|
48739
49261
|
literal("none"),
|
|
48740
49262
|
literal("auto"),
|
|
48741
49263
|
literal("required"),
|
|
49264
|
+
object({
|
|
49265
|
+
type: literal("allowed_tools"),
|
|
49266
|
+
mode: _enum(["auto", "required"]),
|
|
49267
|
+
tools: array(jsonObjectSchema)
|
|
49268
|
+
}).loose(),
|
|
49269
|
+
object({ type: _enum([
|
|
49270
|
+
"file_search",
|
|
49271
|
+
"web_search_preview",
|
|
49272
|
+
"web_search_preview_2025_03_11",
|
|
49273
|
+
"computer_use_preview",
|
|
49274
|
+
"code_interpreter",
|
|
49275
|
+
"image_generation",
|
|
49276
|
+
"apply_patch",
|
|
49277
|
+
"shell"
|
|
49278
|
+
]) }).loose(),
|
|
48742
49279
|
object({
|
|
48743
49280
|
type: literal("function"),
|
|
48744
49281
|
name: string().min(1)
|
|
49282
|
+
}).loose(),
|
|
49283
|
+
object({
|
|
49284
|
+
type: literal("mcp"),
|
|
49285
|
+
server_label: string().min(1),
|
|
49286
|
+
name: string().min(1).optional()
|
|
49287
|
+
}).loose(),
|
|
49288
|
+
object({
|
|
49289
|
+
type: literal("custom"),
|
|
49290
|
+
name: string().min(1)
|
|
48745
49291
|
}).loose()
|
|
48746
49292
|
]);
|
|
48747
49293
|
const responsesReasoningConfigSchema = object({
|
|
@@ -48753,6 +49299,11 @@ const responsesReasoningConfigSchema = object({
|
|
|
48753
49299
|
"high",
|
|
48754
49300
|
"xhigh"
|
|
48755
49301
|
]).nullable().optional(),
|
|
49302
|
+
generate_summary: _enum([
|
|
49303
|
+
"auto",
|
|
49304
|
+
"concise",
|
|
49305
|
+
"detailed"
|
|
49306
|
+
]).nullable().optional(),
|
|
48756
49307
|
summary: _enum([
|
|
48757
49308
|
"auto",
|
|
48758
49309
|
"concise",
|
|
@@ -48766,7 +49317,7 @@ const responsesTextFormatJsonSchemaSchema = object({
|
|
|
48766
49317
|
name: string().min(1),
|
|
48767
49318
|
schema: jsonObjectSchema,
|
|
48768
49319
|
description: string().nullable().optional(),
|
|
48769
|
-
strict: boolean().
|
|
49320
|
+
strict: boolean().optional()
|
|
48770
49321
|
}).loose();
|
|
48771
49322
|
const responsesTextConfigSchema = object({
|
|
48772
49323
|
format: union([
|
|
@@ -48784,9 +49335,10 @@ const responsesContextManagementSchema = object({
|
|
|
48784
49335
|
type: literal("compaction"),
|
|
48785
49336
|
compact_threshold: nonNegativeIntegerSchema
|
|
48786
49337
|
}).loose();
|
|
48787
|
-
const responsesConversationSchema = union([string().min(1), object({ id: string().
|
|
49338
|
+
const responsesConversationSchema = union([string().min(1), object({ id: string().min(1) }).loose()]);
|
|
48788
49339
|
function createResponsesPayloadSchema(options) {
|
|
48789
49340
|
return object({
|
|
49341
|
+
background: boolean().nullable().optional(),
|
|
48790
49342
|
model: options.requireModel ? string().min(1) : string().min(1).nullable().optional(),
|
|
48791
49343
|
instructions: string().nullable().optional(),
|
|
48792
49344
|
input: union([
|
|
@@ -48804,19 +49356,36 @@ function createResponsesPayloadSchema(options) {
|
|
|
48804
49356
|
max_tool_calls: nonNegativeIntegerSchema.nullable().optional(),
|
|
48805
49357
|
metadata: record(string(), string()).nullable().optional(),
|
|
48806
49358
|
stream: boolean().nullable().optional(),
|
|
49359
|
+
stream_options: object({ include_obfuscation: boolean().nullable().optional() }).loose().nullable().optional(),
|
|
48807
49360
|
safety_identifier: string().nullable().optional(),
|
|
48808
49361
|
prompt_cache_key: string().nullable().optional(),
|
|
49362
|
+
prompt_cache_retention: _enum(["in-memory", "24h"]).nullable().optional(),
|
|
48809
49363
|
truncation: _enum(["auto", "disabled"]).nullable().optional(),
|
|
48810
49364
|
parallel_tool_calls: boolean().nullable().optional(),
|
|
48811
49365
|
store: boolean().nullable().optional(),
|
|
48812
49366
|
user: string().nullable().optional(),
|
|
48813
|
-
prompt:
|
|
49367
|
+
prompt: object({
|
|
49368
|
+
id: string().min(1),
|
|
49369
|
+
variables: record(string(), unknown()).optional(),
|
|
49370
|
+
version: string().min(1).optional()
|
|
49371
|
+
}).loose().nullable().optional(),
|
|
48814
49372
|
text: responsesTextConfigSchema.nullable().optional(),
|
|
48815
49373
|
reasoning: responsesReasoningConfigSchema.nullable().optional(),
|
|
48816
49374
|
context_management: array(responsesContextManagementSchema).nullable().optional(),
|
|
48817
49375
|
include: array(string().min(1)).nullable().optional(),
|
|
48818
|
-
service_tier:
|
|
49376
|
+
service_tier: _enum([
|
|
49377
|
+
"auto",
|
|
49378
|
+
"default",
|
|
49379
|
+
"flex",
|
|
49380
|
+
"scale",
|
|
49381
|
+
"priority"
|
|
49382
|
+
]).nullable().optional()
|
|
48819
49383
|
}).loose().superRefine((payload, ctx) => {
|
|
49384
|
+
if (payload.previous_response_id && payload.conversation) ctx.addIssue({
|
|
49385
|
+
code: "custom",
|
|
49386
|
+
message: "previous_response_id cannot be used together with conversation",
|
|
49387
|
+
path: ["previous_response_id"]
|
|
49388
|
+
});
|
|
48820
49389
|
const toolChoice = payload.tool_choice;
|
|
48821
49390
|
if (toolChoice && typeof toolChoice === "object" && "name" in toolChoice && typeof toolChoice.name === "string" && Array.isArray(payload.tools)) {
|
|
48822
49391
|
if (!payload.tools.filter((tool) => {
|
|
@@ -48871,6 +49440,7 @@ function createChatCompletionsStrategy(transport, adapter, plan, signal) {
|
|
|
48871
49440
|
async function handleCompletionCore({ body, signal, headers }) {
|
|
48872
49441
|
const adapter = new OpenAIChatAdapter();
|
|
48873
49442
|
let payload = parseOpenAIChatPayload(body);
|
|
49443
|
+
const requestContext = normalizeChatRequestContext(payload, headers);
|
|
48874
49444
|
consola.debug("Request payload:", JSON.stringify(payload).slice(-400));
|
|
48875
49445
|
const rewrite = applyModelRewrite(payload);
|
|
48876
49446
|
const originalModel = rewrite.originalModel;
|
|
@@ -48891,7 +49461,7 @@ async function handleCompletionCore({ body, signal, headers }) {
|
|
|
48891
49461
|
consola.debug("Set max_tokens to:", JSON.stringify(payload.max_tokens));
|
|
48892
49462
|
}
|
|
48893
49463
|
const upstreamSignal = createUpstreamSignalFromConfig(signal);
|
|
48894
|
-
const plan = adapter.toCapiPlan(payload, { requestContext
|
|
49464
|
+
const plan = adapter.toCapiPlan(payload, { requestContext });
|
|
48895
49465
|
const modelMapping = {
|
|
48896
49466
|
originalModel,
|
|
48897
49467
|
rewrittenModel: rewrite.model,
|
|
@@ -48923,12 +49493,18 @@ function createCompletionRoutes() {
|
|
|
48923
49493
|
|
|
48924
49494
|
//#endregion
|
|
48925
49495
|
//#region src/routes/embeddings/handler.ts
|
|
49496
|
+
function normalizeEmbeddingRequest(payload) {
|
|
49497
|
+
return {
|
|
49498
|
+
...payload,
|
|
49499
|
+
input: typeof payload.input === "string" ? [payload.input] : payload.input
|
|
49500
|
+
};
|
|
49501
|
+
}
|
|
48926
49502
|
/**
|
|
48927
49503
|
* Core handler for creating embeddings.
|
|
48928
49504
|
*/
|
|
48929
49505
|
async function handleEmbeddingsCore(body) {
|
|
48930
49506
|
const payload = parseEmbeddingRequest(body);
|
|
48931
|
-
return await createCopilotClient().createEmbeddings(payload);
|
|
49507
|
+
return await createCopilotClient().createEmbeddings(normalizeEmbeddingRequest(payload));
|
|
48932
49508
|
}
|
|
48933
49509
|
|
|
48934
49510
|
//#endregion
|
|
@@ -48956,16 +49532,23 @@ function createAnthropicAdapter() {
|
|
|
48956
49532
|
|
|
48957
49533
|
//#endregion
|
|
48958
49534
|
//#region src/routes/messages/count-tokens-handler.ts
|
|
48959
|
-
const
|
|
48960
|
-
|
|
48961
|
-
|
|
48962
|
-
|
|
49535
|
+
const TOOL_OVERHEAD_TOKENS = {
|
|
49536
|
+
claude: 346,
|
|
49537
|
+
grok: 480,
|
|
49538
|
+
gpt: 346
|
|
49539
|
+
};
|
|
49540
|
+
const ESTIMATION_FACTOR = {
|
|
49541
|
+
claude: 1.15,
|
|
49542
|
+
grok: 1.03,
|
|
49543
|
+
gpt: 1.1
|
|
49544
|
+
};
|
|
48963
49545
|
/**
|
|
48964
49546
|
* Core handler for counting tokens.
|
|
48965
49547
|
*/
|
|
48966
49548
|
async function handleCountTokensCore({ body, headers }) {
|
|
48967
49549
|
const anthropicBeta = headers.get("anthropic-beta") ?? void 0;
|
|
48968
49550
|
const anthropicPayload = parseAnthropicCountTokensPayload(body);
|
|
49551
|
+
normalizeAnthropicRequestContext(anthropicPayload, headers);
|
|
48969
49552
|
const adapter = createAnthropicAdapter();
|
|
48970
49553
|
let openAIPayload;
|
|
48971
49554
|
try {
|
|
@@ -48984,13 +49567,13 @@ async function handleCountTokensCore({ body, headers }) {
|
|
|
48984
49567
|
let mcpToolExist = false;
|
|
48985
49568
|
if (anthropicBeta?.startsWith("claude-code")) mcpToolExist = anthropicPayload.tools.some((tool) => tool.name.startsWith("mcp__"));
|
|
48986
49569
|
if (!mcpToolExist) {
|
|
48987
|
-
|
|
48988
|
-
|
|
49570
|
+
const overhead = TOOL_OVERHEAD_TOKENS[inferModelFamily(anthropicPayload.model)];
|
|
49571
|
+
if (overhead) tokenCount.input = tokenCount.input + overhead;
|
|
48989
49572
|
}
|
|
48990
49573
|
}
|
|
48991
49574
|
let finalTokenCount = tokenCount.input + tokenCount.output;
|
|
48992
|
-
|
|
48993
|
-
|
|
49575
|
+
const factor = ESTIMATION_FACTOR[inferModelFamily(anthropicPayload.model)];
|
|
49576
|
+
if (factor) finalTokenCount = Math.round(finalTokenCount * factor);
|
|
48994
49577
|
consola.info("Token count:", finalTokenCount);
|
|
48995
49578
|
return { input_tokens: finalTokenCount };
|
|
48996
49579
|
}
|
|
@@ -49056,6 +49639,49 @@ function containsVisionContent$1(content) {
|
|
|
49056
49639
|
return content.some((block) => block.type === "image");
|
|
49057
49640
|
}
|
|
49058
49641
|
|
|
49642
|
+
//#endregion
|
|
49643
|
+
//#region src/lib/function-schema.ts
|
|
49644
|
+
function isRecord$2(value) {
|
|
49645
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
49646
|
+
}
|
|
49647
|
+
const COPILOT_UNSUPPORTED_SCHEMA_ANNOTATIONS = new Set([
|
|
49648
|
+
"$schema",
|
|
49649
|
+
"$id",
|
|
49650
|
+
"id",
|
|
49651
|
+
"title",
|
|
49652
|
+
"format",
|
|
49653
|
+
"default",
|
|
49654
|
+
"example",
|
|
49655
|
+
"examples",
|
|
49656
|
+
"deprecated",
|
|
49657
|
+
"readOnly",
|
|
49658
|
+
"writeOnly",
|
|
49659
|
+
"contentEncoding",
|
|
49660
|
+
"contentMediaType"
|
|
49661
|
+
]);
|
|
49662
|
+
function normalizeSchemaNode(node) {
|
|
49663
|
+
if (Array.isArray(node)) return node.map(normalizeSchemaNode);
|
|
49664
|
+
if (!isRecord$2(node)) return node;
|
|
49665
|
+
const normalized = {};
|
|
49666
|
+
for (const [key, value] of Object.entries(node)) {
|
|
49667
|
+
if (COPILOT_UNSUPPORTED_SCHEMA_ANNOTATIONS.has(key)) continue;
|
|
49668
|
+
if (key === "properties" && isRecord$2(value)) {
|
|
49669
|
+
normalized[key] = Object.fromEntries(Object.entries(value).map(([propertyName, propertySchema]) => [propertyName, normalizeSchemaNode(propertySchema)]));
|
|
49670
|
+
continue;
|
|
49671
|
+
}
|
|
49672
|
+
normalized[key] = normalizeSchemaNode(value);
|
|
49673
|
+
}
|
|
49674
|
+
if (node.type === "object" || isRecord$2(normalized.properties)) {
|
|
49675
|
+
normalized.required = isRecord$2(normalized.properties) ? Object.keys(normalized.properties) : [];
|
|
49676
|
+
normalized.additionalProperties = false;
|
|
49677
|
+
}
|
|
49678
|
+
return normalized;
|
|
49679
|
+
}
|
|
49680
|
+
function normalizeFunctionParametersSchemaForCopilot(schema) {
|
|
49681
|
+
if (!schema) return schema;
|
|
49682
|
+
return normalizeSchemaNode(schema);
|
|
49683
|
+
}
|
|
49684
|
+
|
|
49059
49685
|
//#endregion
|
|
49060
49686
|
//#region src/translator/responses/signature-codec.ts
|
|
49061
49687
|
const COMPACTION_PREFIX = "cm1#";
|
|
@@ -49188,12 +49814,15 @@ function translateAssistantMessage(message) {
|
|
|
49188
49814
|
continue;
|
|
49189
49815
|
}
|
|
49190
49816
|
if (SignatureCodec.isReasoningSignature(block.signature)) {
|
|
49191
|
-
|
|
49192
|
-
|
|
49193
|
-
|
|
49194
|
-
|
|
49195
|
-
|
|
49196
|
-
|
|
49817
|
+
const { id } = SignatureCodec.decodeReasoning(block.signature);
|
|
49818
|
+
if (id) {
|
|
49819
|
+
flushPendingContent(pendingContent, items, {
|
|
49820
|
+
role: "assistant",
|
|
49821
|
+
phase: assistantPhase
|
|
49822
|
+
});
|
|
49823
|
+
items.push(createReasoningContent(block));
|
|
49824
|
+
continue;
|
|
49825
|
+
}
|
|
49197
49826
|
}
|
|
49198
49827
|
}
|
|
49199
49828
|
const converted = translateAssistantContentBlock(block);
|
|
@@ -49313,7 +49942,7 @@ function convertAnthropicTools(tools) {
|
|
|
49313
49942
|
return tools.map((tool) => ({
|
|
49314
49943
|
type: "function",
|
|
49315
49944
|
name: tool.name,
|
|
49316
|
-
parameters: tool.input_schema,
|
|
49945
|
+
parameters: normalizeFunctionParametersSchemaForCopilot(tool.input_schema),
|
|
49317
49946
|
strict: false,
|
|
49318
49947
|
...tool.description ? { description: tool.description } : {}
|
|
49319
49948
|
}));
|
|
@@ -49426,6 +50055,7 @@ function applyContextManagement(payload, maxPromptTokens) {
|
|
|
49426
50055
|
payload.context_management = createCompactionContextManagement(resolveResponsesCompactThreshold(maxPromptTokens));
|
|
49427
50056
|
}
|
|
49428
50057
|
function compactInputByLatestCompaction(payload) {
|
|
50058
|
+
if (!shouldAutoCompactResponsesInput()) return;
|
|
49429
50059
|
if (!Array.isArray(payload.input) || payload.input.length === 0) return;
|
|
49430
50060
|
const latestCompactionMessageIndex = getLatestCompactionMessageIndex(payload.input);
|
|
49431
50061
|
if (latestCompactionMessageIndex === void 0) return;
|
|
@@ -49661,14 +50291,14 @@ function mapResponsesUsage(response) {
|
|
|
49661
50291
|
...cachedTokens !== void 0 ? { cache_read_input_tokens: cachedTokens } : {}
|
|
49662
50292
|
};
|
|
49663
50293
|
}
|
|
49664
|
-
function isRecord(value) {
|
|
50294
|
+
function isRecord$1(value) {
|
|
49665
50295
|
return typeof value === "object" && value !== null;
|
|
49666
50296
|
}
|
|
49667
50297
|
function isResponseOutputText(block) {
|
|
49668
|
-
return isRecord(block) && block.type === "output_text";
|
|
50298
|
+
return isRecord$1(block) && block.type === "output_text";
|
|
49669
50299
|
}
|
|
49670
50300
|
function isResponseOutputRefusal(block) {
|
|
49671
|
-
return isRecord(block) && block.type === "refusal";
|
|
50301
|
+
return isRecord$1(block) && block.type === "refusal";
|
|
49672
50302
|
}
|
|
49673
50303
|
|
|
49674
50304
|
//#endregion
|
|
@@ -49831,6 +50461,7 @@ var ResponsesStreamTranslator = class {
|
|
|
49831
50461
|
this.closeScalarBlock(`thinking:${rawEvent.output_index}`, events);
|
|
49832
50462
|
}
|
|
49833
50463
|
if (rawEvent.item.type === "function_call") {
|
|
50464
|
+
if (this.state.functionCallStateByOutputIndex.get(rawEvent.output_index)?.closed) return events;
|
|
49834
50465
|
const blockIndex = this.openFunctionCallBlock({
|
|
49835
50466
|
outputIndex: rawEvent.output_index,
|
|
49836
50467
|
toolCallId: rawEvent.item.call_id,
|
|
@@ -50272,6 +50903,7 @@ function processAnthropicBetaHeader(rawHeader, model) {
|
|
|
50272
50903
|
*/
|
|
50273
50904
|
async function handleMessagesCore({ body, signal, headers }) {
|
|
50274
50905
|
const anthropicPayload = parseAnthropicMessagesPayload(body);
|
|
50906
|
+
const requestContext = normalizeAnthropicRequestContext(anthropicPayload, headers);
|
|
50275
50907
|
if (consola.level >= 4) consola.debug("Anthropic request payload:", JSON.stringify(anthropicPayload));
|
|
50276
50908
|
const rewrite = applyModelRewrite(anthropicPayload);
|
|
50277
50909
|
const betaResult = processAnthropicBetaHeader(headers.get("anthropic-beta"), anthropicPayload.model);
|
|
@@ -50298,7 +50930,7 @@ async function handleMessagesCore({ body, signal, headers }) {
|
|
|
50298
50930
|
selectedModel,
|
|
50299
50931
|
upstreamSignal,
|
|
50300
50932
|
headers,
|
|
50301
|
-
requestContext
|
|
50933
|
+
requestContext,
|
|
50302
50934
|
modelMapping
|
|
50303
50935
|
};
|
|
50304
50936
|
let strategyResult;
|
|
@@ -50380,8 +51012,246 @@ function createModelRoutes() {
|
|
|
50380
51012
|
});
|
|
50381
51013
|
}
|
|
50382
51014
|
|
|
51015
|
+
//#endregion
|
|
51016
|
+
//#region src/routes/responses/emulator.ts
|
|
51017
|
+
function cloneValue(value) {
|
|
51018
|
+
if (typeof globalThis.structuredClone === "function") return globalThis.structuredClone(value);
|
|
51019
|
+
return JSON.parse(JSON.stringify(value));
|
|
51020
|
+
}
|
|
51021
|
+
function rejectUnsupportedBackground(payload) {
|
|
51022
|
+
if (payload.background) throwInvalidRequestError("background mode is not supported by the responses official emulator.", "background", "unsupported_background_mode");
|
|
51023
|
+
}
|
|
51024
|
+
function prepareEmulatorRequest(payload) {
|
|
51025
|
+
rejectUnsupportedBackground(payload);
|
|
51026
|
+
const normalizedCurrentInput = normalizeResponsesInput(payload.input);
|
|
51027
|
+
const { continuationSourceResponseId, conversation: resolvedConversation, previousResponse } = resolveContinuation(payload);
|
|
51028
|
+
const conversation = resolvedConversation ?? createConversationRef();
|
|
51029
|
+
const effectiveInputItems = [...continuationSourceResponseId ? buildContinuationHistory(continuationSourceResponseId) : [], ...normalizedCurrentInput];
|
|
51030
|
+
const shouldStore = payload.store ?? true;
|
|
51031
|
+
return {
|
|
51032
|
+
upstreamPayload: {
|
|
51033
|
+
...payload,
|
|
51034
|
+
background: void 0,
|
|
51035
|
+
conversation: void 0,
|
|
51036
|
+
previous_response_id: void 0,
|
|
51037
|
+
store: void 0,
|
|
51038
|
+
input: effectiveInputItems
|
|
51039
|
+
},
|
|
51040
|
+
effectiveInputItems,
|
|
51041
|
+
previousResponseId: previousResponse?.id,
|
|
51042
|
+
conversation,
|
|
51043
|
+
shouldStore
|
|
51044
|
+
};
|
|
51045
|
+
}
|
|
51046
|
+
function decorateStoredResponse(upstreamResponse, requestPayload, prepared) {
|
|
51047
|
+
return {
|
|
51048
|
+
...cloneValue(upstreamResponse),
|
|
51049
|
+
previous_response_id: prepared.previousResponseId ?? null,
|
|
51050
|
+
conversation: prepared.conversation,
|
|
51051
|
+
truncation: requestPayload.truncation ?? null,
|
|
51052
|
+
store: prepared.shouldStore,
|
|
51053
|
+
user: normalizeNullableString(requestPayload.user),
|
|
51054
|
+
service_tier: normalizeServiceTier(requestPayload.service_tier)
|
|
51055
|
+
};
|
|
51056
|
+
}
|
|
51057
|
+
function persistEmulatorResponse(response, effectiveInputItems) {
|
|
51058
|
+
state.responsesEmulator.setResponse(response);
|
|
51059
|
+
if (response.conversation) {
|
|
51060
|
+
state.responsesEmulator.setConversation(response.conversation);
|
|
51061
|
+
state.responsesEmulator.setConversationHead(getConversationId(response.conversation), response.id);
|
|
51062
|
+
}
|
|
51063
|
+
state.responsesEmulator.setInputItems(response.id, effectiveInputItems);
|
|
51064
|
+
}
|
|
51065
|
+
function getStoredResponseOrThrow(responseId) {
|
|
51066
|
+
const response = state.responsesEmulator.getResponse(responseId);
|
|
51067
|
+
if (!response) throw new HTTPError(404, { error: {
|
|
51068
|
+
message: `No response found with id '${responseId}'.`,
|
|
51069
|
+
type: "invalid_request_error"
|
|
51070
|
+
} });
|
|
51071
|
+
return response;
|
|
51072
|
+
}
|
|
51073
|
+
function listStoredInputItemsOrThrow(responseId, params) {
|
|
51074
|
+
const items = state.responsesEmulator.getInputItems(responseId);
|
|
51075
|
+
if (!items) throw new HTTPError(404, { error: {
|
|
51076
|
+
message: `No response input items found for id '${responseId}'.`,
|
|
51077
|
+
type: "invalid_request_error"
|
|
51078
|
+
} });
|
|
51079
|
+
let orderedItems = cloneValue(items);
|
|
51080
|
+
if (params?.order === "desc") orderedItems.reverse();
|
|
51081
|
+
if (params?.after) {
|
|
51082
|
+
const afterIndex = orderedItems.findIndex((item) => getInputItemId(item) === params.after);
|
|
51083
|
+
if (afterIndex >= 0) orderedItems = orderedItems.slice(afterIndex + 1);
|
|
51084
|
+
}
|
|
51085
|
+
const limitedItems = orderedItems.slice(0, params?.limit ?? orderedItems.length);
|
|
51086
|
+
return {
|
|
51087
|
+
object: "list",
|
|
51088
|
+
data: limitedItems,
|
|
51089
|
+
first_id: getInputItemId(limitedItems[0]) ?? null,
|
|
51090
|
+
last_id: getInputItemId(limitedItems.at(-1)) ?? null,
|
|
51091
|
+
has_more: limitedItems.length < orderedItems.length
|
|
51092
|
+
};
|
|
51093
|
+
}
|
|
51094
|
+
function deleteStoredResponseOrThrow(responseId) {
|
|
51095
|
+
getStoredResponseOrThrow(responseId);
|
|
51096
|
+
return state.responsesEmulator.deleteResponse(responseId);
|
|
51097
|
+
}
|
|
51098
|
+
async function estimateEmulatorInputTokens(payload, selectedModel) {
|
|
51099
|
+
return {
|
|
51100
|
+
object: "response.input_tokens",
|
|
51101
|
+
input_tokens: await estimateResponsesInputTokens(resolveEffectiveInputForInputTokens(payload), selectedModel)
|
|
51102
|
+
};
|
|
51103
|
+
}
|
|
51104
|
+
function resolveEffectiveInputForInputTokens(payload) {
|
|
51105
|
+
const normalizedInput = normalizeResponsesInput(payload.input);
|
|
51106
|
+
const background = payload.background === null || typeof payload.background === "boolean" ? payload.background : void 0;
|
|
51107
|
+
const conversation = isConversationReference(payload.conversation) ? payload.conversation : void 0;
|
|
51108
|
+
const previousResponseId = typeof payload.previous_response_id === "string" ? payload.previous_response_id : void 0;
|
|
51109
|
+
rejectUnsupportedBackground({ background });
|
|
51110
|
+
const { continuationSourceResponseId } = resolveContinuation({
|
|
51111
|
+
conversation,
|
|
51112
|
+
previous_response_id: previousResponseId
|
|
51113
|
+
});
|
|
51114
|
+
if (continuationSourceResponseId) return [...buildContinuationHistory(continuationSourceResponseId), ...normalizedInput];
|
|
51115
|
+
return normalizedInput;
|
|
51116
|
+
}
|
|
51117
|
+
function resolveContinuation(payload) {
|
|
51118
|
+
const previousResponse = resolvePreviousResponse(payload.previous_response_id);
|
|
51119
|
+
const conversation = resolveConversation(payload.conversation, previousResponse);
|
|
51120
|
+
return {
|
|
51121
|
+
previousResponse,
|
|
51122
|
+
conversation,
|
|
51123
|
+
continuationSourceResponseId: resolveContinuationSourceResponseId(previousResponse, conversation)
|
|
51124
|
+
};
|
|
51125
|
+
}
|
|
51126
|
+
function resolvePreviousResponse(previousResponseId) {
|
|
51127
|
+
if (typeof previousResponseId !== "string" || previousResponseId.length === 0) return;
|
|
51128
|
+
const previousResponse = state.responsesEmulator.getResponse(previousResponseId);
|
|
51129
|
+
if (!previousResponse) throwInvalidRequestError("The selected previous_response_id could not be resolved.", "previous_response_id");
|
|
51130
|
+
return previousResponse;
|
|
51131
|
+
}
|
|
51132
|
+
function resolveConversation(conversation, previousResponse) {
|
|
51133
|
+
if (isConversationReference(conversation)) {
|
|
51134
|
+
const conversationId = getConversationId(conversation);
|
|
51135
|
+
const existingConversation = state.responsesEmulator.getConversation(conversationId);
|
|
51136
|
+
if (!existingConversation) throwInvalidRequestError("The selected conversation could not be resolved.", "conversation");
|
|
51137
|
+
if (previousResponse?.conversation && getConversationId(previousResponse.conversation) !== conversationId) throwInvalidRequestError("The selected previous_response_id does not belong to the selected conversation.", "previous_response_id");
|
|
51138
|
+
return existingConversation;
|
|
51139
|
+
}
|
|
51140
|
+
return previousResponse?.conversation ?? void 0;
|
|
51141
|
+
}
|
|
51142
|
+
function resolveContinuationSourceResponseId(previousResponse, conversation) {
|
|
51143
|
+
if (previousResponse) return previousResponse.id;
|
|
51144
|
+
if (!conversation) return;
|
|
51145
|
+
const head = state.responsesEmulator.getConversationHead(getConversationId(conversation));
|
|
51146
|
+
if (!head) throwInvalidRequestError("The selected conversation could not be resolved.", "conversation");
|
|
51147
|
+
return head;
|
|
51148
|
+
}
|
|
51149
|
+
function buildContinuationHistory(responseId) {
|
|
51150
|
+
const previousResponse = getStoredResponseOrThrow(responseId);
|
|
51151
|
+
const previousInput = state.responsesEmulator.getInputItems(responseId);
|
|
51152
|
+
if (!previousInput) throwInvalidRequestError("The selected previous_response_id is missing stored input items.", "previous_response_id");
|
|
51153
|
+
return [...cloneValue(previousInput), ...convertOutputItemsToInputItems(previousResponse.output)];
|
|
51154
|
+
}
|
|
51155
|
+
function normalizeResponsesInput(input) {
|
|
51156
|
+
if (!input) return [];
|
|
51157
|
+
if (typeof input === "string") return [{
|
|
51158
|
+
type: "message",
|
|
51159
|
+
role: "user",
|
|
51160
|
+
content: input
|
|
51161
|
+
}];
|
|
51162
|
+
if (Array.isArray(input)) return cloneValue(input);
|
|
51163
|
+
return [];
|
|
51164
|
+
}
|
|
51165
|
+
function convertOutputItemsToInputItems(output) {
|
|
51166
|
+
const items = [];
|
|
51167
|
+
for (const item of output) switch (item.type) {
|
|
51168
|
+
case "message":
|
|
51169
|
+
items.push(convertMessageOutputToInput(item));
|
|
51170
|
+
break;
|
|
51171
|
+
case "function_call":
|
|
51172
|
+
items.push(convertFunctionCallOutputToInput(item));
|
|
51173
|
+
break;
|
|
51174
|
+
case "reasoning": {
|
|
51175
|
+
const reasoningInput = convertReasoningOutputToInput(item);
|
|
51176
|
+
if (reasoningInput) items.push(reasoningInput);
|
|
51177
|
+
break;
|
|
51178
|
+
}
|
|
51179
|
+
case "compaction":
|
|
51180
|
+
items.push(convertCompactionOutputToInput(item));
|
|
51181
|
+
break;
|
|
51182
|
+
}
|
|
51183
|
+
return items;
|
|
51184
|
+
}
|
|
51185
|
+
function convertMessageOutputToInput(item) {
|
|
51186
|
+
return {
|
|
51187
|
+
type: "message",
|
|
51188
|
+
role: item.role,
|
|
51189
|
+
status: item.status,
|
|
51190
|
+
content: item.content?.map((content) => {
|
|
51191
|
+
if (content.type === "output_text" && typeof content.text === "string") return {
|
|
51192
|
+
type: "output_text",
|
|
51193
|
+
text: content.text
|
|
51194
|
+
};
|
|
51195
|
+
return cloneValue(content);
|
|
51196
|
+
}) ?? []
|
|
51197
|
+
};
|
|
51198
|
+
}
|
|
51199
|
+
function convertFunctionCallOutputToInput(item) {
|
|
51200
|
+
return {
|
|
51201
|
+
type: "function_call",
|
|
51202
|
+
call_id: item.call_id,
|
|
51203
|
+
name: item.name,
|
|
51204
|
+
arguments: item.arguments,
|
|
51205
|
+
status: item.status
|
|
51206
|
+
};
|
|
51207
|
+
}
|
|
51208
|
+
function convertReasoningOutputToInput(item) {
|
|
51209
|
+
if (!item.encrypted_content) return;
|
|
51210
|
+
return {
|
|
51211
|
+
id: item.id,
|
|
51212
|
+
type: "reasoning",
|
|
51213
|
+
summary: (item.summary ?? []).filter((summary) => typeof summary.text === "string").map((summary) => ({
|
|
51214
|
+
type: "summary_text",
|
|
51215
|
+
text: summary.text
|
|
51216
|
+
})),
|
|
51217
|
+
encrypted_content: item.encrypted_content
|
|
51218
|
+
};
|
|
51219
|
+
}
|
|
51220
|
+
function convertCompactionOutputToInput(item) {
|
|
51221
|
+
return {
|
|
51222
|
+
id: item.id,
|
|
51223
|
+
type: "compaction",
|
|
51224
|
+
encrypted_content: item.encrypted_content
|
|
51225
|
+
};
|
|
51226
|
+
}
|
|
51227
|
+
function normalizeNullableString(value) {
|
|
51228
|
+
return typeof value === "string" ? value : null;
|
|
51229
|
+
}
|
|
51230
|
+
function normalizeServiceTier(value) {
|
|
51231
|
+
if (value === "auto" || value === "default" || value === "flex" || value === "scale" || value === "priority") return value;
|
|
51232
|
+
return null;
|
|
51233
|
+
}
|
|
51234
|
+
function createConversationRef() {
|
|
51235
|
+
return { id: `conv_${randomUUID().replaceAll("-", "")}` };
|
|
51236
|
+
}
|
|
51237
|
+
function isConversationReference(value) {
|
|
51238
|
+
if (typeof value === "string") return value.length > 0;
|
|
51239
|
+
return typeof value === "object" && value !== null && "id" in value && typeof value.id === "string" && value.id.length > 0;
|
|
51240
|
+
}
|
|
51241
|
+
function getConversationId(conversation) {
|
|
51242
|
+
return typeof conversation === "string" ? conversation : conversation.id;
|
|
51243
|
+
}
|
|
51244
|
+
function getInputItemId(item) {
|
|
51245
|
+
if (!item || typeof item !== "object") return;
|
|
51246
|
+
if ("id" in item && typeof item.id === "string") return item.id;
|
|
51247
|
+
if ("call_id" in item && typeof item.call_id === "string") return item.call_id;
|
|
51248
|
+
}
|
|
51249
|
+
|
|
50383
51250
|
//#endregion
|
|
50384
51251
|
//#region src/routes/responses/strategy.ts
|
|
51252
|
+
function isRecord(value) {
|
|
51253
|
+
return typeof value === "object" && value !== null;
|
|
51254
|
+
}
|
|
50385
51255
|
function createStreamIdTracker() {
|
|
50386
51256
|
return { itemIdsByOutputIndex: /* @__PURE__ */ new Map() };
|
|
50387
51257
|
}
|
|
@@ -50393,23 +51263,24 @@ function fixStreamIds(rawData, eventName, state) {
|
|
|
50393
51263
|
} catch {
|
|
50394
51264
|
return rawData;
|
|
50395
51265
|
}
|
|
50396
|
-
|
|
50397
|
-
|
|
50398
|
-
if (
|
|
51266
|
+
const response = isRecord(parsed.response) ? parsed.response : void 0;
|
|
51267
|
+
if (typeof response?.id === "string") {
|
|
51268
|
+
if (!state.responseId) state.responseId = response.id;
|
|
51269
|
+
else if (response.id !== state.responseId) response.id = state.responseId;
|
|
50399
51270
|
}
|
|
50400
51271
|
if (eventName === "response.output_item.added" || eventName === "response.output_item.done") {
|
|
50401
51272
|
const outputIndex = typeof parsed.output_index === "number" ? parsed.output_index : void 0;
|
|
50402
|
-
const item = parsed.item;
|
|
50403
|
-
if (outputIndex !== void 0 && typeof item?.id === "string")
|
|
51273
|
+
const item = isRecord(parsed.item) ? parsed.item : void 0;
|
|
51274
|
+
if (outputIndex !== void 0 && typeof item?.id === "string") {
|
|
51275
|
+
const stableId = state.itemIdsByOutputIndex.get(outputIndex);
|
|
51276
|
+
if (!stableId) state.itemIdsByOutputIndex.set(outputIndex, item.id);
|
|
51277
|
+
else if (item.id !== stableId) item.id = stableId;
|
|
51278
|
+
}
|
|
50404
51279
|
}
|
|
50405
|
-
if (
|
|
51280
|
+
if (typeof parsed.output_index === "number" && typeof parsed.item_id === "string") {
|
|
50406
51281
|
const stableId = state.itemIdsByOutputIndex.get(parsed.output_index);
|
|
50407
51282
|
if (stableId && parsed.item_id !== stableId) parsed.item_id = stableId;
|
|
50408
51283
|
}
|
|
50409
|
-
if (state.responseId && parsed.response && typeof parsed.response === "object") {
|
|
50410
|
-
const response = parsed.response;
|
|
50411
|
-
if (response.id !== state.responseId) response.id = state.responseId;
|
|
50412
|
-
}
|
|
50413
51284
|
return JSON.stringify(parsed);
|
|
50414
51285
|
}
|
|
50415
51286
|
function createResponsesPassthroughStrategy(copilotClient, payload, options) {
|
|
@@ -50425,10 +51296,34 @@ function createResponsesPassthroughStrategy(copilotClient, payload, options) {
|
|
|
50425
51296
|
return result;
|
|
50426
51297
|
},
|
|
50427
51298
|
translateStreamChunk(chunk) {
|
|
50428
|
-
|
|
51299
|
+
const fixedData = fixStreamIds(chunk.data ?? "", chunk.event, tracker);
|
|
51300
|
+
const mappedData = options.mapResponse ? mapChunkResponse(fixedData, options.mapResponse) : fixedData;
|
|
51301
|
+
const parsedResponse = tryExtractTerminalResponse(mappedData);
|
|
51302
|
+
if (parsedResponse) options.onTerminalResponse?.(parsedResponse);
|
|
51303
|
+
return passthroughSSEChunk(chunk, mappedData);
|
|
50429
51304
|
}
|
|
50430
51305
|
};
|
|
50431
51306
|
}
|
|
51307
|
+
function mapChunkResponse(rawData, mapResponse) {
|
|
51308
|
+
if (!rawData) return rawData;
|
|
51309
|
+
try {
|
|
51310
|
+
const parsed = JSON.parse(rawData);
|
|
51311
|
+
if (isRecord(parsed.response)) {
|
|
51312
|
+
parsed.response = mapResponse(parsed.response);
|
|
51313
|
+
return JSON.stringify(parsed);
|
|
51314
|
+
}
|
|
51315
|
+
} catch {}
|
|
51316
|
+
return rawData;
|
|
51317
|
+
}
|
|
51318
|
+
function tryExtractTerminalResponse(rawData) {
|
|
51319
|
+
if (!rawData) return;
|
|
51320
|
+
try {
|
|
51321
|
+
const parsed = JSON.parse(rawData);
|
|
51322
|
+
if (parsed.type !== "response.completed" && parsed.type !== "response.incomplete" && parsed.type !== "response.failed") return;
|
|
51323
|
+
const response = parsed.response;
|
|
51324
|
+
if (response && typeof response === "object") return response;
|
|
51325
|
+
} catch {}
|
|
51326
|
+
}
|
|
50432
51327
|
|
|
50433
51328
|
//#endregion
|
|
50434
51329
|
//#region src/routes/responses/handler.ts
|
|
@@ -50438,34 +51333,65 @@ const HTTP_URL_RE = /^https?:\/\//i;
|
|
|
50438
51333
|
*/
|
|
50439
51334
|
async function handleResponsesCore({ body, signal, headers }) {
|
|
50440
51335
|
const payload = parseResponsesPayload(body);
|
|
50441
|
-
const
|
|
50442
|
-
|
|
50443
|
-
|
|
50444
|
-
|
|
50445
|
-
|
|
51336
|
+
const requestContext = normalizeResponsesRequestContext(payload, headers);
|
|
51337
|
+
const emulatorPrepared = shouldUseResponsesOfficialEmulator() ? prepareEmulatorRequest(payload) : void 0;
|
|
51338
|
+
const rewrite = applyModelRewrite(emulatorPrepared?.upstreamPayload ?? payload);
|
|
51339
|
+
const effectivePayload = emulatorPrepared?.upstreamPayload ?? payload;
|
|
51340
|
+
applyResponsesToolTransforms(effectivePayload);
|
|
51341
|
+
applyResponsesInputPolicies(effectivePayload);
|
|
51342
|
+
compactInputByLatestCompaction(effectivePayload);
|
|
51343
|
+
const selectedModel = findModelById(effectivePayload.model);
|
|
50446
51344
|
if (!selectedModel) throwInvalidRequestError("The selected model could not be resolved.", "model");
|
|
50447
51345
|
if (!modelSupportsEndpoint(selectedModel, RESPONSES_ENDPOINT)) throwInvalidRequestError("The selected model does not support the responses endpoint.", "model");
|
|
50448
|
-
applyContextManagement(
|
|
50449
|
-
const { vision, initiator } = getResponsesRequestOptions(
|
|
51346
|
+
applyContextManagement(effectivePayload, selectedModel.capabilities.limits.max_prompt_tokens);
|
|
51347
|
+
const { vision, initiator } = getResponsesRequestOptions(effectivePayload);
|
|
50450
51348
|
const upstreamSignal = createUpstreamSignalFromConfig(signal);
|
|
51349
|
+
const copilotClient = createCopilotClient();
|
|
51350
|
+
const decorateResponse = emulatorPrepared ? (response) => decorateStoredResponse(response, payload, emulatorPrepared) : void 0;
|
|
51351
|
+
const result = await runStrategy(createResponsesPassthroughStrategy(copilotClient, effectivePayload, {
|
|
51352
|
+
vision,
|
|
51353
|
+
initiator: resolveInitiator(initiator, requestContext),
|
|
51354
|
+
requestContext,
|
|
51355
|
+
signal: upstreamSignal.signal,
|
|
51356
|
+
mapResponse: decorateResponse,
|
|
51357
|
+
onTerminalResponse: emulatorPrepared ? (terminalResponse) => {
|
|
51358
|
+
if (!emulatorPrepared?.shouldStore) return;
|
|
51359
|
+
persistEmulatorResponse(terminalResponse, emulatorPrepared.effectiveInputItems);
|
|
51360
|
+
} : void 0
|
|
51361
|
+
}), upstreamSignal);
|
|
51362
|
+
if (emulatorPrepared && result.kind === "json") {
|
|
51363
|
+
const emulatedResponse = decorateStoredResponse(result.data, payload, emulatorPrepared);
|
|
51364
|
+
if (emulatorPrepared.shouldStore) persistEmulatorResponse(emulatedResponse, emulatorPrepared.effectiveInputItems);
|
|
51365
|
+
result.data = emulatedResponse;
|
|
51366
|
+
}
|
|
50451
51367
|
return {
|
|
50452
|
-
result
|
|
50453
|
-
vision,
|
|
50454
|
-
initiator,
|
|
50455
|
-
requestContext: readCapiRequestContext(headers),
|
|
50456
|
-
signal: upstreamSignal.signal
|
|
50457
|
-
}), upstreamSignal),
|
|
51368
|
+
result,
|
|
50458
51369
|
modelMapping: {
|
|
50459
51370
|
originalModel: rewrite.originalModel,
|
|
50460
51371
|
rewrittenModel: rewrite.model,
|
|
50461
|
-
mappedModel:
|
|
51372
|
+
mappedModel: effectivePayload.model
|
|
50462
51373
|
}
|
|
50463
51374
|
};
|
|
50464
51375
|
}
|
|
50465
51376
|
function applyResponsesToolTransforms(payload) {
|
|
50466
51377
|
applyFunctionApplyPatch(payload);
|
|
51378
|
+
applyFunctionToolCompatibilityDefaults(payload);
|
|
50467
51379
|
rejectUnsupportedBuiltinTools(payload);
|
|
50468
51380
|
}
|
|
51381
|
+
function applyFunctionToolCompatibilityDefaults(payload) {
|
|
51382
|
+
if (!Array.isArray(payload.tools)) return;
|
|
51383
|
+
payload.tools = payload.tools.map((tool) => {
|
|
51384
|
+
if (!isResponseFunctionTool(tool)) return tool;
|
|
51385
|
+
return {
|
|
51386
|
+
...tool,
|
|
51387
|
+
parameters: normalizeFunctionParametersSchemaForCopilot(tool.parameters),
|
|
51388
|
+
strict: tool.strict ?? true
|
|
51389
|
+
};
|
|
51390
|
+
});
|
|
51391
|
+
}
|
|
51392
|
+
function isResponseFunctionTool(tool) {
|
|
51393
|
+
return tool.type === "function";
|
|
51394
|
+
}
|
|
50469
51395
|
function applyFunctionApplyPatch(payload) {
|
|
50470
51396
|
if (!shouldUseFunctionApplyPatch() || !Array.isArray(payload.tools)) return;
|
|
50471
51397
|
payload.tools = payload.tools.map((tool) => {
|
|
@@ -50487,6 +51413,7 @@ function applyFunctionApplyPatch(payload) {
|
|
|
50487
51413
|
});
|
|
50488
51414
|
}
|
|
50489
51415
|
function rejectUnsupportedBuiltinTools(payload) {
|
|
51416
|
+
if (payload.tool_choice && typeof payload.tool_choice === "object" && "type" in payload.tool_choice && (payload.tool_choice.type === "web_search_preview" || payload.tool_choice.type === "web_search_preview_2025_03_11")) throwInvalidRequestError("The selected Copilot endpoint does not support the Responses web_search tool.", "tool_choice", "unsupported_tool_web_search");
|
|
50490
51417
|
if (!Array.isArray(payload.tools)) return;
|
|
50491
51418
|
for (const tool of payload.tools) if (tool.type === "web_search") throwInvalidRequestError("The selected Copilot endpoint does not support the Responses web_search tool.", "tools", "unsupported_tool_web_search");
|
|
50492
51419
|
}
|
|
@@ -50510,6 +51437,7 @@ function containsRemoteImageUrl(value) {
|
|
|
50510
51437
|
//#region src/routes/responses/resource-handler.ts
|
|
50511
51438
|
async function handleRetrieveResponseCore({ params, url, headers, signal }) {
|
|
50512
51439
|
const responseId = requireResponseId(params.responseId);
|
|
51440
|
+
if (shouldUseResponsesOfficialEmulator()) return getStoredResponseOrThrow(responseId);
|
|
50513
51441
|
return await createCopilotClient().getResponse(responseId, {
|
|
50514
51442
|
params: getRetrieveParamsFromUrl(url),
|
|
50515
51443
|
requestContext: readCapiRequestContext(headers),
|
|
@@ -50518,6 +51446,7 @@ async function handleRetrieveResponseCore({ params, url, headers, signal }) {
|
|
|
50518
51446
|
}
|
|
50519
51447
|
async function handleListResponseInputItemsCore({ params, url, headers, signal }) {
|
|
50520
51448
|
const responseId = requireResponseId(params.responseId);
|
|
51449
|
+
if (shouldUseResponsesOfficialEmulator()) return listStoredInputItemsOrThrow(responseId, getInputItemsParamsFromUrl(url));
|
|
50521
51450
|
return await createCopilotClient().getResponseInputItems(responseId, getInputItemsParamsFromUrl(url), {
|
|
50522
51451
|
requestContext: readCapiRequestContext(headers),
|
|
50523
51452
|
signal
|
|
@@ -50525,13 +51454,22 @@ async function handleListResponseInputItemsCore({ params, url, headers, signal }
|
|
|
50525
51454
|
}
|
|
50526
51455
|
async function handleCreateResponseInputTokensCore({ body, headers, signal }) {
|
|
50527
51456
|
const payload = parseResponsesInputTokensPayload(body);
|
|
51457
|
+
const requestContext = normalizeResponsesRequestContext(payload, headers);
|
|
51458
|
+
if (shouldUseResponsesOfficialEmulator()) {
|
|
51459
|
+
const model = payload.model;
|
|
51460
|
+
if (!model) throwInvalidRequestError("The selected model could not be resolved.", "model");
|
|
51461
|
+
const selectedModel = findModelById(model);
|
|
51462
|
+
if (!selectedModel) throwInvalidRequestError("The selected model could not be resolved.", "model");
|
|
51463
|
+
return await estimateEmulatorInputTokens(payload, selectedModel);
|
|
51464
|
+
}
|
|
50528
51465
|
return await createCopilotClient().createResponseInputTokens(payload, {
|
|
50529
|
-
requestContext
|
|
51466
|
+
requestContext,
|
|
50530
51467
|
signal
|
|
50531
51468
|
});
|
|
50532
51469
|
}
|
|
50533
51470
|
async function handleDeleteResponseCore({ params, headers, signal }) {
|
|
50534
51471
|
const responseId = requireResponseId(params.responseId);
|
|
51472
|
+
if (shouldUseResponsesOfficialEmulator()) return deleteStoredResponseOrThrow(responseId);
|
|
50535
51473
|
return await createCopilotClient().deleteResponse(responseId, {
|
|
50536
51474
|
requestContext: readCapiRequestContext(headers),
|
|
50537
51475
|
signal
|