@copilotkit/aimock 1.45.1 → 1.47.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 (492) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +25 -1
  4. package/README.md +11 -2
  5. package/dist/agui-mock.cjs +25 -25
  6. package/dist/agui-mock.cjs.map +1 -1
  7. package/dist/agui-mock.d.cts.map +1 -1
  8. package/dist/agui-mock.d.ts.map +1 -1
  9. package/dist/agui-mock.js +25 -25
  10. package/dist/agui-mock.js.map +1 -1
  11. package/dist/agui-types.d.cts.map +1 -1
  12. package/dist/aimock-cli.cjs +15 -1
  13. package/dist/aimock-cli.cjs.map +1 -1
  14. package/dist/aimock-cli.d.cts.map +1 -1
  15. package/dist/aimock-cli.d.ts.map +1 -1
  16. package/dist/aimock-cli.js +16 -2
  17. package/dist/aimock-cli.js.map +1 -1
  18. package/dist/api-key-auth.cjs +10 -9
  19. package/dist/api-key-auth.cjs.map +1 -1
  20. package/dist/api-key-auth.d.cts.map +1 -1
  21. package/dist/api-key-auth.d.ts.map +1 -1
  22. package/dist/api-key-auth.js +11 -10
  23. package/dist/api-key-auth.js.map +1 -1
  24. package/dist/aws-event-stream.cjs +20 -23
  25. package/dist/aws-event-stream.cjs.map +1 -1
  26. package/dist/aws-event-stream.d.cts +0 -1
  27. package/dist/aws-event-stream.d.ts +0 -1
  28. package/dist/aws-event-stream.js +20 -24
  29. package/dist/aws-event-stream.js.map +1 -1
  30. package/dist/batches.cjs +2 -4
  31. package/dist/batches.cjs.map +1 -1
  32. package/dist/batches.d.cts.map +1 -1
  33. package/dist/batches.d.ts.map +1 -1
  34. package/dist/batches.js +2 -4
  35. package/dist/batches.js.map +1 -1
  36. package/dist/bedrock-converse.cjs +139 -161
  37. package/dist/bedrock-converse.cjs.map +1 -1
  38. package/dist/bedrock-converse.d.cts.map +1 -1
  39. package/dist/bedrock-converse.d.ts.map +1 -1
  40. package/dist/bedrock-converse.js +137 -159
  41. package/dist/bedrock-converse.js.map +1 -1
  42. package/dist/bedrock.cjs +175 -216
  43. package/dist/bedrock.cjs.map +1 -1
  44. package/dist/bedrock.d.cts.map +1 -1
  45. package/dist/bedrock.d.ts.map +1 -1
  46. package/dist/bedrock.js +172 -213
  47. package/dist/bedrock.js.map +1 -1
  48. package/dist/byteplus-video.cjs +11 -10
  49. package/dist/byteplus-video.cjs.map +1 -1
  50. package/dist/byteplus-video.d.cts.map +1 -1
  51. package/dist/byteplus-video.d.ts.map +1 -1
  52. package/dist/byteplus-video.js +5 -4
  53. package/dist/byteplus-video.js.map +1 -1
  54. package/dist/chaos.cjs +5 -4
  55. package/dist/chaos.cjs.map +1 -1
  56. package/dist/chaos.d.cts.map +1 -1
  57. package/dist/chaos.d.ts.map +1 -1
  58. package/dist/chaos.js +5 -4
  59. package/dist/chaos.js.map +1 -1
  60. package/dist/cli.cjs +15 -0
  61. package/dist/cli.cjs.map +1 -1
  62. package/dist/cli.js +15 -0
  63. package/dist/cli.js.map +1 -1
  64. package/dist/cohere.cjs +107 -180
  65. package/dist/cohere.cjs.map +1 -1
  66. package/dist/cohere.d.cts.map +1 -1
  67. package/dist/cohere.d.ts.map +1 -1
  68. package/dist/cohere.js +106 -179
  69. package/dist/cohere.js.map +1 -1
  70. package/dist/config-loader.cjs +29 -1
  71. package/dist/config-loader.cjs.map +1 -1
  72. package/dist/config-loader.d.cts +7 -1
  73. package/dist/config-loader.d.cts.map +1 -1
  74. package/dist/config-loader.d.ts +7 -1
  75. package/dist/config-loader.d.ts.map +1 -1
  76. package/dist/config-loader.js +29 -2
  77. package/dist/config-loader.js.map +1 -1
  78. package/dist/count-tokens.cjs +146 -0
  79. package/dist/count-tokens.cjs.map +1 -0
  80. package/dist/count-tokens.js +146 -0
  81. package/dist/count-tokens.js.map +1 -0
  82. package/dist/elevenlabs-audio.cjs +36 -34
  83. package/dist/elevenlabs-audio.cjs.map +1 -1
  84. package/dist/elevenlabs-audio.d.cts.map +1 -1
  85. package/dist/elevenlabs-audio.d.ts.map +1 -1
  86. package/dist/elevenlabs-audio.js +33 -31
  87. package/dist/elevenlabs-audio.js.map +1 -1
  88. package/dist/elevenlabs-voice.cjs +38 -37
  89. package/dist/elevenlabs-voice.cjs.map +1 -1
  90. package/dist/elevenlabs-voice.d.cts.map +1 -1
  91. package/dist/elevenlabs-voice.d.ts.map +1 -1
  92. package/dist/elevenlabs-voice.js +33 -32
  93. package/dist/elevenlabs-voice.js.map +1 -1
  94. package/dist/embedding-request.cjs +16 -0
  95. package/dist/embedding-request.cjs.map +1 -0
  96. package/dist/embedding-request.js +14 -0
  97. package/dist/embedding-request.js.map +1 -0
  98. package/dist/embeddings.cjs +30 -20
  99. package/dist/embeddings.cjs.map +1 -1
  100. package/dist/embeddings.d.cts.map +1 -1
  101. package/dist/embeddings.d.ts.map +1 -1
  102. package/dist/embeddings.js +30 -20
  103. package/dist/embeddings.js.map +1 -1
  104. package/dist/fal-audio.cjs +45 -43
  105. package/dist/fal-audio.cjs.map +1 -1
  106. package/dist/fal-audio.d.cts.map +1 -1
  107. package/dist/fal-audio.d.ts.map +1 -1
  108. package/dist/fal-audio.js +42 -40
  109. package/dist/fal-audio.js.map +1 -1
  110. package/dist/fal.cjs +17 -15
  111. package/dist/fal.cjs.map +1 -1
  112. package/dist/fal.js +16 -14
  113. package/dist/fal.js.map +1 -1
  114. package/dist/files.cjs +2 -4
  115. package/dist/files.cjs.map +1 -1
  116. package/dist/files.d.cts.map +1 -1
  117. package/dist/files.d.ts.map +1 -1
  118. package/dist/files.js +2 -4
  119. package/dist/files.js.map +1 -1
  120. package/dist/fine-tuning.cjs +2 -4
  121. package/dist/fine-tuning.cjs.map +1 -1
  122. package/dist/fine-tuning.d.cts.map +1 -1
  123. package/dist/fine-tuning.d.ts.map +1 -1
  124. package/dist/fine-tuning.js +2 -4
  125. package/dist/fine-tuning.js.map +1 -1
  126. package/dist/fixture-loader.cjs +140 -44
  127. package/dist/fixture-loader.cjs.map +1 -1
  128. package/dist/fixture-loader.d.cts.map +1 -1
  129. package/dist/fixture-loader.d.ts.map +1 -1
  130. package/dist/fixture-loader.js +141 -46
  131. package/dist/fixture-loader.js.map +1 -1
  132. package/dist/gemini-embeddings.cjs +26 -24
  133. package/dist/gemini-embeddings.cjs.map +1 -1
  134. package/dist/gemini-embeddings.js +26 -24
  135. package/dist/gemini-embeddings.js.map +1 -1
  136. package/dist/gemini-interactions.cjs +113 -156
  137. package/dist/gemini-interactions.cjs.map +1 -1
  138. package/dist/gemini-interactions.d.cts +0 -1
  139. package/dist/gemini-interactions.d.cts.map +1 -1
  140. package/dist/gemini-interactions.d.ts +0 -1
  141. package/dist/gemini-interactions.d.ts.map +1 -1
  142. package/dist/gemini-interactions.js +113 -156
  143. package/dist/gemini-interactions.js.map +1 -1
  144. package/dist/gemini.cjs +295 -218
  145. package/dist/gemini.cjs.map +1 -1
  146. package/dist/gemini.d.cts.map +1 -1
  147. package/dist/gemini.d.ts.map +1 -1
  148. package/dist/gemini.js +295 -219
  149. package/dist/gemini.js.map +1 -1
  150. package/dist/grok-video.cjs +14 -12
  151. package/dist/grok-video.cjs.map +1 -1
  152. package/dist/grok-video.d.cts.map +1 -1
  153. package/dist/grok-video.d.ts.map +1 -1
  154. package/dist/grok-video.js +8 -6
  155. package/dist/grok-video.js.map +1 -1
  156. package/dist/helpers.cjs +411 -75
  157. package/dist/helpers.cjs.map +1 -1
  158. package/dist/helpers.d.cts +51 -1
  159. package/dist/helpers.d.cts.map +1 -1
  160. package/dist/helpers.d.ts +51 -1
  161. package/dist/helpers.d.ts.map +1 -1
  162. package/dist/helpers.js +402 -74
  163. package/dist/helpers.js.map +1 -1
  164. package/dist/images.cjs +30 -28
  165. package/dist/images.cjs.map +1 -1
  166. package/dist/images.d.cts.map +1 -1
  167. package/dist/images.d.ts.map +1 -1
  168. package/dist/images.js +27 -25
  169. package/dist/images.js.map +1 -1
  170. package/dist/index.cjs +4 -2
  171. package/dist/index.d.cts +4 -4
  172. package/dist/index.d.ts +4 -4
  173. package/dist/index.js +4 -4
  174. package/dist/journal.cjs +3 -1
  175. package/dist/journal.cjs.map +1 -1
  176. package/dist/journal.d.cts.map +1 -1
  177. package/dist/journal.d.ts.map +1 -1
  178. package/dist/journal.js +2 -1
  179. package/dist/journal.js.map +1 -1
  180. package/dist/llmock.cjs +3 -0
  181. package/dist/llmock.cjs.map +1 -1
  182. package/dist/llmock.d.cts.map +1 -1
  183. package/dist/llmock.d.ts.map +1 -1
  184. package/dist/llmock.js +3 -0
  185. package/dist/llmock.js.map +1 -1
  186. package/dist/mcp-fakes.d.cts.map +1 -1
  187. package/dist/mcp-handler.cjs +7 -3
  188. package/dist/mcp-handler.cjs.map +1 -1
  189. package/dist/mcp-handler.js +7 -3
  190. package/dist/mcp-handler.js.map +1 -1
  191. package/dist/mcp-recorder.cjs +2 -1
  192. package/dist/mcp-recorder.cjs.map +1 -1
  193. package/dist/mcp-recorder.js +3 -2
  194. package/dist/mcp-recorder.js.map +1 -1
  195. package/dist/messages.cjs +235 -202
  196. package/dist/messages.cjs.map +1 -1
  197. package/dist/messages.d.cts.map +1 -1
  198. package/dist/messages.d.ts.map +1 -1
  199. package/dist/messages.js +234 -202
  200. package/dist/messages.js.map +1 -1
  201. package/dist/metrics.cjs +5 -2
  202. package/dist/metrics.cjs.map +1 -1
  203. package/dist/metrics.d.cts.map +1 -1
  204. package/dist/metrics.d.ts.map +1 -1
  205. package/dist/metrics.js +6 -3
  206. package/dist/metrics.js.map +1 -1
  207. package/dist/misbehavior.cjs +62 -3
  208. package/dist/misbehavior.cjs.map +1 -1
  209. package/dist/misbehavior.d.cts.map +1 -1
  210. package/dist/misbehavior.d.ts.map +1 -1
  211. package/dist/misbehavior.js +63 -4
  212. package/dist/misbehavior.js.map +1 -1
  213. package/dist/model-utils.cjs +1 -0
  214. package/dist/model-utils.cjs.map +1 -1
  215. package/dist/model-utils.js +1 -1
  216. package/dist/model-utils.js.map +1 -1
  217. package/dist/moderation.cjs +15 -12
  218. package/dist/moderation.cjs.map +1 -1
  219. package/dist/moderation.js +14 -11
  220. package/dist/moderation.js.map +1 -1
  221. package/dist/ndjson-writer.cjs +21 -23
  222. package/dist/ndjson-writer.cjs.map +1 -1
  223. package/dist/ndjson-writer.d.cts +0 -1
  224. package/dist/ndjson-writer.d.cts.map +1 -1
  225. package/dist/ndjson-writer.d.ts +0 -1
  226. package/dist/ndjson-writer.d.ts.map +1 -1
  227. package/dist/ndjson-writer.js +21 -24
  228. package/dist/ndjson-writer.js.map +1 -1
  229. package/dist/ollama.cjs +276 -210
  230. package/dist/ollama.cjs.map +1 -1
  231. package/dist/ollama.d.cts.map +1 -1
  232. package/dist/ollama.d.ts.map +1 -1
  233. package/dist/ollama.js +273 -207
  234. package/dist/ollama.js.map +1 -1
  235. package/dist/openapi.cjs +323 -3
  236. package/dist/openapi.cjs.map +1 -1
  237. package/dist/openapi.d.cts.map +1 -1
  238. package/dist/openapi.d.ts.map +1 -1
  239. package/dist/openapi.js +324 -4
  240. package/dist/openapi.js.map +1 -1
  241. package/dist/openrouter-chat.cjs +11 -155
  242. package/dist/openrouter-chat.cjs.map +1 -1
  243. package/dist/openrouter-chat.js +11 -155
  244. package/dist/openrouter-chat.js.map +1 -1
  245. package/dist/openrouter-video.cjs +51 -74
  246. package/dist/openrouter-video.cjs.map +1 -1
  247. package/dist/openrouter-video.d.cts.map +1 -1
  248. package/dist/openrouter-video.d.ts.map +1 -1
  249. package/dist/openrouter-video.js +37 -60
  250. package/dist/openrouter-video.js.map +1 -1
  251. package/dist/raw-validation.cjs +177 -0
  252. package/dist/raw-validation.cjs.map +1 -0
  253. package/dist/raw-validation.js +176 -0
  254. package/dist/raw-validation.js.map +1 -0
  255. package/dist/recorder.cjs +176 -95
  256. package/dist/recorder.cjs.map +1 -1
  257. package/dist/recorder.d.cts.map +1 -1
  258. package/dist/recorder.d.ts.map +1 -1
  259. package/dist/recorder.js +176 -95
  260. package/dist/recorder.js.map +1 -1
  261. package/dist/rerank.cjs +13 -11
  262. package/dist/rerank.cjs.map +1 -1
  263. package/dist/rerank.js +12 -10
  264. package/dist/rerank.js.map +1 -1
  265. package/dist/response/catalog/anthropic-page.cjs +39 -0
  266. package/dist/response/catalog/anthropic-page.cjs.map +1 -0
  267. package/dist/response/catalog/anthropic-page.js +38 -0
  268. package/dist/response/catalog/anthropic-page.js.map +1 -0
  269. package/dist/response/catalog/collect.cjs +61 -0
  270. package/dist/response/catalog/collect.cjs.map +1 -0
  271. package/dist/response/catalog/collect.js +59 -0
  272. package/dist/response/catalog/collect.js.map +1 -0
  273. package/dist/response/catalog/gemini-page.cjs +25 -0
  274. package/dist/response/catalog/gemini-page.cjs.map +1 -0
  275. package/dist/response/catalog/gemini-page.js +24 -0
  276. package/dist/response/catalog/gemini-page.js.map +1 -0
  277. package/dist/response/catalog/render.cjs +182 -0
  278. package/dist/response/catalog/render.cjs.map +1 -0
  279. package/dist/response/catalog/render.js +171 -0
  280. package/dist/response/catalog/render.js.map +1 -0
  281. package/dist/response/deliver.cjs +144 -0
  282. package/dist/response/deliver.cjs.map +1 -0
  283. package/dist/response/deliver.js +143 -0
  284. package/dist/response/deliver.js.map +1 -0
  285. package/dist/response/errors.cjs +225 -0
  286. package/dist/response/errors.cjs.map +1 -0
  287. package/dist/response/errors.js +224 -0
  288. package/dist/response/errors.js.map +1 -0
  289. package/dist/response/finish.cjs +39 -0
  290. package/dist/response/finish.cjs.map +1 -0
  291. package/dist/response/finish.js +35 -0
  292. package/dist/response/finish.js.map +1 -0
  293. package/dist/response/frame-loop.cjs +102 -0
  294. package/dist/response/frame-loop.cjs.map +1 -0
  295. package/dist/response/frame-loop.js +100 -0
  296. package/dist/response/frame-loop.js.map +1 -0
  297. package/dist/response/lifecycle.cjs +223 -0
  298. package/dist/response/lifecycle.cjs.map +1 -0
  299. package/dist/response/lifecycle.js +211 -0
  300. package/dist/response/lifecycle.js.map +1 -0
  301. package/dist/response/policy.cjs +126 -0
  302. package/dist/response/policy.cjs.map +1 -0
  303. package/dist/response/policy.js +120 -0
  304. package/dist/response/policy.js.map +1 -0
  305. package/dist/response/profiles.cjs +69 -0
  306. package/dist/response/profiles.cjs.map +1 -0
  307. package/dist/response/profiles.js +65 -0
  308. package/dist/response/profiles.js.map +1 -0
  309. package/dist/response/proxy.cjs +71 -0
  310. package/dist/response/proxy.cjs.map +1 -0
  311. package/dist/response/proxy.js +70 -0
  312. package/dist/response/proxy.js.map +1 -0
  313. package/dist/response/raw.cjs +228 -0
  314. package/dist/response/raw.cjs.map +1 -0
  315. package/dist/response/raw.js +227 -0
  316. package/dist/response/raw.js.map +1 -0
  317. package/dist/response/timing.cjs +157 -0
  318. package/dist/response/timing.cjs.map +1 -0
  319. package/dist/response/timing.js +150 -0
  320. package/dist/response/timing.js.map +1 -0
  321. package/dist/response/usage/codecs/anthropic.cjs +52 -0
  322. package/dist/response/usage/codecs/anthropic.cjs.map +1 -0
  323. package/dist/response/usage/codecs/anthropic.js +50 -0
  324. package/dist/response/usage/codecs/anthropic.js.map +1 -0
  325. package/dist/response/usage/codecs/cohere.cjs +36 -0
  326. package/dist/response/usage/codecs/cohere.cjs.map +1 -0
  327. package/dist/response/usage/codecs/cohere.js +35 -0
  328. package/dist/response/usage/codecs/cohere.js.map +1 -0
  329. package/dist/response/usage/codecs/converse.cjs +16 -0
  330. package/dist/response/usage/codecs/converse.cjs.map +1 -0
  331. package/dist/response/usage/codecs/converse.js +15 -0
  332. package/dist/response/usage/codecs/converse.js.map +1 -0
  333. package/dist/response/usage/codecs/gemini.cjs +31 -0
  334. package/dist/response/usage/codecs/gemini.cjs.map +1 -0
  335. package/dist/response/usage/codecs/gemini.js +31 -0
  336. package/dist/response/usage/codecs/gemini.js.map +1 -0
  337. package/dist/response/usage/codecs/interactions.cjs +22 -0
  338. package/dist/response/usage/codecs/interactions.cjs.map +1 -0
  339. package/dist/response/usage/codecs/interactions.js +21 -0
  340. package/dist/response/usage/codecs/interactions.js.map +1 -0
  341. package/dist/response/usage/codecs/ollama.cjs +17 -0
  342. package/dist/response/usage/codecs/ollama.cjs.map +1 -0
  343. package/dist/response/usage/codecs/ollama.js +17 -0
  344. package/dist/response/usage/codecs/ollama.js.map +1 -0
  345. package/dist/response/usage/codecs/openai.cjs +52 -0
  346. package/dist/response/usage/codecs/openai.cjs.map +1 -0
  347. package/dist/response/usage/codecs/openai.js +50 -0
  348. package/dist/response/usage/codecs/openai.js.map +1 -0
  349. package/dist/response/usage/codecs/openrouter.cjs +68 -0
  350. package/dist/response/usage/codecs/openrouter.cjs.map +1 -0
  351. package/dist/response/usage/codecs/openrouter.js +67 -0
  352. package/dist/response/usage/codecs/openrouter.js.map +1 -0
  353. package/dist/response/usage/codecs/realtime.cjs +19 -0
  354. package/dist/response/usage/codecs/realtime.cjs.map +1 -0
  355. package/dist/response/usage/codecs/realtime.js +18 -0
  356. package/dist/response/usage/codecs/realtime.js.map +1 -0
  357. package/dist/response/usage/codecs/responses.cjs +21 -0
  358. package/dist/response/usage/codecs/responses.cjs.map +1 -0
  359. package/dist/response/usage/codecs/responses.js +20 -0
  360. package/dist/response/usage/codecs/responses.js.map +1 -0
  361. package/dist/response/usage/estimate.cjs +23 -0
  362. package/dist/response/usage/estimate.cjs.map +1 -0
  363. package/dist/response/usage/estimate.js +21 -0
  364. package/dist/response/usage/estimate.js.map +1 -0
  365. package/dist/response/usage/fields.cjs +72 -0
  366. package/dist/response/usage/fields.cjs.map +1 -0
  367. package/dist/response/usage/fields.js +70 -0
  368. package/dist/response/usage/fields.js.map +1 -0
  369. package/dist/response/usage/recording.cjs +52 -0
  370. package/dist/response/usage/recording.cjs.map +1 -0
  371. package/dist/response/usage/recording.js +52 -0
  372. package/dist/response/usage/recording.js.map +1 -0
  373. package/dist/responses.cjs +304 -196
  374. package/dist/responses.cjs.map +1 -1
  375. package/dist/responses.d.cts.map +1 -1
  376. package/dist/responses.d.ts.map +1 -1
  377. package/dist/responses.js +303 -195
  378. package/dist/responses.js.map +1 -1
  379. package/dist/route-registry.cjs +45 -0
  380. package/dist/route-registry.cjs.map +1 -1
  381. package/dist/route-registry.d.cts.map +1 -1
  382. package/dist/route-registry.d.ts.map +1 -1
  383. package/dist/route-registry.js +41 -1
  384. package/dist/route-registry.js.map +1 -1
  385. package/dist/router.cjs +24 -4
  386. package/dist/router.cjs.map +1 -1
  387. package/dist/router.d.cts +7 -1
  388. package/dist/router.d.cts.map +1 -1
  389. package/dist/router.d.ts +7 -1
  390. package/dist/router.d.ts.map +1 -1
  391. package/dist/router.js +24 -5
  392. package/dist/router.js.map +1 -1
  393. package/dist/search.cjs +13 -11
  394. package/dist/search.cjs.map +1 -1
  395. package/dist/search.js +12 -10
  396. package/dist/search.js.map +1 -1
  397. package/dist/server.cjs +293 -248
  398. package/dist/server.cjs.map +1 -1
  399. package/dist/server.d.cts.map +1 -1
  400. package/dist/server.d.ts.map +1 -1
  401. package/dist/server.js +294 -249
  402. package/dist/server.js.map +1 -1
  403. package/dist/speech.cjs +20 -18
  404. package/dist/speech.cjs.map +1 -1
  405. package/dist/speech.d.cts.map +1 -1
  406. package/dist/speech.d.ts.map +1 -1
  407. package/dist/speech.js +19 -17
  408. package/dist/speech.js.map +1 -1
  409. package/dist/sse-writer.cjs +56 -30
  410. package/dist/sse-writer.cjs.map +1 -1
  411. package/dist/sse-writer.d.cts +0 -1
  412. package/dist/sse-writer.d.cts.map +1 -1
  413. package/dist/sse-writer.d.ts +0 -1
  414. package/dist/sse-writer.d.ts.map +1 -1
  415. package/dist/sse-writer.js +55 -31
  416. package/dist/sse-writer.js.map +1 -1
  417. package/dist/stream-collapse.cjs +118 -11
  418. package/dist/stream-collapse.cjs.map +1 -1
  419. package/dist/stream-collapse.d.cts +10 -9
  420. package/dist/stream-collapse.d.cts.map +1 -1
  421. package/dist/stream-collapse.d.ts +10 -9
  422. package/dist/stream-collapse.d.ts.map +1 -1
  423. package/dist/stream-collapse.js +118 -11
  424. package/dist/stream-collapse.js.map +1 -1
  425. package/dist/transcription.cjs +31 -43
  426. package/dist/transcription.cjs.map +1 -1
  427. package/dist/transcription.d.cts.map +1 -1
  428. package/dist/transcription.d.ts.map +1 -1
  429. package/dist/transcription.js +31 -43
  430. package/dist/transcription.js.map +1 -1
  431. package/dist/types.cjs.map +1 -1
  432. package/dist/types.d.cts +231 -9
  433. package/dist/types.d.cts.map +1 -1
  434. package/dist/types.d.ts +231 -9
  435. package/dist/types.d.ts.map +1 -1
  436. package/dist/types.js.map +1 -1
  437. package/dist/vector-mock.cjs +3 -8
  438. package/dist/vector-mock.cjs.map +1 -1
  439. package/dist/vector-mock.d.cts.map +1 -1
  440. package/dist/vector-mock.d.ts.map +1 -1
  441. package/dist/vector-mock.js +3 -8
  442. package/dist/vector-mock.js.map +1 -1
  443. package/dist/vector-stores.cjs +2 -4
  444. package/dist/vector-stores.cjs.map +1 -1
  445. package/dist/vector-stores.d.cts.map +1 -1
  446. package/dist/vector-stores.d.ts.map +1 -1
  447. package/dist/vector-stores.js +2 -4
  448. package/dist/vector-stores.js.map +1 -1
  449. package/dist/veo-video.cjs +16 -14
  450. package/dist/veo-video.cjs.map +1 -1
  451. package/dist/veo-video.js +10 -8
  452. package/dist/veo-video.js.map +1 -1
  453. package/dist/video.cjs +21 -19
  454. package/dist/video.cjs.map +1 -1
  455. package/dist/video.d.cts.map +1 -1
  456. package/dist/video.d.ts.map +1 -1
  457. package/dist/video.js +20 -18
  458. package/dist/video.js.map +1 -1
  459. package/dist/ws-framing.cjs +12 -6
  460. package/dist/ws-framing.cjs.map +1 -1
  461. package/dist/ws-framing.d.cts +2 -0
  462. package/dist/ws-framing.d.cts.map +1 -1
  463. package/dist/ws-framing.d.ts +2 -0
  464. package/dist/ws-framing.d.ts.map +1 -1
  465. package/dist/ws-framing.js +12 -6
  466. package/dist/ws-framing.js.map +1 -1
  467. package/dist/ws-gemini-live.cjs +131 -96
  468. package/dist/ws-gemini-live.cjs.map +1 -1
  469. package/dist/ws-gemini-live.d.cts +0 -1
  470. package/dist/ws-gemini-live.d.cts.map +1 -1
  471. package/dist/ws-gemini-live.d.ts +0 -1
  472. package/dist/ws-gemini-live.d.ts.map +1 -1
  473. package/dist/ws-gemini-live.js +130 -95
  474. package/dist/ws-gemini-live.js.map +1 -1
  475. package/dist/ws-live.cjs +6 -5
  476. package/dist/ws-live.cjs.map +1 -1
  477. package/dist/ws-live.js +5 -4
  478. package/dist/ws-live.js.map +1 -1
  479. package/dist/ws-realtime.cjs +108 -124
  480. package/dist/ws-realtime.cjs.map +1 -1
  481. package/dist/ws-realtime.d.cts.map +1 -1
  482. package/dist/ws-realtime.d.ts.map +1 -1
  483. package/dist/ws-realtime.js +105 -121
  484. package/dist/ws-realtime.js.map +1 -1
  485. package/dist/ws-responses.cjs +80 -59
  486. package/dist/ws-responses.cjs.map +1 -1
  487. package/dist/ws-responses.d.cts.map +1 -1
  488. package/dist/ws-responses.d.ts.map +1 -1
  489. package/dist/ws-responses.js +79 -58
  490. package/dist/ws-responses.js.map +1 -1
  491. package/package.json +4 -1
  492. package/skills/write-fixtures/SKILL.md +57 -16
