@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/server.cjs CHANGED
@@ -1,7 +1,10 @@
1
1
  const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
+ const require_profiles = require('./response/profiles.cjs');
3
+ const require_errors = require('./response/errors.cjs');
2
4
  const require_constants = require('./constants.cjs');
3
5
  const require_message_text = require('./message-text.cjs');
4
6
  const require_api_key_auth = require('./api-key-auth.cjs');
7
+ const require_policy = require('./response/policy.cjs');
5
8
  const require_helpers = require('./helpers.cjs');
6
9
  const require_live_fixture = require('./live-fixture.cjs');
7
10
  const require_sse_writer = require('./sse-writer.cjs');
@@ -12,11 +15,20 @@ const require_router = require('./router.cjs');
12
15
  const require_recorder = require('./recorder.cjs');
13
16
  const require_logger = require('./logger.cjs');
14
17
  const require_journal = require('./journal.cjs');
15
- const require_interruption = require('./interruption.cjs');
18
+ const require_lifecycle = require('./response/lifecycle.cjs');
19
+ const require_timing = require('./response/timing.cjs');
20
+ const require_deliver = require('./response/deliver.cjs');
21
+ const require_proxy = require('./response/proxy.cjs');
22
+ const require_collect = require('./response/catalog/collect.cjs');
23
+ const require_render = require('./response/catalog/render.cjs');
16
24
  const require_openrouter_chat = require('./openrouter-chat.cjs');
25
+ const require_raw = require('./response/raw.cjs');
26
+ const require_anthropic_page = require('./response/catalog/anthropic-page.cjs');
27
+ const require_gemini_page = require('./response/catalog/gemini-page.cjs');
17
28
  const require_responses = require('./responses.cjs');
18
29
  const require_messages = require('./messages.cjs');
19
30
  const require_gemini = require('./gemini.cjs');
31
+ const require_count_tokens = require('./count-tokens.cjs');
20
32
  const require_gemini_embeddings = require('./gemini-embeddings.cjs');
21
33
  const require_bedrock = require('./bedrock.cjs');
22
34
  const require_bedrock_converse = require('./bedrock-converse.cjs');
@@ -89,13 +101,6 @@ function normalizeCompatPath(pathname, logger) {
89
101
  }
90
102
  return pathname;
91
103
  }
92
- const DEFAULT_MODELS = [
93
- "gpt-4",
94
- "gpt-4o",
95
- "claude-3-5-sonnet-20241022",
96
- "gemini-2.0-flash",
97
- "text-embedding-3-small"
98
- ];
99
104
  const CORS_HEADERS = {
100
105
  "Access-Control-Allow-Origin": "*",
101
106
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
@@ -112,10 +117,10 @@ function handleOptions(res) {
112
117
  }
113
118
  function handleNotFound(res, message) {
114
119
  setCorsHeaders(res);
115
- require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
120
+ require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "route-failure", {
116
121
  message,
117
122
  type: "not_found"
118
- } }));
123
+ }).body);
119
124
  }
120
125
  /** The complete `GET /__aimock/fixtures` query-param vocabulary; anything else 400s. */
121
126
  const FIXTURES_PARAMS = new Set(["include"]);
@@ -212,6 +217,7 @@ function fixtureResponseKind(response) {
212
217
  if (require_helpers.isCombinedFixtureResponse(response)) return "contentWithToolCalls";
213
218
  if (require_helpers.isToolCallResponse(response)) return "toolCalls";
214
219
  if (require_helpers.isTextResponse(response)) return "text";
220
+ if (require_helpers.isRawResponse(response)) return "raw";
215
221
  return "unknown";
216
222
  }
