@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.
- package/README.md +34 -24
- package/dist/account-DhQb2A6q.js +17 -0
- package/dist/account-DhQb2A6q.js.map +1 -0
- package/dist/{accounts-manager-H7YGTVk8.js → accounts-manager-BGBtDChT.js} +25 -573
- package/dist/accounts-manager-BGBtDChT.js.map +1 -0
- package/dist/accounts-registry-c7rs5Ed9.js +180 -0
- package/dist/accounts-registry-c7rs5Ed9.js.map +1 -0
- package/dist/admin/assets/index-BB9SaCFS.js +57 -0
- package/dist/admin/assets/{index-D-pIr-q0.css → index-CvffOmW7.css} +1 -1
- package/dist/admin/index.html +2 -2
- package/dist/auth-BvIHvhP9.js +241 -0
- package/dist/auth-BvIHvhP9.js.map +1 -0
- package/dist/check-usage-CiTcYDij.js +82 -0
- package/dist/check-usage-CiTcYDij.js.map +1 -0
- package/dist/debug-hQJWwXtC.js +82 -0
- package/dist/debug-hQJWwXtC.js.map +1 -0
- package/dist/get-copilot-token-CUT8hpgX.js +13 -0
- package/dist/get-copilot-token-CUT8hpgX.js.map +1 -0
- package/dist/main.js +25 -735
- package/dist/main.js.map +1 -1
- package/dist/paths-DoT4SZ8f.js +49 -0
- package/dist/paths-DoT4SZ8f.js.map +1 -0
- package/dist/poll-access-token-Dnd_xK36.js +52 -0
- package/dist/poll-access-token-Dnd_xK36.js.map +1 -0
- package/dist/{server-BZhJgGbw.js → server-COWbIpDR.js} +277 -23
- package/dist/server-COWbIpDR.js.map +1 -0
- package/dist/start-BbULwJ9B.js +306 -0
- package/dist/start-BbULwJ9B.js.map +1 -0
- package/dist/utils-BaoXuYkx.js +338 -0
- package/dist/utils-BaoXuYkx.js.map +1 -0
- package/package.json +1 -1
- package/dist/accounts-manager-H7YGTVk8.js.map +0 -1
- package/dist/admin/assets/index-C9gbhsHu.js +0 -56
- package/dist/server-BZhJgGbw.js.map +0 -1
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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
|
-
|
|
5553
|
+
if (!state.models) await cacheModels();
|
|
5332
5554
|
const blockedTargets = getAliasTargetSet();
|
|
5333
|
-
const models =
|
|
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
|
|
5497
|
-
|
|
5498
|
-
const
|
|
5499
|
-
|
|
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
|
-
|
|
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-
|
|
6401
|
+
//# sourceMappingURL=server-COWbIpDR.js.map
|