@xpert-ai/chatkit-ui 0.5.2 → 0.5.4

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 (338) hide show
  1. package/dist/app/assets/{_baseUniq-DMPA_oa4.js → _baseUniq-DMOCw35x.js} +1 -1
  2. package/dist/app/assets/{abap-Cj2zL0JN.js → abap-Bwac32zp.js} +1 -1
  3. package/dist/app/assets/{abnf-CX4bCmMj.js → abnf-XuDqV3sf.js} +1 -1
  4. package/dist/app/assets/{actionscript-D-EhiET_.js → actionscript-CWEQruXL.js} +1 -1
  5. package/dist/app/assets/{ada-Bqjbr4-K.js → ada-BeyOoTNZ.js} +1 -1
  6. package/dist/app/assets/{agda-DTG3BItC.js → agda-DM2nELzN.js} +1 -1
  7. package/dist/app/assets/{al-quk_zUjL.js → al-BoMzGy9R.js} +1 -1
  8. package/dist/app/assets/{antlr4-C-SKSOZR.js → antlr4-Bjlafc2T.js} +1 -1
  9. package/dist/app/assets/{apacheconf-B4MHVph_.js → apacheconf-CDbPiwWC.js} +1 -1
  10. package/dist/app/assets/{apex-cbqOGViP.js → apex-E4CSbA6l.js} +1 -1
  11. package/dist/app/assets/{apl-BLpOFeja.js → apl-DndAMDM0.js} +1 -1
  12. package/dist/app/assets/{applescript-CK66K0iL.js → applescript-CF_1Snqu.js} +1 -1
  13. package/dist/app/assets/{aql-BeBrwxVC.js → aql-BaOiUvRD.js} +1 -1
  14. package/dist/app/assets/{arc-CcRTWZ_M.js → arc-Clg4el_l.js} +1 -1
  15. package/dist/app/assets/{architectureDiagram-Q4EWVU46-BGOqzZxe.js → architectureDiagram-Q4EWVU46-BQjH7jPS.js} +1 -1
  16. package/dist/app/assets/{arduino-CuMzU4Nc.js → arduino-B_RAK_0k.js} +1 -1
  17. package/dist/app/assets/{arff-D6des0tj.js → arff-ALjJPG-v.js} +1 -1
  18. package/dist/app/assets/{asciidoc-DkUYz8D6.js → asciidoc-C5DKyBG_.js} +1 -1
  19. package/dist/app/assets/{asm6502-CDxIqge4.js → asm6502-B3Mlc96p.js} +1 -1
  20. package/dist/app/assets/{asmatmel-DA5GvT3C.js → asmatmel-C1tzeqyn.js} +1 -1
  21. package/dist/app/assets/{aspnet-DwHgq8BN.js → aspnet-FJjQJZ-l.js} +1 -1
  22. package/dist/app/assets/{autohotkey-m_x4HDjz.js → autohotkey-Ba-oQsKG.js} +1 -1
  23. package/dist/app/assets/{autoit-DD3JIMtp.js → autoit-gdQ0fcTW.js} +1 -1
  24. package/dist/app/assets/{avisynth-BQ6krU9c.js → avisynth-D8feN2CN.js} +1 -1
  25. package/dist/app/assets/{avro-idl-RNMFYlHc.js → avro-idl-BvOZAG1C.js} +1 -1
  26. package/dist/app/assets/{bash-DsSMsygL.js → bash-CWG_jeOA.js} +1 -1
  27. package/dist/app/assets/{basic-CWxIL949.js → basic-B8xqGayQ.js} +1 -1
  28. package/dist/app/assets/{batch-B_YcBqUM.js → batch-DL8dfZHp.js} +1 -1
  29. package/dist/app/assets/{bbcode-m2CB613Z.js → bbcode-BshzRgA_.js} +1 -1
  30. package/dist/app/assets/{bicep-CZoEzXRK.js → bicep-Bfl07x5z.js} +1 -1
  31. package/dist/app/assets/{birb-C45GxEuv.js → birb-hQTWt4gT.js} +1 -1
  32. package/dist/app/assets/{bison-B2Cyv-Jg.js → bison-BZqgUQ29.js} +1 -1
  33. package/dist/app/assets/{blockDiagram-DXYQGD6D-Bw_AvB9J.js → blockDiagram-DXYQGD6D-YShqaJER.js} +1 -1
  34. package/dist/app/assets/{bnf-Bqy7WaG8.js → bnf-DUVse2KP.js} +1 -1
  35. package/dist/app/assets/{brainfuck-CZfj6bhY.js → brainfuck-Bu3NW3aS.js} +1 -1
  36. package/dist/app/assets/{brightscript-CYTjxugS.js → brightscript-C0GeKHI_.js} +1 -1
  37. package/dist/app/assets/{bro-TUn5kzss.js → bro-BLds2A1m.js} +1 -1
  38. package/dist/app/assets/{bsl-DIouJkZU.js → bsl-DmHvdU2a.js} +1 -1
  39. package/dist/app/assets/{c-DgEMJzlq.js → c-BS2cF__m.js} +1 -1
  40. package/dist/app/assets/{c4Diagram-AHTNJAMY-BZ1aSEKn.js → c4Diagram-AHTNJAMY-BXzNi2Xz.js} +1 -1
  41. package/dist/app/assets/{cfscript-CXMqhOEs.js → cfscript-BYSTy-me.js} +1 -1
  42. package/dist/app/assets/{chaiscript-CbswHI99.js → chaiscript-DgP4hQHX.js} +1 -1
  43. package/dist/app/assets/channel-ZWsVuMuK.js +1 -0
  44. package/dist/app/assets/{chunk-4BX2VUAB-C1NxsBOT.js → chunk-4BX2VUAB-DExUwpHa.js} +1 -1
  45. package/dist/app/assets/{chunk-4TB4RGXK-DVMRNBq9.js → chunk-4TB4RGXK-BOkQHv8_.js} +1 -1
  46. package/dist/app/assets/{chunk-55IACEB6-Cc2HT1dN.js → chunk-55IACEB6-CLQ6xN1-.js} +1 -1
  47. package/dist/app/assets/{chunk-EDXVE4YY-CE4IFknJ.js → chunk-EDXVE4YY-BeUFxqxB.js} +1 -1
  48. package/dist/app/assets/{chunk-FMBD7UC4-Dpwq2Fyq.js → chunk-FMBD7UC4-DQbOG9LT.js} +1 -1
  49. package/dist/app/assets/{chunk-OYMX7WX6-B5HRrsAE.js → chunk-OYMX7WX6-BOWS5K_U.js} +1 -1
  50. package/dist/app/assets/{chunk-QZHKN3VN-DW4jQzcx.js → chunk-QZHKN3VN-B7BYmIon.js} +1 -1
  51. package/dist/app/assets/{chunk-YZCP3GAM-DibQdouJ.js → chunk-YZCP3GAM-DsHse404.js} +1 -1
  52. package/dist/app/assets/{cil-BoU9SAC0.js → cil-w2QHvA4j.js} +1 -1
  53. package/dist/app/assets/classDiagram-6PBFFD2Q-lDdKGvxc.js +1 -0
  54. package/dist/app/assets/classDiagram-v2-HSJHXN6E-lDdKGvxc.js +1 -0
  55. package/dist/app/assets/{clike-_aTdr-fb.js → clike-Br9rvy8L.js} +1 -1
  56. package/dist/app/assets/{clojure-C9TT8oBQ.js → clojure-8ZXdIPPq.js} +1 -1
  57. package/dist/app/assets/clone-CS3cnCuu.js +1 -0
  58. package/dist/app/assets/{cmake-Dy5-b1yK.js → cmake-CvEaJy7h.js} +1 -1
  59. package/dist/app/assets/{cobol-NUAmiaV7.js → cobol-M72fZmMC.js} +1 -1
  60. package/dist/app/assets/{coffeescript-CNW8xSj3.js → coffeescript-C5xJdhaj.js} +1 -1
  61. package/dist/app/assets/{concurnas-zmOlqEBl.js → concurnas-CdlNXgIt.js} +1 -1
  62. package/dist/app/assets/{coq-BjQlvNZL.js → coq-BYQTyuV-.js} +1 -1
  63. package/dist/app/assets/{core-CjEsXh7s.js → core-DnOolKys.js} +1 -1
  64. package/dist/app/assets/{cose-bilkent-S5V4N54A-DTpBdRjm.js → cose-bilkent-S5V4N54A-sFy0HB_g.js} +1 -1
  65. package/dist/app/assets/{cpp-DlbtfO9_.js → cpp-CZphUwmQ.js} +1 -1
  66. package/dist/app/assets/{crystal-D_FpS8EO.js → crystal-CUe5clIL.js} +1 -1
  67. package/dist/app/assets/{csharp-CcBkcqul.js → csharp-BJgKnlvC.js} +1 -1
  68. package/dist/app/assets/{cshtml-Co8xpPOu.js → cshtml-C9vsKRks.js} +1 -1
  69. package/dist/app/assets/{csp-I3DvvTD_.js → csp-DIXOXJub.js} +1 -1
  70. package/dist/app/assets/{css-extras-DK8RR_-K.js → css-extras-DjOIy_vc.js} +1 -1
  71. package/dist/app/assets/{css-B96lK0h5.js → css-mB1wvHfo.js} +1 -1
  72. package/dist/app/assets/{csv-COrR5Oay.js → csv-DXsT9LhL.js} +1 -1
  73. package/dist/app/assets/{cypher-BT7uRwlq.js → cypher-YE9UQm-0.js} +1 -1
  74. package/dist/app/assets/{d-BgMcdgIJ.js → d-BnVGSkU6.js} +1 -1
  75. package/dist/app/assets/{dagre-KV5264BT-BzAdnA6d.js → dagre-KV5264BT-Qs4OIWYq.js} +1 -1
  76. package/dist/app/assets/{dart-yK6F88CW.js → dart-DBwvOqyJ.js} +1 -1
  77. package/dist/app/assets/{dataweave-Dm-qpzhK.js → dataweave-DDd-NH0e.js} +1 -1
  78. package/dist/app/assets/{dax-Cj2gxnM-.js → dax-BWU_B3kH.js} +1 -1
  79. package/dist/app/assets/{dhall-nQjelIAq.js → dhall-BBvMj82b.js} +1 -1
  80. package/dist/app/assets/{diagram-5BDNPKRD-CvZU2QL3.js → diagram-5BDNPKRD-RXruFkHY.js} +1 -1
  81. package/dist/app/assets/{diagram-G4DWMVQ6-CQ5Hcvj3.js → diagram-G4DWMVQ6-Bzx7lA4J.js} +1 -1
  82. package/dist/app/assets/{diagram-MMDJMWI5-yACl-dt-.js → diagram-MMDJMWI5-B8rWkSor.js} +1 -1
  83. package/dist/app/assets/{diagram-TYMM5635-BUu215MN.js → diagram-TYMM5635-EZPdbp6x.js} +1 -1
  84. package/dist/app/assets/{diff-D4n6eVkt.js → diff-jE6nXQ7L.js} +1 -1
  85. package/dist/app/assets/{django-B9MiHxlG.js → django-Brhbv2JO.js} +1 -1
  86. package/dist/app/assets/{dns-zone-file-VD8eyEBf.js → dns-zone-file-Ce5cMsLg.js} +1 -1
  87. package/dist/app/assets/{docker-Dd8HMn45.js → docker-Bfq4doN7.js} +1 -1
  88. package/dist/app/assets/{dot-nHpGp3MO.js → dot-DMWN4mEC.js} +1 -1
  89. package/dist/app/assets/{ebnf-ZDntitCJ.js → ebnf-DYXRLHUG.js} +1 -1
  90. package/dist/app/assets/{editorconfig-D_mDhoqj.js → editorconfig-CbJknMcb.js} +1 -1
  91. package/dist/app/assets/{eiffel-BBAjnLtv.js → eiffel-B4EZvlGs.js} +1 -1
  92. package/dist/app/assets/{ejs-D41FeLkK.js → ejs-BEU-qjf7.js} +1 -1
  93. package/dist/app/assets/{elixir-CJpjQBGg.js → elixir-B_a2ycY4.js} +1 -1
  94. package/dist/app/assets/{elm-C8xeCxT5.js → elm-leMW8E0P.js} +1 -1
  95. package/dist/app/assets/{erDiagram-SMLLAGMA-B_XYwb20.js → erDiagram-SMLLAGMA-LzJyKDT4.js} +1 -1
  96. package/dist/app/assets/{erb-CDlRljTJ.js → erb-D3vrulF7.js} +1 -1
  97. package/dist/app/assets/{erlang-DAsGKBqs.js → erlang-RNH0tzGN.js} +1 -1
  98. package/dist/app/assets/{etlua-080SN-ad.js → etlua-BFVTp3-T.js} +1 -1
  99. package/dist/app/assets/{excel-formula-C1ourZkH.js → excel-formula-DlSyXE4L.js} +1 -1
  100. package/dist/app/assets/{factor-3iu3Iq_3.js → factor-uwksoWD7.js} +1 -1
  101. package/dist/app/assets/{false-BssRf9La.js → false-BpdJd_Yz.js} +1 -1
  102. package/dist/app/assets/{firestore-security-rules-CBt6qjzb.js → firestore-security-rules-C5uPMG3k.js} +1 -1
  103. package/dist/app/assets/{flow-B6-gkILu.js → flow-BL5s74Nr.js} +1 -1
  104. package/dist/app/assets/{flowDiagram-DWJPFMVM-BW8OeHws.js → flowDiagram-DWJPFMVM-D0X8qkzm.js} +1 -1
  105. package/dist/app/assets/{fortran--gLPNveO.js → fortran-B9uAh6kv.js} +1 -1
  106. package/dist/app/assets/{fsharp-Ccsw25Pl.js → fsharp-CFUi3hZF.js} +1 -1
  107. package/dist/app/assets/{ftl-BAbnPQW4.js → ftl-BmFITVHz.js} +1 -1
  108. package/dist/app/assets/{ganttDiagram-T4ZO3ILL-Cjx_nnPG.js → ganttDiagram-T4ZO3ILL-BumD1IN7.js} +1 -1
  109. package/dist/app/assets/{gap-Ccu9ovLm.js → gap-eoD5aEtL.js} +1 -1
  110. package/dist/app/assets/{gcode-Cy1a8PDW.js → gcode-Ct0C6tkJ.js} +1 -1
  111. package/dist/app/assets/{gdscript-y4aaFG00.js → gdscript-IAeaSiET.js} +1 -1
  112. package/dist/app/assets/{gedcom-BuHJMovk.js → gedcom-Cp6ETPlx.js} +1 -1
  113. package/dist/app/assets/{gherkin-DI_FlrZP.js → gherkin-gQBC5_Tm.js} +1 -1
  114. package/dist/app/assets/{git-CdMKKQEU.js → git-BUb2Ef5G.js} +1 -1
  115. package/dist/app/assets/{gitGraphDiagram-UUTBAWPF-CdHhQZSB.js → gitGraphDiagram-UUTBAWPF-CwIjnG1f.js} +1 -1
  116. package/dist/app/assets/{glsl-4F4N5Sux.js → glsl-ha500tad.js} +1 -1
  117. package/dist/app/assets/{gml-D81YX-Rx.js → gml-D9UKe8HS.js} +1 -1
  118. package/dist/app/assets/{gn-DnsgJxRB.js → gn-BSitOcQd.js} +1 -1
  119. package/dist/app/assets/{go-CfGHIbHP.js → go-DMF0ihJu.js} +1 -1
  120. package/dist/app/assets/{go-module-v1qReyj4.js → go-module-DMB1tWdY.js} +1 -1
  121. package/dist/app/assets/{graph-BXB1kC50.js → graph-DLHVWCQv.js} +1 -1
  122. package/dist/app/assets/{graphql-B3jwaFVl.js → graphql-CEPu_6ph.js} +1 -1
  123. package/dist/app/assets/{groovy-CqJsjrfP.js → groovy-eBWL80CL.js} +1 -1
  124. package/dist/app/assets/{haml-CnEGtX4u.js → haml-BCDJxgmu.js} +1 -1
  125. package/dist/app/assets/{handlebars-BMvQ3BzY.js → handlebars-CapCjGml.js} +1 -1
  126. package/dist/app/assets/{haskell-Cf0RBiXF.js → haskell-HSDXTiY3.js} +1 -1
  127. package/dist/app/assets/{haxe-CUFzN8sZ.js → haxe-CYhicWLF.js} +1 -1
  128. package/dist/app/assets/{hcl-BAnkSgip.js → hcl-DaEJ63gk.js} +1 -1
  129. package/dist/app/assets/{hlsl-DCwNlMrb.js → hlsl-R7suMNE4.js} +1 -1
  130. package/dist/app/assets/{hoon-C15vAmJ-.js → hoon-Bv-chbF9.js} +1 -1
  131. package/dist/app/assets/{hpkp-C3kAfIYl.js → hpkp-C4ADGtou.js} +1 -1
  132. package/dist/app/assets/{hsts-Bhenzx1_.js → hsts-CB5oK3VS.js} +1 -1
  133. package/dist/app/assets/{http-DPLUui5c.js → http-C1PyXYUv.js} +1 -1
  134. package/dist/app/assets/{ichigojam-CjxT7NsH.js → ichigojam-CE_ZgXG6.js} +1 -1
  135. package/dist/app/assets/{icon-Cbzclc37.js → icon-uu24hWNu.js} +1 -1
  136. package/dist/app/assets/{icu-message-format-39S6o6G6.js → icu-message-format-Cp77XkuC.js} +1 -1
  137. package/dist/app/assets/{idris-CzUqPzGL.js → idris-Wy9aFZCq.js} +1 -1
  138. package/dist/app/assets/{iecst-D75uKMw6.js → iecst-BaML-dA3.js} +1 -1
  139. package/dist/app/assets/{ignore-DD-Nam9y.js → ignore-DZVOppkK.js} +1 -1
  140. package/dist/app/assets/index-LG2WR4hb.css +1 -0
  141. package/dist/app/assets/index-_eY4MICm.js +785 -0
  142. package/dist/app/assets/{infoDiagram-42DDH7IO-B8Rc8Ml2.js → infoDiagram-42DDH7IO-CKVpsNj5.js} +1 -1
  143. package/dist/app/assets/{inform7-DnYdJ-VQ.js → inform7-B3imwI6a.js} +1 -1
  144. package/dist/app/assets/{ini-CvifbSz9.js → ini-Dr_5Tj7S.js} +1 -1
  145. package/dist/app/assets/{io-DVWzqa0n.js → io-Dd7l3Ejv.js} +1 -1
  146. package/dist/app/assets/{ishikawaDiagram-UXIWVN3A-D5_HvTRV.js → ishikawaDiagram-UXIWVN3A-CtXPpTJL.js} +1 -1
  147. package/dist/app/assets/{j-BY7qyUJ5.js → j-Bl30FFSs.js} +1 -1
  148. package/dist/app/assets/{java-ChK2qUMm.js → java-p9valxE9.js} +1 -1
  149. package/dist/app/assets/{javadoc-CX4rgTSj.js → javadoc-BdL9LnX5.js} +1 -1
  150. package/dist/app/assets/{javadoclike-IU9Y8dsz.js → javadoclike-CySMyw18.js} +1 -1
  151. package/dist/app/assets/{javascript-mp-N-liG.js → javascript-C48aNs7d.js} +1 -1
  152. package/dist/app/assets/{javastacktrace-CijsCdli.js → javastacktrace-6b_tZrg9.js} +1 -1
  153. package/dist/app/assets/{jexl-CdTS_LMa.js → jexl-B3GBQzoE.js} +1 -1
  154. package/dist/app/assets/{jolie-CSLVrie0.js → jolie-Btit-ayQ.js} +1 -1
  155. package/dist/app/assets/{journeyDiagram-VCZTEJTY-T4W9I372.js → journeyDiagram-VCZTEJTY-DMKzhP-U.js} +1 -1
  156. package/dist/app/assets/{jq-BCAti0ZE.js → jq-n-PpCC5g.js} +1 -1
  157. package/dist/app/assets/{js-extras-C0llDM_8.js → js-extras-B4ul5r_s.js} +1 -1
  158. package/dist/app/assets/{js-templates-BBzwC4yV.js → js-templates-C6x6N4O8.js} +1 -1
  159. package/dist/app/assets/{jsdoc-B5c682J0.js → jsdoc-RY0uysf7.js} +1 -1
  160. package/dist/app/assets/{json-B6fifvmp.js → json-CoYnVzf7.js} +1 -1
  161. package/dist/app/assets/{json5-lhM974rx.js → json5-wfhl3hVZ.js} +1 -1
  162. package/dist/app/assets/{jsonp-Df-i1Psr.js → jsonp-D7odwsds.js} +1 -1
  163. package/dist/app/assets/{jsstacktrace-CGlls4Vc.js → jsstacktrace-CIqOyedq.js} +1 -1
  164. package/dist/app/assets/{jsx-CyoPYOBK.js → jsx-CA2INXPZ.js} +1 -1
  165. package/dist/app/assets/{julia-3ryHaHXf.js → julia-DRAXTapb.js} +1 -1
  166. package/dist/app/assets/{kanban-definition-6JOO6SKY-Dg098cTB.js → kanban-definition-6JOO6SKY-CSlAUcL1.js} +1 -1
  167. package/dist/app/assets/{keepalived-D_ad2ZoL.js → keepalived-dklp9jjH.js} +1 -1
  168. package/dist/app/assets/{keyman-BcEhx9gP.js → keyman-meTz7YQ0.js} +1 -1
  169. package/dist/app/assets/{kotlin-Da5vJL1Z.js → kotlin-lzQH4oZA.js} +1 -1
  170. package/dist/app/assets/{kumir-CjOTreP0.js → kumir-BVPwdvkd.js} +1 -1
  171. package/dist/app/assets/{kusto-DapEHOsI.js → kusto-CCesvOw9.js} +1 -1
  172. package/dist/app/assets/{latex-2otmSFTQ.js → latex-C0A08YOT.js} +1 -1
  173. package/dist/app/assets/{latte-CHcNDgGe.js → latte-DRyPL0o_.js} +1 -1
  174. package/dist/app/assets/{layout-DdWXXHsC.js → layout-Ft7nrLFj.js} +1 -1
  175. package/dist/app/assets/{less-1cuPUrve.js → less-0YGaK1Ny.js} +1 -1
  176. package/dist/app/assets/{lilypond-C01MfJr5.js → lilypond-xc0GRZDM.js} +1 -1
  177. package/dist/app/assets/{linear-Cue29L8J.js → linear-C0AD7ApO.js} +1 -1
  178. package/dist/app/assets/{liquid-T3d-Jjz8.js → liquid-CAIlXM7k.js} +1 -1
  179. package/dist/app/assets/{lisp-DlC_64cM.js → lisp-CWIf4a4E.js} +1 -1
  180. package/dist/app/assets/{livescript-X_Nv563A.js → livescript-W1wch9_n.js} +1 -1
  181. package/dist/app/assets/{llvm-BlMM3E2w.js → llvm-D35zJvME.js} +1 -1
  182. package/dist/app/assets/{log-cRhyBxgW.js → log-B35gSywI.js} +1 -1
  183. package/dist/app/assets/{lolcode-B710kwlH.js → lolcode-CXJWr_kr.js} +1 -1
  184. package/dist/app/assets/{lua-NNXJ23Pq.js → lua-DZP9Jv1z.js} +1 -1
  185. package/dist/app/assets/{magma-q5JeQg-k.js → magma-DqAgLAeM.js} +1 -1
  186. package/dist/app/assets/{makefile-PAGfpPD0.js → makefile-D33QCWzY.js} +1 -1
  187. package/dist/app/assets/{markdown-B8N4gsSe.js → markdown-hEkMDik6.js} +1 -1
  188. package/dist/app/assets/{markup-DhDTZYHM.js → markup-B_53o2jo.js} +1 -1
  189. package/dist/app/assets/{markup-templating-DDsqqM79.js → markup-templating-D1WOoUgZ.js} +1 -1
  190. package/dist/app/assets/{matlab-BXuUDvsA.js → matlab-Dqmrg6Ws.js} +1 -1
  191. package/dist/app/assets/{maxscript-Ck9qDjH2.js → maxscript-CimjIQuJ.js} +1 -1
  192. package/dist/app/assets/{mel-7zzDDxVd.js → mel-ofsHC9z3.js} +1 -1
  193. package/dist/app/assets/{mermaid-iLA8KbdM.js → mermaid-XfHMFgmD.js} +1 -1
  194. package/dist/app/assets/{min-CNdWWplt.js → min-BYbIgXZp.js} +1 -1
  195. package/dist/app/assets/{mindmap-definition-QFDTVHPH-0OnT-ARj.js → mindmap-definition-QFDTVHPH-a6Q2rDfi.js} +1 -1
  196. package/dist/app/assets/{mizar-BHRRxVF_.js → mizar-BNQ6o-Bx.js} +1 -1
  197. package/dist/app/assets/{mongodb-LWsLd7ke.js → mongodb-lpxH5Xg9.js} +1 -1
  198. package/dist/app/assets/{monkey-BuQXg-U8.js → monkey-Bba_gZQn.js} +1 -1
  199. package/dist/app/assets/{moonscript-BE_r-EfQ.js → moonscript-DWR-S8NH.js} +1 -1
  200. package/dist/app/assets/{n1ql-DmSGOs0a.js → n1ql-ChFtbfC1.js} +1 -1
  201. package/dist/app/assets/{n4js-CJ1VQre2.js → n4js-ubMYO9Op.js} +1 -1
  202. package/dist/app/assets/{nand2tetris-hdl-BRqm3JJX.js → nand2tetris-hdl-BMx7J0Cm.js} +1 -1
  203. package/dist/app/assets/{naniscript-B54PZYOr.js → naniscript-B94tammc.js} +1 -1
  204. package/dist/app/assets/{nasm-Bw7pDJBj.js → nasm-Bw4v9N74.js} +1 -1
  205. package/dist/app/assets/{neon-Btmhw7Ub.js → neon-BPjulnW3.js} +1 -1
  206. package/dist/app/assets/{nevod-DhI0_sqm.js → nevod-BLFD8Hth.js} +1 -1
  207. package/dist/app/assets/{nginx-DW1MSbQn.js → nginx-NgR-A9p9.js} +1 -1
  208. package/dist/app/assets/{nim-CXfKNptR.js → nim-2UMsJk0h.js} +1 -1
  209. package/dist/app/assets/{nix-BI9LrRLV.js → nix-DzhMPUNa.js} +1 -1
  210. package/dist/app/assets/{nsis-C45AtXuI.js → nsis-D5JKfUzv.js} +1 -1
  211. package/dist/app/assets/{objectivec-DoO786la.js → objectivec-BFcK3aFm.js} +1 -1
  212. package/dist/app/assets/{ocaml-DrOZ6uhT.js → ocaml-cs-S8ytT.js} +1 -1
  213. package/dist/app/assets/{opencl-f3QHGMdv.js → opencl-BR0vmM-J.js} +1 -1
  214. package/dist/app/assets/{openqasm-DnrYX2xV.js → openqasm-DjYO7UoV.js} +1 -1
  215. package/dist/app/assets/{oz-Cve8q8bA.js → oz-vHrTzEJX.js} +1 -1
  216. package/dist/app/assets/{parigp-Lh1bwfe1.js → parigp-Br7qKWCs.js} +1 -1
  217. package/dist/app/assets/{parser-BuuUTn0B.js → parser-DhDTWFrT.js} +1 -1
  218. package/dist/app/assets/{pascal-B44YxN9A.js → pascal-kENE5zmU.js} +1 -1
  219. package/dist/app/assets/{pascaligo-scYe-UN-.js → pascaligo-BAPxnaBd.js} +1 -1
  220. package/dist/app/assets/{pcaxis-D-IBiT9E.js → pcaxis-BA1b4CIO.js} +1 -1
  221. package/dist/app/assets/{peoplecode-D3sw6W4w.js → peoplecode-p7XS_-Wa.js} +1 -1
  222. package/dist/app/assets/{perl-CAWraJC1.js → perl-D5mJsCLY.js} +1 -1
  223. package/dist/app/assets/{php-CDW877Rv.js → php-DUBpHLia.js} +1 -1
  224. package/dist/app/assets/{php-extras-Ex6l_6iC.js → php-extras-BWnVpw6t.js} +1 -1
  225. package/dist/app/assets/{phpdoc-BjNC6X9h.js → phpdoc-DM85q7ja.js} +1 -1
  226. package/dist/app/assets/{pieDiagram-DEJITSTG-BtzVkX77.js → pieDiagram-DEJITSTG-Dg7k6vMC.js} +1 -1
  227. package/dist/app/assets/{plsql-CQQK_Pez.js → plsql-CcON0sDP.js} +1 -1
  228. package/dist/app/assets/{powerquery-CJuVpd-P.js → powerquery-w3urf2s7.js} +1 -1
  229. package/dist/app/assets/{powershell-Cc1fiasK.js → powershell-RBZ_T_y0.js} +1 -1
  230. package/dist/app/assets/{processing-CDodPUaF.js → processing-CE_dP2y5.js} +1 -1
  231. package/dist/app/assets/{prolog-Ji8Z1wBQ.js → prolog-CCjdx3vK.js} +1 -1
  232. package/dist/app/assets/{promql-B504eXKs.js → promql-DF2l993Q.js} +1 -1
  233. package/dist/app/assets/{properties-4pit0xKE.js → properties-Dz9yMKdu.js} +1 -1
  234. package/dist/app/assets/{protobuf-D65fgnCD.js → protobuf-DpCG-FTC.js} +1 -1
  235. package/dist/app/assets/{psl-BKfdnwL1.js → psl-DiIv5-zc.js} +1 -1
  236. package/dist/app/assets/{pug-44XVrvbS.js → pug-CBSV-T7k.js} +1 -1
  237. package/dist/app/assets/{puppet-CQ6pr95X.js → puppet-CoJZxRyQ.js} +1 -1
  238. package/dist/app/assets/{pure-B4d8unMA.js → pure-DDJg8__Y.js} +1 -1
  239. package/dist/app/assets/{purebasic-DIykjgce.js → purebasic-Do52PcJ6.js} +1 -1
  240. package/dist/app/assets/{purescript-b6UyO-Xd.js → purescript-CseI23J6.js} +1 -1
  241. package/dist/app/assets/{q-Dnh5m5NP.js → q-CQ0Fi_W7.js} +1 -1
  242. package/dist/app/assets/{qml-DT98Gva2.js → qml-tusJIup1.js} +1 -1
  243. package/dist/app/assets/{qore-DCDmqmqp.js → qore-BtvvaJR_.js} +1 -1
  244. package/dist/app/assets/{qsharp-DlVIr-Lk.js → qsharp-BfVEvXBF.js} +1 -1
  245. package/dist/app/assets/{quadrantDiagram-34T5L4WZ-CPX0aeas.js → quadrantDiagram-34T5L4WZ-eEHJOsLr.js} +1 -1
  246. package/dist/app/assets/{r-C0SqQ1if.js → r-CFBNVcXJ.js} +1 -1
  247. package/dist/app/assets/{racket-D6Rv9Y58.js → racket-CvgNN1WQ.js} +1 -1
  248. package/dist/app/assets/{reason-DOnbeD4h.js → reason-CUswFuTE.js} +1 -1
  249. package/dist/app/assets/{regex-BCE-dtFq.js → regex-DnbwmfQN.js} +1 -1
  250. package/dist/app/assets/{rego-CrqPRQqA.js → rego-DpVCunB6.js} +1 -1
  251. package/dist/app/assets/{renpy-DIdQy3U0.js → renpy-B0lK40hX.js} +1 -1
  252. package/dist/app/assets/{requirementDiagram-MS252O5E-DFqVROz9.js → requirementDiagram-MS252O5E-CoedzQM0.js} +1 -1
  253. package/dist/app/assets/{rest-lUPl_Dmb.js → rest-tHxDA5UT.js} +1 -1
  254. package/dist/app/assets/{rip-DpzQKsBT.js → rip-DHl6JkL5.js} +1 -1
  255. package/dist/app/assets/{roboconf-_7841m8Q.js → roboconf-BUo2Guju.js} +1 -1
  256. package/dist/app/assets/{robotframework-Byk4ohWk.js → robotframework-k6_Fb56G.js} +1 -1
  257. package/dist/app/assets/{ruby-BqQe_4Re.js → ruby-CLb5Fz0R.js} +1 -1
  258. package/dist/app/assets/{rust-By7W81wI.js → rust-BXLrPbwf.js} +1 -1
  259. package/dist/app/assets/{sankeyDiagram-XADWPNL6-C153VKrH.js → sankeyDiagram-XADWPNL6-CqaF9kZ3.js} +1 -1
  260. package/dist/app/assets/{sas-CCW8wZ8Y.js → sas-Bpgnp1ig.js} +1 -1
  261. package/dist/app/assets/{sass-Che-FE1n.js → sass-Cgz-UsH3.js} +1 -1
  262. package/dist/app/assets/{scala-Bzj7EBGD.js → scala-Dmm3REVa.js} +1 -1
  263. package/dist/app/assets/{scheme-CXNP4zbg.js → scheme-CQmKio0N.js} +1 -1
  264. package/dist/app/assets/{scss-BifR9Paq.js → scss-BLP0nDvE.js} +1 -1
  265. package/dist/app/assets/{sequenceDiagram-FGHM5R23-CwrMkWeC.js → sequenceDiagram-FGHM5R23-B5MJ9gfZ.js} +1 -1
  266. package/dist/app/assets/{shell-session-BIeaOWoA.js → shell-session-BWkQN5bW.js} +1 -1
  267. package/dist/app/assets/{smali-BhhFxYnC.js → smali-DP-sUoIm.js} +1 -1
  268. package/dist/app/assets/{smalltalk-CqeF5SEc.js → smalltalk-j0aPXd7c.js} +1 -1
  269. package/dist/app/assets/{smarty-DODx5tBJ.js → smarty-DP8LPkcc.js} +1 -1
  270. package/dist/app/assets/{sml-CMLl-jfZ.js → sml-Cu-zdNr3.js} +1 -1
  271. package/dist/app/assets/{solidity-DfihEf5n.js → solidity-Xjl7eHDy.js} +1 -1
  272. package/dist/app/assets/{solution-file-C-G5iX9Q.js → solution-file-BNt1IPOz.js} +1 -1
  273. package/dist/app/assets/{soy-BjYcrOfB.js → soy-DyX2-Hmb.js} +1 -1
  274. package/dist/app/assets/{sparql-Bo9ifGdT.js → sparql-7i1KmBR3.js} +1 -1
  275. package/dist/app/assets/{splunk-spl-C1rMe6Nu.js → splunk-spl-CO-w6uHT.js} +1 -1
  276. package/dist/app/assets/{sqf-DTlxXox6.js → sqf-fZNyI68i.js} +1 -1
  277. package/dist/app/assets/{sql-Bw_EHPvn.js → sql-CLyoIc_c.js} +1 -1
  278. package/dist/app/assets/{squirrel-DW457Ax9.js → squirrel-DrAMhT71.js} +1 -1
  279. package/dist/app/assets/{stan-B7n50noR.js → stan-BypwYcFh.js} +1 -1
  280. package/dist/app/assets/{stateDiagram-FHFEXIEX-CEQf98RN.js → stateDiagram-FHFEXIEX-oJFgiWhq.js} +1 -1
  281. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-Dyl4RScY.js +1 -0
  282. package/dist/app/assets/{stylus-Dv2Gpd2n.js → stylus-BidBaX29.js} +1 -1
  283. package/dist/app/assets/{swift-BAIbo1ZL.js → swift-Bn0pagVh.js} +1 -1
  284. package/dist/app/assets/{systemd-CM8gGPdt.js → systemd-CZ1o-JQg.js} +1 -1
  285. package/dist/app/assets/{t4-cs-DJQvnuVA.js → t4-cs-Bkh2kv5Q.js} +1 -1
  286. package/dist/app/assets/{t4-templating---KLNzA1.js → t4-templating-8Qw7j-Xz.js} +1 -1
  287. package/dist/app/assets/{t4-vb-Cseiaqvq.js → t4-vb-C60BV6kL.js} +1 -1
  288. package/dist/app/assets/{tap-BI8A4lyv.js → tap-D822RxOA.js} +1 -1
  289. package/dist/app/assets/{tcl-D0Ygia4-.js → tcl-C2D2mZvS.js} +1 -1
  290. package/dist/app/assets/{textile-Ckovp5lE.js → textile-CI5t3Qqr.js} +1 -1
  291. package/dist/app/assets/{timeline-definition-GMOUNBTQ-QGPqOu2_.js → timeline-definition-GMOUNBTQ-SDBaeRi8.js} +1 -1
  292. package/dist/app/assets/{toml-ic0y606Q.js → toml-B_Eg4X8A.js} +1 -1
  293. package/dist/app/assets/{tremor-DjtMl9Xw.js → tremor-CHIIVOuv.js} +1 -1
  294. package/dist/app/assets/{tt2-DIAkCzMt.js → tt2-BYHSEepO.js} +1 -1
  295. package/dist/app/assets/{turtle-CRztIQUt.js → turtle-Dt6tpQUG.js} +1 -1
  296. package/dist/app/assets/{twig-DMU8J6pK.js → twig-_HFRCYxa.js} +1 -1
  297. package/dist/app/assets/{typescript-Iz5CtnCc.js → typescript-BnPtnkdK.js} +1 -1
  298. package/dist/app/assets/{typoscript-zTZzZE8x.js → typoscript-C7j6S0bP.js} +1 -1
  299. package/dist/app/assets/{unrealscript-CODlSqBt.js → unrealscript-CZlqMla5.js} +1 -1
  300. package/dist/app/assets/{uorazor-TLqdcdSp.js → uorazor-Csue52-p.js} +1 -1
  301. package/dist/app/assets/{uri-X04B-1Ku.js → uri-BiN1ta3O.js} +1 -1
  302. package/dist/app/assets/{v-uEza4RBu.js → v-BtfXUB0f.js} +1 -1
  303. package/dist/app/assets/{vala-D9bku9j-.js → vala-CE2F_wJv.js} +1 -1
  304. package/dist/app/assets/{vbnet-DW8U376e.js → vbnet-BU5QIJlD.js} +1 -1
  305. package/dist/app/assets/{velocity-Chey_Yus.js → velocity-CmWxHoQq.js} +1 -1
  306. package/dist/app/assets/{vennDiagram-DHZGUBPP-aPpSiaPL.js → vennDiagram-DHZGUBPP-C9fT-XZa.js} +1 -1
  307. package/dist/app/assets/{verilog-BQ8HwcNa.js → verilog-ls1aPPY9.js} +1 -1
  308. package/dist/app/assets/{vhdl-BrZZFPeO.js → vhdl-Bu0bjyCA.js} +1 -1
  309. package/dist/app/assets/{vim-CIqO-Os5.js → vim-BJl0TEm7.js} +1 -1
  310. package/dist/app/assets/{visual-basic-Dt7-DW2C.js → visual-basic-BrKILmGh.js} +1 -1
  311. package/dist/app/assets/{wardley-RL74JXVD-BIubZMCY.js → wardley-RL74JXVD-DvBkFeP9.js} +1 -1
  312. package/dist/app/assets/{wardleyDiagram-NUSXRM2D-DYAY6Rx4.js → wardleyDiagram-NUSXRM2D-Bv8biw-m.js} +1 -1
  313. package/dist/app/assets/{warpscript-BaRoeM5L.js → warpscript-L4xE7joB.js} +1 -1
  314. package/dist/app/assets/{wasm-czQaol6D.js → wasm-sBd3DoVe.js} +1 -1
  315. package/dist/app/assets/{web-idl-Bsa21vQT.js → web-idl-N21KHGKr.js} +1 -1
  316. package/dist/app/assets/{wiki-LSYNKBVL.js → wiki-Cch7G73V.js} +1 -1
  317. package/dist/app/assets/{wolfram-C5If9Dhv.js → wolfram-TjVuyqlD.js} +1 -1
  318. package/dist/app/assets/{wren-DDo7JOZT.js → wren-DTY3PAiS.js} +1 -1
  319. package/dist/app/assets/{xeora-Ktg8q8zo.js → xeora-C4v3g3wC.js} +1 -1
  320. package/dist/app/assets/{xml-doc-DBE-2UUP.js → xml-doc-auzoR3BG.js} +1 -1
  321. package/dist/app/assets/{xojo-DWfIpwtt.js → xojo-DybgyESv.js} +1 -1
  322. package/dist/app/assets/{xquery-CFJU3zRn.js → xquery-UwgeP1gv.js} +1 -1
  323. package/dist/app/assets/{xychartDiagram-5P7HB3ND-BJY2wkwC.js → xychartDiagram-5P7HB3ND-Cv9o5KMB.js} +1 -1
  324. package/dist/app/assets/{yaml-DJmmt8p-.js → yaml-BU5qIDxs.js} +1 -1
  325. package/dist/app/assets/{yang-Bf5HN1Sx.js → yang-vmPGVjAI.js} +1 -1
  326. package/dist/app/assets/{zig-Sgl0VF72.js → zig-Cxu7_0qW.js} +1 -1
  327. package/dist/app/index.html +2 -2
  328. package/dist/app/mcp-app-sandbox-proxy.html +114 -0
  329. package/dist/index.cjs +1252 -217
  330. package/dist/index.js +1276 -234
  331. package/package.json +4 -4
  332. package/dist/app/assets/channel-C9F_V90G.js +0 -1
  333. package/dist/app/assets/classDiagram-6PBFFD2Q-Cf8DAzB0.js +0 -1
  334. package/dist/app/assets/classDiagram-v2-HSJHXN6E-Cf8DAzB0.js +0 -1
  335. package/dist/app/assets/clone-1urtxbkU.js +0 -1
  336. package/dist/app/assets/index-ByEJy9Db.css +0 -1
  337. package/dist/app/assets/index-C4MhPDCR.js +0 -783
  338. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-DN7a7q3Y.js +0 -1
