@copilotkit/aimock 1.37.3 → 1.38.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 +35 -0
- package/README.md +27 -9
- package/dist/agui-recorder.cjs +6 -0
- package/dist/agui-recorder.cjs.map +1 -1
- package/dist/agui-recorder.d.cts.map +1 -1
- package/dist/agui-recorder.d.ts.map +1 -1
- package/dist/agui-recorder.js +6 -0
- package/dist/agui-recorder.js.map +1 -1
- package/dist/agui-types.d.ts.map +1 -1
- package/dist/api-key-auth.cjs +166 -0
- package/dist/api-key-auth.cjs.map +1 -0
- package/dist/api-key-auth.d.cts +17 -0
- package/dist/api-key-auth.d.cts.map +1 -0
- package/dist/api-key-auth.d.ts +17 -0
- package/dist/api-key-auth.d.ts.map +1 -0
- package/dist/api-key-auth.js +158 -0
- package/dist/api-key-auth.js.map +1 -0
- package/dist/cli.cjs +4 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/config-loader.cjs +4 -2
- package/dist/config-loader.cjs.map +1 -1
- package/dist/config-loader.d.cts +2 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts +2 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +5 -3
- package/dist/config-loader.js.map +1 -1
- package/dist/fal-audio.cjs +2 -0
- 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 +2 -0
- package/dist/fal-audio.js.map +1 -1
- package/dist/fal.cjs +4 -1
- 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 +4 -1
- package/dist/fal.js.map +1 -1
- package/dist/fixture-loader.cjs +0 -0
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts +3 -1
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts +3 -1
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +0 -0
- package/dist/fixture-loader.js.map +1 -1
- package/dist/grok-video.cjs +9 -2
- package/dist/grok-video.cjs.map +1 -1
- package/dist/grok-video.js +10 -3
- package/dist/grok-video.js.map +1 -1
- package/dist/helpers.cjs +16 -22
- 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 +16 -21
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/llmock.cjs +14 -3
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +4 -2
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +4 -2
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +15 -5
- package/dist/llmock.js.map +1 -1
- package/dist/messages.cjs +4 -4
- 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 +4 -4
- package/dist/messages.js.map +1 -1
- package/dist/openrouter-chat.cjs +333 -0
- package/dist/openrouter-chat.cjs.map +1 -0
- package/dist/openrouter-chat.js +325 -0
- package/dist/openrouter-chat.js.map +1 -0
- package/dist/openrouter-video.cjs +24 -7
- package/dist/openrouter-video.cjs.map +1 -1
- package/dist/openrouter-video.d.cts.map +1 -1
- package/dist/openrouter-video.d.ts.map +1 -1
- package/dist/openrouter-video.js +25 -8
- package/dist/openrouter-video.js.map +1 -1
- package/dist/provider-auth.cjs +20 -0
- package/dist/provider-auth.cjs.map +1 -1
- package/dist/provider-auth.js +20 -1
- package/dist/provider-auth.js.map +1 -1
- package/dist/recorder.cjs +51 -9
- 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 +52 -12
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +200 -89
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts +18 -3
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts +18 -3
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +199 -90
- package/dist/responses.js.map +1 -1
- package/dist/router.cjs +41 -6
- 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 +41 -7
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +156 -66
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +157 -68
- package/dist/server.js.map +1 -1
- package/dist/sse-writer.cjs +3 -0
- package/dist/sse-writer.cjs.map +1 -1
- package/dist/sse-writer.d.cts +8 -0
- package/dist/sse-writer.d.cts.map +1 -1
- package/dist/sse-writer.d.ts +8 -0
- package/dist/sse-writer.d.ts.map +1 -1
- package/dist/sse-writer.js +3 -0
- package/dist/sse-writer.js.map +1 -1
- package/dist/stream-collapse.cjs +26 -0
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +7 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +7 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +26 -0
- package/dist/stream-collapse.js.map +1 -1
- package/dist/transcription.cjs +49 -2
- 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 +50 -3
- package/dist/transcription.js.map +1 -1
- package/dist/types.d.cts +202 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +202 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.cts.map +1 -1
- package/dist/veo-video.cjs +9 -2
- package/dist/veo-video.cjs.map +1 -1
- package/dist/veo-video.js +10 -3
- package/dist/veo-video.js.map +1 -1
- package/dist/ws-realtime.cjs +306 -57
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts +1 -0
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts +1 -0
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +307 -58
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +11 -6
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +12 -7
- package/dist/ws-responses.js.map +1 -1
- package/package.json +1 -1
- package/skills/write-fixtures/SKILL.md +81 -47
package/dist/recorder.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.cts","names":[],"sources":["../src/recorder.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"recorder.d.cts","names":[],"sources":["../src/recorder.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UAkMiB,qBAAA;;;QAGT;;UAGS,YAAA;;;;;;;;;;;;;;;;;;mCAkBkB,oCAAoC;;;;;;;;;;;;;;;;;;;;;;KAuB3D,YAAA;;;;;;;;;;;;;;;iBA6MU,cAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yBACD,oCACI,+CAEH;WAEC;UACD;2BACiB,0BAA0B;+BAG3C,eACT,QAAQ"}
|
package/dist/recorder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","names":[],"sources":["../src/recorder.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","names":[],"sources":["../src/recorder.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UAkMiB,qBAAA;;;QAGT;;UAGS,YAAA;;;;;;;;;;;;;;;;;;mCAkBkB,oCAAoC;;;;;;;;;;;;;;;;;;;;;;KAuB3D,YAAA;;;;;;;;;;;;;;;iBA6MU,cAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,yBACD,oCACI,+CAEH;WAEC;UACD;2BACiB,0BAA0B;+BAG3C,eACT,QAAQ"}
|
package/dist/recorder.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DEFAULT_TEST_ID } from "./constants.js";
|
|
2
2
|
import { normalizeModelName } from "./model-utils.js";
|
|
3
|
+
import { isAuthenticatedRequest, isRecognizedApiKeyHeader } from "./api-key-auth.js";
|
|
3
4
|
import { getTestId, slugifyContext, slugifyTestId } from "./helpers.js";
|
|
4
|
-
import { getLastMessageByRole, getTextContent } from "./router.js";
|
|
5
|
+
import { currentTurnHasToolResult, getLastMessageByRole, getTextContent } from "./router.js";
|
|
5
6
|
import { writeErrorResponse } from "./sse-writer.js";
|
|
6
7
|
import { capturedRedactedData, collapseStreamingResponse } from "./stream-collapse.js";
|
|
7
8
|
import { resolveUpstreamUrl } from "./url.js";
|
|
8
|
-
import { applyProviderAuth } from "./provider-auth.js";
|
|
9
|
+
import { applyConfiguredProviderAuth, applyProviderAuth } from "./provider-auth.js";
|
|
9
10
|
import * as http$1 from "node:http";
|
|
10
11
|
import * as crypto$1 from "node:crypto";
|
|
11
12
|
import * as https from "node:https";
|
|
@@ -14,6 +15,16 @@ import * as path from "node:path";
|
|
|
14
15
|
import { StringDecoder } from "node:string_decoder";
|
|
15
16
|
|
|
16
17
|
//#region src/recorder.ts
|
|
18
|
+
/** True when an SSE frame completes an OpenAI stream. */
|
|
19
|
+
function isTerminalSSEFrame(frame) {
|
|
20
|
+
const data = frame.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n").trim();
|
|
21
|
+
if (data === "[DONE]") return true;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(data).type === "transcript.text.done";
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
17
28
|
/** Headers to strip when proxying — hop-by-hop (RFC 2616 §13.5.1) + client-set. */
|
|
18
29
|
/**
|
|
19
30
|
* Default ceiling (bytes) for the in-memory proxy-path buffer. Chosen well
|
|
@@ -97,11 +108,30 @@ function buildForwardHeaders(req) {
|
|
|
97
108
|
const out = {};
|
|
98
109
|
for (const [name, val] of Object.entries(req.headers)) {
|
|
99
110
|
const lower = name.toLowerCase();
|
|
100
|
-
if (val === void 0 || STRIP_HEADERS.has(lower) || lower.startsWith("x-aimock-chaos-")) continue;
|
|
111
|
+
if (val === void 0 || STRIP_HEADERS.has(lower) || lower.startsWith("x-aimock-chaos-") || isAuthenticatedRequest(req) && isRecognizedApiKeyHeader(lower)) continue;
|
|
101
112
|
out[name] = Array.isArray(val) ? val.join(", ") : val;
|
|
102
113
|
}
|
|
103
114
|
return out;
|
|
104
115
|
}
|
|
116
|
+
/** Remove every casing of a header from an egress map. */
|
|
117
|
+
function removeForwardHeader(headers, name) {
|
|
118
|
+
const lowerName = name.toLowerCase();
|
|
119
|
+
for (const key of Object.keys(headers)) if (key.toLowerCase() === lowerName) delete headers[key];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Construct the only safe egress map when inbound access control is enabled.
|
|
123
|
+
* Test credentials are always removed; a static configured provider credential
|
|
124
|
+
* is mandatory so an accepted test credential can never become an upstream one.
|
|
125
|
+
*/
|
|
126
|
+
function prepareEgressHeaders(req, target, providerKey, configuredKey) {
|
|
127
|
+
const headers = buildForwardHeaders(req);
|
|
128
|
+
if (!isAuthenticatedRequest(req)) {
|
|
129
|
+
applyProviderAuth(headers, target, providerKey, configuredKey);
|
|
130
|
+
return headers;
|
|
131
|
+
}
|
|
132
|
+
for (const name of Object.keys(headers)) if (isRecognizedApiKeyHeader(name)) delete headers[name];
|
|
133
|
+
return configuredKey && applyConfiguredProviderAuth(headers, target, providerKey, configuredKey) ? headers : void 0;
|
|
134
|
+
}
|
|
105
135
|
/**
|
|
106
136
|
* Make an arbitrary string safe to set as an HTTP header value. Node's
|
|
107
137
|
* `res.setHeader` throws ERR_INVALID_CHAR on anything outside Latin-1 (plus
|
|
@@ -230,8 +260,14 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
|
|
|
230
260
|
return "relayed";
|
|
231
261
|
}
|
|
232
262
|
defaults.logger.warn(`NO FIXTURE MATCH — proxying to ${upstreamUrl}${pathname}`);
|
|
233
|
-
const forwardHeaders =
|
|
234
|
-
|
|
263
|
+
const forwardHeaders = prepareEgressHeaders(req, target, providerKey, record.providerKeys?.[lookupKey]);
|
|
264
|
+
if (!forwardHeaders) {
|
|
265
|
+
writeErrorResponse(res, 502, JSON.stringify({ error: {
|
|
266
|
+
message: "No configured provider credential",
|
|
267
|
+
type: "proxy_error"
|
|
268
|
+
} }));
|
|
269
|
+
return "relayed";
|
|
270
|
+
}
|
|
235
271
|
const requestBody = rawBody ?? JSON.stringify(request);
|
|
236
272
|
let upstreamStatus;
|
|
237
273
|
let upstreamHeaders;
|
|
@@ -318,7 +354,8 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
|
|
|
318
354
|
if (collapsed.truncated) defaults.logger.warn("Bedrock EventStream: CRC mismatch — response may be truncated");
|
|
319
355
|
if (collapsed.droppedChunks && collapsed.droppedChunks > 0) defaults.logger.warn(`${collapsed.droppedChunks} chunk(s) dropped during stream collapse${collapsed.firstDroppedSample ? ` — first: ${collapsed.firstDroppedSample}` : ""}`);
|
|
320
356
|
if (collapsed.harmonyUnparsed) defaults.logger.warn(`Harmony tokens present but unparseable — content preserved verbatim${collapsed.harmonyNote ? ` (${collapsed.harmonyNote})` : ""}`);
|
|
321
|
-
if (collapsed.
|
|
357
|
+
if (collapsed.transcription) fixtureResponse = { transcription: collapsed.transcription };
|
|
358
|
+
else if (collapsed.audioB64) {
|
|
322
359
|
const audioToolCallsSpread = collapsed.toolCalls && collapsed.toolCalls.length > 0 ? { toolCalls: collapsed.toolCalls.map((tc) => ({
|
|
323
360
|
...tc,
|
|
324
361
|
name: tc.name ?? "",
|
|
@@ -411,7 +448,7 @@ async function proxyAndRecord(req, res, request, providerKey, pathname, fixtures
|
|
|
411
448
|
json: parsedResponse,
|
|
412
449
|
status: upstreamStatus
|
|
413
450
|
};
|
|
414
|
-
} else fixtureResponse = buildFixtureResponse(parsedResponse, upstreamStatus, defaults.logger);
|
|
451
|
+
} else fixtureResponse = buildFixtureResponse(parsedResponse, upstreamStatus, defaults.logger, request);
|
|
415
452
|
}
|
|
416
453
|
if (clientDisconnected) {
|
|
417
454
|
if (!sawDone) {
|
|
@@ -644,7 +681,7 @@ function makeUpstreamRequest(target, headers, body, clientRes, method = "POST",
|
|
|
644
681
|
const frame = parts[fi].trim();
|
|
645
682
|
if (frame.length > 0) {
|
|
646
683
|
frameTimestamps.push(Date.now());
|
|
647
|
-
if (frame
|
|
684
|
+
if (isTerminalSSEFrame(frame)) sawDone = true;
|
|
648
685
|
}
|
|
649
686
|
}
|
|
650
687
|
if (!bufferTruncated) frameBuffer = parts[parts.length - 1];
|
|
@@ -737,7 +774,7 @@ function toToolCallArguments(raw) {
|
|
|
737
774
|
* Detect the response format from the parsed upstream JSON and convert
|
|
738
775
|
* it into an aimock FixtureResponse.
|
|
739
776
|
*/
|
|
740
|
-
function buildFixtureResponse(parsed, status, logger) {
|
|
777
|
+
function buildFixtureResponse(parsed, status, logger, request) {
|
|
741
778
|
if (parsed === null || parsed === void 0) return {
|
|
742
779
|
error: {
|
|
743
780
|
message: "Upstream returned non-JSON response",
|
|
@@ -790,10 +827,13 @@ function buildFixtureResponse(parsed, status, logger) {
|
|
|
790
827
|
if (images.length === 1) return { image: images[0] };
|
|
791
828
|
return { images };
|
|
792
829
|
}
|
|
793
|
-
|
|
830
|
+
const isTranscriptionRequest = request?._endpointType === "transcription" || request?._endpointType === "translation";
|
|
831
|
+
if (typeof obj.text === "string" && (isTranscriptionRequest || obj.task === "transcribe" || obj.language !== void 0 && obj.duration !== void 0) && !("choices" in obj) && !("candidates" in obj) && !("object" in obj) && !("message" in obj) && !("outputs" in obj)) return { transcription: {
|
|
794
832
|
text: obj.text,
|
|
795
833
|
...obj.language ? { language: String(obj.language) } : {},
|
|
834
|
+
...Array.isArray(obj.languages) ? { languages: obj.languages.filter((language) => typeof language === "object" && language !== null && typeof language.code === "string").map((language) => ({ code: language.code })) } : {},
|
|
796
835
|
...obj.duration !== void 0 ? { duration: Number(obj.duration) } : {},
|
|
836
|
+
...obj.usage && typeof obj.usage === "object" ? { usage: obj.usage } : {},
|
|
797
837
|
...Array.isArray(obj.words) ? { words: obj.words } : {},
|
|
798
838
|
...Array.isArray(obj.segments) ? { segments: obj.segments } : {}
|
|
799
839
|
} };
|
|
@@ -1101,7 +1141,7 @@ function buildFixtureMatch(request, recordConfig) {
|
|
|
1101
1141
|
const messages = request.messages ?? [];
|
|
1102
1142
|
if (messages.length > 0 && (request._endpointType === "chat" || request._endpointType === void 0)) {
|
|
1103
1143
|
match.turnIndex = messages.filter((m) => m.role === "assistant").length;
|
|
1104
|
-
match.hasToolResult = messages
|
|
1144
|
+
match.hasToolResult = currentTurnHasToolResult(messages);
|
|
1105
1145
|
}
|
|
1106
1146
|
if (request._context) match.context = request._context;
|
|
1107
1147
|
return match;
|
|
@@ -1120,5 +1160,5 @@ function buildFixtureMetadata(request) {
|
|
|
1120
1160
|
}
|
|
1121
1161
|
|
|
1122
1162
|
//#endregion
|
|
1123
|
-
export { buildFixtureMatch, buildForwardHeaders, clampTimeout, persistFixture, proxyAndRecord, sanitizeHeaderValue };
|
|
1163
|
+
export { buildFixtureMatch, buildForwardHeaders, clampTimeout, persistFixture, prepareEgressHeaders, proxyAndRecord, removeForwardHeader, sanitizeHeaderValue };
|
|
1124
1164
|
//# sourceMappingURL=recorder.js.map
|