@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.
Files changed (396) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +46 -0
  4. package/README.md +14 -2
  5. package/dist/agui-handler.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 +344 -43
  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 +345 -44
  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 +9 -5
  25. package/dist/chaos.cjs.map +1 -1
  26. package/dist/chaos.d.cts.map +1 -1
  27. package/dist/chaos.d.ts.map +1 -1
  28. package/dist/chaos.js +10 -7
  29. package/dist/chaos.js.map +1 -1
  30. package/dist/cli.cjs +238 -9
  31. package/dist/cli.cjs.map +1 -1
  32. package/dist/cli.js +242 -13
  33. package/dist/cli.js.map +1 -1
  34. package/dist/cohere.cjs +159 -72
  35. package/dist/cohere.cjs.map +1 -1
  36. package/dist/cohere.d.cts.map +1 -1
  37. package/dist/cohere.d.ts.map +1 -1
  38. package/dist/cohere.js +160 -73
  39. package/dist/cohere.js.map +1 -1
  40. package/dist/config-loader.cjs +63 -5
  41. package/dist/config-loader.cjs.map +1 -1
  42. package/dist/config-loader.d.cts +37 -4
  43. package/dist/config-loader.d.cts.map +1 -1
  44. package/dist/config-loader.d.ts +37 -4
  45. package/dist/config-loader.d.ts.map +1 -1
  46. package/dist/config-loader.js +63 -5
  47. package/dist/config-loader.js.map +1 -1
  48. package/dist/constants.cjs +8 -0
  49. package/dist/constants.cjs.map +1 -1
  50. package/dist/constants.d.cts +6 -2
  51. package/dist/constants.d.ts +6 -2
  52. package/dist/constants.js +8 -1
  53. package/dist/constants.js.map +1 -1
  54. package/dist/echo-text.cjs +65 -0
  55. package/dist/echo-text.cjs.map +1 -0
  56. package/dist/echo-text.d.cts +22 -0
  57. package/dist/echo-text.d.cts.map +1 -0
  58. package/dist/echo-text.d.ts +22 -0
  59. package/dist/echo-text.d.ts.map +1 -0
  60. package/dist/echo-text.js +65 -0
  61. package/dist/echo-text.js.map +1 -0
  62. package/dist/embeddings.cjs +18 -1
  63. package/dist/embeddings.cjs.map +1 -1
  64. package/dist/embeddings.d.cts +1 -1
  65. package/dist/embeddings.d.cts.map +1 -1
  66. package/dist/embeddings.d.ts +1 -1
  67. package/dist/embeddings.d.ts.map +1 -1
  68. package/dist/embeddings.js +18 -1
  69. package/dist/embeddings.js.map +1 -1
  70. package/dist/fakes-plugin.cjs +131 -0
  71. package/dist/fakes-plugin.cjs.map +1 -0
  72. package/dist/fakes-plugin.d.cts +23 -0
  73. package/dist/fakes-plugin.d.cts.map +1 -0
  74. package/dist/fakes-plugin.d.ts +23 -0
  75. package/dist/fakes-plugin.d.ts.map +1 -0
  76. package/dist/fakes-plugin.js +127 -0
  77. package/dist/fakes-plugin.js.map +1 -0
  78. package/dist/files.cjs +9 -11
  79. package/dist/files.cjs.map +1 -1
  80. package/dist/files.d.cts.map +1 -1
  81. package/dist/files.d.ts.map +1 -1
  82. package/dist/files.js +10 -13
  83. package/dist/files.js.map +1 -1
  84. package/dist/fine-tuning.cjs +1 -19
  85. package/dist/fine-tuning.cjs.map +1 -1
  86. package/dist/fine-tuning.d.cts.map +1 -1
  87. package/dist/fine-tuning.d.ts.map +1 -1
  88. package/dist/fine-tuning.js +2 -20
  89. package/dist/fine-tuning.js.map +1 -1
  90. package/dist/fixture-loader-services.cjs +116 -0
  91. package/dist/fixture-loader-services.cjs.map +1 -0
  92. package/dist/fixture-loader-services.d.cts +48 -0
  93. package/dist/fixture-loader-services.d.cts.map +1 -0
  94. package/dist/fixture-loader-services.d.ts +48 -0
  95. package/dist/fixture-loader-services.d.ts.map +1 -0
  96. package/dist/fixture-loader-services.js +114 -0
  97. package/dist/fixture-loader-services.js.map +1 -0
  98. package/dist/fixture-loader.cjs +552 -29
  99. package/dist/fixture-loader.cjs.map +1 -1
  100. package/dist/fixture-loader.d.cts +140 -2
  101. package/dist/fixture-loader.d.cts.map +1 -1
  102. package/dist/fixture-loader.d.ts +140 -2
  103. package/dist/fixture-loader.d.ts.map +1 -1
  104. package/dist/fixture-loader.js +542 -31
  105. package/dist/fixture-loader.js.map +1 -1
  106. package/dist/gemini-embeddings.cjs +42 -2
  107. package/dist/gemini-embeddings.cjs.map +1 -1
  108. package/dist/gemini-embeddings.js +43 -3
  109. package/dist/gemini-embeddings.js.map +1 -1
  110. package/dist/gemini-interactions.cjs +288 -52
  111. package/dist/gemini-interactions.cjs.map +1 -1
  112. package/dist/gemini-interactions.d.cts.map +1 -1
  113. package/dist/gemini-interactions.d.ts.map +1 -1
  114. package/dist/gemini-interactions.js +289 -53
  115. package/dist/gemini-interactions.js.map +1 -1
  116. package/dist/gemini.cjs +234 -38
  117. package/dist/gemini.cjs.map +1 -1
  118. package/dist/gemini.d.cts.map +1 -1
  119. package/dist/gemini.d.ts.map +1 -1
  120. package/dist/gemini.js +235 -39
  121. package/dist/gemini.js.map +1 -1
  122. package/dist/helpers.cjs +1157 -12
  123. package/dist/helpers.cjs.map +1 -1
  124. package/dist/helpers.d.cts +85 -4
  125. package/dist/helpers.d.cts.map +1 -1
  126. package/dist/helpers.d.ts +85 -4
  127. package/dist/helpers.d.ts.map +1 -1
  128. package/dist/helpers.js +1113 -14
  129. package/dist/helpers.js.map +1 -1
  130. package/dist/images.cjs +3 -2
  131. package/dist/images.cjs.map +1 -1
  132. package/dist/images.js +3 -2
  133. package/dist/images.js.map +1 -1
  134. package/dist/index.cjs +39 -1
  135. package/dist/index.d.cts +11 -4
  136. package/dist/index.d.ts +11 -4
  137. package/dist/index.js +11 -4
  138. package/dist/jest.cjs +43 -14
  139. package/dist/jest.cjs.map +1 -1
  140. package/dist/jest.d.cts +47 -5
  141. package/dist/jest.d.cts.map +1 -1
  142. package/dist/jest.d.ts +47 -5
  143. package/dist/jest.d.ts.map +1 -1
  144. package/dist/jest.js +45 -16
  145. package/dist/jest.js.map +1 -1
  146. package/dist/journal.cjs +155 -13
  147. package/dist/journal.cjs.map +1 -1
  148. package/dist/journal.d.cts +54 -4
  149. package/dist/journal.d.cts.map +1 -1
  150. package/dist/journal.d.ts +54 -4
  151. package/dist/journal.d.ts.map +1 -1
  152. package/dist/journal.js +155 -13
  153. package/dist/journal.js.map +1 -1
  154. package/dist/live-sanitize.cjs +4 -32
  155. package/dist/live-sanitize.cjs.map +1 -1
  156. package/dist/live-sanitize.js +4 -32
  157. package/dist/live-sanitize.js.map +1 -1
  158. package/dist/llmock.cjs +204 -39
  159. package/dist/llmock.cjs.map +1 -1
  160. package/dist/llmock.d.cts +51 -1
  161. package/dist/llmock.d.cts.map +1 -1
  162. package/dist/llmock.d.ts +51 -1
  163. package/dist/llmock.d.ts.map +1 -1
  164. package/dist/llmock.js +206 -41
  165. package/dist/llmock.js.map +1 -1
  166. package/dist/mcp-fakes-mount.cjs +217 -0
  167. package/dist/mcp-fakes-mount.cjs.map +1 -0
  168. package/dist/mcp-fakes-mount.js +211 -0
  169. package/dist/mcp-fakes-mount.js.map +1 -0
  170. package/dist/mcp-fakes-report.cjs +111 -0
  171. package/dist/mcp-fakes-report.cjs.map +1 -0
  172. package/dist/mcp-fakes-report.d.cts +40 -0
  173. package/dist/mcp-fakes-report.d.cts.map +1 -0
  174. package/dist/mcp-fakes-report.d.ts +40 -0
  175. package/dist/mcp-fakes-report.d.ts.map +1 -0
  176. package/dist/mcp-fakes-report.js +107 -0
  177. package/dist/mcp-fakes-report.js.map +1 -0
  178. package/dist/mcp-fakes.cjs +1942 -0
  179. package/dist/mcp-fakes.cjs.map +1 -0
  180. package/dist/mcp-fakes.d.cts +504 -0
  181. package/dist/mcp-fakes.d.cts.map +1 -0
  182. package/dist/mcp-fakes.d.ts +504 -0
  183. package/dist/mcp-fakes.d.ts.map +1 -0
  184. package/dist/mcp-fakes.js +1937 -0
  185. package/dist/mcp-fakes.js.map +1 -0
  186. package/dist/mcp-handler.cjs +534 -27
  187. package/dist/mcp-handler.cjs.map +1 -1
  188. package/dist/mcp-handler.d.cts +49 -0
  189. package/dist/mcp-handler.d.cts.map +1 -0
  190. package/dist/mcp-handler.d.ts +49 -0
  191. package/dist/mcp-handler.d.ts.map +1 -0
  192. package/dist/mcp-handler.js +530 -28
  193. package/dist/mcp-handler.js.map +1 -1
  194. package/dist/mcp-mock.cjs +326 -47
  195. package/dist/mcp-mock.cjs.map +1 -1
  196. package/dist/mcp-mock.d.cts +97 -1
  197. package/dist/mcp-mock.d.cts.map +1 -1
  198. package/dist/mcp-mock.d.ts +97 -1
  199. package/dist/mcp-mock.d.ts.map +1 -1
  200. package/dist/mcp-mock.js +327 -48
  201. package/dist/mcp-mock.js.map +1 -1
  202. package/dist/mcp-recorder.cjs +1224 -0
  203. package/dist/mcp-recorder.cjs.map +1 -0
  204. package/dist/mcp-recorder.d.cts +108 -0
  205. package/dist/mcp-recorder.d.cts.map +1 -0
  206. package/dist/mcp-recorder.d.ts +108 -0
  207. package/dist/mcp-recorder.d.ts.map +1 -0
  208. package/dist/mcp-recorder.js +1215 -0
  209. package/dist/mcp-recorder.js.map +1 -0
  210. package/dist/mcp-stub.cjs +5 -1
  211. package/dist/mcp-stub.d.cts +3 -1
  212. package/dist/mcp-stub.d.ts +3 -1
  213. package/dist/mcp-stub.js +3 -1
  214. package/dist/mcp-types.d.cts +6 -0
  215. package/dist/mcp-types.d.ts +6 -0
  216. package/dist/message-text.cjs +192 -0
  217. package/dist/message-text.cjs.map +1 -0
  218. package/dist/message-text.d.cts +31 -0
  219. package/dist/message-text.d.cts.map +1 -0
  220. package/dist/message-text.d.ts +31 -0
  221. package/dist/message-text.d.ts.map +1 -0
  222. package/dist/message-text.js +184 -0
  223. package/dist/message-text.js.map +1 -0
  224. package/dist/messages.cjs +400 -56
  225. package/dist/messages.cjs.map +1 -1
  226. package/dist/messages.d.cts.map +1 -1
  227. package/dist/messages.d.ts.map +1 -1
  228. package/dist/messages.js +401 -58
  229. package/dist/messages.js.map +1 -1
  230. package/dist/metrics.cjs +46 -66
  231. package/dist/metrics.cjs.map +1 -1
  232. package/dist/metrics.d.cts +14 -6
  233. package/dist/metrics.d.cts.map +1 -1
  234. package/dist/metrics.d.ts +14 -6
  235. package/dist/metrics.d.ts.map +1 -1
  236. package/dist/metrics.js +32 -40
  237. package/dist/metrics.js.map +1 -1
  238. package/dist/misbehavior.cjs +1523 -0
  239. package/dist/misbehavior.cjs.map +1 -0
  240. package/dist/misbehavior.d.cts +43 -0
  241. package/dist/misbehavior.d.cts.map +1 -0
  242. package/dist/misbehavior.d.ts +43 -0
  243. package/dist/misbehavior.d.ts.map +1 -0
  244. package/dist/misbehavior.js +1511 -0
  245. package/dist/misbehavior.js.map +1 -0
  246. package/dist/ollama.cjs +315 -113
  247. package/dist/ollama.cjs.map +1 -1
  248. package/dist/ollama.d.cts.map +1 -1
  249. package/dist/ollama.d.ts.map +1 -1
  250. package/dist/ollama.js +316 -114
  251. package/dist/ollama.js.map +1 -1
  252. package/dist/openapi.cjs +3405 -0
  253. package/dist/openapi.cjs.map +1 -0
  254. package/dist/openapi.d.cts +30 -0
  255. package/dist/openapi.d.cts.map +1 -0
  256. package/dist/openapi.d.ts +30 -0
  257. package/dist/openapi.d.ts.map +1 -0
  258. package/dist/openapi.js +3404 -0
  259. package/dist/openapi.js.map +1 -0
  260. package/dist/openrouter-video.cjs +4 -4
  261. package/dist/openrouter-video.cjs.map +1 -1
  262. package/dist/openrouter-video.d.cts.map +1 -1
  263. package/dist/openrouter-video.d.ts.map +1 -1
  264. package/dist/openrouter-video.js +4 -4
  265. package/dist/openrouter-video.js.map +1 -1
  266. package/dist/record-sanitize.cjs +231 -0
  267. package/dist/record-sanitize.cjs.map +1 -0
  268. package/dist/record-sanitize.js +224 -0
  269. package/dist/record-sanitize.js.map +1 -0
  270. package/dist/recorder.cjs +115 -6
  271. package/dist/recorder.cjs.map +1 -1
  272. package/dist/recorder.d.cts +2 -1
  273. package/dist/recorder.d.cts.map +1 -1
  274. package/dist/recorder.d.ts +2 -1
  275. package/dist/recorder.d.ts.map +1 -1
  276. package/dist/recorder.js +116 -8
  277. package/dist/recorder.js.map +1 -1
  278. package/dist/responses.cjs +701 -166
  279. package/dist/responses.cjs.map +1 -1
  280. package/dist/responses.d.cts +5 -13
  281. package/dist/responses.d.cts.map +1 -1
  282. package/dist/responses.d.ts +5 -13
  283. package/dist/responses.d.ts.map +1 -1
  284. package/dist/responses.js +699 -169
  285. package/dist/responses.js.map +1 -1
  286. package/dist/route-registry.cjs +951 -0
  287. package/dist/route-registry.cjs.map +1 -0
  288. package/dist/route-registry.d.cts +33 -0
  289. package/dist/route-registry.d.cts.map +1 -0
  290. package/dist/route-registry.d.ts +33 -0
  291. package/dist/route-registry.d.ts.map +1 -0
  292. package/dist/route-registry.js +866 -0
  293. package/dist/route-registry.js.map +1 -0
  294. package/dist/router.cjs +24 -2
  295. package/dist/router.cjs.map +1 -1
  296. package/dist/router.d.cts.map +1 -1
  297. package/dist/router.d.ts.map +1 -1
  298. package/dist/router.js +25 -4
  299. package/dist/router.js.map +1 -1
  300. package/dist/server.cjs +1159 -264
  301. package/dist/server.cjs.map +1 -1
  302. package/dist/server.d.cts +4 -1
  303. package/dist/server.d.cts.map +1 -1
  304. package/dist/server.d.ts +4 -1
  305. package/dist/server.d.ts.map +1 -1
  306. package/dist/server.js +1067 -172
  307. package/dist/server.js.map +1 -1
  308. package/dist/speech.cjs +4 -2
  309. package/dist/speech.cjs.map +1 -1
  310. package/dist/speech.js +4 -2
  311. package/dist/speech.js.map +1 -1
  312. package/dist/stream-collapse.cjs +236 -34
  313. package/dist/stream-collapse.cjs.map +1 -1
  314. package/dist/stream-collapse.d.cts +39 -4
  315. package/dist/stream-collapse.d.cts.map +1 -1
  316. package/dist/stream-collapse.d.ts +39 -4
  317. package/dist/stream-collapse.d.ts.map +1 -1
  318. package/dist/stream-collapse.js +235 -35
  319. package/dist/stream-collapse.js.map +1 -1
  320. package/dist/suite.cjs +1 -1
  321. package/dist/suite.js +1 -1
  322. package/dist/transcription.cjs +2 -2
  323. package/dist/transcription.cjs.map +1 -1
  324. package/dist/transcription.d.cts.map +1 -1
  325. package/dist/transcription.d.ts.map +1 -1
  326. package/dist/transcription.js +2 -2
  327. package/dist/transcription.js.map +1 -1
  328. package/dist/types.cjs +18 -0
  329. package/dist/types.cjs.map +1 -0
  330. package/dist/types.d.cts +516 -5
  331. package/dist/types.d.cts.map +1 -1
  332. package/dist/types.d.ts +516 -5
  333. package/dist/types.d.ts.map +1 -1
  334. package/dist/types.js +17 -0
  335. package/dist/types.js.map +1 -0
  336. package/dist/validate-cli.cjs +123 -33
  337. package/dist/validate-cli.cjs.map +1 -1
  338. package/dist/validate-cli.js +125 -35
  339. package/dist/validate-cli.js.map +1 -1
  340. package/dist/vector-stores.cjs +1180 -0
  341. package/dist/vector-stores.cjs.map +1 -0
  342. package/dist/vector-stores.d.cts +106 -0
  343. package/dist/vector-stores.d.cts.map +1 -0
  344. package/dist/vector-stores.d.ts +106 -0
  345. package/dist/vector-stores.d.ts.map +1 -0
  346. package/dist/vector-stores.js +1164 -0
  347. package/dist/vector-stores.js.map +1 -0
  348. package/dist/vector-types.d.cts.map +1 -1
  349. package/dist/version.cjs +45 -0
  350. package/dist/version.cjs.map +1 -0
  351. package/dist/version.js +44 -0
  352. package/dist/version.js.map +1 -0
  353. package/dist/video.cjs +19 -0
  354. package/dist/video.cjs.map +1 -1
  355. package/dist/video.d.cts.map +1 -1
  356. package/dist/video.d.ts.map +1 -1
  357. package/dist/video.js +19 -0
  358. package/dist/video.js.map +1 -1
  359. package/dist/vitest.cjs +77 -16
  360. package/dist/vitest.cjs.map +1 -1
  361. package/dist/vitest.d.cts +38 -5
  362. package/dist/vitest.d.cts.map +1 -1
  363. package/dist/vitest.d.ts +38 -5
  364. package/dist/vitest.d.ts.map +1 -1
  365. package/dist/vitest.js +78 -17
  366. package/dist/vitest.js.map +1 -1
  367. package/dist/watcher.cjs +6 -2
  368. package/dist/watcher.cjs.map +1 -1
  369. package/dist/watcher.js +6 -2
  370. package/dist/watcher.js.map +1 -1
  371. package/dist/ws-gemini-live.cjs +210 -101
  372. package/dist/ws-gemini-live.cjs.map +1 -1
  373. package/dist/ws-gemini-live.d.cts +9 -3
  374. package/dist/ws-gemini-live.d.cts.map +1 -1
  375. package/dist/ws-gemini-live.d.ts +9 -3
  376. package/dist/ws-gemini-live.d.ts.map +1 -1
  377. package/dist/ws-gemini-live.js +211 -102
  378. package/dist/ws-gemini-live.js.map +1 -1
  379. package/dist/ws-realtime.cjs +175 -62
  380. package/dist/ws-realtime.cjs.map +1 -1
  381. package/dist/ws-realtime.d.cts +8 -3
  382. package/dist/ws-realtime.d.cts.map +1 -1
  383. package/dist/ws-realtime.d.ts +8 -3
  384. package/dist/ws-realtime.d.ts.map +1 -1
  385. package/dist/ws-realtime.js +176 -63
  386. package/dist/ws-realtime.js.map +1 -1
  387. package/dist/ws-responses.cjs +121 -16
  388. package/dist/ws-responses.cjs.map +1 -1
  389. package/dist/ws-responses.d.cts +8 -12
  390. package/dist/ws-responses.d.cts.map +1 -1
  391. package/dist/ws-responses.d.ts +8 -12
  392. package/dist/ws-responses.d.ts.map +1 -1
  393. package/dist/ws-responses.js +123 -18
  394. package/dist/ws-responses.js.map +1 -1
  395. package/package.json +13 -2
  396. package/skills/write-fixtures/SKILL.md +179 -21