package/dist/index.cjs CHANGED
@@ -2342,6 +2342,14 @@ var en_US_default = {
2342
2342
  },
2343
2343
  hitl: {
2344
2344
  title: "Action review",
2345
+ mcpElicitationTitle: "MCP Elicitation",
2346
+ fieldProgress: "Field {{current}}/{{total}}",
2347
+ requiredUnanswered: "1 required unanswered",
2348
+ requiredAnswered: "All required fields answered",
2349
+ true: "True",
2350
+ false: "False",
2351
+ cancel: "Cancel",
2352
+ elicitationSubmit: "Submit",
2345
2353
  actionProgress: "{{current}} of {{total}}",
2346
2354
  previousAction: "Previous action",
2347
2355
  nextAction: "Next action",
@@ -2477,7 +2485,16 @@ var en_US_default = {
2477
2485
  moreTags: "+{{count}}"
2478
2486
  },
2479
2487
  mcpApp: {
2480
- loading: "Loading MCP App"
2488
+ loading: "Loading MCP App",
2489
+ fullscreen: "Open fullscreen",
2490
+ pictureInPicture: "Open picture in picture",
2491
+ returnInline: "Return inline",
2492
+ approvalTitle: "Confirm MCP App action",
2493
+ toolApprovalDescription: 'The app wants to run "{{tool}}". Review the request before allowing it.',
2494
+ downloadApprovalDescription: "The app wants to download files to this device. Review the file details before allowing it.",
2495
+ requestDetails: "Request details",
2496
+ approve: "Allow",
2497
+ reject: "Reject"
2481
2498
  },
2482
2499
  contextCompression: {
2483
2500
  running: "Automatically compressing context",
@@ -2825,6 +2842,14 @@ var zh_CN_default = {
2825
2842
  },
2826
2843
  hitl: {
2827
2844
  title: "\u64CD\u4F5C\u5BA1\u6838",
2845
+ mcpElicitationTitle: "MCP Elicitation",
2846
+ fieldProgress: "\u5B57\u6BB5 {{current}}/{{total}}",
2847
+ requiredUnanswered: "1 \u4E2A\u5FC5\u586B\u9879\u5F85\u56DE\u7B54",
2848
+ requiredAnswered: "\u5FC5\u586B\u9879\u5DF2\u56DE\u7B54",
2849
+ true: "\u662F",
2850
+ false: "\u5426",
2851
+ cancel: "\u53D6\u6D88",
2852
+ elicitationSubmit: "\u63D0\u4EA4",
2828
2853
  actionProgress: "{{current}} / {{total}}",
2829
2854
  previousAction: "\u4E0A\u4E00\u4E2A\u64CD\u4F5C",
2830
2855
  nextAction: "\u4E0B\u4E00\u4E2A\u64CD\u4F5C",
@@ -2960,7 +2985,16 @@ var zh_CN_default = {
2960
2985
  moreTags: "+{{count}}"
2961
2986
  },
2962
2987
  mcpApp: {
2963
- loading: "\u6B63\u5728\u52A0\u8F7D MCP App"
2988
+ loading: "\u6B63\u5728\u52A0\u8F7D MCP App",
2989
+ fullscreen: "\u5168\u5C4F\u663E\u793A",
2990
+ pictureInPicture: "\u753B\u4E2D\u753B\u663E\u793A",
2991
+ returnInline: "\u8FD4\u56DE\u884C\u5185\u663E\u793A",
2992
+ approvalTitle: "\u786E\u8BA4 MCP App \u64CD\u4F5C",
2993
+ toolApprovalDescription: "App \u8BF7\u6C42\u8FD0\u884C\u201C{{tool}}\u201D\u3002\u8BF7\u68C0\u67E5\u8BF7\u6C42\u5185\u5BB9\u540E\u518D\u51B3\u5B9A\u662F\u5426\u5141\u8BB8\u3002",
2994
+ downloadApprovalDescription: "App \u8BF7\u6C42\u5C06\u6587\u4EF6\u4E0B\u8F7D\u5230\u6B64\u8BBE\u5907\u3002\u8BF7\u68C0\u67E5\u6587\u4EF6\u8BE6\u60C5\u540E\u518D\u51B3\u5B9A\u662F\u5426\u5141\u8BB8\u3002",
2995
+ requestDetails: "\u8BF7\u6C42\u8BE6\u60C5",
2996
+ approve: "\u5141\u8BB8",
2997
+ reject: "\u62D2\u7EDD"
2964
2998
  },
2965
2999
  contextCompression: {
2966
3000
  running: "\u6B63\u5728\u81EA\u52A8\u538B\u7F29\u4E0A\u4E0B\u6587",
@@ -5791,8 +5825,8 @@ function JsonTreeNode({
5791
5825
  depth = 0
5792
5826
  }) {
5793
5827
  const isArray = Array.isArray(value);
5794
- const isObject2 = isJsonObjectValue(value);
5795
- const isExpandable = isArray || isObject2;
5828
+ const isObject3 = isJsonObjectValue(value);
5829
+ const isExpandable = isArray || isObject3;
5796
5830
  const [isExpanded, setIsExpanded] = React18.useState(depth < 2);
5797
5831
  if (!isExpandable) {
5798
5832
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex min-w-0 gap-2 leading-6", children: [
@@ -6091,6 +6125,199 @@ function HITLApprovalPanel({
6091
6125
  onDismiss,
6092
6126
  attachToComposer = true,
6093
6127
  className
6128
+ }) {
6129
+ if (request?.request.elicitation?.kind === "mcp_elicitation" && request.request.actionRequests.length === 1 && request.request.actionRequests[0]?.name === request.request.elicitation.actionName) {
6130
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6131
+ MCPBooleanElicitationPanel,
6132
+ {
6133
+ request,
6134
+ onSubmit,
6135
+ onDismiss,
6136
+ attachToComposer,
6137
+ className
6138
+ }
6139
+ );
6140
+ }
6141
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6142
+ ActionReviewPanel,
6143
+ {
6144
+ request,
6145
+ onSubmit,
6146
+ onDismiss,
6147
+ attachToComposer,
6148
+ className
6149
+ }
6150
+ );
6151
+ }
6152
+ function MCPBooleanElicitationPanel({
6153
+ request,
6154
+ onSubmit,
6155
+ onDismiss,
6156
+ attachToComposer = true,
6157
+ className
6158
+ }) {
6159
+ const { t } = useChatkitTranslation();
6160
+ const rounded = useRoundedClasses4();
6161
+ const [decision, setDecision] = React19.useState(
6162
+ null
6163
+ );
6164
+ const elicitation = request?.request.elicitation;
6165
+ const action = request?.request.actionRequests.find(
6166
+ (candidate) => candidate.name === elicitation?.actionName
6167
+ );
6168
+ React19.useEffect(() => {
6169
+ setDecision(null);
6170
+ }, [request?.id]);
6171
+ React19.useEffect(() => {
6172
+ if (!request || !onDismiss) return;
6173
+ const handleKeyDown = (event) => {
6174
+ if (event.isComposing) return;
6175
+ if (event.key !== "Escape" && event.key !== "Esc") return;
6176
+ event.preventDefault();
6177
+ onDismiss();
6178
+ };
6179
+ document.addEventListener("keydown", handleKeyDown);
6180
+ return () => document.removeEventListener("keydown", handleKeyDown);
6181
+ }, [onDismiss, request]);
6182
+ if (!request || !elicitation || !action) return null;
6183
+ const fieldTitle = elicitation.field.title ?? action.name;
6184
+ const options = [
6185
+ {
6186
+ decision: "approve",
6187
+ label: t("composer.hitl.true")
6188
+ },
6189
+ {
6190
+ decision: "reject",
6191
+ label: t("composer.hitl.false")
6192
+ }
6193
+ ];
6194
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6195
+ "section",
6196
+ {
6197
+ "aria-label": t("composer.hitl.mcpElicitationTitle"),
6198
+ "aria-live": "polite",
6199
+ className: cn(
6200
+ "mx-2 border border-border bg-background/95 shadow-sm",
6201
+ rounded.density.section,
6202
+ attachToComposer ? "border-b-0" : null,
6203
+ attachToComposer ? rounded.top : rounded.panel,
6204
+ className
6205
+ ),
6206
+ children: [
6207
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6208
+ "div",
6209
+ {
6210
+ className: cn(
6211
+ "flex items-center gap-1.5 font-medium text-muted-foreground",
6212
+ rounded.density.eyebrow
6213
+ ),
6214
+ children: [
6215
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.ShieldCheck, { className: "h-3.5 w-3.5" }),
6216
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: t("composer.hitl.mcpElicitationTitle") })
6217
+ ]
6218
+ }
6219
+ ),
6220
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("space-y-2.5", rounded.density.body), children: [
6221
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-wrap items-center gap-x-1.5 gap-y-0.5 text-xs font-medium text-muted-foreground", children: [
6222
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: t("composer.hitl.fieldProgress", { current: 1, total: 1 }) }),
6223
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
6224
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: decision ? t("composer.hitl.requiredAnswered") : t("composer.hitl.requiredUnanswered") })
6225
+ ] }),
6226
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
6227
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6228
+ "h3",
6229
+ {
6230
+ className: cn(
6231
+ "font-semibold text-foreground",
6232
+ rounded.density.title
6233
+ ),
6234
+ children: fieldTitle
6235
+ }
6236
+ ),
6237
+ action.description ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "mt-1 whitespace-pre-wrap text-sm leading-5 text-muted-foreground", children: action.description }) : null
6238
+ ] }),
6239
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { role: "radiogroup", "aria-label": fieldTitle, className: "grid gap-1.5", children: options.map((option) => {
6240
+ const selected = decision === option.decision;
6241
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6242
+ "button",
6243
+ {
6244
+ type: "button",
6245
+ role: "radio",
6246
+ "aria-checked": selected,
6247
+ onClick: () => setDecision(option.decision),
6248
+ className: cn(
6249
+ "flex w-full items-center gap-2.5 border px-3 py-2 text-left text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
6250
+ rounded.control,
6251
+ selected ? "border-primary/50 bg-primary/10 text-foreground" : "border-border bg-background text-foreground/85 hover:bg-muted/70"
6252
+ ),
6253
+ children: [
6254
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6255
+ "span",
6256
+ {
6257
+ className: cn(
6258
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded-full border",
6259
+ selected ? "border-primary" : "border-muted-foreground/45"
6260
+ ),
6261
+ children: selected ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2 w-2 rounded-full bg-primary" }) : null
6262
+ }
6263
+ ),
6264
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: option.label })
6265
+ ]
6266
+ },
6267
+ option.decision
6268
+ );
6269
+ }) })
6270
+ ] }),
6271
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6272
+ "div",
6273
+ {
6274
+ className: cn("flex items-center justify-end", rounded.density.footer),
6275
+ children: [
6276
+ onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6277
+ "button",
6278
+ {
6279
+ type: "button",
6280
+ onClick: onDismiss,
6281
+ className: cn(
6282
+ "inline-flex items-center justify-center font-medium text-muted-foreground hover:text-foreground",
6283
+ rounded.control,
6284
+ rounded.density.dismissButton
6285
+ ),
6286
+ children: t("composer.hitl.cancel")
6287
+ }
6288
+ ) : null,
6289
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
6290
+ "button",
6291
+ {
6292
+ type: "button",
6293
+ disabled: !decision,
6294
+ onClick: () => {
6295
+ if (decision) onSubmit([{ type: decision }]);
6296
+ },
6297
+ className: cn(
6298
+ "inline-flex shrink-0 items-center justify-center gap-1.5 bg-primary font-semibold text-primary-foreground hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-45",
6299
+ rounded.control,
6300
+ rounded.density.continueButton
6301
+ ),
6302
+ children: [
6303
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react12.CornerDownLeft, { className: rounded.density.continueIcon }),
6304
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: t("composer.hitl.elicitationSubmit") })
6305
+ ]
6306
+ }
6307
+ )
6308
+ ]
6309
+ }
6310
+ )
6311
+ ]
6312
+ }
6313
+ );
6314
+ }
6315
+ function ActionReviewPanel({
6316
+ request,
6317
+ onSubmit,
6318
+ onDismiss,
6319
+ attachToComposer = true,
6320
+ className
6094
6321
  }) {
6095
6322
  const { t } = useChatkitTranslation();
6096
6323
  const rounded = useRoundedClasses4();
@@ -9558,8 +9785,8 @@ function getFallbackPalette(isDarkMode) {
9558
9785
  text: "#18181b"
9559
9786
  };
9560
9787
  }