217
223
  /**
@@ -897,7 +903,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
897
903
  const clientAbort = clientAbortedMidBody(req, res, err);
898
904
  const bodyLimitDisconnect = clientFault && (req.destroyed || res.destroyed);
899
905
  if (clientAbort || bodyLimitDisconnect) {
900
- const interruptReason = bodyLimitDisconnect ? "request body exceeded size limit" : "client aborted";
906
+ const interruptReason = bodyLimitDisconnect ? "request body exceeded size limit" : require_lifecycle.CLIENT_ABORTED;
901
907
  defaults.logger.warn(bodyLimitDisconnect ? `${route}: ${msg}` : `${route}: client aborted mid-body (${msg})`);
902
908
  journal.add({
903
909
  method: req.method ?? "POST",
@@ -926,10 +932,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
926
932
  fixture: null
927
933
  }
928
934
  });
929
- require_sse_writer.writeErrorResponse(res, status, openRouter ? require_openrouter_chat.serializeOpenRouterError(status, `Request body read failed: ${msg}`) : JSON.stringify({ error: {
935
+ require_sse_writer.writeErrorResponse(res, status, openRouter ? require_openrouter_chat.serializeOpenRouterError(status, `Request body read failed: ${msg}`) : require_errors.renderError("openai", "transport-failure", {
930
936
  message: `Request body read failed: ${msg}`,
931
937
  type: clientFault ? "invalid_request_error" : "server_error"
932
- } }));
938
+ }).body);
933
939
  return;
934
940
  }
935
941
  let body;
@@ -947,12 +953,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
947
953
  fixture: null
948
954
  }
949
955
  });
950
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, `Malformed JSON: ${detail}`) : JSON.stringify({ error: {
956
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, `Malformed JSON: ${detail}`) : require_errors.renderError("openai", "validation", {
951
957
  message: `Malformed JSON: ${detail}`,
952
958
  type: "invalid_request_error",
953
959
  param: null,
954
- code: "invalid_json"
955
- } }));
960
+ code: "invalid_json",
961
+ includeParam: true
962
+ }).body);
956
963
  return;
957
964
  }
958
965
  if (!require_helpers.isJsonObject(body)) {
@@ -966,10 +973,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
966
973
  fixture: null
967
974
  }
968
975
  });
969
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Request body must be a JSON object") : JSON.stringify({ error: {
976
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Request body must be a JSON object") : require_errors.renderError("openai", "validation", {
970
977
  message: "Request body must be a JSON object",
971
978
  type: "invalid_request_error"
972
- } }));
979
+ }).body);
973
980
  return;
974
981
  }
975
982
  if (modelFallback && !body.model) body.model = modelFallback;
@@ -984,12 +991,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
984
991
  fixture: null
985
992
  }
986
993
  });
987
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Missing required parameter: 'messages'") : JSON.stringify({ error: {
994
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Missing required parameter: 'messages'") : require_errors.renderError("openai", "validation", {
988
995
  message: "Missing required parameter: 'messages'",
989
996
  type: "invalid_request_error",
990
997
  param: null,
991
- code: null
992
- } }));
998
+ code: null,
999
+ includeParam: true
1000
+ }).body);
993
1001
  return;
994
1002
  }
995
1003
  const nullMessageIndex = body.messages.findIndex((message) => message === null);
@@ -1005,12 +1013,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1005
1013
  fixture: null
1006
1014
  }
1007
1015
  });
1008
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, message) : JSON.stringify({ error: {
1016
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, message) : require_errors.renderError("openai", "validation", {
1009
1017
  message,
1010
1018
  type: "invalid_request_error",
1011
1019
  param: null,
1012
- code: null
1013
- } }));
1020
+ code: null,
1021
+ includeParam: true
1022
+ }).body);
1014
1023
  return;
1015
1024
  }
1016
1025
  if (new URL(req.url ?? require_route_registry.COMPLETIONS_PATH, "http://localhost").pathname === require_route_registry.COMPLETIONS_PATH) {
@@ -1030,10 +1039,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1030
1039
  fixture: null
1031
1040
  }
1032
1041
  });
1033
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
1042
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
1034
1043
  message: toolsError,
1035
1044
  type: "invalid_request_error"
1036
- } }));
1045
+ }).body);
1037
1046
  return;
1038
1047
  }
1039
1048
  }
@@ -1043,7 +1052,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1043
1052
  body._endpointType = "chat";
1044
1053
  body._context = require_helpers.getContext(req);
1045
1054
  const testId = require_helpers.getTestId(req);
1046
- const matchOptions = require_router.recordMatchOptions(!!(defaults.record && providerKey), defaults.logger);
1055
+ const matchOptions = {
1056
+ ...require_router.recordMatchOptions(!!(defaults.record && providerKey), defaults.logger),
1057
+ wire: "openai-chat"
1058
+ };
1047
1059
  let fixture = null;
1048
1060
  let skippedBySequenceOrTurn = 0;
1049
1061
  let preResolvedResponse = null;
@@ -1073,10 +1085,11 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1073
1085
  skippedBySequenceOrTurn = Math.max(skippedBySequenceOrTurn, attempt.skippedBySequenceOrTurn);
1074
1086
  if (!attempt.fixture) return null;
1075
1087
  const response = await require_helpers.resolveResponse(attempt.fixture, probe);
1088
+ const isError = require_helpers.isErrorResponse(response) || require_helpers.isRawResponse(response) && (response.raw.status ?? 200) >= 400;
1076
1089
  return {
1077
1090
  fixture: attempt.fixture,
1078
1091
  response,
1079
- isError: require_helpers.isErrorResponse(response)
1092
+ isError
1080
1093
  };
1081
1094
  };
1082
1095
  for (const candidate of candidates) {
@@ -1090,7 +1103,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1090
1103
  matchCounts = journal.getFixtureMatchCountsForTest(testId);
1091
1104
  responseModel = candidate;
1092
1105
  if (outcome.isError) {
1093
- const errorFallsThrough = outcome.response.fallthrough !== false;
1106
+ const errorFallsThrough = !require_helpers.isErrorResponse(outcome.response) || outcome.response.fallthrough !== false;
1094
1107
  if (allowFallbacks && errorFallsThrough) {
1095
1108
  lastErrorFixture = outcome.fixture;
1096
1109
  lastErrorResponse = outcome.response;
@@ -1133,8 +1146,9 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1133
1146
  headers: flatHeaders,
1134
1147
  body
1135
1148
  };
1136
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1137
- const missWouldProxy = require_helpers.wouldProxyMiss(effectiveStrict, defaults.record, providerKey);
1149
+ const missDecisions = require_policy.resolveRequestDecisions(defaults.strict, req.headers);
1150
+ const effectiveStrict = missDecisions.fixtureMiss;
1151
+ const missWouldProxy = require_helpers.wouldProxyMiss(!missDecisions.upstream, defaults.record, providerKey);
1138
1152
  const noFixtureSource = missWouldProxy ? "proxy" : "internal";
1139
1153
  const recordBypass = (reason) => {
1140
1154
  const entry = getRequestEntry();
@@ -1178,15 +1192,16 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1178
1192
  response: {
1179
1193
  status: strictStatus,
1180
1194
  fixture: null,
1181
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1195
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1182
1196
  }
1183
1197
  });
1184
- require_sse_writer.writeErrorResponse(res, strictStatus, openRouter ? require_openrouter_chat.serializeOpenRouterError(strictStatus, strictMessage) : JSON.stringify({ error: {
1198
+ require_sse_writer.writeErrorResponse(res, strictStatus, openRouter ? require_openrouter_chat.serializeOpenRouterError(strictStatus, strictMessage) : require_errors.renderError("openai", "strict-miss", {
1185
1199
  message: strictMessage,
1186
1200
  type: "invalid_request_error",
1187
1201
  param: null,
1188
- code: "no_fixture_match"
1189
- } }));
1202
+ code: "no_fixture_match",
1203
+ includeParam: true
1204
+ }).body);
1190
1205
  return;
1191
1206
  }
1192
1207
  if (defaults.record && providerKey) {
@@ -1205,22 +1220,9 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1205
1220
  });
1206
1221
  }
1207
1222
  } : void 0;
1208
- let clientHungUp = false;
1209
- const noteClientHangUp = () => {
1210
- if (!res.writableEnded) clientHungUp = true;
1211
- };
1212
- req.socket?.on("end", noteClientHangUp);
1213
- req.socket?.on("error", noteClientHangUp);
1214
- let outcome;
1215
- try {
1216
- outcome = await require_recorder.proxyAndRecord(req, res, body, providerKey, req.url ?? require_route_registry.COMPLETIONS_PATH, fixtures, defaults, raw, hookOptions);
1217
- } finally {
1218
- req.socket?.off("end", noteClientHangUp);
1219
- req.socket?.off("error", noteClientHangUp);
1220
- }
1223
+ const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, body, providerKey, req.url ?? require_route_registry.COMPLETIONS_PATH, fixtures, defaults, raw, hookOptions));
1221
1224
  if (outcome === "handled_by_hook") return;
1222
1225
  if (outcome !== "not_configured") {
1223
- const destroyedMidStream = res.destroyed && !res.writableEnded;
1224
1226
  journal.add({
1225
1227
  method: req.method ?? "POST",
1226
1228
  path: req.url ?? require_route_registry.COMPLETIONS_PATH,
@@ -1230,10 +1232,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1230
1232
  status: res.statusCode ?? 200,
1231
1233
  fixture: null,
1232
1234
  source: "proxy",
1233
- ...destroyedMidStream ? {
1234
- interrupted: true,
1235
- interruptReason: clientHungUp ? "client aborted" : "proxy stream destroyed"
1236
- } : {}
1235
+ ...require_proxy.proxyInterruption(res, clientHungUp)
1237
1236
  }
1238
1237
  });
1239
1238
  recordBypass("proxied");
@@ -1253,15 +1252,16 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1253
1252
  response: {
1254
1253
  status: 404,
1255
1254
  fixture: null,
1256
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1255
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1257
1256
  }
1258
1257
  });
1259
- require_sse_writer.writeErrorResponse(res, 404, openRouter ? require_openrouter_chat.serializeOpenRouterError(404, "No fixture matched") : JSON.stringify({ error: {
1258
+ require_sse_writer.writeErrorResponse(res, 404, openRouter ? require_openrouter_chat.serializeOpenRouterError(404, "No fixture matched") : require_errors.renderError("openai", "fixture-miss", {
1260
1259
  message: "No fixture matched",
1261
1260
  type: "invalid_request_error",
1262
1261
  param: null,
1263
- code: "no_fixture_match"
1264
- } }));
1262
+ code: "no_fixture_match",
1263
+ includeParam: true
1264
+ }).body);
1265
1265
  return;
1266
1266
  }
1267
1267
  const resolvedResponse = preResolvedResponse ?? await require_helpers.resolveResponse(fixture, body);
@@ -1292,12 +1292,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1292
1292
  testId
1293
1293
  });
1294
1294
  if (!evaluation.summary?.evaluations.some((row) => row.outcome === "error")) defaults.logger.error(`${evaluation.code}: ${evaluation.message}`);
1295
- require_sse_writer.writeErrorResponse(res, evaluation.status, openRouter ? require_openrouter_chat.serializeOpenRouterError(evaluation.status, `${evaluation.code}: ${evaluation.message}`) : JSON.stringify({ error: {
1295
+ require_sse_writer.writeErrorResponse(res, evaluation.status, openRouter ? require_openrouter_chat.serializeOpenRouterError(evaluation.status, `${evaluation.code}: ${evaluation.message}`) : require_errors.renderError("openai", "misbehavior", {
1296
1296
  message: evaluation.message,
1297
1297
  type: "invalid_request_error",
1298
1298
  param: null,
1299
- code: evaluation.code
1300
- } }));
1299
+ code: evaluation.code,
1300
+ includeParam: true
1301
+ }).body);
1301
1302
  return;
1302
1303
  }
1303
1304
  const appliedPlan = evaluation.kind === "applied" ? require_helpers.prepareOpenAIChatMisbehavior(evaluation) : void 0;
@@ -1311,21 +1312,30 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1311
1312
  testId
1312
1313
  });
1313
1314
  };
1314
- const appliedReasoning = appliedPlan && appliedPlan.reasoning === void 0 && (require_helpers.isTextResponse(response) || require_helpers.isToolCallResponse(response) || require_helpers.isCombinedFixtureResponse(response)) ? require_helpers.resolveReasoningForModel(response.reasoning, responseModel, require_helpers.resolveStrictMode(defaults.strict, req.headers), defaults.logger) : void 0;
1315
+ const appliedReasoning = appliedPlan && appliedPlan.reasoning === void 0 && (require_helpers.isTextResponse(response) || require_helpers.isToolCallResponse(response) || require_helpers.isCombinedFixtureResponse(response)) ? require_helpers.resolveReasoningForModel(response.reasoning, responseModel, require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression, defaults.logger) : void 0;
1315
1316
  const appliedUsage = appliedPlan ? require_helpers.resolveOpenAIChatMisbehaviorUsage(appliedPlan, body, appliedPlan.reasoning === void 0 ? appliedReasoning !== void 0 : openRouter) : void 0;
1316
1317
  const latency = fixture.latency ?? defaults.latency;
1317
1318
  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
1318
1319
  const emitStreamingUsage = body.stream === true && body.stream_options?.include_usage === true || openRouter;
1319
1320
  const streamingPromptText = body.messages.map((m) => typeof m.content === "string" ? m.content : Array.isArray(m.content) ? m.content.map((p) => p.text ?? "").join("") : "").join("");
1320
1321
  const resolveStreamingUsageTokens = (overrides, completionText) => appliedUsage ?? require_helpers.resolveUsage(overrides, streamingPromptText, completionText);
1321
- const resolveRecordedTimings = (chunks) => {
1322
- const timings = fixture.recordedTimings;
1323
- if (!appliedPlan?.duplicateId || !timings) return timings;
1324
- const gaps = timings.interChunkDelaysMs;
1325
- return {
1326
- ...timings,
1327
- interChunkDelaysMs: Array.from({ length: Math.max(gaps.length, chunks.length - 1) }, (_, index) => gaps[index] ?? gaps.at(-1) ?? 0)
1328
- };
1322
+ const nonStreamingOpts = (payloadLength) => ({
1323
+ surface: "openai-chat",
1324
+ payloadLength,
1325
+ chunkSize,
1326
+ recordedTimings: fixture.recordedTimings,
1327
+ duplicateId: !!appliedPlan?.duplicateId,
1328
+ replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed
1329
+ });
1330
+ const streamTiming = (frameCount) => ({
1331
+ latency,
1332
+ streamingProfile: fixture.streamingProfile,
1333
+ recordedTimings: require_timing.extendRecordedTimings(fixture.recordedTimings, frameCount, !!appliedPlan?.duplicateId),
1334
+ replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed
1335
+ });
1336
+ const commitNonStream = async (entry, reply, payloadLength) => {
1337
+ recordOutcome(entry);
1338
+ await require_deliver.deliverJson(res, entry, fixture, () => reply, nonStreamingOpts(payloadLength));
1329
1339
  };
1330
1340
  const shapeORCompletion = (completion, overrides) => {
1331
1341
  if (appliedUsage) completion.usage = appliedUsage;
@@ -1339,6 +1349,24 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1339
1349
  if (usageChunk) require_openrouter_chat.shapeOpenRouterChunks([usageChunk], shaping, overrides?.id !== void 0);
1340
1350
  };
1341
1351
  const openRouterProcessing = !!(openRouter && fixture.openRouterProcessing);
1352
+ if (require_helpers.isRawResponse(response)) {
1353
+ await require_raw.serveRawResponse({
1354
+ wire: "openai-chat",
1355
+ stream: body.stream === true,
1356
+ req,
1357
+ res,
1358
+ fixture,
1359
+ response,
1360
+ body,
1361
+ journal,
1362
+ defaults,
1363
+ testId,
1364
+ misbehaviorSummary: evaluation.summary,
1365
+ errorWire: "openai",
1366
+ openRouter
1367
+ });
1368
+ return;
1369
+ }
1342
1370
  if (require_helpers.isErrorResponse(response)) {
1343
1371
  const status = response.status ?? 500;
1344
1372
  recordOutcome(journal.add({
@@ -1365,10 +1393,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1365
1393
  fixture
1366
1394
  }
1367
1395
  }));
1368
- require_sse_writer.writeErrorResponse(res, 422, openRouter ? require_openrouter_chat.serializeOpenRouterError(422, "Audio responses are not supported on the chat completions endpoint. Use Gemini generateContent or a dedicated audio endpoint.") : JSON.stringify({ error: {
1396
+ require_sse_writer.writeErrorResponse(res, 422, openRouter ? require_openrouter_chat.serializeOpenRouterError(422, "Audio responses are not supported on the chat completions endpoint. Use Gemini generateContent or a dedicated audio endpoint.") : require_errors.renderError("openai", "validation", {
1369
1397
  message: "Audio responses are not supported on the chat completions endpoint. Use Gemini generateContent or a dedicated audio endpoint.",
1370
1398
  type: "invalid_request_error"
1371
- } }));
1399
+ }).body);
1372
1400
  return;
1373
1401
  }
1374
1402
  if (appliedPlan && require_helpers.isTextResponse(response) && (appliedPlan.stop === "refusal" || appliedPlan.stop === "content_filter" || appliedPlan.reasoning !== void 0)) {
@@ -1383,38 +1411,25 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1383
1411
  fixture
1384
1412
  }
1385
1413
  });
1386
- recordOutcome(entry);
1387
- if (body.stream !== true) {
1388
- const completion = appliedPlan.stop === "refusal" ? require_helpers.buildOpenAIRefusalCompletion(appliedPlan.refusal ?? "", responseModel, overrides, body.messages) : appliedPlan.stop === "content_filter" ? require_helpers.buildOpenAIContentFilterCompletion(responseModel, overrides, body.messages) : require_helpers.buildOpenAIReasoningCompletion(appliedPlan.reasoning ?? "", responseModel, openRouter, overrides, body.messages);
1389
- res.writeHead(200, { "Content-Type": "application/json" });
1390
- res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1391
- } else {
1414
+ require_helpers.rejectGeneratedFiles(response, wire);
1415
+ if (body.stream !== true) await commitNonStream(entry, shapeORCompletion(appliedPlan.stop === "refusal" ? require_helpers.buildOpenAIRefusalCompletion(appliedPlan.refusal ?? "", responseModel, overrides, body.messages) : appliedPlan.stop === "content_filter" ? require_helpers.buildOpenAIContentFilterCompletion(responseModel, overrides, body.messages) : require_helpers.buildOpenAIReasoningCompletion(appliedPlan.reasoning ?? "", responseModel, openRouter, overrides, body.messages), overrides), require_timing.misbehaviorPayloadLength(appliedPlan, appliedReasoning));
1416
+ else {
1392
1417
  const chunks = appliedPlan.stop === "refusal" ? require_helpers.buildOpenAIRefusalChunks(appliedPlan.refusal ?? "", responseModel, chunkSize, overrides) : appliedPlan.stop === "content_filter" ? require_helpers.buildOpenAIContentFilterChunks(responseModel, overrides) : require_helpers.buildOpenAIReasoningChunks(appliedPlan.reasoning ?? "", responseModel, chunkSize, openRouter, overrides);
1393
1418
  const usageChunk = emitStreamingUsage ? require_helpers.buildUsageChunk(chunks[0].id, overrides?.model ?? responseModel, chunks[0].created, resolveStreamingUsageTokens(overrides, ""), overrides?.systemFingerprint) : void 0;
1394
1419
  shapeORChunks(chunks, usageChunk, overrides);
1395
- const interruption = require_interruption.createInterruptionSignal(fixture);
1396
- if (!await require_sse_writer.writeSSEStream(res, chunks, {
1397
- latency,
1398
- streamingProfile: fixture.streamingProfile,
1399
- signal: interruption?.signal,
1400
- onChunkSent: interruption?.tick,
1420
+ recordOutcome(entry);
1421
+ await require_deliver.deliverStream(res, entry, fixture, require_sse_writer.sseCodec({
1422
+ done: true,
1401
1423
  usageChunk,
1402
- recordedTimings: resolveRecordedTimings(chunks),
1403
- replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1404
1424
  openRouterProcessing
1405
- })) {
1406
- if (!res.writableEnded) res.destroy();
1407
- entry.response.interrupted = true;
1408
- entry.response.interruptReason = interruption?.reason();
1409
- }
1410
- interruption?.cleanup();
1425
+ }), chunks, streamTiming(chunks.length));
1411
1426
  }
1412
1427
  return;
1413
1428
  }
1414
1429
  if (require_helpers.isCombinedFixtureResponse(response)) {
1415
1430
  if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
1416
1431
  const overrides = require_helpers.extractOverrides(response);
1417
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1432
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1418
1433
  const effReasoning = appliedPlan ? appliedReasoning : require_helpers.resolveReasoningForModel(response.reasoning, responseModel, effectiveStrict, defaults.logger);
1419
1434
  const streaming = body.stream === true;
1420
1435
  const blockOutcome = response.blocks && response.blocks.length > 0 ? require_helpers.resolveFixtureBlockOutcome(response.blocks) : void 0;
@@ -1428,43 +1443,33 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1428
1443
  fixture
1429
1444
  }
1430
1445
  });
1431
- recordOutcome(journalEntry);
1446
+ require_helpers.rejectGeneratedFiles(response, wire);
1432
1447
  const toolCalls = require_helpers.requireEmittedFunctionToolCalls(response, wire);
1448
+ const completionText = blockOutcome ? blockOutcome.content + blockOutcome.toolCalls.map((tc) => tc.name + tc.arguments).join("") : (response.content ?? "") + toolCalls.map((tc) => tc.name + tc.arguments).join("");
1433
1449
  if (!streaming) {
1434
1450
  const completion = require_helpers.buildContentWithToolCallsCompletion(blockOutcome?.content ?? response.content ?? "", blockOutcome?.toolCalls ?? toolCalls, responseModel, effReasoning, blockOutcome ? {
1435
1451
  ...overrides,
1436
1452
  finishReason: overrides?.finishReason ?? (blockOutcome.hasToolCalls ? "tool_calls" : "stop")
1437
1453
  } : overrides, body.messages);
1438
- res.writeHead(200, { "Content-Type": "application/json" });
1439
- res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1454
+ const contentLength = (effReasoning?.length ?? 0) + completionText.length;
1455
+ await commitNonStream(journalEntry, shapeORCompletion(completion, overrides), contentLength);
1440
1456
  } else {
1441
1457
  const chunks = require_helpers.buildContentWithToolCallsChunks(blockOutcome?.content ?? response.content ?? "", blockOutcome?.toolCalls ?? toolCalls, responseModel, chunkSize, effReasoning, overrides, blockOutcome?.ordered);
1442
- const completionText = blockOutcome ? blockOutcome.content + blockOutcome.toolCalls.map((tc) => tc.name + tc.arguments).join("") : (response.content ?? "") + toolCalls.map((tc) => tc.name + tc.arguments).join("");
1443
1458
  const usageChunk = emitStreamingUsage ? require_helpers.buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? responseModel, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), resolveStreamingUsageTokens(overrides, completionText), overrides?.systemFingerprint) : void 0;
1444
1459
  shapeORChunks(chunks, usageChunk, overrides);
1445
- const interruption = require_interruption.createInterruptionSignal(fixture);
1446
- if (!await require_sse_writer.writeSSEStream(res, chunks, {
1447
- latency,
1448
- streamingProfile: fixture.streamingProfile,
1449
- signal: interruption?.signal,
1450
- onChunkSent: interruption?.tick,
1460
+ recordOutcome(journalEntry);
1461
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.sseCodec({
1462
+ done: true,
1451
1463
  usageChunk,
1452
- recordedTimings: resolveRecordedTimings(chunks),
1453
- replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1454
1464
  openRouterProcessing
1455
- })) {
1456
- if (!res.writableEnded) res.destroy();
1457
- journalEntry.response.interrupted = true;
1458
- journalEntry.response.interruptReason = interruption?.reason();
1459
- }
1460
- interruption?.cleanup();
1465
+ }), chunks, streamTiming(chunks.length));
1461
1466
  }
1462
1467
  return;
1463
1468
  }
1464
1469
  if (require_helpers.isTextResponse(response)) {
1465
1470
  if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
1466
1471
  const overrides = require_helpers.extractOverrides(response);
1467
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1472
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1468
1473
  const effReasoning = appliedPlan ? appliedReasoning : require_helpers.resolveReasoningForModel(response.reasoning, responseModel, effectiveStrict, defaults.logger);
1469
1474
  const journalEntry = journal.add({
1470
1475
  method: req.method ?? "POST",
@@ -1476,38 +1481,28 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1476
1481
  fixture
1477
1482
  }
1478
1483
  });
1479
- recordOutcome(journalEntry);
1484
+ require_helpers.rejectGeneratedFiles(response, wire);
1480
1485
  if (body.stream !== true) {
1481
1486
  const completion = require_helpers.buildTextCompletion(response.content, responseModel, effReasoning, overrides, body.messages);
1482
- res.writeHead(200, { "Content-Type": "application/json" });
1483
- res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1487
+ const contentLength = (effReasoning?.length ?? 0) + response.content.length;
1488
+ await commitNonStream(journalEntry, shapeORCompletion(completion, overrides), contentLength);
1484
1489
  } else {
1485
1490
  const chunks = require_helpers.buildTextChunks(response.content, responseModel, chunkSize, effReasoning, overrides);
1486
1491
  const usageChunk = emitStreamingUsage ? require_helpers.buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? responseModel, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), resolveStreamingUsageTokens(overrides, response.content), overrides?.systemFingerprint) : void 0;
1487
1492
  shapeORChunks(chunks, usageChunk, overrides);
1488
- const interruption = require_interruption.createInterruptionSignal(fixture);
1489
- if (!await require_sse_writer.writeSSEStream(res, chunks, {
1490
- latency,
1491
- streamingProfile: fixture.streamingProfile,
1492
- signal: interruption?.signal,
1493
- onChunkSent: interruption?.tick,
1493
+ recordOutcome(journalEntry);
1494
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.sseCodec({
1495
+ done: true,
1494
1496
  usageChunk,
1495
- recordedTimings: resolveRecordedTimings(chunks),
1496
- replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1497
1497
  openRouterProcessing
1498
- })) {
1499
- if (!res.writableEnded) res.destroy();
1500
- journalEntry.response.interrupted = true;
1501
- journalEntry.response.interruptReason = interruption?.reason();
1502
- }
1503
- interruption?.cleanup();
1498
+ }), chunks, streamTiming(chunks.length));
1504
1499
  }
1505
1500
  return;
1506
1501
  }
1507
1502
  if (require_helpers.isToolCallResponse(response)) {
1508
1503
  if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
1509
1504
  const overrides = require_helpers.extractOverrides(response);
1510
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1505
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1511
1506
  const effReasoning = appliedPlan ? appliedReasoning : require_helpers.resolveReasoningForModel(response.reasoning, responseModel, effectiveStrict, defaults.logger);
1512
1507
  const journalEntry = journal.add({
1513
1508
  method: req.method ?? "POST",
@@ -1519,33 +1514,24 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1519
1514
  fixture
1520
1515
  }
1521
1516
  });
1522
- recordOutcome(journalEntry);
1517
+ require_helpers.rejectGeneratedFiles(response, wire);
1523
1518
  const toolCalls = require_helpers.requireServedFunctionToolCalls(response, wire);
1524
1519
  if (body.stream !== true) {
1520
+ const toolCallText = toolCalls.map((tc) => tc.name + tc.arguments).join("");
1525
1521
  const completion = require_helpers.buildToolCallCompletion(toolCalls, responseModel, effReasoning, overrides, body.messages);
1526
- res.writeHead(200, { "Content-Type": "application/json" });
1527
- res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1522
+ const contentLength = (effReasoning?.length ?? 0) + toolCallText.length;
1523
+ await commitNonStream(journalEntry, shapeORCompletion(completion, overrides), contentLength);
1528
1524
  } else {
1529
1525
  const chunks = require_helpers.buildToolCallChunks(toolCalls, responseModel, chunkSize, effReasoning, overrides);
1530
1526
  const completionText = toolCalls.map((tc) => tc.name + tc.arguments).join("");
1531
1527
  const usageChunk = emitStreamingUsage ? require_helpers.buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? responseModel, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), resolveStreamingUsageTokens(overrides, completionText), overrides?.systemFingerprint) : void 0;
1532
1528
  shapeORChunks(chunks, usageChunk, overrides);
1533
- const interruption = require_interruption.createInterruptionSignal(fixture);
1534
- if (!await require_sse_writer.writeSSEStream(res, chunks, {
1535
- latency,
1536
- streamingProfile: fixture.streamingProfile,
1537
- signal: interruption?.signal,
1538
- onChunkSent: interruption?.tick,
1529
+ recordOutcome(journalEntry);
1530
+ await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.sseCodec({
1531
+ done: true,
1539
1532
  usageChunk,
1540
- recordedTimings: resolveRecordedTimings(chunks),
1541
- replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1542
1533
  openRouterProcessing
1543
- })) {
1544
- if (!res.writableEnded) res.destroy();
1545
- journalEntry.response.interrupted = true;
1546
- journalEntry.response.interruptReason = interruption?.reason();
1547
- }
1548
- interruption?.cleanup();
1534
+ }), chunks, streamTiming(chunks.length));
1549
1535
  }
1550
1536
  return;
1551
1537
  }
@@ -1559,10 +1545,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1559
1545
  fixture
1560
1546
  }
1561
1547
  }));
1562
- require_sse_writer.writeErrorResponse(res, 500, openRouter ? require_openrouter_chat.serializeOpenRouterError(500, "Fixture response did not match any known type") : JSON.stringify({ error: {
1548
+ require_sse_writer.writeErrorResponse(res, 500, openRouter ? require_openrouter_chat.serializeOpenRouterError(500, "Fixture response did not match any known type") : require_errors.renderError("openai", "unknown-response", {
1563
1549
  message: "Fixture response did not match any known type",
1564
1550
  type: "server_error"
1565
- } }));
1551
+ }).body);
1566
1552
  }
1567
1553
  async function createServer(fixtures, options, mounts, serviceFixtures) {
1568
1554
  return createServerWithResolvedAuth(fixtures, options, require_api_key_auth.resolveInboundAuth({
@@ -1631,6 +1617,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1631
1617
  const port = options?.port ?? 0;
1632
1618
  const registry = options?.metrics ? require_metrics.createMetricsRegistry() : void 0;
1633
1619
  const serverOptions = options ?? {};
1620
+ require_policy.parsePolicy(serverOptions.policy, (message) => new require_logger.Logger("warn").warn(message));
1634
1621
  const validResponsesTools = (mode) => mode === "legacy" || mode === "extended";
1635
1622
  if (serverOptions.responsesTools !== void 0 && !validResponsesTools(serverOptions.responsesTools)) new require_logger.Logger("warn").warn(`Ignoring responsesTools because it must be "legacy" or "extended", got ${JSON.stringify(serverOptions.responsesTools)}. Using "legacy".`);
1636
1623
  fixtures = require_helpers.createServerFixtureList(callerFixtures, () => serverOptions.responsesTools, require_fixture_loader.responsesToolsExtendedView);
@@ -1689,6 +1676,9 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1689
1676
  get strict() {
1690
1677
  return serverOptions.strict;
1691
1678
  },
1679
+ get policy() {
1680
+ return serverOptions.policy;
1681
+ },
1692
1682
  get strictToolArguments() {
1693
1683
  return serverOptions.strictToolArguments;
1694
1684
  },
@@ -1801,10 +1791,12 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1801
1791
  return status >= 400 && status < 500 ? "invalid_request_error" : "server_error";
1802
1792
  }
1803
1793
  /**
1804
- * Envelope for a fixture tool-call error (see isFixtureToolCallError: invalid
1805
- * JSON arguments on an object wire, a custom tool call on a non-Responses
1806
- * wire, or a malformed fixture tool call). It is the provider envelope aimock
1807
- * emits for that route, with the aimock `code` in it: Google's
1794
+ * Envelope for a fixture error (see isFixtureToolCallError: invalid JSON
1795
+ * arguments on an object wire, a custom tool call on a non-Responses wire, a
1796
+ * malformed fixture tool call, generated `files` on a wire that cannot carry
1797
+ * them, or a malformed fixture `citations` or `files` value). It is the
1798
+ * provider envelope aimock emits for that route, with the aimock `code` in
1799
+ * it: Google's
1808
1800
  * `google.rpc.ErrorInfo` detail on Gemini and Vertex AI, a string
1809
1801
  * `error.code` on Gemini Interactions and Anthropic Messages, a `reason`
1810
1802
  * member on Bedrock (a `code` member would replace `__type` as the AWS SDK's
@@ -1814,70 +1806,63 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1814
1806
  * `toolCallEnvelope` instead of using this one.
1815
1807
  */
