@copilotkit/aimock 1.45.1 → 1.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (492) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +25 -1
  4. package/README.md +11 -2
  5. package/dist/agui-mock.cjs +25 -25
  6. package/dist/agui-mock.cjs.map +1 -1
  7. package/dist/agui-mock.d.cts.map +1 -1
  8. package/dist/agui-mock.d.ts.map +1 -1
  9. package/dist/agui-mock.js +25 -25
  10. package/dist/agui-mock.js.map +1 -1
  11. package/dist/agui-types.d.cts.map +1 -1
  12. package/dist/aimock-cli.cjs +15 -1
  13. package/dist/aimock-cli.cjs.map +1 -1
  14. package/dist/aimock-cli.d.cts.map +1 -1
  15. package/dist/aimock-cli.d.ts.map +1 -1
  16. package/dist/aimock-cli.js +16 -2
  17. package/dist/aimock-cli.js.map +1 -1
  18. package/dist/api-key-auth.cjs +10 -9
  19. package/dist/api-key-auth.cjs.map +1 -1
  20. package/dist/api-key-auth.d.cts.map +1 -1
  21. package/dist/api-key-auth.d.ts.map +1 -1
  22. package/dist/api-key-auth.js +11 -10
  23. package/dist/api-key-auth.js.map +1 -1
  24. package/dist/aws-event-stream.cjs +20 -23
  25. package/dist/aws-event-stream.cjs.map +1 -1
  26. package/dist/aws-event-stream.d.cts +0 -1
  27. package/dist/aws-event-stream.d.ts +0 -1
  28. package/dist/aws-event-stream.js +20 -24
  29. package/dist/aws-event-stream.js.map +1 -1
  30. package/dist/batches.cjs +2 -4
  31. package/dist/batches.cjs.map +1 -1
  32. package/dist/batches.d.cts.map +1 -1
  33. package/dist/batches.d.ts.map +1 -1
  34. package/dist/batches.js +2 -4
  35. package/dist/batches.js.map +1 -1
  36. package/dist/bedrock-converse.cjs +139 -161
  37. package/dist/bedrock-converse.cjs.map +1 -1
  38. package/dist/bedrock-converse.d.cts.map +1 -1
  39. package/dist/bedrock-converse.d.ts.map +1 -1
  40. package/dist/bedrock-converse.js +137 -159
  41. package/dist/bedrock-converse.js.map +1 -1
  42. package/dist/bedrock.cjs +175 -216
  43. package/dist/bedrock.cjs.map +1 -1
  44. package/dist/bedrock.d.cts.map +1 -1
  45. package/dist/bedrock.d.ts.map +1 -1
  46. package/dist/bedrock.js +172 -213
  47. package/dist/bedrock.js.map +1 -1
  48. package/dist/byteplus-video.cjs +11 -10
  49. package/dist/byteplus-video.cjs.map +1 -1
  50. package/dist/byteplus-video.d.cts.map +1 -1
  51. package/dist/byteplus-video.d.ts.map +1 -1
  52. package/dist/byteplus-video.js +5 -4
  53. package/dist/byteplus-video.js.map +1 -1
  54. package/dist/chaos.cjs +5 -4
  55. package/dist/chaos.cjs.map +1 -1
  56. package/dist/chaos.d.cts.map +1 -1
  57. package/dist/chaos.d.ts.map +1 -1
  58. package/dist/chaos.js +5 -4
  59. package/dist/chaos.js.map +1 -1
  60. package/dist/cli.cjs +15 -0
  61. package/dist/cli.cjs.map +1 -1
  62. package/dist/cli.js +15 -0
  63. package/dist/cli.js.map +1 -1
  64. package/dist/cohere.cjs +107 -180
  65. package/dist/cohere.cjs.map +1 -1
  66. package/dist/cohere.d.cts.map +1 -1
  67. package/dist/cohere.d.ts.map +1 -1
  68. package/dist/cohere.js +106 -179
  69. package/dist/cohere.js.map +1 -1
  70. package/dist/config-loader.cjs +29 -1
  71. package/dist/config-loader.cjs.map +1 -1
  72. package/dist/config-loader.d.cts +7 -1
  73. package/dist/config-loader.d.cts.map +1 -1
  74. package/dist/config-loader.d.ts +7 -1
  75. package/dist/config-loader.d.ts.map +1 -1
  76. package/dist/config-loader.js +29 -2
  77. package/dist/config-loader.js.map +1 -1
  78. package/dist/count-tokens.cjs +146 -0
  79. package/dist/count-tokens.cjs.map +1 -0
  80. package/dist/count-tokens.js +146 -0
  81. package/dist/count-tokens.js.map +1 -0
  82. package/dist/elevenlabs-audio.cjs +36 -34
  83. package/dist/elevenlabs-audio.cjs.map +1 -1
  84. package/dist/elevenlabs-audio.d.cts.map +1 -1
  85. package/dist/elevenlabs-audio.d.ts.map +1 -1
  86. package/dist/elevenlabs-audio.js +33 -31
  87. package/dist/elevenlabs-audio.js.map +1 -1
  88. package/dist/elevenlabs-voice.cjs +38 -37
  89. package/dist/elevenlabs-voice.cjs.map +1 -1
  90. package/dist/elevenlabs-voice.d.cts.map +1 -1
  91. package/dist/elevenlabs-voice.d.ts.map +1 -1
  92. package/dist/elevenlabs-voice.js +33 -32
  93. package/dist/elevenlabs-voice.js.map +1 -1
  94. package/dist/embedding-request.cjs +16 -0
  95. package/dist/embedding-request.cjs.map +1 -0
  96. package/dist/embedding-request.js +14 -0
  97. package/dist/embedding-request.js.map +1 -0
  98. package/dist/embeddings.cjs +30 -20
  99. package/dist/embeddings.cjs.map +1 -1
  100. package/dist/embeddings.d.cts.map +1 -1
  101. package/dist/embeddings.d.ts.map +1 -1
  102. package/dist/embeddings.js +30 -20
  103. package/dist/embeddings.js.map +1 -1
  104. package/dist/fal-audio.cjs +45 -43
  105. package/dist/fal-audio.cjs.map +1 -1
  106. package/dist/fal-audio.d.cts.map +1 -1
  107. package/dist/fal-audio.d.ts.map +1 -1
  108. package/dist/fal-audio.js +42 -40
  109. package/dist/fal-audio.js.map +1 -1
  110. package/dist/fal.cjs +17 -15
  111. package/dist/fal.cjs.map +1 -1
  112. package/dist/fal.js +16 -14
  113. package/dist/fal.js.map +1 -1
  114. package/dist/files.cjs +2 -4
  115. package/dist/files.cjs.map +1 -1
  116. package/dist/files.d.cts.map +1 -1
  117. package/dist/files.d.ts.map +1 -1
  118. package/dist/files.js +2 -4
  119. package/dist/files.js.map +1 -1
  120. package/dist/fine-tuning.cjs +2 -4
  121. package/dist/fine-tuning.cjs.map +1 -1
  122. package/dist/fine-tuning.d.cts.map +1 -1
  123. package/dist/fine-tuning.d.ts.map +1 -1
  124. package/dist/fine-tuning.js +2 -4
  125. package/dist/fine-tuning.js.map +1 -1
  126. package/dist/fixture-loader.cjs +140 -44
  127. package/dist/fixture-loader.cjs.map +1 -1
  128. package/dist/fixture-loader.d.cts.map +1 -1
  129. package/dist/fixture-loader.d.ts.map +1 -1
  130. package/dist/fixture-loader.js +141 -46
  131. package/dist/fixture-loader.js.map +1 -1
  132. package/dist/gemini-embeddings.cjs +26 -24
  133. package/dist/gemini-embeddings.cjs.map +1 -1
  134. package/dist/gemini-embeddings.js +26 -24
  135. package/dist/gemini-embeddings.js.map +1 -1
  136. package/dist/gemini-interactions.cjs +113 -156
  137. package/dist/gemini-interactions.cjs.map +1 -1
  138. package/dist/gemini-interactions.d.cts +0 -1
  139. package/dist/gemini-interactions.d.cts.map +1 -1
  140. package/dist/gemini-interactions.d.ts +0 -1
  141. package/dist/gemini-interactions.d.ts.map +1 -1
  142. package/dist/gemini-interactions.js +113 -156
  143. package/dist/gemini-interactions.js.map +1 -1
  144. package/dist/gemini.cjs +295 -218
  145. package/dist/gemini.cjs.map +1 -1
  146. package/dist/gemini.d.cts.map +1 -1
  147. package/dist/gemini.d.ts.map +1 -1
  148. package/dist/gemini.js +295 -219
  149. package/dist/gemini.js.map +1 -1
  150. package/dist/grok-video.cjs +14 -12
  151. package/dist/grok-video.cjs.map +1 -1
  152. package/dist/grok-video.d.cts.map +1 -1
  153. package/dist/grok-video.d.ts.map +1 -1
  154. package/dist/grok-video.js +8 -6
  155. package/dist/grok-video.js.map +1 -1
  156. package/dist/helpers.cjs +411 -75
  157. package/dist/helpers.cjs.map +1 -1
  158. package/dist/helpers.d.cts +51 -1
  159. package/dist/helpers.d.cts.map +1 -1
  160. package/dist/helpers.d.ts +51 -1
  161. package/dist/helpers.d.ts.map +1 -1
  162. package/dist/helpers.js +402 -74
  163. package/dist/helpers.js.map +1 -1
  164. package/dist/images.cjs +30 -28
  165. package/dist/images.cjs.map +1 -1
  166. package/dist/images.d.cts.map +1 -1
  167. package/dist/images.d.ts.map +1 -1
  168. package/dist/images.js +27 -25
  169. package/dist/images.js.map +1 -1
  170. package/dist/index.cjs +4 -2
  171. package/dist/index.d.cts +4 -4
  172. package/dist/index.d.ts +4 -4
  173. package/dist/index.js +4 -4
  174. package/dist/journal.cjs +3 -1
  175. package/dist/journal.cjs.map +1 -1
  176. package/dist/journal.d.cts.map +1 -1
  177. package/dist/journal.d.ts.map +1 -1
  178. package/dist/journal.js +2 -1
  179. package/dist/journal.js.map +1 -1
  180. package/dist/llmock.cjs +3 -0
  181. package/dist/llmock.cjs.map +1 -1
  182. package/dist/llmock.d.cts.map +1 -1
  183. package/dist/llmock.d.ts.map +1 -1
  184. package/dist/llmock.js +3 -0
  185. package/dist/llmock.js.map +1 -1
  186. package/dist/mcp-fakes.d.cts.map +1 -1
  187. package/dist/mcp-handler.cjs +7 -3
  188. package/dist/mcp-handler.cjs.map +1 -1
  189. package/dist/mcp-handler.js +7 -3
  190. package/dist/mcp-handler.js.map +1 -1
  191. package/dist/mcp-recorder.cjs +2 -1
  192. package/dist/mcp-recorder.cjs.map +1 -1
  193. package/dist/mcp-recorder.js +3 -2
  194. package/dist/mcp-recorder.js.map +1 -1
  195. package/dist/messages.cjs +235 -202
  196. package/dist/messages.cjs.map +1 -1
  197. package/dist/messages.d.cts.map +1 -1
  198. package/dist/messages.d.ts.map +1 -1
  199. package/dist/messages.js +234 -202
  200. package/dist/messages.js.map +1 -1
  201. package/dist/metrics.cjs +5 -2
  202. package/dist/metrics.cjs.map +1 -1
  203. package/dist/metrics.d.cts.map +1 -1
  204. package/dist/metrics.d.ts.map +1 -1
  205. package/dist/metrics.js +6 -3
  206. package/dist/metrics.js.map +1 -1
  207. package/dist/misbehavior.cjs +62 -3
  208. package/dist/misbehavior.cjs.map +1 -1
  209. package/dist/misbehavior.d.cts.map +1 -1
  210. package/dist/misbehavior.d.ts.map +1 -1
  211. package/dist/misbehavior.js +63 -4
  212. package/dist/misbehavior.js.map +1 -1
  213. package/dist/model-utils.cjs +1 -0
  214. package/dist/model-utils.cjs.map +1 -1
  215. package/dist/model-utils.js +1 -1
  216. package/dist/model-utils.js.map +1 -1
  217. package/dist/moderation.cjs +15 -12
  218. package/dist/moderation.cjs.map +1 -1
  219. package/dist/moderation.js +14 -11
  220. package/dist/moderation.js.map +1 -1
  221. package/dist/ndjson-writer.cjs +21 -23
  222. package/dist/ndjson-writer.cjs.map +1 -1
  223. package/dist/ndjson-writer.d.cts +0 -1
  224. package/dist/ndjson-writer.d.cts.map +1 -1
  225. package/dist/ndjson-writer.d.ts +0 -1
  226. package/dist/ndjson-writer.d.ts.map +1 -1
  227. package/dist/ndjson-writer.js +21 -24
  228. package/dist/ndjson-writer.js.map +1 -1
  229. package/dist/ollama.cjs +276 -210
  230. package/dist/ollama.cjs.map +1 -1
  231. package/dist/ollama.d.cts.map +1 -1
  232. package/dist/ollama.d.ts.map +1 -1
  233. package/dist/ollama.js +273 -207
  234. package/dist/ollama.js.map +1 -1
  235. package/dist/openapi.cjs +323 -3
  236. package/dist/openapi.cjs.map +1 -1
  237. package/dist/openapi.d.cts.map +1 -1
  238. package/dist/openapi.d.ts.map +1 -1
  239. package/dist/openapi.js +324 -4
  240. package/dist/openapi.js.map +1 -1
  241. package/dist/openrouter-chat.cjs +11 -155
  242. package/dist/openrouter-chat.cjs.map +1 -1
  243. package/dist/openrouter-chat.js +11 -155
  244. package/dist/openrouter-chat.js.map +1 -1
  245. package/dist/openrouter-video.cjs +51 -74
  246. package/dist/openrouter-video.cjs.map +1 -1
  247. package/dist/openrouter-video.d.cts.map +1 -1
  248. package/dist/openrouter-video.d.ts.map +1 -1
  249. package/dist/openrouter-video.js +37 -60
  250. package/dist/openrouter-video.js.map +1 -1
  251. package/dist/raw-validation.cjs +177 -0
  252. package/dist/raw-validation.cjs.map +1 -0
  253. package/dist/raw-validation.js +176 -0
  254. package/dist/raw-validation.js.map +1 -0
  255. package/dist/recorder.cjs +176 -95
  256. package/dist/recorder.cjs.map +1 -1
  257. package/dist/recorder.d.cts.map +1 -1
  258. package/dist/recorder.d.ts.map +1 -1
  259. package/dist/recorder.js +176 -95
  260. package/dist/recorder.js.map +1 -1
  261. package/dist/rerank.cjs +13 -11
  262. package/dist/rerank.cjs.map +1 -1
  263. package/dist/rerank.js +12 -10
  264. package/dist/rerank.js.map +1 -1
  265. package/dist/response/catalog/anthropic-page.cjs +39 -0
  266. package/dist/response/catalog/anthropic-page.cjs.map +1 -0
  267. package/dist/response/catalog/anthropic-page.js +38 -0
  268. package/dist/response/catalog/anthropic-page.js.map +1 -0
  269. package/dist/response/catalog/collect.cjs +61 -0
  270. package/dist/response/catalog/collect.cjs.map +1 -0
  271. package/dist/response/catalog/collect.js +59 -0
  272. package/dist/response/catalog/collect.js.map +1 -0
  273. package/dist/response/catalog/gemini-page.cjs +25 -0
  274. package/dist/response/catalog/gemini-page.cjs.map +1 -0
  275. package/dist/response/catalog/gemini-page.js +24 -0
  276. package/dist/response/catalog/gemini-page.js.map +1 -0
  277. package/dist/response/catalog/render.cjs +182 -0
  278. package/dist/response/catalog/render.cjs.map +1 -0
  279. package/dist/response/catalog/render.js +171 -0
  280. package/dist/response/catalog/render.js.map +1 -0
  281. package/dist/response/deliver.cjs +144 -0
  282. package/dist/response/deliver.cjs.map +1 -0
  283. package/dist/response/deliver.js +143 -0
  284. package/dist/response/deliver.js.map +1 -0
  285. package/dist/response/errors.cjs +225 -0
  286. package/dist/response/errors.cjs.map +1 -0
  287. package/dist/response/errors.js +224 -0
  288. package/dist/response/errors.js.map +1 -0
  289. package/dist/response/finish.cjs +39 -0
  290. package/dist/response/finish.cjs.map +1 -0
  291. package/dist/response/finish.js +35 -0
  292. package/dist/response/finish.js.map +1 -0
  293. package/dist/response/frame-loop.cjs +102 -0
  294. package/dist/response/frame-loop.cjs.map +1 -0
  295. package/dist/response/frame-loop.js +100 -0
  296. package/dist/response/frame-loop.js.map +1 -0
  297. package/dist/response/lifecycle.cjs +223 -0
  298. package/dist/response/lifecycle.cjs.map +1 -0
  299. package/dist/response/lifecycle.js +211 -0
  300. package/dist/response/lifecycle.js.map +1 -0
  301. package/dist/response/policy.cjs +126 -0
  302. package/dist/response/policy.cjs.map +1 -0
  303. package/dist/response/policy.js +120 -0
  304. package/dist/response/policy.js.map +1 -0
  305. package/dist/response/profiles.cjs +69 -0
  306. package/dist/response/profiles.cjs.map +1 -0
  307. package/dist/response/profiles.js +65 -0
  308. package/dist/response/profiles.js.map +1 -0
  309. package/dist/response/proxy.cjs +71 -0
  310. package/dist/response/proxy.cjs.map +1 -0
  311. package/dist/response/proxy.js +70 -0
  312. package/dist/response/proxy.js.map +1 -0
  313. package/dist/response/raw.cjs +228 -0
  314. package/dist/response/raw.cjs.map +1 -0
  315. package/dist/response/raw.js +227 -0
  316. package/dist/response/raw.js.map +1 -0
  317. package/dist/response/timing.cjs +157 -0
  318. package/dist/response/timing.cjs.map +1 -0
  319. package/dist/response/timing.js +150 -0
  320. package/dist/response/timing.js.map +1 -0
  321. package/dist/response/usage/codecs/anthropic.cjs +52 -0
  322. package/dist/response/usage/codecs/anthropic.cjs.map +1 -0
  323. package/dist/response/usage/codecs/anthropic.js +50 -0
  324. package/dist/response/usage/codecs/anthropic.js.map +1 -0
  325. package/dist/response/usage/codecs/cohere.cjs +36 -0
  326. package/dist/response/usage/codecs/cohere.cjs.map +1 -0
  327. package/dist/response/usage/codecs/cohere.js +35 -0
  328. package/dist/response/usage/codecs/cohere.js.map +1 -0
  329. package/dist/response/usage/codecs/converse.cjs +16 -0
  330. package/dist/response/usage/codecs/converse.cjs.map +1 -0
  331. package/dist/response/usage/codecs/converse.js +15 -0
  332. package/dist/response/usage/codecs/converse.js.map +1 -0
  333. package/dist/response/usage/codecs/gemini.cjs +31 -0
  334. package/dist/response/usage/codecs/gemini.cjs.map +1 -0
  335. package/dist/response/usage/codecs/gemini.js +31 -0
  336. package/dist/response/usage/codecs/gemini.js.map +1 -0
  337. package/dist/response/usage/codecs/interactions.cjs +22 -0
  338. package/dist/response/usage/codecs/interactions.cjs.map +1 -0
  339. package/dist/response/usage/codecs/interactions.js +21 -0
  340. package/dist/response/usage/codecs/interactions.js.map +1 -0
  341. package/dist/response/usage/codecs/ollama.cjs +17 -0
  342. package/dist/response/usage/codecs/ollama.cjs.map +1 -0
  343. package/dist/response/usage/codecs/ollama.js +17 -0
  344. package/dist/response/usage/codecs/ollama.js.map +1 -0
  345. package/dist/response/usage/codecs/openai.cjs +52 -0
  346. package/dist/response/usage/codecs/openai.cjs.map +1 -0
  347. package/dist/response/usage/codecs/openai.js +50 -0
  348. package/dist/response/usage/codecs/openai.js.map +1 -0
  349. package/dist/response/usage/codecs/openrouter.cjs +68 -0
  350. package/dist/response/usage/codecs/openrouter.cjs.map +1 -0
  351. package/dist/response/usage/codecs/openrouter.js +67 -0
  352. package/dist/response/usage/codecs/openrouter.js.map +1 -0
  353. package/dist/response/usage/codecs/realtime.cjs +19 -0
  354. package/dist/response/usage/codecs/realtime.cjs.map +1 -0
  355. package/dist/response/usage/codecs/realtime.js +18 -0
  356. package/dist/response/usage/codecs/realtime.js.map +1 -0
  357. package/dist/response/usage/codecs/responses.cjs +21 -0
  358. package/dist/response/usage/codecs/responses.cjs.map +1 -0
  359. package/dist/response/usage/codecs/responses.js +20 -0
  360. package/dist/response/usage/codecs/responses.js.map +1 -0
  361. package/dist/response/usage/estimate.cjs +23 -0
  362. package/dist/response/usage/estimate.cjs.map +1 -0
  363. package/dist/response/usage/estimate.js +21 -0
  364. package/dist/response/usage/estimate.js.map +1 -0
  365. package/dist/response/usage/fields.cjs +72 -0
  366. package/dist/response/usage/fields.cjs.map +1 -0
  367. package/dist/response/usage/fields.js +70 -0
  368. package/dist/response/usage/fields.js.map +1 -0
  369. package/dist/response/usage/recording.cjs +52 -0
  370. package/dist/response/usage/recording.cjs.map +1 -0
  371. package/dist/response/usage/recording.js +52 -0
  372. package/dist/response/usage/recording.js.map +1 -0
  373. package/dist/responses.cjs +304 -196
  374. package/dist/responses.cjs.map +1 -1
  375. package/dist/responses.d.cts.map +1 -1
  376. package/dist/responses.d.ts.map +1 -1
  377. package/dist/responses.js +303 -195
  378. package/dist/responses.js.map +1 -1
  379. package/dist/route-registry.cjs +45 -0
  380. package/dist/route-registry.cjs.map +1 -1
  381. package/dist/route-registry.d.cts.map +1 -1
  382. package/dist/route-registry.d.ts.map +1 -1
  383. package/dist/route-registry.js +41 -1
  384. package/dist/route-registry.js.map +1 -1
  385. package/dist/router.cjs +24 -4
  386. package/dist/router.cjs.map +1 -1
  387. package/dist/router.d.cts +7 -1
  388. package/dist/router.d.cts.map +1 -1
  389. package/dist/router.d.ts +7 -1
  390. package/dist/router.d.ts.map +1 -1
  391. package/dist/router.js +24 -5
  392. package/dist/router.js.map +1 -1
  393. package/dist/search.cjs +13 -11
  394. package/dist/search.cjs.map +1 -1
  395. package/dist/search.js +12 -10
  396. package/dist/search.js.map +1 -1
  397. package/dist/server.cjs +293 -248
  398. package/dist/server.cjs.map +1 -1
  399. package/dist/server.d.cts.map +1 -1
  400. package/dist/server.d.ts.map +1 -1
  401. package/dist/server.js +294 -249
  402. package/dist/server.js.map +1 -1
  403. package/dist/speech.cjs +20 -18
  404. package/dist/speech.cjs.map +1 -1
  405. package/dist/speech.d.cts.map +1 -1
  406. package/dist/speech.d.ts.map +1 -1
  407. package/dist/speech.js +19 -17
  408. package/dist/speech.js.map +1 -1
  409. package/dist/sse-writer.cjs +56 -30
  410. package/dist/sse-writer.cjs.map +1 -1
  411. package/dist/sse-writer.d.cts +0 -1
  412. package/dist/sse-writer.d.cts.map +1 -1
  413. package/dist/sse-writer.d.ts +0 -1
  414. package/dist/sse-writer.d.ts.map +1 -1
  415. package/dist/sse-writer.js +55 -31
  416. package/dist/sse-writer.js.map +1 -1
  417. package/dist/stream-collapse.cjs +118 -11
  418. package/dist/stream-collapse.cjs.map +1 -1
  419. package/dist/stream-collapse.d.cts +10 -9
  420. package/dist/stream-collapse.d.cts.map +1 -1
  421. package/dist/stream-collapse.d.ts +10 -9
  422. package/dist/stream-collapse.d.ts.map +1 -1
  423. package/dist/stream-collapse.js +118 -11
  424. package/dist/stream-collapse.js.map +1 -1
  425. package/dist/transcription.cjs +31 -43
  426. package/dist/transcription.cjs.map +1 -1
  427. package/dist/transcription.d.cts.map +1 -1
  428. package/dist/transcription.d.ts.map +1 -1
  429. package/dist/transcription.js +31 -43
  430. package/dist/transcription.js.map +1 -1
  431. package/dist/types.cjs.map +1 -1
  432. package/dist/types.d.cts +231 -9
  433. package/dist/types.d.cts.map +1 -1
  434. package/dist/types.d.ts +231 -9
  435. package/dist/types.d.ts.map +1 -1
  436. package/dist/types.js.map +1 -1
  437. package/dist/vector-mock.cjs +3 -8
  438. package/dist/vector-mock.cjs.map +1 -1
  439. package/dist/vector-mock.d.cts.map +1 -1
  440. package/dist/vector-mock.d.ts.map +1 -1
  441. package/dist/vector-mock.js +3 -8
  442. package/dist/vector-mock.js.map +1 -1
  443. package/dist/vector-stores.cjs +2 -4
  444. package/dist/vector-stores.cjs.map +1 -1
  445. package/dist/vector-stores.d.cts.map +1 -1
  446. package/dist/vector-stores.d.ts.map +1 -1
  447. package/dist/vector-stores.js +2 -4
  448. package/dist/vector-stores.js.map +1 -1
  449. package/dist/veo-video.cjs +16 -14
  450. package/dist/veo-video.cjs.map +1 -1
  451. package/dist/veo-video.js +10 -8
  452. package/dist/veo-video.js.map +1 -1
  453. package/dist/video.cjs +21 -19
  454. package/dist/video.cjs.map +1 -1
  455. package/dist/video.d.cts.map +1 -1
  456. package/dist/video.d.ts.map +1 -1
  457. package/dist/video.js +20 -18
  458. package/dist/video.js.map +1 -1
  459. package/dist/ws-framing.cjs +12 -6
  460. package/dist/ws-framing.cjs.map +1 -1
  461. package/dist/ws-framing.d.cts +2 -0
  462. package/dist/ws-framing.d.cts.map +1 -1
  463. package/dist/ws-framing.d.ts +2 -0
  464. package/dist/ws-framing.d.ts.map +1 -1
  465. package/dist/ws-framing.js +12 -6
  466. package/dist/ws-framing.js.map +1 -1
  467. package/dist/ws-gemini-live.cjs +131 -96
  468. package/dist/ws-gemini-live.cjs.map +1 -1
  469. package/dist/ws-gemini-live.d.cts +0 -1
  470. package/dist/ws-gemini-live.d.cts.map +1 -1
  471. package/dist/ws-gemini-live.d.ts +0 -1
  472. package/dist/ws-gemini-live.d.ts.map +1 -1
  473. package/dist/ws-gemini-live.js +130 -95
  474. package/dist/ws-gemini-live.js.map +1 -1
  475. package/dist/ws-live.cjs +6 -5
  476. package/dist/ws-live.cjs.map +1 -1
  477. package/dist/ws-live.js +5 -4
  478. package/dist/ws-live.js.map +1 -1
  479. package/dist/ws-realtime.cjs +108 -124
  480. package/dist/ws-realtime.cjs.map +1 -1
  481. package/dist/ws-realtime.d.cts.map +1 -1
  482. package/dist/ws-realtime.d.ts.map +1 -1
  483. package/dist/ws-realtime.js +105 -121
  484. package/dist/ws-realtime.js.map +1 -1
  485. package/dist/ws-responses.cjs +80 -59
  486. package/dist/ws-responses.cjs.map +1 -1
  487. package/dist/ws-responses.d.cts.map +1 -1
  488. package/dist/ws-responses.d.ts.map +1 -1
  489. package/dist/ws-responses.js +79 -58
  490. package/dist/ws-responses.js.map +1 -1
  491. package/package.json +4 -1
  492. package/skills/write-fixtures/SKILL.md +57 -16
