@waniwani/sdk 0.1.20-beta.2 → 0.1.20-beta.21

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 (715) hide show
  1. package/README.md +103 -52
  2. package/dist/abap-KGVIZMDC.js +3 -0
  3. package/dist/abap-KGVIZMDC.js.map +1 -0
  4. package/dist/actionscript-3-2UHK5QYP.js +3 -0
  5. package/dist/actionscript-3-2UHK5QYP.js.map +1 -0
  6. package/dist/ada-JKTWR5BV.js +3 -0
  7. package/dist/ada-JKTWR5BV.js.map +1 -0
  8. package/dist/andromeeda-HAPOYWX3.js +3 -0
  9. package/dist/andromeeda-HAPOYWX3.js.map +1 -0
  10. package/dist/angular-html-EOIKHM3D.js +3 -0
  11. package/dist/angular-html-EOIKHM3D.js.map +1 -0
  12. package/dist/angular-ts-A7ZNTSV6.js +3 -0
  13. package/dist/angular-ts-A7ZNTSV6.js.map +1 -0
  14. package/dist/apache-MPGFGQFB.js +3 -0
  15. package/dist/apache-MPGFGQFB.js.map +1 -0
  16. package/dist/apex-BOAZL66Z.js +3 -0
  17. package/dist/apex-BOAZL66Z.js.map +1 -0
  18. package/dist/apl-QBN4KIYA.js +3 -0
  19. package/dist/apl-QBN4KIYA.js.map +1 -0
  20. package/dist/applescript-C4CJ3STL.js +3 -0
  21. package/dist/applescript-C4CJ3STL.js.map +1 -0
  22. package/dist/ara-FSFFBRSD.js +3 -0
  23. package/dist/ara-FSFFBRSD.js.map +1 -0
  24. package/dist/asciidoc-QQK2LANG.js +3 -0
  25. package/dist/asciidoc-QQK2LANG.js.map +1 -0
  26. package/dist/asm-X43A2VYW.js +3 -0
  27. package/dist/asm-X43A2VYW.js.map +1 -0
  28. package/dist/astro-OQUOYMBE.js +3 -0
  29. package/dist/astro-OQUOYMBE.js.map +1 -0
  30. package/dist/aurora-x-R6WAWEBC.js +3 -0
  31. package/dist/aurora-x-R6WAWEBC.js.map +1 -0
  32. package/dist/awk-4Z3PRTF7.js +3 -0
  33. package/dist/awk-4Z3PRTF7.js.map +1 -0
  34. package/dist/ayu-dark-KMD4YO7F.js +3 -0
  35. package/dist/ayu-dark-KMD4YO7F.js.map +1 -0
  36. package/dist/ayu-light-2ATPDILG.js +3 -0
  37. package/dist/ayu-light-2ATPDILG.js.map +1 -0
  38. package/dist/ayu-mirage-LJ7PG5AM.js +3 -0
  39. package/dist/ayu-mirage-LJ7PG5AM.js.map +1 -0
  40. package/dist/ballerina-JCXSJ2QD.js +3 -0
  41. package/dist/ballerina-JCXSJ2QD.js.map +1 -0
  42. package/dist/bat-XFWR7RMZ.js +3 -0
  43. package/dist/bat-XFWR7RMZ.js.map +1 -0
  44. package/dist/beancount-7BBDB4BH.js +3 -0
  45. package/dist/beancount-7BBDB4BH.js.map +1 -0
  46. package/dist/berry-PQ2BEJIZ.js +3 -0
  47. package/dist/berry-PQ2BEJIZ.js.map +1 -0
  48. package/dist/bibtex-J2PAB23I.js +3 -0
  49. package/dist/bibtex-J2PAB23I.js.map +1 -0
  50. package/dist/bicep-TNKT6R3W.js +3 -0
  51. package/dist/bicep-TNKT6R3W.js.map +1 -0
  52. package/dist/blade-QBDEYXMB.js +3 -0
  53. package/dist/blade-QBDEYXMB.js.map +1 -0
  54. package/dist/bsl-PQW6E45S.js +3 -0
  55. package/dist/bsl-PQW6E45S.js.map +1 -0
  56. package/dist/c-PZBJFNXE.js +3 -0
  57. package/dist/c-PZBJFNXE.js.map +1 -0
  58. package/dist/c3-GP7XYHE6.js +3 -0
  59. package/dist/c3-GP7XYHE6.js.map +1 -0
  60. package/dist/cadence-NABGDHKY.js +3 -0
  61. package/dist/cadence-NABGDHKY.js.map +1 -0
  62. package/dist/cairo-WQSC2GLN.js +3 -0
  63. package/dist/cairo-WQSC2GLN.js.map +1 -0
  64. package/dist/catppuccin-frappe-Z4Y2POK6.js +3 -0
  65. package/dist/catppuccin-frappe-Z4Y2POK6.js.map +1 -0
  66. package/dist/catppuccin-latte-4TQUIKX4.js +3 -0
  67. package/dist/catppuccin-latte-4TQUIKX4.js.map +1 -0
  68. package/dist/catppuccin-macchiato-B7YYPERT.js +3 -0
  69. package/dist/catppuccin-macchiato-B7YYPERT.js.map +1 -0
  70. package/dist/catppuccin-mocha-KX33VXKA.js +3 -0
  71. package/dist/catppuccin-mocha-KX33VXKA.js.map +1 -0
  72. package/dist/chat/index.d.ts +15 -5
  73. package/dist/chat/index.js +49 -1
  74. package/dist/chat/index.js.map +1 -1
  75. package/dist/chat/next-js/index.d.ts +95 -40
  76. package/dist/chat/next-js/index.js +1 -1
  77. package/dist/chat/next-js/index.js.map +1 -1
  78. package/dist/chat/server/index.d.ts +5 -0
  79. package/dist/chat/styles.css +1 -1
  80. package/dist/chunk-2RR26LLP.js +3 -0
  81. package/dist/chunk-2RR26LLP.js.map +1 -0
  82. package/dist/chunk-3MXGGSWX.js +3 -0
  83. package/dist/chunk-3MXGGSWX.js.map +1 -0
  84. package/dist/chunk-4LBJUPWV.js +3 -0
  85. package/dist/chunk-4LBJUPWV.js.map +1 -0
  86. package/dist/chunk-4VTSQZWF.js +3 -0
  87. package/dist/chunk-4VTSQZWF.js.map +1 -0
  88. package/dist/chunk-7JLJRE2N.js +3 -0
  89. package/dist/chunk-7JLJRE2N.js.map +1 -0
  90. package/dist/chunk-7PHUBJVC.js +3 -0
  91. package/dist/chunk-7PHUBJVC.js.map +1 -0
  92. package/dist/chunk-AGWJ4LUC.js +3 -0
  93. package/dist/chunk-AGWJ4LUC.js.map +1 -0
  94. package/dist/chunk-ASVQBXNX.js +3 -0
  95. package/dist/chunk-ASVQBXNX.js.map +1 -0
  96. package/dist/chunk-ATLIFHJQ.js +3 -0
  97. package/dist/chunk-ATLIFHJQ.js.map +1 -0
  98. package/dist/chunk-BWAU264B.js +3 -0
  99. package/dist/chunk-BWAU264B.js.map +1 -0
  100. package/dist/chunk-C2XW4T23.js +3 -0
  101. package/dist/chunk-C2XW4T23.js.map +1 -0
  102. package/dist/chunk-C3DWQQH3.js +3 -0
  103. package/dist/chunk-C3DWQQH3.js.map +1 -0
  104. package/dist/chunk-CIEDXAJY.js +3 -0
  105. package/dist/chunk-CIEDXAJY.js.map +1 -0
  106. package/dist/chunk-CNY3RWNZ.js +3 -0
  107. package/dist/chunk-CNY3RWNZ.js.map +1 -0
  108. package/dist/chunk-ED2SBPIQ.js +3 -0
  109. package/dist/chunk-ED2SBPIQ.js.map +1 -0
  110. package/dist/chunk-F3QSOBPN.js +3 -0
  111. package/dist/chunk-F3QSOBPN.js.map +1 -0
  112. package/dist/chunk-FHRHXPXN.js +3 -0
  113. package/dist/chunk-FHRHXPXN.js.map +1 -0
  114. package/dist/chunk-FWHINPYE.js +3 -0
  115. package/dist/chunk-FWHINPYE.js.map +1 -0
  116. package/dist/chunk-HMEGK7JX.js +3 -0
  117. package/dist/chunk-HMEGK7JX.js.map +1 -0
  118. package/dist/chunk-HU77EH3T.js +3 -0
  119. package/dist/chunk-HU77EH3T.js.map +1 -0
  120. package/dist/chunk-HVAT4SNH.js +116 -0
  121. package/dist/chunk-HVAT4SNH.js.map +1 -0
  122. package/dist/chunk-IXROC4D6.js +3 -0
  123. package/dist/chunk-IXROC4D6.js.map +1 -0
  124. package/dist/chunk-JVRIR5KA.js +3 -0
  125. package/dist/chunk-JVRIR5KA.js.map +1 -0
  126. package/dist/chunk-JXSURY23.js +3 -0
  127. package/dist/chunk-JXSURY23.js.map +1 -0
  128. package/dist/chunk-JZBW5KEX.js +3 -0
  129. package/dist/chunk-JZBW5KEX.js.map +1 -0
  130. package/dist/chunk-M4CKEROZ.js +3 -0
  131. package/dist/chunk-M4CKEROZ.js.map +1 -0
  132. package/dist/chunk-NWMKWKIF.js +3 -0
  133. package/dist/chunk-NWMKWKIF.js.map +1 -0
  134. package/dist/chunk-OZU5OBWU.js +3 -0
  135. package/dist/chunk-OZU5OBWU.js.map +1 -0
  136. package/dist/chunk-Q7Y54EZU.js +3 -0
  137. package/dist/chunk-Q7Y54EZU.js.map +1 -0
  138. package/dist/chunk-QLNWMFSL.js +3 -0
  139. package/dist/chunk-QLNWMFSL.js.map +1 -0
  140. package/dist/chunk-R5U25TSM.js +3 -0
  141. package/dist/chunk-R5U25TSM.js.map +1 -0
  142. package/dist/chunk-RH56J7QY.js +3 -0
  143. package/dist/chunk-RH56J7QY.js.map +1 -0
  144. package/dist/chunk-RLHBVYHM.js +3 -0
  145. package/dist/chunk-RLHBVYHM.js.map +1 -0
  146. package/dist/chunk-RYVXTIMY.js +3 -0
  147. package/dist/chunk-RYVXTIMY.js.map +1 -0
  148. package/dist/chunk-U4R5XKLD.js +3 -0
  149. package/dist/chunk-U4R5XKLD.js.map +1 -0
  150. package/dist/chunk-V3ZDECK5.js +3 -0
  151. package/dist/chunk-V3ZDECK5.js.map +1 -0
  152. package/dist/chunk-VBWVDIIW.js +3 -0
  153. package/dist/chunk-VBWVDIIW.js.map +1 -0
  154. package/dist/chunk-VME4UB43.js +3 -0
  155. package/dist/chunk-VME4UB43.js.map +1 -0
  156. package/dist/chunk-VNX5AK2O.js +3 -0
  157. package/dist/chunk-VNX5AK2O.js.map +1 -0
  158. package/dist/chunk-WKR2RWJ6.js +3 -0
  159. package/dist/chunk-WKR2RWJ6.js.map +1 -0
  160. package/dist/chunk-XD5VGPVP.js +3 -0
  161. package/dist/chunk-XD5VGPVP.js.map +1 -0
  162. package/dist/chunk-Z3IKGRKN.js +3 -0
  163. package/dist/chunk-Z3IKGRKN.js.map +1 -0
  164. package/dist/chunk-Z7QCZ4DQ.js +3 -0
  165. package/dist/chunk-Z7QCZ4DQ.js.map +1 -0
  166. package/dist/chunk-ZHMHS6LG.js +3 -0
  167. package/dist/chunk-ZHMHS6LG.js.map +1 -0
  168. package/dist/chunk-ZU32Z5HV.js +3 -0
  169. package/dist/chunk-ZU32Z5HV.js.map +1 -0
  170. package/dist/clarity-NXNSINKX.js +3 -0
  171. package/dist/clarity-NXNSINKX.js.map +1 -0
  172. package/dist/clojure-Y57BKRMA.js +3 -0
  173. package/dist/clojure-Y57BKRMA.js.map +1 -0
  174. package/dist/cmake-LVMEA3JZ.js +3 -0
  175. package/dist/cmake-LVMEA3JZ.js.map +1 -0
  176. package/dist/cobol-6DNJTKH3.js +3 -0
  177. package/dist/cobol-6DNJTKH3.js.map +1 -0
  178. package/dist/code-block-37QAKDTI-M2QCKVTI.js +4 -0
  179. package/dist/code-block-37QAKDTI-M2QCKVTI.js.map +1 -0
  180. package/dist/codeowners-JYHOTXQS.js +3 -0
  181. package/dist/codeowners-JYHOTXQS.js.map +1 -0
  182. package/dist/codeql-IWWSYR3L.js +3 -0
  183. package/dist/codeql-IWWSYR3L.js.map +1 -0
  184. package/dist/coffee-NNDQ5QXC.js +3 -0
  185. package/dist/coffee-NNDQ5QXC.js.map +1 -0
  186. package/dist/common-lisp-JKXCDYH3.js +3 -0
  187. package/dist/common-lisp-JKXCDYH3.js.map +1 -0
  188. package/dist/coq-BEHPNP64.js +3 -0
  189. package/dist/coq-BEHPNP64.js.map +1 -0
  190. package/dist/cpp-IALOHSZA.js +3 -0
  191. package/dist/cpp-IALOHSZA.js.map +1 -0
  192. package/dist/crystal-ZDP3FIUI.js +3 -0
  193. package/dist/crystal-ZDP3FIUI.js.map +1 -0
  194. package/dist/csharp-ODFBXRGA.js +3 -0
  195. package/dist/csharp-ODFBXRGA.js.map +1 -0
  196. package/dist/css-CJGL5AVH.js +3 -0
  197. package/dist/css-CJGL5AVH.js.map +1 -0
  198. package/dist/csv-LIK4TU3Z.js +3 -0
  199. package/dist/csv-LIK4TU3Z.js.map +1 -0
  200. package/dist/cue-UAAEAKHI.js +3 -0
  201. package/dist/cue-UAAEAKHI.js.map +1 -0
  202. package/dist/cypher-SZPVUQZJ.js +3 -0
  203. package/dist/cypher-SZPVUQZJ.js.map +1 -0
  204. package/dist/d-VSCA3XHG.js +3 -0
  205. package/dist/d-VSCA3XHG.js.map +1 -0
  206. package/dist/dark-plus-LNHXUR7U.js +3 -0
  207. package/dist/dark-plus-LNHXUR7U.js.map +1 -0
  208. package/dist/dart-A4PE6FIS.js +3 -0
  209. package/dist/dart-A4PE6FIS.js.map +1 -0
  210. package/dist/dax-TILIKSFB.js +3 -0
  211. package/dist/dax-TILIKSFB.js.map +1 -0
  212. package/dist/desktop-75KK3D55.js +3 -0
  213. package/dist/desktop-75KK3D55.js.map +1 -0
  214. package/dist/diff-HOT6P45M.js +3 -0
  215. package/dist/diff-HOT6P45M.js.map +1 -0
  216. package/dist/docker-FF35TY6T.js +3 -0
  217. package/dist/docker-FF35TY6T.js.map +1 -0
  218. package/dist/dotenv-FVPPHJI3.js +3 -0
  219. package/dist/dotenv-FVPPHJI3.js.map +1 -0
  220. package/dist/dracula-T2CMBBQ5.js +3 -0
  221. package/dist/dracula-T2CMBBQ5.js.map +1 -0
  222. package/dist/dracula-soft-SMFRNKX2.js +3 -0
  223. package/dist/dracula-soft-SMFRNKX2.js.map +1 -0
  224. package/dist/dream-maker-SYE3ZPSJ.js +3 -0
  225. package/dist/dream-maker-SYE3ZPSJ.js.map +1 -0
  226. package/dist/edge-CCLQ2CKA.js +3 -0
  227. package/dist/edge-CCLQ2CKA.js.map +1 -0
  228. package/dist/elixir-F6DQGRKA.js +3 -0
  229. package/dist/elixir-F6DQGRKA.js.map +1 -0
  230. package/dist/elm-5QRQXDZ6.js +3 -0
  231. package/dist/elm-5QRQXDZ6.js.map +1 -0
  232. package/dist/emacs-lisp-NJ4S4OHV.js +3 -0
  233. package/dist/emacs-lisp-NJ4S4OHV.js.map +1 -0
  234. package/dist/erb-HGSLHT5Y.js +3 -0
  235. package/dist/erb-HGSLHT5Y.js.map +1 -0
  236. package/dist/erlang-APEONNZ6.js +3 -0
  237. package/dist/erlang-APEONNZ6.js.map +1 -0
  238. package/dist/everforest-dark-DBZHIUAO.js +3 -0
  239. package/dist/everforest-dark-DBZHIUAO.js.map +1 -0
  240. package/dist/everforest-light-TDAGYJUK.js +3 -0
  241. package/dist/everforest-light-TDAGYJUK.js.map +1 -0
  242. package/dist/fennel-7OCMFVPS.js +3 -0
  243. package/dist/fennel-7OCMFVPS.js.map +1 -0
  244. package/dist/fish-BC46ME2N.js +3 -0
  245. package/dist/fish-BC46ME2N.js.map +1 -0
  246. package/dist/fluent-MXZS6EX3.js +3 -0
  247. package/dist/fluent-MXZS6EX3.js.map +1 -0
  248. package/dist/fortran-fixed-form-35BC2KX6.js +3 -0
  249. package/dist/fortran-fixed-form-35BC2KX6.js.map +1 -0
  250. package/dist/fortran-free-form-AXRAI2HH.js +3 -0
  251. package/dist/fortran-free-form-AXRAI2HH.js.map +1 -0
  252. package/dist/fsharp-JKNSQXHD.js +3 -0
  253. package/dist/fsharp-JKNSQXHD.js.map +1 -0
  254. package/dist/gdresource-ZMKZGPZV.js +3 -0
  255. package/dist/gdresource-ZMKZGPZV.js.map +1 -0
  256. package/dist/gdscript-HNCVXEYB.js +3 -0
  257. package/dist/gdscript-HNCVXEYB.js.map +1 -0
  258. package/dist/gdshader-XAJ4QRYP.js +3 -0
  259. package/dist/gdshader-XAJ4QRYP.js.map +1 -0
  260. package/dist/genie-HEFVQZAP.js +3 -0
  261. package/dist/genie-HEFVQZAP.js.map +1 -0
  262. package/dist/gherkin-OFBRDPXX.js +3 -0
  263. package/dist/gherkin-OFBRDPXX.js.map +1 -0
  264. package/dist/git-commit-ZE2M3Q5H.js +3 -0
  265. package/dist/git-commit-ZE2M3Q5H.js.map +1 -0
  266. package/dist/git-rebase-3N3INGLU.js +3 -0
  267. package/dist/git-rebase-3N3INGLU.js.map +1 -0
  268. package/dist/github-dark-3E25TTAN.js +3 -0
  269. package/dist/github-dark-3E25TTAN.js.map +1 -0
  270. package/dist/github-dark-default-KCBFVSS5.js +3 -0
  271. package/dist/github-dark-default-KCBFVSS5.js.map +1 -0
  272. package/dist/github-dark-dimmed-WRCBXEVS.js +3 -0
  273. package/dist/github-dark-dimmed-WRCBXEVS.js.map +1 -0
  274. package/dist/github-dark-high-contrast-ET7SAHAV.js +3 -0
  275. package/dist/github-dark-high-contrast-ET7SAHAV.js.map +1 -0
  276. package/dist/github-light-6FNTZH5H.js +3 -0
  277. package/dist/github-light-6FNTZH5H.js.map +1 -0
  278. package/dist/github-light-default-GGTAKNM7.js +3 -0
  279. package/dist/github-light-default-GGTAKNM7.js.map +1 -0
  280. package/dist/github-light-high-contrast-LHYKPR5E.js +3 -0
  281. package/dist/github-light-high-contrast-LHYKPR5E.js.map +1 -0
  282. package/dist/gleam-NFFQFQLP.js +3 -0
  283. package/dist/gleam-NFFQFQLP.js.map +1 -0
  284. package/dist/glimmer-js-RSUW6JYN.js +3 -0
  285. package/dist/glimmer-js-RSUW6JYN.js.map +1 -0
  286. package/dist/glimmer-ts-EZGWLX5T.js +3 -0
  287. package/dist/glimmer-ts-EZGWLX5T.js.map +1 -0
  288. package/dist/glsl-VJLRYEVJ.js +3 -0
  289. package/dist/glsl-VJLRYEVJ.js.map +1 -0
  290. package/dist/gn-UH2XQWLG.js +3 -0
  291. package/dist/gn-UH2XQWLG.js.map +1 -0
  292. package/dist/gnuplot-K6IV6NNR.js +3 -0
  293. package/dist/gnuplot-K6IV6NNR.js.map +1 -0
  294. package/dist/go-BDV7RR5G.js +3 -0
  295. package/dist/go-BDV7RR5G.js.map +1 -0
  296. package/dist/graphql-YEJQLMOO.js +3 -0
  297. package/dist/graphql-YEJQLMOO.js.map +1 -0
  298. package/dist/groovy-SX7K3XGL.js +3 -0
  299. package/dist/groovy-SX7K3XGL.js.map +1 -0
  300. package/dist/gruvbox-dark-hard-IQWZCHF7.js +3 -0
  301. package/dist/gruvbox-dark-hard-IQWZCHF7.js.map +1 -0
  302. package/dist/gruvbox-dark-medium-ARPWF4FS.js +3 -0
  303. package/dist/gruvbox-dark-medium-ARPWF4FS.js.map +1 -0
  304. package/dist/gruvbox-dark-soft-ODS6FPID.js +3 -0
  305. package/dist/gruvbox-dark-soft-ODS6FPID.js.map +1 -0
  306. package/dist/gruvbox-light-hard-KFA5YFDW.js +3 -0
  307. package/dist/gruvbox-light-hard-KFA5YFDW.js.map +1 -0
  308. package/dist/gruvbox-light-medium-MMET4L3Y.js +3 -0
  309. package/dist/gruvbox-light-medium-MMET4L3Y.js.map +1 -0
  310. package/dist/gruvbox-light-soft-DBZDERMK.js +3 -0
  311. package/dist/gruvbox-light-soft-DBZDERMK.js.map +1 -0
  312. package/dist/hack-3TGPQNR2.js +3 -0
  313. package/dist/hack-3TGPQNR2.js.map +1 -0
  314. package/dist/haml-335RVEQR.js +3 -0
  315. package/dist/haml-335RVEQR.js.map +1 -0
  316. package/dist/handlebars-73IS6B2J.js +3 -0
  317. package/dist/handlebars-73IS6B2J.js.map +1 -0
  318. package/dist/haskell-P5PTJARU.js +3 -0
  319. package/dist/haskell-P5PTJARU.js.map +1 -0
  320. package/dist/haxe-RCPSSA3N.js +3 -0
  321. package/dist/haxe-RCPSSA3N.js.map +1 -0
  322. package/dist/hcl-AKKZAVC2.js +3 -0
  323. package/dist/hcl-AKKZAVC2.js.map +1 -0
  324. package/dist/hjson-REXV6F6N.js +3 -0
  325. package/dist/hjson-REXV6F6N.js.map +1 -0
  326. package/dist/hlsl-AJ7VWOVL.js +3 -0
  327. package/dist/hlsl-AJ7VWOVL.js.map +1 -0
  328. package/dist/horizon-FSOMPXNP.js +3 -0
  329. package/dist/horizon-FSOMPXNP.js.map +1 -0
  330. package/dist/houston-FAQBCORN.js +3 -0
  331. package/dist/houston-FAQBCORN.js.map +1 -0
  332. package/dist/html-654LNGWF.js +3 -0
  333. package/dist/html-654LNGWF.js.map +1 -0
  334. package/dist/html-derivative-CMQ7BFDQ.js +3 -0
  335. package/dist/html-derivative-CMQ7BFDQ.js.map +1 -0
  336. package/dist/http-NEPTRAQZ.js +3 -0
  337. package/dist/http-NEPTRAQZ.js.map +1 -0
  338. package/dist/hurl-V6ZX2Q3F.js +3 -0
  339. package/dist/hurl-V6ZX2Q3F.js.map +1 -0
  340. package/dist/hxml-5BXJCAAU.js +3 -0
  341. package/dist/hxml-5BXJCAAU.js.map +1 -0
  342. package/dist/hy-SB4TMFE7.js +3 -0
  343. package/dist/hy-SB4TMFE7.js.map +1 -0
  344. package/dist/imba-Y64MHYWP.js +3 -0
  345. package/dist/imba-Y64MHYWP.js.map +1 -0
  346. package/dist/index.d.ts +134 -41
  347. package/dist/index.js +1 -1
  348. package/dist/index.js.map +1 -1
  349. package/dist/ini-J2OP4CNW.js +3 -0
  350. package/dist/ini-J2OP4CNW.js.map +1 -0
  351. package/dist/java-MJKJ5GPP.js +3 -0
  352. package/dist/java-MJKJ5GPP.js.map +1 -0
  353. package/dist/javascript-IYAGHPR6.js +3 -0
  354. package/dist/javascript-IYAGHPR6.js.map +1 -0
  355. package/dist/jinja-WPD26JJ6.js +3 -0
  356. package/dist/jinja-WPD26JJ6.js.map +1 -0
  357. package/dist/jison-UYDZQBN5.js +3 -0
  358. package/dist/jison-UYDZQBN5.js.map +1 -0
  359. package/dist/json-5V4JESJO.js +3 -0
  360. package/dist/json-5V4JESJO.js.map +1 -0
  361. package/dist/json5-7SHUZD3R.js +3 -0
  362. package/dist/json5-7SHUZD3R.js.map +1 -0
  363. package/dist/jsonc-X3Z34FN3.js +3 -0
  364. package/dist/jsonc-X3Z34FN3.js.map +1 -0
  365. package/dist/jsonl-6I3D2HM6.js +3 -0
  366. package/dist/jsonl-6I3D2HM6.js.map +1 -0
  367. package/dist/jsonnet-PZEQIBYV.js +3 -0
  368. package/dist/jsonnet-PZEQIBYV.js.map +1 -0
  369. package/dist/jssm-GJJ25IKR.js +3 -0
  370. package/dist/jssm-GJJ25IKR.js.map +1 -0
  371. package/dist/jsx-NI2J427C.js +3 -0
  372. package/dist/jsx-NI2J427C.js.map +1 -0
  373. package/dist/julia-QPZ7EOS6.js +3 -0
  374. package/dist/julia-QPZ7EOS6.js.map +1 -0
  375. package/dist/kanagawa-dragon-JNDVF5RJ.js +3 -0
  376. package/dist/kanagawa-dragon-JNDVF5RJ.js.map +1 -0
  377. package/dist/kanagawa-lotus-S7JK6TQ6.js +3 -0
  378. package/dist/kanagawa-lotus-S7JK6TQ6.js.map +1 -0
  379. package/dist/kanagawa-wave-QJJIMVEV.js +3 -0
  380. package/dist/kanagawa-wave-QJJIMVEV.js.map +1 -0
  381. package/dist/kdl-IA7HA2TL.js +3 -0
  382. package/dist/kdl-IA7HA2TL.js.map +1 -0
  383. package/dist/kotlin-CCRMGYMI.js +3 -0
  384. package/dist/kotlin-CCRMGYMI.js.map +1 -0
  385. package/dist/kusto-7DW25GYH.js +3 -0
  386. package/dist/kusto-7DW25GYH.js.map +1 -0
  387. package/dist/laserwave-YFP3EJVX.js +3 -0
  388. package/dist/laserwave-YFP3EJVX.js.map +1 -0
  389. package/dist/latex-F2CTDTFG.js +3 -0
  390. package/dist/latex-F2CTDTFG.js.map +1 -0
  391. package/dist/lean-MGJJWBTR.js +3 -0
  392. package/dist/lean-MGJJWBTR.js.map +1 -0
  393. package/dist/less-WFSIMX5G.js +3 -0
  394. package/dist/less-WFSIMX5G.js.map +1 -0
  395. package/dist/light-plus-NGDHCPUZ.js +3 -0
  396. package/dist/light-plus-NGDHCPUZ.js.map +1 -0
  397. package/dist/liquid-7CFNUD3V.js +3 -0
  398. package/dist/liquid-7CFNUD3V.js.map +1 -0
  399. package/dist/llvm-CFQSEDXB.js +3 -0
  400. package/dist/llvm-CFQSEDXB.js.map +1 -0
  401. package/dist/log-YQNML6LA.js +3 -0
  402. package/dist/log-YQNML6LA.js.map +1 -0
  403. package/dist/logo-2PPKBL2M.js +3 -0
  404. package/dist/logo-2PPKBL2M.js.map +1 -0
  405. package/dist/lua-RPAMRKNG.js +3 -0
  406. package/dist/lua-RPAMRKNG.js.map +1 -0
  407. package/dist/luau-GR2DOH6N.js +3 -0
  408. package/dist/luau-GR2DOH6N.js.map +1 -0
  409. package/dist/make-DQQEEPI4.js +3 -0
  410. package/dist/make-DQQEEPI4.js.map +1 -0
  411. package/dist/markdown-OC5ILZSY.js +3 -0
  412. package/dist/markdown-OC5ILZSY.js.map +1 -0
  413. package/dist/marko-XSB3CTWQ.js +3 -0
  414. package/dist/marko-XSB3CTWQ.js.map +1 -0
  415. package/dist/material-theme-H2BHKUKX.js +3 -0
  416. package/dist/material-theme-H2BHKUKX.js.map +1 -0
  417. package/dist/material-theme-darker-VENCGWTB.js +3 -0
  418. package/dist/material-theme-darker-VENCGWTB.js.map +1 -0
  419. package/dist/material-theme-lighter-SDMLS22W.js +3 -0
  420. package/dist/material-theme-lighter-SDMLS22W.js.map +1 -0
  421. package/dist/material-theme-ocean-UHDBRLVF.js +3 -0
  422. package/dist/material-theme-ocean-UHDBRLVF.js.map +1 -0
  423. package/dist/material-theme-palenight-3TB2BEET.js +3 -0
  424. package/dist/material-theme-palenight-3TB2BEET.js.map +1 -0
  425. package/dist/matlab-YQY6FS4U.js +3 -0
  426. package/dist/matlab-YQY6FS4U.js.map +1 -0
  427. package/dist/mcp/index.d.ts +397 -39
  428. package/dist/mcp/index.js +3 -3
  429. package/dist/mcp/index.js.map +1 -1
  430. package/dist/mcp/react.d.ts +84 -25
  431. package/dist/mcp/react.js +7 -7
  432. package/dist/mcp/react.js.map +1 -1
  433. package/dist/mcp-apps-client-6WEBHSGH.js +3 -0
  434. package/dist/mcp-apps-client-6WEBHSGH.js.map +1 -0
  435. package/dist/mdc-TEVTGSC7.js +3 -0
  436. package/dist/mdc-TEVTGSC7.js.map +1 -0
  437. package/dist/mdx-ZIH2JLVR.js +3 -0
  438. package/dist/mdx-ZIH2JLVR.js.map +1 -0
  439. package/dist/mermaid-4DMBBIKO-NR6M3PLG.js +3 -0
  440. package/dist/mermaid-4DMBBIKO-NR6M3PLG.js.map +1 -0
  441. package/dist/mermaid-WPX56SBB.js +3 -0
  442. package/dist/mermaid-WPX56SBB.js.map +1 -0
  443. package/dist/min-dark-CQ5WKNT7.js +3 -0
  444. package/dist/min-dark-CQ5WKNT7.js.map +1 -0
  445. package/dist/min-light-LZRD4NPR.js +3 -0
  446. package/dist/min-light-LZRD4NPR.js.map +1 -0
  447. package/dist/mipsasm-IDXQRZ2B.js +3 -0
  448. package/dist/mipsasm-IDXQRZ2B.js.map +1 -0
  449. package/dist/mojo-MH7EQVOK.js +3 -0
  450. package/dist/mojo-MH7EQVOK.js.map +1 -0
  451. package/dist/monokai-WHRY6275.js +3 -0
  452. package/dist/monokai-WHRY6275.js.map +1 -0
  453. package/dist/moonbit-5JDFTWKE.js +3 -0
  454. package/dist/moonbit-5JDFTWKE.js.map +1 -0
  455. package/dist/move-RWSXKYDY.js +3 -0
  456. package/dist/move-RWSXKYDY.js.map +1 -0
  457. package/dist/narrat-QJUEXMVV.js +3 -0
  458. package/dist/narrat-QJUEXMVV.js.map +1 -0
  459. package/dist/nextflow-2EICNZA3.js +3 -0
  460. package/dist/nextflow-2EICNZA3.js.map +1 -0
  461. package/dist/nginx-RIWAEC5Z.js +3 -0
  462. package/dist/nginx-RIWAEC5Z.js.map +1 -0
  463. package/dist/night-owl-7PNEW2JB.js +3 -0
  464. package/dist/night-owl-7PNEW2JB.js.map +1 -0
  465. package/dist/night-owl-light-GJUYOOJR.js +3 -0
  466. package/dist/night-owl-light-GJUYOOJR.js.map +1 -0
  467. package/dist/nim-JPSYX5KC.js +3 -0
  468. package/dist/nim-JPSYX5KC.js.map +1 -0
  469. package/dist/nix-XCKQVWCN.js +3 -0
  470. package/dist/nix-XCKQVWCN.js.map +1 -0
  471. package/dist/nord-EVGUMUX2.js +3 -0
  472. package/dist/nord-EVGUMUX2.js.map +1 -0
  473. package/dist/nushell-QGW7HANA.js +3 -0
  474. package/dist/nushell-QGW7HANA.js.map +1 -0
  475. package/dist/objective-c-V7KYXFHL.js +3 -0
  476. package/dist/objective-c-V7KYXFHL.js.map +1 -0
  477. package/dist/objective-cpp-NKUEWVGU.js +3 -0
  478. package/dist/objective-cpp-NKUEWVGU.js.map +1 -0
  479. package/dist/ocaml-QT2CZJZN.js +3 -0
  480. package/dist/ocaml-QT2CZJZN.js.map +1 -0
  481. package/dist/odin-MVMIXBHP.js +3 -0
  482. package/dist/odin-MVMIXBHP.js.map +1 -0
  483. package/dist/one-dark-pro-PMTR3SA7.js +3 -0
  484. package/dist/one-dark-pro-PMTR3SA7.js.map +1 -0
  485. package/dist/one-light-O7WH4N5X.js +3 -0
  486. package/dist/one-light-O7WH4N5X.js.map +1 -0
  487. package/dist/openai-client-HLQSYZJC.js +3 -0
  488. package/dist/openai-client-HLQSYZJC.js.map +1 -0
  489. package/dist/openscad-BJDUXUUZ.js +3 -0
  490. package/dist/openscad-BJDUXUUZ.js.map +1 -0
  491. package/dist/pascal-HGWEFD6L.js +3 -0
  492. package/dist/pascal-HGWEFD6L.js.map +1 -0
  493. package/dist/perl-X4IFZB22.js +3 -0
  494. package/dist/perl-X4IFZB22.js.map +1 -0
  495. package/dist/php-3V7EPUAN.js +3 -0
  496. package/dist/php-3V7EPUAN.js.map +1 -0
  497. package/dist/pkl-VA5ZK5DW.js +3 -0
  498. package/dist/pkl-VA5ZK5DW.js.map +1 -0
  499. package/dist/plastic-FBVUW6NJ.js +3 -0
  500. package/dist/plastic-FBVUW6NJ.js.map +1 -0
  501. package/dist/plsql-J7A7YWFH.js +3 -0
  502. package/dist/plsql-J7A7YWFH.js.map +1 -0
  503. package/dist/po-5RDI65JX.js +3 -0
  504. package/dist/po-5RDI65JX.js.map +1 -0
  505. package/dist/poimandres-WBB7GZAD.js +3 -0
  506. package/dist/poimandres-WBB7GZAD.js.map +1 -0
  507. package/dist/polar-VUJL2E7F.js +3 -0
  508. package/dist/polar-VUJL2E7F.js.map +1 -0
  509. package/dist/postcss-ESTB5G7N.js +3 -0
  510. package/dist/postcss-ESTB5G7N.js.map +1 -0
  511. package/dist/powerquery-ODTEKQCW.js +3 -0
  512. package/dist/powerquery-ODTEKQCW.js.map +1 -0
  513. package/dist/powershell-ZOYRAWBJ.js +3 -0
  514. package/dist/powershell-ZOYRAWBJ.js.map +1 -0
  515. package/dist/prisma-QHG2W5GE.js +3 -0
  516. package/dist/prisma-QHG2W5GE.js.map +1 -0
  517. package/dist/prolog-CSAPG5PH.js +3 -0
  518. package/dist/prolog-CSAPG5PH.js.map +1 -0
  519. package/dist/proto-WDNJBTSW.js +3 -0
  520. package/dist/proto-WDNJBTSW.js.map +1 -0
  521. package/dist/pug-P7LS6DER.js +3 -0
  522. package/dist/pug-P7LS6DER.js.map +1 -0
  523. package/dist/puppet-LHFWHTY3.js +3 -0
  524. package/dist/puppet-LHFWHTY3.js.map +1 -0
  525. package/dist/purescript-DUFJP4FY.js +3 -0
  526. package/dist/purescript-DUFJP4FY.js.map +1 -0
  527. package/dist/python-5ZNZSNQ2.js +3 -0
  528. package/dist/python-5ZNZSNQ2.js.map +1 -0
  529. package/dist/qml-LTAXB6W5.js +3 -0
  530. package/dist/qml-LTAXB6W5.js.map +1 -0
  531. package/dist/qmldir-7Z2ODQLM.js +3 -0
  532. package/dist/qmldir-7Z2ODQLM.js.map +1 -0
  533. package/dist/qss-FDFD3HQD.js +3 -0
  534. package/dist/qss-FDFD3HQD.js.map +1 -0
  535. package/dist/r-6ZOS53WN.js +3 -0
  536. package/dist/r-6ZOS53WN.js.map +1 -0
  537. package/dist/racket-7AYZPEUI.js +3 -0
  538. package/dist/racket-7AYZPEUI.js.map +1 -0
  539. package/dist/raku-A4F6VHVG.js +3 -0
  540. package/dist/raku-A4F6VHVG.js.map +1 -0
  541. package/dist/razor-4QOCK4UD.js +3 -0
  542. package/dist/razor-4QOCK4UD.js.map +1 -0
  543. package/dist/red-7KAMONOP.js +3 -0
  544. package/dist/red-7KAMONOP.js.map +1 -0
  545. package/dist/reg-FAPHGG66.js +3 -0
  546. package/dist/reg-FAPHGG66.js.map +1 -0
  547. package/dist/regexp-5BYLYA2R.js +3 -0
  548. package/dist/regexp-5BYLYA2R.js.map +1 -0
  549. package/dist/rel-7DJ7HHU4.js +3 -0
  550. package/dist/rel-7DJ7HHU4.js.map +1 -0
  551. package/dist/riscv-YIYJATFG.js +3 -0
  552. package/dist/riscv-YIYJATFG.js.map +1 -0
  553. package/dist/ron-HYYMCHTX.js +3 -0
  554. package/dist/ron-HYYMCHTX.js.map +1 -0
  555. package/dist/rose-pine-F2G5IHZD.js +3 -0
  556. package/dist/rose-pine-F2G5IHZD.js.map +1 -0
  557. package/dist/rose-pine-dawn-ALZ7XGH2.js +3 -0
  558. package/dist/rose-pine-dawn-ALZ7XGH2.js.map +1 -0
  559. package/dist/rose-pine-moon-D3K4SWUL.js +3 -0
  560. package/dist/rose-pine-moon-D3K4SWUL.js.map +1 -0
  561. package/dist/rosmsg-FDNH6QF7.js +3 -0
  562. package/dist/rosmsg-FDNH6QF7.js.map +1 -0
  563. package/dist/rst-WIWCR2KQ.js +3 -0
  564. package/dist/rst-WIWCR2KQ.js.map +1 -0
  565. package/dist/ruby-LXZJUMFB.js +3 -0
  566. package/dist/ruby-LXZJUMFB.js.map +1 -0
  567. package/dist/rust-V3GMJA2K.js +3 -0
  568. package/dist/rust-V3GMJA2K.js.map +1 -0
  569. package/dist/sas-D3G4GB3X.js +3 -0
  570. package/dist/sas-D3G4GB3X.js.map +1 -0
  571. package/dist/sass-JTO65AGR.js +3 -0
  572. package/dist/sass-JTO65AGR.js.map +1 -0
  573. package/dist/scala-4XQGFSVM.js +3 -0
  574. package/dist/scala-4XQGFSVM.js.map +1 -0
  575. package/dist/scheme-CB7AC7IL.js +3 -0
  576. package/dist/scheme-CB7AC7IL.js.map +1 -0
  577. package/dist/scss-6SKV4OGI.js +3 -0
  578. package/dist/scss-6SKV4OGI.js.map +1 -0
  579. package/dist/sdbl-LKGZFJ46.js +3 -0
  580. package/dist/sdbl-LKGZFJ46.js.map +1 -0
  581. package/dist/shaderlab-K536DHEB.js +3 -0
  582. package/dist/shaderlab-K536DHEB.js.map +1 -0
  583. package/dist/shellscript-LRNUKUSZ.js +3 -0
  584. package/dist/shellscript-LRNUKUSZ.js.map +1 -0
  585. package/dist/shellsession-IBQK7VWQ.js +3 -0
  586. package/dist/shellsession-IBQK7VWQ.js.map +1 -0
  587. package/dist/slack-dark-YFPJODWS.js +3 -0
  588. package/dist/slack-dark-YFPJODWS.js.map +1 -0
  589. package/dist/slack-ochin-H67AWZOI.js +3 -0
  590. package/dist/slack-ochin-H67AWZOI.js.map +1 -0
  591. package/dist/smalltalk-DQOSWAW7.js +3 -0
  592. package/dist/smalltalk-DQOSWAW7.js.map +1 -0
  593. package/dist/snazzy-light-OUVS63VK.js +3 -0
  594. package/dist/snazzy-light-OUVS63VK.js.map +1 -0
  595. package/dist/solarized-dark-2RCAVEXJ.js +3 -0
  596. package/dist/solarized-dark-2RCAVEXJ.js.map +1 -0
  597. package/dist/solarized-light-XFSENHTC.js +3 -0
  598. package/dist/solarized-light-XFSENHTC.js.map +1 -0
  599. package/dist/solidity-V2FMZEG4.js +3 -0
  600. package/dist/solidity-V2FMZEG4.js.map +1 -0
  601. package/dist/soy-VW3CKXWF.js +3 -0
  602. package/dist/soy-VW3CKXWF.js.map +1 -0
  603. package/dist/sparql-L2VKP7YP.js +3 -0
  604. package/dist/sparql-L2VKP7YP.js.map +1 -0
  605. package/dist/splunk-KDKHP7GC.js +3 -0
  606. package/dist/splunk-KDKHP7GC.js.map +1 -0
  607. package/dist/sql-UF27CALT.js +3 -0
  608. package/dist/sql-UF27CALT.js.map +1 -0
  609. package/dist/ssh-config-JC2DQ6ED.js +3 -0
  610. package/dist/ssh-config-JC2DQ6ED.js.map +1 -0
  611. package/dist/stata-7PXCUY24.js +3 -0
  612. package/dist/stata-7PXCUY24.js.map +1 -0
  613. package/dist/stylus-2L7N3EZD.js +3 -0
  614. package/dist/stylus-2L7N3EZD.js.map +1 -0
  615. package/dist/surrealql-ZY3E6XEL.js +3 -0
  616. package/dist/surrealql-ZY3E6XEL.js.map +1 -0
  617. package/dist/svelte-Q45XIK2A.js +3 -0
  618. package/dist/svelte-Q45XIK2A.js.map +1 -0
  619. package/dist/swift-XBH5HZSC.js +3 -0
  620. package/dist/swift-XBH5HZSC.js.map +1 -0
  621. package/dist/synthwave-84-5XXB3K6S.js +3 -0
  622. package/dist/synthwave-84-5XXB3K6S.js.map +1 -0
  623. package/dist/system-verilog-VRAUSZY3.js +3 -0
  624. package/dist/system-verilog-VRAUSZY3.js.map +1 -0
  625. package/dist/systemd-JOTSGJD4.js +3 -0
  626. package/dist/systemd-JOTSGJD4.js.map +1 -0
  627. package/dist/talonscript-NNZRZKOU.js +3 -0
  628. package/dist/talonscript-NNZRZKOU.js.map +1 -0
  629. package/dist/tasl-MBFZ4QNC.js +3 -0
  630. package/dist/tasl-MBFZ4QNC.js.map +1 -0
  631. package/dist/tcl-4GEDCBVE.js +3 -0
  632. package/dist/tcl-4GEDCBVE.js.map +1 -0
  633. package/dist/templ-3XM7DLQ3.js +3 -0
  634. package/dist/templ-3XM7DLQ3.js.map +1 -0
  635. package/dist/terraform-XTHOS4UK.js +3 -0
  636. package/dist/terraform-XTHOS4UK.js.map +1 -0
  637. package/dist/tex-UXMN2CV7.js +3 -0
  638. package/dist/tex-UXMN2CV7.js.map +1 -0
  639. package/dist/tokyo-night-CHJCCBJH.js +3 -0
  640. package/dist/tokyo-night-CHJCCBJH.js.map +1 -0
  641. package/dist/toml-J6K55ZSV.js +3 -0
  642. package/dist/toml-J6K55ZSV.js.map +1 -0
  643. package/dist/ts-tags-7WGDLEKX.js +3 -0
  644. package/dist/ts-tags-7WGDLEKX.js.map +1 -0
  645. package/dist/tsv-DOUJHQDQ.js +3 -0
  646. package/dist/tsv-DOUJHQDQ.js.map +1 -0
  647. package/dist/tsx-G5BMVRHK.js +3 -0
  648. package/dist/tsx-G5BMVRHK.js.map +1 -0
  649. package/dist/turtle-JHJ7W6U5.js +3 -0
  650. package/dist/turtle-JHJ7W6U5.js.map +1 -0
  651. package/dist/twig-C6YWFFZU.js +3 -0
  652. package/dist/twig-C6YWFFZU.js.map +1 -0
  653. package/dist/typescript-LMKEAHFC.js +3 -0
  654. package/dist/typescript-LMKEAHFC.js.map +1 -0
  655. package/dist/typespec-5CLTIJYY.js +3 -0
  656. package/dist/typespec-5CLTIJYY.js.map +1 -0
  657. package/dist/typst-4W4Z436Z.js +3 -0
  658. package/dist/typst-4W4Z436Z.js.map +1 -0
  659. package/dist/v-Y4SBDBN7.js +3 -0
  660. package/dist/v-Y4SBDBN7.js.map +1 -0
  661. package/dist/vala-UMKT2MFA.js +3 -0
  662. package/dist/vala-UMKT2MFA.js.map +1 -0
  663. package/dist/vb-DQ7A5WJU.js +3 -0
  664. package/dist/vb-DQ7A5WJU.js.map +1 -0
  665. package/dist/verilog-N6ZF7GQD.js +3 -0
  666. package/dist/verilog-N6ZF7GQD.js.map +1 -0
  667. package/dist/vesper-Y5GIEAN4.js +3 -0
  668. package/dist/vesper-Y5GIEAN4.js.map +1 -0
  669. package/dist/vhdl-BNYDT37G.js +3 -0
  670. package/dist/vhdl-BNYDT37G.js.map +1 -0
  671. package/dist/viml-37RMDCBC.js +3 -0
  672. package/dist/viml-37RMDCBC.js.map +1 -0
  673. package/dist/vitesse-black-7TI33KHX.js +3 -0
  674. package/dist/vitesse-black-7TI33KHX.js.map +1 -0
  675. package/dist/vitesse-dark-FOB25MRB.js +3 -0
  676. package/dist/vitesse-dark-FOB25MRB.js.map +1 -0
  677. package/dist/vitesse-light-4WCNCTCO.js +3 -0
  678. package/dist/vitesse-light-4WCNCTCO.js.map +1 -0
  679. package/dist/vue-O6SLORWU.js +3 -0
  680. package/dist/vue-O6SLORWU.js.map +1 -0
  681. package/dist/vue-html-ZLTZN573.js +3 -0
  682. package/dist/vue-html-ZLTZN573.js.map +1 -0
  683. package/dist/vue-vine-6JKAZ54I.js +3 -0
  684. package/dist/vue-vine-6JKAZ54I.js.map +1 -0
  685. package/dist/vyper-GVXF46KD.js +3 -0
  686. package/dist/vyper-GVXF46KD.js.map +1 -0
  687. package/dist/wasm-EOPKAILK.js +3 -0
  688. package/dist/wasm-EOPKAILK.js.map +1 -0
  689. package/dist/wasm-NTB4O7GL.js +3 -0
  690. package/dist/wasm-NTB4O7GL.js.map +1 -0
  691. package/dist/wenyan-W7WB3BC7.js +3 -0
  692. package/dist/wenyan-W7WB3BC7.js.map +1 -0
  693. package/dist/wgsl-7GTDVXHG.js +3 -0
  694. package/dist/wgsl-7GTDVXHG.js.map +1 -0
  695. package/dist/wikitext-ASAFPAIL.js +3 -0
  696. package/dist/wikitext-ASAFPAIL.js.map +1 -0
  697. package/dist/wit-ZBCR6544.js +3 -0
  698. package/dist/wit-ZBCR6544.js.map +1 -0
  699. package/dist/wolfram-SZRZOETJ.js +3 -0
  700. package/dist/wolfram-SZRZOETJ.js.map +1 -0
  701. package/dist/xml-EBTJCOTU.js +3 -0
  702. package/dist/xml-EBTJCOTU.js.map +1 -0
  703. package/dist/xsl-IBYEXWDX.js +3 -0
  704. package/dist/xsl-IBYEXWDX.js.map +1 -0
  705. package/dist/yaml-GMVQNECR.js +3 -0
  706. package/dist/yaml-GMVQNECR.js.map +1 -0
  707. package/dist/zenscript-O2TZFP4A.js +3 -0
  708. package/dist/zenscript-O2TZFP4A.js.map +1 -0
  709. package/dist/zig-ZLGM7IMN.js +3 -0
  710. package/dist/zig-ZLGM7IMN.js.map +1 -0
  711. package/package.json +15 -39
  712. package/dist/mcp-apps-client-Z62VBB36.js +0 -3
  713. package/dist/mcp-apps-client-Z62VBB36.js.map +0 -1
  714. package/dist/openai-client-MVV4KJUO.js +0 -3
  715. package/dist/openai-client-MVV4KJUO.js.map +0 -1