package/dist/helpers.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { estimatePromptTokens as estimatePromptTokens$1, estimateTokens as estimateTokens$1 } from "./response/usage/estimate.js";
2
+ import { render, resolve } from "./response/usage/codecs/openai.js";
3
+ import { renderError } from "./response/errors.js";
1
4
  import { DEFAULT_TEST_ID, MCP_FAKES_ECHO_LIMIT } from "./constants.js";
2
5
  import { cutText } from "./echo-text.js";
3
6
  import { build, fixed, msg, quote } from "./message-text.js";
@@ -212,12 +215,331 @@ function requireEmittedFunctionToolCalls(response, wire) {
212
215
  if (Array.isArray(response.blocks) && response.blocks.length > 0) return [];
213
216
  return requireFunctionToolCalls(response.toolCalls ?? []);
214
217
  }
215
- /** True for the fixture tool-call errors a handler surfaces as a coded 500. */
218
+ /**
219
+ * A fixture's model-generated `files` reached a wire that has no faithful
220
+ * projection for them. Gemini (`inlineData` parts) and the OpenAI Responses
221
+ * API (`image_generation_call` items, `image/*` only) serve generated files.
222
+ * Chat Completions (OpenAI, Azure OpenAI, OpenRouter and BytePlus ModelArk)
223
+ * and Anthropic Messages raise this through {@link rejectGeneratedFiles}, and
224
+ * the Responses API raises a subclass for a non-`image/*` file, before any
225
+ * content is written. The handler surfaces it as a coded 500
226
+ * (`aimock_unsupported_generated_file`) like {@link UnsupportedToolCallError}.
227
+ */
228
+ var UnsupportedGeneratedFileError = class extends Error {
229
+ wire;
230
+ constructor(wire) {
231
+ super(`aimock: fixture "files" (model-generated files) are only supported on Gemini and the OpenAI Responses API; this request arrived on ${wire}`);
232
+ this.name = "UnsupportedGeneratedFileError";
233
+ this.wire = wire;
234
+ }
235
+ };
236
+ /**
237
+ * Reject a fixture that sets a non-empty `files` on a wire that cannot carry
238
+ * model-generated files. Throws {@link UnsupportedGeneratedFileError} naming
239
+ * `wire`. A malformed `files` value (see {@link fixtureFiles}) throws
240
+ * {@link InvalidFixtureOutputError} (`aimock_invalid_fixture_file`) first.
241
+ * Chat Completions and Anthropic Messages call this. Gemini and OpenAI
242
+ * Responses serve `files`; other wires ignore the field.
243
+ */
244
+ function rejectGeneratedFiles(response, wire) {
245
+ if (fixtureFiles(response.files).length > 0) throw new UnsupportedGeneratedFileError(wire);
246
+ }
247
+ /**
248
+ * A fixture's `citations` or `files` is malformed: not an array, an entry
249
+ * missing a required field, a non-integer offset, citation offsets outside
250
+ * `0 <= startIndex <= endIndex <= text.length`, a file citation `index`
251
+ * outside `0 <= index <= text.length`, an offset or `index` that splits a
252
+ * UTF-16 surrogate pair, a citation that mixes URL and file citation fields,
253
+ * or any `citations` but an empty array on a turn with no text (tool calls
254
+ * only, `blocks` with no text block, or empty content). The wires that read
255
+ * these keys (Chat Completions, Anthropic Messages, Gemini and OpenAI
256
+ * Responses) read them
257
+ * through {@link fixtureFiles} and {@link fixtureCitations}, which throw this
258
+ * at serve time, before any byte is written; the handler surfaces it as a
259
+ * coded 500 like {@link UnsupportedGeneratedFileError}. Other wires ignore
260
+ * `citations` and `files`, so they never throw this. The message names the
261
+ * offending entry and how to fix the fixture.
262
+ */
263
+ var InvalidFixtureOutputError = class extends Error {
264
+ code;
265
+ constructor(code, problem) {
266
+ super(`aimock: invalid fixture "${code === "aimock_invalid_fixture_file" ? "files" : "citations"}": ${problem}`);
267
+ this.name = "InvalidFixtureOutputError";
268
+ this.code = code;
269
+ }
270
+ };
271
+ /**
272
+ * A short description of a fixture value for an error message. Never throws:
273
+ * a programmatic fixture can hold values JSON cannot carry (BigInt, Symbol,
274
+ * function, NaN, Infinity), and each gets a readable name.
275
+ */
276
+ function describeFixtureValue(value) {
277
+ if (value === void 0) return "undefined";
278
+ if (Array.isArray(value)) return "an array";
279
+ if (value !== null && typeof value === "object") return "an object";
280
+ if (typeof value === "function") return "a function";
281
+ if (typeof value === "symbol") return value.toString();
282
+ if (typeof value === "bigint") return `${value}n`;
283
+ if (typeof value === "number" && !Number.isFinite(value)) return String(value);
284
+ const json = JSON.stringify(value);
285
+ return json.length > 40 ? `${json.slice(0, 37)}...` : json;
286
+ }
287
+ /**
288
+ * The UTF-16 index `at` falls between the two halves of a surrogate pair, so
289
+ * a span that starts or ends there cuts a character in half.
290
+ */
291
+ function splitsSurrogatePair(text, at) {
292
+ if (at <= 0 || at >= text.length) return false;
293
+ const before = text.charCodeAt(at - 1);
294
+ const after = text.charCodeAt(at);
295
+ return before >= 55296 && before <= 56319 && after >= 56320 && after <= 57343;
296
+ }
297
+ /**
298
+ * `text` cut into slices of at most `chunkSize` UTF-16 units, never between
299
+ * the two halves of a surrogate pair: a cut that would land inside a pair
300
+ * moves back before it, or, when that would leave the slice empty
301
+ * (`chunkSize` 1), forward past it. The slices rejoin to `text` exactly.
302
+ */
303
+ function surrogateSafeChunks(text, chunkSize) {
304
+ const chunks = [];
305
+ for (let i = 0; i < text.length;) {
306
+ let end = Math.min(i + chunkSize, text.length);
307
+ const high = text.charCodeAt(end - 1);
308
+ const low = text.charCodeAt(end);
309
+ if (high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343) end = end - 1 > i ? end - 1 : end + 1;
310
+ chunks.push(text.slice(i, end));
311
+ i = end;
312
+ }
313
+ return chunks;
314
+ }
315
+ /** The message for a citation offset that splits a surrogate pair. */
316
+ function surrogateSplitProblem(where, at) {
317
+ return `${where} ${at} splits a UTF-16 surrogate pair (one character, e.g. an emoji); fix the offset to fall before or after the whole character`;
318
+ }
319
+ /** Fields only a URL citation has. */
320
+ const URL_CITATION_FIELDS = [
321
+ "url",
322
+ "title",
323
+ "startIndex",
324
+ "endIndex"
325
+ ];
326
+ /** Fields only a file citation has. */
327
+ const FILE_CITATION_FIELDS = [
328
+ "fileId",
329
+ "filename",
330
+ "index"
331
+ ];
332
+ /**
333
+ * A citation that mixes URL and file citation fields, or a file-shaped one
334
+ * (`fileId` / `filename` / `index`) with no `type`, which would otherwise be
335
+ * read as a URL citation and lose its file data. Undefined when the fields
336
+ * agree.
337
+ */
338
+ function mixedCitationProblem(citation, i) {
339
+ const present = (names) => names.filter((n) => citation[n] != null);
340
+ const fileFields = present(FILE_CITATION_FIELDS);
341
+ if (fileFields.length === 0) return void 0;
342
+ const urlFields = present(URL_CITATION_FIELDS);
343
+ const fix = citation.type === "file" ? `remove the URL citation fields (${urlFields.join(", ")}) from this file citation` : citation.type === "url" ? `remove the file citation fields (${fileFields.join(", ")}) from this URL citation, or set type: "file" for a file citation` : `set type: "file" for a file citation, or remove the stray fields`;
344
+ if (urlFields.length > 0) return `citations[${i}] mixes URL citation fields (${urlFields.join(", ")}) with file citation fields (${fileFields.join(", ")}); ${fix}`;
345
+ if (citation.type == null) return `citations[${i}] has file citation fields (${fileFields.join(", ")}) but no type; ${fix}`;
346
+ if (citation.type === "url") return `citations[${i}] has type "url" but file citation fields (${fileFields.join(", ")}); ${fix}`;
347
+ }
348
+ /** "an object", "a string", ... for a value that should have been an array. */
349
+ function describeFixtureKind(value) {
350
+ if (value === null) return "null";
351
+ if (value !== null && typeof value === "object") return "an object";
352
+ return typeof value === "string" ? "a string" : `a ${typeof value}`;
353
+ }
354
+ /**
355
+ * What is wrong with a fixture `files` value, or undefined when it is absent
356
+ * or an array of `{ mimeType, data }` string pairs. Shared by the serve-time
357
+ * check ({@link fixtureFiles}) and fixture load validation.
358
+ */
359
+ function fixtureFilesProblem(files) {
360
+ if (files === void 0 || files === null) return void 0;
361
+ if (!Array.isArray(files)) return `"files" must be an array of { mimeType, data } objects, got ${describeFixtureKind(files)}; wrap a single file in [ ]`;
362
+ for (let i = 0; i < files.length; i++) {
363
+ const file = files[i];
364
+ if (file === null || typeof file !== "object" || Array.isArray(file)) return `files[${i}] must be a { mimeType, data } object, got ${describeFixtureValue(file)}`;
365
+ const { mimeType, data } = file;
366
+ if (typeof mimeType !== "string" || mimeType.length === 0) return `files[${i}].mimeType must be a non-empty string, got ${describeFixtureValue(mimeType)}; set the file's MIME type, e.g. "image/png"`;
367
+ if (typeof data !== "string") return `files[${i}].data must be a string, got ${describeFixtureValue(data)}; set the base64-encoded file bytes`;
368
+ }
369
+ }
370
+ /**
371
+ * What is wrong with a fixture `citations` value, or undefined when it is
372
+ * absent or valid: an array of citation objects. A URL citation (no `type`,
373
+ * or `type: "url"`) has a non-empty string `url`, an optional string `title`
374
+ * and optional integer offsets. A file citation (`type: "file"`) has a
375
+ * non-empty string `fileId` and `filename` and an optional integer `index`;
376
+ * it has no `url`. When `text` is given, the resolved offsets must also
377
+ * satisfy `0 <= startIndex <= endIndex <= text.length`, and a file citation's
378
+ * `index` must satisfy `0 <= index <= text.length`, and no offset may split a
379
+ * UTF-16 surrogate pair. A citation must not mix URL and file citation
380
+ * fields, and one with file fields needs `type: "file"`. A `null` value, or a
381
+ * `null` optional field, is treated as absent. An empty `text` is a turn with
382
+ * no text (tool calls only, `blocks` with no text block, or empty content): a
383
+ * well-formed non-empty array is then a problem, since there is nothing to
384
+ * cite; a malformed value is reported by its shape first. Shared by the
385
+ * serve-time check ({@link fixtureCitations}) and fixture load validation.
386
+ */
387
+ function fixtureCitationsProblem(citations, text) {
388
+ if (citations === void 0 || citations === null) return void 0;
389
+ if (!Array.isArray(citations)) return `"citations" must be an array of { url, title?, startIndex?, endIndex? } or { type: "file", fileId, filename, index? } objects, got ${describeFixtureKind(citations)}; wrap a single citation in [ ]`;
390
+ const shape = citationEntriesProblem(citations, void 0);
391
+ if (shape !== void 0 || text === void 0) return shape;
392
+ if (text === "" && citations.length > 0) return "\"citations\" has nothing to cite: this turn has no text (only tool calls, or empty content); add text to the response or remove the citations";
393
+ return citationEntriesProblem(citations, text);
394
+ }
395
+ /**
396
+ * What is wrong with the entries of a `citations` array, or undefined when
397
+ * all are valid. Offsets are checked against `text` only when it is given. A
398
+ * `null` optional field (`type`, `title`, `startIndex`, `endIndex`, `index`)
399
+ * is treated as absent, as a `null` top-level key is.
400
+ */
401
+ function citationEntriesProblem(citations, text) {
402
+ for (let i = 0; i < citations.length; i++) {
403
+ const citation = citations[i];
404
+ if (citation === null || typeof citation !== "object" || Array.isArray(citation)) return `citations[${i}] must be a { url, title?, startIndex?, endIndex? } or { type: "file", fileId, filename, index? } object, got ${describeFixtureValue(citation)}`;
405
+ const fields = citation;
406
+ const url = fields.url;
407
+ const type = fields.type ?? void 0;
408
+ const title = fields.title ?? void 0;
409
+ const startIndex = fields.startIndex ?? void 0;
410
+ const endIndex = fields.endIndex ?? void 0;
411
+ if (type === void 0 || type === "url" || type === "file") {
412
+ const mixed = mixedCitationProblem(citation, i);
413
+ if (mixed !== void 0) return mixed;
414
+ }
415
+ if (type === "file") {
416
+ const problem = fixtureFileCitationProblem(citation, i, text);
417
+ if (problem !== void 0) return problem;
418
+ continue;
419
+ }
420
+ if (type !== void 0 && type !== "url") return `citations[${i}].type must be "url" or "file" when set, got ${describeFixtureValue(type)}; omit it for a URL citation`;
421
+ if (typeof url !== "string" || url.length === 0) return `citations[${i}].url must be a non-empty string, got ${describeFixtureValue(url)}; set the cited source URL`;
422
+ if (title !== void 0 && typeof title !== "string") return `citations[${i}].title must be a string when set, got ${describeFixtureValue(title)}`;
423
+ for (const [name, value] of [["startIndex", startIndex], ["endIndex", endIndex]]) if (value !== void 0 && !Number.isInteger(value)) return `citations[${i}].${name} must be an integer when set, got ${describeFixtureValue(value)}; give a character offset into the text, or omit it`;
424
+ if (text === void 0) continue;
425
+ const start = startIndex ?? 0;
426
+ const end = endIndex ?? text.length;
427
+ if (start < 0 || start > end || end > text.length) return `citations[${i}] offsets must satisfy 0 <= startIndex <= endIndex <= text length (${text.length}), got startIndex ${start}, endIndex ${end}; fix the offsets, or omit them to cite the whole text`;
428
+ if (splitsSurrogatePair(text, start)) return surrogateSplitProblem(`citations[${i}].startIndex`, start);
429
+ if (splitsSurrogatePair(text, end)) return surrogateSplitProblem(`citations[${i}].endIndex`, end);
430
+ }
431
+ }
432
+ /** What is wrong with the file citation `citations[i]`, or undefined when valid. */
433
+ function fixtureFileCitationProblem(citation, i, text) {
434
+ const { fileId, filename } = citation;
435
+ const index = citation.index ?? void 0;
436
+ if (typeof fileId !== "string" || fileId.length === 0) return `citations[${i}].fileId must be a non-empty string, got ${describeFixtureValue(fileId)}; set the cited file's ID, e.g. "file-abc123"`;
437
+ if (typeof filename !== "string" || filename.length === 0) return `citations[${i}].filename must be a non-empty string, got ${describeFixtureValue(filename)}; set the cited file's name`;
438
+ if (index !== void 0 && !Number.isInteger(index)) return `citations[${i}].index must be an integer when set, got ${describeFixtureValue(index)}; give a character position in the text, or omit it`;
439
+ if (text === void 0) return void 0;
440
+ const at = index ?? text.length;
441
+ if (at < 0 || at > text.length) return `citations[${i}].index must satisfy 0 <= index <= text length (${text.length}), got ${at}; fix the index, or omit it to cite the end of the text`;
442
+ if (splitsSurrogatePair(text, at)) return surrogateSplitProblem(`citations[${i}].index`, at);
443
+ }
444
+ /**
445
+ * Fixture `citations`, checked against the text they cite: the array itself,
446
+ * or empty when absent. Throws {@link InvalidFixtureOutputError}
447
+ * (`aimock_invalid_fixture_citation`) for every problem
448
+ * {@link fixtureCitationsProblem} reports: a malformed value, an offset
449
+ * outside the text or one that splits a surrogate pair, mixed URL and file
450
+ * citation fields, or citations on a turn with no text (`content` is empty:
451
+ * tool calls only, `blocks` with no text block, or empty content). Every
452
+ * provider that reads `citations` goes through this.
453
+ */
454
+ function fixtureCitations(content, citations) {
455
+ const problem = fixtureCitationsProblem(citations, content);
456
+ if (problem !== void 0) throw new InvalidFixtureOutputError("aimock_invalid_fixture_citation", problem);
457
+ return citations ?? [];
458
+ }
459
+ /**
460
+ * Fixture `files`, checked: the array itself, or empty when absent. Throws
461
+ * {@link InvalidFixtureOutputError} (`aimock_invalid_fixture_file`) for a
462
+ * malformed value. Every provider that reads `files` goes through this.
463
+ */
464
+ function fixtureFiles(files) {
465
+ const problem = fixtureFilesProblem(files);
466
+ if (problem !== void 0) throw new InvalidFixtureOutputError("aimock_invalid_fixture_file", problem);
467
+ return files ?? [];
468
+ }
469
+ /**
470
+ * Fixture URL `citations` against the text they cite, with defaults applied:
471
+ * the title falls back to the URL and the offsets to the whole text. Empty
472
+ * when the fixture sets none. File citations (`type: "file"`) are skipped:
473
+ * only OpenAI Responses has a wire shape for them (`file_citation`), and it
474
+ * builds those itself. Chat Completions, Anthropic Messages and Gemini, which
475
+ * resolve through here, serve URL citations only. This reads `citations`
476
+ * through {@link fixtureCitations}, so it is the serve-time check for those
477
+ * three wires: every problem {@link fixtureCitationsProblem} reports against
478
+ * `content`, including one in a file citation it then skips, throws
479
+ * {@link InvalidFixtureOutputError} (`aimock_invalid_fixture_citation`).
480
+ * OpenAI Responses calls {@link fixtureCitations} directly. Other wires
481
+ * ignore `citations`.
482
+ */
483
+ function resolveCitations(content, citations) {
484
+ return fixtureCitations(content, citations).flatMap((c) => c.type === "file" ? [] : [c]).map((c) => ({
485
+ url: c.url,
486
+ title: c.title ?? c.url,
487
+ startIndex: c.startIndex ?? 0,
488
+ endIndex: c.endIndex ?? content.length
489
+ }));
490
+ }
491
+ /**
492
+ * Fixture `citations` as Chat Completions `url_citation` annotations. File
493
+ * citations are skipped (see {@link resolveCitations}): Chat Completions has no
494
+ * `file_citation` annotation.
495
+ */
496
+ function chatCompletionAnnotations(content, citations) {
497
+ return resolveCitations(content, citations).map((c) => ({
498
+ type: "url_citation",
499
+ url_citation: {
500
+ url: c.url,
501
+ title: c.title,
502
+ start_index: c.startIndex,
503
+ end_index: c.endIndex
504
+ }
505
+ }));
506
+ }
507
+ /** `{ annotations }` for a Chat Completions message, or nothing when the fixture has no citations. */
508
+ function annotationsField(content, overrides) {
509
+ const annotations = chatCompletionAnnotations(content, overrides?.citations);
510
+ return annotations.length > 0 ? { annotations } : {};
511
+ }
512
+ /**
513
+ * The streamed form of {@link chatCompletionAnnotations}: one chunk whose
514
+ * `delta.annotations` holds every annotation, sent after the content and
515
+ * before the finish chunk. Nothing when the fixture has no citations.
516
+ */
517
+ function chatAnnotationChunks(content, overrides, envelope) {
518
+ const annotations = chatCompletionAnnotations(content, overrides?.citations);
519
+ if (annotations.length === 0) return [];
520
+ const fingerprint = overrides?.systemFingerprint;
521
+ return [{
522
+ id: envelope.id,
523
+ object: "chat.completion.chunk",
524
+ created: envelope.created,
525
+ model: envelope.model,
526
+ choices: [{
527
+ index: 0,
528
+ delta: { annotations },
529
+ logprobs: null,
530
+ finish_reason: null
531
+ }],
532
+ ...fingerprint !== void 0 && { system_fingerprint: fingerprint }
533
+ }];
534
+ }
535
+ /** True for the fixture errors a handler surfaces as a coded 500. */
216
536
  function isFixtureToolCallError(error) {
217
- return error instanceof InvalidToolArgumentsError || error instanceof UnsupportedToolCallError || error instanceof InvalidFixtureToolCallError;
537
+ return error instanceof InvalidToolArgumentsError || error instanceof UnsupportedToolCallError || error instanceof InvalidFixtureToolCallError || error instanceof UnsupportedGeneratedFileError || error instanceof InvalidFixtureOutputError;
218
538
  }
