@copilotkit/aimock 1.43.0 → 1.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +46 -0
- package/README.md +14 -2
- package/dist/agui-handler.d.ts.map +1 -1
- package/dist/aimock-cli.cjs +31 -5
- package/dist/aimock-cli.cjs.map +1 -1
- package/dist/aimock-cli.d.cts.map +1 -1
- package/dist/aimock-cli.d.ts.map +1 -1
- package/dist/aimock-cli.js +31 -5
- package/dist/aimock-cli.js.map +1 -1
- package/dist/bedrock-converse.cjs +344 -43
- 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 +345 -44
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +195 -42
- 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 +196 -43
- package/dist/bedrock.js.map +1 -1
- package/dist/chaos.cjs +9 -5
- package/dist/chaos.cjs.map +1 -1
- package/dist/chaos.d.cts.map +1 -1
- package/dist/chaos.d.ts.map +1 -1
- package/dist/chaos.js +10 -7
- package/dist/chaos.js.map +1 -1
- package/dist/cli.cjs +238 -9
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +242 -13
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +159 -72
- 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 +160 -73
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.cjs +63 -5
- package/dist/config-loader.cjs.map +1 -1
- package/dist/config-loader.d.cts +37 -4
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts +37 -4
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +63 -5
- package/dist/config-loader.js.map +1 -1
- package/dist/constants.cjs +8 -0
- package/dist/constants.cjs.map +1 -1
- package/dist/constants.d.cts +6 -2
- package/dist/constants.d.ts +6 -2
- package/dist/constants.js +8 -1
- package/dist/constants.js.map +1 -1
- package/dist/echo-text.cjs +65 -0
- package/dist/echo-text.cjs.map +1 -0
- package/dist/echo-text.d.cts +22 -0
- package/dist/echo-text.d.cts.map +1 -0
- package/dist/echo-text.d.ts +22 -0
- package/dist/echo-text.d.ts.map +1 -0
- package/dist/echo-text.js +65 -0
- package/dist/echo-text.js.map +1 -0
- package/dist/embeddings.cjs +18 -1
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.d.cts +1 -1
- package/dist/embeddings.d.cts.map +1 -1
- package/dist/embeddings.d.ts +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +18 -1
- package/dist/embeddings.js.map +1 -1
- package/dist/fakes-plugin.cjs +131 -0
- package/dist/fakes-plugin.cjs.map +1 -0
- package/dist/fakes-plugin.d.cts +23 -0
- package/dist/fakes-plugin.d.cts.map +1 -0
- package/dist/fakes-plugin.d.ts +23 -0
- package/dist/fakes-plugin.d.ts.map +1 -0
- package/dist/fakes-plugin.js +127 -0
- package/dist/fakes-plugin.js.map +1 -0
- package/dist/files.cjs +9 -11
- package/dist/files.cjs.map +1 -1
- package/dist/files.d.cts.map +1 -1
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +10 -13
- package/dist/files.js.map +1 -1
- package/dist/fine-tuning.cjs +1 -19
- package/dist/fine-tuning.cjs.map +1 -1
- package/dist/fine-tuning.d.cts.map +1 -1
- package/dist/fine-tuning.d.ts.map +1 -1
- package/dist/fine-tuning.js +2 -20
- package/dist/fine-tuning.js.map +1 -1
- package/dist/fixture-loader-services.cjs +116 -0
- package/dist/fixture-loader-services.cjs.map +1 -0
- package/dist/fixture-loader-services.d.cts +48 -0
- package/dist/fixture-loader-services.d.cts.map +1 -0
- package/dist/fixture-loader-services.d.ts +48 -0
- package/dist/fixture-loader-services.d.ts.map +1 -0
- package/dist/fixture-loader-services.js +114 -0
- package/dist/fixture-loader-services.js.map +1 -0
- package/dist/fixture-loader.cjs +552 -29
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts +140 -2
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts +140 -2
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +542 -31
- package/dist/fixture-loader.js.map +1 -1
- package/dist/gemini-embeddings.cjs +42 -2
- package/dist/gemini-embeddings.cjs.map +1 -1
- package/dist/gemini-embeddings.js +43 -3
- package/dist/gemini-embeddings.js.map +1 -1
- package/dist/gemini-interactions.cjs +288 -52
- 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 +289 -53
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +234 -38
- 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 +235 -39
- package/dist/gemini.js.map +1 -1
- package/dist/helpers.cjs +1157 -12
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +85 -4
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts +85 -4
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +1113 -14
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +3 -2
- package/dist/images.cjs.map +1 -1
- package/dist/images.js +3 -2
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +39 -1
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +11 -4
- package/dist/jest.cjs +43 -14
- package/dist/jest.cjs.map +1 -1
- package/dist/jest.d.cts +47 -5
- package/dist/jest.d.cts.map +1 -1
- package/dist/jest.d.ts +47 -5
- package/dist/jest.d.ts.map +1 -1
- package/dist/jest.js +45 -16
- package/dist/jest.js.map +1 -1
- package/dist/journal.cjs +155 -13
- package/dist/journal.cjs.map +1 -1
- package/dist/journal.d.cts +54 -4
- package/dist/journal.d.cts.map +1 -1
- package/dist/journal.d.ts +54 -4
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +155 -13
- package/dist/journal.js.map +1 -1
- package/dist/live-sanitize.cjs +4 -32
- package/dist/live-sanitize.cjs.map +1 -1
- package/dist/live-sanitize.js +4 -32
- package/dist/live-sanitize.js.map +1 -1
- package/dist/llmock.cjs +204 -39
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +51 -1
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +51 -1
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +206 -41
- package/dist/llmock.js.map +1 -1
- package/dist/mcp-fakes-mount.cjs +217 -0
- package/dist/mcp-fakes-mount.cjs.map +1 -0
- package/dist/mcp-fakes-mount.js +211 -0
- package/dist/mcp-fakes-mount.js.map +1 -0
- package/dist/mcp-fakes-report.cjs +111 -0
- package/dist/mcp-fakes-report.cjs.map +1 -0
- package/dist/mcp-fakes-report.d.cts +40 -0
- package/dist/mcp-fakes-report.d.cts.map +1 -0
- package/dist/mcp-fakes-report.d.ts +40 -0
- package/dist/mcp-fakes-report.d.ts.map +1 -0
- package/dist/mcp-fakes-report.js +107 -0
- package/dist/mcp-fakes-report.js.map +1 -0
- package/dist/mcp-fakes.cjs +1942 -0
- package/dist/mcp-fakes.cjs.map +1 -0
- package/dist/mcp-fakes.d.cts +504 -0
- package/dist/mcp-fakes.d.cts.map +1 -0
- package/dist/mcp-fakes.d.ts +504 -0
- package/dist/mcp-fakes.d.ts.map +1 -0
- package/dist/mcp-fakes.js +1937 -0
- package/dist/mcp-fakes.js.map +1 -0
- package/dist/mcp-handler.cjs +534 -27
- package/dist/mcp-handler.cjs.map +1 -1
- package/dist/mcp-handler.d.cts +49 -0
- package/dist/mcp-handler.d.cts.map +1 -0
- package/dist/mcp-handler.d.ts +49 -0
- package/dist/mcp-handler.d.ts.map +1 -0
- package/dist/mcp-handler.js +530 -28
- package/dist/mcp-handler.js.map +1 -1
- package/dist/mcp-mock.cjs +326 -47
- package/dist/mcp-mock.cjs.map +1 -1
- package/dist/mcp-mock.d.cts +97 -1
- package/dist/mcp-mock.d.cts.map +1 -1
- package/dist/mcp-mock.d.ts +97 -1
- package/dist/mcp-mock.d.ts.map +1 -1
- package/dist/mcp-mock.js +327 -48
- package/dist/mcp-mock.js.map +1 -1
- package/dist/mcp-recorder.cjs +1224 -0
- package/dist/mcp-recorder.cjs.map +1 -0
- package/dist/mcp-recorder.d.cts +108 -0
- package/dist/mcp-recorder.d.cts.map +1 -0
- package/dist/mcp-recorder.d.ts +108 -0
- package/dist/mcp-recorder.d.ts.map +1 -0
- package/dist/mcp-recorder.js +1215 -0
- package/dist/mcp-recorder.js.map +1 -0
- package/dist/mcp-stub.cjs +5 -1
- package/dist/mcp-stub.d.cts +3 -1
- package/dist/mcp-stub.d.ts +3 -1
- package/dist/mcp-stub.js +3 -1
- package/dist/mcp-types.d.cts +6 -0
- package/dist/mcp-types.d.ts +6 -0
- package/dist/message-text.cjs +192 -0
- package/dist/message-text.cjs.map +1 -0
- package/dist/message-text.d.cts +31 -0
- package/dist/message-text.d.cts.map +1 -0
- package/dist/message-text.d.ts +31 -0
- package/dist/message-text.d.ts.map +1 -0
- package/dist/message-text.js +184 -0
- package/dist/message-text.js.map +1 -0
- package/dist/messages.cjs +400 -56
- 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 +401 -58
- package/dist/messages.js.map +1 -1
- package/dist/metrics.cjs +46 -66
- package/dist/metrics.cjs.map +1 -1
- package/dist/metrics.d.cts +14 -6
- package/dist/metrics.d.cts.map +1 -1
- package/dist/metrics.d.ts +14 -6
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +32 -40
- package/dist/metrics.js.map +1 -1
- package/dist/misbehavior.cjs +1523 -0
- package/dist/misbehavior.cjs.map +1 -0
- package/dist/misbehavior.d.cts +43 -0
- package/dist/misbehavior.d.cts.map +1 -0
- package/dist/misbehavior.d.ts +43 -0
- package/dist/misbehavior.d.ts.map +1 -0
- package/dist/misbehavior.js +1511 -0
- package/dist/misbehavior.js.map +1 -0
- package/dist/ollama.cjs +315 -113
- 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 +316 -114
- package/dist/ollama.js.map +1 -1
- package/dist/openapi.cjs +3405 -0
- package/dist/openapi.cjs.map +1 -0
- package/dist/openapi.d.cts +30 -0
- package/dist/openapi.d.cts.map +1 -0
- package/dist/openapi.d.ts +30 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +3404 -0
- package/dist/openapi.js.map +1 -0
- package/dist/openrouter-video.cjs +4 -4
- 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 +4 -4
- package/dist/openrouter-video.js.map +1 -1
- package/dist/record-sanitize.cjs +231 -0
- package/dist/record-sanitize.cjs.map +1 -0
- package/dist/record-sanitize.js +224 -0
- package/dist/record-sanitize.js.map +1 -0
- package/dist/recorder.cjs +115 -6
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts +2 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts +2 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +116 -8
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +701 -166
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts +5 -13
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts +5 -13
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +699 -169
- package/dist/responses.js.map +1 -1
- package/dist/route-registry.cjs +951 -0
- package/dist/route-registry.cjs.map +1 -0
- package/dist/route-registry.d.cts +33 -0
- package/dist/route-registry.d.cts.map +1 -0
- package/dist/route-registry.d.ts +33 -0
- package/dist/route-registry.d.ts.map +1 -0
- package/dist/route-registry.js +866 -0
- package/dist/route-registry.js.map +1 -0
- package/dist/router.cjs +24 -2
- 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 +25 -4
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +1159 -264
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +4 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +4 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1067 -172
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +4 -2
- package/dist/speech.cjs.map +1 -1
- package/dist/speech.js +4 -2
- package/dist/speech.js.map +1 -1
- package/dist/stream-collapse.cjs +236 -34
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +39 -4
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +39 -4
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +235 -35
- package/dist/stream-collapse.js.map +1 -1
- package/dist/suite.cjs +1 -1
- package/dist/suite.js +1 -1
- package/dist/transcription.cjs +2 -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 +2 -2
- package/dist/transcription.js.map +1 -1
- package/dist/types.cjs +18 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +516 -5
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +516 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/dist/validate-cli.cjs +123 -33
- package/dist/validate-cli.cjs.map +1 -1
- package/dist/validate-cli.js +125 -35
- package/dist/validate-cli.js.map +1 -1
- package/dist/vector-stores.cjs +1180 -0
- package/dist/vector-stores.cjs.map +1 -0
- package/dist/vector-stores.d.cts +106 -0
- package/dist/vector-stores.d.cts.map +1 -0
- package/dist/vector-stores.d.ts +106 -0
- package/dist/vector-stores.d.ts.map +1 -0
- package/dist/vector-stores.js +1164 -0
- package/dist/vector-stores.js.map +1 -0
- package/dist/vector-types.d.cts.map +1 -1
- package/dist/version.cjs +45 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.js +44 -0
- package/dist/version.js.map +1 -0
- package/dist/video.cjs +19 -0
- package/dist/video.cjs.map +1 -1
- package/dist/video.d.cts.map +1 -1
- package/dist/video.d.ts.map +1 -1
- package/dist/video.js +19 -0
- package/dist/video.js.map +1 -1
- package/dist/vitest.cjs +77 -16
- package/dist/vitest.cjs.map +1 -1
- package/dist/vitest.d.cts +38 -5
- package/dist/vitest.d.cts.map +1 -1
- package/dist/vitest.d.ts +38 -5
- package/dist/vitest.d.ts.map +1 -1
- package/dist/vitest.js +78 -17
- package/dist/vitest.js.map +1 -1
- package/dist/watcher.cjs +6 -2
- package/dist/watcher.cjs.map +1 -1
- package/dist/watcher.js +6 -2
- package/dist/watcher.js.map +1 -1
- package/dist/ws-gemini-live.cjs +210 -101
- package/dist/ws-gemini-live.cjs.map +1 -1
- package/dist/ws-gemini-live.d.cts +9 -3
- package/dist/ws-gemini-live.d.cts.map +1 -1
- package/dist/ws-gemini-live.d.ts +9 -3
- package/dist/ws-gemini-live.d.ts.map +1 -1
- package/dist/ws-gemini-live.js +211 -102
- package/dist/ws-gemini-live.js.map +1 -1
- package/dist/ws-realtime.cjs +175 -62
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts +8 -3
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts +8 -3
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +176 -63
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +121 -16
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts +8 -12
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts +8 -12
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +123 -18
- package/dist/ws-responses.js.map +1 -1
- package/package.json +13 -2
- package/skills/write-fixtures/SKILL.md +179 -21
package/dist/gemini.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_helpers = require('./helpers.cjs');
|
|
2
2
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
3
3
|
const require_chaos = require('./chaos.cjs');
|
|
4
|
+
const require_misbehavior = require('./misbehavior.cjs');
|
|
4
5
|
const require_router = require('./router.cjs');
|
|
5
6
|
const require_recorder = require('./recorder.cjs');
|
|
6
7
|
const require_interruption = require('./interruption.cjs');
|
|
@@ -29,7 +30,14 @@ function validateGeminiBody(req) {
|
|
|
29
30
|
const parts = req.systemInstruction.parts;
|
|
30
31
|
if (parts !== void 0 && parts !== null && !Array.isArray(parts)) return "systemInstruction.parts must be an array";
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
const toolsError = require_helpers.validateToolsField(req.tools);
|
|
34
|
+
if (toolsError) return toolsError;
|
|
35
|
+
if (Array.isArray(req.tools)) for (const [toolIndex, tool] of req.tools.entries()) {
|
|
36
|
+
if (!Array.isArray(tool.functionDeclarations)) continue;
|
|
37
|
+
const declarationIndex = tool.functionDeclarations.findIndex((declaration) => declaration === null);
|
|
38
|
+
if (declarationIndex !== -1) return `tools[${toolIndex}].functionDeclarations[${declarationIndex}] must not be null`;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
33
41
|
}
|
|
34
42
|
function geminiToCompletionRequest(req, model, stream) {
|
|
35
43
|
const messages = [];
|
|
@@ -108,7 +116,7 @@ function geminiToCompletionRequest(req, model, stream) {
|
|
|
108
116
|
function: {
|
|
109
117
|
name: d.name,
|
|
110
118
|
description: d.description,
|
|
111
|
-
parameters: d.parameters
|
|
119
|
+
parameters: d.parameters ?? d.parametersJsonSchema
|
|
112
120
|
}
|
|
113
121
|
}));
|
|
114
122
|
}
|
|
@@ -192,16 +200,10 @@ function buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) {
|
|
|
192
200
|
return chunks;
|
|
193
201
|
}
|
|
194
202
|
function parseToolCallPart(tc, logger) {
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
argsObj = JSON.parse(tc.arguments || "{}");
|
|
198
|
-
} catch {
|
|
199
|
-
logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
|
|
200
|
-
argsObj = {};
|
|
201
|
-
}
|
|
203
|
+
const args = require_helpers.servedToolArgs(tc, "object", logger);
|
|
202
204
|
const functionCall = {
|
|
203
205
|
name: tc.name,
|
|
204
|
-
args:
|
|
206
|
+
args: args.value
|
|
205
207
|
};
|
|
206
208
|
if (tc.id) functionCall.id = tc.id;
|
|
207
209
|
return { functionCall };
|
|
@@ -418,24 +420,24 @@ function resolveAudioInlineData(audio) {
|
|
|
418
420
|
data: audio.audio.b64Json
|
|
419
421
|
};
|
|
420
422
|
}
|
|
421
|
-
function buildGeminiAudioParts(audio, logger, effReasoning) {
|
|
423
|
+
function buildGeminiAudioParts(audio, toolCalls, logger, effReasoning) {
|
|
422
424
|
const parts = [{ inlineData: resolveAudioInlineData(audio) }];
|
|
423
425
|
if (effReasoning) parts.push({
|
|
424
426
|
text: effReasoning,
|
|
425
427
|
thought: true
|
|
426
428
|
});
|
|
427
429
|
if (audio.content) parts.push({ text: audio.content });
|
|
428
|
-
if (
|
|
430
|
+
if (toolCalls.length) parts.push(...toolCalls.map((tc) => parseToolCallPart(tc, logger)));
|
|
429
431
|
return parts;
|
|
430
432
|
}
|
|
431
|
-
function buildGeminiAudioResponse(audio, logger, effReasoning) {
|
|
433
|
+
function buildGeminiAudioResponse(audio, toolCalls, logger, effReasoning) {
|
|
432
434
|
return {
|
|
433
435
|
candidates: [{
|
|
434
436
|
content: {
|
|
435
437
|
role: "model",
|
|
436
|
-
parts: buildGeminiAudioParts(audio, logger, effReasoning)
|
|
438
|
+
parts: buildGeminiAudioParts(audio, toolCalls, logger, effReasoning)
|
|
437
439
|
},
|
|
438
|
-
finishReason:
|
|
440
|
+
finishReason: toolCalls.length ? "FUNCTION_CALL" : "STOP",
|
|
439
441
|
index: 0
|
|
440
442
|
}],
|
|
441
443
|
usageMetadata: {
|
|
@@ -445,14 +447,14 @@ function buildGeminiAudioResponse(audio, logger, effReasoning) {
|
|
|
445
447
|
}
|
|
446
448
|
};
|
|
447
449
|
}
|
|
448
|
-
function buildGeminiAudioStreamChunks(audio, logger, effReasoning) {
|
|
450
|
+
function buildGeminiAudioStreamChunks(audio, toolCalls, logger, effReasoning) {
|
|
449
451
|
return [{
|
|
450
452
|
candidates: [{
|
|
451
453
|
content: {
|
|
452
454
|
role: "model",
|
|
453
|
-
parts: buildGeminiAudioParts(audio, logger, effReasoning)
|
|
455
|
+
parts: buildGeminiAudioParts(audio, toolCalls, logger, effReasoning)
|
|
454
456
|
},
|
|
455
|
-
finishReason:
|
|
457
|
+
finishReason: toolCalls.length ? "FUNCTION_CALL" : "STOP",
|
|
456
458
|
index: 0
|
|
457
459
|
}],
|
|
458
460
|
usageMetadata: {
|
|
@@ -487,8 +489,90 @@ async function writeGeminiSSEStream(res, chunks, optionsOrLatency) {
|
|
|
487
489
|
if (!res.writableEnded) res.end();
|
|
488
490
|
return true;
|
|
489
491
|
}
|
|
492
|
+
/** Prepare native fault output once; the journal describes these exact parts. */
|
|
493
|
+
function prepareGeminiMisbehavior(plan, request, streaming, chunkSize, logger, strict) {
|
|
494
|
+
const response = plan.response;
|
|
495
|
+
const combined = require_helpers.isCombinedFixtureResponse(response);
|
|
496
|
+
if (!(combined || require_helpers.isToolCallResponse(response) || require_helpers.isTextResponse(response))) throw new Error("Applied Gemini misbehavior requires a chat response");
|
|
497
|
+
const outcome = combined && response.blocks?.length ? require_helpers.resolveFixtureBlockOutcome(response.blocks) : void 0;
|
|
498
|
+
const content = outcome?.content ?? ("content" in response ? response.content ?? "" : "");
|
|
499
|
+
const calls = outcome?.toolCalls ?? ("toolCalls" in response ? response.toolCalls ?? [] : []);
|
|
500
|
+
const overrides = require_helpers.extractOverrides(response);
|
|
501
|
+
delete overrides.usage;
|
|
502
|
+
const fault = plan.summary.fault;
|
|
503
|
+
const candidate = {
|
|
504
|
+
content: {
|
|
505
|
+
role: "model",
|
|
506
|
+
parts: []
|
|
507
|
+
},
|
|
508
|
+
index: 0
|
|
509
|
+
};
|
|
510
|
+
let chunks;
|
|
511
|
+
if (fault === "tool-args-invalid-json") {
|
|
512
|
+
const target = calls[plan.target?.index ?? 0];
|
|
513
|
+
if (!target) throw new Error("Gemini malformed-call plan requires its selected tool call");
|
|
514
|
+
chunks = [{ candidates: [{
|
|
515
|
+
index: 0,
|
|
516
|
+
finishReason: "MALFORMED_FUNCTION_CALL",
|
|
517
|
+
finishMessage: `Malformed function call: ${target.name}(${target.arguments})`
|
|
518
|
+
}] }];
|
|
519
|
+
} else if (fault === "tool-unknown-name" && !request.tools?.length) {
|
|
520
|
+
candidate.finishReason = "UNEXPECTED_TOOL_CALL";
|
|
521
|
+
chunks = [{ candidates: [candidate] }];
|
|
522
|
+
} else if (fault === "stop-length-mid-tool") {
|
|
523
|
+
candidate.content.parts = content ? [{ text: content }] : [];
|
|
524
|
+
candidate.finishReason = "MAX_TOKENS";
|
|
525
|
+
chunks = [{ candidates: [candidate] }];
|
|
526
|
+
} else if (fault === "empty-response") {
|
|
527
|
+
candidate.content.parts = [{ text: "" }];
|
|
528
|
+
candidate.finishReason = "STOP";
|
|
529
|
+
chunks = [{ candidates: [candidate] }];
|
|
530
|
+
} else if (fault === "content-filter") {
|
|
531
|
+
candidate.finishReason = "SAFETY";
|
|
532
|
+
candidate.safetyRatings = [{
|
|
533
|
+
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
|
|
534
|
+
probability: "HIGH",
|
|
535
|
+
blocked: true
|
|
536
|
+
}];
|
|
537
|
+
chunks = [{ candidates: [candidate] }];
|
|
538
|
+
} else if (fault === "reasoning-only") {
|
|
539
|
+
candidate.content.parts = [{
|
|
540
|
+
text: plan.reasoning ?? "",
|
|
541
|
+
thought: true
|
|
542
|
+
}];
|
|
543
|
+
candidate.finishReason = "MAX_TOKENS";
|
|
544
|
+
chunks = [{ candidates: [candidate] }];
|
|
545
|
+
} else {
|
|
546
|
+
const reasoning = require_helpers.resolveReasoningForModel(response.reasoning, request.model, strict, logger);
|
|
547
|
+
if (fault === "tool-unknown-name") overrides.finishReason = "stop";
|
|
548
|
+
if (combined) chunks = streaming ? buildGeminiContentWithToolCallsStreamChunks(content, calls, chunkSize, logger, reasoning, overrides, response.blocks) : [buildGeminiContentWithToolCallsResponse(content, calls, logger, reasoning, overrides, response.blocks)];
|
|
549
|
+
else if (require_helpers.isToolCallResponse(response)) chunks = streaming ? buildGeminiToolCallStreamChunks(calls, chunkSize, logger, reasoning, overrides) : [buildGeminiToolCallResponse(calls, logger, reasoning, overrides)];
|
|
550
|
+
else chunks = streaming ? buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) : [buildGeminiTextResponse(content, reasoning, overrides)];
|
|
551
|
+
}
|
|
552
|
+
const parts = chunks.flatMap((chunk) => chunk.candidates.flatMap((item) => item.content?.parts ?? []));
|
|
553
|
+
const servedToolCalls = parts.flatMap((part) => part.functionCall ? [{
|
|
554
|
+
name: part.functionCall.name,
|
|
555
|
+
arguments: JSON.stringify(part.functionCall.args),
|
|
556
|
+
...part.functionCall.id ? { id: part.functionCall.id } : {}
|
|
557
|
+
}] : []);
|
|
558
|
+
const usage = require_helpers.resolveUsage(void 0, request.messages.map((message) => typeof message.content === "string" ? message.content : (message.content ?? []).map((part) => part.text ?? "").join("")).join(""), parts.map((part) => part.text ?? (part.functionCall ? part.functionCall.name + JSON.stringify(part.functionCall.args) : "")).join(""));
|
|
559
|
+
for (const chunk of chunks) delete chunk.usageMetadata;
|
|
560
|
+
chunks[chunks.length - 1].usageMetadata = {
|
|
561
|
+
promptTokenCount: usage.prompt_tokens,
|
|
562
|
+
candidatesTokenCount: usage.completion_tokens,
|
|
563
|
+
totalTokenCount: usage.total_tokens
|
|
564
|
+
};
|
|
565
|
+
return {
|
|
566
|
+
chunks,
|
|
567
|
+
summary: {
|
|
568
|
+
...plan.summary,
|
|
569
|
+
servedToolCalls
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
}
|
|
490
573
|
async function handleGemini(req, res, raw, model, streaming, fixtures, journal, defaults, setCorsHeaders, providerKey = "gemini") {
|
|
491
574
|
const { logger } = defaults;
|
|
575
|
+
const wire = providerKey === "vertexai" ? "Vertex AI" : "Gemini";
|
|
492
576
|
setCorsHeaders(res);
|
|
493
577
|
let geminiReq;
|
|
494
578
|
try {
|
|
@@ -623,21 +707,101 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
623
707
|
return;
|
|
624
708
|
}
|
|
625
709
|
const response = await require_helpers.resolveResponse(fixture, completionReq);
|
|
710
|
+
const misbehavior = require_misbehavior.planMisbehavior({
|
|
711
|
+
wire: "gemini",
|
|
712
|
+
toolCallIdMode: "authored-nonempty",
|
|
713
|
+
fixture,
|
|
714
|
+
response,
|
|
715
|
+
request: completionReq,
|
|
716
|
+
stream: streaming,
|
|
717
|
+
defaults,
|
|
718
|
+
rawHeaders: req.headers,
|
|
719
|
+
url: req.url
|
|
720
|
+
});
|
|
721
|
+
if (misbehavior.kind === "error") {
|
|
722
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
723
|
+
entry: journal.add({
|
|
724
|
+
method: req.method ?? "POST",
|
|
725
|
+
path,
|
|
726
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
727
|
+
body: completionReq,
|
|
728
|
+
response: {
|
|
729
|
+
status: misbehavior.status,
|
|
730
|
+
fixture,
|
|
731
|
+
error: misbehavior.message
|
|
732
|
+
}
|
|
733
|
+
}),
|
|
734
|
+
summary: misbehavior.summary,
|
|
735
|
+
defaults,
|
|
736
|
+
testId
|
|
737
|
+
});
|
|
738
|
+
if (misbehavior.summary?.evaluations.length === 0) logger.error(`${req.method ?? "POST"} ${path}: ${misbehavior.message}`);
|
|
739
|
+
require_sse_writer.writeErrorResponse(res, misbehavior.status, JSON.stringify({ error: {
|
|
740
|
+
code: misbehavior.status,
|
|
741
|
+
message: misbehavior.message,
|
|
742
|
+
status: misbehavior.status === 400 ? "INVALID_ARGUMENT" : "UNIMPLEMENTED"
|
|
743
|
+
} }));
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
626
746
|
const latency = fixture.latency ?? defaults.latency;
|
|
627
747
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
628
748
|
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
629
|
-
if (
|
|
630
|
-
const
|
|
631
|
-
journal.add({
|
|
749
|
+
if (misbehavior.kind === "applied") {
|
|
750
|
+
const prepared = prepareGeminiMisbehavior(misbehavior, completionReq, streaming, chunkSize, logger, require_helpers.resolveStrictMode(defaults.strict, req.headers));
|
|
751
|
+
const entry = journal.add({
|
|
632
752
|
method: req.method ?? "POST",
|
|
633
753
|
path,
|
|
634
754
|
headers: require_helpers.flattenHeaders(req.headers),
|
|
635
755
|
body: completionReq,
|
|
636
756
|
response: {
|
|
637
|
-
status,
|
|
757
|
+
status: 200,
|
|
638
758
|
fixture
|
|
639
759
|
}
|
|
640
760
|
});
|
|
761
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
762
|
+
entry,
|
|
763
|
+
summary: prepared.summary,
|
|
764
|
+
defaults,
|
|
765
|
+
testId
|
|
766
|
+
});
|
|
767
|
+
if (!streaming) {
|
|
768
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
769
|
+
res.end(JSON.stringify(prepared.chunks[0]));
|
|
770
|
+
} else {
|
|
771
|
+
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
772
|
+
if (!await writeGeminiSSEStream(res, prepared.chunks, {
|
|
773
|
+
latency,
|
|
774
|
+
streamingProfile: fixture.streamingProfile,
|
|
775
|
+
recordedTimings: fixture.recordedTimings,
|
|
776
|
+
replaySpeed,
|
|
777
|
+
signal: interruption?.signal,
|
|
778
|
+
onChunkSent: interruption?.tick
|
|
779
|
+
})) {
|
|
780
|
+
if (!res.writableEnded) res.destroy();
|
|
781
|
+
entry.response.interrupted = true;
|
|
782
|
+
entry.response.interruptReason = interruption?.reason();
|
|
783
|
+
}
|
|
784
|
+
interruption?.cleanup();
|
|
785
|
+
}
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
if (require_helpers.isErrorResponse(response)) {
|
|
789
|
+
const status = response.status ?? 500;
|
|
790
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
791
|
+
entry: journal.add({
|
|
792
|
+
method: req.method ?? "POST",
|
|
793
|
+
path,
|
|
794
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
795
|
+
body: completionReq,
|
|
796
|
+
response: {
|
|
797
|
+
status,
|
|
798
|
+
fixture
|
|
799
|
+
}
|
|
800
|
+
}),
|
|
801
|
+
summary: misbehavior.summary,
|
|
802
|
+
defaults,
|
|
803
|
+
testId
|
|
804
|
+
});
|
|
641
805
|
const geminiError = { error: {
|
|
642
806
|
code: status,
|
|
643
807
|
message: response.error.message,
|
|
@@ -659,12 +823,19 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
659
823
|
fixture
|
|
660
824
|
}
|
|
661
825
|
});
|
|
826
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
827
|
+
entry: journalEntry,
|
|
828
|
+
summary: misbehavior.summary,
|
|
829
|
+
defaults,
|
|
830
|
+
testId
|
|
831
|
+
});
|
|
832
|
+
const audioToolCalls = Array.isArray(response.toolCalls) ? require_helpers.requireServedFunctionToolCalls(response, wire) : [];
|
|
662
833
|
if (!streaming) {
|
|
663
|
-
const body = buildGeminiAudioResponse(response, logger, effReasoning);
|
|
834
|
+
const body = buildGeminiAudioResponse(response, audioToolCalls, logger, effReasoning);
|
|
664
835
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
665
836
|
res.end(JSON.stringify(body));
|
|
666
837
|
} else {
|
|
667
|
-
const chunks = buildGeminiAudioStreamChunks(response, logger, effReasoning);
|
|
838
|
+
const chunks = buildGeminiAudioStreamChunks(response, audioToolCalls, logger, effReasoning);
|
|
668
839
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
669
840
|
if (!await writeGeminiSSEStream(res, chunks, {
|
|
670
841
|
latency,
|
|
@@ -682,7 +853,7 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
682
853
|
}
|
|
683
854
|
return;
|
|
684
855
|
}
|
|
685
|
-
if (require_helpers.
|
|
856
|
+
if (require_helpers.isCombinedFixtureResponse(response)) {
|
|
686
857
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
|
|
687
858
|
const overrides = require_helpers.extractOverrides(response);
|
|
688
859
|
const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
|
|
@@ -697,12 +868,19 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
697
868
|
fixture
|
|
698
869
|
}
|
|
699
870
|
});
|
|
871
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
872
|
+
entry: journalEntry,
|
|
873
|
+
summary: misbehavior.summary,
|
|
874
|
+
defaults,
|
|
875
|
+
testId
|
|
876
|
+
});
|
|
877
|
+
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, wire);
|
|
700
878
|
if (!streaming) {
|
|
701
|
-
const body = buildGeminiContentWithToolCallsResponse(response.content ?? "",
|
|
879
|
+
const body = buildGeminiContentWithToolCallsResponse(response.content ?? "", functionToolCalls, logger, effReasoning, overrides, response.blocks);
|
|
702
880
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
703
881
|
res.end(JSON.stringify(body));
|
|
704
882
|
} else {
|
|
705
|
-
const chunks = buildGeminiContentWithToolCallsStreamChunks(response.content ?? "",
|
|
883
|
+
const chunks = buildGeminiContentWithToolCallsStreamChunks(response.content ?? "", functionToolCalls, chunkSize, logger, effReasoning, overrides, response.blocks);
|
|
706
884
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
707
885
|
if (!await writeGeminiSSEStream(res, chunks, {
|
|
708
886
|
latency,
|
|
@@ -735,6 +913,12 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
735
913
|
fixture
|
|
736
914
|
}
|
|
737
915
|
});
|
|
916
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
917
|
+
entry: journalEntry,
|
|
918
|
+
summary: misbehavior.summary,
|
|
919
|
+
defaults,
|
|
920
|
+
testId
|
|
921
|
+
});
|
|
738
922
|
if (!streaming) {
|
|
739
923
|
const body = buildGeminiTextResponse(response.content, effReasoning, overrides);
|
|
740
924
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -773,12 +957,19 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
773
957
|
fixture
|
|
774
958
|
}
|
|
775
959
|
});
|
|
960
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
961
|
+
entry: journalEntry,
|
|
962
|
+
summary: misbehavior.summary,
|
|
963
|
+
defaults,
|
|
964
|
+
testId
|
|
965
|
+
});
|
|
966
|
+
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, wire);
|
|
776
967
|
if (!streaming) {
|
|
777
|
-
const body = buildGeminiToolCallResponse(
|
|
968
|
+
const body = buildGeminiToolCallResponse(functionToolCalls, logger, effReasoning, overrides);
|
|
778
969
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
779
970
|
res.end(JSON.stringify(body));
|
|
780
971
|
} else {
|
|
781
|
-
const chunks = buildGeminiToolCallStreamChunks(
|
|
972
|
+
const chunks = buildGeminiToolCallStreamChunks(functionToolCalls, chunkSize, logger, effReasoning, overrides);
|
|
782
973
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
783
974
|
if (!await writeGeminiSSEStream(res, chunks, {
|
|
784
975
|
latency,
|
|
@@ -796,15 +987,20 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
796
987
|
}
|
|
797
988
|
return;
|
|
798
989
|
}
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
990
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
991
|
+
entry: journal.add({
|
|
992
|
+
method: req.method ?? "POST",
|
|
993
|
+
path,
|
|
994
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
995
|
+
body: completionReq,
|
|
996
|
+
response: {
|
|
997
|
+
status: 500,
|
|
998
|
+
fixture
|
|
999
|
+
}
|
|
1000
|
+
}),
|
|
1001
|
+
summary: misbehavior.summary,
|
|
1002
|
+
defaults,
|
|
1003
|
+
testId
|
|
808
1004
|
});
|
|
809
1005
|
require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
810
1006
|
message: "Fixture response did not match any known type",
|