@copilotkit/aimock 1.45.0 → 1.46.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 (426) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/README.md +7 -1
  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.ts.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/batches.cjs +2 -4
  25. package/dist/batches.cjs.map +1 -1
  26. package/dist/batches.d.cts.map +1 -1
  27. package/dist/batches.d.ts.map +1 -1
  28. package/dist/batches.js +2 -4
  29. package/dist/batches.js.map +1 -1
  30. package/dist/bedrock-converse.cjs +61 -80
  31. package/dist/bedrock-converse.cjs.map +1 -1
  32. package/dist/bedrock-converse.d.cts.map +1 -1
  33. package/dist/bedrock-converse.d.ts.map +1 -1
  34. package/dist/bedrock-converse.js +58 -77
  35. package/dist/bedrock-converse.js.map +1 -1
  36. package/dist/bedrock.cjs +65 -97
  37. package/dist/bedrock.cjs.map +1 -1
  38. package/dist/bedrock.d.cts.map +1 -1
  39. package/dist/bedrock.d.ts.map +1 -1
  40. package/dist/bedrock.js +62 -94
  41. package/dist/bedrock.js.map +1 -1
  42. package/dist/byteplus-video.cjs +11 -10
  43. package/dist/byteplus-video.cjs.map +1 -1
  44. package/dist/byteplus-video.d.cts.map +1 -1
  45. package/dist/byteplus-video.d.ts.map +1 -1
  46. package/dist/byteplus-video.js +5 -4
  47. package/dist/byteplus-video.js.map +1 -1
  48. package/dist/chaos.cjs +5 -4
  49. package/dist/chaos.cjs.map +1 -1
  50. package/dist/chaos.d.cts.map +1 -1
  51. package/dist/chaos.d.ts.map +1 -1
  52. package/dist/chaos.js +5 -4
  53. package/dist/chaos.js.map +1 -1
  54. package/dist/cli.cjs +15 -0
  55. package/dist/cli.cjs.map +1 -1
  56. package/dist/cli.js +15 -0
  57. package/dist/cli.js.map +1 -1
  58. package/dist/cohere.cjs +49 -74
  59. package/dist/cohere.cjs.map +1 -1
  60. package/dist/cohere.d.cts.map +1 -1
  61. package/dist/cohere.d.ts.map +1 -1
  62. package/dist/cohere.js +47 -72
  63. package/dist/cohere.js.map +1 -1
  64. package/dist/config-loader.cjs +29 -1
  65. package/dist/config-loader.cjs.map +1 -1
  66. package/dist/config-loader.d.cts +7 -1
  67. package/dist/config-loader.d.cts.map +1 -1
  68. package/dist/config-loader.d.ts +7 -1
  69. package/dist/config-loader.d.ts.map +1 -1
  70. package/dist/config-loader.js +29 -2
  71. package/dist/config-loader.js.map +1 -1
  72. package/dist/count-tokens.cjs +146 -0
  73. package/dist/count-tokens.cjs.map +1 -0
  74. package/dist/count-tokens.js +146 -0
  75. package/dist/count-tokens.js.map +1 -0
  76. package/dist/elevenlabs-audio.cjs +36 -34
  77. package/dist/elevenlabs-audio.cjs.map +1 -1
  78. package/dist/elevenlabs-audio.d.cts.map +1 -1
  79. package/dist/elevenlabs-audio.d.ts.map +1 -1
  80. package/dist/elevenlabs-audio.js +33 -31
  81. package/dist/elevenlabs-audio.js.map +1 -1
  82. package/dist/elevenlabs-voice.cjs +38 -37
  83. package/dist/elevenlabs-voice.cjs.map +1 -1
  84. package/dist/elevenlabs-voice.d.cts.map +1 -1
  85. package/dist/elevenlabs-voice.d.ts.map +1 -1
  86. package/dist/elevenlabs-voice.js +33 -32
  87. package/dist/elevenlabs-voice.js.map +1 -1
  88. package/dist/embedding-request.cjs +16 -0
  89. package/dist/embedding-request.cjs.map +1 -0
  90. package/dist/embedding-request.js +14 -0
  91. package/dist/embedding-request.js.map +1 -0
  92. package/dist/embeddings.cjs +30 -20
  93. package/dist/embeddings.cjs.map +1 -1
  94. package/dist/embeddings.d.cts.map +1 -1
  95. package/dist/embeddings.d.ts.map +1 -1
  96. package/dist/embeddings.js +30 -20
  97. package/dist/embeddings.js.map +1 -1
  98. package/dist/fal-audio.cjs +45 -43
  99. package/dist/fal-audio.cjs.map +1 -1
  100. package/dist/fal-audio.d.cts.map +1 -1
  101. package/dist/fal-audio.d.ts.map +1 -1
  102. package/dist/fal-audio.js +42 -40
  103. package/dist/fal-audio.js.map +1 -1
  104. package/dist/fal.cjs +17 -15
  105. package/dist/fal.cjs.map +1 -1
  106. package/dist/fal.js +16 -14
  107. package/dist/fal.js.map +1 -1
  108. package/dist/files.cjs +2 -4
  109. package/dist/files.cjs.map +1 -1
  110. package/dist/files.d.cts.map +1 -1
  111. package/dist/files.d.ts.map +1 -1
  112. package/dist/files.js +2 -4
  113. package/dist/files.js.map +1 -1
  114. package/dist/fine-tuning.cjs +2 -4
  115. package/dist/fine-tuning.cjs.map +1 -1
  116. package/dist/fine-tuning.d.cts.map +1 -1
  117. package/dist/fine-tuning.d.ts.map +1 -1
  118. package/dist/fine-tuning.js +2 -4
  119. package/dist/fine-tuning.js.map +1 -1
  120. package/dist/fixture-loader.cjs +37 -42
  121. package/dist/fixture-loader.cjs.map +1 -1
  122. package/dist/fixture-loader.d.cts.map +1 -1
  123. package/dist/fixture-loader.d.ts.map +1 -1
  124. package/dist/fixture-loader.js +37 -42
  125. package/dist/fixture-loader.js.map +1 -1
  126. package/dist/gemini-embeddings.cjs +26 -24
  127. package/dist/gemini-embeddings.cjs.map +1 -1
  128. package/dist/gemini-embeddings.js +26 -24
  129. package/dist/gemini-embeddings.js.map +1 -1
  130. package/dist/gemini-interactions.cjs +50 -35
  131. package/dist/gemini-interactions.cjs.map +1 -1
  132. package/dist/gemini-interactions.d.cts +0 -1
  133. package/dist/gemini-interactions.d.cts.map +1 -1
  134. package/dist/gemini-interactions.d.ts +0 -1
  135. package/dist/gemini-interactions.d.ts.map +1 -1
  136. package/dist/gemini-interactions.js +49 -34
  137. package/dist/gemini-interactions.js.map +1 -1
  138. package/dist/gemini.cjs +57 -67
  139. package/dist/gemini.cjs.map +1 -1
  140. package/dist/gemini.d.cts.map +1 -1
  141. package/dist/gemini.d.ts.map +1 -1
  142. package/dist/gemini.js +56 -67
  143. package/dist/gemini.js.map +1 -1
  144. package/dist/grok-video.cjs +14 -12
  145. package/dist/grok-video.cjs.map +1 -1
  146. package/dist/grok-video.d.cts.map +1 -1
  147. package/dist/grok-video.d.ts.map +1 -1
  148. package/dist/grok-video.js +8 -6
  149. package/dist/grok-video.js.map +1 -1
  150. package/dist/helpers.cjs +11 -68
  151. package/dist/helpers.cjs.map +1 -1
  152. package/dist/helpers.d.cts.map +1 -1
  153. package/dist/helpers.d.ts.map +1 -1
  154. package/dist/helpers.js +12 -67
  155. package/dist/helpers.js.map +1 -1
  156. package/dist/images.cjs +30 -28
  157. package/dist/images.cjs.map +1 -1
  158. package/dist/images.d.cts.map +1 -1
  159. package/dist/images.d.ts.map +1 -1
  160. package/dist/images.js +27 -25
  161. package/dist/images.js.map +1 -1
  162. package/dist/index.d.cts +2 -2
  163. package/dist/index.d.ts +2 -2
  164. package/dist/journal.cjs +3 -1
  165. package/dist/journal.cjs.map +1 -1
  166. package/dist/journal.d.cts.map +1 -1
  167. package/dist/journal.d.ts.map +1 -1
  168. package/dist/journal.js +2 -1
  169. package/dist/journal.js.map +1 -1
  170. package/dist/llmock.cjs +3 -0
  171. package/dist/llmock.cjs.map +1 -1
  172. package/dist/llmock.d.cts.map +1 -1
  173. package/dist/llmock.d.ts.map +1 -1
  174. package/dist/llmock.js +3 -0
  175. package/dist/llmock.js.map +1 -1
  176. package/dist/mcp-fakes.d.cts.map +1 -1
  177. package/dist/mcp-handler.cjs +14 -4
  178. package/dist/mcp-handler.cjs.map +1 -1
  179. package/dist/mcp-handler.js +14 -4
  180. package/dist/mcp-handler.js.map +1 -1
  181. package/dist/mcp-recorder.cjs +2 -1
  182. package/dist/mcp-recorder.cjs.map +1 -1
  183. package/dist/mcp-recorder.js +3 -2
  184. package/dist/mcp-recorder.js.map +1 -1
  185. package/dist/messages.cjs +111 -96
  186. package/dist/messages.cjs.map +1 -1
  187. package/dist/messages.d.cts.map +1 -1
  188. package/dist/messages.d.ts.map +1 -1
  189. package/dist/messages.js +109 -95
  190. package/dist/messages.js.map +1 -1
  191. package/dist/metrics.cjs +5 -2
  192. package/dist/metrics.cjs.map +1 -1
  193. package/dist/metrics.d.cts.map +1 -1
  194. package/dist/metrics.d.ts.map +1 -1
  195. package/dist/metrics.js +6 -3
  196. package/dist/metrics.js.map +1 -1
  197. package/dist/model-utils.cjs +1 -0
  198. package/dist/model-utils.cjs.map +1 -1
  199. package/dist/model-utils.js +1 -1
  200. package/dist/model-utils.js.map +1 -1
  201. package/dist/moderation.cjs +15 -12
  202. package/dist/moderation.cjs.map +1 -1
  203. package/dist/moderation.js +14 -11
  204. package/dist/moderation.js.map +1 -1
  205. package/dist/ollama.cjs +128 -68
  206. package/dist/ollama.cjs.map +1 -1
  207. package/dist/ollama.d.cts.map +1 -1
  208. package/dist/ollama.d.ts.map +1 -1
  209. package/dist/ollama.js +124 -64
  210. package/dist/ollama.js.map +1 -1
  211. package/dist/openapi.cjs +323 -3
  212. package/dist/openapi.cjs.map +1 -1
  213. package/dist/openapi.d.cts.map +1 -1
  214. package/dist/openapi.d.ts.map +1 -1
  215. package/dist/openapi.js +324 -4
  216. package/dist/openapi.js.map +1 -1
  217. package/dist/openrouter-chat.cjs +11 -155
  218. package/dist/openrouter-chat.cjs.map +1 -1
  219. package/dist/openrouter-chat.js +11 -155
  220. package/dist/openrouter-chat.js.map +1 -1
  221. package/dist/openrouter-video.cjs +76 -71
  222. package/dist/openrouter-video.cjs.map +1 -1
  223. package/dist/openrouter-video.d.cts.map +1 -1
  224. package/dist/openrouter-video.d.ts.map +1 -1
  225. package/dist/openrouter-video.js +63 -58
  226. package/dist/openrouter-video.js.map +1 -1
  227. package/dist/recorder.cjs +176 -95
  228. package/dist/recorder.cjs.map +1 -1
  229. package/dist/recorder.d.cts.map +1 -1
  230. package/dist/recorder.d.ts.map +1 -1
  231. package/dist/recorder.js +176 -95
  232. package/dist/recorder.js.map +1 -1
  233. package/dist/rerank.cjs +13 -11
  234. package/dist/rerank.cjs.map +1 -1
  235. package/dist/rerank.js +12 -10
  236. package/dist/rerank.js.map +1 -1
  237. package/dist/response/catalog/anthropic-page.cjs +39 -0
  238. package/dist/response/catalog/anthropic-page.cjs.map +1 -0
  239. package/dist/response/catalog/anthropic-page.js +38 -0
  240. package/dist/response/catalog/anthropic-page.js.map +1 -0
  241. package/dist/response/catalog/collect.cjs +61 -0
  242. package/dist/response/catalog/collect.cjs.map +1 -0
  243. package/dist/response/catalog/collect.js +59 -0
  244. package/dist/response/catalog/collect.js.map +1 -0
  245. package/dist/response/catalog/gemini-page.cjs +25 -0
  246. package/dist/response/catalog/gemini-page.cjs.map +1 -0
  247. package/dist/response/catalog/gemini-page.js +24 -0
  248. package/dist/response/catalog/gemini-page.js.map +1 -0
  249. package/dist/response/catalog/render.cjs +182 -0
  250. package/dist/response/catalog/render.cjs.map +1 -0
  251. package/dist/response/catalog/render.js +171 -0
  252. package/dist/response/catalog/render.js.map +1 -0
  253. package/dist/response/errors.cjs +225 -0
  254. package/dist/response/errors.cjs.map +1 -0
  255. package/dist/response/errors.js +224 -0
  256. package/dist/response/errors.js.map +1 -0
  257. package/dist/response/finish.cjs +39 -0
  258. package/dist/response/finish.cjs.map +1 -0
  259. package/dist/response/finish.js +35 -0
  260. package/dist/response/finish.js.map +1 -0
  261. package/dist/response/policy.cjs +126 -0
  262. package/dist/response/policy.cjs.map +1 -0
  263. package/dist/response/policy.js +120 -0
  264. package/dist/response/policy.js.map +1 -0
  265. package/dist/response/profiles.cjs +69 -0
  266. package/dist/response/profiles.cjs.map +1 -0
  267. package/dist/response/profiles.js +65 -0
  268. package/dist/response/profiles.js.map +1 -0
  269. package/dist/response/usage/codecs/anthropic.cjs +52 -0
  270. package/dist/response/usage/codecs/anthropic.cjs.map +1 -0
  271. package/dist/response/usage/codecs/anthropic.js +50 -0
  272. package/dist/response/usage/codecs/anthropic.js.map +1 -0
  273. package/dist/response/usage/codecs/cohere.cjs +36 -0
  274. package/dist/response/usage/codecs/cohere.cjs.map +1 -0
  275. package/dist/response/usage/codecs/cohere.js +35 -0
  276. package/dist/response/usage/codecs/cohere.js.map +1 -0
  277. package/dist/response/usage/codecs/converse.cjs +16 -0
  278. package/dist/response/usage/codecs/converse.cjs.map +1 -0
  279. package/dist/response/usage/codecs/converse.js +15 -0
  280. package/dist/response/usage/codecs/converse.js.map +1 -0
  281. package/dist/response/usage/codecs/gemini.cjs +31 -0
  282. package/dist/response/usage/codecs/gemini.cjs.map +1 -0
  283. package/dist/response/usage/codecs/gemini.js +31 -0
  284. package/dist/response/usage/codecs/gemini.js.map +1 -0
  285. package/dist/response/usage/codecs/interactions.cjs +22 -0
  286. package/dist/response/usage/codecs/interactions.cjs.map +1 -0
  287. package/dist/response/usage/codecs/interactions.js +21 -0
  288. package/dist/response/usage/codecs/interactions.js.map +1 -0
  289. package/dist/response/usage/codecs/ollama.cjs +17 -0
  290. package/dist/response/usage/codecs/ollama.cjs.map +1 -0
  291. package/dist/response/usage/codecs/ollama.js +17 -0
  292. package/dist/response/usage/codecs/ollama.js.map +1 -0
  293. package/dist/response/usage/codecs/openai.cjs +52 -0
  294. package/dist/response/usage/codecs/openai.cjs.map +1 -0
  295. package/dist/response/usage/codecs/openai.js +50 -0
  296. package/dist/response/usage/codecs/openai.js.map +1 -0
  297. package/dist/response/usage/codecs/openrouter.cjs +68 -0
  298. package/dist/response/usage/codecs/openrouter.cjs.map +1 -0
  299. package/dist/response/usage/codecs/openrouter.js +67 -0
  300. package/dist/response/usage/codecs/openrouter.js.map +1 -0
  301. package/dist/response/usage/codecs/realtime.cjs +19 -0
  302. package/dist/response/usage/codecs/realtime.cjs.map +1 -0
  303. package/dist/response/usage/codecs/realtime.js +18 -0
  304. package/dist/response/usage/codecs/realtime.js.map +1 -0
  305. package/dist/response/usage/codecs/responses.cjs +21 -0
  306. package/dist/response/usage/codecs/responses.cjs.map +1 -0
  307. package/dist/response/usage/codecs/responses.js +20 -0
  308. package/dist/response/usage/codecs/responses.js.map +1 -0
  309. package/dist/response/usage/estimate.cjs +23 -0
  310. package/dist/response/usage/estimate.cjs.map +1 -0
  311. package/dist/response/usage/estimate.js +21 -0
  312. package/dist/response/usage/estimate.js.map +1 -0
  313. package/dist/response/usage/fields.cjs +72 -0
  314. package/dist/response/usage/fields.cjs.map +1 -0
  315. package/dist/response/usage/fields.js +70 -0
  316. package/dist/response/usage/fields.js.map +1 -0
  317. package/dist/response/usage/recording.cjs +52 -0
  318. package/dist/response/usage/recording.cjs.map +1 -0
  319. package/dist/response/usage/recording.js +52 -0
  320. package/dist/response/usage/recording.js.map +1 -0
  321. package/dist/responses.cjs +45 -58
  322. package/dist/responses.cjs.map +1 -1
  323. package/dist/responses.d.cts.map +1 -1
  324. package/dist/responses.d.ts.map +1 -1
  325. package/dist/responses.js +44 -57
  326. package/dist/responses.js.map +1 -1
  327. package/dist/route-registry.cjs +45 -0
  328. package/dist/route-registry.cjs.map +1 -1
  329. package/dist/route-registry.d.cts.map +1 -1
  330. package/dist/route-registry.d.ts.map +1 -1
  331. package/dist/route-registry.js +41 -1
  332. package/dist/route-registry.js.map +1 -1
  333. package/dist/router.cjs +4 -0
  334. package/dist/router.cjs.map +1 -1
  335. package/dist/router.d.cts.map +1 -1
  336. package/dist/router.d.ts.map +1 -1
  337. package/dist/router.js +3 -0
  338. package/dist/router.js.map +1 -1
  339. package/dist/search.cjs +13 -11
  340. package/dist/search.cjs.map +1 -1
  341. package/dist/search.js +12 -10
  342. package/dist/search.js.map +1 -1
  343. package/dist/server.cjs +222 -146
  344. package/dist/server.cjs.map +1 -1
  345. package/dist/server.d.cts.map +1 -1
  346. package/dist/server.d.ts.map +1 -1
  347. package/dist/server.js +223 -147
  348. package/dist/server.js.map +1 -1
  349. package/dist/speech.cjs +20 -18
  350. package/dist/speech.cjs.map +1 -1
  351. package/dist/speech.d.cts.map +1 -1
  352. package/dist/speech.d.ts.map +1 -1
  353. package/dist/speech.js +19 -17
  354. package/dist/speech.js.map +1 -1
  355. package/dist/sse-writer.cjs +7 -0
  356. package/dist/sse-writer.cjs.map +1 -1
  357. package/dist/sse-writer.d.cts.map +1 -1
  358. package/dist/sse-writer.d.ts.map +1 -1
  359. package/dist/sse-writer.js +7 -1
  360. package/dist/sse-writer.js.map +1 -1
  361. package/dist/stream-collapse.cjs +118 -11
  362. package/dist/stream-collapse.cjs.map +1 -1
  363. package/dist/stream-collapse.d.cts +10 -9
  364. package/dist/stream-collapse.d.cts.map +1 -1
  365. package/dist/stream-collapse.d.ts +10 -9
  366. package/dist/stream-collapse.d.ts.map +1 -1
  367. package/dist/stream-collapse.js +118 -11
  368. package/dist/stream-collapse.js.map +1 -1
  369. package/dist/transcription.cjs +12 -10
  370. package/dist/transcription.cjs.map +1 -1
  371. package/dist/transcription.d.cts.map +1 -1
  372. package/dist/transcription.d.ts.map +1 -1
  373. package/dist/transcription.js +11 -9
  374. package/dist/transcription.js.map +1 -1
  375. package/dist/types.cjs.map +1 -1
  376. package/dist/types.d.cts +62 -3
  377. package/dist/types.d.cts.map +1 -1
  378. package/dist/types.d.ts +62 -3
  379. package/dist/types.d.ts.map +1 -1
  380. package/dist/types.js.map +1 -1
  381. package/dist/vector-mock.cjs +3 -8
  382. package/dist/vector-mock.cjs.map +1 -1
  383. package/dist/vector-mock.d.cts.map +1 -1
  384. package/dist/vector-mock.d.ts.map +1 -1
  385. package/dist/vector-mock.js +3 -8
  386. package/dist/vector-mock.js.map +1 -1
  387. package/dist/vector-stores.cjs +2 -4
  388. package/dist/vector-stores.cjs.map +1 -1
  389. package/dist/vector-stores.d.cts.map +1 -1
  390. package/dist/vector-stores.d.ts.map +1 -1
  391. package/dist/vector-stores.js +2 -4
  392. package/dist/vector-stores.js.map +1 -1
  393. package/dist/veo-video.cjs +16 -14
  394. package/dist/veo-video.cjs.map +1 -1
  395. package/dist/veo-video.js +10 -8
  396. package/dist/veo-video.js.map +1 -1
  397. package/dist/video.cjs +21 -19
  398. package/dist/video.cjs.map +1 -1
  399. package/dist/video.d.cts.map +1 -1
  400. package/dist/video.d.ts.map +1 -1
  401. package/dist/video.js +20 -18
  402. package/dist/video.js.map +1 -1
  403. package/dist/ws-gemini-live.cjs +11 -3
  404. package/dist/ws-gemini-live.cjs.map +1 -1
  405. package/dist/ws-gemini-live.d.cts +0 -1
  406. package/dist/ws-gemini-live.d.cts.map +1 -1
  407. package/dist/ws-gemini-live.d.ts +0 -1
  408. package/dist/ws-gemini-live.d.ts.map +1 -1
  409. package/dist/ws-gemini-live.js +10 -2
  410. package/dist/ws-gemini-live.js.map +1 -1
  411. package/dist/ws-live.cjs +6 -5
  412. package/dist/ws-live.cjs.map +1 -1
  413. package/dist/ws-live.js +5 -4
  414. package/dist/ws-live.js.map +1 -1
  415. package/dist/ws-realtime.cjs +28 -54
  416. package/dist/ws-realtime.cjs.map +1 -1
  417. package/dist/ws-realtime.d.cts.map +1 -1
  418. package/dist/ws-realtime.d.ts.map +1 -1
  419. package/dist/ws-realtime.js +25 -51
  420. package/dist/ws-realtime.js.map +1 -1
  421. package/dist/ws-responses.cjs +8 -6
  422. package/dist/ws-responses.cjs.map +1 -1
  423. package/dist/ws-responses.js +7 -5
  424. package/dist/ws-responses.js.map +1 -1
  425. package/package.json +4 -1
  426. package/skills/write-fixtures/SKILL.md +25 -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');
