@copilotkit/aimock 1.10.0 → 1.12.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/README.md +4 -2
- package/dist/a2a-types.d.cts.map +1 -1
- package/dist/a2a-types.d.ts.map +1 -1
- package/dist/agui-handler.cjs +340 -0
- package/dist/agui-handler.cjs.map +1 -0
- package/dist/agui-handler.d.cts +96 -0
- package/dist/agui-handler.d.cts.map +1 -0
- package/dist/agui-handler.d.ts +96 -0
- package/dist/agui-handler.d.ts.map +1 -0
- package/dist/agui-handler.js +326 -0
- package/dist/agui-handler.js.map +1 -0
- package/dist/agui-mock.cjs +190 -0
- package/dist/agui-mock.cjs.map +1 -0
- package/dist/agui-mock.d.cts +50 -0
- package/dist/agui-mock.d.cts.map +1 -0
- package/dist/agui-mock.d.ts +50 -0
- package/dist/agui-mock.d.ts.map +1 -0
- package/dist/agui-mock.js +188 -0
- package/dist/agui-mock.js.map +1 -0
- package/dist/agui-recorder.cjs +153 -0
- package/dist/agui-recorder.cjs.map +1 -0
- package/dist/agui-recorder.d.cts +19 -0
- package/dist/agui-recorder.d.cts.map +1 -0
- package/dist/agui-recorder.d.ts +19 -0
- package/dist/agui-recorder.d.ts.map +1 -0
- package/dist/agui-recorder.js +147 -0
- package/dist/agui-recorder.js.map +1 -0
- package/dist/agui-types.d.cts +231 -0
- package/dist/agui-types.d.cts.map +1 -0
- package/dist/agui-types.d.ts +231 -0
- package/dist/agui-types.d.ts.map +1 -0
- package/dist/bedrock-converse.cjs +2 -0
- 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 +2 -0
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +2 -0
- 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 +2 -0
- package/dist/bedrock.js.map +1 -1
- package/dist/cli.cjs +32 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +32 -1
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +1 -0
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.js +1 -0
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.cjs +19 -0
- package/dist/config-loader.cjs.map +1 -1
- package/dist/config-loader.d.cts +16 -0
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts +16 -0
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +19 -0
- package/dist/config-loader.js.map +1 -1
- package/dist/embeddings.cjs +2 -1
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.js +2 -1
- package/dist/embeddings.js.map +1 -1
- package/dist/gemini.cjs +1 -0
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.js +1 -0
- package/dist/gemini.js.map +1 -1
- package/dist/helpers.cjs +16 -0
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +6 -2
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts +6 -2
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +13 -1
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +166 -0
- package/dist/images.cjs.map +1 -0
- package/dist/images.d.cts +11 -0
- package/dist/images.d.cts.map +1 -0
- package/dist/images.d.ts +11 -0
- package/dist/images.d.ts.map +1 -0
- package/dist/images.js +166 -0
- package/dist/images.js.map +1 -0
- package/dist/index.cjs +32 -0
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +9 -2
- package/dist/llmock.cjs +37 -1
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +5 -1
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +5 -1
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +37 -1
- package/dist/llmock.js.map +1 -1
- package/dist/messages.cjs +1 -0
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.js +1 -0
- package/dist/messages.js.map +1 -1
- package/dist/ollama.cjs +2 -0
- 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 +2 -0
- package/dist/ollama.js.map +1 -1
- package/dist/recorder.cjs +50 -7
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.js +50 -7
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +1 -0
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.js +1 -0
- package/dist/responses.js.map +1 -1
- package/dist/router.cjs +8 -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 +9 -0
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +80 -3
- 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 +80 -3
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +144 -0
- package/dist/speech.cjs.map +1 -0
- package/dist/speech.d.cts +11 -0
- package/dist/speech.d.cts.map +1 -0
- package/dist/speech.d.ts +11 -0
- package/dist/speech.d.ts.map +1 -0
- package/dist/speech.js +144 -0
- package/dist/speech.js.map +1 -0
- package/dist/suite.cjs +8 -0
- package/dist/suite.cjs.map +1 -1
- package/dist/suite.d.cts +4 -0
- package/dist/suite.d.cts.map +1 -1
- package/dist/suite.d.ts +4 -0
- package/dist/suite.d.ts.map +1 -1
- package/dist/suite.js +8 -0
- package/dist/suite.js.map +1 -1
- package/dist/transcription.cjs +134 -0
- package/dist/transcription.cjs.map +1 -0
- package/dist/transcription.d.cts +11 -0
- package/dist/transcription.d.cts.map +1 -0
- package/dist/transcription.d.ts +11 -0
- package/dist/transcription.d.ts.map +1 -0
- package/dist/transcription.js +134 -0
- package/dist/transcription.js.map +1 -0
- package/dist/types.d.cts +44 -2
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +44 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.ts.map +1 -1
- package/dist/video.cjs +196 -0
- package/dist/video.cjs.map +1 -0
- package/dist/video.d.cts +14 -0
- package/dist/video.d.cts.map +1 -0
- package/dist/video.d.ts +14 -0
- package/dist/video.d.ts.map +1 -0
- package/dist/video.js +195 -0
- package/dist/video.js.map +1 -0
- package/package.json +2 -2
package/dist/speech.cjs
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const require_helpers = require('./helpers.cjs');
|
|
2
|
+
const require_router = require('./router.cjs');
|
|
3
|
+
const require_sse_writer = require('./sse-writer.cjs');
|
|
4
|
+
const require_chaos = require('./chaos.cjs');
|
|
5
|
+
const require_recorder = require('./recorder.cjs');
|
|
6
|
+
|
|
7
|
+
//#region src/speech.ts
|
|
8
|
+
const FORMAT_TO_CONTENT_TYPE = {
|
|
9
|
+
mp3: "audio/mpeg",
|
|
10
|
+
opus: "audio/opus",
|
|
11
|
+
aac: "audio/aac",
|
|
12
|
+
flac: "audio/flac",
|
|
13
|
+
wav: "audio/wav",
|
|
14
|
+
pcm: "audio/pcm"
|
|
15
|
+
};
|
|
16
|
+
async function handleSpeech(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
17
|
+
setCorsHeaders(res);
|
|
18
|
+
const path = req.url ?? "/v1/audio/speech";
|
|
19
|
+
const method = req.method ?? "POST";
|
|
20
|
+
let speechReq;
|
|
21
|
+
try {
|
|
22
|
+
speechReq = JSON.parse(raw);
|
|
23
|
+
} catch {
|
|
24
|
+
journal.add({
|
|
25
|
+
method,
|
|
26
|
+
path,
|
|
27
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
28
|
+
body: null,
|
|
29
|
+
response: {
|
|
30
|
+
status: 400,
|
|
31
|
+
fixture: null
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
35
|
+
message: "Malformed JSON",
|
|
36
|
+
type: "invalid_request_error",
|
|
37
|
+
code: "invalid_json"
|
|
38
|
+
} }));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const syntheticReq = {
|
|
42
|
+
model: speechReq.model ?? "tts-1",
|
|
43
|
+
messages: [{
|
|
44
|
+
role: "user",
|
|
45
|
+
content: speechReq.input
|
|
46
|
+
}],
|
|
47
|
+
_endpointType: "speech"
|
|
48
|
+
};
|
|
49
|
+
const testId = require_helpers.getTestId(req);
|
|
50
|
+
const fixture = require_router.matchFixture(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
51
|
+
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
52
|
+
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
53
|
+
method,
|
|
54
|
+
path,
|
|
55
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
56
|
+
body: syntheticReq
|
|
57
|
+
}, defaults.registry, defaults.logger)) return;
|
|
58
|
+
if (!fixture) {
|
|
59
|
+
if (defaults.record) {
|
|
60
|
+
if (await require_recorder.proxyAndRecord(req, res, syntheticReq, "openai", req.url ?? "/v1/audio/speech", fixtures, defaults, raw)) {
|
|
61
|
+
journal.add({
|
|
62
|
+
method,
|
|
63
|
+
path,
|
|
64
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
65
|
+
body: syntheticReq,
|
|
66
|
+
response: {
|
|
67
|
+
status: res.statusCode ?? 200,
|
|
68
|
+
fixture: null
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const strictStatus = defaults.strict ? 503 : 404;
|
|
75
|
+
const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
|
|
76
|
+
journal.add({
|
|
77
|
+
method,
|
|
78
|
+
path,
|
|
79
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
80
|
+
body: syntheticReq,
|
|
81
|
+
response: {
|
|
82
|
+
status: strictStatus,
|
|
83
|
+
fixture: null
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
|
|
87
|
+
message: strictMessage,
|
|
88
|
+
type: "invalid_request_error",
|
|
89
|
+
code: "no_fixture_match"
|
|
90
|
+
} }));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const response = fixture.response;
|
|
94
|
+
if (require_helpers.isErrorResponse(response)) {
|
|
95
|
+
const status = response.status ?? 500;
|
|
96
|
+
journal.add({
|
|
97
|
+
method,
|
|
98
|
+
path,
|
|
99
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
100
|
+
body: syntheticReq,
|
|
101
|
+
response: {
|
|
102
|
+
status,
|
|
103
|
+
fixture
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
require_sse_writer.writeErrorResponse(res, status, JSON.stringify(response));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!require_helpers.isAudioResponse(response)) {
|
|
110
|
+
journal.add({
|
|
111
|
+
method,
|
|
112
|
+
path,
|
|
113
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
114
|
+
body: syntheticReq,
|
|
115
|
+
response: {
|
|
116
|
+
status: 500,
|
|
117
|
+
fixture
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
121
|
+
message: "Fixture response is not an audio type",
|
|
122
|
+
type: "server_error"
|
|
123
|
+
} }));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
journal.add({
|
|
127
|
+
method,
|
|
128
|
+
path,
|
|
129
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
130
|
+
body: syntheticReq,
|
|
131
|
+
response: {
|
|
132
|
+
status: 200,
|
|
133
|
+
fixture
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
const contentType = FORMAT_TO_CONTENT_TYPE[response.format ?? "mp3"] ?? "audio/mpeg";
|
|
137
|
+
const audioBytes = Buffer.from(response.audio, "base64");
|
|
138
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
139
|
+
res.end(audioBytes);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
exports.handleSpeech = handleSpeech;
|
|
144
|
+
//# sourceMappingURL=speech.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speech.cjs","names":["flattenHeaders","getTestId","matchFixture","applyChaos","proxyAndRecord","isErrorResponse","isAudioResponse"],"sources":["../src/speech.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport { isAudioResponse, isErrorResponse, flattenHeaders, getTestId } from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\ninterface SpeechRequest {\n model?: string;\n input: string;\n voice?: string;\n response_format?: string;\n speed?: number;\n [key: string]: unknown;\n}\n\nconst FORMAT_TO_CONTENT_TYPE: Record<string, string> = {\n mp3: \"audio/mpeg\",\n opus: \"audio/opus\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n wav: \"audio/wav\",\n pcm: \"audio/pcm\",\n};\n\nexport async function handleSpeech(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/audio/speech\";\n const method = req.method ?? \"POST\";\n\n let speechReq: SpeechRequest;\n try {\n speechReq = JSON.parse(raw) as SpeechRequest;\n } catch {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Malformed JSON\", type: \"invalid_request_error\", code: \"invalid_json\" },\n }),\n );\n return;\n }\n\n const syntheticReq: ChatCompletionRequest = {\n model: speechReq.model ?? \"tts-1\",\n messages: [{ role: \"user\", content: speechReq.input }],\n _endpointType: \"speech\",\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/audio/speech\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n const strictStatus = defaults.strict ? 503 : 404;\n const strictMessage = defaults.strict\n ? \"Strict mode: no fixture matched\"\n : \"No fixture matched\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: strictStatus, fixture: null },\n });\n writeErrorResponse(\n res,\n strictStatus,\n JSON.stringify({\n error: { message: strictMessage, type: \"invalid_request_error\", code: \"no_fixture_match\" },\n }),\n );\n return;\n }\n\n const response = fixture.response;\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const format = response.format ?? \"mp3\";\n const contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n const audioBytes = Buffer.from(response.audio, \"base64\");\n\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Journal } from "./journal.cjs";
|
|
2
|
+
import { Fixture, HandlerDefaults } from "./types.cjs";
|
|
3
|
+
import * as http from "node:http";
|
|
4
|
+
|
|
5
|
+
//#region src/speech.d.ts
|
|
6
|
+
declare function handleSpeech(req: http.IncomingMessage, res: http.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http.ServerResponse) => void): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=speech.d.ts.map
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { handleSpeech };
|
|
11
|
+
//# sourceMappingURL=speech.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speech.d.cts","names":[],"sources":["../src/speech.ts"],"sourcesContent":[],"mappings":";;;;;iBA2BsB,YAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,IAAA,CAAK,0BAC1B"}
|
package/dist/speech.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Journal } from "./journal.js";
|
|
2
|
+
import { Fixture, HandlerDefaults } from "./types.js";
|
|
3
|
+
import * as http from "node:http";
|
|
4
|
+
|
|
5
|
+
//#region src/speech.d.ts
|
|
6
|
+
declare function handleSpeech(req: http.IncomingMessage, res: http.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http.ServerResponse) => void): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=speech.d.ts.map
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { handleSpeech };
|
|
11
|
+
//# sourceMappingURL=speech.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speech.d.ts","names":[],"sources":["../src/speech.ts"],"sourcesContent":[],"mappings":";;;;;iBA2BsB,YAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,IAAA,CAAK,0BAC1B"}
|
package/dist/speech.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { flattenHeaders, getTestId, isAudioResponse, isErrorResponse } from "./helpers.js";
|
|
2
|
+
import { matchFixture } from "./router.js";
|
|
3
|
+
import { writeErrorResponse } from "./sse-writer.js";
|
|
4
|
+
import { applyChaos } from "./chaos.js";
|
|
5
|
+
import { proxyAndRecord } from "./recorder.js";
|
|
6
|
+
|
|
7
|
+
//#region src/speech.ts
|
|
8
|
+
const FORMAT_TO_CONTENT_TYPE = {
|
|
9
|
+
mp3: "audio/mpeg",
|
|
10
|
+
opus: "audio/opus",
|
|
11
|
+
aac: "audio/aac",
|
|
12
|
+
flac: "audio/flac",
|
|
13
|
+
wav: "audio/wav",
|
|
14
|
+
pcm: "audio/pcm"
|
|
15
|
+
};
|
|
16
|
+
async function handleSpeech(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
17
|
+
setCorsHeaders(res);
|
|
18
|
+
const path = req.url ?? "/v1/audio/speech";
|
|
19
|
+
const method = req.method ?? "POST";
|
|
20
|
+
let speechReq;
|
|
21
|
+
try {
|
|
22
|
+
speechReq = JSON.parse(raw);
|
|
23
|
+
} catch {
|
|
24
|
+
journal.add({
|
|
25
|
+
method,
|
|
26
|
+
path,
|
|
27
|
+
headers: flattenHeaders(req.headers),
|
|
28
|
+
body: null,
|
|
29
|
+
response: {
|
|
30
|
+
status: 400,
|
|
31
|
+
fixture: null
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
writeErrorResponse(res, 400, JSON.stringify({ error: {
|
|
35
|
+
message: "Malformed JSON",
|
|
36
|
+
type: "invalid_request_error",
|
|
37
|
+
code: "invalid_json"
|
|
38
|
+
} }));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const syntheticReq = {
|
|
42
|
+
model: speechReq.model ?? "tts-1",
|
|
43
|
+
messages: [{
|
|
44
|
+
role: "user",
|
|
45
|
+
content: speechReq.input
|
|
46
|
+
}],
|
|
47
|
+
_endpointType: "speech"
|
|
48
|
+
};
|
|
49
|
+
const testId = getTestId(req);
|
|
50
|
+
const fixture = matchFixture(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
51
|
+
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
52
|
+
if (applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
53
|
+
method,
|
|
54
|
+
path,
|
|
55
|
+
headers: flattenHeaders(req.headers),
|
|
56
|
+
body: syntheticReq
|
|
57
|
+
}, defaults.registry, defaults.logger)) return;
|
|
58
|
+
if (!fixture) {
|
|
59
|
+
if (defaults.record) {
|
|
60
|
+
if (await proxyAndRecord(req, res, syntheticReq, "openai", req.url ?? "/v1/audio/speech", fixtures, defaults, raw)) {
|
|
61
|
+
journal.add({
|
|
62
|
+
method,
|
|
63
|
+
path,
|
|
64
|
+
headers: flattenHeaders(req.headers),
|
|
65
|
+
body: syntheticReq,
|
|
66
|
+
response: {
|
|
67
|
+
status: res.statusCode ?? 200,
|
|
68
|
+
fixture: null
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const strictStatus = defaults.strict ? 503 : 404;
|
|
75
|
+
const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
|
|
76
|
+
journal.add({
|
|
77
|
+
method,
|
|
78
|
+
path,
|
|
79
|
+
headers: flattenHeaders(req.headers),
|
|
80
|
+
body: syntheticReq,
|
|
81
|
+
response: {
|
|
82
|
+
status: strictStatus,
|
|
83
|
+
fixture: null
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
|
|
87
|
+
message: strictMessage,
|
|
88
|
+
type: "invalid_request_error",
|
|
89
|
+
code: "no_fixture_match"
|
|
90
|
+
} }));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const response = fixture.response;
|
|
94
|
+
if (isErrorResponse(response)) {
|
|
95
|
+
const status = response.status ?? 500;
|
|
96
|
+
journal.add({
|
|
97
|
+
method,
|
|
98
|
+
path,
|
|
99
|
+
headers: flattenHeaders(req.headers),
|
|
100
|
+
body: syntheticReq,
|
|
101
|
+
response: {
|
|
102
|
+
status,
|
|
103
|
+
fixture
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
writeErrorResponse(res, status, JSON.stringify(response));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!isAudioResponse(response)) {
|
|
110
|
+
journal.add({
|
|
111
|
+
method,
|
|
112
|
+
path,
|
|
113
|
+
headers: flattenHeaders(req.headers),
|
|
114
|
+
body: syntheticReq,
|
|
115
|
+
response: {
|
|
116
|
+
status: 500,
|
|
117
|
+
fixture
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
121
|
+
message: "Fixture response is not an audio type",
|
|
122
|
+
type: "server_error"
|
|
123
|
+
} }));
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
journal.add({
|
|
127
|
+
method,
|
|
128
|
+
path,
|
|
129
|
+
headers: flattenHeaders(req.headers),
|
|
130
|
+
body: syntheticReq,
|
|
131
|
+
response: {
|
|
132
|
+
status: 200,
|
|
133
|
+
fixture
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
const contentType = FORMAT_TO_CONTENT_TYPE[response.format ?? "mp3"] ?? "audio/mpeg";
|
|
137
|
+
const audioBytes = Buffer.from(response.audio, "base64");
|
|
138
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
139
|
+
res.end(audioBytes);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
//#endregion
|
|
143
|
+
export { handleSpeech };
|
|
144
|
+
//# sourceMappingURL=speech.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speech.js","names":[],"sources":["../src/speech.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport { isAudioResponse, isErrorResponse, flattenHeaders, getTestId } from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\ninterface SpeechRequest {\n model?: string;\n input: string;\n voice?: string;\n response_format?: string;\n speed?: number;\n [key: string]: unknown;\n}\n\nconst FORMAT_TO_CONTENT_TYPE: Record<string, string> = {\n mp3: \"audio/mpeg\",\n opus: \"audio/opus\",\n aac: \"audio/aac\",\n flac: \"audio/flac\",\n wav: \"audio/wav\",\n pcm: \"audio/pcm\",\n};\n\nexport async function handleSpeech(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/audio/speech\";\n const method = req.method ?? \"POST\";\n\n let speechReq: SpeechRequest;\n try {\n speechReq = JSON.parse(raw) as SpeechRequest;\n } catch {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Malformed JSON\", type: \"invalid_request_error\", code: \"invalid_json\" },\n }),\n );\n return;\n }\n\n const syntheticReq: ChatCompletionRequest = {\n model: speechReq.model ?? \"tts-1\",\n messages: [{ role: \"user\", content: speechReq.input }],\n _endpointType: \"speech\",\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/audio/speech\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n const strictStatus = defaults.strict ? 503 : 404;\n const strictMessage = defaults.strict\n ? \"Strict mode: no fixture matched\"\n : \"No fixture matched\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: strictStatus, fixture: null },\n });\n writeErrorResponse(\n res,\n strictStatus,\n JSON.stringify({\n error: { message: strictMessage, type: \"invalid_request_error\", code: \"no_fixture_match\" },\n }),\n );\n return;\n }\n\n const response = fixture.response;\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const format = response.format ?? \"mp3\";\n const contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n const audioBytes = Buffer.from(response.audio, \"base64\");\n\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
|
package/dist/suite.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_a2a_mock = require('./a2a-mock.cjs');
|
|
2
2
|
const require_llmock = require('./llmock.cjs');
|
|
3
3
|
const require_mcp_mock = require('./mcp-mock.cjs');
|
|
4
|
+
const require_agui_mock = require('./agui-mock.cjs');
|
|
4
5
|
const require_vector_mock = require('./vector-mock.cjs');
|
|
5
6
|
|
|
6
7
|
//#region src/suite.ts
|
|
@@ -9,6 +10,7 @@ async function createMockSuite(options = {}) {
|
|
|
9
10
|
let mcp;
|
|
10
11
|
let a2a;
|
|
11
12
|
let vector;
|
|
13
|
+
let agui;
|
|
12
14
|
if (options.mcp) {
|
|
13
15
|
mcp = new require_mcp_mock.MCPMock(options.mcp);
|
|
14
16
|
llm.mount("/mcp", mcp);
|
|
@@ -21,11 +23,16 @@ async function createMockSuite(options = {}) {
|
|
|
21
23
|
vector = new require_vector_mock.VectorMock(options.vector);
|
|
22
24
|
llm.mount("/vector", vector);
|
|
23
25
|
}
|
|
26
|
+
if (options.agui) {
|
|
27
|
+
agui = new require_agui_mock.AGUIMock(options.agui);
|
|
28
|
+
llm.mount("/agui", agui);
|
|
29
|
+
}
|
|
24
30
|
return {
|
|
25
31
|
llm,
|
|
26
32
|
mcp,
|
|
27
33
|
a2a,
|
|
28
34
|
vector,
|
|
35
|
+
agui,
|
|
29
36
|
async start() {
|
|
30
37
|
await llm.start();
|
|
31
38
|
},
|
|
@@ -37,6 +44,7 @@ async function createMockSuite(options = {}) {
|
|
|
37
44
|
if (mcp) mcp.reset();
|
|
38
45
|
if (a2a) a2a.reset();
|
|
39
46
|
if (vector) vector.reset();
|
|
47
|
+
if (agui) agui.reset();
|
|
40
48
|
}
|
|
41
49
|
};
|
|
42
50
|
}
|
package/dist/suite.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite.cjs","names":["LLMock","MCPMock","A2AMock","VectorMock"],"sources":["../src/suite.ts"],"sourcesContent":["import { LLMock } from \"./llmock.js\";\nimport { MCPMock } from \"./mcp-mock.js\";\nimport { A2AMock } from \"./a2a-mock.js\";\nimport { VectorMock } from \"./vector-mock.js\";\nimport type { MockServerOptions } from \"./types.js\";\nimport type { MCPMockOptions } from \"./mcp-types.js\";\nimport type { A2AMockOptions } from \"./a2a-types.js\";\nimport type { VectorMockOptions } from \"./vector-types.js\";\n\nexport interface MockSuiteOptions {\n llm?: MockServerOptions;\n mcp?: MCPMockOptions;\n a2a?: A2AMockOptions;\n vector?: VectorMockOptions;\n}\n\nexport interface MockSuite {\n llm: LLMock;\n mcp?: MCPMock;\n a2a?: A2AMock;\n vector?: VectorMock;\n start(): Promise<void>;\n stop(): Promise<void>;\n reset(): void;\n}\n\nexport async function createMockSuite(options: MockSuiteOptions = {}): Promise<MockSuite> {\n const llm = new LLMock(options.llm);\n let mcp: MCPMock | undefined;\n let a2a: A2AMock | undefined;\n let vector: VectorMock | undefined;\n\n if (options.mcp) {\n mcp = new MCPMock(options.mcp);\n llm.mount(\"/mcp\", mcp);\n }\n\n if (options.a2a) {\n a2a = new A2AMock(options.a2a);\n llm.mount(\"/a2a\", a2a);\n }\n\n if (options.vector) {\n vector = new VectorMock(options.vector);\n llm.mount(\"/vector\", vector);\n }\n\n return {\n llm,\n mcp,\n a2a,\n vector,\n async start() {\n await llm.start();\n },\n async stop() {\n await llm.stop();\n },\n reset() {\n llm.reset();\n if (mcp) mcp.reset();\n if (a2a) a2a.reset();\n if (vector) vector.reset();\n },\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"suite.cjs","names":["LLMock","MCPMock","A2AMock","VectorMock","AGUIMock"],"sources":["../src/suite.ts"],"sourcesContent":["import { LLMock } from \"./llmock.js\";\nimport { MCPMock } from \"./mcp-mock.js\";\nimport { A2AMock } from \"./a2a-mock.js\";\nimport { VectorMock } from \"./vector-mock.js\";\nimport { AGUIMock } from \"./agui-mock.js\";\nimport type { MockServerOptions } from \"./types.js\";\nimport type { MCPMockOptions } from \"./mcp-types.js\";\nimport type { A2AMockOptions } from \"./a2a-types.js\";\nimport type { VectorMockOptions } from \"./vector-types.js\";\nimport type { AGUIMockOptions } from \"./agui-types.js\";\n\nexport interface MockSuiteOptions {\n llm?: MockServerOptions;\n mcp?: MCPMockOptions;\n a2a?: A2AMockOptions;\n vector?: VectorMockOptions;\n agui?: AGUIMockOptions;\n}\n\nexport interface MockSuite {\n llm: LLMock;\n mcp?: MCPMock;\n a2a?: A2AMock;\n vector?: VectorMock;\n agui?: AGUIMock;\n start(): Promise<void>;\n stop(): Promise<void>;\n reset(): void;\n}\n\nexport async function createMockSuite(options: MockSuiteOptions = {}): Promise<MockSuite> {\n const llm = new LLMock(options.llm);\n let mcp: MCPMock | undefined;\n let a2a: A2AMock | undefined;\n let vector: VectorMock | undefined;\n let agui: AGUIMock | undefined;\n\n if (options.mcp) {\n mcp = new MCPMock(options.mcp);\n llm.mount(\"/mcp\", mcp);\n }\n\n if (options.a2a) {\n a2a = new A2AMock(options.a2a);\n llm.mount(\"/a2a\", a2a);\n }\n\n if (options.vector) {\n vector = new VectorMock(options.vector);\n llm.mount(\"/vector\", vector);\n }\n\n if (options.agui) {\n agui = new AGUIMock(options.agui);\n llm.mount(\"/agui\", agui);\n }\n\n return {\n llm,\n mcp,\n a2a,\n vector,\n agui,\n async start() {\n await llm.start();\n },\n async stop() {\n await llm.stop();\n },\n reset() {\n llm.reset();\n if (mcp) mcp.reset();\n if (a2a) a2a.reset();\n if (vector) vector.reset();\n if (agui) agui.reset();\n },\n };\n}\n"],"mappings":";;;;;;;AA8BA,eAAsB,gBAAgB,UAA4B,EAAE,EAAsB;CACxF,MAAM,MAAM,IAAIA,sBAAO,QAAQ,IAAI;CACnC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AAEJ,KAAI,QAAQ,KAAK;AACf,QAAM,IAAIC,yBAAQ,QAAQ,IAAI;AAC9B,MAAI,MAAM,QAAQ,IAAI;;AAGxB,KAAI,QAAQ,KAAK;AACf,QAAM,IAAIC,yBAAQ,QAAQ,IAAI;AAC9B,MAAI,MAAM,QAAQ,IAAI;;AAGxB,KAAI,QAAQ,QAAQ;AAClB,WAAS,IAAIC,+BAAW,QAAQ,OAAO;AACvC,MAAI,MAAM,WAAW,OAAO;;AAG9B,KAAI,QAAQ,MAAM;AAChB,SAAO,IAAIC,2BAAS,QAAQ,KAAK;AACjC,MAAI,MAAM,SAAS,KAAK;;AAG1B,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,MAAM,QAAQ;AACZ,SAAM,IAAI,OAAO;;EAEnB,MAAM,OAAO;AACX,SAAM,IAAI,MAAM;;EAElB,QAAQ;AACN,OAAI,OAAO;AACX,OAAI,IAAK,KAAI,OAAO;AACpB,OAAI,IAAK,KAAI,OAAO;AACpB,OAAI,OAAQ,QAAO,OAAO;AAC1B,OAAI,KAAM,MAAK,OAAO;;EAEzB"}
|
package/dist/suite.d.cts
CHANGED
|
@@ -3,9 +3,11 @@ import { A2AMockOptions } from "./a2a-types.cjs";
|
|
|
3
3
|
import { A2AMock } from "./a2a-mock.cjs";
|
|
4
4
|
import { LLMock } from "./llmock.cjs";
|
|
5
5
|
import { MCPMockOptions } from "./mcp-types.cjs";
|
|
6
|
+
import { AGUIMockOptions } from "./agui-types.cjs";
|
|
6
7
|
import { VectorMockOptions } from "./vector-types.cjs";
|
|
7
8
|
import { MCPMock } from "./mcp-mock.cjs";
|
|
8
9
|
import { VectorMock } from "./vector-mock.cjs";
|
|
10
|
+
import { AGUIMock } from "./agui-mock.cjs";
|
|
9
11
|
|
|
10
12
|
//#region src/suite.d.ts
|
|
11
13
|
interface MockSuiteOptions {
|
|
@@ -13,12 +15,14 @@ interface MockSuiteOptions {
|
|
|
13
15
|
mcp?: MCPMockOptions;
|
|
14
16
|
a2a?: A2AMockOptions;
|
|
15
17
|
vector?: VectorMockOptions;
|
|
18
|
+
agui?: AGUIMockOptions;
|
|
16
19
|
}
|
|
17
20
|
interface MockSuite {
|
|
18
21
|
llm: LLMock;
|
|
19
22
|
mcp?: MCPMock;
|
|
20
23
|
a2a?: A2AMock;
|
|
21
24
|
vector?: VectorMock;
|
|
25
|
+
agui?: AGUIMock;
|
|
22
26
|
start(): Promise<void>;
|
|
23
27
|
stop(): Promise<void>;
|
|
24
28
|
reset(): void;
|
package/dist/suite.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite.d.cts","names":[],"sources":["../src/suite.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"suite.d.cts","names":[],"sources":["../src/suite.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;UAWiB,gBAAA;QACT;EADS,GAAA,CAAA,EAET,cAFyB;EAAA,GAAA,CAAA,EAGzB,cAHyB;QACzB,CAAA,EAGG,iBAHH;MACA,CAAA,EAGC,eAHD;;AAEG,UAIM,SAAA,CAJN;KACF,EAIF,MAJE;EAAe,GAAA,CAAA,EAKhB,OALgB;EAGP,GAAA,CAAA,EAGT,OAHkB;EAAA,MAAA,CAAA,EAIf,UAJe;MACnB,CAAA,EAIE,QAJF;OACC,EAAA,EAIG,OAJH,CAAA,IAAA,CAAA;MACA,EAAA,EAIE,OAJF,CAAA,IAAA,CAAA;OACG,EAAA,EAAA,IAAA;;AAEA,iBAKW,eAAA,CALX,OAAA,CAAA,EAKoC,gBALpC,CAAA,EAK4D,OAL5D,CAKoE,SALpE,CAAA"}
|
package/dist/suite.d.ts
CHANGED
|
@@ -3,9 +3,11 @@ import { A2AMockOptions } from "./a2a-types.js";
|
|
|
3
3
|
import { A2AMock } from "./a2a-mock.js";
|
|
4
4
|
import { LLMock } from "./llmock.js";
|
|
5
5
|
import { MCPMockOptions } from "./mcp-types.js";
|
|
6
|
+
import { AGUIMockOptions } from "./agui-types.js";
|
|
6
7
|
import { VectorMockOptions } from "./vector-types.js";
|
|
7
8
|
import { MCPMock } from "./mcp-mock.js";
|
|
8
9
|
import { VectorMock } from "./vector-mock.js";
|
|
10
|
+
import { AGUIMock } from "./agui-mock.js";
|
|
9
11
|
|
|
10
12
|
//#region src/suite.d.ts
|
|
11
13
|
interface MockSuiteOptions {
|
|
@@ -13,12 +15,14 @@ interface MockSuiteOptions {
|
|
|
13
15
|
mcp?: MCPMockOptions;
|
|
14
16
|
a2a?: A2AMockOptions;
|
|
15
17
|
vector?: VectorMockOptions;
|
|
18
|
+
agui?: AGUIMockOptions;
|
|
16
19
|
}
|
|
17
20
|
interface MockSuite {
|
|
18
21
|
llm: LLMock;
|
|
19
22
|
mcp?: MCPMock;
|
|
20
23
|
a2a?: A2AMock;
|
|
21
24
|
vector?: VectorMock;
|
|
25
|
+
agui?: AGUIMock;
|
|
22
26
|
start(): Promise<void>;
|
|
23
27
|
stop(): Promise<void>;
|
|
24
28
|
reset(): void;
|
package/dist/suite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite.d.ts","names":[],"sources":["../src/suite.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"suite.d.ts","names":[],"sources":["../src/suite.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;UAWiB,gBAAA;QACT;EADS,GAAA,CAAA,EAET,cAFyB;EAAA,GAAA,CAAA,EAGzB,cAHyB;QACzB,CAAA,EAGG,iBAHH;MACA,CAAA,EAGC,eAHD;;AAEG,UAIM,SAAA,CAJN;KACF,EAIF,MAJE;EAAe,GAAA,CAAA,EAKhB,OALgB;EAGP,GAAA,CAAA,EAGT,OAHkB;EAAA,MAAA,CAAA,EAIf,UAJe;MACnB,CAAA,EAIE,QAJF;OACC,EAAA,EAIG,OAJH,CAAA,IAAA,CAAA;MACA,EAAA,EAIE,OAJF,CAAA,IAAA,CAAA;OACG,EAAA,EAAA,IAAA;;AAEA,iBAKW,eAAA,CALX,OAAA,CAAA,EAKoC,gBALpC,CAAA,EAK4D,OAL5D,CAKoE,SALpE,CAAA"}
|
package/dist/suite.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { A2AMock } from "./a2a-mock.js";
|
|
2
2
|
import { LLMock } from "./llmock.js";
|
|
3
3
|
import { MCPMock } from "./mcp-mock.js";
|
|
4
|
+
import { AGUIMock } from "./agui-mock.js";
|
|
4
5
|
import { VectorMock } from "./vector-mock.js";
|
|
5
6
|
|
|
6
7
|
//#region src/suite.ts
|
|
@@ -9,6 +10,7 @@ async function createMockSuite(options = {}) {
|
|
|
9
10
|
let mcp;
|
|
10
11
|
let a2a;
|
|
11
12
|
let vector;
|
|
13
|
+
let agui;
|
|
12
14
|
if (options.mcp) {
|
|
13
15
|
mcp = new MCPMock(options.mcp);
|
|
14
16
|
llm.mount("/mcp", mcp);
|
|
@@ -21,11 +23,16 @@ async function createMockSuite(options = {}) {
|
|
|
21
23
|
vector = new VectorMock(options.vector);
|
|
22
24
|
llm.mount("/vector", vector);
|
|
23
25
|
}
|
|
26
|
+
if (options.agui) {
|
|
27
|
+
agui = new AGUIMock(options.agui);
|
|
28
|
+
llm.mount("/agui", agui);
|
|
29
|
+
}
|
|
24
30
|
return {
|
|
25
31
|
llm,
|
|
26
32
|
mcp,
|
|
27
33
|
a2a,
|
|
28
34
|
vector,
|
|
35
|
+
agui,
|
|
29
36
|
async start() {
|
|
30
37
|
await llm.start();
|
|
31
38
|
},
|
|
@@ -37,6 +44,7 @@ async function createMockSuite(options = {}) {
|
|
|
37
44
|
if (mcp) mcp.reset();
|
|
38
45
|
if (a2a) a2a.reset();
|
|
39
46
|
if (vector) vector.reset();
|
|
47
|
+
if (agui) agui.reset();
|
|
40
48
|
}
|
|
41
49
|
};
|
|
42
50
|
}
|
package/dist/suite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suite.js","names":[],"sources":["../src/suite.ts"],"sourcesContent":["import { LLMock } from \"./llmock.js\";\nimport { MCPMock } from \"./mcp-mock.js\";\nimport { A2AMock } from \"./a2a-mock.js\";\nimport { VectorMock } from \"./vector-mock.js\";\nimport type { MockServerOptions } from \"./types.js\";\nimport type { MCPMockOptions } from \"./mcp-types.js\";\nimport type { A2AMockOptions } from \"./a2a-types.js\";\nimport type { VectorMockOptions } from \"./vector-types.js\";\n\nexport interface MockSuiteOptions {\n llm?: MockServerOptions;\n mcp?: MCPMockOptions;\n a2a?: A2AMockOptions;\n vector?: VectorMockOptions;\n}\n\nexport interface MockSuite {\n llm: LLMock;\n mcp?: MCPMock;\n a2a?: A2AMock;\n vector?: VectorMock;\n start(): Promise<void>;\n stop(): Promise<void>;\n reset(): void;\n}\n\nexport async function createMockSuite(options: MockSuiteOptions = {}): Promise<MockSuite> {\n const llm = new LLMock(options.llm);\n let mcp: MCPMock | undefined;\n let a2a: A2AMock | undefined;\n let vector: VectorMock | undefined;\n\n if (options.mcp) {\n mcp = new MCPMock(options.mcp);\n llm.mount(\"/mcp\", mcp);\n }\n\n if (options.a2a) {\n a2a = new A2AMock(options.a2a);\n llm.mount(\"/a2a\", a2a);\n }\n\n if (options.vector) {\n vector = new VectorMock(options.vector);\n llm.mount(\"/vector\", vector);\n }\n\n return {\n llm,\n mcp,\n a2a,\n vector,\n async start() {\n await llm.start();\n },\n async stop() {\n await llm.stop();\n },\n reset() {\n llm.reset();\n if (mcp) mcp.reset();\n if (a2a) a2a.reset();\n if (vector) vector.reset();\n },\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"suite.js","names":[],"sources":["../src/suite.ts"],"sourcesContent":["import { LLMock } from \"./llmock.js\";\nimport { MCPMock } from \"./mcp-mock.js\";\nimport { A2AMock } from \"./a2a-mock.js\";\nimport { VectorMock } from \"./vector-mock.js\";\nimport { AGUIMock } from \"./agui-mock.js\";\nimport type { MockServerOptions } from \"./types.js\";\nimport type { MCPMockOptions } from \"./mcp-types.js\";\nimport type { A2AMockOptions } from \"./a2a-types.js\";\nimport type { VectorMockOptions } from \"./vector-types.js\";\nimport type { AGUIMockOptions } from \"./agui-types.js\";\n\nexport interface MockSuiteOptions {\n llm?: MockServerOptions;\n mcp?: MCPMockOptions;\n a2a?: A2AMockOptions;\n vector?: VectorMockOptions;\n agui?: AGUIMockOptions;\n}\n\nexport interface MockSuite {\n llm: LLMock;\n mcp?: MCPMock;\n a2a?: A2AMock;\n vector?: VectorMock;\n agui?: AGUIMock;\n start(): Promise<void>;\n stop(): Promise<void>;\n reset(): void;\n}\n\nexport async function createMockSuite(options: MockSuiteOptions = {}): Promise<MockSuite> {\n const llm = new LLMock(options.llm);\n let mcp: MCPMock | undefined;\n let a2a: A2AMock | undefined;\n let vector: VectorMock | undefined;\n let agui: AGUIMock | undefined;\n\n if (options.mcp) {\n mcp = new MCPMock(options.mcp);\n llm.mount(\"/mcp\", mcp);\n }\n\n if (options.a2a) {\n a2a = new A2AMock(options.a2a);\n llm.mount(\"/a2a\", a2a);\n }\n\n if (options.vector) {\n vector = new VectorMock(options.vector);\n llm.mount(\"/vector\", vector);\n }\n\n if (options.agui) {\n agui = new AGUIMock(options.agui);\n llm.mount(\"/agui\", agui);\n }\n\n return {\n llm,\n mcp,\n a2a,\n vector,\n agui,\n async start() {\n await llm.start();\n },\n async stop() {\n await llm.stop();\n },\n reset() {\n llm.reset();\n if (mcp) mcp.reset();\n if (a2a) a2a.reset();\n if (vector) vector.reset();\n if (agui) agui.reset();\n },\n };\n}\n"],"mappings":";;;;;;;AA8BA,eAAsB,gBAAgB,UAA4B,EAAE,EAAsB;CACxF,MAAM,MAAM,IAAI,OAAO,QAAQ,IAAI;CACnC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;AAEJ,KAAI,QAAQ,KAAK;AACf,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,MAAI,MAAM,QAAQ,IAAI;;AAGxB,KAAI,QAAQ,KAAK;AACf,QAAM,IAAI,QAAQ,QAAQ,IAAI;AAC9B,MAAI,MAAM,QAAQ,IAAI;;AAGxB,KAAI,QAAQ,QAAQ;AAClB,WAAS,IAAI,WAAW,QAAQ,OAAO;AACvC,MAAI,MAAM,WAAW,OAAO;;AAG9B,KAAI,QAAQ,MAAM;AAChB,SAAO,IAAI,SAAS,QAAQ,KAAK;AACjC,MAAI,MAAM,SAAS,KAAK;;AAG1B,QAAO;EACL;EACA;EACA;EACA;EACA;EACA,MAAM,QAAQ;AACZ,SAAM,IAAI,OAAO;;EAEnB,MAAM,OAAO;AACX,SAAM,IAAI,MAAM;;EAElB,QAAQ;AACN,OAAI,OAAO;AACX,OAAI,IAAK,KAAI,OAAO;AACpB,OAAI,IAAK,KAAI,OAAO;AACpB,OAAI,OAAQ,QAAO,OAAO;AAC1B,OAAI,KAAM,MAAK,OAAO;;EAEzB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const require_helpers = require('./helpers.cjs');
|
|
2
|
+
const require_router = require('./router.cjs');
|
|
3
|
+
const require_sse_writer = require('./sse-writer.cjs');
|
|
4
|
+
const require_chaos = require('./chaos.cjs');
|
|
5
|
+
const require_recorder = require('./recorder.cjs');
|
|
6
|
+
|
|
7
|
+
//#region src/transcription.ts
|
|
8
|
+
/**
|
|
9
|
+
* Extract a named field value from a multipart/form-data body.
|
|
10
|
+
* Lightweight parser — scans for Content-Disposition headers
|
|
11
|
+
* to find simple string field values.
|
|
12
|
+
*/
|
|
13
|
+
function extractFormField(raw, fieldName) {
|
|
14
|
+
const pattern = new RegExp(`Content-Disposition:\\s*form-data;[^\\r\\n]*name="${fieldName}"[^\\r\\n]*\\r\\n\\r\\n([^\\r\\n]*)`, "i");
|
|
15
|
+
return raw.match(pattern)?.[1];
|
|
16
|
+
}
|
|
17
|
+
async function handleTranscription(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
18
|
+
setCorsHeaders(res);
|
|
19
|
+
const path = req.url ?? "/v1/audio/transcriptions";
|
|
20
|
+
const method = req.method ?? "POST";
|
|
21
|
+
const model = extractFormField(raw, "model") ?? "whisper-1";
|
|
22
|
+
const responseFormat = extractFormField(raw, "response_format") ?? "json";
|
|
23
|
+
const syntheticReq = {
|
|
24
|
+
model,
|
|
25
|
+
messages: [],
|
|
26
|
+
_endpointType: "transcription"
|
|
27
|
+
};
|
|
28
|
+
const testId = require_helpers.getTestId(req);
|
|
29
|
+
const fixture = require_router.matchFixture(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
30
|
+
if (fixture) journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
31
|
+
if (require_chaos.applyChaos(res, fixture, defaults.chaos, req.headers, journal, {
|
|
32
|
+
method,
|
|
33
|
+
path,
|
|
34
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
35
|
+
body: syntheticReq
|
|
36
|
+
}, defaults.registry, defaults.logger)) return;
|
|
37
|
+
if (!fixture) {
|
|
38
|
+
if (defaults.record) {
|
|
39
|
+
if (await require_recorder.proxyAndRecord(req, res, syntheticReq, "openai", req.url ?? "/v1/audio/transcriptions", fixtures, defaults, raw)) {
|
|
40
|
+
journal.add({
|
|
41
|
+
method,
|
|
42
|
+
path,
|
|
43
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
44
|
+
body: syntheticReq,
|
|
45
|
+
response: {
|
|
46
|
+
status: res.statusCode ?? 200,
|
|
47
|
+
fixture: null
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const strictStatus = defaults.strict ? 503 : 404;
|
|
54
|
+
const strictMessage = defaults.strict ? "Strict mode: no fixture matched" : "No fixture matched";
|
|
55
|
+
journal.add({
|
|
56
|
+
method,
|
|
57
|
+
path,
|
|
58
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
59
|
+
body: syntheticReq,
|
|
60
|
+
response: {
|
|
61
|
+
status: strictStatus,
|
|
62
|
+
fixture: null
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
|
|
66
|
+
message: strictMessage,
|
|
67
|
+
type: "invalid_request_error",
|
|
68
|
+
code: "no_fixture_match"
|
|
69
|
+
} }));
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const response = fixture.response;
|
|
73
|
+
if (require_helpers.isErrorResponse(response)) {
|
|
74
|
+
const status = response.status ?? 500;
|
|
75
|
+
journal.add({
|
|
76
|
+
method,
|
|
77
|
+
path,
|
|
78
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
79
|
+
body: syntheticReq,
|
|
80
|
+
response: {
|
|
81
|
+
status,
|
|
82
|
+
fixture
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
require_sse_writer.writeErrorResponse(res, status, JSON.stringify(response));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (!require_helpers.isTranscriptionResponse(response)) {
|
|
89
|
+
journal.add({
|
|
90
|
+
method,
|
|
91
|
+
path,
|
|
92
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
93
|
+
body: syntheticReq,
|
|
94
|
+
response: {
|
|
95
|
+
status: 500,
|
|
96
|
+
fixture
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
100
|
+
message: "Fixture response is not a transcription type",
|
|
101
|
+
type: "server_error"
|
|
102
|
+
} }));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
journal.add({
|
|
106
|
+
method,
|
|
107
|
+
path,
|
|
108
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
109
|
+
body: syntheticReq,
|
|
110
|
+
response: {
|
|
111
|
+
status: 200,
|
|
112
|
+
fixture
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
const t = response.transcription;
|
|
116
|
+
if (responseFormat === "verbose_json" || t.words != null || t.segments != null) {
|
|
117
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
118
|
+
res.end(JSON.stringify({
|
|
119
|
+
task: "transcribe",
|
|
120
|
+
language: t.language ?? "english",
|
|
121
|
+
duration: t.duration ?? 0,
|
|
122
|
+
text: t.text,
|
|
123
|
+
words: t.words ?? [],
|
|
124
|
+
segments: t.segments ?? []
|
|
125
|
+
}));
|
|
126
|
+
} else {
|
|
127
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
128
|
+
res.end(JSON.stringify({ text: t.text }));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
exports.handleTranscription = handleTranscription;
|
|
134
|
+
//# sourceMappingURL=transcription.cjs.map
|