9561
- function resolveColor(styles, property, fallback, background) {
9562
- const parsed = parseCssColor(styles.getPropertyValue(property));
9788
+ function resolveColor(styles, property2, fallback, background) {
9789
+ const parsed = parseCssColor(styles.getPropertyValue(property2));
9563
9790
  if (!parsed) return fallback;
9564
9791
  if (parsed.a < 1 && background) {
9565
9792
  return rgbaToHex(compositeColor(parsed, background));
@@ -13093,15 +13320,15 @@ function getObjectProperty(value, key) {
13093
13320
  if (!isPlainObject2(value)) {
13094
13321
  return void 0;
13095
13322
  }
13096
- const property = value[key];
13097
- return isPlainObject2(property) ? property : void 0;
13323
+ const property2 = value[key];
13324
+ return isPlainObject2(property2) ? property2 : void 0;
13098
13325
  }
13099
13326
  function getStringProperty(value, key) {
13100
13327
  if (!isPlainObject2(value)) {
13101
13328
  return void 0;
13102
13329
  }
13103
- const property = value[key];
13104
- return typeof property === "string" ? property : void 0;
13330
+ const property2 = value[key];
13331
+ return typeof property2 === "string" ? property2 : void 0;
13105
13332
  }
13106
13333
  function isPlainObject2(value) {
13107
13334
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -13114,6 +13341,223 @@ function hasLegacySurface(surface) {
13114
13341
  var React37 = __toESM(require("react"), 1);
13115
13342
  var import_chatkit_types11 = require("@xpert-ai/chatkit-types");
13116
13343
  var import_lucide_react24 = require("lucide-react");
13344
+
13345
+ // src/components/thread/messages/mcp-app/host.ts
13346
+ function isObject2(value) {
13347
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
13348
+ }
13349
+ function property(value, key) {
13350
+ return Reflect.get(value, key);
13351
+ }
13352
+ function stringProperty(value, key) {
13353
+ const field = property(value, key);
13354
+ return typeof field === "string" && field.trim() ? field.trim() : void 0;
13355
+ }
13356
+ function isMcpAppRpcSuccess(value) {
13357
+ return isObject2(value) && Reflect.has(value, "result") && !Reflect.has(value, "error");
13358
+ }
13359
+ function readMcpAppDisplayMode(value) {
13360
+ if (!isObject2(value)) return void 0;
13361
+ const result = property(value, "result");
13362
+ if (!isObject2(result)) return void 0;
13363
+ const mode = property(result, "mode");
13364
+ if (mode === "picture-in-picture") return "pip";
13365
+ return mode === "inline" || mode === "fullscreen" || mode === "pip" ? mode : void 0;
13366
+ }
13367
+ function readMcpAppPendingApproval(response, request) {
13368
+ if (!isObject2(response)) return null;
13369
+ const error = property(response, "error");
13370
+ if (!isObject2(error) || property(error, "code") !== -32001) return null;
13371
+ const data = property(error, "data");
13372
+ if (!isObject2(data)) return null;
13373
+ const approvalId = stringProperty(data, "approvalId");
13374
+ const risk = property(data, "risk");
13375
+ const expiresAt = property(data, "expiresAt");
13376
+ if (!approvalId || risk !== "write" && risk !== "destructive" || typeof expiresAt !== "number" || !Number.isFinite(expiresAt)) {
13377
+ return null;
13378
+ }
13379
+ const params = isObject2(request.params) ? request.params : void 0;
13380
+ const requestedTool = params ? stringProperty(params, "name") : void 0;
13381
+ const kind = request.method === "ui/download-file" ? "download" : "tool";
13382
+ return {
13383
+ approvalId,
13384
+ risk,
13385
+ expiresAt,
13386
+ toolName: kind === "download" ? "ui/download-file" : requestedTool ?? request.method ?? "tools/call",
13387
+ kind,
13388
+ request,
13389
+ details: kind === "download" ? formatDownloadApprovalDetails(request.params) : formatApprovalDetails(request.params)
13390
+ };
13391
+ }
13392
+ function withMcpAppApprovalId(request, approvalId) {
13393
+ return {
13394
+ ...request,
13395
+ params: {
13396
+ ...isObject2(request.params) ? request.params : {},
13397
+ approvalId
13398
+ }
13399
+ };
13400
+ }
13401
+ function formatApprovalDetails(value) {
13402
+ try {
13403
+ const text = JSON.stringify(redactSensitiveValue(value, 0), null, 2);
13404
+ if (!text) return "{}";
13405
+ return text.length > 4e3 ? `${text.slice(0, 4e3)}
13406
+ \u2026` : text;
13407
+ } catch {
13408
+ return "[Request details unavailable]";
13409
+ }
13410
+ }
13411
+ function redactSensitiveValue(value, depth) {
13412
+ if (depth >= 6) return "[Nested value omitted]";
13413
+ if (typeof value === "string" && value.length > 1e3) {
13414
+ return `${value.slice(0, 1e3)}\u2026 [${value.length} characters]`;
13415
+ }
13416
+ if (Array.isArray(value)) {
13417
+ return value.slice(0, 20).map((item) => redactSensitiveValue(item, depth + 1));
13418
+ }
13419
+ if (!isObject2(value)) return value;
13420
+ const output = {};
13421
+ for (const [key, field] of Object.entries(value).slice(0, 50)) {
13422
+ output[key] = /password|secret|token|authorization|api[-_]?key/i.test(key) ? "[Redacted]" : redactSensitiveValue(field, depth + 1);
13423
+ }
13424
+ return output;
13425
+ }
13426
+ function formatDownloadApprovalDetails(value) {
13427
+ if (!isObject2(value)) return "{}";
13428
+ const contents = property(value, "contents");
13429
+ if (!Array.isArray(contents)) return "{}";
13430
+ const summary = contents.slice(0, 20).map((item) => {
13431
+ if (!isObject2(item)) return { type: "invalid" };
13432
+ if (property(item, "type") === "resource_link") {
13433
+ return {
13434
+ type: "resource_link",
13435
+ name: stringProperty(item, "name"),
13436
+ uri: stringProperty(item, "uri"),
13437
+ mimeType: stringProperty(item, "mimeType")
13438
+ };
13439
+ }
13440
+ const resource = property(item, "resource");
13441
+ if (!isObject2(resource)) return { type: property(item, "type") };
13442
+ const text = property(resource, "text");
13443
+ const blob = property(resource, "blob");
13444
+ return {
13445
+ type: "resource",
13446
+ name: stringProperty(resource, "name"),
13447
+ uri: stringProperty(resource, "uri"),
13448
+ mimeType: stringProperty(resource, "mimeType"),
13449
+ size: typeof text === "string" ? `${new TextEncoder().encode(text).byteLength} bytes` : typeof blob === "string" ? `approximately ${Math.floor(blob.length * 3 / 4)} bytes` : void 0
13450
+ };
13451
+ });
13452
+ return JSON.stringify({ files: summary }, null, 2);
13453
+ }
13454
+ function triggerMcpAppDownloads(value) {
13455
+ const downloads = parseDownloadItems(value);
13456
+ for (const download of downloads) {
13457
+ if (download.kind === "link") {
13458
+ clickDownload(download.uri, download.filename);
13459
+ continue;
13460
+ }
13461
+ const blob = new Blob(
13462
+ [
13463
+ download.text !== void 0 ? download.text : decodeBase64(download.blob ?? "")
13464
+ ],
13465
+ { type: download.mimeType }
13466
+ );
13467
+ const url = URL.createObjectURL(blob);
13468
+ clickDownload(url, download.filename);
13469
+ window.setTimeout(() => URL.revokeObjectURL(url), 0);
13470
+ }
13471
+ }
13472
+ function parseDownloadItems(value) {
13473
+ if (!isObject2(value)) throw new Error("Download params must be an object");
13474
+ if (property(value, "isError") === true) {
13475
+ throw new Error("The MCP App reported that the download failed");
13476
+ }
13477
+ const contents = property(value, "contents");
13478
+ if (!Array.isArray(contents) || contents.length === 0) {
13479
+ throw new Error("Download contents must be a non-empty array");
13480
+ }
13481
+ return contents.map((item, index) => {
13482
+ if (!isObject2(item)) throw new Error("Download content is invalid");
13483
+ const type = property(item, "type");
13484
+ if (type === "resource_link") {
13485
+ const uri2 = stringProperty(item, "uri");
13486
+ const name = stringProperty(item, "name");
13487
+ if (!uri2 || !name || !isHttpUrl(uri2)) {
13488
+ throw new Error(
13489
+ "Download link must use HTTP or HTTPS and include a name"
13490
+ );
13491
+ }
13492
+ return {
13493
+ kind: "link",
13494
+ filename: sanitizeFilename(name, index),
13495
+ uri: uri2
13496
+ };
13497
+ }
13498
+ if (type !== "resource") {
13499
+ throw new Error("Download content type is unsupported");
13500
+ }
13501
+ const resource = property(item, "resource");
13502
+ if (!isObject2(resource)) throw new Error("Embedded download is invalid");
13503
+ const uri = stringProperty(resource, "uri");
13504
+ if (!uri) throw new Error("Embedded download URI is required");
13505
+ const text = property(resource, "text");
13506
+ const blob = property(resource, "blob");
13507
+ if (typeof text !== "string" && typeof blob !== "string") {
13508
+ throw new Error("Embedded download must include text or base64 data");
13509
+ }
13510
+ const common = {
13511
+ kind: "embedded",
13512
+ filename: sanitizeFilename(
13513
+ stringProperty(resource, "name") ?? filenameFromUri(uri),
13514
+ index
13515
+ ),
13516
+ mimeType: stringProperty(resource, "mimeType") ?? "application/octet-stream"
13517
+ };
13518
+ return typeof text === "string" ? { ...common, text } : { ...common, blob };
13519
+ });
13520
+ }
13521
+ function decodeBase64(value) {
13522
+ const decoded = window.atob(value);
13523
+ return Uint8Array.from(decoded, (character) => character.charCodeAt(0));
13524
+ }
13525
+ function filenameFromUri(uri) {
13526
+ try {
13527
+ const pathname = new URL(uri).pathname;
13528
+ const segment = pathname.split("/").filter(Boolean).at(-1);
13529
+ return segment ? decodeURIComponent(segment) : "download";
13530
+ } catch {
13531
+ return uri.split("/").filter(Boolean).at(-1) ?? "download";
13532
+ }
13533
+ }
13534
+ function sanitizeFilename(value, index) {
13535
+ const sanitized = Array.from(
13536
+ value,
13537
+ (character) => character.charCodeAt(0) <= 31 || /[\\/:*?"<>|]/.test(character) ? "_" : character
13538
+ ).join("").trim().slice(0, 255);
13539
+ return sanitized || `download-${index + 1}`;
13540
+ }
13541
+ function isHttpUrl(value) {
13542
+ try {
13543
+ const url = new URL(value);
13544
+ return url.protocol === "http:" || url.protocol === "https:";
13545
+ } catch {
13546
+ return false;
13547
+ }
13548
+ }
13549
+ function clickDownload(uri, filename) {
13550
+ const anchor = document.createElement("a");
13551
+ anchor.href = uri;
13552
+ anchor.download = filename;
13553
+ anchor.rel = "noopener noreferrer";
13554
+ anchor.hidden = true;
13555
+ document.body.append(anchor);
13556
+ anchor.click();
13557
+ anchor.remove();
13558
+ }
13559
+
13560
+ // src/components/thread/messages/mcp-app.tsx
13117
13561
  var import_jsx_runtime43 = require("react/jsx-runtime");
13118
13562
  var EMPTY_INPUT_SCHEMA = {
13119
13563
  type: "object",
@@ -13146,53 +13590,28 @@ function readIconDefinition(value) {
13146
13590
  }
13147
13591
  function readStringList(value) {
13148
13592
  if (!Array.isArray(value)) return void 0;
13149
- const strings = value.filter((item) => typeof item === "string");
13593
+ const strings = value.filter(
13594
+ (item) => typeof item === "string"
13595
+ );
13150
13596
  return strings.length ? strings : void 0;
13151
13597
  }
13152
- function buildXpertApiUrl(apiUrl, path) {
13153
- const normalizedApiUrl = apiUrl.trim();
13154
- if (!normalizedApiUrl) return path;
13155
- try {
13156
- const url = new URL(normalizedApiUrl);
13157
- return `${url.origin}${path}`;
13158
- } catch {
13159
- return path;
13160
- }
13161
- }
13162
- function appendQuery(path, params) {
13163
- const query = params.toString();
13164
- return query ? `${path}?${query}` : path;
13165
- }
13166
- function buildMcpAppReviveParams(data, options) {
13167
- const params = new URLSearchParams();
13168
- const add = (key, value) => {
13169
- if (value) {
13170
- params.set(key, value);
13171
- }
13598
+ function buildMcpAppReviveQuery(data, options) {
13599
+ return {
13600
+ toolsetId: data.toolsetId,
13601
+ serverName: data.serverName,
13602
+ toolName: data.toolName,
13603
+ toolCallId: data.toolCallId,
13604
+ resourceUri: data.resourceUri,
13605
+ title: typeof data.title === "string" ? data.title : void 0,
13606
+ messageId: options?.messageId,
13607
+ token: options?.appInstanceToken ?? data.appInstanceToken
13172
13608
  };
13173
- add("toolsetId", data.toolsetId);
13174
- add("serverName", data.serverName);
13175
- add("toolName", data.toolName);
13176
- add("toolCallId", data.toolCallId);
13177
- add("resourceUri", data.resourceUri);
13178
- add("title", typeof data.title === "string" ? data.title : void 0);
13179
- add("messageId", options?.messageId);
13180
- add("token", options?.appInstanceToken ?? data.appInstanceToken);
13181
- return params;
13182
- }
13183
- function buildMcpAppEndpointPath(data, endpoint, options) {
13184
- return appendQuery(
13185
- `/api/xpert-toolset/mcp-apps/${encodeURIComponent(
13186
- data.appInstanceId
13187
- )}/${endpoint}`,
13188
- buildMcpAppReviveParams(data, options)
13189
- );
13190
13609
  }
13191
13610
  function escapeHtmlAttribute(value) {
13192
13611
  return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
13193
13612
  }
13194
13613
  function domains(values) {
13195
- return values?.filter((value) => value.trim()).join(" ") ?? "";
13614
+ return values?.map((value) => value.trim()).filter((value) => value && !/[\s;'"<>]/.test(value)).join(" ") ?? "";
13196
13615
  }
13197
13616
  function buildCsp(csp) {
13198
13617
  const resourceDomains = domains(csp?.resourceDomains);
@@ -13207,7 +13626,9 @@ function buildCsp(csp) {
13207
13626
  `media-src data: blob: ${resourceDomains}`.trim(),
13208
13627
  `font-src data: ${resourceDomains}`.trim(),
13209
13628
  `connect-src ${connectDomains}`,
13629
+ `form-action ${connectDomains}`,
13210
13630
  `frame-src ${frameDomains}`,
13631
+ "object-src 'none'",
13211
13632
  `base-uri ${baseUriDomains}`
13212
13633
  ].join("; ");
13213
13634
  }
@@ -13293,13 +13714,14 @@ function jsonRpcResult(id, result) {
13293
13714
  result
13294
13715
  };
13295
13716
  }
13296
- function jsonRpcError(id, message) {
13717
+ function jsonRpcError(id, message, code = -32e3, data) {
13297
13718
  return {
13298
13719
  jsonrpc: "2.0",
13299
13720
  id: id ?? null,
13300
13721
  error: {
13301
- code: -32e3,
13302
- message
13722
+ code,
13723
+ message,
13724
+ ...data === void 0 ? {} : { data }
13303
13725
  }
13304
13726
  };
13305
13727
  }
@@ -13350,11 +13772,7 @@ var MCP_APP_THEME_COLOR_TOKENS = [
13350
13772
  ["--background", "--mcp-app-color-background", "oklch(1 0 0)"],
13351
13773
  ["--foreground", "--mcp-app-color-foreground", "oklch(0.145 0 0)"],
13352
13774
  ["--card", "--mcp-app-color-card", "oklch(1 0 0)"],
13353
- [
13354
- "--card-foreground",
13355
- "--mcp-app-color-card-foreground",
13356
- "oklch(0.145 0 0)"
13357
- ],
13775
+ ["--card-foreground", "--mcp-app-color-card-foreground", "oklch(0.145 0 0)"],
13358
13776
  ["--popover", "--mcp-app-color-popover", "oklch(1 0 0)"],
13359
13777
  [
13360
13778
  "--popover-foreground",
@@ -13385,11 +13803,7 @@ var MCP_APP_THEME_COLOR_TOKENS = [
13385
13803
  "--mcp-app-color-accent-foreground",
13386
13804
  "oklch(0.205 0 0)"
13387
13805
  ],
13388
- [
13389
- "--destructive",
13390
- "--mcp-app-color-destructive",
13391
- "oklch(0.577 0.245 27.325)"
13392
- ],
13806
+ ["--destructive", "--mcp-app-color-destructive", "oklch(0.577 0.245 27.325)"],
13393
13807
  [
13394
13808
  "--destructive-foreground",
13395
13809
  "--mcp-app-color-destructive-foreground",
@@ -13503,9 +13917,7 @@ function normalizeMcpAppToolInfo(value, data, resource = {}) {
13503
13917
  ...rawTool,
13504
13918
  name: originalName,
13505
13919
  title: readLocalizedText(rawTool.title) ?? title,
13506
- inputSchema: normalizeInputSchema(
13507
- rawTool.inputSchema ?? raw.inputSchema
13508
- ),
13920
+ inputSchema: normalizeInputSchema(rawTool.inputSchema ?? raw.inputSchema),
13509
13921
  ...description ? {
13510
13922
  description: readLocalizedText(rawTool.description) ?? description
13511
13923
  } : {},
@@ -13534,10 +13946,66 @@ function buildIframeAllow(permissions) {
13534
13946
  return policies.length ? policies.join("; ") : void 0;
13535
13947
  }
13536
13948
  function buildSandboxAttribute() {
13537
- return ["allow-downloads", "allow-forms", "allow-modals", "allow-scripts"].join(
13538
- " "
13949
+ return ["allow-forms", "allow-modals", "allow-scripts"].join(" ");
13950
+ }
13951
+ function isLoopbackHostname(hostname) {
13952
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
13953
+ }
13954
+ function normalizeRequestedDomain(value) {
13955
+ const domain = value?.trim().toLowerCase().replace(/\.$/, "");
13956
+ if (!domain || /[/:?#@]/.test(domain)) return null;
13957
+ try {
13958
+ const parsed = new URL(`https://${domain}`);
13959
+ return parsed.hostname === domain && !parsed.port ? domain : null;
13960
+ } catch {
13961
+ return null;
13962
+ }
13963
+ }
13964
+ function domainMatchesAllowlist(domain, allowedDomains) {
13965
+ return Boolean(
13966
+ allowedDomains?.some((value) => {
13967
+ const entry = value.trim().toLowerCase().replace(/\.$/, "");
13968
+ if (entry.startsWith("*.")) {
13969
+ const suffix = entry.slice(2);
13970
+ return Boolean(suffix) && domain !== suffix && domain.endsWith(`.${suffix}`);
13971
+ }
13972
+ return domain === entry;
13973
+ })
13539
13974
  );
13540
13975
  }
13976
+ function resolveMcpAppSandboxProxy(options, requestedDomain, hostLocation = window.location.href) {
13977
+ const configuredUrl = options?.sandboxProxyUrl?.trim();
13978
+ if (!configuredUrl) return null;
13979
+ try {
13980
+ const hostOrigin = new URL(hostLocation).origin;
13981
+ const proxyUrl = new URL(configuredUrl, hostLocation);
13982
+ if (proxyUrl.protocol !== "https:" && !(proxyUrl.protocol === "http:" && isLoopbackHostname(proxyUrl.hostname))) {
13983
+ return null;
13984
+ }
13985
+ const domain = normalizeRequestedDomain(requestedDomain);
13986
+ const dedicatedOrigin = Boolean(
13987
+ domain && (domain === proxyUrl.hostname.toLowerCase() || domainMatchesAllowlist(domain, options?.allowedDomains))
13988
+ );
13989
+ if (domain && dedicatedOrigin) {
13990
+ proxyUrl.hostname = domain;
13991
+ proxyUrl.port = "";
13992
+ }
13993
+ if (proxyUrl.origin === hostOrigin) return null;
13994
+ const fragment = new URLSearchParams(proxyUrl.hash.slice(1));
13995
+ fragment.set("parentOrigin", hostOrigin);
13996
+ proxyUrl.hash = fragment.toString();
13997
+ return {
13998
+ url: proxyUrl.toString(),
13999
+ origin: proxyUrl.origin,
14000
+ dedicatedOrigin
14001
+ };
14002
+ } catch {
14003
+ return null;
14004
+ }
14005
+ }
14006
+ function buildMcpAppInnerSandbox(dedicatedOrigin) {
14007
+ return dedicatedOrigin ? `${buildSandboxAttribute()} allow-same-origin` : buildSandboxAttribute();
14008
+ }
13541
14009
  function stringifyToolResult(value) {
13542
14010
  if (typeof value === "string") return value;
13543
14011
  try {
@@ -13660,7 +14128,7 @@ function normalizeMcpAppResourceResponse(value, data) {
13660
14128
  rawToolResult
13661
14129
  };
13662
14130
  }
13663
- function isHttpUrl(value) {
14131
+ function isHttpUrl2(value) {
13664
14132
  try {
13665
14133
  const url = new URL(value);
13666
14134
  return url.protocol === "http:" || url.protocol === "https:";
@@ -13668,91 +14136,330 @@ function isHttpUrl(value) {
13668
14136
  return false;
13669
14137
  }
13670
14138
  }
13671
- function contentBlocksToText(content) {
13672
- if (!Array.isArray(content)) return null;
13673
- const parts = content.map((item) => {
13674
- if (!isRecord5(item)) return "";
13675
- if (item.type === "text" && typeof item.text === "string") {
13676
- return item.text;
14139
+ var MCP_APP_MESSAGE_MAX_BINARY_BYTES = 25 * 1024 * 1024;
14140
+ function normalizeMcpMimeType(value, fallback) {
14141
+ const mimeType = typeof value === "string" ? value.trim() : fallback;
14142
+ return mimeType && /^[a-z0-9][a-z0-9!#$&^_.+-]*\/[a-z0-9][a-z0-9!#$&^_.+-]*$/i.test(mimeType) ? mimeType.toLowerCase() : null;
14143
+ }
14144
+ function normalizeMcpBase64(value) {
14145
+ if (typeof value !== "string") return null;
14146
+ const data = value.replace(/\s/g, "");
14147
+ if (!data || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {
14148
+ return null;
14149
+ }
14150
+ return data;
14151
+ }
14152
+ function decodedBase64Bytes(data) {
14153
+ const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
14154
+ return data.length / 4 * 3 - padding;
14155
+ }
14156
+ function mcpMessageFile(data, mimeType, name) {
14157
+ return {
14158
+ name,
14159
+ originalName: name,
14160
+ mimeType,
14161
+ fileUrl: `data:${mimeType};base64,${data}`
14162
+ };
14163
+ }
14164
+ function resourceLabel(resource) {
14165
+ const details = {
14166
+ uri: readString3(resource.uri),
14167
+ mimeType: readString3(resource.mimeType)
14168
+ };
14169
+ return `[Resource ${stringifyToolResult(details)}]`;
14170
+ }
14171
+ function resourceLinkLabel(resourceLink) {
14172
+ const details = {
14173
+ uri: readString3(resourceLink.uri),
14174
+ name: readString3(resourceLink.name),
14175
+ description: readString3(resourceLink.description),
14176
+ mimeType: readString3(resourceLink.mimeType),
14177
+ size: typeof resourceLink.size === "number" ? resourceLink.size : void 0
14178
+ };
14179
+ return `[Resource link ${stringifyToolResult(details)}]`;
14180
+ }
14181
+ function contentBlocksToChatInput(content) {
14182
+ if (!Array.isArray(content)) {
14183
+ throw new Error("ui/message content must be an array");
14184
+ }
14185
+ const text = [];
14186
+ const files = [];
14187
+ let binaryBytes = 0;
14188
+ content.forEach((item, index) => {
14189
+ if (!isRecord5(item) || typeof item.type !== "string") {
14190
+ throw new Error(`ui/message content block ${index + 1} is invalid`);
13677
14191
  }
13678
- if (item.type === "resource_link" && typeof item.uri === "string") {
13679
- return item.uri;
14192
+ if (item.type === "text") {
14193
+ if (typeof item.text !== "string") {
14194
+ throw new Error(`ui/message text block ${index + 1} is invalid`);
14195
+ }
14196
+ if (item.text.length) text.push(item.text);
14197
+ return;
13680
14198
  }
13681
14199
  if (item.type === "image" || item.type === "audio") {
13682
- return `[${item.type}]`;
13683
- }
13684
- return stringifyToolResult(item);
13685
- }).map((part) => part.trim()).filter(Boolean);
13686
- return parts.length ? parts.join("\n\n") : null;
13687
- }
14200
+ const mimeType = normalizeMcpMimeType(item.mimeType);
14201
+ const data = normalizeMcpBase64(item.data);
14202
+ if (!mimeType || !data || !mimeType.startsWith(`${item.type}/`)) {
14203
+ throw new Error(
14204
+ `ui/message ${item.type} block ${index + 1} is invalid`
14205
+ );
14206
+ }
14207
+ binaryBytes += decodedBase64Bytes(data);
14208
+ files.push(
14209
+ mcpMessageFile(data, mimeType, `mcp-app-${item.type}-${index + 1}`)
14210
+ );
14211
+ return;
14212
+ }
14213
+ if (item.type === "resource") {
14214
+ const resource = readRecord(item.resource);
14215
+ if (!resource || typeof resource.uri !== "string") {
14216
+ throw new Error(`ui/message resource block ${index + 1} is invalid`);
14217
+ }
14218
+ const label = resourceLabel(resource);
14219
+ if (typeof resource.text === "string") {
14220
+ text.push(`${label}
14221
+ ${resource.text}`);
14222
+ return;
14223
+ }
14224
+ const data = normalizeMcpBase64(resource.blob);
14225
+ const mimeType = normalizeMcpMimeType(
14226
+ resource.mimeType,
14227
+ "application/octet-stream"
14228
+ );
14229
+ if (!data || !mimeType) {
14230
+ throw new Error(`ui/message resource block ${index + 1} is invalid`);
14231
+ }
14232
+ binaryBytes += decodedBase64Bytes(data);
14233
+ text.push(label);
14234
+ files.push(
14235
+ mcpMessageFile(data, mimeType, `mcp-app-resource-${index + 1}`)
14236
+ );
14237
+ return;
14238
+ }
14239
+ if (item.type === "resource_link" && typeof item.uri === "string") {
14240
+ text.push(resourceLinkLabel(item));
14241
+ return;
14242
+ }
14243
+ throw new Error(
14244
+ `ui/message content block ${index + 1} uses an unsupported type`
14245
+ );
14246
+ });
14247
+ if (binaryBytes > MCP_APP_MESSAGE_MAX_BINARY_BYTES) {
14248
+ throw new Error("ui/message binary content exceeds the 25 MiB limit");
14249
+ }
14250
+ if (!text.length && !files.length) {
14251
+ throw new Error("ui/message content is empty");
14252
+ }
14253
+ return {
14254
+ input: text.join("\n\n"),
14255
+ files
14256
+ };
14257
+ }
13688
14258
  function isMcpAppComponentData(data) {
13689
14259
  return isRecord5(data) && data.type === "McpApp" && typeof data.appInstanceId === "string" && typeof data.resourceUri === "string";
13690
14260
  }
13691
14261
  function McpAppMessage({
13692
14262
  data,
13693
14263
  messageId,
13694
- className
14264
+ className,
14265
+ mcpApps
13695
14266
  }) {
13696
14267
  const { i18n: i18n2 } = useChatkitTranslation();
13697
- const {
13698
- apiUrl,
13699
- authenticatedFetch,
13700
- isLoading: streamIsLoading,
13701
- submit
13702
- } = useStreamContext();
14268
+ const { client, isLoading: streamIsLoading, submit } = useStreamContext();
13703
14269
  const iframeRef = React37.useRef(null);
14270
+ const appWindowRef = React37.useRef(null);
13704
14271
  const containerRef = React37.useRef(null);
13705
14272
  const initializedRef = React37.useRef(false);
13706
14273
  const sentInitialResultRef = React37.useRef(false);
13707
14274
  const modelContextRef = React37.useRef(null);
14275
+ const pendingApprovalRef = React37.useRef(null);
14276
+ const approvalActionRef = React37.useRef(null);
14277
+ const runtimeAppInstanceTokenRef = React37.useRef(
14278
+ data.appInstanceToken
14279
+ );
14280
+ const teardownGenerationRef = React37.useRef(0);
14281
+ const teardownStartedRef = React37.useRef(false);
14282
+ const activeAppInstanceIdRef = React37.useRef(data.appInstanceId);
13708
14283
  const [resource, setResource] = React37.useState(null);
13709
14284
  const [runtimeAppInstanceToken, setRuntimeAppInstanceToken] = React37.useState(data.appInstanceToken);
13710
14285
  const [srcDoc, setSrcDoc] = React37.useState(null);
13711
14286
  const [height, setHeight] = React37.useState(420);
14287
+ const [displayMode, setDisplayMode] = React37.useState("inline");
14288
+ const [pendingApproval, setPendingApproval] = React37.useState(null);
14289
+ const [approvalAction, setApprovalAction] = React37.useState(null);
14290
+ const [approvalError, setApprovalError] = React37.useState(null);
13712
14291
  const [error, setError] = React37.useState(null);
13713
14292
  const [isLoading, setIsLoading] = React37.useState(true);
13714
- const resourceUrl = React37.useMemo(
13715
- () => buildXpertApiUrl(
13716
- apiUrl,
13717
- buildMcpAppEndpointPath(data, "resource", {
13718
- messageId
13719
- })
13720
- ),
13721
- [apiUrl, data, messageId]
14293
+ const [isTornDown, setIsTornDown] = React37.useState(false);
14294
+ const sandboxProxy = React37.useMemo(
14295
+ () => resolveMcpAppSandboxProxy(mcpApps, resource?.domain ?? data.domain),
14296
+ [data.domain, mcpApps, resource?.domain]
13722
14297
  );
13723
- const rpcUrl = React37.useMemo(
13724
- () => buildXpertApiUrl(
13725
- apiUrl,
13726
- buildMcpAppEndpointPath(data, "rpc", {
13727
- appInstanceToken: runtimeAppInstanceToken,
13728
- messageId
13729
- })
13730
- ),
13731
- [apiUrl, data, messageId, runtimeAppInstanceToken]
14298
+ React37.useEffect(() => {
14299
+ runtimeAppInstanceTokenRef.current = runtimeAppInstanceToken;
14300
+ }, [runtimeAppInstanceToken]);
14301
+ const bindIframeRef = React37.useCallback(
14302
+ (iframe) => {
14303
+ iframeRef.current = iframe;
14304
+ if (iframe?.contentWindow) {
14305
+ appWindowRef.current = iframe.contentWindow;
14306
+ }
14307
+ },
14308
+ []
14309
+ );
14310
+ const postToApp = React37.useCallback(
14311
+ (message) => {
14312
+ iframeRef.current?.contentWindow?.postMessage(
14313
+ message,
14314
+ sandboxProxy?.origin ?? "*"
14315
+ );
14316
+ },
14317
+ [sandboxProxy?.origin]
13732
14318
  );
13733
- const postToApp = React37.useCallback((message) => {
13734
- iframeRef.current?.contentWindow?.postMessage(message, "*");
13735
- }, []);
13736
14319
  const callHostRpc = React37.useCallback(
13737
14320
  async (request) => {
13738
- const response = await authenticatedFetch(rpcUrl, {
13739
- method: "POST",
13740
- headers: {
13741
- "content-type": "application/json"
13742
- },
13743
- body: JSON.stringify({
14321
+ return client.mcp.apps.rpc(
14322
+ data.appInstanceId,
14323
+ {
13744
14324
  jsonrpc: "2.0",
13745
14325
  id: request.id ?? null,
13746
14326
  method: request.method,
13747
14327
  params: request.params
14328
+ },
14329
+ buildMcpAppReviveQuery(data, {
14330
+ appInstanceToken: runtimeAppInstanceToken,
14331
+ messageId
13748
14332
  })
14333
+ );
14334
+ },
14335
+ [client, data, messageId, runtimeAppInstanceToken]
14336
+ );
14337
+ const clearPendingApproval = React37.useCallback(() => {
14338
+ pendingApprovalRef.current = null;
14339
+ approvalActionRef.current = null;
14340
+ setPendingApproval(null);
14341
+ setApprovalAction(null);
14342
+ setApprovalError(null);
14343
+ }, []);
14344
+ const isSupersededStrictModeTeardown = React37.useCallback(
14345
+ (generation, appInstanceId) => teardownGenerationRef.current !== generation && activeAppInstanceIdRef.current === appInstanceId,
14346
+ []
14347
+ );
14348
+ const processHostRpcResponse = React37.useCallback(
14349
+ (request, response) => {
14350
+ const nextApproval = readMcpAppPendingApproval(response, request);
14351
+ if (nextApproval) {
14352
+ if (pendingApprovalRef.current) {
14353
+ postToApp(
14354
+ jsonRpcError(
14355
+ request.id,
14356
+ "Another MCP App approval request is already pending",
14357
+ -32004
14358
+ )
14359
+ );
14360
+ return;
14361
+ }
14362
+ pendingApprovalRef.current = nextApproval;
14363
+ setPendingApproval(nextApproval);
14364
+ setApprovalError(null);
14365
+ return;
14366
+ }
14367
+ const nextDisplayMode = readMcpAppDisplayMode(response);
14368
+ if (request.method === "ui/request-display-mode" && nextDisplayMode) {
14369
+ setDisplayMode(nextDisplayMode);
14370
+ }
14371
+ if (request.method === "ui/download-file" && isMcpAppRpcSuccess(response)) {
14372
+ try {
14373
+ triggerMcpAppDownloads(request.params);
14374
+ } catch (downloadError) {
14375
+ postToApp(
14376
+ jsonRpcError(request.id, getErrorMessage(downloadError), -32005)
14377
+ );
14378
+ return;
14379
+ }
14380
+ }
14381
+ postToApp(response);
14382
+ },
14383
+ [postToApp]
14384
+ );
14385
+ const dispatchHostRpc = React37.useCallback(
14386
+ async (request) => {
14387
+ try {
14388
+ processHostRpcResponse(request, await callHostRpc(request));
14389
+ } catch (rpcError) {
14390
+ postToApp(jsonRpcError(request.id, getErrorMessage(rpcError)));
14391
+ }
14392
+ },
14393
+ [callHostRpc, postToApp, processHostRpcResponse]
14394
+ );
14395
+ const resolvePendingApproval = React37.useCallback(
14396
+ async (action) => {
14397
+ const approval = pendingApprovalRef.current;
14398
+ if (!approval || approvalActionRef.current) return;
14399
+ if (approval.expiresAt <= Date.now()) {
14400
+ clearPendingApproval();
14401
+ postToApp(
14402
+ jsonRpcError(
14403
+ approval.request.id,
14404
+ "The MCP App approval request expired",
14405
+ -32003
14406
+ )
14407
+ );
14408
+ return;
14409
+ }
14410
+ approvalActionRef.current = action;
14411
+ setApprovalAction(action);
14412
+ setApprovalError(null);
14413
+ const query = buildMcpAppReviveQuery(data, {
14414
+ appInstanceToken: runtimeAppInstanceToken,
14415
+ messageId
13749
14416
  });
13750
- if (!response.ok) {
13751
- throw new Error(`MCP App RPC failed with ${response.status}`);
14417
+ try {
14418
+ if (action === "reject") {
14419
+ await client.mcp.apps.reject(
14420
+ data.appInstanceId,
14421
+ approval.approvalId,
14422
+ query
14423
+ );
14424
+ clearPendingApproval();
14425
+ postToApp(
14426
+ jsonRpcError(
14427
+ approval.request.id,
14428
+ "The user rejected the MCP App action",
14429
+ -32002,
14430
+ { approvalId: approval.approvalId, rejected: true }
14431
+ )
14432
+ );
14433
+ return;
14434
+ }
14435
+ await client.mcp.apps.approve(
14436
+ data.appInstanceId,
14437
+ approval.approvalId,
14438
+ query
14439
+ );
14440
+ const retryRequest = withMcpAppApprovalId(
14441
+ approval.request,
14442
+ approval.approvalId
14443
+ );
14444
+ const response = await callHostRpc(retryRequest);
14445
+ clearPendingApproval();
14446
+ processHostRpcResponse(retryRequest, response);
14447
+ } catch (approvalRequestError) {
14448
+ approvalActionRef.current = null;
14449
+ setApprovalAction(null);
14450
+ setApprovalError(getErrorMessage(approvalRequestError));
13752
14451
  }
13753
- return response.json();
13754
14452
  },
13755
- [authenticatedFetch, rpcUrl]
14453
+ [
14454
+ callHostRpc,
14455
+ clearPendingApproval,
14456
+ client,
14457
+ data,
14458
+ messageId,
14459
+ postToApp,
14460
+ processHostRpcResponse,
14461
+ runtimeAppInstanceToken
14462
+ ]
13756
14463
  );
13757
14464
  const sendInitialToolNotifications = React37.useCallback(() => {
13758
14465
  if (!initializedRef.current || sentInitialResultRef.current || !resource) {
@@ -13785,28 +14492,35 @@ function McpAppMessage({
13785
14492
  const controller = new AbortController();
13786
14493
  initializedRef.current = false;
13787
14494
  sentInitialResultRef.current = false;
14495
+ pendingApprovalRef.current = null;
14496
+ approvalActionRef.current = null;
13788
14497
  setRuntimeAppInstanceToken(data.appInstanceToken);
14498
+ runtimeAppInstanceTokenRef.current = data.appInstanceToken;
14499
+ teardownStartedRef.current = false;
14500
+ setIsTornDown(false);
14501
+ setDisplayMode("inline");
14502
+ setPendingApproval(null);
14503
+ setApprovalAction(null);
14504
+ setApprovalError(null);
13789
14505
  setIsLoading(true);
13790
14506
  setError(null);
13791
14507
  setResource(null);
13792
14508
  setSrcDoc(null);
13793
14509
  void (async () => {
13794
14510
  try {
13795
- const response = await authenticatedFetch(resourceUrl, {
13796
- signal: controller.signal
13797
- });
13798
- if (!response.ok) {
13799
- throw new Error(`MCP App resource failed with ${response.status}`);
13800
- }
13801
- const payload = await response.json();
14511
+ const payload = await client.mcp.apps.getResource(
14512
+ data.appInstanceId,
14513
+ buildMcpAppReviveQuery(data, { messageId }),
14514
+ { signal: controller.signal }
14515
+ );
13802
14516
  const normalizedResource = normalizeMcpAppResourceResponse(
13803
14517
  payload,
13804
14518
  data
13805
14519
  );
13806
14520
  setResource(normalizedResource);
13807
- setRuntimeAppInstanceToken(
13808
- normalizedResource.appInstanceToken ?? data.appInstanceToken
13809
- );
14521
+ const nextAppInstanceToken = normalizedResource.appInstanceToken ?? data.appInstanceToken;
14522
+ runtimeAppInstanceTokenRef.current = nextAppInstanceToken;
14523
+ setRuntimeAppInstanceToken(nextAppInstanceToken);
13810
14524
  const hostLocale = normalizeHostLocale(i18n2.language);
13811
14525
  setSrcDoc(
13812
14526
  injectMcpAppTheme(
@@ -13831,26 +14545,131 @@ function McpAppMessage({
13831
14545
  controller.abort();
13832
14546
  };
13833
14547
  }, [
13834
- authenticatedFetch,
14548
+ client,
13835
14549
  data,
13836
14550
  data.appInstanceId,
13837
14551
  data.appInstanceToken,
13838
14552
  data.csp,
13839
14553
  i18n2.language,
13840
- resourceUrl
14554
+ messageId
13841
14555
  ]);
14556
+ React37.useEffect(() => {
14557
+ const generation = ++teardownGenerationRef.current;
14558
+ activeAppInstanceIdRef.current = data.appInstanceId;
14559
+ return () => {
14560
+ const appWindow = appWindowRef.current;
14561
+ const appOrigin = sandboxProxy?.origin ?? "*";
14562
+ const query = buildMcpAppReviveQuery(data, {
14563
+ appInstanceToken: runtimeAppInstanceTokenRef.current,
14564
+ messageId
14565
+ });
14566
+ const approval = pendingApprovalRef.current;
14567
+ queueMicrotask(() => {
14568
+ if (isSupersededStrictModeTeardown(generation, data.appInstanceId)) {
14569
+ return;
14570
+ }
14571
+ if (teardownStartedRef.current) {
14572
+ return;
14573
+ }
14574
+ teardownStartedRef.current = true;
14575
+ try {
14576
+ appWindow?.postMessage(
14577
+ {
14578
+ jsonrpc: "2.0",
14579
+ id: `xpert-teardown-${data.appInstanceId}`,
14580
+ method: "ui/resource-teardown",
14581
+ params: { reason: "host-unmount" }
14582
+ },
14583
+ appOrigin
14584
+ );
14585
+ } catch {
14586
+ }
14587
+ void (async () => {
14588
+ if (approval) {
14589
+ await client.mcp.apps.reject(data.appInstanceId, approval.approvalId, query).catch(() => void 0);
14590
+ }
14591
+ await client.mcp.apps.teardown(data.appInstanceId, query).catch(() => void 0);
14592
+ })();
14593
+ });
14594
+ };
14595
+ }, [
14596
+ client,
14597
+ data,
14598
+ data.appInstanceId,
14599
+ isSupersededStrictModeTeardown,
14600
+ messageId,
14601
+ sandboxProxy?.origin
14602
+ ]);
14603
+ React37.useEffect(() => {
14604
+ if (!pendingApproval) return;
14605
+ const remaining = pendingApproval.expiresAt - Date.now();
14606
+ if (remaining <= 0) {
14607
+ clearPendingApproval();
14608
+ postToApp(
14609
+ jsonRpcError(
14610
+ pendingApproval.request.id,
14611
+ "The MCP App approval request expired",
14612
+ -32003
14613
+ )
14614
+ );
14615
+ return;
14616
+ }
14617
+ const timeout = window.setTimeout(() => {
14618
+ if (pendingApprovalRef.current?.approvalId !== pendingApproval.approvalId) {
14619
+ return;
14620
+ }
14621
+ clearPendingApproval();
14622
+ postToApp(
14623
+ jsonRpcError(
14624
+ pendingApproval.request.id,
14625
+ "The MCP App approval request expired",
14626
+ -32003
14627
+ )
14628
+ );
14629
+ }, remaining);
14630
+ return () => window.clearTimeout(timeout);
14631
+ }, [clearPendingApproval, pendingApproval, postToApp]);
13842
14632
  React37.useEffect(() => {
13843
14633
  sendInitialToolNotifications();
13844
14634
  }, [sendInitialToolNotifications]);
14635
+ React37.useEffect(() => {
14636
+ if (!initializedRef.current) return;
14637
+ postToApp({
14638
+ jsonrpc: "2.0",
14639
+ method: "ui/notifications/host-context-changed",
14640
+ params: {
14641
+ displayMode,
14642
+ containerDimensions: getContainerDimensions(containerRef.current)
14643
+ }
14644
+ });
14645
+ }, [displayMode, height, postToApp]);
13845
14646
  React37.useEffect(() => {
13846
14647
  const handleMessage = async (event) => {
13847
14648
  if (event.source !== iframeRef.current?.contentWindow) {
13848
14649
  return;
13849
14650
  }
14651
+ if (sandboxProxy && event.origin !== sandboxProxy.origin) {
14652
+ return;
14653
+ }
13850
14654
  const request = normalizeJsonRpcMessage(event.data);
13851
14655
  if (!request?.method) {
13852
14656
  return;
13853
14657
  }
14658
+ if (request.method === "ui/notifications/sandbox-proxy-ready" && sandboxProxy && srcDoc) {
14659
+ const permissions = resource?.permissions ?? data.permissions;
14660
+ const csp = resource?.csp ?? data.csp;
14661
+ postToApp({
14662
+ jsonrpc: "2.0",
14663
+ method: "ui/notifications/sandbox-resource-ready",
14664
+ params: {
14665
+ html: srcDoc,
14666
+ sandbox: buildMcpAppInnerSandbox(sandboxProxy.dedicatedOrigin),
14667
+ ...csp ? { csp } : {},
14668
+ ...permissions ? { permissions } : {}
14669
+ }
14670
+ });
14671
+ return;
14672
+ }
13854
14673
  if (request.method === "ui/notifications/initialized") {
13855
14674
  initializedRef.current = true;
13856
14675
  sendInitialToolNotifications();
@@ -13863,6 +14682,39 @@ function McpAppMessage({
13863
14682
  }
13864
14683
  return;
13865
14684
  }
14685
+ if (request.method === "ui/notifications/request-teardown") {
14686
+ if (teardownStartedRef.current) {
14687
+ return;
14688
+ }
14689
+ teardownStartedRef.current = true;
14690
+ postToApp({
14691
+ jsonrpc: "2.0",
14692
+ id: `xpert-teardown-${data.appInstanceId}`,
14693
+ method: "ui/resource-teardown",
14694
+ params: { reason: "app-requested" }
14695
+ });
14696
+ const query = buildMcpAppReviveQuery(data, {
14697
+ appInstanceToken: runtimeAppInstanceTokenRef.current,
14698
+ messageId
14699
+ });
14700
+ const approval = pendingApprovalRef.current;
14701
+ try {
14702
+ if (approval) {
14703
+ await client.mcp.apps.reject(
14704
+ data.appInstanceId,
14705
+ approval.approvalId,
14706
+ query
14707
+ );
14708
+ }
14709
+ await client.mcp.apps.teardown(data.appInstanceId, query);
14710
+ clearPendingApproval();
14711
+ setIsTornDown(true);
14712
+ } catch (teardownError) {
14713
+ teardownStartedRef.current = false;
14714
+ setError(getErrorMessage(teardownError));
14715
+ }
14716
+ return;
14717
+ }
13866
14718
  if (request.method === "ui/initialize") {
13867
14719
  initializedRef.current = true;
13868
14720
  const permissions = resource?.permissions ?? data.permissions;
@@ -13886,7 +14738,11 @@ function McpAppMessage({
13886
14738
  openLinks: {},
13887
14739
  logging: {},
13888
14740
  message: {
13889
- text: {}
14741
+ text: {},
14742
+ image: {},
14743
+ audio: {},
14744
+ resource: {},
14745
+ resourceLink: {}
13890
14746
  },
13891
14747
  updateModelContext: {
13892
14748
  text: {},
@@ -13895,29 +14751,33 @@ function McpAppMessage({
13895
14751
  sandbox: {
13896
14752
  ...permissions ? { permissions } : {},
13897
14753
  ...csp ? { csp } : {}
13898
- }
14754
+ },
14755
+ downloadFile: {}
13899
14756
  },
13900
14757
  hostContext: {
13901
14758
  toolInfo,
13902
14759
  theme: theme.mode,
14760
+ styles: {
14761
+ variables: theme.cssVariables
14762
+ },
13903
14763
  themeCssVariables: theme.cssVariables,
13904
14764
  locale: hostLocale,
13905
14765
  language: hostLanguage,
13906
14766
  direction: hostDirection,
13907
14767
  timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
13908
- displayMode: "inline",
13909
- availableDisplayModes: ["inline"],
14768
+ displayMode,
14769
+ availableDisplayModes: ["inline", "fullscreen", "pip"],
13910
14770
  containerDimensions: getContainerDimensions(containerRef.current),
13911
14771
  userAgent: "xpert-chatkit",
13912
14772
  platform: "web",
13913
14773
  deviceCapabilities: {
13914
14774
  touch: navigator.maxTouchPoints > 0,
13915
- hover: window.matchMedia("(hover: hover)").matches
14775
+ hover: typeof window.matchMedia === "function" ? window.matchMedia("(hover: hover)").matches : false
13916
14776
  }
13917
14777
  },
13918
14778
  // Legacy compatibility for apps written before the 2026-01-26 result shape.
13919
14779
  capabilities: {
13920
- displayModes: ["inline"],
14780
+ displayModes: ["inline", "fullscreen", "pip"],
13921
14781
  serverTools: true,
13922
14782
  serverResources: true,
13923
14783
  openLinks: true
@@ -13930,8 +14790,8 @@ function McpAppMessage({
13930
14790
  language: hostLanguage,
13931
14791
  direction: hostDirection,
13932
14792
  timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
13933
- displayMode: "inline",
13934
- availableDisplayModes: ["inline"],
14793
+ displayMode,
14794
+ availableDisplayModes: ["inline", "fullscreen", "pip"],
13935
14795
  containerDimensions: getContainerDimensions(containerRef.current),
13936
14796
  userAgent: navigator.userAgent,
13937
14797
  platform: navigator.platform
@@ -13943,20 +14803,33 @@ function McpAppMessage({
13943
14803
  }
13944
14804
  if (request.method === "ui/open-link") {
13945
14805
  const href = isRecord5(request.params) && typeof request.params.url === "string" ? request.params.url : isRecord5(request.params) && typeof request.params.href === "string" ? request.params.href : null;
13946
- if (href && isHttpUrl(href)) {
13947
- window.open(href, "_blank", "noopener,noreferrer");
14806
+ if (!href || !isHttpUrl2(href)) {
13948
14807
  if (request.id !== void 0) {
13949
- postToApp(jsonRpcResult(request.id, {}));
14808
+ postToApp(jsonRpcError(request.id, "Invalid URL"));
14809
+ }
14810
+ return;
14811
+ }
14812
+ try {
14813
+ const response = await callHostRpc({
14814
+ ...request,
14815
+ params: { url: href }
14816
+ });
14817
+ if (isMcpAppRpcSuccess(response)) {
14818
+ window.open(href, "_blank", "noopener,noreferrer");
13950
14819
  }
13951
- } else if (request.id !== void 0) {
13952
- postToApp(jsonRpcResult(request.id, { isError: true }));
14820
+ postToApp(response);
14821
+ } catch (linkError) {
14822
+ postToApp(jsonRpcError(request.id, getErrorMessage(linkError)));
13953
14823
  }
13954
14824
  return;
13955
14825
  }
13956
14826
  if (request.method === "ui/update-model-context") {
13957
- modelContextRef.current = request.params;
13958
14827
  try {
13959
- postToApp(await callHostRpc(request));
14828
+ const response = await callHostRpc(request);
14829
+ if (isMcpAppRpcSuccess(response)) {
14830
+ modelContextRef.current = request.params;
14831
+ }
14832
+ postToApp(response);
13960
14833
  } catch (rpcError) {
13961
14834
  postToApp(jsonRpcError(request.id, getErrorMessage(rpcError)));
13962
14835
  }
@@ -13974,14 +14847,12 @@ function McpAppMessage({
13974
14847
  postToApp(hostResponse);
13975
14848
  return;
13976
14849
  }
13977
- const inputText = contentBlocksToText(request.params.content);
13978
- if (!inputText) {
13979
- throw new Error("ui/message content did not include text");
13980
- }
14850
+ const messageInput = contentBlocksToChatInput(request.params.content);
13981
14851
  await submit(
13982
14852
  {
13983
14853
  input: {
13984
- input: inputText
14854
+ input: messageInput.input,
14855
+ ...messageInput.files.length ? { files: messageInput.files } : {}
13985
14856
  }
13986
14857
  },
13987
14858
  {
@@ -14006,11 +14877,7 @@ function McpAppMessage({
14006
14877
  if (request.id === void 0 && request.method.startsWith("ui/")) {
14007
14878
  return;
14008
14879
  }
14009
- try {
14010
- postToApp(await callHostRpc(request));
14011
- } catch (rpcError) {
14012
- postToApp(jsonRpcError(request.id, getErrorMessage(rpcError)));
14013
- }
14880
+ await dispatchHostRpc(request);
14014
14881
  };
14015
14882
  window.addEventListener("message", handleMessage);
14016
14883
  return () => {
@@ -14018,19 +14885,20 @@ function McpAppMessage({
14018
14885
  };
14019
14886
  }, [
14020
14887
  callHostRpc,
14021
- data.appInstanceId,
14022
- data.csp,
14023
- data.permissions,
14024
- data.resourceUri,
14025
- data.title,
14026
- data.toolCallId,
14027
- data.toolName,
14888
+ clearPendingApproval,
14889
+ client,
14890
+ data,
14891
+ dispatchHostRpc,
14892
+ displayMode,
14028
14893
  i18n2.language,
14894
+ messageId,
14029
14895
  postToApp,
14030
14896
  resource?.csp,
14031
14897
  resource?.permissions,
14032
14898
  resource?.toolInfo,
14899
+ sandboxProxy,
14033
14900
  sendInitialToolNotifications,
14901
+ srcDoc,
14034
14902
  streamIsLoading,
14035
14903
  submit
14036
14904
  ]);
@@ -14039,7 +14907,7 @@ function McpAppMessage({
14039
14907
  () => buildIframeAllow(iframePermissions),
14040
14908
  [iframePermissions]
14041
14909
  );
14042
- const sandbox = React37.useMemo(() => buildSandboxAttribute(), []);
14910
+ const sandbox = sandboxProxy ? "allow-scripts allow-same-origin" : buildSandboxAttribute();
14043
14911
  const prefersBorder = resource?.prefersBorder ?? data.prefersBorder ?? true;
14044
14912
  const displayTitle = (0, import_chatkit_types11.resolveLocalizedText)(resource?.title ?? data.title, i18n2.language) ?? data.toolName;
14045
14913
  const displayDescription = (0, import_chatkit_types11.resolveLocalizedText)(
@@ -14047,56 +14915,212 @@ function McpAppMessage({
14047
14915
  i18n2.language
14048
14916
  );
14049
14917
  const displayIcon = resource?.icon ?? data.icon;
14050
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
14051
- "div",
14052
- {
14053
- ref: containerRef,
14054
- className: cn(
14055
- "overflow-hidden rounded-lg border bg-background shadow-sm",
14056
- !prefersBorder && "border-transparent shadow-none",
14057
- className
14058
- ),
14059
- children: [
14060
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex min-h-10 items-center justify-between gap-3 border-b px-3 py-2", children: [
14061
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
14062
- displayIcon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14063
- IconDefinitionRenderer,
14064
- {
14065
- icon: displayIcon,
14066
- size: 18,
14067
- className: "shrink-0",
14068
- decorative: true
14069
- }
14070
- ) : null,
14071
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0", children: [
14072
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "truncate text-sm font-medium", children: displayTitle }),
14073
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "truncate text-[11px] text-muted-foreground", children: displayDescription ?? data.resourceUri })
14918
+ const elevatedDisplayMode = displayMode !== "inline";
14919
+ if (isTornDown) {
14920
+ return null;
14921
+ }
14922
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
14923
+ displayMode === "fullscreen" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14924
+ "div",
14925
+ {
14926
+ "aria-hidden": "true",
14927
+ className: "fixed inset-0 z-[79] bg-background/80 backdrop-blur-sm"
14928
+ }
14929
+ ) : null,
14930
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
14931
+ "div",
14932
+ {
14933
+ ref: containerRef,
14934
+ "data-display-mode": displayMode,
14935
+ className: cn(
14936
+ "relative flex flex-col overflow-hidden rounded-lg border bg-background shadow-sm",
14937
+ displayMode === "fullscreen" && "fixed inset-4 z-[80] shadow-2xl",
14938
+ displayMode === "pip" && "fixed right-4 bottom-4 z-[80] h-[min(640px,calc(100vh-2rem))] w-[min(480px,calc(100vw-2rem))] shadow-2xl",
14939
+ !prefersBorder && "border-transparent shadow-none",
14940
+ className
14941
+ ),
14942
+ children: [
14943
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex min-h-10 items-center justify-between gap-3 border-b px-3 py-2", children: [
14944
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex min-w-0 items-center gap-2", children: [
14945
+ displayIcon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14946
+ IconDefinitionRenderer,
14947
+ {
14948
+ icon: displayIcon,
14949
+ size: 18,
14950
+ className: "shrink-0",
14951
+ decorative: true
14952
+ }
14953
+ ) : null,
14954
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0", children: [
14955
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "truncate text-sm font-medium", children: displayTitle }),
14956
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "truncate text-[11px] text-muted-foreground", children: displayDescription ?? data.resourceUri })
14957
+ ] })
14958
+ ] }),
14959
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex shrink-0 items-center gap-1", children: [
14960
+ displayMode !== "fullscreen" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14961
+ Button,
14962
+ {
14963
+ type: "button",
14964
+ variant: "ghost",
14965
+ size: "icon-xs",
14966
+ title: i18n2.t("message.mcpApp.fullscreen"),
14967
+ "aria-label": i18n2.t("message.mcpApp.fullscreen"),
14968
+ onClick: () => setDisplayMode("fullscreen"),
14969
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Maximize2, {})
14970
+ }
14971
+ ) : null,
14972
+ displayMode !== "pip" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14973
+ Button,
14974
+ {
14975
+ type: "button",
14976
+ variant: "ghost",
14977
+ size: "icon-xs",
14978
+ title: i18n2.t("message.mcpApp.pictureInPicture"),
14979
+ "aria-label": i18n2.t("message.mcpApp.pictureInPicture"),
14980
+ onClick: () => setDisplayMode("pip"),
14981
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.PictureInPicture2, {})
14982
+ }
14983
+ ) : null,
14984
+ elevatedDisplayMode ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14985
+ Button,
14986
+ {
14987
+ type: "button",
14988
+ variant: "ghost",
14989
+ size: "icon-xs",
14990
+ title: i18n2.t("message.mcpApp.returnInline"),
14991
+ "aria-label": i18n2.t("message.mcpApp.returnInline"),
14992
+ onClick: () => setDisplayMode("inline"),
14993
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Minimize2, {})
14994
+ }
14995
+ ) : null,
14996
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, { variant: "secondary", className: "ml-1 rounded-md", children: "MCP App" })
14074
14997
  ] })
14075
14998
  ] }),
14076
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Badge, { variant: "secondary", className: "shrink-0 rounded-md", children: "MCP App" })
14077
- ] }),
14078
- isLoading ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex h-40 items-center justify-center gap-2 text-sm text-muted-foreground", children: [
14079
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Loader2, { className: "h-4 w-4 animate-spin" }),
14080
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: i18n2.t("message.mcpApp.loading") })
14081
- ] }) : error ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex h-40 items-center justify-center gap-2 px-4 text-sm text-destructive", children: [
14082
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.AlertCircle, { className: "h-4 w-4 shrink-0" }),
14083
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "min-w-0 break-words", children: error })
14084
- ] }) : srcDoc ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
14085
- "iframe",
14086
- {
14087
- ref: iframeRef,
14088
- title: displayTitle,
14089
- srcDoc,
14090
- className: "block w-full bg-background",
14091
- style: { height },
14092
- sandbox,
14093
- allow: iframeAllow,
14094
- referrerPolicy: "no-referrer"
14095
- }
14096
- ) : null
14097
- ]
14098
- }
14099
- );
14999
+ pendingApproval ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
15000
+ "div",
15001
+ {
15002
+ role: "alertdialog",
15003
+ "aria-modal": "true",
15004
+ "aria-labelledby": `mcp-app-approval-${pendingApproval.approvalId}`,
15005
+ className: "absolute inset-0 z-20 flex items-center justify-center bg-background/90 p-4 backdrop-blur-sm",
15006
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex max-h-full w-full max-w-lg flex-col gap-4 overflow-hidden rounded-lg border bg-background p-4 shadow-xl", children: [
15007
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-start gap-3", children: [
15008
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "rounded-full bg-destructive/10 p-2 text-destructive", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.ShieldAlert, { className: "size-5" }) }),
15009
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0 flex-1", children: [
15010
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
15011
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
15012
+ "h3",
15013
+ {
15014
+ id: `mcp-app-approval-${pendingApproval.approvalId}`,
15015
+ className: "text-sm font-semibold",
15016
+ children: i18n2.t("message.mcpApp.approvalTitle")
15017
+ }
15018
+ ),
15019
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
15020
+ Badge,
15021
+ {
15022
+ variant: "outline",
15023
+ className: "border-destructive/40 text-destructive",
15024
+ children: pendingApproval.risk
15025
+ }
15026
+ )
15027
+ ] }),
15028
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-1 text-xs text-muted-foreground", children: i18n2.t(
15029
+ pendingApproval.kind === "download" ? "message.mcpApp.downloadApprovalDescription" : "message.mcpApp.toolApprovalDescription",
15030
+ { tool: pendingApproval.toolName }
15031
+ ) })
15032
+ ] })
15033
+ ] }),
15034
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-h-0", children: [
15035
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "mb-1 text-xs font-medium", children: i18n2.t("message.mcpApp.requestDetails") }),
15036
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("pre", { className: "max-h-48 overflow-auto rounded-md border bg-muted/40 p-3 text-[11px] leading-5 whitespace-pre-wrap break-all", children: pendingApproval.details })
15037
+ ] }),
15038
+ approvalError ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
15039
+ "div",
15040
+ {
15041
+ role: "alert",
15042
+ className: "flex items-start gap-2 text-xs text-destructive",
15043
+ children: [
15044
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.AlertCircle, { className: "mt-0.5 size-4 shrink-0" }),
15045
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: approvalError })
15046
+ ]
15047
+ }
15048
+ ) : null,
15049
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex justify-end gap-2", children: [
15050
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
15051
+ Button,
15052
+ {
15053
+ type: "button",
15054
+ variant: "outline",
15055
+ disabled: approvalAction !== null,
15056
+ onClick: () => void resolvePendingApproval("reject"),
15057
+ children: [
15058
+ approvalAction === "reject" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Loader2, { className: "animate-spin" }) : null,
15059
+ i18n2.t("message.mcpApp.reject")
15060
+ ]
15061
+ }
15062
+ ),
15063
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
15064
+ Button,
15065
+ {
15066
+ type: "button",
15067
+ variant: pendingApproval.risk === "destructive" ? "destructive" : "default",
15068
+ disabled: approvalAction !== null,
15069
+ onClick: () => void resolvePendingApproval("approve"),
15070
+ children: [
15071
+ approvalAction === "approve" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Loader2, { className: "animate-spin" }) : null,
15072
+ i18n2.t("message.mcpApp.approve")
15073
+ ]
15074
+ }
15075
+ )
15076
+ ] })
15077
+ ] })
15078
+ }
15079
+ ) : null,
15080
+ isLoading ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
15081
+ "div",
15082
+ {
15083
+ className: cn(
15084
+ "flex h-40 items-center justify-center gap-2 text-sm text-muted-foreground",
15085
+ elevatedDisplayMode && "min-h-0 flex-1"
15086
+ ),
15087
+ children: [
15088
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Loader2, { className: "h-4 w-4 animate-spin" }),
15089
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: i18n2.t("message.mcpApp.loading") })
15090
+ ]
15091
+ }
15092
+ ) : error ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
15093
+ "div",
15094
+ {
15095
+ className: cn(
15096
+ "flex h-40 items-center justify-center gap-2 px-4 text-sm text-destructive",
15097
+ elevatedDisplayMode && "min-h-0 flex-1"
15098
+ ),
15099
+ children: [
15100
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.AlertCircle, { className: "h-4 w-4 shrink-0" }),
15101
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "min-w-0 break-words", children: error })
15102
+ ]
15103
+ }
15104
+ ) : srcDoc ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
15105
+ "iframe",
15106
+ {
15107
+ ref: bindIframeRef,
15108
+ title: displayTitle,
15109
+ ...sandboxProxy ? { src: sandboxProxy.url } : { srcDoc },
15110
+ className: cn(
15111
+ "block w-full bg-background",
15112
+ elevatedDisplayMode && "min-h-0 flex-1"
15113
+ ),
15114
+ style: elevatedDisplayMode ? void 0 : { height },
15115
+ sandbox,
15116
+ allow: iframeAllow,
15117
+ referrerPolicy: "no-referrer"
15118
+ }
15119
+ ) : null
15120
+ ]
15121
+ }
15122
+ )
15123
+ ] });
14100
15124
  }