@@ -13,10 +16,15 @@ const require_recorder = require('./recorder.cjs');
13
16
  const require_logger = require('./logger.cjs');
14
17
  const require_journal = require('./journal.cjs');
15
18
  const require_interruption = require('./interruption.cjs');
19
+ const require_collect = require('./response/catalog/collect.cjs');
20
+ const require_anthropic_page = require('./response/catalog/anthropic-page.cjs');
21
+ const require_gemini_page = require('./response/catalog/gemini-page.cjs');
22
+ const require_render = require('./response/catalog/render.cjs');
16
23
  const require_openrouter_chat = require('./openrouter-chat.cjs');
17
24
  const require_responses = require('./responses.cjs');
18
25
  const require_messages = require('./messages.cjs');
19
26
  const require_gemini = require('./gemini.cjs');
27
+ const require_count_tokens = require('./count-tokens.cjs');
20
28
  const require_gemini_embeddings = require('./gemini-embeddings.cjs');
21
29
  const require_bedrock = require('./bedrock.cjs');
22
30
  const require_bedrock_converse = require('./bedrock-converse.cjs');
@@ -89,13 +97,6 @@ function normalizeCompatPath(pathname, logger) {
89
97
  }
90
98
  return pathname;
91
99
  }
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
100
  const CORS_HEADERS = {
100
101
  "Access-Control-Allow-Origin": "*",
101
102
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
@@ -112,10 +113,10 @@ function handleOptions(res) {
112
113
  }
113
114
  function handleNotFound(res, message) {
114
115
  setCorsHeaders(res);
115
- require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
116
+ require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "route-failure", {
116
117
  message,
117
118
  type: "not_found"
118
- } }));
119
+ }).body);
119
120
  }