1816
1808
  function invalidToolArgumentsEnvelope(pathname, message, code) {
1817
- if (pathname === require_route_registry.OLLAMA_CHAT_PATH) return JSON.stringify({
1818
- error: message,
1809
+ if (pathname === require_route_registry.OLLAMA_CHAT_PATH) return require_errors.renderError("ollama", "tool-argument", {
1810
+ message,
1819
1811
  code
1820
- });
1821
- if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return JSON.stringify({ error: {
1812
+ }).body;
1813
+ if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return require_errors.renderError("interactions", "tool-argument", {
1814
+ message,
1815
+ code
1816
+ }).body;
1817
+ if (require_route_registry.GEMINI_PATH_RE.test(pathname) || require_route_registry.VERTEX_AI_RE.test(pathname)) return require_errors.renderError("gemini", "tool-argument", {
1818
+ message,
1822
1819
  code,
1823
- message
1824
- } });
1825
- if (require_route_registry.GEMINI_PATH_RE.test(pathname) || require_route_registry.VERTEX_AI_RE.test(pathname)) return JSON.stringify({ error: {
1826
- code: 500,
1820
+ googleDetails: require_helpers.googleFixtureToolCallErrorDetails(code)
1821
+ }).body;
1822
+ if (pathname === require_route_registry.MESSAGES_PATH) return require_errors.renderError("messages", "tool-argument", {
1827
1823
  message,
1828
- status: "INTERNAL",
1829
- details: require_helpers.googleFixtureToolCallErrorDetails(code)
1830
- } });
1831
- if (pathname === require_route_registry.MESSAGES_PATH) return JSON.stringify({
1832
- type: "error",
1833
- error: {
1834
- type: "api_error",
1835
- code,
1836
- message
1837
- }
1838
- });
1839
- if (require_route_registry.BEDROCK_INVOKE_RE.test(pathname) || require_route_registry.BEDROCK_STREAM_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_STREAM_RE.test(pathname)) return JSON.stringify({
1840
- __type: "InternalServerException",
1824
+ code
1825
+ }).body;
1826
+ if (require_route_registry.BEDROCK_INVOKE_RE.test(pathname) || require_route_registry.BEDROCK_STREAM_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_STREAM_RE.test(pathname)) return require_errors.renderError("bedrock", "tool-argument", {
1841
1827
  message,
1842
- reason: code
1843
- });
1844
- return JSON.stringify({ error: {
1828
+ code
1829
+ }).body;
1830
+ return require_errors.renderError("openai", "tool-argument", {
1845
1831
  message,
1846
- type: "server_error",
1847
1832
  code
1848
- } });
1833
+ }).body;
1849
1834
  }