14101
15125
 
14102
15126
  // src/components/thread/messages/ai.tsx
@@ -14384,7 +15408,14 @@ function renderContentItem(content, index, message, lookupMessages, options) {
14384
15408
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
14385
15409
  }
14386
15410
  if (isMcpAppComponent(content)) {
14387
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(McpAppMessage, { messageId, data: content.data }) }, content.id ?? `mcp-app-${index}`);
15411
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
15412
+ McpAppMessage,
15413
+ {
15414
+ messageId,
15415
+ data: content.data,
15416
+ mcpApps: options?.mcpApps
15417
+ }
15418
+ ) }, content.id ?? `mcp-app-${index}`);
14388
15419
  }
14389
15420
  if (getComponentMessagePresentation(content, getToolStepData(content)) === "grouped-step") {
14390
15421
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
@@ -14414,7 +15445,8 @@ function renderContentUnit(unit, message, lookupMessages, hasFollowingItem, opti
14414
15445
  isThreadRunning: options?.isThreadRunning,
14415
15446
  organizationId: options?.organizationId,
14416
15447
  apiUrl: options?.apiUrl,
14417
- isAgentOutput: options?.isAgentOutput
15448
+ isAgentOutput: options?.isAgentOutput,
15449
+ mcpApps: options?.mcpApps
14418
15450
  });