120
121
  /** The complete `GET /__aimock/fixtures` query-param vocabulary; anything else 400s. */
121
122
  const FIXTURES_PARAMS = new Set(["include"]);
@@ -926,10 +927,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
926
927
  fixture: null
927
928
  }
928
929
  });
929
- require_sse_writer.writeErrorResponse(res, status, openRouter ? require_openrouter_chat.serializeOpenRouterError(status, `Request body read failed: ${msg}`) : JSON.stringify({ error: {
930
+ require_sse_writer.writeErrorResponse(res, status, openRouter ? require_openrouter_chat.serializeOpenRouterError(status, `Request body read failed: ${msg}`) : require_errors.renderError("openai", "transport-failure", {
930
931
  message: `Request body read failed: ${msg}`,
931
932
  type: clientFault ? "invalid_request_error" : "server_error"
932
- } }));
933
+ }).body);
933
934
  return;
934
935
  }
935
936
  let body;
@@ -947,12 +948,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
947
948
  fixture: null
948
949
  }
949
950
  });
950
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, `Malformed JSON: ${detail}`) : JSON.stringify({ error: {
951
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, `Malformed JSON: ${detail}`) : require_errors.renderError("openai", "validation", {
951
952
  message: `Malformed JSON: ${detail}`,
952
953
  type: "invalid_request_error",
953
954
  param: null,
954
- code: "invalid_json"
955
- } }));
955
+ code: "invalid_json",
956
+ includeParam: true
957
+ }).body);
956
958
  return;