package/dist/mcp/index.js CHANGED
@@ -1,4 +1,4 @@
1
- function M(){return typeof window<"u"&&"openai"in window?"openai":"mcp-apps"}function J(){return M()==="openai"}function z(){return M()==="mcp-apps"}var y="__start__",R="__end__",I=Symbol.for("waniwani.flow.interrupt"),F=Symbol.for("waniwani.flow.widget");function O(e){return{__type:I,...e}}function H(e,t){return{__type:F,resource:e,...t}}function _(e){return typeof e=="object"&&e!==null&&"__type"in e&&e.__type===I}function $(e){return typeof e=="object"&&e!==null&&"__type"in e&&e.__type===F}import{z as m}from"zod";var v="text/html+skybridge",E="text/html;profile=mcp-app",A=async(e,t)=>{let o=e.endsWith("/")?e.slice(0,-1):e;return await(await fetch(`${o}${t}`)).text()};function D(e){return{"openai/widgetDescription":e.description,"openai/widgetPrefersBorder":e.prefersBorder,"openai/widgetDomain":e.widgetDomain,...e.widgetCSP&&{"openai/widgetCSP":e.widgetCSP}}}function W(e){let t=e.widgetCSP?{connectDomains:e.widgetCSP.connect_domains,resourceDomains:e.widgetCSP.resource_domains,frameDomains:e.widgetCSP.frame_domains,redirectDomains:e.widgetCSP.redirect_domains}:void 0;return{ui:{...t&&{csp:t},...e.widgetDomain&&{domain:e.widgetDomain},...e.prefersBorder!==void 0&&{prefersBorder:e.prefersBorder}}}}function C(e){return{"openai/outputTemplate":e.openaiTemplateUri,"openai/toolInvocation/invoking":e.invoking,"openai/toolInvocation/invoked":e.invoked,"openai/widgetAccessible":!0,"openai/resultCanProduceWidget":!0,ui:{resourceUri:e.mcpTemplateUri,...e.autoHeight&&{autoHeight:!0}}}}function B(e){let t=e.description??"",o=e._zod?.def;if(o?.type==="enum"&&o.entries){let s=Object.keys(o.entries).map(d=>`"${d}"`).join(" | ");return t?`${s} \u2014 ${t}`:s}return t}function L(e){let t=["","## FLOW EXECUTION PROTOCOL","","This tool implements a multi-step conversational flow. Follow this protocol exactly:","",'1. Call with `action: "start"` to begin. If the user\'s message already'," contains answers to likely questions, extract them into `initialState`"," as `{ field: value }` pairs. The engine will auto-skip questions whose"," fields are already filled."," Only extract values the user explicitly stated \u2014 do NOT guess or invent values."];if(e.fields){let o=Object.entries(e.fields).map(([s,d])=>{let g=B(d);return g?`\`${s}\` (${g})`:`\`${s}\``}).join(", ");t.push(` Known fields: ${o}.`)}return t.push("2. The response JSON `status` field tells you what to do next:",' - `"interrupt"`: Ask the user the `question`. If a `context` field is present,'," use it as hidden instructions to enrich your response (do NOT show it verbatim)."," Then call again with:",' `action: "continue"`, `step` = the returned `step`, `state` = the returned `state`,'," `answer` = the user's answer.",' - `"widget"`: A widget UI is being shown. The user will interact with the widget.'," When the user makes a choice and you need to continue the flow, call again with:",' `action: "widget_result"`, `step` = the returned `step`, `state` = the returned `state`,'," `answer` = the user's selection.",' - `"complete"`: The flow is done. Present the result to the user.',' - `"error"`: Something went wrong. Show the `error` message.',"","3. ALWAYS pass back the `state` object exactly as received.","4. Do NOT invent state values. Only use `initialState` for information the user explicitly provided."),t.join(`
2
- `)}async function N(e,t){return e.type==="direct"?e.to:e.condition(t)}async function b(e,t,o,s,d,g,h){let r=e,p={...t},x=50,n=0;for(;n++<x;){if(r===R)return{text:JSON.stringify({status:"complete",state:p}),data:{status:"complete",state:p}};let l=o.get(r);if(!l)return{text:JSON.stringify({status:"error",error:`Unknown node: "${r}"`}),data:{status:"error"}};try{let a=await l(p,h);if(_(a)){let i=p[a.field];if(i!=null&&i!==""){let u=d.get(r);if(!u)return{text:JSON.stringify({status:"error",error:`No outgoing edge from node "${r}"`}),data:{status:"error"}};r=await N(u,p);continue}return{text:JSON.stringify({status:"interrupt",step:r,question:a.question,field:a.field,suggestions:a.suggestions,...a.context?{context:a.context}:{},state:p}),data:{status:"interrupt",step:r,state:p}}}if($(a)){let i=s.get(r)?.field;if(i){let w=p[i];if(w!=null&&w!==""){let f=d.get(r);if(!f)return{text:JSON.stringify({status:"error",error:`No outgoing edge from node "${r}"`}),data:{status:"error"}};r=await N(f,p);continue}}let u=a.resource;return{text:JSON.stringify({status:"widget",step:r,widgetId:u.id,description:a.description,state:p}),data:{...a.data,__flow:{flowId:g,step:r,state:p}},widgetMeta:C({openaiTemplateUri:u.openaiUri,mcpTemplateUri:u.mcpUri,invoking:"Loading...",invoked:"Loaded",autoHeight:u.autoHeight})}}p={...p,...a};let c=d.get(r);if(!c)return{text:JSON.stringify({status:"error",error:`No outgoing edge from node "${r}"`}),data:{status:"error"}};r=await N(c,p)}catch(a){let c=a instanceof Error?a.message:String(a);return{text:JSON.stringify({status:"error",step:r,error:c,state:p}),data:{status:"error",error:c}}}}return{text:JSON.stringify({status:"error",error:"Flow exceeded maximum iterations (possible infinite loop)"}),data:{status:"error"}}}var Y={action:m.enum(["start","continue","widget_result"]).describe('"start" to begin the flow, "continue" after the user answers a question, "widget_result" when a widget returns data'),step:m.string().optional().describe("Current step name (from the previous response)"),state:m.record(m.string(),m.unknown()).optional().describe("Flow state \u2014 pass back exactly as received"),answer:m.string().optional().describe("The user's answer (for interrupt steps)"),widgetResult:m.record(m.string(),m.unknown()).optional().describe("Data returned by a widget callback"),initialState:m.record(m.string(),m.unknown()).optional().describe(`Pre-filled answers extracted from the user's message (only for action: "start")`)};function U(e){let{config:t,nodes:o,nodeConfigs:s,edges:d}=e,g=L(t),h=`${t.description}
3
- ${g}`,r;for(let n of s.values())if(n.resource){r=n.resource;break}let p=r?C({openaiTemplateUri:r.openaiUri,mcpTemplateUri:r.mcpUri,invoking:"Loading...",invoked:"Loaded",autoHeight:r.autoHeight}):void 0;async function x(n,l){let a=n.state??{};if(n.action==="start"){let c=d.get(y);if(!c)return{text:JSON.stringify({status:"error",error:"No start edge"}),data:{status:"error"}};let i=n.initialState?{...a,...n.initialState}:a,u=await N(c,i);return b(u,i,o,s,d,t.id,l)}if(n.action==="continue"){if(!n.step)return{text:JSON.stringify({status:"error",error:'Missing "step" for continue action'}),data:{status:"error"}};let c={...a};if(n.answer){let w=o.get(n.step);if(w)try{let f=await w(c,l);_(f)&&f.field&&(c={...c,[f.field]:n.answer})}catch{}}let i=d.get(n.step);if(!i)return{text:JSON.stringify({status:"error",error:`No edge from step "${n.step}"`}),data:{status:"error"}};let u=await N(i,c);return b(u,c,o,s,d,t.id,l)}if(n.action==="widget_result"){if(!n.step)return{text:JSON.stringify({status:"error",error:'Missing "step" for widget_result action'}),data:{status:"error"}};let c=n.widgetResult??{};if(n.answer!==void 0&&Object.keys(c).length===0){let f=s.get(n.step)?.field;f&&(c={[f]:n.answer})}let i={...a,...c},u=d.get(n.step);if(!u)return{text:JSON.stringify({status:"error",error:`No edge from step "${n.step}"`}),data:{status:"error"}};let w=await N(u,i);return b(w,i,o,s,d,t.id,l)}return{text:JSON.stringify({status:"error",error:`Unknown action: "${n.action}"`}),data:{status:"error"}}}return{id:t.id,title:t.title,description:h,async register(n){n.registerTool(t.id,{title:t.title,description:h,inputSchema:Y,annotations:t.annotations,...p&&{_meta:p}},(async(l,a)=>{let i=a._meta??{},u=await x(l,i);return u.widgetMeta?{content:[{type:"text",text:u.text}],structuredContent:u.data,_meta:{...u.widgetMeta,...i}}:{content:[{type:"text",text:u.text}]}}))}}}var k=class{nodes=new Map;nodeConfigs=new Map;edges=new Map;config;constructor(t){this.config=t}addNode(t,o,s){if(t===y||t===R)throw new Error(`"${t}" is a reserved name and cannot be used as a node name`);if(this.nodes.has(t))throw new Error(`Node "${t}" already exists`);let d,g={};if(typeof o=="function")d=o;else{if(!s)throw new Error(`addNode("${t}", config, handler) requires a handler as the third argument`);d=s,g=o}return this.nodes.set(t,d),this.nodeConfigs.set(t,g),this}addEdge(t,o){if(this.edges.has(t))throw new Error(`Node "${t}" already has an outgoing edge. Use addConditionalEdge for branching.`);return this.edges.set(t,{type:"direct",to:o}),this}addConditionalEdge(t,o){if(this.edges.has(t))throw new Error(`Node "${t}" already has an outgoing edge.`);return this.edges.set(t,{type:"conditional",condition:o}),this}compile(){return this.validate(),U({config:this.config,nodes:new Map(this.nodes),nodeConfigs:new Map(this.nodeConfigs),edges:new Map(this.edges)})}validate(){if(!this.edges.has(y))throw new Error('Flow must have an entry point. Add an edge from START: .addEdge(START, "first_node")');let t=this.edges.get(y);if(t?.type==="direct"&&t.to!==R&&!this.nodes.has(t.to))throw new Error(`START edge references non-existent node: "${t.to}"`);for(let[o,s]of this.edges){if(o!==y&&!this.nodes.has(o))throw new Error(`Edge from non-existent node: "${o}"`);if(s.type==="direct"&&s.to!==R&&!this.nodes.has(s.to))throw new Error(`Edge from "${o}" references non-existent node: "${s.to}"`)}for(let[o]of this.nodes)if(!this.edges.has(o))throw new Error(`Node "${o}" has no outgoing edge. Add one with .addEdge("${o}", ...) or .addConditionalEdge("${o}", ...)`)}};function q(e){return new k(e)}function j(e){let{id:t,title:o,description:s,baseUrl:d,htmlPath:g,widgetDomain:h,prefersBorder:r=!0,autoHeight:p}=e,x=e.widgetCSP??{connect_domains:[d],resource_domains:[d]},n=`ui://widgets/apps-sdk/${t}.html`,l=`ui://widgets/ext-apps/${t}.html`,a=null,c=()=>(a||(a=A(d,g)),a),i=s;async function u(w){let f=await c();w.registerResource(`${t}-openai-widget`,n,{title:o,description:i,mimeType:v,_meta:{"openai/widgetDescription":i,"openai/widgetPrefersBorder":r}},async P=>({contents:[{uri:P.href,mimeType:v,text:f,_meta:D({description:i,prefersBorder:r,widgetDomain:h,widgetCSP:x})}]})),w.registerResource(`${t}-mcp-widget`,l,{title:o,description:i,mimeType:E,_meta:{ui:{prefersBorder:r}}},async P=>({contents:[{uri:P.href,mimeType:E,text:f,_meta:W({description:i,prefersBorder:r,widgetCSP:x})}]}))}return{id:t,title:o,description:s,openaiUri:n,mcpUri:l,autoHeight:p,register:u}}function G(e,t){let{resource:o,description:s,inputSchema:d,annotations:g}=e,h=e.id??o?.id,r=e.title??o?.title;if(!h)throw new Error("createTool: `id` is required when no resource is provided");if(!r)throw new Error("createTool: `title` is required when no resource is provided");let p=o?C({openaiTemplateUri:o.openaiUri,mcpTemplateUri:o.mcpUri,invoking:e.invoking??"Loading...",invoked:e.invoked??"Loaded",autoHeight:o.autoHeight}):void 0;return{id:h,title:r,description:s,async register(x){x.registerTool(h,{title:r,description:s,inputSchema:d,annotations:g,...p&&{_meta:p}},(async(n,l)=>{let c=l._meta??{},i=await t(n,{extra:{_meta:c}});return o&&i.data?{content:[{type:"text",text:i.text}],structuredContent:i.data,_meta:{...p,...c}}:{content:[{type:"text",text:i.text}]}}))}}}async function Z(e,t){await Promise.all(t.map(o=>o.register(e)))}export{R as END,y as START,k as StateGraph,q as createFlow,j as createResource,G as createTool,M as detectPlatform,O as interrupt,z as isMCPApps,J as isOpenAI,Z as registerTools,H as showWidget};
1
+ function D(){return typeof window<"u"&&"openai"in window?"openai":"mcp-apps"}function de(){return D()==="openai"}function ce(){return D()==="mcp-apps"}var E="__start__",R="__end__",B=Symbol.for("waniwani.flow.interrupt"),V=Symbol.for("waniwani.flow.widget");function $(e){if("questions"in e)return{__type:B,questions:e.questions,context:e.context};let{question:t,field:n,context:r,suggestions:o}=e;return{__type:B,questions:[{question:t,field:n,context:r,suggestions:o}]}}function C(e,t){return{__type:V,resource:e,...t}}function H(e){return typeof e=="object"&&e!==null&&"__type"in e&&e.__type===B}function z(e){return typeof e=="object"&&e!==null&&"__type"in e&&e.__type===V}import{z as v}from"zod";var b="text/html+skybridge",P="text/html;profile=mcp-app",K=async(e,t)=>{let n=e.endsWith("/")?e.slice(0,-1):e;return await(await fetch(`${n}${t}`)).text()};function Y(e){return{"openai/widgetDescription":e.description,"openai/widgetPrefersBorder":e.prefersBorder,"openai/widgetDomain":e.widgetDomain,...e.widgetCSP&&{"openai/widgetCSP":e.widgetCSP}}}function X(e){let t=e.widgetCSP?{connectDomains:e.widgetCSP.connect_domains,resourceDomains:e.widgetCSP.resource_domains,frameDomains:e.widgetCSP.frame_domains,redirectDomains:e.widgetCSP.redirect_domains}:void 0;return{ui:{...t&&{csp:t},...e.widgetDomain&&{domain:e.widgetDomain},...e.prefersBorder!==void 0&&{prefersBorder:e.prefersBorder}}}}function x(e){return{"openai/outputTemplate":e.openaiTemplateUri,"openai/toolInvocation/invoking":e.invoking,"openai/toolInvocation/invoked":e.invoked,"openai/widgetAccessible":!0,"openai/resultCanProduceWidget":!0,ui:{resourceUri:e.mcpTemplateUri,...e.autoHeight&&{autoHeight:!0}}}}function ue(e){let t=e.description??"",n=e._zod?.def;if(n?.type==="enum"&&n.entries){let r=Object.keys(n.entries).map(o=>`"${o}"`).join(" | ");return t?`${r} \u2014 ${t}`:r}return t}function pe(e){let t=["","## FLOW EXECUTION PROTOCOL","","This tool implements a multi-step conversational flow. Follow this protocol exactly:","",'1. Call with `action: "start"` to begin. If the user\'s message already'," contains answers to likely questions, extract them into `stateUpdates`"," as `{ field: value }` pairs. The engine will auto-skip steps whose"," fields are already filled."," Only extract values the user explicitly stated \u2014 do NOT guess or invent values."];if(e.state){let n=Object.entries(e.state).map(([r,o])=>{let a=ue(o);return a?`\`${r}\` (${a})`:`\`${r}\``}).join(", ");t.push(` Known fields: ${n}.`)}return t.push("2. The response JSON `status` field tells you what to do next:",' - `"interrupt"`: Pause and ask the user. Two forms:'," a. Single question: `{ question, field, context? }` \u2014 ask `question`, store answer in `field`."," b. Multi-question: `{ questions: [{question, field}, ...], context? }` \u2014 ask ALL questions"," in one conversational message, collect all answers."," `context` (if present) is hidden AI instructions \u2014 use to shape your response, do NOT show verbatim."," Then call again with:",' `action: "continue"`, `state` = the returned `state`,'," `stateUpdates` = answers keyed by their `field` names, plus any other fields the user mentioned.",' - `"widget"`: A widget UI is being shown. The user will interact with the widget.'," When the user makes a choice, call again with:",' `action: "continue"`, `state` = the returned `state`,'," `stateUpdates` = `{ [_meta.flow.field]: <user's selection> }` plus any other fields the user mentioned.",' - `"complete"`: The flow is done. Present the result to the user.',' - `"error"`: Something went wrong. Show the `error` message.',"","3. ALWAYS pass back the `state` object exactly as received.","4. Do NOT invent state values. Only use `stateUpdates` for information the user explicitly provided.","5. Always include answers for all pending fields in `stateUpdates` when resuming."," If the user mentioned values for other known fields, include those too \u2014"," they will be applied immediately and those steps will be auto-skipped."),t.join(`
2
+ `)}function le(e){let t=e._meta?.flow?.state??{},n=e._meta?.flow?.step,r=e._meta?.flow?.field,o=e._meta?.flow?.widgetId;return{step:n,state:t,field:r,widgetId:o}}async function M(e,t){return e.type==="direct"?e.to:e.condition(t)}async function J(e,t,n,r,o,a){let i=e,s={...t},c=50,g=0;for(;g++<c;){if(i===R)return{payload:{status:"complete"},flowMeta:{state:s}};let k=n.get(i);if(!k)return{payload:{status:"error",error:`Unknown node: "${i}"`}};try{let d=await k(s,a);if(H(d)){if(d.questions.every(m=>{let h=s[m.field];return h!=null&&h!==""})){let m=o.get(i);if(!m)return{payload:{status:"error",error:`No outgoing edge from node "${i}"`}};i=await M(m,s);continue}let l=d.questions.length===1,p=d.questions[0];return{payload:l&&p?{status:"interrupt",question:p.question,field:p.field,...p.suggestions?{suggestions:p.suggestions}:{},...p.context||d.context?{context:p.context??d.context}:{}}:{status:"interrupt",questions:d.questions,...d.context?{context:d.context}:{}},flowMeta:{step:i,state:s,...l&&p?{field:p.field}:{}}}}if(z(d)){let T=d.field??r.get(i)?.field;if(T){let p=s[T];if(p!=null&&p!==""){let u=o.get(i);if(!u)return{payload:{status:"error",error:`No outgoing edge from node "${i}"`}};i=await M(u,s);continue}}let l=d.resource;return{payload:{status:"widget",description:d.description},data:d.data,widgetMeta:x({openaiTemplateUri:l.openaiUri,mcpTemplateUri:l.mcpUri,invoking:"Loading...",invoked:"Loaded",autoHeight:l.autoHeight}),flowMeta:{step:i,state:s,field:T,widgetId:l.id}}}s={...s,...d};let f=o.get(i);if(!f)return{payload:{status:"error",error:`No outgoing edge from node "${i}"`}};i=await M(f,s)}catch(d){return{payload:{status:"error",error:d instanceof Error?d.message:String(d)},flowMeta:{step:i,state:s}}}}return{payload:{status:"error",error:"Flow exceeded maximum iterations (possible infinite loop)"}}}var ge={action:v.enum(["start","continue"]).describe('"start" to begin the flow, "continue" to resume after a pause (interrupt or widget)'),stateUpdates:v.record(v.string(),v.unknown()).optional().describe("State field values to set before processing the next node. Use this to pass the user's answer (keyed by the field name from _meta.flow.field) and any other values the user mentioned."),_meta:v.object({flow:v.object({step:v.string().optional().describe("Current step name (from the previous response)"),state:v.record(v.string(),v.unknown()).optional().describe("Flow state \u2014 pass back exactly as received"),field:v.string().optional(),widgetId:v.string().optional()}).optional().describe("Flow routing data. Pass back exactly as received.")}).optional().describe("Internal flow routing data. Pass back the _meta object from the previous response exactly as received.")};function Z(e){let{config:t,nodes:n,nodeConfigs:r,edges:o,resources:a}=e,i=pe(t),s=`${t.description}
3
+ ${i}`,c=a[0],g=c?x({openaiTemplateUri:c.openaiUri,mcpTemplateUri:c.mcpUri,invoking:"Loading...",invoked:"Loaded",autoHeight:c.autoHeight}):void 0;async function k(d,f){let T=le(d),l=T.state;if(d.action==="start"){let p=o.get(E);if(!p)return{payload:{status:"error",error:"No start edge"}};let u={...l,...d.stateUpdates??{}},m=await M(p,u);return J(m,u,n,r,o,f)}if(d.action==="continue"){let p=T.step;if(!p)return{payload:{status:"error",error:'Missing "_meta.flow.step" for continue action'}};let u={...l,...d.stateUpdates??{}},m=o.get(p);if(!m)return{payload:{status:"error",error:`No edge from step "${p}"`}};let h=await M(m,u);return J(h,u,n,r,o,f)}return{payload:{status:"error",error:`Unknown action: "${d.action}"`}}}return{id:t.id,title:t.title,description:s,async register(d){d.registerTool(t.id,{title:t.title,description:s,inputSchema:ge,annotations:t.annotations,...g&&{_meta:g}},(async(f,T)=>{let p=T._meta??{},u=await k(f,p),m={...u.widgetMeta??{},...p,...u.flowMeta?{flow:{flowId:t.id,...u.flowMeta}}:{}},h=[{type:"text",text:JSON.stringify(u.payload,null,2)}];return u.widgetMeta?{content:h,structuredContent:u.data,_meta:m}:{content:h,...Object.keys(m).length>0?{_meta:m}:{}}}))}}}var I=class{nodes=new Map;nodeConfigs=new Map;edges=new Map;config;resources=[];constructor(t){this.config=t}addNode(t,n,r){if(t===E||t===R)throw new Error(`"${t}" is a reserved name and cannot be used as a node name`);if(this.nodes.has(t))throw new Error(`Node "${t}" already exists`);let o,a={};if(typeof n=="function")o=n;else if(r)o=r,a=n;else{let i=n;this.resources.push(i.resource),a={field:i.field},o=s=>C(i.resource,{data:typeof i.data=="function"?i.data(s):i.data??{},description:i.description,field:i.field})}return this.nodes.set(t,o),this.nodeConfigs.set(t,a),this}addEdge(t,n){if(this.edges.has(t))throw new Error(`Node "${t}" already has an outgoing edge. Use addConditionalEdge for branching.`);return this.edges.set(t,{type:"direct",to:n}),this}addConditionalEdge(t,n){if(this.edges.has(t))throw new Error(`Node "${t}" already has an outgoing edge.`);return this.edges.set(t,{type:"conditional",condition:n}),this}compile(){return this.validate(),Z({config:this.config,nodes:new Map(this.nodes),nodeConfigs:new Map(this.nodeConfigs),edges:new Map(this.edges),resources:[...this.resources]})}validate(){if(!this.edges.has(E))throw new Error('Flow must have an entry point. Add an edge from START: .addEdge(START, "first_node")');let t=this.edges.get(E);if(t?.type==="direct"&&t.to!==R&&!this.nodes.has(t.to))throw new Error(`START edge references non-existent node: "${t.to}"`);for(let[n,r]of this.edges){if(n!==E&&!this.nodes.has(n))throw new Error(`Edge from non-existent node: "${n}"`);if(r.type==="direct"&&r.to!==R&&!this.nodes.has(r.to))throw new Error(`Edge from "${n}" references non-existent node: "${r.to}"`)}for(let[n]of this.nodes)if(!this.edges.has(n))throw new Error(`Node "${n}" has no outgoing edge. Add one with .addEdge("${n}", ...) or .addConditionalEdge("${n}", ...)`)}};function G(e){return new I(e)}function Q(e){let{id:t,title:n,description:r,baseUrl:o,htmlPath:a,widgetDomain:i,prefersBorder:s=!0,autoHeight:c=!0}=e,g=e.widgetCSP??{connect_domains:[o],resource_domains:[o]};if(process.env.NODE_ENV==="development")try{let{hostname:u}=new URL(o);(u==="localhost"||u==="127.0.0.1")&&(g={...g,connect_domains:[...g.connect_domains||[],`ws://${u}:*`,`wss://${u}:*`],resource_domains:[...g.resource_domains||[],`http://${u}:*`]})}catch{}let k=`ui://widgets/apps-sdk/${t}.html`,d=`ui://widgets/ext-apps/${t}.html`,f=null,T=()=>(f||(f=K(o,a)),f),l=r;async function p(u){let m=await T();u.registerResource(`${t}-openai-widget`,k,{title:n,description:l,mimeType:b,_meta:{"openai/widgetDescription":l,"openai/widgetPrefersBorder":s}},async h=>({contents:[{uri:h.href,mimeType:b,text:m,_meta:Y({description:l,prefersBorder:s,widgetDomain:i,widgetCSP:g})}]})),u.registerResource(`${t}-mcp-widget`,d,{title:n,description:l,mimeType:P,_meta:{ui:{prefersBorder:s}}},async h=>({contents:[{uri:h.href,mimeType:P,text:m,_meta:X({description:l,prefersBorder:s,widgetCSP:g})}]}))}return{id:t,title:n,description:r,openaiUri:k,mcpUri:d,autoHeight:c,register:p}}function fe(e,t){let{resource:n,description:r,inputSchema:o,annotations:a}=e,i=e.id??n?.id,s=e.title??n?.title;if(!i)throw new Error("createTool: `id` is required when no resource is provided");if(!s)throw new Error("createTool: `title` is required when no resource is provided");let c=n?x({openaiTemplateUri:n.openaiUri,mcpTemplateUri:n.mcpUri,invoking:e.invoking??"Loading...",invoked:e.invoked??"Loaded",autoHeight:n.autoHeight}):void 0;return{id:i,title:s,description:r,async register(g){g.registerTool(i,{title:s,description:r,inputSchema:o,annotations:a,...c&&{_meta:c}},(async(k,d)=>{let T=d._meta??{},l=await t(k,{extra:{_meta:T}});return n&&l.data?{content:[{type:"text",text:l.text}],structuredContent:l.data,_meta:{...c,...T}}:{content:[{type:"text",text:l.text}]}}))}}}async function he(e,t){await Promise.all(t.map(n=>n.register(e)))}var me="@waniwani/sdk";function O(e,t={}){let n=t.now??(()=>new Date),r=t.generateId??ee,o=Te(e),a=W(e.meta),i=W(e.metadata),s=ke(e,a),c=S(e.eventId)??r(),g=ve(e.timestamp,n),k=S(e.source)??t.source??me,d=q(e)?{...e}:void 0,f={...i};return Object.keys(a).length>0&&(f.meta=a),d&&(f.rawLegacy=d),{id:c,type:"mcp.event",name:o,source:k,timestamp:g,correlation:s,properties:we(e,o),metadata:f,rawLegacy:d}}function ee(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`evt_${crypto.randomUUID()}`:`evt_${Math.random().toString(36).slice(2,10)}_${Date.now().toString(36)}`}function we(e,t){if(!q(e))return W(e.properties);let n=ye(e,t),r=W(e.properties);return{...n,...r}}function ye(e,t){switch(t){case"tool.called":{let n={};return S(e.toolName)&&(n.name=e.toolName),S(e.toolType)&&(n.type=e.toolType),n}case"quote.succeeded":{let n={};return typeof e.quoteAmount=="number"&&(n.amount=e.quoteAmount),S(e.quoteCurrency)&&(n.currency=e.quoteCurrency),n}case"link.clicked":{let n={};return S(e.linkUrl)&&(n.url=e.linkUrl),n}case"purchase.completed":{let n={};return typeof e.purchaseAmount=="number"&&(n.amount=e.purchaseAmount),S(e.purchaseCurrency)&&(n.currency=e.purchaseCurrency),n}default:return{}}}function Te(e){return q(e)?e.eventType:e.event}function ke(e,t){let n=S(e.requestId)??_(t,["openai/requestId","requestId","mcp/requestId"]),r=S(e.sessionId)??_(t,["openai/sessionId","sessionId","conversationId","anthropic/sessionId"]),o=S(e.traceId)??_(t,["openai/traceId","traceId","mcp/traceId","openai/requestId","requestId"]),a=S(e.externalUserId)??_(t,["openai/userId","externalUserId","userId","actorId"]),i=S(e.correlationId)??_(t,["correlationId","openai/requestId"])??n,s={};return r&&(s.sessionId=r),o&&(s.traceId=o),n&&(s.requestId=n),i&&(s.correlationId=i),a&&(s.externalUserId=a),s}function ve(e,t){if(e instanceof Date)return e.toISOString();if(typeof e=="string"){let n=new Date(e);if(!Number.isNaN(n.getTime()))return n.toISOString()}return t().toISOString()}function _(e,t){for(let n of t){let r=e[n];if(typeof r=="string"&&r.trim().length>0)return r}}function W(e){return!e||typeof e!="object"||Array.isArray(e)?{}:e}function S(e){if(typeof e=="string"&&e.trim().length!==0)return e}function q(e){return"eventType"in e}var Se="/api/mcp/events/v2/batch";var te="@waniwani/sdk",Ee=new Set([401,403]),Re=new Set([408,425,429,500,502,503,504]);function ne(e){return new j(e)}var j=class{endpointUrl;flushIntervalMs;maxBatchSize;maxBufferSize;maxRetries;retryBaseDelayMs;retryMaxDelayMs;shutdownTimeoutMs;sdkVersion;fetchFn;logger;now;sleep;apiKey;buffer=[];flushTimer;flushScheduled=!1;flushScheduledTimer;flushInFlight;inFlightCount=0;isStopped=!1;isShuttingDown=!1;constructor(t){this.endpointUrl=Me(t.baseUrl,t.endpointPath??Se),this.flushIntervalMs=t.flushIntervalMs??1e3,this.maxBatchSize=t.maxBatchSize??20,this.maxBufferSize=t.maxBufferSize??1e3,this.maxRetries=t.maxRetries??3,this.retryBaseDelayMs=t.retryBaseDelayMs??200,this.retryMaxDelayMs=t.retryMaxDelayMs??2e3,this.shutdownTimeoutMs=t.shutdownTimeoutMs??2e3,this.fetchFn=t.fetchFn??fetch,this.logger=t.logger??console,this.now=t.now??(()=>new Date),this.sleep=t.sleep??(n=>new Promise(r=>setTimeout(r,n))),this.apiKey=t.apiKey,this.sdkVersion=t.sdkVersion,this.flushIntervalMs>0&&(this.flushTimer=setInterval(()=>{this.flush()},this.flushIntervalMs))}enqueue(t){if(this.isStopped||this.isShuttingDown){this.logger.warn("[WaniWani] Tracking transport is stopped, dropping event %s",t.id);return}if(this.buffer.length>=this.maxBufferSize){let n=this.buffer.length-this.maxBufferSize+1;this.buffer.splice(0,n),this.logger.warn("[WaniWani] Tracking buffer overflow, dropped %d oldest event(s)",n)}if(this.buffer.push(t),this.buffer.length>=this.maxBatchSize){this.flush();return}this.scheduleMicroFlush()}pendingEvents(){return this.buffer.length+this.inFlightCount}async flush(){return this.flushInFlight?this.flushInFlight:(this.flushInFlight=this.flushLoop().finally(()=>{this.flushInFlight=void 0}),this.flushInFlight)}async shutdown(t){this.isShuttingDown=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=void 0),this.flushScheduledTimer&&(clearTimeout(this.flushScheduledTimer),this.flushScheduledTimer=void 0,this.flushScheduled=!1);let n=t?.timeoutMs??this.shutdownTimeoutMs,r=this.flush();if(!Number.isFinite(n)||n<=0)return await r,this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()};let o=Symbol("shutdown-timeout");return await Promise.race([r.then(()=>"flushed"),this.sleep(n).then(()=>o)])===o?(this.isStopped=!0,{timedOut:!0,pendingEvents:this.pendingEvents()}):(this.isStopped=!0,{timedOut:!1,pendingEvents:this.pendingEvents()})}scheduleMicroFlush(){this.flushScheduled||(this.flushScheduled=!0,this.flushScheduledTimer=setTimeout(()=>{this.flushScheduledTimer=void 0,this.flushScheduled=!1,this.flush()},0))}async flushLoop(){for(;this.buffer.length>0&&!this.isStopped;){let t=this.buffer.splice(0,this.maxBatchSize);await this.sendBatchWithRetry(t)}}async sendBatchWithRetry(t){let n=0,r=t;for(;r.length>0&&!this.isStopped;){this.inFlightCount=r.length;let o=await this.sendBatchOnce(r);switch(this.inFlightCount=0,o.kind){case"success":return;case"auth":this.stopTransportForAuthFailure(o.status,r.length);return;case"permanent":this.logger.error("[WaniWani] Dropping %d event(s) after permanent failure: %s",r.length,o.reason);return;case"retryable":if(n>=this.maxRetries){this.logger.error("[WaniWani] Dropping %d event(s) after retry exhaustion: %s",r.length,o.reason);return}await this.sleep(this.backoffDelayMs(n)),n+=1;continue;case"partial":if(o.permanent.length>0&&this.logger.error("[WaniWani] Dropping %d event(s) rejected as permanent",o.permanent.length),o.retryable.length===0)return;if(n>=this.maxRetries){this.logger.error("[WaniWani] Dropping %d retryable event(s) after retry exhaustion",o.retryable.length);return}r=o.retryable,await this.sleep(this.backoffDelayMs(n)),n+=1;continue}}}async sendBatchOnce(t){let n;try{n=await this.fetchFn(this.endpointUrl,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-WaniWani-SDK":te},body:JSON.stringify(this.makeBatchRequest(t))})}catch(a){return{kind:"retryable",reason:_e(a)}}if(Ee.has(n.status))return{kind:"auth",status:n.status};if(Re.has(n.status))return{kind:"retryable",reason:`HTTP ${n.status}`};if(!n.ok)return{kind:"permanent",reason:`HTTP ${n.status}`};let r=await Ie(n);if(!r?.rejected||r.rejected.length===0)return{kind:"success"};let o=this.classifyRejectedEvents(t,r.rejected);return o.retryable.length===0&&o.permanent.length===0?{kind:"success"}:{kind:"partial",retryable:o.retryable,permanent:o.permanent}}makeBatchRequest(t){return{sentAt:this.now().toISOString(),source:{sdk:te,version:this.sdkVersion??"0.0.0"},events:t}}classifyRejectedEvents(t,n){let r=new Map(t.map(i=>[i.id,i])),o=[],a=[];for(let i of n){let s=r.get(i.eventId);if(s){if(xe(i)){o.push(s);continue}a.push(s)}}return{retryable:o,permanent:a}}backoffDelayMs(t){let n=this.retryBaseDelayMs*2**t;return Math.min(n,this.retryMaxDelayMs)}stopTransportForAuthFailure(t,n){this.isStopped=!0;let r=this.buffer.length;this.buffer.splice(0,r),this.logger.error("[WaniWani] Auth failure (HTTP %d). Stopping tracking transport and dropping %d queued event(s)",t,n+r)}};function xe(e){if(e.retryable===!0)return!0;let t=e.code.toLowerCase();return t.includes("timeout")||t.includes("temporary")||t.includes("unavailable")||t.includes("rate_limit")||t.includes("transient")||t.includes("server")}async function Ie(e){let t=await e.text();if(t)try{return JSON.parse(t)}catch{return}}function Me(e,t){let n=e.endsWith("/")?e:`${e}/`,r=t.startsWith("/")?t.slice(1):t;return`${n}${r}`}function _e(e){return e instanceof Error?e.message:String(e)}function re(e){let{baseUrl:t,apiKey:n,tracking:r}=e;function o(){if(!n)throw new Error("WANIWANI_API_KEY is not set");return n}let a=n?ne({baseUrl:t,apiKey:n,endpointPath:r.endpointPath,flushIntervalMs:r.flushIntervalMs,maxBatchSize:r.maxBatchSize,maxBufferSize:r.maxBufferSize,maxRetries:r.maxRetries,retryBaseDelayMs:r.retryBaseDelayMs,retryMaxDelayMs:r.retryMaxDelayMs,shutdownTimeoutMs:r.shutdownTimeoutMs}):void 0,i={async track(s){o();let c=O(s);return a?.enqueue(c),{eventId:c.id}},async flush(){o(),await a?.flush()},async shutdown(s){return o(),await a?.shutdown({timeoutMs:s?.timeoutMs??r.shutdownTimeoutMs})??{timedOut:!1,pendingEvents:0}}};return a&&Ce(i,r.shutdownTimeoutMs),i}function Ce(e,t){if(typeof process>"u"||typeof process.once!="function"||typeof process.on!="function")return;let n=()=>{e.shutdown({timeoutMs:t})};process.once("beforeExit",n),process.once("SIGINT",n),process.once("SIGTERM",n)}function A(e){let t=e?.baseUrl??"https://app.waniwani.ai",n=e?.apiKey??process.env.WANIWANI_API_KEY,r={endpointPath:e?.tracking?.endpointPath??"/api/mcp/events/v2/batch",flushIntervalMs:e?.tracking?.flushIntervalMs??1e3,maxBatchSize:e?.tracking?.maxBatchSize??20,maxBufferSize:e?.tracking?.maxBufferSize??1e3,maxRetries:e?.tracking?.maxRetries??3,retryBaseDelayMs:e?.tracking?.retryBaseDelayMs??200,retryMaxDelayMs:e?.tracking?.retryMaxDelayMs??2e3,shutdownTimeoutMs:e?.tracking?.shutdownTimeoutMs??2e3},o={baseUrl:t,apiKey:n,tracking:r};return{...re(o),_config:o}}function be(e){let t=e.event_type??"widget_click",r=t.startsWith("widget_")?t:`widget_${t}`,o={...e.metadata??{}};return e.event_name&&(o.event_name=e.event_name),{event:r,properties:o,sessionId:e.session_id,traceId:e.trace_id,externalUserId:e.user_id,eventId:e.event_id,timestamp:e.timestamp,source:e.source??"widget"}}function Pe(e){let t={apiKey:e?.apiKey,baseUrl:e?.baseUrl},n;function r(){return n||(n=A(t)),n}return async function(a){let i;try{i=await a.json()}catch{return new Response(JSON.stringify({error:"Invalid JSON"}),{status:400,headers:{"Content-Type":"application/json"}})}if(!Array.isArray(i.events)||i.events.length===0)return new Response(JSON.stringify({error:"Missing or empty events array"}),{status:400,headers:{"Content-Type":"application/json"}});try{let s=r(),c=[];for(let g of i.events){let k=be(g),d=await s.track(k);c.push(d.eventId)}return await s.flush(),new Response(JSON.stringify({ok:!0,accepted:c.length}),{status:200,headers:{"Content-Type":"application/json"}})}catch(s){let c=s instanceof Error?s.message:"Unknown error";return new Response(JSON.stringify({error:c}),{status:500,headers:{"Content-Type":"application/json"}})}}}var N=class{cached=null;pending=null;config;constructor(t){this.config=t}async getToken(t,n){return this.cached&&Date.now()<this.cached.expiresAt-12e4?this.cached.token:this.pending?this.pending:(this.pending=this.mint(t,n).finally(()=>{this.pending=null}),this.pending)}async mint(t,n){let r=We(this.config.baseUrl,"/api/mcp/widget-tokens"),o={};t&&(o.sessionId=t),n&&(o.traceId=n);try{let a=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`},body:JSON.stringify(o)});if(!a.ok)return null;let i=await a.json(),s=i.data&&typeof i.data=="object"?i.data:i,c=new Date(s.expiresAt).getTime();return!s.token||Number.isNaN(c)?null:(this.cached={token:s.token,expiresAt:c},s.token)}catch{return null}}};function We(e,t){return`${e.endsWith("/")?e.slice(0,-1):e}${t}`}var oe="https://app.waniwani.ai";function Ae(e,t={}){let n=e;if(n.__waniwaniWrapped)return n;n.__waniwaniWrapped=!0;let r=t.client??A(t.config),o=t.injectWidgetToken!==!1,a=null;function i(){if(a)return a;let c=r._config.apiKey;return c?(a=new N({baseUrl:r._config.baseUrl??oe,apiKey:c}),a):null}let s=e.registerTool.bind(e);return n.registerTool=((...c)=>{let[g,k,d]=c,f=typeof g=="string"&&g.trim().length>0?g:"unknown";if(typeof d!="function")return s(...c);let T=d;return s(g,k,async(p,u)=>{let m=performance.now();try{let h=await T(p,u),U=Math.round(performance.now()-m);return await se(r,ie(f,u,t,{durationMs:U,status:"ok"}),t.onError),t.flushAfterToolCall&&await ae(r,t.onError),o&&await Ne(h,i(),r._config.baseUrl??oe,t.onError),h}catch(h){let U=Math.round(performance.now()-m);throw await se(r,ie(f,u,t,{durationMs:U,status:"error",errorMessage:h instanceof Error?h.message:String(h)}),t.onError),t.flushAfterToolCall&&await ae(r,t.onError),h}})}),n}async function Ne(e,t,n,r){if(!F(e))return;F(e._meta)||(e._meta={});let o=e._meta,a={endpoint:`${n.replace(/\/$/,"")}/api/mcp/events/v2/batch`};if(t)try{let i=await t.getToken();i&&(a.token=i)}catch(i){r?.(L(i))}o.waniwani=a}function ie(e,t,n,r){let o=Fe(e,n.toolType),a=Ue(t);return{event:"tool.called",properties:{name:e,type:o,...r??{}},meta:a,metadata:{source:"withWaniwani",...n.metadata??{}}}}function Fe(e,t){return typeof t=="function"?t(e)??"other":t??"other"}function Ue(e){if(!F(e))return;let t=e._meta;if(F(t))return t}function F(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}async function se(e,t,n){try{await e.track(t)}catch(r){n?.(L(r))}}async function ae(e,t){try{await e.flush()}catch(n){t?.(L(n))}}function L(e){return e instanceof Error?e:new Error(String(e))}export{R as END,E as START,I as StateGraph,G as createFlow,Q as createResource,fe as createTool,Pe as createTrackingRoute,D as detectPlatform,$ as interrupt,ce as isMCPApps,de as isOpenAI,he as registerTools,C as showWidget,Ae as withWaniwani};
4
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/react/widgets/platform.ts","../../src/mcp/server/flows/@types.ts","../../src/mcp/server/flows/compile.ts","../../src/mcp/server/resources/meta.ts","../../src/mcp/server/flows/state-graph.ts","../../src/mcp/server/flows/create-flow.ts","../../src/mcp/server/resources/create-resource.ts","../../src/mcp/server/tools/create-tool.ts"],"sourcesContent":["/**\n * Widget platform types\n */\nexport type WidgetPlatform = \"openai\" | \"mcp-apps\";\n\n/**\n * Detects which platform the widget is running on.\n *\n * OpenAI injects a global `window.openai` object.\n * MCP Apps runs in a sandboxed iframe and uses postMessage.\n */\nexport function detectPlatform(): WidgetPlatform {\n\tif (typeof window !== \"undefined\" && \"openai\" in window) {\n\t\treturn \"openai\";\n\t}\n\treturn \"mcp-apps\";\n}\n\n/**\n * Check if running on OpenAI platform\n */\nexport function isOpenAI(): boolean {\n\treturn detectPlatform() === \"openai\";\n}\n\n/**\n * Check if running on MCP Apps platform\n */\nexport function isMCPApps(): boolean {\n\treturn detectPlatform() === \"mcp-apps\";\n}\n","import type { z } from \"zod\";\nimport type { McpServer, RegisteredResource } from \"../resources/types\";\n\nexport type { McpServer };\n\n// ============================================================================\n// Sentinel constants\n// ============================================================================\n\nexport const START = \"__start__\" as const;\nexport const END = \"__end__\" as const;\n\n// ============================================================================\n// Signal types — returned by node handlers to control flow behavior\n// ============================================================================\n\nconst INTERRUPT = Symbol.for(\"waniwani.flow.interrupt\");\nconst WIDGET = Symbol.for(\"waniwani.flow.widget\");\n\nexport type InterruptSignal = {\n\treadonly __type: typeof INTERRUPT;\n\t/** Question to ask the user */\n\tquestion: string;\n\t/** State key where the answer will be stored */\n\tfield: string;\n\t/** Optional suggestions to present as options */\n\tsuggestions?: string[];\n\t/** Hidden context/instructions for the assistant (not shown to user directly) */\n\tcontext?: string;\n};\n\nexport type WidgetSignal = {\n\treadonly __type: typeof WIDGET;\n\t/** The resource to display */\n\tresource: RegisteredResource;\n\t/** Data to pass to the widget as structuredContent */\n\tdata: Record<string, unknown>;\n\t/** Description of what the widget does (for the AI's context) */\n\tdescription?: string;\n};\n\n/**\n * Create an interrupt signal — pauses the flow and asks the user a text question.\n */\nexport function interrupt(config: {\n\tquestion: string;\n\tfield: string;\n\tsuggestions?: string[];\n\tcontext?: string;\n}): InterruptSignal {\n\treturn { __type: INTERRUPT, ...config };\n}\n\n/**\n * Create a widget signal — pauses the flow and renders a widget UI.\n */\nexport function showWidget(\n\tresource: RegisteredResource,\n\tconfig: {\n\t\tdata: Record<string, unknown>;\n\t\tdescription?: string;\n\t},\n): WidgetSignal {\n\treturn { __type: WIDGET, resource, ...config };\n}\n\nexport function isInterrupt(value: unknown): value is InterruptSignal {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"__type\" in value &&\n\t\t(value as InterruptSignal).__type === INTERRUPT\n\t);\n}\n\nexport function isWidget(value: unknown): value is WidgetSignal {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"__type\" in value &&\n\t\t(value as WidgetSignal).__type === WIDGET\n\t);\n}\n\n// ============================================================================\n// Node & edge definitions\n// ============================================================================\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/** Configuration for a flow node */\nexport type NodeConfig<\n\tTState extends Record<string, unknown> = Record<string, unknown>,\n> = {\n\t/** Resource to display when this node returns a WidgetSignal */\n\tresource?: RegisteredResource;\n\t/** State key this node fills — enables auto-skip when the field is already in state via `initialState` */\n\tfield?: Extract<keyof TState, string>;\n};\n\n/**\n * Node handler — a single function type for all node kinds.\n * The return value determines behavior:\n * - `Partial<TState>` → action node (state merged, auto-advance)\n * - `InterruptSignal` → interrupt (pause, ask user)\n * - `WidgetSignal` → widget step (pause, show widget)\n */\nexport type NodeHandler<TState> = (\n\tstate: Partial<TState>,\n\tmeta?: Record<string, unknown>,\n) => MaybePromise<Partial<TState> | InterruptSignal | WidgetSignal>;\n\n/**\n * Condition function for conditional edges.\n * Receives current state, returns the name of the next node.\n */\nexport type ConditionFn<TState> = (\n\tstate: Partial<TState>,\n) => string | Promise<string>;\n\nexport type Edge<TState> =\n\t| { type: \"direct\"; to: string }\n\t| { type: \"conditional\"; condition: ConditionFn<TState> };\n\n// ============================================================================\n// Flow config & compiled output\n// ============================================================================\n\nexport type FlowConfig = {\n\t/** Unique identifier for the flow (becomes the MCP tool name) */\n\tid: string;\n\t/** Display title */\n\ttitle: string;\n\t/** Description for the AI (explains when to use this flow) */\n\tdescription: string;\n\t/**\n\t * Describe the flow's state fields so the AI can pre-fill answers\n\t * from the user's message via `initialState`.\n\t * Keys are the field names used in `interrupt({ field })`,\n\t * values are Zod schemas with `.describe()`.\n\t *\n\t * @example\n\t * ```ts\n\t * fields: {\n\t * country: z.string().describe(\"Country the business is based in\"),\n\t * status: z.enum([\"registered\", \"unregistered\"]).describe(\"Business registration status\"),\n\t * }\n\t * ```\n\t */\n\tfields?: Record<string, z.ZodType>;\n\t/** Optional tool annotations */\n\tannotations?: {\n\t\treadOnlyHint?: boolean;\n\t\tidempotentHint?: boolean;\n\t\topenWorldHint?: boolean;\n\t\tdestructiveHint?: boolean;\n\t};\n};\n\n/**\n * A compiled flow — can be registered on an McpServer.\n */\nexport type RegisteredFlow = {\n\tid: string;\n\ttitle: string;\n\tdescription: string;\n\tregister: (server: McpServer) => Promise<void>;\n};\n","import type { ToolCallback } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n\tServerNotification,\n\tServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { buildToolMeta } from \"../resources/meta\";\nimport type { RegisteredResource } from \"../resources/types\";\nimport type {\n\tEdge,\n\tFlowConfig,\n\tMcpServer,\n\tNodeConfig,\n\tNodeHandler,\n\tRegisteredFlow,\n} from \"./@types\";\nimport { END, isInterrupt, isWidget, START } from \"./@types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface CompileInput<TState extends Record<string, unknown>> {\n\tconfig: FlowConfig;\n\tnodes: Map<string, NodeHandler<TState>>;\n\tnodeConfigs: Map<string, NodeConfig<TState>>;\n\tedges: Map<string, Edge<TState>>;\n}\n\ntype FlowToolInput = {\n\taction: \"start\" | \"continue\" | \"widget_result\";\n\tstep?: string;\n\tstate?: Record<string, unknown>;\n\tanswer?: string;\n\twidgetResult?: Record<string, unknown>;\n\tinitialState?: Record<string, unknown>;\n};\n\ntype ExecutionResult = {\n\ttext: string;\n\tdata: Record<string, unknown>;\n\twidgetMeta?: Record<string, unknown>;\n};\n\n// ============================================================================\n// Flow protocol — embedded in tool description\n// ============================================================================\n\n/** Extract a human-readable label from a Zod schema for the AI protocol */\nfunction describeZodField(schema: z.ZodType): string {\n\tconst desc = schema.description ?? \"\";\n\tconst def = (\n\t\tschema as unknown as {\n\t\t\t_zod: { def: { type: string; entries?: Record<string, string> } };\n\t\t}\n\t)._zod?.def;\n\n\tif (def?.type === \"enum\" && def.entries) {\n\t\tconst vals = Object.keys(def.entries)\n\t\t\t.map((v) => `\"${v}\"`)\n\t\t\t.join(\" | \");\n\t\treturn desc ? `${vals} — ${desc}` : vals;\n\t}\n\n\treturn desc;\n}\n\nfunction buildFlowProtocol(config: FlowConfig): string {\n\tconst lines = [\n\t\t\"\",\n\t\t\"## FLOW EXECUTION PROTOCOL\",\n\t\t\"\",\n\t\t\"This tool implements a multi-step conversational flow. Follow this protocol exactly:\",\n\t\t\"\",\n\t\t'1. Call with `action: \"start\"` to begin. If the user\\'s message already',\n\t\t\" contains answers to likely questions, extract them into `initialState`\",\n\t\t\" as `{ field: value }` pairs. The engine will auto-skip questions whose\",\n\t\t\" fields are already filled.\",\n\t\t\" Only extract values the user explicitly stated — do NOT guess or invent values.\",\n\t];\n\n\tif (config.fields) {\n\t\tconst fieldList = Object.entries(config.fields)\n\t\t\t.map(([key, schema]) => {\n\t\t\t\tconst info = describeZodField(schema);\n\t\t\t\treturn info ? `\\`${key}\\` (${info})` : `\\`${key}\\``;\n\t\t\t})\n\t\t\t.join(\", \");\n\t\tlines.push(` Known fields: ${fieldList}.`);\n\t}\n\n\tlines.push(\n\t\t\"2. The response JSON `status` field tells you what to do next:\",\n\t\t' - `\"interrupt\"`: Ask the user the `question`. If a `context` field is present,',\n\t\t\" use it as hidden instructions to enrich your response (do NOT show it verbatim).\",\n\t\t\" Then call again with:\",\n\t\t' `action: \"continue\"`, `step` = the returned `step`, `state` = the returned `state`,',\n\t\t\" `answer` = the user's answer.\",\n\t\t' - `\"widget\"`: A widget UI is being shown. The user will interact with the widget.',\n\t\t\" When the user makes a choice and you need to continue the flow, call again with:\",\n\t\t' `action: \"widget_result\"`, `step` = the returned `step`, `state` = the returned `state`,',\n\t\t\" `answer` = the user's selection.\",\n\t\t' - `\"complete\"`: The flow is done. Present the result to the user.',\n\t\t' - `\"error\"`: Something went wrong. Show the `error` message.',\n\t\t\"\",\n\t\t\"3. ALWAYS pass back the `state` object exactly as received.\",\n\t\t\"4. Do NOT invent state values. Only use `initialState` for information the user explicitly provided.\",\n\t);\n\n\treturn lines.join(\"\\n\");\n}\n\n// ============================================================================\n// Edge resolution\n// ============================================================================\n\nasync function resolveNextNode<TState extends Record<string, unknown>>(\n\tedge: Edge<TState>,\n\tstate: Partial<TState>,\n): Promise<string> {\n\tif (edge.type === \"direct\") return edge.to;\n\treturn edge.condition(state);\n}\n\n// ============================================================================\n// Execution engine\n// ============================================================================\n\nasync function executeFrom<TState extends Record<string, unknown>>(\n\tstartNodeName: string,\n\tinitialState: TState,\n\tnodes: Map<string, NodeHandler<TState>>,\n\tnodeConfigs: Map<string, NodeConfig<TState>>,\n\tedges: Map<string, Edge<TState>>,\n\tflowId: string,\n\tmeta?: Record<string, unknown>,\n): Promise<ExecutionResult> {\n\tlet currentNode = startNodeName;\n\tlet state = { ...initialState };\n\n\t// Safety limit to prevent infinite loops\n\tconst MAX_ITERATIONS = 50;\n\tlet iterations = 0;\n\n\twhile (iterations++ < MAX_ITERATIONS) {\n\t\t// Reached END\n\t\tif (currentNode === END) {\n\t\t\treturn {\n\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\tstatus: \"complete\",\n\t\t\t\t\tstate,\n\t\t\t\t}),\n\t\t\t\tdata: { status: \"complete\", state },\n\t\t\t};\n\t\t}\n\n\t\tconst handler = nodes.get(currentNode);\n\t\tif (!handler) {\n\t\t\treturn {\n\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\terror: `Unknown node: \"${currentNode}\"`,\n\t\t\t\t}),\n\t\t\t\tdata: { status: \"error\" },\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await handler(state, meta);\n\n\t\t\t// Interrupt signal — pause and ask the user\n\t\t\tif (isInterrupt(result)) {\n\t\t\t\t// Auto-skip: if the field already has a value in state, advance\n\t\t\t\tconst existingValue = state[result.field as keyof TState];\n\t\t\t\tif (\n\t\t\t\t\texistingValue !== undefined &&\n\t\t\t\t\texistingValue !== null &&\n\t\t\t\t\texistingValue !== \"\"\n\t\t\t\t) {\n\t\t\t\t\tconst edge = edges.get(currentNode);\n\t\t\t\t\tif (!edge) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"interrupt\",\n\t\t\t\t\t\tstep: currentNode,\n\t\t\t\t\t\tquestion: result.question,\n\t\t\t\t\t\tfield: result.field,\n\t\t\t\t\t\tsuggestions: result.suggestions,\n\t\t\t\t\t\t...(result.context ? { context: result.context } : {}),\n\t\t\t\t\t\tstate,\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"interrupt\", step: currentNode, state },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Widget signal — pause and show widget\n\t\t\tif (isWidget(result)) {\n\t\t\t\t// Auto-skip: if the node config declares a field and it's already filled, advance\n\t\t\t\tconst nodeField = nodeConfigs.get(currentNode)?.field;\n\t\t\t\tif (nodeField) {\n\t\t\t\t\tconst existingValue = state[nodeField as keyof TState];\n\t\t\t\t\tif (\n\t\t\t\t\t\texistingValue !== undefined &&\n\t\t\t\t\t\texistingValue !== null &&\n\t\t\t\t\t\texistingValue !== \"\"\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst edge = edges.get(currentNode);\n\t\t\t\t\t\tif (!edge) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst resource = result.resource;\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"widget\",\n\t\t\t\t\t\tstep: currentNode,\n\t\t\t\t\t\twidgetId: resource.id,\n\t\t\t\t\t\tdescription: result.description,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t}),\n\t\t\t\t\tdata: {\n\t\t\t\t\t\t...result.data,\n\t\t\t\t\t\t__flow: {\n\t\t\t\t\t\t\tflowId,\n\t\t\t\t\t\t\tstep: currentNode,\n\t\t\t\t\t\t\tstate,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\twidgetMeta: buildToolMeta({\n\t\t\t\t\t\topenaiTemplateUri: resource.openaiUri,\n\t\t\t\t\t\tmcpTemplateUri: resource.mcpUri,\n\t\t\t\t\t\tinvoking: \"Loading...\",\n\t\t\t\t\t\tinvoked: \"Loaded\",\n\t\t\t\t\t\tautoHeight: resource.autoHeight,\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Action node — merge state and auto-advance\n\t\t\tstate = { ...state, ...result } as TState;\n\n\t\t\tconst edge = edges.get(currentNode);\n\t\t\tif (!edge) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\treturn {\n\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\tstep: currentNode,\n\t\t\t\t\terror: message,\n\t\t\t\t\tstate,\n\t\t\t\t}),\n\t\t\t\tdata: { status: \"error\", error: message },\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\ttext: JSON.stringify({\n\t\t\tstatus: \"error\",\n\t\t\terror: \"Flow exceeded maximum iterations (possible infinite loop)\",\n\t\t}),\n\t\tdata: { status: \"error\" },\n\t};\n}\n\n// ============================================================================\n// Compile\n// ============================================================================\n\nconst inputSchema = {\n\taction: z\n\t\t.enum([\"start\", \"continue\", \"widget_result\"])\n\t\t.describe(\n\t\t\t'\"start\" to begin the flow, \"continue\" after the user answers a question, \"widget_result\" when a widget returns data',\n\t\t),\n\tstep: z\n\t\t.string()\n\t\t.optional()\n\t\t.describe(\"Current step name (from the previous response)\"),\n\tstate: z\n\t\t.record(z.string(), z.unknown())\n\t\t.optional()\n\t\t.describe(\"Flow state — pass back exactly as received\"),\n\tanswer: z\n\t\t.string()\n\t\t.optional()\n\t\t.describe(\"The user's answer (for interrupt steps)\"),\n\twidgetResult: z\n\t\t.record(z.string(), z.unknown())\n\t\t.optional()\n\t\t.describe(\"Data returned by a widget callback\"),\n\tinitialState: z\n\t\t.record(z.string(), z.unknown())\n\t\t.optional()\n\t\t.describe(\n\t\t\t'Pre-filled answers extracted from the user\\'s message (only for action: \"start\")',\n\t\t),\n};\n\nexport function compileFlow<TState extends Record<string, unknown>>(\n\tinput: CompileInput<TState>,\n): RegisteredFlow {\n\tconst { config, nodes, nodeConfigs, edges } = input;\n\tconst protocol = buildFlowProtocol(config);\n\tconst fullDescription = `${config.description}\\n${protocol}`;\n\n\t// Find the first resource from node configs to build tool-level widget metadata.\n\t// This tells OpenAI/Claude that this tool can produce widget UIs.\n\tlet firstResource: RegisteredResource | undefined;\n\tfor (const nc of nodeConfigs.values()) {\n\t\tif (nc.resource) {\n\t\t\tfirstResource = nc.resource;\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst toolMeta = firstResource\n\t\t? buildToolMeta({\n\t\t\t\topenaiTemplateUri: firstResource.openaiUri,\n\t\t\t\tmcpTemplateUri: firstResource.mcpUri,\n\t\t\t\tinvoking: \"Loading...\",\n\t\t\t\tinvoked: \"Loaded\",\n\t\t\t\tautoHeight: firstResource.autoHeight,\n\t\t\t})\n\t\t: undefined;\n\n\tasync function handleToolCall(\n\t\targs: FlowToolInput,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<ExecutionResult> {\n\t\tconst state = (args.state ?? {}) as TState;\n\n\t\tif (args.action === \"start\") {\n\t\t\tconst startEdge = edges.get(START);\n\t\t\tif (!startEdge) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: \"No start edge\",\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Merge pre-filled answers from the user's initial message\n\t\t\tconst startState = (\n\t\t\t\targs.initialState ? { ...state, ...args.initialState } : state\n\t\t\t) as TState;\n\n\t\t\tconst firstNode = await resolveNextNode(startEdge, startState);\n\t\t\treturn executeFrom(\n\t\t\t\tfirstNode,\n\t\t\t\tstartState,\n\t\t\t\tnodes,\n\t\t\t\tnodeConfigs,\n\t\t\t\tedges,\n\t\t\t\tconfig.id,\n\t\t\t\tmeta,\n\t\t\t);\n\t\t}\n\n\t\tif (args.action === \"continue\") {\n\t\t\tif (!args.step) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: 'Missing \"step\" for continue action',\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Apply user's answer to state using the field from the interrupt\n\t\t\tlet updatedState = { ...state };\n\t\t\tif (args.answer) {\n\t\t\t\tconst handler = nodes.get(args.step);\n\t\t\t\tif (handler) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await handler(updatedState, meta);\n\t\t\t\t\t\tif (isInterrupt(result) && result.field) {\n\t\t\t\t\t\t\tupdatedState = {\n\t\t\t\t\t\t\t\t...updatedState,\n\t\t\t\t\t\t\t\t[result.field]: args.answer,\n\t\t\t\t\t\t\t} as TState;\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// If re-running the handler fails, still proceed with the answer\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Advance to next node\n\t\t\tconst edge = edges.get(args.step);\n\t\t\tif (!edge) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: `No edge from step \"${args.step}\"`,\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst nextNode = await resolveNextNode(edge, updatedState);\n\t\t\treturn executeFrom(\n\t\t\t\tnextNode,\n\t\t\t\tupdatedState,\n\t\t\t\tnodes,\n\t\t\t\tnodeConfigs,\n\t\t\t\tedges,\n\t\t\t\tconfig.id,\n\t\t\t\tmeta,\n\t\t\t);\n\t\t}\n\n\t\tif (args.action === \"widget_result\") {\n\t\t\tif (!args.step) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: 'Missing \"step\" for widget_result action',\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Merge widget result into state.\n\t\t\t// If `answer` is provided and the node declares a `field`, auto-map it.\n\t\t\tlet widgetUpdate: Record<string, unknown> = args.widgetResult ?? {};\n\t\t\tif (args.answer !== undefined && Object.keys(widgetUpdate).length === 0) {\n\t\t\t\tconst nodeField = nodeConfigs.get(args.step)?.field;\n\t\t\t\tif (nodeField) {\n\t\t\t\t\twidgetUpdate = { [nodeField]: args.answer };\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst updatedState = {\n\t\t\t\t...state,\n\t\t\t\t...widgetUpdate,\n\t\t\t} as TState;\n\n\t\t\t// Advance to next node\n\t\t\tconst edge = edges.get(args.step);\n\t\t\tif (!edge) {\n\t\t\t\treturn {\n\t\t\t\t\ttext: JSON.stringify({\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: `No edge from step \"${args.step}\"`,\n\t\t\t\t\t}),\n\t\t\t\t\tdata: { status: \"error\" },\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst nextNode = await resolveNextNode(edge, updatedState);\n\t\t\treturn executeFrom(\n\t\t\t\tnextNode,\n\t\t\t\tupdatedState,\n\t\t\t\tnodes,\n\t\t\t\tnodeConfigs,\n\t\t\t\tedges,\n\t\t\t\tconfig.id,\n\t\t\t\tmeta,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\ttext: JSON.stringify({\n\t\t\t\tstatus: \"error\",\n\t\t\t\terror: `Unknown action: \"${args.action}\"`,\n\t\t\t}),\n\t\t\tdata: { status: \"error\" },\n\t\t};\n\t}\n\n\treturn {\n\t\tid: config.id,\n\t\ttitle: config.title,\n\t\tdescription: fullDescription,\n\n\t\tasync register(server: McpServer): Promise<void> {\n\t\t\tserver.registerTool(\n\t\t\t\tconfig.id,\n\t\t\t\t{\n\t\t\t\t\ttitle: config.title,\n\t\t\t\t\tdescription: fullDescription,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tannotations: config.annotations,\n\t\t\t\t\t...(toolMeta && { _meta: toolMeta }),\n\t\t\t\t},\n\t\t\t\t(async (args: FlowToolInput, extra: unknown) => {\n\t\t\t\t\tconst requestExtra = extra as RequestHandlerExtra<\n\t\t\t\t\t\tServerRequest,\n\t\t\t\t\t\tServerNotification\n\t\t\t\t\t>;\n\t\t\t\t\tconst _meta: Record<string, unknown> = requestExtra._meta ?? {};\n\n\t\t\t\t\tconst result = await handleToolCall(args, _meta);\n\n\t\t\t\t\t// Widget response — include structuredContent + widget metadata\n\t\t\t\t\tif (result.widgetMeta) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: result.text }],\n\t\t\t\t\t\t\tstructuredContent: result.data,\n\t\t\t\t\t\t\t_meta: {\n\t\t\t\t\t\t\t\t...result.widgetMeta,\n\t\t\t\t\t\t\t\t..._meta,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Non-widget response (interrupt, complete, error) — text only\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: result.text }],\n\t\t\t\t\t};\n\t\t\t\t}) as unknown as ToolCallback<typeof inputSchema>,\n\t\t\t);\n\t\t},\n\t};\n}\n","import type { WidgetCSP } from \"./types\";\n\n/**\n * MIME types for widget resources.\n * OpenAI Apps SDK uses \"text/html+skybridge\"\n * MCP Apps uses \"text/html;profile=mcp-app\"\n */\nexport const MIME_TYPE_OPENAI = \"text/html+skybridge\";\nexport const MIME_TYPE_MCP = \"text/html;profile=mcp-app\";\n\n// ---- HTML fetching ----\n\nexport const fetchHtml = async (\n\tbaseUrl: string,\n\tpath: string,\n): Promise<string> => {\n\tconst normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\tconst result = await fetch(`${normalizedBase}${path}`);\n\treturn await result.text();\n};\n\n// ---- OpenAI resource metadata ----\n\ninterface OpenAIResourceMeta {\n\t[key: string]: unknown;\n\t\"openai/widgetDescription\"?: string;\n\t\"openai/widgetPrefersBorder\"?: boolean;\n\t\"openai/widgetDomain\"?: string;\n\t\"openai/widgetCSP\"?: WidgetCSP;\n}\n\nexport function buildOpenAIResourceMeta(config: {\n\tdescription?: string;\n\tprefersBorder?: boolean;\n\twidgetDomain: string;\n\twidgetCSP?: WidgetCSP;\n}): OpenAIResourceMeta {\n\treturn {\n\t\t\"openai/widgetDescription\": config.description,\n\t\t\"openai/widgetPrefersBorder\": config.prefersBorder,\n\t\t\"openai/widgetDomain\": config.widgetDomain,\n\t\t...(config.widgetCSP && { \"openai/widgetCSP\": config.widgetCSP }),\n\t};\n}\n\n// ---- MCP Apps resource metadata ----\n\ninterface McpAppsResourceMeta {\n\t[key: string]: unknown;\n\tui?: {\n\t\tcsp?: {\n\t\t\tconnectDomains?: string[];\n\t\t\tresourceDomains?: string[];\n\t\t\tframeDomains?: string[];\n\t\t\tredirectDomains?: string[];\n\t\t};\n\t\tdomain?: string;\n\t\tprefersBorder?: boolean;\n\t};\n}\n\nexport function buildMcpAppsResourceMeta(config: {\n\tdescription?: string;\n\tprefersBorder?: boolean;\n\twidgetDomain?: string;\n\twidgetCSP?: WidgetCSP;\n}): McpAppsResourceMeta {\n\tconst csp = config.widgetCSP\n\t\t? {\n\t\t\t\tconnectDomains: config.widgetCSP.connect_domains,\n\t\t\t\tresourceDomains: config.widgetCSP.resource_domains,\n\t\t\t\tframeDomains: config.widgetCSP.frame_domains,\n\t\t\t\tredirectDomains: config.widgetCSP.redirect_domains,\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\tui: {\n\t\t\t...(csp && { csp }),\n\t\t\t...(config.widgetDomain && { domain: config.widgetDomain }),\n\t\t\t...(config.prefersBorder !== undefined && {\n\t\t\t\tprefersBorder: config.prefersBorder,\n\t\t\t}),\n\t\t},\n\t};\n}\n\n// ---- Tool metadata (references resource URIs) ----\n\nexport function buildToolMeta(config: {\n\topenaiTemplateUri: string;\n\tmcpTemplateUri: string;\n\tinvoking: string;\n\tinvoked: string;\n\tautoHeight?: boolean;\n}) {\n\treturn {\n\t\t// OpenAI metadata\n\t\t\"openai/outputTemplate\": config.openaiTemplateUri,\n\t\t\"openai/toolInvocation/invoking\": config.invoking,\n\t\t\"openai/toolInvocation/invoked\": config.invoked,\n\t\t\"openai/widgetAccessible\": true,\n\t\t\"openai/resultCanProduceWidget\": true,\n\t\t// MCP Apps metadata\n\t\tui: {\n\t\t\tresourceUri: config.mcpTemplateUri,\n\t\t\t...(config.autoHeight && { autoHeight: true }),\n\t\t},\n\t} as const;\n}\n","import type {\n\tConditionFn,\n\tEdge,\n\tFlowConfig,\n\tNodeConfig,\n\tNodeHandler,\n\tRegisteredFlow,\n} from \"./@types\";\nimport { END, START } from \"./@types\";\nimport { compileFlow } from \"./compile\";\n\n/**\n * A LangGraph-inspired state graph builder for MCP tools.\n *\n * @example\n * ```ts\n * const flow = new StateGraph<MyState>({\n * id: \"onboarding\",\n * title: \"User Onboarding\",\n * description: \"Guides users through onboarding\",\n * })\n * .addNode(\"ask_name\", () => interrupt({ question: \"What's your name?\", field: \"name\" }))\n * .addNode(\"greet\", (state) => ({ greeting: `Hello ${state.name}!` }))\n * .addEdge(START, \"ask_name\")\n * .addEdge(\"ask_name\", \"greet\")\n * .addEdge(\"greet\", END)\n * .compile();\n * ```\n */\nexport class StateGraph<TState extends Record<string, unknown>> {\n\tprivate nodes = new Map<string, NodeHandler<TState>>();\n\tprivate nodeConfigs = new Map<string, NodeConfig<TState>>();\n\tprivate edges = new Map<string, Edge<TState>>();\n\tprivate config: FlowConfig;\n\n\tconstructor(config: FlowConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Add a node with just a handler.\n\t */\n\taddNode(name: string, handler: NodeHandler<TState>): this;\n\t/**\n\t * Add a node with config (e.g., resource, field) and a handler.\n\t */\n\taddNode(\n\t\tname: string,\n\t\tconfig: NodeConfig<TState>,\n\t\thandler: NodeHandler<TState>,\n\t): this;\n\taddNode(\n\t\tname: string,\n\t\tconfigOrHandler: NodeConfig<TState> | NodeHandler<TState>,\n\t\tmaybeHandler?: NodeHandler<TState>,\n\t): this {\n\t\tif (name === START || name === END) {\n\t\t\tthrow new Error(\n\t\t\t\t`\"${name}\" is a reserved name and cannot be used as a node name`,\n\t\t\t);\n\t\t}\n\t\tif (this.nodes.has(name)) {\n\t\t\tthrow new Error(`Node \"${name}\" already exists`);\n\t\t}\n\n\t\tlet handler: NodeHandler<TState>;\n\t\tlet nodeConfig: NodeConfig<TState> = {};\n\n\t\tif (typeof configOrHandler === \"function\") {\n\t\t\thandler = configOrHandler;\n\t\t} else {\n\t\t\tif (!maybeHandler) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`addNode(\"${name}\", config, handler) requires a handler as the third argument`,\n\t\t\t\t);\n\t\t\t}\n\t\t\thandler = maybeHandler;\n\t\t\tnodeConfig = configOrHandler;\n\t\t}\n\n\t\tthis.nodes.set(name, handler);\n\t\tthis.nodeConfigs.set(name, nodeConfig);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a direct edge between two nodes.\n\t *\n\t * Use `START` as `from` to set the entry point.\n\t * Use `END` as `to` to mark a terminal node.\n\t */\n\taddEdge(from: string, to: string): this {\n\t\tif (this.edges.has(from)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node \"${from}\" already has an outgoing edge. Use addConditionalEdge for branching.`,\n\t\t\t);\n\t\t}\n\t\tthis.edges.set(from, { type: \"direct\", to });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a conditional edge from a node.\n\t *\n\t * The condition function receives current state and returns the name of the next node.\n\t */\n\taddConditionalEdge(from: string, condition: ConditionFn<TState>): this {\n\t\tif (this.edges.has(from)) {\n\t\t\tthrow new Error(`Node \"${from}\" already has an outgoing edge.`);\n\t\t}\n\t\tthis.edges.set(from, { type: \"conditional\", condition });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Compile the graph into a RegisteredFlow that can be registered on an McpServer.\n\t *\n\t * Validates the graph structure and returns a registration-compatible object.\n\t */\n\tcompile(): RegisteredFlow {\n\t\tthis.validate();\n\n\t\treturn compileFlow<TState>({\n\t\t\tconfig: this.config,\n\t\t\tnodes: new Map(this.nodes),\n\t\t\tnodeConfigs: new Map(this.nodeConfigs),\n\t\t\tedges: new Map(this.edges),\n\t\t});\n\t}\n\n\tprivate validate(): void {\n\t\t// Must have a START edge\n\t\tif (!this.edges.has(START)) {\n\t\t\tthrow new Error(\n\t\t\t\t'Flow must have an entry point. Add an edge from START: .addEdge(START, \"first_node\")',\n\t\t\t);\n\t\t}\n\n\t\t// START edge target must exist\n\t\tconst startEdge = this.edges.get(START);\n\t\tif (\n\t\t\tstartEdge?.type === \"direct\" &&\n\t\t\tstartEdge.to !== END &&\n\t\t\t!this.nodes.has(startEdge.to)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`START edge references non-existent node: \"${startEdge.to}\"`,\n\t\t\t);\n\t\t}\n\n\t\t// All static edge targets must reference existing nodes (or END)\n\t\tfor (const [from, edge] of this.edges) {\n\t\t\tif (from !== START && !this.nodes.has(from)) {\n\t\t\t\tthrow new Error(`Edge from non-existent node: \"${from}\"`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tedge.type === \"direct\" &&\n\t\t\t\tedge.to !== END &&\n\t\t\t\t!this.nodes.has(edge.to)\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Edge from \"${from}\" references non-existent node: \"${edge.to}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Every node must have an outgoing edge\n\t\tfor (const [name] of this.nodes) {\n\t\t\tif (!this.edges.has(name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${name}\" has no outgoing edge. Add one with .addEdge(\"${name}\", ...) or .addConditionalEdge(\"${name}\", ...)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { FlowConfig } from \"./@types\";\nimport { StateGraph } from \"./state-graph\";\n\n/**\n * Create a new flow graph — convenience factory for `new StateGraph()`.\n *\n * @example\n * ```ts\n * import { createFlow, interrupt, START, END } from \"@waniwani/sdk/mcp\";\n *\n * type MyState = { name: string; email: string };\n *\n * const flow = createFlow<MyState>({\n * id: \"onboarding\",\n * title: \"User Onboarding\",\n * description: \"Guides users through onboarding. Use when a user wants to get started.\",\n * })\n * .addNode(\"ask_name\", () => interrupt({ question: \"What's your name?\", field: \"name\" }))\n * .addNode(\"ask_email\", () => interrupt({ question: \"What's your email?\", field: \"email\" }))\n * .addEdge(START, \"ask_name\")\n * .addEdge(\"ask_name\", \"ask_email\")\n * .addEdge(\"ask_email\", END)\n * .compile();\n * ```\n */\nexport function createFlow<TState extends Record<string, unknown>>(\n\tconfig: FlowConfig,\n): StateGraph<TState> {\n\treturn new StateGraph<TState>(config);\n}\n","import {\n\tbuildMcpAppsResourceMeta,\n\tbuildOpenAIResourceMeta,\n\tfetchHtml,\n\tMIME_TYPE_MCP,\n\tMIME_TYPE_OPENAI,\n} from \"./meta\";\nimport type { McpServer, RegisteredResource, ResourceConfig } from \"./types\";\n\n/**\n * Creates a reusable UI resource (HTML template) that can be attached\n * to tools or flow nodes.\n *\n * @example\n * ```ts\n * const pricingUI = createResource({\n * id: \"pricing_table\",\n * title: \"Pricing Table\",\n * baseUrl: \"https://my-app.com\",\n * htmlPath: \"/widgets/pricing\",\n * widgetDomain: \"my-app.com\",\n * });\n *\n * await pricingUI.register(server);\n * ```\n */\nexport function createResource(config: ResourceConfig): RegisteredResource {\n\tconst {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\t\tbaseUrl,\n\t\thtmlPath,\n\t\twidgetDomain,\n\t\tprefersBorder = true,\n\t\tautoHeight,\n\t} = config;\n\n\t// Auto-generate CSP from baseUrl if not explicitly provided\n\tconst widgetCSP = config.widgetCSP ?? {\n\t\tconnect_domains: [baseUrl],\n\t\tresource_domains: [baseUrl],\n\t};\n\n\tconst openaiUri = `ui://widgets/apps-sdk/${id}.html`;\n\tconst mcpUri = `ui://widgets/ext-apps/${id}.html`;\n\n\t// Lazy HTML — fetched once, shared across all calls\n\tlet htmlPromise: Promise<string> | null = null;\n\tconst getHtml = () => {\n\t\tif (!htmlPromise) htmlPromise = fetchHtml(baseUrl, htmlPath);\n\t\treturn htmlPromise;\n\t};\n\n\t// Use description for UI metadata\n\tconst uiDescription = description;\n\n\tasync function register(server: McpServer): Promise<void> {\n\t\tconst html = await getHtml();\n\n\t\t// Register OpenAI Apps SDK resource\n\t\tserver.registerResource(\n\t\t\t`${id}-openai-widget`,\n\t\t\topenaiUri,\n\t\t\t{\n\t\t\t\ttitle,\n\t\t\t\tdescription: uiDescription,\n\t\t\t\tmimeType: MIME_TYPE_OPENAI,\n\t\t\t\t_meta: {\n\t\t\t\t\t\"openai/widgetDescription\": uiDescription,\n\t\t\t\t\t\"openai/widgetPrefersBorder\": prefersBorder,\n\t\t\t\t},\n\t\t\t},\n\t\t\tasync (uri) => ({\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: MIME_TYPE_OPENAI,\n\t\t\t\t\t\ttext: html,\n\t\t\t\t\t\t_meta: buildOpenAIResourceMeta({\n\t\t\t\t\t\t\tdescription: uiDescription,\n\t\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t\t\twidgetDomain,\n\t\t\t\t\t\t\twidgetCSP,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t);\n\n\t\t// Register MCP Apps resource\n\t\tserver.registerResource(\n\t\t\t`${id}-mcp-widget`,\n\t\t\tmcpUri,\n\t\t\t{\n\t\t\t\ttitle,\n\t\t\t\tdescription: uiDescription,\n\t\t\t\tmimeType: MIME_TYPE_MCP,\n\t\t\t\t_meta: {\n\t\t\t\t\tui: {\n\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tasync (uri) => ({\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: MIME_TYPE_MCP,\n\t\t\t\t\t\ttext: html,\n\t\t\t\t\t\t_meta: buildMcpAppsResourceMeta({\n\t\t\t\t\t\t\tdescription: uiDescription,\n\t\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t\t\twidgetCSP,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t);\n\t}\n\n\treturn {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\t\topenaiUri,\n\t\tmcpUri,\n\t\tautoHeight,\n\t\tregister,\n\t};\n}\n","import type { ToolCallback } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ShapeOutput } from \"@modelcontextprotocol/sdk/server/zod-compat.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n\tServerNotification,\n\tServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { z } from \"zod\";\nimport { buildToolMeta } from \"../resources/meta\";\nimport type {\n\tMcpServer,\n\tRegisteredTool,\n\tToolConfig,\n\tToolHandler,\n} from \"./types\";\n\n/**\n * Creates an MCP tool with minimal boilerplate.\n *\n * When `config.resource` is provided, the tool returns `structuredContent` + widget metadata.\n * Without a resource, the tool returns plain text content.\n *\n * @example\n * ```ts\n * // Widget tool (with resource)\n * const pricingTool = createTool({\n * resource: pricingUI,\n * description: \"Show pricing comparison\",\n * inputSchema: { postalCode: z.string() },\n * }, async ({ postalCode }) => ({\n * text: \"Pricing loaded\",\n * data: { postalCode, prices: [] },\n * }));\n *\n * // Plain tool (no resource)\n * const searchTool = createTool({\n * id: \"search\",\n * title: \"Search\",\n * description: \"Search the knowledge base\",\n * inputSchema: { query: z.string() },\n * }, async ({ query }) => ({\n * text: `Results for \"${query}\"`,\n * }));\n * ```\n */\nexport function createTool<TInput extends z.ZodRawShape>(\n\tconfig: ToolConfig<TInput>,\n\thandler: ToolHandler<TInput>,\n): RegisteredTool {\n\tconst { resource, description, inputSchema, annotations } = config;\n\n\tconst id = config.id ?? resource?.id;\n\tconst title = config.title ?? resource?.title;\n\n\tif (!id) {\n\t\tthrow new Error(\n\t\t\t\"createTool: `id` is required when no resource is provided\",\n\t\t);\n\t}\n\tif (!title) {\n\t\tthrow new Error(\n\t\t\t\"createTool: `title` is required when no resource is provided\",\n\t\t);\n\t}\n\n\t// Build widget metadata only when resource is present\n\tconst toolMeta = resource\n\t\t? buildToolMeta({\n\t\t\t\topenaiTemplateUri: resource.openaiUri,\n\t\t\t\tmcpTemplateUri: resource.mcpUri,\n\t\t\t\tinvoking: config.invoking ?? \"Loading...\",\n\t\t\t\tinvoked: config.invoked ?? \"Loaded\",\n\t\t\t\tautoHeight: resource.autoHeight,\n\t\t\t})\n\t\t: undefined;\n\n\treturn {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\n\t\tasync register(server: McpServer): Promise<void> {\n\t\t\tserver.registerTool(\n\t\t\t\tid,\n\t\t\t\t{\n\t\t\t\t\ttitle,\n\t\t\t\t\tdescription,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tannotations,\n\t\t\t\t\t...(toolMeta && { _meta: toolMeta }),\n\t\t\t\t},\n\t\t\t\t(async (args: ShapeOutput<TInput>, extra: unknown) => {\n\t\t\t\t\tconst requestExtra = extra as RequestHandlerExtra<\n\t\t\t\t\t\tServerRequest,\n\t\t\t\t\t\tServerNotification\n\t\t\t\t\t>;\n\t\t\t\t\tconst _meta: Record<string, unknown> = requestExtra._meta ?? {};\n\n\t\t\t\t\tconst result = await handler(args, { extra: { _meta } });\n\n\t\t\t\t\t// Widget tool: return structuredContent + widget metadata\n\t\t\t\t\tif (resource && result.data) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: result.text }],\n\t\t\t\t\t\t\tstructuredContent: result.data,\n\t\t\t\t\t\t\t_meta: {\n\t\t\t\t\t\t\t\t...toolMeta,\n\t\t\t\t\t\t\t\t..._meta,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Plain tool: return text content only\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: result.text }],\n\t\t\t\t\t};\n\t\t\t\t}) as unknown as ToolCallback<TInput>,\n\t\t\t);\n\t\t},\n\t};\n}\n\n/**\n * Registers multiple tools on the server\n */\nexport async function registerTools(\n\tserver: McpServer,\n\ttools: RegisteredTool[],\n): Promise<void> {\n\tawait Promise.all(tools.map((t) => t.register(server)));\n}\n"],"mappings":"AAWO,SAASA,GAAiC,CAChD,OAAI,OAAO,OAAW,KAAe,WAAY,OACzC,SAED,UACR,CAKO,SAASC,GAAoB,CACnC,OAAOD,EAAe,IAAM,QAC7B,CAKO,SAASE,GAAqB,CACpC,OAAOF,EAAe,IAAM,UAC7B,CCrBO,IAAMG,EAAQ,YACRC,EAAM,UAMbC,EAAY,OAAO,IAAI,yBAAyB,EAChDC,EAAS,OAAO,IAAI,sBAAsB,EA2BzC,SAASC,EAAUC,EAKN,CACnB,MAAO,CAAE,OAAQH,EAAW,GAAGG,CAAO,CACvC,CAKO,SAASC,EACfC,EACAF,EAIe,CACf,MAAO,CAAE,OAAQF,EAAQ,SAAAI,EAAU,GAAGF,CAAO,CAC9C,CAEO,SAASG,EAAYC,EAA0C,CACrE,OACC,OAAOA,GAAU,UACjBA,IAAU,MACV,WAAYA,GACXA,EAA0B,SAAWP,CAExC,CAEO,SAASQ,EAASD,EAAuC,CAC/D,OACC,OAAOA,GAAU,UACjBA,IAAU,MACV,WAAYA,GACXA,EAAuB,SAAWN,CAErC,CC5EA,OAAS,KAAAQ,MAAS,MCCX,IAAMC,EAAmB,sBACnBC,EAAgB,4BAIhBC,EAAY,MACxBC,EACAC,IACqB,CACrB,IAAMC,EAAiBF,EAAQ,SAAS,GAAG,EAAIA,EAAQ,MAAM,EAAG,EAAE,EAAIA,EAEtE,OAAO,MADQ,MAAM,MAAM,GAAGE,CAAc,GAAGD,CAAI,EAAE,GACjC,KAAK,CAC1B,EAYO,SAASE,EAAwBC,EAKjB,CACtB,MAAO,CACN,2BAA4BA,EAAO,YACnC,6BAA8BA,EAAO,cACrC,sBAAuBA,EAAO,aAC9B,GAAIA,EAAO,WAAa,CAAE,mBAAoBA,EAAO,SAAU,CAChE,CACD,CAkBO,SAASC,EAAyBD,EAKjB,CACvB,IAAME,EAAMF,EAAO,UAChB,CACA,eAAgBA,EAAO,UAAU,gBACjC,gBAAiBA,EAAO,UAAU,iBAClC,aAAcA,EAAO,UAAU,cAC/B,gBAAiBA,EAAO,UAAU,gBACnC,EACC,OAEH,MAAO,CACN,GAAI,CACH,GAAIE,GAAO,CAAE,IAAAA,CAAI,EACjB,GAAIF,EAAO,cAAgB,CAAE,OAAQA,EAAO,YAAa,EACzD,GAAIA,EAAO,gBAAkB,QAAa,CACzC,cAAeA,EAAO,aACvB,CACD,CACD,CACD,CAIO,SAASG,EAAcH,EAM3B,CACF,MAAO,CAEN,wBAAyBA,EAAO,kBAChC,iCAAkCA,EAAO,SACzC,gCAAiCA,EAAO,QACxC,0BAA2B,GAC3B,gCAAiC,GAEjC,GAAI,CACH,YAAaA,EAAO,eACpB,GAAIA,EAAO,YAAc,CAAE,WAAY,EAAK,CAC7C,CACD,CACD,CD3DA,SAASI,EAAiBC,EAA2B,CACpD,IAAMC,EAAOD,EAAO,aAAe,GAC7BE,EACLF,EAGC,MAAM,IAER,GAAIE,GAAK,OAAS,QAAUA,EAAI,QAAS,CACxC,IAAMC,EAAO,OAAO,KAAKD,EAAI,OAAO,EAClC,IAAKE,GAAM,IAAIA,CAAC,GAAG,EACnB,KAAK,KAAK,EACZ,OAAOH,EAAO,GAAGE,CAAI,WAAMF,CAAI,GAAKE,CACrC,CAEA,OAAOF,CACR,CAEA,SAASI,EAAkBC,EAA4B,CACtD,IAAMC,EAAQ,CACb,GACA,6BACA,GACA,uFACA,GACA,0EACA,4EACA,4EACA,gCACA,yFACD,EAEA,GAAID,EAAO,OAAQ,CAClB,IAAME,EAAY,OAAO,QAAQF,EAAO,MAAM,EAC5C,IAAI,CAAC,CAACG,EAAKT,CAAM,IAAM,CACvB,IAAMU,EAAOX,EAAiBC,CAAM,EACpC,OAAOU,EAAO,KAAKD,CAAG,OAAOC,CAAI,IAAM,KAAKD,CAAG,IAChD,CAAC,EACA,KAAK,IAAI,EACXF,EAAM,KAAK,oBAAoBC,CAAS,GAAG,CAC5C,CAEA,OAAAD,EAAM,KACL,iEACA,oFACA,wFACA,6BACA,2FACA,qCACA,uFACA,wFACA,gGACA,wCACA,uEACA,kEACA,GACA,8DACA,sGACD,EAEOA,EAAM,KAAK;AAAA,CAAI,CACvB,CAMA,eAAeI,EACdC,EACAC,EACkB,CAClB,OAAID,EAAK,OAAS,SAAiBA,EAAK,GACjCA,EAAK,UAAUC,CAAK,CAC5B,CAMA,eAAeC,EACdC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAC2B,CAC3B,IAAIC,EAAcP,EACdF,EAAQ,CAAE,GAAGG,CAAa,EAGxBO,EAAiB,GACnBC,EAAa,EAEjB,KAAOA,IAAeD,GAAgB,CAErC,GAAID,IAAgBG,EACnB,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,WACR,MAAAZ,CACD,CAAC,EACD,KAAM,CAAE,OAAQ,WAAY,MAAAA,CAAM,CACnC,EAGD,IAAMa,EAAUT,EAAM,IAAIK,CAAW,EACrC,GAAI,CAACI,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,kBAAkBJ,CAAW,GACrC,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAGD,GAAI,CACH,IAAMK,EAAS,MAAMD,EAAQb,EAAOQ,CAAI,EAGxC,GAAIO,EAAYD,CAAM,EAAG,CAExB,IAAME,EAAgBhB,EAAMc,EAAO,KAAqB,EACxD,GAECE,GAAkB,MAClBA,IAAkB,GACjB,CACD,IAAMjB,EAAOO,EAAM,IAAIG,CAAW,EAClC,GAAI,CAACV,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,+BAA+BU,CAAW,GAClD,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAEDA,EAAc,MAAMX,EAAgBC,EAAMC,CAAK,EAC/C,QACD,CAEA,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,YACR,KAAMS,EACN,SAAUK,EAAO,SACjB,MAAOA,EAAO,MACd,YAAaA,EAAO,YACpB,GAAIA,EAAO,QAAU,CAAE,QAASA,EAAO,OAAQ,EAAI,CAAC,EACpD,MAAAd,CACD,CAAC,EACD,KAAM,CAAE,OAAQ,YAAa,KAAMS,EAAa,MAAAT,CAAM,CACvD,CACD,CAGA,GAAIiB,EAASH,CAAM,EAAG,CAErB,IAAMI,EAAYb,EAAY,IAAII,CAAW,GAAG,MAChD,GAAIS,EAAW,CACd,IAAMF,EAAgBhB,EAAMkB,CAAyB,EACrD,GAECF,GAAkB,MAClBA,IAAkB,GACjB,CACD,IAAMjB,EAAOO,EAAM,IAAIG,CAAW,EAClC,GAAI,CAACV,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,+BAA+BU,CAAW,GAClD,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAEDA,EAAc,MAAMX,EAAgBC,EAAMC,CAAK,EAC/C,QACD,CACD,CAEA,IAAMmB,EAAWL,EAAO,SACxB,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,SACR,KAAML,EACN,SAAUU,EAAS,GACnB,YAAaL,EAAO,YACpB,MAAAd,CACD,CAAC,EACD,KAAM,CACL,GAAGc,EAAO,KACV,OAAQ,CACP,OAAAP,EACA,KAAME,EACN,MAAAT,CACD,CACD,EACA,WAAYoB,EAAc,CACzB,kBAAmBD,EAAS,UAC5B,eAAgBA,EAAS,OACzB,SAAU,aACV,QAAS,SACT,WAAYA,EAAS,UACtB,CAAC,CACF,CACD,CAGAnB,EAAQ,CAAE,GAAGA,EAAO,GAAGc,CAAO,EAE9B,IAAMf,EAAOO,EAAM,IAAIG,CAAW,EAClC,GAAI,CAACV,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,+BAA+BU,CAAW,GAClD,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAEDA,EAAc,MAAMX,EAAgBC,EAAMC,CAAK,CAChD,OAASqB,EAAO,CACf,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACrE,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,KAAMZ,EACN,MAAOa,EACP,MAAAtB,CACD,CAAC,EACD,KAAM,CAAE,OAAQ,QAAS,MAAOsB,CAAQ,CACzC,CACD,CACD,CAEA,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,2DACR,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,CACD,CAMA,IAAMC,EAAc,CACnB,OAAQC,EACN,KAAK,CAAC,QAAS,WAAY,eAAe,CAAC,EAC3C,SACA,qHACD,EACD,KAAMA,EACJ,OAAO,EACP,SAAS,EACT,SAAS,gDAAgD,EAC3D,MAAOA,EACL,OAAOA,EAAE,OAAO,EAAGA,EAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SAAS,iDAA4C,EACvD,OAAQA,EACN,OAAO,EACP,SAAS,EACT,SAAS,yCAAyC,EACpD,aAAcA,EACZ,OAAOA,EAAE,OAAO,EAAGA,EAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SAAS,oCAAoC,EAC/C,aAAcA,EACZ,OAAOA,EAAE,OAAO,EAAGA,EAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SACA,iFACD,CACF,EAEO,SAASC,EACfC,EACiB,CACjB,GAAM,CAAE,OAAAjC,EAAQ,MAAAW,EAAO,YAAAC,EAAa,MAAAC,CAAM,EAAIoB,EACxCC,EAAWnC,EAAkBC,CAAM,EACnCmC,EAAkB,GAAGnC,EAAO,WAAW;AAAA,EAAKkC,CAAQ,GAItDE,EACJ,QAAWC,KAAMzB,EAAY,OAAO,EACnC,GAAIyB,EAAG,SAAU,CAChBD,EAAgBC,EAAG,SACnB,KACD,CAED,IAAMC,EAAWF,EACdT,EAAc,CACd,kBAAmBS,EAAc,UACjC,eAAgBA,EAAc,OAC9B,SAAU,aACV,QAAS,SACT,WAAYA,EAAc,UAC3B,CAAC,EACA,OAEH,eAAeG,EACdC,EACAzB,EAC2B,CAC3B,IAAMR,EAASiC,EAAK,OAAS,CAAC,EAE9B,GAAIA,EAAK,SAAW,QAAS,CAC5B,IAAMC,EAAY5B,EAAM,IAAI6B,CAAK,EACjC,GAAI,CAACD,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,eACR,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAID,IAAME,EACLH,EAAK,aAAe,CAAE,GAAGjC,EAAO,GAAGiC,EAAK,YAAa,EAAIjC,EAGpDqC,EAAY,MAAMvC,EAAgBoC,EAAWE,CAAU,EAC7D,OAAOnC,EACNoC,EACAD,EACAhC,EACAC,EACAC,EACAb,EAAO,GACPe,CACD,CACD,CAEA,GAAIyB,EAAK,SAAW,WAAY,CAC/B,GAAI,CAACA,EAAK,KACT,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,oCACR,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAID,IAAIK,EAAe,CAAE,GAAGtC,CAAM,EAC9B,GAAIiC,EAAK,OAAQ,CAChB,IAAMpB,EAAUT,EAAM,IAAI6B,EAAK,IAAI,EACnC,GAAIpB,EACH,GAAI,CACH,IAAMC,EAAS,MAAMD,EAAQyB,EAAc9B,CAAI,EAC3CO,EAAYD,CAAM,GAAKA,EAAO,QACjCwB,EAAe,CACd,GAAGA,EACH,CAACxB,EAAO,KAAK,EAAGmB,EAAK,MACtB,EAEF,MAAQ,CAER,CAEF,CAGA,IAAMlC,EAAOO,EAAM,IAAI2B,EAAK,IAAI,EAChC,GAAI,CAAClC,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,sBAAsBkC,EAAK,IAAI,GACvC,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAED,IAAMM,EAAW,MAAMzC,EAAgBC,EAAMuC,CAAY,EACzD,OAAOrC,EACNsC,EACAD,EACAlC,EACAC,EACAC,EACAb,EAAO,GACPe,CACD,CACD,CAEA,GAAIyB,EAAK,SAAW,gBAAiB,CACpC,GAAI,CAACA,EAAK,KACT,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,yCACR,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAKD,IAAIO,EAAwCP,EAAK,cAAgB,CAAC,EAClE,GAAIA,EAAK,SAAW,QAAa,OAAO,KAAKO,CAAY,EAAE,SAAW,EAAG,CACxE,IAAMtB,EAAYb,EAAY,IAAI4B,EAAK,IAAI,GAAG,MAC1Cf,IACHsB,EAAe,CAAE,CAACtB,CAAS,EAAGe,EAAK,MAAO,EAE5C,CACA,IAAMK,EAAe,CACpB,GAAGtC,EACH,GAAGwC,CACJ,EAGMzC,EAAOO,EAAM,IAAI2B,EAAK,IAAI,EAChC,GAAI,CAAClC,EACJ,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,sBAAsBkC,EAAK,IAAI,GACvC,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,EAED,IAAMM,EAAW,MAAMzC,EAAgBC,EAAMuC,CAAY,EACzD,OAAOrC,EACNsC,EACAD,EACAlC,EACAC,EACAC,EACAb,EAAO,GACPe,CACD,CACD,CAEA,MAAO,CACN,KAAM,KAAK,UAAU,CACpB,OAAQ,QACR,MAAO,oBAAoByB,EAAK,MAAM,GACvC,CAAC,EACD,KAAM,CAAE,OAAQ,OAAQ,CACzB,CACD,CAEA,MAAO,CACN,GAAIxC,EAAO,GACX,MAAOA,EAAO,MACd,YAAamC,EAEb,MAAM,SAASa,EAAkC,CAChDA,EAAO,aACNhD,EAAO,GACP,CACC,MAAOA,EAAO,MACd,YAAamC,EACb,YAAAL,EACA,YAAa9B,EAAO,YACpB,GAAIsC,GAAY,CAAE,MAAOA,CAAS,CACnC,GACC,MAAOE,EAAqBS,IAAmB,CAK/C,IAAMC,EAJeD,EAI+B,OAAS,CAAC,EAExD5B,EAAS,MAAMkB,EAAeC,EAAMU,CAAK,EAG/C,OAAI7B,EAAO,WACH,CACN,QAAS,CAAC,CAAE,KAAM,OAAiB,KAAMA,EAAO,IAAK,CAAC,EACtD,kBAAmBA,EAAO,KAC1B,MAAO,CACN,GAAGA,EAAO,WACV,GAAG6B,CACJ,CACD,EAIM,CACN,QAAS,CAAC,CAAE,KAAM,OAAiB,KAAM7B,EAAO,IAAK,CAAC,CACvD,CACD,EACD,CACD,CACD,CACD,CEtgBO,IAAM8B,EAAN,KAAyD,CACvD,MAAQ,IAAI,IACZ,YAAc,IAAI,IAClB,MAAQ,IAAI,IACZ,OAER,YAAYC,EAAoB,CAC/B,KAAK,OAASA,CACf,CAcA,QACCC,EACAC,EACAC,EACO,CACP,GAAIF,IAASG,GAASH,IAASI,EAC9B,MAAM,IAAI,MACT,IAAIJ,CAAI,wDACT,EAED,GAAI,KAAK,MAAM,IAAIA,CAAI,EACtB,MAAM,IAAI,MAAM,SAASA,CAAI,kBAAkB,EAGhD,IAAIK,EACAC,EAAiC,CAAC,EAEtC,GAAI,OAAOL,GAAoB,WAC9BI,EAAUJ,MACJ,CACN,GAAI,CAACC,EACJ,MAAM,IAAI,MACT,YAAYF,CAAI,8DACjB,EAEDK,EAAUH,EACVI,EAAaL,CACd,CAEA,YAAK,MAAM,IAAID,EAAMK,CAAO,EAC5B,KAAK,YAAY,IAAIL,EAAMM,CAAU,EAC9B,IACR,CAQA,QAAQC,EAAcC,EAAkB,CACvC,GAAI,KAAK,MAAM,IAAID,CAAI,EACtB,MAAM,IAAI,MACT,SAASA,CAAI,uEACd,EAED,YAAK,MAAM,IAAIA,EAAM,CAAE,KAAM,SAAU,GAAAC,CAAG,CAAC,EACpC,IACR,CAOA,mBAAmBD,EAAcE,EAAsC,CACtE,GAAI,KAAK,MAAM,IAAIF,CAAI,EACtB,MAAM,IAAI,MAAM,SAASA,CAAI,iCAAiC,EAE/D,YAAK,MAAM,IAAIA,EAAM,CAAE,KAAM,cAAe,UAAAE,CAAU,CAAC,EAChD,IACR,CAOA,SAA0B,CACzB,YAAK,SAAS,EAEPC,EAAoB,CAC1B,OAAQ,KAAK,OACb,MAAO,IAAI,IAAI,KAAK,KAAK,EACzB,YAAa,IAAI,IAAI,KAAK,WAAW,EACrC,MAAO,IAAI,IAAI,KAAK,KAAK,CAC1B,CAAC,CACF,CAEQ,UAAiB,CAExB,GAAI,CAAC,KAAK,MAAM,IAAIP,CAAK,EACxB,MAAM,IAAI,MACT,sFACD,EAID,IAAMQ,EAAY,KAAK,MAAM,IAAIR,CAAK,EACtC,GACCQ,GAAW,OAAS,UACpBA,EAAU,KAAOP,GACjB,CAAC,KAAK,MAAM,IAAIO,EAAU,EAAE,EAE5B,MAAM,IAAI,MACT,6CAA6CA,EAAU,EAAE,GAC1D,EAID,OAAW,CAACJ,EAAMK,CAAI,IAAK,KAAK,MAAO,CACtC,GAAIL,IAASJ,GAAS,CAAC,KAAK,MAAM,IAAII,CAAI,EACzC,MAAM,IAAI,MAAM,iCAAiCA,CAAI,GAAG,EAEzD,GACCK,EAAK,OAAS,UACdA,EAAK,KAAOR,GACZ,CAAC,KAAK,MAAM,IAAIQ,EAAK,EAAE,EAEvB,MAAM,IAAI,MACT,cAAcL,CAAI,oCAAoCK,EAAK,EAAE,GAC9D,CAEF,CAGA,OAAW,CAACZ,CAAI,IAAK,KAAK,MACzB,GAAI,CAAC,KAAK,MAAM,IAAIA,CAAI,EACvB,MAAM,IAAI,MACT,SAASA,CAAI,kDAAkDA,CAAI,mCAAmCA,CAAI,SAC3G,CAGH,CACD,ECtJO,SAASa,EACfC,EACqB,CACrB,OAAO,IAAIC,EAAmBD,CAAM,CACrC,CCHO,SAASE,EAAeC,EAA4C,CAC1E,GAAM,CACL,GAAAC,EACA,MAAAC,EACA,YAAAC,EACA,QAAAC,EACA,SAAAC,EACA,aAAAC,EACA,cAAAC,EAAgB,GAChB,WAAAC,CACD,EAAIR,EAGES,EAAYT,EAAO,WAAa,CACrC,gBAAiB,CAACI,CAAO,EACzB,iBAAkB,CAACA,CAAO,CAC3B,EAEMM,EAAY,yBAAyBT,CAAE,QACvCU,EAAS,yBAAyBV,CAAE,QAGtCW,EAAsC,KACpCC,EAAU,KACVD,IAAaA,EAAcE,EAAUV,EAASC,CAAQ,GACpDO,GAIFG,EAAgBZ,EAEtB,eAAea,EAASC,EAAkC,CACzD,IAAMC,EAAO,MAAML,EAAQ,EAG3BI,EAAO,iBACN,GAAGhB,CAAE,iBACLS,EACA,CACC,MAAAR,EACA,YAAaa,EACb,SAAUI,EACV,MAAO,CACN,2BAA4BJ,EAC5B,6BAA8BR,CAC/B,CACD,EACA,MAAOa,IAAS,CACf,SAAU,CACT,CACC,IAAKA,EAAI,KACT,SAAUD,EACV,KAAMD,EACN,MAAOG,EAAwB,CAC9B,YAAaN,EACb,cAAAR,EACA,aAAAD,EACA,UAAAG,CACD,CAAC,CACF,CACD,CACD,EACD,EAGAQ,EAAO,iBACN,GAAGhB,CAAE,cACLU,EACA,CACC,MAAAT,EACA,YAAaa,EACb,SAAUO,EACV,MAAO,CACN,GAAI,CACH,cAAAf,CACD,CACD,CACD,EACA,MAAOa,IAAS,CACf,SAAU,CACT,CACC,IAAKA,EAAI,KACT,SAAUE,EACV,KAAMJ,EACN,MAAOK,EAAyB,CAC/B,YAAaR,EACb,cAAAR,EACA,UAAAE,CACD,CAAC,CACF,CACD,CACD,EACD,CACD,CAEA,MAAO,CACN,GAAAR,EACA,MAAAC,EACA,YAAAC,EACA,UAAAO,EACA,OAAAC,EACA,WAAAH,EACA,SAAAQ,CACD,CACD,CCrFO,SAASQ,EACfC,EACAC,EACiB,CACjB,GAAM,CAAE,SAAAC,EAAU,YAAAC,EAAa,YAAAC,EAAa,YAAAC,CAAY,EAAIL,EAEtDM,EAAKN,EAAO,IAAME,GAAU,GAC5BK,EAAQP,EAAO,OAASE,GAAU,MAExC,GAAI,CAACI,EACJ,MAAM,IAAI,MACT,2DACD,EAED,GAAI,CAACC,EACJ,MAAM,IAAI,MACT,8DACD,EAID,IAAMC,EAAWN,EACdO,EAAc,CACd,kBAAmBP,EAAS,UAC5B,eAAgBA,EAAS,OACzB,SAAUF,EAAO,UAAY,aAC7B,QAASA,EAAO,SAAW,SAC3B,WAAYE,EAAS,UACtB,CAAC,EACA,OAEH,MAAO,CACN,GAAAI,EACA,MAAAC,EACA,YAAAJ,EAEA,MAAM,SAASO,EAAkC,CAChDA,EAAO,aACNJ,EACA,CACC,MAAAC,EACA,YAAAJ,EACA,YAAAC,EACA,YAAAC,EACA,GAAIG,GAAY,CAAE,MAAOA,CAAS,CACnC,GACC,MAAOG,EAA2BC,IAAmB,CAKrD,IAAMC,EAJeD,EAI+B,OAAS,CAAC,EAExDE,EAAS,MAAMb,EAAQU,EAAM,CAAE,MAAO,CAAE,MAAAE,CAAM,CAAE,CAAC,EAGvD,OAAIX,GAAYY,EAAO,KACf,CACN,QAAS,CAAC,CAAE,KAAM,OAAQ,KAAMA,EAAO,IAAK,CAAC,EAC7C,kBAAmBA,EAAO,KAC1B,MAAO,CACN,GAAGN,EACH,GAAGK,CACJ,CACD,EAIM,CACN,QAAS,CAAC,CAAE,KAAM,OAAiB,KAAMC,EAAO,IAAK,CAAC,CACvD,CACD,EACD,CACD,CACD,CACD,CAKA,eAAsBC,EACrBL,EACAM,EACgB,CAChB,MAAM,QAAQ,IAAIA,EAAM,IAAKC,GAAMA,EAAE,SAASP,CAAM,CAAC,CAAC,CACvD","names":["detectPlatform","isOpenAI","isMCPApps","START","END","INTERRUPT","WIDGET","interrupt","config","showWidget","resource","isInterrupt","value","isWidget","z","MIME_TYPE_OPENAI","MIME_TYPE_MCP","fetchHtml","baseUrl","path","normalizedBase","buildOpenAIResourceMeta","config","buildMcpAppsResourceMeta","csp","buildToolMeta","describeZodField","schema","desc","def","vals","v","buildFlowProtocol","config","lines","fieldList","key","info","resolveNextNode","edge","state","executeFrom","startNodeName","initialState","nodes","nodeConfigs","edges","flowId","meta","currentNode","MAX_ITERATIONS","iterations","END","handler","result","isInterrupt","existingValue","isWidget","nodeField","resource","buildToolMeta","error","message","inputSchema","z","compileFlow","input","protocol","fullDescription","firstResource","nc","toolMeta","handleToolCall","args","startEdge","START","startState","firstNode","updatedState","nextNode","widgetUpdate","server","extra","_meta","StateGraph","config","name","configOrHandler","maybeHandler","START","END","handler","nodeConfig","from","to","condition","compileFlow","startEdge","edge","createFlow","config","StateGraph","createResource","config","id","title","description","baseUrl","htmlPath","widgetDomain","prefersBorder","autoHeight","widgetCSP","openaiUri","mcpUri","htmlPromise","getHtml","fetchHtml","uiDescription","register","server","html","MIME_TYPE_OPENAI","uri","buildOpenAIResourceMeta","MIME_TYPE_MCP","buildMcpAppsResourceMeta","createTool","config","handler","resource","description","inputSchema","annotations","id","title","toolMeta","buildToolMeta","server","args","extra","_meta","result","registerTools","tools","t"]}
1
+ {"version":3,"sources":["../../src/mcp/react/widgets/platform.ts","../../src/mcp/server/flows/@types.ts","../../src/mcp/server/flows/compile.ts","../../src/mcp/server/resources/meta.ts","../../src/mcp/server/flows/state-graph.ts","../../src/mcp/server/flows/create-flow.ts","../../src/mcp/server/resources/create-resource.ts","../../src/mcp/server/tools/create-tool.ts","../../src/tracking/mapper.ts","../../src/tracking/transport.ts","../../src/tracking/index.ts","../../src/waniwani.ts","../../src/mcp/server/tracking-route.ts","../../src/mcp/server/widget-token.ts","../../src/mcp/server/with-waniwani.ts"],"sourcesContent":["/**\n * Widget platform types\n */\nexport type WidgetPlatform = \"openai\" | \"mcp-apps\";\n\n/**\n * Detects which platform the widget is running on.\n *\n * OpenAI injects a global `window.openai` object.\n * MCP Apps runs in a sandboxed iframe and uses postMessage.\n */\nexport function detectPlatform(): WidgetPlatform {\n\tif (typeof window !== \"undefined\" && \"openai\" in window) {\n\t\treturn \"openai\";\n\t}\n\treturn \"mcp-apps\";\n}\n\n/**\n * Check if running on OpenAI platform\n */\nexport function isOpenAI(): boolean {\n\treturn detectPlatform() === \"openai\";\n}\n\n/**\n * Check if running on MCP Apps platform\n */\nexport function isMCPApps(): boolean {\n\treturn detectPlatform() === \"mcp-apps\";\n}\n","import type { z } from \"zod\";\nimport type { McpServer, RegisteredResource } from \"../resources/types\";\n\nexport type { McpServer };\n\n// ============================================================================\n// Sentinel constants\n// ============================================================================\n\nexport const START = \"__start__\" as const;\nexport const END = \"__end__\" as const;\n\n// ============================================================================\n// Signal types — returned by node handlers to control flow behavior\n// ============================================================================\n\nconst INTERRUPT = Symbol.for(\"waniwani.flow.interrupt\");\nconst WIDGET = Symbol.for(\"waniwani.flow.widget\");\n\n/** A single question within an interrupt step */\nexport type InterruptQuestion = {\n\t/** Question to ask the user */\n\tquestion: string;\n\t/** State key where the answer will be stored */\n\tfield: string;\n\t/** Optional suggestions to present as options */\n\tsuggestions?: string[];\n\t/** Hidden context/instructions for this specific question (not shown to user directly) */\n\tcontext?: string;\n};\n\n/**\n * Interrupt signal — pauses the flow and asks the user one or more questions.\n * Single-question and multi-question interrupts use the same type.\n */\nexport type InterruptSignal = {\n\treadonly __type: typeof INTERRUPT;\n\t/** Questions to ask — ask all in one conversational message */\n\tquestions: InterruptQuestion[];\n\t/** Overall hidden context/instructions for the assistant (not shown to user directly) */\n\tcontext?: string;\n};\n\nexport type WidgetSignal = {\n\treadonly __type: typeof WIDGET;\n\t/** The resource to display */\n\tresource: RegisteredResource;\n\t/** Data to pass to the widget as structuredContent */\n\tdata: Record<string, unknown>;\n\t/** Description of what the widget does (for the AI's context) */\n\tdescription?: string;\n\t/**\n\t * State key this widget fills — enables auto-skip when the field is already in state.\n\t * Pass this so the engine can skip the widget step when the answer is already known.\n\t */\n\tfield?: string;\n};\n\n/**\n * Create an interrupt signal — pauses the flow and asks the user a question.\n *\n * Accepts a single question (shorthand) or multiple questions (array form).\n * Both produce the same signal type.\n *\n * @example Single question\n * ```ts\n * return interrupt({ question: \"Your email?\", field: \"email\" })\n * ```\n *\n * @example Multiple questions (asked together in one message)\n * ```ts\n * return interrupt({ questions: [\n * { question: \"How many employees?\", field: \"headcount\" },\n * { question: \"Average age?\", field: \"averageAge\" },\n * ]})\n * ```\n */\nexport function interrupt(\n\tconfig:\n\t\t| {\n\t\t\t\tquestion: string;\n\t\t\t\tfield: string;\n\t\t\t\tsuggestions?: string[];\n\t\t\t\tcontext?: string;\n\t\t }\n\t\t| { questions: InterruptQuestion[]; context?: string },\n): InterruptSignal {\n\tif (\"questions\" in config) {\n\t\treturn {\n\t\t\t__type: INTERRUPT,\n\t\t\tquestions: config.questions,\n\t\t\tcontext: config.context,\n\t\t};\n\t}\n\tconst { question, field, context, suggestions } = config;\n\treturn {\n\t\t__type: INTERRUPT,\n\t\tquestions: [{ question, field, context, suggestions }],\n\t};\n}\n\n/**\n * Create a widget signal — pauses the flow and renders a widget UI.\n *\n * Pass `field` to enable auto-skip: if the field is already in state, the widget\n * step will be skipped automatically.\n */\nexport function showWidget(\n\tresource: RegisteredResource,\n\tconfig: {\n\t\tdata: Record<string, unknown>;\n\t\tdescription?: string;\n\t\tfield?: string;\n\t},\n): WidgetSignal {\n\treturn { __type: WIDGET, resource, ...config };\n}\n\nexport function isInterrupt(value: unknown): value is InterruptSignal {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"__type\" in value &&\n\t\t(value as InterruptSignal).__type === INTERRUPT\n\t);\n}\n\nexport function isWidget(value: unknown): value is WidgetSignal {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"__type\" in value &&\n\t\t(value as WidgetSignal).__type === WIDGET\n\t);\n}\n\n// ============================================================================\n// Node & edge definitions\n// ============================================================================\n\nexport type MaybePromise<T> = T | Promise<T>;\n\n/**\n * Optional config for handler-based nodes.\n * Provides metadata used by the engine (e.g., auto-skip on widget steps).\n *\n * For declarative nodes, config is inferred automatically — no need to pass this.\n */\nexport type NodeConfig<\n\tTState extends Record<string, unknown> = Record<string, unknown>,\n> = {\n\t/**\n\t * State key this node fills.\n\t * When set on a handler-based widget node and the field is already in state,\n\t * the node is auto-skipped. (Alternatively, pass `field` to `showWidget()`.)\n\t */\n\tfield?: Extract<keyof TState, string>;\n};\n\n// ============================================================================\n// Declarative node configs — shorthand for common patterns, no handler needed\n// ============================================================================\n\n/**\n * Declarative widget node config — show a widget without writing a handler.\n * Eliminates duplicate resource references: declare it once, not in both addNode and showWidget.\n *\n * `data` can be a static object or a function receiving current state for dynamic data.\n * `field` enables auto-skip when the field is already in state.\n *\n * @example\n * ```ts\n * .addNode(\"show_pricing\", {\n * resource: pricingTableResource,\n * field: \"selectedPlan\",\n * description: \"Show the 3 pricing tiers.\",\n * data: (state) => ({ ccnName: state.ccnName, offers: computeOffers(state.idcc) }),\n * })\n * ```\n */\nexport type WidgetNodeConfig<\n\tTState extends Record<string, unknown> = Record<string, unknown>,\n> = {\n\tresource: RegisteredResource;\n\tfield?: Extract<keyof TState, string>;\n\tdescription?: string;\n\tdata?:\n\t\t| Record<string, unknown>\n\t\t| ((state: Partial<TState>) => Record<string, unknown>);\n};\n\n/**\n * Node handler — a single function type for all node kinds.\n * The return value determines behavior:\n * - `Partial<TState>` → action node (state merged, auto-advance)\n * - `InterruptSignal` → interrupt (pause, ask user one or more questions)\n * - `WidgetSignal` → widget step (pause, show widget)\n */\nexport type NodeHandler<TState> = (\n\tstate: Partial<TState>,\n\tmeta?: Record<string, unknown>,\n) => MaybePromise<Partial<TState> | InterruptSignal | WidgetSignal>;\n\n/**\n * Condition function for conditional edges.\n * Receives current state, returns the name of the next node.\n */\nexport type ConditionFn<TState> = (\n\tstate: Partial<TState>,\n) => string | Promise<string>;\n\nexport type Edge<TState> =\n\t| { type: \"direct\"; to: string }\n\t| { type: \"conditional\"; condition: ConditionFn<TState> };\n\n// ============================================================================\n// Flow config & compiled output\n// ============================================================================\n\nexport type FlowConfig = {\n\t/** Unique identifier for the flow (becomes the MCP tool name) */\n\tid: string;\n\t/** Display title */\n\ttitle: string;\n\t/** Description for the AI (explains when to use this flow) */\n\tdescription: string;\n\t/**\n\t * Define the flow's state — each field the flow collects.\n\t * Keys are the field names used in `interrupt({ field })` or `NodeConfig.field`,\n\t * values are Zod schemas with `.describe()`.\n\t *\n\t * The state definition serves two purposes:\n\t * 1. Type inference — `TState` is automatically derived, no explicit generic needed\n\t * 2. AI protocol — field names, types, and descriptions are included in the tool\n\t * description so the AI can pre-fill answers via `_meta.flow.state`\n\t *\n\t * @example\n\t * ```ts\n\t * state: {\n\t * country: z.string().describe(\"Country the business is based in\"),\n\t * status: z.enum([\"registered\", \"unregistered\"]).describe(\"Business registration status\"),\n\t * }\n\t * ```\n\t */\n\tstate: Record<string, z.ZodType>;\n\t/** Optional tool annotations */\n\tannotations?: {\n\t\treadOnlyHint?: boolean;\n\t\tidempotentHint?: boolean;\n\t\topenWorldHint?: boolean;\n\t\tdestructiveHint?: boolean;\n\t};\n};\n\n/**\n * Infer the runtime state type from a flow's state schema definition.\n *\n * @example\n * ```ts\n * const config = {\n * state: {\n * country: z.enum([\"FR\", \"DE\"]),\n * status: z.enum([\"registered\", \"unregistered\"]),\n * }\n * };\n * type MyState = InferFlowState<typeof config.state>;\n * // { country: \"FR\" | \"DE\"; status: \"registered\" | \"unregistered\" }\n * ```\n */\nexport type InferFlowState<T extends Record<string, z.ZodType>> = {\n\t[K in keyof T]: z.infer<T[K]>;\n};\n\n/**\n * A compiled flow — can be registered on an McpServer.\n */\nexport type RegisteredFlow = {\n\tid: string;\n\ttitle: string;\n\tdescription: string;\n\tregister: (server: McpServer) => Promise<void>;\n};\n","import type { ToolCallback } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n\tServerNotification,\n\tServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { buildToolMeta } from \"../resources/meta\";\nimport type { RegisteredResource } from \"../resources/types\";\nimport type {\n\tEdge,\n\tFlowConfig,\n\tMcpServer,\n\tNodeConfig,\n\tNodeHandler,\n\tRegisteredFlow,\n} from \"./@types\";\nimport { END, isInterrupt, isWidget, START } from \"./@types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface CompileInput<TState extends Record<string, unknown>> {\n\tconfig: FlowConfig;\n\tnodes: Map<string, NodeHandler<TState>>;\n\tnodeConfigs: Map<string, NodeConfig<TState>>;\n\tedges: Map<string, Edge<TState>>;\n\t/** Widget resources declared in declarative widget nodes — used for tool-level widget metadata */\n\tresources: RegisteredResource[];\n}\n\ntype FlowToolInput = {\n\taction: \"start\" | \"continue\";\n\tstateUpdates?: Record<string, unknown>;\n\t_meta?: {\n\t\tflow?: {\n\t\t\tstep?: string;\n\t\t\tstate?: Record<string, unknown>;\n\t\t\tfield?: string;\n\t\t\twidgetId?: string;\n\t\t};\n\t};\n};\n\ntype FlowPayload = {\n\tstatus: \"widget\" | \"interrupt\" | \"complete\" | \"error\";\n\t[key: string]: unknown;\n};\n\ntype ExecutionResult = {\n\tpayload: FlowPayload;\n\tdata?: Record<string, unknown>;\n\twidgetMeta?: Record<string, unknown>;\n\tflowMeta?: {\n\t\tstep?: string;\n\t\tstate: Record<string, unknown>;\n\t\tfield?: string;\n\t\twidgetId?: string;\n\t};\n};\n\n// ============================================================================\n// Flow protocol — embedded in tool description\n// ============================================================================\n\n/** Extract a human-readable label from a Zod schema for the AI protocol */\nfunction describeZodField(schema: z.ZodType): string {\n\tconst desc = schema.description ?? \"\";\n\tconst def = (\n\t\tschema as unknown as {\n\t\t\t_zod: { def: { type: string; entries?: Record<string, string> } };\n\t\t}\n\t)._zod?.def;\n\n\tif (def?.type === \"enum\" && def.entries) {\n\t\tconst vals = Object.keys(def.entries)\n\t\t\t.map((v) => `\"${v}\"`)\n\t\t\t.join(\" | \");\n\t\treturn desc ? `${vals} — ${desc}` : vals;\n\t}\n\n\treturn desc;\n}\n\nfunction buildFlowProtocol(config: FlowConfig): string {\n\tconst lines = [\n\t\t\"\",\n\t\t\"## FLOW EXECUTION PROTOCOL\",\n\t\t\"\",\n\t\t\"This tool implements a multi-step conversational flow. Follow this protocol exactly:\",\n\t\t\"\",\n\t\t'1. Call with `action: \"start\"` to begin. If the user\\'s message already',\n\t\t\" contains answers to likely questions, extract them into `stateUpdates`\",\n\t\t\" as `{ field: value }` pairs. The engine will auto-skip steps whose\",\n\t\t\" fields are already filled.\",\n\t\t\" Only extract values the user explicitly stated — do NOT guess or invent values.\",\n\t];\n\n\tif (config.state) {\n\t\tconst fieldList = Object.entries(config.state)\n\t\t\t.map(([key, schema]) => {\n\t\t\t\tconst info = describeZodField(schema);\n\t\t\t\treturn info ? `\\`${key}\\` (${info})` : `\\`${key}\\``;\n\t\t\t})\n\t\t\t.join(\", \");\n\t\tlines.push(` Known fields: ${fieldList}.`);\n\t}\n\n\tlines.push(\n\t\t\"2. The response JSON `status` field tells you what to do next:\",\n\t\t' - `\"interrupt\"`: Pause and ask the user. Two forms:',\n\t\t\" a. Single question: `{ question, field, context? }` — ask `question`, store answer in `field`.\",\n\t\t\" b. Multi-question: `{ questions: [{question, field}, ...], context? }` — ask ALL questions\",\n\t\t\" in one conversational message, collect all answers.\",\n\t\t\" `context` (if present) is hidden AI instructions — use to shape your response, do NOT show verbatim.\",\n\t\t\" Then call again with:\",\n\t\t' `action: \"continue\"`, `state` = the returned `state`,',\n\t\t\" `stateUpdates` = answers keyed by their `field` names, plus any other fields the user mentioned.\",\n\t\t' - `\"widget\"`: A widget UI is being shown. The user will interact with the widget.',\n\t\t\" When the user makes a choice, call again with:\",\n\t\t' `action: \"continue\"`, `state` = the returned `state`,',\n\t\t\" `stateUpdates` = `{ [_meta.flow.field]: <user's selection> }` plus any other fields the user mentioned.\",\n\t\t' - `\"complete\"`: The flow is done. Present the result to the user.',\n\t\t' - `\"error\"`: Something went wrong. Show the `error` message.',\n\t\t\"\",\n\t\t\"3. ALWAYS pass back the `state` object exactly as received.\",\n\t\t\"4. Do NOT invent state values. Only use `stateUpdates` for information the user explicitly provided.\",\n\t\t\"5. Always include answers for all pending fields in `stateUpdates` when resuming.\",\n\t\t\" If the user mentioned values for other known fields, include those too —\",\n\t\t\" they will be applied immediately and those steps will be auto-skipped.\",\n\t);\n\n\treturn lines.join(\"\\n\");\n}\n\nfunction getInputMeta(args: FlowToolInput): {\n\tstep?: string;\n\tstate: Record<string, unknown>;\n\tfield?: string;\n\twidgetId?: string;\n} {\n\tconst state = args._meta?.flow?.state ?? {};\n\tconst step = args._meta?.flow?.step;\n\tconst field = args._meta?.flow?.field;\n\tconst widgetId = args._meta?.flow?.widgetId;\n\treturn { step, state, field, widgetId };\n}\n\n// ============================================================================\n// Edge resolution\n// ============================================================================\n\nasync function resolveNextNode<TState extends Record<string, unknown>>(\n\tedge: Edge<TState>,\n\tstate: Partial<TState>,\n): Promise<string> {\n\tif (edge.type === \"direct\") return edge.to;\n\treturn edge.condition(state);\n}\n\n// ============================================================================\n// Execution engine\n// ============================================================================\n\nasync function executeFrom<TState extends Record<string, unknown>>(\n\tstartNodeName: string,\n\tstartState: TState,\n\tnodes: Map<string, NodeHandler<TState>>,\n\tnodeConfigs: Map<string, NodeConfig<TState>>,\n\tedges: Map<string, Edge<TState>>,\n\tmeta?: Record<string, unknown>,\n): Promise<ExecutionResult> {\n\tlet currentNode = startNodeName;\n\tlet state = { ...startState };\n\n\t// Safety limit to prevent infinite loops\n\tconst MAX_ITERATIONS = 50;\n\tlet iterations = 0;\n\n\twhile (iterations++ < MAX_ITERATIONS) {\n\t\t// Reached END\n\t\tif (currentNode === END) {\n\t\t\treturn {\n\t\t\t\tpayload: { status: \"complete\" },\n\t\t\t\tflowMeta: { state },\n\t\t\t};\n\t\t}\n\n\t\tconst handler = nodes.get(currentNode);\n\t\tif (!handler) {\n\t\t\treturn {\n\t\t\t\tpayload: {\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\terror: `Unknown node: \"${currentNode}\"`,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await handler(state, meta);\n\n\t\t\t// Interrupt signal — pause and ask the user one or more questions\n\t\t\tif (isInterrupt(result)) {\n\t\t\t\t// Auto-skip: advance only when ALL question fields are already in state\n\t\t\t\tconst allFilled = result.questions.every((q) => {\n\t\t\t\t\tconst v = state[q.field as keyof TState];\n\t\t\t\t\treturn v !== undefined && v !== null && v !== \"\";\n\t\t\t\t});\n\t\t\t\tif (allFilled) {\n\t\t\t\t\tconst edge = edges.get(currentNode);\n\t\t\t\t\tif (!edge) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tpayload: {\n\t\t\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Single-question shorthand: unwrap for cleaner AI payload\n\t\t\t\tconst isSingle = result.questions.length === 1;\n\t\t\t\tconst q0 = result.questions[0];\n\t\t\t\tconst payload =\n\t\t\t\t\tisSingle && q0\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tstatus: \"interrupt\" as const,\n\t\t\t\t\t\t\t\tquestion: q0.question,\n\t\t\t\t\t\t\t\tfield: q0.field,\n\t\t\t\t\t\t\t\t...(q0.suggestions ? { suggestions: q0.suggestions } : {}),\n\t\t\t\t\t\t\t\t...(q0.context || result.context\n\t\t\t\t\t\t\t\t\t? { context: q0.context ?? result.context }\n\t\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\tstatus: \"interrupt\" as const,\n\t\t\t\t\t\t\t\tquestions: result.questions,\n\t\t\t\t\t\t\t\t...(result.context ? { context: result.context } : {}),\n\t\t\t\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tpayload,\n\t\t\t\t\tflowMeta: {\n\t\t\t\t\t\tstep: currentNode,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\t...(isSingle && q0 ? { field: q0.field } : {}),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Widget signal — pause and show widget\n\t\t\tif (isWidget(result)) {\n\t\t\t\t// Auto-skip: use field from the signal, fall back to nodeConfig\n\t\t\t\tconst widgetField = result.field ?? nodeConfigs.get(currentNode)?.field;\n\t\t\t\tif (widgetField) {\n\t\t\t\t\tconst v = state[widgetField as keyof TState];\n\t\t\t\t\tif (v !== undefined && v !== null && v !== \"\") {\n\t\t\t\t\t\tconst edge = edges.get(currentNode);\n\t\t\t\t\t\tif (!edge) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tpayload: {\n\t\t\t\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst resource = result.resource;\n\t\t\t\treturn {\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tstatus: \"widget\",\n\t\t\t\t\t\tdescription: result.description,\n\t\t\t\t\t},\n\t\t\t\t\tdata: result.data,\n\t\t\t\t\twidgetMeta: buildToolMeta({\n\t\t\t\t\t\topenaiTemplateUri: resource.openaiUri,\n\t\t\t\t\t\tmcpTemplateUri: resource.mcpUri,\n\t\t\t\t\t\tinvoking: \"Loading...\",\n\t\t\t\t\t\tinvoked: \"Loaded\",\n\t\t\t\t\t\tautoHeight: resource.autoHeight,\n\t\t\t\t\t}),\n\t\t\t\t\tflowMeta: {\n\t\t\t\t\t\tstep: currentNode,\n\t\t\t\t\t\tstate,\n\t\t\t\t\t\tfield: widgetField,\n\t\t\t\t\t\twidgetId: resource.id,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Action node — merge state and auto-advance\n\t\t\tstate = { ...state, ...result } as TState;\n\n\t\t\tconst edge = edges.get(currentNode);\n\t\t\tif (!edge) {\n\t\t\t\treturn {\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: `No outgoing edge from node \"${currentNode}\"`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tcurrentNode = await resolveNextNode(edge, state);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\t\treturn {\n\t\t\t\tpayload: { status: \"error\", error: message },\n\t\t\t\tflowMeta: { step: currentNode, state },\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tpayload: {\n\t\t\tstatus: \"error\",\n\t\t\terror: \"Flow exceeded maximum iterations (possible infinite loop)\",\n\t\t},\n\t};\n}\n\n// ============================================================================\n// Compile\n// ============================================================================\n\nconst inputSchema = {\n\taction: z\n\t\t.enum([\"start\", \"continue\"])\n\t\t.describe(\n\t\t\t'\"start\" to begin the flow, \"continue\" to resume after a pause (interrupt or widget)',\n\t\t),\n\tstateUpdates: z\n\t\t.record(z.string(), z.unknown())\n\t\t.optional()\n\t\t.describe(\n\t\t\t\"State field values to set before processing the next node. Use this to pass the user's answer (keyed by the field name from _meta.flow.field) and any other values the user mentioned.\",\n\t\t),\n\t_meta: z\n\t\t.object({\n\t\t\tflow: z\n\t\t\t\t.object({\n\t\t\t\t\tstep: z\n\t\t\t\t\t\t.string()\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe(\"Current step name (from the previous response)\"),\n\t\t\t\t\tstate: z\n\t\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t\t.optional()\n\t\t\t\t\t\t.describe(\"Flow state — pass back exactly as received\"),\n\t\t\t\t\tfield: z.string().optional(),\n\t\t\t\t\twidgetId: z.string().optional(),\n\t\t\t\t})\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Flow routing data. Pass back exactly as received.\"),\n\t\t})\n\t\t.optional()\n\t\t.describe(\n\t\t\t\"Internal flow routing data. Pass back the _meta object from the previous response exactly as received.\",\n\t\t),\n};\n\nexport function compileFlow<TState extends Record<string, unknown>>(\n\tinput: CompileInput<TState>,\n): RegisteredFlow {\n\tconst { config, nodes, nodeConfigs, edges, resources } = input;\n\tconst protocol = buildFlowProtocol(config);\n\tconst fullDescription = `${config.description}\\n${protocol}`;\n\n\t// Use the first declared resource to build tool-level widget metadata.\n\t// This tells OpenAI/Claude that this tool can produce widget UIs.\n\tconst firstResource = resources[0];\n\tconst toolMeta = firstResource\n\t\t? buildToolMeta({\n\t\t\t\topenaiTemplateUri: firstResource.openaiUri,\n\t\t\t\tmcpTemplateUri: firstResource.mcpUri,\n\t\t\t\tinvoking: \"Loading...\",\n\t\t\t\tinvoked: \"Loaded\",\n\t\t\t\tautoHeight: firstResource.autoHeight,\n\t\t\t})\n\t\t: undefined;\n\n\tasync function handleToolCall(\n\t\targs: FlowToolInput,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<ExecutionResult> {\n\t\tconst inputMeta = getInputMeta(args);\n\t\tconst state = inputMeta.state as TState;\n\n\t\tif (args.action === \"start\") {\n\t\t\tconst startEdge = edges.get(START);\n\t\t\tif (!startEdge) {\n\t\t\t\treturn {\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: \"No start edge\",\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Merge pre-filled answers and any stateUpdates\n\t\t\tconst startState = {\n\t\t\t\t...state,\n\t\t\t\t...(args.stateUpdates ?? {}),\n\t\t\t} as TState;\n\n\t\t\tconst firstNode = await resolveNextNode(startEdge, startState);\n\t\t\treturn executeFrom(\n\t\t\t\tfirstNode,\n\t\t\t\tstartState,\n\t\t\t\tnodes,\n\t\t\t\tnodeConfigs,\n\t\t\t\tedges,\n\t\t\t\tmeta,\n\t\t\t);\n\t\t}\n\n\t\tif (args.action === \"continue\") {\n\t\t\tconst step = inputMeta.step;\n\t\t\tif (!step) {\n\t\t\t\treturn {\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: 'Missing \"_meta.flow.step\" for continue action',\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst updatedState = {\n\t\t\t\t...state,\n\t\t\t\t...(args.stateUpdates ?? {}),\n\t\t\t} as TState;\n\n\t\t\tconst edge = edges.get(step);\n\t\t\tif (!edge) {\n\t\t\t\treturn {\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: `No edge from step \"${step}\"`,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst nextNode = await resolveNextNode(edge, updatedState);\n\t\t\treturn executeFrom(\n\t\t\t\tnextNode,\n\t\t\t\tupdatedState,\n\t\t\t\tnodes,\n\t\t\t\tnodeConfigs,\n\t\t\t\tedges,\n\t\t\t\tmeta,\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tpayload: {\n\t\t\t\tstatus: \"error\",\n\t\t\t\terror: `Unknown action: \"${args.action}\"`,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn {\n\t\tid: config.id,\n\t\ttitle: config.title,\n\t\tdescription: fullDescription,\n\n\t\tasync register(server: McpServer): Promise<void> {\n\t\t\tserver.registerTool(\n\t\t\t\tconfig.id,\n\t\t\t\t{\n\t\t\t\t\ttitle: config.title,\n\t\t\t\t\tdescription: fullDescription,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tannotations: config.annotations,\n\t\t\t\t\t...(toolMeta && { _meta: toolMeta }),\n\t\t\t\t},\n\t\t\t\t(async (args: FlowToolInput, extra: unknown) => {\n\t\t\t\t\tconst requestExtra = extra as RequestHandlerExtra<\n\t\t\t\t\t\tServerRequest,\n\t\t\t\t\t\tServerNotification\n\t\t\t\t\t>;\n\t\t\t\t\tconst _meta: Record<string, unknown> = requestExtra._meta ?? {};\n\n\t\t\t\t\tconst result = await handleToolCall(args, _meta);\n\t\t\t\t\tconst responseMeta = {\n\t\t\t\t\t\t...(result.widgetMeta ?? {}),\n\t\t\t\t\t\t..._meta,\n\t\t\t\t\t\t...(result.flowMeta\n\t\t\t\t\t\t\t? { flow: { flowId: config.id, ...result.flowMeta } }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t};\n\t\t\t\t\tconst content = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\t\ttext: JSON.stringify(result.payload, null, 2),\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\n\t\t\t\t\t// Widget response — include structuredContent + widget metadata + flow in _meta\n\t\t\t\t\tif (result.widgetMeta) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tstructuredContent: result.data,\n\t\t\t\t\t\t\t_meta: responseMeta,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Non-widget response (interrupt, complete, error)\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t...(Object.keys(responseMeta).length > 0\n\t\t\t\t\t\t\t? { _meta: responseMeta }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t};\n\t\t\t\t}) as unknown as ToolCallback<typeof inputSchema>,\n\t\t\t);\n\t\t},\n\t};\n}\n","import type { WidgetCSP } from \"./types\";\n\n/**\n * MIME types for widget resources.\n * OpenAI Apps SDK uses \"text/html+skybridge\"\n * MCP Apps uses \"text/html;profile=mcp-app\"\n */\nexport const MIME_TYPE_OPENAI = \"text/html+skybridge\";\nexport const MIME_TYPE_MCP = \"text/html;profile=mcp-app\";\n\n// ---- HTML fetching ----\n\nexport const fetchHtml = async (\n\tbaseUrl: string,\n\tpath: string,\n): Promise<string> => {\n\tconst normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\tconst result = await fetch(`${normalizedBase}${path}`);\n\treturn await result.text();\n};\n\n// ---- OpenAI resource metadata ----\n\ninterface OpenAIResourceMeta {\n\t[key: string]: unknown;\n\t\"openai/widgetDescription\"?: string;\n\t\"openai/widgetPrefersBorder\"?: boolean;\n\t\"openai/widgetDomain\"?: string;\n\t\"openai/widgetCSP\"?: WidgetCSP;\n}\n\nexport function buildOpenAIResourceMeta(config: {\n\tdescription?: string;\n\tprefersBorder?: boolean;\n\twidgetDomain: string;\n\twidgetCSP?: WidgetCSP;\n}): OpenAIResourceMeta {\n\treturn {\n\t\t\"openai/widgetDescription\": config.description,\n\t\t\"openai/widgetPrefersBorder\": config.prefersBorder,\n\t\t\"openai/widgetDomain\": config.widgetDomain,\n\t\t...(config.widgetCSP && { \"openai/widgetCSP\": config.widgetCSP }),\n\t};\n}\n\n// ---- MCP Apps resource metadata ----\n\ninterface McpAppsResourceMeta {\n\t[key: string]: unknown;\n\tui?: {\n\t\tcsp?: {\n\t\t\tconnectDomains?: string[];\n\t\t\tresourceDomains?: string[];\n\t\t\tframeDomains?: string[];\n\t\t\tredirectDomains?: string[];\n\t\t};\n\t\tdomain?: string;\n\t\tprefersBorder?: boolean;\n\t};\n}\n\nexport function buildMcpAppsResourceMeta(config: {\n\tdescription?: string;\n\tprefersBorder?: boolean;\n\twidgetDomain?: string;\n\twidgetCSP?: WidgetCSP;\n}): McpAppsResourceMeta {\n\tconst csp = config.widgetCSP\n\t\t? {\n\t\t\t\tconnectDomains: config.widgetCSP.connect_domains,\n\t\t\t\tresourceDomains: config.widgetCSP.resource_domains,\n\t\t\t\tframeDomains: config.widgetCSP.frame_domains,\n\t\t\t\tredirectDomains: config.widgetCSP.redirect_domains,\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\tui: {\n\t\t\t...(csp && { csp }),\n\t\t\t...(config.widgetDomain && { domain: config.widgetDomain }),\n\t\t\t...(config.prefersBorder !== undefined && {\n\t\t\t\tprefersBorder: config.prefersBorder,\n\t\t\t}),\n\t\t},\n\t};\n}\n\n// ---- Tool metadata (references resource URIs) ----\n\nexport function buildToolMeta(config: {\n\topenaiTemplateUri: string;\n\tmcpTemplateUri: string;\n\tinvoking: string;\n\tinvoked: string;\n\tautoHeight?: boolean;\n}) {\n\treturn {\n\t\t// OpenAI metadata\n\t\t\"openai/outputTemplate\": config.openaiTemplateUri,\n\t\t\"openai/toolInvocation/invoking\": config.invoking,\n\t\t\"openai/toolInvocation/invoked\": config.invoked,\n\t\t\"openai/widgetAccessible\": true,\n\t\t\"openai/resultCanProduceWidget\": true,\n\t\t// MCP Apps metadata\n\t\tui: {\n\t\t\tresourceUri: config.mcpTemplateUri,\n\t\t\t...(config.autoHeight && { autoHeight: true }),\n\t\t},\n\t} as const;\n}\n","import type { RegisteredResource } from \"../resources/types\";\nimport type {\n\tConditionFn,\n\tEdge,\n\tFlowConfig,\n\tNodeConfig,\n\tNodeHandler,\n\tRegisteredFlow,\n\tWidgetNodeConfig,\n} from \"./@types\";\nimport { END, START, showWidget } from \"./@types\";\nimport { compileFlow } from \"./compile\";\n\n/**\n * A LangGraph-inspired state graph builder for MCP tools.\n *\n * @example\n * ```ts\n * const flow = new StateGraph<MyState>({\n * id: \"onboarding\",\n * title: \"User Onboarding\",\n * description: \"Guides users through onboarding\",\n * })\n * .addNode(\"ask_name\", (state) => interrupt({ question: \"What's your name?\", field: \"name\" }))\n * .addNode(\"greet\", (state) => ({ greeting: `Hello ${state.name}!` }))\n * .addEdge(START, \"ask_name\")\n * .addEdge(\"ask_name\", \"greet\")\n * .addEdge(\"greet\", END)\n * .compile();\n * ```\n */\nexport class StateGraph<TState extends Record<string, unknown>> {\n\tprivate nodes = new Map<string, NodeHandler<TState>>();\n\tprivate nodeConfigs = new Map<string, NodeConfig<TState>>();\n\tprivate edges = new Map<string, Edge<TState>>();\n\tprivate config: FlowConfig;\n\tprivate resources: RegisteredResource[] = [];\n\n\tconstructor(config: FlowConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Add a node with just a handler.\n\t */\n\taddNode(name: string, handler: NodeHandler<TState>): this;\n\t/**\n\t * Add a node with config and a handler.\n\t * Pass `field` to enable auto-skip on widget nodes.\n\t */\n\taddNode(\n\t\tname: string,\n\t\tconfig: NodeConfig<TState>,\n\t\thandler: NodeHandler<TState>,\n\t): this;\n\t/**\n\t * Declarative widget node — show a widget without writing a handler.\n\t * Resource is declared once; no `showWidget()` call needed.\n\t *\n\t * @example\n\t * ```ts\n\t * .addNode(\"show_pricing\", {\n\t * resource: pricingResource,\n\t * field: \"selectedPlan\",\n\t * description: \"Show the pricing tiers.\",\n\t * data: (state) => ({ offers: computeOffers(state.idcc) }),\n\t * })\n\t * ```\n\t */\n\taddNode(name: string, config: WidgetNodeConfig<TState>): this;\n\taddNode(\n\t\tname: string,\n\t\tconfigOrHandler:\n\t\t\t| NodeConfig<TState>\n\t\t\t| NodeHandler<TState>\n\t\t\t| WidgetNodeConfig<TState>,\n\t\tmaybeHandler?: NodeHandler<TState>,\n\t): this {\n\t\tif (name === START || name === END) {\n\t\t\tthrow new Error(\n\t\t\t\t`\"${name}\" is a reserved name and cannot be used as a node name`,\n\t\t\t);\n\t\t}\n\t\tif (this.nodes.has(name)) {\n\t\t\tthrow new Error(`Node \"${name}\" already exists`);\n\t\t}\n\n\t\tlet handler: NodeHandler<TState>;\n\t\tlet nodeConfig: NodeConfig<TState> = {};\n\n\t\tif (typeof configOrHandler === \"function\") {\n\t\t\t// addNode(name, handler)\n\t\t\thandler = configOrHandler;\n\t\t} else if (maybeHandler) {\n\t\t\t// addNode(name, nodeConfig, handler)\n\t\t\thandler = maybeHandler;\n\t\t\tnodeConfig = configOrHandler as NodeConfig<TState>;\n\t\t} else {\n\t\t\t// Declarative widget node\n\t\t\tconst cfg = configOrHandler as WidgetNodeConfig<TState>;\n\t\t\tthis.resources.push(cfg.resource);\n\t\t\tnodeConfig = { field: cfg.field };\n\t\t\thandler = (state) =>\n\t\t\t\tshowWidget(cfg.resource, {\n\t\t\t\t\tdata:\n\t\t\t\t\t\ttypeof cfg.data === \"function\" ? cfg.data(state) : (cfg.data ?? {}),\n\t\t\t\t\tdescription: cfg.description,\n\t\t\t\t\tfield: cfg.field,\n\t\t\t\t});\n\t\t}\n\n\t\tthis.nodes.set(name, handler);\n\t\tthis.nodeConfigs.set(name, nodeConfig);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a direct edge between two nodes.\n\t *\n\t * Use `START` as `from` to set the entry point.\n\t * Use `END` as `to` to mark a terminal node.\n\t */\n\taddEdge(from: string, to: string): this {\n\t\tif (this.edges.has(from)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node \"${from}\" already has an outgoing edge. Use addConditionalEdge for branching.`,\n\t\t\t);\n\t\t}\n\t\tthis.edges.set(from, { type: \"direct\", to });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Add a conditional edge from a node.\n\t *\n\t * The condition function receives current state and returns the name of the next node.\n\t */\n\taddConditionalEdge(from: string, condition: ConditionFn<TState>): this {\n\t\tif (this.edges.has(from)) {\n\t\t\tthrow new Error(`Node \"${from}\" already has an outgoing edge.`);\n\t\t}\n\t\tthis.edges.set(from, { type: \"conditional\", condition });\n\t\treturn this;\n\t}\n\n\t/**\n\t * Compile the graph into a RegisteredFlow that can be registered on an McpServer.\n\t *\n\t * Validates the graph structure and returns a registration-compatible object.\n\t */\n\tcompile(): RegisteredFlow {\n\t\tthis.validate();\n\n\t\treturn compileFlow<TState>({\n\t\t\tconfig: this.config,\n\t\t\tnodes: new Map(this.nodes),\n\t\t\tnodeConfigs: new Map(this.nodeConfigs),\n\t\t\tedges: new Map(this.edges),\n\t\t\tresources: [...this.resources],\n\t\t});\n\t}\n\n\tprivate validate(): void {\n\t\t// Must have a START edge\n\t\tif (!this.edges.has(START)) {\n\t\t\tthrow new Error(\n\t\t\t\t'Flow must have an entry point. Add an edge from START: .addEdge(START, \"first_node\")',\n\t\t\t);\n\t\t}\n\n\t\t// START edge target must exist\n\t\tconst startEdge = this.edges.get(START);\n\t\tif (\n\t\t\tstartEdge?.type === \"direct\" &&\n\t\t\tstartEdge.to !== END &&\n\t\t\t!this.nodes.has(startEdge.to)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`START edge references non-existent node: \"${startEdge.to}\"`,\n\t\t\t);\n\t\t}\n\n\t\t// All static edge targets must reference existing nodes (or END)\n\t\tfor (const [from, edge] of this.edges) {\n\t\t\tif (from !== START && !this.nodes.has(from)) {\n\t\t\t\tthrow new Error(`Edge from non-existent node: \"${from}\"`);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tedge.type === \"direct\" &&\n\t\t\t\tedge.to !== END &&\n\t\t\t\t!this.nodes.has(edge.to)\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Edge from \"${from}\" references non-existent node: \"${edge.to}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Every node must have an outgoing edge\n\t\tfor (const [name] of this.nodes) {\n\t\t\tif (!this.edges.has(name)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${name}\" has no outgoing edge. Add one with .addEdge(\"${name}\", ...) or .addConditionalEdge(\"${name}\", ...)`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { z } from \"zod\";\nimport type { FlowConfig, InferFlowState } from \"./@types\";\nimport { StateGraph } from \"./state-graph\";\n\n/**\n * Create a new flow graph — convenience factory for `new StateGraph()`.\n *\n * The state type is automatically inferred from the `state` definition —\n * no explicit generic parameter needed.\n *\n * @example\n * ```ts\n * import { createFlow, interrupt, START, END } from \"@waniwani/sdk/mcp\";\n * import { z } from \"zod\";\n *\n * const flow = createFlow({\n * id: \"onboarding\",\n * title: \"User Onboarding\",\n * description: \"Guides users through onboarding. Use when a user wants to get started.\",\n * state: {\n * name: z.string().describe(\"The user's name\"),\n * email: z.string().describe(\"The user's email address\"),\n * },\n * })\n * .addNode(\"ask_name\", () => interrupt({ question: \"What's your name?\", field: \"name\" }))\n * .addNode(\"ask_email\", () => interrupt({ question: \"What's your email?\", field: \"email\" }))\n * .addEdge(START, \"ask_name\")\n * .addEdge(\"ask_name\", \"ask_email\")\n * .addEdge(\"ask_email\", END)\n * .compile();\n * ```\n */\nexport function createFlow<const TSchema extends Record<string, z.ZodType>>(\n\tconfig: Omit<FlowConfig, \"state\"> & { state: TSchema },\n): StateGraph<InferFlowState<TSchema>> {\n\treturn new StateGraph<InferFlowState<TSchema>>(config);\n}\n","import {\n\tbuildMcpAppsResourceMeta,\n\tbuildOpenAIResourceMeta,\n\tfetchHtml,\n\tMIME_TYPE_MCP,\n\tMIME_TYPE_OPENAI,\n} from \"./meta\";\nimport type { McpServer, RegisteredResource, ResourceConfig } from \"./types\";\n\n/**\n * Creates a reusable UI resource (HTML template) that can be attached\n * to tools or flow nodes.\n *\n * @example\n * ```ts\n * const pricingUI = createResource({\n * id: \"pricing_table\",\n * title: \"Pricing Table\",\n * baseUrl: \"https://my-app.com\",\n * htmlPath: \"/widgets/pricing\",\n * widgetDomain: \"my-app.com\",\n * });\n *\n * await pricingUI.register(server);\n * ```\n */\nexport function createResource(config: ResourceConfig): RegisteredResource {\n\tconst {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\t\tbaseUrl,\n\t\thtmlPath,\n\t\twidgetDomain,\n\t\tprefersBorder = true,\n\t\tautoHeight = true,\n\t} = config;\n\n\t// Auto-generate CSP from baseUrl if not explicitly provided\n\tlet widgetCSP = config.widgetCSP ?? {\n\t\tconnect_domains: [baseUrl],\n\t\tresource_domains: [baseUrl],\n\t};\n\n\t// In development with localhost, add extra CSP domains for\n\t// Next.js dev features (WebSocket HMR, Turbopack font serving)\n\tif (process.env.NODE_ENV === \"development\") {\n\t\ttry {\n\t\t\tconst { hostname } = new URL(baseUrl);\n\t\t\tif (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n\t\t\t\twidgetCSP = {\n\t\t\t\t\t...widgetCSP,\n\t\t\t\t\tconnect_domains: [\n\t\t\t\t\t\t...(widgetCSP.connect_domains || []),\n\t\t\t\t\t\t`ws://${hostname}:*`,\n\t\t\t\t\t\t`wss://${hostname}:*`,\n\t\t\t\t\t],\n\t\t\t\t\tresource_domains: [\n\t\t\t\t\t\t...(widgetCSP.resource_domains || []),\n\t\t\t\t\t\t`http://${hostname}:*`,\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t} catch {\n\t\t\t// Invalid baseUrl — skip dev CSP additions\n\t\t}\n\t}\n\n\tconst openaiUri = `ui://widgets/apps-sdk/${id}.html`;\n\tconst mcpUri = `ui://widgets/ext-apps/${id}.html`;\n\n\t// Lazy HTML — fetched once, shared across all calls\n\tlet htmlPromise: Promise<string> | null = null;\n\tconst getHtml = () => {\n\t\tif (!htmlPromise) htmlPromise = fetchHtml(baseUrl, htmlPath);\n\t\treturn htmlPromise;\n\t};\n\n\t// Use description for UI metadata\n\tconst uiDescription = description;\n\n\tasync function register(server: McpServer): Promise<void> {\n\t\tconst html = await getHtml();\n\n\t\t// Register OpenAI Apps SDK resource\n\t\tserver.registerResource(\n\t\t\t`${id}-openai-widget`,\n\t\t\topenaiUri,\n\t\t\t{\n\t\t\t\ttitle,\n\t\t\t\tdescription: uiDescription,\n\t\t\t\tmimeType: MIME_TYPE_OPENAI,\n\t\t\t\t_meta: {\n\t\t\t\t\t\"openai/widgetDescription\": uiDescription,\n\t\t\t\t\t\"openai/widgetPrefersBorder\": prefersBorder,\n\t\t\t\t},\n\t\t\t},\n\t\t\tasync (uri) => ({\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: MIME_TYPE_OPENAI,\n\t\t\t\t\t\ttext: html,\n\t\t\t\t\t\t_meta: buildOpenAIResourceMeta({\n\t\t\t\t\t\t\tdescription: uiDescription,\n\t\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t\t\twidgetDomain,\n\t\t\t\t\t\t\twidgetCSP,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t);\n\n\t\t// Register MCP Apps resource\n\t\tserver.registerResource(\n\t\t\t`${id}-mcp-widget`,\n\t\t\tmcpUri,\n\t\t\t{\n\t\t\t\ttitle,\n\t\t\t\tdescription: uiDescription,\n\t\t\t\tmimeType: MIME_TYPE_MCP,\n\t\t\t\t_meta: {\n\t\t\t\t\tui: {\n\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tasync (uri) => ({\n\t\t\t\tcontents: [\n\t\t\t\t\t{\n\t\t\t\t\t\turi: uri.href,\n\t\t\t\t\t\tmimeType: MIME_TYPE_MCP,\n\t\t\t\t\t\ttext: html,\n\t\t\t\t\t\t_meta: buildMcpAppsResourceMeta({\n\t\t\t\t\t\t\tdescription: uiDescription,\n\t\t\t\t\t\t\tprefersBorder,\n\t\t\t\t\t\t\twidgetCSP,\n\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t);\n\t}\n\n\treturn {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\t\topenaiUri,\n\t\tmcpUri,\n\t\tautoHeight,\n\t\tregister,\n\t};\n}\n","import type { ToolCallback } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ShapeOutput } from \"@modelcontextprotocol/sdk/server/zod-compat.js\";\nimport type { RequestHandlerExtra } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n\tServerNotification,\n\tServerRequest,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { z } from \"zod\";\nimport { buildToolMeta } from \"../resources/meta\";\nimport type {\n\tMcpServer,\n\tRegisteredTool,\n\tToolConfig,\n\tToolHandler,\n} from \"./types\";\n\n/**\n * Creates an MCP tool with minimal boilerplate.\n *\n * When `config.resource` is provided, the tool returns `structuredContent` + widget metadata.\n * Without a resource, the tool returns plain text content.\n *\n * @example\n * ```ts\n * // Widget tool (with resource)\n * const pricingTool = createTool({\n * resource: pricingUI,\n * description: \"Show pricing comparison\",\n * inputSchema: { postalCode: z.string() },\n * }, async ({ postalCode }) => ({\n * text: \"Pricing loaded\",\n * data: { postalCode, prices: [] },\n * }));\n *\n * // Plain tool (no resource)\n * const searchTool = createTool({\n * id: \"search\",\n * title: \"Search\",\n * description: \"Search the knowledge base\",\n * inputSchema: { query: z.string() },\n * }, async ({ query }) => ({\n * text: `Results for \"${query}\"`,\n * }));\n * ```\n */\nexport function createTool<TInput extends z.ZodRawShape>(\n\tconfig: ToolConfig<TInput>,\n\thandler: ToolHandler<TInput>,\n): RegisteredTool {\n\tconst { resource, description, inputSchema, annotations } = config;\n\n\tconst id = config.id ?? resource?.id;\n\tconst title = config.title ?? resource?.title;\n\n\tif (!id) {\n\t\tthrow new Error(\n\t\t\t\"createTool: `id` is required when no resource is provided\",\n\t\t);\n\t}\n\tif (!title) {\n\t\tthrow new Error(\n\t\t\t\"createTool: `title` is required when no resource is provided\",\n\t\t);\n\t}\n\n\t// Build widget metadata only when resource is present\n\tconst toolMeta = resource\n\t\t? buildToolMeta({\n\t\t\t\topenaiTemplateUri: resource.openaiUri,\n\t\t\t\tmcpTemplateUri: resource.mcpUri,\n\t\t\t\tinvoking: config.invoking ?? \"Loading...\",\n\t\t\t\tinvoked: config.invoked ?? \"Loaded\",\n\t\t\t\tautoHeight: resource.autoHeight,\n\t\t\t})\n\t\t: undefined;\n\n\treturn {\n\t\tid,\n\t\ttitle,\n\t\tdescription,\n\n\t\tasync register(server: McpServer): Promise<void> {\n\t\t\tserver.registerTool(\n\t\t\t\tid,\n\t\t\t\t{\n\t\t\t\t\ttitle,\n\t\t\t\t\tdescription,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tannotations,\n\t\t\t\t\t...(toolMeta && { _meta: toolMeta }),\n\t\t\t\t},\n\t\t\t\t(async (args: ShapeOutput<TInput>, extra: unknown) => {\n\t\t\t\t\tconst requestExtra = extra as RequestHandlerExtra<\n\t\t\t\t\t\tServerRequest,\n\t\t\t\t\t\tServerNotification\n\t\t\t\t\t>;\n\t\t\t\t\tconst _meta: Record<string, unknown> = requestExtra._meta ?? {};\n\n\t\t\t\t\tconst result = await handler(args, { extra: { _meta } });\n\n\t\t\t\t\t// Widget tool: return structuredContent + widget metadata\n\t\t\t\t\tif (resource && result.data) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: result.text }],\n\t\t\t\t\t\t\tstructuredContent: result.data,\n\t\t\t\t\t\t\t_meta: {\n\t\t\t\t\t\t\t\t...toolMeta,\n\t\t\t\t\t\t\t\t..._meta,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Plain tool: return text content only\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: result.text }],\n\t\t\t\t\t};\n\t\t\t\t}) as unknown as ToolCallback<TInput>,\n\t\t\t);\n\t\t},\n\t};\n}\n\n/**\n * Registers multiple tools on the server\n */\nexport async function registerTools(\n\tserver: McpServer,\n\ttools: RegisteredTool[],\n): Promise<void> {\n\tawait Promise.all(tools.map((t) => t.register(server)));\n}\n","import type { EventType, LegacyTrackEvent, TrackInput } from \"./@types.js\";\nimport type { V2CorrelationIds, V2EventEnvelope } from \"./v2-types.js\";\n\nconst DEFAULT_SOURCE = \"@waniwani/sdk\";\n\nexport interface MapTrackEventOptions {\n\tnow?: () => Date;\n\tgenerateId?: () => string;\n\tsource?: string;\n}\n\nexport function mapTrackEventToV2(\n\tinput: TrackInput,\n\toptions: MapTrackEventOptions = {},\n): V2EventEnvelope {\n\tconst now = options.now ?? (() => new Date());\n\tconst generateId = options.generateId ?? createEventId;\n\tconst eventName = resolveEventName(input);\n\tconst meta = toRecord(input.meta);\n\tconst metadata = toRecord(input.metadata);\n\tconst correlation = resolveCorrelationIds(input, meta);\n\tconst eventId = takeNonEmptyString(input.eventId) ?? generateId();\n\tconst timestamp = normalizeTimestamp(input.timestamp, now);\n\tconst source =\n\t\ttakeNonEmptyString(input.source) ?? options.source ?? DEFAULT_SOURCE;\n\tconst rawLegacy = isLegacyTrackEvent(input) ? { ...input } : undefined;\n\n\tconst mappedMetadata: Record<string, unknown> = {\n\t\t...metadata,\n\t};\n\tif (Object.keys(meta).length > 0) mappedMetadata.meta = meta;\n\tif (rawLegacy) mappedMetadata.rawLegacy = rawLegacy;\n\n\treturn {\n\t\tid: eventId,\n\t\ttype: \"mcp.event\",\n\t\tname: eventName,\n\t\tsource,\n\t\ttimestamp,\n\t\tcorrelation,\n\t\tproperties: mapProperties(input, eventName),\n\t\tmetadata: mappedMetadata,\n\t\trawLegacy,\n\t};\n}\n\nexport function createEventId(): string {\n\tif (\n\t\ttypeof crypto !== \"undefined\" &&\n\t\ttypeof crypto.randomUUID === \"function\"\n\t) {\n\t\treturn `evt_${crypto.randomUUID()}`;\n\t}\n\n\treturn `evt_${Math.random().toString(36).slice(2, 10)}_${Date.now().toString(36)}`;\n}\n\nfunction mapProperties(\n\tinput: TrackInput,\n\teventName: EventType,\n): Record<string, unknown> {\n\tif (!isLegacyTrackEvent(input)) {\n\t\treturn toRecord(input.properties);\n\t}\n\n\tconst legacyProperties = mapLegacyProperties(input, eventName);\n\tconst explicitProperties = toRecord(input.properties);\n\treturn {\n\t\t...legacyProperties,\n\t\t...explicitProperties,\n\t};\n}\n\nfunction mapLegacyProperties(\n\tinput: LegacyTrackEvent,\n\teventName: EventType,\n): Record<string, unknown> {\n\tswitch (eventName) {\n\t\tcase \"tool.called\": {\n\t\t\tconst properties: Record<string, unknown> = {};\n\t\t\tif (takeNonEmptyString(input.toolName)) properties.name = input.toolName;\n\t\t\tif (takeNonEmptyString(input.toolType)) properties.type = input.toolType;\n\t\t\treturn properties;\n\t\t}\n\t\tcase \"quote.succeeded\": {\n\t\t\tconst properties: Record<string, unknown> = {};\n\t\t\tif (typeof input.quoteAmount === \"number\") {\n\t\t\t\tproperties.amount = input.quoteAmount;\n\t\t\t}\n\t\t\tif (takeNonEmptyString(input.quoteCurrency)) {\n\t\t\t\tproperties.currency = input.quoteCurrency;\n\t\t\t}\n\t\t\treturn properties;\n\t\t}\n\t\tcase \"link.clicked\": {\n\t\t\tconst properties: Record<string, unknown> = {};\n\t\t\tif (takeNonEmptyString(input.linkUrl)) properties.url = input.linkUrl;\n\t\t\treturn properties;\n\t\t}\n\t\tcase \"purchase.completed\": {\n\t\t\tconst properties: Record<string, unknown> = {};\n\t\t\tif (typeof input.purchaseAmount === \"number\") {\n\t\t\t\tproperties.amount = input.purchaseAmount;\n\t\t\t}\n\t\t\tif (takeNonEmptyString(input.purchaseCurrency)) {\n\t\t\t\tproperties.currency = input.purchaseCurrency;\n\t\t\t}\n\t\t\treturn properties;\n\t\t}\n\t\tdefault:\n\t\t\treturn {};\n\t}\n}\n\nfunction resolveEventName(input: TrackInput): EventType {\n\tif (isLegacyTrackEvent(input)) return input.eventType;\n\treturn input.event;\n}\n\nfunction resolveCorrelationIds(\n\tinput: TrackInput,\n\tmeta: Record<string, unknown>,\n): V2CorrelationIds {\n\tconst requestId =\n\t\ttakeNonEmptyString(input.requestId) ??\n\t\tpickFirstString(meta, [\"openai/requestId\", \"requestId\", \"mcp/requestId\"]);\n\n\tconst sessionId =\n\t\ttakeNonEmptyString(input.sessionId) ??\n\t\tpickFirstString(meta, [\n\t\t\t\"openai/sessionId\",\n\t\t\t\"sessionId\",\n\t\t\t\"conversationId\",\n\t\t\t\"anthropic/sessionId\",\n\t\t]);\n\n\tconst traceId =\n\t\ttakeNonEmptyString(input.traceId) ??\n\t\tpickFirstString(meta, [\n\t\t\t\"openai/traceId\",\n\t\t\t\"traceId\",\n\t\t\t\"mcp/traceId\",\n\t\t\t\"openai/requestId\",\n\t\t\t\"requestId\",\n\t\t]);\n\n\tconst externalUserId =\n\t\ttakeNonEmptyString(input.externalUserId) ??\n\t\tpickFirstString(meta, [\n\t\t\t\"openai/userId\",\n\t\t\t\"externalUserId\",\n\t\t\t\"userId\",\n\t\t\t\"actorId\",\n\t\t]);\n\n\tconst correlationId =\n\t\ttakeNonEmptyString(input.correlationId) ??\n\t\tpickFirstString(meta, [\"correlationId\", \"openai/requestId\"]) ??\n\t\trequestId;\n\n\tconst correlation: V2CorrelationIds = {};\n\tif (sessionId) correlation.sessionId = sessionId;\n\tif (traceId) correlation.traceId = traceId;\n\tif (requestId) correlation.requestId = requestId;\n\tif (correlationId) correlation.correlationId = correlationId;\n\tif (externalUserId) correlation.externalUserId = externalUserId;\n\treturn correlation;\n}\n\nfunction normalizeTimestamp(\n\tinput: string | Date | undefined,\n\tnow: () => Date,\n): string {\n\tif (input instanceof Date) return input.toISOString();\n\tif (typeof input === \"string\") {\n\t\tconst date = new Date(input);\n\t\tif (!Number.isNaN(date.getTime())) return date.toISOString();\n\t}\n\treturn now().toISOString();\n}\n\nfunction pickFirstString(\n\trecord: Record<string, unknown>,\n\tkeys: readonly string[],\n): string | undefined {\n\tfor (const key of keys) {\n\t\tconst value = record[key];\n\t\tif (typeof value === \"string\" && value.trim().length > 0) {\n\t\t\treturn value;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> {\n\tif (!value || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn {};\n\t}\n\treturn value as Record<string, unknown>;\n}\n\nfunction takeNonEmptyString(value: unknown): string | undefined {\n\tif (typeof value !== \"string\") return undefined;\n\tif (value.trim().length === 0) return undefined;\n\treturn value;\n}\n\nfunction isLegacyTrackEvent(input: TrackInput): input is LegacyTrackEvent {\n\treturn \"eventType\" in input;\n}\n","import type {\n\tTrackingShutdownOptions,\n\tTrackingShutdownResult,\n} from \"./@types.js\";\nimport type {\n\tV2BatchRejectedEvent,\n\tV2BatchRequest,\n\tV2BatchResponse,\n\tV2EventEnvelope,\n} from \"./v2-types.js\";\n\nconst DEFAULT_ENDPOINT_PATH = \"/api/mcp/events/v2/batch\";\nconst DEFAULT_FLUSH_INTERVAL_MS = 1_000;\nconst DEFAULT_MAX_BATCH_SIZE = 20;\nconst DEFAULT_MAX_BUFFER_SIZE = 1_000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_RETRY_BASE_DELAY_MS = 200;\nconst DEFAULT_RETRY_MAX_DELAY_MS = 2_000;\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 2_000;\nconst SDK_NAME = \"@waniwani/sdk\";\n\nconst AUTH_FAILURE_STATUS = new Set([401, 403]);\nconst RETRYABLE_STATUS = new Set([408, 425, 429, 500, 502, 503, 504]);\n\ninterface Logger {\n\twarn: (message: string, ...args: unknown[]) => void;\n\terror: (message: string, ...args: unknown[]) => void;\n}\n\nexport interface V2TransportOptions {\n\tbaseUrl: string;\n\tapiKey: string;\n\tendpointPath?: string;\n\tflushIntervalMs?: number;\n\tmaxBatchSize?: number;\n\tmaxBufferSize?: number;\n\tmaxRetries?: number;\n\tretryBaseDelayMs?: number;\n\tretryMaxDelayMs?: number;\n\tshutdownTimeoutMs?: number;\n\tsdkVersion?: string;\n\tfetchFn?: typeof fetch;\n\tlogger?: Logger;\n\tnow?: () => Date;\n\tsleep?: (delayMs: number) => Promise<void>;\n}\n\nexport interface V2BatchTransport {\n\tenqueue: (event: V2EventEnvelope) => void;\n\tflush: () => Promise<void>;\n\tshutdown: (\n\t\toptions?: TrackingShutdownOptions,\n\t) => Promise<TrackingShutdownResult>;\n\tpendingEvents: () => number;\n}\n\ntype SendBatchResult =\n\t| { kind: \"success\" }\n\t| { kind: \"retryable\"; reason: string }\n\t| { kind: \"permanent\"; reason: string }\n\t| { kind: \"auth\"; status: number }\n\t| {\n\t\t\tkind: \"partial\";\n\t\t\tretryable: V2EventEnvelope[];\n\t\t\tpermanent: V2EventEnvelope[];\n\t };\n\nexport function createV2BatchTransport(\n\toptions: V2TransportOptions,\n): V2BatchTransport {\n\treturn new BatchingV2Transport(options);\n}\n\nclass BatchingV2Transport implements V2BatchTransport {\n\tprivate readonly endpointUrl: string;\n\tprivate readonly flushIntervalMs: number;\n\tprivate readonly maxBatchSize: number;\n\tprivate readonly maxBufferSize: number;\n\tprivate readonly maxRetries: number;\n\tprivate readonly retryBaseDelayMs: number;\n\tprivate readonly retryMaxDelayMs: number;\n\tprivate readonly shutdownTimeoutMs: number;\n\tprivate readonly sdkVersion?: string;\n\tprivate readonly fetchFn: typeof fetch;\n\tprivate readonly logger: Logger;\n\tprivate readonly now: () => Date;\n\tprivate readonly sleep: (delayMs: number) => Promise<void>;\n\tprivate readonly apiKey: string;\n\n\tprivate readonly buffer: V2EventEnvelope[] = [];\n\tprivate flushTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate flushScheduled = false;\n\tprivate flushScheduledTimer: ReturnType<typeof setTimeout> | undefined;\n\tprivate flushInFlight: Promise<void> | undefined;\n\tprivate inFlightCount = 0;\n\tprivate isStopped = false;\n\tprivate isShuttingDown = false;\n\n\tconstructor(options: V2TransportOptions) {\n\t\tthis.endpointUrl = joinUrl(\n\t\t\toptions.baseUrl,\n\t\t\toptions.endpointPath ?? DEFAULT_ENDPOINT_PATH,\n\t\t);\n\t\tthis.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n\t\tthis.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;\n\t\tthis.maxBufferSize = options.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;\n\t\tthis.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n\t\tthis.retryBaseDelayMs =\n\t\t\toptions.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS;\n\t\tthis.retryMaxDelayMs =\n\t\t\toptions.retryMaxDelayMs ?? DEFAULT_RETRY_MAX_DELAY_MS;\n\t\tthis.shutdownTimeoutMs =\n\t\t\toptions.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS;\n\t\tthis.fetchFn = options.fetchFn ?? fetch;\n\t\tthis.logger = options.logger ?? console;\n\t\tthis.now = options.now ?? (() => new Date());\n\t\tthis.sleep =\n\t\t\toptions.sleep ??\n\t\t\t((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));\n\t\tthis.apiKey = options.apiKey;\n\t\tthis.sdkVersion = options.sdkVersion;\n\n\t\tif (this.flushIntervalMs > 0) {\n\t\t\tthis.flushTimer = setInterval(() => {\n\t\t\t\tvoid this.flush();\n\t\t\t}, this.flushIntervalMs);\n\t\t}\n\t}\n\n\tenqueue(event: V2EventEnvelope): void {\n\t\tif (this.isStopped || this.isShuttingDown) {\n\t\t\tthis.logger.warn(\n\t\t\t\t\"[WaniWani] Tracking transport is stopped, dropping event %s\",\n\t\t\t\tevent.id,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.buffer.length >= this.maxBufferSize) {\n\t\t\tconst dropCount = this.buffer.length - this.maxBufferSize + 1;\n\t\t\tthis.buffer.splice(0, dropCount);\n\t\t\tthis.logger.warn(\n\t\t\t\t\"[WaniWani] Tracking buffer overflow, dropped %d oldest event(s)\",\n\t\t\t\tdropCount,\n\t\t\t);\n\t\t}\n\n\t\tthis.buffer.push(event);\n\n\t\tif (this.buffer.length >= this.maxBatchSize) {\n\t\t\tvoid this.flush();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.scheduleMicroFlush();\n\t}\n\n\tpendingEvents(): number {\n\t\treturn this.buffer.length + this.inFlightCount;\n\t}\n\n\tasync flush(): Promise<void> {\n\t\tif (this.flushInFlight) return this.flushInFlight;\n\t\tthis.flushInFlight = this.flushLoop().finally(() => {\n\t\t\tthis.flushInFlight = undefined;\n\t\t});\n\t\treturn this.flushInFlight;\n\t}\n\n\tasync shutdown(\n\t\toptions?: TrackingShutdownOptions,\n\t): Promise<TrackingShutdownResult> {\n\t\tthis.isShuttingDown = true;\n\t\tif (this.flushTimer) {\n\t\t\tclearInterval(this.flushTimer);\n\t\t\tthis.flushTimer = undefined;\n\t\t}\n\t\tif (this.flushScheduledTimer) {\n\t\t\tclearTimeout(this.flushScheduledTimer);\n\t\t\tthis.flushScheduledTimer = undefined;\n\t\t\tthis.flushScheduled = false;\n\t\t}\n\n\t\tconst timeoutMs = options?.timeoutMs ?? this.shutdownTimeoutMs;\n\t\tconst flushPromise = this.flush();\n\n\t\tif (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n\t\t\tawait flushPromise;\n\t\t\tthis.isStopped = true;\n\t\t\treturn { timedOut: false, pendingEvents: this.pendingEvents() };\n\t\t}\n\n\t\tconst timeoutSignal = Symbol(\"shutdown-timeout\");\n\t\tconst result = await Promise.race([\n\t\t\tflushPromise.then(() => \"flushed\" as const),\n\t\t\tthis.sleep(timeoutMs).then(() => timeoutSignal),\n\t\t]);\n\n\t\tif (result === timeoutSignal) {\n\t\t\tthis.isStopped = true;\n\t\t\treturn { timedOut: true, pendingEvents: this.pendingEvents() };\n\t\t}\n\n\t\tthis.isStopped = true;\n\t\treturn { timedOut: false, pendingEvents: this.pendingEvents() };\n\t}\n\n\tprivate scheduleMicroFlush(): void {\n\t\tif (this.flushScheduled) return;\n\t\tthis.flushScheduled = true;\n\t\tthis.flushScheduledTimer = setTimeout(() => {\n\t\t\tthis.flushScheduledTimer = undefined;\n\t\t\tthis.flushScheduled = false;\n\t\t\tvoid this.flush();\n\t\t}, 0);\n\t}\n\n\tprivate async flushLoop(): Promise<void> {\n\t\twhile (this.buffer.length > 0 && !this.isStopped) {\n\t\t\tconst batch = this.buffer.splice(0, this.maxBatchSize);\n\t\t\tawait this.sendBatchWithRetry(batch);\n\t\t}\n\t}\n\n\tprivate async sendBatchWithRetry(batch: V2EventEnvelope[]): Promise<void> {\n\t\tlet attempt = 0;\n\t\tlet pendingBatch = batch;\n\n\t\twhile (pendingBatch.length > 0 && !this.isStopped) {\n\t\t\tthis.inFlightCount = pendingBatch.length;\n\t\t\tconst result = await this.sendBatchOnce(pendingBatch);\n\t\t\tthis.inFlightCount = 0;\n\n\t\t\tswitch (result.kind) {\n\t\t\t\tcase \"success\":\n\t\t\t\t\treturn;\n\t\t\t\tcase \"auth\":\n\t\t\t\t\tthis.stopTransportForAuthFailure(result.status, pendingBatch.length);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"permanent\":\n\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\"[WaniWani] Dropping %d event(s) after permanent failure: %s\",\n\t\t\t\t\t\tpendingBatch.length,\n\t\t\t\t\t\tresult.reason,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\tcase \"retryable\":\n\t\t\t\t\tif (attempt >= this.maxRetries) {\n\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\"[WaniWani] Dropping %d event(s) after retry exhaustion: %s\",\n\t\t\t\t\t\t\tpendingBatch.length,\n\t\t\t\t\t\t\tresult.reason,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tawait this.sleep(this.backoffDelayMs(attempt));\n\t\t\t\t\tattempt += 1;\n\t\t\t\t\tcontinue;\n\t\t\t\tcase \"partial\":\n\t\t\t\t\tif (result.permanent.length > 0) {\n\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\"[WaniWani] Dropping %d event(s) rejected as permanent\",\n\t\t\t\t\t\t\tresult.permanent.length,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (result.retryable.length === 0) return;\n\t\t\t\t\tif (attempt >= this.maxRetries) {\n\t\t\t\t\t\tthis.logger.error(\n\t\t\t\t\t\t\t\"[WaniWani] Dropping %d retryable event(s) after retry exhaustion\",\n\t\t\t\t\t\t\tresult.retryable.length,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tpendingBatch = result.retryable;\n\t\t\t\t\tawait this.sleep(this.backoffDelayMs(attempt));\n\t\t\t\t\tattempt += 1;\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async sendBatchOnce(\n\t\tevents: V2EventEnvelope[],\n\t): Promise<SendBatchResult> {\n\t\tlet response: Response;\n\n\t\ttry {\n\t\t\tresponse = await this.fetchFn(this.endpointUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.apiKey}`,\n\t\t\t\t\t\"X-WaniWani-SDK\": SDK_NAME,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(this.makeBatchRequest(events)),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tkind: \"retryable\",\n\t\t\t\treason: getErrorMessage(error),\n\t\t\t};\n\t\t}\n\n\t\tif (AUTH_FAILURE_STATUS.has(response.status)) {\n\t\t\treturn { kind: \"auth\", status: response.status };\n\t\t}\n\n\t\tif (RETRYABLE_STATUS.has(response.status)) {\n\t\t\treturn {\n\t\t\t\tkind: \"retryable\",\n\t\t\t\treason: `HTTP ${response.status}`,\n\t\t\t};\n\t\t}\n\n\t\tif (!response.ok) {\n\t\t\treturn {\n\t\t\t\tkind: \"permanent\",\n\t\t\t\treason: `HTTP ${response.status}`,\n\t\t\t};\n\t\t}\n\n\t\tconst data = await parseJsonResponse<V2BatchResponse>(response);\n\t\tif (!data?.rejected || data.rejected.length === 0) {\n\t\t\treturn { kind: \"success\" };\n\t\t}\n\n\t\tconst partial = this.classifyRejectedEvents(events, data.rejected);\n\t\tif (partial.retryable.length === 0 && partial.permanent.length === 0) {\n\t\t\treturn { kind: \"success\" };\n\t\t}\n\n\t\treturn {\n\t\t\tkind: \"partial\",\n\t\t\tretryable: partial.retryable,\n\t\t\tpermanent: partial.permanent,\n\t\t};\n\t}\n\n\tprivate makeBatchRequest(events: V2EventEnvelope[]): V2BatchRequest {\n\t\treturn {\n\t\t\tsentAt: this.now().toISOString(),\n\t\t\tsource: {\n\t\t\t\tsdk: SDK_NAME,\n\t\t\t\tversion: this.sdkVersion ?? \"0.0.0\",\n\t\t\t},\n\t\t\tevents,\n\t\t};\n\t}\n\n\tprivate classifyRejectedEvents(\n\t\tevents: V2EventEnvelope[],\n\t\trejected: V2BatchRejectedEvent[],\n\t): {\n\t\tretryable: V2EventEnvelope[];\n\t\tpermanent: V2EventEnvelope[];\n\t} {\n\t\tconst byId = new Map(events.map((event) => [event.id, event]));\n\t\tconst retryable: V2EventEnvelope[] = [];\n\t\tconst permanent: V2EventEnvelope[] = [];\n\n\t\tfor (const rejectedEvent of rejected) {\n\t\t\tconst event = byId.get(rejectedEvent.eventId);\n\t\t\tif (!event) continue;\n\t\t\tif (isRetryableRejectedEvent(rejectedEvent)) {\n\t\t\t\tretryable.push(event);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tpermanent.push(event);\n\t\t}\n\n\t\treturn { retryable, permanent };\n\t}\n\n\tprivate backoffDelayMs(attempt: number): number {\n\t\tconst rawDelay = this.retryBaseDelayMs * 2 ** attempt;\n\t\treturn Math.min(rawDelay, this.retryMaxDelayMs);\n\t}\n\n\tprivate stopTransportForAuthFailure(\n\t\tstatus: number,\n\t\trejectedCount: number,\n\t): void {\n\t\tthis.isStopped = true;\n\t\tconst buffered = this.buffer.length;\n\t\tthis.buffer.splice(0, buffered);\n\t\tthis.logger.error(\n\t\t\t\"[WaniWani] Auth failure (HTTP %d). Stopping tracking transport and dropping %d queued event(s)\",\n\t\t\tstatus,\n\t\t\trejectedCount + buffered,\n\t\t);\n\t}\n}\n\nfunction isRetryableRejectedEvent(\n\trejectedEvent: V2BatchRejectedEvent,\n): boolean {\n\tif (rejectedEvent.retryable === true) return true;\n\tconst code = rejectedEvent.code.toLowerCase();\n\treturn (\n\t\tcode.includes(\"timeout\") ||\n\t\tcode.includes(\"temporary\") ||\n\t\tcode.includes(\"unavailable\") ||\n\t\tcode.includes(\"rate_limit\") ||\n\t\tcode.includes(\"transient\") ||\n\t\tcode.includes(\"server\")\n\t);\n}\n\nasync function parseJsonResponse<T>(\n\tresponse: Response,\n): Promise<T | undefined> {\n\tconst body = await response.text();\n\tif (!body) return undefined;\n\ttry {\n\t\treturn JSON.parse(body) as T;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction joinUrl(baseUrl: string, endpointPath: string): string {\n\tconst normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;\n\tconst normalizedPath = endpointPath.startsWith(\"/\")\n\t\t? endpointPath.slice(1)\n\t\t: endpointPath;\n\treturn `${normalizedBase}${normalizedPath}`;\n}\n\nfunction getErrorMessage(error: unknown): string {\n\tif (error instanceof Error) return error.message;\n\treturn String(error);\n}\n","// Tracking Module\n\nimport type { InternalConfig } from \"../types.js\";\nimport type {\n\tTrackInput,\n\tTrackingClient,\n\tTrackingShutdownOptions,\n} from \"./@types.js\";\nimport { mapTrackEventToV2 } from \"./mapper.js\";\nimport { createV2BatchTransport } from \"./transport.js\";\n\n// Re-export types\nexport type {\n\tEventType,\n\tLegacyTrackEvent,\n\tLinkClickedProperties,\n\tPurchaseCompletedProperties,\n\tQuoteSucceededProperties,\n\tToolCalledProperties,\n\tTrackEvent,\n\tTrackInput,\n\tTrackingClient,\n\tTrackingConfig,\n\tTrackingShutdownOptions,\n\tTrackingShutdownResult,\n} from \"./@types.js\";\nexport { createEventId, mapTrackEventToV2 } from \"./mapper.js\";\nexport type {\n\tV2BatchRejectedEvent,\n\tV2BatchRequest,\n\tV2BatchResponse,\n\tV2CorrelationIds,\n\tV2EnvelopeType,\n\tV2EventEnvelope,\n} from \"./v2-types.js\";\n\nexport function createTrackingClient(config: InternalConfig): TrackingClient {\n\tconst { baseUrl, apiKey, tracking } = config;\n\n\tfunction requireApiKey(): string {\n\t\tif (!apiKey) {\n\t\t\tthrow new Error(\"WANIWANI_API_KEY is not set\");\n\t\t}\n\t\treturn apiKey;\n\t}\n\n\tconst transport = apiKey\n\t\t? createV2BatchTransport({\n\t\t\t\tbaseUrl,\n\t\t\t\tapiKey,\n\t\t\t\tendpointPath: tracking.endpointPath,\n\t\t\t\tflushIntervalMs: tracking.flushIntervalMs,\n\t\t\t\tmaxBatchSize: tracking.maxBatchSize,\n\t\t\t\tmaxBufferSize: tracking.maxBufferSize,\n\t\t\t\tmaxRetries: tracking.maxRetries,\n\t\t\t\tretryBaseDelayMs: tracking.retryBaseDelayMs,\n\t\t\t\tretryMaxDelayMs: tracking.retryMaxDelayMs,\n\t\t\t\tshutdownTimeoutMs: tracking.shutdownTimeoutMs,\n\t\t\t})\n\t\t: undefined;\n\n\tconst client: TrackingClient = {\n\t\tasync track(event: TrackInput): Promise<{ eventId: string }> {\n\t\t\trequireApiKey();\n\t\t\tconst mappedEvent = mapTrackEventToV2(event);\n\t\t\ttransport?.enqueue(mappedEvent);\n\t\t\treturn { eventId: mappedEvent.id };\n\t\t},\n\t\tasync flush(): Promise<void> {\n\t\t\trequireApiKey();\n\t\t\tawait transport?.flush();\n\t\t},\n\t\tasync shutdown(options?: TrackingShutdownOptions) {\n\t\t\trequireApiKey();\n\t\t\treturn (\n\t\t\t\t(await transport?.shutdown({\n\t\t\t\t\ttimeoutMs: options?.timeoutMs ?? tracking.shutdownTimeoutMs,\n\t\t\t\t})) ?? { timedOut: false, pendingEvents: 0 }\n\t\t\t);\n\t\t},\n\t};\n\n\tif (transport) {\n\t\tattachShutdownHooks(client, tracking.shutdownTimeoutMs);\n\t}\n\treturn client;\n}\n\nfunction attachShutdownHooks(\n\tclient: TrackingClient,\n\tdefaultTimeoutMs: number,\n): void {\n\tif (\n\t\ttypeof process === \"undefined\" ||\n\t\ttypeof process.once !== \"function\" ||\n\t\ttypeof process.on !== \"function\"\n\t) {\n\t\treturn;\n\t}\n\n\tconst shutdown = () => {\n\t\tvoid client.shutdown({ timeoutMs: defaultTimeoutMs });\n\t};\n\n\tprocess.once(\"beforeExit\", shutdown);\n\tprocess.once(\"SIGINT\", shutdown);\n\tprocess.once(\"SIGTERM\", shutdown);\n}\n","// WaniWani SDK - Main Entry\n\nimport { createTrackingClient } from \"./tracking/index.js\";\nimport type { WaniWaniClient, WaniWaniConfig } from \"./types.js\";\n\n/**\n * Create a WaniWani SDK client\n *\n * @param config - Configuration options\n * @returns A fully typed WaniWani client\n *\n * @example\n * ```typescript\n * import { waniwani } from \"@waniwani/sdk\";\n * import { toNextJsHandler } from \"@waniwani/sdk/next-js\";\n *\n * const wani = waniwani({ apiKey: \"...\" });\n *\n * // Next.js route handler\n * export const { GET, POST } = toNextJsHandler(wani, {\n * chat: { systemPrompt: \"You are a helpful assistant.\" },\n * });\n * ```\n */\nexport function waniwani(config?: WaniWaniConfig): WaniWaniClient {\n\tconst baseUrl = config?.baseUrl ?? \"https://app.waniwani.ai\";\n\tconst apiKey = config?.apiKey ?? process.env.WANIWANI_API_KEY;\n\tconst trackingConfig = {\n\t\tendpointPath: config?.tracking?.endpointPath ?? \"/api/mcp/events/v2/batch\",\n\t\tflushIntervalMs: config?.tracking?.flushIntervalMs ?? 1_000,\n\t\tmaxBatchSize: config?.tracking?.maxBatchSize ?? 20,\n\t\tmaxBufferSize: config?.tracking?.maxBufferSize ?? 1_000,\n\t\tmaxRetries: config?.tracking?.maxRetries ?? 3,\n\t\tretryBaseDelayMs: config?.tracking?.retryBaseDelayMs ?? 200,\n\t\tretryMaxDelayMs: config?.tracking?.retryMaxDelayMs ?? 2_000,\n\t\tshutdownTimeoutMs: config?.tracking?.shutdownTimeoutMs ?? 2_000,\n\t};\n\n\tconst internalConfig = { baseUrl, apiKey, tracking: trackingConfig };\n\n\t// Compose client from modules\n\tconst trackingClient = createTrackingClient(internalConfig);\n\n\treturn {\n\t\t...trackingClient,\n\t\t_config: internalConfig,\n\t};\n}\n","/**\n * Server-side API route handler for widget tracking events.\n *\n * Receives batched events from the `useWaniwani` React hook and forwards them\n * to the WaniWani backend using the server-side SDK.\n *\n * @example Next.js App Router\n * ```typescript\n * // app/api/waniwani/track/route.ts\n * import { createTrackingRoute } from \"@waniwani/sdk/mcp\";\n *\n * const handler = createTrackingRoute({\n * apiKey: process.env.WANIWANI_API_KEY,\n * baseUrl: process.env.WANIWANI_BASE_URL,\n * });\n *\n * export { handler as POST };\n * ```\n */\n\nimport type { EventType, TrackInput } from \"../../tracking/@types.js\";\nimport type { WaniWaniConfig } from \"../../types.js\";\nimport { waniwani } from \"../../waniwani.js\";\n\nexport interface TrackingRouteOptions {\n\t/** API key for the WaniWani backend. Defaults to WANIWANI_API_KEY env var. */\n\tapiKey?: string;\n\t/** Base URL for the WaniWani backend. Defaults to https://app.waniwani.ai. */\n\tbaseUrl?: string;\n}\n\n/** Shape of a single event from the WidgetTransport client. */\ninterface WidgetEventPayload {\n\tevent_id?: string;\n\tevent_type?: string;\n\ttimestamp?: string;\n\tsource?: string;\n\tsession_id?: string;\n\ttrace_id?: string;\n\tuser_id?: string;\n\tevent_name?: string;\n\tmetadata?: Record<string, unknown>;\n\t[key: string]: unknown;\n}\n\n/** Batch payload sent by WidgetTransport. */\ninterface BatchPayload {\n\tevents: WidgetEventPayload[];\n\tsentAt?: string;\n}\n\n/**\n * Map a WidgetEvent from the client to the SDK's TrackInput format.\n */\nfunction mapWidgetEvent(ev: WidgetEventPayload): TrackInput {\n\tconst eventType = ev.event_type ?? \"widget_click\";\n\n\t// For manual tracking methods (track, identify, step, conversion),\n\t// use \"widget_<type>\" as the event name. Auto-capture events already\n\t// have the \"widget_\" prefix.\n\tconst isAutoCapture = eventType.startsWith(\"widget_\");\n\tconst eventName: EventType = (\n\t\tisAutoCapture ? eventType : `widget_${eventType}`\n\t) as EventType;\n\n\t// Merge metadata + any extra properties from the event\n\tconst properties: Record<string, unknown> = {\n\t\t...(ev.metadata ?? {}),\n\t};\n\tif (ev.event_name) properties.event_name = ev.event_name;\n\n\treturn {\n\t\tevent: eventName,\n\t\tproperties,\n\t\tsessionId: ev.session_id,\n\t\ttraceId: ev.trace_id,\n\t\texternalUserId: ev.user_id,\n\t\teventId: ev.event_id,\n\t\ttimestamp: ev.timestamp,\n\t\tsource: ev.source ?? \"widget\",\n\t} as TrackInput;\n}\n\n/**\n * Creates a POST handler that receives tracking events from `useWaniwani`\n * and forwards them to the WaniWani backend.\n */\nexport function createTrackingRoute(options?: TrackingRouteOptions) {\n\tconst config: WaniWaniConfig = {\n\t\tapiKey: options?.apiKey,\n\t\tbaseUrl: options?.baseUrl,\n\t};\n\n\t// Lazy singleton — created on first request\n\tlet client: ReturnType<typeof waniwani> | undefined;\n\n\tfunction getClient() {\n\t\tif (!client) {\n\t\t\tclient = waniwani(config);\n\t\t}\n\t\treturn client;\n\t}\n\n\treturn async function handler(request: Request): Promise<Response> {\n\t\tlet body: BatchPayload;\n\t\ttry {\n\t\t\tbody = (await request.json()) as BatchPayload;\n\t\t} catch {\n\t\t\treturn new Response(JSON.stringify({ error: \"Invalid JSON\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\tif (!Array.isArray(body.events) || body.events.length === 0) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: \"Missing or empty events array\" }),\n\t\t\t\t{\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst c = getClient();\n\t\t\tconst results: string[] = [];\n\n\t\t\tfor (const ev of body.events) {\n\t\t\t\tconst trackInput = mapWidgetEvent(ev);\n\t\t\t\tconst result = await c.track(trackInput);\n\t\t\t\tresults.push(result.eventId);\n\t\t\t}\n\n\t\t\tawait c.flush();\n\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ ok: true, accepted: results.length }),\n\t\t\t\t{\n\t\t\t\t\tstatus: 200,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t},\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\t\treturn new Response(JSON.stringify({ error: message }), {\n\t\t\t\tstatus: 500,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\t};\n}\n","/**\n * Widget token minting — fetches short-lived JWTs from the WaniWani backend\n * so browser widgets can POST events directly.\n */\n\ninterface WidgetTokenConfig {\n\tbaseUrl: string;\n\tapiKey: string;\n}\n\ninterface WidgetTokenResult {\n\ttoken: string;\n\texpiresAt: string;\n}\n\ninterface CachedToken {\n\ttoken: string;\n\t/** Unix ms when the token expires */\n\texpiresAt: number;\n}\n\n/** Re-mint when < 2 minutes remain to avoid using nearly-expired tokens. */\nconst EXPIRY_BUFFER_MS = 2 * 60 * 1000;\n\nexport class WidgetTokenCache {\n\tprivate cached: CachedToken | null = null;\n\tprivate pending: Promise<string | null> | null = null;\n\tprivate readonly config: WidgetTokenConfig;\n\n\tconstructor(config: WidgetTokenConfig) {\n\t\tthis.config = config;\n\t}\n\n\t/**\n\t * Get a valid widget token. Returns a cached token if still fresh,\n\t * otherwise mints a new one. Returns `null` on failure.\n\t */\n\tasync getToken(sessionId?: string, traceId?: string): Promise<string | null> {\n\t\tif (this.cached && Date.now() < this.cached.expiresAt - EXPIRY_BUFFER_MS) {\n\t\t\treturn this.cached.token;\n\t\t}\n\n\t\t// Deduplicate concurrent requests\n\t\tif (this.pending) return this.pending;\n\n\t\tthis.pending = this.mint(sessionId, traceId).finally(() => {\n\t\t\tthis.pending = null;\n\t\t});\n\n\t\treturn this.pending;\n\t}\n\n\tprivate async mint(\n\t\tsessionId?: string,\n\t\ttraceId?: string,\n\t): Promise<string | null> {\n\t\tconst url = joinUrl(this.config.baseUrl, \"/api/mcp/widget-tokens\");\n\n\t\tconst body: Record<string, string> = {};\n\t\tif (sessionId) body.sessionId = sessionId;\n\t\tif (traceId) body.traceId = traceId;\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\tAuthorization: `Bearer ${this.config.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(body),\n\t\t\t});\n\n\t\t\tif (!response.ok) return null;\n\n\t\t\tconst json = (await response.json()) as Record<string, unknown>;\n\n\t\t\t// Support both flat { token, expiresAt } and nested { data: { token, expiresAt } }\n\t\t\tconst result = (\n\t\t\t\tjson.data && typeof json.data === \"object\" ? json.data : json\n\t\t\t) as WidgetTokenResult;\n\n\t\t\tconst expiresAtMs = new Date(result.expiresAt).getTime();\n\t\t\tif (!result.token || Number.isNaN(expiresAtMs)) return null;\n\n\t\t\tthis.cached = {\n\t\t\t\ttoken: result.token,\n\t\t\t\texpiresAt: expiresAtMs,\n\t\t\t};\n\n\t\t\treturn result.token;\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n\nfunction joinUrl(baseUrl: string, path: string): string {\n\tconst base = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n\treturn `${base}${path}`;\n}\n","import type { ToolCalledProperties, TrackInput } from \"../../tracking/index.js\";\nimport type { WaniWaniClient, WaniWaniConfig } from \"../../types.js\";\nimport { waniwani } from \"../../waniwani.js\";\nimport type { McpServer } from \"./tools/types\";\nimport { WidgetTokenCache } from \"./widget-token.js\";\n\ntype WaniwaniTracker = Pick<WaniWaniClient, \"flush\" | \"track\" | \"_config\">;\ntype UnknownRecord = Record<string, unknown>;\n\ntype WrappedServer = McpServer & {\n\t__waniwaniWrapped?: true;\n};\n\n/**\n * Options for withWaniwani().\n */\nexport type WithWaniwaniOptions = {\n\t/**\n\t * Optional pre-built WaniWani client.\n\t * When omitted, a new client is created from `config`.\n\t */\n\tclient?: WaniwaniTracker;\n\t/**\n\t * WaniWani client config used when `client` is omitted.\n\t */\n\tconfig?: WaniWaniConfig;\n\t/**\n\t * Optional explicit tool type. Defaults to `\"other\"`.\n\t */\n\ttoolType?:\n\t\t| ToolCalledProperties[\"type\"]\n\t\t| ((toolName: string) => ToolCalledProperties[\"type\"] | undefined);\n\t/**\n\t * Optional metadata merged into every tracked event.\n\t */\n\tmetadata?: UnknownRecord;\n\t/**\n\t * Flush tracking transport after each tool call.\n\t */\n\tflushAfterToolCall?: boolean;\n\t/**\n\t * Optional error callback for non-fatal tracking errors.\n\t */\n\tonError?: (error: Error) => void;\n\t/**\n\t * Inject widget tracking config into tool response `_meta.waniwani` so browser\n\t * widgets can send events directly to the WaniWani backend.\n\t *\n\t * Always injects `endpoint`. Injects `token` when an API key is configured\n\t * and token minting succeeds.\n\t *\n\t * @default true\n\t */\n\tinjectWidgetToken?: boolean;\n};\n\nconst DEFAULT_BASE_URL = \"https://app.waniwani.ai\";\n\n/**\n * Wrap an MCP server so tool handlers automatically emit `tool.called` events.\n *\n * The wrapper intercepts `server.registerTool(...)`, tracks each invocation,\n * then forwards execution to the original tool handler.\n *\n * When `injectWidgetToken` is enabled (default), tracking config is injected\n * into tool response `_meta.waniwani` so browser widgets can post events\n * directly to the WaniWani backend without a server-side proxy.\n */\nexport function withWaniwani(\n\tserver: McpServer,\n\toptions: WithWaniwaniOptions = {},\n): McpServer {\n\tconst wrappedServer = server as WrappedServer;\n\tif (wrappedServer.__waniwaniWrapped) {\n\t\treturn wrappedServer;\n\t}\n\n\twrappedServer.__waniwaniWrapped = true;\n\n\tconst tracker = options.client ?? waniwani(options.config);\n\tconst injectToken = options.injectWidgetToken !== false;\n\n\t// Lazy-init token cache — only created if we have an API key\n\tlet tokenCache: WidgetTokenCache | null = null;\n\n\tfunction getTokenCache(): WidgetTokenCache | null {\n\t\tif (tokenCache) return tokenCache;\n\t\tconst apiKey = tracker._config.apiKey;\n\t\tif (!apiKey) return null;\n\t\ttokenCache = new WidgetTokenCache({\n\t\t\tbaseUrl: tracker._config.baseUrl ?? DEFAULT_BASE_URL,\n\t\t\tapiKey,\n\t\t});\n\t\treturn tokenCache;\n\t}\n\n\tconst originalRegisterTool = server.registerTool.bind(server) as (\n\t\t...args: unknown[]\n\t) => unknown;\n\n\twrappedServer.registerTool = ((...args: unknown[]) => {\n\t\tconst [toolNameRaw, config, handlerRaw] = args;\n\t\tconst toolName =\n\t\t\ttypeof toolNameRaw === \"string\" && toolNameRaw.trim().length > 0\n\t\t\t\t? toolNameRaw\n\t\t\t\t: \"unknown\";\n\n\t\tif (typeof handlerRaw !== \"function\") {\n\t\t\treturn originalRegisterTool(...args);\n\t\t}\n\n\t\tconst handler = handlerRaw as (\n\t\t\tinput: unknown,\n\t\t\textra: unknown,\n\t\t) => Promise<unknown> | unknown;\n\n\t\tconst wrappedHandler = async (input: unknown, extra: unknown) => {\n\t\t\tconst startTime = performance.now();\n\t\t\ttry {\n\t\t\t\tconst result = await handler(input, extra);\n\t\t\t\tconst durationMs = Math.round(performance.now() - startTime);\n\n\t\t\t\tawait safeTrack(\n\t\t\t\t\ttracker,\n\t\t\t\t\tbuildTrackInput(toolName, extra, options, {\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tstatus: \"ok\",\n\t\t\t\t\t}),\n\t\t\t\t\toptions.onError,\n\t\t\t\t);\n\n\t\t\t\tif (options.flushAfterToolCall) {\n\t\t\t\t\tawait safeFlush(tracker, options.onError);\n\t\t\t\t}\n\n\t\t\t\tif (injectToken) {\n\t\t\t\t\tawait injectWidgetConfig(\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\tgetTokenCache(),\n\t\t\t\t\t\ttracker._config.baseUrl ?? DEFAULT_BASE_URL,\n\t\t\t\t\t\toptions.onError,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tconst durationMs = Math.round(performance.now() - startTime);\n\n\t\t\t\tawait safeTrack(\n\t\t\t\t\ttracker,\n\t\t\t\t\tbuildTrackInput(toolName, extra, options, {\n\t\t\t\t\t\tdurationMs,\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terrorMessage:\n\t\t\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\t}),\n\t\t\t\t\toptions.onError,\n\t\t\t\t);\n\n\t\t\t\tif (options.flushAfterToolCall) {\n\t\t\t\t\tawait safeFlush(tracker, options.onError);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t};\n\n\t\treturn originalRegisterTool(toolNameRaw, config, wrappedHandler);\n\t}) as McpServer[\"registerTool\"];\n\n\treturn wrappedServer;\n}\n\nasync function injectWidgetConfig(\n\tresult: unknown,\n\tcache: WidgetTokenCache | null,\n\tbaseUrl: string,\n\tonError?: (error: Error) => void,\n): Promise<void> {\n\tif (!isRecord(result)) return;\n\n\tif (!isRecord(result._meta)) {\n\t\t(result as UnknownRecord)._meta = {};\n\t}\n\n\tconst meta = (result as UnknownRecord)._meta as UnknownRecord;\n\tconst waniwaniConfig: UnknownRecord = {\n\t\tendpoint: `${baseUrl.replace(/\\/$/, \"\")}/api/mcp/events/v2/batch`,\n\t};\n\n\tif (cache) {\n\t\ttry {\n\t\t\tconst token = await cache.getToken();\n\t\t\tif (token) {\n\t\t\t\twaniwaniConfig.token = token;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tonError?.(toError(error));\n\t\t}\n\t}\n\n\tmeta.waniwani = waniwaniConfig;\n}\n\nfunction buildTrackInput(\n\ttoolName: string,\n\textra: unknown,\n\toptions: WithWaniwaniOptions,\n\ttiming?: { durationMs: number; status: string; errorMessage?: string },\n): TrackInput {\n\tconst toolType = resolveToolType(toolName, options.toolType);\n\tconst meta = extractMeta(extra);\n\n\treturn {\n\t\tevent: \"tool.called\",\n\t\tproperties: {\n\t\t\tname: toolName,\n\t\t\ttype: toolType,\n\t\t\t...(timing ?? {}),\n\t\t},\n\t\tmeta,\n\t\tmetadata: {\n\t\t\tsource: \"withWaniwani\",\n\t\t\t...(options.metadata ?? {}),\n\t\t},\n\t};\n}\n\nfunction resolveToolType(\n\ttoolName: string,\n\ttoolTypeOption: WithWaniwaniOptions[\"toolType\"],\n): ToolCalledProperties[\"type\"] {\n\tif (typeof toolTypeOption === \"function\") {\n\t\treturn toolTypeOption(toolName) ?? \"other\";\n\t}\n\treturn toolTypeOption ?? \"other\";\n}\n\nfunction extractMeta(extra: unknown): UnknownRecord | undefined {\n\tif (!isRecord(extra)) return undefined;\n\n\tconst meta = extra._meta;\n\tif (!isRecord(meta)) return undefined;\n\n\treturn meta;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n\treturn Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nasync function safeTrack(\n\ttracker: Pick<WaniWaniClient, \"track\">,\n\tinput: TrackInput,\n\tonError?: (error: Error) => void,\n): Promise<void> {\n\ttry {\n\t\tawait tracker.track(input);\n\t} catch (error) {\n\t\tonError?.(toError(error));\n\t}\n}\n\nasync function safeFlush(\n\ttracker: Pick<WaniWaniClient, \"flush\">,\n\tonError?: (error: Error) => void,\n): Promise<void> {\n\ttry {\n\t\tawait tracker.flush();\n\t} catch (error) {\n\t\tonError?.(toError(error));\n\t}\n}\n\nfunction toError(error: unknown): Error {\n\tif (error instanceof Error) {\n\t\treturn error;\n\t}\n\treturn new Error(String(error));\n}\n"],"mappings":"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","names":["detectPlatform","isOpenAI","isMCPApps","START","END","INTERRUPT","WIDGET","interrupt","config","question","field","context","suggestions","showWidget","resource","isInterrupt","value","isWidget","z","MIME_TYPE_OPENAI","MIME_TYPE_MCP","fetchHtml","baseUrl","path","normalizedBase","buildOpenAIResourceMeta","config","buildMcpAppsResourceMeta","csp","buildToolMeta","describeZodField","schema","desc","def","vals","v","buildFlowProtocol","config","lines","fieldList","key","info","getInputMeta","args","state","step","field","widgetId","resolveNextNode","edge","executeFrom","startNodeName","startState","nodes","nodeConfigs","edges","meta","currentNode","MAX_ITERATIONS","iterations","END","handler","result","isInterrupt","q","isSingle","q0","isWidget","widgetField","resource","buildToolMeta","error","inputSchema","z","compileFlow","input","resources","protocol","fullDescription","firstResource","toolMeta","handleToolCall","inputMeta","startEdge","START","firstNode","updatedState","nextNode","server","extra","_meta","responseMeta","content","StateGraph","config","name","configOrHandler","maybeHandler","START","END","handler","nodeConfig","cfg","state","showWidget","from","to","condition","compileFlow","startEdge","edge","createFlow","config","StateGraph","createResource","config","id","title","description","baseUrl","htmlPath","widgetDomain","prefersBorder","autoHeight","widgetCSP","hostname","openaiUri","mcpUri","htmlPromise","getHtml","fetchHtml","uiDescription","register","server","html","MIME_TYPE_OPENAI","uri","buildOpenAIResourceMeta","MIME_TYPE_MCP","buildMcpAppsResourceMeta","createTool","config","handler","resource","description","inputSchema","annotations","id","title","toolMeta","buildToolMeta","server","args","extra","_meta","result","registerTools","tools","t","DEFAULT_SOURCE","mapTrackEventToV2","input","options","now","generateId","createEventId","eventName","resolveEventName","meta","toRecord","metadata","correlation","resolveCorrelationIds","eventId","takeNonEmptyString","timestamp","normalizeTimestamp","source","rawLegacy","isLegacyTrackEvent","mappedMetadata","mapProperties","legacyProperties","mapLegacyProperties","explicitProperties","properties","requestId","pickFirstString","sessionId","traceId","externalUserId","correlationId","date","record","keys","key","value","DEFAULT_ENDPOINT_PATH","SDK_NAME","AUTH_FAILURE_STATUS","RETRYABLE_STATUS","createV2BatchTransport","options","BatchingV2Transport","joinUrl","DEFAULT_ENDPOINT_PATH","delayMs","resolve","event","dropCount","timeoutMs","flushPromise","timeoutSignal","batch","attempt","pendingBatch","result","events","response","error","getErrorMessage","data","parseJsonResponse","partial","rejected","byId","retryable","permanent","rejectedEvent","isRetryableRejectedEvent","rawDelay","status","rejectedCount","buffered","code","body","baseUrl","endpointPath","normalizedBase","normalizedPath","createTrackingClient","config","baseUrl","apiKey","tracking","requireApiKey","transport","createV2BatchTransport","client","event","mappedEvent","mapTrackEventToV2","options","attachShutdownHooks","defaultTimeoutMs","shutdown","waniwani","config","baseUrl","apiKey","trackingConfig","internalConfig","createTrackingClient","mapWidgetEvent","ev","eventType","eventName","properties","createTrackingRoute","options","config","client","getClient","waniwani","request","body","c","results","trackInput","result","error","message","WidgetTokenCache","config","sessionId","traceId","url","joinUrl","body","response","json","result","expiresAtMs","baseUrl","path","DEFAULT_BASE_URL","withWaniwani","server","options","wrappedServer","tracker","waniwani","injectToken","tokenCache","getTokenCache","apiKey","WidgetTokenCache","originalRegisterTool","args","toolNameRaw","config","handlerRaw","toolName","handler","input","extra","startTime","result","durationMs","safeTrack","buildTrackInput","safeFlush","injectWidgetConfig","error","cache","baseUrl","onError","isRecord","meta","waniwaniConfig","token","toError","timing","toolType","resolveToolType","extractMeta","toolTypeOption","value"]}