@@ -1,3 +1,5 @@
1
+ const require_errors = require('./response/errors.cjs');
2
+ const require_policy = require('./response/policy.cjs');
1
3
  const require_helpers = require('./helpers.cjs');
2
4
  const require_sse_writer = require('./sse-writer.cjs');
3
5
  const require_chaos = require('./chaos.cjs');
@@ -23,11 +25,11 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
23
25
  fixture: null
24
26
  }
25
27
  });
26
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
28
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
27
29
  message: `Malformed JSON: ${detail}`,
28
30
  type: "invalid_request_error",
29
31
  code: "invalid_json"
30
- } }));
32
+ }).body);
31
33
  return;
32
34
  }
33
35
  if (!require_helpers.isJsonObject(parsed)) {
@@ -41,10 +43,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
41
43
  fixture: null
42
44
  }
43
45
  });
44
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
46
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
45
47
  message: "Request body must be a JSON object",
46
48
  type: "invalid_request_error"
47
- } }));
49
+ }).body);
48
50
  return;
49
51
  }
50
52
  const promptText = typeof parsed.text === "string" && parsed.text ? parsed.text : void 0;
@@ -68,10 +70,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
68
70
  fixture: null
69
71
  }
70
72
  });
71
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
73
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
72
74
  message: "Missing required parameter: 'text'",