957
959
  }
958
960
  if (!require_helpers.isJsonObject(body)) {
@@ -966,10 +968,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
966
968
  fixture: null
967
969
  }
968
970
  });
969
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Request body must be a JSON object") : JSON.stringify({ error: {
971
+ 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
972
  message: "Request body must be a JSON object",
971
973
  type: "invalid_request_error"
972
- } }));
974
+ }).body);
973
975
  return;
974
976
  }
975
977
  if (modelFallback && !body.model) body.model = modelFallback;
@@ -984,12 +986,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
984
986
  fixture: null
985
987
  }
986
988
  });
987
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Missing required parameter: 'messages'") : JSON.stringify({ error: {
989
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, "Missing required parameter: 'messages'") : require_errors.renderError("openai", "validation", {
988
990
  message: "Missing required parameter: 'messages'",
989
991
  type: "invalid_request_error",
990
992
  param: null,
991
- code: null
992
- } }));
993
+ code: null,
994
+ includeParam: true
995
+ }).body);
993
996
  return;
994
997
  }
995
998
  const nullMessageIndex = body.messages.findIndex((message) => message === null);
@@ -1005,12 +1008,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1005
1008
  fixture: null
1006
1009
  }
1007
1010
  });
1008
- require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, message) : JSON.stringify({ error: {
1011
+ require_sse_writer.writeErrorResponse(res, 400, openRouter ? require_openrouter_chat.serializeOpenRouterError(400, message) : require_errors.renderError("openai", "validation", {
1009
1012
  message,
1010
1013
  type: "invalid_request_error",
1011
1014
  param: null,
1012
- code: null
1013
- } }));
1015
+ code: null,
1016
+ includeParam: true
1017
+ }).body);
1014
1018
  return;
1015
1019
  }
1016
1020
  if (new URL(req.url ?? require_route_registry.COMPLETIONS_PATH, "http://localhost").pathname === require_route_registry.COMPLETIONS_PATH) {
@@ -1030,10 +1034,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1030
1034
  fixture: null
1031
1035
  }
1032
1036
  });
1033
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
1037
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
1034
1038
  message: toolsError,
1035
1039
  type: "invalid_request_error"
1036
- } }));
1040
+ }).body);
1037
1041
  return;
1038
1042
  }
1039
1043
  }
@@ -1133,8 +1137,9 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1133
1137
  headers: flatHeaders,
