@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.
Files changed (272) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +31 -0
  4. package/README.md +6 -0
  5. package/dist/agui-types.d.ts.map +1 -1
  6. package/dist/aimock-cli.cjs +31 -5
  7. package/dist/aimock-cli.cjs.map +1 -1
  8. package/dist/aimock-cli.d.cts.map +1 -1
  9. package/dist/aimock-cli.d.ts.map +1 -1
  10. package/dist/aimock-cli.js +31 -5
  11. package/dist/aimock-cli.js.map +1 -1
  12. package/dist/bedrock-converse.cjs +312 -39
  13. package/dist/bedrock-converse.cjs.map +1 -1
  14. package/dist/bedrock-converse.d.cts.map +1 -1
  15. package/dist/bedrock-converse.d.ts.map +1 -1
  16. package/dist/bedrock-converse.js +313 -40
  17. package/dist/bedrock-converse.js.map +1 -1
  18. package/dist/bedrock.cjs +195 -42
  19. package/dist/bedrock.cjs.map +1 -1
  20. package/dist/bedrock.d.cts.map +1 -1
  21. package/dist/bedrock.d.ts.map +1 -1
  22. package/dist/bedrock.js +196 -43
  23. package/dist/bedrock.js.map +1 -1
  24. package/dist/chaos.cjs +1 -0
  25. package/dist/chaos.js +1 -1
  26. package/dist/cli.cjs +152 -5
  27. package/dist/cli.cjs.map +1 -1
  28. package/dist/cli.js +155 -8
  29. package/dist/cli.js.map +1 -1
  30. package/dist/cohere.cjs +132 -71
  31. package/dist/cohere.cjs.map +1 -1
  32. package/dist/cohere.d.cts.map +1 -1
  33. package/dist/cohere.d.ts.map +1 -1
  34. package/dist/cohere.js +133 -72
  35. package/dist/cohere.js.map +1 -1
  36. package/dist/config-loader.cjs +62 -4
  37. package/dist/config-loader.cjs.map +1 -1
  38. package/dist/config-loader.d.cts +37 -4
  39. package/dist/config-loader.d.cts.map +1 -1
  40. package/dist/config-loader.d.ts +37 -4
  41. package/dist/config-loader.d.ts.map +1 -1
  42. package/dist/config-loader.js +62 -4
  43. package/dist/config-loader.js.map +1 -1
  44. package/dist/fakes-plugin.cjs +131 -0
  45. package/dist/fakes-plugin.cjs.map +1 -0
  46. package/dist/fakes-plugin.d.cts +23 -0
  47. package/dist/fakes-plugin.d.cts.map +1 -0
  48. package/dist/fakes-plugin.d.ts +23 -0
  49. package/dist/fakes-plugin.d.ts.map +1 -0
  50. package/dist/fakes-plugin.js +127 -0
  51. package/dist/fakes-plugin.js.map +1 -0
  52. package/dist/fixture-loader-services.cjs +1 -1
  53. package/dist/fixture-loader-services.cjs.map +1 -1
  54. package/dist/fixture-loader-services.js +1 -1
  55. package/dist/fixture-loader-services.js.map +1 -1
  56. package/dist/fixture-loader.cjs +389 -27
  57. package/dist/fixture-loader.cjs.map +1 -1
  58. package/dist/fixture-loader.d.cts +47 -3
  59. package/dist/fixture-loader.d.cts.map +1 -1
  60. package/dist/fixture-loader.d.ts +47 -3
  61. package/dist/fixture-loader.d.ts.map +1 -1
  62. package/dist/fixture-loader.js +384 -29
  63. package/dist/fixture-loader.js.map +1 -1
  64. package/dist/gemini-interactions.cjs +250 -52
  65. package/dist/gemini-interactions.cjs.map +1 -1
  66. package/dist/gemini-interactions.d.cts.map +1 -1
  67. package/dist/gemini-interactions.d.ts.map +1 -1
  68. package/dist/gemini-interactions.js +251 -53
  69. package/dist/gemini-interactions.js.map +1 -1
  70. package/dist/gemini.cjs +226 -37
  71. package/dist/gemini.cjs.map +1 -1
  72. package/dist/gemini.d.cts.map +1 -1
  73. package/dist/gemini.d.ts.map +1 -1
  74. package/dist/gemini.js +227 -38
  75. package/dist/gemini.js.map +1 -1
  76. package/dist/helpers.cjs +881 -7
  77. package/dist/helpers.cjs.map +1 -1
  78. package/dist/helpers.d.cts +85 -4
  79. package/dist/helpers.d.cts.map +1 -1
  80. package/dist/helpers.d.ts +85 -4
  81. package/dist/helpers.d.ts.map +1 -1
  82. package/dist/helpers.js +839 -8
  83. package/dist/helpers.js.map +1 -1
  84. package/dist/index.cjs +9 -0
  85. package/dist/index.d.cts +7 -5
  86. package/dist/index.d.ts +7 -5
  87. package/dist/index.js +4 -3
  88. package/dist/jest.cjs +31 -7
  89. package/dist/jest.cjs.map +1 -1
  90. package/dist/jest.d.cts +43 -3
  91. package/dist/jest.d.cts.map +1 -1
  92. package/dist/jest.d.ts +43 -3
  93. package/dist/jest.d.ts.map +1 -1
  94. package/dist/jest.js +33 -9
  95. package/dist/jest.js.map +1 -1
  96. package/dist/journal.cjs +135 -13
  97. package/dist/journal.cjs.map +1 -1
  98. package/dist/journal.d.cts +38 -4
  99. package/dist/journal.d.cts.map +1 -1
  100. package/dist/journal.d.ts +38 -4
  101. package/dist/journal.d.ts.map +1 -1
  102. package/dist/journal.js +135 -13
  103. package/dist/journal.js.map +1 -1
  104. package/dist/live-sanitize.cjs +4 -32
  105. package/dist/live-sanitize.cjs.map +1 -1
  106. package/dist/live-sanitize.js +4 -32
  107. package/dist/live-sanitize.js.map +1 -1
  108. package/dist/llmock.cjs +123 -30
  109. package/dist/llmock.cjs.map +1 -1
  110. package/dist/llmock.d.cts +16 -1
  111. package/dist/llmock.d.cts.map +1 -1
  112. package/dist/llmock.d.ts +16 -1
  113. package/dist/llmock.d.ts.map +1 -1
  114. package/dist/llmock.js +125 -32
  115. package/dist/llmock.js.map +1 -1
  116. package/dist/mcp-fakes-mount.cjs +1 -0
  117. package/dist/mcp-fakes-mount.cjs.map +1 -1
  118. package/dist/mcp-fakes-mount.js +1 -0
  119. package/dist/mcp-fakes-mount.js.map +1 -1
  120. package/dist/mcp-fakes-report.cjs +111 -0
  121. package/dist/mcp-fakes-report.cjs.map +1 -0
  122. package/dist/mcp-fakes-report.d.cts +40 -0
  123. package/dist/mcp-fakes-report.d.cts.map +1 -0
  124. package/dist/mcp-fakes-report.d.ts +40 -0
  125. package/dist/mcp-fakes-report.d.ts.map +1 -0
  126. package/dist/mcp-fakes-report.js +107 -0
  127. package/dist/mcp-fakes-report.js.map +1 -0
  128. package/dist/mcp-fakes.cjs +331 -8
  129. package/dist/mcp-fakes.cjs.map +1 -1
  130. package/dist/mcp-fakes.d.cts +406 -3
  131. package/dist/mcp-fakes.d.cts.map +1 -1
  132. package/dist/mcp-fakes.d.ts +406 -3
  133. package/dist/mcp-fakes.d.ts.map +1 -1
  134. package/dist/mcp-fakes.js +331 -8
  135. package/dist/mcp-fakes.js.map +1 -1
  136. package/dist/mcp-handler.cjs +209 -16
  137. package/dist/mcp-handler.cjs.map +1 -1
  138. package/dist/mcp-handler.d.cts +49 -0
  139. package/dist/mcp-handler.d.cts.map +1 -0
  140. package/dist/mcp-handler.d.ts +49 -0
  141. package/dist/mcp-handler.d.ts.map +1 -0
  142. package/dist/mcp-handler.js +207 -17
  143. package/dist/mcp-handler.js.map +1 -1
  144. package/dist/mcp-mock.cjs +112 -1
  145. package/dist/mcp-mock.cjs.map +1 -1
  146. package/dist/mcp-mock.d.cts +33 -2
  147. package/dist/mcp-mock.d.cts.map +1 -1
  148. package/dist/mcp-mock.d.ts +33 -2
  149. package/dist/mcp-mock.d.ts.map +1 -1
  150. package/dist/mcp-mock.js +112 -1
  151. package/dist/mcp-mock.js.map +1 -1
  152. package/dist/mcp-recorder.cjs +1224 -0
  153. package/dist/mcp-recorder.cjs.map +1 -0
  154. package/dist/mcp-recorder.d.cts +108 -0
  155. package/dist/mcp-recorder.d.cts.map +1 -0
  156. package/dist/mcp-recorder.d.ts +108 -0
  157. package/dist/mcp-recorder.d.ts.map +1 -0
  158. package/dist/mcp-recorder.js +1215 -0
  159. package/dist/mcp-recorder.js.map +1 -0
  160. package/dist/messages.cjs +362 -56
  161. package/dist/messages.cjs.map +1 -1
  162. package/dist/messages.d.cts.map +1 -1
  163. package/dist/messages.d.ts.map +1 -1
  164. package/dist/messages.js +363 -58
  165. package/dist/messages.js.map +1 -1
  166. package/dist/misbehavior.cjs +1523 -0
  167. package/dist/misbehavior.cjs.map +1 -0
  168. package/dist/misbehavior.d.cts +43 -0
  169. package/dist/misbehavior.d.cts.map +1 -0
  170. package/dist/misbehavior.d.ts +43 -0
  171. package/dist/misbehavior.d.ts.map +1 -0
  172. package/dist/misbehavior.js +1511 -0
  173. package/dist/misbehavior.js.map +1 -0
  174. package/dist/ollama.cjs +310 -112
  175. package/dist/ollama.cjs.map +1 -1
  176. package/dist/ollama.d.cts.map +1 -1
  177. package/dist/ollama.d.ts.map +1 -1
  178. package/dist/ollama.js +311 -113
  179. package/dist/ollama.js.map +1 -1
  180. package/dist/record-sanitize.cjs +231 -0
  181. package/dist/record-sanitize.cjs.map +1 -0
  182. package/dist/record-sanitize.js +224 -0
  183. package/dist/record-sanitize.js.map +1 -0
  184. package/dist/recorder.cjs +106 -5
  185. package/dist/recorder.cjs.map +1 -1
  186. package/dist/recorder.d.cts +2 -1
  187. package/dist/recorder.d.cts.map +1 -1
  188. package/dist/recorder.d.ts +2 -1
  189. package/dist/recorder.d.ts.map +1 -1
  190. package/dist/recorder.js +107 -7
  191. package/dist/recorder.js.map +1 -1
  192. package/dist/responses.cjs +667 -171
  193. package/dist/responses.cjs.map +1 -1
  194. package/dist/responses.d.cts +5 -13
  195. package/dist/responses.d.cts.map +1 -1
  196. package/dist/responses.d.ts +5 -13
  197. package/dist/responses.d.ts.map +1 -1
  198. package/dist/responses.js +665 -174
  199. package/dist/responses.js.map +1 -1
  200. package/dist/router.cjs +24 -2
  201. package/dist/router.cjs.map +1 -1
  202. package/dist/router.d.cts.map +1 -1
  203. package/dist/router.d.ts.map +1 -1
  204. package/dist/router.js +25 -4
  205. package/dist/router.js.map +1 -1
  206. package/dist/server.cjs +572 -76
  207. package/dist/server.cjs.map +1 -1
  208. package/dist/server.d.cts.map +1 -1
  209. package/dist/server.d.ts.map +1 -1
  210. package/dist/server.js +574 -78
  211. package/dist/server.js.map +1 -1
  212. package/dist/stream-collapse.cjs +236 -34
  213. package/dist/stream-collapse.cjs.map +1 -1
  214. package/dist/stream-collapse.d.cts +39 -4
  215. package/dist/stream-collapse.d.cts.map +1 -1
  216. package/dist/stream-collapse.d.ts +39 -4
  217. package/dist/stream-collapse.d.ts.map +1 -1
  218. package/dist/stream-collapse.js +235 -35
  219. package/dist/stream-collapse.js.map +1 -1
  220. package/dist/types.cjs.map +1 -1
  221. package/dist/types.d.cts +315 -4
  222. package/dist/types.d.cts.map +1 -1
  223. package/dist/types.d.ts +315 -4
  224. package/dist/types.d.ts.map +1 -1
  225. package/dist/types.js.map +1 -1
  226. package/dist/validate-cli.cjs +36 -4
  227. package/dist/validate-cli.cjs.map +1 -1
  228. package/dist/validate-cli.js +37 -5
  229. package/dist/validate-cli.js.map +1 -1
  230. package/dist/vector-types.d.ts.map +1 -1
  231. package/dist/version.cjs +45 -0
  232. package/dist/version.cjs.map +1 -0
  233. package/dist/version.js +44 -0
  234. package/dist/version.js.map +1 -0
  235. package/dist/vitest.cjs +66 -10
  236. package/dist/vitest.cjs.map +1 -1
  237. package/dist/vitest.d.cts +35 -4
  238. package/dist/vitest.d.cts.map +1 -1
  239. package/dist/vitest.d.ts +35 -4
  240. package/dist/vitest.d.ts.map +1 -1
  241. package/dist/vitest.js +67 -11
  242. package/dist/vitest.js.map +1 -1
  243. package/dist/watcher.cjs +6 -2
  244. package/dist/watcher.cjs.map +1 -1
  245. package/dist/watcher.js +6 -2
  246. package/dist/watcher.js.map +1 -1
  247. package/dist/ws-gemini-live.cjs +210 -101
  248. package/dist/ws-gemini-live.cjs.map +1 -1
  249. package/dist/ws-gemini-live.d.cts +9 -3
  250. package/dist/ws-gemini-live.d.cts.map +1 -1
  251. package/dist/ws-gemini-live.d.ts +9 -3
  252. package/dist/ws-gemini-live.d.ts.map +1 -1
  253. package/dist/ws-gemini-live.js +211 -102
  254. package/dist/ws-gemini-live.js.map +1 -1
  255. package/dist/ws-realtime.cjs +175 -62
  256. package/dist/ws-realtime.cjs.map +1 -1
  257. package/dist/ws-realtime.d.cts +8 -3
  258. package/dist/ws-realtime.d.cts.map +1 -1
  259. package/dist/ws-realtime.d.ts +8 -3
  260. package/dist/ws-realtime.d.ts.map +1 -1
  261. package/dist/ws-realtime.js +176 -63
  262. package/dist/ws-realtime.js.map +1 -1
  263. package/dist/ws-responses.cjs +109 -16
  264. package/dist/ws-responses.cjs.map +1 -1
  265. package/dist/ws-responses.d.cts +8 -12
  266. package/dist/ws-responses.d.cts.map +1 -1
  267. package/dist/ws-responses.d.ts +8 -12
  268. package/dist/ws-responses.d.ts.map +1 -1
  269. package/dist/ws-responses.js +111 -18
  270. package/dist/ws-responses.js.map +1 -1
  271. package/package.json +10 -2
  272. package/skills/write-fixtures/SKILL.md +179 -21