219
539
  /** The aimock error code carried in every provider envelope for a fixture tool-call error. */
220
540
  function fixtureToolCallErrorCode(error) {
541
+ if (error instanceof UnsupportedGeneratedFileError) return "aimock_unsupported_generated_file";
542
+ if (error instanceof InvalidFixtureOutputError) return error.code;
221
543
  if (error instanceof UnsupportedToolCallError) return "aimock_unsupported_tool_call";
222
544
  if (error instanceof InvalidFixtureToolCallError) return error.code;
223
545
  return "aimock_invalid_tool_arguments";
@@ -236,9 +558,10 @@ function googleFixtureToolCallErrorDetails(code) {
236
558
  }];
237
559
  }
238
560
  /**
239
- * Run a WebSocket preflight `check` that may raise a fixture tool-call error
240
- * ({@link InvalidToolArgumentsError}, {@link UnsupportedToolCallError} or
241
- * {@link InvalidFixtureToolCallError}).
561
+ * Run a WebSocket preflight `check` that may raise a fixture error
562
+ * ({@link InvalidToolArgumentsError}, {@link UnsupportedToolCallError},
563
+ * {@link InvalidFixtureToolCallError}, {@link UnsupportedGeneratedFileError}
564
+ * or {@link InvalidFixtureOutputError}).
242
565
  * Such an error marks the already-journaled entry as a 500 carrying the
243
566
  * message, then propagates to the transport's error handler.
244
567
  */
