@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
@@ -1,12 +1,19 @@
1
1
  const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
+ const require_errors = require('./response/errors.cjs');
2
3
  const require_model_utils = require('./model-utils.cjs');
4
+ const require_policy = require('./response/policy.cjs');
3
5
  const require_helpers = require('./helpers.cjs');
4
6
  const require_sse_writer = require('./sse-writer.cjs');
5
7
  const require_chaos = require('./chaos.cjs');
6
8
  const require_misbehavior = require('./misbehavior.cjs');
7
9
  const require_router = require('./router.cjs');
8
10
  const require_recorder = require('./recorder.cjs');
9
- const require_interruption = require('./interruption.cjs');
11
+ const require_timing = require('./response/timing.cjs');
12
+ const require_deliver = require('./response/deliver.cjs');
13
+ const require_proxy = require('./response/proxy.cjs');
14
+ const require_raw = require('./response/raw.cjs');
15
+ const require_responses = require('./response/usage/codecs/responses.cjs');
16
+ const require_finish = require('./response/finish.cjs');
10
17
  let node_crypto = require("node:crypto");
11
18
 
12
19
  //#region src/responses.ts
@@ -311,25 +318,7 @@ function validateResponsesTools(tools) {
311
318
  }
312
319
  function responsesStatus(finishReason, defaultStatus) {
313
320
  if (!finishReason) return defaultStatus;
314
- if (finishReason === "stop") return "completed";
315
- if (finishReason === "tool_calls") return "completed";
316
- if (finishReason === "length") return "incomplete";
317
- if (finishReason === "content_filter") return "failed";
318
- return finishReason;
319
- }
320
- function responsesUsage(overrides) {
321
- if (!overrides?.usage) return {
322
- input_tokens: 0,
323
- output_tokens: 0,
324
- total_tokens: 0
325
- };
326
- const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
327
- const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
328
- return {
329
- input_tokens: input,
330
- output_tokens: output,
331
- total_tokens: overrides.usage.total_tokens ?? input + output
332
- };
321
+ return require_finish.mapResponsesFinish(finishReason);
333
322
  }
334
323
  function responseId() {
335
324
  return require_helpers.generateId("resp");
@@ -339,7 +328,7 @@ function itemId() {
339
328
  }
340
329
  function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
341
330
  const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
342
- const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
331
+ const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex, overrides?.phase, buildAnnotations(content, overrides?.citations));
343
332
  events.push(...msgEvents);
344
333
  events.push({
345
334
  type: "response.completed",
@@ -350,7 +339,7 @@ function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches
350
339
  model: overrides?.model ?? model,
351
340
  status: responsesStatus(overrides?.finishReason, "completed"),
352
341
  output: [...prefixOutputItems, msgItem],
353
- usage: responsesUsage(overrides)
342
+ usage: require_responses.render(overrides)
354
343
  }
355
344
  });
356
345
  return events;
@@ -448,6 +437,7 @@ function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSe
448
437
  }
449
438
  function toolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
450
439
  require_helpers.assertResponsesToolCalls(toolCalls);
440
+ require_helpers.fixtureCitations("", overrides?.citations);
451
441
  const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
452
442
  const fcOutputItems = [];
453
443
  for (let idx = 0; idx < toolCalls.length; idx++) {
@@ -464,7 +454,7 @@ function toolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearche
464
454
  model: overrides?.model ?? model,
465
455
  status: responsesStatus(overrides?.finishReason, "completed"),
466
456
  output: [...prefixOutputItems, ...fcOutputItems],
467
- usage: responsesUsage(overrides)
457
+ usage: require_responses.render(overrides)
468
458
  }
469
459
  });
470
460
  return events;
@@ -684,6 +674,79 @@ function buildWebSearchStreamEvents(queries, startOutputIndex) {
684
674
  }
685
675
  return events;
686
676
  }