1850
1835
  function invalidMisbehaviorHeaderEnvelope(pathname, detail) {
1851
1836
  const code = "aimock_misbehavior_invalid";
1852
1837
  const message = `${code}: ${detail}`;
1853
- if (pathname === require_route_registry.OLLAMA_CHAT_PATH || pathname === require_route_registry.OLLAMA_GENERATE_PATH) return JSON.stringify({ error: message });
1854
- if (pathname === require_route_registry.COHERE_CHAT_PATH) return JSON.stringify({ message });
1855
- if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return JSON.stringify({ error: {
1856
- code,
1857
- message
1858
- } });
1859
- if (require_route_registry.GEMINI_PATH_RE.test(pathname) || require_route_registry.VERTEX_AI_RE.test(pathname)) return JSON.stringify({ error: {
1860
- code: 400,
1838
+ if (pathname === require_route_registry.OLLAMA_CHAT_PATH || pathname === require_route_registry.OLLAMA_GENERATE_PATH) return require_errors.renderError("ollama", "invalid-misbehavior-header", {
1861
1839
  message,
1862
- status: "INVALID_ARGUMENT"
1863
- } });
1864
- if (pathname === require_route_registry.MESSAGES_PATH) return JSON.stringify({
1865
- type: "error",
1866
- error: {
1867
- type: "invalid_request_error",
1868
- code,
1869
- message
1870
- }
1871
- });
1872
- if (require_route_registry.BEDROCK_INVOKE_RE.test(pathname) || require_route_registry.BEDROCK_STREAM_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_STREAM_RE.test(pathname)) return JSON.stringify({
1873
- __type: "ValidationException",
1874
- message
1875
- });
1876
- return JSON.stringify({ error: {
1840
+ code
1841
+ }).body;
1842
+ if (pathname === require_route_registry.COHERE_CHAT_PATH) return require_errors.renderError("cohere", "invalid-misbehavior-header", {
1843
+ message,
1844
+ code
1845
+ }).body;
1846
+ if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return require_errors.renderError("interactions", "invalid-misbehavior-header", {
1847
+ message,
1848
+ code
1849
+ }).body;
1850
+ if (require_route_registry.GEMINI_PATH_RE.test(pathname) || require_route_registry.VERTEX_AI_RE.test(pathname)) return require_errors.renderError("gemini", "invalid-misbehavior-header", {
1877
1851
  message,
1878
- type: "invalid_request_error",
1879
1852
  code
1880
- } });
1853
+ }).body;
1854
+ if (pathname === require_route_registry.MESSAGES_PATH) return require_errors.renderError("messages", "invalid-misbehavior-header", {
1855
+ message,
1856
+ code
1857
+ }).body;
1858
+ if (require_route_registry.BEDROCK_INVOKE_RE.test(pathname) || require_route_registry.BEDROCK_STREAM_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_RE.test(pathname) || require_route_registry.BEDROCK_CONVERSE_STREAM_RE.test(pathname)) return require_errors.renderError("bedrock", "invalid-misbehavior-header", {
1859
+ message,
1860
+ code
1861
+ }).body;
1862
+ return require_errors.renderError("openai", "invalid-misbehavior-header", {
1863
+ message,
1864
+ code
1865
+ }).body;
1881
1866
  }