package/dist/bedrock.cjs CHANGED
@@ -1,9 +1,11 @@
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');
8
+ const require_messages = require('./messages.cjs');
7
9
  const require_aws_event_stream = require('./aws-event-stream.cjs');
8
10
 
9
11
  //#region src/bedrock.ts
@@ -155,18 +157,12 @@ function buildBedrockToolCallResponse(toolCalls, model, logger, reasoning, overr
155
157
  signature: ""
156
158
  });
157
159
  for (const tc of toolCalls) {
158
- let argsObj;
159
- try {
160
- argsObj = JSON.parse(tc.arguments || "{}");
161
- } catch {
162
- logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
163
- argsObj = {};
164
- }
160
+ const args = require_helpers.servedToolArgs(tc, "object", logger);
165
161
  contentBlocks.push({
166
162
  type: "tool_use",
167
163
  id: tc.id || require_helpers.generateToolUseId(),
168
164
  name: tc.name,
169
- input: argsObj
165
+ input: args.value
170
166
  });
171
167
  }
172
168
  return {
@@ -205,18 +201,12 @@ function buildBedrockBlocksResponse(blocks, model, logger, reasoning, overrides)
205
201
  text: block.text
206
202
  });
207
203
  else {
208
- let argsObj;
209
- try {
210
- argsObj = JSON.parse(block.arguments || "{}");
211
- } catch {
212
- logger.warn(`Malformed JSON in fixture tool call arguments for "${block.name}": ${block.arguments}`);
213
- argsObj = {};
214
- }
204
+ const args = require_helpers.servedToolArgs(block, "object", logger);
215
205
  contentBlocks.push({
216
206
  type: "tool_use",
217
207
  id: block.id || require_helpers.generateToolUseId(),
218
208
  name: block.name,
219
- input: argsObj
209
+ input: args.value
220
210
  });
221
211
  }
