@nick3/copilot-api 1.9.2 → 1.9.15

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.
Files changed (42) hide show
  1. package/README.md +111 -88
  2. package/README.zh-CN.md +111 -85
  3. package/dist/{account-MllYSdRC.js → account-DjCbqJ2Q.js} +20 -24
  4. package/dist/account-DjCbqJ2Q.js.map +1 -0
  5. package/dist/admin/assets/index-BRnD4-DB.js +110 -0
  6. package/dist/admin/assets/index-CBMFCvqO.css +1 -0
  7. package/dist/admin/index.html +2 -2
  8. package/dist/{auth-DZoQA-kn.js → auth--I1utaB6.js} +103 -112
  9. package/dist/auth--I1utaB6.js.map +1 -0
  10. package/dist/{check-usage-DEbsehjH.js → check-usage-DHvjdha4.js} +6 -7
  11. package/dist/{check-usage-DEbsehjH.js.map → check-usage-DHvjdha4.js.map} +1 -1
  12. package/dist/{debug-BJfZVBB7.js → debug-BMo6ltbp.js} +6 -6
  13. package/dist/debug-BMo6ltbp.js.map +1 -0
  14. package/dist/{get-copilot-token-4mCKt94e.js → get-copilot-token-ZbmbVF0I.js} +3 -4
  15. package/dist/{get-copilot-token-4mCKt94e.js.map → get-copilot-token-ZbmbVF0I.js.map} +1 -1
  16. package/dist/main.js +6 -7
  17. package/dist/main.js.map +1 -1
  18. package/dist/{paths-DGlr310R.js → paths-CclKwouX.js} +3 -5
  19. package/dist/{paths-DGlr310R.js.map → paths-CclKwouX.js.map} +1 -1
  20. package/dist/{poll-access-token-Dvk6Ho0R.js → poll-access-token-CIPDXrcm.js} +4 -16
  21. package/dist/poll-access-token-CIPDXrcm.js.map +1 -0
  22. package/dist/{accounts-manager-BM66oT38.js → quota-refresh-scheduler-runtime-XD2fDa2K.js} +434 -51
  23. package/dist/quota-refresh-scheduler-runtime-XD2fDa2K.js.map +1 -0
  24. package/dist/{request-outbound-qyTeXbzy.js → request-outbound-CxvpSkOn.js} +14 -9
  25. package/dist/request-outbound-CxvpSkOn.js.map +1 -0
  26. package/dist/request-outbound-Cy6huWjK.js +2 -0
  27. package/dist/{server-DR9ZR_MN.js → server-BDCnb3Ao.js} +1760 -975
  28. package/dist/server-BDCnb3Ao.js.map +1 -0
  29. package/dist/{start-DDhYUFQR.js → start-DkBnp9d8.js} +11 -13
  30. package/dist/start-DkBnp9d8.js.map +1 -0
  31. package/package.json +20 -7
  32. package/dist/account-MllYSdRC.js.map +0 -1
  33. package/dist/accounts-manager-BM66oT38.js.map +0 -1
  34. package/dist/admin/assets/index-8eGib92I.js +0 -107
  35. package/dist/admin/assets/index-B2qj1asn.css +0 -1
  36. package/dist/auth-DZoQA-kn.js.map +0 -1
  37. package/dist/debug-BJfZVBB7.js.map +0 -1
  38. package/dist/poll-access-token-Dvk6Ho0R.js.map +0 -1
  39. package/dist/request-outbound-DhI9-SrV.js +0 -4
  40. package/dist/request-outbound-qyTeXbzy.js.map +0 -1
  41. package/dist/server-DR9ZR_MN.js.map +0 -1
  42. package/dist/start-DDhYUFQR.js.map +0 -1
@@ -1,23 +1,21 @@
1
- import { A as captureOutboundHeadersSnapshot, D as prepareMessageProxyHeaders, E as prepareInteractionHeaders, M as requestContext, N as resolveTraceId, O as accountFromState, T as prepareForCompact, _ as HTTPError, b as copilotHeaders, c as getUUID, d as parseUserIdMetadata, f as resolveAffinityKey, g as getCopilotUsage, h as getDeviceCode, k as state, l as isNullish, m as getGitHubUser, o as generateRequestIdFromPayload, p as sleep, s as getRootSessionId, t as pollAccessToken, u as normalizeStableSessionId, v as forwardError, w as normalizeDomain, y as copilotBaseUrl } from "./poll-access-token-Dvk6Ho0R.js";
2
- import { _ as DEFAULT_IDENTITY_ENTERPRISE_DOMAIN, a as getAccountClientIdentityByLoginAndApp, b as getCurrentIdentityEnvironment, d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, p as removeAccountFromRegistry, r as addAccountToRegistry, t as isAccountType } from "./account-MllYSdRC.js";
3
- import { r as ensurePaths, t as PATHS } from "./paths-DGlr310R.js";
4
- import "./get-copilot-token-4mCKt94e.js";
5
- import { i as getRequestOutboundStore, r as getRedactedHeaderKeys } from "./request-outbound-qyTeXbzy.js";
6
- import { A as isMessageStartInputTokensFallbackEnabled, C as getModelAliasesInfo, D as getSmallModel, E as getReasoningEffortForModel, F as resolveModelAlias, I as shouldCompactUseSmallModel, M as isResponsesApiContextManagementModel, N as isResponsesApiWebSearchEnabled, O as isAccountAffinityEnabled, P as mergeConfigWithDefaults, S as getModelAliases, T as getProviderConfig, _ as getAnthropicApiKey, a as getClientIpInfo, b as getExtraPromptForModel, c as normalizeChatCompletionsUsage, d as toLocalDateString, f as copilotFetch, g as getAliasTargetSet, h as PROVIDER_TYPE_ANTHROPIC, i as extractResponsesUsageFromStreamEvent, j as isMessagesApiEnabled, k as isForceAgentEnabled, l as normalizeEmbeddingsUsage, m as isDevModeEnabled, n as applySharedSessionAffinityRetention, o as getRequestHistoryStore, p as flushPendingCapture, r as extractResponsesUsageFromResult, s as getStatsStore, t as accountsManager, u as normalizeMessagesUsage, v as getClaudeTokenMultiplier, w as getModelRefreshIntervalMs, x as getLogLevel, y as getConfig } from "./accounts-manager-BM66oT38.js";
1
+ import { A as captureOutboundHeadersSnapshot, D as prepareMessageProxyHeaders, E as prepareInteractionHeaders, M as requestContext, N as resolveTraceId, O as accountFromState, T as prepareForCompact, _ as HTTPError, b as copilotHeaders, c as getUUID, d as parseUserIdMetadata, f as resolveAffinityKey, g as getCopilotUsage, h as getDeviceCode, k as state, l as isNullish, m as getGitHubUser, o as generateRequestIdFromPayload, p as sleep, s as getRootSessionId, t as pollAccessToken, u as normalizeStableSessionId, v as forwardError, w as normalizeDomain, y as copilotBaseUrl } from "./poll-access-token-CIPDXrcm.js";
2
+ import { a as getAccountClientIdentityByLoginAndApp, b as getCurrentIdentityEnvironment, d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, p as removeAccountFromRegistry, r as addAccountToRegistry, t as isAccountType } from "./account-DjCbqJ2Q.js";
3
+ import { r as ensurePaths, t as PATHS } from "./paths-CclKwouX.js";
4
+ import { i as getRequestOutboundStore, r as getRedactedHeaderKeys } from "./request-outbound-CxvpSkOn.js";
5
+ import { A as getReasoningEffortForModel, B as shouldCompactUseSmallModel, C as getConfig, D as getModelAliasesInfo, E as getModelAliases, F as isMessagesApiEnabled, I as isResponsesApiContextManagementModel, L as isResponsesApiWebSearchEnabled, M as isAccountAffinityEnabled, N as isForceAgentEnabled, O as getModelRefreshIntervalMs, P as isMessageStartInputTokensFallbackEnabled, R as mergeConfigWithDefaults, S as getClaudeTokenMultiplier, T as getLogLevel, _ as flushPendingCapture, a as accountsManager, b as getAliasTargetSet, c as extractResponsesUsageFromStreamEvent, d as getStatsStore, f as normalizeChatCompletionsUsage, g as copilotFetch, h as toLocalDateString, i as updateQuotaRefreshSchedulerFromConfig, j as getSmallModel, k as getProviderConfig, l as getClientIpInfo, m as normalizeMessagesUsage, o as applySharedSessionAffinityRetention, p as normalizeEmbeddingsUsage, s as extractResponsesUsageFromResult, u as getRequestHistoryStore, v as isDevModeEnabled, w as getExtraPromptForModel, x as getAnthropicApiKey, y as PROVIDER_TYPE_ANTHROPIC, z as resolveModelAlias } from "./quota-refresh-scheduler-runtime-XD2fDa2K.js";
7
6
  import consola from "consola";
8
7
  import fs, { readFile } from "node:fs/promises";
9
- import { randomUUID, timingSafeEqual } from "node:crypto";
8
+ import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
10
9
  import * as path$1 from "node:path";
11
10
  import path from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
12
  import { Hono } from "hono";
13
13
  import { cors } from "hono/cors";
14
14
  import { logger } from "hono/logger";
15
15
  import fs$1, { existsSync } from "node:fs";
16
16
  import { streamSSE } from "hono/streaming";
17
17
  import { events } from "fetch-event-stream";
18
- import { fileURLToPath } from "node:url";
19
18
  import util from "node:util";
20
-
21
19
  //#region src/lib/request-auth.ts
22
20
  const LEGACY_API_KEY_ENV_VAR = "COPILOT_API_KEY";
23
21
  let warnedLegacyEnvFallback = false;
@@ -88,8 +86,8 @@ function timingSafeKeyCompare(a, b) {
88
86
  }
89
87
  function createAuthMiddleware(options = {}) {
90
88
  const getApiKeys = options.getApiKeys ?? getConfiguredApiKeys;
91
- const allowUnauthenticatedPaths = new Set((options.allowUnauthenticatedPaths ?? ["/"]).map((path$2) => normalizePathname(path$2)));
92
- const allowUnauthenticatedPathPrefixes = (options.allowUnauthenticatedPathPrefixes ?? []).map((path$2) => normalizePathname(path$2));
89
+ const allowUnauthenticatedPaths = new Set((options.allowUnauthenticatedPaths ?? ["/"]).map((path) => normalizePathname(path)));
90
+ const allowUnauthenticatedPathPrefixes = (options.allowUnauthenticatedPathPrefixes ?? []).map((path) => normalizePathname(path));
93
91
  const allowOptionsBypass = options.allowOptionsBypass ?? true;
94
92
  return async (c, next) => {
95
93
  if (allowOptionsBypass && c.req.method === "OPTIONS") return next();
@@ -103,7 +101,6 @@ function createAuthMiddleware(options = {}) {
103
101
  return next();
104
102
  };
105
103
  }
106
-
107
104
  //#endregion
108
105
  //#region src/lib/trace.ts
109
106
  const traceIdMiddleware = async (c, next) => {
@@ -120,7 +117,6 @@ const traceIdMiddleware = async (c, next) => {
120
117
  await next();
121
118
  });
122
119
  };
123
-
124
120
  //#endregion
125
121
  //#region src/routes/admin-api/auth-sessions.ts
126
122
  function buildOauthUrls(enterpriseDomain) {
@@ -277,7 +273,6 @@ var AuthSessionManager = class {
277
273
  }
278
274
  };
279
275
  const authSessionManager = new AuthSessionManager();
280
-
281
276
  //#endregion
282
277
  //#region src/routes/admin-api/config-writer.ts
283
278
  async function writeConfigFile(config) {
@@ -298,7 +293,6 @@ async function writeConfigFile(config) {
298
293
  throw error;
299
294
  }
300
295
  }
301
-
302
296
  //#endregion
303
297
  //#region src/lib/models.ts
304
298
  const getAvailableModels = () => (accountsManager.getFirstAccountModels()?.data ?? []).filter((model) => model.model_picker_enabled || model.capabilities.type === "embeddings");
@@ -349,7 +343,6 @@ const _normalizeSdkModelId = (sdkModelId) => {
349
343
  version: pattern5[1]
350
344
  };
351
345
  };
352
-
353
346
  //#endregion
354
347
  //#region src/lib/copilot-rate-limit.ts
355
348
  const copilotRateLimitTypes = ["session", "weekly"];
@@ -395,14 +388,12 @@ const logCopilotRateLimits = (headers) => {
395
388
  consola.info(`Copilot ${usage.type} quota remaining: ${usage.remaining}, resets at: ${dateStr}`);
396
389
  }
397
390
  };
398
-
399
391
  //#endregion
400
392
  //#region src/lib/request-initiator.ts
401
393
  function resolveEffectiveInitiator(baseInitiator, options) {
402
394
  if (options.isCompact || options.isSubagent) return "agent";
403
395
  return baseInitiator;
404
396
  }
405
-
406
397
  //#endregion
407
398
  //#region src/services/copilot/create-chat-completions.ts
