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/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
- const text = await response.text();
5712
- const json = JSON.parse(text);
5733
+ rawText = await response.text();
5734
+ const json = JSON.parse(rawText);
5713
5735
  body = isStructuredErrorPayload(json) ? json : { error: {
5714
- message: text,
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:", body);
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.1";
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: false,
46715
- includeUsageOnStream: false,
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().nullable().optional(),
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().nullable().optional()
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().nullable().optional() }).loose()]);
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: 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(),
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: string().nullable().optional()
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: readCapiRequestContext(headers) });
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 CLAUDE_TOOL_OVERHEAD_TOKENS = 346;
48960
- const GROK_TOOL_OVERHEAD_TOKENS = 480;
48961
- const CLAUDE_ESTIMATION_FACTOR = 1.15;
48962
- const GROK_ESTIMATION_FACTOR = 1.03;
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
- if (anthropicPayload.model.startsWith("claude")) tokenCount.input = tokenCount.input + CLAUDE_TOOL_OVERHEAD_TOKENS;
48988
- else if (anthropicPayload.model.startsWith("grok")) tokenCount.input = tokenCount.input + GROK_TOOL_OVERHEAD_TOKENS;
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
- if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount * CLAUDE_ESTIMATION_FACTOR);
48993
- else if (anthropicPayload.model.startsWith("grok")) finalTokenCount = Math.round(finalTokenCount * GROK_ESTIMATION_FACTOR);
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
- flushPendingContent(pendingContent, items, {
49192
- role: "assistant",
49193
- phase: assistantPhase
49194
- });
49195
- items.push(createReasoningContent(block));
49196
- continue;
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: readCapiRequestContext(headers),
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
- if (eventName === "response.created" || eventName === "response.completed" || eventName === "response.incomplete") {
50397
- const response = parsed.response;
50398
- 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;
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") 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
+ }
50404
51279
  }
50405
- 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") {
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
- 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);
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 rewrite = applyModelRewrite(payload);
50442
- applyResponsesToolTransforms(payload);
50443
- applyResponsesInputPolicies(payload);
50444
- compactInputByLatestCompaction(payload);
50445
- 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);
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(payload, selectedModel.capabilities.limits.max_prompt_tokens);
50449
- const { vision, initiator } = getResponsesRequestOptions(payload);
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: await runStrategy(createResponsesPassthroughStrategy(createCopilotClient(), payload, {
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: payload.model
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: readCapiRequestContext(headers),
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