@copilotkit/aimock 1.39.0 → 1.41.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +46 -0
- package/README.md +4 -2
- package/dist/agui-stub.d.cts +2 -2
- package/dist/agui-stub.d.ts +2 -2
- package/dist/agui-types.d.cts +66 -3
- package/dist/agui-types.d.cts.map +1 -1
- package/dist/agui-types.d.ts +66 -3
- package/dist/agui-types.d.ts.map +1 -1
- package/dist/byteplus-video.cjs +954 -0
- package/dist/byteplus-video.cjs.map +1 -0
- package/dist/byteplus-video.d.cts +176 -0
- package/dist/byteplus-video.d.cts.map +1 -0
- package/dist/byteplus-video.d.ts +176 -0
- package/dist/byteplus-video.d.ts.map +1 -0
- package/dist/byteplus-video.js +947 -0
- package/dist/byteplus-video.js.map +1 -0
- package/dist/cli.cjs +5 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/helpers.cjs +8 -4
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +8 -4
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +2 -2
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts +11 -3
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts +11 -3
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +2 -2
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/metrics.cjs +20 -0
- package/dist/metrics.cjs.map +1 -1
- package/dist/metrics.d.cts.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +19 -1
- package/dist/metrics.js.map +1 -1
- package/dist/openrouter-chat.cjs +41 -0
- package/dist/openrouter-chat.cjs.map +1 -1
- package/dist/openrouter-chat.js +41 -0
- package/dist/openrouter-chat.js.map +1 -1
- package/dist/provider-auth.cjs +2 -0
- package/dist/provider-auth.cjs.map +1 -1
- package/dist/provider-auth.js +2 -0
- package/dist/provider-auth.js.map +1 -1
- package/dist/recorder.cjs +77 -8
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +77 -8
- package/dist/recorder.js.map +1 -1
- package/dist/router.cjs +1 -0
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +1 -0
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +137 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -0
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +138 -7
- package/dist/server.js.map +1 -1
- package/dist/stream-collapse.cjs +21 -6
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +16 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +16 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +21 -6
- package/dist/stream-collapse.js.map +1 -1
- package/dist/types.d.cts +41 -6
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +41 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.cts.map +1 -1
- package/package.json +4 -3
package/dist/server.d.cts
CHANGED
|
@@ -7,6 +7,7 @@ import { VideoStateMap } from "./video.cjs";
|
|
|
7
7
|
import { OpenRouterVideoJobMap } from "./openrouter-video.cjs";
|
|
8
8
|
import { VeoVideoJobMap } from "./veo-video.cjs";
|
|
9
9
|
import { GrokVideoJobMap } from "./grok-video.cjs";
|
|
10
|
+
import { BytePlusVideoJobMap } from "./byteplus-video.cjs";
|
|
10
11
|
import * as http$1 from "node:http";
|
|
11
12
|
|
|
12
13
|
//#region src/server.d.ts
|
|
@@ -19,6 +20,7 @@ interface ServerInstance {
|
|
|
19
20
|
openRouterVideoJobs: OpenRouterVideoJobMap;
|
|
20
21
|
veoVideoJobs: VeoVideoJobMap;
|
|
21
22
|
grokVideoJobs: GrokVideoJobMap;
|
|
23
|
+
bytePlusVideoJobs: BytePlusVideoJobMap;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* The per-server state a full reset clears. `ServerInstance` structurally
|
package/dist/server.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.cts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.cts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;UAgIiB,cAAA;EAAA,MAAA,EACP,MAAA,CAAK,MADgB;EAAA,OAAA,EAEpB,OAFoB;KACrB,EAAA,MAAK;UACJ,EAEC,eAFD;aAEC,EACG,aADH;qBACG,EACQ,qBADR;cACQ,EACP,cADO;eACP,EACC,eADD;mBACC,EACI,mBADJ;;;AA+rCjB;;;;;UAAiB,eAAA;UACP;UACA;cACI;;iBAMQ,YAAA,WACV,qBACA,4BACD;;WAA+B;sBACtB,kBACjB,QAAQ"}
|
package/dist/server.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { VideoStateMap } from "./video.js";
|
|
|
7
7
|
import { OpenRouterVideoJobMap } from "./openrouter-video.js";
|
|
8
8
|
import { VeoVideoJobMap } from "./veo-video.js";
|
|
9
9
|
import { GrokVideoJobMap } from "./grok-video.js";
|
|
10
|
+
import { BytePlusVideoJobMap } from "./byteplus-video.js";
|
|
10
11
|
import * as http$1 from "node:http";
|
|
11
12
|
|
|
12
13
|
//#region src/server.d.ts
|
|
@@ -19,6 +20,7 @@ interface ServerInstance {
|
|
|
19
20
|
openRouterVideoJobs: OpenRouterVideoJobMap;
|
|
20
21
|
veoVideoJobs: VeoVideoJobMap;
|
|
21
22
|
grokVideoJobs: GrokVideoJobMap;
|
|
23
|
+
bytePlusVideoJobs: BytePlusVideoJobMap;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* The per-server state a full reset clears. `ServerInstance` structurally
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;UAgIiB,cAAA;EAAA,MAAA,EACP,MAAA,CAAK,MADgB;EAAA,OAAA,EAEpB,OAFoB;KACrB,EAAA,MAAK;UACJ,EAEC,eAFD;aAEC,EACG,aADH;qBACG,EACQ,qBADR;cACQ,EACP,cADO;eACP,EACC,eADD;mBACC,EACI,mBADJ;;;AA+rCjB;;;;;UAAiB,eAAA;UACP;UACA;cACI;;iBAMQ,YAAA,WACV,qBACA,4BACD;;WAA+B;sBACtB,kBACjB,QAAQ"}
|
package/dist/server.js
CHANGED
|
@@ -26,6 +26,7 @@ import { falQueueStates, handleFal } from "./fal.js";
|
|
|
26
26
|
import { OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OpenRouterVideoJobMap, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus } from "./openrouter-video.js";
|
|
27
27
|
import { VeoVideoJobMap, handleVeoVideoCreate, handleVeoVideoStatus } from "./veo-video.js";
|
|
28
28
|
import { GrokVideoJobMap, handleGrokVideoCreate, handleGrokVideoStatus } from "./grok-video.js";
|
|
29
|
+
import { BytePlusVideoJobMap, handleBytePlusVideoCreate, handleBytePlusVideoStatus } from "./byteplus-video.js";
|
|
29
30
|
import { handleElevenLabsAudio, handleElevenLabsTTS } from "./elevenlabs-audio.js";
|
|
30
31
|
import { handleOllama, handleOllamaEmbeddings, handleOllamaGenerate } from "./ollama.js";
|
|
31
32
|
import { handleCohere, handleCohereEmbed } from "./cohere.js";
|
|
@@ -36,7 +37,7 @@ import { upgradeToWebSocket } from "./ws-framing.js";
|
|
|
36
37
|
import { handleWebSocketResponses } from "./ws-responses.js";
|
|
37
38
|
import { handleWebSocketRealtime } from "./ws-realtime.js";
|
|
38
39
|
import { handleWebSocketGeminiLive } from "./ws-gemini-live.js";
|
|
39
|
-
import { GROK_VIDEO_STATUS_RE, GROK_VIDEO_SUBMIT_PATH, OPENROUTER_VIDEO_CONTENT_RE, OPENROUTER_VIDEO_STATUS_RE, VEO_OPERATION_RE, VEO_PREDICT_LRO_RE, createMetricsRegistry, normalizePathLabel } from "./metrics.js";
|
|
40
|
+
import { BYTEPLUS_VIDEO_STATUS_RE, BYTEPLUS_VIDEO_SUBMIT_RE, GROK_VIDEO_STATUS_RE, GROK_VIDEO_SUBMIT_PATH, OPENROUTER_VIDEO_CONTENT_RE, OPENROUTER_VIDEO_STATUS_RE, VEO_OPERATION_RE, VEO_PREDICT_LRO_RE, createMetricsRegistry, normalizePathLabel } from "./metrics.js";
|
|
40
41
|
import * as http$1 from "node:http";
|
|
41
42
|
|
|
42
43
|
//#region src/server.ts
|
|
@@ -167,13 +168,14 @@ function performFullReset(fixtures, targets) {
|
|
|
167
168
|
targets.openRouterVideoJobs.clear();
|
|
168
169
|
targets.veoVideoJobs.clear();
|
|
169
170
|
targets.grokVideoJobs.clear();
|
|
171
|
+
targets.bytePlusVideoJobs.clear();
|
|
170
172
|
if (targets.defaults.registry) targets.defaults.registry.setGauge("aimock_fixtures_loaded", {}, fixtures.length);
|
|
171
173
|
}
|
|
172
174
|
/**
|
|
173
175
|
* Handle requests under `/__aimock/`. Returns `true` if the request was
|
|
174
176
|
* handled, `false` if the path doesn't match the control prefix.
|
|
175
177
|
*/
|
|
176
|
-
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, defaults) {
|
|
178
|
+
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, bytePlusVideoJobs, defaults) {
|
|
177
179
|
if (!pathname.startsWith(CONTROL_PREFIX)) return false;
|
|
178
180
|
const subPath = pathname.slice(9);
|
|
179
181
|
setCorsHeaders(res);
|
|
@@ -187,6 +189,11 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
187
189
|
res.end(JSON.stringify(journal.getAll()));
|
|
188
190
|
return true;
|
|
189
191
|
}
|
|
192
|
+
if (subPath === "/fixtures" && req.method === "GET") {
|
|
193
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
194
|
+
res.end(JSON.stringify({ count: fixtures.length }));
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
190
197
|
if (subPath === "/fixtures" && req.method === "POST") {
|
|
191
198
|
let raw;
|
|
192
199
|
try {
|
|
@@ -242,6 +249,7 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
242
249
|
openRouterVideoJobs,
|
|
243
250
|
veoVideoJobs,
|
|
244
251
|
grokVideoJobs,
|
|
252
|
+
bytePlusVideoJobs,
|
|
245
253
|
defaults
|
|
246
254
|
});
|
|
247
255
|
if (subPath === "/reset" && req.method === "POST") {
|
|
@@ -791,6 +799,9 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
791
799
|
},
|
|
792
800
|
get grokVideo() {
|
|
793
801
|
return serverOptions.grokVideo;
|
|
802
|
+
},
|
|
803
|
+
get bytePlusVideo() {
|
|
804
|
+
return serverOptions.bytePlusVideo;
|
|
794
805
|
}
|
|
795
806
|
};
|
|
796
807
|
if (options?.chaos) {
|
|
@@ -826,6 +837,10 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
826
837
|
{
|
|
827
838
|
name: "grokVideo",
|
|
828
839
|
config: options?.grokVideo
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
name: "bytePlusVideo",
|
|
843
|
+
config: options?.bytePlusVideo
|
|
829
844
|
}
|
|
830
845
|
]) {
|
|
831
846
|
if (!config) continue;
|
|
@@ -840,6 +855,16 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
840
855
|
const cap = options?.record?.openRouterVideo?.maxContentBytes;
|
|
841
856
|
if (cap !== void 0 && (!Number.isInteger(cap) || cap < 0)) logger.warn(`record.openRouterVideo.maxContentBytes (${cap}) is not a non-negative integer — using the default cap (${OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES})`);
|
|
842
857
|
}
|
|
858
|
+
{
|
|
859
|
+
const bytePlusBase = options?.record?.providers?.byteplus;
|
|
860
|
+
if (bytePlusBase !== void 0) {
|
|
861
|
+
let basePath;
|
|
862
|
+
try {
|
|
863
|
+
basePath = new URL(bytePlusBase).pathname;
|
|
864
|
+
} catch {}
|
|
865
|
+
if (basePath !== void 0 && /(^|\/)api\/v3\/?$/.test(basePath)) throw new Error(`record.providers.byteplus (${bytePlusBase}) ends in /api/v3, but aimock appends the /api/v3 prefix itself — every BytePlus request would go to /api/v3/api/v3/... and fail upstream. Configure the ORIGIN only (e.g. https://ark.ap-southeast.bytepluses.com).`);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
843
868
|
const journal = new Journal({
|
|
844
869
|
maxEntries: options?.journalMaxEntries ?? 1e3,
|
|
845
870
|
fixtureCountsMaxTestIds: options?.fixtureCountsMaxTestIds ?? 500
|
|
@@ -848,6 +873,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
848
873
|
const openRouterVideoJobs = new OpenRouterVideoJobMap();
|
|
849
874
|
const veoVideoJobs = new VeoVideoJobMap();
|
|
850
875
|
const grokVideoJobs = new GrokVideoJobMap();
|
|
876
|
+
const bytePlusVideoJobs = new BytePlusVideoJobMap();
|
|
851
877
|
if (mounts) for (const { handler } of mounts) {
|
|
852
878
|
if (handler.setJournal) handler.setJournal(journal);
|
|
853
879
|
if (registry && handler.setRegistry) handler.setRegistry(registry);
|
|
@@ -873,7 +899,9 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
873
899
|
const startTime = registry ? process.hrtime.bigint() : 0n;
|
|
874
900
|
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
875
901
|
let pathname = parsedUrl.pathname;
|
|
876
|
-
const
|
|
902
|
+
const originalPathname = pathname;
|
|
903
|
+
const isOpenRouter = isOpenRouterPath(originalPathname);
|
|
904
|
+
const isBytePlusArk = defaults.record?.providers.byteplus !== void 0 && originalPathname.startsWith("/api/v3/");
|
|
877
905
|
if (registry) res.on("finish", () => {
|
|
878
906
|
try {
|
|
879
907
|
const normalizedPath = normalizePathLabel(pathname);
|
|
@@ -905,7 +933,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
905
933
|
markAuthenticatedRequest(req, resolvedAuth.policy);
|
|
906
934
|
}
|
|
907
935
|
if (pathname.startsWith(CONTROL_PREFIX)) {
|
|
908
|
-
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, defaults);
|
|
936
|
+
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, bytePlusVideoJobs, defaults);
|
|
909
937
|
return;
|
|
910
938
|
}
|
|
911
939
|
if (mounts) {
|
|
@@ -1088,6 +1116,66 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1088
1116
|
}
|
|
1089
1117
|
return;
|
|
1090
1118
|
}
|
|
1119
|
+
const bytePlusVideoStatusMatch = pathname.match(BYTEPLUS_VIDEO_STATUS_RE);
|
|
1120
|
+
if (bytePlusVideoStatusMatch && req.method === "GET") {
|
|
1121
|
+
try {
|
|
1122
|
+
await handleBytePlusVideoStatus(req, res, bytePlusVideoStatusMatch[1], fixtures, journal, defaults, setCorsHeaders, bytePlusVideoJobs);
|
|
1123
|
+
} catch (err) {
|
|
1124
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1125
|
+
defaults.logger.error(`byteplus-video status: ${msg}`);
|
|
1126
|
+
if (!res.headersSent) {
|
|
1127
|
+
try {
|
|
1128
|
+
journal.add({
|
|
1129
|
+
method: req.method ?? "GET",
|
|
1130
|
+
path: req.url ?? pathname,
|
|
1131
|
+
headers: flattenHeaders(req.headers),
|
|
1132
|
+
body: null,
|
|
1133
|
+
response: {
|
|
1134
|
+
status: 500,
|
|
1135
|
+
fixture: null
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
} catch (jErr) {
|
|
1139
|
+
defaults.logger.warn(`byteplus-video status: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
1140
|
+
}
|
|
1141
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
1142
|
+
message: msg,
|
|
1143
|
+
type: "server_error"
|
|
1144
|
+
} }));
|
|
1145
|
+
} else if (!res.writableEnded) res.destroy();
|
|
1146
|
+
}
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (BYTEPLUS_VIDEO_SUBMIT_RE.test(pathname) && req.method === "POST") {
|
|
1150
|
+
setCorsHeaders(res);
|
|
1151
|
+
try {
|
|
1152
|
+
await handleBytePlusVideoCreate(req, res, await readBody(req), fixtures, journal, defaults, setCorsHeaders, bytePlusVideoJobs);
|
|
1153
|
+
} catch (err) {
|
|
1154
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1155
|
+
defaults.logger.error(`byteplus-video submit: ${msg}`);
|
|
1156
|
+
if (!res.headersSent) {
|
|
1157
|
+
try {
|
|
1158
|
+
journal.add({
|
|
1159
|
+
method: req.method ?? "POST",
|
|
1160
|
+
path: req.url ?? pathname,
|
|
1161
|
+
headers: flattenHeaders(req.headers),
|
|
1162
|
+
body: null,
|
|
1163
|
+
response: {
|
|
1164
|
+
status: 500,
|
|
1165
|
+
fixture: null
|
|
1166
|
+
}
|
|
1167
|
+
});
|
|
1168
|
+
} catch (jErr) {
|
|
1169
|
+
defaults.logger.warn(`byteplus-video submit: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
1170
|
+
}
|
|
1171
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
1172
|
+
message: msg,
|
|
1173
|
+
type: "server_error"
|
|
1174
|
+
} }));
|
|
1175
|
+
} else if (!res.writableEnded) res.destroy();
|
|
1176
|
+
}
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1091
1179
|
if (pathname === "/api/v1/models" && req.method === "GET") {
|
|
1092
1180
|
handleOpenRouterModels(req, res, fixtures, journal, defaults, setCorsHeaders);
|
|
1093
1181
|
return;
|
|
@@ -1286,7 +1374,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1286
1374
|
}
|
|
1287
1375
|
if (pathname === IMAGES_PATH && req.method === "POST") {
|
|
1288
1376
|
try {
|
|
1289
|
-
await handleImages(req, res, await readBody(req), fixtures, journal, defaults, setCorsHeaders);
|
|
1377
|
+
await handleImages(req, res, await readBody(req), fixtures, journal, defaults, setCorsHeaders, "openai", void 0, isBytePlusArk ? "byteplus" : void 0);
|
|
1290
1378
|
} catch (err) {
|
|
1291
1379
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1292
1380
|
if (!res.headersSent) writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1825,7 +1913,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1825
1913
|
handleNotFound(res, "Not found");
|
|
1826
1914
|
return;
|
|
1827
1915
|
}
|
|
1828
|
-
const completionsProvider = azureDeploymentId ? "azure" : isOpenRouter ? "openrouter" : "openai";
|
|
1916
|
+
const completionsProvider = azureDeploymentId ? "azure" : isOpenRouter ? "openrouter" : isBytePlusArk ? "byteplus" : "openai";
|
|
1829
1917
|
try {
|
|
1830
1918
|
await handleCompletions(req, res, fixtures, journal, defaults, azureDeploymentId, completionsProvider, isOpenRouter);
|
|
1831
1919
|
} catch (err) {
|
|
@@ -1853,7 +1941,48 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1853
1941
|
if (!socket.destroyed) socket.destroy();
|
|
1854
1942
|
});
|
|
1855
1943
|
});
|
|
1944
|
+
/**
|
|
1945
|
+
* Body bytes the platform already parsed onto `req` for an upgrade request.
|
|
1946
|
+
*
|
|
1947
|
+
* Node >= 26 delivers an upgrade request's body here and leaves `head`
|
|
1948
|
+
* empty; Node <= 24 leaves the body in `head` and ends `req` with nothing.
|
|
1949
|
+
* The stream has already ended in both cases, so this resolves on the next
|
|
1950
|
+
* tick either way — it never waits on the network.
|
|
1951
|
+
*/
|
|
1952
|
+
function drainParsedRequestBody(req) {
|
|
1953
|
+
return new Promise((resolve) => {
|
|
1954
|
+
const chunks = [];
|
|
1955
|
+
let settled = false;
|
|
1956
|
+
const done = () => {
|
|
1957
|
+
if (settled) return;
|
|
1958
|
+
settled = true;
|
|
1959
|
+
resolve(Buffer.concat(chunks));
|
|
1960
|
+
};
|
|
1961
|
+
req.on("data", (c) => chunks.push(c));
|
|
1962
|
+
req.on("end", done);
|
|
1963
|
+
req.on("error", done);
|
|
1964
|
+
req.on("close", done);
|
|
1965
|
+
req.resume();
|
|
1966
|
+
});
|
|
1967
|
+
}
|
|
1856
1968
|
async function handleUpgradeRequest(req, socket, head) {
|
|
1969
|
+
if ((req.headers.upgrade ?? "").toLowerCase() !== "websocket") {
|
|
1970
|
+
const parsedBody = await drainParsedRequestBody(req);
|
|
1971
|
+
const requestLine = `${req.method} ${req.url} HTTP/${req.httpVersion}\r\n`;
|
|
1972
|
+
const headerLines = [];
|
|
1973
|
+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
|
|
1974
|
+
if (/^(?:upgrade|connection)$/i.test(req.rawHeaders[i])) continue;
|
|
1975
|
+
headerLines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`);
|
|
1976
|
+
}
|
|
1977
|
+
const rebuilt = Buffer.from(requestLine + headerLines.join("\r\n") + "\r\n\r\n");
|
|
1978
|
+
socket.unshift(Buffer.concat([
|
|
1979
|
+
rebuilt,
|
|
1980
|
+
parsedBody,
|
|
1981
|
+
head
|
|
1982
|
+
]));
|
|
1983
|
+
server.emit("connection", socket);
|
|
1984
|
+
return;
|
|
1985
|
+
}
|
|
1857
1986
|
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
1858
1987
|
let pathname = parsedUrl.pathname;
|
|
1859
1988
|
if (!validateRequestApiKey(req, resolvedAuth.policy).ok) {
|
|
@@ -1922,6 +2051,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1922
2051
|
openRouterVideoJobs.clear();
|
|
1923
2052
|
veoVideoJobs.clear();
|
|
1924
2053
|
grokVideoJobs.clear();
|
|
2054
|
+
bytePlusVideoJobs.clear();
|
|
1925
2055
|
originalClose(callback);
|
|
1926
2056
|
return this;
|
|
1927
2057
|
};
|
|
@@ -1945,7 +2075,8 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1945
2075
|
videoStates,
|
|
1946
2076
|
openRouterVideoJobs,
|
|
1947
2077
|
veoVideoJobs,
|
|
1948
|
-
grokVideoJobs
|
|
2078
|
+
grokVideoJobs,
|
|
2079
|
+
bytePlusVideoJobs
|
|
1949
2080
|
});
|
|
1950
2081
|
});
|
|
1951
2082
|
});
|