ghc-proxy 0.5.2 → 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/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
  }
@@ -6029,6 +6047,221 @@ async function getVSCodeVersion() {
6029
6047
  return remoteVersion ?? localVersion ?? FALLBACK;
6030
6048
  }
6031
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
+
6032
6265
  //#endregion
6033
6266
  //#region src/lib/state.ts
6034
6267
  const state = {
@@ -6040,7 +6273,8 @@ const state = {
6040
6273
  showToken: false
6041
6274
  },
6042
6275
  cache: {},
6043
- rateLimit: {}
6276
+ rateLimit: {},
6277
+ responsesEmulator: responsesEmulatorState
6044
6278
  };
6045
6279
  function getClientConfig() {
6046
6280
  return {
@@ -6232,7 +6466,7 @@ const checkUsage = defineCommand({
6232
6466
 
6233
6467
  //#endregion
6234
6468
  //#region src/lib/version.ts
6235
- const VERSION = "0.5.2";
6469
+ const VERSION = "0.5.3";
6236
6470
 
6237
6471
  //#endregion
6238
6472
  //#region src/debug.ts
@@ -46747,6 +46981,9 @@ function selectCapiProfile(model) {
46747
46981
 
46748
46982
  //#endregion
46749
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>";
46750
46987
  function readHeader(headers, name) {
46751
46988
  return headers.get(name) ?? void 0;
46752
46989
  }
@@ -46758,11 +46995,20 @@ function readCapiRequestContext(headers) {
46758
46995
  interactionType: readHeader(headers, "x-interaction-type"),
46759
46996
  agentTaskId: readHeader(headers, "x-agent-task-id"),
46760
46997
  parentAgentTaskId: readHeader(headers, "x-parent-agent-id"),
46761
- clientSessionId: readHeader(headers, "x-client-session-id"),
46998
+ clientSessionId: readHeader(headers, "x-client-session-id") ?? readHeader(headers, "x-session-id"),
46762
46999
  interactionId: readHeader(headers, "x-interaction-id"),
46763
47000
  clientMachineId: readHeader(headers, "x-client-machine-id")
46764
47001
  };
46765
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
+ }
46766
47012
  function buildCapiRequestContext(initiator, overrides = {}) {
46767
47013
  return {
46768
47014
  interactionType: overrides.interactionType ?? (initiator === "agent" ? "conversation-agent" : "conversation-user"),
@@ -46773,6 +47019,269 @@ function buildCapiRequestContext(initiator, overrides = {}) {
46773
47019
  clientMachineId: overrides.clientMachineId
46774
47020
  };
46775
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
+ }
46776
47285
 
46777
47286
  //#endregion
46778
47287
  //#region src/core/capi/plan-builder.ts
@@ -46951,7 +47460,7 @@ function stripTransportFields(payload) {
46951
47460
  function buildCapiExecutionPlan(request, options = {}) {
46952
47461
  const resolvedModel = options.resolveModel?.(request.model) ?? request.model;
46953
47462
  const profile = selectCapiProfile(resolvedModel);
46954
- const initiator = inferInitiator(request.turns);
47463
+ const initiator = resolveInitiator(inferInitiator(request.turns), options.requestContext);
46955
47464
  const payload = {
46956
47465
  model: resolvedModel,
46957
47466
  messages: serializeTurns(request.turns),
@@ -48269,6 +48778,9 @@ async function getTokenCount(payload, model) {
48269
48778
  output: outputTokens
48270
48779
  };
48271
48780
  }
48781
+ async function estimateResponsesInputTokens(inputItems, model) {
48782
+ return (await getEncoder(getTokenizerFromModel(model))).encode(JSON.stringify(inputItems)).length;
48783
+ }
48272
48784
  /**
48273
48785
  * Fast character-based token estimate for Anthropic payloads.
48274
48786
  * Uses ~3.5 chars/token ratio (conservative for Claude's tokenizer).
@@ -48735,7 +49247,7 @@ const responsesFunctionToolSchema = object({
48735
49247
  type: literal("function"),
48736
49248
  name: string().min(1),
48737
49249
  parameters: jsonObjectSchema.nullable().optional(),
48738
- strict: boolean().nullable().optional(),
49250
+ strict: boolean().optional(),
48739
49251
  description: string().nullable().optional()
48740
49252
  }).loose();
48741
49253
  const responsesUnknownToolSchema = object({ type: string().min(1) }).catchall(unknown()).superRefine((tool, ctx) => {
@@ -48749,9 +49261,33 @@ const responsesToolChoiceSchema = union([
48749
49261
  literal("none"),
48750
49262
  literal("auto"),
48751
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(),
48752
49279
  object({
48753
49280
  type: literal("function"),
48754
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)
48755
49291
  }).loose()
48756
49292
  ]);
48757
49293
  const responsesReasoningConfigSchema = object({
@@ -48763,6 +49299,11 @@ const responsesReasoningConfigSchema = object({
48763
49299
  "high",
48764
49300
  "xhigh"
48765
49301
  ]).nullable().optional(),
49302
+ generate_summary: _enum([
49303
+ "auto",
49304
+ "concise",
49305
+ "detailed"
49306
+ ]).nullable().optional(),
48766
49307
  summary: _enum([
48767
49308
  "auto",
48768
49309
  "concise",
@@ -48776,7 +49317,7 @@ const responsesTextFormatJsonSchemaSchema = object({
48776
49317
  name: string().min(1),
48777
49318
  schema: jsonObjectSchema,
48778
49319
  description: string().nullable().optional(),
48779
- strict: boolean().nullable().optional()
49320
+ strict: boolean().optional()
48780
49321
  }).loose();
48781
49322
  const responsesTextConfigSchema = object({
48782
49323
  format: union([
@@ -48794,9 +49335,10 @@ const responsesContextManagementSchema = object({
48794
49335
  type: literal("compaction"),
48795
49336
  compact_threshold: nonNegativeIntegerSchema
48796
49337
  }).loose();
48797
- const responsesConversationSchema = union([string().min(1), object({ id: string().nullable().optional() }).loose()]);
49338
+ const responsesConversationSchema = union([string().min(1), object({ id: string().min(1) }).loose()]);
48798
49339
  function createResponsesPayloadSchema(options) {
48799
49340
  return object({
49341
+ background: boolean().nullable().optional(),
48800
49342
  model: options.requireModel ? string().min(1) : string().min(1).nullable().optional(),
48801
49343
  instructions: string().nullable().optional(),
48802
49344
  input: union([
@@ -48814,19 +49356,36 @@ function createResponsesPayloadSchema(options) {
48814
49356
  max_tool_calls: nonNegativeIntegerSchema.nullable().optional(),
48815
49357
  metadata: record(string(), string()).nullable().optional(),
48816
49358
  stream: boolean().nullable().optional(),
49359
+ stream_options: object({ include_obfuscation: boolean().nullable().optional() }).loose().nullable().optional(),
48817
49360
  safety_identifier: string().nullable().optional(),
48818
49361
  prompt_cache_key: string().nullable().optional(),
49362
+ prompt_cache_retention: _enum(["in-memory", "24h"]).nullable().optional(),
48819
49363
  truncation: _enum(["auto", "disabled"]).nullable().optional(),
48820
49364
  parallel_tool_calls: boolean().nullable().optional(),
48821
49365
  store: boolean().nullable().optional(),
48822
49366
  user: string().nullable().optional(),
48823
- prompt: union([string().min(1), jsonObjectSchema]).nullable().optional(),
49367
+ prompt: object({
49368
+ id: string().min(1),
49369
+ variables: record(string(), unknown()).optional(),
49370
+ version: string().min(1).optional()
49371
+ }).loose().nullable().optional(),
48824
49372
  text: responsesTextConfigSchema.nullable().optional(),
48825
49373
  reasoning: responsesReasoningConfigSchema.nullable().optional(),
48826
49374
  context_management: array(responsesContextManagementSchema).nullable().optional(),
48827
49375
  include: array(string().min(1)).nullable().optional(),
48828
- service_tier: string().nullable().optional()
49376
+ service_tier: _enum([
49377
+ "auto",
49378
+ "default",
49379
+ "flex",
49380
+ "scale",
49381
+ "priority"
49382
+ ]).nullable().optional()
48829
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
+ });
48830
49389
  const toolChoice = payload.tool_choice;
48831
49390
  if (toolChoice && typeof toolChoice === "object" && "name" in toolChoice && typeof toolChoice.name === "string" && Array.isArray(payload.tools)) {
48832
49391
  if (!payload.tools.filter((tool) => {
@@ -48881,6 +49440,7 @@ function createChatCompletionsStrategy(transport, adapter, plan, signal) {
48881
49440
  async function handleCompletionCore({ body, signal, headers }) {
48882
49441
  const adapter = new OpenAIChatAdapter();
48883
49442
  let payload = parseOpenAIChatPayload(body);
49443
+ const requestContext = normalizeChatRequestContext(payload, headers);
48884
49444
  consola.debug("Request payload:", JSON.stringify(payload).slice(-400));
48885
49445
  const rewrite = applyModelRewrite(payload);
48886
49446
  const originalModel = rewrite.originalModel;
@@ -48901,7 +49461,7 @@ async function handleCompletionCore({ body, signal, headers }) {
48901
49461
  consola.debug("Set max_tokens to:", JSON.stringify(payload.max_tokens));
48902
49462
  }
48903
49463
  const upstreamSignal = createUpstreamSignalFromConfig(signal);
48904
- const plan = adapter.toCapiPlan(payload, { requestContext: readCapiRequestContext(headers) });
49464
+ const plan = adapter.toCapiPlan(payload, { requestContext });
48905
49465
  const modelMapping = {
48906
49466
  originalModel,
48907
49467
  rewrittenModel: rewrite.model,
@@ -48988,6 +49548,7 @@ const ESTIMATION_FACTOR = {
48988
49548
  async function handleCountTokensCore({ body, headers }) {
48989
49549
  const anthropicBeta = headers.get("anthropic-beta") ?? void 0;
48990
49550
  const anthropicPayload = parseAnthropicCountTokensPayload(body);
49551
+ normalizeAnthropicRequestContext(anthropicPayload, headers);
48991
49552
  const adapter = createAnthropicAdapter();
48992
49553
  let openAIPayload;
48993
49554
  try {
@@ -49078,6 +49639,49 @@ function containsVisionContent$1(content) {
49078
49639
  return content.some((block) => block.type === "image");
49079
49640
  }
49080
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
+
49081
49685
  //#endregion
49082
49686
  //#region src/translator/responses/signature-codec.ts
49083
49687
  const COMPACTION_PREFIX = "cm1#";
@@ -49338,7 +49942,7 @@ function convertAnthropicTools(tools) {
49338
49942
  return tools.map((tool) => ({
49339
49943
  type: "function",
49340
49944
  name: tool.name,
49341
- parameters: tool.input_schema,
49945
+ parameters: normalizeFunctionParametersSchemaForCopilot(tool.input_schema),
49342
49946
  strict: false,
49343
49947
  ...tool.description ? { description: tool.description } : {}
49344
49948
  }));
@@ -49451,6 +50055,7 @@ function applyContextManagement(payload, maxPromptTokens) {
49451
50055
  payload.context_management = createCompactionContextManagement(resolveResponsesCompactThreshold(maxPromptTokens));
49452
50056
  }
49453
50057
  function compactInputByLatestCompaction(payload) {
50058
+ if (!shouldAutoCompactResponsesInput()) return;
49454
50059
  if (!Array.isArray(payload.input) || payload.input.length === 0) return;
49455
50060
  const latestCompactionMessageIndex = getLatestCompactionMessageIndex(payload.input);
49456
50061
  if (latestCompactionMessageIndex === void 0) return;
@@ -49686,14 +50291,14 @@ function mapResponsesUsage(response) {
49686
50291
  ...cachedTokens !== void 0 ? { cache_read_input_tokens: cachedTokens } : {}
49687
50292
  };
49688
50293
  }
49689
- function isRecord(value) {
50294
+ function isRecord$1(value) {
49690
50295
  return typeof value === "object" && value !== null;
49691
50296
  }
49692
50297
  function isResponseOutputText(block) {
49693
- return isRecord(block) && block.type === "output_text";
50298
+ return isRecord$1(block) && block.type === "output_text";
49694
50299
  }
49695
50300
  function isResponseOutputRefusal(block) {
49696
- return isRecord(block) && block.type === "refusal";
50301
+ return isRecord$1(block) && block.type === "refusal";
49697
50302
  }
49698
50303
 
49699
50304
  //#endregion
@@ -50298,6 +50903,7 @@ function processAnthropicBetaHeader(rawHeader, model) {
50298
50903
  */
50299
50904
  async function handleMessagesCore({ body, signal, headers }) {
50300
50905
  const anthropicPayload = parseAnthropicMessagesPayload(body);
50906
+ const requestContext = normalizeAnthropicRequestContext(anthropicPayload, headers);
50301
50907
  if (consola.level >= 4) consola.debug("Anthropic request payload:", JSON.stringify(anthropicPayload));
50302
50908
  const rewrite = applyModelRewrite(anthropicPayload);
50303
50909
  const betaResult = processAnthropicBetaHeader(headers.get("anthropic-beta"), anthropicPayload.model);
@@ -50324,7 +50930,7 @@ async function handleMessagesCore({ body, signal, headers }) {
50324
50930
  selectedModel,
50325
50931
  upstreamSignal,
50326
50932
  headers,
50327
- requestContext: readCapiRequestContext(headers),
50933
+ requestContext,
50328
50934
  modelMapping
50329
50935
  };
50330
50936
  let strategyResult;
@@ -50406,8 +51012,246 @@ function createModelRoutes() {
50406
51012
  });
50407
51013
  }
50408
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
+
50409
51250
  //#endregion
50410
51251
  //#region src/routes/responses/strategy.ts
51252
+ function isRecord(value) {
51253
+ return typeof value === "object" && value !== null;
51254
+ }
50411
51255
  function createStreamIdTracker() {
50412
51256
  return { itemIdsByOutputIndex: /* @__PURE__ */ new Map() };
50413
51257
  }
@@ -50419,23 +51263,24 @@ function fixStreamIds(rawData, eventName, state) {
50419
51263
  } catch {
50420
51264
  return rawData;
50421
51265
  }
50422
- if (eventName === "response.created" || eventName === "response.completed" || eventName === "response.incomplete") {
50423
- const response = parsed.response;
50424
- if (response?.id && typeof response.id === "string") state.responseId = response.id;
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;
50425
51270
  }
50426
51271
  if (eventName === "response.output_item.added" || eventName === "response.output_item.done") {
50427
51272
  const outputIndex = typeof parsed.output_index === "number" ? parsed.output_index : void 0;
50428
- const item = parsed.item;
50429
- if (outputIndex !== void 0 && typeof item?.id === "string") state.itemIdsByOutputIndex.set(outputIndex, item.id);
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
+ }
50430
51279
  }
50431
- if ((eventName === "response.function_call_arguments.delta" || eventName === "response.function_call_arguments.done" || eventName === "response.output_text.delta" || eventName === "response.output_text.done" || eventName === "response.reasoning_summary_text.delta" || eventName === "response.reasoning_summary_text.done") && typeof parsed.output_index === "number") {
51280
+ if (typeof parsed.output_index === "number" && typeof parsed.item_id === "string") {
50432
51281
  const stableId = state.itemIdsByOutputIndex.get(parsed.output_index);
50433
51282
  if (stableId && parsed.item_id !== stableId) parsed.item_id = stableId;
50434
51283
  }
50435
- if (state.responseId && parsed.response && typeof parsed.response === "object") {
50436
- const response = parsed.response;
50437
- if (response.id !== state.responseId) response.id = state.responseId;
50438
- }
50439
51284
  return JSON.stringify(parsed);
50440
51285
  }
50441
51286
  function createResponsesPassthroughStrategy(copilotClient, payload, options) {
@@ -50451,10 +51296,34 @@ function createResponsesPassthroughStrategy(copilotClient, payload, options) {
50451
51296
  return result;
50452
51297
  },
50453
51298
  translateStreamChunk(chunk) {
50454
- return passthroughSSEChunk(chunk, fixStreamIds(chunk.data ?? "", chunk.event, tracker));
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);
50455
51304
  }
50456
51305
  };
50457
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
+ }
50458
51327
 
50459
51328
  //#endregion
50460
51329
  //#region src/routes/responses/handler.ts
@@ -50464,34 +51333,65 @@ const HTTP_URL_RE = /^https?:\/\//i;
50464
51333
  */
50465
51334
  async function handleResponsesCore({ body, signal, headers }) {
50466
51335
  const payload = parseResponsesPayload(body);
50467
- const rewrite = applyModelRewrite(payload);
50468
- applyResponsesToolTransforms(payload);
50469
- applyResponsesInputPolicies(payload);
50470
- compactInputByLatestCompaction(payload);
50471
- const selectedModel = findModelById(payload.model);
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);
50472
51344
  if (!selectedModel) throwInvalidRequestError("The selected model could not be resolved.", "model");
50473
51345
  if (!modelSupportsEndpoint(selectedModel, RESPONSES_ENDPOINT)) throwInvalidRequestError("The selected model does not support the responses endpoint.", "model");
50474
- applyContextManagement(payload, selectedModel.capabilities.limits.max_prompt_tokens);
50475
- const { vision, initiator } = getResponsesRequestOptions(payload);
51346
+ applyContextManagement(effectivePayload, selectedModel.capabilities.limits.max_prompt_tokens);
51347
+ const { vision, initiator } = getResponsesRequestOptions(effectivePayload);
50476
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
+ }
50477
51367
  return {
50478
- result: await runStrategy(createResponsesPassthroughStrategy(createCopilotClient(), payload, {
50479
- vision,
50480
- initiator,
50481
- requestContext: readCapiRequestContext(headers),
50482
- signal: upstreamSignal.signal
50483
- }), upstreamSignal),
51368
+ result,
50484
51369
  modelMapping: {
50485
51370
  originalModel: rewrite.originalModel,
50486
51371
  rewrittenModel: rewrite.model,
50487
- mappedModel: payload.model
51372
+ mappedModel: effectivePayload.model
50488
51373
  }
50489
51374
  };
50490
51375
  }
50491
51376
  function applyResponsesToolTransforms(payload) {
50492
51377
  applyFunctionApplyPatch(payload);
51378
+ applyFunctionToolCompatibilityDefaults(payload);
50493
51379
  rejectUnsupportedBuiltinTools(payload);
50494
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
+ }
50495
51395
  function applyFunctionApplyPatch(payload) {
50496
51396
  if (!shouldUseFunctionApplyPatch() || !Array.isArray(payload.tools)) return;
50497
51397
  payload.tools = payload.tools.map((tool) => {
@@ -50513,6 +51413,7 @@ function applyFunctionApplyPatch(payload) {
50513
51413
  });
50514
51414
  }
50515
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");
50516
51417
  if (!Array.isArray(payload.tools)) return;
50517
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");
50518
51419
  }
@@ -50536,6 +51437,7 @@ function containsRemoteImageUrl(value) {
50536
51437
  //#region src/routes/responses/resource-handler.ts
50537
51438
  async function handleRetrieveResponseCore({ params, url, headers, signal }) {
50538
51439
  const responseId = requireResponseId(params.responseId);
51440
+ if (shouldUseResponsesOfficialEmulator()) return getStoredResponseOrThrow(responseId);
50539
51441
  return await createCopilotClient().getResponse(responseId, {
50540
51442
  params: getRetrieveParamsFromUrl(url),
50541
51443
  requestContext: readCapiRequestContext(headers),
@@ -50544,6 +51446,7 @@ async function handleRetrieveResponseCore({ params, url, headers, signal }) {
50544
51446
  }
50545
51447
  async function handleListResponseInputItemsCore({ params, url, headers, signal }) {
50546
51448
  const responseId = requireResponseId(params.responseId);
51449
+ if (shouldUseResponsesOfficialEmulator()) return listStoredInputItemsOrThrow(responseId, getInputItemsParamsFromUrl(url));
50547
51450
  return await createCopilotClient().getResponseInputItems(responseId, getInputItemsParamsFromUrl(url), {
50548
51451
  requestContext: readCapiRequestContext(headers),
50549
51452
  signal
@@ -50551,13 +51454,22 @@ async function handleListResponseInputItemsCore({ params, url, headers, signal }
50551
51454
  }
50552
51455
  async function handleCreateResponseInputTokensCore({ body, headers, signal }) {
50553
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
+ }
50554
51465
  return await createCopilotClient().createResponseInputTokens(payload, {
50555
- requestContext: readCapiRequestContext(headers),
51466
+ requestContext,
50556
51467
  signal
50557
51468
  });
50558
51469
  }
50559
51470
  async function handleDeleteResponseCore({ params, headers, signal }) {
50560
51471
  const responseId = requireResponseId(params.responseId);
51472
+ if (shouldUseResponsesOfficialEmulator()) return deleteStoredResponseOrThrow(responseId);
50561
51473
  return await createCopilotClient().deleteResponse(responseId, {
50562
51474
  requestContext: readCapiRequestContext(headers),
50563
51475
  signal