@nick3/copilot-api 1.3.3 → 1.3.8

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 (34) hide show
  1. package/README.md +34 -24
  2. package/dist/account-DhQb2A6q.js +17 -0
  3. package/dist/account-DhQb2A6q.js.map +1 -0
  4. package/dist/{accounts-manager-H7YGTVk8.js → accounts-manager-BGBtDChT.js} +25 -573
  5. package/dist/accounts-manager-BGBtDChT.js.map +1 -0
  6. package/dist/accounts-registry-c7rs5Ed9.js +180 -0
  7. package/dist/accounts-registry-c7rs5Ed9.js.map +1 -0
  8. package/dist/admin/assets/index-BB9SaCFS.js +57 -0
  9. package/dist/admin/assets/{index-D-pIr-q0.css → index-CvffOmW7.css} +1 -1
  10. package/dist/admin/index.html +2 -2
  11. package/dist/auth-BvIHvhP9.js +241 -0
  12. package/dist/auth-BvIHvhP9.js.map +1 -0
  13. package/dist/check-usage-CiTcYDij.js +82 -0
  14. package/dist/check-usage-CiTcYDij.js.map +1 -0
  15. package/dist/debug-hQJWwXtC.js +82 -0
  16. package/dist/debug-hQJWwXtC.js.map +1 -0
  17. package/dist/get-copilot-token-CUT8hpgX.js +13 -0
  18. package/dist/get-copilot-token-CUT8hpgX.js.map +1 -0
  19. package/dist/main.js +25 -735
  20. package/dist/main.js.map +1 -1
  21. package/dist/paths-DoT4SZ8f.js +49 -0
  22. package/dist/paths-DoT4SZ8f.js.map +1 -0
  23. package/dist/poll-access-token-Dnd_xK36.js +52 -0
  24. package/dist/poll-access-token-Dnd_xK36.js.map +1 -0
  25. package/dist/{server-BZhJgGbw.js → server-COWbIpDR.js} +277 -23
  26. package/dist/server-COWbIpDR.js.map +1 -0
  27. package/dist/start-BbULwJ9B.js +306 -0
  28. package/dist/start-BbULwJ9B.js.map +1 -0
  29. package/dist/utils-BaoXuYkx.js +338 -0
  30. package/dist/utils-BaoXuYkx.js.map +1 -0
  31. package/package.json +1 -1
  32. package/dist/accounts-manager-H7YGTVk8.js.map +0 -1
  33. package/dist/admin/assets/index-C9gbhsHu.js +0 -56
  34. package/dist/server-BZhJgGbw.js.map +0 -1
@@ -1,13 +1,18 @@
1
- import { HTTPError, PATHS, accountFromState, accountsManager, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getAliasTargetSet, getConfig, getCopilotUsage, getExtraPromptForModel, getModelAliases, getModelAliasesInfo, getModelRefreshIntervalMs, getProviderConfig, getReasoningEffortForModel, getRootSessionId, getSmallModel, getUUID, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isMessageStartInputTokensFallbackEnabled, isMessagesApiEnabled, isNullish, isResponsesApiContextManagementModel, listAccountsFromRegistry, mergeConfigWithDefaults, prepareInteractionHeaders, shouldCompactUseSmallModel, sleep, state } from "./accounts-manager-H7YGTVk8.js";
1
+ import { PATHS } from "./paths-DoT4SZ8f.js";
2
+ import { listAccountsFromRegistry } from "./accounts-registry-c7rs5Ed9.js";
3
+ import { HTTPError, accountFromState, cacheModels, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getCopilotUsage, getRootSessionId, getUUID, isNullish, prepareForCompact, prepareInteractionHeaders, sleep, state } from "./utils-BaoXuYkx.js";
4
+ import "./get-copilot-token-CUT8hpgX.js";
5
+ import { PROVIDER_TYPE_ANTHROPIC, accountsManager, getAliasTargetSet, getConfig, getExtraPromptForModel, getModelAliases, getModelAliasesInfo, getModelRefreshIntervalMs, getProviderConfig, getReasoningEffortForModel, getSmallModel, isForceAgentEnabled, isFreeModelLoadBalancingEnabled, isMessageStartInputTokensFallbackEnabled, isMessagesApiEnabled, isResponsesApiContextManagementModel, mergeConfigWithDefaults, shouldCompactUseSmallModel } from "./accounts-manager-BGBtDChT.js";
2
6
  import consola from "consola";