73
75
  type: "invalid_request_error"
74
- } }));
76
+ }).body);
75
77
  return;
76
78
  }
77
79
  const testId = require_helpers.getTestId(req);
@@ -84,7 +86,7 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
84
86
  body: syntheticReq
85
87
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
86
88
  if (!fixture) {
87
- if (require_helpers.resolveStrictMode(defaults.strict, req.headers)) {
89
+ if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
88
90
  const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
89
91
  defaults.logger.error(require_helpers.strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
90
92
  journal.add({
@@ -95,14 +97,14 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
95
97
  response: {
96
98
  status: 503,
97
99
  fixture: null,
98
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
100
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
99
101
  }
100
102
  });
101
- require_sse_writer.writeErrorResponse(res, 503, JSON.stringify({ error: {
103
+ require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError("openai", "strict-miss", {
102
104
  message: strictMessage,
103
105
  type: "invalid_request_error",
104
106
  code: "no_fixture_match"
105
- } }));
107
+ }).body);
106
108
  return;
107
109
  }
108
110
  if (defaults.record) {
@@ -131,14 +133,14 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
131
133
  response: {
132
134
  status: 404,
133
135
  fixture: null,
134
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
136
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
135
137
  }
136
138
  });
137
- require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
139
+ require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
138
140
  message: "No fixture matched",
