@copilotkit/aimock 1.45.0 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/README.md +7 -1
  5. package/dist/agui-mock.cjs +25 -25
  6. package/dist/agui-mock.cjs.map +1 -1
  7. package/dist/agui-mock.d.cts.map +1 -1
  8. package/dist/agui-mock.d.ts.map +1 -1
  9. package/dist/agui-mock.js +25 -25
  10. package/dist/agui-mock.js.map +1 -1
  11. package/dist/agui-types.d.ts.map +1 -1
  12. package/dist/aimock-cli.cjs +15 -1
  13. package/dist/aimock-cli.cjs.map +1 -1
  14. package/dist/aimock-cli.d.cts.map +1 -1
  15. package/dist/aimock-cli.d.ts.map +1 -1
  16. package/dist/aimock-cli.js +16 -2
  17. package/dist/aimock-cli.js.map +1 -1
  18. package/dist/api-key-auth.cjs +10 -9
  19. package/dist/api-key-auth.cjs.map +1 -1
  20. package/dist/api-key-auth.d.cts.map +1 -1
  21. package/dist/api-key-auth.d.ts.map +1 -1
  22. package/dist/api-key-auth.js +11 -10
  23. package/dist/api-key-auth.js.map +1 -1
  24. package/dist/batches.cjs +2 -4
  25. package/dist/batches.cjs.map +1 -1
  26. package/dist/batches.d.cts.map +1 -1
  27. package/dist/batches.d.ts.map +1 -1
  28. package/dist/batches.js +2 -4
  29. package/dist/batches.js.map +1 -1
  30. package/dist/bedrock-converse.cjs +61 -80
  31. package/dist/bedrock-converse.cjs.map +1 -1
  32. package/dist/bedrock-converse.d.cts.map +1 -1
  33. package/dist/bedrock-converse.d.ts.map +1 -1
  34. package/dist/bedrock-converse.js +58 -77
  35. package/dist/bedrock-converse.js.map +1 -1
  36. package/dist/bedrock.cjs +65 -97
  37. package/dist/bedrock.cjs.map +1 -1
  38. package/dist/bedrock.d.cts.map +1 -1
  39. package/dist/bedrock.d.ts.map +1 -1
  40. package/dist/bedrock.js +62 -94
  41. package/dist/bedrock.js.map +1 -1
  42. package/dist/byteplus-video.cjs +11 -10
  43. package/dist/byteplus-video.cjs.map +1 -1
  44. package/dist/byteplus-video.d.cts.map +1 -1
  45. package/dist/byteplus-video.d.ts.map +1 -1
  46. package/dist/byteplus-video.js +5 -4
  47. package/dist/byteplus-video.js.map +1 -1
  48. package/dist/chaos.cjs +5 -4
  49. package/dist/chaos.cjs.map +1 -1
  50. package/dist/chaos.d.cts.map +1 -1
  51. package/dist/chaos.d.ts.map +1 -1
  52. package/dist/chaos.js +5 -4
  53. package/dist/chaos.js.map +1 -1
  54. package/dist/cli.cjs +15 -0
  55. package/dist/cli.cjs.map +1 -1
  56. package/dist/cli.js +15 -0
  57. package/dist/cli.js.map +1 -1
  58. package/dist/cohere.cjs +49 -74
  59. package/dist/cohere.cjs.map +1 -1
  60. package/dist/cohere.d.cts.map +1 -1
  61. package/dist/cohere.d.ts.map +1 -1
  62. package/dist/cohere.js +47 -72
  63. package/dist/cohere.js.map +1 -1
  64. package/dist/config-loader.cjs +29 -1
  65. package/dist/config-loader.cjs.map +1 -1
  66. package/dist/config-loader.d.cts +7 -1
  67. package/dist/config-loader.d.cts.map +1 -1
  68. package/dist/config-loader.d.ts +7 -1
  69. package/dist/config-loader.d.ts.map +1 -1
  70. package/dist/config-loader.js +29 -2
  71. package/dist/config-loader.js.map +1 -1
  72. package/dist/count-tokens.cjs +146 -0
  73. package/dist/count-tokens.cjs.map +1 -0
  74. package/dist/count-tokens.js +146 -0
  75. package/dist/count-tokens.js.map +1 -0
  76. package/dist/elevenlabs-audio.cjs +36 -34
  77. package/dist/elevenlabs-audio.cjs.map +1 -1
  78. package/dist/elevenlabs-audio.d.cts.map +1 -1
  79. package/dist/elevenlabs-audio.d.ts.map +1 -1
  80. package/dist/elevenlabs-audio.js +33 -31
  81. package/dist/elevenlabs-audio.js.map +1 -1
  82. package/dist/elevenlabs-voice.cjs +38 -37
  83. package/dist/elevenlabs-voice.cjs.map +1 -1
  84. package/dist/elevenlabs-voice.d.cts.map +1 -1
  85. package/dist/elevenlabs-voice.d.ts.map +1 -1
  86. package/dist/elevenlabs-voice.js +33 -32
  87. package/dist/elevenlabs-voice.js.map +1 -1
  88. package/dist/embedding-request.cjs +16 -0
  89. package/dist/embedding-request.cjs.map +1 -0
  90. package/dist/embedding-request.js +14 -0
  91. package/dist/embedding-request.js.map +1 -0
  92. package/dist/embeddings.cjs +30 -20
  93. package/dist/embeddings.cjs.map +1 -1
  94. package/dist/embeddings.d.cts.map +1 -1
  95. package/dist/embeddings.d.ts.map +1 -1
  96. package/dist/embeddings.js +30 -20
  97. package/dist/embeddings.js.map +1 -1
  98. package/dist/fal-audio.cjs +45 -43
  99. package/dist/fal-audio.cjs.map +1 -1
  100. package/dist/fal-audio.d.cts.map +1 -1
  101. package/dist/fal-audio.d.ts.map +1 -1
  102. package/dist/fal-audio.js +42 -40
  103. package/dist/fal-audio.js.map +1 -1
  104. package/dist/fal.cjs +17 -15
  105. package/dist/fal.cjs.map +1 -1
  106. package/dist/fal.js +16 -14
  107. package/dist/fal.js.map +1 -1
  108. package/dist/files.cjs +2 -4
  109. package/dist/files.cjs.map +1 -1
  110. package/dist/files.d.cts.map +1 -1
  111. package/dist/files.d.ts.map +1 -1
  112. package/dist/files.js +2 -4
  113. package/dist/files.js.map +1 -1
  114. package/dist/fine-tuning.cjs +2 -4
  115. package/dist/fine-tuning.cjs.map +1 -1
  116. package/dist/fine-tuning.d.cts.map +1 -1
  117. package/dist/fine-tuning.d.ts.map +1 -1
  118. package/dist/fine-tuning.js +2 -4
  119. package/dist/fine-tuning.js.map +1 -1
  120. package/dist/fixture-loader.cjs +37 -42
  121. package/dist/fixture-loader.cjs.map +1 -1
  122. package/dist/fixture-loader.d.cts.map +1 -1
  123. package/dist/fixture-loader.d.ts.map +1 -1
  124. package/dist/fixture-loader.js +37 -42
  125. package/dist/fixture-loader.js.map +1 -1
  126. package/dist/gemini-embeddings.cjs +26 -24
  127. package/dist/gemini-embeddings.cjs.map +1 -1
  128. package/dist/gemini-embeddings.js +26 -24
  129. package/dist/gemini-embeddings.js.map +1 -1
  130. package/dist/gemini-interactions.cjs +50 -35
  131. package/dist/gemini-interactions.cjs.map +1 -1
  132. package/dist/gemini-interactions.d.cts +0 -1
  133. package/dist/gemini-interactions.d.cts.map +1 -1
  134. package/dist/gemini-interactions.d.ts +0 -1
  135. package/dist/gemini-interactions.d.ts.map +1 -1
  136. package/dist/gemini-interactions.js +49 -34
  137. package/dist/gemini-interactions.js.map +1 -1
  138. package/dist/gemini.cjs +57 -67
  139. package/dist/gemini.cjs.map +1 -1
  140. package/dist/gemini.d.cts.map +1 -1
  141. package/dist/gemini.d.ts.map +1 -1
  142. package/dist/gemini.js +56 -67
  143. package/dist/gemini.js.map +1 -1
  144. package/dist/grok-video.cjs +14 -12
  145. package/dist/grok-video.cjs.map +1 -1
  146. package/dist/grok-video.d.cts.map +1 -1
  147. package/dist/grok-video.d.ts.map +1 -1
  148. package/dist/grok-video.js +8 -6
  149. package/dist/grok-video.js.map +1 -1
  150. package/dist/helpers.cjs +11 -68
  151. package/dist/helpers.cjs.map +1 -1
  152. package/dist/helpers.d.cts.map +1 -1
  153. package/dist/helpers.d.ts.map +1 -1
  154. package/dist/helpers.js +12 -67
  155. package/dist/helpers.js.map +1 -1
  156. package/dist/images.cjs +30 -28
  157. package/dist/images.cjs.map +1 -1
  158. package/dist/images.d.cts.map +1 -1
  159. package/dist/images.d.ts.map +1 -1
  160. package/dist/images.js +27 -25
  161. package/dist/images.js.map +1 -1
  162. package/dist/index.d.cts +2 -2
  163. package/dist/index.d.ts +2 -2
  164. package/dist/journal.cjs +3 -1
  165. package/dist/journal.cjs.map +1 -1
  166. package/dist/journal.d.cts.map +1 -1
  167. package/dist/journal.d.ts.map +1 -1
  168. package/dist/journal.js +2 -1
  169. package/dist/journal.js.map +1 -1
  170. package/dist/llmock.cjs +3 -0
  171. package/dist/llmock.cjs.map +1 -1
  172. package/dist/llmock.d.cts.map +1 -1
  173. package/dist/llmock.d.ts.map +1 -1
  174. package/dist/llmock.js +3 -0
  175. package/dist/llmock.js.map +1 -1
  176. package/dist/mcp-fakes.d.cts.map +1 -1
  177. package/dist/mcp-handler.cjs +14 -4
  178. package/dist/mcp-handler.cjs.map +1 -1
  179. package/dist/mcp-handler.js +14 -4
  180. package/dist/mcp-handler.js.map +1 -1
  181. package/dist/mcp-recorder.cjs +2 -1
  182. package/dist/mcp-recorder.cjs.map +1 -1
  183. package/dist/mcp-recorder.js +3 -2
  184. package/dist/mcp-recorder.js.map +1 -1
  185. package/dist/messages.cjs +111 -96
  186. package/dist/messages.cjs.map +1 -1
  187. package/dist/messages.d.cts.map +1 -1
  188. package/dist/messages.d.ts.map +1 -1
  189. package/dist/messages.js +109 -95
  190. package/dist/messages.js.map +1 -1
  191. package/dist/metrics.cjs +5 -2
  192. package/dist/metrics.cjs.map +1 -1
  193. package/dist/metrics.d.cts.map +1 -1
  194. package/dist/metrics.d.ts.map +1 -1
  195. package/dist/metrics.js +6 -3
  196. package/dist/metrics.js.map +1 -1
  197. package/dist/model-utils.cjs +1 -0
  198. package/dist/model-utils.cjs.map +1 -1
  199. package/dist/model-utils.js +1 -1
  200. package/dist/model-utils.js.map +1 -1
  201. package/dist/moderation.cjs +15 -12
  202. package/dist/moderation.cjs.map +1 -1
  203. package/dist/moderation.js +14 -11
  204. package/dist/moderation.js.map +1 -1
  205. package/dist/ollama.cjs +128 -68
  206. package/dist/ollama.cjs.map +1 -1
  207. package/dist/ollama.d.cts.map +1 -1
  208. package/dist/ollama.d.ts.map +1 -1
  209. package/dist/ollama.js +124 -64
  210. package/dist/ollama.js.map +1 -1
  211. package/dist/openapi.cjs +323 -3
  212. package/dist/openapi.cjs.map +1 -1
  213. package/dist/openapi.d.cts.map +1 -1
  214. package/dist/openapi.d.ts.map +1 -1
  215. package/dist/openapi.js +324 -4
  216. package/dist/openapi.js.map +1 -1
  217. package/dist/openrouter-chat.cjs +11 -155
  218. package/dist/openrouter-chat.cjs.map +1 -1
  219. package/dist/openrouter-chat.js +11 -155
  220. package/dist/openrouter-chat.js.map +1 -1
  221. package/dist/openrouter-video.cjs +76 -71
  222. package/dist/openrouter-video.cjs.map +1 -1
  223. package/dist/openrouter-video.d.cts.map +1 -1
  224. package/dist/openrouter-video.d.ts.map +1 -1
  225. package/dist/openrouter-video.js +63 -58
  226. package/dist/openrouter-video.js.map +1 -1
  227. package/dist/recorder.cjs +176 -95
  228. package/dist/recorder.cjs.map +1 -1
  229. package/dist/recorder.d.cts.map +1 -1
  230. package/dist/recorder.d.ts.map +1 -1
  231. package/dist/recorder.js +176 -95
  232. package/dist/recorder.js.map +1 -1
  233. package/dist/rerank.cjs +13 -11
  234. package/dist/rerank.cjs.map +1 -1
  235. package/dist/rerank.js +12 -10
  236. package/dist/rerank.js.map +1 -1
  237. package/dist/response/catalog/anthropic-page.cjs +39 -0
  238. package/dist/response/catalog/anthropic-page.cjs.map +1 -0
  239. package/dist/response/catalog/anthropic-page.js +38 -0
  240. package/dist/response/catalog/anthropic-page.js.map +1 -0
  241. package/dist/response/catalog/collect.cjs +61 -0
  242. package/dist/response/catalog/collect.cjs.map +1 -0
  243. package/dist/response/catalog/collect.js +59 -0
  244. package/dist/response/catalog/collect.js.map +1 -0
  245. package/dist/response/catalog/gemini-page.cjs +25 -0
  246. package/dist/response/catalog/gemini-page.cjs.map +1 -0
  247. package/dist/response/catalog/gemini-page.js +24 -0
  248. package/dist/response/catalog/gemini-page.js.map +1 -0
  249. package/dist/response/catalog/render.cjs +182 -0
  250. package/dist/response/catalog/render.cjs.map +1 -0
  251. package/dist/response/catalog/render.js +171 -0
  252. package/dist/response/catalog/render.js.map +1 -0
  253. package/dist/response/errors.cjs +225 -0
  254. package/dist/response/errors.cjs.map +1 -0
  255. package/dist/response/errors.js +224 -0
  256. package/dist/response/errors.js.map +1 -0
  257. package/dist/response/finish.cjs +39 -0
  258. package/dist/response/finish.cjs.map +1 -0
  259. package/dist/response/finish.js +35 -0
  260. package/dist/response/finish.js.map +1 -0
  261. package/dist/response/policy.cjs +126 -0
  262. package/dist/response/policy.cjs.map +1 -0
  263. package/dist/response/policy.js +120 -0
  264. package/dist/response/policy.js.map +1 -0
  265. package/dist/response/profiles.cjs +69 -0
  266. package/dist/response/profiles.cjs.map +1 -0
  267. package/dist/response/profiles.js +65 -0
  268. package/dist/response/profiles.js.map +1 -0
  269. package/dist/response/usage/codecs/anthropic.cjs +52 -0
  270. package/dist/response/usage/codecs/anthropic.cjs.map +1 -0
  271. package/dist/response/usage/codecs/anthropic.js +50 -0
  272. package/dist/response/usage/codecs/anthropic.js.map +1 -0
  273. package/dist/response/usage/codecs/cohere.cjs +36 -0
  274. package/dist/response/usage/codecs/cohere.cjs.map +1 -0
  275. package/dist/response/usage/codecs/cohere.js +35 -0
  276. package/dist/response/usage/codecs/cohere.js.map +1 -0
  277. package/dist/response/usage/codecs/converse.cjs +16 -0
  278. package/dist/response/usage/codecs/converse.cjs.map +1 -0
  279. package/dist/response/usage/codecs/converse.js +15 -0
  280. package/dist/response/usage/codecs/converse.js.map +1 -0
  281. package/dist/response/usage/codecs/gemini.cjs +31 -0
  282. package/dist/response/usage/codecs/gemini.cjs.map +1 -0
  283. package/dist/response/usage/codecs/gemini.js +31 -0
  284. package/dist/response/usage/codecs/gemini.js.map +1 -0
  285. package/dist/response/usage/codecs/interactions.cjs +22 -0
  286. package/dist/response/usage/codecs/interactions.cjs.map +1 -0
  287. package/dist/response/usage/codecs/interactions.js +21 -0
  288. package/dist/response/usage/codecs/interactions.js.map +1 -0
  289. package/dist/response/usage/codecs/ollama.cjs +17 -0
  290. package/dist/response/usage/codecs/ollama.cjs.map +1 -0
  291. package/dist/response/usage/codecs/ollama.js +17 -0
  292. package/dist/response/usage/codecs/ollama.js.map +1 -0
  293. package/dist/response/usage/codecs/openai.cjs +52 -0
  294. package/dist/response/usage/codecs/openai.cjs.map +1 -0
  295. package/dist/response/usage/codecs/openai.js +50 -0
  296. package/dist/response/usage/codecs/openai.js.map +1 -0
  297. package/dist/response/usage/codecs/openrouter.cjs +68 -0
  298. package/dist/response/usage/codecs/openrouter.cjs.map +1 -0
  299. package/dist/response/usage/codecs/openrouter.js +67 -0
  300. package/dist/response/usage/codecs/openrouter.js.map +1 -0
  301. package/dist/response/usage/codecs/realtime.cjs +19 -0
  302. package/dist/response/usage/codecs/realtime.cjs.map +1 -0
  303. package/dist/response/usage/codecs/realtime.js +18 -0
  304. package/dist/response/usage/codecs/realtime.js.map +1 -0
  305. package/dist/response/usage/codecs/responses.cjs +21 -0
  306. package/dist/response/usage/codecs/responses.cjs.map +1 -0
  307. package/dist/response/usage/codecs/responses.js +20 -0
  308. package/dist/response/usage/codecs/responses.js.map +1 -0
  309. package/dist/response/usage/estimate.cjs +23 -0
  310. package/dist/response/usage/estimate.cjs.map +1 -0
  311. package/dist/response/usage/estimate.js +21 -0
  312. package/dist/response/usage/estimate.js.map +1 -0
  313. package/dist/response/usage/fields.cjs +72 -0
  314. package/dist/response/usage/fields.cjs.map +1 -0
  315. package/dist/response/usage/fields.js +70 -0
  316. package/dist/response/usage/fields.js.map +1 -0
  317. package/dist/response/usage/recording.cjs +52 -0
  318. package/dist/response/usage/recording.cjs.map +1 -0
  319. package/dist/response/usage/recording.js +52 -0
  320. package/dist/response/usage/recording.js.map +1 -0
  321. package/dist/responses.cjs +45 -58
  322. package/dist/responses.cjs.map +1 -1
  323. package/dist/responses.d.cts.map +1 -1
  324. package/dist/responses.d.ts.map +1 -1
  325. package/dist/responses.js +44 -57
  326. package/dist/responses.js.map +1 -1
  327. package/dist/route-registry.cjs +45 -0
  328. package/dist/route-registry.cjs.map +1 -1
  329. package/dist/route-registry.d.cts.map +1 -1
  330. package/dist/route-registry.d.ts.map +1 -1
  331. package/dist/route-registry.js +41 -1
  332. package/dist/route-registry.js.map +1 -1
  333. package/dist/router.cjs +4 -0
  334. package/dist/router.cjs.map +1 -1
  335. package/dist/router.d.cts.map +1 -1
  336. package/dist/router.d.ts.map +1 -1
  337. package/dist/router.js +3 -0
  338. package/dist/router.js.map +1 -1
  339. package/dist/search.cjs +13 -11
  340. package/dist/search.cjs.map +1 -1
  341. package/dist/search.js +12 -10
  342. package/dist/search.js.map +1 -1
  343. package/dist/server.cjs +222 -146
  344. package/dist/server.cjs.map +1 -1
  345. package/dist/server.d.cts.map +1 -1
  346. package/dist/server.d.ts.map +1 -1
  347. package/dist/server.js +223 -147
  348. package/dist/server.js.map +1 -1
  349. package/dist/speech.cjs +20 -18
  350. package/dist/speech.cjs.map +1 -1
  351. package/dist/speech.d.cts.map +1 -1
  352. package/dist/speech.d.ts.map +1 -1
  353. package/dist/speech.js +19 -17
  354. package/dist/speech.js.map +1 -1
  355. package/dist/sse-writer.cjs +7 -0
  356. package/dist/sse-writer.cjs.map +1 -1
  357. package/dist/sse-writer.d.cts.map +1 -1
  358. package/dist/sse-writer.d.ts.map +1 -1
  359. package/dist/sse-writer.js +7 -1
  360. package/dist/sse-writer.js.map +1 -1
  361. package/dist/stream-collapse.cjs +118 -11
  362. package/dist/stream-collapse.cjs.map +1 -1
  363. package/dist/stream-collapse.d.cts +10 -9
  364. package/dist/stream-collapse.d.cts.map +1 -1
  365. package/dist/stream-collapse.d.ts +10 -9
  366. package/dist/stream-collapse.d.ts.map +1 -1
  367. package/dist/stream-collapse.js +118 -11
  368. package/dist/stream-collapse.js.map +1 -1
  369. package/dist/transcription.cjs +12 -10
  370. package/dist/transcription.cjs.map +1 -1
  371. package/dist/transcription.d.cts.map +1 -1
  372. package/dist/transcription.d.ts.map +1 -1
  373. package/dist/transcription.js +11 -9
  374. package/dist/transcription.js.map +1 -1
  375. package/dist/types.cjs.map +1 -1
  376. package/dist/types.d.cts +62 -3
  377. package/dist/types.d.cts.map +1 -1
  378. package/dist/types.d.ts +62 -3
  379. package/dist/types.d.ts.map +1 -1
  380. package/dist/types.js.map +1 -1
  381. package/dist/vector-mock.cjs +3 -8
  382. package/dist/vector-mock.cjs.map +1 -1
  383. package/dist/vector-mock.d.cts.map +1 -1
  384. package/dist/vector-mock.d.ts.map +1 -1
  385. package/dist/vector-mock.js +3 -8
  386. package/dist/vector-mock.js.map +1 -1
  387. package/dist/vector-stores.cjs +2 -4
  388. package/dist/vector-stores.cjs.map +1 -1
  389. package/dist/vector-stores.d.cts.map +1 -1
  390. package/dist/vector-stores.d.ts.map +1 -1
  391. package/dist/vector-stores.js +2 -4
  392. package/dist/vector-stores.js.map +1 -1
  393. package/dist/veo-video.cjs +16 -14
  394. package/dist/veo-video.cjs.map +1 -1
  395. package/dist/veo-video.js +10 -8
  396. package/dist/veo-video.js.map +1 -1
  397. package/dist/video.cjs +21 -19
  398. package/dist/video.cjs.map +1 -1
  399. package/dist/video.d.cts.map +1 -1
  400. package/dist/video.d.ts.map +1 -1
  401. package/dist/video.js +20 -18
  402. package/dist/video.js.map +1 -1
  403. package/dist/ws-gemini-live.cjs +11 -3
  404. package/dist/ws-gemini-live.cjs.map +1 -1
  405. package/dist/ws-gemini-live.d.cts +0 -1
  406. package/dist/ws-gemini-live.d.cts.map +1 -1
  407. package/dist/ws-gemini-live.d.ts +0 -1
  408. package/dist/ws-gemini-live.d.ts.map +1 -1
  409. package/dist/ws-gemini-live.js +10 -2
  410. package/dist/ws-gemini-live.js.map +1 -1
  411. package/dist/ws-live.cjs +6 -5
  412. package/dist/ws-live.cjs.map +1 -1
  413. package/dist/ws-live.js +5 -4
  414. package/dist/ws-live.js.map +1 -1
  415. package/dist/ws-realtime.cjs +28 -54
  416. package/dist/ws-realtime.cjs.map +1 -1
  417. package/dist/ws-realtime.d.cts.map +1 -1
  418. package/dist/ws-realtime.d.ts.map +1 -1
  419. package/dist/ws-realtime.js +25 -51
  420. package/dist/ws-realtime.js.map +1 -1
  421. package/dist/ws-responses.cjs +8 -6
  422. package/dist/ws-responses.cjs.map +1 -1
  423. package/dist/ws-responses.js +7 -5
  424. package/dist/ws-responses.js.map +1 -1
  425. package/package.json +4 -1
  426. package/skills/write-fixtures/SKILL.md +25 -16