222
212
  return {
@@ -362,9 +352,79 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
362
352
  return;
363
353
  }
364
354
  const response = await require_helpers.resolveResponse(fixture, completionReq);
355
+ const misbehavior = require_misbehavior.planMisbehavior({
356
+ wire: "bedrock-invoke",
357
+ emitsToolCallIds: true,
358
+ fixture,
359
+ response,
360
+ request: completionReq,
361
+ stream: completionReq.stream === true,
362
+ defaults,
363
+ rawHeaders: req.headers,
364
+ url: req.url
365
+ });
366
+ const addResponseEntry = (input) => {
367
+ const entry = journal.add(input);
368
+ require_misbehavior.recordMisbehaviorOutcome({
369
+ entry,
370
+ summary: misbehavior.summary,
371
+ defaults,
372
+ testId
373
+ });
374
+ return entry;
375
+ };
376
+ if (misbehavior.kind === "error") {
377
+ if (!misbehavior.summary?.evaluations.length) logger.error(`[misbehavior] ${misbehavior.message}`);
378
+ addResponseEntry({
379
+ method: req.method ?? "POST",
380
+ path: urlPath,
381
+ headers: require_helpers.flattenHeaders(req.headers),
382
+ body: completionReq,
383
+ response: {
384
+ status: misbehavior.status,
385
+ fixture
386
+ }
387
+ });
388
+ const type = misbehavior.status === 400 ? "ValidationException" : "NotImplementedException";
389
+ res.setHeader("x-amzn-errortype", type);
390
+ require_sse_writer.writeErrorResponse(res, misbehavior.status, JSON.stringify({
391
+ __type: type,
392
+ code: misbehavior.code,
393
+ message: misbehavior.message
394
+ }));
395
+ return;
396
+ }
397
+ if (misbehavior.kind === "applied") {
398
+ const prepared = require_messages.prepareClaudeMisbehavior(misbehavior, {
399
+ request: completionReq,
400
+ stream: false,
401
+ chunkSize: Math.max(1, fixture.chunkSize ?? defaults.chunkSize),
402
+ logger,
403
+ strict: require_helpers.resolveStrictMode(defaults.strict, req.headers)
404
+ });
405
+ if (prepared.stream) throw new TypeError("InvokeModel requires non-stream Claude output");
406
+ require_misbehavior.recordMisbehaviorOutcome({
407
+ entry: journal.add({
408
+ method: req.method ?? "POST",
409
+ path: urlPath,
410
+ headers: require_helpers.flattenHeaders(req.headers),
411
+ body: completionReq,
412
+ response: {
413
+ status: 200,
414
+ fixture
415
+ }
416
+ }),
417
+ summary: prepared.plan.summary,
418
+ defaults,
419
+ testId
420
+ });
421
+ res.writeHead(200, { "Content-Type": "application/json" });
422
+ res.end(JSON.stringify(prepared.body));
423
+ return;
424
+ }
365
425
  if (require_helpers.isErrorResponse(response)) {
366
426
  const status = response.status ?? 500;
367
- journal.add({
427
+ addResponseEntry({
368
428
  method: req.method ?? "POST",
369
429
  path: urlPath,
370
430
  headers: require_helpers.flattenHeaders(req.headers),
@@ -384,11 +444,11 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
384
444
  require_sse_writer.writeErrorResponse(res, status, JSON.stringify(anthropicError), { retryAfter: response.retryAfter });
385
445
  return;
386
446
  }
387
- if (require_helpers.isContentWithToolCallsResponse(response)) {
447
+ if (require_helpers.isCombinedFixtureResponse(response)) {
388
448
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
389
449
  const overrides = require_helpers.extractOverrides(response);
390
450
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
391
- journal.add({
451
+ addResponseEntry({
392
452
  method: req.method ?? "POST",
393
453
  path: urlPath,
394
454
  headers: require_helpers.flattenHeaders(req.headers),
@@ -398,6 +458,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
398
458
  fixture
399
459
  }
400
460
  });
461
+ const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, "Bedrock InvokeModel");
401
462
  if (response.blocks && response.blocks.length > 0) {
402
463
  const blocksBody = buildBedrockBlocksResponse(response.blocks, completionReq.model, logger, effReasoning, overrides);
403
464
  res.writeHead(200, { "Content-Type": "application/json" });
@@ -405,7 +466,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
405
466
  return;
406
467
  }
407
468
  const textBody = buildBedrockTextResponse(response.content ?? "", completionReq.model, effReasoning, overrides);
408
- const toolBody = buildBedrockToolCallResponse(response.toolCalls ?? [], completionReq.model, logger, void 0, overrides);
469
+ const toolBody = buildBedrockToolCallResponse(functionToolCalls, completionReq.model, logger, void 0, overrides);
409
470
  const merged = {
410
471
  ...textBody,
411
472
  content: [...textBody.content, ...toolBody.content],
@@ -419,7 +480,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
419
480
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
420
481
  const overrides = require_helpers.extractOverrides(response);
421
482
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
422
- journal.add({
483
+ addResponseEntry({
423
484
  method: req.method ?? "POST",
424
485
  path: urlPath,
425
486
  headers: require_helpers.flattenHeaders(req.headers),
@@ -438,7 +499,7 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
438
499
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
439
500
  const overrides = require_helpers.extractOverrides(response);
440
501
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
441
- journal.add({
502
+ addResponseEntry({
442
503
  method: req.method ?? "POST",
443
504
  path: urlPath,
444
505
  headers: require_helpers.flattenHeaders(req.headers),
@@ -448,12 +509,12 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
448
509
  fixture
449
510
  }
450
511
  });
451
- const body = buildBedrockToolCallResponse(response.toolCalls, completionReq.model, logger, effReasoning, overrides);
512
+ const body = buildBedrockToolCallResponse(require_helpers.requireEmittedFunctionToolCalls(response, "Bedrock InvokeModel"), completionReq.model, logger, effReasoning, overrides);
452
513
  res.writeHead(200, { "Content-Type": "application/json" });
453
514
  res.end(JSON.stringify(body));
454
515
  return;
455
516
  }
456
- journal.add({
517
+ addResponseEntry({
457
518
  method: req.method ?? "POST",
458
519
  path: urlPath,
459
520
  headers: require_helpers.flattenHeaders(req.headers),
@@ -469,6 +530,13 @@ async function handleBedrock(req, res, raw, modelId, fixtures, journal, defaults
469
530
  } }));
470
531
  }
471
532
  const BEDROCK_INVOKE_STREAM_EVENT_TYPE = "chunk";
533
+ /** Serialize Claude events as InvokeModel PayloadPart, leaving generic AWS framing unchanged. */
534
+ function writeBedrockInvokeStream(res, events, options) {
535
+ return require_aws_event_stream.writeEventStream(res, events.map((event) => ({
536
+ eventType: event.eventType,
537
+ payload: { bytes: Buffer.from(JSON.stringify(event.payload), "utf8").toString("base64") }
538
+ })), options);
539
+ }
472
540
  function buildBedrockInvokeMessageStart(model, overrides) {
473
541
  return {
474
542
  eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,
@@ -507,13 +575,7 @@ function buildBedrockInvokeMessageStop() {
507
575
  };
508
576
  }
509
577
  function parseToolArgumentsForStream(toolCall, logger) {
510
- try {
511
- const parsed = JSON.parse(toolCall.arguments || "{}");
512
- return JSON.stringify(parsed);
513
- } catch {
514
- logger.warn(`Malformed JSON in fixture tool call arguments for "${toolCall.name}": ${toolCall.arguments}`);
515
- return "{}";
516
- }
578
+ return require_helpers.servedToolArgs(toolCall, "string", logger).text;
517
579
  }
518
580
  function buildBedrockStreamTextEvents(content, model, chunkSize, reasoning, overrides) {
519
581
  const events = [];
@@ -1041,11 +1103,101 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1041
1103
  return;
1042
1104
  }
1043
1105
  const response = await require_helpers.resolveResponse(fixture, completionReq);
1106
+ const misbehavior = require_misbehavior.planMisbehavior({
1107
+ wire: "bedrock-invoke",
1108
+ emitsToolCallIds: true,
1109
+ fixture,
1110
+ response,
1111
+ request: completionReq,
1112
+ stream: completionReq.stream === true,
1113
+ defaults,
1114
+ rawHeaders: req.headers,
1115
+ url: req.url
1116
+ });
1117
+ const addResponseEntry = (input) => {
1118
+ const entry = journal.add(input);
1119
+ require_misbehavior.recordMisbehaviorOutcome({
1120
+ entry,
1121
+ summary: misbehavior.summary,
1122
+ defaults,
1123
+ testId
1124
+ });
1125
+ return entry;
1126
+ };
1127
+ if (misbehavior.kind === "error") {
1128
+ if (!misbehavior.summary?.evaluations.length) logger.error(`[misbehavior] ${misbehavior.message}`);
1129
+ addResponseEntry({
1130
+ method: req.method ?? "POST",
1131
+ path: urlPath,
1132
+ headers: require_helpers.flattenHeaders(req.headers),
1133
+ body: completionReq,
1134
+ response: {
1135
+ status: misbehavior.status,
1136
+ fixture
1137
+ }
1138
+ });
1139
+ const type = misbehavior.status === 400 ? "ValidationException" : "NotImplementedException";
1140
+ res.setHeader("x-amzn-errortype", type);
1141
+ require_sse_writer.writeErrorResponse(res, misbehavior.status, JSON.stringify({
1142
+ __type: type,
1143
+ code: misbehavior.code,
1144
+ message: misbehavior.message
1145
+ }));
1146
+ return;
1147
+ }
1044
1148
  const latency = fixture.latency ?? defaults.latency;
1045
1149
  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
1150
+ if (misbehavior.kind === "applied") {
1151
+ const prepared = require_messages.prepareClaudeMisbehavior(misbehavior, {
1152
+ request: completionReq,
1153
+ stream: true,
1154
+ chunkSize,
1155
+ logger,
1156
+ strict: require_helpers.resolveStrictMode(defaults.strict, req.headers)
1157
+ });
1158
+ if (!prepared.stream) throw new TypeError("InvokeModel stream requires Claude events");
1159
+ const entry = journal.add({
1160
+ method: req.method ?? "POST",
1161
+ path: urlPath,
1162
+ headers: require_helpers.flattenHeaders(req.headers),
1163
+ body: completionReq,
1164
+ response: {
1165
+ status: 200,
1166
+ fixture
1167
+ }
1168
+ });
1169
+ require_misbehavior.recordMisbehaviorOutcome({
1170
+ entry,
1171
+ summary: prepared.plan.summary,
1172
+ defaults,
1173
+ testId
1174
+ });
1175
+ const events = prepared.events.map((event) => ({
1176
+ eventType: BEDROCK_INVOKE_STREAM_EVENT_TYPE,
1177
+ payload: event
1178
+ }));
1179
+ const interruption = require_interruption.createInterruptionSignal(fixture);
1180
+ try {
1181
+ if (!await writeBedrockInvokeStream(res, events, {
1182
+ latency,
1183
+ streamingProfile: fixture.streamingProfile,
1184
+ recordedTimings: fixture.recordedTimings,
1185
+ replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1186
+ signal: interruption?.signal,
1187
+ onChunkSent: interruption?.tick
1188
+ })) {
1189
+ if (!res.writableEnded) res.destroy();
1190
+ entry.response.interrupted = true;
1191
+ entry.response.interruptReason = interruption?.reason();
1192
+ }
1193
+ } finally {
1194
+ interruption?.cleanup();
1195
+ }
1196
+ return;
1197
+ }
1046
1198
  if (require_helpers.isErrorResponse(response)) {
1047
1199
  const status = response.status ?? 500;
1048
- journal.add({
1200
+ addResponseEntry({
1049
1201
  method: req.method ?? "POST",
1050
1202
  path: urlPath,
1051
1203
  headers: require_helpers.flattenHeaders(req.headers),
@@ -1065,11 +1217,11 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1065
1217
  require_sse_writer.writeErrorResponse(res, status, JSON.stringify(anthropicError), { retryAfter: response.retryAfter });
1066
1218
  return;
1067
1219
  }
1068
- if (require_helpers.isContentWithToolCallsResponse(response)) {
1220
+ if (require_helpers.isCombinedFixtureResponse(response)) {
1069
1221
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
1070
1222
  const overrides = require_helpers.extractOverrides(response);
1071
1223
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
1072
- const journalEntry = journal.add({
1224
+ const journalEntry = addResponseEntry({
1073
1225
  method: req.method ?? "POST",
1074
1226
  path: urlPath,
1075
1227
  headers: require_helpers.flattenHeaders(req.headers),
@@ -1079,9 +1231,10 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1079
1231
  fixture
1080
1232
  }
1081
1233
  });
1082
- const events = buildBedrockStreamContentWithToolCallsEvents(response.content ?? "", response.toolCalls ?? [], completionReq.model, chunkSize, logger, effReasoning, overrides, response.blocks);
1234
+ const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, "Bedrock InvokeModel");
1235
+ const events = buildBedrockStreamContentWithToolCallsEvents(response.content ?? "", functionToolCalls, completionReq.model, chunkSize, logger, effReasoning, overrides, response.blocks);
1083
1236
  const interruption = require_interruption.createInterruptionSignal(fixture);
1084
- if (!await require_aws_event_stream.writeEventStream(res, events, {
1237
+ if (!await writeBedrockInvokeStream(res, events, {
1085
1238
  latency,
1086
1239
  streamingProfile: fixture.streamingProfile,
1087
1240
  recordedTimings: fixture.recordedTimings,
@@ -1100,7 +1253,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1100
1253
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
1101
1254
  const overrides = require_helpers.extractOverrides(response);
1102
1255
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
1103
- const journalEntry = journal.add({
1256
+ const journalEntry = addResponseEntry({
1104
1257
  method: req.method ?? "POST",
1105
1258
  path: urlPath,
1106
1259
  headers: require_helpers.flattenHeaders(req.headers),
@@ -1112,7 +1265,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1112
1265
  });
1113
1266
  const events = buildBedrockStreamTextEvents(response.content, completionReq.model, chunkSize, effReasoning, overrides);
1114
1267
  const interruption = require_interruption.createInterruptionSignal(fixture);
1115
- if (!await require_aws_event_stream.writeEventStream(res, events, {
1268
+ if (!await writeBedrockInvokeStream(res, events, {
1116
1269
  latency,
1117
1270
  streamingProfile: fixture.streamingProfile,
1118
1271
  recordedTimings: fixture.recordedTimings,
@@ -1131,7 +1284,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1131
1284
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Bedrock API — ignoring");
1132
1285
  const overrides = require_helpers.extractOverrides(response);
1133
1286
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, require_helpers.resolveStrictMode(defaults.strict, req.headers), logger);
1134
- const journalEntry = journal.add({
1287
+ const journalEntry = addResponseEntry({
1135
1288
  method: req.method ?? "POST",
1136
1289
  path: urlPath,
1137
1290
  headers: require_helpers.flattenHeaders(req.headers),
@@ -1141,9 +1294,9 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1141
1294
  fixture
1142
1295
  }
1143
1296
  });
1144
- const events = buildBedrockStreamToolCallEvents(response.toolCalls, completionReq.model, chunkSize, logger, effReasoning, overrides);
1297
+ const events = buildBedrockStreamToolCallEvents(require_helpers.requireEmittedFunctionToolCalls(response, "Bedrock InvokeModel"), completionReq.model, chunkSize, logger, effReasoning, overrides);
1145
1298
  const interruption = require_interruption.createInterruptionSignal(fixture);
1146
- if (!await require_aws_event_stream.writeEventStream(res, events, {
1299
+ if (!await writeBedrockInvokeStream(res, events, {
1147
1300
  latency,
1148
1301
  streamingProfile: fixture.streamingProfile,
1149
1302
  recordedTimings: fixture.recordedTimings,
@@ -1158,7 +1311,7 @@ async function handleBedrockStream(req, res, raw, modelId, fixtures, journal, de
1158
1311
  interruption?.cleanup();
1159
1312
  return;
1160
1313
  }
1161
- journal.add({
1314
+ addResponseEntry({
1162
1315
  method: req.method ?? "POST",
1163
1316
  path: urlPath,
1164
1317
  headers: require_helpers.flattenHeaders(req.headers),