139
141
  type: "invalid_request_error",
140
142
  code: "no_fixture_match"
141
- } }));
143
+ }).body);
142
144
  return;
143
145
  }
144
146
  const response = await require_helpers.resolveResponse(fixture, syntheticReq);
@@ -154,7 +156,7 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
154
156
  fixture
155
157
  }
156
158
  });
157
- require_sse_writer.writeErrorResponse(res, status, require_helpers.serializeErrorResponse(response), { retryAfter: response.retryAfter });
159
+ require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
158
160
  return;
159
161
  }
160
162
  if (!require_helpers.isAudioResponse(response)) {
@@ -168,10 +170,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
168
170
  fixture
169
171
  }
170
172
  });
171
- require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
173
+ require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
172
174
  message: "Fixture response is not an audio type",
173
175
  type: "server_error"
174
- } }));
176
+ }).body);
175
177
  return;
176
178
  }
177
179
  let audioBytes;
@@ -214,11 +216,11 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
214
216
  fixture: null
215
217
  }
216
218
  });
217
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
219
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
218
220
  message: `Malformed JSON: ${detail}`,
219
221
  type: "invalid_request_error",
220
222
  code: "invalid_json"
221
- } }));
223
+ }).body);
222
224
  return;
223
225
  }
224
226
  if (!require_helpers.isJsonObject(parsed)) {
@@ -232,10 +234,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
232
234
  fixture: null
233
235
  }