1882
1867
  /**
1883
1868
  * The newest journal entry this request already produced, or null.
@@ -1941,7 +1926,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1941
1926
  const existing = lastJournalEntryFor(req);
1942
1927
  const bodyLimitDisconnect = clientFault && (req.destroyed || res.destroyed);
1943
1928
  if ((clientAbort || bodyLimitDisconnect) && !res.headersSent) {
1944
- const interruptReason = bodyLimitDisconnect ? "request body exceeded size limit" : "client aborted";
1929
+ const interruptReason = bodyLimitDisconnect ? "request body exceeded size limit" : require_lifecycle.CLIENT_ABORTED;
1945
1930
  if (existing) {
1946
1931
  if (!existing.response.interrupted) {
1947
1932
  existing.response.status = 0;
@@ -1992,12 +1977,12 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1992
1977
  logger.warn(`${route}: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
1993
1978
  }
1994
1979
  setCorsHeaders(res);
1995
- require_sse_writer.writeErrorResponse(res, status, invalidToolArguments ? (opts?.toolCallEnvelope ?? ((m, c) => invalidToolArgumentsEnvelope(pathname, m, c)))(msg, require_helpers.fixtureToolCallErrorCode(err)) : opts?.envelope ? opts.envelope(msg, status) : JSON.stringify({ error: {
1980
+ require_sse_writer.writeErrorResponse(res, status, invalidToolArguments ? (opts?.toolCallEnvelope ?? ((m, c) => invalidToolArgumentsEnvelope(pathname, m, c)))(msg, require_helpers.fixtureToolCallErrorCode(err)) : opts?.envelope ? opts.envelope(msg, status) : require_errors.renderError("openai", "route-failure", {
1996
1981
  message: msg,
1997
1982
  type: errorTypeForStatus(status)
1998
- } }));
1983
+ }).body);
1999
1984
  } else {
2000
- const midStreamReason = clientAbort ? "client aborted" : "handler crashed mid-stream";
1985
+ const midStreamReason = clientAbort ? require_lifecycle.CLIENT_ABORTED : "handler crashed mid-stream";
2001
1986
  if (existing) {
2002
1987
  if (res.writableEnded) {
2003
1988
  if (existing.response.error === void 0) existing.response.error = msg;
@@ -2112,10 +2097,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2112
2097
  logger.warn(`${route}: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
2113
2098
  }
2114
2099
  setCorsHeaders(res);
2115
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
2100
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "route-failure", {
2116
2101
  message: "Invalid request target",
2117
2102
  type: "invalid_request_error"
2118
- } }));
2103
+ }).body);
2119
2104
  return;
2120
2105
  }
2121
2106
  pathname = parsedUrl.pathname;
@@ -2128,7 +2113,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2128
2113
  }
2129
2114
  if (!(req.method === "GET" && (pathname === require_route_registry.HEALTH_PATH || pathname === require_route_registry.READY_PATH || pathname === require_route_registry.METRICS_PATH))) {
2130
2115
  if (!require_api_key_auth.validateRequestApiKey(req, resolvedAuth.policy).ok) {
2131
- require_api_key_auth.writeApiKeyHttpRejection(res, setCorsHeaders);
2116
+ require_api_key_auth.writeApiKeyHttpRejection(res, setCorsHeaders, pathname, require_policy.resolvePolicy(defaults, req.headers).authErrors);
2132
2117
  return;
2133
2118
  }
2134
2119
  require_api_key_auth.markAuthenticatedRequest(req, resolvedAuth.policy);
@@ -2195,18 +2180,9 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2195
2180
  }
2196
2181
  if (pathname === require_route_registry.OLLAMA_TAGS_PATH && req.method === "GET") {
2197
2182
  setCorsHeaders(res);
2198
- const modelIds = /* @__PURE__ */ new Set();
2199
- for (const f of fixtures) if (f.match.model && typeof f.match.model === "string") modelIds.add(f.match.model);
2200
- const models = (modelIds.size > 0 ? [...modelIds] : DEFAULT_MODELS).map((name) => ({
2201
- name,
2202
- model: name,
2203
- modified_at: (/* @__PURE__ */ new Date()).toISOString(),
2204
- size: 0,
2205
- digest: "",
2206
- details: {}
2207
- }));
2183
+ const body = require_render.renderOllamaTags(require_collect.collect(fixtures, "all").ids, () => (/* @__PURE__ */ new Date()).toISOString());
2208
2184
  res.writeHead(200, { "Content-Type": "application/json" });