@@ -253,27 +576,6 @@ function journalFixtureToolCallError(journalEntry, check) {
253
576
  throw error;
254
577
  }
255
578
  }
256
- /**
257
- * Resolve effective strict mode from per-request header and server default.
258
- * Header values override the server default — same precedence pattern as chaos
259
- * config headers (see resolveChaosConfig in chaos.ts).
260
- *
261
- * Header: `X-AIMock-Strict` — "true"/"1" → strict on, "false"/"0" → strict off
262
- * (case-insensitive, surrounding whitespace trimmed).
263
- * When absent or unrecognised, falls back to the server-level default.
264
- */
265
- function resolveStrictMode(serverDefault, rawHeaders) {
266
- if (rawHeaders) {
267
- const header = rawHeaders["x-aimock-strict"];
268
- const rawVal = typeof header === "string" ? header : Array.isArray(header) ? header[0] : void 0;
269
- if (typeof rawVal === "string") {
270
- const val = rawVal.trim().toLowerCase();
271
- if (val === "true" || val === "1") return true;
272
- if (val === "false" || val === "0") return false;
273
- }
274
- }
275
- return serverDefault ?? false;
276
- }
277
579
  const STRICT_INTEGER_RE = /^\d+$/;
278
580
  /**
279
581
  * Strict decimal-integer grammar shared by the query/list parsers that grew
@@ -306,18 +608,6 @@ function wouldProxyMiss(effectiveStrict, record, providerKey) {
306
608
  return Boolean(record?.providers?.[providerKey]);
307
609
  }
308
610
  /**
309
- * Returns `true` or `false` when the X-AIMock-Strict header overrides the
310
- * server default, or `undefined` when it doesn't. Designed to be spread
311
- * directly into a journal entry's `response` object:
312
- *
313
- * response: { status, fixture, ...strictOverrideField(defaults.strict, req.headers) }
314
- */
315
- function strictOverrideField(serverDefault, rawHeaders) {
316
- const effective = resolveStrictMode(serverDefault, rawHeaders);
317
- if (effective !== (serverDefault ?? false)) return { strictOverride: effective };
318
- return {};
319
- }
320
- /**
321
611
  * Build the strict-mode 503 error message, distinguishing a true no-match from
322
612
  * a sequence/turn-exhausted miss.
323
613
  *
@@ -1055,12 +1345,7 @@ function isErrorResponse(r) {
1055
1345
  * response body. Real LLM APIs don't include it.
1056
1346
  */
