@copilotkit/aimock 1.44.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 +31 -0
- package/README.md +6 -0
- package/dist/agui-types.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 +312 -39
- 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 +313 -40
- 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 +1 -0
- package/dist/chaos.js +1 -1
- package/dist/cli.cjs +152 -5
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +155 -8
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +132 -71
- 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 +133 -72
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.cjs +62 -4
- 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 +62 -4
- package/dist/config-loader.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/fixture-loader-services.cjs +1 -1
- package/dist/fixture-loader-services.cjs.map +1 -1
- package/dist/fixture-loader-services.js +1 -1
- package/dist/fixture-loader-services.js.map +1 -1
- package/dist/fixture-loader.cjs +389 -27
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts +47 -3
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts +47 -3
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +384 -29
- package/dist/fixture-loader.js.map +1 -1
- package/dist/gemini-interactions.cjs +250 -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 +251 -53
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +226 -37
- 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 +227 -38
- package/dist/gemini.js.map +1 -1
- package/dist/helpers.cjs +881 -7
- 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 +839 -8
- package/dist/helpers.js.map +1 -1
- package/dist/index.cjs +9 -0
- package/dist/index.d.cts +7 -5
- package/dist/index.d.ts +7 -5
- package/dist/index.js +4 -3
- package/dist/jest.cjs +31 -7
- package/dist/jest.cjs.map +1 -1
- package/dist/jest.d.cts +43 -3
- package/dist/jest.d.cts.map +1 -1
- package/dist/jest.d.ts +43 -3
- package/dist/jest.d.ts.map +1 -1
- package/dist/jest.js +33 -9
- package/dist/jest.js.map +1 -1
- package/dist/journal.cjs +135 -13
- package/dist/journal.cjs.map +1 -1
- package/dist/journal.d.cts +38 -4
- package/dist/journal.d.cts.map +1 -1
- package/dist/journal.d.ts +38 -4
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +135 -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 +123 -30
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts +16 -1
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts +16 -1
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +125 -32
- package/dist/llmock.js.map +1 -1
- package/dist/mcp-fakes-mount.cjs +1 -0
- package/dist/mcp-fakes-mount.cjs.map +1 -1
- package/dist/mcp-fakes-mount.js +1 -0
- package/dist/mcp-fakes-mount.js.map +1 -1
- 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 +331 -8
- package/dist/mcp-fakes.cjs.map +1 -1
- package/dist/mcp-fakes.d.cts +406 -3
- package/dist/mcp-fakes.d.cts.map +1 -1
- package/dist/mcp-fakes.d.ts +406 -3
- package/dist/mcp-fakes.d.ts.map +1 -1
- package/dist/mcp-fakes.js +331 -8
- package/dist/mcp-fakes.js.map +1 -1
- package/dist/mcp-handler.cjs +209 -16
- 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 +207 -17
- package/dist/mcp-handler.js.map +1 -1
- package/dist/mcp-mock.cjs +112 -1
- package/dist/mcp-mock.cjs.map +1 -1
- package/dist/mcp-mock.d.cts +33 -2
- package/dist/mcp-mock.d.cts.map +1 -1
- package/dist/mcp-mock.d.ts +33 -2
- package/dist/mcp-mock.d.ts.map +1 -1
- package/dist/mcp-mock.js +112 -1
- 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/messages.cjs +362 -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 +363 -58
- package/dist/messages.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 +310 -112
- 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 +311 -113
- package/dist/ollama.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 +106 -5
- 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 +107 -7
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +667 -171
- 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 +665 -174
- package/dist/responses.js.map +1 -1
- 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 +572 -76
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +574 -78
- package/dist/server.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/types.cjs.map +1 -1
- package/dist/types.d.cts +315 -4
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +315 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validate-cli.cjs +36 -4
- package/dist/validate-cli.cjs.map +1 -1
- package/dist/validate-cli.js +37 -5
- package/dist/validate-cli.js.map +1 -1
- package/dist/vector-types.d.ts.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/vitest.cjs +66 -10
- package/dist/vitest.cjs.map +1 -1
- package/dist/vitest.d.cts +35 -4
- package/dist/vitest.d.cts.map +1 -1
- package/dist/vitest.d.ts +35 -4
- package/dist/vitest.d.ts.map +1 -1
- package/dist/vitest.js +67 -11
- 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 +109 -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 +111 -18
- package/dist/ws-responses.js.map +1 -1
- package/package.json +10 -2
- package/skills/write-fixtures/SKILL.md +179 -21
package/dist/ws-gemini-live.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_constants = require('./constants.cjs');
|
|
2
2
|
const require_helpers = require('./helpers.cjs');
|
|
3
3
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
4
|
+
const require_misbehavior = require('./misbehavior.cjs');
|
|
4
5
|
const require_router = require('./router.cjs');
|
|
5
6
|
require('./journal.cjs');
|
|
6
7
|
const require_interruption = require('./interruption.cjs');
|
|
@@ -102,10 +103,94 @@ function convertTools(geminiTools) {
|
|
|
102
103
|
function: {
|
|
103
104
|
name: d.name,
|
|
104
105
|
description: d.description,
|
|
105
|
-
parameters: d.parameters
|
|
106
|
+
parameters: d.parameters ?? d.parametersJsonSchema
|
|
106
107
|
}
|
|
107
108
|
}));
|
|
108
109
|
}
|
|
110
|
+
function liveToolArguments(tc) {
|
|
111
|
+
return require_helpers.servedToolArgs(tc, "object").value;
|
|
112
|
+
}
|
|
113
|
+
const GEMINI_LIVE_WIRE = "Gemini Live";
|
|
114
|
+
/** Prepare native object arguments and IDs once for both output and the journal. */
|
|
115
|
+
function prepareLiveMisbehavior(plan) {
|
|
116
|
+
if (plan.summary.fault === "tool-args-invalid-json" || plan.summary.fault === "empty-response") return {
|
|
117
|
+
...plan,
|
|
118
|
+
summary: {
|
|
119
|
+
...plan.summary,
|
|
120
|
+
servedToolCalls: []
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const response = plan.response;
|
|
124
|
+
const combined = require_helpers.isCombinedFixtureResponse(response);
|
|
125
|
+
const outcome = combined && response.blocks?.length ? require_helpers.resolveFixtureBlockOutcome(response.blocks) : void 0;
|
|
126
|
+
const calls = outcome?.toolCalls ?? (combined || require_helpers.isToolCallResponse(response) ? response.toolCalls ?? [] : []);
|
|
127
|
+
const duplicate = plan.duplicateId;
|
|
128
|
+
const toolCalls = calls.map((call, index) => {
|
|
129
|
+
const args = require_helpers.toolArgsForWire(call);
|
|
130
|
+
return {
|
|
131
|
+
...call,
|
|
132
|
+
arguments: args.kind === "parsed" ? args.text : args.raw,
|
|
133
|
+
...index === duplicate?.destinationIndex ? {} : { id: call.id ?? require_helpers.generateToolCallId() }
|
|
134
|
+
};
|
|
135
|
+
});
|
|
136
|
+
if (duplicate) toolCalls[duplicate.destinationIndex].id = toolCalls[duplicate.sourceIndex].id;
|
|
137
|
+
let preparedResponse = { ...response };
|
|
138
|
+
if ("usage" in preparedResponse) delete preparedResponse.usage;
|
|
139
|
+
if (outcome) {
|
|
140
|
+
let index = 0;
|
|
141
|
+
const blocks = outcome.ordered.map((block) => block.type === "text" ? { ...block } : {
|
|
142
|
+
...block,
|
|
143
|
+
...toolCalls[index++]
|
|
144
|
+
});
|
|
145
|
+
preparedResponse = {
|
|
146
|
+
...preparedResponse,
|
|
147
|
+
content: outcome.content,
|
|
148
|
+
toolCalls,
|
|
149
|
+
blocks
|
|
150
|
+
};
|
|
151
|
+
} else if (combined || require_helpers.isToolCallResponse(response)) preparedResponse = {
|
|
152
|
+
...preparedResponse,
|
|
153
|
+
toolCalls
|
|
154
|
+
};
|
|
155
|
+
return {
|
|
156
|
+
...plan,
|
|
157
|
+
response: preparedResponse,
|
|
158
|
+
summary: {
|
|
159
|
+
...plan.summary,
|
|
160
|
+
servedToolCalls: toolCalls.map(({ name, arguments: args, id }) => ({
|
|
161
|
+
name,
|
|
162
|
+
arguments: args,
|
|
163
|
+
id
|
|
164
|
+
}))
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Validate the whole selected response before audio, text, or any tool is
|
|
170
|
+
* sent: every entry is validated, custom tool calls are rejected, and every
|
|
171
|
+
* argument string must parse. Returns the calls narrowed to function calls. On
|
|
172
|
+
* failure the journal entry becomes a 500, and the outer message handler sends
|
|
173
|
+
* code 13 with `google.rpc.ErrorInfo` details carrying the aimock code, drops
|
|
174
|
+
* this turn from the history, and leaves the socket open.
|
|
175
|
+
*/
|
|
176
|
+
function preflightToolArguments(response, journalEntry) {
|
|
177
|
+
return require_helpers.journalFixtureToolCallError(journalEntry, () => {
|
|
178
|
+
const functionCalls = require_helpers.requireServedFunctionToolCalls(response, GEMINI_LIVE_WIRE);
|
|
179
|
+
if (require_helpers.strictToolArgumentsEnabled()) for (const tc of functionCalls) liveToolArguments(tc);
|
|
180
|
+
return functionCalls;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/** Resolve ordered blocks (rejecting custom tool calls) and preflight their arguments. */
|
|
184
|
+
function preflightBlocks(response, journalEntry) {
|
|
185
|
+
return require_helpers.journalFixtureToolCallError(journalEntry, () => {
|
|
186
|
+
require_helpers.rejectResponsesOnlyToolCalls(response, GEMINI_LIVE_WIRE);
|
|
187
|
+
const resolved = require_helpers.resolveFixtureBlocks(response.blocks ?? []);
|
|
188
|
+
if (require_helpers.strictToolArgumentsEnabled()) {
|
|
189
|
+
for (const block of resolved) if (block.type === "toolCall") liveToolArguments(block);
|
|
190
|
+
}
|
|
191
|
+
return resolved;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
109
194
|
function handleWebSocketGeminiLive(ws, fixtures, journal, defaults) {
|
|
110
195
|
const { logger } = defaults;
|
|
111
196
|
const session = {
|
|
@@ -116,19 +201,31 @@ function handleWebSocketGeminiLive(ws, fixtures, journal, defaults) {
|
|
|
116
201
|
};
|
|
117
202
|
let pending = Promise.resolve();
|
|
118
203
|
ws.on("message", (raw) => {
|
|
119
|
-
pending = pending.then(
|
|
120
|
-
const
|
|
121
|
-
logger.error(`WebSocket Gemini Live error: ${msg}`);
|
|
204
|
+
pending = pending.then(async () => {
|
|
205
|
+
const historyMark = session.conversationHistory.length;
|
|
122
206
|
try {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
} catch (
|
|
129
|
-
|
|
207
|
+
defaults.beforeProcessMessage?.();
|
|
208
|
+
await require_helpers.runWithToolArgumentsScope({
|
|
209
|
+
strict: defaults.strictToolArguments === true,
|
|
210
|
+
logger
|
|
211
|
+
}, () => processMessage(raw, ws, fixtures, journal, defaults, session));
|
|
212
|
+
} catch (err) {
|
|
213
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
214
|
+
logger.error(`WebSocket Gemini Live error: ${msg}`);
|
|
215
|
+
const fixtureToolCallError = require_helpers.isFixtureToolCallError(err);
|
|
216
|
+
if (fixtureToolCallError) session.conversationHistory.length = historyMark;
|
|
217
|
+
try {
|
|
218
|
+
ws.send(JSON.stringify({ error: {
|
|
219
|
+
code: 13,
|
|
220
|
+
message: msg,
|
|
221
|
+
status: "INTERNAL",
|
|
222
|
+
...fixtureToolCallError ? { details: require_helpers.googleFixtureToolCallErrorDetails(require_helpers.fixtureToolCallErrorCode(err)) } : {}
|
|
223
|
+
} }));
|
|
224
|
+
} catch (sendErr) {
|
|
225
|
+
defaults.logger.debug(`Failed to send error to client: ${sendErr instanceof Error ? sendErr.message : "unknown"}`);
|
|
226
|
+
}
|
|
130
227
|
}
|
|
131
|
-
})
|
|
228
|
+
});
|
|
132
229
|
});
|
|
133
230
|
}
|
|
134
231
|
async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
@@ -240,12 +337,28 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
240
337
|
return;
|
|
241
338
|
}
|
|
242
339
|
session.conversationHistory.push(...newMessages);
|
|
243
|
-
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
340
|
+
let response = await require_helpers.resolveResponse(fixture, completionReq);
|
|
341
|
+
const plannerDefaults = {
|
|
342
|
+
...defaults,
|
|
343
|
+
replaySpeed: defaults.replaySpeed ?? 1
|
|
344
|
+
};
|
|
345
|
+
let misbehavior = require_misbehavior.planMisbehavior({
|
|
346
|
+
wire: "gemini-live",
|
|
347
|
+
emitsToolCallIds: true,
|
|
348
|
+
fixture,
|
|
349
|
+
response,
|
|
350
|
+
request: completionReq,
|
|
351
|
+
stream: true,
|
|
352
|
+
defaults: plannerDefaults,
|
|
353
|
+
rawHeaders: defaults.upgradeHeaders ?? {},
|
|
354
|
+
url: `${path}?testId=${encodeURIComponent(testId)}`
|
|
355
|
+
});
|
|
356
|
+
if (misbehavior.kind === "applied") {
|
|
357
|
+
misbehavior = prepareLiveMisbehavior(misbehavior);
|
|
358
|
+
response = misbehavior.response;
|
|
359
|
+
}
|
|
360
|
+
const addResponseEntry = (status) => {
|
|
361
|
+
const entry = journal.add({
|
|
249
362
|
method: "WS",
|
|
250
363
|
path,
|
|
251
364
|
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
@@ -255,6 +368,68 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
255
368
|
fixture
|
|
256
369
|
}
|
|
257
370
|
});
|
|
371
|
+
require_misbehavior.recordMisbehaviorOutcome({
|
|
372
|
+
entry,
|
|
373
|
+
summary: misbehavior.summary,
|
|
374
|
+
defaults: plannerDefaults,
|
|
375
|
+
testId
|
|
376
|
+
});
|
|
377
|
+
return entry;
|
|
378
|
+
};
|
|
379
|
+
if (misbehavior.kind === "error") {
|
|
380
|
+
addResponseEntry(misbehavior.status);
|
|
381
|
+
if (!misbehavior.summary?.evaluations.length) defaults.logger.error(`[misbehavior] ${misbehavior.message} (testId=${testId})`);
|
|
382
|
+
ws.send(JSON.stringify({ error: {
|
|
383
|
+
code: httpToGrpc(misbehavior.status),
|
|
384
|
+
message: misbehavior.message,
|
|
385
|
+
status: misbehavior.status === 400 ? "INVALID_ARGUMENT" : "UNIMPLEMENTED"
|
|
386
|
+
} }));
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const latency = fixture.latency ?? defaults.latency;
|
|
390
|
+
if (misbehavior.kind === "applied" && (misbehavior.summary.fault === "tool-args-invalid-json" || misbehavior.summary.fault === "empty-response")) {
|
|
391
|
+
const journalEntry = addResponseEntry(200);
|
|
392
|
+
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
393
|
+
const markInterrupted = () => {
|
|
394
|
+
journalEntry.response.interrupted = true;
|
|
395
|
+
journalEntry.response.interruptReason = interruption?.reason();
|
|
396
|
+
ws.destroy();
|
|
397
|
+
};
|
|
398
|
+
try {
|
|
399
|
+
if (ws.isClosed) return;
|
|
400
|
+
const chunkDelay = require_sse_writer.calculateDelay(0, void 0, latency, fixture.recordedTimings, fixture.replaySpeed ?? defaults.replaySpeed);
|
|
401
|
+
if (chunkDelay > 0) await require_sse_writer.delay(chunkDelay, interruption?.signal);
|
|
402
|
+
if (interruption?.signal.aborted) {
|
|
403
|
+
markInterrupted();
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (ws.isClosed) return;
|
|
407
|
+
const malformed = misbehavior.summary.fault === "tool-args-invalid-json";
|
|
408
|
+
ws.send(JSON.stringify({ serverContent: malformed ? {
|
|
409
|
+
turnComplete: true,
|
|
410
|
+
turnCompleteReason: "MALFORMED_FUNCTION_CALL"
|
|
411
|
+
} : { modelTurn: { parts: [{ text: "" }] } } }));
|
|
412
|
+
interruption?.tick();
|
|
413
|
+
if (interruption?.signal.aborted) {
|
|
414
|
+
markInterrupted();
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
if (!malformed && !ws.isClosed) {
|
|
418
|
+
ws.send(JSON.stringify({ serverContent: { turnComplete: true } }));
|
|
419
|
+
session.conversationHistory.push({
|
|
420
|
+
role: "assistant",
|
|
421
|
+
content: ""
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
} finally {
|
|
425
|
+
interruption?.cleanup();
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
430
|
+
if (require_helpers.isErrorResponse(response)) {
|
|
431
|
+
const status = response.status ?? 500;
|
|
432
|
+
addResponseEntry(status);
|
|
258
433
|
ws.send(JSON.stringify({ error: {
|
|
259
434
|
code: httpToGrpc(status),
|
|
260
435
|
message: response.error.message,
|
|
@@ -263,17 +438,9 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
263
438
|
return;
|
|
264
439
|
}
|
|
265
440
|
if (require_helpers.isAudioResponse(response)) {
|
|
266
|
-
|
|
267
|
-
method: "WS",
|
|
268
|
-
path,
|
|
269
|
-
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
270
|
-
body: completionReq,
|
|
271
|
-
response: {
|
|
272
|
-
status: 200,
|
|
273
|
-
fixture
|
|
274
|
-
}
|
|
275
|
-
});
|
|
441
|
+
const journalEntry = addResponseEntry(200);
|
|
276
442
|
const audioResp = response;
|
|
443
|
+
const audioToolCalls = preflightToolArguments(audioResp, journalEntry);
|
|
277
444
|
let mimeType;
|
|
278
445
|
let data;
|
|
279
446
|
if (typeof audioResp.audio === "string") {
|
|
@@ -288,7 +455,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
288
455
|
data
|
|
289
456
|
} }];
|
|
290
457
|
if (audioResp.content) parts.push({ text: audioResp.content });
|
|
291
|
-
const resolvedToolCalls =
|
|
458
|
+
const resolvedToolCalls = audioToolCalls.map((tc) => ({
|
|
292
459
|
...tc,
|
|
293
460
|
resolvedId: tc.id ?? require_helpers.generateToolCallId()
|
|
294
461
|
}));
|
|
@@ -300,13 +467,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
300
467
|
ws.send(JSON.stringify({ serverContent: { modelTurn: { parts } } }));
|
|
301
468
|
if (!ws.isClosed) {
|
|
302
469
|
const functionCalls = resolvedToolCalls.map((tc) => {
|
|
303
|
-
|
|
304
|
-
try {
|
|
305
|
-
argsObj = JSON.parse(tc.arguments || "{}");
|
|
306
|
-
} catch {
|
|
307
|
-
defaults.logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
|
|
308
|
-
argsObj = {};
|
|
309
|
-
}
|
|
470
|
+
const argsObj = liveToolArguments(tc);
|
|
310
471
|
return {
|
|
311
472
|
name: tc.name,
|
|
312
473
|
args: argsObj,
|
|
@@ -331,19 +492,10 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
331
492
|
});
|
|
332
493
|
return;
|
|
333
494
|
}
|
|
334
|
-
if (require_helpers.
|
|
335
|
-
const journalEntry =
|
|
336
|
-
method: "WS",
|
|
337
|
-
path,
|
|
338
|
-
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
339
|
-
body: completionReq,
|
|
340
|
-
response: {
|
|
341
|
-
status: 200,
|
|
342
|
-
fixture
|
|
343
|
-
}
|
|
344
|
-
});
|
|
495
|
+
if (require_helpers.isCombinedFixtureResponse(response)) {
|
|
496
|
+
const journalEntry = addResponseEntry(200);
|
|
345
497
|
if (response.blocks && response.blocks.length > 0) {
|
|
346
|
-
const resolvedBlocks =
|
|
498
|
+
const resolvedBlocks = preflightBlocks(response, journalEntry);
|
|
347
499
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
348
500
|
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
349
501
|
const { recordedTimings } = fixture;
|
|
@@ -361,13 +513,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
361
513
|
}
|
|
362
514
|
if (ws.isClosed) break;
|
|
363
515
|
const resolvedId = block.id ?? require_helpers.generateToolCallId();
|
|
364
|
-
|
|
365
|
-
try {
|
|
366
|
-
argsObj = JSON.parse(block.arguments || "{}");
|
|
367
|
-
} catch {
|
|
368
|
-
defaults.logger.warn(`Malformed JSON in fixture tool call arguments for "${block.name}": ${block.arguments}`);
|
|
369
|
-
argsObj = {};
|
|
370
|
-
}
|
|
516
|
+
const argsObj = liveToolArguments(block);
|
|
371
517
|
try {
|
|
372
518
|
ws.send(JSON.stringify({ toolCall: { functionCalls: [{
|
|
373
519
|
name: block.name,
|
|
@@ -435,6 +581,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
435
581
|
});
|
|
436
582
|
return;
|
|
437
583
|
}
|
|
584
|
+
const functionToolCalls = preflightToolArguments(response, journalEntry);
|
|
438
585
|
const content = response.content ?? "";
|
|
439
586
|
const chunkList = [];
|
|
440
587
|
for (let i = 0; i < content.length; i += chunkSize) chunkList.push(content.slice(i, i + chunkSize));
|
|
@@ -472,7 +619,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
472
619
|
interruption?.cleanup();
|
|
473
620
|
return;
|
|
474
621
|
}
|
|
475
|
-
const resolvedToolCalls =
|
|
622
|
+
const resolvedToolCalls = functionToolCalls.map((tc) => ({
|
|
476
623
|
...tc,
|
|
477
624
|
resolvedId: tc.id ?? require_helpers.generateToolCallId()
|
|
478
625
|
}));
|
|
@@ -487,13 +634,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
487
634
|
return;
|
|
488
635
|
}
|
|
489
636
|
const functionCalls = resolvedToolCalls.map((tc) => {
|
|
490
|
-
|
|
491
|
-
try {
|
|
492
|
-
argsObj = JSON.parse(tc.arguments || "{}");
|
|
493
|
-
} catch {
|
|
494
|
-
defaults.logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
|
|
495
|
-
argsObj = {};
|
|
496
|
-
}
|
|
637
|
+
const argsObj = liveToolArguments(tc);
|
|
497
638
|
return {
|
|
498
639
|
name: tc.name,
|
|
499
640
|
args: argsObj,
|
|
@@ -527,16 +668,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
527
668
|
return;
|
|
528
669
|
}
|
|
529
670
|
if (require_helpers.isTextResponse(response)) {
|
|
530
|
-
const journalEntry =
|
|
531
|
-
method: "WS",
|
|
532
|
-
path,
|
|
533
|
-
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
534
|
-
body: completionReq,
|
|
535
|
-
response: {
|
|
536
|
-
status: 200,
|
|
537
|
-
fixture
|
|
538
|
-
}
|
|
539
|
-
});
|
|
671
|
+
const journalEntry = addResponseEntry(200);
|
|
540
672
|
const content = response.content;
|
|
541
673
|
if (content.length === 0) {
|
|
542
674
|
if (ws.isClosed) return;
|
|
@@ -587,16 +719,8 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
587
719
|
return;
|
|
588
720
|
}
|
|
589
721
|
if (require_helpers.isToolCallResponse(response)) {
|
|
590
|
-
const journalEntry =
|
|
591
|
-
|
|
592
|
-
path,
|
|
593
|
-
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
594
|
-
body: completionReq,
|
|
595
|
-
response: {
|
|
596
|
-
status: 200,
|
|
597
|
-
fixture
|
|
598
|
-
}
|
|
599
|
-
});
|
|
722
|
+
const journalEntry = addResponseEntry(200);
|
|
723
|
+
const functionToolCalls = preflightToolArguments(response, journalEntry);
|
|
600
724
|
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
601
725
|
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
602
726
|
const { recordedTimings } = fixture;
|
|
@@ -617,18 +741,12 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
617
741
|
interruption?.cleanup();
|
|
618
742
|
return;
|
|
619
743
|
}
|
|
620
|
-
const resolvedToolCalls =
|
|
744
|
+
const resolvedToolCalls = functionToolCalls.map((tc) => ({
|
|
621
745
|
...tc,
|
|
622
746
|
resolvedId: tc.id ?? require_helpers.generateToolCallId()
|
|
623
747
|
}));
|
|
624
748
|
const functionCalls = resolvedToolCalls.map((tc) => {
|
|
625
|
-
|
|
626
|
-
try {
|
|
627
|
-
argsObj = JSON.parse(tc.arguments || "{}");
|
|
628
|
-
} catch {
|
|
629
|
-
defaults.logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
|
|
630
|
-
argsObj = {};
|
|
631
|
-
}
|
|
749
|
+
const argsObj = liveToolArguments(tc);
|
|
632
750
|
return {
|
|
633
751
|
name: tc.name,
|
|
634
752
|
args: argsObj,
|
|
@@ -660,16 +778,7 @@ async function processMessage(raw, ws, fixtures, journal, defaults, session) {
|
|
|
660
778
|
});
|
|
661
779
|
return;
|
|
662
780
|
}
|
|
663
|
-
|
|
664
|
-
method: "WS",
|
|
665
|
-
path,
|
|
666
|
-
headers: require_helpers.flattenHeaders(defaults.upgradeHeaders ?? {}),
|
|
667
|
-
body: completionReq,
|
|
668
|
-
response: {
|
|
669
|
-
status: 500,
|
|
670
|
-
fixture
|
|
671
|
-
}
|
|
672
|
-
});
|
|
781
|
+
addResponseEntry(500);
|
|
673
782
|
ws.send(JSON.stringify({ error: {
|
|
674
783
|
code: 13,
|
|
675
784
|
message: "Fixture response did not match any known type",
|