3
7
  import fs, { readFile } from "node:fs/promises";
4
8
  import * as path$1 from "node:path";
5
9
  import path from "node:path";
6
10
  import { randomUUID, timingSafeEqual } from "node:crypto";
7
- import fs$1, { existsSync } from "node:fs";
8
11
  import { Hono } from "hono";
9
12
  import { cors } from "hono/cors";
10
13
  import { logger } from "hono/logger";
14
+ import fs$1, { existsSync } from "node:fs";
15
+ import { AsyncLocalStorage } from "node:async_hooks";
11
16
  import { Database } from "bun:sqlite";
12
17
  import { fileURLToPath } from "node:url";
13
18
  import { streamSSE } from "hono/streaming";
@@ -100,6 +105,40 @@ function createAuthMiddleware(options = {}) {
100
105
  };
101
106
  }
102
107
 
108
+ //#endregion
109
+ //#region src/lib/request-context.ts
110
+ const TRACE_ID_MAX_LENGTH = 64;
111
+ const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
112
+ const asyncLocalStorage = new AsyncLocalStorage();
113
+ const requestContext = {
114
+ getStore: () => asyncLocalStorage.getStore(),
115
+ run: (context, callback) => asyncLocalStorage.run(context, callback)
116
+ };
117
+ function generateTraceId() {
118
+ const timestamp = Date.now().toString(36);
119
+ const random = Math.random().toString(36).slice(2, 8);
120
+ return `${timestamp}-${random}`;
121
+ }
122
+ function resolveTraceId(traceId) {
123
+ const candidate = traceId?.trim();
124
+ if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
125
+ return candidate;
126
+ }
127
+
128
+ //#endregion
129
+ //#region src/lib/trace.ts
130
+ const traceIdMiddleware = async (c, next) => {
131
+ const traceId = resolveTraceId(c.req.header("x-trace-id"));
132
+ c.header("x-trace-id", traceId);
133
+ const context = {
134
+ traceId,
135
+ startTime: Date.now()
136
+ };
137
+ await requestContext.run(context, async () => {
138
+ await next();
139
+ });
140
+ };
141
+
103
142
  //#endregion
104
143
  //#region src/lib/admin-db.ts
105
144
  const DEFAULT_DB_PATH = path.join(PATHS.APP_DIR, "admin.sqlite");