234
236
  });
235
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
237
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
236
238
  message: "Request body must be a JSON object",
237
239
  type: "invalid_request_error"
238
- } }));
240
+ }).body);
239
241
  return;
240
242
  }
241
243
  let promptText;
@@ -264,10 +266,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
264
266
  fixture: null
265
267
  }
266
268
  });
267
- require_sse_writer.writeErrorResponse(res, 400, JSON.stringify({ error: {
269
+ require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
268
270
  message: `Missing required parameter: '${field}'`,
269
271
  type: "invalid_request_error"
270
- } }));
272
+ }).body);
271
273
  return;
272
274
  }
273
275
  const testId = require_helpers.getTestId(req);
@@ -280,7 +282,7 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
280
282
  body: syntheticReq
281
283
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
282
284
  if (!fixture) {
283
- if (require_helpers.resolveStrictMode(defaults.strict, req.headers)) {
285
+ if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
284
286
  const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
285
287
  defaults.logger.error(require_helpers.strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
286
288
  journal.add({
@@ -291,14 +293,14 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
291
293
  response: {
292
294
  status: 503,
293
295
  fixture: null,
294
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
296
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
295
297
  }
296
298
  });
297
- require_sse_writer.writeErrorResponse(res, 503, JSON.stringify({ error: {
299
+ require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError("openai", "strict-miss", {
298
300
  message: strictMessage,
299
301
  type: "invalid_request_error",
300
302
  code: "no_fixture_match"
301
- } }));
303
+ }).body);
302
304
  return;
303
305
  }
304
306
  if (defaults.record) {
@@ -327,14 +329,14 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
327
329
  response: {
328
330
  status: 404,
329
331
  fixture: null,
330
- ...require_helpers.strictOverrideField(defaults.strict, req.headers)
332
+ ...require_policy.strictOverrideField(defaults.strict, req.headers)
331
333
  }
332
334
  });