1134
1138
  body
1135
1139
  };
1136
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1137
- const missWouldProxy = require_helpers.wouldProxyMiss(effectiveStrict, defaults.record, providerKey);
1140
+ const missDecisions = require_policy.resolveRequestDecisions(defaults.strict, req.headers);
1141
+ const effectiveStrict = missDecisions.fixtureMiss;
1142
+ const missWouldProxy = require_helpers.wouldProxyMiss(!missDecisions.upstream, defaults.record, providerKey);
1138
1143
  const noFixtureSource = missWouldProxy ? "proxy" : "internal";
1139
1144
  const recordBypass = (reason) => {
1140
1145
  const entry = getRequestEntry();
@@ -1178,15 +1183,16 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1178
1183
  response: {
1179
1184
  status: strictStatus,
1180
1185
  fixture: null,
1181
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1186
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1182
1187
  }
1183
1188
  });
1184
- require_sse_writer.writeErrorResponse(res, strictStatus, openRouter ? require_openrouter_chat.serializeOpenRouterError(strictStatus, strictMessage) : JSON.stringify({ error: {
1189
+ require_sse_writer.writeErrorResponse(res, strictStatus, openRouter ? require_openrouter_chat.serializeOpenRouterError(strictStatus, strictMessage) : require_errors.renderError("openai", "strict-miss", {
1185
1190
  message: strictMessage,
1186
1191
  type: "invalid_request_error",
1187
1192
  param: null,
1188
- code: "no_fixture_match"
1189
- } }));
1193
+ code: "no_fixture_match",
1194
+ includeParam: true
1195
+ }).body);
1190
1196
  return;
1191
1197
  }
1192
1198
  if (defaults.record && providerKey) {
@@ -1253,15 +1259,16 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1253
1259
  response: {
1254
1260
  status: 404,
1255
1261
  fixture: null,
1256
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
1262
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
1257
1263
  }
1258
1264
  });
1259
- require_sse_writer.writeErrorResponse(res, 404, openRouter ? require_openrouter_chat.serializeOpenRouterError(404, "No fixture matched") : JSON.stringify({ error: {
1265
+ require_sse_writer.writeErrorResponse(res, 404, openRouter ? require_openrouter_chat.serializeOpenRouterError(404, "No fixture matched") : require_errors.renderError("openai", "fixture-miss", {
1260
1266
  message: "No fixture matched",
1261
1267
  type: "invalid_request_error",
1262
1268
  param: null,
1263
- code: "no_fixture_match"
1264
- } }));
1269
+ code: "no_fixture_match",
1270
+ includeParam: true
1271
+ }).body);
1265
1272
  return;
1266
1273
  }
1267
1274
  const resolvedResponse = preResolvedResponse ?? await require_helpers.resolveResponse(fixture, body);
@@ -1292,12 +1299,13 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1292
1299
  testId
1293
1300
  });
1294
1301
  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: {
1302
+ require_sse_writer.writeErrorResponse(res, evaluation.status, openRouter ? require_openrouter_chat.serializeOpenRouterError(evaluation.status, `${evaluation.code}: ${evaluation.message}`) : require_errors.renderError("openai", "misbehavior", {
1296
1303
  message: evaluation.message,
1297
1304
  type: "invalid_request_error",
1298
1305
  param: null,
1299
- code: evaluation.code
1300
- } }));
1306
+ code: evaluation.code,
1307
+ includeParam: true
1308
+ }).body);
1301
1309
  return;
1302
1310
  }
1303
1311
  const appliedPlan = evaluation.kind === "applied" ? require_helpers.prepareOpenAIChatMisbehavior(evaluation) : void 0;
@@ -1311,22 +1319,28 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1311
1319
  testId
1312
1320
  });
1313
1321
  };
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;
1322
+ 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
1323
  const appliedUsage = appliedPlan ? require_helpers.resolveOpenAIChatMisbehaviorUsage(appliedPlan, body, appliedPlan.reasoning === void 0 ? appliedReasoning !== void 0 : openRouter) : void 0;
1316
1324
  const latency = fixture.latency ?? defaults.latency;
1317
1325
  const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
1318
1326
  const emitStreamingUsage = body.stream === true && body.stream_options?.include_usage === true || openRouter;
1319
1327
  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
1328
  const resolveStreamingUsageTokens = (overrides, completionText) => appliedUsage ?? require_helpers.resolveUsage(overrides, streamingPromptText, completionText);
1321
- const resolveRecordedTimings = (chunks) => {
1329
+ const resolveRecordedTimings = (chunkCount) => {
1322
1330
  const timings = fixture.recordedTimings;
1323
1331
  if (!appliedPlan?.duplicateId || !timings) return timings;
1324
1332
  const gaps = timings.interChunkDelaysMs;
1325
1333
  return {
1326
1334
  ...timings,
1327
- interChunkDelaysMs: Array.from({ length: Math.max(gaps.length, chunks.length - 1) }, (_, index) => gaps[index] ?? gaps.at(-1) ?? 0)
1335
+ interChunkDelaysMs: Array.from({ length: Math.max(gaps.length, chunkCount - 1) }, (_, index) => gaps[index] ?? gaps.at(-1) ?? 0)
1328
1336
  };
1329
1337
  };
1338
+ const awaitNonStreamingTiming = (contentLength) => {
1339
+ if (fixture.nonStreamingTiming !== true) return Promise.resolve();
1340
+ if (!fixture.streamingProfile && !fixture.recordedTimings) return Promise.resolve();
1341
+ const chunkCount = Math.max(1, Math.ceil(contentLength / chunkSize));
1342
+ return require_sse_writer.delay(require_sse_writer.calculateTotalDelay(contentLength, chunkSize, fixture.streamingProfile, resolveRecordedTimings(chunkCount), fixture.replaySpeed ?? defaults.replaySpeed));
1343
+ };
1330
1344
  const shapeORCompletion = (completion, overrides) => {
1331
1345
  if (appliedUsage) completion.usage = appliedUsage;
1332
1346
  if (!openRouter) return completion;
@@ -1365,10 +1379,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1365
1379
  fixture
1366
1380
  }
1367
1381
  }));
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: {
1382
+ 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
1383
  message: "Audio responses are not supported on the chat completions endpoint. Use Gemini generateContent or a dedicated audio endpoint.",
1370
1384
  type: "invalid_request_error"
1371
- } }));
1385
+ }).body);
1372
1386
  return;
1373
1387
  }
1374
1388
  if (appliedPlan && require_helpers.isTextResponse(response) && (appliedPlan.stop === "refusal" || appliedPlan.stop === "content_filter" || appliedPlan.reasoning !== void 0)) {
@@ -1386,6 +1400,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1386
1400
  recordOutcome(entry);
1387
1401
  if (body.stream !== true) {
1388
1402
  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);
1403
+ await awaitNonStreamingTiming((appliedPlan.stop === "refusal" ? appliedPlan.refusal ?? "" : appliedPlan.stop === "content_filter" ? "" : appliedPlan.reasoning ?? "").length);
1389
1404
  res.writeHead(200, { "Content-Type": "application/json" });
1390
1405
  res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1391
1406
  } else {
@@ -1399,7 +1414,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1399
1414
  signal: interruption?.signal,
1400
1415
  onChunkSent: interruption?.tick,
1401
1416
  usageChunk,
1402
- recordedTimings: resolveRecordedTimings(chunks),
1417
+ recordedTimings: resolveRecordedTimings(chunks.length),
1403
1418
  replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1404
1419
  openRouterProcessing
1405
1420
  })) {
@@ -1414,7 +1429,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
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;
@@ -1430,7 +1445,9 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1430
1445
  });