677
+ /**
678
+ * A Responses `image_generation_call` output item for one fixture file (see
679
+ * `ResponseOutputItem.ImageGenerationCall` in the openai SDK): `result` holds
680
+ * the base64 bytes once completed and is null while in progress.
681
+ */
682
+ function imageGenerationCallItem(id, file, status) {
683
+ return {
684
+ type: "image_generation_call",
685
+ id,
686
+ status,
687
+ result: status === "completed" ? file.data : null
688
+ };
689
+ }
690
+ /**
691
+ * A fixture file that is not `image/*` reached the Responses API, which
692
+ * carries generated files only as `image_generation_call` items. Surfaces as
693
+ * the same coded 500 (`aimock_unsupported_generated_file`), naming `mimeType`.
694
+ */
695
+ var NonImageGeneratedFileError = class extends require_helpers.UnsupportedGeneratedFileError {
696
+ constructor(mimeType) {
697
+ super("the OpenAI Responses API");
698
+ this.message = `aimock: fixture "files" on the OpenAI Responses API carry only image/* files (as image_generation_call items); got mimeType "${mimeType}"`;
699
+ }
700
+ };
701
+ /**
702
+ * Throw {@link NonImageGeneratedFileError} for the first fixture file whose
703
+ * `mimeType` is not `image/*`. Called before any output item is built, so
704
+ * nothing reaches the client.
705
+ */
706
+ function requireImageFiles(files) {
707
+ const nonImage = files.find((f) => !f.mimeType.toLowerCase().startsWith("image/"));
708
+ if (nonImage) throw new NonImageGeneratedFileError(nonImage.mimeType);
709
+ }
710
+ /** Fixture `files` as completed `image_generation_call` items (non-streaming). */
711
+ function imageGenerationCallItems(files) {
712
+ const validated = require_helpers.fixtureFiles(files);
713
+ requireImageFiles(validated);
714
+ return validated.map((f) => imageGenerationCallItem(require_helpers.generateId("ig"), f, "completed"));
715
+ }
716
+ /**
717
+ * Streamed form of {@link imageGenerationCallItems}: per file, the item's
718
+ * `output_item.added`, the `image_generation_call` `in_progress`,
719
+ * `generating` and `completed` events, then `output_item.done` carrying the
720
+ * completed item.
721
+ */
722
+ function buildImageGenerationStreamEvents(files, startOutputIndex) {
723
+ requireImageFiles(files);
724
+ const events = [];
725
+ files.forEach((file, i) => {
726
+ const id = require_helpers.generateId("ig");
727
+ const outputIndex = startOutputIndex + i;
728
+ events.push({
729
+ type: "response.output_item.added",
730
+ output_index: outputIndex,
731
+ item: imageGenerationCallItem(id, file, "in_progress")
732
+ });
733
+ for (const phase of [
734
+ "in_progress",
735
+ "generating",
736
+ "completed"
737
+ ]) events.push({
738
+ type: `response.image_generation_call.${phase}`,
739
+ output_index: outputIndex,
740
+ item_id: id
741
+ });
742
+ events.push({
743
+ type: "response.output_item.done",
744
+ output_index: outputIndex,
745
+ item: imageGenerationCallItem(id, file, "completed")
746
+ });
747
+ });
748
+ return events;
749
+ }
687
750
  function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false, forceReasoning = false) {
688
751
  const respId = overrides?.id ?? responseId();
689
752
  const created = overrides?.created ?? Math.floor(Date.now() / 1e3);
@@ -727,6 +790,13 @@ function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrid
727
790
  for (const de of doneEvents) prefixOutputItems.push(de.item);
728
791
  nextOutputIndex += webSearches.length;
729
792
  }
793
+ const files = require_helpers.fixtureFiles(overrides?.files);
794
+ if (files.length > 0) {
795
+ const fileEvents = buildImageGenerationStreamEvents(files, nextOutputIndex);
796
+ events.push(...fileEvents);
797
+ for (const e of fileEvents) if (e.type === "response.output_item.done") prefixOutputItems.push(e.item);
798
+ nextOutputIndex += files.length;
799
+ }
730
800
  return {
731
801
  respId,
732
802
  created,
@@ -735,7 +805,84 @@ function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrid
735
805
  nextOutputIndex
736
806
  };
737
807
  }
738
- function buildMessageOutputEvents(content, chunkSize, outputIndex) {
808
+ /**
809
+ * Fixture `citations` as `output_text` annotations for each text in `texts`
810
+ * (one per message item), in fixture order: a URL citation becomes
811
+ * `url_citation`, a file citation (`type: "file"`) becomes `file_citation`
812
+ * (`file_id`, `filename`, `index`; see `ResponseOutputText.FileCitation` in
813
+ * the openai SDK). Offsets index the joined text of all texts, as on every
814
+ * other provider. A URL citation is a range and goes only to the text holding
815
+ * its `startIndex`. A file citation is a point after the cited text, so it
816
+ * goes to the last text starting before its `index`: an `index` equal to a
817
+ * text's end stays at the end of that text (not at 0 of the next text), and
818
+ * an `index` of 0 goes to the first text. Each citation is rebased onto its
819
+ * text since Responses offsets are per `output_text`, with `end_index`
820
+ * clamped to it. Anthropic and Gemini need no point rule: they have no file
821
+ * citation. Anthropic URL citations follow the same start-owns-range rule;
822
+ * Gemini does not, and splits a citation that spans several text parts into
823
+ * one grounding support per part (see geminiGroundingSupports).
824
+ * Missing offsets take the defaults `resolveCitations` applies: a URL
825
+ * citation starts at 0 and ends at the end of the joined text, so one without
826
+ * offsets goes on the first text and covers all of it; a file citation's
827
+ * `index` defaults to the end of the joined text (the last text).
828
+ */
829
+ function blockAnnotations(texts, citations) {
830
+ const perText = texts.map(() => []);
831
+ if (texts.length === 0) {
832
+ require_helpers.fixtureCitations("", citations);
833
+ return perText;
834
+ }
835
+ const starts = [];
836
+ let offset = 0;
837
+ for (const text of texts) {
838
+ starts.push(offset);
839
+ offset += text.length;
840
+ }
841
+ const joinedLength = offset;
842
+ const ownerOf = (start) => {
843
+ let owner = 0;
844
+ for (let k = 1; k < starts.length; k++) if (starts[k] <= start) owner = k;
845
+ return owner;
846
+ };
847
+ const pointOwnerOf = (index) => {
848
+ let owner = 0;
849
+ for (let k = 1; k < starts.length; k++) if (starts[k] < index) owner = k;
850
+ return owner;
851
+ };
852
+ for (const c of require_helpers.fixtureCitations(texts.join(""), citations)) {
853
+ if (c.type === "file") {
854
+ const index = c.index ?? joinedLength;
855
+ const owner = pointOwnerOf(index);
856
+ perText[owner].push({
857
+ type: "file_citation",
858
+ file_id: c.fileId,
859
+ filename: c.filename,
860
+ index: index - starts[owner]
861
+ });
862
+ continue;
863
+ }
864
+ const start = c.startIndex ?? 0;
865
+ const end = c.endIndex ?? joinedLength;
866
+ const owner = ownerOf(start);
867
+ perText[owner].push({
868
+ type: "url_citation",
869
+ url: c.url,
870
+ title: c.title ?? c.url,
871
+ start_index: start - starts[owner],
872
+ end_index: Math.min(end - starts[owner], texts[owner].length)
873
+ });
874
+ }
875
+ return perText;
876
+ }
877
+ /** {@link blockAnnotations} for a turn with a single text. */
878
+ function buildAnnotations(content, citations) {
879
+ return blockAnnotations([content], citations)[0];
880
+ }
881
+ /** The annotations of each text block in `blocks`, in block order. */
882
+ function orderedBlockAnnotations(blocks, citations) {
883
+ return blockAnnotations(blocks.flatMap((b) => b.type === "text" ? [b.text] : []), citations);
884
+ }
885
+ function buildMessageOutputEvents(content, chunkSize, outputIndex, phase, annotations) {
739
886
  const msgId = itemId();
740
887
  const events = [];
741
888
  events.push({
@@ -746,6 +893,7 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
746
893
  id: msgId,
747
894
  status: "in_progress",
748
895
  role: "assistant",
896
+ ...phase !== void 0 ? { phase } : {},
749
897
  content: []
750
898
  }
751
899
  });
@@ -774,6 +922,16 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
774
922
  content_index: 0,
775
923
  text: content
776
924
  });