333
- require_sse_writer.writeErrorResponse(res, 404, JSON.stringify({ error: {
335
+ require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
334
336
  message: "No fixture matched",
335
337
  type: "invalid_request_error",
336
338
  code: "no_fixture_match"
337
- } }));
339
+ }).body);
338
340
  return;
339
341
  }
340
342
  const response = await require_helpers.resolveResponse(fixture, syntheticReq);
@@ -350,7 +352,7 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
350
352
  fixture
351
353
  }
352
354
  });
353
- require_sse_writer.writeErrorResponse(res, status, require_helpers.serializeErrorResponse(response), { retryAfter: response.retryAfter });
355
+ require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
354
356
  return;
355
357
  }
356
358
  if (subType === "plan") {
@@ -365,10 +367,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
365
367
  fixture
366
368
  }
367
369
  });
368
- require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
370
+ require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
369
371
  message: "Fixture response is not a text type for plan endpoint",
370
372
  type: "server_error"
371
- } }));
373
+ }).body);
372
374
  return;
373
375
  }
374
376
  journal.add({
@@ -396,10 +398,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
396
398
  fixture
397
399
  }
398
400
  });
399
- require_sse_writer.writeErrorResponse(res, 500, JSON.stringify({ error: {
401
+ require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
400
402
  message: "Fixture response is not an audio type",
401
403
  type: "server_error"
402
- } }));
404
+ }).body);
403
405
  return;
404
406
  }
405
407
  let audioBytes;