1431
1446
  recordOutcome(journalEntry);
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) {
1450
+ await awaitNonStreamingTiming((effReasoning?.length ?? 0) + completionText.length);
1434
1451
  const completion = require_helpers.buildContentWithToolCallsCompletion(blockOutcome?.content ?? response.content ?? "", blockOutcome?.toolCalls ?? toolCalls, responseModel, effReasoning, blockOutcome ? {
1435
1452
  ...overrides,
1436
1453
  finishReason: overrides?.finishReason ?? (blockOutcome.hasToolCalls ? "tool_calls" : "stop")
@@ -1439,7 +1456,6 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1439
1456
  res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
1440
1457
  } else {
1441
1458
  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
1459
  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
1460
  shapeORChunks(chunks, usageChunk, overrides);
1445
1461
  const interruption = require_interruption.createInterruptionSignal(fixture);
@@ -1449,7 +1465,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1449
1465
  signal: interruption?.signal,
1450
1466
  onChunkSent: interruption?.tick,
1451
1467
  usageChunk,
1452
- recordedTimings: resolveRecordedTimings(chunks),
1468
+ recordedTimings: resolveRecordedTimings(chunks.length),
1453
1469
  replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1454
1470
  openRouterProcessing
1455
1471
  })) {
@@ -1464,7 +1480,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1464
1480
  if (require_helpers.isTextResponse(response)) {
1465
1481
  if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
1466
1482
  const overrides = require_helpers.extractOverrides(response);
1467
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1483
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1468
1484
  const effReasoning = appliedPlan ? appliedReasoning : require_helpers.resolveReasoningForModel(response.reasoning, responseModel, effectiveStrict, defaults.logger);
1469
1485
  const journalEntry = journal.add({
1470
1486
  method: req.method ?? "POST",
@@ -1478,6 +1494,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1478
1494
  });
1479
1495
  recordOutcome(journalEntry);
1480
1496
  if (body.stream !== true) {
1497
+ await awaitNonStreamingTiming((effReasoning?.length ?? 0) + response.content.length);
1481
1498
  const completion = require_helpers.buildTextCompletion(response.content, responseModel, effReasoning, overrides, body.messages);
1482
1499
  res.writeHead(200, { "Content-Type": "application/json" });
1483
1500
  res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
@@ -1492,7 +1509,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1492
1509
  signal: interruption?.signal,
1493
1510
  onChunkSent: interruption?.tick,
1494
1511
  usageChunk,
1495
- recordedTimings: resolveRecordedTimings(chunks),
1512
+ recordedTimings: resolveRecordedTimings(chunks.length),
1496
1513
  replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1497
1514
  openRouterProcessing
1498
1515
  })) {
@@ -1507,7 +1524,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1507
1524
  if (require_helpers.isToolCallResponse(response)) {
1508
1525
  if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
1509
1526
  const overrides = require_helpers.extractOverrides(response);
1510
- const effectiveStrict = require_helpers.resolveStrictMode(defaults.strict, req.headers);
1527
+ const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
1511
1528
  const effReasoning = appliedPlan ? appliedReasoning : require_helpers.resolveReasoningForModel(response.reasoning, responseModel, effectiveStrict, defaults.logger);
1512
1529
  const journalEntry = journal.add({
1513
1530
  method: req.method ?? "POST",
@@ -1522,6 +1539,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1522
1539
  recordOutcome(journalEntry);
1523
1540
  const toolCalls = require_helpers.requireServedFunctionToolCalls(response, wire);
1524
1541
  if (body.stream !== true) {
1542
+ const toolCallText = toolCalls.map((tc) => tc.name + tc.arguments).join("");
1543
+ await awaitNonStreamingTiming((effReasoning?.length ?? 0) + toolCallText.length);
1525
1544
  const completion = require_helpers.buildToolCallCompletion(toolCalls, responseModel, effReasoning, overrides, body.messages);
1526
1545
  res.writeHead(200, { "Content-Type": "application/json" });
1527
1546
  res.end(JSON.stringify(shapeORCompletion(completion, overrides)));
@@ -1537,7 +1556,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1537
1556
  signal: interruption?.signal,
1538
1557
  onChunkSent: interruption?.tick,
1539
1558
  usageChunk,
1540
- recordedTimings: resolveRecordedTimings(chunks),
1559
+ recordedTimings: resolveRecordedTimings(chunks.length),
1541
1560
  replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
1542
1561
  openRouterProcessing
1543
1562
  })) {
@@ -1559,10 +1578,10 @@ async function handleCompletions(req, res, fixtures, journal, defaults, getReque
1559
1578
  fixture
1560
1579
  }
1561
1580
  }));
1562
- require_sse_writer.writeErrorResponse(res, 500, openRouter ? require_openrouter_chat.serializeOpenRouterError(500, "Fixture response did not match any known type") : JSON.stringify({ error: {
1581
+ 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
1582
  message: "Fixture response did not match any known type",
1564
1583
  type: "server_error"
1565
- } }));
1584
+ }).body);
1566
1585
  }