@@ -726,6 +765,8 @@ const CONFIG_KEYS = new Set([
726
765
  "smallModel",
727
766
  "freeModelLoadBalancing",
728
767
  "apiKey",
768
+ "providers",
769
+ "responsesApiContextManagementModels",
729
770
  "modelReasoningEfforts",
730
771
  "modelAliases",
731
772
  "allowOriginalModelNamesForAliases",
@@ -733,7 +774,8 @@ const CONFIG_KEYS = new Set([
733
774
  "forceAgent",
734
775
  "compactUseSmallModel",
735
776
  "messageStartInputTokensFallback",
736
- "modelRefreshIntervalHours"
777
+ "modelRefreshIntervalHours",
778
+ "useMessagesApi"
737
779
  ]);
738
780
  const REASONING_EFFORTS = new Set([
739
781
  "none",
@@ -772,6 +814,18 @@ function parseOptionalNonNegativeNumber(value, field) {
772
814
  if (!Number.isFinite(value) || value < 0) return { error: `${field} must be a non-negative number` };
773
815
  return { value };
774
816
  }
817
+ function parseOptionalStringArray(value, field) {
818
+ if (value === null || value === void 0) return { clear: true };
819
+ if (!Array.isArray(value)) return { error: `${field} must be an array of strings` };
820
+ const out = [];
821
+ for (const [index, entry] of value.entries()) {
822
+ if (typeof entry !== "string") return { error: `${field}[${index}] must be a string` };
823
+ const trimmed = entry.trim();
824
+ if (!trimmed) return { error: `${field}[${index}] must be a non-empty string` };
825
+ out.push(trimmed);
826
+ }
827
+ return { value: [...new Set(out)] };
828
+ }
775
829
  function parseAuthConfig(value) {
776
830
  if (value === null || value === void 0) return { clear: true };
777
831
  if (!isPlainObject(value)) return { error: "auth must be an object" };
@@ -793,6 +847,142 @@ function parseStringRecord(value, field) {
793
847
  }
794
848
  return { value: record };
795
849
  }
850
+ const PROVIDER_MODEL_CONFIG_KEYS = new Set([
851
+ "temperature",
852
+ "topP",
853
+ "topK"
854
+ ]);
855
+ const PROVIDER_CONFIG_KEYS = new Set([
856
+ "type",
857
+ "enabled",
858
+ "baseUrl",
859
+ "apiKey",
860
+ "models"
861
+ ]);
862
+ function validateAllowedObjectKeys(value, field, allowed) {
863
+ for (const key of Object.keys(value)) if (!allowed.has(key)) return `${field}.${key} is not supported`;
864
+ }
865
+ function applyProviderModelTemperature(config, value, field) {
866
+ if (!Object.hasOwn(value, "temperature")) return void 0;
867
+ const parsed = parseOptionalNonNegativeNumber(value.temperature, `${field}.temperature`);
868
+ if ("error" in parsed) return parsed.error;
869
+ if ("value" in parsed) config.temperature = parsed.value;
870
+ }
871
+ function applyProviderModelTopP(config, value, field) {
872
+ if (!Object.hasOwn(value, "topP")) return void 0;
873
+ const parsed = parseOptionalNonNegativeNumber(value.topP, `${field}.topP`);
874
+ if ("error" in parsed) return parsed.error;
875
+ if ("value" in parsed) config.topP = parsed.value;
876
+ }
877
+ function applyProviderModelTopK(config, value, field) {
878
+ if (!Object.hasOwn(value, "topK")) return void 0;
879
+ const parsed = parseOptionalNonNegativeNumber(value.topK, `${field}.topK`);
880
+ if ("error" in parsed) return parsed.error;
881
+ if ("value" in parsed) config.topK = parsed.value;
882
+ }
883
+ function parseProviderModelConfig(value, field) {
884
+ if (value === null || value === void 0) return { error: `${field} must be an object` };
885
+ if (!isPlainObject(value)) return { error: `${field} must be an object` };
886
+ const keyError = validateAllowedObjectKeys(value, field, PROVIDER_MODEL_CONFIG_KEYS);
887
+ if (keyError) return { error: keyError };
888
+ const config = {};
889
+ const temperatureError = applyProviderModelTemperature(config, value, field);
890
+ if (temperatureError) return { error: temperatureError };
891
+ const topPError = applyProviderModelTopP(config, value, field);
892
+ if (topPError) return { error: topPError };
893
+ const topKError = applyProviderModelTopK(config, value, field);
894
+ if (topKError) return { error: topKError };
895
+ return { value: config };
896
+ }
897
+ function parseProviderModelsRecord(value, field) {
898
+ if (value === null || value === void 0) return { clear: true };
899
+ if (!isPlainObject(value)) return { error: `${field} must be an object` };
900
+ const record = Object.create(null);
901
+ for (const [rawModelId, rawModelConfig] of Object.entries(value)) {
902
+ if (BLOCKED_KEYS.has(rawModelId)) return { error: `${field}.${rawModelId} is not allowed` };
903
+ const modelId = rawModelId.trim();
904
+ if (!modelId) return { error: `${field} keys must be non-empty strings` };
905
+ if (rawModelId !== modelId) return { error: `${field}.${rawModelId} must not include leading/trailing whitespace` };
906
+ if (BLOCKED_KEYS.has(modelId)) return { error: `${field}.${modelId} is not allowed` };
907
+ const parsed = parseProviderModelConfig(rawModelConfig, `${field}.${modelId}`);
908
+ if ("error" in parsed) return parsed;
909
+ if ("clear" in parsed) continue;
910
+ record[modelId] = parsed.value;
911
+ }
912
+ return { value: record };
913
+ }
914
+ function applyProviderType(provider, value, field) {
915
+ if (!Object.hasOwn(value, "type")) return void 0;
916
+ const parsed = parseOptionalString(value.type, `${field}.type`);
917
+ if ("error" in parsed) return parsed.error;
918
+ if ("value" in parsed) {
919
+ if (parsed.value !== PROVIDER_TYPE_ANTHROPIC) return `${field}.type must be "${PROVIDER_TYPE_ANTHROPIC}"`;
920
+ provider.type = PROVIDER_TYPE_ANTHROPIC;
921
+ }
922
+ }
923
+ function applyProviderEnabled(provider, value, field) {
924
+ if (!Object.hasOwn(value, "enabled")) return void 0;
925
+ const parsed = parseOptionalBoolean(value.enabled, `${field}.enabled`);
926
+ if ("error" in parsed) return parsed.error;
927
+ if ("value" in parsed) provider.enabled = parsed.value;
928
+ }
929
+ function applyProviderBaseUrl(provider, value, field) {
930
+ if (!Object.hasOwn(value, "baseUrl")) return void 0;
931
+ const parsed = parseOptionalString(value.baseUrl, `${field}.baseUrl`);
932
+ if ("error" in parsed) return parsed.error;
933
+ if ("value" in parsed) provider.baseUrl = parsed.value;
934
+ }
935
+ function applyProviderApiKey(provider, value, field) {
936
+ if (!Object.hasOwn(value, "apiKey")) return void 0;
937
+ const parsed = parseOptionalString(value.apiKey, `${field}.apiKey`);
938
+ if ("error" in parsed) return parsed.error;
939
+ if ("value" in parsed) provider.apiKey = parsed.value;
940
+ }
941
+ function applyProviderModels(provider, value, field) {
942
+ if (!Object.hasOwn(value, "models")) return void 0;
943
+ const parsed = parseProviderModelsRecord(value.models, `${field}.models`);
944
+ if ("error" in parsed) return parsed.error;
945
+ if ("value" in parsed) provider.models = parsed.value;
946
+ }
947
+ function parseProviderConfig(value, field) {
948
+ if (value === null || value === void 0) return { error: `${field} must be an object` };
949
+ if (!isPlainObject(value)) return { error: `${field} must be an object` };
950
+ const keyError = validateAllowedObjectKeys(value, field, PROVIDER_CONFIG_KEYS);
951
+ if (keyError) return { error: keyError };
952
+ const provider = {};
953
+ const typeError = applyProviderType(provider, value, field);
954
+ if (typeError) return { error: typeError };
955
+ const enabledError = applyProviderEnabled(provider, value, field);
956
+ if (enabledError) return { error: enabledError };
957
+ const baseUrlError = applyProviderBaseUrl(provider, value, field);
958
+ if (baseUrlError) return { error: baseUrlError };
959
+ const apiKeyError = applyProviderApiKey(provider, value, field);
960
+ if (apiKeyError) return { error: apiKeyError };
961
+ const modelsError = applyProviderModels(provider, value, field);
962
+ if (modelsError) return { error: modelsError };
963
+ return { value: provider };
964
+ }
965
+ function parseProviders(value) {
966
+ if (value === null || value === void 0) return { clear: true };
967
+ if (!isPlainObject(value)) return { error: "providers must be an object" };
968
+ const record = Object.create(null);
969
+ const seenProviderNames = /* @__PURE__ */ new Set();
970
+ for (const [rawProviderName, rawProviderConfig] of Object.entries(value)) {
971
+ if (BLOCKED_KEYS.has(rawProviderName)) return { error: `providers.${rawProviderName} is not allowed` };
972
+ const providerName = rawProviderName.trim();
973
+ if (!providerName) return { error: "providers keys must be non-empty strings" };
974
+ if (rawProviderName !== providerName) return { error: `providers.${rawProviderName} must not include leading/trailing whitespace` };
975
+ if (BLOCKED_KEYS.has(providerName)) return { error: `providers.${providerName} is not allowed` };
976
+ const normalizedProviderName = providerName.toLowerCase();
977
+ if (seenProviderNames.has(normalizedProviderName)) return { error: `providers.${rawProviderName} conflicts with another provider` };
978
+ seenProviderNames.add(normalizedProviderName);
979
+ const parsed = parseProviderConfig(rawProviderConfig, `providers.${providerName}`);
980
+ if ("error" in parsed) return parsed;
981
+ if ("clear" in parsed) continue;
982
+ record[providerName] = parsed.value;
983
+ }
984
+ return { value: record };
985
+ }
796
986
  function parseReasoningRecord(value) {
797
987
  if (value === null || value === void 0) return { clear: true };
798
988
  if (!isPlainObject(value)) return { error: "modelReasoningEfforts must be an object" };
@@ -911,12 +1101,32 @@ function applyModelAliases(next, value) {
911
1101
  }
912
1102
  next.modelAliases = parsed.value;
913
1103
  }
1104
+ function applyResponsesApiContextManagementModels(next, value) {
1105
+ const parsed = parseOptionalStringArray(value, "responsesApiContextManagementModels");
1106
+ if ("error" in parsed) return parsed.error;
1107
+ if ("clear" in parsed) {
1108
+ delete next.responsesApiContextManagementModels;
1109
+ return;
1110
+ }
1111
+ next.responsesApiContextManagementModels = parsed.value;
1112
+ }
1113
+ function applyProvidersConfig(next, value) {
1114
+ const parsed = parseProviders(value);
1115
+ if ("error" in parsed) return parsed.error;
1116
+ if ("clear" in parsed) {
1117
+ delete next.providers;
1118
+ return;
1119
+ }
1120
+ next.providers = parsed.value;
1121
+ }
914
1122
  const CONFIG_PATCH_HANDLERS = {
915
1123
  auth: applyAuthConfig,
916
1124
  extraPrompts: applyExtraPrompts,
917
1125
  smallModel: (next, value) => applyOptionalString(next, "smallModel", value),
918
1126
  freeModelLoadBalancing: (next, value) => applyOptionalBoolean(next, "freeModelLoadBalancing", value),
919
1127
  apiKey: (next, value) => applyOptionalString(next, "apiKey", value),
1128
+ providers: applyProvidersConfig,
1129
+ responsesApiContextManagementModels: applyResponsesApiContextManagementModels,
920
1130
  modelReasoningEfforts: applyReasoningEfforts,
921
1131
  modelAliases: applyModelAliases,
922
1132
  allowOriginalModelNamesForAliases: (next, value) => applyOptionalBoolean(next, "allowOriginalModelNamesForAliases", value),
@@ -924,7 +1134,8 @@ const CONFIG_PATCH_HANDLERS = {
924
1134
  forceAgent: (next, value) => applyOptionalBoolean(next, "forceAgent", value),
925
1135
  compactUseSmallModel: (next, value) => applyOptionalBoolean(next, "compactUseSmallModel", value),
926
1136
  messageStartInputTokensFallback: (next, value) => applyOptionalBoolean(next, "messageStartInputTokensFallback", value),
927
- modelRefreshIntervalHours: (next, value) => applyOptionalNumber(next, "modelRefreshIntervalHours", value)
1137
+ modelRefreshIntervalHours: (next, value) => applyOptionalNumber(next, "modelRefreshIntervalHours", value),
1138
+ useMessagesApi: (next, value) => applyOptionalBoolean(next, "useMessagesApi", value)
928
1139
  };
929
1140
  function applyConfigPatch(base, input) {
930
1141
  const next = { ...base };
@@ -1972,12 +2183,14 @@ const createHandlerLogger = (name) => {
1972
2183
  cleanupOldLogs();
1973
2184
  lastCleanup = Date.now();
1974
2185
  }
2186
+ const traceId = requestContext.getStore()?.traceId;
1975
2187
  const date = logObj.date;
1976
2188
  const dateKey = date.toLocaleDateString("sv-SE");
1977
2189
  const timestamp = date.toLocaleString("sv-SE", { hour12: false });
1978
2190
  const filePath = path.join(LOG_DIR, `${sanitizedName}-${dateKey}.log`);
1979
2191
  const message = formatArgs(logObj.args);
1980
- const line = `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${message ? ` ${message}` : ""}`;
2192
+ const traceIdStr = traceId ? ` [${traceId}]` : "";
2193
+ const line = `[${timestamp}] [${logObj.type}] [${logObj.tag || name}]${traceIdStr}${message ? ` ${message}` : ""}`;
1981
2194
  appendLine(filePath, line);
1982
2195
  } });
1983
2196
  return instance;
@@ -2227,7 +2440,7 @@ const getTokenCount = async (payload, model) => {
2227
2440
 
2228
2441
  //#endregion
2229
2442
  //#region src/services/copilot/create-responses.ts
2230
- const createResponses = async (payload, { vision, initiator, upstreamRequestId, subagentMarker, sessionId }, account) => {
2443
+ const createResponses = async (payload, { vision, initiator, upstreamRequestId, subagentMarker, sessionId, isCompact }, account) => {
2231
2444
  const ctx = account ?? accountFromState();
2232
2445
  if (!ctx.copilotToken) throw new Error("Copilot token not found");
2233
2446
  const headers = {
@@ -2235,6 +2448,7 @@ const createResponses = async (payload, { vision, initiator, upstreamRequestId,
2235
2448
  "x-initiator": initiator
2236
2449
  };
2237
2450
  prepareInteractionHeaders(sessionId, Boolean(subagentMarker), headers);
2451
+ prepareForCompact(headers, isCompact);
2238
2452
  payload.service_tier = null;
2239
2453
  const response = await fetch(`${copilotBaseUrl(ctx)}/responses`, {
2240
2454
  method: "POST",
@@ -2716,6 +2930,7 @@ const createChatCompletions = async (payload, account, options) => {
2716
2930
  };
2717
2931
  prepareInteractionHeaders(options?.sessionId, Boolean(options?.subagentMarker), headers);
2718
2932
  const upstreamPayload = applyDefaultReasoningEffort(payload);
2933
+ prepareForCompact(headers, options?.isCompact);
2719
2934
  const response = await fetch(`${copilotBaseUrl(ctx)}/chat/completions`, {
2720
2935
  method: "POST",
2721
2936
  headers,
@@ -4265,6 +4480,7 @@ const createMessages = async (payload, account, options) => {
4265
4480
  "x-initiator": options?.subagentMarker ? "agent" : initiator
4266
4481
  };
4267
4482
  prepareInteractionHeaders(options?.sessionId, Boolean(options?.subagentMarker), headers);
4483
+ prepareForCompact(headers, options?.isCompact);
4268
4484
  const anthropicBeta = buildAnthropicBetaHeader(options?.anthropicBetaHeader, payload.thinking);
4269
4485
  if (anthropicBeta) headers["anthropic-beta"] = anthropicBeta;
4270
4486
  const response = await fetch(`${copilotBaseUrl(ctx)}/v1/messages`, {
@@ -4711,7 +4927,8 @@ async function handleCompletion(c) {
4711
4927
  subagentMarker,
4712
4928
  sessionId,
4713
4929
  instr,
4714
- selectedModel
4930
+ selectedModel,
4931
+ isCompact
4715
4932
  });
4716
4933
  if (endpoint === RESPONSES_ENDPOINT$1) return await handleWithResponsesApi({
4717
4934
  c,
@@ -4721,7 +4938,8 @@ async function handleCompletion(c) {
4721
4938
  subagentMarker,
4722
4939
  sessionId,
4723
4940
  selectedModel,
4724
- instr
4941
+ instr,
4942
+ isCompact
4725
4943
  });
4726
4944
  return await handleWithChatCompletions({
4727
4945
  c,
@@ -4730,11 +4948,12 @@ async function handleCompletion(c) {
4730
4948
  subagentMarker,
4731
4949
  sessionId,
4732
4950
  selectedModel,
4733
- instr
4951
+ instr,
4952
+ isCompact
4734
4953
  });
4735
4954
  }
4736
4955
  const handleWithChatCompletions = async (params) => {
4737
- const { c, openAIPayload, initiatorOverride, subagentMarker, sessionId, selectedModel, instr } = params;
4956
+ const { c, openAIPayload, initiatorOverride, subagentMarker, sessionId, selectedModel, instr, isCompact } = params;
4738
4957
  logger$5.debug("Translated OpenAI request payload:", JSON.stringify(openAIPayload));
4739
4958
  const ctx = toAccountContext(instr.account);
4740
4959
  const initiator = initiatorOverride ?? getChatInitiator(openAIPayload.messages);
@@ -4745,7 +4964,8 @@ const handleWithChatCompletions = async (params) => {
4745
4964
  upstreamRequestId: instr.upstreamRequestId,
4746
4965
  initiator,
4747
4966
  subagentMarker,
4748
- sessionId
4967
+ sessionId,
4968
+ isCompact
4749
4969
  });
4750
4970
  } catch (error) {
4751
4971
  return await handleChatCompletionsCreateError({
@@ -4776,7 +4996,7 @@ const handleWithChatCompletions = async (params) => {
4776
4996
  }));
4777
4997
  };
4778
4998
  const handleWithResponsesApi = async (params) => {
4779
- const { c, anthropicPayload, openAIPayload, initiatorOverride, subagentMarker, sessionId, selectedModel, instr } = params;
4999
+ const { c, anthropicPayload, openAIPayload, initiatorOverride, subagentMarker, sessionId, selectedModel, instr, isCompact } = params;
4780
5000
  const responsesPayload = translateAnthropicMessagesToResponsesPayload(anthropicPayload, selectedModel.id);
4781
5001
  applyResponsesApiContextManagement(responsesPayload, selectedModel.capabilities.limits.max_prompt_tokens);
4782
5002
  compactInputByLatestCompaction(responsesPayload);
@@ -4792,7 +5012,8 @@ const handleWithResponsesApi = async (params) => {
4792
5012
  initiator: resolvedInitiator,
4793
5013
  upstreamRequestId: instr.upstreamRequestId,
4794
5014
  subagentMarker,
4795
- sessionId
5015
+ sessionId,
5016
+ isCompact
4796
5017
  }, ctx);
4797
5018
  } catch (error) {
4798
5019
  return await handleResponsesCreateError({
@@ -5243,7 +5464,7 @@ async function streamMessagesAndLog(params) {
5243
5464
  }
5244
5465
  }
5245
5466
  const handleWithMessagesApi = async (params) => {
5246
- const { c, anthropicPayload, anthropicBetaHeader, initiatorOverride, subagentMarker, sessionId, instr, selectedModel } = params;
5467
+ const { c, anthropicPayload, anthropicBetaHeader, initiatorOverride, subagentMarker, sessionId, instr, selectedModel, isCompact } = params;
5247
5468
  for (const msg of anthropicPayload.messages) if (msg.role === "assistant" && Array.isArray(msg.content)) msg.content = msg.content.filter((block) => {
5248
5469
  if (block.type !== "thinking") return true;
5249
5470
  return block.thinking && block.thinking !== "Thinking..." && block.signature && !block.signature.includes("@");
@@ -5267,7 +5488,8 @@ const handleWithMessagesApi = async (params) => {
5267
5488
  upstreamRequestId: instr.upstreamRequestId,
5268
5489
  initiator,
5269
5490
  subagentMarker,
5270
- sessionId
5491
+ sessionId,
5492
+ isCompact
5271
5493
  });
5272
5494
  } catch (error) {
5273
5495
  return await handleMessagesCreateError({
@@ -5328,9 +5550,9 @@ messageRoutes.post("/count_tokens", async (c) => {
5328
5550
  const modelRoutes = new Hono();
5329
5551
  modelRoutes.get("/", async (c) => {
5330
5552
  try {
5331
- const accountModels = accountsManager.getFirstAccountModels();
5553
+ if (!state.models) await cacheModels();
5332
5554
  const blockedTargets = getAliasTargetSet();
5333
- const models = accountModels?.data.filter((model) => !blockedTargets.has(model.id.toLowerCase())).map((model) => ({
5555
+ const models = state.models?.data.filter((model) => !blockedTargets.has(model.id.toLowerCase())).map((model) => ({
5334
5556
  id: model.id,
5335
5557
  object: "model",
5336
5558
  type: "model",
@@ -5489,14 +5711,37 @@ async function handleProviderMessages(c) {
5489
5711
  provider
5490
5712
  }));
5491
5713
  const upstreamResponse = await forwardProviderMessages(providerConfig, payload, c.req.raw.headers);
5714
+ if (!upstreamResponse.ok) {
5715
+ logger$3.error("Failed to create responses", upstreamResponse);
5716
+ throw new HTTPError("Failed to create responses", upstreamResponse);
5717
+ }
5492
5718
  const contentType = upstreamResponse.headers.get("content-type") ?? "";
5493
5719
  if (Boolean(payload.stream) && contentType.includes("text/event-stream")) {
5494
5720
  logger$3.debug("provider.messages.streaming");
5495
5721
  return streamSSE(c, async (stream) => {
5496
- for await (const event of events(upstreamResponse)) {
5497
- const eventName = event.event;
5498
- const data = event.data ?? "";
5499
- logger$3.debug("provider.messages.raw_stream_event", data);
5722
+ for await (const chunk of events(upstreamResponse)) {
5723
+ logger$3.debug("provider.messages.raw_stream_event:", chunk.data);
5724
+ const eventName = chunk.event;
5725
+ if (eventName === "ping") {
5726
+ await stream.writeSSE({
5727
+ event: "ping",
5728
+ data: "{\"type\":\"ping\"}"
5729
+ });
5730
+ continue;
5731
+ }
5732
+ let data = chunk.data;
5733
+ if (!data) continue;
5734
+ try {
5735
+ const parsed = JSON.parse(data);
5736
+ if (parsed.type === "message_start") adjustInputTokens(providerConfig, parsed.message.usage);
5737
+ else if (parsed.type === "message_delta") adjustInputTokens(providerConfig, parsed.usage);
5738
+ data = JSON.stringify(parsed);
5739
+ } catch (error) {
5740
+ logger$3.error("provider.messages.streaming.adjust_tokens_error", {
5741
+ error,
5742
+ originalData: data
5743
+ });
5744
+ }
5500
5745
  await stream.writeSSE({
5501
5746
  event: eventName,
5502
5747
  data
@@ -5504,7 +5749,10 @@ async function handleProviderMessages(c) {
5504
5749
  }
5505
5750
  });
5506
5751
  }
5507
- return createProviderProxyResponse(upstreamResponse);
5752
+ const jsonBody = await upstreamResponse.json();
5753
+ adjustInputTokens(providerConfig, jsonBody.usage);
5754
+ logger$3.debug("provider.messages.no_stream result:", JSON.stringify(jsonBody));
5755
+ return c.json(jsonBody);
5508
5756
  } catch (error) {
5509
5757
  logger$3.error("provider.messages.error", {
5510
5758
  provider,
@@ -5513,6 +5761,11 @@ async function handleProviderMessages(c) {
5513
5761
  throw error;
5514
5762
  }
5515
5763
  }
5764
+ const adjustInputTokens = (providerConfig, usage) => {
5765
+ if (!providerConfig.adjustInputTokens || !usage) return;
5766
+ usage.input_tokens = Math.max(0, (usage.input_tokens ?? 0) - (usage.cache_read_input_tokens ?? 0) - (usage.cache_creation_input_tokens ?? 0));
5767
+ logger$3.debug("provider.messages.adjusted_usage:", JSON.stringify(usage));
5768
+ };
5516
5769
 
5517
5770
  //#endregion
5518
5771
  //#region src/routes/provider/messages/route.ts
@@ -6119,6 +6372,7 @@ usageRoute.get("/:accountIndex", async (c) => {
6119
6372
  //#endregion
6120
6373
  //#region src/server.ts
6121
6374
  const server = new Hono();
6375
+ server.use(traceIdMiddleware);
6122
6376
  server.use(logger());
6123
6377
  server.use(cors());
6124
6378
  server.use("*", createAuthMiddleware({
@@ -6144,4 +6398,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
6144
6398
 
6145
6399
  //#endregion
6146
6400
  export { server };
6147
- //# sourceMappingURL=server-BZhJgGbw.js.map
6401
+ //# sourceMappingURL=server-COWbIpDR.js.map