@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.cjs
CHANGED
|
@@ -27,6 +27,7 @@ const require_fal = require('./fal.cjs');
|
|
|
27
27
|
const require_openrouter_video = require('./openrouter-video.cjs');
|
|
28
28
|
const require_veo_video = require('./veo-video.cjs');
|
|
29
29
|
const require_grok_video = require('./grok-video.cjs');
|
|
30
|
+
const require_byteplus_video = require('./byteplus-video.cjs');
|
|
30
31
|
const require_elevenlabs_audio = require('./elevenlabs-audio.cjs');
|
|
31
32
|
const require_ollama = require('./ollama.cjs');
|
|
32
33
|
const require_cohere = require('./cohere.cjs');
|
|
@@ -169,13 +170,14 @@ function performFullReset(fixtures, targets) {
|
|
|
169
170
|
targets.openRouterVideoJobs.clear();
|
|
170
171
|
targets.veoVideoJobs.clear();
|
|
171
172
|
targets.grokVideoJobs.clear();
|
|
173
|
+
targets.bytePlusVideoJobs.clear();
|
|
172
174
|
if (targets.defaults.registry) targets.defaults.registry.setGauge("aimock_fixtures_loaded", {}, fixtures.length);
|
|
173
175
|
}
|
|
174
176
|
/**
|
|
175
177
|
* Handle requests under `/__aimock/`. Returns `true` if the request was
|
|
176
178
|
* handled, `false` if the path doesn't match the control prefix.
|
|
177
179
|
*/
|
|
178
|
-
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, defaults) {
|
|
180
|
+
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, bytePlusVideoJobs, defaults) {
|
|
179
181
|
if (!pathname.startsWith(CONTROL_PREFIX)) return false;
|
|
180
182
|
const subPath = pathname.slice(9);
|
|
181
183
|
setCorsHeaders(res);
|
|
@@ -189,6 +191,11 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
189
191
|
res.end(JSON.stringify(journal.getAll()));
|
|
190
192
|
return true;
|
|
191
193
|
}
|
|
194
|
+
if (subPath === "/fixtures" && req.method === "GET") {
|
|
195
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
196
|
+
res.end(JSON.stringify({ count: fixtures.length }));
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
192
199
|
if (subPath === "/fixtures" && req.method === "POST") {
|
|
193
200
|
let raw;
|
|
194
201
|
try {
|
|
@@ -244,6 +251,7 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
244
251
|
openRouterVideoJobs,
|
|
245
252
|
veoVideoJobs,
|
|
246
253
|
grokVideoJobs,
|
|
254
|
+
bytePlusVideoJobs,
|
|
247
255
|
defaults
|
|
248
256
|
});
|
|
249
257
|
if (subPath === "/reset" && req.method === "POST") {
|
|
@@ -793,6 +801,9 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
793
801
|
},
|
|
794
802
|
get grokVideo() {
|
|
795
803
|
return serverOptions.grokVideo;
|
|
804
|
+
},
|
|
805
|
+
get bytePlusVideo() {
|
|
806
|
+
return serverOptions.bytePlusVideo;
|
|
796
807
|
}
|
|
797
808
|
};
|
|
798
809
|
if (options?.chaos) {
|
|
@@ -828,6 +839,10 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
828
839
|
{
|
|
829
840
|
name: "grokVideo",
|
|
830
841
|
config: options?.grokVideo
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
name: "bytePlusVideo",
|
|
845
|
+
config: options?.bytePlusVideo
|
|
831
846
|
}
|
|
832
847
|
]) {
|
|
833
848
|
if (!config) continue;
|
|
@@ -842,6 +857,16 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
842
857
|
const cap = options?.record?.openRouterVideo?.maxContentBytes;
|
|
843
858
|
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 (${require_openrouter_video.OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES})`);
|
|
844
859
|
}
|
|
860
|
+
{
|
|
861
|
+
const bytePlusBase = options?.record?.providers?.byteplus;
|
|
862
|
+
if (bytePlusBase !== void 0) {
|
|
863
|
+
let basePath;
|
|
864
|
+
try {
|
|
865
|
+
basePath = new URL(bytePlusBase).pathname;
|
|
866
|
+
} catch {}
|
|
867
|
+
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).`);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
845
870
|
const journal = new require_journal.Journal({
|
|
846
871
|
maxEntries: options?.journalMaxEntries ?? 1e3,
|
|
847
872
|
fixtureCountsMaxTestIds: options?.fixtureCountsMaxTestIds ?? 500
|
|
@@ -850,6 +875,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
850
875
|
const openRouterVideoJobs = new require_openrouter_video.OpenRouterVideoJobMap();
|
|
851
876
|
const veoVideoJobs = new require_veo_video.VeoVideoJobMap();
|
|
852
877
|
const grokVideoJobs = new require_grok_video.GrokVideoJobMap();
|
|
878
|
+
const bytePlusVideoJobs = new require_byteplus_video.BytePlusVideoJobMap();
|
|
853
879
|
if (mounts) for (const { handler } of mounts) {
|
|
854
880
|
if (handler.setJournal) handler.setJournal(journal);
|
|
855
881
|
if (registry && handler.setRegistry) handler.setRegistry(registry);
|
|
@@ -875,7 +901,9 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
875
901
|
const startTime = registry ? process.hrtime.bigint() : 0n;
|
|
876
902
|
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
877
903
|
let pathname = parsedUrl.pathname;
|
|
878
|
-
const
|
|
904
|
+
const originalPathname = pathname;
|
|
905
|
+
const isOpenRouter = require_openrouter_chat.isOpenRouterPath(originalPathname);
|
|
906
|
+
const isBytePlusArk = defaults.record?.providers.byteplus !== void 0 && originalPathname.startsWith("/api/v3/");
|
|
879
907
|
if (registry) res.on("finish", () => {
|
|
880
908
|
try {
|
|
881
909
|
const normalizedPath = require_metrics.normalizePathLabel(pathname);
|
|
@@ -907,7 +935,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
907
935
|
require_api_key_auth.markAuthenticatedRequest(req, resolvedAuth.policy);
|
|
908
936
|
}
|
|
909
937
|
if (pathname.startsWith(CONTROL_PREFIX)) {
|
|
910
|
-
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, defaults);
|
|
938
|
+
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, veoVideoJobs, grokVideoJobs, bytePlusVideoJobs, defaults);
|
|
911
939
|
return;
|
|
912
940
|
}
|
|
913
941
|
if (mounts) {
|
|
@@ -1090,6 +1118,66 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1090
1118
|
}
|
|
1091
1119
|
return;
|
|
1092
1120
|
}
|
|
1121
|
+
const bytePlusVideoStatusMatch = pathname.match(require_metrics.BYTEPLUS_VIDEO_STATUS_RE);
|
|
1122
|
+
if (bytePlusVideoStatusMatch && req.method === "GET") {
|
|
1123
|
+
try {
|
|
1124
|
+
await require_byteplus_video.handleBytePlusVideoStatus(req, res, bytePlusVideoStatusMatch[1], fixtures, journal, defaults, setCorsHeaders, bytePlusVideoJobs);
|
|
1125
|
+
} catch (err) {
|
|
1126
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1127
|
+
defaults.logger.error(`byteplus-video status: ${msg}`);
|
|
1128
|
+
if (!res.headersSent) {
|
|
1129
|
+
try {
|
|
1130
|
+
journal.add({
|
|
1131
|
+
method: req.method ?? "GET",
|
|
1132
|
+
path: req.url ?? pathname,
|
|
1133
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
1134
|
+
body: null,
|
|
1135
|
+
response: {
|
|
1136
|
+
status: 500,
|
|
1137
|
+
fixture: null
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
} catch (jErr) {
|
|
1141
|
+
defaults.logger.warn(`byteplus-video status: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
1142
|
+
}
|
|
1143
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
1144
|
+
message: msg,
|
|
1145
|
+
type: "server_error"
|
|
1146
|
+
} }));
|
|
1147
|
+
} else if (!res.writableEnded) res.destroy();
|
|
1148
|
+
}
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
if (require_metrics.BYTEPLUS_VIDEO_SUBMIT_RE.test(pathname) && req.method === "POST") {
|
|
1152
|
+
setCorsHeaders(res);
|
|
1153
|
+
try {
|
|
1154
|
+
await require_byteplus_video.handleBytePlusVideoCreate(req, res, await require_helpers.readBody(req), fixtures, journal, defaults, setCorsHeaders, bytePlusVideoJobs);
|
|
1155
|
+
} catch (err) {
|
|
1156
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1157
|
+
defaults.logger.error(`byteplus-video submit: ${msg}`);
|
|
1158
|
+
if (!res.headersSent) {
|
|
1159
|
+
try {
|
|
1160
|
+
journal.add({
|
|
1161
|
+
method: req.method ?? "POST",
|
|
1162
|
+
path: req.url ?? pathname,
|
|
1163
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
1164
|
+
body: null,
|
|
1165
|
+
response: {
|
|
1166
|
+
status: 500,
|
|
1167
|
+
fixture: null
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
} catch (jErr) {
|
|
1171
|
+
defaults.logger.warn(`byteplus-video submit: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
1172
|
+
}
|
|
1173
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
1174
|
+
message: msg,
|
|
1175
|
+
type: "server_error"
|
|
1176
|
+
} }));
|
|
1177
|
+
} else if (!res.writableEnded) res.destroy();
|
|
1178
|
+
}
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1093
1181
|
if (pathname === "/api/v1/models" && req.method === "GET") {
|
|
1094
1182
|
require_openrouter_chat.handleOpenRouterModels(req, res, fixtures, journal, defaults, setCorsHeaders);
|
|
1095
1183
|
return;
|
|
@@ -1288,7 +1376,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1288
1376
|
}
|
|
1289
1377
|
if (pathname === IMAGES_PATH && req.method === "POST") {
|
|
1290
1378
|
try {
|
|
1291
|
-
await require_images.handleImages(req, res, await require_helpers.readBody(req), fixtures, journal, defaults, setCorsHeaders);
|
|
1379
|
+
await require_images.handleImages(req, res, await require_helpers.readBody(req), fixtures, journal, defaults, setCorsHeaders, "openai", void 0, isBytePlusArk ? "byteplus" : void 0);
|
|
1292
1380
|
} catch (err) {
|
|
1293
1381
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1294
1382
|
if (!res.headersSent) require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1827,7 +1915,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1827
1915
|
handleNotFound(res, "Not found");
|
|
1828
1916
|
return;
|
|
1829
1917
|
}
|
|
1830
|
-
const completionsProvider = azureDeploymentId ? "azure" : isOpenRouter ? "openrouter" : "openai";
|
|
1918
|
+
const completionsProvider = azureDeploymentId ? "azure" : isOpenRouter ? "openrouter" : isBytePlusArk ? "byteplus" : "openai";
|
|
1831
1919
|
try {
|
|
1832
1920
|
await handleCompletions(req, res, fixtures, journal, defaults, azureDeploymentId, completionsProvider, isOpenRouter);
|
|
1833
1921
|
} catch (err) {
|
|
@@ -1855,7 +1943,48 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1855
1943
|
if (!socket.destroyed) socket.destroy();
|
|
1856
1944
|
});
|
|
1857
1945
|
});
|
|
1946
|
+
/**
|
|
1947
|
+
* Body bytes the platform already parsed onto `req` for an upgrade request.
|
|
1948
|
+
*
|
|
1949
|
+
* Node >= 26 delivers an upgrade request's body here and leaves `head`
|
|
1950
|
+
* empty; Node <= 24 leaves the body in `head` and ends `req` with nothing.
|
|
1951
|
+
* The stream has already ended in both cases, so this resolves on the next
|
|
1952
|
+
* tick either way — it never waits on the network.
|
|
1953
|
+
*/
|
|
1954
|
+
function drainParsedRequestBody(req) {
|
|
1955
|
+
return new Promise((resolve) => {
|
|
1956
|
+
const chunks = [];
|
|
1957
|
+
let settled = false;
|
|
1958
|
+
const done = () => {
|
|
1959
|
+
if (settled) return;
|
|
1960
|
+
settled = true;
|
|
1961
|
+
resolve(Buffer.concat(chunks));
|
|
1962
|
+
};
|
|
1963
|
+
req.on("data", (c) => chunks.push(c));
|
|
1964
|
+
req.on("end", done);
|
|
1965
|
+
req.on("error", done);
|
|
1966
|
+
req.on("close", done);
|
|
1967
|
+
req.resume();
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1858
1970
|
async function handleUpgradeRequest(req, socket, head) {
|
|
1971
|
+
if ((req.headers.upgrade ?? "").toLowerCase() !== "websocket") {
|
|
1972
|
+
const parsedBody = await drainParsedRequestBody(req);
|
|
1973
|
+
const requestLine = `${req.method} ${req.url} HTTP/${req.httpVersion}\r\n`;
|
|
1974
|
+
const headerLines = [];
|
|
1975
|
+
for (let i = 0; i < req.rawHeaders.length; i += 2) {
|
|
1976
|
+
if (/^(?:upgrade|connection)$/i.test(req.rawHeaders[i])) continue;
|
|
1977
|
+
headerLines.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i + 1]}`);
|
|
1978
|
+
}
|
|
1979
|
+
const rebuilt = Buffer.from(requestLine + headerLines.join("\r\n") + "\r\n\r\n");
|
|
1980
|
+
socket.unshift(Buffer.concat([
|
|
1981
|
+
rebuilt,
|
|
1982
|
+
parsedBody,
|
|
1983
|
+
head
|
|
1984
|
+
]));
|
|
1985
|
+
server.emit("connection", socket);
|
|
1986
|
+
return;
|
|
1987
|
+
}
|
|
1859
1988
|
const parsedUrl = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
1860
1989
|
let pathname = parsedUrl.pathname;
|
|
1861
1990
|
if (!require_api_key_auth.validateRequestApiKey(req, resolvedAuth.policy).ok) {
|
|
@@ -1924,6 +2053,7 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1924
2053
|
openRouterVideoJobs.clear();
|
|
1925
2054
|
veoVideoJobs.clear();
|
|
1926
2055
|
grokVideoJobs.clear();
|
|
2056
|
+
bytePlusVideoJobs.clear();
|
|
1927
2057
|
originalClose(callback);
|
|
1928
2058
|
return this;
|
|
1929
2059
|
};
|
|
@@ -1947,7 +2077,8 @@ async function createServerWithResolvedAuth(fixtures, options, resolvedAuth, mou
|
|
|
1947
2077
|
videoStates,
|
|
1948
2078
|
openRouterVideoJobs,
|
|
1949
2079
|
veoVideoJobs,
|
|
1950
|
-
grokVideoJobs
|
|
2080
|
+
grokVideoJobs,
|
|
2081
|
+
bytePlusVideoJobs
|
|
1951
2082
|
});
|
|
1952
2083
|
});
|
|
1953
2084
|
});
|