@@ -9,7 +9,7 @@
9
9
  "source": {
10
10
  "source": "npm",
11
11
  "package": "@copilotkit/aimock",
12
- "version": "^1.45.0"
12
+ "version": "^1.46.0"
13
13
  },
14
14
  "description": "Fixture authoring skill for @copilotkit/aimock — LLM, multimedia (image/TTS/transcription/video), MCP, A2A, AG-UI, vector, embeddings, structured output, sequential responses, streaming physics, record/replay, agent loop patterns, and debugging"
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimock",
3
- "version": "1.45.0",
3
+ "version": "1.46.0",
4
4
  "description": "Fixture authoring guidance for @copilotkit/aimock — LLM, multimedia, MCP, A2A, AG-UI, vector, and service mocking",
5
5
  "author": {
6
6
  "name": "CopilotKit"
package/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.46.0] - 2026-10-20
6
+
7
+ ### Added
8
+
9
+ - Gemini model list/detail, Anthropic model detail, and token-count routes (#542, #551)
10
+ - Opt-in policies: `requiredHeaders`, native `authErrors`, native `modelCatalog` (#542, #566, #568)
11
+ - Opt-in fixture `nonStreamingTiming: true` delays non-streaming OpenAI chat replies (#545, #567)
12
+ - Anthropic/Bedrock cache usage kept in replay and record; Responses `phase` override (#531, #542)
13
+
14
+ ### Fixed
15
+
16
+ - Ollama embed batches, AG-UI thread/run IDs, empty MCP reads, Anthropic aborts (#533, #553, #557)
17
+
18
+ ## [1.45.1] - 2026-10-11
19
+
20
+ ### Changed
21
+
22
+ - OpenRouter Video: `openai/sora-2` now returns OpenRouter's 400 removal error, not a job (#520)
23
+
24
+ ### Fixed
25
+
26
+ - MCP `tools/list`: a tool registered without `inputSchema` now lists `{"type":"object"}` (#529)
27
+ - MCP `tools/list`: a registered `inputSchema` with no `type` now gets `"type": "object"` (#529)
28
+
5
29
  ## [1.45.0] - 2026-10-10
6
30
 
7
31
  Every fixture, config and request that 1.44.0 accepted behaves the same by default. New behavior that would change those inputs is opt-in.
package/README.md CHANGED
@@ -72,7 +72,9 @@ Run them all on one port with `npx @copilotkit/aimock --config aimock.json`, or
72
72
  - **Timing-aware recording and replay** — Recorded fixtures capture per-frame arrival timestamps; replay uses recorded timings for approximate timing reproduction based on recorded TTFT and inter-frame cadence (replay chunk count may differ from recording — TTFT and average pace are preserved, not per-token fidelity) with configurable `--replay-speed` multiplier
73
73
  - **[Recorded token usage and cost](https://aimock.copilotkit.dev/record-replay)** — Recording captures the final usage frame of a streaming completion, so replayed fixtures serve real `prompt_tokens` / `completion_tokens` instead of a length estimate; OpenRouter's provider-reported `usage.cost` and its `cost_details` / `*_tokens_details` breakdowns are captured too, so an app that bills from real provider cost can e2e-test its wallet path from a tape
74
74
  - **[Multi-turn Conversations](https://aimock.copilotkit.dev/multi-turn)** — Record and replay multi-turn traces with tool rounds; match distinct turns via `turnIndex`, `hasToolResult`, `toolCallId`, `toolResultContains` (gate on the tool-result payload), `sequenceIndex`, `systemMessage` (gate on host-supplied agent context), or custom predicates
75
+ - **[Ollama embedding recordings](https://aimock.copilotkit.dev/ollama)** — Current `/api/embed` captures retain input shape, dimensions and model in their match and stay separate from legacy/OpenAI embedding operations.
75
76
  - **[11 providers across 22 API surfaces](https://aimock.copilotkit.dev/docs)** — OpenAI Chat, OpenAI Responses, OpenAI Realtime (GA; an `OpenAI-Beta: realtime=v1` request gets the real sunset rejection), GPT-Live, Claude, Gemini REST, Gemini embedContent, Gemini Live, Gemini Interactions, Azure, Bedrock, Vertex AI, Ollama (chat + embeddings), Cohere (chat + embed), OpenRouter (chat + router failover), BytePlus Ark (OpenAI-compatible chat + images under `/api/v3`), ElevenLabs TTS and Voice Design — full streaming support
77
+ Bedrock with the current AWS JavaScript SDK needs `requestHandler: new NodeHttpHandler()` from `@smithy/node-http-handler` for aimock's HTTP/1 server. See [SDK setup](https://aimock.copilotkit.dev/aws-bedrock/#sdk-configuration).
76
78
  - **Multimedia APIs** — [image generation](https://aimock.copilotkit.dev/images) (`gpt-image-1` default, Imagen; `/v1/images/variations` replays OpenAI's removal 404), [image editing](https://aimock.copilotkit.dev/images) (/v1/images/edits), [text-to-speech](https://aimock.copilotkit.dev/speech) (OpenAI + ElevenLabs TTS and Voice Design), [audio transcription](https://aimock.copilotkit.dev/transcription), [audio translation](https://aimock.copilotkit.dev/transcription) (/v1/audio/translations), [video generation](https://aimock.copilotkit.dev/video), [OpenRouter video generation](https://aimock.copilotkit.dev/openrouter-video) (/api/v1/videos with async job lifecycle), [Google Veo video generation](https://aimock.copilotkit.dev/veo-video) (:predictLongRunning + /v1beta/operations async lifecycle), [Grok Imagine video generation](https://aimock.copilotkit.dev/grok-video) (/v1/videos/generations with async job lifecycle), [BytePlus Ark video generation](https://aimock.copilotkit.dev/byteplus-video) (Seedance, /api/v3/contents/generations/tasks with async task lifecycle), [fal.ai](https://aimock.copilotkit.dev/fal-ai) (image / video / audio with queue lifecycle)
77
79
  - **OpenAI platform APIs** — [Files](https://aimock.copilotkit.dev/files) (byte-exact uploads, purpose validation), [Vector Stores](https://aimock.copilotkit.dev/vector-stores) (CRUD, file attach with deterministic poll progression, file batches, deterministic direct search; hosted `file_search` execution is not supported), [fine-tuning jobs](https://aimock.copilotkit.dev/fine-tuning) (deterministic lifecycle, events, cursor pages) and Batches (`/v1/batches` create/list/retrieve/cancel with deterministic poll progression and real output files)
78
80
  - **[MCP](https://aimock.copilotkit.dev/mcp-mock) / [A2A](https://aimock.copilotkit.dev/a2a-mock) / [AG-UI](https://aimock.copilotkit.dev/agui-mock) / [Vector](https://aimock.copilotkit.dev/vector-mock)** — Mock every protocol your AI agents use
@@ -85,6 +87,8 @@ Run them all on one port with `npx @copilotkit/aimock --config aimock.json`, or
85
87
  - **HTTP route catalog** — `GET /__aimock/openapi.json` returns OpenAPI 3.1; `GET /__aimock/routes` returns `{ count, routes }`. For programmatic inspection, import `buildOpenApiDocument`, `CATALOG_ROUTES` and `ROUTE_DEFINITIONS` (with `CatalogRoute`/`RouteDefinition` types) from `@copilotkit/aimock`. The catalog describes HTTP operations; streaming responses include media and framing metadata, not a complete-stream JSON body.
86
88
  - **Request IDs** — every response carries `X-Request-Id`, echoing the caller's header or minting one; the journal stores it on each entry and `GET /__aimock/journal?requestId=<id>` returns that request. A minted id is never forwarded upstream in record/proxy mode
87
89
  - **Per-Request Strict Mode** — `X-AIMock-Strict` header overrides the server-level `--strict` flag per request (`true`/`1` = strict, `false`/`0` = lenient)
90
+ - **[Required Header Policy](https://aimock.copilotkit.dev/aimock-cli#required-header-policy)** — Opt-in `requiredHeaders: "enforce"` (programmatic `policy`, config `llm.policy`, repeatable `--policy` on both CLIs, or the `X-AIMock-Policy` request header) rejects Anthropic HTTP requests (`/v1/messages`, `/v1/messages/count_tokens`, Anthropic-flavored `/v1/models/{id}`, and the `/v1/models` list with `modelCatalog: "native"`) that omit `anthropic-version` with a native 400. Off by default, and independent of strict mode
91
+ - **[Native model catalogs and token counts](https://aimock.copilotkit.dev/claude-messages#model-catalog)** — Anthropic `GET /v1/models` (selected by `anthropic-version`, or `x-api-key` without `Authorization`; the list route needs `policy.modelCatalog: "native"` and otherwise stays the OpenAI list) and Gemini `GET /v1beta/models` list and detail routes with provider paging, built from fixture model IDs with synthetic metadata; `POST /v1/messages/count_tokens` and Gemini `:countTokens` return a deterministic estimate of about 1 token per 4 characters of messages (plus tool definitions), minimum 1. These routes never proxy or record
88
92
  - **Context-Based Fixture Routing** — `X-AIMock-Context` header scopes fixtures per integration; fixtures with `match.context` only match requests carrying that context, fixtures without it remain shared
89
93
  - **[Drift Detection](https://aimock.copilotkit.dev/drift-detection)** — Daily CI validation against real APIs
90
94
  - **[Streaming Physics](https://aimock.copilotkit.dev/streaming-physics)** — Configurable `ttft`, `tps`, and `jitter`
@@ -257,7 +261,9 @@ await createServer(fixtures, { auth: { apiKeys: ["test-key"] } });
257
261
  AIMOCK_API_KEYS=test-key,rotated-key npx @copilotkit/aimock --config aimock.json
258
262
  ```
259
263
 
260
- Use `Authorization: Bearer <key>`, `Authorization: Key <key>`, `x-api-key`, `x-goog-api-key`, `api-key`, or `xi-api-key`. Every supplied credential must resolve to one configured key; mismatches return `401` with an OpenAI-compatible authentication error. HTTP routes, control APIs, mounts, and WebSocket upgrades are protected. Genuine CORS preflights plus `GET /health`, `GET /ready`, and `GET /metrics` remain public. This is inbound test access control, distinct from `record.providerKeys`; when enabled, proxying strips test credentials and requires a configured static provider credential before egress.
264
+ Use `Authorization: Bearer <key>`, `Authorization: Key <key>`, `x-api-key`, `x-goog-api-key`, `api-key`, or `xi-api-key`. Every supplied credential must resolve to one configured key; mismatches return `401`. HTTP routes, control APIs, mounts, and WebSocket upgrades are protected. Genuine CORS preflights plus `GET /health`, `GET /ready`, and `GET /metrics` remain public. This is inbound test access control, distinct from `record.providerKeys`; when enabled, proxying strips test credentials and requires a configured static provider credential before egress.
265
+
266
+ **Auth error bodies:** by default every HTTP route returns the 1.45 body `{"error":{"message":"Invalid API key","type":"authentication_error","code":"invalid_api_key"}}`. Set `policy.authErrors` to `"native"` (or `--policy authErrors=native`, or the request header `X-AIMock-Policy: authErrors=native`) to get provider-native 401 bodies on Anthropic Messages/count_tokens and Gemini/Vertex Google HTTP paths. Shared `/v1/models`, other HTTP paths, and WebSocket rejections always keep the legacy body. See the [Anthropic](docs/claude-messages/index.html#authentication-errors) and [Gemini](docs/gemini/index.html#authentication-errors) examples.
261
267
 
262
268
  ### aimock-owned upstream keys — `AIMOCK_PROVIDER_*_KEY`
263
269
 
@@ -7,6 +7,17 @@ let node_http = require("node:http");
7
7
  node_http = require_runtime.__toESM(node_http);
8
8
 
9
9
  //#region src/agui-mock.ts
10
+ const generatedEvents = /* @__PURE__ */ new WeakMap();
11
+ /** Keep convenience builders lazy so each request gets its own run and content IDs. */
12
+ function generatedFixture(match, build, delayMs) {
13
+ const fixture = {
14
+ match,
15
+ events: [],
16
+ delayMs
17
+ };
18
+ generatedEvents.set(fixture, build);
19
+ return fixture;
20
+ }
10
21
  var AGUIMock = class {
11
22
  fixtures = [];
12
23
  server = null;
@@ -25,12 +36,7 @@ var AGUIMock = class {
25
36
  return this;
26
37
  }
27
38
  onMessage(pattern, text, opts) {
28
- const events = require_agui_handler.buildTextResponse(text);
29
- this.fixtures.push({
30
- match: { message: pattern },
31
- events,
32
- delayMs: opts?.delayMs
33
- });
39
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => require_agui_handler.buildTextResponse(text, ids), opts?.delayMs));
34
40
  return this;
35
41
  }
36
42
  onRun(pattern, events, delayMs) {
@@ -42,30 +48,19 @@ var AGUIMock = class {
42
48
  return this;
43
49
  }
44
50
  onToolCall(pattern, toolName, args, opts) {
45
- const events = require_agui_handler.buildToolCallResponse(toolName, args, { result: opts?.result });
46
- this.fixtures.push({
47
- match: { message: pattern },
48
- events,
49
- delayMs: opts?.delayMs
50
- });
51
+ const result = opts?.result;
52
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => require_agui_handler.buildToolCallResponse(toolName, args, {
53
+ ...ids,
54
+ result
55
+ }), opts?.delayMs));
51
56
  return this;
52
57
  }
53
58
  onStateKey(key, snapshot, delayMs) {
54
- const events = require_agui_handler.buildStateUpdate(snapshot);
55
- this.fixtures.push({
56
- match: { stateKey: key },
57
- events,
58
- delayMs
59
- });
59
+ this.fixtures.push(generatedFixture({ stateKey: key }, (ids) => require_agui_handler.buildStateUpdate(snapshot, ids), delayMs));
60
60
  return this;
61
61
  }
62
62
  onReasoning(pattern, text, opts) {
63
- const events = require_agui_handler.buildReasoningResponse(text);
64
- this.fixtures.push({
65
- match: { message: pattern },
66
- events,
67
- delayMs: opts?.delayMs
68
- });
63
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => require_agui_handler.buildReasoningResponse(text, ids), opts?.delayMs));
69
64
  return this;
70
65
  }
71
66
  onPredicate(predicate, events, delayMs) {
@@ -124,7 +119,12 @@ var AGUIMock = class {
124
119
  }
125
120
  const fixture = require_agui_handler.findFixture(input, this.fixtures);
126
121
  if (fixture) {
127
- await require_agui_handler.writeAGUIEventStream(res, fixture.events, { delayMs: fixture.delayMs });
122
+ const build = generatedEvents.get(fixture);
123
+ await require_agui_handler.writeAGUIEventStream(res, build ? build({
124
+ threadId: input.threadId,
125
+ runId: input.runId,
126
+ parentRunId: input.parentRunId
127
+ }) : fixture.events, { delayMs: fixture.delayMs });
128
128
  this.journalRequest(req, pathname, 200);
129
129
  return true;
130
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agui-mock.cjs","names":["Logger","buildTextResponse","buildToolCallResponse","buildStateUpdate","buildReasoningResponse","readBody","findFixture","writeAGUIEventStream","proxyAndRecordAGUI","http","flattenHeaders"],"sources":["../src/agui-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n AGUIFixture,\n AGUIMockOptions,\n AGUIRecordConfig,\n AGUIEvent,\n AGUIRunAgentInput,\n} from \"./agui-types.js\";\nimport {\n findFixture,\n buildTextResponse,\n buildToolCallResponse,\n buildStateUpdate,\n buildReasoningResponse,\n writeAGUIEventStream,\n} from \"./agui-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\nimport { proxyAndRecordAGUI } from \"./agui-recorder.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\n\nexport class AGUIMock implements Mountable {\n private fixtures: AGUIFixture[] = [];\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: AGUIMockOptions;\n private baseUrl = \"\";\n private recordConfig: AGUIRecordConfig | undefined;\n private logger: Logger;\n\n constructor(options?: AGUIMockOptions) {\n this.options = options ?? {};\n this.logger = new Logger((options?.logLevel as LogLevel) ?? \"warn\");\n }\n\n // ---- Fluent registration API ----\n\n addFixture(fixture: AGUIFixture): this {\n this.fixtures.push(fixture);\n return this;\n }\n\n onMessage(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n const events = buildTextResponse(text);\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onRun(pattern: string | RegExp, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolCall(\n pattern: string | RegExp,\n toolName: string,\n args: string,\n opts?: { result?: string; delayMs?: number },\n ): this {\n const events = buildToolCallResponse(toolName, args, {\n result: opts?.result,\n });\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onStateKey(key: string, snapshot: Record<string, unknown>, delayMs?: number): this {\n const events = buildStateUpdate(snapshot);\n this.fixtures.push({\n match: { stateKey: key },\n events,\n delayMs,\n });\n return this;\n }\n\n onReasoning(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n const events = buildReasoningResponse(text);\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onPredicate(\n predicate: (input: AGUIRunAgentInput) => boolean,\n events: AGUIEvent[],\n delayMs?: number,\n ): this {\n this.fixtures.push({\n match: { predicate },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolResult(toolCallId: string, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { toolCallId },\n events,\n delayMs,\n });\n return this;\n }\n\n enableRecording(config: AGUIRecordConfig): this {\n this.recordConfig = config;\n return this;\n }\n\n reset(): this {\n this.fixtures = [];\n this.recordConfig = undefined;\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"POST\" || (pathname !== \"/\" && pathname !== \"\")) {\n return false;\n }\n\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_agui_requests_total\", { method: \"POST\" });\n }\n\n let body: string;\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"body read failed\";\n res.end(JSON.stringify({ error: `Failed to read request body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n let input: AGUIRunAgentInput;\n try {\n input = JSON.parse(body) as AGUIRunAgentInput;\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"unknown parse error\";\n res.end(JSON.stringify({ error: `Invalid JSON body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n if (input.messages !== undefined && !Array.isArray(input.messages)) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Invalid input: 'messages' must be an array when provided\",\n }),\n );\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n const fixture = findFixture(input, this.fixtures);\n\n if (fixture) {\n await writeAGUIEventStream(res, fixture.events, { delayMs: fixture.delayMs });\n this.journalRequest(req, pathname, 200);\n return true;\n }\n\n // No match — if recording is enabled, proxy to upstream\n if (this.recordConfig) {\n const result = await proxyAndRecordAGUI(\n req,\n res,\n input,\n this.fixtures,\n this.recordConfig,\n this.logger,\n body,\n );\n if (result !== false) {\n this.journalRequest(req, pathname, result);\n return true;\n }\n }\n\n // No match, no recorder — 404\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"No matching AG-UI fixture\" }));\n this.journalRequest(req, pathname, 404);\n return true;\n }\n\n health(): { status: string; fixtures: number } {\n return {\n status: \"ok\",\n fixtures: this.fixtures.length,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"AGUIMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const handled = await this.handleRequest(req, res, url.pathname).catch((err) => {\n this.logger.error(`AGUIMock request error: ${err instanceof Error ? err.message : err}`);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n } else if (!res.writableEnded) {\n res.end();\n }\n this.journalRequest(req, url.pathname, res.statusCode);\n return true;\n });\n if (!handled && !res.headersSent) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n this.journalRequest(req, url.pathname, 404);\n }\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Private helpers ----\n\n private journalRequest(req: http.IncomingMessage, pathname: string, status: number): void {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"agui\",\n response: { status, fixture: null },\n });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agui-mock.cjs","names":["Logger","buildTextResponse","buildToolCallResponse","buildStateUpdate","buildReasoningResponse","readBody","findFixture","writeAGUIEventStream","proxyAndRecordAGUI","http","flattenHeaders"],"sources":["../src/agui-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n AGUIFixture,\n AGUIMockOptions,\n AGUIRecordConfig,\n AGUIEvent,\n AGUIRunAgentInput,\n} from \"./agui-types.js\";\nimport {\n findFixture,\n buildTextResponse,\n buildToolCallResponse,\n buildStateUpdate,\n buildReasoningResponse,\n writeAGUIEventStream,\n type AGUIBuildOpts,\n} from \"./agui-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\nimport { proxyAndRecordAGUI } from \"./agui-recorder.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\n\nconst generatedEvents = new WeakMap<AGUIFixture, (opts: AGUIBuildOpts) => AGUIEvent[]>();\n\n/** Keep convenience builders lazy so each request gets its own run and content IDs. */\nfunction generatedFixture(\n match: AGUIFixture[\"match\"],\n build: (opts: AGUIBuildOpts) => AGUIEvent[],\n delayMs?: number,\n): AGUIFixture {\n const fixture: AGUIFixture = { match, events: [], delayMs };\n generatedEvents.set(fixture, build);\n return fixture;\n}\n\nexport class AGUIMock implements Mountable {\n private fixtures: AGUIFixture[] = [];\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: AGUIMockOptions;\n private baseUrl = \"\";\n private recordConfig: AGUIRecordConfig | undefined;\n private logger: Logger;\n\n constructor(options?: AGUIMockOptions) {\n this.options = options ?? {};\n this.logger = new Logger((options?.logLevel as LogLevel) ?? \"warn\");\n }\n\n // ---- Fluent registration API ----\n\n addFixture(fixture: AGUIFixture): this {\n this.fixtures.push(fixture);\n return this;\n }\n\n onMessage(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n this.fixtures.push(\n generatedFixture({ message: pattern }, (ids) => buildTextResponse(text, ids), opts?.delayMs),\n );\n return this;\n }\n\n onRun(pattern: string | RegExp, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolCall(\n pattern: string | RegExp,\n toolName: string,\n args: string,\n opts?: { result?: string; delayMs?: number },\n ): this {\n const result = opts?.result;\n this.fixtures.push(\n generatedFixture(\n { message: pattern },\n (ids) => buildToolCallResponse(toolName, args, { ...ids, result }),\n opts?.delayMs,\n ),\n );\n return this;\n }\n\n onStateKey(key: string, snapshot: Record<string, unknown>, delayMs?: number): this {\n this.fixtures.push(\n generatedFixture({ stateKey: key }, (ids) => buildStateUpdate(snapshot, ids), delayMs),\n );\n return this;\n }\n\n onReasoning(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n this.fixtures.push(\n generatedFixture(\n { message: pattern },\n (ids) => buildReasoningResponse(text, ids),\n opts?.delayMs,\n ),\n );\n return this;\n }\n\n onPredicate(\n predicate: (input: AGUIRunAgentInput) => boolean,\n events: AGUIEvent[],\n delayMs?: number,\n ): this {\n this.fixtures.push({\n match: { predicate },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolResult(toolCallId: string, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { toolCallId },\n events,\n delayMs,\n });\n return this;\n }\n\n enableRecording(config: AGUIRecordConfig): this {\n this.recordConfig = config;\n return this;\n }\n\n reset(): this {\n this.fixtures = [];\n this.recordConfig = undefined;\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"POST\" || (pathname !== \"/\" && pathname !== \"\")) {\n return false;\n }\n\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_agui_requests_total\", { method: \"POST\" });\n }\n\n let body: string;\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"body read failed\";\n res.end(JSON.stringify({ error: `Failed to read request body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n let input: AGUIRunAgentInput;\n try {\n input = JSON.parse(body) as AGUIRunAgentInput;\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"unknown parse error\";\n res.end(JSON.stringify({ error: `Invalid JSON body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n if (input.messages !== undefined && !Array.isArray(input.messages)) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Invalid input: 'messages' must be an array when provided\",\n }),\n );\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n const fixture = findFixture(input, this.fixtures);\n\n if (fixture) {\n const build = generatedEvents.get(fixture);\n const events = build\n ? build({ threadId: input.threadId, runId: input.runId, parentRunId: input.parentRunId })\n : fixture.events;\n await writeAGUIEventStream(res, events, { delayMs: fixture.delayMs });\n this.journalRequest(req, pathname, 200);\n return true;\n }\n\n // No match — if recording is enabled, proxy to upstream\n if (this.recordConfig) {\n const result = await proxyAndRecordAGUI(\n req,\n res,\n input,\n this.fixtures,\n this.recordConfig,\n this.logger,\n body,\n );\n if (result !== false) {\n this.journalRequest(req, pathname, result);\n return true;\n }\n }\n\n // No match, no recorder — 404\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"No matching AG-UI fixture\" }));\n this.journalRequest(req, pathname, 404);\n return true;\n }\n\n health(): { status: string; fixtures: number } {\n return {\n status: \"ok\",\n fixtures: this.fixtures.length,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"AGUIMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const handled = await this.handleRequest(req, res, url.pathname).catch((err) => {\n this.logger.error(`AGUIMock request error: ${err instanceof Error ? err.message : err}`);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n } else if (!res.writableEnded) {\n res.end();\n }\n this.journalRequest(req, url.pathname, res.statusCode);\n return true;\n });\n if (!handled && !res.headersSent) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n this.journalRequest(req, url.pathname, 404);\n }\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Private helpers ----\n\n private journalRequest(req: http.IncomingMessage, pathname: string, status: number): void {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"agui\",\n response: { status, fixture: null },\n });\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agui-mock.d.cts","names":[],"sources":["../src/agui-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,QAAA,YAAoB;;EAApB,QAAA,MAAS;EAAA,QAAA,OAAA;UAUE,QAAA;UAOF,OAAA;UAKQ,OAAA;UAUJ,YAAA;UAAgB,MAAA;aAUpB,CAAA,OAAA,CAAA,EAhCE,eAgCF;YAgBc,CAAA,OAAA,EAzCd,WAyCc,CAAA,EAAA,IAAA;WAUJ,CAAA,OAAA,EAAA,MAAA,GA9CF,MA8CE,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAWT,OAAA,CAAA,EAAA,MAAA;MACX,IAAA;OAW+B,CAAA,OAAA,EAAA,MAAA,GA3DjB,MA2DiB,EAAA,MAAA,EA3DD,SA2DC,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;YASjB,CAAA,OAAA,EAAA,MAAA,GA1DJ,MA0DI,EAAA,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAcjB,MAAK,CAAA,EAAA,MAAA;IACL,OAAK,CAAA,EAAA,MAAA;MAET,IAAA;YAiFiB,CAAA,GAAA,EAAA,MAAA,EAAA,QAAA,EA5Ic,MA4Id,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;aAQE,CAAA,OAAA,EAAA,MAAA,GA1IQ,MA0IR,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAMP,OAAA,CAAA,EAAA,MAAA;MA0CD,IAAA;aA9PiB,CAAA,SAAA,EAAA,CAAA,KAAA,EA+EV,iBA/EU,EAAA,GAAA,OAAA,EAAA,MAAA,EAgFrB,SAhFqB,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAS,YAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EA2FC,SA3FD,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;0BAoGhB;;qBAcjB,MAAA,CAAK,sBACL,MAAA,CAAK,mCAET;;;;;sBAiFiB;;wBAQE;WAMP;UA0CD"}
1
+ {"version":3,"file":"agui-mock.d.cts","names":[],"sources":["../src/agui-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAqCa,QAAA,YAAoB;;EAApB,QAAA,MAAS;EAAA,QAAA,OAAA;UAUE,QAAA;UAOF,OAAA;UAKQ,OAAA;UAOJ,YAAA;UAAgB,MAAA;aAUpB,CAAA,OAAA,CAAA,EA7BE,eA6BF;YAgBc,CAAA,OAAA,EAtCd,WAsCc,CAAA,EAAA,IAAA;WAOJ,CAAA,OAAA,EAAA,MAAA,GAxCF,MAwCE,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAYT,OAAA,CAAA,EAAA,MAAA;MACX,IAAA;OAW+B,CAAA,OAAA,EAAA,MAAA,GAzDjB,MAyDiB,EAAA,MAAA,EAzDD,SAyDC,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;YASjB,CAAA,OAAA,EAAA,MAAA,GAxDJ,MAwDI,EAAA,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAcjB,MAAK,CAAA,EAAA,MAAA;IACL,OAAK,CAAA,EAAA,MAAA;MAET,IAAA;YAqFiB,CAAA,GAAA,EAAA,MAAA,EAAA,QAAA,EA9Ic,MA8Id,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;aAQE,CAAA,OAAA,EAAA,MAAA,GA/IQ,MA+IR,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAMP,OAAA,CAAA,EAAA,MAAA;MA0CD,IAAA;aA7PiB,CAAA,SAAA,EAAA,CAAA,KAAA,EA0EV,iBA1EU,EAAA,GAAA,OAAA,EAAA,MAAA,EA2ErB,SA3EqB,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAS,YAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EAsFC,SAtFD,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;0BA+FhB;;qBAcjB,MAAA,CAAK,sBACL,MAAA,CAAK,mCAET;;;;;sBAqFiB;;wBAQE;WAMP;UA0CD"}
@@ -1 +1 @@
1
- {"version":3,"file":"agui-mock.d.ts","names":[],"sources":["../src/agui-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAuBa,QAAA,YAAoB;;EAApB,QAAA,MAAS;EAAA,QAAA,OAAA;UAUE,QAAA;UAOF,OAAA;UAKQ,OAAA;UAUJ,YAAA;UAAgB,MAAA;aAUpB,CAAA,OAAA,CAAA,EAhCE,eAgCF;YAgBc,CAAA,OAAA,EAzCd,WAyCc,CAAA,EAAA,IAAA;WAUJ,CAAA,OAAA,EAAA,MAAA,GA9CF,MA8CE,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAWT,OAAA,CAAA,EAAA,MAAA;MACX,IAAA;OAW+B,CAAA,OAAA,EAAA,MAAA,GA3DjB,MA2DiB,EAAA,MAAA,EA3DD,SA2DC,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;YASjB,CAAA,OAAA,EAAA,MAAA,GA1DJ,MA0DI,EAAA,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAcjB,MAAK,CAAA,EAAA,MAAA;IACL,OAAK,CAAA,EAAA,MAAA;MAET,IAAA;YAiFiB,CAAA,GAAA,EAAA,MAAA,EAAA,QAAA,EA5Ic,MA4Id,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;aAQE,CAAA,OAAA,EAAA,MAAA,GA1IQ,MA0IR,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAMP,OAAA,CAAA,EAAA,MAAA;MA0CD,IAAA;aA9PiB,CAAA,SAAA,EAAA,CAAA,KAAA,EA+EV,iBA/EU,EAAA,GAAA,OAAA,EAAA,MAAA,EAgFrB,SAhFqB,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAS,YAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EA2FC,SA3FD,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;0BAoGhB;;qBAcjB,MAAA,CAAK,sBACL,MAAA,CAAK,mCAET;;;;;sBAiFiB;;wBAQE;WAMP;UA0CD"}
1
+ {"version":3,"file":"agui-mock.d.ts","names":[],"sources":["../src/agui-mock.ts"],"sourcesContent":[],"mappings":";;;;;;;cAqCa,QAAA,YAAoB;;EAApB,QAAA,MAAS;EAAA,QAAA,OAAA;UAUE,QAAA;UAOF,OAAA;UAKQ,OAAA;UAOJ,YAAA;UAAgB,MAAA;aAUpB,CAAA,OAAA,CAAA,EA7BE,eA6BF;YAgBc,CAAA,OAAA,EAtCd,WAsCc,CAAA,EAAA,IAAA;WAOJ,CAAA,OAAA,EAAA,MAAA,GAxCF,MAwCE,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAYT,OAAA,CAAA,EAAA,MAAA;MACX,IAAA;OAW+B,CAAA,OAAA,EAAA,MAAA,GAzDjB,MAyDiB,EAAA,MAAA,EAzDD,SAyDC,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;YASjB,CAAA,OAAA,EAAA,MAAA,GAxDJ,MAwDI,EAAA,QAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAcjB,MAAK,CAAA,EAAA,MAAA;IACL,OAAK,CAAA,EAAA,MAAA;MAET,IAAA;YAqFiB,CAAA,GAAA,EAAA,MAAA,EAAA,QAAA,EA9Ic,MA8Id,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;aAQE,CAAA,OAAA,EAAA,MAAA,GA/IQ,MA+IR,EAAA,IAAA,EAAA,MAAA,EAAA,KAAA,EAAA;IAMP,OAAA,CAAA,EAAA,MAAA;MA0CD,IAAA;aA7PiB,CAAA,SAAA,EAAA,CAAA,KAAA,EA0EV,iBA1EU,EAAA,GAAA,OAAA,EAAA,MAAA,EA2ErB,SA3EqB,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAS,YAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EAsFC,SAtFD,EAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAAA,IAAA;0BA+FhB;;qBAcjB,MAAA,CAAK,sBACL,MAAA,CAAK,mCAET;;;;;sBAqFiB;;wBAQE;WAMP;UA0CD"}
package/dist/agui-mock.js CHANGED
@@ -5,6 +5,17 @@ import { Logger } from "./logger.js";
5
5
  import * as http$1 from "node:http";
6
6
 
7
7
  //#region src/agui-mock.ts
8
+ const generatedEvents = /* @__PURE__ */ new WeakMap();
9
+ /** Keep convenience builders lazy so each request gets its own run and content IDs. */
10
+ function generatedFixture(match, build, delayMs) {
11
+ const fixture = {
12
+ match,
13
+ events: [],
14
+ delayMs
15
+ };
16
+ generatedEvents.set(fixture, build);
17
+ return fixture;
18
+ }
8
19
  var AGUIMock = class {
9
20
  fixtures = [];
10
21
  server = null;
@@ -23,12 +34,7 @@ var AGUIMock = class {
23
34
  return this;
24
35
  }
25
36
  onMessage(pattern, text, opts) {
26
- const events = buildTextResponse(text);
27
- this.fixtures.push({
28
- match: { message: pattern },
29
- events,
30
- delayMs: opts?.delayMs
31
- });
37
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => buildTextResponse(text, ids), opts?.delayMs));
32
38
  return this;
33
39
  }
34
40
  onRun(pattern, events, delayMs) {
@@ -40,30 +46,19 @@ var AGUIMock = class {
40
46
  return this;
41
47
  }
42
48
  onToolCall(pattern, toolName, args, opts) {
43
- const events = buildToolCallResponse(toolName, args, { result: opts?.result });
44
- this.fixtures.push({
45
- match: { message: pattern },
46
- events,
47
- delayMs: opts?.delayMs
48
- });
49
+ const result = opts?.result;
50
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => buildToolCallResponse(toolName, args, {
51
+ ...ids,
52
+ result
53
+ }), opts?.delayMs));
49
54
  return this;
50
55
  }
51
56
  onStateKey(key, snapshot, delayMs) {
52
- const events = buildStateUpdate(snapshot);
53
- this.fixtures.push({
54
- match: { stateKey: key },
55
- events,
56
- delayMs
57
- });
57
+ this.fixtures.push(generatedFixture({ stateKey: key }, (ids) => buildStateUpdate(snapshot, ids), delayMs));
58
58
  return this;
59
59
  }
60
60
  onReasoning(pattern, text, opts) {
61
- const events = buildReasoningResponse(text);
62
- this.fixtures.push({
63
- match: { message: pattern },
64
- events,
65
- delayMs: opts?.delayMs
66
- });
61
+ this.fixtures.push(generatedFixture({ message: pattern }, (ids) => buildReasoningResponse(text, ids), opts?.delayMs));
67
62
  return this;
68
63
  }
69
64
  onPredicate(predicate, events, delayMs) {
@@ -122,7 +117,12 @@ var AGUIMock = class {
122
117
  }
123
118
  const fixture = findFixture(input, this.fixtures);
124
119
  if (fixture) {
125
- await writeAGUIEventStream(res, fixture.events, { delayMs: fixture.delayMs });
120
+ const build = generatedEvents.get(fixture);
121
+ await writeAGUIEventStream(res, build ? build({
122
+ threadId: input.threadId,
123
+ runId: input.runId,
124
+ parentRunId: input.parentRunId
125
+ }) : fixture.events, { delayMs: fixture.delayMs });
126
126
  this.journalRequest(req, pathname, 200);
127
127
  return true;
128
128
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agui-mock.js","names":["http"],"sources":["../src/agui-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n AGUIFixture,\n AGUIMockOptions,\n AGUIRecordConfig,\n AGUIEvent,\n AGUIRunAgentInput,\n} from \"./agui-types.js\";\nimport {\n findFixture,\n buildTextResponse,\n buildToolCallResponse,\n buildStateUpdate,\n buildReasoningResponse,\n writeAGUIEventStream,\n} from \"./agui-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\nimport { proxyAndRecordAGUI } from \"./agui-recorder.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\n\nexport class AGUIMock implements Mountable {\n private fixtures: AGUIFixture[] = [];\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: AGUIMockOptions;\n private baseUrl = \"\";\n private recordConfig: AGUIRecordConfig | undefined;\n private logger: Logger;\n\n constructor(options?: AGUIMockOptions) {\n this.options = options ?? {};\n this.logger = new Logger((options?.logLevel as LogLevel) ?? \"warn\");\n }\n\n // ---- Fluent registration API ----\n\n addFixture(fixture: AGUIFixture): this {\n this.fixtures.push(fixture);\n return this;\n }\n\n onMessage(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n const events = buildTextResponse(text);\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onRun(pattern: string | RegExp, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolCall(\n pattern: string | RegExp,\n toolName: string,\n args: string,\n opts?: { result?: string; delayMs?: number },\n ): this {\n const events = buildToolCallResponse(toolName, args, {\n result: opts?.result,\n });\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onStateKey(key: string, snapshot: Record<string, unknown>, delayMs?: number): this {\n const events = buildStateUpdate(snapshot);\n this.fixtures.push({\n match: { stateKey: key },\n events,\n delayMs,\n });\n return this;\n }\n\n onReasoning(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n const events = buildReasoningResponse(text);\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs: opts?.delayMs,\n });\n return this;\n }\n\n onPredicate(\n predicate: (input: AGUIRunAgentInput) => boolean,\n events: AGUIEvent[],\n delayMs?: number,\n ): this {\n this.fixtures.push({\n match: { predicate },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolResult(toolCallId: string, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { toolCallId },\n events,\n delayMs,\n });\n return this;\n }\n\n enableRecording(config: AGUIRecordConfig): this {\n this.recordConfig = config;\n return this;\n }\n\n reset(): this {\n this.fixtures = [];\n this.recordConfig = undefined;\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"POST\" || (pathname !== \"/\" && pathname !== \"\")) {\n return false;\n }\n\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_agui_requests_total\", { method: \"POST\" });\n }\n\n let body: string;\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"body read failed\";\n res.end(JSON.stringify({ error: `Failed to read request body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n let input: AGUIRunAgentInput;\n try {\n input = JSON.parse(body) as AGUIRunAgentInput;\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"unknown parse error\";\n res.end(JSON.stringify({ error: `Invalid JSON body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n if (input.messages !== undefined && !Array.isArray(input.messages)) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Invalid input: 'messages' must be an array when provided\",\n }),\n );\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n const fixture = findFixture(input, this.fixtures);\n\n if (fixture) {\n await writeAGUIEventStream(res, fixture.events, { delayMs: fixture.delayMs });\n this.journalRequest(req, pathname, 200);\n return true;\n }\n\n // No match — if recording is enabled, proxy to upstream\n if (this.recordConfig) {\n const result = await proxyAndRecordAGUI(\n req,\n res,\n input,\n this.fixtures,\n this.recordConfig,\n this.logger,\n body,\n );\n if (result !== false) {\n this.journalRequest(req, pathname, result);\n return true;\n }\n }\n\n // No match, no recorder — 404\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"No matching AG-UI fixture\" }));\n this.journalRequest(req, pathname, 404);\n return true;\n }\n\n health(): { status: string; fixtures: number } {\n return {\n status: \"ok\",\n fixtures: this.fixtures.length,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"AGUIMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const handled = await this.handleRequest(req, res, url.pathname).catch((err) => {\n this.logger.error(`AGUIMock request error: ${err instanceof Error ? err.message : err}`);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n } else if (!res.writableEnded) {\n res.end();\n }\n this.journalRequest(req, url.pathname, res.statusCode);\n return true;\n });\n if (!handled && !res.headersSent) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n this.journalRequest(req, url.pathname, 404);\n }\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Private helpers ----\n\n private journalRequest(req: http.IncomingMessage, pathname: string, status: number): void {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"agui\",\n response: { status, fixture: null },\n });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"agui-mock.js","names":["http"],"sources":["../src/agui-mock.ts"],"sourcesContent":["import * as http from \"node:http\";\nimport type { Mountable } from \"./types.js\";\nimport type { Journal } from \"./journal.js\";\nimport type { MetricsRegistry } from \"./metrics.js\";\nimport type {\n AGUIFixture,\n AGUIMockOptions,\n AGUIRecordConfig,\n AGUIEvent,\n AGUIRunAgentInput,\n} from \"./agui-types.js\";\nimport {\n findFixture,\n buildTextResponse,\n buildToolCallResponse,\n buildStateUpdate,\n buildReasoningResponse,\n writeAGUIEventStream,\n type AGUIBuildOpts,\n} from \"./agui-handler.js\";\nimport { flattenHeaders, readBody } from \"./helpers.js\";\nimport { proxyAndRecordAGUI } from \"./agui-recorder.js\";\nimport { Logger, type LogLevel } from \"./logger.js\";\n\nconst generatedEvents = new WeakMap<AGUIFixture, (opts: AGUIBuildOpts) => AGUIEvent[]>();\n\n/** Keep convenience builders lazy so each request gets its own run and content IDs. */\nfunction generatedFixture(\n match: AGUIFixture[\"match\"],\n build: (opts: AGUIBuildOpts) => AGUIEvent[],\n delayMs?: number,\n): AGUIFixture {\n const fixture: AGUIFixture = { match, events: [], delayMs };\n generatedEvents.set(fixture, build);\n return fixture;\n}\n\nexport class AGUIMock implements Mountable {\n private fixtures: AGUIFixture[] = [];\n private server: http.Server | null = null;\n private journal: Journal | null = null;\n private registry: MetricsRegistry | null = null;\n private options: AGUIMockOptions;\n private baseUrl = \"\";\n private recordConfig: AGUIRecordConfig | undefined;\n private logger: Logger;\n\n constructor(options?: AGUIMockOptions) {\n this.options = options ?? {};\n this.logger = new Logger((options?.logLevel as LogLevel) ?? \"warn\");\n }\n\n // ---- Fluent registration API ----\n\n addFixture(fixture: AGUIFixture): this {\n this.fixtures.push(fixture);\n return this;\n }\n\n onMessage(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n this.fixtures.push(\n generatedFixture({ message: pattern }, (ids) => buildTextResponse(text, ids), opts?.delayMs),\n );\n return this;\n }\n\n onRun(pattern: string | RegExp, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { message: pattern },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolCall(\n pattern: string | RegExp,\n toolName: string,\n args: string,\n opts?: { result?: string; delayMs?: number },\n ): this {\n const result = opts?.result;\n this.fixtures.push(\n generatedFixture(\n { message: pattern },\n (ids) => buildToolCallResponse(toolName, args, { ...ids, result }),\n opts?.delayMs,\n ),\n );\n return this;\n }\n\n onStateKey(key: string, snapshot: Record<string, unknown>, delayMs?: number): this {\n this.fixtures.push(\n generatedFixture({ stateKey: key }, (ids) => buildStateUpdate(snapshot, ids), delayMs),\n );\n return this;\n }\n\n onReasoning(pattern: string | RegExp, text: string, opts?: { delayMs?: number }): this {\n this.fixtures.push(\n generatedFixture(\n { message: pattern },\n (ids) => buildReasoningResponse(text, ids),\n opts?.delayMs,\n ),\n );\n return this;\n }\n\n onPredicate(\n predicate: (input: AGUIRunAgentInput) => boolean,\n events: AGUIEvent[],\n delayMs?: number,\n ): this {\n this.fixtures.push({\n match: { predicate },\n events,\n delayMs,\n });\n return this;\n }\n\n onToolResult(toolCallId: string, events: AGUIEvent[], delayMs?: number): this {\n this.fixtures.push({\n match: { toolCallId },\n events,\n delayMs,\n });\n return this;\n }\n\n enableRecording(config: AGUIRecordConfig): this {\n this.recordConfig = config;\n return this;\n }\n\n reset(): this {\n this.fixtures = [];\n this.recordConfig = undefined;\n return this;\n }\n\n // ---- Mountable interface ----\n\n async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n pathname: string,\n ): Promise<boolean> {\n if (req.method !== \"POST\" || (pathname !== \"/\" && pathname !== \"\")) {\n return false;\n }\n\n if (this.registry) {\n this.registry.incrementCounter(\"aimock_agui_requests_total\", { method: \"POST\" });\n }\n\n let body: string;\n try {\n body = await readBody(req);\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"body read failed\";\n res.end(JSON.stringify({ error: `Failed to read request body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n let input: AGUIRunAgentInput;\n try {\n input = JSON.parse(body) as AGUIRunAgentInput;\n } catch (err) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n const detail = err instanceof Error ? err.message : \"unknown parse error\";\n res.end(JSON.stringify({ error: `Invalid JSON body: ${detail}` }));\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n if (input.messages !== undefined && !Array.isArray(input.messages)) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: \"Invalid input: 'messages' must be an array when provided\",\n }),\n );\n this.journalRequest(req, pathname, 400);\n return true;\n }\n\n const fixture = findFixture(input, this.fixtures);\n\n if (fixture) {\n const build = generatedEvents.get(fixture);\n const events = build\n ? build({ threadId: input.threadId, runId: input.runId, parentRunId: input.parentRunId })\n : fixture.events;\n await writeAGUIEventStream(res, events, { delayMs: fixture.delayMs });\n this.journalRequest(req, pathname, 200);\n return true;\n }\n\n // No match — if recording is enabled, proxy to upstream\n if (this.recordConfig) {\n const result = await proxyAndRecordAGUI(\n req,\n res,\n input,\n this.fixtures,\n this.recordConfig,\n this.logger,\n body,\n );\n if (result !== false) {\n this.journalRequest(req, pathname, result);\n return true;\n }\n }\n\n // No match, no recorder — 404\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"No matching AG-UI fixture\" }));\n this.journalRequest(req, pathname, 404);\n return true;\n }\n\n health(): { status: string; fixtures: number } {\n return {\n status: \"ok\",\n fixtures: this.fixtures.length,\n };\n }\n\n setJournal(journal: Journal): void {\n this.journal = journal;\n }\n\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n setRegistry(registry: MetricsRegistry): void {\n this.registry = registry;\n }\n\n // ---- Standalone mode ----\n\n async start(): Promise<string> {\n if (this.server) {\n throw new Error(\"AGUIMock server already started\");\n }\n\n const host = this.options.host ?? \"127.0.0.1\";\n const port = this.options.port ?? 0;\n\n return new Promise<string>((resolve, reject) => {\n const srv = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://${req.headers.host ?? \"localhost\"}`);\n const handled = await this.handleRequest(req, res, url.pathname).catch((err) => {\n this.logger.error(`AGUIMock request error: ${err instanceof Error ? err.message : err}`);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal server error\");\n } else if (!res.writableEnded) {\n res.end();\n }\n this.journalRequest(req, url.pathname, res.statusCode);\n return true;\n });\n if (!handled && !res.headersSent) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\" }));\n this.journalRequest(req, url.pathname, 404);\n }\n });\n\n srv.on(\"error\", reject);\n\n srv.listen(port, host, () => {\n const addr = srv.address();\n if (typeof addr === \"object\" && addr !== null) {\n this.baseUrl = `http://${host}:${addr.port}`;\n }\n this.server = srv;\n resolve(this.baseUrl);\n });\n });\n }\n\n async stop(): Promise<void> {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n const srv = this.server;\n await new Promise<void>((resolve, reject) => {\n srv.close((err: Error | undefined) => (err ? reject(err) : resolve()));\n });\n this.server = null;\n }\n\n get url(): string {\n if (!this.server) {\n throw new Error(\"AGUIMock server not started\");\n }\n return this.baseUrl;\n }\n\n // ---- Private helpers ----\n\n private journalRequest(req: http.IncomingMessage, pathname: string, status: number): void {\n if (this.journal) {\n this.journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? pathname,\n headers: flattenHeaders(req.headers),\n body: null,\n service: \"agui\",\n response: { status, fixture: null },\n });\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agui-types.d.ts","names":[],"sources":["../src/agui-types.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"agui-types.d.ts","names":[],"sources":["../src/agui-types.ts"],"sourcesContent":[],"mappings":"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"}
@@ -22,6 +22,9 @@ Options:
22
22
  instead of serving {} (same as llm.strictToolArguments: true)
23
23
  --responses-tools <mode> OpenAI Responses tool handling: legacy (default) or
24
24
  extended (overrides llm.responsesTools)
25
+ --policy <key=value> Request policy (repeatable): requiredHeaders=off|enforce,
26
+ authErrors=legacy|native, modelCatalog=legacy|native
27
+ Overrides individual llm.policy keys (defaults: off, legacy, legacy)
25
28
  -h, --help Show this help message
26
29
 
27
30
  Subcommands:
@@ -80,6 +83,10 @@ function runAimockCli(deps = {}) {
80
83
  default: false
81
84
  },
82
85
  "responses-tools": { type: "string" },
86
+ policy: {
87
+ type: "string",
88
+ multiple: true
89
+ },
83
90
  help: {
84
91
  type: "boolean",
85
92
  short: "h",
@@ -137,12 +144,19 @@ function runAimockCli(deps = {}) {
137
144
  return;
138
145
  }
139
146
  const responsesTools = responsesToolsFlag;
147
+ const parsedPolicy = require_config_loader.parsePolicyFlags(values.policy ?? []);
148
+ if (!parsedPolicy.ok) {
149
+ logError(`${parsedPolicy.error}\n\n${HELP}`);
150
+ exit(1);
151
+ return;
152
+ }
140
153
  const overrides = {
141
154
  port,
142
155
  host,
143
156
  ...values.misbehavior ? { enableMisbehavior: true } : {},
144
157
  ...values["strict-tool-arguments"] ? { strictToolArguments: true } : {},
145
- ...responsesTools !== void 0 ? { responsesTools } : {}
158
+ ...responsesTools !== void 0 ? { responsesTools } : {},
159
+ ...values.policy !== void 0 ? { policy: parsedPolicy.policy } : {}
146
160
  };
147
161
  async function main() {
148
162
  const { llmock, url } = await startFromConfigFn(config, overrides);
@@ -1 +1 @@
1
- {"version":3,"file":"aimock-cli.cjs","names":["loadConfig","startFromConfig"],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport { loadConfig, startFromConfig, type StartFromConfigOverrides } from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\nimport { runValidateCli } from \"./validate-cli.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n aimock validate [--strict] [--json] [--] <path> [more paths ...]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n --host <string> Host override (default: from config or 127.0.0.1)\n --misbehavior Enable model misbehavior (same as llm.enableMisbehavior: true)\n --strict-tool-arguments Reject fixture tool calls with invalid JSON arguments\n instead of serving {} (same as llm.strictToolArguments: true)\n --responses-tools <mode> OpenAI Responses tool handling: legacy (default) or\n extended (overrides llm.responsesTools)\n -h, --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n validate Validate fixture files or directories offline\n Run \"aimock validate --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n validateDeps?: {\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n };\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n // Intercept \"validate\" the same way — it takes file paths, not --config.\n if (argv[0] === \"validate\") {\n runValidateCli({\n argv: argv.slice(1),\n log: deps.validateDeps?.log ?? log,\n logError: deps.validateDeps?.logError ?? logError,\n exit: deps.validateDeps?.exit ?? exit,\n });\n return;\n }\n\n // Short-flag rule for the `aimock` bin: a short flag means the same thing at\n // the top level and in every subcommand. `-h` is `--help` everywhere, which\n // is what `convert` (src/convert.ts) and `validate` (src/validate-cli.ts)\n // already did and what a reader typing `aimock -h` expects; the host\n // override is long-form `--host` only, and had no documented short use.\n // Short flags are per-bin: the separate `llmock` bin (src/cli.ts, the\n // Docker ENTRYPOINT) keeps its own documented set, where `-h` is `--host`\n // and `-c` is `--chunk-size`.\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\" },\n misbehavior: { type: \"boolean\", default: false },\n \"strict-tool-arguments\": { type: \"boolean\", default: false },\n \"responses-tools\": { type: \"string\" },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (values.config === undefined) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n // A value-taking option that was GIVEN an empty (or blank) value is a usage\n // error, not an absent option. Testing these for truthiness instead let\n // `--config \"\"` read as \"not given\", and let `--port \"\"` / `--host \"\"` be\n // dropped in silence — `--host \"\"` in particular reached the server as an\n // empty bind address, which listens on every interface rather than on the\n // documented 127.0.0.1 default.\n const blank = (\n [\n [\"config\", values.config],\n [\"port\", values.port],\n [\"host\", values.host],\n [\"responses-tools\", values[\"responses-tools\"]],\n ] as const\n ).find(([, value]) => value !== undefined && value.trim() === \"\");\n if (blank !== undefined) {\n logError(`Error: --${blank[0]} requires a non-empty value.\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port === undefined ? undefined : Number(values.port);\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n const responsesToolsFlag = values[\"responses-tools\"];\n if (\n responsesToolsFlag !== undefined &&\n responsesToolsFlag !== \"legacy\" &&\n responsesToolsFlag !== \"extended\"\n ) {\n logError(\n `Error: invalid --responses-tools \"${responsesToolsFlag}\" (expected \"legacy\" or \"extended\").\\n\\n${HELP}`,\n );\n exit(1);\n return;\n }\n // The boolean opt-ins override the config only when given, so an absent flag\n // leaves llm.enableMisbehavior / llm.strictToolArguments in charge.\n const responsesTools: StartFromConfigOverrides[\"responsesTools\"] = responsesToolsFlag;\n const overrides: StartFromConfigOverrides = {\n port,\n host,\n ...(values.misbehavior ? { enableMisbehavior: true } : {}),\n ...(values[\"strict-tool-arguments\"] ? { strictToolArguments: true } : {}),\n ...(responsesTools !== undefined ? { responsesTools } : {}),\n };\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, overrides);\n\n function shutdown() {\n log(\"Shutting down...\");\n process.removeListener(\"SIGINT\", shutdown);\n process.removeListener(\"SIGTERM\", shutdown);\n llmock.stop().then(\n () => exit(0),\n (err) => {\n logError(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`);\n exit(1);\n },\n );\n }\n // Register BEFORE announcing readiness — see the note in src/cli.ts. A supervisor\n // that reacts to the readiness line must never win a race against this listener.\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n log(`aimock server listening on ${url}`);\n\n if (deps.onReady) {\n deps.onReady({ shutdown });\n }\n }\n\n main().catch((err) => {\n logError(err instanceof Error ? err.message : String(err));\n exit(1);\n });\n}\n\n// Run when executed as a script (not when imported for testing).\n/* v8 ignore start -- entry-point guard, exercised by integration tests */\n// The basenames this module is ever argv[1] under: the `aimock` bin (the\n// package.json \"bin\" name), both build outputs — tsdown.config.ts builds\n// src/aimock-cli.ts in \"esm\" AND \"cjs\" format, which under `\"type\": \"module\"`\n// emits dist/aimock-cli.js and dist/aimock-cli.cjs — and the TypeScript\n// source, run through tsx. Omitting the .cjs made `node dist/aimock-cli.cjs`\n// print nothing and exit 0 despite its shebang and exec bit.\nconst ENTRY_BASENAMES = new Set([\"aimock\", \"aimock-cli.js\", \"aimock-cli.cjs\", \"aimock-cli.ts\"]);\nconst scriptName = process.argv[1] ?? \"\";\nif (ENTRY_BASENAMES.has(basename(scriptName))) {\n runAimockCli();\n}\n/* v8 ignore stop */\n"],"mappings":"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"}
1
+ {"version":3,"file":"aimock-cli.cjs","names":["loadConfig","startFromConfig","parsePolicyFlags"],"sources":["../src/aimock-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\";\nimport { resolve, basename } from \"node:path\";\nimport {\n loadConfig,\n parsePolicyFlags,\n startFromConfig,\n type StartFromConfigOverrides,\n} from \"./config-loader.js\";\nimport { runConvertCli, type ConvertCliDeps } from \"./convert.js\";\nimport { runValidateCli } from \"./validate-cli.js\";\n\nconst HELP = `\nUsage: aimock [options]\n aimock convert <format> <input> [output]\n aimock validate [--strict] [--json] [--] <path> [more paths ...]\n\nOptions:\n -c, --config <path> Path to aimock config JSON file (required)\n -p, --port <number> Port override (default: from config or 0)\n --host <string> Host override (default: from config or 127.0.0.1)\n --misbehavior Enable model misbehavior (same as llm.enableMisbehavior: true)\n --strict-tool-arguments Reject fixture tool calls with invalid JSON arguments\n instead of serving {} (same as llm.strictToolArguments: true)\n --responses-tools <mode> OpenAI Responses tool handling: legacy (default) or\n extended (overrides llm.responsesTools)\n --policy <key=value> Request policy (repeatable): requiredHeaders=off|enforce,\n authErrors=legacy|native, modelCatalog=legacy|native\n Overrides individual llm.policy keys (defaults: off, legacy, legacy)\n -h, --help Show this help message\n\nSubcommands:\n convert Convert third-party mock configs to aimock format\n Run \"aimock convert --help\" for details\n validate Validate fixture files or directories offline\n Run \"aimock validate --help\" for details\n`.trim();\n\nexport interface AimockCliDeps {\n argv?: string[];\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n loadConfigFn?: typeof loadConfig;\n startFromConfigFn?: typeof startFromConfig;\n onReady?: (ctx: { shutdown: () => void }) => void;\n convertDeps?: Partial<ConvertCliDeps>;\n validateDeps?: {\n log?: (msg: string) => void;\n logError?: (msg: string) => void;\n exit?: (code: number) => void;\n };\n}\n\nexport function runAimockCli(deps: AimockCliDeps = {}): void {\n /* v8 ignore next 6 -- defaults used only when called from CLI entry point */\n const argv = deps.argv ?? process.argv.slice(2);\n const log = deps.log ?? console.log.bind(console);\n const logError = deps.logError ?? console.error.bind(console);\n const exit = deps.exit ?? process.exit.bind(process);\n const loadConfigFn = deps.loadConfigFn ?? loadConfig;\n const startFromConfigFn = deps.startFromConfigFn ?? startFromConfig;\n\n // Intercept \"convert\" subcommand before parseArgs (which uses strict mode)\n if (argv[0] === \"convert\") {\n runConvertCli({\n argv: argv.slice(1),\n log,\n logError,\n exit,\n ...deps.convertDeps,\n });\n return;\n }\n\n // Intercept \"validate\" the same way — it takes file paths, not --config.\n if (argv[0] === \"validate\") {\n runValidateCli({\n argv: argv.slice(1),\n log: deps.validateDeps?.log ?? log,\n logError: deps.validateDeps?.logError ?? logError,\n exit: deps.validateDeps?.exit ?? exit,\n });\n return;\n }\n\n // Short-flag rule for the `aimock` bin: a short flag means the same thing at\n // the top level and in every subcommand. `-h` is `--help` everywhere, which\n // is what `convert` (src/convert.ts) and `validate` (src/validate-cli.ts)\n // already did and what a reader typing `aimock -h` expects; the host\n // override is long-form `--host` only, and had no documented short use.\n // Short flags are per-bin: the separate `llmock` bin (src/cli.ts, the\n // Docker ENTRYPOINT) keeps its own documented set, where `-h` is `--host`\n // and `-c` is `--chunk-size`.\n let values;\n try {\n ({ values } = parseArgs({\n args: argv,\n options: {\n config: { type: \"string\", short: \"c\" },\n port: { type: \"string\", short: \"p\" },\n host: { type: \"string\" },\n misbehavior: { type: \"boolean\", default: false },\n \"strict-tool-arguments\": { type: \"boolean\", default: false },\n \"responses-tools\": { type: \"string\" },\n policy: { type: \"string\", multiple: true },\n help: { type: \"boolean\", short: \"h\", default: false },\n },\n strict: true,\n }));\n } catch (err) {\n /* v8 ignore next -- parseArgs always throws Error subclasses */\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Error: ${msg}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n if (values.help) {\n log(HELP);\n exit(0);\n return;\n }\n if (values.config === undefined) {\n logError(\"Error: --config is required.\\n\\n\" + HELP);\n exit(1);\n return;\n }\n // A value-taking option that was GIVEN an empty (or blank) value is a usage\n // error, not an absent option. Testing these for truthiness instead let\n // `--config \"\"` read as \"not given\", and let `--port \"\"` / `--host \"\"` be\n // dropped in silence — `--host \"\"` in particular reached the server as an\n // empty bind address, which listens on every interface rather than on the\n // documented 127.0.0.1 default.\n const blank = (\n [\n [\"config\", values.config],\n [\"port\", values.port],\n [\"host\", values.host],\n [\"responses-tools\", values[\"responses-tools\"]],\n ] as const\n ).find(([, value]) => value !== undefined && value.trim() === \"\");\n if (blank !== undefined) {\n logError(`Error: --${blank[0]} requires a non-empty value.\\n\\n${HELP}`);\n exit(1);\n return;\n }\n\n const configPath = resolve(values.config);\n let config;\n try {\n config = loadConfigFn(configPath);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logError(`Failed to load config from ${configPath}: ${msg}`);\n exit(1);\n return;\n }\n\n const port = values.port === undefined ? undefined : Number(values.port);\n if (\n port !== undefined &&\n (Number.isNaN(port) || !Number.isInteger(port) || port < 0 || port > 65535)\n ) {\n logError(`Error: invalid port \"${values.port}\".\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const host = values.host;\n const responsesToolsFlag = values[\"responses-tools\"];\n if (\n responsesToolsFlag !== undefined &&\n responsesToolsFlag !== \"legacy\" &&\n responsesToolsFlag !== \"extended\"\n ) {\n logError(\n `Error: invalid --responses-tools \"${responsesToolsFlag}\" (expected \"legacy\" or \"extended\").\\n\\n${HELP}`,\n );\n exit(1);\n return;\n }\n // The boolean opt-ins override the config only when given, so an absent flag\n // leaves llm.enableMisbehavior / llm.strictToolArguments in charge.\n const responsesTools: StartFromConfigOverrides[\"responsesTools\"] = responsesToolsFlag;\n const parsedPolicy = parsePolicyFlags(values.policy ?? []);\n if (!parsedPolicy.ok) {\n logError(`${parsedPolicy.error}\\n\\n${HELP}`);\n exit(1);\n return;\n }\n const overrides: StartFromConfigOverrides = {\n port,\n host,\n ...(values.misbehavior ? { enableMisbehavior: true } : {}),\n ...(values[\"strict-tool-arguments\"] ? { strictToolArguments: true } : {}),\n ...(responsesTools !== undefined ? { responsesTools } : {}),\n ...(values.policy !== undefined ? { policy: parsedPolicy.policy } : {}),\n };\n\n async function main() {\n const { llmock, url } = await startFromConfigFn(config!, overrides);\n\n function shutdown() {\n log(\"Shutting down...\");\n process.removeListener(\"SIGINT\", shutdown);\n process.removeListener(\"SIGTERM\", shutdown);\n llmock.stop().then(\n () => exit(0),\n (err) => {\n logError(`Shutdown error: ${err instanceof Error ? err.message : String(err)}`);\n exit(1);\n },\n );\n }\n // Register BEFORE announcing readiness — see the note in src/cli.ts. A supervisor\n // that reacts to the readiness line must never win a race against this listener.\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n log(`aimock server listening on ${url}`);\n\n if (deps.onReady) {\n deps.onReady({ shutdown });\n }\n }\n\n main().catch((err) => {\n logError(err instanceof Error ? err.message : String(err));\n exit(1);\n });\n}\n\n// Run when executed as a script (not when imported for testing).\n/* v8 ignore start -- entry-point guard, exercised by integration tests */\n// The basenames this module is ever argv[1] under: the `aimock` bin (the\n// package.json \"bin\" name), both build outputs — tsdown.config.ts builds\n// src/aimock-cli.ts in \"esm\" AND \"cjs\" format, which under `\"type\": \"module\"`\n// emits dist/aimock-cli.js and dist/aimock-cli.cjs — and the TypeScript\n// source, run through tsx. Omitting the .cjs made `node dist/aimock-cli.cjs`\n// print nothing and exit 0 despite its shebang and exec bit.\nconst ENTRY_BASENAMES = new Set([\"aimock\", \"aimock-cli.js\", \"aimock-cli.cjs\", \"aimock-cli.ts\"]);\nconst scriptName = process.argv[1] ?? \"\";\nif (ENTRY_BASENAMES.has(basename(scriptName))) {\n runAimockCli();\n}\n/* v8 ignore stop */\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"aimock-cli.d.cts","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":[],"mappings":";;;;UA8BiB,aAAA;EAAA,IAAA,CAAA,EAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;UAKN,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;MACK,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;cAEL,CAAA,EAAA,OAHA,UAGA;mBAAR,CAAA,EAAA,OAFa,eAEb;EAAO,OAAA,CAAA,EAAA,CAAA,GAAA,EAAA;IAQP,QAAA,EAAA,GAAY,GAAA,IAAA;;gBARZ,QAAQ;;;;;;;iBAQR,YAAA,QAAmB"}
1
+ {"version":3,"file":"aimock-cli.d.cts","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":[],"mappings":";;;;UAsCiB,aAAA;EAAA,IAAA,CAAA,EAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;UAKN,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;MACK,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;cAEL,CAAA,EAAA,OAHA,UAGA;mBAAR,CAAA,EAAA,OAFa,eAEb;EAAO,OAAA,CAAA,EAAA,CAAA,GAAA,EAAA;IAQP,QAAA,EAAA,GAAY,GAAA,IAAA;;gBARZ,QAAQ;;;;;;;iBAQR,YAAA,QAAmB"}
@@ -1 +1 @@
1
- {"version":3,"file":"aimock-cli.d.ts","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":[],"mappings":";;;;UA8BiB,aAAA;EAAA,IAAA,CAAA,EAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;UAKN,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;MACK,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;cAEL,CAAA,EAAA,OAHA,UAGA;mBAAR,CAAA,EAAA,OAFa,eAEb;EAAO,OAAA,CAAA,EAAA,CAAA,GAAA,EAAA;IAQP,QAAA,EAAA,GAAY,GAAA,IAAA;;gBARZ,QAAQ;;;;;;;iBAQR,YAAA,QAAmB"}
1
+ {"version":3,"file":"aimock-cli.d.ts","names":[],"sources":["../src/aimock-cli.ts"],"sourcesContent":[],"mappings":";;;;UAsCiB,aAAA;EAAA,IAAA,CAAA,EAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;UAKN,CAAA,EAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,IAAA;MACK,CAAA,EAAA,CAAA,IAAA,EAAA,MAAA,EAAA,GAAA,IAAA;cAEL,CAAA,EAAA,OAHA,UAGA;mBAAR,CAAA,EAAA,OAFa,eAEb;EAAO,OAAA,CAAA,EAAA,CAAA,GAAA,EAAA;IAQP,QAAA,EAAA,GAAY,GAAA,IAAA;;gBARZ,QAAQ;;;;;;;iBAQR,YAAA,QAAmB"}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { loadConfig, startFromConfig } from "./config-loader.js";
2
+ import { loadConfig, parsePolicyFlags, startFromConfig } from "./config-loader.js";
3
3
  import { runConvertCli } from "./convert.js";
4
4
  import { runValidateCli } from "./validate-cli.js";
5
5
  import { basename, resolve } from "node:path";
@@ -20,6 +20,9 @@ Options:
20
20
  instead of serving {} (same as llm.strictToolArguments: true)
21
21
  --responses-tools <mode> OpenAI Responses tool handling: legacy (default) or
22
22
  extended (overrides llm.responsesTools)
23
+ --policy <key=value> Request policy (repeatable): requiredHeaders=off|enforce,
24
+ authErrors=legacy|native, modelCatalog=legacy|native
25
+ Overrides individual llm.policy keys (defaults: off, legacy, legacy)
23
26
  -h, --help Show this help message
24
27
 
25
28
  Subcommands:
@@ -78,6 +81,10 @@ function runAimockCli(deps = {}) {
78
81
  default: false
79
82
  },
80
83
  "responses-tools": { type: "string" },
84
+ policy: {
85
+ type: "string",
86
+ multiple: true
87
+ },
81
88
  help: {
82
89
  type: "boolean",
83
90
  short: "h",
@@ -135,12 +142,19 @@ function runAimockCli(deps = {}) {
135
142
  return;
136
143
  }
137
144
  const responsesTools = responsesToolsFlag;
145
+ const parsedPolicy = parsePolicyFlags(values.policy ?? []);
146
+ if (!parsedPolicy.ok) {
147
+ logError(`${parsedPolicy.error}\n\n${HELP}`);
148
+ exit(1);
149
+ return;
150
+ }
138
151
  const overrides = {
139
152
  port,
140
153
  host,
141
154
  ...values.misbehavior ? { enableMisbehavior: true } : {},
142
155
  ...values["strict-tool-arguments"] ? { strictToolArguments: true } : {},
143
- ...responsesTools !== void 0 ? { responsesTools } : {}
156
+ ...responsesTools !== void 0 ? { responsesTools } : {},
157
+ ...values.policy !== void 0 ? { policy: parsedPolicy.policy } : {}
144
158
  };
145
159
  async function main() {
146
160
  const { llmock, url } = await startFromConfigFn(config, overrides);