package/dist/cohere.js CHANGED
@@ -1,6 +1,7 @@
1
- import { extractOverrides, flattenHeaders, generateDeterministicEmbedding, generateMessageId, generateToolCallId, getContext, getTestId, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isJsonObject, isTextResponse, isToolCallResponse, resolveFixtureBlockOutcome, resolveReasoningForModel, resolveResponse, resolveStrictMode, serializeErrorResponse, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField, validateChatMessages, validateToolsField } from "./helpers.js";
1
+ import { extractOverrides, flattenHeaders, generateDeterministicEmbedding, generateMessageId, generateToolCallId, getContext, getTestId, isCombinedFixtureResponse, isEmbeddingResponse, isErrorResponse, isJsonObject, isTextResponse, isToolCallResponse, prepareOpenAIChatMisbehavior, requireEmittedFunctionToolCalls, resolveFixtureBlockOutcome, resolveOpenAIChatMisbehaviorUsage, resolveReasoningForModel, resolveResponse, resolveStrictMode, serializeErrorResponse, servedToolArgs, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField, validateChatMessages, validateToolsField } from "./helpers.js";
2
2
  import { calculateDelay, delay, writeErrorResponse } from "./sse-writer.js";
3
3
  import { applyChaosAsync } from "./chaos.js";
