@copilotkit/aimock 1.21.0 → 1.22.1
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 +56 -0
- package/README.md +1 -0
- package/dist/a2a-mock.cjs +1 -1
- package/dist/a2a-mock.cjs.map +1 -1
- package/dist/a2a-mock.d.cts.map +1 -1
- package/dist/a2a-mock.d.ts.map +1 -1
- package/dist/a2a-mock.js +1 -1
- package/dist/a2a-mock.js.map +1 -1
- package/dist/agui-recorder.cjs +25 -12
- package/dist/agui-recorder.cjs.map +1 -1
- package/dist/agui-recorder.js +25 -12
- package/dist/agui-recorder.js.map +1 -1
- package/dist/agui-types.d.cts.map +1 -1
- package/dist/aimock-cli.cjs +0 -0
- package/dist/aimock-cli.js +0 -0
- package/dist/bedrock-converse.cjs +72 -26
- package/dist/bedrock-converse.cjs.map +1 -1
- package/dist/bedrock-converse.d.cts.map +1 -1
- package/dist/bedrock-converse.d.ts.map +1 -1
- package/dist/bedrock-converse.js +73 -27
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +69 -24
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts.map +1 -1
- package/dist/bedrock.d.ts.map +1 -1
- package/dist/bedrock.js +70 -25
- package/dist/bedrock.js.map +1 -1
- package/dist/cli.cjs +2 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +34 -11
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.d.cts.map +1 -1
- package/dist/cohere.d.ts.map +1 -1
- package/dist/cohere.js +35 -12
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/constants.cjs +8 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.d.cts +8 -0
- package/dist/constants.d.cts.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/elevenlabs-audio.cjs +46 -20
- package/dist/elevenlabs-audio.cjs.map +1 -1
- package/dist/elevenlabs-audio.d.cts.map +1 -1
- package/dist/elevenlabs-audio.d.ts.map +1 -1
- package/dist/elevenlabs-audio.js +47 -21
- package/dist/elevenlabs-audio.js.map +1 -1
- package/dist/embeddings.cjs +25 -21
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.d.cts.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +26 -22
- package/dist/embeddings.js.map +1 -1
- package/dist/fal-audio.cjs +138 -43
- package/dist/fal-audio.cjs.map +1 -1
- package/dist/fal-audio.d.cts.map +1 -1
- package/dist/fal-audio.d.ts.map +1 -1
- package/dist/fal-audio.js +139 -44
- package/dist/fal-audio.js.map +1 -1
- package/dist/fal.cjs +27 -8
- package/dist/fal.cjs.map +1 -1
- package/dist/fal.d.cts.map +1 -1
- package/dist/fal.d.ts.map +1 -1
- package/dist/fal.js +28 -9
- package/dist/fal.js.map +1 -1
- package/dist/fixture-loader.cjs +9 -1
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.js +9 -1
- package/dist/fixture-loader.js.map +1 -1
- package/dist/gemini-interactions.cjs +34 -9
- package/dist/gemini-interactions.cjs.map +1 -1
- package/dist/gemini-interactions.d.cts.map +1 -1
- package/dist/gemini-interactions.d.ts.map +1 -1
- package/dist/gemini-interactions.js +34 -11
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +50 -21
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.d.cts.map +1 -1
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +51 -22
- package/dist/gemini.js.map +1 -1
- package/dist/helpers.cjs +82 -8
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +7 -0
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts +7 -0
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +80 -9
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +31 -10
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +32 -11
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/journal.cjs +17 -7
- package/dist/journal.cjs.map +1 -1
- package/dist/journal.d.cts +2 -3
- package/dist/journal.d.cts.map +1 -1
- package/dist/journal.d.ts +2 -3
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +15 -4
- package/dist/journal.js.map +1 -1
- package/dist/mcp-mock.cjs +1 -1
- package/dist/mcp-mock.cjs.map +1 -1
- package/dist/mcp-mock.d.cts.map +1 -1
- package/dist/mcp-mock.d.ts.map +1 -1
- package/dist/mcp-mock.js +1 -1
- package/dist/mcp-mock.js.map +1 -1
- package/dist/messages.cjs +38 -14
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.d.cts.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +39 -15
- package/dist/messages.js.map +1 -1
- package/dist/moderation.cjs +3 -2
- package/dist/moderation.cjs.map +1 -1
- package/dist/moderation.js +3 -2
- package/dist/moderation.js.map +1 -1
- package/dist/ollama.cjs +69 -22
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts.map +1 -1
- package/dist/ollama.d.ts.map +1 -1
- package/dist/ollama.js +70 -23
- package/dist/ollama.js.map +1 -1
- package/dist/recorder.cjs +89 -41
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts +3 -2
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts +3 -2
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +89 -41
- package/dist/recorder.js.map +1 -1
- package/dist/rerank.cjs +3 -2
- package/dist/rerank.cjs.map +1 -1
- package/dist/rerank.js +3 -2
- package/dist/rerank.js.map +1 -1
- package/dist/responses.cjs +66 -54
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts +1 -1
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts +1 -1
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +67 -55
- package/dist/responses.js.map +1 -1
- package/dist/search.cjs +3 -2
- package/dist/search.cjs.map +1 -1
- package/dist/search.js +3 -2
- package/dist/search.js.map +1 -1
- package/dist/server.cjs +117 -171
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +95 -149
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +31 -10
- package/dist/speech.cjs.map +1 -1
- package/dist/speech.d.cts.map +1 -1
- package/dist/speech.d.ts.map +1 -1
- package/dist/speech.js +32 -11
- package/dist/speech.js.map +1 -1
- package/dist/stream-collapse.cjs +51 -21
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +1 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +1 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +51 -21
- package/dist/stream-collapse.js.map +1 -1
- package/dist/transcription.cjs +59 -19
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.cts.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +60 -20
- package/dist/transcription.js.map +1 -1
- package/dist/types.d.cts +4 -0
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-mock.cjs +10 -8
- package/dist/vector-mock.cjs.map +1 -1
- package/dist/vector-mock.d.cts.map +1 -1
- package/dist/vector-mock.d.ts.map +1 -1
- package/dist/vector-mock.js +10 -8
- package/dist/vector-mock.js.map +1 -1
- package/dist/vector-types.d.ts.map +1 -1
- package/dist/video.cjs +55 -16
- package/dist/video.cjs.map +1 -1
- package/dist/video.d.cts +8 -1
- package/dist/video.d.cts.map +1 -1
- package/dist/video.d.ts +8 -1
- package/dist/video.d.ts.map +1 -1
- package/dist/video.js +56 -17
- package/dist/video.js.map +1 -1
- package/dist/ws-gemini-live.cjs +40 -31
- package/dist/ws-gemini-live.cjs.map +1 -1
- package/dist/ws-gemini-live.d.cts +2 -0
- package/dist/ws-gemini-live.d.cts.map +1 -1
- package/dist/ws-gemini-live.d.ts +2 -0
- package/dist/ws-gemini-live.d.ts.map +1 -1
- package/dist/ws-gemini-live.js +40 -31
- package/dist/ws-gemini-live.js.map +1 -1
- package/dist/ws-realtime.cjs +257 -16
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts +2 -0
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts +2 -0
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +257 -16
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +54 -16
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts +2 -0
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts +2 -0
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +55 -17
- package/dist/ws-responses.js.map +1 -1
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, extractOverrides, flattenHeaders, getTestId, isAudioResponse, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, resolveResponse } from "./helpers.js";
|
|
1
|
+
import { buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, extractOverrides, flattenHeaders, getTestId, isAudioResponse, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, readBody, resolveResponse, resolveStrictMode, serializeErrorResponse, strictOverrideField } from "./helpers.js";
|
|
2
2
|
import { Logger } from "./logger.js";
|
|
3
3
|
import { Journal } from "./journal.js";
|
|
4
4
|
import { matchFixture } from "./router.js";
|
|
@@ -12,7 +12,7 @@ import { handleMessages } from "./messages.js";
|
|
|
12
12
|
import { handleGemini } from "./gemini.js";
|
|
13
13
|
import { handleBedrock, handleBedrockStream } from "./bedrock.js";
|
|
14
14
|
import { handleConverse, handleConverseStream } from "./bedrock-converse.js";
|
|
15
|
-
import { handleGeminiInteractions } from "./gemini-interactions.js";
|
|
15
|
+
import { handleGeminiInteractions, resetEventIdCounter, resetInteractionCounter } from "./gemini-interactions.js";
|
|
16
16
|
import { handleEmbeddings } from "./embeddings.js";
|
|
17
17
|
import { handleImages } from "./images.js";
|
|
18
18
|
import { handleSpeech } from "./speech.js";
|
|
@@ -111,21 +111,6 @@ const CORS_HEADERS = {
|
|
|
111
111
|
function setCorsHeaders(res) {
|
|
112
112
|
for (const [key, value] of Object.entries(CORS_HEADERS)) res.setHeader(key, value);
|
|
113
113
|
}
|
|
114
|
-
const DEFAULT_MAX_BODY_BYTES = 10 * 1024 * 1024;
|
|
115
|
-
async function readBody(req, maxBytes = DEFAULT_MAX_BODY_BYTES) {
|
|
116
|
-
const buffers = [];
|
|
117
|
-
let totalBytes = 0;
|
|
118
|
-
for await (const chunk of req) {
|
|
119
|
-
const buf = chunk;
|
|
120
|
-
totalBytes += buf.length;
|
|
121
|
-
if (totalBytes > maxBytes) {
|
|
122
|
-
req.destroy();
|
|
123
|
-
throw new Error(`Request body exceeded size limit of ${maxBytes} bytes`);
|
|
124
|
-
}
|
|
125
|
-
buffers.push(buf);
|
|
126
|
-
}
|
|
127
|
-
return Buffer.concat(buffers).toString();
|
|
128
|
-
}
|
|
129
114
|
function handleOptions(res) {
|
|
130
115
|
setCorsHeaders(res);
|
|
131
116
|
res.writeHead(204);
|
|
@@ -212,6 +197,8 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
212
197
|
videoStates.clear();
|
|
213
198
|
falJobs.clear();
|
|
214
199
|
falQueueStates.clear();
|
|
200
|
+
resetInteractionCounter();
|
|
201
|
+
resetEventIdCounter();
|
|
215
202
|
if (defaults.registry) defaults.registry.setGauge("aimock_fixtures_loaded", {}, fixtures.length);
|
|
216
203
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
217
204
|
res.end(JSON.stringify({ reset: true }));
|
|
@@ -252,12 +239,17 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
252
239
|
}
|
|
253
240
|
};
|
|
254
241
|
fixtures.unshift(errorFixture);
|
|
242
|
+
let consumed = false;
|
|
255
243
|
const original = errorFixture.match.predicate;
|
|
256
244
|
errorFixture.match.predicate = (req) => {
|
|
245
|
+
if (consumed) return false;
|
|
257
246
|
const result = original(req);
|
|
258
247
|
if (result) {
|
|
259
|
-
|
|
260
|
-
|
|
248
|
+
consumed = true;
|
|
249
|
+
queueMicrotask(() => {
|
|
250
|
+
const idx = fixtures.indexOf(errorFixture);
|
|
251
|
+
if (idx !== -1) fixtures.splice(idx, 1);
|
|
252
|
+
});
|
|
261
253
|
}
|
|
262
254
|
return result;
|
|
263
255
|
};
|
|
@@ -295,7 +287,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
295
287
|
try {
|
|
296
288
|
body = JSON.parse(raw);
|
|
297
289
|
if (modelFallback && !body.model) body.model = modelFallback;
|
|
298
|
-
} catch {
|
|
290
|
+
} catch (parseErr) {
|
|
291
|
+
const detail = parseErr instanceof Error ? parseErr.message : "unknown parse error";
|
|
299
292
|
journal.add({
|
|
300
293
|
method: req.method ?? "POST",
|
|
301
294
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -307,7 +300,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
307
300
|
}
|
|
308
301
|
});
|
|
309
302
|
writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
310
|
-
message:
|
|
303
|
+
message: `Malformed JSON: ${detail}`,
|
|
311
304
|
type: "invalid_request_error",
|
|
312
305
|
param: null,
|
|
313
306
|
code: "invalid_json"
|
|
@@ -363,6 +356,29 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
363
356
|
return;
|
|
364
357
|
}
|
|
365
358
|
if (!fixture) {
|
|
359
|
+
if (resolveStrictMode(defaults.strict, req.headers)) {
|
|
360
|
+
const strictStatus = 503;
|
|
361
|
+
const strictMessage = "Strict mode: no fixture matched";
|
|
362
|
+
defaults.logger.error(`STRICT: No fixture matched for ${req.method ?? "POST"} ${req.url ?? COMPLETIONS_PATH}`);
|
|
363
|
+
journal.add({
|
|
364
|
+
method: req.method ?? "POST",
|
|
365
|
+
path: req.url ?? COMPLETIONS_PATH,
|
|
366
|
+
headers: flattenHeaders(req.headers),
|
|
367
|
+
body,
|
|
368
|
+
response: {
|
|
369
|
+
status: strictStatus,
|
|
370
|
+
fixture: null,
|
|
371
|
+
...strictOverrideField(defaults.strict, req.headers)
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
|
|
375
|
+
message: strictMessage,
|
|
376
|
+
type: "invalid_request_error",
|
|
377
|
+
param: null,
|
|
378
|
+
code: "no_fixture_match"
|
|
379
|
+
} }));
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
366
382
|
if (defaults.record && providerKey) {
|
|
367
383
|
const hookOptions = chaosAction === "malformed" ? {
|
|
368
384
|
beforeWriteResponse: () => {
|
|
@@ -370,7 +386,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
370
386
|
return true;
|
|
371
387
|
},
|
|
372
388
|
onHookBypassed: (reason) => {
|
|
373
|
-
defaults.logger.warn(`[chaos] malformed bypassed on proxy: upstream returned
|
|
389
|
+
defaults.logger.warn(`[chaos] malformed bypassed on proxy: upstream returned streaming response (${reason})`);
|
|
374
390
|
defaults.registry?.incrementCounter("aimock_chaos_bypassed_total", {
|
|
375
391
|
action: "malformed",
|
|
376
392
|
source: "proxy",
|
|
@@ -380,7 +396,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
380
396
|
} : void 0;
|
|
381
397
|
const outcome = await proxyAndRecord(req, res, body, providerKey, req.url ?? COMPLETIONS_PATH, fixtures, defaults, raw, hookOptions);
|
|
382
398
|
if (outcome === "handled_by_hook") return;
|
|
383
|
-
if (outcome
|
|
399
|
+
if (outcome !== "not_configured") {
|
|
384
400
|
journal.add({
|
|
385
401
|
method: req.method ?? "POST",
|
|
386
402
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -395,21 +411,19 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
395
411
|
return;
|
|
396
412
|
}
|
|
397
413
|
}
|
|
398
|
-
const strictStatus = defaults.strict ? 503 : 404;
|
|
399
|
-
const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
|
|
400
|
-
if (defaults.strict) defaults.logger.error(`STRICT: No fixture matched for ${req.method ?? "POST"} ${req.url ?? COMPLETIONS_PATH}`);
|
|
401
414
|
journal.add({
|
|
402
415
|
method: req.method ?? "POST",
|
|
403
416
|
path: req.url ?? COMPLETIONS_PATH,
|
|
404
417
|
headers: flattenHeaders(req.headers),
|
|
405
418
|
body,
|
|
406
419
|
response: {
|
|
407
|
-
status:
|
|
408
|
-
fixture: null
|
|
420
|
+
status: 404,
|
|
421
|
+
fixture: null,
|
|
422
|
+
...strictOverrideField(defaults.strict, req.headers)
|
|
409
423
|
}
|
|
410
424
|
});
|
|
411
|
-
writeErrorResponse(res,
|
|
412
|
-
message:
|
|
425
|
+
writeErrorResponse(res, 404, JSON.stringify({ error: {
|
|
426
|
+
message: "No fixture matched",
|
|
413
427
|
type: "invalid_request_error",
|
|
414
428
|
param: null,
|
|
415
429
|
code: "no_fixture_match"
|
|
@@ -431,13 +445,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
431
445
|
fixture
|
|
432
446
|
}
|
|
433
447
|
});
|
|
434
|
-
|
|
435
|
-
message: response.error.message,
|
|
436
|
-
type: response.error.type ?? "server_error",
|
|
437
|
-
param: null,
|
|
438
|
-
code: response.error.code ?? null
|
|
439
|
-
} };
|
|
440
|
-
writeErrorResponse(res, status, JSON.stringify(errorBody));
|
|
448
|
+
writeErrorResponse(res, status, serializeErrorResponse(response));
|
|
441
449
|
return;
|
|
442
450
|
}
|
|
443
451
|
if (isAudioResponse(response)) {
|
|
@@ -526,6 +534,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
526
534
|
return;
|
|
527
535
|
}
|
|
528
536
|
if (isToolCallResponse(response)) {
|
|
537
|
+
if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
|
|
529
538
|
const overrides = extractOverrides(response);
|
|
530
539
|
const journalEntry = journal.add({
|
|
531
540
|
method: req.method ?? "POST",
|
|
@@ -634,7 +643,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
634
643
|
message: msg,
|
|
635
644
|
type: "server_error"
|
|
636
645
|
} }));
|
|
637
|
-
}
|
|
646
|
+
} else if (!res.writableEnded) res.end();
|
|
638
647
|
});
|
|
639
648
|
});
|
|
640
649
|
async function handleHttpRequest(req, res) {
|
|
@@ -775,13 +784,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
775
784
|
message: msg,
|
|
776
785
|
type: "server_error"
|
|
777
786
|
} }));
|
|
778
|
-
else if (!res.writableEnded) {
|
|
779
|
-
|
|
780
|
-
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
781
|
-
} catch (writeErr) {
|
|
782
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
783
|
-
}
|
|
787
|
+
else if (!res.writableEnded) try {
|
|
788
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
784
789
|
res.end();
|
|
790
|
+
} catch (writeErr) {
|
|
791
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
785
792
|
}
|
|
786
793
|
}
|
|
787
794
|
return;
|
|
@@ -795,13 +802,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
795
802
|
message: msg,
|
|
796
803
|
type: "server_error"
|
|
797
804
|
} }));
|
|
798
|
-
else if (!res.writableEnded) {
|
|
799
|
-
|
|
800
|
-
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
801
|
-
} catch (writeErr) {
|
|
802
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
803
|
-
}
|
|
805
|
+
else if (!res.writableEnded) try {
|
|
806
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
804
807
|
res.end();
|
|
808
|
+
} catch (writeErr) {
|
|
809
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
805
810
|
}
|
|
806
811
|
}
|
|
807
812
|
return;
|
|
@@ -815,13 +820,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
815
820
|
message: msg,
|
|
816
821
|
type: "server_error"
|
|
817
822
|
} }));
|
|
818
|
-
else if (!res.writableEnded) {
|
|
819
|
-
|
|
820
|
-
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
821
|
-
} catch (writeErr) {
|
|
822
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
823
|
-
}
|
|
823
|
+
else if (!res.writableEnded) try {
|
|
824
|
+
res.write(`event: error\ndata: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
824
825
|
res.end();
|
|
826
|
+
} catch (writeErr) {
|
|
827
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
825
828
|
}
|
|
826
829
|
}
|
|
827
830
|
return;
|
|
@@ -837,7 +840,9 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
837
840
|
parsed.model = deploymentId;
|
|
838
841
|
raw = JSON.stringify(parsed);
|
|
839
842
|
}
|
|
840
|
-
} catch {
|
|
843
|
+
} catch (err) {
|
|
844
|
+
if (!(err instanceof SyntaxError)) defaults.logger.error(`Unexpected error in Azure model injection: ${err instanceof Error ? err.message : String(err)}`);
|
|
845
|
+
}
|
|
841
846
|
await handleEmbeddings(req, res, raw, fixtures, journal, defaults, setCorsHeaders, embeddingsProvider);
|
|
842
847
|
} catch (err) {
|
|
843
848
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
@@ -931,13 +936,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
931
936
|
message: msg,
|
|
932
937
|
type: "server_error"
|
|
933
938
|
} }));
|
|
934
|
-
else if (!res.writableEnded) {
|
|
935
|
-
|
|
936
|
-
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
937
|
-
} catch (writeErr) {
|
|
938
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
939
|
-
}
|
|
939
|
+
else if (!res.writableEnded) try {
|
|
940
|
+
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
940
941
|
res.end();
|
|
942
|
+
} catch (writeErr) {
|
|
943
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
941
944
|
}
|
|
942
945
|
}
|
|
943
946
|
return;
|
|
@@ -954,13 +957,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
954
957
|
message: msg,
|
|
955
958
|
type: "server_error"
|
|
956
959
|
} }));
|
|
957
|
-
else if (!res.writableEnded) {
|
|
958
|
-
|
|
959
|
-
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
960
|
-
} catch (writeErr) {
|
|
961
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
962
|
-
}
|
|
960
|
+
else if (!res.writableEnded) try {
|
|
961
|
+
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
963
962
|
res.end();
|
|
963
|
+
} catch (writeErr) {
|
|
964
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
964
965
|
}
|
|
965
966
|
}
|
|
966
967
|
return;
|
|
@@ -977,13 +978,11 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
977
978
|
message: msg,
|
|
978
979
|
type: "server_error"
|
|
979
980
|
} }));
|
|
980
|
-
else if (!res.writableEnded) {
|
|
981
|
-
|
|
982
|
-
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
983
|
-
} catch (writeErr) {
|
|
984
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
985
|
-
}
|
|
981
|
+
else if (!res.writableEnded) try {
|
|
982
|
+
res.write(`data: ${JSON.stringify({ error: { message: msg } })}\n\n`);
|
|
986
983
|
res.end();
|
|
984
|
+
} catch (writeErr) {
|
|
985
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
987
986
|
}
|
|
988
987
|
}
|
|
989
988
|
return;
|
|
@@ -1132,21 +1131,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1132
1131
|
if (pathname === ELEVENLABS_SOUND_GENERATION_PATH && req.method === "POST") {
|
|
1133
1132
|
setCorsHeaders(res);
|
|
1134
1133
|
try {
|
|
1135
|
-
|
|
1136
|
-
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1137
|
-
if (chaosAction) {
|
|
1138
|
-
applyChaosAction(chaosAction, res, null, journal, {
|
|
1139
|
-
method: req.method ?? "POST",
|
|
1140
|
-
path: pathname,
|
|
1141
|
-
headers: flattenHeaders(req.headers),
|
|
1142
|
-
body: {
|
|
1143
|
-
model: "",
|
|
1144
|
-
messages: []
|
|
1145
|
-
}
|
|
1146
|
-
}, "fixture", defaults.registry);
|
|
1147
|
-
return;
|
|
1148
|
-
}
|
|
1149
|
-
await handleElevenLabsAudio(req, res, raw, fixtures, defaults, journal, "sound-generation");
|
|
1134
|
+
await handleElevenLabsAudio(req, res, await readBody(req), fixtures, defaults, journal, "sound-generation");
|
|
1150
1135
|
} catch (err) {
|
|
1151
1136
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1152
1137
|
if (!res.headersSent) writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1162,21 +1147,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1162
1147
|
setCorsHeaders(res);
|
|
1163
1148
|
const musicSubType = musicMatch[1] ?? "music";
|
|
1164
1149
|
try {
|
|
1165
|
-
|
|
1166
|
-
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1167
|
-
if (chaosAction) {
|
|
1168
|
-
applyChaosAction(chaosAction, res, null, journal, {
|
|
1169
|
-
method: req.method ?? "POST",
|
|
1170
|
-
path: pathname,
|
|
1171
|
-
headers: flattenHeaders(req.headers),
|
|
1172
|
-
body: {
|
|
1173
|
-
model: "",
|
|
1174
|
-
messages: []
|
|
1175
|
-
}
|
|
1176
|
-
}, "fixture", defaults.registry);
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
await handleElevenLabsAudio(req, res, raw, fixtures, defaults, journal, musicSubType);
|
|
1150
|
+
await handleElevenLabsAudio(req, res, await readBody(req), fixtures, defaults, journal, musicSubType);
|
|
1180
1151
|
} catch (err) {
|
|
1181
1152
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1182
1153
|
if (!res.headersSent) writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1187,10 +1158,12 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1187
1158
|
}
|
|
1188
1159
|
return;
|
|
1189
1160
|
}
|
|
1161
|
+
let falBody;
|
|
1190
1162
|
if (FAL_PREFIX_RE.test(pathname) && req.headers["x-fal-target-host"]) {
|
|
1191
1163
|
setCorsHeaders(res);
|
|
1192
1164
|
try {
|
|
1193
|
-
|
|
1165
|
+
falBody = req.method === "POST" || req.method === "PUT" ? await readBody(req) : "";
|
|
1166
|
+
const raw = falBody;
|
|
1194
1167
|
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1195
1168
|
if (chaosAction) {
|
|
1196
1169
|
applyChaosAction(chaosAction, res, null, journal, {
|
|
@@ -1218,21 +1191,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1218
1191
|
if (pathname.match(FAL_QUEUE_SUBMIT_RE) && req.method === "POST") {
|
|
1219
1192
|
setCorsHeaders(res);
|
|
1220
1193
|
try {
|
|
1221
|
-
|
|
1222
|
-
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1223
|
-
if (chaosAction) {
|
|
1224
|
-
applyChaosAction(chaosAction, res, null, journal, {
|
|
1225
|
-
method: req.method ?? "POST",
|
|
1226
|
-
path: pathname,
|
|
1227
|
-
headers: flattenHeaders(req.headers),
|
|
1228
|
-
body: {
|
|
1229
|
-
model: "",
|
|
1230
|
-
messages: []
|
|
1231
|
-
}
|
|
1232
|
-
}, "fixture", defaults.registry);
|
|
1233
|
-
return;
|
|
1234
|
-
}
|
|
1235
|
-
await handleFalQueue(req, res, raw, pathname, fixtures, defaults, journal);
|
|
1194
|
+
await handleFalQueue(req, res, falBody ?? await readBody(req), pathname, fixtures, defaults, journal);
|
|
1236
1195
|
} catch (err) {
|
|
1237
1196
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1238
1197
|
if (!res.headersSent) writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1246,7 +1205,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1246
1205
|
if (pathname.match(FAL_QUEUE_REQUESTS_RE) && (req.method === "GET" || req.method === "POST" || req.method === "PUT")) {
|
|
1247
1206
|
setCorsHeaders(res);
|
|
1248
1207
|
try {
|
|
1249
|
-
const raw = req.method === "POST" ? await readBody(req) : "{}";
|
|
1208
|
+
const raw = req.method === "POST" || req.method === "PUT" ? falBody ?? await readBody(req) : "{}";
|
|
1250
1209
|
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1251
1210
|
if (chaosAction) {
|
|
1252
1211
|
applyChaosAction(chaosAction, res, null, journal, {
|
|
@@ -1274,21 +1233,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1274
1233
|
if (pathname.match(FAL_RUN_RE) && req.method === "POST") {
|
|
1275
1234
|
setCorsHeaders(res);
|
|
1276
1235
|
try {
|
|
1277
|
-
|
|
1278
|
-
const chaosAction = evaluateChaos(null, defaults.chaos, req.headers, defaults.logger);
|
|
1279
|
-
if (chaosAction) {
|
|
1280
|
-
applyChaosAction(chaosAction, res, null, journal, {
|
|
1281
|
-
method: req.method ?? "POST",
|
|
1282
|
-
path: pathname,
|
|
1283
|
-
headers: flattenHeaders(req.headers),
|
|
1284
|
-
body: {
|
|
1285
|
-
model: "",
|
|
1286
|
-
messages: []
|
|
1287
|
-
}
|
|
1288
|
-
}, "fixture", defaults.registry);
|
|
1289
|
-
return;
|
|
1290
|
-
}
|
|
1291
|
-
await handleFalQueue(req, res, raw, pathname, fixtures, defaults, journal);
|
|
1236
|
+
await handleFalQueue(req, res, falBody ?? await readBody(req), pathname, fixtures, defaults, journal);
|
|
1292
1237
|
} catch (err) {
|
|
1293
1238
|
const msg = err instanceof Error ? err.message : "Internal error";
|
|
1294
1239
|
if (!res.headersSent) writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
@@ -1316,16 +1261,14 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1316
1261
|
message: msg,
|
|
1317
1262
|
type: "server_error"
|
|
1318
1263
|
} }));
|
|
1319
|
-
else if (!res.writableEnded) {
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
} })}\n\n`);
|
|
1325
|
-
} catch (writeErr) {
|
|
1326
|
-
logger.debug("Failed to write error recovery response:", writeErr);
|
|
1327
|
-
}
|
|
1264
|
+
else if (!res.writableEnded) try {
|
|
1265
|
+
res.write(`data: ${JSON.stringify({ error: {
|
|
1266
|
+
message: msg,
|
|
1267
|
+
type: "server_error"
|
|
1268
|
+
} })}\n\n`);
|
|
1328
1269
|
res.end();
|
|
1270
|
+
} catch (writeErr) {
|
|
1271
|
+
logger.debug("Failed to write error recovery response:", writeErr);
|
|
1329
1272
|
}
|
|
1330
1273
|
}
|
|
1331
1274
|
}
|
|
@@ -1374,19 +1317,22 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1374
1317
|
if (pathname === RESPONSES_PATH) handleWebSocketResponses(ws, fixtures, journal, {
|
|
1375
1318
|
...defaults,
|
|
1376
1319
|
model: "gpt-4",
|
|
1377
|
-
testId: wsTestId
|
|
1320
|
+
testId: wsTestId,
|
|
1321
|
+
upgradeHeaders: req.headers
|
|
1378
1322
|
});
|
|
1379
1323
|
else if (pathname === REALTIME_PATH) {
|
|
1380
1324
|
const model = parsedUrl.searchParams.get("model") ?? "gpt-4o-realtime";
|
|
1381
1325
|
handleWebSocketRealtime(ws, fixtures, journal, {
|
|
1382
1326
|
...defaults,
|
|
1383
1327
|
model,
|
|
1384
|
-
testId: wsTestId
|
|
1328
|
+
testId: wsTestId,
|
|
1329
|
+
upgradeHeaders: req.headers
|
|
1385
1330
|
});
|
|
1386
1331
|
} else if (pathname === GEMINI_LIVE_PATH) handleWebSocketGeminiLive(ws, fixtures, journal, {
|
|
1387
1332
|
...defaults,
|
|
1388
1333
|
model: "gemini-2.0-flash",
|
|
1389
|
-
testId: wsTestId
|
|
1334
|
+
testId: wsTestId,
|
|
1335
|
+
upgradeHeaders: req.headers
|
|
1390
1336
|
});
|
|
1391
1337
|
}
|
|
1392
1338
|
const originalClose = server.close.bind(server);
|