@copilotkit/aimock 1.11.0 → 1.13.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 (289) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +24 -4
  4. package/dist/_virtual/_rolldown/runtime.cjs +2 -0
  5. package/dist/_virtual/_rolldown/runtime.js +29 -0
  6. package/dist/agui-types.d.cts.map +1 -1
  7. package/dist/aimock-cli.cjs +16 -0
  8. package/dist/aimock-cli.cjs.map +1 -1
  9. package/dist/aimock-cli.d.cts +2 -0
  10. package/dist/aimock-cli.d.cts.map +1 -1
  11. package/dist/aimock-cli.d.ts +2 -0
  12. package/dist/aimock-cli.d.ts.map +1 -1
  13. package/dist/aimock-cli.js +16 -0
  14. package/dist/aimock-cli.js.map +1 -1
  15. package/dist/bedrock-converse.cjs +2 -0
  16. package/dist/bedrock-converse.cjs.map +1 -1
  17. package/dist/bedrock-converse.d.cts.map +1 -1
  18. package/dist/bedrock-converse.d.ts.map +1 -1
  19. package/dist/bedrock-converse.js +2 -0
  20. package/dist/bedrock-converse.js.map +1 -1
  21. package/dist/bedrock.cjs +2 -0
  22. package/dist/bedrock.cjs.map +1 -1
  23. package/dist/bedrock.d.cts.map +1 -1
  24. package/dist/bedrock.d.ts.map +1 -1
  25. package/dist/bedrock.js +2 -0
  26. package/dist/bedrock.js.map +1 -1
  27. package/dist/cohere.cjs +1 -0
  28. package/dist/cohere.cjs.map +1 -1
  29. package/dist/cohere.js +1 -0
  30. package/dist/cohere.js.map +1 -1
  31. package/dist/config-loader.d.cts.map +1 -1
  32. package/dist/convert-mockllm.cjs +232 -0
  33. package/dist/convert-mockllm.cjs.map +1 -0
  34. package/dist/convert-mockllm.js +230 -0
  35. package/dist/convert-mockllm.js.map +1 -0
  36. package/dist/convert-vidaimock.cjs +110 -0
  37. package/dist/convert-vidaimock.cjs.map +1 -0
  38. package/dist/convert-vidaimock.js +108 -0
  39. package/dist/convert-vidaimock.js.map +1 -0
  40. package/dist/convert.cjs +158 -0
  41. package/dist/convert.cjs.map +1 -0
  42. package/dist/convert.d.cts +16 -0
  43. package/dist/convert.d.cts.map +1 -0
  44. package/dist/convert.d.ts +16 -0
  45. package/dist/convert.d.ts.map +1 -0
  46. package/dist/convert.js +157 -0
  47. package/dist/convert.js.map +1 -0
  48. package/dist/embeddings.cjs +2 -1
  49. package/dist/embeddings.cjs.map +1 -1
  50. package/dist/embeddings.js +2 -1
  51. package/dist/embeddings.js.map +1 -1
  52. package/dist/gemini.cjs +1 -0
  53. package/dist/gemini.cjs.map +1 -1
  54. package/dist/gemini.js +1 -0
  55. package/dist/gemini.js.map +1 -1
  56. package/dist/helpers.cjs +16 -0
  57. package/dist/helpers.cjs.map +1 -1
  58. package/dist/helpers.d.cts +6 -2
  59. package/dist/helpers.d.cts.map +1 -1
  60. package/dist/helpers.d.ts +6 -2
  61. package/dist/helpers.d.ts.map +1 -1
  62. package/dist/helpers.js +13 -1
  63. package/dist/helpers.js.map +1 -1
  64. package/dist/images.cjs +166 -0
  65. package/dist/images.cjs.map +1 -0
  66. package/dist/images.d.cts +11 -0
  67. package/dist/images.d.cts.map +1 -0
  68. package/dist/images.d.ts +11 -0
  69. package/dist/images.d.ts.map +1 -0
  70. package/dist/images.js +166 -0
  71. package/dist/images.js.map +1 -0
  72. package/dist/index.cjs +13 -0
  73. package/dist/index.d.cts +7 -3
  74. package/dist/index.d.ts +7 -3
  75. package/dist/index.js +6 -2
  76. package/dist/jest.cjs +70 -0
  77. package/dist/jest.cjs.map +1 -0
  78. package/dist/jest.d.cts +33 -0
  79. package/dist/jest.d.cts.map +1 -0
  80. package/dist/jest.d.ts +33 -0
  81. package/dist/jest.d.ts.map +1 -0
  82. package/dist/jest.js +67 -0
  83. package/dist/jest.js.map +1 -0
  84. package/dist/llmock.cjs +37 -1
  85. package/dist/llmock.cjs.map +1 -1
  86. package/dist/llmock.d.cts +5 -1
  87. package/dist/llmock.d.cts.map +1 -1
  88. package/dist/llmock.d.ts +5 -1
  89. package/dist/llmock.d.ts.map +1 -1
  90. package/dist/llmock.js +37 -1
  91. package/dist/llmock.js.map +1 -1
  92. package/dist/messages.cjs +1 -0
  93. package/dist/messages.cjs.map +1 -1
  94. package/dist/messages.js +1 -0
  95. package/dist/messages.js.map +1 -1
  96. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.2.4/node_modules/@vitest/pretty-format/dist/index.cjs +934 -0
  97. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.2.4/node_modules/@vitest/pretty-format/dist/index.cjs.map +1 -0
  98. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.2.4/node_modules/@vitest/pretty-format/dist/index.js +934 -0
  99. package/dist/node_modules/.pnpm/@vitest_pretty-format@3.2.4/node_modules/@vitest/pretty-format/dist/index.js.map +1 -0
  100. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.cjs +1051 -0
  101. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.cjs.map +1 -0
  102. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js +1042 -0
  103. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js.map +1 -0
  104. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/index.cjs +1 -0
  105. package/dist/node_modules/.pnpm/@vitest_runner@3.2.4/node_modules/@vitest/runner/dist/index.js +3 -0
  106. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.cjs +96 -0
  107. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.cjs.map +1 -0
  108. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js +93 -0
  109. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.js.map +1 -0
  110. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/helpers.cjs +49 -0
  111. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/helpers.cjs.map +1 -0
  112. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/helpers.js +43 -0
  113. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/helpers.js.map +1 -0
  114. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/index.cjs +456 -0
  115. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/index.cjs.map +1 -0
  116. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/index.js +456 -0
  117. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/index.js.map +1 -0
  118. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/source-map.cjs +170 -0
  119. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/source-map.cjs.map +1 -0
  120. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/source-map.js +169 -0
  121. package/dist/node_modules/.pnpm/@vitest_utils@3.2.4/node_modules/@vitest/utils/dist/source-map.js.map +1 -0
  122. package/dist/node_modules/.pnpm/js-tokens@9.0.1/node_modules/js-tokens/index.cjs +388 -0
  123. package/dist/node_modules/.pnpm/js-tokens@9.0.1/node_modules/js-tokens/index.cjs.map +1 -0
  124. package/dist/node_modules/.pnpm/js-tokens@9.0.1/node_modules/js-tokens/index.js +385 -0
  125. package/dist/node_modules/.pnpm/js-tokens@9.0.1/node_modules/js-tokens/index.js.map +1 -0
  126. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.cjs +12 -0
  127. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.cjs.map +1 -0
  128. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js +12 -0
  129. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/arguments.js.map +1 -0
  130. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.cjs +17 -0
  131. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.cjs.map +1 -0
  132. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js +17 -0
  133. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/array.js.map +1 -0
  134. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.cjs +12 -0
  135. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.cjs.map +1 -0
  136. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js +12 -0
  137. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/bigint.js.map +1 -0
  138. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.cjs +16 -0
  139. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.cjs.map +1 -0
  140. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js +16 -0
  141. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/class.js.map +1 -0
  142. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.cjs +14 -0
  143. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.cjs.map +1 -0
  144. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js +14 -0
  145. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/date.js.map +1 -0
  146. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.cjs +35 -0
  147. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.cjs.map +1 -0
  148. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js +35 -0
  149. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/error.js.map +1 -0
  150. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.cjs +13 -0
  151. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.cjs.map +1 -0
  152. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js +13 -0
  153. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/function.js.map +1 -0
  154. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.cjs +128 -0
  155. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.cjs.map +1 -0
  156. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js +123 -0
  157. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/helpers.js.map +1 -0
  158. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.cjs +41 -0
  159. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.cjs.map +1 -0
  160. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js +40 -0
  161. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/html.js.map +1 -0
  162. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.cjs +100 -0
  163. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.cjs.map +1 -0
  164. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js +100 -0
  165. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/index.js.map +1 -0
  166. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.cjs +26 -0
  167. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.cjs.map +1 -0
  168. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js +26 -0
  169. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/map.js.map +1 -0
  170. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.cjs +15 -0
  171. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.cjs.map +1 -0
  172. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js +15 -0
  173. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/number.js.map +1 -0
  174. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.cjs +22 -0
  175. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.cjs.map +1 -0
  176. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js +22 -0
  177. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/object.js.map +1 -0
  178. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.cjs +7 -0
  179. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.cjs.map +1 -0
  180. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js +6 -0
  181. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/promise.js.map +1 -0
  182. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.cjs +13 -0
  183. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.cjs.map +1 -0
  184. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js +13 -0
  185. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/regexp.js.map +1 -0
  186. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.cjs +19 -0
  187. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.cjs.map +1 -0
  188. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js +19 -0
  189. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/set.js.map +1 -0
  190. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.cjs +26 -0
  191. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.cjs.map +1 -0
  192. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js +26 -0
  193. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/string.js.map +1 -0
  194. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.cjs +10 -0
  195. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.cjs.map +1 -0
  196. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js +9 -0
  197. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/symbol.js.map +1 -0
  198. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.cjs +31 -0
  199. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.cjs.map +1 -0
  200. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js +31 -0
  201. package/dist/node_modules/.pnpm/loupe@3.2.1/node_modules/loupe/lib/typedarray.js.map +1 -0
  202. package/dist/node_modules/.pnpm/strip-literal@3.1.0/node_modules/strip-literal/dist/index.cjs +52 -0
  203. package/dist/node_modules/.pnpm/strip-literal@3.1.0/node_modules/strip-literal/dist/index.cjs.map +1 -0
  204. package/dist/node_modules/.pnpm/strip-literal@3.1.0/node_modules/strip-literal/dist/index.js +52 -0
  205. package/dist/node_modules/.pnpm/strip-literal@3.1.0/node_modules/strip-literal/dist/index.js.map +1 -0
  206. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.cjs +83 -0
  207. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.cjs.map +1 -0
  208. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js +82 -0
  209. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.js.map +1 -0
  210. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.cjs +10 -0
  211. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.cjs.map +1 -0
  212. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.js +10 -0
  213. package/dist/node_modules/.pnpm/tinyrainbow@2.0.0/node_modules/tinyrainbow/dist/node.js.map +1 -0
  214. package/dist/ollama.cjs +2 -0
  215. package/dist/ollama.cjs.map +1 -1
  216. package/dist/ollama.d.cts.map +1 -1
  217. package/dist/ollama.d.ts.map +1 -1
  218. package/dist/ollama.js +2 -0
  219. package/dist/ollama.js.map +1 -1
  220. package/dist/recorder.cjs +50 -7
  221. package/dist/recorder.cjs.map +1 -1
  222. package/dist/recorder.js +50 -7
  223. package/dist/recorder.js.map +1 -1
  224. package/dist/responses.cjs +1 -0
  225. package/dist/responses.cjs.map +1 -1
  226. package/dist/responses.js +1 -0
  227. package/dist/responses.js.map +1 -1
  228. package/dist/router.cjs +8 -0
  229. package/dist/router.cjs.map +1 -1
  230. package/dist/router.d.cts.map +1 -1
  231. package/dist/router.d.ts.map +1 -1
  232. package/dist/router.js +9 -0
  233. package/dist/router.js.map +1 -1
  234. package/dist/server.cjs +80 -3
  235. package/dist/server.cjs.map +1 -1
  236. package/dist/server.d.cts +2 -0
  237. package/dist/server.d.cts.map +1 -1
  238. package/dist/server.d.ts +2 -0
  239. package/dist/server.d.ts.map +1 -1
  240. package/dist/server.js +80 -3
  241. package/dist/server.js.map +1 -1
  242. package/dist/speech.cjs +144 -0
  243. package/dist/speech.cjs.map +1 -0
  244. package/dist/speech.d.cts +11 -0
  245. package/dist/speech.d.cts.map +1 -0
  246. package/dist/speech.d.ts +11 -0
  247. package/dist/speech.d.ts.map +1 -0
  248. package/dist/speech.js +144 -0
  249. package/dist/speech.js.map +1 -0
  250. package/dist/transcription.cjs +134 -0
  251. package/dist/transcription.cjs.map +1 -0
  252. package/dist/transcription.d.cts +11 -0
  253. package/dist/transcription.d.cts.map +1 -0
  254. package/dist/transcription.d.ts +11 -0
  255. package/dist/transcription.d.ts.map +1 -0
  256. package/dist/transcription.js +134 -0
  257. package/dist/transcription.js.map +1 -0
  258. package/dist/types.d.cts +44 -2
  259. package/dist/types.d.cts.map +1 -1
  260. package/dist/types.d.ts +44 -2
  261. package/dist/types.d.ts.map +1 -1
  262. package/dist/video.cjs +196 -0
  263. package/dist/video.cjs.map +1 -0
  264. package/dist/video.d.cts +14 -0
  265. package/dist/video.d.cts.map +1 -0
  266. package/dist/video.d.ts +14 -0
  267. package/dist/video.d.ts.map +1 -0
  268. package/dist/video.js +195 -0
  269. package/dist/video.js.map +1 -0
  270. package/dist/vitest.cjs +80 -0
  271. package/dist/vitest.cjs.map +1 -0
  272. package/dist/vitest.d.cts +30 -0
  273. package/dist/vitest.d.cts.map +1 -0
  274. package/dist/vitest.d.ts +30 -0
  275. package/dist/vitest.d.ts.map +1 -0
  276. package/dist/vitest.js +77 -0
  277. package/dist/vitest.js.map +1 -0
  278. package/fixtures/examples/a2a/a2a-config.json +42 -0
  279. package/fixtures/examples/agui/agui-text-response.json +35 -0
  280. package/fixtures/examples/chaos/chaos-config.json +10 -0
  281. package/fixtures/examples/full-suite.json +116 -0
  282. package/fixtures/examples/llm/embeddings.json +10 -0
  283. package/fixtures/examples/llm/error-injection.json +15 -0
  284. package/fixtures/examples/llm/sequential-responses.json +20 -0
  285. package/fixtures/examples/llm/streaming-physics.json +15 -0
  286. package/fixtures/examples/mcp/mcp-config.json +26 -0
  287. package/fixtures/examples/record-replay/record-config.json +11 -0
  288. package/fixtures/examples/vector/vector-config.json +34 -0
  289. package/package.json +60 -2