1567
1586
  async function createServer(fixtures, options, mounts, serviceFixtures) {
1568
1587
  return createServerWithResolvedAuth(fixtures, options, require_api_key_auth.resolveInboundAuth({
@@ -1631,6 +1650,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1631
1650
  const port = options?.port ?? 0;
1632
1651
  const registry = options?.metrics ? require_metrics.createMetricsRegistry() : void 0;
1633
1652
  const serverOptions = options ?? {};
1653
+ require_policy.parsePolicy(serverOptions.policy, (message) => new require_logger.Logger("warn").warn(message));
1634
1654
  const validResponsesTools = (mode) => mode === "legacy" || mode === "extended";
1635
1655
  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
1656
  fixtures = require_helpers.createServerFixtureList(callerFixtures, () => serverOptions.responsesTools, require_fixture_loader.responsesToolsExtendedView);
@@ -1689,6 +1709,9 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1689
1709
  get strict() {
1690
1710
  return serverOptions.strict;
1691
1711
  },
1712
+ get policy() {
1713
+ return serverOptions.policy;
1714
+ },
1692
1715
  get strictToolArguments() {
1693
1716
  return serverOptions.strictToolArguments;
1694
1717
  },
@@ -1814,70 +1837,63 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1814
1837
  * `toolCallEnvelope` instead of using this one.
1815
1838
  */
1816
1839
  function invalidToolArgumentsEnvelope(pathname, message, code) {
1817
- if (pathname === require_route_registry.OLLAMA_CHAT_PATH) return JSON.stringify({
1818
- error: message,
1840
+ if (pathname === require_route_registry.OLLAMA_CHAT_PATH) return require_errors.renderError("ollama", "tool-argument", {
1841
+ message,
1819
1842
  code
1820
- });
1821
- if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return JSON.stringify({ error: {
1843
+ }).body;
1844
+ if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return require_errors.renderError("interactions", "tool-argument", {
1845
+ message,
1846
+ code
1847
+ }).body;
1848
+ if (require_route_registry.GEMINI_PATH_RE.test(pathname) || require_route_registry.VERTEX_AI_RE.test(pathname)) return require_errors.renderError("gemini", "tool-argument", {
1849
+ message,
1822
1850
  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,
1851
+ googleDetails: require_helpers.googleFixtureToolCallErrorDetails(code)
1852
+ }).body;
1853
+ if (pathname === require_route_registry.MESSAGES_PATH) return require_errors.renderError("messages", "tool-argument", {
1827
1854
  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",
1855
+ code
1856
+ }).body;
1857
+ 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
1858
  message,
1842
- reason: code
1843
- });
1844
- return JSON.stringify({ error: {
1859
+ code
1860
+ }).body;
1861
+ return require_errors.renderError("openai", "tool-argument", {
1845
1862
  message,
1846
- type: "server_error",
1847
1863
  code
1848
- } });
1864
+ }).body;
1849
1865
  }
1850
1866
  function invalidMisbehaviorHeaderEnvelope(pathname, detail) {
1851
1867
  const code = "aimock_misbehavior_invalid";
1852
1868
  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,
1869
+ if (pathname === require_route_registry.OLLAMA_CHAT_PATH || pathname === require_route_registry.OLLAMA_GENERATE_PATH) return require_errors.renderError("ollama", "invalid-misbehavior-header", {
1861
1870
  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: {
1871
+ code
1872
+ }).body;
1873
+ if (pathname === require_route_registry.COHERE_CHAT_PATH) return require_errors.renderError("cohere", "invalid-misbehavior-header", {
1874
+ message,
1875
+ code
1876
+ }).body;
1877
+ if (pathname === require_route_registry.GEMINI_INTERACTIONS_PATH) return require_errors.renderError("interactions", "invalid-misbehavior-header", {
1878
+ message,
1879
+ code
1880
+ }).body;
1881
+ 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", {
1882
+ message,
1883
+ code
1884
+ }).body;
1885
+ if (pathname === require_route_registry.MESSAGES_PATH) return require_errors.renderError("messages", "invalid-misbehavior-header", {
1877
1886
  message,
1878
- type: "invalid_request_error",
1879
1887
  code
1880
- } });
1888
+ }).body;
1889
+ 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", {
1890
+ message,
1891
+ code
1892
+ }).body;
1893
+ return require_errors.renderError("openai", "invalid-misbehavior-header", {
1894
+ message,
1895
+ code
1896
+ }).body;
1881
1897
  }
1882
1898
  /**
1883
1899
  * The newest journal entry this request already produced, or null.
@@ -1992,10 +2008,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
1992
2008
  logger.warn(`${route}: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
1993
2009
  }
1994
2010
  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: {
2011
+ 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
2012
  message: msg,
1997
2013
  type: errorTypeForStatus(status)
1998
- } }));
2014
+ }).body);
1999
2015
  } else {
2000
2016
  const midStreamReason = clientAbort ? "client aborted" : "handler crashed mid-stream";
2001
2017
  if (existing) {
@@ -2112,10 +2128,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2112
2128
  logger.warn(`${route}: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
2113
2129
  }
2114
2130
  setCorsHeaders(res);
2115
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
2131
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "route-failure", {
2116
2132
  message: "Invalid request target",
2117
2133
  type: "invalid_request_error"
2118
- } }));
2134
+ }).body);
2119
2135
  return;
2120
2136
  }
2121
2137
  pathname = parsedUrl.pathname;
@@ -2128,7 +2144,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2128
2144
  }
2129
2145
  if (!(req.method === "GET" && (pathname === require_route_registry.HEALTH_PATH || pathname === require_route_registry.READY_PATH || pathname === require_route_registry.METRICS_PATH))) {
2130
2146
  if (!require_api_key_auth.validateRequestApiKey(req, resolvedAuth.policy).ok) {
2131
- require_api_key_auth.writeApiKeyHttpRejection(res, setCorsHeaders);
2147
+ require_api_key_auth.writeApiKeyHttpRejection(res, setCorsHeaders, pathname, require_policy.resolvePolicy(defaults, req.headers).authErrors);
2132
2148
  return;
2133
2149
  }
2134
2150
  require_api_key_auth.markAuthenticatedRequest(req, resolvedAuth.policy);
@@ -2195,18 +2211,9 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2195
2211
  }
2196
2212
  if (pathname === require_route_registry.OLLAMA_TAGS_PATH && req.method === "GET") {
2197
2213
  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
- }));
2214
+ const body = require_render.renderOllamaTags(require_collect.collect(fixtures, "all").ids, () => (/* @__PURE__ */ new Date()).toISOString());
2208
2215
  res.writeHead(200, { "Content-Type": "application/json" });
2209
- res.end(JSON.stringify({ models }));
2216
+ res.end(JSON.stringify(body));
2210
2217
  return;
2211
2218
  }
2212
2219
  const openRouterVideoContentMatch = pathname.match(require_route_registry.OPENROUTER_VIDEO_CONTENT_RE);
@@ -2327,21 +2334,70 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2327
2334
  res.end(registry.serialize());
2328
2335
  return;
2329
2336
  }
2330
- if (pathname === require_route_registry.MODELS_PATH && req.method === "GET") {
2337
+ const modelDetailMatch = pathname.match(require_route_registry.MODELS_DETAIL_RE);
2338
+ const geminiModelDetailMatch = pathname.match(require_route_registry.GEMINI_MODEL_DETAIL_RE);
2339
+ if (req.method === "GET" && (pathname === require_route_registry.MODELS_PATH || pathname === require_route_registry.GEMINI_MODELS_PATH || modelDetailMatch || geminiModelDetailMatch)) {
2331
2340
  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
- }));
2341
+ const google = pathname === require_route_registry.GEMINI_MODELS_PATH || geminiModelDetailMatch !== null;
2342
+ const policy = require_policy.resolvePolicy(defaults, req.headers);
2343
+ const anthropic = !google && (modelDetailMatch !== null || policy.modelCatalog === "native") && require_profiles.isAnthropicModelRequest(req.headers);
2344
+ const missingHeader = anthropic && policy.requiredHeaders === "enforce" ? require_profiles.missingRequiredHeader("messages", req.headers) : void 0;
2345
+ if (missingHeader) {
2346
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("messages", "thinking", {
2347
+ message: `${missingHeader}: header is required`,
2348
+ requestId
2349
+ }).body);
2350
+ return;
2351
+ }
2352
+ const ids = require_render.coreModelIds(require_collect.collect(fixtures, "all").ids);
2353
+ const visible = google ? require_collect.idsFor(ids, "google") : anthropic ? require_collect.idsFor(ids, "anthropic") : ids;
2354
+ const catalogError = (status, message) => {
2355
+ const rendered = google ? require_errors.renderError("gemini", "fixture", {
2356
+ bodyCode: status,
2357
+ status: status === 404 ? "NOT_FOUND" : "INVALID_ARGUMENT",
2358
+ message
2359
+ }) : anthropic ? require_errors.renderError("messages", "thinking", {
2360
+ type: status === 404 ? "not_found_error" : "invalid_request_error",
2361
+ message
2362
+ }) : require_errors.renderError("openai", "validation", { message });
2363
+ res.writeHead(status, {
2364
+ "Content-Type": "application/json",
2365
+ ...rendered.headers
2366
+ });
2367
+ res.end(rendered.body);
2368
+ };
2369
+ let body;
2370
+ const detail = modelDetailMatch ?? geminiModelDetailMatch;
2371
+ if (detail) {
2372
+ let id;
2373
+ try {
2374
+ id = decodeURIComponent(detail[1]);
2375
+ } catch {
2376
+ catalogError(404, "Model not found");
2377
+ return;
2378
+ }
2379
+ if (!visible.includes(id)) {
2380
+ catalogError(404, `Model not found: ${id}`);
2381
+ return;
2382
+ }
2383
+ body = google ? require_render.renderGeminiModel(id) : anthropic ? require_render.renderAnthropicModel(id) : require_render.renderOpenAIModel(id);
2384
+ } else if (google) {
2385
+ const result = require_gemini_page.geminiPage(visible, parsedUrl.searchParams);
2386
+ if (result.error !== void 0) {
2387
+ catalogError(400, result.error);
2388
+ return;
2389
+ }
2390
+ body = require_render.renderGeminiModels(result.page);
2391
+ } else if (anthropic) {
2392
+ const result = require_anthropic_page.anthropicPage(visible, parsedUrl.searchParams);
2393
+ if (result.error !== void 0) {
2394
+ catalogError(400, result.error);
2395
+ return;
2396
+ }
2397
+ body = require_render.renderAnthropicModels(result.page);
2398
+ } else body = require_render.renderOpenAIModels(ids);
2340
2399
  res.writeHead(200, { "Content-Type": "application/json" });