1057
1347
  function serializeErrorResponse(response) {
1058
- return JSON.stringify({ error: {
1059
- message: response.error.message,
1060
- type: response.error.type ?? "server_error",
1061
- param: response.error.param ?? null,
1062
- code: response.error.code ?? null
1063
- } });
1348
+ return renderError("openai", "fixture", response.error).body;
1064
1349
  }
1065
1350
  function isEmbeddingResponse(r) {
1066
1351
  return "embedding" in r && Array.isArray(r.embedding);
@@ -1101,9 +1386,47 @@ function isVideoResponse(r) {
1101
1386
  function isJSONResponse(r) {
1102
1387
  return "json" in r && r.json !== void 0;
1103
1388
  }
1389
+ /**
1390
+ * Every key some other response guard reads. A response carrying any of them
1391
+ * is that type (with a stray `raw` key the loader has always ignored), never
1392
+ * a raw response — so adding raw support changes nothing for such fixtures.
1393
+ */
1394
+ const NON_RAW_RESPONSE_MARKERS = [
1395
+ "content",
1396
+ "toolCalls",
1397
+ "blocks",
1398
+ "responsesBlocks",
1399
+ "customToolCalls",
1400
+ "error",
1401
+ "embedding",
1402
+ "image",
1403
+ "images",
1404
+ "audio",
1405
+ "transcription",
1406
+ "video",
1407
+ "json",
1408
+ "live"
1409
+ ];
1410
+ /**
1411
+ * @internal Whether `r` is a raw passthrough response: `raw` is a non-null,
1412
+ * non-array object and no other response type's marker key is present. The
1413
+ * shape of `raw` itself is checked by the loader and again at serve time.
1414
+ * Exported for in-repo use only; not part of the public API.
1415
+ *
1416
+ * A fixture added in code can hold a response that is not an object (null, a
1417
+ * string). `in` throws on such a value, so it is simply not raw.
1418
+ */
1419
+ function isRawResponse(r) {
1420
+ if (typeof r !== "object" || r === null || !("raw" in r)) return false;
1421
+ const raw = r.raw;
1422
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
1423
+ return !NON_RAW_RESPONSE_MARKERS.some((marker) => marker in r);
1424
+ }
1104
1425
  function extractOverrides(response) {
1105
1426
  const r = response;
1106
1427
  return {
1428
+ ...r.citations !== void 0 && { citations: r.citations },
1429
+ ...r.files !== void 0 && { files: r.files },
1107
1430
  ...r.id !== void 0 && { id: r.id },
1108
1431
  ...r.created !== void 0 && { created: r.created },
1109
1432
  ...r.model !== void 0 && { model: r.model },
@@ -1111,6 +1434,7 @@ function extractOverrides(response) {
1111
1434
  ...r.systemFingerprint !== void 0 && { systemFingerprint: r.systemFingerprint },
1112
1435
  ...r.finishReason !== void 0 && { finishReason: r.finishReason },
1113
1436
  ...r.role !== void 0 && { role: r.role },
1437
+ ...r.phase !== void 0 && { phase: r.phase },
1114
1438
  ...r.provider !== void 0 && { provider: r.provider },
1115
1439
  ...r.nativeFinishReason !== void 0 && { nativeFinishReason: r.nativeFinishReason }
1116
1440
  };
@@ -1120,18 +1444,13 @@ function extractOverrides(response) {
1120
1444
  * Uses the ~4 characters per token heuristic common for English text.
1121
1445
  */
1122
1446
  function estimateTokens(text) {
1123
- return Math.max(1, Math.ceil(text.length / 4));
1447
+ return estimateTokens$1(text);
1124
1448
  }
1125
1449
  /**
1126
1450
  * Estimate prompt tokens from a request's messages array.
1127
1451
  */
1128
1452
  function estimatePromptTokens(messages) {
1129
- let totalChars = 0;
1130
- for (const msg of messages) if (typeof msg.content === "string") totalChars += msg.content.length;
1131
- else if (Array.isArray(msg.content)) {
1132
- for (const part of msg.content) if (part.text) totalChars += part.text.length;
1133
- }
1134
- return Math.max(1, Math.ceil(totalChars / 4));
1453
+ return estimatePromptTokens$1(messages);
1135
1454
  }
1136
1455
  /**
1137
1456
  * Build usage object: use explicit overrides if provided, otherwise estimate.
@@ -1142,26 +1461,10 @@ function estimatePromptTokens(messages) {
1142
1461
  * so the streaming path does not re-implement the estimation logic.
1143
1462
  */
1144
1463
  function resolveUsage(overrides, promptText, completionText) {
1145
- if (overrides?.usage) {
1146
- const u = overrides.usage;
1147
- const hasExplicitTokens = u.prompt_tokens !== void 0 || u.completion_tokens !== void 0 || u.total_tokens !== void 0 || u.input_tokens !== void 0 || u.output_tokens !== void 0 || u.promptTokenCount !== void 0 || u.candidatesTokenCount !== void 0 || u.totalTokenCount !== void 0;
1148
- const fallbackPrompt = hasExplicitTokens ? 0 : estimateTokens(promptText || "x");
1149
- const fallbackCompletion = hasExplicitTokens ? 0 : estimateTokens(completionText || "x");
1150
- const prompt = u.prompt_tokens ?? u.input_tokens ?? u.promptTokenCount ?? fallbackPrompt;
1151
- const completion = u.completion_tokens ?? u.output_tokens ?? u.candidatesTokenCount ?? fallbackCompletion;
1152
- return {
1153
- prompt_tokens: prompt,
1154
- completion_tokens: completion,
1155
- total_tokens: u.total_tokens ?? u.totalTokenCount ?? prompt + completion
1156
- };
1157
- }
1158
- const prompt = estimateTokens(promptText || "x");
1159
- const completion = estimateTokens(completionText || "x");
1160
- return {
1161
- prompt_tokens: prompt,
1162
- completion_tokens: completion,
1163
- total_tokens: prompt + completion
1164
- };
1464
+ return render(resolve(overrides, {
1465
+ promptText,
1466
+ completionText
1467
+ }));
1165
1468
  }
1166
1469
  /**
1167
1470
  * Build an SSE usage chunk for streaming responses.
@@ -1233,6 +1536,11 @@ function buildTextChunks(content, model, chunkSize, reasoning, overrides) {
1233
1536
  ...fingerprint !== void 0 && { system_fingerprint: fingerprint }
1234
1537
  });
1235
1538
  }
1539
+ chunks.push(...chatAnnotationChunks(content, overrides, {
1540
+ id,
1541
+ created,
1542
+ model: effectiveModel
1543
+ }));
1236
1544
  chunks.push({
1237
1545
  id,
1238
1546
  object: "chat.completion.chunk",
@@ -1252,6 +1560,7 @@ function buildTextChunks(content, model, chunkSize, reasoning, overrides) {
1252
1560
  function buildOpenAIReasoningChunks(reasoning, model, chunkSize, exposeReasoning, overrides) {
1253
1561
  return buildTextChunks(exposeReasoning ? reasoning : "", model, chunkSize, void 0, {
1254
1562
  ...overrides,
1563
+ citations: void 0,
1255
1564
  role: "assistant",
1256
1565
  finishReason: "length"
1257
1566
  }).map((chunk) => ({
@@ -1280,6 +1589,7 @@ function buildOpenAIReasoningCompletion(reasoning, model, exposeReasoning, overr
1280
1589
  const visible = exposeReasoning ? reasoning : "";
1281
1590
  const completion = buildTextCompletion(visible, model, void 0, {
1282
1591
  ...overrides,
1592
+ citations: void 0,
1283
1593
  role: "assistant",
1284
1594
  finishReason: "length",
1285
1595
  usage: void 0
@@ -1309,6 +1619,7 @@ function buildOpenAIReasoningCompletion(reasoning, model, exposeReasoning, overr
1309
1619
  function buildOpenAIContentFilterChunks(model, overrides) {
1310
1620
  return buildTextChunks("", model, 1, void 0, {
1311
1621
  ...overrides,
1622
+ citations: void 0,
1312
1623
  role: "assistant",
1313
1624
  finishReason: "content_filter"
1314
1625
  }).map((chunk) => ({
@@ -1326,6 +1637,7 @@ function buildOpenAIContentFilterChunks(model, overrides) {
1326
1637
  function buildOpenAIContentFilterCompletion(model, overrides, requestMessages) {
1327
1638
  const completion = buildTextCompletion("", model, void 0, {
1328
1639
  ...overrides,
1640
+ citations: void 0,
1329
1641
  role: "assistant",
1330
1642
  finishReason: "content_filter",
1331
1643
  usage: void 0
@@ -1346,6 +1658,7 @@ function buildOpenAIContentFilterCompletion(model, overrides, requestMessages) {
1346
1658
  function buildOpenAIRefusalChunks(refusal, model, chunkSize, overrides) {
1347
1659
  return buildTextChunks(refusal, model, chunkSize, void 0, {
1348
1660
  ...overrides,
1661
+ citations: void 0,
1349
1662
  role: "assistant",
1350
1663
  finishReason: "stop"
1351
1664
  }).map((chunk) => ({
@@ -1366,6 +1679,7 @@ function buildOpenAIRefusalChunks(refusal, model, chunkSize, overrides) {
1366
1679
  function buildOpenAIRefusalCompletion(refusal, model, overrides, requestMessages) {
1367
1680
  const completion = buildTextCompletion(refusal, model, void 0, {
1368
1681
  ...overrides,
1682
+ citations: void 0,
1369
1683
  role: "assistant",
1370
1684
  finishReason: "stop",
1371
1685
  usage: void 0
@@ -1383,6 +1697,7 @@ function buildOpenAIRefusalCompletion(refusal, model, overrides, requestMessages
1383
1697
  };
1384
1698
  }
1385
1699
  function buildToolCallChunks(toolCalls, model, chunkSize, reasoning, overrides) {
1700
+ fixtureCitations("", overrides?.citations);
1386
1701
  const id = overrides?.id ?? generateId();
1387
1702
  const created = overrides?.created ?? Math.floor(Date.now() / 1e3);
1388
1703
  const effectiveModel = overrides?.model ?? model;
@@ -1493,7 +1808,8 @@ function buildTextCompletion(content, model, reasoning, overrides, requestMessag
1493
1808
  role: overrides?.role ?? "assistant",
1494
1809
  content,
1495
1810
  refusal: null,
1496
- ...reasoning ? { reasoning_content: reasoning } : {}
1811
+ ...reasoning ? { reasoning_content: reasoning } : {},
1812
+ ...annotationsField(content, overrides)
1497
1813
  },
1498
1814
  logprobs: null,
1499
1815
  finish_reason: overrides?.finishReason ?? "stop"
@@ -1503,6 +1819,7 @@ function buildTextCompletion(content, model, reasoning, overrides, requestMessag
1503
1819
  };
1504
1820
  }
1505
1821
  function buildToolCallCompletion(toolCalls, model, reasoning, overrides, requestMessages) {
1822
+ fixtureCitations("", overrides?.citations);
1506
1823
  const promptText = requestMessages ? requestMessages.map((m) => typeof m.content === "string" ? m.content : Array.isArray(m.content) ? m.content.map((p) => p.text ?? "").join("") : "").join("") : "";
1507
1824
  const completionText = toolCalls.map((tc) => tc.name + tc.arguments).join("");
1508
1825
  return {
@@ -1639,6 +1956,11 @@ function buildContentWithToolCallsChunks(content, toolCalls, model, chunkSize, r
1639
1956
  }
1640
1957
  tcIdx++;
1641
1958
  }
1959
+ chunks.push(...chatAnnotationChunks(outcome.content, overrides, {
1960
+ id,
1961
+ created,
1962
+ model: effectiveModel
1963
+ }));
1642
1964
  chunks.push({
1643
1965
  id,
1644
1966
  object: "chat.completion.chunk",
@@ -1750,6 +2072,11 @@ function buildContentWithToolCallsChunks(content, toolCalls, model, chunkSize, r
1750
2072
  });
1751
2073
  }
1752
2074
  }
2075
+ chunks.push(...chatAnnotationChunks(content, overrides, {
2076
+ id,
2077
+ created,
2078
+ model: effectiveModel
2079
+ }));
1753
2080
  chunks.push({
1754
2081
  id,
1755
2082
  object: "chat.completion.chunk",
@@ -1787,7 +2114,8 @@ function buildContentWithToolCallsCompletion(content, toolCalls, model, reasonin
1787
2114
  name: tc.name,
1788
2115
  arguments: tc.arguments
1789
2116
  }
1790
- }))
2117
+ })),
2118
+ ...annotationsField(content, overrides)
1791
2119
  },
1792
2120
  logprobs: null,
1793
2121
  finish_reason: overrides?.finishReason ?? "tool_calls"
@@ -2429,5 +2757,5 @@ function parseMcpUndeclared(raw) {
2429
2757
  }
2430
2758
 
2431
2759
  //#endregion
2432
- export { FORMAT_TO_CONTENT_TYPE, InvalidFixtureToolCallError, InvalidToolArgumentsError, MAX_EMBEDDING_DIMENSIONS, RequestBodyTooLargeError, UnsupportedToolCallError, assertCustomToolCalls, assertResponsesToolCalls, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildEmbeddingResponse, buildOpenAIContentFilterChunks, buildOpenAIContentFilterCompletion, buildOpenAIReasoningChunks, buildOpenAIReasoningCompletion, buildOpenAIRefusalChunks, buildOpenAIRefusalCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, buildUsageChunk, createServerFixtureList, decodeMcpHeaderValue, describeMatch, estimatePromptTokens, estimateTokens, extractOverrides, fixtureListTarget, fixtureToolCallErrorCode, flattenHeaders, formatToMime, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getContext, getTestId, googleFixtureToolCallErrorDetails, hasMintedRequestId, isAudioResponse, isCombinedFixtureResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isExtendedResponsesToolsList, isFixtureToolCallError, isImageResponse, isJSONResponse, isJsonObject, isLiveResponse, isResponseFactory, isServerOwnedFixtures, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, journalFixtureToolCallError, keepAuthoredToolArguments, markExtendedResponsesToolsRequest, markMintedRequestId, markServerOwnedFixtures, matchesPattern, normalizeEmbeddingInput, normalizeTextInput, parseStrictIntegerText, prepareOpenAIChatMisbehavior, readBody, readBodyBufferBounded, rebuildOrderedBlocks, rejectResponsesOnlyToolCalls, requireEmittedFunctionToolCalls, requireFunctionToolCalls, requireServedFunctionToolCalls, resolveFixtureBlockOutcome, resolveFixtureBlocks, resolveMcpIdentity, resolveOpenAIChatMisbehaviorUsage, resolveReasoningArtifactsForModel, resolveReasoningForModel, resolveRequestId, resolveResponse, resolveResponsesBlocks, resolveServedBlockOutcome, resolveStrictMode, resolveTestId, resolveUsage, runWithToolArgumentsScope, serializeErrorResponse, servedToolArgs, servedToolCalls, slugifyContext, slugifyTestId, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField, strictToolArgumentsEnabled, toolArgsForWire, toolCallFixtureBlock, validateChatMessages, validateEmbeddingDimensions, validateToolsField, withServedToolCalls, withoutLegacyNamespaces, withoutResponsesToolKeys, wouldProxyMiss };
2760
+ export { FORMAT_TO_CONTENT_TYPE, InvalidFixtureOutputError, InvalidFixtureToolCallError, InvalidToolArgumentsError, MAX_EMBEDDING_DIMENSIONS, RequestBodyTooLargeError, UnsupportedGeneratedFileError, UnsupportedToolCallError, assertCustomToolCalls, assertResponsesToolCalls, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildEmbeddingResponse, buildOpenAIContentFilterChunks, buildOpenAIContentFilterCompletion, buildOpenAIReasoningChunks, buildOpenAIReasoningCompletion, buildOpenAIRefusalChunks, buildOpenAIRefusalCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, buildUsageChunk, createServerFixtureList, decodeMcpHeaderValue, describeMatch, estimatePromptTokens, estimateTokens, extractOverrides, fixtureCitations, fixtureCitationsProblem, fixtureFiles, fixtureFilesProblem, fixtureListTarget, fixtureToolCallErrorCode, flattenHeaders, formatToMime, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getContext, getTestId, googleFixtureToolCallErrorDetails, hasMintedRequestId, isAudioResponse, isCombinedFixtureResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isExtendedResponsesToolsList, isFixtureToolCallError, isImageResponse, isJSONResponse, isJsonObject, isLiveResponse, isRawResponse, isResponseFactory, isServerOwnedFixtures, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, journalFixtureToolCallError, keepAuthoredToolArguments, markExtendedResponsesToolsRequest, markMintedRequestId, markServerOwnedFixtures, matchesPattern, normalizeEmbeddingInput, normalizeTextInput, parseStrictIntegerText, prepareOpenAIChatMisbehavior, readBody, readBodyBufferBounded, rebuildOrderedBlocks, rejectGeneratedFiles, rejectResponsesOnlyToolCalls, requireEmittedFunctionToolCalls, requireFunctionToolCalls, requireServedFunctionToolCalls, resolveCitations, resolveFixtureBlockOutcome, resolveFixtureBlocks, resolveMcpIdentity, resolveOpenAIChatMisbehaviorUsage, resolveReasoningArtifactsForModel, resolveReasoningForModel, resolveRequestId, resolveResponse, resolveResponsesBlocks, resolveServedBlockOutcome, resolveTestId, resolveUsage, runWithToolArgumentsScope, serializeErrorResponse, servedToolArgs, servedToolCalls, slugifyContext, slugifyTestId, strictNoMatchLogLine, strictNoMatchMessage, strictToolArgumentsEnabled, surrogateSafeChunks, toolArgsForWire, toolCallFixtureBlock, validateChatMessages, validateEmbeddingDimensions, validateToolsField, withServedToolCalls, withoutLegacyNamespaces, withoutResponsesToolKeys, wouldProxyMiss };
2433
2761
  //# sourceMappingURL=helpers.js.map