4
+ import { normalizeDirectToolSchema, planMisbehavior, recordMisbehaviorOutcome } from "./misbehavior.js";
4
5
  import { matchFixtureDiagnostic, recordMatchOptions } from "./router.js";
5
6
  import { proxyAndRecord } from "./recorder.js";
6
7
  import { createInterruptionSignal } from "./interruption.js";
@@ -96,12 +97,17 @@ function cohereToCompletionRequest(req) {
96
97
  parameters: t.function.parameters
97
98
  }
98
99
  };
100
+ const schema = normalizeDirectToolSchema({ tools: [t] }, t.name);
99
101
  return {
100
102
  type: "function",
101
103
  function: {
102
104
  name: t.name,
103
105
  description: t.description,
104
- parameters: t.parameter_definitions
106
+ parameters: schema ? {
107
+ type: "object",
108
+ properties: schema.properties,
109
+ required: [...schema.required]
110
+ } : void 0
105
111
  }
106
112
  };
107
113
  });
@@ -140,14 +146,7 @@ function buildCohereTextResponse(content, reasoning, overrides) {
140
146
  }
141
147
  function buildCohereToolCallResponse(toolCalls, logger, reasoning, overrides) {
142
148
  const cohereCalls = toolCalls.map((tc) => {
143
- let argsJson;
144
- try {
145
- JSON.parse(tc.arguments || "{}");
146
- argsJson = tc.arguments || "{}";
147
- } catch {
148
- logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
149
- argsJson = "{}";
150
- }
149
+ const argsJson = servedToolArgs(tc, "string", logger).raw;
151
150
  return {
152
151
  id: tc.id || generateToolCallId(),
153
152
  type: "function",
@@ -183,14 +182,7 @@ function buildCohereContentWithToolCallsResponse(content, toolCalls, logger, rea
183
182
  arguments: b.arguments,
184
183
  id: b.id
185
184
  })) : toolCalls).map((tc) => {
186
- let argsJson;
187
- try {
188
- JSON.parse(tc.arguments || "{}");
189
- argsJson = tc.arguments || "{}";
190
- } catch {
191
- logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
192
- argsJson = "{}";
193
- }
185
+ const argsJson = servedToolArgs(tc, "string", logger).raw;
194
186
  return {
195
187
  id: tc.id || generateToolCallId(),
196
188
  type: "function",
@@ -335,14 +327,7 @@ function buildCohereToolCallStreamEvents(toolCalls, chunkSize, logger, reasoning
335
327
  for (let idx = 0; idx < toolCalls.length; idx++) {
336
328
  const tc = toolCalls[idx];
337
329
  const callId = tc.id || generateToolCallId();
338
- let argsJson;
339
- try {
340
- JSON.parse(tc.arguments || "{}");
341
- argsJson = tc.arguments || "{}";
342
- } catch {
343
- logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
344
- argsJson = "{}";
345
- }
330
+ const argsJson = servedToolArgs(tc, "string", logger).raw;
346
331
  events.push({
347
332
  type: "tool-call-start",
348
333
  index: idx,
@@ -430,14 +415,7 @@ function buildCohereContentWithToolCallsStreamEvents(content, toolCalls, chunkSi
430
415
  toolPlanEmitted = true;
431
416
  }
432
417
  const callId = block.id || generateToolCallId();
433
- let argsJson;
434
- try {
435
- JSON.parse(block.arguments || "{}");
436
- argsJson = block.arguments || "{}";
437
- } catch {
438
- logger.warn(`Malformed JSON in fixture tool call arguments for "${block.name}": ${block.arguments}`);
439
- argsJson = "{}";
440
- }
418
+ const argsJson = servedToolArgs(block, "string", logger).raw;
441
419
  events.push({
442
420
  type: "tool-call-start",
443
421
  index: toolIdx,
@@ -517,14 +495,7 @@ function buildCohereContentWithToolCallsStreamEvents(content, toolCalls, chunkSi
517
495
  for (let idx = 0; idx < toolCalls.length; idx++) {
518
496
  const tc = toolCalls[idx];
519
497
  const callId = tc.id || generateToolCallId();
520
- let argsJson;
521
- try {
522
- JSON.parse(tc.arguments || "{}");
523
- argsJson = tc.arguments || "{}";
524
- } catch {
525
- logger.warn(`Malformed JSON in fixture tool call arguments for "${tc.name}": ${tc.arguments}`);
526
- argsJson = "{}";
527
- }
498
+ const argsJson = servedToolArgs(tc, "string", logger).raw;
528
499
  events.push({
529
500
  type: "tool-call-start",
530
501
  index: idx,
@@ -581,7 +552,10 @@ async function writeCohereSSEStream(res, events, optionsOrLatency) {
581
552
  if (signal?.aborted) return false;
582
553
  chunkIndex++;
583
554
  }
584
- if (!res.writableEnded) res.end();
555
+ if (!res.writableEnded) {
556
+ if (opts.terminalSentinel && !signal?.aborted) res.write("data: [DONE]\n\n");
557
+ res.end();
558
+ }
585
559
  return true;
586
560
  }
587
561
  async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
@@ -642,7 +616,11 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
642
616
  } }));
643
617
  return;
644
618
  }
645
- const shapeError = validateChatMessages(cohereReq.messages) ?? validateToolsField(cohereReq.tools);
619
+ let shapeError = validateChatMessages(cohereReq.messages) ?? validateToolsField(cohereReq.tools);
620
+ if (!shapeError && Array.isArray(cohereReq.tools)) {
621
+ const nullFunctionIndex = cohereReq.tools.findIndex((tool) => "function" in tool && tool.function === null);
622
+ if (nullFunctionIndex !== -1) shapeError = `tools[${nullFunctionIndex}].function must be an object`;
623
+ }
646
624
  if (shapeError) {
647
625
  journal.add({
648
626
  method: req.method ?? "POST",
@@ -732,29 +710,79 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
732
710
  } }));
733
711
  return;
734
712
  }
735
- const response = await resolveResponse(fixture, completionReq);
713
+ const resolvedResponse = await resolveResponse(fixture, completionReq);
714
+ const misbehavior = planMisbehavior({
715
+ wire: "cohere",
716
+ fixture,
717
+ response: resolvedResponse,
718
+ request: completionReq,
719
+ stream: cohereReq.stream === true,
720
+ emitsToolCallIds: true,
721
+ defaults,
722
+ rawHeaders: req.headers,
723
+ url: req.url
724
+ });
725
+ if (misbehavior.kind === "error") {
726
+ recordMisbehaviorOutcome({
727
+ entry: journal.add({
728
+ method: req.method ?? "POST",
729
+ path: req.url ?? "/v2/chat",
730
+ headers: flattenHeaders(req.headers),
731
+ body: completionReq,
732
+ response: {
733
+ status: misbehavior.status,
734
+ fixture
735
+ }
736
+ }),
737
+ summary: misbehavior.summary,
738
+ defaults,
739
+ testId
740
+ });
741
+ if (!misbehavior.summary?.evaluations.length) logger.error(misbehavior.message);
742
+ writeErrorResponse(res, misbehavior.status, JSON.stringify({
743
+ message: misbehavior.message,
744
+ code: misbehavior.code
745
+ }));
746
+ return;
747
+ }
748
+ const prepared = misbehavior.kind === "applied" ? prepareOpenAIChatMisbehavior(misbehavior) : void 0;
749
+ const observedK5Stream = cohereReq.stream === true && prepared?.summary.fault === "stop-length-mid-tool";
750
+ const appliedReasoning = prepared && "reasoning" in prepared.response ? resolveReasoningForModel(prepared.response.reasoning, cohereReq.model, resolveStrictMode(defaults.strict, req.headers), logger) : void 0;
751
+ const usage = prepared ? resolveOpenAIChatMisbehaviorUsage(prepared, completionReq, appliedReasoning !== void 0) : void 0;
752
+ const response = prepared && usage ? {
753
+ ...prepared.response,
754
+ usage,
755
+ ...prepared.stop ? { finishReason: observedK5Stream ? "tool_calls" : prepared.stop } : {}
756
+ } : resolvedResponse;
757
+ const summary = prepared?.summary ?? misbehavior.summary;
758
+ const empty = prepared?.summary.fault === "empty-response";
736
759
  const latency = fixture.latency ?? defaults.latency;
737
760
  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
738
761
  if (isErrorResponse(response)) {
739
762
  const status = response.status ?? 500;
740
- journal.add({
741
- method: req.method ?? "POST",
742
- path: req.url ?? "/v2/chat",
743
- headers: flattenHeaders(req.headers),
744
- body: completionReq,
745
- response: {
746
- status,
747
- fixture
748
- }
763
+ recordMisbehaviorOutcome({
764
+ entry: journal.add({
765
+ method: req.method ?? "POST",
766
+ path: req.url ?? "/v2/chat",
767
+ headers: flattenHeaders(req.headers),
768
+ body: completionReq,
769
+ response: {
770
+ status,
771
+ fixture
772
+ }
773
+ }),
774
+ summary,
775
+ defaults,
776
+ testId
749
777
  });
750
778
  writeErrorResponse(res, status, serializeErrorResponse(response), { retryAfter: response.retryAfter });
751
779
  return;
752
780
  }
753
- if (isContentWithToolCallsResponse(response)) {
781
+ if (isCombinedFixtureResponse(response)) {
754
782
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Cohere v2 Chat API — ignoring");
755
783
  const overrides = extractOverrides(response);
756
784
  const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
757
- const effReasoning = resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
785
+ const effReasoning = prepared ? appliedReasoning : resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
758
786
  const journalEntry = journal.add({
759
787
  method: req.method ?? "POST",
760
788
  path: req.url ?? "/v2/chat",
@@ -765,14 +793,22 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
765
793
  fixture
766
794
  }
767
795
  });
796
+ recordMisbehaviorOutcome({
797
+ entry: journalEntry,
798
+ summary,
799
+ defaults,
800
+ testId
801
+ });
802
+ const functionToolCalls = requireEmittedFunctionToolCalls(response, "Cohere");
768
803
  if (cohereReq.stream !== true) {
769
- const body = buildCohereContentWithToolCallsResponse(response.content ?? "", response.toolCalls ?? [], logger, effReasoning, overrides, response.blocks);
804
+ const body = buildCohereContentWithToolCallsResponse(response.content ?? "", functionToolCalls, logger, effReasoning, overrides, response.blocks);
770
805
  res.writeHead(200, { "Content-Type": "application/json" });
771
806
  res.end(JSON.stringify(body));
772
807
  } else {
773
- const events = buildCohereContentWithToolCallsStreamEvents(response.content ?? "", response.toolCalls ?? [], chunkSize, logger, effReasoning, overrides, response.blocks);
808
+ const events = buildCohereContentWithToolCallsStreamEvents(response.content ?? "", functionToolCalls, chunkSize, logger, effReasoning, overrides, response.blocks);
774
809
  const interruption = createInterruptionSignal(fixture);
775
810
  if (!await writeCohereSSEStream(res, events, {
811
+ terminalSentinel: observedK5Stream,
776
812
  latency,
777
813
  streamingProfile: fixture.streamingProfile,
778
814
  recordedTimings: fixture.recordedTimings,
@@ -792,7 +828,7 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
792
828
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Cohere v2 Chat API — ignoring");
793
829
  const overrides = extractOverrides(response);
794
830
  const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
795
- const effReasoning = resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
831
+ const effReasoning = prepared ? appliedReasoning : resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
796
832
  const journalEntry = journal.add({
797
833
  method: req.method ?? "POST",
798
834
  path: req.url ?? "/v2/chat",
@@ -803,14 +839,30 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
803
839
  fixture
804
840
  }
805
841
  });
842
+ recordMisbehaviorOutcome({
843
+ entry: journalEntry,
844
+ summary,
845
+ defaults,
846
+ testId
847
+ });
806
848
  if (cohereReq.stream !== true) {
807
- const body = buildCohereTextResponse(response.content, effReasoning, overrides);
849
+ const body = empty ? {
850
+ ...buildCohereTextResponse("", void 0, overrides),
851
+ message: {
852
+ role: "assistant",
853
+ content: [],
854
+ tool_calls: [],
855
+ tool_plan: "",
856
+ citations: []
857
+ }
858
+ } : buildCohereTextResponse(response.content, effReasoning, overrides);
808
859
  res.writeHead(200, { "Content-Type": "application/json" });
809
860
  res.end(JSON.stringify(body));
810
861
  } else {
811
- const events = buildCohereTextStreamEvents(response.content, chunkSize, effReasoning, overrides);
862
+ const events = buildCohereTextStreamEvents(response.content, chunkSize, effReasoning, overrides).filter((event) => !empty || event.type === "message-start" || event.type === "message-end");
812
863
  const interruption = createInterruptionSignal(fixture);
813
864
  if (!await writeCohereSSEStream(res, events, {
865
+ terminalSentinel: observedK5Stream,
814
866
  latency,
815
867
  streamingProfile: fixture.streamingProfile,
816
868
  recordedTimings: fixture.recordedTimings,
@@ -830,7 +882,7 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
830
882
  if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Cohere v2 Chat API — ignoring");
831
883
  const overrides = extractOverrides(response);
832
884
  const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
833
- const effReasoning = resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
885
+ const effReasoning = prepared ? appliedReasoning : resolveReasoningForModel(response.reasoning, cohereReq.model, effectiveStrict, logger);
834
886
  const journalEntry = journal.add({
835
887
  method: req.method ?? "POST",
836
888
  path: req.url ?? "/v2/chat",
@@ -841,14 +893,22 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
841
893
  fixture
842
894
  }
843
895
  });
896
+ recordMisbehaviorOutcome({
897
+ entry: journalEntry,
898
+ summary,
899
+ defaults,
900
+ testId
901
+ });
902
+ const functionToolCalls = requireEmittedFunctionToolCalls(response, "Cohere");
844
903
  if (cohereReq.stream !== true) {
845
- const body = buildCohereToolCallResponse(response.toolCalls, logger, effReasoning, overrides);
904
+ const body = buildCohereToolCallResponse(functionToolCalls, logger, effReasoning, overrides);
846
905
  res.writeHead(200, { "Content-Type": "application/json" });
847
906
  res.end(JSON.stringify(body));
848
907
  } else {
849
- const events = buildCohereToolCallStreamEvents(response.toolCalls, chunkSize, logger, effReasoning, overrides);
908
+ const events = buildCohereToolCallStreamEvents(functionToolCalls, chunkSize, logger, effReasoning, overrides);
850
909
  const interruption = createInterruptionSignal(fixture);
851
910
  if (!await writeCohereSSEStream(res, events, {
911
+ terminalSentinel: observedK5Stream,
852
912
  latency,
853
913
  streamingProfile: fixture.streamingProfile,
854
914
  recordedTimings: fixture.recordedTimings,
@@ -864,15 +924,20 @@ async function handleCohere(req, res, raw, fixtures, journal, defaults, setCorsH
864
924
  }
865
925
  return;
866
926
  }
867
- journal.add({
868
- method: req.method ?? "POST",
869
- path: req.url ?? "/v2/chat",
870
- headers: flattenHeaders(req.headers),
871
- body: completionReq,
872
- response: {
873
- status: 500,
874
- fixture
875
- }
927
+ recordMisbehaviorOutcome({
928
+ entry: journal.add({
929
+ method: req.method ?? "POST",
930
+ path: req.url ?? "/v2/chat",
931
+ headers: flattenHeaders(req.headers),
932
+ body: completionReq,
933
+ response: {
934
+ status: 500,
935
+ fixture
936
+ }
937
+ }),
938
+ summary,
939
+ defaults,
940
+ testId
876
941
  });
877
942
  writeErrorResponse(res, 500, JSON.stringify({ error: {
878
943
  message: "Fixture response did not match any known type",
@@ -992,6 +1057,26 @@ async function handleCohereEmbed(req, res, raw, fixtures, journal, defaults, set
992
1057
  body: syntheticReq
993
1058
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
994
1059
  const embeddingTypes = embedReq.embedding_types && embedReq.embedding_types.length > 0 ? embedReq.embedding_types : ["float"];
1060
+ function rejectInvalidEmbeddingTypes() {
1061
+ if (embedReq.embedding_types == null) return false;
1062
+ const isArray = Array.isArray(embedReq.embedding_types);
1063
+ if (isArray && embedReq.embedding_types.every((type) => typeof type === "string")) return false;
1064
+ journal.add({
1065
+ method: req.method ?? "POST",
1066
+ path: req.url ?? "/v2/embed",
1067
+ headers: flattenHeaders(req.headers),
1068
+ body: syntheticReq,
1069
+ response: {
1070
+ status: 400,
1071
+ fixture: fixture ?? null
1072
+ }
1073
+ });
1074
+ writeErrorResponse(res, 400, JSON.stringify({ error: {
1075
+ message: isArray ? "Invalid request: embedding_types must be an array of strings" : "Invalid request: embedding_types must be an array",
1076
+ type: "invalid_request_error"
1077
+ } }));
1078
+ return true;
1079
+ }
995
1080
  if (fixture) {
996
1081
  const response = await resolveResponse(fixture, syntheticReq);
997
1082
  if (isErrorResponse(response)) {
@@ -1010,6 +1095,7 @@ async function handleCohereEmbed(req, res, raw, fixtures, journal, defaults, set
1010
1095
  return;
1011
1096
  }
1012
1097
  if (isEmbeddingResponse(response)) {
1098
+ if (rejectInvalidEmbeddingTypes()) return;
1013
1099
  journal.add({
1014
1100
  method: req.method ?? "POST",
1015
1101
  path: req.url ?? "/v2/embed",
@@ -1087,6 +1173,7 @@ async function handleCohereEmbed(req, res, raw, fixtures, journal, defaults, set
1087
1173
  return;
1088
1174
  }
1089
1175
  }
1176
+ if (rejectInvalidEmbeddingTypes()) return;
1090
1177
  logger.warn(`No embedding fixture matched for "${combinedInput.slice(0, 80)}" — returning deterministic fallback`);
1091
1178
  const dimensions = 1024;
1092
1179
  const vectors = embedReq.texts.map((text) => generateDeterministicEmbedding(text, dimensions));