2341
- res.end(JSON.stringify({
2342
- object: "list",
2343
- data
2344
- }));
2400
+ res.end(JSON.stringify(body));
2345
2401
  return;
2346
2402
  }
2347
2403
  const batchesCancelMatch = pathname.match(require_route_registry.BATCHES_CANCEL_RE);
@@ -2599,10 +2655,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2599
2655
  if (limitParam) {
2600
2656
  const limit = Number(limitParam);
2601
2657
  if (!/^\+?\d+$/.test(limitParam.trim()) || !Number.isSafeInteger(limit) || limit <= 0) {
2602
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
2658
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
2603
2659
  message: `Invalid limit parameter: "${limitParam}"`,
2604
2660
  type: "invalid_request_error"
2605
- } }));
2661
+ }).body);
2606
2662
  return;
2607
2663
  }
2608
2664
  opts = { limit };
@@ -2627,7 +2683,27 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2627
2683
  ensureRawFixturePositions();
2628
2684
  await require_responses.handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2629
2685
  } catch (err) {
2630
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2686
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2687
+ }
2688
+ return;
2689
+ }
2690
+ const geminiCountMatch = pathname.match(require_route_registry.GEMINI_COUNT_RE);
2691
+ if (req.method === "POST" && (pathname === require_route_registry.MESSAGES_COUNT_PATH || geminiCountMatch)) {
2692
+ const google = geminiCountMatch !== null;
2693
+ try {
2694
+ require_count_tokens.handleCountTokens(req, res, await require_helpers.readBody(req), google, geminiCountMatch?.[1] ?? "", journal, defaults, setCorsHeaders);
2695
+ } catch (err) {
2696
+ routeError(req, res, err, pathname, {
2697
+ service: google ? "gemini" : "anthropic",
2698
+ envelope: (message, status) => google ? require_errors.renderError("gemini", "fixture", {
2699
+ message,
2700
+ bodyCode: status,
2701
+ status: status === 400 ? "INVALID_ARGUMENT" : "INTERNAL"
2702
+ }).body : require_errors.renderError("messages", "thinking", {
2703
+ message,
2704
+ type: status === 400 ? "invalid_request_error" : "api_error"
2705
+ }).body
2706
+ });
2631
2707
  }
2632
2708
  return;
2633
2709
  }
@@ -2637,7 +2713,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2637
2713
  ensureRawFixturePositions();
2638
2714
  await require_messages.handleMessages(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2639
2715
  } catch (err) {
2640
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2716
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2641
2717
  }
2642
2718
  return;
2643
2719
  }
@@ -2647,7 +2723,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2647
2723
  ensureRawFixturePositions();
2648
2724
  await require_cohere.handleCohere(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2649
2725
  } catch (err) {
2650
- routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${JSON.stringify({ error: { message: m } })}\n\n` });
2726
+ routeError(req, res, err, pathname, { streamEvent: (m) => `event: error\ndata: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2651
2727
  }
2652
2728
  return;
2653
2729
  }
@@ -2813,7 +2889,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2813
2889
  ensureRawFixturePositions();
2814
2890
  await require_gemini_interactions.handleGeminiInteractions(req, res, raw, fixtures, journal, defaults, setCorsHeaders);
2815
2891
  } catch (err) {
2816
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2892
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2817
2893
  }
2818
2894
  return;
2819
2895
  }
@@ -2838,7 +2914,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2838
2914
  ensureRawFixturePositions();
2839
2915
  await require_gemini.handleGemini(req, res, raw, geminiModel, streaming, fixtures, journal, defaults, setCorsHeaders);
2840
2916
  } catch (err) {
2841
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2917
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2842
2918
  }
2843
2919
  return;
2844
2920
  }
@@ -2851,7 +2927,7 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2851
2927
  ensureRawFixturePositions();
2852
2928
  await require_gemini.handleGemini(req, res, raw, vertexModel, streaming, fixtures, journal, defaults, setCorsHeaders, "vertexai");
2853
2929
  } catch (err) {
2854
- routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${JSON.stringify({ error: { message: m } })}\n\n` });
2930
+ routeError(req, res, err, pathname, { streamEvent: (m) => `data: ${require_errors.renderError("openai", "stream-failure", { message: m }).body}\n\n` });
2855
2931
  }
2856
2932
  return;
2857
2933
  }
@@ -2967,10 +3043,10 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
2967
3043
  try {
2968
3044
  voiceId = decodeURIComponent(elevenLabsVoiceMatch[1]);
2969
3045
  } catch {
2970
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
3046
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
2971
3047
  message: `Invalid voice id '${elevenLabsVoiceMatch[1]}': malformed percent-encoding`,
2972
3048
  type: "invalid_request_error"
2973
- } }));
3049
+ }).body);
2974
3050
  journal.add({
2975
3051
  method: req.method ?? "GET",
2976
3052
  path: req.url ?? pathname,
@@ -3120,15 +3196,15 @@ async function startServer(fixtures, options, resolvedAuth, mountList, logger, s
3120
3196
  await handleCompletions(req, res, fixtures, journal, defaults, () => lastJournalEntryFor(req), azureDeploymentId, completionsProvider, isOpenRouter, ensureRawFixturePositions, originalPathname.startsWith("/api/v3/"));
3121
3197
  } catch (err) {
3122
3198
  routeError(req, res, err, pathname, {
3123
- envelope: (m, status) => isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : JSON.stringify({ error: {
3199
+ envelope: (m, status) => isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : require_errors.renderError("openai", "route-failure", {
3124
3200
  message: m,
3125
3201
  type: errorTypeForStatus(status)
3126
- } }),
3202
+ }).body,
3127
3203
  ...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: {
3204
+ streamEvent: (m, status) => `data: ${isOpenRouter ? require_openrouter_chat.serializeOpenRouterError(status, m) : require_errors.renderError("openai", "route-failure", {
3129
3205
  message: m,
3130
3206
  type: errorTypeForStatus(status)
3131
- } })}\n\n`
3207
+ }).body}\n\n`
3132
3208
  });
3133
3209
  }
3134
3210
  }