@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 +1 @@
1
- {"version":3,"file":"ws-live.js","names":[],"sources":["../src/ws-live.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport type { IncomingHttpHeaders } from \"node:http\";\nimport {\n flattenHeaders,\n isLiveResponse,\n resolveResponse,\n resolveStrictMode,\n strictNoMatchLogLine,\n strictNoMatchMessage,\n strictOverrideField,\n wouldProxyMiss,\n} from \"./helpers.js\";\nimport { normalizeLiveFixture, validateLiveClientEvent } from \"./live-fixture.js\";\nimport { createLiveRecorder, LiveRecorderError } from \"./live-recorder.js\";\nimport { applyProviderAuth } from \"./provider-auth.js\";\nimport { connectUpstreamWebSocket } from \"./ws-upstream.js\";\nimport { resolveUpstreamUrl } from \"./url.js\";\nimport {\n clampTimeout,\n DEFAULT_MAX_PROXY_BUFFER_BYTES,\n DEFAULT_MAX_PROXY_BUFFER_FRAMES,\n} from \"./recorder.js\";\nimport { createLiveReplay } from \"./live-replay.js\";\nimport type {\n LiveFailureCategory,\n LiveJson,\n LiveMode,\n LiveObject,\n LiveOptions,\n} from \"./live-types.js\";\nimport type { Journal } from \"./journal.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport type {\n ChatCompletionRequest,\n Fixture,\n FixtureResponse,\n HandlerDefaults,\n JournalEntry,\n} from \"./types.js\";\nimport type { WebSocketConnection } from \"./ws-framing.js\";\n\nexport interface LiveSessionOptions {\n defaults: HandlerDefaults;\n limits: Required<LiveOptions>;\n testId: string;\n headers: IncomingHttpHeaders;\n localApiKeys?: readonly string[];\n onDispose: () => void;\n}\nfunction object(value: LiveJson | undefined): LiveObject | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) ? value : undefined;\n}\n\n/** Node otherwise turns an overflowing delay into a one-millisecond timeout. */\nfunction scheduleLiveTimeout(callback: () => void, timeoutMs: number): () => void {\n const started = performance.now();\n const onTimeout = () => {\n const remaining = timeoutMs - (performance.now() - started);\n if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, 2_147_483_647));\n else callback();\n };\n let timer = setTimeout(onTimeout, Math.min(timeoutMs, 2_147_483_647));\n return () => clearTimeout(timer);\n}\n\n/** Diagnostic copies never retain executable members or mutate replay operands. */\nfunction liveJournalSnapshot(\n entry: Omit<JournalEntry, \"id\" | \"timestamp\">,\n secretValues: readonly string[],\n): Omit<JournalEntry, \"id\" | \"timestamp\"> {\n const secrets = secretValues.filter((secret) => secret.length > 0);\n if (!secrets.length) return entry;\n const containsSecret = (value: string) => secrets.some((secret) => value.includes(secret));\n // Whole-field redaction avoids creating another secret by joining substrings.\n const marker = containsSecret(\"[REDACTED]\") ? \"\" : \"[REDACTED]\";\n const redact = (value: string) => (containsSecret(value) ? marker : value);\n const ancestors = new Set<object>();\n const copy = (value: unknown): unknown => {\n if (typeof value === \"string\") return redact(value);\n if (typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n if (value === null || typeof value !== \"object\") return value;\n if (ancestors.has(value)) return undefined;\n ancestors.add(value);\n try {\n if (Array.isArray(value)) return value.map(copy);\n // Diagnostics contain data only; omit getters and non-JSON objects.\n if (\n Object.getPrototypeOf(value) !== Object.prototype &&\n Object.getPrototypeOf(value) !== null\n )\n return undefined;\n return Object.fromEntries(\n Object.entries(Object.getOwnPropertyDescriptors(value))\n .filter(([, descriptor]) => descriptor.enumerable && \"value\" in descriptor)\n .map(([key, descriptor]) => [redact(key), copy(descriptor.value)]),\n );\n } finally {\n ancestors.delete(value);\n }\n };\n // Preserve the journal schema; copied operands are diagnostics, never replay inputs.\n return {\n ...entry,\n headers: copy(entry.headers) as JournalEntry[\"headers\"],\n body: copy(entry.body) as JournalEntry[\"body\"],\n response: { ...entry.response, fixture: copy(entry.response.fixture) as Fixture | null },\n };\n}\n\n/** Owns a single transport, replay cursor and every cancellation deadline. */\nexport function handleLiveSession(\n ws: WebSocketConnection,\n fixtures: Fixture[],\n journal: Journal,\n options: LiveSessionOptions,\n): () => void {\n const { defaults, limits, testId } = options;\n // HTTP accepts positive finite milliseconds; the connector requires whole safe milliseconds.\n const normalizeRecordTimeout = (value: number | undefined) =>\n Math.min(Number.MAX_SAFE_INTEGER, Math.ceil(clampTimeout(value, 30_000)));\n const upstreamTimeoutMs = normalizeRecordTimeout(defaults.record?.upstreamTimeoutMs);\n const bodyTimeoutMs = normalizeRecordTimeout(defaults.record?.bodyTimeoutMs);\n const controller = new AbortController();\n let state: \"awaiting-start\" | \"active\" | \"closing\" | \"closed\" = \"awaiting-start\";\n let mode: LiveMode | undefined;\n let starting = false;\n const pending: LiveObject[] = [];\n let pendingBytes = 0;\n const maxPendingBytes = Math.min(\n limits.maxBufferedBytes,\n defaults.record?.maxProxyBufferBytes ?? DEFAULT_MAX_PROXY_BUFFER_BYTES,\n );\n const maxPendingFrames = defaults.record?.maxProxyBufferFrames ?? DEFAULT_MAX_PROXY_BUFFER_FRAMES;\n let upstream: WebSocketConnection | undefined;\n let recorder: ReturnType<typeof createLiveRecorder> | undefined;\n let recordingSecrets: string[] = [];\n let terminalReceived = false;\n let captureStarted: number | undefined;\n let recordingJournaled = false;\n let upstreamIdle: (() => void) | undefined;\n let replay: ReturnType<typeof createLiveReplay> | undefined;\n const deadline = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live session duration exceeded\"),\n limits.maxDurationMs,\n );\n const startup = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live startup deadline exceeded\"),\n defaults.record ? upstreamTimeoutMs : limits.idleTimeoutMs,\n );\n\n function recordJournal(category?: LiveFailureCategory) {\n if (recordingJournaled || !recorder) return;\n recordingJournaled = true;\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { \"x-test-id\": testId },\n body: { model: \"gpt-live-1\", messages: [] },\n response: {\n status: category ? 502 : 200,\n fixture: null,\n source: \"proxy\",\n ...strictOverrideField(defaults.strict, options.headers),\n ...(category ? { error: category } : {}),\n },\n },\n [...limits.secretValues, ...recordingSecrets],\n ),\n );\n }\n function cleanup() {\n if (state === \"closed\") return;\n state = \"closed\";\n deadline();\n startup();\n upstreamIdle?.();\n recordJournal(\"incomplete-capture\");\n recorder?.abort();\n upstream?.destroy();\n pending.length = 0;\n pendingBytes = 0;\n replay?.close();\n controller.abort();\n ws.removeListener(\"message\", receive);\n ws.removeListener(\"close\", cleanup);\n ws.removeListener(\"error\", cleanup);\n options.onDispose();\n }\n function dispose() {\n if (state === \"closed\") return;\n ws.close(1001, \"Live session disposed\");\n cleanup();\n }\n function fail(category: LiveFailureCategory, message: string) {\n if (state === \"closed\" || state === \"closing\") return;\n state = \"closing\";\n recorder?.abort(category);\n recordJournal(category);\n // The safe diagnostic contains no caller payload, fixture data or credential.\n ws.send(JSON.stringify({ type: \"aimock.error\", error: { category, message } }));\n ws.close(category === \"resource-limit\" ? 1009 : 1008, \"Live session failed\");\n cleanup();\n }\n function receive(data: string) {\n if (state === \"closed\" || state === \"closing\") return;\n let event: LiveObject;\n try {\n event = validateLiveClientEvent(JSON.parse(data), limits);\n } catch {\n fail(\"invalid-client\", \"Invalid Live client command\");\n return;\n }\n if (starting) {\n if (event.type === \"session.start\") {\n fail(\"invalid-client\", \"Live session has already started\");\n return;\n }\n const bytes = Buffer.byteLength(data);\n if (bytes > maxPendingBytes - pendingBytes || pending.length >= maxPendingFrames) {\n fail(\"resource-limit\", \"Live startup input queue exceeded\");\n return;\n }\n pendingBytes += bytes;\n pending.push(event);\n return;\n }\n accept(event);\n }\n function recordingError(error: unknown) {\n fail(\n error instanceof LiveRecorderError\n ? error.category\n : error instanceof Error && error.message === \"WebSocket write limit exceeded\"\n ? \"resource-limit\"\n : \"upstream-connect\",\n \"Live recording failed\",\n );\n }\n function touchUpstream() {\n upstreamIdle?.();\n upstreamIdle = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live upstream idle deadline exceeded\"),\n bodyTimeoutMs,\n );\n }\n function forward(event: LiveObject) {\n if (!upstream || !recorder || terminalReceived) return;\n try {\n const raw = JSON.stringify(event);\n const now = performance.now();\n captureStarted ??= now;\n recorder.acceptClient(raw, Math.floor(now - captureStarted));\n void upstream.sendAsync(raw, controller.signal).catch(recordingError);\n } catch (error) {\n recordingError(error);\n }\n }\n async function startRecording(first: LiveObject) {\n const record = defaults.record;\n if (!record?.providers.openai) {\n fail(\"fixture-mismatch\", \"No matching Live fixture\");\n return;\n }\n starting = true;\n try {\n const base = new URL(record.providers.openai);\n if (base.username || base.password || base.search || base.hash)\n throw new Error(\"Invalid URL\");\n base.pathname = base.pathname.replace(/\\/v1\\/?$/, \"/\");\n const target = resolveUpstreamUrl(base.href, \"/v1/live/sessions\");\n const headers: Record<string, string> = {};\n const incoming = options.headers.authorization;\n const credential = incoming?.match(/^\\s*(?:Bearer|Key)\\s+(.+)$/i)?.[1].trim();\n if (incoming && !options.localApiKeys?.includes(credential ?? \"\"))\n headers.Authorization = incoming;\n applyProviderAuth(headers, target, \"openai\", record.providerKeys?.openai);\n const selected = headers.Authorization?.replace(/^\\s*(?:Bearer|Key)\\s+/i, \"\").trim();\n recordingSecrets = [...(selected ? [selected] : []), ...(options.localApiKeys ?? [])];\n recorder = createLiveRecorder({\n record,\n fixtures,\n logger: defaults.logger,\n testId,\n live: limits,\n secretValues: recordingSecrets,\n provenance: {\n host: target.host,\n path: \"/v1/live/sessions\",\n observedAt: new Date().toISOString(),\n referenceVersion: \"gpt-live-1-observed-v3\",\n sanitationVersion: 1,\n },\n });\n upstream = await connectUpstreamWebSocket(\n target,\n headers,\n limits,\n controller.signal,\n upstreamTimeoutMs,\n );\n if (controller.signal.aborted) {\n upstream.destroy();\n return;\n }\n upstream.on(\"activity\", touchUpstream);\n upstream.on(\"message\", (raw: string) => {\n if (controller.signal.aborted) return;\n touchUpstream();\n try {\n // Capture at provider arrival, before downstream backpressure settles.\n recorder!.acceptServer(\n raw,\n captureStarted === undefined ? 0 : Math.floor(performance.now() - captureStarted),\n );\n const output: unknown = JSON.parse(raw);\n if (!output || typeof output !== \"object\" || !(\"type\" in output))\n throw new Error(\"Invalid event\");\n if (output.type === \"session.started\") {\n startup();\n starting = false;\n state = \"active\";\n const queued = pending.splice(0);\n pendingBytes = 0;\n for (const event of queued) {\n if (controller.signal.aborted) break;\n accept(event);\n }\n }\n const terminal = output.type === \"session.closed\";\n if (terminal) terminalReceived = true;\n void ws.sendAsync(raw, controller.signal).then(() => {\n if (!terminal || controller.signal.aborted) return;\n const result = recorder!.finish();\n if (result.kind === \"failed\") {\n fail(result.category, \"Live capture export failed\");\n return;\n }\n recordJournal();\n ws.close(1000, \"Live session complete\");\n cleanup();\n }, recordingError);\n } catch (error) {\n recordingError(error);\n }\n });\n upstream.on(\"error\", () => fail(\"upstream-connect\", \"Live upstream connection failed\"));\n upstream.on(\"close\", (code: number) => {\n if (!terminalReceived)\n fail(\n code === 1009 ? \"resource-limit\" : \"incomplete-capture\",\n \"Live upstream closed before completion\",\n );\n });\n touchUpstream();\n // Only startup is forwarded until the provider acknowledges the session.\n // The bounded queue retains commands that the caller pipelined meanwhile.\n forward(first);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"\";\n if (/HTTP 401/.test(message)) fail(\"upstream-auth\", \"Live upstream authentication refused\");\n else if (/HTTP (403|404|429)/.test(message))\n fail(\"upstream-access\", \"Live upstream access refused\");\n else recordingError(error);\n }\n }\n function startReplay(\n fixture: Fixture,\n request: ChatCompletionRequest,\n first: LiveObject,\n raw: FixtureResponse,\n ) {\n if (state === \"closed\" || state === \"closing\") return;\n try {\n if (!isLiveResponse(raw)) throw new Error(\"not a Live fixture\");\n const response = normalizeLiveFixture(raw, limits);\n replay = createLiveReplay(response.live, {\n limits,\n signal: controller.signal,\n timing: response.liveTiming ?? \"recorded\",\n replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n fail,\n send: async (output) => {\n await ws.sendAsync(JSON.stringify(output), controller.signal);\n if (output.type === \"session.closed\" && !controller.signal.aborted) {\n ws.close(1000, \"Live session complete\");\n cleanup();\n }\n },\n });\n } catch {\n fail(\"protocol-divergence\", \"Invalid Live replay configuration\");\n return;\n }\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { ...flattenHeaders(options.headers), \"x-test-id\": testId },\n body: request,\n response: { status: 200, fixture },\n },\n limits.secretValues,\n ),\n fixture,\n );\n startup();\n starting = false;\n state = \"active\";\n replay.accept(first);\n const queued = pending.splice(0);\n pendingBytes = 0;\n for (const event of queued) {\n if (controller.signal.aborted) break;\n accept(event);\n }\n }\n function accept(event: LiveObject) {\n if (state === \"closed\" || state === \"closing\") return;\n if (state === \"awaiting-start\") {\n const session = object(event.session);\n const audio = object(session?.audio);\n const format = object(audio?.format);\n const delegation = object(session?.delegation);\n if (\n event.type !== \"session.start\" ||\n session?.model !== \"gpt-live-1\" ||\n format?.type !== \"audio/pcm\" ||\n format.rate !== 24000 ||\n (delegation?.type !== \"client\" && delegation?.type !== \"responses\")\n ) {\n fail(\n \"invalid-client\",\n \"Live requires session.start with explicit model, PCM24 audio and delegation\",\n );\n return;\n }\n mode = delegation.type === \"client\" ? \"client\" : \"managed\";\n const request: ChatCompletionRequest = {\n model: session.model,\n messages: [],\n _endpointType: \"openai-live\",\n session: structuredClone(session),\n };\n let fixture: Fixture | null;\n let skippedBySequenceOrTurn: number;\n try {\n ({ fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n request,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n ));\n } catch {\n fail(\"protocol-divergence\", \"Live fixture selection failed\");\n return;\n }\n if (!fixture) {\n const strict = resolveStrictMode(defaults.strict, options.headers);\n if (strict) {\n const message = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(\n strictNoMatchLogLine(\"WS\", \"/v1/live/sessions\", skippedBySequenceOrTurn),\n );\n // A rejected startup is diagnostic only: retain test ownership, never\n // caller authorization or session content, and do not create a recorder.\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { \"x-test-id\": testId },\n body: { model: request.model, messages: [] },\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, options.headers),\n },\n },\n limits.secretValues,\n ),\n );\n fail(\"fixture-mismatch\", message);\n } else if (wouldProxyMiss(strict, defaults.record, \"openai\")) {\n void startRecording(event);\n } else {\n fail(\"fixture-mismatch\", \"No matching Live fixture\");\n }\n return;\n }\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n if (typeof fixture.response === \"function\") {\n starting = true;\n const selected = fixture;\n void resolveResponse(selected, request).then(\n (response) => startReplay(selected, request, event, response),\n () => fail(\"protocol-divergence\", \"Live response factory failed\"),\n );\n } else startReplay(fixture, request, event, fixture.response);\n return;\n } else if (event.type === \"session.start\") {\n fail(\"invalid-client\", \"Live session has already started\");\n return;\n }\n if (event.type === \"session.update\") {\n const patch = object(event.session);\n const delegation = object(patch?.delegation);\n const backend = object(delegation?.responses);\n if (\n mode !== \"managed\" ||\n !patch ||\n !delegation ||\n !backend ||\n Object.keys(patch).some((key) => key !== \"delegation\") ||\n Object.keys(delegation).some((key) => key !== \"type\" && key !== \"responses\") ||\n (delegation.type !== undefined && delegation.type !== \"responses\") ||\n Object.keys(backend).some((key) => key !== \"instructions\") ||\n !Object.hasOwn(backend, \"instructions\")\n ) {\n fail(\"invalid-client\", \"Only managed backend instructions can be updated\");\n return;\n }\n }\n // Input acceptance is synchronous; output pressure never serializes duplex input.\n if (upstream) forward(event);\n else replay?.accept(event);\n }\n ws.on(\"message\", receive);\n ws.on(\"close\", cleanup);\n ws.on(\"error\", cleanup);\n return dispose;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ws-live.js","names":[],"sources":["../src/ws-live.ts"],"sourcesContent":["import { performance } from \"node:perf_hooks\";\nimport type { IncomingHttpHeaders } from \"node:http\";\nimport { resolveRequestDecisions, strictOverrideField } from \"./response/policy.js\";\nimport {\n flattenHeaders,\n isLiveResponse,\n resolveResponse,\n strictNoMatchLogLine,\n strictNoMatchMessage,\n wouldProxyMiss,\n} from \"./helpers.js\";\nimport { normalizeLiveFixture, validateLiveClientEvent } from \"./live-fixture.js\";\nimport { createLiveRecorder, LiveRecorderError } from \"./live-recorder.js\";\nimport { applyProviderAuth } from \"./provider-auth.js\";\nimport { connectUpstreamWebSocket } from \"./ws-upstream.js\";\nimport { resolveUpstreamUrl } from \"./url.js\";\nimport {\n clampTimeout,\n DEFAULT_MAX_PROXY_BUFFER_BYTES,\n DEFAULT_MAX_PROXY_BUFFER_FRAMES,\n} from \"./recorder.js\";\nimport { createLiveReplay } from \"./live-replay.js\";\nimport type {\n LiveFailureCategory,\n LiveJson,\n LiveMode,\n LiveObject,\n LiveOptions,\n} from \"./live-types.js\";\nimport type { Journal } from \"./journal.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport type {\n ChatCompletionRequest,\n Fixture,\n FixtureResponse,\n HandlerDefaults,\n JournalEntry,\n} from \"./types.js\";\nimport type { WebSocketConnection } from \"./ws-framing.js\";\n\nexport interface LiveSessionOptions {\n defaults: HandlerDefaults;\n limits: Required<LiveOptions>;\n testId: string;\n headers: IncomingHttpHeaders;\n localApiKeys?: readonly string[];\n onDispose: () => void;\n}\nfunction object(value: LiveJson | undefined): LiveObject | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value) ? value : undefined;\n}\n\n/** Node otherwise turns an overflowing delay into a one-millisecond timeout. */\nfunction scheduleLiveTimeout(callback: () => void, timeoutMs: number): () => void {\n const started = performance.now();\n const onTimeout = () => {\n const remaining = timeoutMs - (performance.now() - started);\n if (remaining > 0) timer = setTimeout(onTimeout, Math.min(remaining, 2_147_483_647));\n else callback();\n };\n let timer = setTimeout(onTimeout, Math.min(timeoutMs, 2_147_483_647));\n return () => clearTimeout(timer);\n}\n\n/** Diagnostic copies never retain executable members or mutate replay operands. */\nfunction liveJournalSnapshot(\n entry: Omit<JournalEntry, \"id\" | \"timestamp\">,\n secretValues: readonly string[],\n): Omit<JournalEntry, \"id\" | \"timestamp\"> {\n const secrets = secretValues.filter((secret) => secret.length > 0);\n if (!secrets.length) return entry;\n const containsSecret = (value: string) => secrets.some((secret) => value.includes(secret));\n // Whole-field redaction avoids creating another secret by joining substrings.\n const marker = containsSecret(\"[REDACTED]\") ? \"\" : \"[REDACTED]\";\n const redact = (value: string) => (containsSecret(value) ? marker : value);\n const ancestors = new Set<object>();\n const copy = (value: unknown): unknown => {\n if (typeof value === \"string\") return redact(value);\n if (typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n if (value === null || typeof value !== \"object\") return value;\n if (ancestors.has(value)) return undefined;\n ancestors.add(value);\n try {\n if (Array.isArray(value)) return value.map(copy);\n // Diagnostics contain data only; omit getters and non-JSON objects.\n if (\n Object.getPrototypeOf(value) !== Object.prototype &&\n Object.getPrototypeOf(value) !== null\n )\n return undefined;\n return Object.fromEntries(\n Object.entries(Object.getOwnPropertyDescriptors(value))\n .filter(([, descriptor]) => descriptor.enumerable && \"value\" in descriptor)\n .map(([key, descriptor]) => [redact(key), copy(descriptor.value)]),\n );\n } finally {\n ancestors.delete(value);\n }\n };\n // Preserve the journal schema; copied operands are diagnostics, never replay inputs.\n return {\n ...entry,\n headers: copy(entry.headers) as JournalEntry[\"headers\"],\n body: copy(entry.body) as JournalEntry[\"body\"],\n response: { ...entry.response, fixture: copy(entry.response.fixture) as Fixture | null },\n };\n}\n\n/** Owns a single transport, replay cursor and every cancellation deadline. */\nexport function handleLiveSession(\n ws: WebSocketConnection,\n fixtures: Fixture[],\n journal: Journal,\n options: LiveSessionOptions,\n): () => void {\n const { defaults, limits, testId } = options;\n // HTTP accepts positive finite milliseconds; the connector requires whole safe milliseconds.\n const normalizeRecordTimeout = (value: number | undefined) =>\n Math.min(Number.MAX_SAFE_INTEGER, Math.ceil(clampTimeout(value, 30_000)));\n const upstreamTimeoutMs = normalizeRecordTimeout(defaults.record?.upstreamTimeoutMs);\n const bodyTimeoutMs = normalizeRecordTimeout(defaults.record?.bodyTimeoutMs);\n const controller = new AbortController();\n let state: \"awaiting-start\" | \"active\" | \"closing\" | \"closed\" = \"awaiting-start\";\n let mode: LiveMode | undefined;\n let starting = false;\n const pending: LiveObject[] = [];\n let pendingBytes = 0;\n const maxPendingBytes = Math.min(\n limits.maxBufferedBytes,\n defaults.record?.maxProxyBufferBytes ?? DEFAULT_MAX_PROXY_BUFFER_BYTES,\n );\n const maxPendingFrames = defaults.record?.maxProxyBufferFrames ?? DEFAULT_MAX_PROXY_BUFFER_FRAMES;\n let upstream: WebSocketConnection | undefined;\n let recorder: ReturnType<typeof createLiveRecorder> | undefined;\n let recordingSecrets: string[] = [];\n let terminalReceived = false;\n let captureStarted: number | undefined;\n let recordingJournaled = false;\n let upstreamIdle: (() => void) | undefined;\n let replay: ReturnType<typeof createLiveReplay> | undefined;\n const deadline = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live session duration exceeded\"),\n limits.maxDurationMs,\n );\n const startup = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live startup deadline exceeded\"),\n defaults.record ? upstreamTimeoutMs : limits.idleTimeoutMs,\n );\n\n function recordJournal(category?: LiveFailureCategory) {\n if (recordingJournaled || !recorder) return;\n recordingJournaled = true;\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { \"x-test-id\": testId },\n body: { model: \"gpt-live-1\", messages: [] },\n response: {\n status: category ? 502 : 200,\n fixture: null,\n source: \"proxy\",\n ...strictOverrideField(defaults.strict, options.headers),\n ...(category ? { error: category } : {}),\n },\n },\n [...limits.secretValues, ...recordingSecrets],\n ),\n );\n }\n function cleanup() {\n if (state === \"closed\") return;\n state = \"closed\";\n deadline();\n startup();\n upstreamIdle?.();\n recordJournal(\"incomplete-capture\");\n recorder?.abort();\n upstream?.destroy();\n pending.length = 0;\n pendingBytes = 0;\n replay?.close();\n controller.abort();\n ws.removeListener(\"message\", receive);\n ws.removeListener(\"close\", cleanup);\n ws.removeListener(\"error\", cleanup);\n options.onDispose();\n }\n function dispose() {\n if (state === \"closed\") return;\n ws.close(1001, \"Live session disposed\");\n cleanup();\n }\n function fail(category: LiveFailureCategory, message: string) {\n if (state === \"closed\" || state === \"closing\") return;\n state = \"closing\";\n recorder?.abort(category);\n recordJournal(category);\n // The safe diagnostic contains no caller payload, fixture data or credential.\n ws.send(JSON.stringify({ type: \"aimock.error\", error: { category, message } }));\n ws.close(category === \"resource-limit\" ? 1009 : 1008, \"Live session failed\");\n cleanup();\n }\n function receive(data: string) {\n if (state === \"closed\" || state === \"closing\") return;\n let event: LiveObject;\n try {\n event = validateLiveClientEvent(JSON.parse(data), limits);\n } catch {\n fail(\"invalid-client\", \"Invalid Live client command\");\n return;\n }\n if (starting) {\n if (event.type === \"session.start\") {\n fail(\"invalid-client\", \"Live session has already started\");\n return;\n }\n const bytes = Buffer.byteLength(data);\n if (bytes > maxPendingBytes - pendingBytes || pending.length >= maxPendingFrames) {\n fail(\"resource-limit\", \"Live startup input queue exceeded\");\n return;\n }\n pendingBytes += bytes;\n pending.push(event);\n return;\n }\n accept(event);\n }\n function recordingError(error: unknown) {\n fail(\n error instanceof LiveRecorderError\n ? error.category\n : error instanceof Error && error.message === \"WebSocket write limit exceeded\"\n ? \"resource-limit\"\n : \"upstream-connect\",\n \"Live recording failed\",\n );\n }\n function touchUpstream() {\n upstreamIdle?.();\n upstreamIdle = scheduleLiveTimeout(\n () => fail(\"timeout\", \"Live upstream idle deadline exceeded\"),\n bodyTimeoutMs,\n );\n }\n function forward(event: LiveObject) {\n if (!upstream || !recorder || terminalReceived) return;\n try {\n const raw = JSON.stringify(event);\n const now = performance.now();\n captureStarted ??= now;\n recorder.acceptClient(raw, Math.floor(now - captureStarted));\n void upstream.sendAsync(raw, controller.signal).catch(recordingError);\n } catch (error) {\n recordingError(error);\n }\n }\n async function startRecording(first: LiveObject) {\n const record = defaults.record;\n if (!record?.providers.openai) {\n fail(\"fixture-mismatch\", \"No matching Live fixture\");\n return;\n }\n starting = true;\n try {\n const base = new URL(record.providers.openai);\n if (base.username || base.password || base.search || base.hash)\n throw new Error(\"Invalid URL\");\n base.pathname = base.pathname.replace(/\\/v1\\/?$/, \"/\");\n const target = resolveUpstreamUrl(base.href, \"/v1/live/sessions\");\n const headers: Record<string, string> = {};\n const incoming = options.headers.authorization;\n const credential = incoming?.match(/^\\s*(?:Bearer|Key)\\s+(.+)$/i)?.[1].trim();\n if (incoming && !options.localApiKeys?.includes(credential ?? \"\"))\n headers.Authorization = incoming;\n applyProviderAuth(headers, target, \"openai\", record.providerKeys?.openai);\n const selected = headers.Authorization?.replace(/^\\s*(?:Bearer|Key)\\s+/i, \"\").trim();\n recordingSecrets = [...(selected ? [selected] : []), ...(options.localApiKeys ?? [])];\n recorder = createLiveRecorder({\n record,\n fixtures,\n logger: defaults.logger,\n testId,\n live: limits,\n secretValues: recordingSecrets,\n provenance: {\n host: target.host,\n path: \"/v1/live/sessions\",\n observedAt: new Date().toISOString(),\n referenceVersion: \"gpt-live-1-observed-v3\",\n sanitationVersion: 1,\n },\n });\n upstream = await connectUpstreamWebSocket(\n target,\n headers,\n limits,\n controller.signal,\n upstreamTimeoutMs,\n );\n if (controller.signal.aborted) {\n upstream.destroy();\n return;\n }\n upstream.on(\"activity\", touchUpstream);\n upstream.on(\"message\", (raw: string) => {\n if (controller.signal.aborted) return;\n touchUpstream();\n try {\n // Capture at provider arrival, before downstream backpressure settles.\n recorder!.acceptServer(\n raw,\n captureStarted === undefined ? 0 : Math.floor(performance.now() - captureStarted),\n );\n const output: unknown = JSON.parse(raw);\n if (!output || typeof output !== \"object\" || !(\"type\" in output))\n throw new Error(\"Invalid event\");\n if (output.type === \"session.started\") {\n startup();\n starting = false;\n state = \"active\";\n const queued = pending.splice(0);\n pendingBytes = 0;\n for (const event of queued) {\n if (controller.signal.aborted) break;\n accept(event);\n }\n }\n const terminal = output.type === \"session.closed\";\n if (terminal) terminalReceived = true;\n void ws.sendAsync(raw, controller.signal).then(() => {\n if (!terminal || controller.signal.aborted) return;\n const result = recorder!.finish();\n if (result.kind === \"failed\") {\n fail(result.category, \"Live capture export failed\");\n return;\n }\n recordJournal();\n ws.close(1000, \"Live session complete\");\n cleanup();\n }, recordingError);\n } catch (error) {\n recordingError(error);\n }\n });\n upstream.on(\"error\", () => fail(\"upstream-connect\", \"Live upstream connection failed\"));\n upstream.on(\"close\", (code: number) => {\n if (!terminalReceived)\n fail(\n code === 1009 ? \"resource-limit\" : \"incomplete-capture\",\n \"Live upstream closed before completion\",\n );\n });\n touchUpstream();\n // Only startup is forwarded until the provider acknowledges the session.\n // The bounded queue retains commands that the caller pipelined meanwhile.\n forward(first);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"\";\n if (/HTTP 401/.test(message)) fail(\"upstream-auth\", \"Live upstream authentication refused\");\n else if (/HTTP (403|404|429)/.test(message))\n fail(\"upstream-access\", \"Live upstream access refused\");\n else recordingError(error);\n }\n }\n function startReplay(\n fixture: Fixture,\n request: ChatCompletionRequest,\n first: LiveObject,\n raw: FixtureResponse,\n ) {\n if (state === \"closed\" || state === \"closing\") return;\n try {\n if (!isLiveResponse(raw)) throw new Error(\"not a Live fixture\");\n const response = normalizeLiveFixture(raw, limits);\n replay = createLiveReplay(response.live, {\n limits,\n signal: controller.signal,\n timing: response.liveTiming ?? \"recorded\",\n replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,\n fail,\n send: async (output) => {\n await ws.sendAsync(JSON.stringify(output), controller.signal);\n if (output.type === \"session.closed\" && !controller.signal.aborted) {\n ws.close(1000, \"Live session complete\");\n cleanup();\n }\n },\n });\n } catch {\n fail(\"protocol-divergence\", \"Invalid Live replay configuration\");\n return;\n }\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { ...flattenHeaders(options.headers), \"x-test-id\": testId },\n body: request,\n response: { status: 200, fixture },\n },\n limits.secretValues,\n ),\n fixture,\n );\n startup();\n starting = false;\n state = \"active\";\n replay.accept(first);\n const queued = pending.splice(0);\n pendingBytes = 0;\n for (const event of queued) {\n if (controller.signal.aborted) break;\n accept(event);\n }\n }\n function accept(event: LiveObject) {\n if (state === \"closed\" || state === \"closing\") return;\n if (state === \"awaiting-start\") {\n const session = object(event.session);\n const audio = object(session?.audio);\n const format = object(audio?.format);\n const delegation = object(session?.delegation);\n if (\n event.type !== \"session.start\" ||\n session?.model !== \"gpt-live-1\" ||\n format?.type !== \"audio/pcm\" ||\n format.rate !== 24000 ||\n (delegation?.type !== \"client\" && delegation?.type !== \"responses\")\n ) {\n fail(\n \"invalid-client\",\n \"Live requires session.start with explicit model, PCM24 audio and delegation\",\n );\n return;\n }\n mode = delegation.type === \"client\" ? \"client\" : \"managed\";\n const request: ChatCompletionRequest = {\n model: session.model,\n messages: [],\n _endpointType: \"openai-live\",\n session: structuredClone(session),\n };\n let fixture: Fixture | null;\n let skippedBySequenceOrTurn: number;\n try {\n ({ fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n request,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n ));\n } catch {\n fail(\"protocol-divergence\", \"Live fixture selection failed\");\n return;\n }\n if (!fixture) {\n const decisions = resolveRequestDecisions(defaults.strict, options.headers);\n if (decisions.fixtureMiss) {\n const message = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(\n strictNoMatchLogLine(\"WS\", \"/v1/live/sessions\", skippedBySequenceOrTurn),\n );\n // A rejected startup is diagnostic only: retain test ownership, never\n // caller authorization or session content, and do not create a recorder.\n journal.add(\n liveJournalSnapshot(\n {\n method: \"WS\",\n path: \"/v1/live/sessions\",\n headers: { \"x-test-id\": testId },\n body: { model: request.model, messages: [] },\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, options.headers),\n },\n },\n limits.secretValues,\n ),\n );\n fail(\"fixture-mismatch\", message);\n } else if (wouldProxyMiss(!decisions.upstream, defaults.record, \"openai\")) {\n void startRecording(event);\n } else {\n fail(\"fixture-mismatch\", \"No matching Live fixture\");\n }\n return;\n }\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n if (typeof fixture.response === \"function\") {\n starting = true;\n const selected = fixture;\n void resolveResponse(selected, request).then(\n (response) => startReplay(selected, request, event, response),\n () => fail(\"protocol-divergence\", \"Live response factory failed\"),\n );\n } else startReplay(fixture, request, event, fixture.response);\n return;\n } else if (event.type === \"session.start\") {\n fail(\"invalid-client\", \"Live session has already started\");\n return;\n }\n if (event.type === \"session.update\") {\n const patch = object(event.session);\n const delegation = object(patch?.delegation);\n const backend = object(delegation?.responses);\n if (\n mode !== \"managed\" ||\n !patch ||\n !delegation ||\n !backend ||\n Object.keys(patch).some((key) => key !== \"delegation\") ||\n Object.keys(delegation).some((key) => key !== \"type\" && key !== \"responses\") ||\n (delegation.type !== undefined && delegation.type !== \"responses\") ||\n Object.keys(backend).some((key) => key !== \"instructions\") ||\n !Object.hasOwn(backend, \"instructions\")\n ) {\n fail(\"invalid-client\", \"Only managed backend instructions can be updated\");\n return;\n }\n }\n // Input acceptance is synchronous; output pressure never serializes duplex input.\n if (upstream) forward(event);\n else replay?.accept(event);\n }\n ws.on(\"message\", receive);\n ws.on(\"close\", cleanup);\n ws.on(\"error\", cleanup);\n return dispose;\n}\n"],"mappings":";;;;;;;;;;;;;AAgDA,SAAS,OAAO,OAAqD;AACnE,QAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG,QAAQ;;;AAIxF,SAAS,oBAAoB,UAAsB,WAA+B;CAChF,MAAM,UAAU,YAAY,KAAK;CACjC,MAAM,kBAAkB;EACtB,MAAM,YAAY,aAAa,YAAY,KAAK,GAAG;AACnD,MAAI,YAAY,EAAG,SAAQ,WAAW,WAAW,KAAK,IAAI,WAAW,WAAc,CAAC;MAC/E,WAAU;;CAEjB,IAAI,QAAQ,WAAW,WAAW,KAAK,IAAI,WAAW,WAAc,CAAC;AACrE,cAAa,aAAa,MAAM;;;AAIlC,SAAS,oBACP,OACA,cACwC;CACxC,MAAM,UAAU,aAAa,QAAQ,WAAW,OAAO,SAAS,EAAE;AAClE,KAAI,CAAC,QAAQ,OAAQ,QAAO;CAC5B,MAAM,kBAAkB,UAAkB,QAAQ,MAAM,WAAW,MAAM,SAAS,OAAO,CAAC;CAE1F,MAAM,SAAS,eAAe,aAAa,GAAG,KAAK;CACnD,MAAM,UAAU,UAAmB,eAAe,MAAM,GAAG,SAAS;CACpE,MAAM,4BAAY,IAAI,KAAa;CACnC,MAAM,QAAQ,UAA4B;AACxC,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,MAAM;AACnD,MAAI,OAAO,UAAU,cAAc,OAAO,UAAU,SAAU,QAAO;AACrE,MAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,MAAI,UAAU,IAAI,MAAM,CAAE,QAAO;AACjC,YAAU,IAAI,MAAM;AACpB,MAAI;AACF,OAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,MAAM,IAAI,KAAK;AAEhD,OACE,OAAO,eAAe,MAAM,KAAK,OAAO,aACxC,OAAO,eAAe,MAAM,KAAK,KAEjC,QAAO;AACT,UAAO,OAAO,YACZ,OAAO,QAAQ,OAAO,0BAA0B,MAAM,CAAC,CACpD,QAAQ,GAAG,gBAAgB,WAAW,cAAc,WAAW,WAAW,CAC1E,KAAK,CAAC,KAAK,gBAAgB,CAAC,OAAO,IAAI,EAAE,KAAK,WAAW,MAAM,CAAC,CAAC,CACrE;YACO;AACR,aAAU,OAAO,MAAM;;;AAI3B,QAAO;EACL,GAAG;EACH,SAAS,KAAK,MAAM,QAAQ;EAC5B,MAAM,KAAK,MAAM,KAAK;EACtB,UAAU;GAAE,GAAG,MAAM;GAAU,SAAS,KAAK,MAAM,SAAS,QAAQ;GAAoB;EACzF;;;AAIH,SAAgB,kBACd,IACA,UACA,SACA,SACY;CACZ,MAAM,EAAE,UAAU,QAAQ,WAAW;CAErC,MAAM,0BAA0B,UAC9B,KAAK,IAAI,OAAO,kBAAkB,KAAK,KAAK,aAAa,OAAO,IAAO,CAAC,CAAC;CAC3E,MAAM,oBAAoB,uBAAuB,SAAS,QAAQ,kBAAkB;CACpF,MAAM,gBAAgB,uBAAuB,SAAS,QAAQ,cAAc;CAC5E,MAAM,aAAa,IAAI,iBAAiB;CACxC,IAAI,QAA4D;CAChE,IAAI;CACJ,IAAI,WAAW;CACf,MAAM,UAAwB,EAAE;CAChC,IAAI,eAAe;CACnB,MAAM,kBAAkB,KAAK,IAC3B,OAAO,kBACP,SAAS,QAAQ,uBAAuB,+BACzC;CACD,MAAM,mBAAmB,SAAS,QAAQ,wBAAwB;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI,mBAA6B,EAAE;CACnC,IAAI,mBAAmB;CACvB,IAAI;CACJ,IAAI,qBAAqB;CACzB,IAAI;CACJ,IAAI;CACJ,MAAM,WAAW,0BACT,KAAK,WAAW,iCAAiC,EACvD,OAAO,cACR;CACD,MAAM,UAAU,0BACR,KAAK,WAAW,iCAAiC,EACvD,SAAS,SAAS,oBAAoB,OAAO,cAC9C;CAED,SAAS,cAAc,UAAgC;AACrD,MAAI,sBAAsB,CAAC,SAAU;AACrC,uBAAqB;AACrB,UAAQ,IACN,oBACE;GACE,QAAQ;GACR,MAAM;GACN,SAAS,EAAE,aAAa,QAAQ;GAChC,MAAM;IAAE,OAAO;IAAc,UAAU,EAAE;IAAE;GAC3C,UAAU;IACR,QAAQ,WAAW,MAAM;IACzB,SAAS;IACT,QAAQ;IACR,GAAG,oBAAoB,SAAS,QAAQ,QAAQ,QAAQ;IACxD,GAAI,WAAW,EAAE,OAAO,UAAU,GAAG,EAAE;IACxC;GACF,EACD,CAAC,GAAG,OAAO,cAAc,GAAG,iBAAiB,CAC9C,CACF;;CAEH,SAAS,UAAU;AACjB,MAAI,UAAU,SAAU;AACxB,UAAQ;AACR,YAAU;AACV,WAAS;AACT,kBAAgB;AAChB,gBAAc,qBAAqB;AACnC,YAAU,OAAO;AACjB,YAAU,SAAS;AACnB,UAAQ,SAAS;AACjB,iBAAe;AACf,UAAQ,OAAO;AACf,aAAW,OAAO;AAClB,KAAG,eAAe,WAAW,QAAQ;AACrC,KAAG,eAAe,SAAS,QAAQ;AACnC,KAAG,eAAe,SAAS,QAAQ;AACnC,UAAQ,WAAW;;CAErB,SAAS,UAAU;AACjB,MAAI,UAAU,SAAU;AACxB,KAAG,MAAM,MAAM,wBAAwB;AACvC,WAAS;;CAEX,SAAS,KAAK,UAA+B,SAAiB;AAC5D,MAAI,UAAU,YAAY,UAAU,UAAW;AAC/C,UAAQ;AACR,YAAU,MAAM,SAAS;AACzB,gBAAc,SAAS;AAEvB,KAAG,KAAK,KAAK,UAAU;GAAE,MAAM;GAAgB,OAAO;IAAE;IAAU;IAAS;GAAE,CAAC,CAAC;AAC/E,KAAG,MAAM,aAAa,mBAAmB,OAAO,MAAM,sBAAsB;AAC5E,WAAS;;CAEX,SAAS,QAAQ,MAAc;AAC7B,MAAI,UAAU,YAAY,UAAU,UAAW;EAC/C,IAAI;AACJ,MAAI;AACF,WAAQ,wBAAwB,KAAK,MAAM,KAAK,EAAE,OAAO;UACnD;AACN,QAAK,kBAAkB,8BAA8B;AACrD;;AAEF,MAAI,UAAU;AACZ,OAAI,MAAM,SAAS,iBAAiB;AAClC,SAAK,kBAAkB,mCAAmC;AAC1D;;GAEF,MAAM,QAAQ,OAAO,WAAW,KAAK;AACrC,OAAI,QAAQ,kBAAkB,gBAAgB,QAAQ,UAAU,kBAAkB;AAChF,SAAK,kBAAkB,oCAAoC;AAC3D;;AAEF,mBAAgB;AAChB,WAAQ,KAAK,MAAM;AACnB;;AAEF,SAAO,MAAM;;CAEf,SAAS,eAAe,OAAgB;AACtC,OACE,iBAAiB,oBACb,MAAM,WACN,iBAAiB,SAAS,MAAM,YAAY,mCAC1C,mBACA,oBACN,wBACD;;CAEH,SAAS,gBAAgB;AACvB,kBAAgB;AAChB,iBAAe,0BACP,KAAK,WAAW,uCAAuC,EAC7D,cACD;;CAEH,SAAS,QAAQ,OAAmB;AAClC,MAAI,CAAC,YAAY,CAAC,YAAY,iBAAkB;AAChD,MAAI;GACF,MAAM,MAAM,KAAK,UAAU,MAAM;GACjC,MAAM,MAAM,YAAY,KAAK;AAC7B,sBAAmB;AACnB,YAAS,aAAa,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAC5D,GAAK,SAAS,UAAU,KAAK,WAAW,OAAO,CAAC,MAAM,eAAe;WAC9D,OAAO;AACd,kBAAe,MAAM;;;CAGzB,eAAe,eAAe,OAAmB;EAC/C,MAAM,SAAS,SAAS;AACxB,MAAI,CAAC,QAAQ,UAAU,QAAQ;AAC7B,QAAK,oBAAoB,2BAA2B;AACpD;;AAEF,aAAW;AACX,MAAI;GACF,MAAM,OAAO,IAAI,IAAI,OAAO,UAAU,OAAO;AAC7C,OAAI,KAAK,YAAY,KAAK,YAAY,KAAK,UAAU,KAAK,KACxD,OAAM,IAAI,MAAM,cAAc;AAChC,QAAK,WAAW,KAAK,SAAS,QAAQ,YAAY,IAAI;GACtD,MAAM,SAAS,mBAAmB,KAAK,MAAM,oBAAoB;GACjE,MAAM,UAAkC,EAAE;GAC1C,MAAM,WAAW,QAAQ,QAAQ;GACjC,MAAM,aAAa,UAAU,MAAM,8BAA8B,GAAG,GAAG,MAAM;AAC7E,OAAI,YAAY,CAAC,QAAQ,cAAc,SAAS,cAAc,GAAG,CAC/D,SAAQ,gBAAgB;AAC1B,qBAAkB,SAAS,QAAQ,UAAU,OAAO,cAAc,OAAO;GACzE,MAAM,WAAW,QAAQ,eAAe,QAAQ,0BAA0B,GAAG,CAAC,MAAM;AACpF,sBAAmB,CAAC,GAAI,WAAW,CAAC,SAAS,GAAG,EAAE,EAAG,GAAI,QAAQ,gBAAgB,EAAE,CAAE;AACrF,cAAW,mBAAmB;IAC5B;IACA;IACA,QAAQ,SAAS;IACjB;IACA,MAAM;IACN,cAAc;IACd,YAAY;KACV,MAAM,OAAO;KACb,MAAM;KACN,6BAAY,IAAI,MAAM,EAAC,aAAa;KACpC,kBAAkB;KAClB,mBAAmB;KACpB;IACF,CAAC;AACF,cAAW,MAAM,yBACf,QACA,SACA,QACA,WAAW,QACX,kBACD;AACD,OAAI,WAAW,OAAO,SAAS;AAC7B,aAAS,SAAS;AAClB;;AAEF,YAAS,GAAG,YAAY,cAAc;AACtC,YAAS,GAAG,YAAY,QAAgB;AACtC,QAAI,WAAW,OAAO,QAAS;AAC/B,mBAAe;AACf,QAAI;AAEF,cAAU,aACR,KACA,mBAAmB,SAAY,IAAI,KAAK,MAAM,YAAY,KAAK,GAAG,eAAe,CAClF;KACD,MAAM,SAAkB,KAAK,MAAM,IAAI;AACvC,SAAI,CAAC,UAAU,OAAO,WAAW,YAAY,EAAE,UAAU,QACvD,OAAM,IAAI,MAAM,gBAAgB;AAClC,SAAI,OAAO,SAAS,mBAAmB;AACrC,eAAS;AACT,iBAAW;AACX,cAAQ;MACR,MAAM,SAAS,QAAQ,OAAO,EAAE;AAChC,qBAAe;AACf,WAAK,MAAM,SAAS,QAAQ;AAC1B,WAAI,WAAW,OAAO,QAAS;AAC/B,cAAO,MAAM;;;KAGjB,MAAM,WAAW,OAAO,SAAS;AACjC,SAAI,SAAU,oBAAmB;AACjC,KAAK,GAAG,UAAU,KAAK,WAAW,OAAO,CAAC,WAAW;AACnD,UAAI,CAAC,YAAY,WAAW,OAAO,QAAS;MAC5C,MAAM,SAAS,SAAU,QAAQ;AACjC,UAAI,OAAO,SAAS,UAAU;AAC5B,YAAK,OAAO,UAAU,6BAA6B;AACnD;;AAEF,qBAAe;AACf,SAAG,MAAM,KAAM,wBAAwB;AACvC,eAAS;QACR,eAAe;aACX,OAAO;AACd,oBAAe,MAAM;;KAEvB;AACF,YAAS,GAAG,eAAe,KAAK,oBAAoB,kCAAkC,CAAC;AACvF,YAAS,GAAG,UAAU,SAAiB;AACrC,QAAI,CAAC,iBACH,MACE,SAAS,OAAO,mBAAmB,sBACnC,yCACD;KACH;AACF,kBAAe;AAGf,WAAQ,MAAM;WACP,OAAO;GACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,OAAI,WAAW,KAAK,QAAQ,CAAE,MAAK,iBAAiB,uCAAuC;YAClF,qBAAqB,KAAK,QAAQ,CACzC,MAAK,mBAAmB,+BAA+B;OACpD,gBAAe,MAAM;;;CAG9B,SAAS,YACP,SACA,SACA,OACA,KACA;AACA,MAAI,UAAU,YAAY,UAAU,UAAW;AAC/C,MAAI;AACF,OAAI,CAAC,eAAe,IAAI,CAAE,OAAM,IAAI,MAAM,qBAAqB;GAC/D,MAAM,WAAW,qBAAqB,KAAK,OAAO;AAClD,YAAS,iBAAiB,SAAS,MAAM;IACvC;IACA,QAAQ,WAAW;IACnB,QAAQ,SAAS,cAAc;IAC/B,aAAa,QAAQ,eAAe,SAAS;IAC7C;IACA,MAAM,OAAO,WAAW;AACtB,WAAM,GAAG,UAAU,KAAK,UAAU,OAAO,EAAE,WAAW,OAAO;AAC7D,SAAI,OAAO,SAAS,oBAAoB,CAAC,WAAW,OAAO,SAAS;AAClE,SAAG,MAAM,KAAM,wBAAwB;AACvC,eAAS;;;IAGd,CAAC;UACI;AACN,QAAK,uBAAuB,oCAAoC;AAChE;;AAEF,UAAQ,IACN,oBACE;GACE,QAAQ;GACR,MAAM;GACN,SAAS;IAAE,GAAG,eAAe,QAAQ,QAAQ;IAAE,aAAa;IAAQ;GACpE,MAAM;GACN,UAAU;IAAE,QAAQ;IAAK;IAAS;GACnC,EACD,OAAO,aACR,EACD,QACD;AACD,WAAS;AACT,aAAW;AACX,UAAQ;AACR,SAAO,OAAO,MAAM;EACpB,MAAM,SAAS,QAAQ,OAAO,EAAE;AAChC,iBAAe;AACf,OAAK,MAAM,SAAS,QAAQ;AAC1B,OAAI,WAAW,OAAO,QAAS;AAC/B,UAAO,MAAM;;;CAGjB,SAAS,OAAO,OAAmB;AACjC,MAAI,UAAU,YAAY,UAAU,UAAW;AAC/C,MAAI,UAAU,kBAAkB;GAC9B,MAAM,UAAU,OAAO,MAAM,QAAQ;GAErC,MAAM,SAAS,OADD,OAAO,SAAS,MAAM,EACP,OAAO;GACpC,MAAM,aAAa,OAAO,SAAS,WAAW;AAC9C,OACE,MAAM,SAAS,mBACf,SAAS,UAAU,gBACnB,QAAQ,SAAS,eACjB,OAAO,SAAS,QACf,YAAY,SAAS,YAAY,YAAY,SAAS,aACvD;AACA,SACE,kBACA,8EACD;AACD;;AAEF,UAAO,WAAW,SAAS,WAAW,WAAW;GACjD,MAAM,UAAiC;IACrC,OAAO,QAAQ;IACf,UAAU,EAAE;IACZ,eAAe;IACf,SAAS,gBAAgB,QAAQ;IAClC;GACD,IAAI;GACJ,IAAI;AACJ,OAAI;AACF,KAAC,CAAE,SAAS,2BAA4B,uBACtC,UACA,SACA,QAAQ,6BAA6B,OAAO,EAC5C,SAAS,iBACV;WACK;AACN,SAAK,uBAAuB,gCAAgC;AAC5D;;AAEF,OAAI,CAAC,SAAS;IACZ,MAAM,YAAY,wBAAwB,SAAS,QAAQ,QAAQ,QAAQ;AAC3E,QAAI,UAAU,aAAa;KACzB,MAAM,UAAU,qBAAqB,wBAAwB;AAC7D,cAAS,OAAO,MACd,qBAAqB,MAAM,qBAAqB,wBAAwB,CACzE;AAGD,aAAQ,IACN,oBACE;MACE,QAAQ;MACR,MAAM;MACN,SAAS,EAAE,aAAa,QAAQ;MAChC,MAAM;OAAE,OAAO,QAAQ;OAAO,UAAU,EAAE;OAAE;MAC5C,UAAU;OACR,QAAQ;OACR,SAAS;OACT,GAAG,oBAAoB,SAAS,QAAQ,QAAQ,QAAQ;OACzD;MACF,EACD,OAAO,aACR,CACF;AACD,UAAK,oBAAoB,QAAQ;eACxB,eAAe,CAAC,UAAU,UAAU,SAAS,QAAQ,SAAS,CACvE,CAAK,eAAe,MAAM;QAE1B,MAAK,oBAAoB,2BAA2B;AAEtD;;AAEF,WAAQ,2BAA2B,SAAS,UAAU,OAAO;AAC7D,OAAI,OAAO,QAAQ,aAAa,YAAY;AAC1C,eAAW;IACX,MAAM,WAAW;AACjB,IAAK,gBAAgB,UAAU,QAAQ,CAAC,MACrC,aAAa,YAAY,UAAU,SAAS,OAAO,SAAS,QACvD,KAAK,uBAAuB,+BAA+B,CAClE;SACI,aAAY,SAAS,SAAS,OAAO,QAAQ,SAAS;AAC7D;aACS,MAAM,SAAS,iBAAiB;AACzC,QAAK,kBAAkB,mCAAmC;AAC1D;;AAEF,MAAI,MAAM,SAAS,kBAAkB;GACnC,MAAM,QAAQ,OAAO,MAAM,QAAQ;GACnC,MAAM,aAAa,OAAO,OAAO,WAAW;GAC5C,MAAM,UAAU,OAAO,YAAY,UAAU;AAC7C,OACE,SAAS,aACT,CAAC,SACD,CAAC,cACD,CAAC,WACD,OAAO,KAAK,MAAM,CAAC,MAAM,QAAQ,QAAQ,aAAa,IACtD,OAAO,KAAK,WAAW,CAAC,MAAM,QAAQ,QAAQ,UAAU,QAAQ,YAAY,IAC3E,WAAW,SAAS,UAAa,WAAW,SAAS,eACtD,OAAO,KAAK,QAAQ,CAAC,MAAM,QAAQ,QAAQ,eAAe,IAC1D,CAAC,OAAO,OAAO,SAAS,eAAe,EACvC;AACA,SAAK,kBAAkB,mDAAmD;AAC1E;;;AAIJ,MAAI,SAAU,SAAQ,MAAM;MACvB,SAAQ,OAAO,MAAM;;AAE5B,IAAG,GAAG,WAAW,QAAQ;AACzB,IAAG,GAAG,SAAS,QAAQ;AACvB,IAAG,GAAG,SAAS,QAAQ;AACvB,QAAO"}