2209
- res.end(JSON.stringify({ models }));
2185
+ res.end(JSON.stringify(body));
2210
2186
  return;
2211
2187
  }
2212
2188
  const openRouterVideoContentMatch = pathname.match(require_route_registry.OPENROUTER_VIDEO_CONTENT_RE);
@@ -2327,21 +2303,70 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2327
2303
  res.end(registry.serialize());
2328
2304
  return;
2329
2305
  }
2330
- if (pathname === require_route_registry.MODELS_PATH && req.method === "GET") {
2306
+ const modelDetailMatch = pathname.match(require_route_registry.MODELS_DETAIL_RE);
2307
+ const geminiModelDetailMatch = pathname.match(require_route_registry.GEMINI_MODEL_DETAIL_RE);
2308
+ if (req.method === "GET" && (pathname === require_route_registry.MODELS_PATH || pathname === require_route_registry.GEMINI_MODELS_PATH || modelDetailMatch || geminiModelDetailMatch)) {
2331
2309
  setCorsHeaders(res);
2332
- const modelIds = /* @__PURE__ */ new Set();
2333
- for (const f of fixtures) if (f.match.model && typeof f.match.model === "string") modelIds.add(f.match.model);
2334
- const data = (modelIds.size > 0 ? [...modelIds] : DEFAULT_MODELS).map((id) => ({
2335
- id,
2336
- object: "model",
2337
- created: 1686935002,
2338
- owned_by: "aimock"
2339
- }));
2310
+ const google = pathname === require_route_registry.GEMINI_MODELS_PATH || geminiModelDetailMatch !== null;
2311
+ const policy = require_policy.resolvePolicy(defaults, req.headers);
2312
+ const anthropic = !google && (modelDetailMatch !== null || policy.modelCatalog === "native") && require_profiles.isAnthropicModelRequest(req.headers);
2313
+ const missingHeader = anthropic && policy.requiredHeaders === "enforce" ? require_profiles.missingRequiredHeader("messages", req.headers) : void 0;
2314
+ if (missingHeader) {
2315
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("messages", "thinking", {
2316
+ message: `${missingHeader}: header is required`,
2317
+ requestId
2318
+ }).body);
2319
+ return;
2320
+ }
2321
+ const ids = require_render.coreModelIds(require_collect.collect(fixtures, "all").ids);
2322
+ const visible = google ? require_collect.idsFor(ids, "google") : anthropic ? require_collect.idsFor(ids, "anthropic") : ids;
2323
+ const catalogError = (status, message) => {
2324
+ const rendered = google ? require_errors.renderError("gemini", "fixture", {
2325
+ bodyCode: status,
2326
+ status: status === 404 ? "NOT_FOUND" : "INVALID_ARGUMENT",
2327
+ message
2328
+ }) : anthropic ? require_errors.renderError("messages", "thinking", {
2329
+ type: status === 404 ? "not_found_error" : "invalid_request_error",
2330
+ message
2331
+ }) : require_errors.renderError("openai", "validation", { message });
2332
+ res.writeHead(status, {
2333
+ "Content-Type": "application/json",
2334
+ ...rendered.headers
2335
+ });
2336
+ res.end(rendered.body);
2337
+ };
2338
+ let body;
2339
+ const detail = modelDetailMatch ?? geminiModelDetailMatch;
2340
+ if (detail) {
2341
+ let id;
2342
+ try {
2343
+ id = decodeURIComponent(detail[1]);
2344
+ } catch {
2345
+ catalogError(404, "Model not found");
2346
+ return;
2347
+ }
2348
+ if (!visible.includes(id)) {
2349
+ catalogError(404, `Model not found: ${id}`);
2350
+ return;
2351
+ }
2352
+ body = google ? require_render.renderGeminiModel(id) : anthropic ? require_render.renderAnthropicModel(id) : require_render.renderOpenAIModel(id);
2353
+ } else if (google) {
2354
+ const result = require_gemini_page.geminiPage(visible, parsedUrl.searchParams);
2355
+ if (result.error !== void 0) {
2356
+ catalogError(400, result.error);
2357
+ return;
2358
+ }
2359
+ body = require_render.renderGeminiModels(result.page);
2360
+ } else if (anthropic) {
2361
+ const result = require_anthropic_page.anthropicPage(visible, parsedUrl.searchParams);
2362
+ if (result.error !== void 0) {
2363
+ catalogError(400, result.error);
2364
+ return;
2365
+ }
2366
+ body = require_render.renderAnthropicModels(result.page);
2367
+ } else body = require_render.renderOpenAIModels(ids);
2340
2368
  res.writeHead(200, { "Content-Type": "application/json" });
2341
- res.end(JSON.stringify({
2342
- object: "list",
2343
- data
2344
- }));
2369
+ res.end(JSON.stringify(body));
2345
2370
  return;
2346
2371
  }