925
+ annotations.forEach((annotation, annotationIndex) => {
926
+ events.push({
927
+ type: "response.output_text.annotation.added",
928
+ item_id: msgId,
929
+ output_index: outputIndex,
930
+ content_index: 0,
931
+ annotation_index: annotationIndex,
932
+ annotation
933
+ });
934
+ });
777
935
  events.push({
778
936
  type: "response.content_part.done",
779
937
  item_id: msgId,
@@ -782,7 +940,7 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
782
940
  part: {
783
941
  type: "output_text",
784
942
  text: content,
785
- annotations: []
943
+ annotations
786
944
  }
787
945
  });
788
946
  const msgItem = {
@@ -790,10 +948,11 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
790
948
  id: msgId,
791
949
  status: "completed",
792
950
  role: "assistant",
951
+ ...phase !== void 0 ? { phase } : {},
793
952
  content: [{
794
953
  type: "output_text",
795
954
  text: content,
796
- annotations: []
955
+ annotations
797
956
  }]
798
957
  };
799
958
  events.push({
@@ -848,24 +1007,6 @@ function buildFunctionCallOutputEvents(toolCall, chunkSize, outputIndex) {
848
1007
  };
849
1008
  }
850
1009
  /**
851
- * `text` cut into slices of at most `chunkSize` UTF-16 units, never between
852
- * the two halves of a surrogate pair: a cut that would land inside a pair
853
- * moves back before it, or, when that would leave the slice empty
854
- * (`chunkSize` 1), forward past it. The slices rejoin to `text` exactly.
855
- */
856
- function surrogateSafeChunks(text, chunkSize) {
857
- const chunks = [];
858
- for (let i = 0; i < text.length;) {
859
- let end = Math.min(i + chunkSize, text.length);
860
- const high = text.charCodeAt(end - 1);
861
- const low = text.charCodeAt(end);
862
- if (high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343) end = end - 1 > i ? end - 1 : end + 1;
863
- chunks.push(text.slice(i, end));
864
- i = end;
865
- }
866
- return chunks;
867
- }
868
- /**
869
1010
  * Emit output_item.added → custom_tool_call_input.delta×N →
870
1011
  * custom_tool_call_input.done → output_item.done for one `custom_tool_call` at
871
1012
  * `outputIndex`, returning the completed item. An empty `input`
@@ -881,7 +1022,7 @@ function buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) {
881
1022
  output_index: outputIndex,
882
1023
  item: customToolCallItem(call, ctcId, callId, "", "in_progress")
883
1024
  });
884
- for (const delta of surrogateSafeChunks(input, chunkSize)) events.push({
1025
+ for (const delta of require_helpers.surrogateSafeChunks(input, chunkSize)) events.push({
885
1026
  type: "response.custom_tool_call_input.delta",
886
1027
  item_id: ctcId,
887
1028
  output_index: outputIndex,
@@ -908,7 +1049,7 @@ function buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) {
908
1049
  function buildToolCallOutputEvents(call, chunkSize, outputIndex) {
909
1050
  return isCustomEmittable(call) ? buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) : buildFunctionCallOutputEvents(call, chunkSize, outputIndex);
910
1051
  }
911
- function buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
1052
+ function buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false, phase, citations, files) {
912
1053
  const output = [];
913
1054
  if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
914
1055
  summaryText: reasoning,
@@ -923,15 +1064,17 @@ function buildOutputPrefix(content, model, reasoning, webSearches, emitEncrypted
923
1064
  query
924
1065
  }
925
1066
  });
1067
+ output.push(...imageGenerationCallItems(files));
926
1068
  output.push({
927
1069
  type: "message",
928
1070
  id: itemId(),
929
1071
  status: "completed",
930
1072
  role: "assistant",
1073
+ ...phase !== void 0 ? { phase } : {},
931
1074
  content: [{
932
1075
  type: "output_text",
933
1076
  text: content,
934
- annotations: []
1077
+ annotations: buildAnnotations(content, citations)
935
1078
  }]
936
1079
  });
937
1080
  return output;
@@ -944,14 +1087,15 @@ function buildResponseEnvelope(model, output, overrides) {
944
1087
  model: overrides?.model ?? model,
945
1088
  status: responsesStatus(overrides?.finishReason, "completed"),
946
1089
  output,
947
- usage: responsesUsage(overrides)
1090
+ usage: require_responses.render(overrides)
948
1091
  };
949
1092
  }
950
1093
  function buildTextResponse(content, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
951
- return buildResponseEnvelope(model, buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning), overrides);
1094
+ return buildResponseEnvelope(model, buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning, overrides?.phase, overrides?.citations, overrides?.files), overrides);
952
1095
  }
953
1096
  function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
954
1097
  require_helpers.assertResponsesToolCalls(toolCalls);
1098
+ require_helpers.fixtureCitations("", overrides?.citations);
955
1099
  const output = [];
956
1100
  if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
957
1101
  summaryText: reasoning,
@@ -966,6 +1110,7 @@ function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrid
966
1110
  query
967
1111
  }
968
1112
  });
1113
+ output.push(...imageGenerationCallItems(overrides?.files));
969
1114
  for (const tc of toolCalls) output.push(buildToolCallOutputItem(tc));
970
1115
  return buildResponseEnvelope(model, output, overrides);
971
1116
  }
@@ -983,9 +1128,11 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
983
1128
  const orderedOutputItems = [];
984
1129
  if (ordered && ordered.length > 0) {
985
1130
  let outputIndex = nextOutputIndex;
1131
+ const textAnnotations = orderedBlockAnnotations(ordered, overrides?.citations);
1132
+ let textPos = 0;
986
1133
  for (const block of ordered) {
987
1134
  if (block.type === "text") {
988
- const { events: msgEvents, msgItem } = buildMessageOutputEvents(block.text, chunkSize, outputIndex);
1135
+ const { events: msgEvents, msgItem } = buildMessageOutputEvents(block.text, chunkSize, outputIndex, overrides?.phase, textAnnotations[textPos++]);
989
1136
  events.push(...msgEvents);
990
1137
  orderedOutputItems.push(msgItem);
991
1138
  } else {
@@ -997,7 +1144,7 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
997
1144
  }
998
1145
  } else {
999
1146
  require_helpers.assertResponsesToolCalls(toolCalls);
1000
- const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
1147
+ const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex, overrides?.phase, buildAnnotations(content, overrides?.citations));
1001
1148
  events.push(...msgEvents);
1002
1149
  orderedOutputItems.push(msgItem);
1003
1150
  for (let idx = 0; idx < toolCalls.length; idx++) {
@@ -1015,7 +1162,7 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
1015
1162
  model: overrides?.model ?? model,
1016
1163
  status: responsesStatus(overrides?.finishReason, "completed"),
1017
1164
  output: [...prefixOutputItems, ...orderedOutputItems],
1018
- usage: responsesUsage(overrides)
1165
+ usage: require_responses.render(overrides)
1019
1166
  }
1020
1167
  });
1021
1168
  return events;
@@ -1025,16 +1172,17 @@ function buildToolCallOutputItem(tc) {
1025
1172
  if (isCustomEmittable(tc)) return customToolCallItem(tc, customToolCallItemId(), tc.id || require_helpers.generateToolCallId(), requireFixtureToolInput(tc.input), "completed");
1026
1173
  return functionCallItem(tc, require_helpers.generateId("fc"), tc.id || require_helpers.generateToolCallId(), requireFixtureToolArguments(tc.arguments), "completed");
1027
1174
  }
1028
- function buildMessageOutputItem(content) {
1175
+ function buildMessageOutputItem(content, phase, annotations) {
1029
1176
  return {
1030
1177
  type: "message",
1031
1178
  id: itemId(),
1032
1179
  status: "completed",
1033
1180
  role: "assistant",
1181
+ ...phase !== void 0 ? { phase } : {},
1034
1182
  content: [{
1035
1183
  type: "output_text",
1036
1184
  text: content,
1037
- annotations: []
1185
+ annotations
1038
1186
  }]
1039
1187
  };
1040
1188
  }
@@ -1054,40 +1202,18 @@ function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning,
1054
1202
  query
1055
1203
  }
1056
1204
  });
1057
- for (const block of ordered) if (block.type === "text") output.push(buildMessageOutputItem(block.text));
1205
+ output.push(...imageGenerationCallItems(overrides?.files));
1206
+ const textAnnotations = orderedBlockAnnotations(ordered, overrides?.citations);
1207
+ let textPos = 0;
1208
+ for (const block of ordered) if (block.type === "text") output.push(buildMessageOutputItem(block.text, overrides?.phase, textAnnotations[textPos++]));
1058
1209
  else output.push(buildToolCallOutputItem(block));
1059
1210
  return buildResponseEnvelope(model, output, overrides);
1060
1211
  }
1061
1212
  require_helpers.assertResponsesToolCalls(toolCalls);
1062
- const output = buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1213
+ const output = buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning, overrides?.phase, overrides?.citations, overrides?.files);
1063
1214
  for (const tc of toolCalls) output.push(buildToolCallOutputItem(tc));
1064
1215
  return buildResponseEnvelope(model, output, overrides);
1065
1216
  }
1066
- async function writeResponsesSSEStream(res, events, optionsOrLatency) {
1067
- const opts = typeof optionsOrLatency === "number" ? { latency: optionsOrLatency } : optionsOrLatency ?? {};
1068
- const latency = opts.latency ?? 0;
1069
- const profile = opts.streamingProfile;
1070
- const { recordedTimings, replaySpeed } = opts;
1071
- const signal = opts.signal;
1072
- const onChunkSent = opts.onChunkSent;
1073
- if (res.writableEnded) return true;
1074
- res.setHeader("Content-Type", "text/event-stream");
1075
- res.setHeader("Cache-Control", "no-cache");
1076
- res.setHeader("Connection", "keep-alive");
1077
- let chunkIndex = 0;
1078
- for (const event of events) {
1079
- const chunkDelay = require_sse_writer.calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);
1080
- if (chunkDelay > 0) await require_sse_writer.delay(chunkDelay, signal);
1081
- if (signal?.aborted) return false;
1082
- if (res.writableEnded) return true;
1083
- res.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
1084
- onChunkSent?.();
1085
- if (signal?.aborted) return false;
1086
- chunkIndex++;
1087
- }
1088
- if (!res.writableEnded) res.end();
1089
- return true;
1090
- }
1091
1217
  async function handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
1092
1218
  setCorsHeaders(res);
1093
1219
  let responsesReq;
@@ -1105,11 +1231,11 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1105
1231
  fixture: null
1106
1232
  }
1107
1233
  });
1108
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
1234
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
1109
1235
  message: `Malformed JSON: ${detail}`,
1110
1236
  type: "invalid_request_error",
1111
1237
  code: "invalid_json"
1112
- } }));
1238
+ }).body);
1113
1239
  return;
1114
1240
  }
1115
1241
  if (!require_helpers.isJsonObject(responsesReq)) {
@@ -1123,10 +1249,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1123
1249
  fixture: null
1124
1250
  }
1125
1251
  });
1126
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
1252
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
1127
1253
  message: "Request body must be a JSON object",
1128
1254
  type: "invalid_request_error"
1129
- } }));
1255
+ }).body);
1130
1256
  return;
1131
1257
  }
1132
1258
  let inputError;
@@ -1153,10 +1279,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1153
1279
  fixture: null
1154
1280
  }
1155
1281
  });
1156
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
1282
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
1157
1283
  message: validationError,
1158
1284
  type: "invalid_request_error"
1159
- } }));
1285
+ }).body);
1160
1286
  return;
1161
1287
  }
1162
1288
  const extendedTools = defaults.responsesTools === "extended";
@@ -1169,7 +1295,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1169
1295
  const emitEncryptedReasoning = requestWantsEncryptedReasoning(responsesReq);
1170
1296
  const synthesizeSummarylessReasoning = requestIncludesEncryptedReasoning(responsesReq);
1171
1297
  const testId = require_helpers.getTestId(req);
1172
- const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
1298
+ const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
1299
+ ...require_router.recordMatchOptions(!!defaults.record, defaults.logger),
1300
+ wire: "openai-responses"
1301
+ });
1173
1302
  if (fixture) {
1174
1303
  defaults.logger.debug(`Responses fixture matched for ${req.method ?? "POST"} ${req.url ?? "/v1/responses"}`);
1175
1304
  journal.incrementFixtureMatchCount(fixture, fixtures, testId);
@@ -1181,7 +1310,7 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1181
1310
  body: completionReq
1182
1311
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
1183
1312
  if (!fixture) {
1184
- if (require_helpers.resolveStrictMode(defaults.strict, req.headers)) {
1313
+ if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
1185
1314
  const strictStatus = 503;
1186
1315
  const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
1187
1316
  defaults.logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", req.url ?? "/v1/responses", skippedBySequenceOrTurn));
@@ -1193,18 +1322,18 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1193
1322
  response: {
1194
1323
  status: strictStatus,
1195
1324
  fixture: null,
1196
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1325
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1197
1326
  }
1198
1327
  });
1199
- require_sse_writer.writeErrorResponse(res, strictStatus, JSON.stringify({ error: {
1328
+ require_sse_writer.writeErrorResponse(res, strictStatus, require_errors.renderError("openai", "strict-miss", {
1200
1329
  message: strictMessage,
1201
1330
  type: "invalid_request_error",
1202
1331
  code: "no_fixture_match"
1203
- } }));
1332
+ }).body);
1204
1333
  return;
1205
1334
  }
1206
1335
  if (defaults.record) {
1207
- const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "openai", req.url ?? "/v1/responses", fixtures, defaults, raw);
1336
+ const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, completionReq, "openai", req.url ?? "/v1/responses", fixtures, defaults, raw));
1208
1337
  if (outcome === "handled_by_hook") return;
1209
1338
  if (outcome !== "not_configured") {
1210
1339
  journal.add({
@@ -1215,7 +1344,8 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1215
1344
  response: {
1216
1345
  status: res.statusCode ?? 200,
1217
1346
  fixture: null,
1218
- source: "proxy"
1347
+ source: "proxy",
1348
+ ...require_proxy.proxyInterruption(res, clientHungUp)
1219
1349
  }
1220
1350
  });
1221
1351
  return;
@@ -1229,14 +1359,14 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1229
1359
  response: {
1230
1360
  status: 404,
1231
1361
  fixture: null,
1232
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1362
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1233
1363
  }
1234
1364
  });
1235
- require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
1365
+ require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
1236
1366
  message: "No fixture matched",
1237
1367
  type: "invalid_request_error",
1238
1368
  code: "no_fixture_match"
1239
- } }));
1369
+ }).body);
1240
1370
  return;
1241
1371
  }
1242
1372
  const resolvedResponse = await require_helpers.resolveResponse(fixture, completionReq);
@@ -1269,20 +1399,34 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1269
1399
  testId
1270
1400
  });
1271
1401
  if (!misbehavior.summary?.evaluations.some((evaluation) => evaluation.outcome === "error")) defaults.logger.error(misbehavior.message);
1272
- require_sse_writer.writeErrorResponse(res, misbehavior.status, JSON.stringify({ error: {
1402
+ require_sse_writer.writeErrorResponse(res, misbehavior.status, require_errors.renderError("openai", "misbehavior", {
1273
1403
  message: misbehavior.message,
1274
1404
  type: "invalid_request_error",
1275
1405
  code: misbehavior.code
1276
- } }));
1406
+ }).body);
1277
1407
  return;
1278
1408
  }
1279
1409
  const latency = fixture.latency ?? defaults.latency;
1280
1410
  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
1281
1411
  const fixtureTimings = fixture.recordedTimings;
1282
1412
  const effectiveReplaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
1413
+ const streamTiming = {
1414
+ latency,
1415
+ streamingProfile: fixture.streamingProfile,
1416
+ recordedTimings: fixtureTimings,
1417
+ replaySpeed: effectiveReplaySpeed
1418
+ };
1419
+ const timedJson = require_timing.nonStreamingTimingEnabled(fixture, "other");
1420
+ const jsonPayloadLength = (r, reasoning) => require_timing.responsesPayloadLength(r, reasoning) + require_timing.responsesOutputFrames(r) * chunkSize;
1421
+ const jsonOpts = (payloadLength, duplicateId = false) => ({
1422
+ surface: "other",
1423
+ payloadLength: timedJson ? payloadLength() : 0,
1424
+ chunkSize,
1425
+ recordedTimings: fixtureTimings,
1426
+ duplicateId,
1427
+ replaySpeed: effectiveReplaySpeed
1428
+ });
1283
1429
  if (misbehavior.kind === "applied") {
1284
- const prepared = prepareResponsesMisbehavior(misbehavior);
1285
- const output = buildResponsesMisbehavior(prepared, completionReq, chunkSize, emitEncryptedReasoning);
1286
1430
  const entry = journal.add({
1287
1431
  method: req.method ?? "POST",
1288
1432
  path: req.url ?? "/v1/responses",
@@ -1293,41 +1437,50 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1293
1437
  fixture
1294
1438
  }
1295
1439
  });
1296
- require_misbehavior.recordMisbehaviorOutcome({
1440
+ const prepared = prepareResponsesMisbehavior(misbehavior);
1441
+ const build = () => buildResponsesMisbehavior(prepared, completionReq, chunkSize, emitEncryptedReasoning);
1442
+ const record = () => require_misbehavior.recordMisbehaviorOutcome({
1297
1443
  entry,
1298
1444
  summary: prepared.summary,
1299
1445
  defaults,
1300
1446
  testId
1301
1447
  });
1448
+ const output = timedJson && responsesReq.stream !== true ? void 0 : build();
1449
+ if (output) record();
1302
1450
  if (responsesReq.stream !== true) {
1303
- res.writeHead(200, { "Content-Type": "application/json" });
1304
- res.end(JSON.stringify(output.response));
1451
+ const servedReasoning = prepared.reasoning ?? ("reasoning" in prepared.response ? prepared.response.reasoning : void 0);
1452
+ await require_deliver.deliverJson(res, entry, fixture, () => {
1453
+ if (output) return output.response;
1454
+ const built = build();
1455
+ record();
1456
+ return built.response;
1457
+ }, jsonOpts(() => require_timing.misbehaviorPayloadLength(prepared, servedReasoning, jsonPayloadLength), !!prepared.duplicateId));
1305
1458
  } else {
1306
- const appliedTimings = prepared.duplicateId && fixtureTimings ? {
1307
- ...fixtureTimings,
1308
- interChunkDelaysMs: [...fixtureTimings.interChunkDelaysMs]
1309
- } : fixtureTimings;
1310
- if (prepared.duplicateId && appliedTimings) {
1311
- const lastGap = appliedTimings.interChunkDelaysMs.at(-1) ?? 0;
1312
- while (appliedTimings.interChunkDelaysMs.length < output.events.length - 1) appliedTimings.interChunkDelaysMs.push(lastGap);
1313
- }
1314
- const interruption = require_interruption.createInterruptionSignal(fixture);
1315
- if (!await writeResponsesSSEStream(res, output.events, {
1316
- latency,
1317
- streamingProfile: fixture.streamingProfile,
1318
- recordedTimings: appliedTimings,
1319
- replaySpeed: effectiveReplaySpeed,
1320
- signal: interruption?.signal,
1321
- onChunkSent: interruption?.tick
1322
- })) {
1323
- if (!res.writableEnded) res.destroy();
1324
- entry.response.interrupted = true;
1325
- entry.response.interruptReason = interruption?.reason();
1326
- }
1327
- interruption?.cleanup();
1459
+ const { events } = output ?? build();
1460
+ await require_deliver.deliverStream(res, entry, fixture, require_sse_writer.typedSseCodec(), events, {
1461
+ ...streamTiming,
1462
+ recordedTimings: require_timing.extendRecordedTimings(fixtureTimings, events.length, !!prepared.duplicateId)
1463
+ });
1328
1464
  }
1329
1465
  return;
1330
1466
  }
1467
+ if (require_helpers.isRawResponse(response)) {
1468
+ await require_raw.serveRawResponse({
1469
+ wire: "openai-responses",
1470
+ stream: responsesReq.stream === true,
1471
+ req,
1472
+ res,
1473
+ fixture,
1474
+ response,
1475
+ body: completionReq,
1476
+ journal,
1477
+ defaults,
1478
+ testId,
1479
+ misbehaviorSummary: misbehavior.summary,
1480
+ errorWire: "openai"
1481
+ });
1482
+ return;
1483
+ }
1331
1484
  if (require_helpers.isErrorResponse(response)) {
1332
1485
  const status = response.status ?? 500;
1333
1486
  require_misbehavior.recordMisbehaviorOutcome({
@@ -1350,7 +1503,7 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1350
1503
  }
1351
1504
  if (require_helpers.isCombinedFixtureResponse(response)) {
1352
1505
  const overrides = require_helpers.extractOverrides(response);
1353
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1506
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1354
1507
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
1355
1508
  const journalEntry = journal.add({
1356
1509
  method: req.method ?? "POST",
@@ -1371,32 +1524,16 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1371
1524
  const ordered = require_helpers.resolveServedBlockOutcome(response)?.ordered;
1372
1525
  if (!ordered) require_helpers.assertCustomToolCalls(response);
1373
1526
  const toolCalls = require_helpers.servedToolCalls(response);
1374
- if (responsesReq.stream !== true) {
1375
- const body = buildContentWithToolCallsResponse(response.content ?? "", toolCalls, completionReq.model, effReasoning, response.webSearches, overrides, ordered, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1376
- res.writeHead(200, { "Content-Type": "application/json" });
1377
- res.end(JSON.stringify(body));
1378
- } else {
1527
+ if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildContentWithToolCallsResponse(response.content ?? "", toolCalls, completionReq.model, effReasoning, response.webSearches, overrides, ordered, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
1528
+ else {
1379
1529
  const events = contentWithToolCallsStreamEvents(response.content ?? "", toolCalls, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, ordered, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1380
- const interruption = require_interruption.createInterruptionSignal(fixture);
1381
- if (!await writeResponsesSSEStream(res, events, {
1382
- latency,
1383
- streamingProfile: fixture.streamingProfile,
1384
- recordedTimings: fixtureTimings,
1385
- replaySpeed: effectiveReplaySpeed,
1386
- signal: interruption?.signal,
1387
- onChunkSent: interruption?.tick
1388
- })) {
1389
- if (!res.writableEnded) res.destroy();
1390
- journalEntry.response.interrupted = true;
1391
- journalEntry.response.interruptReason = interruption?.reason();
1392
- }
1393
- interruption?.cleanup();
1530
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
1394
1531
  }
1395
1532
  return;
1396
1533
  }
1397
1534
  if (require_helpers.isTextResponse(response)) {
1398
1535
  const overrides = require_helpers.extractOverrides(response);
1399
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1536
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1400
1537
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
1401
1538
  const journalEntry = journal.add({
1402
1539
  method: req.method ?? "POST",
@@ -1414,32 +1551,16 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1414
1551
  defaults,
1415
1552
  testId
1416
1553
  });
1417
- if (responsesReq.stream !== true) {
1418
- const body = buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1419
- res.writeHead(200, { "Content-Type": "application/json" });
1420
- res.end(JSON.stringify(body));
1421
- } else {
1554
+ if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
1555
+ else {
1422
1556
  const events = buildTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1423
- const interruption = require_interruption.createInterruptionSignal(fixture);
1424
- if (!await writeResponsesSSEStream(res, events, {
1425
- latency,
1426
- streamingProfile: fixture.streamingProfile,
1427
- recordedTimings: fixtureTimings,
1428
- replaySpeed: effectiveReplaySpeed,
1429
- signal: interruption?.signal,
1430
- onChunkSent: interruption?.tick
1431
- })) {
1432
- if (!res.writableEnded) res.destroy();
1433
- journalEntry.response.interrupted = true;
1434
- journalEntry.response.interruptReason = interruption?.reason();
1435
- }
1436
- interruption?.cleanup();
1557
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
1437
1558
  }
1438
1559
  return;
1439
1560
  }
1440
1561
  if (require_helpers.isToolCallResponse(response)) {
1441
1562
  const overrides = require_helpers.extractOverrides(response);
1442
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1563
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1443
1564
  const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
1444
1565
  const journalEntry = journal.add({
1445
1566
  method: req.method ?? "POST",
@@ -1458,26 +1579,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1458
1579
  testId
1459
1580
  });
1460
1581
  require_helpers.assertCustomToolCalls(response);
1461
- if (responsesReq.stream !== true) {
1462
- const body = buildToolCallResponse(require_helpers.servedToolCalls(response), completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1463
- res.writeHead(200, { "Content-Type": "application/json" });
1464
- res.end(JSON.stringify(body));
1465
- } else {
1582
+ if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildToolCallResponse(require_helpers.servedToolCalls(response), completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
1583
+ else {
1466
1584
  const events = toolCallStreamEvents(require_helpers.servedToolCalls(response), completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
1467
- const interruption = require_interruption.createInterruptionSignal(fixture);
1468
- if (!await writeResponsesSSEStream(res, events, {
1469
- latency,
1470
- streamingProfile: fixture.streamingProfile,
1471
- recordedTimings: fixtureTimings,
1472
- replaySpeed: effectiveReplaySpeed,
1473
- signal: interruption?.signal,
1474
- onChunkSent: interruption?.tick
1475
- })) {
1476
- if (!res.writableEnded) res.destroy();
1477
- journalEntry.response.interrupted = true;
1478
- journalEntry.response.interruptReason = interruption?.reason();
1479
- }
1480
- interruption?.cleanup();
1585
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
1481
1586
  }
1482
1587
  return;
1483
1588
  }
@@ -1496,10 +1601,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
1496
1601
  defaults,
1497
1602
  testId
1498
1603
  });
1499
- require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
1604
+ require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
1500
1605
  message: "Fixture response did not match any known type",
1501
1606
  type: "server_error"
1502
- } }));
1607
+ }).body);
1503
1608
  }
1504
1609
  /** Prepare call IDs once, retaining the engine's effective blocks and exact served-call metadata. */
1505
1610
  function prepareResponsesMisbehavior(plan) {
@@ -1512,7 +1617,11 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
1512
1617
  const overrides = require_helpers.extractOverrides(response);
1513
1618
  const reasoning = plan.reasoning ?? ("reasoning" in response ? response.reasoning : void 0);
1514
1619
  const webSearches = "webSearches" in response ? response.webSearches : void 0;
1515
- const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(request.model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, false, plan.reasoning !== void 0);
1620
+ const outputWithheld = plan.refusal !== void 0 || plan.summary.fault === "empty-response" || plan.stop === "content_filter" || plan.reasoning !== void 0;
1621
+ const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(request.model, chunkSize, reasoning, webSearches, outputWithheld ? {
1622
+ ...overrides,
1623
+ files: void 0
1624
+ } : overrides, emitEncryptedReasoning, false, plan.reasoning !== void 0);
1516
1625
  const output = [...prefixOutputItems];
1517
1626
  let outputIndex = nextOutputIndex;
1518
1627
  const incomplete = plan.stop === "length" || plan.stop === "content_filter";
@@ -1527,6 +1636,7 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
1527
1636
  type: "message",
1528
1637
  role: "assistant",
1529
1638
  status: "completed",
1639
+ ...overrides.phase !== void 0 ? { phase: overrides.phase } : {},
1530
1640
  content: [part]
1531
1641
  };
1532
1642
  const position = {
@@ -1569,16 +1679,18 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
1569
1679
  item
1570
1680
  });