@@ -1 +1 @@
1
- {"version":3,"file":"elevenlabs-audio.cjs","names":["flattenHeaders","isJsonObject","getContext","getTestId","matchFixtureDiagnostic","applyChaosAsync","resolveStrictMode","strictNoMatchMessage","strictNoMatchLogLine","strictOverrideField","proxyAndRecord","resolveResponse","isErrorResponse","serializeErrorResponse","isAudioResponse","FORMAT_TO_CONTENT_TYPE","isTextResponse"],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":["import type http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isAudioResponse,\n isTextResponse,\n isErrorResponse,\n isJsonObject,\n serializeErrorResponse,\n flattenHeaders,\n FORMAT_TO_CONTENT_TYPE,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaosAsync } from \"./chaos.js\";\n\nexport async function handleElevenLabsTTS(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n voiceId: string,\n): Promise<void> {\n const path = req.url ?? `/v1/text-to-speech/${voiceId}`;\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Extract text from request body\n const promptText = typeof parsed.text === \"string\" && parsed.text ? parsed.text : undefined;\n\n // Build synthetic ChatCompletionRequest for fixture matching\n const syntheticReq: ChatCompletionRequest = {\n model: (parsed.model_id as string) ?? \"eleven_multilingual_v2\",\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"elevenlabs-tts\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Missing required parameter: 'text'\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? `/v1/text-to-speech/${voiceId}`,\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // Expect audio response\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Standard binary response\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n\nexport async function handleElevenLabsAudio(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n subType: string, // \"sound-generation\" | \"music\" | \"stream\" | \"plan\"\n): Promise<void> {\n const path = req.url ?? \"/v1/sound-generation\";\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Extract prompt text based on subType\n let promptText: string | undefined;\n if (subType === \"sound-generation\") {\n if (typeof parsed.text === \"string\" && parsed.text) {\n promptText = parsed.text;\n }\n } else {\n // music, music-stream, music-plan all use \"prompt\" (or composition_plan fallback)\n if (typeof parsed.prompt === \"string\" && parsed.prompt) {\n promptText = parsed.prompt;\n } else if (parsed.composition_plan != null) {\n promptText =\n typeof parsed.composition_plan === \"string\"\n ? parsed.composition_plan\n : JSON.stringify(parsed.composition_plan);\n }\n }\n\n // Build synthetic ChatCompletionRequest for fixture matching (needed for journal even on validation failure)\n const syntheticReq: ChatCompletionRequest = {\n model:\n (parsed.model_id as string) ??\n (subType === \"sound-generation\" ? \"eleven_text_to_sound_v2\" : \"music_v1\"),\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"audio-gen\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n const field = subType === \"sound-generation\" ? \"text\" : \"prompt\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Missing required parameter: '${field}'`,\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? \"/v1/sound-generation\",\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // plan returns JSON text, not audio\n if (subType === \"plan\") {\n if (!isTextResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message: \"Fixture response is not a text type for plan endpoint\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(response.content);\n return;\n }\n\n // All other subTypes expect audio\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Music endpoints get a song-id header\n if (subType === \"music\" || subType === \"stream\") {\n res.setHeader(\"song-id\", \"mock-song-\" + Date.now());\n }\n\n // Stream uses chunked transfer encoding\n if (subType === \"stream\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Transfer-Encoding\": \"chunked\",\n });\n res.end(audioBytes);\n return;\n }\n\n // Standard binary response for sound-generation and music\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"elevenlabs-audio.cjs","names":["flattenHeaders","renderError","isJsonObject","getContext","getTestId","matchFixtureDiagnostic","applyChaosAsync","resolveRequestDecisions","strictNoMatchMessage","strictNoMatchLogLine","strictOverrideField","proxyAndRecord","resolveResponse","isErrorResponse","isAudioResponse","FORMAT_TO_CONTENT_TYPE","isTextResponse"],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":["import { renderError } from \"./response/errors.js\";\nimport { resolveRequestDecisions, strictOverrideField } from \"./response/policy.js\";\nimport type http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isAudioResponse,\n isTextResponse,\n isErrorResponse,\n isJsonObject,\n flattenHeaders,\n FORMAT_TO_CONTENT_TYPE,\n getContext,\n getTestId,\n resolveResponse,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaosAsync } from \"./chaos.js\";\n\nexport async function handleElevenLabsTTS(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n voiceId: string,\n): Promise<void> {\n const path = req.url ?? `/v1/text-to-speech/${voiceId}`;\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n }).body,\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Extract text from request body\n const promptText = typeof parsed.text === \"string\" && parsed.text ? parsed.text : undefined;\n\n // Build synthetic ChatCompletionRequest for fixture matching\n const syntheticReq: ChatCompletionRequest = {\n model: (parsed.model_id as string) ?? \"eleven_multilingual_v2\",\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"elevenlabs-tts\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Missing required parameter: 'text'\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss;\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n renderError(\"openai\", \"strict-miss\", {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? `/v1/text-to-speech/${voiceId}`,\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n renderError(\"openai\", \"fixture-miss\", {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, renderError(\"openai\", \"fixture\", response.error).body, {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // Expect audio response\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not an audio type\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Standard binary response\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n\nexport async function handleElevenLabsAudio(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n subType: string, // \"sound-generation\" | \"music\" | \"stream\" | \"plan\"\n): Promise<void> {\n const path = req.url ?? \"/v1/sound-generation\";\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n }).body,\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Extract prompt text based on subType\n let promptText: string | undefined;\n if (subType === \"sound-generation\") {\n if (typeof parsed.text === \"string\" && parsed.text) {\n promptText = parsed.text;\n }\n } else {\n // music, music-stream, music-plan all use \"prompt\" (or composition_plan fallback)\n if (typeof parsed.prompt === \"string\" && parsed.prompt) {\n promptText = parsed.prompt;\n } else if (parsed.composition_plan != null) {\n promptText =\n typeof parsed.composition_plan === \"string\"\n ? parsed.composition_plan\n : JSON.stringify(parsed.composition_plan);\n }\n }\n\n // Build synthetic ChatCompletionRequest for fixture matching (needed for journal even on validation failure)\n const syntheticReq: ChatCompletionRequest = {\n model:\n (parsed.model_id as string) ??\n (subType === \"sound-generation\" ? \"eleven_text_to_sound_v2\" : \"music_v1\"),\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"audio-gen\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n const field = subType === \"sound-generation\" ? \"text\" : \"prompt\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Missing required parameter: '${field}'`,\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss;\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n renderError(\"openai\", \"strict-miss\", {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? \"/v1/sound-generation\",\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n renderError(\"openai\", \"fixture-miss\", {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, renderError(\"openai\", \"fixture\", response.error).body, {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // plan returns JSON text, not audio\n if (subType === \"plan\") {\n if (!isTextResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not a text type for plan endpoint\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(response.content);\n return;\n }\n\n // All other subTypes expect audio\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not an audio type\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Music endpoints get a song-id header\n if (subType === \"music\" || subType === \"stream\") {\n res.setHeader(\"song-id\", \"mock-song-\" + Date.now());\n }\n\n // Stream uses chunked transfer encoding\n if (subType === \"stream\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Transfer-Encoding\": \"chunked\",\n });\n res.end(audioBytes);\n return;\n }\n\n // Standard binary response for sound-generation and music\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"elevenlabs-audio.d.cts","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":[],"mappings":";;;;;iBAmSsB,qBAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,wCAEA,qBACA,0BACD,2BAER;AARH"}
1
+ {"version":3,"file":"elevenlabs-audio.d.cts","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":[],"mappings":";;;;;iBAyRsB,qBAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,wCAEA,qBACA,0BACD,2BAER;AARH"}
@@ -1 +1 @@
1
- {"version":3,"file":"elevenlabs-audio.d.ts","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":[],"mappings":";;;;;iBAmSsB,qBAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,wCAEA,qBACA,0BACD,2BAER;AARH"}
1
+ {"version":3,"file":"elevenlabs-audio.d.ts","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":[],"mappings":";;;;;iBAyRsB,qBAAA,MACf,IAAA,CAAK,sBACL,IAAA,CAAK,wCAEA,qBACA,0BACD,2BAER;AARH"}
@@ -1,4 +1,6 @@
1
- import { FORMAT_TO_CONTENT_TYPE, flattenHeaders, getContext, getTestId, isAudioResponse, isErrorResponse, isJsonObject, isTextResponse, resolveResponse, resolveStrictMode, serializeErrorResponse, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
1
+ import { renderError } from "./response/errors.js";
2
+ import { resolveRequestDecisions, strictOverrideField } from "./response/policy.js";
3
+ import { FORMAT_TO_CONTENT_TYPE, flattenHeaders, getContext, getTestId, isAudioResponse, isErrorResponse, isJsonObject, isTextResponse, resolveResponse, strictNoMatchLogLine, strictNoMatchMessage } from "./helpers.js";
2
4
  import { writeErrorResponse } from "./sse-writer.js";
3
5
  import { applyChaosAsync } from "./chaos.js";
4
6
  import { matchFixtureDiagnostic } from "./router.js";
@@ -23,11 +25,11 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
23
25
  fixture: null
24
26
  }
25
27
  });
26
- writeErrorResponse(res, 400, JSON.stringify({ error: {
28
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
27
29
  message: `Malformed JSON: ${detail}`,
28
30
  type: "invalid_request_error",
29
31
  code: "invalid_json"
30
- } }));
32
+ }).body);
31
33
  return;
32
34
  }
33
35
  if (!isJsonObject(parsed)) {
@@ -41,10 +43,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
41
43
  fixture: null
42
44
  }
43
45
  });
44
- writeErrorResponse(res, 400, JSON.stringify({ error: {
46
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
45
47
  message: "Request body must be a JSON object",
46
48
  type: "invalid_request_error"
47
- } }));
49
+ }).body);
48
50
  return;
49
51
  }
50
52
  const promptText = typeof parsed.text === "string" && parsed.text ? parsed.text : void 0;
@@ -68,10 +70,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
68
70
  fixture: null