2347
2372
  const batchesCancelMatch = pathname.match(require_route_registry.BATCHES_CANCEL_RE);
@@ -2599,10 +2624,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2599
2624
  if (limitParam) {
2600
2625
  const limit = Number(limitParam);
2601
2626
  if (!/^\+?\d+$/.test(limitParam.trim()) || !Number.isSafeInteger(limit) || limit <= 0) {
2602
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
2627
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
2603
2628
  message: `Invalid limit parameter: "${limitParam}"`,
2604
2629
  type: "invalid_request_error"
2605
- } }));
2630
+ }).body);
2606
2631
  return;
2607
2632
  }
2608
2633
  opts = { limit };
@@ -2627,7 +2652,27 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2627
2652
  ensureRawFixturePositions();
2628
2653
  await require_responses.handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2629
2654
  } catch (err) {
2630
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2655
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2656
+ }
2657
+ return;
2658
+ }
2659
+ const geminiCountMatch = pathname.match(require_route_registry.GEMINI_COUNT_RE);
2660
+ if (req.method === "POST" && (pathname === require_route_registry.MESSAGES_COUNT_PATH || geminiCountMatch)) {
2661
+ const google = geminiCountMatch !== null;
2662
+ try {
2663
+ require_count_tokens.handleCountTokens(req, res, await require_helpers.readBody(req), google, geminiCountMatch?.[1] ?? "", journal, defaults, setCorsHeaders);
2664
+ } catch (err) {
2665
+ routeError(req, res, err, pathname, {
2666
+ service: google ? "gemini" : "anthropic",
2667
+ envelope: (message, status) => google ? require_errors.renderError("gemini", "fixture", {
2668
+ message,
2669
+ bodyCode: status,
2670
+ status: status === 400 ? "INVALID_ARGUMENT" : "INTERNAL"
2671
+ }).body : require_errors.renderError("messages", "thinking", {
2672
+ message,
2673
+ type: status === 400 ? "invalid_request_error" : "api_error"
2674
+ }).body
2675
+ });
2631
2676
  }
2632
2677
  return;
2633
2678
  }