@@ -0,0 +1,158 @@
1
+ const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
2
+ const require_convert_vidaimock = require('./convert-vidaimock.cjs');
3
+ const require_convert_mockllm = require('./convert-mockllm.cjs');
4
+ let node_path = require("node:path");
5
+ let node_fs = require("node:fs");
6
+
7
+ //#region src/convert.ts
8
+ /**
9
+ * CLI dispatcher for `aimock convert` subcommands.
10
+ *
11
+ * Delegates to the converter modules in src/convert-vidaimock.ts and
12
+ * src/convert-mockllm.ts.
13
+ */
14
+ const CONVERT_HELP = `
15
+ Usage: aimock convert <format> <input> [output]
16
+
17
+ Formats:
18
+ vidaimock Convert VidaiMock Tera templates to aimock JSON
19
+ mockllm Convert mock-llm YAML config to aimock JSON
20
+
21
+ Examples:
22
+ aimock convert vidaimock ./templates/ ./fixtures/
23
+ aimock convert mockllm ./config.yaml ./fixtures/converted.json
24
+ `.trim();
25
+ function runConvertCli(deps) {
26
+ const { argv, log, logError, exit } = deps;
27
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
28
+ if (argv.length === 0) {
29
+ logError(CONVERT_HELP);
30
+ exit(1);
31
+ } else {
32
+ log(CONVERT_HELP);
33
+ exit(0);
34
+ }
35
+ return;
36
+ }
37
+ const format = argv[0];
38
+ const inputArg = argv[1];
39
+ const outputArg = argv[2];
40
+ if (!inputArg) {
41
+ logError(`Error: missing <input> argument.\n\n${CONVERT_HELP}`);
42
+ exit(1);
43
+ return;
44
+ }
45
+ switch (format) {
46
+ case "vidaimock":
47
+ runVidaimockConvert(inputArg, outputArg, {
48
+ log,
49
+ logError,
50
+ exit
51
+ });
52
+ break;
53
+ case "mockllm":
54
+ runMockllmConvert(inputArg, outputArg, {
55
+ log,
56
+ logError,
57
+ exit
58
+ });
59
+ break;
60
+ default:
61
+ logError(`Error: unknown format "${format}".\n\n${CONVERT_HELP}`);
62
+ exit(1);
63
+ }
64
+ }
65
+ function runVidaimockConvert(inputArg, outputArg, io) {
66
+ const inputPath = (0, node_path.resolve)(inputArg);
67
+ const outputPath = outputArg ? (0, node_path.resolve)(outputArg) : null;
68
+ let fixtures;
69
+ try {
70
+ if ((0, node_fs.statSync)(inputPath).isDirectory()) fixtures = require_convert_vidaimock.convertDirectory(inputPath);
71
+ else {
72
+ const single = require_convert_vidaimock.convertFile(inputPath);
73
+ fixtures = single ? [single] : [];
74
+ }
75
+ } catch (err) {
76
+ io.logError(`Error reading input path: ${inputPath}`);
77
+ io.logError(err instanceof Error ? err.message : String(err));
78
+ io.exit(1);
79
+ return;
80
+ }
81
+ if (fixtures.length === 0) {
82
+ io.logError("No fixtures produced — check that the input contains valid VidaiMock templates.");
83
+ io.exit(1);
84
+ return;
85
+ }
86
+ const output = { fixtures };
87
+ const json = JSON.stringify(output, null, 2) + "\n";
88
+ if (outputPath) {
89
+ try {
90
+ (0, node_fs.writeFileSync)(outputPath, json, "utf-8");
91
+ } catch (err) {
92
+ io.logError(`Error writing output: ${err.message}`);
93
+ io.exit(1);
94
+ return;
95
+ }
96
+ io.log(`Wrote ${fixtures.length} fixture(s) to ${outputPath}`);
97
+ } else io.log(json.trimEnd());
98
+ }
99
+ function runMockllmConvert(inputArg, outputArg, io) {
100
+ const inputPath = (0, node_path.resolve)(inputArg);
101
+ const outputPath = outputArg ? (0, node_path.resolve)(outputArg) : null;
102
+ let yamlContent;
103
+ try {
104
+ yamlContent = (0, node_fs.readFileSync)(inputPath, "utf-8");
105
+ } catch (err) {
106
+ io.logError(`Error reading input file: ${err.message}`);
107
+ io.exit(1);
108
+ return;
109
+ }
110
+ const parsed = require_convert_mockllm.parseSimpleYaml(yamlContent);
111
+ if (!parsed || typeof parsed !== "object") {
112
+ io.logError("Error: could not parse YAML config");
113
+ io.exit(1);
114
+ return;
115
+ }
116
+ const result = require_convert_mockllm.convertConfig(parsed);
117
+ const fixtureJson = JSON.stringify({ fixtures: result.fixtures }, null, 2);
118
+ if (outputPath) {
119
+ try {
120
+ (0, node_fs.writeFileSync)(outputPath, fixtureJson + "\n", "utf-8");
121
+ } catch (err) {
122
+ io.logError(`Error writing output: ${err.message}`);
123
+ io.exit(1);
124
+ return;
125
+ }
126
+ io.log(`Wrote fixtures to ${outputPath}`);
127
+ if (result.mcpTools) {
128
+ const configPath = outputPath.endsWith(".json") ? outputPath.replace(/\.json$/, ".aimock.json") : outputPath + ".aimock.json";
129
+ const aimockConfig = {
130
+ llm: { fixtures: outputPath },
131
+ mcp: { tools: result.mcpTools.map((t) => ({
132
+ name: t.name,
133
+ description: t.description ?? "",
134
+ inputSchema: t.inputSchema ?? {},
135
+ result: `Mock result for ${t.name}`
136
+ })) }
137
+ };
138
+ try {
139
+ (0, node_fs.writeFileSync)(configPath, JSON.stringify(aimockConfig, null, 2) + "\n", "utf-8");
140
+ } catch (err) {
141
+ io.logError(`Error writing config: ${err.message}`);
142
+ io.exit(1);
143
+ return;
144
+ }
145
+ io.log(`Wrote aimock config with MCP tools to ${configPath}`);
146
+ }
147
+ } else {
148
+ io.log(fixtureJson);
149
+ if (result.mcpTools) {
150
+ io.log("\n--- MCP Tools (aimock config format) ---");
151
+ io.log(JSON.stringify({ mcp: { tools: result.mcpTools } }, null, 2));
152
+ }
153
+ }
154
+ }
155
+
156
+ //#endregion
157
+ exports.runConvertCli = runConvertCli;
158
+ //# sourceMappingURL=convert.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.cjs","names":["convertDirectory","convertFile","parseSimpleYaml","convertConfig"],"sources":["../src/convert.ts"],"sourcesContent":["/**\n * CLI dispatcher for `aimock convert` subcommands.\n *\n * Delegates to the converter modules in src/convert-vidaimock.ts and\n * src/convert-mockllm.ts.\n */\n\nimport { readFileSync, writeFileSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { convertFile, convertDirectory, type AimockFixtureFile } from \"./convert-vidaimock.js\";\nimport { parseSimpleYaml, convertConfig, type MockLLMConfig } from \"./convert-mockllm.js\";\n\nconst CONVERT_HELP = `\nUsage: aimock convert <format> <input> [output]\n\nFormats:\n vidaimock Convert VidaiMock Tera templates to aimock JSON\n mockllm Convert mock-llm YAML config to aimock JSON\n\nExamples:\n aimock convert vidaimock ./templates/ ./fixtures/\n aimock convert mockllm ./config.yaml ./fixtures/converted.json\n`.trim();\n\nexport interface ConvertCliDeps {\n argv: string[];\n log: (msg: string) => void;\n logError: (msg: string) => void;\n exit: (code: number) => void;\n}\n\nexport function runConvertCli(deps: ConvertCliDeps): void {\n const { argv, log, logError, exit } = deps;\n\n if (argv.length === 0 || argv[0] === \"--help\" || argv[0] === \"-h\") {\n if (argv.length === 0) {\n logError(CONVERT_HELP);\n exit(1);\n } else {\n log(CONVERT_HELP);\n exit(0);\n }\n return;\n }\n\n const format = argv[0];\n const inputArg = argv[1];\n const outputArg = argv[2];\n\n if (!inputArg) {\n logError(`Error: missing <input> argument.\\n\\n${CONVERT_HELP}`);\n exit(1);\n return;\n }\n\n switch (format) {\n case \"vidaimock\":\n runVidaimockConvert(inputArg, outputArg, { log, logError, exit });\n break;\n case \"mockllm\":\n runMockllmConvert(inputArg, outputArg, { log, logError, exit });\n break;\n default:\n logError(`Error: unknown format \"${format}\".\\n\\n${CONVERT_HELP}`);\n exit(1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// VidaiMock converter\n// ---------------------------------------------------------------------------\n\nfunction runVidaimockConvert(\n inputArg: string,\n outputArg: string | undefined,\n io: { log: (msg: string) => void; logError: (msg: string) => void; exit: (code: number) => void },\n): void {\n const inputPath = resolve(inputArg);\n const outputPath = outputArg ? resolve(outputArg) : null;\n\n let fixtures: AimockFixtureFile[\"fixtures\"];\n\n try {\n const stat = statSync(inputPath);\n if (stat.isDirectory()) {\n fixtures = convertDirectory(inputPath);\n } else {\n const single = convertFile(inputPath);\n fixtures = single ? [single] : [];\n }\n } catch (err) {\n io.logError(`Error reading input path: ${inputPath}`);\n io.logError(err instanceof Error ? err.message : String(err));\n io.exit(1);\n return;\n }\n\n if (fixtures.length === 0) {\n io.logError(\"No fixtures produced — check that the input contains valid VidaiMock templates.\");\n io.exit(1);\n return;\n }\n\n const output: AimockFixtureFile = { fixtures };\n const json = JSON.stringify(output, null, 2) + \"\\n\";\n\n if (outputPath) {\n try {\n writeFileSync(outputPath, json, \"utf-8\");\n } catch (err) {\n io.logError(`Error writing output: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote ${fixtures.length} fixture(s) to ${outputPath}`);\n } else {\n io.log(json.trimEnd());\n }\n}\n\n// ---------------------------------------------------------------------------\n// mock-llm converter\n// ---------------------------------------------------------------------------\n\nfunction runMockllmConvert(\n inputArg: string,\n outputArg: string | undefined,\n io: { log: (msg: string) => void; logError: (msg: string) => void; exit: (code: number) => void },\n): void {\n const inputPath = resolve(inputArg);\n const outputPath = outputArg ? resolve(outputArg) : null;\n\n let yamlContent: string;\n try {\n yamlContent = readFileSync(inputPath, \"utf-8\");\n } catch (err) {\n io.logError(`Error reading input file: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n\n const parsed = parseSimpleYaml(yamlContent) as MockLLMConfig | null;\n if (!parsed || typeof parsed !== \"object\") {\n io.logError(\"Error: could not parse YAML config\");\n io.exit(1);\n return;\n }\n\n const result = convertConfig(parsed);\n const fixtureJson = JSON.stringify({ fixtures: result.fixtures }, null, 2);\n\n if (outputPath) {\n try {\n writeFileSync(outputPath, fixtureJson + \"\\n\", \"utf-8\");\n } catch (err) {\n io.logError(`Error writing output: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote fixtures to ${outputPath}`);\n\n if (result.mcpTools) {\n const configPath = outputPath.endsWith(\".json\")\n ? outputPath.replace(/\\.json$/, \".aimock.json\")\n : outputPath + \".aimock.json\";\n const aimockConfig = {\n llm: { fixtures: outputPath },\n mcp: {\n tools: result.mcpTools.map((t) => ({\n name: t.name,\n description: t.description ?? \"\",\n inputSchema: t.inputSchema ?? {},\n result: `Mock result for ${t.name}`,\n })),\n },\n };\n try {\n writeFileSync(configPath, JSON.stringify(aimockConfig, null, 2) + \"\\n\", \"utf-8\");\n } catch (err) {\n io.logError(`Error writing config: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote aimock config with MCP tools to ${configPath}`);\n }\n } else {\n io.log(fixtureJson);\n\n if (result.mcpTools) {\n io.log(\"\\n--- MCP Tools (aimock config format) ---\");\n io.log(JSON.stringify({ mcp: { tools: result.mcpTools } }, null, 2));\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ //#region src/convert.d.ts
2
+ /**
3
+ * CLI dispatcher for `aimock convert` subcommands.
4
+ *
5
+ * Delegates to the converter modules in src/convert-vidaimock.ts and
6
+ * src/convert-mockllm.ts.
7
+ */
8
+ interface ConvertCliDeps {
9
+ argv: string[];
10
+ log: (msg: string) => void;
11
+ logError: (msg: string) => void;
12
+ exit: (code: number) => void;
13
+ }
14
+ //#endregion
15
+ export { ConvertCliDeps };
16
+ //# sourceMappingURL=convert.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.d.cts","names":[],"sources":["../src/convert.ts"],"sourcesContent":[],"mappings":";;AAwBA;;;;;UAAiB,cAAA"}
@@ -0,0 +1,16 @@
1
+ //#region src/convert.d.ts
2
+ /**
3
+ * CLI dispatcher for `aimock convert` subcommands.
4
+ *
5
+ * Delegates to the converter modules in src/convert-vidaimock.ts and
6
+ * src/convert-mockllm.ts.
7
+ */
8
+ interface ConvertCliDeps {
9
+ argv: string[];
10
+ log: (msg: string) => void;
11
+ logError: (msg: string) => void;
12
+ exit: (code: number) => void;
13
+ }
14
+ //#endregion
15
+ export { ConvertCliDeps };
16
+ //# sourceMappingURL=convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.d.ts","names":[],"sources":["../src/convert.ts"],"sourcesContent":[],"mappings":";;AAwBA;;;;;UAAiB,cAAA"}
@@ -0,0 +1,157 @@
1
+ import { convertDirectory, convertFile } from "./convert-vidaimock.js";
2
+ import { convertConfig, parseSimpleYaml } from "./convert-mockllm.js";
3
+ import { resolve } from "node:path";
4
+ import { readFileSync, statSync, writeFileSync } from "node:fs";
5
+
6
+ //#region src/convert.ts
7
+ /**
8
+ * CLI dispatcher for `aimock convert` subcommands.
9
+ *
10
+ * Delegates to the converter modules in src/convert-vidaimock.ts and
11
+ * src/convert-mockllm.ts.
12
+ */
13
+ const CONVERT_HELP = `
14
+ Usage: aimock convert <format> <input> [output]
15
+
16
+ Formats:
17
+ vidaimock Convert VidaiMock Tera templates to aimock JSON
18
+ mockllm Convert mock-llm YAML config to aimock JSON
19
+
20
+ Examples:
21
+ aimock convert vidaimock ./templates/ ./fixtures/
22
+ aimock convert mockllm ./config.yaml ./fixtures/converted.json
23
+ `.trim();
24
+ function runConvertCli(deps) {
25
+ const { argv, log, logError, exit } = deps;
26
+ if (argv.length === 0 || argv[0] === "--help" || argv[0] === "-h") {
27
+ if (argv.length === 0) {
28
+ logError(CONVERT_HELP);
29
+ exit(1);
30
+ } else {
31
+ log(CONVERT_HELP);
32
+ exit(0);
33
+ }
34
+ return;
35
+ }
36
+ const format = argv[0];
37
+ const inputArg = argv[1];
38
+ const outputArg = argv[2];
39
+ if (!inputArg) {
40
+ logError(`Error: missing <input> argument.\n\n${CONVERT_HELP}`);
41
+ exit(1);
42
+ return;
43
+ }
44
+ switch (format) {
45
+ case "vidaimock":
46
+ runVidaimockConvert(inputArg, outputArg, {
47
+ log,
48
+ logError,
49
+ exit
50
+ });
51
+ break;
52
+ case "mockllm":
53
+ runMockllmConvert(inputArg, outputArg, {
54
+ log,
55
+ logError,
56
+ exit
57
+ });
58
+ break;
59
+ default:
60
+ logError(`Error: unknown format "${format}".\n\n${CONVERT_HELP}`);
61
+ exit(1);
62
+ }
63
+ }
64
+ function runVidaimockConvert(inputArg, outputArg, io) {
65
+ const inputPath = resolve(inputArg);
66
+ const outputPath = outputArg ? resolve(outputArg) : null;
67
+ let fixtures;
68
+ try {
69
+ if (statSync(inputPath).isDirectory()) fixtures = convertDirectory(inputPath);
70
+ else {
71
+ const single = convertFile(inputPath);
72
+ fixtures = single ? [single] : [];
73
+ }
74
+ } catch (err) {
75
+ io.logError(`Error reading input path: ${inputPath}`);
76
+ io.logError(err instanceof Error ? err.message : String(err));
77
+ io.exit(1);
78
+ return;
79
+ }
80
+ if (fixtures.length === 0) {
81
+ io.logError("No fixtures produced — check that the input contains valid VidaiMock templates.");
82
+ io.exit(1);
83
+ return;
84
+ }
85
+ const output = { fixtures };
86
+ const json = JSON.stringify(output, null, 2) + "\n";
87
+ if (outputPath) {
88
+ try {
89
+ writeFileSync(outputPath, json, "utf-8");
90
+ } catch (err) {
91
+ io.logError(`Error writing output: ${err.message}`);
92
+ io.exit(1);
93
+ return;
94
+ }
95
+ io.log(`Wrote ${fixtures.length} fixture(s) to ${outputPath}`);
96
+ } else io.log(json.trimEnd());
97
+ }
98
+ function runMockllmConvert(inputArg, outputArg, io) {
99
+ const inputPath = resolve(inputArg);
100
+ const outputPath = outputArg ? resolve(outputArg) : null;
101
+ let yamlContent;
102
+ try {
103
+ yamlContent = readFileSync(inputPath, "utf-8");
104
+ } catch (err) {
105
+ io.logError(`Error reading input file: ${err.message}`);
106
+ io.exit(1);
107
+ return;
108
+ }
109
+ const parsed = parseSimpleYaml(yamlContent);
110
+ if (!parsed || typeof parsed !== "object") {
111
+ io.logError("Error: could not parse YAML config");
112
+ io.exit(1);
113
+ return;
114
+ }
115
+ const result = convertConfig(parsed);
116
+ const fixtureJson = JSON.stringify({ fixtures: result.fixtures }, null, 2);
117
+ if (outputPath) {
118
+ try {
119
+ writeFileSync(outputPath, fixtureJson + "\n", "utf-8");
120
+ } catch (err) {
121
+ io.logError(`Error writing output: ${err.message}`);
122
+ io.exit(1);
123
+ return;
124
+ }
125
+ io.log(`Wrote fixtures to ${outputPath}`);
126
+ if (result.mcpTools) {
127
+ const configPath = outputPath.endsWith(".json") ? outputPath.replace(/\.json$/, ".aimock.json") : outputPath + ".aimock.json";
128
+ const aimockConfig = {
129
+ llm: { fixtures: outputPath },
130
+ mcp: { tools: result.mcpTools.map((t) => ({
131
+ name: t.name,
132
+ description: t.description ?? "",
133
+ inputSchema: t.inputSchema ?? {},
134
+ result: `Mock result for ${t.name}`
135
+ })) }
136
+ };
137
+ try {
138
+ writeFileSync(configPath, JSON.stringify(aimockConfig, null, 2) + "\n", "utf-8");
139
+ } catch (err) {
140
+ io.logError(`Error writing config: ${err.message}`);
141
+ io.exit(1);
142
+ return;
143
+ }
144
+ io.log(`Wrote aimock config with MCP tools to ${configPath}`);
145
+ }
146
+ } else {
147
+ io.log(fixtureJson);
148
+ if (result.mcpTools) {
149
+ io.log("\n--- MCP Tools (aimock config format) ---");
150
+ io.log(JSON.stringify({ mcp: { tools: result.mcpTools } }, null, 2));
151
+ }
152
+ }
153
+ }
154
+
155
+ //#endregion
156
+ export { runConvertCli };
157
+ //# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.js","names":[],"sources":["../src/convert.ts"],"sourcesContent":["/**\n * CLI dispatcher for `aimock convert` subcommands.\n *\n * Delegates to the converter modules in src/convert-vidaimock.ts and\n * src/convert-mockllm.ts.\n */\n\nimport { readFileSync, writeFileSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { convertFile, convertDirectory, type AimockFixtureFile } from \"./convert-vidaimock.js\";\nimport { parseSimpleYaml, convertConfig, type MockLLMConfig } from \"./convert-mockllm.js\";\n\nconst CONVERT_HELP = `\nUsage: aimock convert <format> <input> [output]\n\nFormats:\n vidaimock Convert VidaiMock Tera templates to aimock JSON\n mockllm Convert mock-llm YAML config to aimock JSON\n\nExamples:\n aimock convert vidaimock ./templates/ ./fixtures/\n aimock convert mockllm ./config.yaml ./fixtures/converted.json\n`.trim();\n\nexport interface ConvertCliDeps {\n argv: string[];\n log: (msg: string) => void;\n logError: (msg: string) => void;\n exit: (code: number) => void;\n}\n\nexport function runConvertCli(deps: ConvertCliDeps): void {\n const { argv, log, logError, exit } = deps;\n\n if (argv.length === 0 || argv[0] === \"--help\" || argv[0] === \"-h\") {\n if (argv.length === 0) {\n logError(CONVERT_HELP);\n exit(1);\n } else {\n log(CONVERT_HELP);\n exit(0);\n }\n return;\n }\n\n const format = argv[0];\n const inputArg = argv[1];\n const outputArg = argv[2];\n\n if (!inputArg) {\n logError(`Error: missing <input> argument.\\n\\n${CONVERT_HELP}`);\n exit(1);\n return;\n }\n\n switch (format) {\n case \"vidaimock\":\n runVidaimockConvert(inputArg, outputArg, { log, logError, exit });\n break;\n case \"mockllm\":\n runMockllmConvert(inputArg, outputArg, { log, logError, exit });\n break;\n default:\n logError(`Error: unknown format \"${format}\".\\n\\n${CONVERT_HELP}`);\n exit(1);\n }\n}\n\n// ---------------------------------------------------------------------------\n// VidaiMock converter\n// ---------------------------------------------------------------------------\n\nfunction runVidaimockConvert(\n inputArg: string,\n outputArg: string | undefined,\n io: { log: (msg: string) => void; logError: (msg: string) => void; exit: (code: number) => void },\n): void {\n const inputPath = resolve(inputArg);\n const outputPath = outputArg ? resolve(outputArg) : null;\n\n let fixtures: AimockFixtureFile[\"fixtures\"];\n\n try {\n const stat = statSync(inputPath);\n if (stat.isDirectory()) {\n fixtures = convertDirectory(inputPath);\n } else {\n const single = convertFile(inputPath);\n fixtures = single ? [single] : [];\n }\n } catch (err) {\n io.logError(`Error reading input path: ${inputPath}`);\n io.logError(err instanceof Error ? err.message : String(err));\n io.exit(1);\n return;\n }\n\n if (fixtures.length === 0) {\n io.logError(\"No fixtures produced — check that the input contains valid VidaiMock templates.\");\n io.exit(1);\n return;\n }\n\n const output: AimockFixtureFile = { fixtures };\n const json = JSON.stringify(output, null, 2) + \"\\n\";\n\n if (outputPath) {\n try {\n writeFileSync(outputPath, json, \"utf-8\");\n } catch (err) {\n io.logError(`Error writing output: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote ${fixtures.length} fixture(s) to ${outputPath}`);\n } else {\n io.log(json.trimEnd());\n }\n}\n\n// ---------------------------------------------------------------------------\n// mock-llm converter\n// ---------------------------------------------------------------------------\n\nfunction runMockllmConvert(\n inputArg: string,\n outputArg: string | undefined,\n io: { log: (msg: string) => void; logError: (msg: string) => void; exit: (code: number) => void },\n): void {\n const inputPath = resolve(inputArg);\n const outputPath = outputArg ? resolve(outputArg) : null;\n\n let yamlContent: string;\n try {\n yamlContent = readFileSync(inputPath, \"utf-8\");\n } catch (err) {\n io.logError(`Error reading input file: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n\n const parsed = parseSimpleYaml(yamlContent) as MockLLMConfig | null;\n if (!parsed || typeof parsed !== \"object\") {\n io.logError(\"Error: could not parse YAML config\");\n io.exit(1);\n return;\n }\n\n const result = convertConfig(parsed);\n const fixtureJson = JSON.stringify({ fixtures: result.fixtures }, null, 2);\n\n if (outputPath) {\n try {\n writeFileSync(outputPath, fixtureJson + \"\\n\", \"utf-8\");\n } catch (err) {\n io.logError(`Error writing output: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote fixtures to ${outputPath}`);\n\n if (result.mcpTools) {\n const configPath = outputPath.endsWith(\".json\")\n ? outputPath.replace(/\\.json$/, \".aimock.json\")\n : outputPath + \".aimock.json\";\n const aimockConfig = {\n llm: { fixtures: outputPath },\n mcp: {\n tools: result.mcpTools.map((t) => ({\n name: t.name,\n description: t.description ?? \"\",\n inputSchema: t.inputSchema ?? {},\n result: `Mock result for ${t.name}`,\n })),\n },\n };\n try {\n writeFileSync(configPath, JSON.stringify(aimockConfig, null, 2) + \"\\n\", \"utf-8\");\n } catch (err) {\n io.logError(`Error writing config: ${(err as Error).message}`);\n io.exit(1);\n return;\n }\n io.log(`Wrote aimock config with MCP tools to ${configPath}`);\n }\n } else {\n io.log(fixtureJson);\n\n if (result.mcpTools) {\n io.log(\"\\n--- MCP Tools (aimock config format) ---\");\n io.log(JSON.stringify({ mcp: { tools: result.mcpTools } }, null, 2));\n }\n }\n}\n"],"mappings":"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"}
@@ -34,7 +34,8 @@ async function handleEmbeddings(req, res, raw, fixtures, journal, defaults, setC
34
34
  const syntheticReq = {
35
35
  model: embeddingReq.model,
36
36
  messages: [],
37
- embeddingInput: combinedInput
37
+ embeddingInput: combinedInput,
38
+ _endpointType: "embedding"
38
39
  };
39
40
  const testId = require_helpers.getTestId(req);
40
41
  const fixture = require_router.matchFixture(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings.cjs","names":["flattenHeaders","getTestId","matchFixture","applyChaos","isErrorResponse","isEmbeddingResponse","buildEmbeddingResponse","proxyAndRecord","generateDeterministicEmbedding"],"sources":["../src/embeddings.ts"],"sourcesContent":["/**\n * OpenAI Embeddings API support for LLMock.\n *\n * Handles POST /v1/embeddings requests. Matches fixtures using the `inputText`\n * field, and falls back to generating a deterministic embedding from the input\n * text hash when no fixture matches.\n */\n\nimport type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isEmbeddingResponse,\n isErrorResponse,\n generateDeterministicEmbedding,\n buildEmbeddingResponse,\n flattenHeaders,\n getTestId,\n} from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n// ─── Embeddings API request types ──────────────────────────────────────────\n\ninterface EmbeddingRequest {\n input: string | string[];\n model: string;\n encoding_format?: \"float\" | \"base64\";\n dimensions?: number;\n [key: string]: unknown;\n}\n\n// ─── Request handler ───────────────────────────────────────────────────────\n\nexport async function handleEmbeddings(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n const { logger } = defaults;\n setCorsHeaders(res);\n\n let embeddingReq: EmbeddingRequest;\n try {\n embeddingReq = JSON.parse(raw) as EmbeddingRequest;\n } catch {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Malformed JSON\",\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Normalize input to array of strings\n const inputs: string[] = Array.isArray(embeddingReq.input)\n ? embeddingReq.input\n : [embeddingReq.input];\n\n // Concatenate all inputs for matching purposes\n const combinedInput = inputs.join(\" \");\n\n // Build a synthetic ChatCompletionRequest for the fixture router.\n // We attach `embeddingInput` so the router's inputText matching can use it.\n const syntheticReq: ChatCompletionRequest = {\n model: embeddingReq.model,\n messages: [],\n embeddingInput: combinedInput,\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n {\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (fixture) {\n const response = fixture.response;\n\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n // Embedding response — use the fixture's embedding for each input\n if (isEmbeddingResponse(response)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n const embeddings = inputs.map(() => [...response.embedding]);\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Fixture matched but response type is not compatible with embeddings\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message:\n \"Fixture response did not match any known embedding type (must have embedding or error)\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — try record-and-replay proxy if configured\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/embeddings\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n if (defaults.strict) {\n logger.error(\n `STRICT: No fixture matched for ${req.method ?? \"POST\"} ${req.url ?? \"/v1/embeddings\"}`,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 503, fixture: null },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: \"Strict mode: no fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — generate deterministic embeddings from input text\n logger.warn(\n `No embedding fixture matched for \"${combinedInput.slice(0, 80)}\" — returning deterministic fallback`,\n );\n const dimensions = embeddingReq.dimensions ?? 1536;\n const embeddings = inputs.map((input) => generateDeterministicEmbedding(input, dimensions));\n\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture: null },\n });\n\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"embeddings.cjs","names":["flattenHeaders","getTestId","matchFixture","applyChaos","isErrorResponse","isEmbeddingResponse","buildEmbeddingResponse","proxyAndRecord","generateDeterministicEmbedding"],"sources":["../src/embeddings.ts"],"sourcesContent":["/**\n * OpenAI Embeddings API support for LLMock.\n *\n * Handles POST /v1/embeddings requests. Matches fixtures using the `inputText`\n * field, and falls back to generating a deterministic embedding from the input\n * text hash when no fixture matches.\n */\n\nimport type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isEmbeddingResponse,\n isErrorResponse,\n generateDeterministicEmbedding,\n buildEmbeddingResponse,\n flattenHeaders,\n getTestId,\n} from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n// ─── Embeddings API request types ──────────────────────────────────────────\n\ninterface EmbeddingRequest {\n input: string | string[];\n model: string;\n encoding_format?: \"float\" | \"base64\";\n dimensions?: number;\n [key: string]: unknown;\n}\n\n// ─── Request handler ───────────────────────────────────────────────────────\n\nexport async function handleEmbeddings(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n const { logger } = defaults;\n setCorsHeaders(res);\n\n let embeddingReq: EmbeddingRequest;\n try {\n embeddingReq = JSON.parse(raw) as EmbeddingRequest;\n } catch {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Malformed JSON\",\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Normalize input to array of strings\n const inputs: string[] = Array.isArray(embeddingReq.input)\n ? embeddingReq.input\n : [embeddingReq.input];\n\n // Concatenate all inputs for matching purposes\n const combinedInput = inputs.join(\" \");\n\n // Build a synthetic ChatCompletionRequest for the fixture router.\n // We attach `embeddingInput` so the router's inputText matching can use it.\n const syntheticReq: ChatCompletionRequest = {\n model: embeddingReq.model,\n messages: [],\n embeddingInput: combinedInput,\n _endpointType: \"embedding\",\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n {\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (fixture) {\n const response = fixture.response;\n\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n // Embedding response — use the fixture's embedding for each input\n if (isEmbeddingResponse(response)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n const embeddings = inputs.map(() => [...response.embedding]);\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Fixture matched but response type is not compatible with embeddings\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message:\n \"Fixture response did not match any known embedding type (must have embedding or error)\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — try record-and-replay proxy if configured\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/embeddings\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n if (defaults.strict) {\n logger.error(\n `STRICT: No fixture matched for ${req.method ?? \"POST\"} ${req.url ?? \"/v1/embeddings\"}`,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 503, fixture: null },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: \"Strict mode: no fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — generate deterministic embeddings from input text\n logger.warn(\n `No embedding fixture matched for \"${combinedInput.slice(0, 80)}\" — returning deterministic fallback`,\n );\n const dimensions = embeddingReq.dimensions ?? 1536;\n const embeddings = inputs.map((input) => generateDeterministicEmbedding(input, dimensions));\n\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture: null },\n });\n\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n"],"mappings":"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"}
@@ -34,7 +34,8 @@ async function handleEmbeddings(req, res, raw, fixtures, journal, defaults, setC
34
34
  const syntheticReq = {
35
35
  model: embeddingReq.model,
36
36
  messages: [],
37
- embeddingInput: combinedInput
37
+ embeddingInput: combinedInput,
38
+ _endpointType: "embedding"
38
39
  };
39
40
  const testId = getTestId(req);
40
41
  const fixture = matchFixture(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
@@ -1 +1 @@
1
- {"version":3,"file":"embeddings.js","names":[],"sources":["../src/embeddings.ts"],"sourcesContent":["/**\n * OpenAI Embeddings API support for LLMock.\n *\n * Handles POST /v1/embeddings requests. Matches fixtures using the `inputText`\n * field, and falls back to generating a deterministic embedding from the input\n * text hash when no fixture matches.\n */\n\nimport type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isEmbeddingResponse,\n isErrorResponse,\n generateDeterministicEmbedding,\n buildEmbeddingResponse,\n flattenHeaders,\n getTestId,\n} from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n// ─── Embeddings API request types ──────────────────────────────────────────\n\ninterface EmbeddingRequest {\n input: string | string[];\n model: string;\n encoding_format?: \"float\" | \"base64\";\n dimensions?: number;\n [key: string]: unknown;\n}\n\n// ─── Request handler ───────────────────────────────────────────────────────\n\nexport async function handleEmbeddings(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n const { logger } = defaults;\n setCorsHeaders(res);\n\n let embeddingReq: EmbeddingRequest;\n try {\n embeddingReq = JSON.parse(raw) as EmbeddingRequest;\n } catch {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Malformed JSON\",\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Normalize input to array of strings\n const inputs: string[] = Array.isArray(embeddingReq.input)\n ? embeddingReq.input\n : [embeddingReq.input];\n\n // Concatenate all inputs for matching purposes\n const combinedInput = inputs.join(\" \");\n\n // Build a synthetic ChatCompletionRequest for the fixture router.\n // We attach `embeddingInput` so the router's inputText matching can use it.\n const syntheticReq: ChatCompletionRequest = {\n model: embeddingReq.model,\n messages: [],\n embeddingInput: combinedInput,\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n {\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (fixture) {\n const response = fixture.response;\n\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n // Embedding response — use the fixture's embedding for each input\n if (isEmbeddingResponse(response)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n const embeddings = inputs.map(() => [...response.embedding]);\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Fixture matched but response type is not compatible with embeddings\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message:\n \"Fixture response did not match any known embedding type (must have embedding or error)\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — try record-and-replay proxy if configured\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/embeddings\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n if (defaults.strict) {\n logger.error(\n `STRICT: No fixture matched for ${req.method ?? \"POST\"} ${req.url ?? \"/v1/embeddings\"}`,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 503, fixture: null },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: \"Strict mode: no fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — generate deterministic embeddings from input text\n logger.warn(\n `No embedding fixture matched for \"${combinedInput.slice(0, 80)}\" — returning deterministic fallback`,\n );\n const dimensions = embeddingReq.dimensions ?? 1536;\n const embeddings = inputs.map((input) => generateDeterministicEmbedding(input, dimensions));\n\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture: null },\n });\n\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n"],"mappings":";;;;;;;AAoCA,eAAsB,iBACpB,KACA,KACA,KACA,UACA,SACA,UACA,gBACe;CACf,MAAM,EAAE,WAAW;AACnB,gBAAe,IAAI;CAEnB,IAAI;AACJ,KAAI;AACF,iBAAe,KAAK,MAAM,IAAI;SACxB;AACN,UAAQ,IAAI;GACV,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI,OAAO;GACjB,SAAS,eAAe,IAAI,QAAQ;GACpC,MAAM;GACN,UAAU;IAAE,QAAQ;IAAK,SAAS;IAAM;GACzC,CAAC;AACF,qBACE,KACA,KACA,KAAK,UAAU,EACb,OAAO;GACL,SAAS;GACT,MAAM;GACN,MAAM;GACP,EACF,CAAC,CACH;AACD;;CAIF,MAAM,SAAmB,MAAM,QAAQ,aAAa,MAAM,GACtD,aAAa,QACb,CAAC,aAAa,MAAM;CAGxB,MAAM,gBAAgB,OAAO,KAAK,IAAI;CAItC,MAAM,eAAsC;EAC1C,OAAO,aAAa;EACpB,UAAU,EAAE;EACZ,gBAAgB;EACjB;CAED,MAAM,SAAS,UAAU,IAAI;CAC7B,MAAM,UAAU,aACd,UACA,cACA,QAAQ,6BAA6B,OAAO,EAC5C,SAAS,iBACV;AAED,KAAI,QACF,SAAQ,2BAA2B,SAAS,UAAU,OAAO;AAG/D,KACE,WACE,KACA,SACA,SAAS,OACT,IAAI,SACJ,SACA;EACE,QAAQ,IAAI,UAAU;EACtB,MAAM,IAAI,OAAO;EACjB,SAAS,eAAe,IAAI,QAAQ;EACpC,MAAM;EACP,EACD,SAAS,UACT,SAAS,OACV,CAED;AAEF,KAAI,SAAS;EACX,MAAM,WAAW,QAAQ;AAGzB,MAAI,gBAAgB,SAAS,EAAE;GAC7B,MAAM,SAAS,SAAS,UAAU;AAClC,WAAQ,IAAI;IACV,QAAQ,IAAI,UAAU;IACtB,MAAM,IAAI,OAAO;IACjB,SAAS,eAAe,IAAI,QAAQ;IACpC,MAAM;IACN,UAAU;KAAE;KAAQ;KAAS;IAC9B,CAAC;AACF,sBAAmB,KAAK,QAAQ,KAAK,UAAU,SAAS,CAAC;AACzD;;AAIF,MAAI,oBAAoB,SAAS,EAAE;AACjC,WAAQ,IAAI;IACV,QAAQ,IAAI,UAAU;IACtB,MAAM,IAAI,OAAO;IACjB,SAAS,eAAe,IAAI,QAAQ;IACpC,MAAM;IACN,UAAU;KAAE,QAAQ;KAAK;KAAS;IACnC,CAAC;GAEF,MAAM,OAAO,uBADM,OAAO,UAAU,CAAC,GAAG,SAAS,UAAU,CAAC,EACZ,aAAa,MAAM;AACnE,OAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,OAAI,IAAI,KAAK,UAAU,KAAK,CAAC;AAC7B;;AAIF,UAAQ,IAAI;GACV,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI,OAAO;GACjB,SAAS,eAAe,IAAI,QAAQ;GACpC,MAAM;GACN,UAAU;IAAE,QAAQ;IAAK;IAAS;GACnC,CAAC;AACF,qBACE,KACA,KACA,KAAK,UAAU,EACb,OAAO;GACL,SACE;GACF,MAAM;GACP,EACF,CAAC,CACH;AACD;;AAIF,KAAI,SAAS,QAWX;MAVgB,MAAM,eACpB,KACA,KACA,cACA,UACA,IAAI,OAAO,kBACX,UACA,UACA,IACD,EACY;AACX,WAAQ,IAAI;IACV,QAAQ,IAAI,UAAU;IACtB,MAAM,IAAI,OAAO;IACjB,SAAS,eAAe,IAAI,QAAQ;IACpC,MAAM;IACN,UAAU;KAAE,QAAQ,IAAI,cAAc;KAAK,SAAS;KAAM;IAC3D,CAAC;AACF;;;AAIJ,KAAI,SAAS,QAAQ;AACnB,SAAO,MACL,kCAAkC,IAAI,UAAU,OAAO,GAAG,IAAI,OAAO,mBACtE;AACD,UAAQ,IAAI;GACV,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI,OAAO;GACjB,SAAS,eAAe,IAAI,QAAQ;GACpC,MAAM;GACN,UAAU;IAAE,QAAQ;IAAK,SAAS;IAAM;GACzC,CAAC;AACF,qBACE,KACA,KACA,KAAK,UAAU,EACb,OAAO;GACL,SAAS;GACT,MAAM;GACN,MAAM;GACP,EACF,CAAC,CACH;AACD;;AAIF,QAAO,KACL,qCAAqC,cAAc,MAAM,GAAG,GAAG,CAAC,sCACjE;CACD,MAAM,aAAa,aAAa,cAAc;CAC9C,MAAM,aAAa,OAAO,KAAK,UAAU,+BAA+B,OAAO,WAAW,CAAC;AAE3F,SAAQ,IAAI;EACV,QAAQ,IAAI,UAAU;EACtB,MAAM,IAAI,OAAO;EACjB,SAAS,eAAe,IAAI,QAAQ;EACpC,MAAM;EACN,UAAU;GAAE,QAAQ;GAAK,SAAS;GAAM;EACzC,CAAC;CAEF,MAAM,OAAO,uBAAuB,YAAY,aAAa,MAAM;AACnE,KAAI,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC;AAC1D,KAAI,IAAI,KAAK,UAAU,KAAK,CAAC"}
1
+ {"version":3,"file":"embeddings.js","names":[],"sources":["../src/embeddings.ts"],"sourcesContent":["/**\n * OpenAI Embeddings API support for LLMock.\n *\n * Handles POST /v1/embeddings requests. Matches fixtures using the `inputText`\n * field, and falls back to generating a deterministic embedding from the input\n * text hash when no fixture matches.\n */\n\nimport type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isEmbeddingResponse,\n isErrorResponse,\n generateDeterministicEmbedding,\n buildEmbeddingResponse,\n flattenHeaders,\n getTestId,\n} from \"./helpers.js\";\nimport { matchFixture } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\n\n// ─── Embeddings API request types ──────────────────────────────────────────\n\ninterface EmbeddingRequest {\n input: string | string[];\n model: string;\n encoding_format?: \"float\" | \"base64\";\n dimensions?: number;\n [key: string]: unknown;\n}\n\n// ─── Request handler ───────────────────────────────────────────────────────\n\nexport async function handleEmbeddings(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n const { logger } = defaults;\n setCorsHeaders(res);\n\n let embeddingReq: EmbeddingRequest;\n try {\n embeddingReq = JSON.parse(raw) as EmbeddingRequest;\n } catch {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Malformed JSON\",\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Normalize input to array of strings\n const inputs: string[] = Array.isArray(embeddingReq.input)\n ? embeddingReq.input\n : [embeddingReq.input];\n\n // Concatenate all inputs for matching purposes\n const combinedInput = inputs.join(\" \");\n\n // Build a synthetic ChatCompletionRequest for the fixture router.\n // We attach `embeddingInput` so the router's inputText matching can use it.\n const syntheticReq: ChatCompletionRequest = {\n model: embeddingReq.model,\n messages: [],\n embeddingInput: combinedInput,\n _endpointType: \"embedding\",\n };\n\n const testId = getTestId(req);\n const fixture = matchFixture(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n {\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n },\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (fixture) {\n const response = fixture.response;\n\n // Error response\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, JSON.stringify(response));\n return;\n }\n\n // Embedding response — use the fixture's embedding for each input\n if (isEmbeddingResponse(response)) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n const embeddings = inputs.map(() => [...response.embedding]);\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n return;\n }\n\n // Fixture matched but response type is not compatible with embeddings\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message:\n \"Fixture response did not match any known embedding type (must have embedding or error)\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — try record-and-replay proxy if configured\n if (defaults.record) {\n const proxied = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/embeddings\",\n fixtures,\n defaults,\n raw,\n );\n if (proxied) {\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null },\n });\n return;\n }\n }\n\n if (defaults.strict) {\n logger.error(\n `STRICT: No fixture matched for ${req.method ?? \"POST\"} ${req.url ?? \"/v1/embeddings\"}`,\n );\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 503, fixture: null },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: \"Strict mode: no fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n // No fixture match — generate deterministic embeddings from input text\n logger.warn(\n `No embedding fixture matched for \"${combinedInput.slice(0, 80)}\" — returning deterministic fallback`,\n );\n const dimensions = embeddingReq.dimensions ?? 1536;\n const embeddings = inputs.map((input) => generateDeterministicEmbedding(input, dimensions));\n\n journal.add({\n method: req.method ?? \"POST\",\n path: req.url ?? \"/v1/embeddings\",\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture: null },\n });\n\n const body = buildEmbeddingResponse(embeddings, embeddingReq.model);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n"],"mappings":"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"}
package/dist/gemini.cjs CHANGED
@@ -310,6 +310,7 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
310
310
  return;
311
311
  }
312
312
  const completionReq = geminiToCompletionRequest(geminiReq, model, streaming);
313
+ completionReq._endpointType = "chat";
313
314
  const testId = require_helpers.getTestId(req);
314
315
  const fixture = require_router.matchFixture(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
315
316
  const path = req.url ?? `/v1beta/models/${model}:generateContent`;