69
71
  }
70
72
  });
71
- writeErrorResponse(res, 400, JSON.stringify({ error: {
73
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
72
74
  message: "Missing required parameter: 'text'",
73
75
  type: "invalid_request_error"
74
- } }));
76
+ }).body);
75
77
  return;
76
78
  }
77
79
  const testId = getTestId(req);
@@ -84,7 +86,7 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
84
86
  body: syntheticReq
85
87
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
86
88
  if (!fixture) {
87
- if (resolveStrictMode(defaults.strict, req.headers)) {
89
+ if (resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
88
90
  const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);
89
91
  defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
90
92
  journal.add({
@@ -98,11 +100,11 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
98
100
  ...strictOverrideField(defaults.strict, req.headers)
99
101
  }
100
102
  });
101
- writeErrorResponse(res, 503, JSON.stringify({ error: {
103
+ writeErrorResponse(res, 503, renderError("openai", "strict-miss", {
102
104
  message: strictMessage,
103
105
  type: "invalid_request_error",
104
106
  code: "no_fixture_match"
105
- } }));
107
+ }).body);
106
108
  return;
107
109
  }
108
110
  if (defaults.record) {
@@ -134,11 +136,11 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
134
136
  ...strictOverrideField(defaults.strict, req.headers)
135
137
  }
136
138
  });
137
- writeErrorResponse(res, 404, JSON.stringify({ error: {
139
+ writeErrorResponse(res, 404, renderError("openai", "fixture-miss", {
138
140
  message: "No fixture matched",
139
141
  type: "invalid_request_error",
140
142
  code: "no_fixture_match"
141
- } }));
143
+ }).body);
142
144
  return;
143
145
  }
144
146
  const response = await resolveResponse(fixture, syntheticReq);
@@ -154,7 +156,7 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
154
156
  fixture
155
157
  }
156
158
  });
157
- writeErrorResponse(res, status, serializeErrorResponse(response), { retryAfter: response.retryAfter });
159
+ writeErrorResponse(res, status, renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
158
160
  return;
159
161
  }
160
162
  if (!isAudioResponse(response)) {
@@ -168,10 +170,10 @@ async function handleElevenLabsTTS(req, res, body, fixtures, defaults, journal,
168
170
  fixture
169
171
  }
170
172
  });
171
- writeErrorResponse(res, 500, JSON.stringify({ error: {
173
+ writeErrorResponse(res, 500, renderError("openai", "unknown-response", {
172
174
  message: "Fixture response is not an audio type",
173
175
  type: "server_error"
174
- } }));
176
+ }).body);
175
177
  return;
176
178
  }
177
179
  let audioBytes;
@@ -214,11 +216,11 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
214
216
  fixture: null
215
217
  }
216
218
  });
217
- writeErrorResponse(res, 400, JSON.stringify({ error: {
219
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
218
220
  message: `Malformed JSON: ${detail}`,
219
221
  type: "invalid_request_error",
220
222
  code: "invalid_json"
221
- } }));
223
+ }).body);
222
224
  return;
223
225
  }
224
226
  if (!isJsonObject(parsed)) {
@@ -232,10 +234,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
232
234
  fixture: null
233
235
  }
234
236
  });
235
- writeErrorResponse(res, 400, JSON.stringify({ error: {
237
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
236
238
  message: "Request body must be a JSON object",
237
239
  type: "invalid_request_error"
238
- } }));
240
+ }).body);
239
241
  return;
240
242
  }
241
243
  let promptText;
@@ -264,10 +266,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
264
266
  fixture: null
265
267
  }
266
268
  });
267
- writeErrorResponse(res, 400, JSON.stringify({ error: {
269
+ writeErrorResponse(res, 400, renderError("openai", "validation", {
268
270
  message: `Missing required parameter: '${field}'`,
269
271
  type: "invalid_request_error"
270
- } }));
272
+ }).body);
271
273
  return;
272
274
  }
273
275
  const testId = getTestId(req);
@@ -280,7 +282,7 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
280
282
  body: syntheticReq
281
283
  }, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
282
284
  if (!fixture) {
283
- if (resolveStrictMode(defaults.strict, req.headers)) {
285
+ if (resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
284
286
  const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);
285
287
  defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
286
288
  journal.add({
@@ -294,11 +296,11 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
294
296
  ...strictOverrideField(defaults.strict, req.headers)
295
297
  }
296
298
  });
297
- writeErrorResponse(res, 503, JSON.stringify({ error: {
299
+ writeErrorResponse(res, 503, renderError("openai", "strict-miss", {
298
300
  message: strictMessage,
299
301
  type: "invalid_request_error",
300
302
  code: "no_fixture_match"
301
- } }));
303
+ }).body);
302
304
  return;
303
305
  }
304
306
  if (defaults.record) {
@@ -330,11 +332,11 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
330
332
  ...strictOverrideField(defaults.strict, req.headers)
331
333
  }
332
334
  });
333
- writeErrorResponse(res, 404, JSON.stringify({ error: {
335
+ writeErrorResponse(res, 404, renderError("openai", "fixture-miss", {
334
336
  message: "No fixture matched",
335
337
  type: "invalid_request_error",
336
338
  code: "no_fixture_match"
337
- } }));
339
+ }).body);
338
340
  return;
339
341
  }
340
342
  const response = await resolveResponse(fixture, syntheticReq);
@@ -350,7 +352,7 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
350
352
  fixture
351
353
  }
352
354
  });
353
- writeErrorResponse(res, status, serializeErrorResponse(response), { retryAfter: response.retryAfter });
355
+ writeErrorResponse(res, status, renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
354
356
  return;
355
357
  }
356
358
  if (subType === "plan") {
@@ -365,10 +367,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
365
367
  fixture
366
368
  }
367
369
  });
368
- writeErrorResponse(res, 500, JSON.stringify({ error: {
370
+ writeErrorResponse(res, 500, renderError("openai", "unknown-response", {
369
371
  message: "Fixture response is not a text type for plan endpoint",
370
372
  type: "server_error"
371
- } }));
373
+ }).body);
372
374
  return;
373
375
  }
374
376
  journal.add({
@@ -396,10 +398,10 @@ async function handleElevenLabsAudio(req, res, body, fixtures, defaults, journal
396
398
  fixture
397
399
  }
398
400
  });
399
- writeErrorResponse(res, 500, JSON.stringify({ error: {
401
+ writeErrorResponse(res, 500, renderError("openai", "unknown-response", {
400
402
  message: "Fixture response is not an audio type",
401
403
  type: "server_error"
402
- } }));
404
+ }).body);
403
405
  return;
404
406
  }
405
407
  let audioBytes;