@@ -2637,7 +2682,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2637
2682
  ensureRawFixturePositions();
2638
2683
  await require_messages.handleMessages(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2639
2684
  } catch (err) {
2640
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2685
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2641
2686
  }
2642
2687
  return;
2643
2688
  }
@@ -2647,7 +2692,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2647
2692
  ensureRawFixturePositions();
2648
2693
  await require_cohere.handleCohere(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2649
2694
  } catch (err) {
2650
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2695
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2651
2696
  }
2652
2697
  return;
2653
2698
  }
@@ -2813,7 +2858,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2813
2858
  ensureRawFixturePositions();
2814
2859
  await require_gemini_interactions.handleGeminiInteractions(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2815
2860
  } catch (err) {
2816
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2861
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2817
2862
  }
2818
2863
  return;
2819
2864
  }
@@ -2838,7 +2883,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2838
2883
  ensureRawFixturePositions();
2839
2884
  await require_gemini.handleGemini(req, res, raw, geminiModel, streaming, fixtures, journal, defaults, setCorsHeaders);
2840
2885
  } catch (err) {
2841
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2886
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2842
2887
  }
2843
2888
  return;
2844
2889
  }
@@ -2851,7 +2896,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2851
2896
  ensureRawFixturePositions();
2852
2897
  await require_gemini.handleGemini(req, res, raw, vertexModel, streaming, fixtures, journal, defaults, setCorsHeaders, "vertexai");
2853
2898
  } catch (err) {
2854
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2899
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2855
2900
  }
2856
2901
  return;
2857
2902
  }
@@ -2967,10 +3012,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2967
3012
  try {
2968
3013
  voiceId = decodeURIComponent(elevenLabsVoiceMatch[1]);
2969
3014
  } catch {
2970
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
3015
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
2971
3016
  message: `Invalid voice id '${elevenLabsVoiceMatch[1]}': malformed percent-encoding`,
2972
3017
  type: "invalid_request_error"
2973
- } }));
3018
+ }).body);
2974
3019
  journal.add({
2975
3020
  method: req.method ?? "GET",
2976
3021
  path: req.url ?? pathname,
@@ -3120,15 +3165,15 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
3120
3165
  await handleCompletions(req, res, fixtures, journal, defaults, () => lastJournalEntryFor(req), azureDeploymentId, completionsProvider, isOpenRouter, ensureRawFixturePositions, originalPathname.startsWith("/api/v3/"));
3121
3166
  } catch (err) {
3122
3167
  routeError(req, res, err, pathname, {
3123
- envelope: (m, status) => isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : JSON.stringify({ error: {
3168
+ envelope: (m, status) => isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : require_errors.renderError("openai", "route-failure", {
3124
3169
  message: m,
3125
3170
  type: errorTypeForStatus(status)
3126
- } }),
3171
+ }).body,
3127
3172
  ...isOpenRouter ? { toolCallEnvelope: (m, code) => require_openrouter_chat.serializeOpenRouterError(500, m, { reason: code }) } : {},
3128
- streamEvent: (m, status) => `data: ${isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : JSON.stringify({ error: {
3173
+ streamEvent: (m, status) => `data: ${isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : require_errors.renderError("openai", "route-failure", {
3129
3174
  message: m,
3130
3175
  type: errorTypeForStatus(status)
3131
- } })}\n\n`
3176
+ }).body}\n\n`
3132
3177
  });
3133
3178
  }
3134
3179
  }