1571
1681
  output.push(item);
1572
- } else if (plan.summary.fault !== "empty-response" && plan.stop !== "content_filter" && plan.reasoning === void 0) {
1682
+ } else if (!outputWithheld) {
1573
1683
  const combined = require_helpers.isCombinedFixtureResponse(response);
1574
1684
  const blocks = (combined ? require_helpers.resolveServedBlockOutcome(response) : void 0)?.ordered ?? [..."content" in response && typeof response.content === "string" ? [{
1575
1685
  type: "text",
1576
1686
  text: response.content
1577
1687
  }] : [], ...combined || require_helpers.isToolCallResponse(response) ? require_helpers.servedToolCalls(response).map(require_helpers.toolCallFixtureBlock) : []];
1578
1688
  let callIndex = 0;
1689
+ const textAnnotations = orderedBlockAnnotations(blocks, overrides.citations);
1690
+ let textPos = 0;
1579
1691
  for (const block of blocks) {
1580
1692
  if (block.type === "text") {
1581
- const message = buildMessageOutputEvents(block.text, chunkSize, outputIndex);
1693
+ const message = buildMessageOutputEvents(block.text, chunkSize, outputIndex, overrides.phase, textAnnotations[textPos++]);
1582
1694
  events.push(...message.events);
1583
1695
  output.push(message.msgItem);
1584
1696
  } else {
@@ -1607,11 +1719,7 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
1607
1719
  status: incomplete ? "incomplete" : responsesStatus(overrides?.finishReason, "completed"),
1608
1720
  ...incomplete ? { incomplete_details: { reason: plan.stop === "content_filter" ? "content_filter" : "max_output_tokens" } } : {},
1609
1721
  output,
1610
- usage: {
1611
- input_tokens: usage.prompt_tokens,
1612
- output_tokens: usage.completion_tokens,
1613
- total_tokens: usage.total_tokens
1614
- }
1722
+ usage: require_responses.render({ usage })
1615
1723
  };
1616
1724
  events.push({
1617
1725
  type: incomplete ? "response.incomplete" : "response.completed",