14419
15451
  }
14420
15452
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
@@ -14565,7 +15597,8 @@ function AssistantMessage({
14565
15597
  isThreadRunning,
14566
15598
  organizationId,
14567
15599
  apiUrl,
14568
- pet
15600
+ pet,
15601
+ mcpApps
14569
15602
  }) {
14570
15603
  const { t } = useChatkitTranslation();
14571
15604
  const renderTree = buildAssistantRenderTree(
@@ -14581,7 +15614,8 @@ function AssistantMessage({
14581
15614
  const answerNode = renderContent(message, lookupMessages, {
14582
15615
  isThreadRunning,
14583
15616
  organizationId,
14584
- apiUrl
15617
+ apiUrl,
15618
+ mcpApps
14585
15619
  });
14586
15620
  const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ReasoningBlock, { reasoning: rootReasoning ?? [] }) : null;
14587
15621
  if (!hasContent && !hasReasoning && !resolvedStreamingStatus) return null;
@@ -20498,7 +21532,8 @@ function Chat({
20498
21532
  isThreadRunning: currentThreadIsRunning,
20499
21533
  organizationId: stream.organizationId,
20500
21534
  apiUrl: stream.apiUrl,
20501
- pet: effectivePet
21535
+ pet: effectivePet,
21536
+ mcpApps: options?.mcpApps
20502
21537
  }
20503
21538
  ) : /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
20504
21539
  message.type === "human" && humanRuntimeCapabilityOptions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(