408
399
  function isGpt5MiniFamily(modelId) {
@@ -425,7 +416,7 @@ const getChatInitiator = (messages) => {
425
416
  const createChatCompletions = async (payload, account, options) => {
426
417
  const ctx = account ?? accountFromState();
427
418
  if (!ctx.copilotToken) throw new Error("Copilot token not found");
428
- const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x$1) => x$1.type === "image_url"));
419
+ const enableVision = payload.messages.some((x) => typeof x.content !== "string" && x.content?.some((x) => x.type === "image_url"));
429
420
  const effectiveInitiator = resolveEffectiveInitiator(options?.initiator ?? getChatInitiator(payload.messages), {
430
421
  isCompact: Boolean(options?.compactType),
431
422
  isSubagent: Boolean(options?.subagentMarker)
@@ -444,7 +435,8 @@ const createChatCompletions = async (payload, account, options) => {
444
435
  body: JSON.stringify(upstreamPayload)
445
436
  }, {
446
437
  requestId: options?.requestId,
447
- callSite: "chat-completions"
438
+ callSite: "chat-completions",
439
+ fetchImpl: options?.fetchImpl
448
440
  });
449
441
  logCopilotRateLimits(response.headers);
450
442
  if (!response.ok) {
@@ -454,7 +446,6 @@ const createChatCompletions = async (payload, account, options) => {
454
446
  if (payload.stream) return events(response);
455
447
  return await response.json();
456
448
  };
457
-
458
449
  //#endregion
459
450
  //#region src/lib/tokenizer.ts
460
451
  const ENCODING_MAP = {
@@ -485,7 +476,10 @@ const calculateToolCallsTokens = (toolCalls, encoder, constants) => {
485
476
  const calculateContentPartsTokens = (contentParts, encoder) => {
486
477
  let tokens = 0;
487
478
  for (const part of contentParts) if (part.type === "image_url") tokens += encoder.encode(part.image_url.url).length + 85;
488
- else if (part.text) tokens += encoder.encode(part.text).length;
479
+ else if (part.type === "file") {
480
+ tokens += encoder.encode(part.file.file_data).length;
481
+ if (part.file.filename) tokens += encoder.encode(part.file.filename).length;
482
+ } else if (part.text) tokens += encoder.encode(part.text).length;
489
483
  return tokens;
490
484
  };
491
485
  /**
@@ -669,29 +663,13 @@ const getTokenCount = async (payload, model) => {
669
663
  output: outputTokens
670
664
  };
671
665
  };
672
-
673
- //#endregion
674
- //#region src/lib/compact.ts
675
- const COMPACT_REQUEST = 1;
676
- const COMPACT_AUTO_CONTINUE = 2;
677
- const compactSystemPromptStart = "You are a helpful AI assistant tasked with summarizing conversations";
678
- const compactOpenCodeSystemPromptStart = "You are an anchored context summarization assistant for coding sessions.";
679
- const compactSystemPromptStarts = [compactSystemPromptStart, compactOpenCodeSystemPromptStart];
680
- const compactTextOnlyGuard = "CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.";
681
- const compactSummaryPromptStart = "Your task is to create a detailed summary of the conversation so far";
682
- const compactAutoContinueClaudeCodePromptStart = "This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.";
683
- const compactAutoContinueOpenCodePromptStart = "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.";
684
- const compactAutoContinueOpenCodePromptStart2 = "The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context.";
666
+ const compactSystemPromptStarts = ["You are a helpful AI assistant tasked with summarizing conversations", "You are an anchored context summarization assistant for coding sessions."];
685
667
  const compactAutoContinuePromptStarts = [
686
- compactAutoContinueClaudeCodePromptStart,
687
- compactAutoContinueOpenCodePromptStart,
688
- compactAutoContinueOpenCodePromptStart2
668
+ "This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.",
669
+ "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.",
670
+ "The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context."
689
671
  ];
690
672
  const compactMessageSections = ["Pending Tasks:", "Current Work:"];
691
-
692
- //#endregion
693
- //#region src/routes/messages/preprocess.ts
694
- const TOOL_REFERENCE_TURN_BOUNDARY = "Tool loaded.";
695
673
  const IDE_EXECUTE_CODE_TOOL = "mcp__ide__executeCode";
696
674
  const IDE_GET_DIAGNOSTICS_TOOL = "mcp__ide__getDiagnostics";
697
675
  const IDE_GET_DIAGNOSTICS_DESCRIPTION = "Get language diagnostics from VS Code. Returns errors, warnings, information, and hints for files in the workspace.";
@@ -704,7 +682,7 @@ const getCompactCandidateText = (message) => {
704
682
  const isCompactMessage = (lastMessage) => {
705
683
  const text = getCompactCandidateText(lastMessage);
706
684
  if (!text) return false;
707
- return text.includes(compactTextOnlyGuard) && text.includes(compactSummaryPromptStart) && compactMessageSections.some((section) => text.includes(section));
685
+ return text.includes("CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.") && text.includes("Your task is to create a detailed summary of the conversation so far") && compactMessageSections.some((section) => text.includes(section));
708
686
  };
709
687
  const isCompactAutoContinueMessage = (lastMessage) => {
710
688
  const text = getCompactCandidateText(lastMessage);
@@ -712,12 +690,12 @@ const isCompactAutoContinueMessage = (lastMessage) => {
712
690
  };
713
691
  const getCompactType = (anthropicPayload) => {
714
692
  const lastMessage = anthropicPayload.messages.at(-1);
715
- if (lastMessage && isCompactMessage(lastMessage)) return COMPACT_REQUEST;
716
- if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return COMPACT_AUTO_CONTINUE;
693
+ if (lastMessage && isCompactMessage(lastMessage)) return 1;
694
+ if (lastMessage && isCompactAutoContinueMessage(lastMessage)) return 2;
717
695
  const system = anthropicPayload.system;
718
- if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ? COMPACT_REQUEST : 0;
696
+ if (typeof system === "string") return compactSystemPromptStarts.some((promptStart) => system.startsWith(promptStart)) ? 1 : 0;
719
697
  if (!Array.isArray(system)) return 0;
720
- if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return COMPACT_REQUEST;
698
+ if (system.some((msg) => typeof msg.text === "string" && compactSystemPromptStarts.some((promptStart) => msg.text.startsWith(promptStart)))) return 1;
721
699
  return 0;
722
700
  };
723
701
  const mergeContentWithText = (tr, textBlock) => {
@@ -778,9 +756,9 @@ const assignAttachmentsToToolResults = (target, attachments, options) => {
778
756
  if (attachments.length === 0) return;
779
757
  if (toolResultIndices.length > 0 && toolResultIndices.length === attachments.length) {
780
758
  for (const [index, toolResultIndex] of toolResultIndices.entries()) {
781
- const currentAttachments$1 = target.get(toolResultIndex);
782
- if (currentAttachments$1) {
783
- currentAttachments$1.push(attachments[index]);
759
+ const currentAttachments = target.get(toolResultIndex);
760
+ if (currentAttachments) {
761
+ currentAttachments.push(attachments[index]);
784
762
  continue;
785
763
  }
786
764
  target.set(toolResultIndex, [attachments[index]]);
@@ -872,7 +850,7 @@ const stripToolReferenceTurnBoundary = (anthropicPayload) => {
872
850
  for (const msg of anthropicPayload.messages) {
873
851
  if (msg.role !== "user" || !Array.isArray(msg.content)) continue;
874
852
  if (!msg.content.some((block) => block.type === "tool_result" && hasToolRef(block))) continue;
875
- msg.content = msg.content.filter((block) => block.type !== "text" || block.text.trim() !== TOOL_REFERENCE_TURN_BOUNDARY);
853
+ msg.content = msg.content.filter((block) => block.type !== "text" || block.text.trim() !== "Tool loaded.");
876
854
  }
877
855
  };
878
856
  const mergeToolResultForClaude = (anthropicPayload, options) => {
@@ -947,7 +925,6 @@ const prepareMessagesApiPayload = (payload, selectedModel) => {
947
925
  payload.output_config = { effort };
948
926
  }
949
927
  };
950
-
951
928
  //#endregion
952
929
  //#region src/routes/messages/utils.ts
953
930
  function mapOpenAIStopReasonToAnthropic(finishReason) {
@@ -959,14 +936,17 @@ function mapOpenAIStopReasonToAnthropic(finishReason) {
959
936
  content_filter: "end_turn"
960
937
  }[finishReason];
961
938
  }
962
- const estimateInputTokens = async (payload, selectedModel, logger$7) => {
939
+ const estimateInputTokens = async (payload, selectedModel, logger) => {
963
940
  try {
964
941
  return (await getTokenCount(payload, selectedModel)).input;
965
942
  } catch (error) {
966
- logger$7.warn("Failed to estimate input tokens for message_start", error);
943
+ logger.warn("Failed to estimate input tokens for message_start", error);
967
944
  return;
968
945
  }
969
946
  };
947
+ function stringifyOwnerKeys$1(keys) {
948
+ return keys && keys.length > 0 ? JSON.stringify(keys) : void 0;
949
+ }
970
950
  const isWarmupProbeRequest = (payload) => {
971
951
  const lastMsg = payload.messages.at(-1);
972
952
  if (!lastMsg || lastMsg.role !== "user" || !Array.isArray(lastMsg.content)) return false;
@@ -983,7 +963,7 @@ const isWarmupProbeRequest = (payload) => {
983
963
  return false;
984
964
  };
985
965
  const handleSelectionFailure = (context) => {
986
- const { c, store, requestId, startedAtMs, method, path: path$2, streamRequested, clientModel, clientIp, clientIpSource, userAgent, userId, safetyIdentifier, promptCacheKey, initiator, isSubagent, affinityKeyUsed, affinityKeySource, selectionReason, selection } = context;
966
+ const { c, store, requestId, startedAtMs, method, path, streamRequested, clientModel, clientIp, clientIpSource, userAgent, userId, safetyIdentifier, promptCacheKey, initiator, isSubagent, affinityKeyUsed, affinityKeySource, selectionReason, responsesItemOwnerLookupKeys, selection } = context;
987
967
  const finishedAtMs = Date.now();
988
968
  store.insert({
989
969
  requestId,
@@ -991,7 +971,7 @@ const handleSelectionFailure = (context) => {
991
971
  finishedAtMs,
992
972
  durationMs: finishedAtMs - startedAtMs,
993
973
  method,
994
- path: path$2,
974
+ path,
995
975
  stream: streamRequested,
996
976
  clientModel,
997
977
  clientIp,
@@ -1004,6 +984,7 @@ const handleSelectionFailure = (context) => {
1004
984
  isSubagent,
1005
985
  affinityKeyUsed,
1006
986
  affinityKeySource,
987
+ responsesItemOwnerLookupKeysJson: stringifyOwnerKeys$1(responsesItemOwnerLookupKeys),
1007
988
  httpStatus: selection.reason === "MODEL_NOT_SUPPORTED" ? 400 : 429,
1008
989
  selectionReason: selectionReason ?? selection.selectionReason,
1009
990
  selectionFailureReason: selection.reason
@@ -1027,16 +1008,19 @@ const maybeBlockOriginalModelName = (context) => {
1027
1008
  }
1028
1009
  });
1029
1010
  };
1030
-
1031
1011
  //#endregion
1032
1012
  //#region src/routes/messages/non-stream-translation.ts
1033
- const THINKING_TEXT = "Thinking...";
1034
- function translateToOpenAI(payload) {
1013
+ const THINKING_TEXT$1 = "Thinking...";
1014
+ const COPILOT_TOOL_CONTENT_SUPPORT_TYPE = ["array", "image"];
1015
+ function translateToOpenAI(payload, options = {}) {
1035
1016
  const modelId = payload.model;
1036
1017
  const thinkingBudget = getThinkingBudget(payload, getAvailableModels().find((m) => m.id === modelId));
1037
1018
  return {
1038
1019
  model: modelId,
1039
- messages: translateAnthropicMessagesToOpenAI(payload, modelId, thinkingBudget),
1020
+ messages: translateAnthropicMessagesToOpenAI(payload, modelId, {
1021
+ supportPdf: options.supportPdf ?? false,
1022
+ toolContentSupportType: options.toolContentSupportType ?? COPILOT_TOOL_CONTENT_SUPPORT_TYPE
1023
+ }),
1040
1024
  max_tokens: payload.max_tokens,
1041
1025
  stop: payload.stop_sequences,
1042
1026
  stream: payload.stream,
@@ -1059,9 +1043,9 @@ function getThinkingBudget(payload, model) {
1059
1043
  }
1060
1044
  }
1061
1045
  }
1062
- function translateAnthropicMessagesToOpenAI(payload, modelId, _thinkingBudget) {
1046
+ function translateAnthropicMessagesToOpenAI(payload, modelId, capabilities) {
1063
1047
  const systemMessages = handleSystemPrompt(payload.system);
1064
- const otherMessages = payload.messages.flatMap((message) => message.role === "user" ? handleUserMessage(message) : handleAssistantMessage(message, modelId));
1048
+ const otherMessages = payload.messages.flatMap((message) => message.role === "user" ? handleUserMessage(message, capabilities) : handleAssistantMessage(message, modelId, capabilities));
1065
1049
  return [...systemMessages, ...otherMessages];
1066
1050
  }
1067
1051
  function handleSystemPrompt(system) {
@@ -1077,19 +1061,21 @@ function handleSystemPrompt(system) {
1077
1061
  }).join("\n\n")
1078
1062
  }];
1079
1063
  }
1080
- function handleUserMessage(message) {
1064
+ function handleUserMessage(message, capabilities) {
1081
1065
  const newMessages = [];
1082
1066
  if (Array.isArray(message.content)) {
1083
1067
  const toolResultBlocks = message.content.filter((block) => block.type === "tool_result");
1084
1068
  const otherBlocks = message.content.filter((block) => block.type !== "tool_result");
1085
- for (const block of toolResultBlocks) newMessages.push({
1086
- role: "tool",
1087
- tool_call_id: block.tool_use_id,
1088
- content: mapContent(block.content)
1089
- });
1069
+ const movedToolResultUserMessages = [];
1070
+ for (const block of toolResultBlocks) {
1071
+ const result = handleToolResultBlock(block, capabilities);
1072
+ newMessages.push(result.toolMessage);
1073
+ if (result.movedUserMessage) movedToolResultUserMessages.push(result.movedUserMessage);
1074
+ }
1075
+ newMessages.push(...movedToolResultUserMessages);
1090
1076
  if (otherBlocks.length > 0) newMessages.push({
1091
1077
  role: "user",
1092
- content: mapContent(otherBlocks)
1078
+ content: mapContent(otherBlocks, { supportPdf: capabilities.supportPdf })
1093
1079
  });
1094
1080
  } else newMessages.push({
1095
1081
  role: "user",
@@ -1097,20 +1083,74 @@ function handleUserMessage(message) {
1097
1083
  });
1098
1084
  return newMessages;
1099
1085
  }
1100
- function handleAssistantMessage(message, modelId) {
1086
+ function handleToolResultBlock(block, capabilities) {
1087
+ if (typeof block.content === "string") return { toolMessage: createToolMessage(block.tool_use_id, block.content) };
1088
+ if (!Array.isArray(block.content)) return { toolMessage: createToolMessage(block.tool_use_id, "") };
1089
+ const support = getToolContentSupport(capabilities);
1090
+ const hasImage = block.content.some((block) => block.type === "image");
1091
+ const hasDocument = block.content.some((block) => block.type === "document");
1092
+ const content = mapContent(block.content, { supportPdf: capabilities.supportPdf });
1093
+ const hasPdfFile = hasDocument && capabilities.supportPdf;
1094
+ const shouldMoveImageToUserMessage = hasImage && !support.image;
1095
+ const shouldMovePdfToUserMessage = hasPdfFile && !support.pdf;
1096
+ if (shouldMoveImageToUserMessage || shouldMovePdfToUserMessage) return {
1097
+ movedUserMessage: createToolResultUserMessage(block, capabilities.supportPdf),
1098
+ toolMessage: createToolMessage(block.tool_use_id, getTextToolContent(content) || "Rich tool result content was moved to a user message because this upstream does not support it in tool messages.")
1099
+ };
1100
+ const hasRichContent = hasImage || hasPdfFile;
1101
+ if (support.array || hasRichContent) return { toolMessage: createToolMessage(block.tool_use_id, content) };
1102
+ return { toolMessage: createToolMessage(block.tool_use_id, getTextToolContent(content)) };
1103
+ }
1104
+ function getTextToolContent(content) {
1105
+ if (!Array.isArray(content)) return content ?? "";
1106
+ return content.flatMap((part) => part.type === "text" && part.text.length > 0 ? [part.text] : []).join("\n");
1107
+ }
1108
+ function getToolContentSupport(capabilities) {
1109
+ return {
1110
+ array: capabilities.toolContentSupportType.includes("array"),
1111
+ image: capabilities.toolContentSupportType.includes("image"),
1112
+ pdf: capabilities.supportPdf && capabilities.toolContentSupportType.includes("pdf")
1113
+ };
1114
+ }
1115
+ function createToolMessage(toolCallId, content) {
1116
+ return {
1117
+ role: "tool",
1118
+ tool_call_id: toolCallId,
1119
+ content
1120
+ };
1121
+ }
1122
+ function createToolResultUserMessage(block, supportPdf) {
1123
+ const prefix = {
1124
+ type: "text",
1125
+ text: `Tool result for ${block.tool_use_id}:`
1126
+ };
1127
+ const content = mapContent(block.content, { supportPdf });
1128
+ if (Array.isArray(content)) return {
1129
+ role: "user",
1130
+ content: [prefix, ...content]
1131
+ };
1132
+ return {
1133
+ role: "user",
1134
+ content: [prefix, {
1135
+ type: "text",
1136
+ text: content ?? ""
1137
+ }]
1138
+ };
1139
+ }
1140
+ function handleAssistantMessage(message, modelId, capabilities) {
1101
1141
  if (!Array.isArray(message.content)) return [{
1102
1142
  role: "assistant",
1103
1143
  content: mapContent(message.content)
1104
1144
  }];
1105
1145
  const toolUseBlocks = message.content.filter((block) => block.type === "tool_use");
1106
1146
  let thinkingBlocks = message.content.filter((block) => block.type === "thinking");
1107
- if (modelId.startsWith("claude")) thinkingBlocks = thinkingBlocks.filter((b) => b.thinking && b.thinking !== THINKING_TEXT && b.signature && !b.signature.includes("@"));
1108
- const thinkingContents = thinkingBlocks.filter((b) => b.thinking && b.thinking !== THINKING_TEXT).map((b) => b.thinking);
1147
+ if (modelId.startsWith("claude")) thinkingBlocks = thinkingBlocks.filter((b) => b.thinking && b.thinking !== "Thinking..." && b.signature && !b.signature.includes("@"));
1148
+ const thinkingContents = thinkingBlocks.filter((b) => b.thinking && b.thinking !== "Thinking...").map((b) => b.thinking);
1109
1149
  const allThinkingContent = thinkingContents.length > 0 ? thinkingContents.join("\n\n") : void 0;
1110
1150
  const signature = thinkingBlocks.find((b) => b.signature)?.signature;
1111
1151
  return toolUseBlocks.length > 0 ? [{
1112
1152
  role: "assistant",
1113
- content: mapContent(message.content),
1153
+ content: mapContent(message.content, { supportPdf: capabilities.supportPdf }),
1114
1154
  reasoning_text: allThinkingContent,
1115
1155
  reasoning_opaque: signature,
1116
1156
  tool_calls: toolUseBlocks.map((toolUse) => ({
@@ -1123,12 +1163,12 @@ function handleAssistantMessage(message, modelId) {
1123
1163
  }))
1124
1164
  }] : [{
1125
1165
  role: "assistant",
1126
- content: mapContent(message.content),
1166
+ content: mapContent(message.content, { supportPdf: capabilities.supportPdf }),
1127
1167
  reasoning_text: allThinkingContent,
1128
1168
  reasoning_opaque: signature
1129
1169
  }];
1130
1170
  }
1131
- function mapContent(content) {
1171
+ function mapContent(content, options = {}) {
1132
1172
  if (typeof content === "string") return content;
1133
1173
  if (!Array.isArray(content)) return null;
1134
1174
  const contentParts = [];
@@ -1146,7 +1186,7 @@ function mapContent(content) {
1146
1186
  });
1147
1187
  break;
1148
1188
  case "document":
1149
- contentParts.push(createDocumentTextPart());
1189
+ contentParts.push(options.supportPdf ? createDocumentFilePart(block) : createDocumentTextPart());
1150
1190
  break;
1151
1191
  case "tool_reference":
1152
1192
  contentParts.push({
@@ -1155,12 +1195,22 @@ function mapContent(content) {
1155
1195
  });
1156
1196
  break;
1157
1197
  }
1198
+ if (contentParts.length === 0) return "";
1158
1199
  return contentParts;
1159
1200
  }
1160
1201
  function createDocumentTextPart() {
1161
1202
  return {
1162
1203
  type: "text",
1163
- text: "A PDF document was attached, but this api cannot send PDF inputs directly. Analyze using other tools."
1204
+ text: "PDF/document content is not supported by this Chat Completions upstream. Use the available text extracted from the document."
1205
+ };
1206
+ }
1207
+ function createDocumentFilePart(block) {
1208
+ return {
1209
+ type: "file",
1210
+ file: {
1211
+ file_data: `data:${block.source.media_type};base64,${block.source.data}`,
1212
+ filename: block.title ?? "document.pdf"
1213
+ }
1164
1214
  };
1165
1215
  }
1166
1216
  function translateAnthropicToolsToOpenAI(anthropicTools) {
@@ -1205,7 +1255,7 @@ function translateToAnthropic(response) {
1205
1255
  let stopReason = response.choices[0]?.finish_reason ?? null;
1206
1256
  for (const choice of response.choices) {
1207
1257
  const textBlocks = getAnthropicTextBlocks(choice.message.content);
1208
- const thinkBlocks = getAnthropicThinkBlocks(choice.message.reasoning_text, choice.message.reasoning_opaque);
1258
+ const thinkBlocks = getAnthropicThinkBlocks(getOpenAIReasoningText(choice.message), choice.message.reasoning_opaque);
1209
1259
  const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls);
1210
1260
  assistantContentBlocks.push(...thinkBlocks, ...textBlocks, ...toolUseBlocks);
1211
1261
  if (choice.finish_reason === "tool_calls" || stopReason === "stop") stopReason = choice.finish_reason;
@@ -1218,12 +1268,24 @@ function translateToAnthropic(response) {
1218
1268
  content: assistantContentBlocks,
1219
1269
  stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),
1220
1270
  stop_sequence: null,
1221
- usage: {
1222
- input_tokens: (response.usage?.prompt_tokens ?? 0) - (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),
1223
- output_tokens: response.usage?.completion_tokens ?? 0,
1224
- ...response.usage?.prompt_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: response.usage.prompt_tokens_details.cached_tokens }
1225
- }
1271
+ usage: mapOpenAIChatCompletionUsage(response)
1272
+ };
1273
+ }
1274
+ function mapOpenAIChatCompletionUsage(response) {
1275
+ const promptDetails = response.usage?.prompt_tokens_details;
1276
+ const promptTokens = response.usage?.prompt_tokens ?? 0;
1277
+ const cachedTokens = promptDetails?.cached_tokens ?? 0;
1278
+ const cacheCreationTokens = promptDetails?.cache_creation_input_tokens ?? 0;
1279
+ const usage = {
1280
+ input_tokens: Math.max(0, promptTokens - cachedTokens - cacheCreationTokens),
1281
+ output_tokens: response.usage?.completion_tokens ?? 0
1226
1282
  };
1283
+ if (promptDetails?.cache_creation_input_tokens !== void 0) usage.cache_creation_input_tokens = cacheCreationTokens;
1284
+ if (promptDetails?.cached_tokens !== void 0) usage.cache_read_input_tokens = cachedTokens;
1285
+ return usage;
1286
+ }
1287
+ function getOpenAIReasoningText(message) {
1288
+ return message.reasoning_text ?? message.reasoning_content;
1227
1289
  }
1228
1290
  function getAnthropicTextBlocks(messageContent) {
1229
1291
  if (typeof messageContent === "string" && messageContent.length > 0) return [{
@@ -1244,7 +1306,7 @@ function getAnthropicThinkBlocks(reasoningText, reasoningOpaque) {
1244
1306
  }];
1245
1307
  if (reasoningOpaque && reasoningOpaque.length > 0) return [{
1246
1308
  type: "thinking",
1247
- thinking: THINKING_TEXT,
1309
+ thinking: THINKING_TEXT$1,
1248
1310
  signature: reasoningOpaque
1249
1311
  }];
1250
1312
  return [];
@@ -1258,7 +1320,6 @@ function getAnthropicToolUseBlocks(toolCalls) {
1258
1320
  input: JSON.parse(toolCall.function.arguments)
1259
1321
  }));
1260
1322
  }
1261
-
1262
1323
  //#endregion
1263
1324
  //#region src/routes/admin-api/replay-translation.ts
1264
1325
  function translateForReplay(input) {
@@ -1276,7 +1337,6 @@ function translateForReplay(input) {
1276
1337
  if (upstreamEndpoint.includes("/responses")) return rawText;
1277
1338
  return null;
1278
1339
  }
1279
-
1280
1340
  //#endregion
1281
1341
  //#region src/routes/admin-api/replay.ts
1282
1342
  const replayRoutes = new Hono();
@@ -1596,7 +1656,6 @@ function requireDevMode(c) {
1596
1656
  } }, 403);
1597
1657
  return null;
1598
1658
  }
1599
-
1600
1659
  //#endregion
1601
1660
  //#region src/routes/admin-api/route.ts
1602
1661
  const ADMIN_TOKEN = process.env.ADMIN_TOKEN?.trim() || void 0;
@@ -1676,7 +1735,8 @@ const CONFIG_KEYS = new Set([
1676
1735
  "sessionAffinityRetentionDays",
1677
1736
  "useMessagesApi",
1678
1737
  "useResponsesApiWebSearch",
1679
- "devMode"
1738
+ "devMode",
1739
+ "quotaRefresh"
1680
1740
  ]);
1681
1741
  const REASONING_EFFORTS = new Set([
1682
1742
  "none",
@@ -1837,7 +1897,7 @@ function applyProviderType(provider, value, field) {
1837
1897
  const parsed = parseOptionalString(value.type, `${field}.type`);
1838
1898
  if ("error" in parsed) return parsed.error;
1839
1899
  if ("value" in parsed) {
1840
- if (parsed.value !== PROVIDER_TYPE_ANTHROPIC) return `${field}.type must be "${PROVIDER_TYPE_ANTHROPIC}"`;
1900
+ if (parsed.value !== "anthropic") return `${field}.type must be "${PROVIDER_TYPE_ANTHROPIC}"`;
1841
1901
  provider.type = PROVIDER_TYPE_ANTHROPIC;
1842
1902
  }
1843
1903
  }
@@ -2103,6 +2163,48 @@ function applyDevModeConfig(next, value) {
2103
2163
  }
2104
2164
  next.devMode = parsed.value;
2105
2165
  }
2166
+ const QUOTA_REFRESH_KEYS = new Set([
2167
+ "enabled",
2168
+ "intervalMinutes",
2169
+ "startupDelaySeconds",
2170
+ "staggerMinSeconds",
2171
+ "staggerMaxSeconds"
2172
+ ]);
2173
+ function parseQuotaRefreshConfig(value) {
2174
+ if (value === null || value === void 0) return { clear: true };
2175
+ if (!isPlainObject(value)) return { error: "quotaRefresh must be an object" };
2176
+ for (const key of Object.keys(value)) if (!QUOTA_REFRESH_KEYS.has(key)) return { error: `quotaRefresh.${key} is not supported` };
2177
+ const out = {};
2178
+ if (Object.hasOwn(value, "enabled")) {
2179
+ const parsed = parseOptionalBoolean(value.enabled, "quotaRefresh.enabled");
2180
+ if ("error" in parsed) return parsed;
2181
+ if ("value" in parsed) out.enabled = parsed.value;
2182
+ }
2183
+ for (const key of [
2184
+ "intervalMinutes",
2185
+ "startupDelaySeconds",
2186
+ "staggerMinSeconds",
2187
+ "staggerMaxSeconds"
2188
+ ]) {
2189
+ if (!Object.hasOwn(value, key)) continue;
2190
+ const parsed = parseOptionalNonNegativeNumber(value[key], `quotaRefresh.${key}`);
2191
+ if ("error" in parsed) return parsed;
2192
+ if ("value" in parsed) out[key] = parsed.value;
2193
+ }
2194
+ return { value: out };
2195
+ }
2196
+ function applyQuotaRefreshConfig(next, value) {
2197
+ const parsed = parseQuotaRefreshConfig(value);
2198
+ if ("error" in parsed) return parsed.error;
2199
+ if ("clear" in parsed) {
2200
+ delete next.quotaRefresh;
2201
+ return;
2202
+ }
2203
+ next.quotaRefresh = next.quotaRefresh === void 0 ? parsed.value : {
2204
+ ...next.quotaRefresh,
2205
+ ...parsed.value
2206
+ };
2207
+ }
2106
2208
  const CONFIG_PATCH_HANDLERS = {
2107
2209
  auth: applyAuthConfig,
2108
2210
  extraPrompts: applyExtraPrompts,
@@ -2124,7 +2226,8 @@ const CONFIG_PATCH_HANDLERS = {
2124
2226
  sessionAffinityRetentionDays: (next, value) => applyOptionalNumber(next, "sessionAffinityRetentionDays", value),
2125
2227
  useMessagesApi: (next, value) => applyOptionalBoolean(next, "useMessagesApi", value),
2126
2228
  useResponsesApiWebSearch: (next, value) => applyOptionalBoolean(next, "useResponsesApiWebSearch", value),
2127
- devMode: applyDevModeConfig
2229
+ devMode: applyDevModeConfig,
2230
+ quotaRefresh: applyQuotaRefreshConfig
2128
2231
  };
2129
2232
  function applyConfigPatch(base, input) {
2130
2233
  const next = { ...base };
@@ -2190,6 +2293,7 @@ adminApiRoutes.post("/config", async (c) => {
2190
2293
  const merged = mergeConfigWithDefaults();
2191
2294
  accountsManager.setAccountAffinityEnabled(isAccountAffinityEnabled());
2192
2295
  accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs());
2296
+ updateQuotaRefreshSchedulerFromConfig();
2193
2297
  applySharedSessionAffinityRetention();
2194
2298
  return c.json({
2195
2299
  ...merged,
@@ -2510,7 +2614,7 @@ adminApiRoutes.post("/accounts/:id/reauth", async (c) => {
2510
2614
  const { oauthApp } = getCurrentIdentityEnvironment();
2511
2615
  const resolvedEnterpriseDomain = (await getAccountClientIdentityByLoginAndApp(accountId, oauthApp))?.enterpriseDomain;
2512
2616
  let enterpriseDomain;
2513
- if (resolvedEnterpriseDomain && resolvedEnterpriseDomain !== DEFAULT_IDENTITY_ENTERPRISE_DOMAIN) enterpriseDomain = resolvedEnterpriseDomain;
2617
+ if (resolvedEnterpriseDomain && resolvedEnterpriseDomain !== "public") enterpriseDomain = resolvedEnterpriseDomain;
2514
2618
  const result = await authSessionManager.startAuth({
2515
2619
  accountType: account.accountType,
2516
2620
  enterpriseDomain,
@@ -2569,14 +2673,14 @@ adminApiRoutes.get("/stats/premium-daily", (c) => {
2569
2673
  message: "Hourly granularity is only supported for ranges up to 35 days.",
2570
2674
  type: "bad_request"
2571
2675
  });
2572
- const result$1 = statsStore.getHourlyPremiumStats({
2676
+ const result = statsStore.getHourlyPremiumStats({
2573
2677
  fromMs,
2574
2678
  toMs,
2575
2679
  accountId
2576
2680
  });
2577
2681
  return c.json({
2578
- daily: result$1.daily,
2579
- by_account: result$1.byAccount,
2682
+ daily: result.daily,
2683
+ by_account: result.byAccount,
2580
2684
  range: {
2581
2685
  from: resolvedFrom,
2582
2686
  to: resolvedTo,
@@ -2600,7 +2704,6 @@ adminApiRoutes.get("/stats/premium-daily", (c) => {
2600
2704
  });
2601
2705
  });
2602
2706
  adminApiRoutes.route("/", replayRoutes);
2603
-
2604
2707
  //#endregion
2605
2708
  //#region src/routes/admin/route.ts
2606
2709
  function resolveAdminDistDir() {
@@ -3239,13 +3342,11 @@ adminRoutes.get("*", async (c) => {
3239
3342
  return c.html(html);
3240
3343
  }
3241
3344
  });
3242
-
3243
3345
  //#endregion
3244
3346
  //#region src/lib/approval.ts
3245
3347
  const awaitApproval = async () => {
3246
3348
  if (!await consola.prompt(`Accept incoming request?`, { type: "confirm" })) throw new HTTPError("Request rejected", Response.json({ message: "Request rejected" }, { status: 403 }));
3247
3349
  };
3248
-
3249
3350
  //#endregion
3250
3351
  //#region src/lib/handler-utils.ts
3251
3352
  function truncate(value, max = 2e3) {
@@ -3354,7 +3455,57 @@ function getUserVisibleErrorMessage(details) {
3354
3455
  function shouldMarkAccountFailed(details) {
3355
3456
  return details.unauthorized && !details.ownershipMismatch && details.upstreamErrorMessageReadFailed !== true;
3356
3457
  }
3357
-
3458
+ //#endregion
3459
+ //#region src/lib/process-cleanup.ts
3460
+ const cleanupHandlers = /* @__PURE__ */ new Set();
3461
+ let cleanupPromise = null;
3462
+ let cleanupState = "idle";
3463
+ let runtimeInitialized$1 = false;
3464
+ function initializeProcessCleanupRuntime() {
3465
+ if (runtimeInitialized$1) return;
3466
+ runtimeInitialized$1 = true;
3467
+ process.once("beforeExit", () => {
3468
+ runProcessCleanups();
3469
+ });
3470
+ process.once("exit", runProcessCleanupsSync);
3471
+ process.once("SIGINT", () => {
3472
+ shutdownProcess(0);
3473
+ });
3474
+ process.once("SIGTERM", () => {
3475
+ shutdownProcess(0);
3476
+ });
3477
+ }
3478
+ function runProcessCleanupsSync() {
3479
+ if (cleanupState !== "idle") return;
3480
+ cleanupState = "done";
3481
+ for (const handler of Array.from(cleanupHandlers)) try {
3482
+ handler();
3483
+ } catch {}
3484
+ }
3485
+ async function runProcessCleanups() {
3486
+ if (cleanupPromise) return cleanupPromise;
3487
+ if (cleanupState === "done") return;
3488
+ cleanupState = "running";
3489
+ cleanupPromise = (async () => {
3490
+ for (const handler of Array.from(cleanupHandlers)) await handler();
3491
+ cleanupState = "done";
3492
+ })();
3493
+ return cleanupPromise;
3494
+ }
3495
+ async function shutdownProcess(exitCode) {
3496
+ try {
3497
+ await runProcessCleanups();
3498
+ } finally {
3499
+ process.exit(exitCode);
3500
+ }
3501
+ }
3502
+ function registerProcessCleanup(handler) {
3503
+ initializeProcessCleanupRuntime();
3504
+ cleanupHandlers.add(handler);
3505
+ return () => {
3506
+ cleanupHandlers.delete(handler);
3507
+ };
3508
+ }
3358
3509
  //#endregion
3359
3510
  //#region src/lib/logger.ts
3360
3511
  const LOG_RETENTION_MS = 10080 * 60 * 1e3;
@@ -3374,9 +3525,6 @@ const logBuffers = /* @__PURE__ */ new Map();
3374
3525
  let runtimeInitialized = false;
3375
3526
  let flushInterval;
3376
3527
  let cleanupInterval;
3377
- let exitHandler;
3378
- let sigintHandler;
3379
- let sigtermHandler;
3380
3528
  const ensureLogDirectory = () => {
3381
3529
  if (!fs$1.existsSync(logDir)) fs$1.mkdirSync(logDir, { recursive: true });
3382
3530
  };
@@ -3454,18 +3602,7 @@ const initializeLoggerRuntime = () => {
3454
3602
  maybeUnref(flushInterval);
3455
3603
  cleanupInterval = setInterval(cleanupOldLogs, CLEANUP_INTERVAL_MS);
3456
3604
  maybeUnref(cleanupInterval);
3457
- exitHandler = cleanup;
3458
- sigintHandler = () => {
3459
- cleanup();
3460
- process.exit(0);
3461
- };
3462
- sigtermHandler = () => {
3463
- cleanup();
3464
- process.exit(0);
3465
- };
3466
- process.once("exit", exitHandler);
3467
- process.once("SIGINT", sigintHandler);
3468
- process.once("SIGTERM", sigtermHandler);
3605
+ registerProcessCleanup(cleanup);
3469
3606
  };
3470
3607
  const getLogStream = (filePath) => {
3471
3608
  initializeLoggerRuntime();
@@ -3502,15 +3639,15 @@ const shouldWriteFileLog = (type, logLevel = resolveLogLevel()) => {
3502
3639
  };
3503
3640
  const resolveLogLevel = () => testLogLevelOverride ?? getLogLevel();
3504
3641
  const isDebugFileLoggingEnabled = () => resolveLogLevel() === "debug";
3505
- const debugLazy = (logger$7, factory) => {
3642
+ const debugLazy = (logger, factory) => {
3506
3643
  if (!isDebugFileLoggingEnabled()) return;
3507
- logger$7.debug(...factory());
3644
+ logger.debug(...factory());
3508
3645
  };
3509
- const debugJson = (logger$7, label, value) => {
3510
- debugLazy(logger$7, () => [label, JSON.stringify(value)]);
3646
+ const debugJson = (logger, label, value) => {
3647
+ debugLazy(logger, () => [label, JSON.stringify(value)]);
3511
3648
  };
3512
- const debugJsonTail = (logger$7, label, { value, tailLength = 400 }) => {
3513
- debugLazy(logger$7, () => [label, JSON.stringify(value).slice(-tailLength)]);
3649
+ const debugJsonTail = (logger, label, { value, tailLength = 400 }) => {
3650
+ debugLazy(logger, () => [label, JSON.stringify(value).slice(-tailLength)]);
3514
3651
  };
3515
3652
  const getConsolaLevel = () => {
3516
3653
  const logLevel = resolveLogLevel();
@@ -3543,33 +3680,31 @@ const createHandlerLogger = (name) => {
3543
3680
  } });
3544
3681
  return instance;
3545
3682
  };
3546
-
3547
3683
  //#endregion
3548
3684
  //#region src/lib/rate-limit.ts
3549
- async function checkRateLimit(state$1) {
3550
- if (state$1.rateLimitSeconds === void 0) return;
3685
+ async function checkRateLimit(state) {
3686
+ if (state.rateLimitSeconds === void 0) return;
3551
3687
  const now = Date.now();
3552
- if (!state$1.lastRequestTimestamp) {
3553
- state$1.lastRequestTimestamp = now;
3688
+ if (!state.lastRequestTimestamp) {
3689
+ state.lastRequestTimestamp = now;
3554
3690
  return;
3555
3691
  }
3556
- const elapsedSeconds = (now - state$1.lastRequestTimestamp) / 1e3;
3557
- if (elapsedSeconds > state$1.rateLimitSeconds) {
3558
- state$1.lastRequestTimestamp = now;
3692
+ const elapsedSeconds = (now - state.lastRequestTimestamp) / 1e3;
3693
+ if (elapsedSeconds > state.rateLimitSeconds) {
3694
+ state.lastRequestTimestamp = now;
3559
3695
  return;
3560
3696
  }
3561
- const waitTimeSeconds = Math.ceil(state$1.rateLimitSeconds - elapsedSeconds);
3562
- if (!state$1.rateLimitWait) {
3697
+ const waitTimeSeconds = Math.ceil(state.rateLimitSeconds - elapsedSeconds);
3698
+ if (!state.rateLimitWait) {
3563
3699
  consola.warn(`Rate limit exceeded. Need to wait ${waitTimeSeconds} more seconds.`);
3564
3700
  throw new HTTPError("Rate limit exceeded", Response.json({ message: "Rate limit exceeded" }, { status: 429 }));
3565
3701
  }
3566
3702
  const waitTimeMs = waitTimeSeconds * 1e3;
3567
3703
  consola.warn(`Rate limit reached. Waiting ${waitTimeSeconds} seconds before proceeding...`);
3568
3704
  await sleep(waitTimeMs);
3569
- state$1.lastRequestTimestamp = now;
3705
+ state.lastRequestTimestamp = now;
3570
3706
  consola.info("Rate limit wait completed, proceeding with request");
3571
3707
  }
3572
-
3573
3708
  //#endregion
3574
3709
  //#region src/routes/chat-completions/support.ts
3575
3710
  const CHAT_COMPLETIONS_ENDPOINT$1 = "/chat/completions";
@@ -3579,13 +3714,13 @@ function buildRequestContext$1(c) {
3579
3714
  const requestId = randomUUID();
3580
3715
  const startedAtMs = Date.now();
3581
3716
  const method = c.req.raw.method;
3582
- const path$2 = new URL(c.req.url, "http://local").pathname;
3717
+ const path = new URL(c.req.url, "http://local").pathname;
3583
3718
  const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
3584
3719
  return {
3585
3720
  requestId,
3586
3721
  startedAtMs,
3587
3722
  method,
3588
- path: path$2,
3723
+ path,
3589
3724
  clientIp,
3590
3725
  clientIpSource,
3591
3726
  userAgent: c.req.header("user-agent") ?? void 0
@@ -3678,7 +3813,6 @@ function selectionFailureResponse$2(c, params) {
3678
3813
  type: "rate_limit_error"
3679
3814
  } }, 429);
3680
3815
  }
3681
-
3682
3816
  //#endregion
3683
3817
  //#region src/routes/chat-completions/handler.ts
3684
3818
  const logger$6 = createHandlerLogger("chat-completions-handler");
@@ -3746,7 +3880,7 @@ async function handleCompletion$1(c) {
3746
3880
  request.selectionReason = selection.selectionReason;
3747
3881
  const premiumRemainingBefore = account.premiumRemaining;
3748
3882
  const premiumUnlimitedBefore = account.unlimited;
3749
- if (selectedModel.id === GPT_5_4_MODEL_ID) {
3883
+ if (selectedModel.id === "gpt-5.4") {
3750
3884
  await accountsManager.finalizeQuota(account, reservation);
3751
3885
  recordUnsupportedChatCompletionsModel(store, {
3752
3886
  request,
@@ -4136,7 +4270,6 @@ async function handleNonStreamingRequest(params) {
4136
4270
  }
4137
4271
  }
4138
4272
  const isNonStreaming$1 = (response) => Object.hasOwn(response, "choices");
4139
-
4140
4273
  //#endregion
4141
4274
  //#region src/routes/chat-completions/route.ts
4142
4275
  const completionRoutes = new Hono();
@@ -4147,7 +4280,6 @@ completionRoutes.post("/", async (c) => {
4147
4280
  return await forwardError(c, error);
4148
4281
  }
4149
4282
  });
4150
-
4151
4283
  //#endregion
4152
4284
  //#region src/services/copilot/create-embeddings.ts
4153
4285
  const createEmbeddings = async (payload, account, options) => {
@@ -4167,7 +4299,6 @@ const createEmbeddings = async (payload, account, options) => {
4167
4299
  if (!response.ok) throw new HTTPError("Failed to create embeddings", response);
4168
4300
  return await response.json();
4169
4301
  };
4170
-
4171
4302
  //#endregion
4172
4303
  //#region src/routes/embeddings/route.ts
4173
4304
  const embeddingRoutes = new Hono();
@@ -4178,13 +4309,13 @@ embeddingRoutes.post("/", async (c) => {
4178
4309
  const requestId = randomUUID();
4179
4310
  const startedAtMs = Date.now();
4180
4311
  const method = c.req.raw.method;
4181
- const path$2 = new URL(c.req.url, "http://local").pathname;
4312
+ const path = new URL(c.req.url, "http://local").pathname;
4182
4313
  const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
4183
4314
  const ctx = {
4184
4315
  requestId,
4185
4316
  startedAtMs,
4186
4317
  method,
4187
- path: path$2,
4318
+ path,
4188
4319
  clientIp,
4189
4320
  clientIpSource,
4190
4321
  userAgent: c.req.header("user-agent") ?? void 0
@@ -4318,9 +4449,99 @@ async function runEmbeddingsWithAccount({ c, store, ctx, payload, clientModel, s
4318
4449
  });
4319
4450
  }
4320
4451
  }
4321
-
4452
+ //#endregion
4453
+ //#region src/lib/provider-model.ts
4454
+ const parseProviderModelAlias = (model) => {
4455
+ const separatorIndex = model.indexOf("/");
4456
+ if (separatorIndex <= 0 || separatorIndex === model.length - 1) return null;
4457
+ const provider = model.slice(0, separatorIndex).trim();
4458
+ const providerModel = model.slice(separatorIndex + 1).trim();
4459
+ if (!provider || !providerModel) return null;
4460
+ return {
4461
+ model: providerModel,
4462
+ provider
4463
+ };
4464
+ };
4465
+ const createFallbackModel = (modelId) => ({
4466
+ capabilities: {
4467
+ family: "provider",
4468
+ limits: {},
4469
+ object: "model_capabilities",
4470
+ supports: {},
4471
+ tokenizer: "o200k_base",
4472
+ type: "chat"
4473
+ },
4474
+ id: modelId,
4475
+ model_picker_enabled: false,
4476
+ name: modelId,
4477
+ object: "model",
4478
+ preview: false,
4479
+ vendor: "provider",
4480
+ version: "unknown"
4481
+ });
4482
+ //#endregion
4483
+ //#region src/routes/provider/messages/count-tokens-handler.ts
4484
+ const logger$5 = createHandlerLogger("provider-count-tokens-handler");
4485
+ const resolveProviderConfig$2 = (c, provider) => {
4486
+ return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
4487
+ };
4488
+ async function handleProviderCountTokens(c) {
4489
+ const provider = c.req.param("provider");
4490
+ return await handleProviderCountTokensForProvider(c, {
4491
+ payload: await c.req.json(),
4492
+ provider
4493
+ });
4494
+ }
4495
+ async function handleProviderCountTokensForProvider(c, options) {
4496
+ const { payload: anthropicPayload, provider } = options;
4497
+ const providerConfig = resolveProviderConfig$2(c, provider);
4498
+ if (!providerConfig) return c.json({ error: {
4499
+ message: `Provider '${provider}' not found or disabled`,
4500
+ type: "invalid_request_error"
4501
+ } }, 404);
4502
+ if (typeof anthropicPayload.model !== "string" || !Array.isArray(anthropicPayload.messages)) return c.json({ error: {
4503
+ message: "Invalid Anthropic messages count_tokens payload",
4504
+ type: "invalid_request_error"
4505
+ } }, 400);
4506
+ const modelId = anthropicPayload.model.trim();
4507
+ const modelConfig = providerConfig.models?.[modelId];
4508
+ const translationOptions = providerConfig.type === "openai-compatible" ? {
4509
+ supportPdf: modelConfig?.supportPdf,
4510
+ toolContentSupportType: modelConfig?.toolContentSupportType ?? []
4511
+ } : void 0;
4512
+ try {
4513
+ const tokenCount = await getTokenCount(translateToOpenAI(anthropicPayload, translationOptions), findEndpointModel(modelId) ?? createFallbackModel(modelId));
4514
+ const finalTokenCount = tokenCount.input + tokenCount.output;
4515
+ logger$5.debug("provider.count_tokens.success", {
4516
+ provider,
4517
+ model: anthropicPayload.model,
4518
+ input_tokens: finalTokenCount
4519
+ });
4520
+ return c.json({ input_tokens: finalTokenCount });
4521
+ } catch (error) {
4522
+ logger$5.error("provider.count_tokens.error", {
4523
+ provider,
4524
+ error
4525
+ });
4526
+ return c.json({ error: {
4527
+ message: "Failed to count provider tokens",
4528
+ type: "internal_server_error"
4529
+ } }, 500);
4530
+ }
4531
+ }
4322
4532
  //#endregion
4323
4533
  //#region src/routes/messages/count-tokens-handler.ts
4534
+ const resolveCountTokensModel = (modelId, findModel = findEndpointModel) => {
4535
+ const selectedModel = findModel(modelId);
4536
+ if (selectedModel) return {
4537
+ fallback: false,
4538
+ model: selectedModel
4539
+ };
4540
+ return {
4541
+ fallback: true,
4542
+ model: createFallbackModel(modelId.trim())
4543
+ };
4544
+ };
4324
4545
  /**
4325
4546
  * Forwards token counting to Anthropic's real /v1/messages/count_tokens endpoint.
4326
4547
  * Returns the result on success, or null to fall through to estimation.
@@ -4359,43 +4580,44 @@ async function countTokensViaAnthropic(c, payload) {
4359
4580
  * endpoint for accurate counts. Otherwise falls back to GPT tokenizer estimation.
4360
4581
  */
4361
4582
  async function handleCountTokens(c) {
4362
- try {
4363
- const anthropicPayload = await c.req.json();
4364
- const anthropicResult = await countTokensViaAnthropic(c, anthropicPayload);
4365
- if (anthropicResult) return anthropicResult;
4366
- const anthropicBeta = c.req.header("anthropic-beta");
4367
- const openAIPayload = translateToOpenAI(anthropicPayload);
4368
- const selectedModel = findEndpointModel(anthropicPayload.model);
4369
- anthropicPayload.model = selectedModel?.id ?? anthropicPayload.model;
4370
- if (!selectedModel) {
4371
- consola.warn("Model not found, returning default token count");
4372
- return c.json({ input_tokens: 1 });
4583
+ const anthropicPayload = await c.req.json();
4584
+ const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
4585
+ if (providerModelAlias) {
4586
+ anthropicPayload.model = providerModelAlias.model;
4587
+ return await handleProviderCountTokensForProvider(c, {
4588
+ payload: anthropicPayload,
4589
+ provider: providerModelAlias.provider
4590
+ });
4591
+ }
4592
+ const anthropicResult = await countTokensViaAnthropic(c, anthropicPayload);
4593
+ if (anthropicResult) return anthropicResult;
4594
+ const anthropicBeta = c.req.header("anthropic-beta");
4595
+ const openAIPayload = translateToOpenAI(anthropicPayload);
4596
+ const requestedModel = anthropicPayload.model;
4597
+ const resolve = resolveCountTokensModel(requestedModel);
4598
+ const selectedModel = resolve.model;
4599
+ anthropicPayload.model = selectedModel.id;
4600
+ if (resolve.fallback) consola.warn(`Model '${requestedModel}' not found, using o200k_base fallback tokenizer`);
4601
+ const tokenCount = await getTokenCount(openAIPayload, selectedModel);
4602
+ if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {
4603
+ let addToolSystemPromptCount = false;
4604
+ if (anthropicBeta) {
4605
+ const toolsLength = anthropicPayload.tools.length;
4606
+ addToolSystemPromptCount = !anthropicPayload.tools.some((tool) => tool.name.startsWith("mcp__") || tool.name === "Skill" && toolsLength === 1);
4373
4607
  }
4374
- const tokenCount = await getTokenCount(openAIPayload, selectedModel);
4375
- if (anthropicPayload.tools && anthropicPayload.tools.length > 0) {
4376
- let addToolSystemPromptCount = false;
4377
- if (anthropicBeta) {
4378
- const toolsLength = anthropicPayload.tools.length;
4379
- addToolSystemPromptCount = !anthropicPayload.tools.some((tool) => tool.name.startsWith("mcp__") || tool.name === "Skill" && toolsLength === 1);
4380
- }
4381
- if (addToolSystemPromptCount) {
4382
- if (anthropicPayload.model.startsWith("claude")) tokenCount.input = tokenCount.input + 346;
4383
- else if (anthropicPayload.model.startsWith("grok")) tokenCount.input = tokenCount.input + 120;
4384
- }
4608
+ if (addToolSystemPromptCount) {
4609
+ if (anthropicPayload.model.startsWith("claude")) tokenCount.input = tokenCount.input + 346;
4610
+ else if (anthropicPayload.model.startsWith("grok")) tokenCount.input = tokenCount.input + 120;
4385
4611
  }
4386
- let finalTokenCount = tokenCount.input + tokenCount.output;
4387
- if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount * getClaudeTokenMultiplier());
4388
- consola.info("Token count:", finalTokenCount);
4389
- return c.json({ input_tokens: finalTokenCount });
4390
- } catch (error) {
4391
- consola.error("Error counting tokens:", error);
4392
- return c.json({ input_tokens: 1 });
4393
4612
  }
4613
+ let finalTokenCount = tokenCount.input + tokenCount.output;
4614
+ if (anthropicPayload.model.startsWith("claude")) finalTokenCount = Math.round(finalTokenCount * getClaudeTokenMultiplier());
4615
+ consola.info("Token count:", finalTokenCount);
4616
+ return c.json({ input_tokens: finalTokenCount });
4394
4617
  }
4395
-
4396
4618
  //#endregion
4397
4619
  //#region src/services/copilot/create-responses.ts
4398
- const createResponses = async (payload, { vision, initiator, upstreamRequestId, subagentMarker, sessionId, compactType, requestId }, account) => {
4620
+ const createResponses = async (payload, { vision, initiator, upstreamRequestId, subagentMarker, sessionId, compactType, requestId, fetchImpl }, account) => {
4399
4621
  const ctx = account ?? accountFromState();
4400
4622
  if (!ctx.copilotToken) throw new Error("Copilot token not found");
4401
4623
  const effectiveInitiator = resolveEffectiveInitiator(initiator, {
@@ -4416,7 +4638,8 @@ const createResponses = async (payload, { vision, initiator, upstreamRequestId,
4416
4638
  body: JSON.stringify(payload)
4417
4639
  }, {
4418
4640
  requestId,
4419
- callSite: "responses"
4641
+ callSite: "responses",
4642
+ fetchImpl
4420
4643
  });
4421
4644
  logCopilotRateLimits(response.headers);
4422
4645
  if (!response.ok) {
@@ -4426,13 +4649,12 @@ const createResponses = async (payload, { vision, initiator, upstreamRequestId,
4426
4649
  if (payload.stream) return events(response);
4427
4650
  return await response.json();
4428
4651
  };
4429
-
4430
4652
  //#endregion
4431
4653
  //#region src/routes/messages/responses-translation.ts
4432
4654
  const MESSAGE_TYPE = "message";
4433
4655
  const COMPACTION_SIGNATURE_PREFIX = "cm1#";
4434
4656
  const COMPACTION_SIGNATURE_SEPARATOR = "@";
4435
- const THINKING_TEXT$1 = "Thinking...";
4657
+ const THINKING_TEXT = "Thinking...";
4436
4658
  const translateAnthropicMessagesToResponsesPayload = (payload, modelOverride) => {
4437
4659
  const model = modelOverride ?? payload.model;
4438
4660
  const input = [];
@@ -4598,8 +4820,8 @@ const createFileContent = (block) => ({
4598
4820
  filename: block.title ?? "document.pdf"
4599
4821
  });
4600
4822
  const createReasoningContent = (block) => {
4601
- const { encryptedContent, id } = parseReasoningSignature(block.signature);
4602
- const thinking = block.thinking === THINKING_TEXT$1 ? "" : block.thinking;
4823
+ const { encryptedContent, id } = parseReasoningSignature$1(block.signature);
4824
+ const thinking = block.thinking === "Thinking..." ? "" : block.thinking;
4603
4825
  return {
4604
4826
  id,
4605
4827
  type: "reasoning",
@@ -4619,7 +4841,7 @@ const createCompactionContent = (block) => {
4619
4841
  encrypted_content: compaction.encrypted_content
4620
4842
  };
4621
4843
  };
4622
- const parseReasoningSignature = (signature) => {
4844
+ const parseReasoningSignature$1 = (signature) => {
4623
4845
  const splitIndex = signature.lastIndexOf("@");
4624
4846
  if (splitIndex <= 0 || splitIndex === signature.length - 1) return {
4625
4847
  encryptedContent: signature,
@@ -4765,7 +4987,7 @@ const extractReasoningText = (item) => {
4765
4987
  continue;
4766
4988
  }
4767
4989
  };
4768
- if (!item.summary || item.summary.length === 0) return THINKING_TEXT$1;
4990
+ if (!item.summary || item.summary.length === 0) return THINKING_TEXT;
4769
4991
  collectFromBlocks(item.summary);
4770
4992
  return segments.join("").trim();
4771
4993
  };
@@ -4784,7 +5006,7 @@ const createCompactionThinkingBlock = (item) => {
4784
5006
  if (!item.id || !item.encrypted_content) return null;
4785
5007
  return {
4786
5008
  type: "thinking",
4787
- thinking: THINKING_TEXT$1,
5009
+ thinking: THINKING_TEXT,
4788
5010
  signature: encodeCompactionCarrierSignature({
4789
5011
  id: item.id,
4790
5012
  encrypted_content: item.encrypted_content
@@ -4859,107 +5081,969 @@ const convertToolResultContent = (content) => {
4859
5081
  }
4860
5082
  return "";
4861
5083
  };
4862
-
4863
5084
  //#endregion
4864
- //#region src/routes/messages/responses-stream-translation.ts
4865
- const MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20;
4866
- var FunctionCallArgumentsValidationError = class extends Error {
4867
- constructor(message) {
4868
- super(message);
4869
- this.name = "FunctionCallArgumentsValidationError";
4870
- }
4871
- };
4872
- const updateWhitespaceRunState = (previousCount, chunk) => {
4873
- let count = previousCount;
4874
- for (const char of chunk) {
4875
- if (char === "\r" || char === "\n" || char === " ") {
4876
- count += 1;
4877
- if (count > MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE) return {
4878
- nextCount: count,
4879
- exceeded: true
4880
- };
4881
- continue;
5085
+ //#region src/routes/messages/responses-item-ownership.ts
5086
+ function buildResponsesItemOwnershipKey(kind, value) {
5087
+ return `responses-item-owner:${kind}:${createHash("sha256").update(value).digest("hex")}`;
5088
+ }
5089
+ function extractAnthropicResponsesItemOwnerKeys(payload) {
5090
+ const keys = [];
5091
+ for (const message of payload.messages) {
5092
+ if (message.role !== "assistant" || !Array.isArray(message.content)) continue;
5093
+ for (const block of message.content) {
5094
+ if (block.type !== "thinking" || !block.signature) continue;
5095
+ addSignatureOwnerKeys(keys, block.signature);
4882
5096
  }
4883
- if (char !== " ") count = 0;
4884
5097
  }
5098
+ return unique(keys);
5099
+ }
5100
+ function extractResponsesResultOwnerKeys(result) {
5101
+ const keys = [];
5102
+ for (const item of result.output) addOutputItemOwnerKeys(keys, item);
5103
+ return unique(keys);
5104
+ }
5105
+ function extractResponsesStreamEventOwnerKeys(event) {
5106
+ if (event.type === "response.output_item.done") {
5107
+ const keys = [];
5108
+ addOutputItemOwnerKeys(keys, event.item);
5109
+ return unique(keys);
5110
+ }
5111
+ if (event.type === "response.completed" || event.type === "response.incomplete") return extractResponsesResultOwnerKeys(event.response);
5112
+ return [];
5113
+ }
5114
+ function addSignatureOwnerKeys(keys, signature) {
5115
+ if (signature.startsWith("cm1#")) {
5116
+ const compaction = decodeCompactionCarrierSignature(signature);
5117
+ if (compaction) addRawOwnerKeys(keys, compaction.id, compaction.encrypted_content);
5118
+ return;
5119
+ }
5120
+ const reasoning = parseReasoningSignature(signature);
5121
+ if (!reasoning) return;
5122
+ addRawOwnerKeys(keys, reasoning.id, reasoning.encryptedContent);
5123
+ }
5124
+ function parseReasoningSignature(signature) {
5125
+ const splitIndex = signature.lastIndexOf("@");
5126
+ if (splitIndex <= 0 || splitIndex === signature.length - 1) return;
4885
5127
  return {
4886
- nextCount: count,
4887
- exceeded: false
5128
+ encryptedContent: signature.slice(0, splitIndex),
5129
+ id: signature.slice(splitIndex + 1)
4888
5130
  };
4889
- };
4890
- const createResponsesStreamState = () => ({
4891
- messageStartSent: false,
4892
- messageCompleted: false,
4893
- nextContentBlockIndex: 0,
4894
- blockIndexByKey: /* @__PURE__ */ new Map(),
4895
- openBlocks: /* @__PURE__ */ new Set(),
4896
- blockHasDelta: /* @__PURE__ */ new Set(),
4897
- functionCallStateByOutputIndex: /* @__PURE__ */ new Map()
4898
- });
4899
- const translateResponsesStreamEvent = (rawEvent, state$1) => {
4900
- switch (rawEvent.type) {
4901
- case "response.created": return handleResponseCreated(rawEvent, state$1);
4902
- case "response.output_item.added": return handleOutputItemAdded$1(rawEvent, state$1);
4903
- case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state$1);
4904
- case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state$1);
4905
- case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state$1);
4906
- case "response.output_text.done": return handleOutputTextDone(rawEvent, state$1);
4907
- case "response.output_item.done": return handleOutputItemDone$1(rawEvent, state$1);
4908
- case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state$1);
4909
- case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state$1);
4910
- case "response.completed":
4911
- case "response.incomplete": return handleResponseCompleted(rawEvent, state$1);
4912
- case "response.failed": return handleResponseFailed(rawEvent, state$1);
4913
- case "error": return handleErrorEvent(rawEvent, state$1);
4914
- default: return [];
5131
+ }
5132
+ function addOutputItemOwnerKeys(keys, item) {
5133
+ if (!isOwnerBearingOutputItem(item)) return;
5134
+ addRawOwnerKeys(keys, item.id, item.encrypted_content);
5135
+ }
5136
+ function isOwnerBearingOutputItem(item) {
5137
+ return item.type === "reasoning" || item.type === "compaction";
5138
+ }
5139
+ function addRawOwnerKeys(keys, id, encryptedContent) {
5140
+ if (id) keys.push(buildResponsesItemOwnershipKey("id", id));
5141
+ if (encryptedContent) keys.push(buildResponsesItemOwnershipKey("encrypted_content", encryptedContent));
5142
+ }
5143
+ function unique(values) {
5144
+ return [...new Set(values)];
5145
+ }
5146
+ //#endregion
5147
+ //#region src/routes/messages/stream-translation.ts
5148
+ function isToolBlockOpen(state) {
5149
+ if (!state.contentBlockOpen) return false;
5150
+ return Object.values(state.toolCalls).some((tc) => tc.anthropicBlockIndex === state.contentBlockIndex);
5151
+ }
5152
+ function translateChunkToAnthropicEvents(chunk, state) {
5153
+ const events = [];
5154
+ if (chunk.choices.length === 0) {
5155
+ completePendingMessage(state, events, chunk);
5156
+ return events;
4915
5157
  }
4916
- };
4917
- const handleResponseCreated = (rawEvent, state$1) => {
4918
- return messageStart(state$1, rawEvent.response);
4919
- };
4920
- const handleOutputItemAdded$1 = (rawEvent, state$1) => {
4921
- const events$1 = new Array();
4922
- const functionCallDetails = extractFunctionCallDetails(rawEvent);
4923
- if (!functionCallDetails) return events$1;
4924
- const { outputIndex, toolCallId, name, initialArguments } = functionCallDetails;
4925
- const blockIndex = openFunctionCallBlock(state$1, {
4926
- outputIndex,
4927
- toolCallId,
4928
- name,
4929
- events: events$1
5158
+ const choice = chunk.choices[0];
5159
+ const { delta } = choice;
5160
+ handleMessageStart(state, events, chunk);
5161
+ handleThinkingText(delta, state, events);
5162
+ handleContent(delta, state, events);
5163
+ handleToolCalls(delta, state, events);
5164
+ handleFinish(choice, state, {
5165
+ events,
5166
+ chunk
4930
5167
  });
4931
- if (initialArguments !== void 0 && initialArguments.length > 0) {
4932
- events$1.push({
4933
- type: "content_block_delta",
4934
- index: blockIndex,
5168
+ return events;
5169
+ }
5170
+ function flushPendingAnthropicStreamEvents(state) {
5171
+ const events = [];
5172
+ completePendingMessage(state, events);
5173
+ return events;
5174
+ }
5175
+ function completePendingMessage(state, events, chunk) {
5176
+ if (!state.pendingMessageDelta) return;
5177
+ if (chunk?.usage) state.pendingMessageDelta.usage = getAnthropicUsageFromOpenAIChunk(chunk, state);
5178
+ events.push(state.pendingMessageDelta, { type: "message_stop" });
5179
+ state.pendingMessageDelta = void 0;
5180
+ }
5181
+ function handleFinish(choice, state, context) {
5182
+ const { events, chunk } = context;
5183
+ if (choice.finish_reason && choice.finish_reason.length > 0) {
5184
+ if (state.contentBlockOpen) {
5185
+ const toolBlockOpen = isToolBlockOpen(state);
5186
+ context.events.push({
5187
+ type: "content_block_stop",
5188
+ index: state.contentBlockIndex
5189
+ });
5190
+ state.contentBlockOpen = false;
5191
+ state.contentBlockIndex++;
5192
+ if (!toolBlockOpen) handleReasoningOpaque(choice.delta, events, state);
5193
+ }
5194
+ flushDeferredContent(state, events);
5195
+ state.pendingMessageDelta = {
5196
+ type: "message_delta",
4935
5197
  delta: {
4936
- type: "input_json_delta",
4937
- partial_json: initialArguments
4938
- }
4939
- });
4940
- state$1.blockHasDelta.add(blockIndex);
5198
+ stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
5199
+ stop_sequence: null
5200
+ },
5201
+ usage: getAnthropicUsageFromOpenAIChunk(chunk, state)
5202
+ };
5203
+ if (chunk.usage) completePendingMessage(state, events, chunk);
4941
5204
  }
4942
- return events$1;
4943
- };
4944
- const handleOutputItemDone$1 = (rawEvent, state$1) => {
4945
- const events$1 = new Array();
4946
- const item = rawEvent.item;
4947
- const itemType = item.type;
4948
- const outputIndex = rawEvent.output_index;
4949
- if (itemType === "compaction") {
4950
- if (!item.id || !item.encrypted_content) return events$1;
4951
- const blockIndex$1 = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
4952
- if (!state$1.blockHasDelta.has(blockIndex$1)) events$1.push({
4953
- type: "content_block_delta",
4954
- index: blockIndex$1,
4955
- delta: {
4956
- type: "thinking_delta",
4957
- thinking: THINKING_TEXT$1
4958
- }
4959
- });
4960
- events$1.push({
4961
- type: "content_block_delta",
4962
- index: blockIndex$1,
5205
+ }
5206
+ function getAnthropicUsageFromOpenAIChunk(chunk, state) {
5207
+ const { cacheCreationTokens, inputTokens, cacheReadTokens } = getOpenAIChunkUsageTokens(chunk, state);
5208
+ return {
5209
+ input_tokens: inputTokens,
5210
+ output_tokens: chunk.usage?.completion_tokens ?? 0,
5211
+ ...chunk.usage?.prompt_tokens_details?.cache_creation_input_tokens !== void 0 && { cache_creation_input_tokens: cacheCreationTokens },
5212
+ ...cacheReadTokens !== void 0 && { cache_read_input_tokens: cacheReadTokens }
5213
+ };
5214
+ }
5215
+ function getOpenAIChunkUsageTokens(chunk, state) {
5216
+ const promptTokens = chunk.usage?.prompt_tokens;
5217
+ const cachedTokens = chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0;
5218
+ const cacheCreationTokens = chunk.usage?.prompt_tokens_details?.cache_creation_input_tokens ?? 0;
5219
+ if (promptTokens !== void 0) return {
5220
+ cacheCreationTokens,
5221
+ cachedTokens,
5222
+ inputTokens: Math.max(0, promptTokens - cachedTokens - cacheCreationTokens),
5223
+ cacheReadTokens: chunk.usage?.prompt_tokens_details?.cached_tokens
5224
+ };
5225
+ const historicalInputTokens = state?.historicalInputTokens;
5226
+ const historicalOutputTokens = state?.historicalOutputTokens ?? 0;
5227
+ return {
5228
+ cacheCreationTokens,
5229
+ cachedTokens,
5230
+ inputTokens: (historicalInputTokens !== void 0 ? historicalInputTokens + historicalOutputTokens : void 0) ?? state?.estimatedInputTokens ?? 0,
5231
+ cacheReadTokens: state?.historicalCachedInputTokens
5232
+ };
5233
+ }
5234
+ function handleToolCalls(delta, state, events) {
5235
+ if (delta.tool_calls && delta.tool_calls.length > 0) {
5236
+ closeThinkingBlockIfOpen(state, events);
5237
+ handleReasoningOpaqueInToolCalls(state, events, delta);
5238
+ for (const toolCall of delta.tool_calls) {
5239
+ if (toolCall.id && toolCall.function?.name) {
5240
+ if (state.contentBlockOpen) {
5241
+ events.push({
5242
+ type: "content_block_stop",
5243
+ index: state.contentBlockIndex
5244
+ });
5245
+ state.contentBlockIndex++;
5246
+ state.contentBlockOpen = false;
5247
+ }
5248
+ const anthropicBlockIndex = state.contentBlockIndex;
5249
+ state.toolCalls[toolCall.index] = {
5250
+ id: toolCall.id,
5251
+ name: toolCall.function.name,
5252
+ anthropicBlockIndex
5253
+ };
5254
+ events.push({
5255
+ type: "content_block_start",
5256
+ index: anthropicBlockIndex,
5257
+ content_block: {
5258
+ type: "tool_use",
5259
+ id: toolCall.id,
5260
+ name: toolCall.function.name,
5261
+ input: {}
5262
+ }
5263
+ });
5264
+ state.contentBlockOpen = true;
5265
+ }
5266
+ if (toolCall.function?.arguments) {
5267
+ const toolCallInfo = state.toolCalls[toolCall.index];
5268
+ if (toolCallInfo) events.push({
5269
+ type: "content_block_delta",
5270
+ index: toolCallInfo.anthropicBlockIndex,
5271
+ delta: {
5272
+ type: "input_json_delta",
5273
+ partial_json: toolCall.function.arguments
5274
+ }
5275
+ });
5276
+ }
5277
+ }
5278
+ }
5279
+ }
5280
+ function handleReasoningOpaqueInToolCalls(state, events, delta) {
5281
+ if (state.contentBlockOpen && !isToolBlockOpen(state)) {
5282
+ events.push({
5283
+ type: "content_block_stop",
5284
+ index: state.contentBlockIndex
5285
+ });
5286
+ state.contentBlockIndex++;
5287
+ state.contentBlockOpen = false;
5288
+ }
5289
+ handleReasoningOpaque(delta, events, state);
5290
+ }
5291
+ function handleContent(delta, state, events) {
5292
+ if (delta.content && delta.content.length > 0) {
5293
+ closeThinkingBlockIfOpen(state, events);
5294
+ if (isToolBlockOpen(state) || hasToolCallDelta(delta)) {
5295
+ state.deferredContent = `${state.deferredContent ?? ""}${delta.content}`;
5296
+ return;
5297
+ }
5298
+ if (!state.contentBlockOpen) {
5299
+ events.push({
5300
+ type: "content_block_start",
5301
+ index: state.contentBlockIndex,
5302
+ content_block: {
5303
+ type: "text",
5304
+ text: ""
5305
+ }
5306
+ });
5307
+ state.contentBlockOpen = true;
5308
+ }
5309
+ events.push({
5310
+ type: "content_block_delta",
5311
+ index: state.contentBlockIndex,
5312
+ delta: {
5313
+ type: "text_delta",
5314
+ text: delta.content
5315
+ }
5316
+ });
5317
+ }
5318
+ if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state.thinkingBlockOpen) {
5319
+ events.push({
5320
+ type: "content_block_delta",
5321
+ index: state.contentBlockIndex,
5322
+ delta: {
5323
+ type: "signature_delta",
5324
+ signature: delta.reasoning_opaque
5325
+ }
5326
+ }, {
5327
+ type: "content_block_stop",
5328
+ index: state.contentBlockIndex
5329
+ });
5330
+ state.contentBlockIndex++;
5331
+ state.thinkingBlockOpen = false;
5332
+ }
5333
+ }
5334
+ function hasToolCallDelta(delta) {
5335
+ return Boolean(delta.tool_calls && delta.tool_calls.length > 0);
5336
+ }
5337
+ function flushDeferredContent(state, events) {
5338
+ if (!state.deferredContent) return;
5339
+ if (!state.contentBlockOpen) {
5340
+ events.push({
5341
+ type: "content_block_start",
5342
+ index: state.contentBlockIndex,
5343
+ content_block: {
5344
+ type: "text",
5345
+ text: ""
5346
+ }
5347
+ });
5348
+ state.contentBlockOpen = true;
5349
+ }
5350
+ events.push({
5351
+ type: "content_block_delta",
5352
+ index: state.contentBlockIndex,
5353
+ delta: {
5354
+ type: "text_delta",
5355
+ text: state.deferredContent
5356
+ }
5357
+ }, {
5358
+ type: "content_block_stop",
5359
+ index: state.contentBlockIndex
5360
+ });
5361
+ state.deferredContent = void 0;
5362
+ state.contentBlockOpen = false;
5363
+ state.contentBlockIndex++;
5364
+ }
5365
+ function handleMessageStart(state, events, chunk) {
5366
+ if (!state.messageStartSent) {
5367
+ const { cacheCreationTokens, inputTokens, cacheReadTokens } = getOpenAIChunkUsageTokens(chunk, state);
5368
+ events.push({
5369
+ type: "message_start",
5370
+ message: {
5371
+ id: chunk.id,
5372
+ type: "message",
5373
+ role: "assistant",
5374
+ content: [],
5375
+ model: chunk.model,
5376
+ stop_reason: null,
5377
+ stop_sequence: null,
5378
+ usage: {
5379
+ input_tokens: inputTokens,
5380
+ output_tokens: 0,
5381
+ ...chunk.usage?.prompt_tokens_details?.cache_creation_input_tokens !== void 0 && { cache_creation_input_tokens: cacheCreationTokens },
5382
+ ...cacheReadTokens !== void 0 && { cache_read_input_tokens: cacheReadTokens }
5383
+ }
5384
+ }
5385
+ });
5386
+ state.messageStartSent = true;
5387
+ }
5388
+ }
5389
+ function handleReasoningOpaque(delta, events, state) {
5390
+ if (delta.reasoning_opaque && delta.reasoning_opaque.length > 0) {
5391
+ events.push({
5392
+ type: "content_block_start",
5393
+ index: state.contentBlockIndex,
5394
+ content_block: {
5395
+ type: "thinking",
5396
+ thinking: ""
5397
+ }
5398
+ }, {
5399
+ type: "content_block_delta",
5400
+ index: state.contentBlockIndex,
5401
+ delta: {
5402
+ type: "thinking_delta",
5403
+ thinking: THINKING_TEXT$1
5404
+ }
5405
+ }, {
5406
+ type: "content_block_delta",
5407
+ index: state.contentBlockIndex,
5408
+ delta: {
5409
+ type: "signature_delta",
5410
+ signature: delta.reasoning_opaque
5411
+ }
5412
+ }, {
5413
+ type: "content_block_stop",
5414
+ index: state.contentBlockIndex
5415
+ });
5416
+ state.contentBlockIndex++;
5417
+ }
5418
+ }
5419
+ function handleThinkingText(delta, state, events) {
5420
+ const reasoningText = delta.reasoning_text ?? delta.reasoning_content;
5421
+ if (reasoningText && reasoningText.length > 0) {
5422
+ if (state.contentBlockOpen) {
5423
+ delta.content = reasoningText;
5424
+ delta.reasoning_text = void 0;
5425
+ delta.reasoning_content = void 0;
5426
+ return;
5427
+ }
5428
+ if (!state.thinkingBlockOpen) {
5429
+ events.push({
5430
+ type: "content_block_start",
5431
+ index: state.contentBlockIndex,
5432
+ content_block: {
5433
+ type: "thinking",
5434
+ thinking: ""
5435
+ }
5436
+ });
5437
+ state.thinkingBlockOpen = true;
5438
+ }
5439
+ events.push({
5440
+ type: "content_block_delta",
5441
+ index: state.contentBlockIndex,
5442
+ delta: {
5443
+ type: "thinking_delta",
5444
+ thinking: reasoningText
5445
+ }
5446
+ });
5447
+ }
5448
+ }
5449
+ function closeThinkingBlockIfOpen(state, events) {
5450
+ if (state.thinkingBlockOpen) {
5451
+ events.push({
5452
+ type: "content_block_delta",
5453
+ index: state.contentBlockIndex,
5454
+ delta: {
5455
+ type: "signature_delta",
5456
+ signature: ""
5457
+ }
5458
+ }, {
5459
+ type: "content_block_stop",
5460
+ index: state.contentBlockIndex
5461
+ });
5462
+ state.contentBlockIndex++;
5463
+ state.thinkingBlockOpen = false;
5464
+ }
5465
+ }
5466
+ //#endregion
5467
+ //#region src/services/providers/anthropic-proxy.ts
5468
+ const SHARED_FORWARDABLE_HEADERS = ["accept", "user-agent"];
5469
+ const ANTHROPIC_FORWARDABLE_HEADERS = ["anthropic-version", "anthropic-beta"];
5470
+ const STRIPPED_RESPONSE_HEADERS = [
5471
+ "connection",
5472
+ "content-encoding",
5473
+ "content-length",
5474
+ "keep-alive",
5475
+ "proxy-authenticate",
5476
+ "proxy-authorization",
5477
+ "te",
5478
+ "trailer",
5479
+ "transfer-encoding",
5480
+ "upgrade"
5481
+ ];
5482
+ function buildProviderUpstreamHeaders(providerConfig, requestHeaders) {
5483
+ const authHeaders = {};
5484
+ if (providerConfig.authType === "authorization") authHeaders.authorization = `Bearer ${providerConfig.apiKey}`;
5485
+ else authHeaders["x-api-key"] = providerConfig.apiKey;
5486
+ const headers = {
5487
+ "content-type": "application/json",
5488
+ accept: "application/json",
5489
+ ...authHeaders
5490
+ };
5491
+ for (const headerName of SHARED_FORWARDABLE_HEADERS) {
5492
+ const headerValue = requestHeaders.get(headerName);
5493
+ if (headerValue) headers[headerName] = headerValue;
5494
+ }
5495
+ if (providerConfig.type !== "anthropic") return headers;
5496
+ for (const headerName of ANTHROPIC_FORWARDABLE_HEADERS) {
5497
+ const headerValue = requestHeaders.get(headerName);
5498
+ if (headerValue) headers[headerName] = headerValue;
5499
+ }
5500
+ return headers;
5501
+ }
5502
+ function createProviderProxyResponse(upstreamResponse) {
5503
+ const headers = new Headers(upstreamResponse.headers);
5504
+ for (const headerName of STRIPPED_RESPONSE_HEADERS) headers.delete(headerName);
5505
+ return new Response(upstreamResponse.body, {
5506
+ headers,
5507
+ status: upstreamResponse.status,
5508
+ statusText: upstreamResponse.statusText
5509
+ });
5510
+ }
5511
+ async function forwardProviderMessages(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
5512
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/messages`, {
5513
+ method: "POST",
5514
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
5515
+ body: JSON.stringify(payload)
5516
+ });
5517
+ }
5518
+ async function forwardProviderChatCompletions(providerConfig, payload, requestHeaders, fetchImpl = fetch) {
5519
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/chat/completions`, {
5520
+ method: "POST",
5521
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
5522
+ body: JSON.stringify(payload)
5523
+ });
5524
+ }
5525
+ async function forwardProviderModels(providerConfig, requestHeaders, fetchImpl = fetch) {
5526
+ return await fetchImpl(`${providerConfig.baseUrl}/v1/models`, {
5527
+ method: "GET",
5528
+ headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
5529
+ });
5530
+ }
5531
+ //#endregion
5532
+ //#region src/routes/provider/messages/handler.ts
5533
+ const logger$4 = createHandlerLogger("provider-messages-handler");
5534
+ const getProviderFetch$1 = (c) => c.get("providerFetch") ?? fetch;
5535
+ const resolveProviderConfig$1 = (c, provider) => {
5536
+ return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
5537
+ };
5538
+ const OPENAI_COMPATIBLE_CONTEXT_CACHE_MARKER_LIMIT = 4;
5539
+ const OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL = { type: "ephemeral" };
5540
+ const OPENAI_COMPATIBLE_CONTEXT_CACHE_ROLES = new Set([
5541
+ "system",
5542
+ "user",
5543
+ "assistant",
5544
+ "tool"
5545
+ ]);
5546
+ const writeProviderStreamError = async (stream, message) => {
5547
+ try {
5548
+ await stream.writeSSE({
5549
+ event: "error",
5550
+ data: JSON.stringify({
5551
+ error: {
5552
+ message,
5553
+ type: "api_error"
5554
+ },
5555
+ type: "error"
5556
+ })
5557
+ });
5558
+ } catch (error) {
5559
+ logger$4.warn("Failed to write provider stream error event", error);
5560
+ }
5561
+ };
5562
+ async function handleProviderMessages(c) {
5563
+ const provider = c.req.param("provider");
5564
+ return await handleProviderMessagesForProvider(c, {
5565
+ payload: await c.req.json(),
5566
+ provider
5567
+ });
5568
+ }
5569
+ async function handleProviderMessagesForProvider(c, options) {
5570
+ const { instrumentation, payload, provider } = options;
5571
+ const providerConfig = resolveProviderConfig$1(c, provider);
5572
+ if (!providerConfig) {
5573
+ const message = `Provider '${provider}' not found or disabled`;
5574
+ instrumentation?.onError?.({
5575
+ errorMessage: message,
5576
+ errorName: "ProviderNotFoundError",
5577
+ errorStatus: 404,
5578
+ httpStatus: 404
5579
+ });
5580
+ return c.json({ error: {
5581
+ message,
5582
+ type: "invalid_request_error"
5583
+ } }, 404);
5584
+ }
5585
+ try {
5586
+ const modelConfig = providerConfig.models?.[payload.model];
5587
+ applyModelDefaults(payload, modelConfig);
5588
+ debugJson(logger$4, "provider.messages.request", {
5589
+ payload,
5590
+ provider
5591
+ });
5592
+ if (providerConfig.type === "openai-compatible") return await handleOpenAICompatibleProviderMessages(c, {
5593
+ instrumentation,
5594
+ modelConfig,
5595
+ payload,
5596
+ provider,
5597
+ providerConfig
5598
+ });
5599
+ applyMissingExtraBody(payload, { extraBody: modelConfig?.extraBody });
5600
+ const upstreamResponse = await forwardProviderMessages(providerConfig, payload, c.req.raw.headers, getProviderFetch$1(c));
5601
+ if (!upstreamResponse.ok) {
5602
+ logger$4.error("Failed to create responses", upstreamResponse);
5603
+ throw new HTTPError("Failed to create responses", upstreamResponse);
5604
+ }
5605
+ const contentType = upstreamResponse.headers.get("content-type") ?? "";
5606
+ if (Boolean(payload.stream) && contentType.includes("text/event-stream")) return streamProviderMessages({
5607
+ c,
5608
+ instrumentation,
5609
+ payload,
5610
+ provider,
5611
+ providerConfig,
5612
+ upstreamResponse
5613
+ });
5614
+ return respondProviderMessagesJson(c, {
5615
+ body: await upstreamResponse.json(),
5616
+ instrumentation,
5617
+ payload,
5618
+ provider,
5619
+ providerConfig
5620
+ });
5621
+ } catch (error) {
5622
+ logger$4.error("provider.messages.error", {
5623
+ provider,
5624
+ error
5625
+ });
5626
+ throw error;
5627
+ }
5628
+ }
5629
+ const applyModelDefaults = (payload, modelConfig) => {
5630
+ payload.temperature ??= modelConfig?.temperature;
5631
+ payload.top_p ??= modelConfig?.topP;
5632
+ payload.top_k ??= modelConfig?.topK;
5633
+ };
5634
+ const applyMissingExtraBody = (payload, options) => {
5635
+ for (const [key, value] of Object.entries(options.extraBody ?? {})) if (!Object.hasOwn(payload, key)) payload[key] = value;
5636
+ };
5637
+ const handleOpenAICompatibleProviderMessages = async (c, options) => {
5638
+ const { instrumentation, modelConfig, payload, provider, providerConfig } = options;
5639
+ const openAIPayload = createOpenAICompatiblePayload(payload, modelConfig);
5640
+ debugJson(logger$4, "provider.messages.openai_compatible.request", {
5641
+ payload: openAIPayload,
5642
+ provider
5643
+ });
5644
+ const upstreamResponse = await forwardProviderChatCompletions(providerConfig, openAIPayload, c.req.raw.headers, getProviderFetch$1(c));
5645
+ if (!upstreamResponse.ok) {
5646
+ logger$4.error("Failed to create openai-compatible responses", upstreamResponse);
5647
+ throw new HTTPError("Failed to create openai-compatible responses", upstreamResponse);
5648
+ }
5649
+ const contentType = upstreamResponse.headers.get("content-type") ?? "";
5650
+ if (Boolean(openAIPayload.stream) && contentType.includes("text/event-stream")) return streamOpenAICompatibleProviderMessages({
5651
+ c,
5652
+ instrumentation,
5653
+ payload,
5654
+ provider,
5655
+ upstreamResponse
5656
+ });
5657
+ return respondOpenAICompatibleProviderMessagesJson(c, {
5658
+ body: await upstreamResponse.json(),
5659
+ instrumentation,
5660
+ payload,
5661
+ provider
5662
+ });
5663
+ };
5664
+ const createOpenAICompatiblePayload = (payload, modelConfig) => {
5665
+ const openAIPayload = translateToOpenAI(payload, {
5666
+ supportPdf: modelConfig?.supportPdf,
5667
+ toolContentSupportType: modelConfig?.toolContentSupportType ?? []
5668
+ });
5669
+ if (payload.top_k !== void 0) openAIPayload.top_k = payload.top_k;
5670
+ if (openAIPayload.stream) openAIPayload.stream_options = { include_usage: true };
5671
+ normalizeOpenAICompatibleReasoningContent(openAIPayload);
5672
+ applyOpenAICompatibleRequestOverrides(openAIPayload, {
5673
+ extraBody: modelConfig?.extraBody,
5674
+ source: payload
5675
+ });
5676
+ applyMissingExtraBody(openAIPayload, { extraBody: modelConfig?.extraBody });
5677
+ if (!Object.hasOwn(openAIPayload, "parallel_tool_calls")) openAIPayload.parallel_tool_calls = true;
5678
+ if (modelConfig?.contextCache !== false) applyOpenAICompatibleContextCache(openAIPayload);
5679
+ return openAIPayload;
5680
+ };
5681
+ const normalizeOpenAICompatibleReasoningContent = (payload) => {
5682
+ for (const message of payload.messages) {
5683
+ if (message.role !== "assistant") continue;
5684
+ if (message.reasoning_content === void 0 && message.reasoning_text !== void 0) message.reasoning_content = message.reasoning_text;
5685
+ delete message.reasoning_text;
5686
+ delete message.reasoning_opaque;
5687
+ }
5688
+ };
5689
+ const applyOpenAICompatibleRequestOverrides = (payload, options) => {
5690
+ const allowedKeys = new Set(Object.keys(options.extraBody ?? {}));
5691
+ for (const key of allowedKeys) if (Object.hasOwn(options.source, key)) payload[key] = options.source[key];
5692
+ };
5693
+ const applyOpenAICompatibleContextCache = (payload) => {
5694
+ const messageIndexes = selectContextCacheMessageIndexes(payload.messages);
5695
+ for (const messageIndex of messageIndexes) applyContextCacheControl(payload.messages[messageIndex]);
5696
+ };
5697
+ const selectContextCacheMessageIndexes = (messages) => {
5698
+ const cacheableIndexes = messages.flatMap((message, index) => isContextCacheMarkerEligible(message) ? [index] : []);
5699
+ const systemIndexes = cacheableIndexes.filter((index) => messages[index]?.role === "system").slice(0, 2);
5700
+ const finalIndexes = cacheableIndexes.filter((index) => messages[index]?.role !== "system").slice(-2);
5701
+ return uniqueIndexes([...systemIndexes, ...finalIndexes]).sort((a, b) => a - b);
5702
+ };
5703
+ const uniqueIndexes = (indexes) => [...new Set(indexes)].slice(0, OPENAI_COMPATIBLE_CONTEXT_CACHE_MARKER_LIMIT);
5704
+ const isContextCacheMarkerEligible = (message) => {
5705
+ if (!OPENAI_COMPATIBLE_CONTEXT_CACHE_ROLES.has(message.role)) return false;
5706
+ if (typeof message.content === "string") return message.content.length > 0;
5707
+ return Array.isArray(message.content) && message.content.length > 0;
5708
+ };
5709
+ const applyContextCacheControl = (message) => {
5710
+ if (!message) return;
5711
+ if (typeof message.content === "string") {
5712
+ message.content = [{
5713
+ type: "text",
5714
+ text: message.content,
5715
+ cache_control: { ...OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL }
5716
+ }];
5717
+ return;
5718
+ }
5719
+ if (!Array.isArray(message.content)) return;
5720
+ const lastPart = message.content.at(-1);
5721
+ if (!lastPart) return;
5722
+ setContextCacheControl(lastPart);
5723
+ };
5724
+ const setContextCacheControl = (part) => {
5725
+ part.cache_control = { ...OPENAI_COMPATIBLE_CONTEXT_CACHE_CONTROL };
5726
+ };
5727
+ const streamProviderMessages = ({ c, instrumentation, providerConfig, upstreamResponse }) => {
5728
+ logger$4.debug("provider.messages.streaming");
5729
+ return streamSSE(c, async (stream) => {
5730
+ let usage = {};
5731
+ try {
5732
+ let completed = false;
5733
+ for await (const chunk of events(upstreamResponse)) {
5734
+ logger$4.debug("provider.messages.raw_stream_event:", chunk.data);
5735
+ const eventName = chunk.event;
5736
+ if (eventName === "ping") {
5737
+ await stream.writeSSE({
5738
+ event: "ping",
5739
+ data: "{\"type\":\"ping\"}"
5740
+ });
5741
+ continue;
5742
+ }
5743
+ let data = chunk.data;
5744
+ if (!data) continue;
5745
+ if (chunk.data === "[DONE]") {
5746
+ completed = true;
5747
+ break;
5748
+ }
5749
+ const parsed = parseProviderStreamEvent(data, providerConfig);
5750
+ usage = mergeAnthropicUsage(usage, parsed.usage);
5751
+ data = parsed.data;
5752
+ await stream.writeSSE({
5753
+ event: eventName,
5754
+ data
5755
+ });
5756
+ if (parsed.error || eventName === "error") {
5757
+ instrumentation?.onError?.(parsed.error ?? {
5758
+ errorMessage: data,
5759
+ errorName: "ProviderStreamError",
5760
+ httpStatus: 500
5761
+ });
5762
+ return;
5763
+ }
5764
+ completed ||= parsed.done;
5765
+ }
5766
+ if (!completed) throw new Error("Provider messages stream ended before completion");
5767
+ instrumentation?.onComplete?.(usage);
5768
+ } catch (error) {
5769
+ const details = await extractErrorObservability(error);
5770
+ logger$4.warn("provider.messages.streaming.error", error);
5771
+ instrumentation?.onError?.(details);
5772
+ await writeProviderStreamError(stream, getUserVisibleErrorMessage(details));
5773
+ }
5774
+ });
5775
+ };
5776
+ const streamOpenAICompatibleProviderMessages = ({ c, instrumentation, upstreamResponse }) => {
5777
+ logger$4.debug("provider.messages.openai_compatible.streaming");
5778
+ return streamSSE(c, async (stream) => {
5779
+ let usage = {};
5780
+ const streamState = {
5781
+ messageStartSent: false,
5782
+ contentBlockIndex: 0,
5783
+ contentBlockOpen: false,
5784
+ toolCalls: {},
5785
+ thinkingBlockOpen: false
5786
+ };
5787
+ try {
5788
+ let completed = false;
5789
+ for await (const chunk of events(upstreamResponse)) {
5790
+ logger$4.debug("provider.messages.openai_compatible.raw_stream_event:", chunk.data);
5791
+ if (chunk.event === "ping") {
5792
+ await stream.writeSSE({
5793
+ event: "ping",
5794
+ data: "{\"type\":\"ping\"}"
5795
+ });
5796
+ continue;
5797
+ }
5798
+ if (!chunk.data) continue;
5799
+ if (chunk.data === "[DONE]") {
5800
+ completed = true;
5801
+ break;
5802
+ }
5803
+ const parsed = parseOpenAICompatibleStreamChunk(chunk.data);
5804
+ if (parsed.usage) usage = normalizeOpenAIUsage(parsed.usage);
5805
+ const events = translateChunkToAnthropicEvents(parsed, streamState);
5806
+ for (const event of events) {
5807
+ const eventData = JSON.stringify(event);
5808
+ debugLazy(logger$4, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
5809
+ await stream.writeSSE({
5810
+ event: event.type,
5811
+ data: eventData
5812
+ });
5813
+ completed ||= event.type === "message_stop";
5814
+ }
5815
+ }
5816
+ for (const event of flushPendingAnthropicStreamEvents(streamState)) {
5817
+ const eventData = JSON.stringify(event);
5818
+ debugLazy(logger$4, () => ["provider.messages.openai_compatible.translated_event:", eventData]);
5819
+ await stream.writeSSE({
5820
+ event: event.type,
5821
+ data: eventData
5822
+ });
5823
+ completed ||= event.type === "message_stop";
5824
+ }
5825
+ if (!completed) throw new Error("OpenAI-compatible provider messages stream ended before completion");
5826
+ instrumentation?.onComplete?.(usage);
5827
+ } catch (error) {
5828
+ const details = await extractErrorObservability(error);
5829
+ logger$4.warn("provider.messages.openai_compatible.streaming.error", error);
5830
+ instrumentation?.onError?.(details);
5831
+ await writeProviderStreamError(stream, getUserVisibleErrorMessage(details));
5832
+ }
5833
+ });
5834
+ };
5835
+ const parseOpenAICompatibleStreamChunk = (data) => {
5836
+ let parsed;
5837
+ try {
5838
+ parsed = JSON.parse(data);
5839
+ } catch (error) {
5840
+ logger$4.error("provider.messages.openai_compatible.parse_chunk_error", {
5841
+ data,
5842
+ error
5843
+ });
5844
+ throw new Error("Failed to parse OpenAI-compatible stream chunk", { cause: error });
5845
+ }
5846
+ const streamErrorMessage = getOpenAICompatibleStreamErrorMessage(parsed.error);
5847
+ if (streamErrorMessage) throw new Error(streamErrorMessage);
5848
+ return parsed;
5849
+ };
5850
+ const getOpenAICompatibleStreamErrorMessage = (error) => {
5851
+ if (typeof error === "string") return error;
5852
+ if (!error || typeof error !== "object") return null;
5853
+ const message = error.message;
5854
+ return typeof message === "string" ? message : JSON.stringify(error);
5855
+ };
5856
+ const parseProviderStreamEvent = (data, providerConfig) => {
5857
+ try {
5858
+ const parsed = JSON.parse(data);
5859
+ if (parsed.type === "message_start") {
5860
+ adjustInputTokens(providerConfig, parsed.message.usage);
5861
+ return {
5862
+ data: JSON.stringify(parsed),
5863
+ done: false,
5864
+ model: parsed.message.model,
5865
+ usage: normalizeAnthropicUsage(parsed.message.usage)
5866
+ };
5867
+ }
5868
+ if (parsed.type === "message_delta") {
5869
+ adjustInputTokens(providerConfig, parsed.usage);
5870
+ return {
5871
+ data: JSON.stringify(parsed),
5872
+ done: false,
5873
+ usage: normalizeAnthropicUsage(parsed.usage)
5874
+ };
5875
+ }
5876
+ if (parsed.type === "message_stop") return {
5877
+ data: JSON.stringify(parsed),
5878
+ done: true,
5879
+ usage: {}
5880
+ };
5881
+ if (parsed.type === "error") return {
5882
+ data: JSON.stringify(parsed),
5883
+ done: false,
5884
+ error: {
5885
+ errorMessage: parsed.error.message,
5886
+ errorName: parsed.error.type,
5887
+ httpStatus: 500
5888
+ },
5889
+ usage: {}
5890
+ };
5891
+ return {
5892
+ data: JSON.stringify(parsed),
5893
+ done: false,
5894
+ usage: {}
5895
+ };
5896
+ } catch (error) {
5897
+ logger$4.error("provider.messages.streaming.adjust_tokens_error", {
5898
+ error,
5899
+ originalData: data
5900
+ });
5901
+ throw new Error("Failed to parse provider messages stream event", { cause: error });
5902
+ }
5903
+ };
5904
+ const respondProviderMessagesJson = (c, options) => {
5905
+ const { body, instrumentation, providerConfig } = options;
5906
+ adjustInputTokens(providerConfig, body.usage);
5907
+ debugJson(logger$4, "provider.messages.no_stream result:", body);
5908
+ const response = c.json(body);
5909
+ instrumentation?.onComplete?.(normalizeAnthropicUsage(body.usage));
5910
+ return response;
5911
+ };
5912
+ const respondOpenAICompatibleProviderMessagesJson = (c, options) => {
5913
+ const { body, instrumentation } = options;
5914
+ const anthropicResponse = translateToAnthropic(body);
5915
+ debugJson(logger$4, "provider.messages.openai_compatible.no_stream result:", anthropicResponse);
5916
+ const response = c.json(anthropicResponse);
5917
+ instrumentation?.onComplete?.(normalizeOpenAIUsage(body.usage));
5918
+ return response;
5919
+ };
5920
+ const normalizeOpenAIUsage = (usage) => {
5921
+ const cacheCreationInputTokens = usage?.prompt_tokens_details?.cache_creation_input_tokens;
5922
+ const cacheReadInputTokens = usage?.prompt_tokens_details?.cached_tokens;
5923
+ return {
5924
+ inputTokens: usage?.prompt_tokens === void 0 ? void 0 : Math.max(0, usage.prompt_tokens - (cacheCreationInputTokens ?? 0) - (cacheReadInputTokens ?? 0)),
5925
+ outputTokens: usage?.completion_tokens,
5926
+ cacheCreationInputTokens,
5927
+ cacheReadInputTokens
5928
+ };
5929
+ };
5930
+ const normalizeAnthropicUsage = (usage) => ({
5931
+ inputTokens: usage?.input_tokens,
5932
+ outputTokens: usage?.output_tokens,
5933
+ cacheCreationInputTokens: usage?.cache_creation_input_tokens,
5934
+ cacheReadInputTokens: usage?.cache_read_input_tokens
5935
+ });
5936
+ const mergeAnthropicUsage = (current, next) => ({
5937
+ inputTokens: next.inputTokens ?? current.inputTokens,
5938
+ outputTokens: next.outputTokens ?? current.outputTokens,
5939
+ cacheCreationInputTokens: next.cacheCreationInputTokens ?? current.cacheCreationInputTokens,
5940
+ cacheReadInputTokens: next.cacheReadInputTokens ?? current.cacheReadInputTokens
5941
+ });
5942
+ const adjustInputTokens = (providerConfig, usage) => {
5943
+ if (!providerConfig.adjustInputTokens || !usage) return;
5944
+ usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
5945
+ debugJson(logger$4, "provider.messages.adjusted_usage:", usage);
5946
+ };
5947
+ //#endregion
5948
+ //#region src/routes/messages/responses-stream-translation.ts
5949
+ const MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE = 20;
5950
+ var FunctionCallArgumentsValidationError = class extends Error {
5951
+ constructor(message) {
5952
+ super(message);
5953
+ this.name = "FunctionCallArgumentsValidationError";
5954
+ }
5955
+ };
5956
+ const updateWhitespaceRunState = (previousCount, chunk) => {
5957
+ let count = previousCount;
5958
+ for (const char of chunk) {
5959
+ if (char === "\r" || char === "\n" || char === " ") {
5960
+ count += 1;
5961
+ if (count > MAX_CONSECUTIVE_FUNCTION_CALL_WHITESPACE) return {
5962
+ nextCount: count,
5963
+ exceeded: true
5964
+ };
5965
+ continue;
5966
+ }
5967
+ if (char !== " ") count = 0;
5968
+ }
5969
+ return {
5970
+ nextCount: count,
5971
+ exceeded: false
5972
+ };
5973
+ };
5974
+ const createResponsesStreamState = () => ({
5975
+ messageStartSent: false,
5976
+ messageCompleted: false,
5977
+ nextContentBlockIndex: 0,
5978
+ blockIndexByKey: /* @__PURE__ */ new Map(),
5979
+ openBlocks: /* @__PURE__ */ new Set(),
5980
+ blockHasDelta: /* @__PURE__ */ new Set(),
5981
+ functionCallStateByOutputIndex: /* @__PURE__ */ new Map()
5982
+ });
5983
+ const translateResponsesStreamEvent = (rawEvent, state) => {
5984
+ switch (rawEvent.type) {
5985
+ case "response.created": return handleResponseCreated(rawEvent, state);
5986
+ case "response.output_item.added": return handleOutputItemAdded$1(rawEvent, state);
5987
+ case "response.reasoning_summary_text.delta": return handleReasoningSummaryTextDelta(rawEvent, state);
5988
+ case "response.output_text.delta": return handleOutputTextDelta(rawEvent, state);
5989
+ case "response.reasoning_summary_text.done": return handleReasoningSummaryTextDone(rawEvent, state);
5990
+ case "response.output_text.done": return handleOutputTextDone(rawEvent, state);
5991
+ case "response.output_item.done": return handleOutputItemDone$1(rawEvent, state);
5992
+ case "response.function_call_arguments.delta": return handleFunctionCallArgumentsDelta(rawEvent, state);
5993
+ case "response.function_call_arguments.done": return handleFunctionCallArgumentsDone(rawEvent, state);
5994
+ case "response.completed":
5995
+ case "response.incomplete": return handleResponseCompleted(rawEvent, state);
5996
+ case "response.failed": return handleResponseFailed(rawEvent, state);
5997
+ case "error": return handleErrorEvent(rawEvent, state);
5998
+ default: return [];
5999
+ }
6000
+ };
6001
+ const handleResponseCreated = (rawEvent, state) => {
6002
+ return messageStart(state, rawEvent.response);
6003
+ };
6004
+ const handleOutputItemAdded$1 = (rawEvent, state) => {
6005
+ const events = new Array();
6006
+ const functionCallDetails = extractFunctionCallDetails(rawEvent);
6007
+ if (!functionCallDetails) return events;
6008
+ const { outputIndex, toolCallId, name, initialArguments } = functionCallDetails;
6009
+ const blockIndex = openFunctionCallBlock(state, {
6010
+ outputIndex,
6011
+ toolCallId,
6012
+ name,
6013
+ events
6014
+ });
6015
+ if (initialArguments !== void 0 && initialArguments.length > 0) {
6016
+ events.push({
6017
+ type: "content_block_delta",
6018
+ index: blockIndex,
6019
+ delta: {
6020
+ type: "input_json_delta",
6021
+ partial_json: initialArguments
6022
+ }
6023
+ });
6024
+ state.blockHasDelta.add(blockIndex);
6025
+ }
6026
+ return events;
6027
+ };
6028
+ const handleOutputItemDone$1 = (rawEvent, state) => {
6029
+ const events = new Array();
6030
+ const item = rawEvent.item;
6031
+ const itemType = item.type;
6032
+ const outputIndex = rawEvent.output_index;
6033
+ if (itemType === "compaction") {
6034
+ if (!item.id || !item.encrypted_content) return events;
6035
+ const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
6036
+ if (!state.blockHasDelta.has(blockIndex)) events.push({
6037
+ type: "content_block_delta",
6038
+ index: blockIndex,
6039
+ delta: {
6040
+ type: "thinking_delta",
6041
+ thinking: THINKING_TEXT
6042
+ }
6043
+ });
6044
+ events.push({
6045
+ type: "content_block_delta",
6046
+ index: blockIndex,
4963
6047
  delta: {
4964
6048
  type: "signature_delta",
4965
6049
  signature: encodeCompactionCarrierSignature({
@@ -4968,22 +6052,22 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
4968
6052
  })
4969
6053
  }
4970
6054
  });
4971
- state$1.blockHasDelta.add(blockIndex$1);
4972
- return events$1;
6055
+ state.blockHasDelta.add(blockIndex);
6056
+ return events;
4973
6057
  }
4974
- if (itemType !== "reasoning") return events$1;
4975
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
6058
+ if (itemType !== "reasoning") return events;
6059
+ const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
4976
6060
  const signature = (item.encrypted_content ?? "") + "@" + item.id;
4977
6061
  if (signature) {
4978
- if (!item.summary || item.summary.length === 0) events$1.push({
6062
+ if (!item.summary || item.summary.length === 0) events.push({
4979
6063
  type: "content_block_delta",
4980
6064
  index: blockIndex,
4981
6065
  delta: {
4982
6066
  type: "thinking_delta",
4983
- thinking: THINKING_TEXT$1
6067
+ thinking: THINKING_TEXT
4984
6068
  }
4985
6069
  });
4986
- events$1.push({
6070
+ events.push({
4987
6071
  type: "content_block_delta",
4988
6072
  index: blockIndex,
4989
6073
  delta: {
@@ -4991,25 +6075,25 @@ const handleOutputItemDone$1 = (rawEvent, state$1) => {
4991
6075
  signature
4992
6076
  }
4993
6077
  });
4994
- state$1.blockHasDelta.add(blockIndex);
6078
+ state.blockHasDelta.add(blockIndex);
4995
6079
  }
4996
- return events$1;
6080
+ return events;
4997
6081
  };
4998
- const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
4999
- const events$1 = new Array();
6082
+ const handleFunctionCallArgumentsDelta = (rawEvent, state) => {
6083
+ const events = new Array();
5000
6084
  const outputIndex = rawEvent.output_index;
5001
6085
  const deltaText = rawEvent.delta;
5002
- if (!deltaText) return events$1;
5003
- const blockIndex = openFunctionCallBlock(state$1, {
6086
+ if (!deltaText) return events;
6087
+ const blockIndex = openFunctionCallBlock(state, {
5004
6088
  outputIndex,
5005
- events: events$1
6089
+ events
5006
6090
  });
5007
- const functionCallState = state$1.functionCallStateByOutputIndex.get(outputIndex);
5008
- if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state$1, events$1);
6091
+ const functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
6092
+ if (!functionCallState) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta without an open tool call block."), state, events);
5009
6093
  const { nextCount, exceeded } = updateWhitespaceRunState(functionCallState.consecutiveWhitespaceCount, deltaText);
5010
- if (exceeded) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta containing more than 20 consecutive whitespace characters."), state$1, events$1);
6094
+ if (exceeded) return handleFunctionCallArgumentsValidationError(new FunctionCallArgumentsValidationError("Received function call arguments delta containing more than 20 consecutive whitespace characters."), state, events);
5011
6095
  functionCallState.consecutiveWhitespaceCount = nextCount;
5012
- events$1.push({
6096
+ events.push({
5013
6097
  type: "content_block_delta",
5014
6098
  index: blockIndex,
5015
6099
  delta: {
@@ -5017,19 +6101,19 @@ const handleFunctionCallArgumentsDelta = (rawEvent, state$1) => {
5017
6101
  partial_json: deltaText
5018
6102
  }
5019
6103
  });
5020
- state$1.blockHasDelta.add(blockIndex);
5021
- return events$1;
6104
+ state.blockHasDelta.add(blockIndex);
6105
+ return events;
5022
6106
  };
5023
- const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
5024
- const events$1 = new Array();
6107
+ const handleFunctionCallArgumentsDone = (rawEvent, state) => {
6108
+ const events = new Array();
5025
6109
  const outputIndex = rawEvent.output_index;
5026
- const blockIndex = openFunctionCallBlock(state$1, {
6110
+ const blockIndex = openFunctionCallBlock(state, {
5027
6111
  outputIndex,
5028
- events: events$1
6112
+ events
5029
6113
  });
5030
6114
  const finalArguments = typeof rawEvent.arguments === "string" ? rawEvent.arguments : void 0;
5031
- if (!state$1.blockHasDelta.has(blockIndex) && finalArguments) {
5032
- events$1.push({
6115
+ if (!state.blockHasDelta.has(blockIndex) && finalArguments) {
6116
+ events.push({
5033
6117
  type: "content_block_delta",
5034
6118
  index: blockIndex,
5035
6119
  delta: {
@@ -5037,23 +6121,23 @@ const handleFunctionCallArgumentsDone = (rawEvent, state$1) => {
5037
6121
  partial_json: finalArguments
5038
6122
  }
5039
6123
  });
5040
- state$1.blockHasDelta.add(blockIndex);
6124
+ state.blockHasDelta.add(blockIndex);
5041
6125
  }
5042
- state$1.functionCallStateByOutputIndex.delete(outputIndex);
5043
- return events$1;
6126
+ state.functionCallStateByOutputIndex.delete(outputIndex);
6127
+ return events;
5044
6128
  };
5045
- const handleOutputTextDelta = (rawEvent, state$1) => {
5046
- const events$1 = new Array();
6129
+ const handleOutputTextDelta = (rawEvent, state) => {
6130
+ const events = new Array();
5047
6131
  const outputIndex = rawEvent.output_index;
5048
6132
  const contentIndex = rawEvent.content_index;
5049
6133
  const deltaText = rawEvent.delta;
5050
- if (!deltaText) return events$1;
5051
- const blockIndex = openTextBlockIfNeeded(state$1, {
6134
+ if (!deltaText) return events;
6135
+ const blockIndex = openTextBlockIfNeeded(state, {
5052
6136
  outputIndex,
5053
6137
  contentIndex,
5054
- events: events$1
6138
+ events
5055
6139
  });
5056
- events$1.push({
6140
+ events.push({
5057
6141
  type: "content_block_delta",
5058
6142
  index: blockIndex,
5059
6143
  delta: {
@@ -5061,15 +6145,15 @@ const handleOutputTextDelta = (rawEvent, state$1) => {
5061
6145
  text: deltaText
5062
6146
  }
5063
6147
  });
5064
- state$1.blockHasDelta.add(blockIndex);
5065
- return events$1;
6148
+ state.blockHasDelta.add(blockIndex);
6149
+ return events;
5066
6150
  };
5067
- const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
6151
+ const handleReasoningSummaryTextDelta = (rawEvent, state) => {
5068
6152
  const outputIndex = rawEvent.output_index;
5069
6153
  const deltaText = rawEvent.delta;
5070
- const events$1 = new Array();
5071
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
5072
- events$1.push({
6154
+ const events = new Array();
6155
+ const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
6156
+ events.push({
5073
6157
  type: "content_block_delta",
5074
6158
  index: blockIndex,
5075
6159
  delta: {
@@ -5077,15 +6161,15 @@ const handleReasoningSummaryTextDelta = (rawEvent, state$1) => {
5077
6161
  thinking: deltaText
5078
6162
  }
5079
6163
  });
5080
- state$1.blockHasDelta.add(blockIndex);
5081
- return events$1;
6164
+ state.blockHasDelta.add(blockIndex);
6165
+ return events;
5082
6166
  };
5083
- const handleReasoningSummaryTextDone = (rawEvent, state$1) => {
6167
+ const handleReasoningSummaryTextDone = (rawEvent, state) => {
5084
6168
  const outputIndex = rawEvent.output_index;
5085
6169
  const text = rawEvent.text;
5086
- const events$1 = new Array();
5087
- const blockIndex = openThinkingBlockIfNeeded(state$1, outputIndex, events$1);
5088
- if (text && !state$1.blockHasDelta.has(blockIndex)) events$1.push({
6170
+ const events = new Array();
6171
+ const blockIndex = openThinkingBlockIfNeeded(state, outputIndex, events);
6172
+ if (text && !state.blockHasDelta.has(blockIndex)) events.push({
5089
6173
  type: "content_block_delta",
5090
6174
  index: blockIndex,
5091
6175
  delta: {
@@ -5093,19 +6177,19 @@ const handleReasoningSummaryTextDone = (rawEvent, state$1) => {
5093
6177
  thinking: text
5094
6178
  }
5095
6179
  });
5096
- return events$1;
6180
+ return events;
5097
6181
  };
5098
- const handleOutputTextDone = (rawEvent, state$1) => {
5099
- const events$1 = new Array();
6182
+ const handleOutputTextDone = (rawEvent, state) => {
6183
+ const events = new Array();
5100
6184
  const outputIndex = rawEvent.output_index;
5101
6185
  const contentIndex = rawEvent.content_index;
5102
6186
  const text = rawEvent.text;
5103
- const blockIndex = openTextBlockIfNeeded(state$1, {
6187
+ const blockIndex = openTextBlockIfNeeded(state, {
5104
6188
  outputIndex,
5105
6189
  contentIndex,
5106
- events: events$1
6190
+ events
5107
6191
  });
5108
- if (text && !state$1.blockHasDelta.has(blockIndex)) events$1.push({
6192
+ if (text && !state.blockHasDelta.has(blockIndex)) events.push({
5109
6193
  type: "content_block_delta",
5110
6194
  index: blockIndex,
5111
6195
  delta: {
@@ -5113,14 +6197,15 @@ const handleOutputTextDone = (rawEvent, state$1) => {
5113
6197
  text
5114
6198
  }
5115
6199
  });
5116
- return events$1;
6200
+ return events;
5117
6201
  };
5118
- const handleResponseCompleted = (rawEvent, state$1) => {
6202
+ const handleResponseCompleted = (rawEvent, state) => {
5119
6203
  const response = rawEvent.response;
5120
- const events$1 = new Array();
5121
- closeAllOpenBlocks(state$1, events$1);
6204
+ const events = new Array();
6205
+ closeAllOpenBlocks(state, events);
6206
+ state.responseStatus = response.status;
5122
6207
  const anthropic = translateResponsesResultToAnthropic(response);
5123
- events$1.push({
6208
+ events.push({
5124
6209
  type: "message_delta",
5125
6210
  delta: {
5126
6211
  stop_reason: anthropic.stop_reason,
@@ -5128,39 +6213,40 @@ const handleResponseCompleted = (rawEvent, state$1) => {
5128
6213
  },
5129
6214
  usage: anthropic.usage
5130
6215
  }, { type: "message_stop" });
5131
- state$1.messageCompleted = true;
5132
- return events$1;
6216
+ state.messageCompleted = true;
6217
+ return events;
5133
6218
  };
5134
- const handleResponseFailed = (rawEvent, state$1) => {
6219
+ const handleResponseFailed = (rawEvent, state) => {
5135
6220
  const response = rawEvent.response;
5136
- const events$1 = new Array();
5137
- closeAllOpenBlocks(state$1, events$1);
6221
+ const events = new Array();
6222
+ closeAllOpenBlocks(state, events);
6223
+ state.responseStatus = response.status;
5138
6224
  const message = response.error?.message ?? "The response failed due to an unknown error.";
5139
- events$1.push(buildErrorEvent(message));
5140
- state$1.messageCompleted = true;
5141
- return events$1;
6225
+ events.push(buildErrorEvent(message));
6226
+ state.messageCompleted = true;
6227
+ return events;
5142
6228
  };
5143
- const handleErrorEvent = (rawEvent, state$1) => {
6229
+ const handleErrorEvent = (rawEvent, state) => {
5144
6230
  const message = typeof rawEvent.message === "string" ? rawEvent.message : "An unexpected error occurred during streaming.";
5145
- state$1.messageCompleted = true;
6231
+ state.messageCompleted = true;
5146
6232
  return [buildErrorEvent(message)];
5147
6233
  };
5148
- const handleFunctionCallArgumentsValidationError = (error, state$1, events$1 = []) => {
6234
+ const handleFunctionCallArgumentsValidationError = (error, state, events = []) => {
5149
6235
  const reason = error.message;
5150
- closeAllOpenBlocks(state$1, events$1);
5151
- state$1.messageCompleted = true;
5152
- events$1.push(buildErrorEvent(reason));
5153
- return events$1;
6236
+ closeAllOpenBlocks(state, events);
6237
+ state.messageCompleted = true;
6238
+ events.push(buildErrorEvent(reason));
6239
+ return events;
5154
6240
  };
5155
- const messageStart = (state$1, response) => {
5156
- state$1.messageStartSent = true;
6241
+ const messageStart = (state, response) => {
6242
+ state.messageStartSent = true;
5157
6243
  const inputCachedTokens = response.usage?.input_tokens_details?.cached_tokens;
5158
6244
  const upstreamInputTokens = response.usage?.input_tokens;
5159
- const historicalInputTokens = state$1.historicalInputTokens;
5160
- const historicalOutputTokens = state$1.historicalOutputTokens ?? 0;
6245
+ const historicalInputTokens = state.historicalInputTokens;
6246
+ const historicalOutputTokens = state.historicalOutputTokens ?? 0;
5161
6247
  const historicalTotalTokens = historicalInputTokens !== void 0 ? historicalInputTokens + historicalOutputTokens : void 0;
5162
- const inputTokens = upstreamInputTokens !== void 0 ? upstreamInputTokens - (inputCachedTokens ?? 0) : historicalTotalTokens ?? state$1.estimatedInputTokens ?? 0;
5163
- const cacheReadTokens = upstreamInputTokens !== void 0 ? inputCachedTokens ?? 0 : state$1.historicalCachedInputTokens ?? 0;
6248
+ const inputTokens = upstreamInputTokens !== void 0 ? upstreamInputTokens - (inputCachedTokens ?? 0) : historicalTotalTokens ?? state.estimatedInputTokens ?? 0;
6249
+ const cacheReadTokens = upstreamInputTokens !== void 0 ? inputCachedTokens ?? 0 : state.historicalCachedInputTokens ?? 0;
5164
6250
  return [{
5165
6251
  type: "message_start",
5166
6252
  message: {
@@ -5179,18 +6265,18 @@ const messageStart = (state$1, response) => {
5179
6265
  }
5180
6266
  }];
5181
6267
  };
5182
- const openTextBlockIfNeeded = (state$1, params) => {
5183
- const { outputIndex, contentIndex, events: events$1 } = params;
6268
+ const openTextBlockIfNeeded = (state, params) => {
6269
+ const { outputIndex, contentIndex, events } = params;
5184
6270
  const key = getBlockKey(outputIndex, contentIndex);
5185
- let blockIndex = state$1.blockIndexByKey.get(key);
6271
+ let blockIndex = state.blockIndexByKey.get(key);
5186
6272
  if (blockIndex === void 0) {
5187
- blockIndex = state$1.nextContentBlockIndex;
5188
- state$1.nextContentBlockIndex += 1;
5189
- state$1.blockIndexByKey.set(key, blockIndex);
6273
+ blockIndex = state.nextContentBlockIndex;
6274
+ state.nextContentBlockIndex += 1;
6275
+ state.blockIndexByKey.set(key, blockIndex);
5190
6276
  }
5191
- if (!state$1.openBlocks.has(blockIndex)) {
5192
- closeOpenBlocks(state$1, events$1);
5193
- events$1.push({
6277
+ if (!state.openBlocks.has(blockIndex)) {
6278
+ closeOpenBlocks(state, events);
6279
+ events.push({
5194
6280
  type: "content_block_start",
5195
6281
  index: blockIndex,
5196
6282
  content_block: {
@@ -5198,21 +6284,21 @@ const openTextBlockIfNeeded = (state$1, params) => {
5198
6284
  text: ""
5199
6285
  }
5200
6286
  });
5201
- state$1.openBlocks.add(blockIndex);
6287
+ state.openBlocks.add(blockIndex);
5202
6288
  }
5203
6289
  return blockIndex;
5204
6290
  };
5205
- const openThinkingBlockIfNeeded = (state$1, outputIndex, events$1) => {
6291
+ const openThinkingBlockIfNeeded = (state, outputIndex, events) => {
5206
6292
  const key = getBlockKey(outputIndex, 0);
5207
- let blockIndex = state$1.blockIndexByKey.get(key);
6293
+ let blockIndex = state.blockIndexByKey.get(key);
5208
6294
  if (blockIndex === void 0) {
5209
- blockIndex = state$1.nextContentBlockIndex;
5210
- state$1.nextContentBlockIndex += 1;
5211
- state$1.blockIndexByKey.set(key, blockIndex);
6295
+ blockIndex = state.nextContentBlockIndex;
6296
+ state.nextContentBlockIndex += 1;
6297
+ state.blockIndexByKey.set(key, blockIndex);
5212
6298
  }
5213
- if (!state$1.openBlocks.has(blockIndex)) {
5214
- closeOpenBlocks(state$1, events$1);
5215
- events$1.push({
6299
+ if (!state.openBlocks.has(blockIndex)) {
6300
+ closeOpenBlocks(state, events);
6301
+ events.push({
5216
6302
  type: "content_block_start",
5217
6303
  index: blockIndex,
5218
6304
  content_block: {
@@ -5220,25 +6306,25 @@ const openThinkingBlockIfNeeded = (state$1, outputIndex, events$1) => {
5220
6306
  thinking: ""
5221
6307
  }
5222
6308
  });
5223
- state$1.openBlocks.add(blockIndex);
6309
+ state.openBlocks.add(blockIndex);
5224
6310
  }
5225
6311
  return blockIndex;
5226
6312
  };
5227
- const closeBlockIfOpen = (state$1, blockIndex, events$1) => {
5228
- if (!state$1.openBlocks.has(blockIndex)) return;
5229
- events$1.push({
6313
+ const closeBlockIfOpen = (state, blockIndex, events) => {
6314
+ if (!state.openBlocks.has(blockIndex)) return;
6315
+ events.push({
5230
6316
  type: "content_block_stop",
5231
6317
  index: blockIndex
5232
6318
  });
5233
- state$1.openBlocks.delete(blockIndex);
5234
- state$1.blockHasDelta.delete(blockIndex);
6319
+ state.openBlocks.delete(blockIndex);
6320
+ state.blockHasDelta.delete(blockIndex);
5235
6321
  };
5236
- const closeOpenBlocks = (state$1, events$1) => {
5237
- for (const blockIndex of state$1.openBlocks) closeBlockIfOpen(state$1, blockIndex, events$1);
6322
+ const closeOpenBlocks = (state, events) => {
6323
+ for (const blockIndex of state.openBlocks) closeBlockIfOpen(state, blockIndex, events);
5238
6324
  };
5239
- const closeAllOpenBlocks = (state$1, events$1) => {
5240
- closeOpenBlocks(state$1, events$1);
5241
- state$1.functionCallStateByOutputIndex.clear();
6325
+ const closeAllOpenBlocks = (state, events) => {
6326
+ closeOpenBlocks(state, events);
6327
+ state.functionCallStateByOutputIndex.clear();
5242
6328
  };
5243
6329
  const buildErrorEvent = (message) => ({
5244
6330
  type: "error",
@@ -5248,24 +6334,24 @@ const buildErrorEvent = (message) => ({
5248
6334
  }
5249
6335
  });
5250
6336
  const getBlockKey = (outputIndex, contentIndex) => `${outputIndex}:${contentIndex}`;
5251
- const openFunctionCallBlock = (state$1, params) => {
5252
- const { outputIndex, toolCallId, name, events: events$1 } = params;
5253
- let functionCallState = state$1.functionCallStateByOutputIndex.get(outputIndex);
6337
+ const openFunctionCallBlock = (state, params) => {
6338
+ const { outputIndex, toolCallId, name, events } = params;
6339
+ let functionCallState = state.functionCallStateByOutputIndex.get(outputIndex);
5254
6340
  if (!functionCallState) {
5255
- const blockIndex$1 = state$1.nextContentBlockIndex;
5256
- state$1.nextContentBlockIndex += 1;
6341
+ const blockIndex = state.nextContentBlockIndex;
6342
+ state.nextContentBlockIndex += 1;
5257
6343
  functionCallState = {
5258
- blockIndex: blockIndex$1,
5259
- toolCallId: toolCallId ?? `tool_call_${blockIndex$1}`,
6344
+ blockIndex,
6345
+ toolCallId: toolCallId ?? `tool_call_${blockIndex}`,
5260
6346
  name: name ?? "function",
5261
6347
  consecutiveWhitespaceCount: 0
5262
6348
  };
5263
- state$1.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
6349
+ state.functionCallStateByOutputIndex.set(outputIndex, functionCallState);
5264
6350
  }
5265
6351
  const { blockIndex } = functionCallState;
5266
- if (!state$1.openBlocks.has(blockIndex)) {
5267
- closeOpenBlocks(state$1, events$1);
5268
- events$1.push({
6352
+ if (!state.openBlocks.has(blockIndex)) {
6353
+ closeOpenBlocks(state, events);
6354
+ events.push({
5269
6355
  type: "content_block_start",
5270
6356
  index: blockIndex,
5271
6357
  content_block: {
@@ -5275,7 +6361,7 @@ const openFunctionCallBlock = (state$1, params) => {
5275
6361
  input: {}
5276
6362
  }
5277
6363
  });
5278
- state$1.openBlocks.add(blockIndex);
6364
+ state.openBlocks.add(blockIndex);
5279
6365
  }
5280
6366
  return blockIndex;
5281
6367
  };
@@ -5289,7 +6375,6 @@ const extractFunctionCallDetails = (rawEvent) => {
5289
6375
  initialArguments: item.arguments
5290
6376
  };
5291
6377
  };
5292
-
5293
6378
  //#endregion
5294
6379
  //#region src/routes/responses/utils.ts
5295
6380
  const getResponsesRequestOptions = (payload) => {
@@ -5380,7 +6465,7 @@ function getStreamChunkFields(chunk) {
5380
6465
  data: c.data
5381
6466
  };
5382
6467
  }
5383
- const isAsyncIterable = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
6468
+ const isAsyncIterable$1 = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
5384
6469
  const containsVisionContent = (value) => {
5385
6470
  if (!value) return false;
5386
6471
  if (Array.isArray(value)) return value.some((entry) => containsVisionContent(entry));
@@ -5390,7 +6475,6 @@ const containsVisionContent = (value) => {
5390
6475
  if (Array.isArray(record.content)) return record.content.some((entry) => containsVisionContent(entry));
5391
6476
  return false;
5392
6477
  };
5393
-
5394
6478
  //#endregion
5395
6479
  //#region src/services/copilot/create-messages.ts
5396
6480
  const isAgentMessage = (msg) => {
@@ -5445,305 +6529,44 @@ const buildMessagesHeaders = ({ ctx, enableVision, initiator, options, payload }
5445
6529
  isSubagent: Boolean(options?.subagentMarker)
5446
6530
  });
5447
6531
  const headers = {
5448
- ...copilotHeaders(ctx, enableVision, options?.upstreamRequestId),
5449
- "x-initiator": effectiveInitiator
5450
- };
5451
- prepareInteractionHeaders(options?.sessionId, Boolean(options?.subagentMarker), headers);
5452
- prepareForCompact(headers, options?.compactType);
5453
- if (shouldUseMessageProxyHeaders(payload)) prepareMessageProxyHeaders(headers);
5454
- const anthropicBeta = buildAnthropicBetaHeader(options?.anthropicBetaHeader, payload.thinking, payload.model);
5455
- if (anthropicBeta) headers["anthropic-beta"] = anthropicBeta;
5456
- return headers;
5457
- };
5458
- const createMessages = async (payload, account, options) => {
5459
- const ctx = account ?? accountFromState();
5460
- if (!ctx.copilotToken) throw new Error("Copilot token not found");
5461
- const headers = buildMessagesHeaders({
5462
- ctx,
5463
- enableVision: hasVisionInput(payload),
5464
- initiator: options?.initiator ?? getMessagesInitiator(payload),
5465
- options,
5466
- payload
5467
- });
5468
- captureOutboundHeadersSnapshot(headers);
5469
- const response = await copilotFetch(`${copilotBaseUrl(ctx)}/v1/messages`, {
5470
- method: "POST",
5471
- headers,
5472
- body: JSON.stringify(payload)
5473
- }, {
5474
- requestId: options?.requestId,
5475
- callSite: "messages"
5476
- });
5477
- logCopilotRateLimits(response.headers);
5478
- if (!response.ok) {
5479
- consola.error("Failed to create messages", response);
5480
- throw new HTTPError("Failed to create messages", response);
5481
- }
5482
- if (payload.stream) return events(response);
5483
- return await response.json();
5484
- };
5485
-
5486
- //#endregion
5487
- //#region src/routes/messages/stream-translation.ts
5488
- function isToolBlockOpen(state$1) {
5489
- if (!state$1.contentBlockOpen) return false;
5490
- return Object.values(state$1.toolCalls).some((tc) => tc.anthropicBlockIndex === state$1.contentBlockIndex);
5491
- }
5492
- function translateChunkToAnthropicEvents(chunk, state$1) {
5493
- const events$1 = [];
5494
- if (chunk.choices.length === 0) return events$1;
5495
- const choice = chunk.choices[0];
5496
- const { delta } = choice;
5497
- handleMessageStart(state$1, events$1, chunk);
5498
- handleThinkingText(delta, state$1, events$1);
5499
- handleContent(delta, state$1, events$1);
5500
- handleToolCalls(delta, state$1, events$1);
5501
- handleFinish(choice, state$1, {
5502
- events: events$1,
5503
- chunk
5504
- });
5505
- return events$1;
5506
- }
5507
- function handleFinish(choice, state$1, context) {
5508
- const { events: events$1, chunk } = context;
5509
- if (choice.finish_reason && choice.finish_reason.length > 0) {
5510
- if (state$1.contentBlockOpen) {
5511
- const toolBlockOpen = isToolBlockOpen(state$1);
5512
- context.events.push({
5513
- type: "content_block_stop",
5514
- index: state$1.contentBlockIndex
5515
- });
5516
- state$1.contentBlockOpen = false;
5517
- state$1.contentBlockIndex++;
5518
- if (!toolBlockOpen) handleReasoningOpaque(choice.delta, events$1, state$1);
5519
- }
5520
- events$1.push({
5521
- type: "message_delta",
5522
- delta: {
5523
- stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
5524
- stop_sequence: null
5525
- },
5526
- usage: {
5527
- input_tokens: (chunk.usage?.prompt_tokens ?? 0) - (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),
5528
- output_tokens: chunk.usage?.completion_tokens ?? 0,
5529
- ...chunk.usage?.prompt_tokens_details?.cached_tokens !== void 0 && { cache_read_input_tokens: chunk.usage.prompt_tokens_details.cached_tokens }
5530
- }
5531
- }, { type: "message_stop" });
5532
- }
5533
- }
5534
- function handleToolCalls(delta, state$1, events$1) {
5535
- if (delta.tool_calls && delta.tool_calls.length > 0) {
5536
- closeThinkingBlockIfOpen(state$1, events$1);
5537
- handleReasoningOpaqueInToolCalls(state$1, events$1, delta);
5538
- for (const toolCall of delta.tool_calls) {
5539
- if (toolCall.id && toolCall.function?.name) {
5540
- if (state$1.contentBlockOpen) {
5541
- events$1.push({
5542
- type: "content_block_stop",
5543
- index: state$1.contentBlockIndex
5544
- });
5545
- state$1.contentBlockIndex++;
5546
- state$1.contentBlockOpen = false;
5547
- }
5548
- const anthropicBlockIndex = state$1.contentBlockIndex;
5549
- state$1.toolCalls[toolCall.index] = {
5550
- id: toolCall.id,
5551
- name: toolCall.function.name,
5552
- anthropicBlockIndex
5553
- };
5554
- events$1.push({
5555
- type: "content_block_start",
5556
- index: anthropicBlockIndex,
5557
- content_block: {
5558
- type: "tool_use",
5559
- id: toolCall.id,
5560
- name: toolCall.function.name,
5561
- input: {}
5562
- }
5563
- });
5564
- state$1.contentBlockOpen = true;
5565
- }
5566
- if (toolCall.function?.arguments) {
5567
- const toolCallInfo = state$1.toolCalls[toolCall.index];
5568
- if (toolCallInfo) events$1.push({
5569
- type: "content_block_delta",
5570
- index: toolCallInfo.anthropicBlockIndex,
5571
- delta: {
5572
- type: "input_json_delta",
5573
- partial_json: toolCall.function.arguments
5574
- }
5575
- });
5576
- }
5577
- }
5578
- }
5579
- }
5580
- function handleReasoningOpaqueInToolCalls(state$1, events$1, delta) {
5581
- if (state$1.contentBlockOpen && !isToolBlockOpen(state$1)) {
5582
- events$1.push({
5583
- type: "content_block_stop",
5584
- index: state$1.contentBlockIndex
5585
- });
5586
- state$1.contentBlockIndex++;
5587
- state$1.contentBlockOpen = false;
5588
- }
5589
- handleReasoningOpaque(delta, events$1, state$1);
5590
- }
5591
- function handleContent(delta, state$1, events$1) {
5592
- if (delta.content && delta.content.length > 0) {
5593
- closeThinkingBlockIfOpen(state$1, events$1);
5594
- if (isToolBlockOpen(state$1)) {
5595
- events$1.push({
5596
- type: "content_block_stop",
5597
- index: state$1.contentBlockIndex
5598
- });
5599
- state$1.contentBlockIndex++;
5600
- state$1.contentBlockOpen = false;
5601
- }
5602
- if (!state$1.contentBlockOpen) {
5603
- events$1.push({
5604
- type: "content_block_start",
5605
- index: state$1.contentBlockIndex,
5606
- content_block: {
5607
- type: "text",
5608
- text: ""
5609
- }
5610
- });
5611
- state$1.contentBlockOpen = true;
5612
- }
5613
- events$1.push({
5614
- type: "content_block_delta",
5615
- index: state$1.contentBlockIndex,
5616
- delta: {
5617
- type: "text_delta",
5618
- text: delta.content
5619
- }
5620
- });
5621
- }
5622
- if (delta.content === "" && delta.reasoning_opaque && delta.reasoning_opaque.length > 0 && state$1.thinkingBlockOpen) {
5623
- events$1.push({
5624
- type: "content_block_delta",
5625
- index: state$1.contentBlockIndex,
5626
- delta: {
5627
- type: "signature_delta",
5628
- signature: delta.reasoning_opaque
5629
- }
5630
- }, {
5631
- type: "content_block_stop",
5632
- index: state$1.contentBlockIndex
5633
- });
5634
- state$1.contentBlockIndex++;
5635
- state$1.thinkingBlockOpen = false;
5636
- }
5637
- }
5638
- function handleMessageStart(state$1, events$1, chunk) {
5639
- if (!state$1.messageStartSent) {
5640
- const cachedTokens = chunk.usage?.prompt_tokens_details?.cached_tokens;
5641
- const upstreamPromptTokens = chunk.usage?.prompt_tokens;
5642
- const historicalInputTokens = state$1.historicalInputTokens;
5643
- const historicalOutputTokens = state$1.historicalOutputTokens ?? 0;
5644
- const historicalTotalTokens = historicalInputTokens !== void 0 ? historicalInputTokens + historicalOutputTokens : void 0;
5645
- const inputTokens = upstreamPromptTokens !== void 0 ? upstreamPromptTokens - (cachedTokens ?? 0) : historicalTotalTokens ?? state$1.estimatedInputTokens ?? 0;
5646
- const cacheReadTokens = upstreamPromptTokens !== void 0 ? cachedTokens : state$1.historicalCachedInputTokens;
5647
- events$1.push({
5648
- type: "message_start",
5649
- message: {
5650
- id: chunk.id,
5651
- type: "message",
5652
- role: "assistant",
5653
- content: [],
5654
- model: chunk.model,
5655
- stop_reason: null,
5656
- stop_sequence: null,
5657
- usage: {
5658
- input_tokens: inputTokens,
5659
- output_tokens: 0,
5660
- ...cacheReadTokens !== void 0 && { cache_read_input_tokens: cacheReadTokens }
5661
- }
5662
- }
5663
- });
5664
- state$1.messageStartSent = true;
5665
- }
5666
- }
5667
- function handleReasoningOpaque(delta, events$1, state$1) {
5668
- if (delta.reasoning_opaque && delta.reasoning_opaque.length > 0) {
5669
- events$1.push({
5670
- type: "content_block_start",
5671
- index: state$1.contentBlockIndex,
5672
- content_block: {
5673
- type: "thinking",
5674
- thinking: ""
5675
- }
5676
- }, {
5677
- type: "content_block_delta",
5678
- index: state$1.contentBlockIndex,
5679
- delta: {
5680
- type: "thinking_delta",
5681
- thinking: THINKING_TEXT
5682
- }
5683
- }, {
5684
- type: "content_block_delta",
5685
- index: state$1.contentBlockIndex,
5686
- delta: {
5687
- type: "signature_delta",
5688
- signature: delta.reasoning_opaque
5689
- }
5690
- }, {
5691
- type: "content_block_stop",
5692
- index: state$1.contentBlockIndex
5693
- });
5694
- state$1.contentBlockIndex++;
5695
- }
5696
- }
5697
- function handleThinkingText(delta, state$1, events$1) {
5698
- if (delta.reasoning_text && delta.reasoning_text.length > 0) {
5699
- if (state$1.contentBlockOpen) {
5700
- delta.content = delta.reasoning_text;
5701
- delta.reasoning_text = void 0;
5702
- return;
5703
- }
5704
- if (!state$1.thinkingBlockOpen) {
5705
- events$1.push({
5706
- type: "content_block_start",
5707
- index: state$1.contentBlockIndex,
5708
- content_block: {
5709
- type: "thinking",
5710
- thinking: ""
5711
- }
5712
- });
5713
- state$1.thinkingBlockOpen = true;
5714
- }
5715
- events$1.push({
5716
- type: "content_block_delta",
5717
- index: state$1.contentBlockIndex,
5718
- delta: {
5719
- type: "thinking_delta",
5720
- thinking: delta.reasoning_text
5721
- }
5722
- });
5723
- }
5724
- }
5725
- function closeThinkingBlockIfOpen(state$1, events$1) {
5726
- if (state$1.thinkingBlockOpen) {
5727
- events$1.push({
5728
- type: "content_block_delta",
5729
- index: state$1.contentBlockIndex,
5730
- delta: {
5731
- type: "signature_delta",
5732
- signature: ""
5733
- }
5734
- }, {
5735
- type: "content_block_stop",
5736
- index: state$1.contentBlockIndex
5737
- });
5738
- state$1.contentBlockIndex++;
5739
- state$1.thinkingBlockOpen = false;
6532
+ ...copilotHeaders(ctx, enableVision, options?.upstreamRequestId),
6533
+ "x-initiator": effectiveInitiator
6534
+ };
6535
+ prepareInteractionHeaders(options?.sessionId, Boolean(options?.subagentMarker), headers);
6536
+ prepareForCompact(headers, options?.compactType);
6537
+ if (shouldUseMessageProxyHeaders(payload)) prepareMessageProxyHeaders(headers);
6538
+ const anthropicBeta = buildAnthropicBetaHeader(options?.anthropicBetaHeader, payload.thinking, payload.model);
6539
+ if (anthropicBeta) headers["anthropic-beta"] = anthropicBeta;
6540
+ return headers;
6541
+ };
6542
+ const createMessages = async (payload, account, options) => {
6543
+ const ctx = account ?? accountFromState();
6544
+ if (!ctx.copilotToken) throw new Error("Copilot token not found");
6545
+ const headers = buildMessagesHeaders({
6546
+ ctx,
6547
+ enableVision: hasVisionInput(payload),
6548
+ initiator: options?.initiator ?? getMessagesInitiator(payload),
6549
+ options,
6550
+ payload
6551
+ });
6552
+ captureOutboundHeadersSnapshot(headers);
6553
+ const response = await copilotFetch(`${copilotBaseUrl(ctx)}/v1/messages`, {
6554
+ method: "POST",
6555
+ headers,
6556
+ body: JSON.stringify(payload)
6557
+ }, {
6558
+ requestId: options?.requestId,
6559
+ callSite: "messages",
6560
+ fetchImpl: options?.fetchImpl
6561
+ });
6562
+ logCopilotRateLimits(response.headers);
6563
+ if (!response.ok) {
6564
+ consola.error("Failed to create messages", response);
6565
+ throw new HTTPError("Failed to create messages", response);
5740
6566
  }
5741
- }
5742
-
5743
- //#endregion
5744
- //#region src/lib/subagent.ts
5745
- const subagentMarkerPrefix = "__SUBAGENT_MARKER__";
5746
-
6567
+ if (payload.stream) return events(response);
6568
+ return await response.json();
6569
+ };
5747
6570
  //#endregion
5748
6571
  //#region src/routes/messages/subagent-marker.ts
5749
6572
  const subagentStartContextPrefix = "SubagentStart hook additional context:";
@@ -5778,8 +6601,8 @@ const extractMarkerPayloadFromReminderLine = (line) => {
5778
6601
  if (!trimmedLine) return null;
5779
6602
  let markerLine = trimmedLine;
5780
6603
  if (markerLine.startsWith(subagentStartContextPrefix)) markerLine = markerLine.slice(38).trimStart();
5781
- if (!markerLine.startsWith(subagentMarkerPrefix)) return null;
5782
- return markerLine.slice(subagentMarkerPrefix.length).trimStart();
6604
+ if (!markerLine.startsWith("__SUBAGENT_MARKER__")) return null;
6605
+ return markerLine.slice(19).trimStart();
5783
6606
  };
5784
6607
  const inspectSubagentMarkerFromSystemReminder = (text) => {
5785
6608
  let sawInvalidMarker = false;
@@ -5848,32 +6671,127 @@ const extractBalancedJson = (text) => {
5848
6671
  }
5849
6672
  return null;
5850
6673
  };
5851
-
5852
6674
  //#endregion
5853
6675
  //#region src/routes/messages/handler.ts
5854
- const logger$5 = createHandlerLogger("messages-handler");
6676
+ const logger$3 = createHandlerLogger("messages-handler");
5855
6677
  const CHAT_COMPLETIONS_ENDPOINT = "/chat/completions";
5856
6678
  const RESPONSES_ENDPOINT$1 = "/responses";
5857
6679
  const MESSAGES_ENDPOINT = "/v1/messages";
6680
+ function normalizeProviderAliasUsage(usage) {
6681
+ const tokensInput = usage.inputTokens === void 0 ? void 0 : Math.max(0, usage.inputTokens);
6682
+ const tokensCachedInput = usage.cacheReadInputTokens;
6683
+ const tokensTotal = usage.inputTokens === void 0 && usage.outputTokens === void 0 ? void 0 : (tokensInput ?? 0) + (usage.outputTokens ?? 0) + (usage.cacheCreationInputTokens ?? 0) + (tokensCachedInput ?? 0);
6684
+ return {
6685
+ tokensCachedInput,
6686
+ tokensInput,
6687
+ tokensOutput: usage.outputTokens,
6688
+ tokensTotal,
6689
+ usageJson: JSON.stringify({
6690
+ input_tokens: usage.inputTokens,
6691
+ output_tokens: usage.outputTokens,
6692
+ cache_creation_input_tokens: usage.cacheCreationInputTokens,
6693
+ cache_read_input_tokens: usage.cacheReadInputTokens
6694
+ })
6695
+ };
6696
+ }
6697
+ async function handleProviderAliasCompletion(c, options) {
6698
+ const { payload, provider, providerModel } = options;
6699
+ const requestId = randomUUID();
6700
+ const startedAtMs = Date.now();
6701
+ const method = c.req.raw.method;
6702
+ const path = new URL(c.req.url, "http://local").pathname;
6703
+ const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
6704
+ const userAgent = c.req.header("user-agent") ?? void 0;
6705
+ const streamRequested = Boolean(payload.stream);
6706
+ const originalModel = payload.model;
6707
+ const rawUserId = payload.metadata?.user_id;
6708
+ const userId = typeof rawUserId === "string" ? rawUserId : void 0;
6709
+ const { safetyIdentifier, sessionId: promptCacheKey } = parseUserIdMetadata(userId);
6710
+ const isSubagent = inspectSubagentMarkerFromFirstUser(payload).kind === "valid";
6711
+ let requestRecorded = false;
6712
+ const insertProviderAliasLog = (record) => {
6713
+ if (requestRecorded) {
6714
+ logger$3.warn("provider alias request already recorded", { requestId });
6715
+ return;
6716
+ }
6717
+ requestRecorded = true;
6718
+ const finishedAtMs = Date.now();
6719
+ getRequestHistoryStore().insert({
6720
+ requestId,
6721
+ startedAtMs,
6722
+ finishedAtMs,
6723
+ durationMs: finishedAtMs - startedAtMs,
6724
+ method,
6725
+ path,
6726
+ clientIp,
6727
+ clientIpSource,
6728
+ userAgent,
6729
+ userId,
6730
+ safetyIdentifier: safetyIdentifier ?? void 0,
6731
+ promptCacheKey: promptCacheKey ?? void 0,
6732
+ isSubagent,
6733
+ clientModel: originalModel,
6734
+ upstreamEndpoint: `/providers/${provider}/messages`,
6735
+ stream: streamRequested,
6736
+ upstreamModel: providerModel,
6737
+ ...record
6738
+ });
6739
+ };
6740
+ const instrumentation = {
6741
+ onComplete: (usage) => {
6742
+ insertProviderAliasLog({
6743
+ ...normalizeProviderAliasUsage(usage),
6744
+ httpStatus: 200
6745
+ });
6746
+ },
6747
+ onError: (error) => {
6748
+ insertProviderAliasLog({
6749
+ httpStatus: error.httpStatus,
6750
+ errorName: error.errorName,
6751
+ errorStatus: error.errorStatus,
6752
+ errorMessage: error.errorMessage,
6753
+ upstreamErrorMessageRaw: error.upstreamErrorMessageRaw
6754
+ });
6755
+ }
6756
+ };
6757
+ payload.model = providerModel;
6758
+ try {
6759
+ return await handleProviderMessagesForProvider(c, {
6760
+ instrumentation,
6761
+ payload,
6762
+ provider
6763
+ });
6764
+ } catch (error) {
6765
+ const observableError = await extractErrorObservability(error);
6766
+ instrumentation.onError?.(observableError);
6767
+ throw error;
6768
+ }
6769
+ }
5858
6770
  async function handleCompletion(c) {
6771
+ const anthropicPayload = await c.req.json();
6772
+ const providerModelAlias = parseProviderModelAlias(anthropicPayload.model);
6773
+ if (providerModelAlias) return await handleProviderAliasCompletion(c, {
6774
+ payload: anthropicPayload,
6775
+ provider: providerModelAlias.provider,
6776
+ providerModel: providerModelAlias.model
6777
+ });
5859
6778
  await checkRateLimit(state);
5860
6779
  const store = getRequestHistoryStore();
5861
6780
  const requestId = randomUUID();
5862
6781
  const startedAtMs = Date.now();
5863
6782
  const method = c.req.raw.method;
5864
- const path$2 = new URL(c.req.url, "http://local").pathname;
6783
+ const path = new URL(c.req.url, "http://local").pathname;
5865
6784
  const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
5866
6785
  const userAgent = c.req.header("user-agent") ?? void 0;
5867
- const anthropicPayload = await c.req.json();
5868
6786
  sanitizeIdeTools(anthropicPayload);
5869
- debugJson(logger$5, "Anthropic request payload:", anthropicPayload);
6787
+ debugJson(logger$3, "Anthropic request payload:", anthropicPayload);
5870
6788
  const markerInspection = inspectSubagentMarkerFromFirstUser(anthropicPayload);
5871
6789
  const subagentMarker = markerInspection.kind === "valid" ? markerInspection.marker : null;
5872
6790
  const isSubagentRequest = subagentMarker !== null;
5873
6791
  const invalidSubagentMarkerSelectionReason = markerInspection.kind === "invalid" ? "subagent_marker_invalid_fallback" : void 0;
5874
- if (subagentMarker) debugJson(logger$5, "Detected Subagent marker:", subagentMarker);
6792
+ if (subagentMarker) debugJson(logger$3, "Detected Subagent marker:", subagentMarker);
5875
6793
  const sessionId = getRootSessionId(anthropicPayload, c);
5876
- logger$5.debug("Extracted session ID:", sessionId);
6794
+ logger$3.debug("Extracted session ID:", sessionId);
5877
6795
  const ownershipLookupSessionId = markerInspection.kind === "valid" ? normalizeStableSessionId(markerInspection.marker.session_id) : void 0;
5878
6796
  const ownershipWriteSessionId = markerInspection.kind === "none" ? sessionId : void 0;
5879
6797
  const anthropicBeta = c.req.header("anthropic-beta");
@@ -5881,14 +6799,14 @@ async function handleCompletion(c) {
5881
6799
  const isCompact = compactType !== 0;
5882
6800
  const originalRequestModel = anthropicPayload.model;
5883
6801
  if (anthropicBeta && isWarmupProbeRequest(anthropicPayload)) anthropicPayload.model = getSmallModel();
5884
- if (compactType !== 0) logger$5.debug("Compact request type:", compactType);
5885
- if (compactType === COMPACT_REQUEST && shouldCompactUseSmallModel()) anthropicPayload.model = getSmallModel();
6802
+ if (compactType !== 0) logger$3.debug("Compact request type:", compactType);
6803
+ if (compactType === 1 && shouldCompactUseSmallModel()) anthropicPayload.model = getSmallModel();
5886
6804
  if (compactType === 0) {
5887
6805
  stripToolReferenceTurnBoundary(anthropicPayload);
5888
6806
  mergeToolResultForClaude(anthropicPayload);
5889
6807
  }
5890
6808
  const upstreamRequestId = generateRequestIdFromPayload(anthropicPayload, sessionId);
5891
- logger$5.debug("Generated request ID:", upstreamRequestId);
6809
+ logger$3.debug("Generated request ID:", upstreamRequestId);
5892
6810
  const clientModel = anthropicPayload.model;
5893
6811
  const streamRequested = Boolean(anthropicPayload.stream);
5894
6812
  const rawUserId = anthropicPayload.metadata?.user_id;
@@ -5907,7 +6825,7 @@ async function handleCompletion(c) {
5907
6825
  requestId,
5908
6826
  startedAtMs,
5909
6827
  method,
5910
- path: path$2,
6828
+ path,
5911
6829
  streamRequested,
5912
6830
  clientModel,
5913
6831
  clientIp,
@@ -5942,11 +6860,13 @@ async function handleCompletion(c) {
5942
6860
  headerSessionId: c.req.header("x-session-id") ?? null,
5943
6861
  upstreamRequestId
5944
6862
  });
6863
+ const responsesItemOwnershipKeys = extractAnthropicResponsesItemOwnerKeys(anthropicPayload);
5945
6864
  const selection = await accountsManager.selectAccountForRequest(candidates, {
5946
6865
  requestId: affinityKey.requestId,
5947
6866
  affinityModelId,
5948
6867
  ownershipLookupSessionId,
5949
- ownershipWriteSessionId
6868
+ ownershipWriteSessionId,
6869
+ responsesItemOwnershipKeys
5950
6870
  });
5951
6871
  const selectionReason = invalidSubagentMarkerSelectionReason ?? selection.selectionReason;
5952
6872
  if (!selection.ok) return handleSelectionFailure({
@@ -5955,7 +6875,7 @@ async function handleCompletion(c) {
5955
6875
  requestId,
5956
6876
  startedAtMs,
5957
6877
  method,
5958
- path: path$2,
6878
+ path,
5959
6879
  streamRequested,
5960
6880
  clientModel,
5961
6881
  clientIp,
@@ -5969,6 +6889,7 @@ async function handleCompletion(c) {
5969
6889
  affinityKeyUsed: affinityKey.affinityKeyUsed,
5970
6890
  affinityKeySource: affinityKey.affinityKeySource,
5971
6891
  selectionReason,
6892
+ responsesItemOwnerLookupKeys: responsesItemOwnershipKeys,
5972
6893
  selection
5973
6894
  });
5974
6895
  const { account, reservation, selectedModel, endpoint, costUnits } = selection;
@@ -5982,7 +6903,7 @@ async function handleCompletion(c) {
5982
6903
  requestId,
5983
6904
  startedAtMs,
5984
6905
  method,
5985
- path: path$2,
6906
+ path,
5986
6907
  clientIp,
5987
6908
  clientIpSource,
5988
6909
  userAgent,
@@ -6005,7 +6926,8 @@ async function handleCompletion(c) {
6005
6926
  affinityCacheKey: selection.affinityCacheKey,
6006
6927
  affinityKeyUsed: affinityKey.affinityKeyUsed,
6007
6928
  affinityKeySource: affinityKey.affinityKeySource,
6008
- selectionReason
6929
+ selectionReason,
6930
+ responsesItemOwnerLookupKeys: responsesItemOwnershipKeys
6009
6931
  };
6010
6932
  if (endpoint === MESSAGES_ENDPOINT) return await handleWithMessagesApi({
6011
6933
  c,
@@ -6039,7 +6961,7 @@ async function handleCompletion(c) {
6039
6961
  }
6040
6962
  const handleWithChatCompletions = async (params) => {
6041
6963
  const { c, openAIPayload, subagentMarker, sessionId, selectedModel, instr, compactType } = params;
6042
- debugJson(logger$5, "Translated OpenAI request payload:", openAIPayload);
6964
+ debugJson(logger$3, "Translated OpenAI request payload:", openAIPayload);
6043
6965
  const ctx = toAccountContext(instr.account);
6044
6966
  const effectiveInitiator = resolveEffectiveInitiator(getChatInitiator(openAIPayload.messages), {
6045
6967
  isCompact: compactType !== 0,
@@ -6070,9 +6992,9 @@ const handleWithChatCompletions = async (params) => {
6070
6992
  response,
6071
6993
  instr
6072
6994
  });
6073
- logger$5.debug("Streaming response from Copilot");
6995
+ logger$3.debug("Streaming response from Copilot");
6074
6996
  const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
6075
- const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$5) : void 0;
6997
+ const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$3) : void 0;
6076
6998
  const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
6077
6999
  promptCacheKey: instr.promptCacheKey,
6078
7000
  safetyIdentifier: instr.safetyIdentifier,
@@ -6091,7 +7013,7 @@ const handleWithResponsesApi = async (params) => {
6091
7013
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload, selectedModel.id);
6092
7014
  applyResponsesApiContextManagement(responsesPayload, selectedModel.capabilities.limits.max_prompt_tokens);
6093
7015
  compactInputByLatestCompaction(responsesPayload);
6094
- debugJson(logger$5, "Translated Responses payload:", responsesPayload);
7016
+ debugJson(logger$3, "Translated Responses payload:", responsesPayload);
6095
7017
  const { vision, initiator } = getResponsesRequestOptions(responsesPayload);
6096
7018
  const effectiveInitiator = resolveEffectiveInitiator(initiator, {
6097
7019
  isCompact: compactType !== 0,
@@ -6119,10 +7041,10 @@ const handleWithResponsesApi = async (params) => {
6119
7041
  stream: Boolean(responsesPayload.stream)
6120
7042
  });
6121
7043
  }
6122
- if (responsesPayload.stream && isAsyncIterable$1(response)) {
6123
- logger$5.debug("Streaming response from Copilot (Responses API)");
7044
+ if (responsesPayload.stream && isAsyncIterable(response)) {
7045
+ logger$3.debug("Streaming response from Copilot (Responses API)");
6124
7046
  const fallbackEnabled = isMessageStartInputTokensFallbackEnabled();
6125
- const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$5) : void 0;
7047
+ const estimatedInputTokens = fallbackEnabled ? await estimateInputTokens(openAIPayload, selectedModel, logger$3) : void 0;
6126
7048
  const historicalUsage = fallbackEnabled && instr.promptCacheKey && instr.safetyIdentifier ? instr.store.getLastCompletedUsageBySession({
6127
7049
  promptCacheKey: instr.promptCacheKey,
6128
7050
  safetyIdentifier: instr.safetyIdentifier,
@@ -6142,13 +7064,16 @@ const handleWithResponsesApi = async (params) => {
6142
7064
  instr
6143
7065
  });
6144
7066
  };
7067
+ function stringifyOwnerKeys(keys) {
7068
+ return keys && keys.length > 0 ? JSON.stringify(keys) : void 0;
7069
+ }
6145
7070
  function insertRequestLog$1(instr, record) {
6146
- const { store, requestId, startedAtMs, method, path: path$2, clientIp, clientIpSource, userAgent, clientModel, account, upstreamEndpoint, upstreamModel, costUnits, premiumRemainingBefore, premiumUnlimitedBefore } = instr;
7071
+ const { store, requestId, startedAtMs, method, path, clientIp, clientIpSource, userAgent, clientModel, account, upstreamEndpoint, upstreamModel, costUnits, premiumRemainingBefore, premiumUnlimitedBefore } = instr;
6147
7072
  store.insert({
6148
7073
  requestId,
6149
7074
  startedAtMs,
6150
7075
  method,
6151
- path: path$2,
7076
+ path,
6152
7077
  clientIp,
6153
7078
  clientIpSource,
6154
7079
  userAgent,
@@ -6171,7 +7096,9 @@ function insertRequestLog$1(instr, record) {
6171
7096
  upstreamModel,
6172
7097
  premiumRemainingBefore,
6173
7098
  premiumUnlimitedBefore,
6174
- ...record
7099
+ ...record,
7100
+ responsesItemOwnerLookupKeysJson: stringifyOwnerKeys(instr.responsesItemOwnerLookupKeys),
7101
+ responsesItemOwnerRecordedKeysJson: stringifyOwnerKeys(instr.responsesItemOwnerRecordedKeys)
6175
7102
  });
6176
7103
  flushPendingCapture(requestId);
6177
7104
  }
@@ -6215,9 +7142,9 @@ async function handleChatCompletionsNonStreaming(params) {
6215
7142
  let upstreamErrorMessageRaw;
6216
7143
  const finishedAtMs = Date.now();
6217
7144
  try {
6218
- logger$5.debug("Non-streaming response from Copilot:", JSON.stringify(response));
7145
+ logger$3.debug("Non-streaming response from Copilot:", JSON.stringify(response));
6219
7146
  const anthropicResponse = translateToAnthropic(response);
6220
- debugJson(logger$5, "Translated Anthropic response:", anthropicResponse);
7147
+ debugJson(logger$3, "Translated Anthropic response:", anthropicResponse);
6221
7148
  return c.json(anthropicResponse);
6222
7149
  } catch (error) {
6223
7150
  const details = await extractErrorObservability(error);
@@ -6268,16 +7195,16 @@ async function streamChatCompletionsAndLog(params) {
6268
7195
  try {
6269
7196
  for await (const rawEvent of response) {
6270
7197
  if (ttfbMs === void 0) ttfbMs = Date.now() - instr.startedAtMs;
6271
- logger$5.debug("Copilot raw stream event:", JSON.stringify(rawEvent));
7198
+ logger$3.debug("Copilot raw stream event:", JSON.stringify(rawEvent));
6272
7199
  const { data: rawData } = rawEvent;
6273
7200
  const data = typeof rawData === "string" ? rawData : await rawData;
6274
7201
  if (data === "[DONE]") break;
6275
7202
  if (!data) continue;
6276
7203
  const chunk = JSON.parse(data);
6277
7204
  if (chunk.usage) lastUsage = normalizeChatCompletionsUsage(chunk.usage);
6278
- const events$1 = translateChunkToAnthropicEvents(chunk, streamState);
6279
- for (const event of events$1) {
6280
- logger$5.debug("Translated Anthropic event:", JSON.stringify(event));
7205
+ const events = translateChunkToAnthropicEvents(chunk, streamState);
7206
+ for (const event of events) {
7207
+ logger$3.debug("Translated Anthropic event:", JSON.stringify(event));
6281
7208
  await stream.writeSSE({
6282
7209
  event: event.type,
6283
7210
  data: JSON.stringify(event)
@@ -6290,7 +7217,7 @@ async function streamChatCompletionsAndLog(params) {
6290
7217
  errorStatus = details.errorStatus;
6291
7218
  errorMessage = details.errorMessage;
6292
7219
  upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
6293
- logger$5.warn("Streaming error:", error);
7220
+ logger$3.warn("Streaming error:", error);
6294
7221
  if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
6295
7222
  await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
6296
7223
  } finally {
@@ -6349,10 +7276,14 @@ async function handleResponsesNonStreaming(params) {
6349
7276
  const finishedAtMs = Date.now();
6350
7277
  try {
6351
7278
  usage = extractResponsesUsageFromResult(result);
6352
- logger$5.debug("Non-streaming Responses result:", JSON.stringify(result).slice(-400));
7279
+ const responseOwnerKeys = extractResponsesResultOwnerKeys(result);
7280
+ instr.responsesItemOwnerRecordedKeys = responseOwnerKeys;
7281
+ logger$3.debug("Non-streaming Responses result:", JSON.stringify(result).slice(-400));
6353
7282
  const anthropicResponse = translateResponsesResultToAnthropic(result);
6354
- debugJson(logger$5, "Translated Anthropic response:", anthropicResponse);
6355
- return c.json(anthropicResponse);
7283
+ debugJson(logger$3, "Translated Anthropic response:", anthropicResponse);
7284
+ const response = c.json(anthropicResponse);
7285
+ if (result.status === "completed") accountsManager.recordResponsesItemOwnership(responseOwnerKeys, instr.account.id);
7286
+ return response;
6356
7287
  } catch (error) {
6357
7288
  const details = await extractErrorObservability(error);
6358
7289
  httpStatus = details.httpStatus;
@@ -6383,7 +7314,7 @@ async function handleResponsesNonStreaming(params) {
6383
7314
  async function ensureResponsesStreamCompleted(params) {
6384
7315
  const { stream, streamState, setStreamError } = params;
6385
7316
  if (streamState.messageCompleted) return;
6386
- logger$5.warn("Responses stream ended without completion; sending error event");
7317
+ logger$3.warn("Responses stream ended without completion; sending error event");
6387
7318
  const msg = "Responses stream ended without completion";
6388
7319
  const errorEvent = buildErrorEvent(msg);
6389
7320
  setStreamError("StreamIncomplete", msg);
@@ -6400,22 +7331,66 @@ async function writeAnthropicStreamError(stream, message) {
6400
7331
  data: JSON.stringify(errorEvent)
6401
7332
  });
6402
7333
  } catch (streamError) {
6403
- logger$5.warn("Failed to write Anthropic stream error event:", streamError);
7334
+ logger$3.warn("Failed to write Anthropic stream error event:", streamError);
7335
+ }
7336
+ }
7337
+ function collectResponsesStreamOwnerKeys(event, responseOwnerKeys) {
7338
+ for (const key of extractResponsesStreamEventOwnerKeys(event)) responseOwnerKeys.add(key);
7339
+ }
7340
+ function createResponsesStreamStateWithUsage(params) {
7341
+ const streamState = createResponsesStreamState();
7342
+ streamState.estimatedInputTokens = params.estimatedInputTokens;
7343
+ streamState.historicalInputTokens = params.historicalUsage?.tokensInput;
7344
+ streamState.historicalOutputTokens = params.historicalUsage?.tokensOutput;
7345
+ streamState.historicalCachedInputTokens = params.historicalUsage?.tokensCachedInput;
7346
+ return streamState;
7347
+ }
7348
+ function recordStreamOwnerKeys(streamState, responseOwnerKeys, instr) {
7349
+ if (!streamState.messageCompleted) return;
7350
+ const ownerKeys = [...responseOwnerKeys];
7351
+ instr.responsesItemOwnerRecordedKeys = ownerKeys;
7352
+ if (streamState.responseStatus === "completed") accountsManager.recordResponsesItemOwnership(ownerKeys, instr.account.id);
7353
+ }
7354
+ function getResponsesStreamEventError(event) {
7355
+ if (event.type === "response.failed") {
7356
+ const message = event.response.error?.message ?? "Responses stream failed upstream.";
7357
+ return {
7358
+ errorName: "ResponsesStreamFailed",
7359
+ errorStatus: 502,
7360
+ errorMessage: message,
7361
+ upstreamErrorMessageRaw: message
7362
+ };
7363
+ }
7364
+ if (event.type === "error") {
7365
+ const message = event.message || "Responses stream returned an error.";
7366
+ return {
7367
+ errorName: "ResponsesStreamError",
7368
+ errorStatus: 502,
7369
+ errorMessage: message,
7370
+ upstreamErrorMessageRaw: message
7371
+ };
7372
+ }
7373
+ }
7374
+ async function writeTranslatedAnthropicStreamEvents(stream, events) {
7375
+ for (const event of events) {
7376
+ const eventData = JSON.stringify(event);
7377
+ logger$3.debug("Translated Anthropic event:", eventData);
7378
+ await stream.writeSSE({
7379
+ event: event.type,
7380
+ data: eventData
7381
+ });
6404
7382
  }
6405
7383
  }
6406
7384
  async function streamResponsesAndLog$1(params) {
6407
- const { stream, response, instr, estimatedInputTokens, historicalUsage } = params;
7385
+ const { stream, response, instr } = params;
6408
7386
  let ttfbMs;
6409
7387
  let lastUsage = {};
6410
7388
  let errorName;
6411
7389
  let errorStatus;
6412
7390
  let errorMessage;
6413
7391
  let upstreamErrorMessageRaw;
6414
- const streamState = createResponsesStreamState();
6415
- streamState.estimatedInputTokens = estimatedInputTokens;
6416
- streamState.historicalInputTokens = historicalUsage?.tokensInput;
6417
- streamState.historicalOutputTokens = historicalUsage?.tokensOutput;
6418
- streamState.historicalCachedInputTokens = historicalUsage?.tokensCachedInput;
7392
+ const streamState = createResponsesStreamStateWithUsage(params);
7393
+ const responseOwnerKeys = /* @__PURE__ */ new Set();
6419
7394
  try {
6420
7395
  for await (const chunk of response) {
6421
7396
  if (ttfbMs === void 0) ttfbMs = Date.now() - instr.startedAtMs;
@@ -6428,21 +7403,21 @@ async function streamResponsesAndLog$1(params) {
6428
7403
  }
6429
7404
  const data = chunk.data;
6430
7405
  if (!data) continue;
6431
- logger$5.debug("Responses raw stream event:", data);
7406
+ logger$3.debug("Responses raw stream event:", data);
6432
7407
  const parsed = JSON.parse(data);
7408
+ const streamEventError = getResponsesStreamEventError(parsed);
7409
+ if (streamEventError) {
7410
+ errorName = streamEventError.errorName;
7411
+ errorStatus = streamEventError.errorStatus;
7412
+ errorMessage = streamEventError.errorMessage;
7413
+ upstreamErrorMessageRaw = streamEventError.upstreamErrorMessageRaw;
7414
+ }
7415
+ collectResponsesStreamOwnerKeys(parsed, responseOwnerKeys);
6433
7416
  const u = extractResponsesUsageFromStreamEvent(parsed);
6434
7417
  if (u.usageJson) lastUsage = u;
6435
- const events$1 = translateResponsesStreamEvent(parsed, streamState);
6436
- for (const event of events$1) {
6437
- const eventData = JSON.stringify(event);
6438
- logger$5.debug("Translated Anthropic event:", eventData);
6439
- await stream.writeSSE({
6440
- event: event.type,
6441
- data: eventData
6442
- });
6443
- }
7418
+ await writeTranslatedAnthropicStreamEvents(stream, translateResponsesStreamEvent(parsed, streamState));
6444
7419
  if (streamState.messageCompleted) {
6445
- logger$5.debug("Message completed, ending stream");
7420
+ logger$3.debug("Message completed, ending stream");
6446
7421
  break;
6447
7422
  }
6448
7423
  }
@@ -6454,13 +7429,14 @@ async function streamResponsesAndLog$1(params) {
6454
7429
  errorMessage = message;
6455
7430
  }
6456
7431
  });
7432
+ recordStreamOwnerKeys(streamState, responseOwnerKeys, instr);
6457
7433
  } catch (error) {
6458
7434
  const details = await extractErrorObservability(error);
6459
7435
  errorName = details.errorName;
6460
7436
  errorStatus = details.errorStatus;
6461
7437
  errorMessage = details.errorMessage;
6462
7438
  upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
6463
- logger$5.warn("Streaming error:", error);
7439
+ logger$3.warn("Streaming error:", error);
6464
7440
  invalidateAffinityOnOwnershipMismatch(details.ownershipMismatch, instr);
6465
7441
  if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
6466
7442
  await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
@@ -6515,7 +7491,7 @@ async function handleMessagesNonStreaming(params) {
6515
7491
  let upstreamErrorMessageRaw;
6516
7492
  const finishedAtMs = Date.now();
6517
7493
  try {
6518
- logger$5.debug("Non-streaming Messages result:", JSON.stringify(response).slice(-400));
7494
+ logger$3.debug("Non-streaming Messages result:", JSON.stringify(response).slice(-400));
6519
7495
  return c.json(response);
6520
7496
  } catch (error) {
6521
7497
  const details = await extractErrorObservability(error);
@@ -6545,14 +7521,15 @@ async function handleMessagesNonStreaming(params) {
6545
7521
  }
6546
7522
  }
6547
7523
  const parseMessagesStreamUsage = (data) => {
6548
- if (!data) return null;
7524
+ if (!data || data === "[DONE]") return null;
6549
7525
  try {
6550
7526
  const parsed = JSON.parse(data);
7527
+ if (parsed.type === "error") throw new Error(parsed.error.message);
6551
7528
  if (parsed.type !== "message_delta" || !parsed.usage) return null;
6552
7529
  return normalizeMessagesUsage(parsed.usage);
6553
7530
  } catch (error) {
6554
- logger$5.warn("Failed to parse messages stream event", error);
6555
- return null;
7531
+ logger$3.warn("Failed to parse messages stream event", error);
7532
+ throw new Error("Failed to parse messages stream event", { cause: error });
6556
7533
  }
6557
7534
  };
6558
7535
  async function streamMessagesAndLog(params) {
@@ -6569,7 +7546,7 @@ async function streamMessagesAndLog(params) {
6569
7546
  const eventNameRaw = rawEvent.event;
6570
7547
  const eventName = typeof eventNameRaw === "string" && eventNameRaw.length > 0 ? eventNameRaw : "message";
6571
7548
  const data = rawEvent.data ?? "";
6572
- logger$5.debug("Messages raw stream event:", data);
7549
+ logger$3.debug("Messages raw stream event:", data);
6573
7550
  const usage = parseMessagesStreamUsage(data);
6574
7551
  if (usage) lastUsage = usage;
6575
7552
  await stream.writeSSE({
@@ -6583,7 +7560,7 @@ async function streamMessagesAndLog(params) {
6583
7560
  errorStatus = details.errorStatus;
6584
7561
  errorMessage = details.errorMessage;
6585
7562
  upstreamErrorMessageRaw = details.upstreamErrorMessageRaw;
6586
- logger$5.warn("Streaming error:", error);
7563
+ logger$3.warn("Streaming error:", error);
6587
7564
  if (shouldMarkAccountFailed(details)) accountsManager.markAccountFailed(instr.account.id, "Unauthorized (401)");
6588
7565
  await writeAnthropicStreamError(stream, getUserVisibleErrorMessage(details));
6589
7566
  } finally {
@@ -6609,7 +7586,7 @@ async function streamMessagesAndLog(params) {
6609
7586
  const handleWithMessagesApi = async (params) => {
6610
7587
  const { c, anthropicPayload, anthropicBetaHeader, subagentMarker, sessionId, instr, selectedModel, compactType } = params;
6611
7588
  prepareMessagesApiPayload(anthropicPayload, selectedModel);
6612
- debugJson(logger$5, "Translated Messages payload:", anthropicPayload);
7589
+ debugJson(logger$3, "Translated Messages payload:", anthropicPayload);
6613
7590
  const ctx = toAccountContext(instr.account);
6614
7591
  const effectiveInitiator = resolveEffectiveInitiator(getMessagesInitiator(anthropicPayload), {
6615
7592
  isCompact: compactType !== 0,
@@ -6636,8 +7613,8 @@ const handleWithMessagesApi = async (params) => {
6636
7613
  stream: Boolean(anthropicPayload.stream)
6637
7614
  });
6638
7615
  }
6639
- if (isAsyncIterable$1(response)) {
6640
- logger$5.debug("Streaming response from Copilot (Messages API)");
7616
+ if (isAsyncIterable(response)) {
7617
+ logger$3.debug("Streaming response from Copilot (Messages API)");
6641
7618
  return streamSSE(c, (stream) => streamMessagesAndLog({
6642
7619
  stream,
6643
7620
  response,
@@ -6651,8 +7628,7 @@ const handleWithMessagesApi = async (params) => {
6651
7628
  });
6652
7629
  };
6653
7630
  const isNonStreaming = (response) => Object.hasOwn(response, "choices");
6654
- const isAsyncIterable$1 = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
6655
-
7631
+ const isAsyncIterable = (value) => Boolean(value) && typeof value[Symbol.asyncIterator] === "function";
6656
7632
  //#endregion
6657
7633
  //#region src/routes/messages/route.ts
6658
7634
  const messageRoutes = new Hono();
@@ -6670,22 +7646,23 @@ messageRoutes.post("/count_tokens", async (c) => {
6670
7646
  return await forwardError(c, error);
6671
7647
  }
6672
7648
  });
6673
-
6674
7649
  //#endregion
6675
7650
  //#region src/routes/models/route.ts
6676
7651
  const modelRoutes = new Hono();
6677
7652
  modelRoutes.get("/", async (c) => {
6678
7653
  try {
6679
7654
  const blockedTargets = getAliasTargetSet();
6680
- const models = getAvailableModels().filter((model) => !blockedTargets.has(model.id.toLowerCase())).map((model) => ({
6681
- id: model.id,
6682
- object: "model",
6683
- type: "model",
6684
- created: 0,
6685
- created_at: (/* @__PURE__ */ new Date(0)).toISOString(),
6686
- owned_by: model.vendor,
6687
- display_name: model.name
6688
- }));
7655
+ const models = getAvailableModels().filter((model) => !blockedTargets.has(model.id.toLowerCase())).map((model) => {
7656
+ return {
7657
+ id: model.capabilities.limits?.max_context_window_tokens === 1e6 ? `${model.id}[1m]` : model.id,
7658
+ object: "model",
7659
+ type: "model",
7660
+ created: 0,
7661
+ created_at: (/* @__PURE__ */ new Date(0)).toISOString(),
7662
+ owned_by: model.vendor,
7663
+ display_name: model.name
7664
+ };
7665
+ });
6689
7666
  const aliasModels = Object.keys(getModelAliases()).map((alias) => ({
6690
7667
  id: alias,
6691
7668
  object: "model",
@@ -6707,195 +7684,6 @@ modelRoutes.get("/", async (c) => {
6707
7684
  return await forwardError(c, error);
6708
7685
  }
6709
7686
  });
6710
-
6711
- //#endregion
6712
- //#region src/routes/provider/messages/count-tokens-handler.ts
6713
- const logger$4 = createHandlerLogger("provider-count-tokens-handler");
6714
- const createFallbackModel = (modelId) => ({
6715
- capabilities: {
6716
- family: "provider",
6717
- limits: {},
6718
- object: "model_capabilities",
6719
- supports: {},
6720
- tokenizer: "o200k_base",
6721
- type: "chat"
6722
- },
6723
- id: modelId,
6724
- model_picker_enabled: false,
6725
- name: modelId,
6726
- object: "model",
6727
- preview: false,
6728
- vendor: "provider",
6729
- version: "unknown"
6730
- });
6731
- async function handleProviderCountTokens(c) {
6732
- const provider = c.req.param("provider");
6733
- try {
6734
- const anthropicPayload = await c.req.json();
6735
- const openAIPayload = translateToOpenAI(anthropicPayload);
6736
- const modelId = anthropicPayload.model.trim();
6737
- let selectedModel = getAvailableModels().find((model) => model.id === modelId);
6738
- if (!selectedModel && modelId) selectedModel = createFallbackModel(modelId);
6739
- if (!selectedModel) {
6740
- logger$4.warn("provider.count_tokens.model_not_found", {
6741
- provider,
6742
- model: anthropicPayload.model
6743
- });
6744
- return c.json({ input_tokens: 1 });
6745
- }
6746
- const tokenCount = await getTokenCount(openAIPayload, selectedModel);
6747
- const finalTokenCount = tokenCount.input + tokenCount.output;
6748
- logger$4.debug("provider.count_tokens.success", {
6749
- provider,
6750
- model: anthropicPayload.model,
6751
- input_tokens: finalTokenCount
6752
- });
6753
- return c.json({ input_tokens: finalTokenCount });
6754
- } catch (error) {
6755
- logger$4.error("provider.count_tokens.error", {
6756
- provider,
6757
- error
6758
- });
6759
- return c.json({ input_tokens: 1 });
6760
- }
6761
- }
6762
-
6763
- //#endregion
6764
- //#region src/services/providers/anthropic-proxy.ts
6765
- const FORWARDABLE_HEADERS = [
6766
- "anthropic-version",
6767
- "anthropic-beta",
6768
- "accept",
6769
- "user-agent"
6770
- ];
6771
- const STRIPPED_RESPONSE_HEADERS = [
6772
- "connection",
6773
- "content-encoding",
6774
- "content-length",
6775
- "keep-alive",
6776
- "proxy-authenticate",
6777
- "proxy-authorization",
6778
- "te",
6779
- "trailer",
6780
- "transfer-encoding",
6781
- "upgrade"
6782
- ];
6783
- function buildProviderUpstreamHeaders(providerConfig, requestHeaders) {
6784
- const authHeaders = {};
6785
- if (providerConfig.authType === "authorization") authHeaders.authorization = `Bearer ${providerConfig.apiKey}`;
6786
- else authHeaders["x-api-key"] = providerConfig.apiKey;
6787
- const headers = {
6788
- "content-type": "application/json",
6789
- accept: "application/json",
6790
- ...authHeaders
6791
- };
6792
- for (const headerName of FORWARDABLE_HEADERS) {
6793
- const headerValue = requestHeaders.get(headerName);
6794
- if (headerValue) headers[headerName] = headerValue;
6795
- }
6796
- return headers;
6797
- }
6798
- function createProviderProxyResponse(upstreamResponse) {
6799
- const headers = new Headers(upstreamResponse.headers);
6800
- for (const headerName of STRIPPED_RESPONSE_HEADERS) headers.delete(headerName);
6801
- return new Response(upstreamResponse.body, {
6802
- headers,
6803
- status: upstreamResponse.status,
6804
- statusText: upstreamResponse.statusText
6805
- });
6806
- }
6807
- async function forwardProviderMessages(providerConfig, payload, requestHeaders) {
6808
- return await fetch(`${providerConfig.baseUrl}/v1/messages`, {
6809
- method: "POST",
6810
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders),
6811
- body: JSON.stringify(payload)
6812
- });
6813
- }
6814
- async function forwardProviderModels(providerConfig, requestHeaders) {
6815
- return await fetch(`${providerConfig.baseUrl}/v1/models`, {
6816
- method: "GET",
6817
- headers: buildProviderUpstreamHeaders(providerConfig, requestHeaders)
6818
- });
6819
- }
6820
-
6821
- //#endregion
6822
- //#region src/routes/provider/messages/handler.ts
6823
- const logger$3 = createHandlerLogger("provider-messages-handler");
6824
- async function handleProviderMessages(c) {
6825
- const provider = c.req.param("provider") ?? "";
6826
- const providerConfig = getProviderConfig(provider);
6827
- if (!providerConfig) return c.json({ error: {
6828
- message: `Provider '${provider}' not found or disabled`,
6829
- type: "invalid_request_error"
6830
- } }, 404);
6831
- try {
6832
- const payload = await c.req.json();
6833
- const modelConfig = providerConfig.models?.[payload.model];
6834
- payload.temperature ??= modelConfig?.temperature;
6835
- payload.top_p ??= modelConfig?.topP;
6836
- payload.top_k ??= modelConfig?.topK;
6837
- debugJson(logger$3, "provider.messages.request", {
6838
- payload,
6839
- provider
6840
- });
6841
- const upstreamResponse = await forwardProviderMessages(providerConfig, payload, c.req.raw.headers);
6842
- if (!upstreamResponse.ok) {
6843
- logger$3.error("Failed to create responses", upstreamResponse);
6844
- throw new HTTPError("Failed to create responses", upstreamResponse);
6845
- }
6846
- const contentType = upstreamResponse.headers.get("content-type") ?? "";
6847
- if (Boolean(payload.stream) && contentType.includes("text/event-stream")) {
6848
- logger$3.debug("provider.messages.streaming");
6849
- return streamSSE(c, async (stream) => {
6850
- for await (const chunk of events(upstreamResponse)) {
6851
- logger$3.debug("provider.messages.raw_stream_event:", chunk.data);
6852
- const eventName = chunk.event;
6853
- if (eventName === "ping") {
6854
- await stream.writeSSE({
6855
- event: "ping",
6856
- data: "{\"type\":\"ping\"}"
6857
- });
6858
- continue;
6859
- }
6860
- let data = chunk.data;
6861
- if (!data) continue;
6862
- if (chunk.data === "[DONE]") break;
6863
- try {
6864
- const parsed = JSON.parse(data);
6865
- if (parsed.type === "message_start") adjustInputTokens(providerConfig, parsed.message.usage);
6866
- else if (parsed.type === "message_delta") adjustInputTokens(providerConfig, parsed.usage);
6867
- data = JSON.stringify(parsed);
6868
- } catch (error) {
6869
- logger$3.error("provider.messages.streaming.adjust_tokens_error", {
6870
- error,
6871
- originalData: data
6872
- });
6873
- }
6874
- await stream.writeSSE({
6875
- event: eventName,
6876
- data
6877
- });
6878
- }
6879
- });
6880
- }
6881
- const jsonBody = await upstreamResponse.json();
6882
- adjustInputTokens(providerConfig, jsonBody.usage);
6883
- debugJson(logger$3, "provider.messages.no_stream result:", jsonBody);
6884
- return c.json(jsonBody);
6885
- } catch (error) {
6886
- logger$3.error("provider.messages.error", {
6887
- provider,
6888
- error
6889
- });
6890
- throw error;
6891
- }
6892
- }
6893
- const adjustInputTokens = (providerConfig, usage) => {
6894
- if (!providerConfig.adjustInputTokens || !usage) return;
6895
- usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
6896
- debugJson(logger$3, "provider.messages.adjusted_usage:", usage);
6897
- };
6898
-
6899
7687
  //#endregion
6900
7688
  //#region src/routes/provider/messages/route.ts
6901
7689
  const providerMessageRoutes = new Hono();
@@ -6913,20 +7701,23 @@ providerMessageRoutes.post("/count_tokens", async (c) => {
6913
7701
  return await forwardError(c, error);
6914
7702
  }
6915
7703
  });
6916
-
6917
7704
  //#endregion
6918
7705
  //#region src/routes/provider/models/route.ts
6919
7706
  const logger$2 = createHandlerLogger("provider-models-handler");
7707
+ const getProviderFetch = (c) => c.get("providerFetch") ?? fetch;
7708
+ const resolveProviderConfig = (c, provider) => {
7709
+ return (c.get("providerConfigResolver") ?? getProviderConfig)(provider);
7710
+ };
6920
7711
  const providerModelRoutes = new Hono();
6921
7712
  providerModelRoutes.get("/", async (c) => {
6922
7713
  const provider = c.req.param("provider") ?? "";
6923
7714
  try {
6924
- const providerConfig = getProviderConfig(provider);
7715
+ const providerConfig = resolveProviderConfig(c, provider);
6925
7716
  if (!providerConfig) return c.json({ error: {
6926
7717
  message: `Provider '${provider}' not found or disabled`,
6927
7718
  type: "invalid_request_error"
6928
7719
  } }, 404);
6929
- const upstreamResponse = await forwardProviderModels(providerConfig, c.req.raw.headers);
7720
+ const upstreamResponse = await forwardProviderModels(providerConfig, c.req.raw.headers, getProviderFetch(c));
6930
7721
  logger$2.debug("provider.models.response", {
6931
7722
  provider,
6932
7723
  statusCode: upstreamResponse.status
@@ -6940,7 +7731,6 @@ providerModelRoutes.get("/", async (c) => {
6940
7731
  return await forwardError(c, error);
6941
7732
  }
6942
7733
  });
6943
-
6944
7734
  //#endregion
6945
7735
  //#region src/routes/responses/stream-id-sync.ts
6946
7736
  const createStreamIdTracker = () => ({ outputItems: /* @__PURE__ */ new Map() });
@@ -6977,7 +7767,6 @@ const handleItemId = (parsed, tracker) => {
6977
7767
  }
6978
7768
  return JSON.stringify(parsed);
6979
7769
  };
6980
-
6981
7770
  //#endregion
6982
7771
  //#region src/routes/responses/handler.ts
6983
7772
  const logger$1 = createHandlerLogger("responses-handler");
@@ -7121,13 +7910,13 @@ function buildRequestContext(c) {
7121
7910
  const requestId = randomUUID();
7122
7911
  const startedAtMs = Date.now();
7123
7912
  const method = c.req.raw.method;
7124
- const path$2 = new URL(c.req.url, "http://local").pathname;
7913
+ const path = new URL(c.req.url, "http://local").pathname;
7125
7914
  const { ip: clientIp, source: clientIpSource } = getClientIpInfo(c);
7126
7915
  return {
7127
7916
  requestId,
7128
7917
  startedAtMs,
7129
7918
  method,
7130
- path: path$2,
7919
+ path,
7131
7920
  clientIp,
7132
7921
  clientIpSource,
7133
7922
  userAgent: c.req.header("user-agent") ?? void 0
@@ -7212,7 +8001,7 @@ async function handleStreamingResponses(params) {
7212
8001
  error
7213
8002
  });
7214
8003
  }
7215
- if (isAsyncIterable(response)) {
8004
+ if (isAsyncIterable$1(response)) {
7216
8005
  logger$1.debug("Forwarding native Responses stream");
7217
8006
  return streamSSE(c, (stream) => streamResponsesAndLog({
7218
8007
  stream,
@@ -7399,7 +8188,7 @@ async function handleNonStreamingResponses(params) {
7399
8188
  sessionId: request.upstreamSessionId,
7400
8189
  requestId: request.requestId
7401
8190
  }, accountCtx);
7402
- if (isAsyncIterable(response)) throw new Error("Upstream returned a stream unexpectedly");
8191
+ if (isAsyncIterable$1(response)) throw new Error("Upstream returned a stream unexpectedly");
7403
8192
  selection.confirmAffinity?.();
7404
8193
  finishedAtMs = Date.now();
7405
8194
  const result = response;
@@ -7459,7 +8248,6 @@ const removeUnsupportedTools = (payload) => {
7459
8248
  });
7460
8249
  if (dropped.length > 0) logger$1.debug("Removed unsupported tools:", dropped);
7461
8250
  };
7462
-
7463
8251
  //#endregion
7464
8252
  //#region src/routes/responses/route.ts
7465
8253
  const responsesRoutes = new Hono();
@@ -7470,7 +8258,6 @@ responsesRoutes.post("/", async (c) => {
7470
8258
  return await forwardError(c, error);
7471
8259
  }
7472
8260
  });
7473
-
7474
8261
  //#endregion
7475
8262
  //#region src/routes/token/route.ts
7476
8263
  const tokenRoute = new Hono();
@@ -7485,7 +8272,6 @@ tokenRoute.get("/", (c) => {
7485
8272
  }, 500);
7486
8273
  }
7487
8274
  });
7488
-
7489
8275
  //#endregion
7490
8276
  //#region src/routes/usage/route.ts
7491
8277
  const usageRoute = new Hono();
@@ -7522,7 +8308,6 @@ usageRoute.get("/:accountIndex", async (c) => {
7522
8308
  return c.json({ error: "Failed to fetch account usage" }, 500);
7523
8309
  }
7524
8310
  });
7525
-
7526
8311
  //#endregion
7527
8312
  //#region src/server.ts
7528
8313
  const server = new Hono();
@@ -7549,7 +8334,7 @@ server.route("/v1/responses", responsesRoutes);
7549
8334
  server.route("/v1/messages", messageRoutes);
7550
8335
  server.route("/:provider/v1/messages", providerMessageRoutes);
7551
8336
  server.route("/:provider/v1/models", providerModelRoutes);
7552
-
7553
8337
  //#endregion
7554
8338
  export { server };
7555
- //# sourceMappingURL=server-DR9ZR_MN.js.map
8339
+
8340
+ //# sourceMappingURL=server-BDCnb3Ao.js.map