@xpert-ai/chatkit-ui 0.1.2 → 0.2.1

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 (336) hide show
  1. package/dist/app/assets/{_baseUniq-Cjg58ynO.js → _baseUniq-DjDJDknP.js} +1 -1
  2. package/dist/app/assets/{abap-CaHNU3KZ.js → abap-DPo8aeMN.js} +1 -1
  3. package/dist/app/assets/{abnf-D-YMXYdM.js → abnf-DItAQ69V.js} +1 -1
  4. package/dist/app/assets/{actionscript-CrHB5nA4.js → actionscript-BdYHRTug.js} +1 -1
  5. package/dist/app/assets/{ada-Dv2nikaa.js → ada-CTvDjLKy.js} +1 -1
  6. package/dist/app/assets/{agda-DFaAW7Yp.js → agda-tRIdddX6.js} +1 -1
  7. package/dist/app/assets/{al-CgiCJJan.js → al-CNKnxyKB.js} +1 -1
  8. package/dist/app/assets/{antlr4-BtYcfzHN.js → antlr4-CpUCFz5F.js} +1 -1
  9. package/dist/app/assets/{apacheconf-CQ7_TaHr.js → apacheconf-C2EcJfTU.js} +1 -1
  10. package/dist/app/assets/{apex-B4zhZGbX.js → apex-DRUs6ylC.js} +1 -1
  11. package/dist/app/assets/{apl-CYl9UMD4.js → apl-DCVKciBu.js} +1 -1
  12. package/dist/app/assets/{applescript-CqOg5uaM.js → applescript-B_Iw1rRk.js} +1 -1
  13. package/dist/app/assets/{aql-g4FQmCtN.js → aql-JwFBm7ZE.js} +1 -1
  14. package/dist/app/assets/{arc-Dg9GdpOd.js → arc-DSexTIIn.js} +1 -1
  15. package/dist/app/assets/{architectureDiagram-Q4EWVU46-D_Hf6A9k.js → architectureDiagram-Q4EWVU46-CxzYOKwD.js} +1 -1
  16. package/dist/app/assets/{arduino-CLAoEDGh.js → arduino-CrjtgA95.js} +1 -1
  17. package/dist/app/assets/{arff-CkPQOMpJ.js → arff-DA_pRZWv.js} +1 -1
  18. package/dist/app/assets/{asciidoc-D6FBYhU4.js → asciidoc-BIUjEl5r.js} +1 -1
  19. package/dist/app/assets/{asm6502-BNREQutf.js → asm6502-BUCQFCP4.js} +1 -1
  20. package/dist/app/assets/{asmatmel-AsGe04C5.js → asmatmel-CXYGWrAF.js} +1 -1
  21. package/dist/app/assets/{aspnet-BowT6uwS.js → aspnet-qR1U_Qy7.js} +1 -1
  22. package/dist/app/assets/{autohotkey-CYQjpY2v.js → autohotkey-2kKLAV5B.js} +1 -1
  23. package/dist/app/assets/{autoit-DZuwPYYs.js → autoit-BIYajj8Z.js} +1 -1
  24. package/dist/app/assets/{avisynth-BApmLDkf.js → avisynth-DJczZ-4A.js} +1 -1
  25. package/dist/app/assets/{avro-idl-DTdqv6Sr.js → avro-idl-1MqfEJSc.js} +1 -1
  26. package/dist/app/assets/{bash-COtf9s5e.js → bash-CJd1ZImg.js} +1 -1
  27. package/dist/app/assets/{basic-0Wk0Z9hh.js → basic-0Q2pqOdz.js} +1 -1
  28. package/dist/app/assets/{batch-yLGV74r2.js → batch-Cm2YtExp.js} +1 -1
  29. package/dist/app/assets/{bbcode-gj0k8ZdD.js → bbcode-DaLsd2mZ.js} +1 -1
  30. package/dist/app/assets/{bicep-BsCXg-ZU.js → bicep-BLql0iFA.js} +1 -1
  31. package/dist/app/assets/{birb-CrVXepVH.js → birb-DbnyW-bu.js} +1 -1
  32. package/dist/app/assets/{bison-CEkN9m61.js → bison-LYQm7vu0.js} +1 -1
  33. package/dist/app/assets/{blockDiagram-DXYQGD6D-Cxg7TJzM.js → blockDiagram-DXYQGD6D-CKgeWXtO.js} +1 -1
  34. package/dist/app/assets/{bnf-BNo5FkNz.js → bnf-B8Oqigof.js} +1 -1
  35. package/dist/app/assets/{brainfuck-Be3VzThb.js → brainfuck-BxGqxlw9.js} +1 -1
  36. package/dist/app/assets/{brightscript-DvlnFSog.js → brightscript-CgO16qEC.js} +1 -1
  37. package/dist/app/assets/{bro-v-4Gv7xz.js → bro-Dxozdcrd.js} +1 -1
  38. package/dist/app/assets/{bsl-Ckf08F6h.js → bsl-Zfb17ZNj.js} +1 -1
  39. package/dist/app/assets/{c-DzIU03a7.js → c-B5XMBaN0.js} +1 -1
  40. package/dist/app/assets/{c4Diagram-AHTNJAMY-ClK737fG.js → c4Diagram-AHTNJAMY-C2DBvHAc.js} +1 -1
  41. package/dist/app/assets/{cfscript-BjMiAM6E.js → cfscript-qexL9CgG.js} +1 -1
  42. package/dist/app/assets/{chaiscript-B43Wj-Sh.js → chaiscript-w-D4zmls.js} +1 -1
  43. package/dist/app/assets/channel-I2WfbmP0.js +1 -0
  44. package/dist/app/assets/{chunk-4BX2VUAB-CLpouVUP.js → chunk-4BX2VUAB-ChDIxBCH.js} +1 -1
  45. package/dist/app/assets/{chunk-4TB4RGXK-Bx935_8R.js → chunk-4TB4RGXK-DujfsOdS.js} +1 -1
  46. package/dist/app/assets/{chunk-55IACEB6-BBvPym8v.js → chunk-55IACEB6-DMXgKWZG.js} +1 -1
  47. package/dist/app/assets/{chunk-EDXVE4YY-DjPOkQ8M.js → chunk-EDXVE4YY-CRwseUBb.js} +1 -1
  48. package/dist/app/assets/{chunk-FMBD7UC4-DYYB_Z9z.js → chunk-FMBD7UC4-976Un_io.js} +1 -1
  49. package/dist/app/assets/{chunk-OYMX7WX6-D6RNfja3.js → chunk-OYMX7WX6-D4LkKrJk.js} +1 -1
  50. package/dist/app/assets/{chunk-QZHKN3VN-C8ZgdC9O.js → chunk-QZHKN3VN-Cq9HBkgP.js} +1 -1
  51. package/dist/app/assets/{chunk-YZCP3GAM-BBgDUOse.js → chunk-YZCP3GAM-LMrtjFPL.js} +1 -1
  52. package/dist/app/assets/{cil-B9ihzdF2.js → cil-DwcP6qEs.js} +1 -1
  53. package/dist/app/assets/classDiagram-6PBFFD2Q-Db-erkl6.js +1 -0
  54. package/dist/app/assets/classDiagram-v2-HSJHXN6E-Db-erkl6.js +1 -0
  55. package/dist/app/assets/{clike-CJh4oCgy.js → clike-DxK6-CnR.js} +1 -1
  56. package/dist/app/assets/{clojure-TlSbaE4l.js → clojure-P1KYiT60.js} +1 -1
  57. package/dist/app/assets/clone-DL9Z_j2z.js +1 -0
  58. package/dist/app/assets/{cmake-BSn84SxA.js → cmake-CBrxNq-v.js} +1 -1
  59. package/dist/app/assets/{cobol-CJ6-cTtI.js → cobol-Dv9E1h9p.js} +1 -1
  60. package/dist/app/assets/{coffeescript-stKJEoMv.js → coffeescript-BkxOEcZ3.js} +1 -1
  61. package/dist/app/assets/{concurnas-1ifwVnR3.js → concurnas-GoyqzOta.js} +1 -1
  62. package/dist/app/assets/{coq-DVFU6UV7.js → coq-DXGqnMrQ.js} +1 -1
  63. package/dist/app/assets/{core-Yh44uZBs.js → core-C0zhR2T4.js} +1 -1
  64. package/dist/app/assets/{cose-bilkent-S5V4N54A-Dx7-_QHb.js → cose-bilkent-S5V4N54A-BgdqFuQe.js} +1 -1
  65. package/dist/app/assets/{cpp-Zzzi5FD8.js → cpp-D5unPdEV.js} +1 -1
  66. package/dist/app/assets/{crystal-DDbZAA_E.js → crystal-CTnUqXD-.js} +1 -1
  67. package/dist/app/assets/{csharp-BZcvKq6n.js → csharp-Bmq2VPH_.js} +1 -1
  68. package/dist/app/assets/{cshtml-9x1DpGIK.js → cshtml-CQUtsyr6.js} +1 -1
  69. package/dist/app/assets/{csp-D1hHVDgG.js → csp-C6_Zu1Wk.js} +1 -1
  70. package/dist/app/assets/{css-BFu7Iqqk.js → css-BE3cxWwI.js} +1 -1
  71. package/dist/app/assets/{css-extras-COx1Ei_l.js → css-extras-Cl6JFry0.js} +1 -1
  72. package/dist/app/assets/{csv-D0CxHXjS.js → csv-DITjzlsd.js} +1 -1
  73. package/dist/app/assets/{cypher-BsuAyRBu.js → cypher-Dzoi6D-N.js} +1 -1
  74. package/dist/app/assets/{d-CtjOdpDZ.js → d-Dh7JHoUe.js} +1 -1
  75. package/dist/app/assets/{dagre-KV5264BT-DjhJCF-B.js → dagre-KV5264BT-bk_4RoUT.js} +1 -1
  76. package/dist/app/assets/{dart-BN9c8RLX.js → dart-Dm__OfR-.js} +1 -1
  77. package/dist/app/assets/{dataweave-DzlUCFjQ.js → dataweave-TbAFxqZB.js} +1 -1
  78. package/dist/app/assets/{dax-D0KU-54t.js → dax-DF0ERzw9.js} +1 -1
  79. package/dist/app/assets/{dhall-BZJS2G5U.js → dhall-CCFJPydK.js} +1 -1
  80. package/dist/app/assets/{diagram-5BDNPKRD-DSws8TSr.js → diagram-5BDNPKRD-DU_4LeyG.js} +1 -1
  81. package/dist/app/assets/{diagram-G4DWMVQ6-Cx7BBH89.js → diagram-G4DWMVQ6-VBhcxXO0.js} +1 -1
  82. package/dist/app/assets/{diagram-MMDJMWI5-D9n-fpq5.js → diagram-MMDJMWI5-CKXJ9_Cn.js} +1 -1
  83. package/dist/app/assets/{diagram-TYMM5635-A2Du0da2.js → diagram-TYMM5635-6p0LeAd3.js} +1 -1
  84. package/dist/app/assets/{diff-2klWb1Uo.js → diff-EAfMrhpZ.js} +1 -1
  85. package/dist/app/assets/{django-B2AbqJYz.js → django-BbGcgP3D.js} +1 -1
  86. package/dist/app/assets/{dns-zone-file-CvZSGx-4.js → dns-zone-file-BN8aKp63.js} +1 -1
  87. package/dist/app/assets/{docker-Cn7U_QhX.js → docker-DTWwH6SY.js} +1 -1
  88. package/dist/app/assets/{dot-B8xtegaK.js → dot-B8GKB0JW.js} +1 -1
  89. package/dist/app/assets/{ebnf-oe3GchaY.js → ebnf-t-QIXi58.js} +1 -1
  90. package/dist/app/assets/{editorconfig-BcXP_CBv.js → editorconfig-CUI1AGkb.js} +1 -1
  91. package/dist/app/assets/{eiffel-2H-hw0_M.js → eiffel-f3za8eTF.js} +1 -1
  92. package/dist/app/assets/{ejs-Ba0Dl3hs.js → ejs-DhRELYtk.js} +1 -1
  93. package/dist/app/assets/{elixir-Zqex1hfd.js → elixir-CxWG1M_v.js} +1 -1
  94. package/dist/app/assets/{elm-BaLOxH54.js → elm-DhmBsMbT.js} +1 -1
  95. package/dist/app/assets/{erDiagram-SMLLAGMA-lphP26u7.js → erDiagram-SMLLAGMA-BILcA9ct.js} +1 -1
  96. package/dist/app/assets/{erb-D4zKB7vm.js → erb-CCixIXZv.js} +1 -1
  97. package/dist/app/assets/{erlang-hK3qlNLz.js → erlang-C6duVw02.js} +1 -1
  98. package/dist/app/assets/{etlua-DmORWQ6o.js → etlua-BeYqrSfo.js} +1 -1
  99. package/dist/app/assets/{excel-formula-Dyve7tHx.js → excel-formula-eG-WgOzN.js} +1 -1
  100. package/dist/app/assets/{factor-aKN6m8fH.js → factor-vSUmFel1.js} +1 -1
  101. package/dist/app/assets/{false-CIRDgfm3.js → false-DXguR4QH.js} +1 -1
  102. package/dist/app/assets/{firestore-security-rules-D8Ht8z5e.js → firestore-security-rules-Iwmv7KsC.js} +1 -1
  103. package/dist/app/assets/{flow-CoMa0rFO.js → flow-V33hHLmJ.js} +1 -1
  104. package/dist/app/assets/{flowDiagram-DWJPFMVM-BLg6doOr.js → flowDiagram-DWJPFMVM-DUYGNTIn.js} +1 -1
  105. package/dist/app/assets/{fortran-CN_uZJ_i.js → fortran-BR84kKl5.js} +1 -1
  106. package/dist/app/assets/{fsharp-C9nE9g7s.js → fsharp-dAAws-8r.js} +1 -1
  107. package/dist/app/assets/{ftl-DvqhmJFJ.js → ftl-5ZQIEjSC.js} +1 -1
  108. package/dist/app/assets/{ganttDiagram-T4ZO3ILL-20MMEZeq.js → ganttDiagram-T4ZO3ILL-CGLdmk8v.js} +1 -1
  109. package/dist/app/assets/{gap-ChJ4bKbS.js → gap-C6w9gcUj.js} +1 -1
  110. package/dist/app/assets/{gcode-D6-Q_Sls.js → gcode-CmkK9ubl.js} +1 -1
  111. package/dist/app/assets/{gdscript-uy9Z57J0.js → gdscript-D20eyBsk.js} +1 -1
  112. package/dist/app/assets/{gedcom-DKejVBFQ.js → gedcom-CLUGQRYt.js} +1 -1
  113. package/dist/app/assets/{gherkin-D309wbrl.js → gherkin-Dj_g6wb4.js} +1 -1
  114. package/dist/app/assets/{git-CXyU-4Kx.js → git-CTLh9jzG.js} +1 -1
  115. package/dist/app/assets/{gitGraphDiagram-UUTBAWPF-CdbhEKk_.js → gitGraphDiagram-UUTBAWPF-B6MbvuO1.js} +1 -1
  116. package/dist/app/assets/{glsl-CUHcECEi.js → glsl-TJ_JJUlS.js} +1 -1
  117. package/dist/app/assets/{gml-BYJwp8Mq.js → gml-FbXn9v6F.js} +1 -1
  118. package/dist/app/assets/{gn-C5jDEgl-.js → gn-1RBBsMuH.js} +1 -1
  119. package/dist/app/assets/{go-4DBR4Ukq.js → go-C-YjWLK5.js} +1 -1
  120. package/dist/app/assets/{go-module-BDCY5HMb.js → go-module-CFaiQzgE.js} +1 -1
  121. package/dist/app/assets/{graph-CasqcucB.js → graph-CXw0D5Yr.js} +1 -1
  122. package/dist/app/assets/{graphql-CUOhePaJ.js → graphql-BVO_hekT.js} +1 -1
  123. package/dist/app/assets/{groovy-C6NRtaMF.js → groovy-BUAS4Wg0.js} +1 -1
  124. package/dist/app/assets/{haml-CeFDFdq_.js → haml-Qy4YiCUH.js} +1 -1
  125. package/dist/app/assets/{handlebars-Diav69MK.js → handlebars-Bcd-RM3T.js} +1 -1
  126. package/dist/app/assets/{haskell-BRtS7ZYk.js → haskell-CQzCy-aa.js} +1 -1
  127. package/dist/app/assets/{haxe-okolorzn.js → haxe-B9BcN22a.js} +1 -1
  128. package/dist/app/assets/{hcl-DUovHBmz.js → hcl-Dc7Ww6Pl.js} +1 -1
  129. package/dist/app/assets/{hlsl-Est_RcA2.js → hlsl-BqEOZLdU.js} +1 -1
  130. package/dist/app/assets/{hoon-BiOVdLrI.js → hoon-Cdd1-GTN.js} +1 -1
  131. package/dist/app/assets/{hpkp-Bm0WuAFk.js → hpkp-CK-Y8jcj.js} +1 -1
  132. package/dist/app/assets/{hsts-CbOaMMM4.js → hsts-Cwm_jZ-H.js} +1 -1
  133. package/dist/app/assets/{http-D0tGKTH_.js → http-DK-bwroV.js} +1 -1
  134. package/dist/app/assets/{ichigojam-WTyjHjN0.js → ichigojam-BMiCcoiC.js} +1 -1
  135. package/dist/app/assets/{icon-Bcw6nO7C.js → icon-CNlxFQam.js} +1 -1
  136. package/dist/app/assets/{icu-message-format-1IVITSOw.js → icu-message-format-B8mMxBdM.js} +1 -1
  137. package/dist/app/assets/{idris-DGiKWxqv.js → idris-Dn9mqH8n.js} +1 -1
  138. package/dist/app/assets/{iecst-_G6fk-6o.js → iecst-DJsoTR-l.js} +1 -1
  139. package/dist/app/assets/{ignore-CGGRjy1I.js → ignore-CHIu0KyT.js} +1 -1
  140. package/dist/app/assets/index-WnsnYyX3.css +1 -0
  141. package/dist/app/assets/{index-BnLZxiSt.js → index-eGI3KklD.js} +179 -175
  142. package/dist/app/assets/{infoDiagram-42DDH7IO-DNXFcEYI.js → infoDiagram-42DDH7IO-Cq_EOn7_.js} +1 -1
  143. package/dist/app/assets/{inform7-DJNO-7Vs.js → inform7-BGRW_5ui.js} +1 -1
  144. package/dist/app/assets/{ini-BXxeA4dZ.js → ini-Dty7p-HN.js} +1 -1
  145. package/dist/app/assets/{io-CZYqA1fa.js → io-nGm8aVJj.js} +1 -1
  146. package/dist/app/assets/{ishikawaDiagram-UXIWVN3A-1FFzVMOS.js → ishikawaDiagram-UXIWVN3A-EOg1GeEY.js} +1 -1
  147. package/dist/app/assets/{j-CLXGTuej.js → j-sWjIzRdE.js} +1 -1
  148. package/dist/app/assets/{java-DgCJQY9_.js → java-B4b3mYVb.js} +1 -1
  149. package/dist/app/assets/{javadoc-rf7ABQVy.js → javadoc-Buz7JqXj.js} +1 -1
  150. package/dist/app/assets/{javadoclike-BhPYSoi1.js → javadoclike-DbIV1Ueb.js} +1 -1
  151. package/dist/app/assets/{javascript-DOESY9kn.js → javascript-BMPS4k3y.js} +1 -1
  152. package/dist/app/assets/{javastacktrace-B40tpYFc.js → javastacktrace-ekAa_8YN.js} +1 -1
  153. package/dist/app/assets/{jexl-CVSwBfWj.js → jexl-Dr6P6jaZ.js} +1 -1
  154. package/dist/app/assets/{jolie-CuMdzw00.js → jolie-n4GrIS6v.js} +1 -1
  155. package/dist/app/assets/{journeyDiagram-VCZTEJTY-DCh9QB_1.js → journeyDiagram-VCZTEJTY-ABN37ufm.js} +1 -1
  156. package/dist/app/assets/{jq-rSPG4wjz.js → jq-DEM5zRoR.js} +1 -1
  157. package/dist/app/assets/{js-extras-DtC7d85t.js → js-extras-CL8cNmmW.js} +1 -1
  158. package/dist/app/assets/{js-templates-BkzRtF3M.js → js-templates-BLPx99vW.js} +1 -1
  159. package/dist/app/assets/{jsdoc-CdEDtKIx.js → jsdoc-C5_qcUBx.js} +1 -1
  160. package/dist/app/assets/{json-DFUISOXb.js → json-DUl0SmcN.js} +1 -1
  161. package/dist/app/assets/{json5-DDXB8kVt.js → json5-8QPAZKDX.js} +1 -1
  162. package/dist/app/assets/{jsonp-B6KceYOu.js → jsonp-DbDSWMi-.js} +1 -1
  163. package/dist/app/assets/{jsstacktrace-BmLmkRns.js → jsstacktrace-CIkbUyNo.js} +1 -1
  164. package/dist/app/assets/{jsx-tZerg2PH.js → jsx-wP0A_rPl.js} +1 -1
  165. package/dist/app/assets/{julia-Bc1WscpO.js → julia-BeWxWQCi.js} +1 -1
  166. package/dist/app/assets/{kanban-definition-6JOO6SKY-BG2AO71l.js → kanban-definition-6JOO6SKY-DEta7KcD.js} +1 -1
  167. package/dist/app/assets/{keepalived-C-VxfNGq.js → keepalived-DyktRD_U.js} +1 -1
  168. package/dist/app/assets/{keyman-EjQIu4mX.js → keyman-wj7jEm-s.js} +1 -1
  169. package/dist/app/assets/{kotlin-CQALgAA5.js → kotlin-CGacKMU9.js} +1 -1
  170. package/dist/app/assets/{kumir-7Nk84McD.js → kumir-BxspyeXR.js} +1 -1
  171. package/dist/app/assets/{kusto-DaP91ut7.js → kusto-CF68mXGU.js} +1 -1
  172. package/dist/app/assets/{latex-DjQNRo9H.js → latex-CzdrimVi.js} +1 -1
  173. package/dist/app/assets/{latte-5JEuNRoR.js → latte-Bl2C83rq.js} +1 -1
  174. package/dist/app/assets/{layout-FVsf45l9.js → layout-C5gS1MJ_.js} +1 -1
  175. package/dist/app/assets/{less-8yUOsL09.js → less-Z0NQzi0y.js} +1 -1
  176. package/dist/app/assets/{lilypond-COsmQkBk.js → lilypond-B7Piaiq8.js} +1 -1
  177. package/dist/app/assets/{linear-C_63YKi4.js → linear-D15dsZdq.js} +1 -1
  178. package/dist/app/assets/{liquid--Ji9gJSD.js → liquid-BErTtHCN.js} +1 -1
  179. package/dist/app/assets/{lisp-DuUkFEfd.js → lisp-B5FC87aY.js} +1 -1
  180. package/dist/app/assets/{livescript-Cs6PchSa.js → livescript-CpvoDKMe.js} +1 -1
  181. package/dist/app/assets/{llvm-COqWFLYS.js → llvm-DjeYSSkR.js} +1 -1
  182. package/dist/app/assets/{log-C8QHMZzv.js → log-BF0e-Fh-.js} +1 -1
  183. package/dist/app/assets/{lolcode-BIsqHJ6H.js → lolcode-C2qA8CWO.js} +1 -1
  184. package/dist/app/assets/{lua-Ds7uGUxB.js → lua-DlgMudiD.js} +1 -1
  185. package/dist/app/assets/{magma-DLHoFFMW.js → magma-B4XiVcsd.js} +1 -1
  186. package/dist/app/assets/{makefile-CW_5azpn.js → makefile-Cn_XGBbt.js} +1 -1
  187. package/dist/app/assets/{markdown-wU5DnlD5.js → markdown-C5RZUICZ.js} +1 -1
  188. package/dist/app/assets/{markup-BjK1nSyh.js → markup-BFHDnsfK.js} +1 -1
  189. package/dist/app/assets/{markup-templating-CfGV0lcD.js → markup-templating-BqT0J8rO.js} +1 -1
  190. package/dist/app/assets/{matlab-Bs2eP0LD.js → matlab-CkOIgInm.js} +1 -1
  191. package/dist/app/assets/{maxscript-D8jwXiPi.js → maxscript-BMihm--T.js} +1 -1
  192. package/dist/app/assets/{mel-Cmbsj11e.js → mel-C9-ARSBL.js} +1 -1
  193. package/dist/app/assets/{mermaid-C-cxdm_P.js → mermaid-Dh7wJQes.js} +1 -1
  194. package/dist/app/assets/{min-BctQ8xDj.js → min-DRiUhcT9.js} +1 -1
  195. package/dist/app/assets/{mindmap-definition-QFDTVHPH-DHcgEjW6.js → mindmap-definition-QFDTVHPH-BaRYeeuH.js} +1 -1
  196. package/dist/app/assets/{mizar-Ca1dbNOh.js → mizar-D_uPuLl-.js} +1 -1
  197. package/dist/app/assets/{mongodb-BocaDOlW.js → mongodb-CfiFIKAd.js} +1 -1
  198. package/dist/app/assets/{monkey-BLhpedmj.js → monkey-CGJzbD7X.js} +1 -1
  199. package/dist/app/assets/{moonscript-CElpz-Ug.js → moonscript-Cy8zBltH.js} +1 -1
  200. package/dist/app/assets/{n1ql-CwNqjlWA.js → n1ql-CHadyFxK.js} +1 -1
  201. package/dist/app/assets/{n4js-B1i6cZX9.js → n4js-RZ4BbLfi.js} +1 -1
  202. package/dist/app/assets/{nand2tetris-hdl-DO01eHXa.js → nand2tetris-hdl-PXu971bJ.js} +1 -1
  203. package/dist/app/assets/{naniscript-C86I87cR.js → naniscript-CPWkgBBc.js} +1 -1
  204. package/dist/app/assets/{nasm-X9SuO04-.js → nasm-BqZzts_G.js} +1 -1
  205. package/dist/app/assets/{neon-Cb3VrB_2.js → neon-BMj8pBAA.js} +1 -1
  206. package/dist/app/assets/{nevod-BiEf92s6.js → nevod-Do6xNQ2C.js} +1 -1
  207. package/dist/app/assets/{nginx-CUAldmyK.js → nginx-DTMznJBr.js} +1 -1
  208. package/dist/app/assets/{nim-CicsGaXu.js → nim-6hqZHqFQ.js} +1 -1
  209. package/dist/app/assets/{nix-CqX4i_yR.js → nix-BSBZmGxO.js} +1 -1
  210. package/dist/app/assets/{nsis-TyCoq1Up.js → nsis-BftPEXyQ.js} +1 -1
  211. package/dist/app/assets/{objectivec-COzECw8M.js → objectivec-DhUoID0Z.js} +1 -1
  212. package/dist/app/assets/{ocaml-CouJ1SZ_.js → ocaml-AkCn2kvI.js} +1 -1
  213. package/dist/app/assets/{opencl-BNCeQsDQ.js → opencl-BivOJE6M.js} +1 -1
  214. package/dist/app/assets/{openqasm-DX-rtDDv.js → openqasm-BlSs1AmW.js} +1 -1
  215. package/dist/app/assets/{oz-CAFaEfY9.js → oz-Bym5cXDj.js} +1 -1
  216. package/dist/app/assets/{parigp-DTj7bCjF.js → parigp-BkRtiOM-.js} +1 -1
  217. package/dist/app/assets/{parser-Dw8xYjDE.js → parser-CA7NSpGA.js} +1 -1
  218. package/dist/app/assets/{pascal-rnwnKrYC.js → pascal-CM4poSN0.js} +1 -1
  219. package/dist/app/assets/{pascaligo-x1XdfDyr.js → pascaligo-Bpba3Rl0.js} +1 -1
  220. package/dist/app/assets/{pcaxis-2ZAgxxTO.js → pcaxis-DZlNK03d.js} +1 -1
  221. package/dist/app/assets/{peoplecode-pTltM-sq.js → peoplecode-BJT0sgl4.js} +1 -1
  222. package/dist/app/assets/{perl-CdAlw2Ho.js → perl-DLtaUkDF.js} +1 -1
  223. package/dist/app/assets/{php-C2mFD2oC.js → php-9ma7CzKS.js} +1 -1
  224. package/dist/app/assets/{php-extras-D7Zt-ImZ.js → php-extras-qmE7vWwu.js} +1 -1
  225. package/dist/app/assets/{phpdoc-C1kmfh9i.js → phpdoc-Cqawu6Bk.js} +1 -1
  226. package/dist/app/assets/{pieDiagram-DEJITSTG-B_eQU9Uk.js → pieDiagram-DEJITSTG-CvdaQ5Ac.js} +1 -1
  227. package/dist/app/assets/{plsql-Im5gOG9c.js → plsql-DYWwpfKm.js} +1 -1
  228. package/dist/app/assets/{powerquery-poq2eyPm.js → powerquery-BPQGe3-J.js} +1 -1
  229. package/dist/app/assets/{powershell-DJ56nmEi.js → powershell-DZU8FXkW.js} +1 -1
  230. package/dist/app/assets/{processing-Bn-H7mMf.js → processing-Dwwck8wV.js} +1 -1
  231. package/dist/app/assets/{prolog-BCb-6dWU.js → prolog-CZ-KYL5V.js} +1 -1
  232. package/dist/app/assets/{promql-CtbjoMKF.js → promql-BnP-xLEb.js} +1 -1
  233. package/dist/app/assets/{properties-CU4TDD4l.js → properties-B143VHj7.js} +1 -1
  234. package/dist/app/assets/{protobuf-_Q2Yj86k.js → protobuf-Be9Wodbr.js} +1 -1
  235. package/dist/app/assets/{psl-DqN21NC_.js → psl-D2xeX54G.js} +1 -1
  236. package/dist/app/assets/{pug-DAgKMecD.js → pug-CiynK7Kx.js} +1 -1
  237. package/dist/app/assets/{puppet-Cc2ljXH1.js → puppet-Yj6DP7-S.js} +1 -1
  238. package/dist/app/assets/{pure-B0x_E1bn.js → pure-CBoFyyui.js} +1 -1
  239. package/dist/app/assets/{purebasic-DcsxzNqC.js → purebasic-D5BrqSvf.js} +1 -1
  240. package/dist/app/assets/{purescript-Cc11iskN.js → purescript-D4qa92Rr.js} +1 -1
  241. package/dist/app/assets/{q-SRKQXeFP.js → q-BvRLzO7z.js} +1 -1
  242. package/dist/app/assets/{qml-COWYdH0A.js → qml-DtRZE43X.js} +1 -1
  243. package/dist/app/assets/{qore-AdoWA6sw.js → qore-qpL3ZEhe.js} +1 -1
  244. package/dist/app/assets/{qsharp-k5lgGfSV.js → qsharp-CnYeogsj.js} +1 -1
  245. package/dist/app/assets/{quadrantDiagram-34T5L4WZ-U_BUH870.js → quadrantDiagram-34T5L4WZ-BxN852yx.js} +1 -1
  246. package/dist/app/assets/{r-Bmcjr3EC.js → r-DikIVlfO.js} +1 -1
  247. package/dist/app/assets/{racket-506ZDFuM.js → racket-B2ofSyK7.js} +1 -1
  248. package/dist/app/assets/{reason-BngsaqkW.js → reason-CG8dmvmL.js} +1 -1
  249. package/dist/app/assets/{regex-BC6jlFZr.js → regex-CnDY2T_v.js} +1 -1
  250. package/dist/app/assets/{rego-BYCQ91X3.js → rego-DsHFNhVK.js} +1 -1
  251. package/dist/app/assets/{renpy-D95h89N9.js → renpy-BikJUsIE.js} +1 -1
  252. package/dist/app/assets/{requirementDiagram-MS252O5E-CWAV9Lki.js → requirementDiagram-MS252O5E-B0sAAcxL.js} +1 -1
  253. package/dist/app/assets/{rest-DiYuUdld.js → rest-BXVEr7Gd.js} +1 -1
  254. package/dist/app/assets/{rip-B1Ip8kd2.js → rip-Bw_MiFIX.js} +1 -1
  255. package/dist/app/assets/{roboconf-DHaw-Q3G.js → roboconf-DXcyt3Q4.js} +1 -1
  256. package/dist/app/assets/{robotframework-HN9oBCJd.js → robotframework-C9fFAEtO.js} +1 -1
  257. package/dist/app/assets/{ruby-C42HzAMc.js → ruby-DSgIlL2S.js} +1 -1
  258. package/dist/app/assets/{rust-DJdUDgl0.js → rust-57C6WRN0.js} +1 -1
  259. package/dist/app/assets/{sankeyDiagram-XADWPNL6-DzoDqMzU.js → sankeyDiagram-XADWPNL6-DyKWGr4n.js} +1 -1
  260. package/dist/app/assets/{sas-EmHkISJg.js → sas-FDqjtO4i.js} +1 -1
  261. package/dist/app/assets/{sass-BEWMjvc2.js → sass-bJzUCejz.js} +1 -1
  262. package/dist/app/assets/{scala-Y9l-QmB_.js → scala-BlhQHE9e.js} +1 -1
  263. package/dist/app/assets/{scheme-oQH0YeM4.js → scheme-D0BV9AZR.js} +1 -1
  264. package/dist/app/assets/{scss-DDqkkzfA.js → scss-B3-qmAuS.js} +1 -1
  265. package/dist/app/assets/{sequenceDiagram-FGHM5R23-BRWyyuf5.js → sequenceDiagram-FGHM5R23-D5cVhoWz.js} +1 -1
  266. package/dist/app/assets/{shell-session-DUtkYnuZ.js → shell-session-sQM5QOrq.js} +1 -1
  267. package/dist/app/assets/{smali-CQN_R6JD.js → smali-YUh0SkT9.js} +1 -1
  268. package/dist/app/assets/{smalltalk-C5vveBjr.js → smalltalk-MO2YTeeA.js} +1 -1
  269. package/dist/app/assets/{smarty-BF9avlDB.js → smarty--CmaK82W.js} +1 -1
  270. package/dist/app/assets/{sml-C_smEF_i.js → sml-LyIKZRiL.js} +1 -1
  271. package/dist/app/assets/{solidity-CsmKUFUp.js → solidity-opa3zksM.js} +1 -1
  272. package/dist/app/assets/{solution-file-5OHlEmXf.js → solution-file-DqpmMsZ8.js} +1 -1
  273. package/dist/app/assets/{soy-DHS0rtw_.js → soy-c703eEnB.js} +1 -1
  274. package/dist/app/assets/{sparql-BxBq3H35.js → sparql-DgTeQ4XW.js} +1 -1
  275. package/dist/app/assets/{splunk-spl-C8VgtuYE.js → splunk-spl-CJob6uaQ.js} +1 -1
  276. package/dist/app/assets/{sqf-hSDek24H.js → sqf-DHFWBHjm.js} +1 -1
  277. package/dist/app/assets/{sql-DYgxUZFA.js → sql-BIblyz9j.js} +1 -1
  278. package/dist/app/assets/{squirrel-C7uGEJgW.js → squirrel-CneYowoV.js} +1 -1
  279. package/dist/app/assets/{stan-CGYqPG3F.js → stan-BKi9wLJ2.js} +1 -1
  280. package/dist/app/assets/{stateDiagram-FHFEXIEX-Dj_QL8hp.js → stateDiagram-FHFEXIEX-BbeWNEIN.js} +1 -1
  281. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-CbgaTj6o.js +1 -0
  282. package/dist/app/assets/{stylus-BCrv-hm1.js → stylus-u4xAjzXL.js} +1 -1
  283. package/dist/app/assets/{swift-3XnbN5uB.js → swift-DdHXY3JF.js} +1 -1
  284. package/dist/app/assets/{systemd-DzUq_PeH.js → systemd-REIO6n5V.js} +1 -1
  285. package/dist/app/assets/{t4-cs-DaXmHhdA.js → t4-cs-BS9N9hN9.js} +1 -1
  286. package/dist/app/assets/{t4-templating-C1pqdj2v.js → t4-templating-_szpR447.js} +1 -1
  287. package/dist/app/assets/{t4-vb-4wqP1_sy.js → t4-vb-BA1pkS-k.js} +1 -1
  288. package/dist/app/assets/{tap-FHe0A6pH.js → tap-Cvc7BK9t.js} +1 -1
  289. package/dist/app/assets/{tcl-DlumdfOH.js → tcl-BBuRnEym.js} +1 -1
  290. package/dist/app/assets/{textile-BmxrCmib.js → textile-DDTb0iwO.js} +1 -1
  291. package/dist/app/assets/{timeline-definition-GMOUNBTQ-BcI-XOle.js → timeline-definition-GMOUNBTQ-CE602-pQ.js} +1 -1
  292. package/dist/app/assets/{toml-BngAbTT7.js → toml-LKeRXFBO.js} +1 -1
  293. package/dist/app/assets/{tremor-BoVxotcN.js → tremor-CchxemQ0.js} +1 -1
  294. package/dist/app/assets/{tt2-BoBfCiJa.js → tt2-BSkF-c0h.js} +1 -1
  295. package/dist/app/assets/{turtle-CJfK17BD.js → turtle-bHklxVlv.js} +1 -1
  296. package/dist/app/assets/{twig-BoM58FfM.js → twig-Da1AnBL_.js} +1 -1
  297. package/dist/app/assets/{typescript-BU7mQ9Me.js → typescript-xzgzatYo.js} +1 -1
  298. package/dist/app/assets/{typoscript-BQMBCyle.js → typoscript-BG7JvWA0.js} +1 -1
  299. package/dist/app/assets/{unrealscript-Bly1rszO.js → unrealscript-xHsE3P7F.js} +1 -1
  300. package/dist/app/assets/{uorazor-AR6v804j.js → uorazor-CVESd0Is.js} +1 -1
  301. package/dist/app/assets/{uri-DQN5AlR9.js → uri-IMjeqwf0.js} +1 -1
  302. package/dist/app/assets/{v-CzlNjPFF.js → v-Bcufz9kX.js} +1 -1
  303. package/dist/app/assets/{vala-D4j-TYUj.js → vala-4Z4rhOq-.js} +1 -1
  304. package/dist/app/assets/{vbnet-BO_zrLTA.js → vbnet-C6qqVGU6.js} +1 -1
  305. package/dist/app/assets/{velocity-D14EQjuJ.js → velocity-CdfNFQQ2.js} +1 -1
  306. package/dist/app/assets/{vennDiagram-DHZGUBPP-Ct-BJj4e.js → vennDiagram-DHZGUBPP-Dgo42bg-.js} +1 -1
  307. package/dist/app/assets/{verilog-8HBCyzJW.js → verilog-DS94QYtZ.js} +1 -1
  308. package/dist/app/assets/{vhdl-CABoGFHh.js → vhdl-BwZa82Ml.js} +1 -1
  309. package/dist/app/assets/{vim-BqejDUiH.js → vim-CGknA_gS.js} +1 -1
  310. package/dist/app/assets/{visual-basic-BBFqe9IH.js → visual-basic-B6KT7sRp.js} +1 -1
  311. package/dist/app/assets/{wardley-RL74JXVD-DF76BHVV.js → wardley-RL74JXVD-CM08iWVZ.js} +1 -1
  312. package/dist/app/assets/{wardleyDiagram-NUSXRM2D-tb9-DpEL.js → wardleyDiagram-NUSXRM2D-CHT9xd3z.js} +1 -1
  313. package/dist/app/assets/{warpscript-D8JsH2aH.js → warpscript-BK2_CfaG.js} +1 -1
  314. package/dist/app/assets/{wasm-usuPS3UI.js → wasm-CBhF4Vrj.js} +1 -1
  315. package/dist/app/assets/{web-idl-CtjhIrn5.js → web-idl-B2RG2Tk-.js} +1 -1
  316. package/dist/app/assets/{wiki-nE7oYJAm.js → wiki-iS1m7Jl9.js} +1 -1
  317. package/dist/app/assets/{wolfram-BpCCg-Fp.js → wolfram-D_oKll9r.js} +1 -1
  318. package/dist/app/assets/{wren-Dtkpodh6.js → wren-Cgfx0a0f.js} +1 -1
  319. package/dist/app/assets/{xeora-BpTlDPdY.js → xeora-r8x2nSqu.js} +1 -1
  320. package/dist/app/assets/{xml-doc-CcDifcyn.js → xml-doc-Csqvt7Bf.js} +1 -1
  321. package/dist/app/assets/{xojo-O-0SvFwZ.js → xojo-C-6qAnHK.js} +1 -1
  322. package/dist/app/assets/{xquery-UAB2jKQB.js → xquery-DsSI5hTR.js} +1 -1
  323. package/dist/app/assets/{xychartDiagram-5P7HB3ND-d6FXhzUl.js → xychartDiagram-5P7HB3ND-CCDNEVlO.js} +1 -1
  324. package/dist/app/assets/{yaml-eCAjf2lJ.js → yaml-BjiEy9xj.js} +1 -1
  325. package/dist/app/assets/{yang-BkCZ0omw.js → yang-I-k6ys7W.js} +1 -1
  326. package/dist/app/assets/{zig-DEIPVEHz.js → zig-zXps1RcN.js} +1 -1
  327. package/dist/app/index.html +2 -2
  328. package/dist/index.cjs +2493 -722
  329. package/dist/index.js +2529 -735
  330. package/package.json +3 -3
  331. package/dist/app/assets/channel-SVZNtrjN.js +0 -1
  332. package/dist/app/assets/classDiagram-6PBFFD2Q-BiMmE_Ro.js +0 -1
  333. package/dist/app/assets/classDiagram-v2-HSJHXN6E-BiMmE_Ro.js +0 -1
  334. package/dist/app/assets/clone-E2Stvins.js +0 -1
  335. package/dist/app/assets/index-D58ynlvg.css +0 -1
  336. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-BJgU_5Se.js +0 -1
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // src/components/chat.tsx
2
- import * as React23 from "react";
2
+ import * as React26 from "react";
3
3
  import {
4
- ArrowDown,
4
+ ArrowDown as ArrowDown2,
5
5
  FileText as FileText2,
6
6
  ImageIcon,
7
- Loader2 as Loader23,
7
+ Loader2 as Loader24,
8
8
  Pencil as Pencil3,
9
9
  Quote,
10
10
  RefreshCw as RefreshCw2,
@@ -114,7 +114,13 @@ import {
114
114
  import "@langchain/core/messages/tool";
115
115
  import {
116
116
  ChatMessageEventTypeEnum,
117
- ChatMessageTypeEnum
117
+ ChatMessageTypeEnum,
118
+ REQUEST_USER_INPUT_RESULT_PURPOSE_IMPLEMENTATION_CONFIRMATION,
119
+ REQUEST_USER_INPUT_RESULT_PURPOSE_PLAN_CLARIFICATION,
120
+ REQUEST_USER_INPUT_RESULT_TYPE,
121
+ REQUEST_USER_INPUT_TOOL_NAME,
122
+ isLangGraphInterruptPayload,
123
+ isClientToolRequest
118
124
  } from "@xpert-ai/chatkit-types";
119
125
 
120
126
  // src/lib/api-config.ts
@@ -646,6 +652,10 @@ function ParentMessengerProvider({
646
652
  }
647
653
  return;
648
654
  }
655
+ const requestHumanInput = params.planMode === true || params.state?.[STATE_VARIABLE_HUMAN2]?.planMode === true ? {
656
+ ...humanInput,
657
+ planMode: true
658
+ } : humanInput;
649
659
  const newMessage = {
650
660
  id: createMessageId(),
651
661
  type: "human",
@@ -659,11 +669,11 @@ function ParentMessengerProvider({
659
669
  const requestOptions = buildInjectedRequestOptions({
660
670
  defaults: latestOptionsRef.current?.request,
661
671
  state: params.state,
662
- humanInput
672
+ humanInput: requestHumanInput
663
673
  });
664
674
  stream?.submit(
665
675
  {
666
- input: humanInput,
676
+ input: requestHumanInput,
667
677
  ...requestOptions.state ? { state: requestOptions.state } : {}
668
678
  },
669
679
  {
@@ -950,6 +960,7 @@ import {
950
960
  Globe,
951
961
  Images,
952
962
  Lightbulb,
963
+ ListChecks,
953
964
  Paperclip,
954
965
  Pencil,
955
966
  Plus,
@@ -1129,14 +1140,31 @@ var en_US_default = {
1129
1140
  composer: {
1130
1141
  openMenu: "Open menu",
1131
1142
  addAttachment: "Add attachment",
1143
+ planMode: "Plan mode",
1132
1144
  removeReference: "Remove reference",
1133
- quoteSelection: "Quote selection"
1145
+ quoteSelection: "Quote selection",
1146
+ requestUserInput: {
1147
+ title: "Input requested",
1148
+ recommended: "Recommended",
1149
+ other: "Other",
1150
+ otherPlaceholder: "Type a custom answer",
1151
+ continue: "Continue",
1152
+ dismiss: "Dismiss",
1153
+ previousQuestion: "Previous question",
1154
+ nextQuestion: "Next question",
1155
+ questionProgress: "{{current}} of {{total}}",
1156
+ optionInfo: "Details for {{label}}",
1157
+ submit: "Continue"
1158
+ }
1134
1159
  },
1135
1160
  sheet: {
1136
1161
  close: "Close"
1137
1162
  },
1138
1163
  markdown: {
1139
1164
  copy: "Copy",
1165
+ plan: {
1166
+ download: "Download Markdown"
1167
+ },
1140
1168
  mermaid: {
1141
1169
  title: "Mermaid",
1142
1170
  diagram: "Diagram",
@@ -1157,7 +1185,58 @@ var en_US_default = {
1157
1185
  reasoning: "Reasoning",
1158
1186
  loading: "Loading",
1159
1187
  thinking: "Thinking",
1160
- answering: "Answering"
1188
+ answering: "Answering",
1189
+ requestUserInputResult: {
1190
+ title: "Selections confirmed",
1191
+ option: "Option",
1192
+ other: "Other"
1193
+ },
1194
+ toolGroup: {
1195
+ status: {
1196
+ running: "Processing",
1197
+ success: "Processed",
1198
+ fail: "Processing failed"
1199
+ },
1200
+ inputTitle: "Input",
1201
+ outputTitle: "Output",
1202
+ errorTitle: "Error",
1203
+ jsonTitle: "JSON",
1204
+ jsonTree: "Tree",
1205
+ jsonRaw: "Raw",
1206
+ copy: "Copy",
1207
+ copied: "Copied",
1208
+ separator: ", ",
1209
+ categories: {
1210
+ files: {
1211
+ one: "{{count}} file",
1212
+ other: "{{count}} files"
1213
+ },
1214
+ searches: {
1215
+ one: "{{count}} search",
1216
+ other: "{{count}} searches"
1217
+ },
1218
+ commands: {
1219
+ one: "{{count}} command",
1220
+ other: "{{count}} commands"
1221
+ },
1222
+ lists: {
1223
+ one: "{{count}} list",
1224
+ other: "{{count}} lists"
1225
+ },
1226
+ tasks: {
1227
+ one: "{{count}} task",
1228
+ other: "{{count}} tasks"
1229
+ },
1230
+ knowledges: {
1231
+ one: "{{count}} knowledge result",
1232
+ other: "{{count}} knowledge results"
1233
+ },
1234
+ tools: {
1235
+ one: "{{count}} tool",
1236
+ other: "{{count}} tools"
1237
+ }
1238
+ }
1239
+ }
1161
1240
  }
1162
1241
  };
1163
1242
 
@@ -1236,14 +1315,31 @@ var zh_CN_default = {
1236
1315
  composer: {
1237
1316
  openMenu: "\u6253\u5F00\u83DC\u5355",
1238
1317
  addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
1318
+ planMode: "\u8BA1\u5212\u6A21\u5F0F",
1239
1319
  removeReference: "\u79FB\u9664\u5F15\u7528",
1240
- quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
1320
+ quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9",
1321
+ requestUserInput: {
1322
+ title: "\u9700\u8981\u4F60\u7684\u8F93\u5165",
1323
+ recommended: "\u63A8\u8350",
1324
+ other: "\u5176\u4ED6",
1325
+ otherPlaceholder: "\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54",
1326
+ continue: "\u7EE7\u7EED",
1327
+ dismiss: "\u5173\u95ED",
1328
+ previousQuestion: "\u4E0A\u4E00\u4E2A\u95EE\u9898",
1329
+ nextQuestion: "\u4E0B\u4E00\u4E2A\u95EE\u9898",
1330
+ questionProgress: "{{current}} / {{total}}",
1331
+ optionInfo: "{{label}} \u7684\u8BF4\u660E",
1332
+ submit: "\u7EE7\u7EED"
1333
+ }
1241
1334
  },
1242
1335
  sheet: {
1243
1336
  close: "\u5173\u95ED"
1244
1337
  },
1245
1338
  markdown: {
1246
1339
  copy: "\u590D\u5236",
1340
+ plan: {
1341
+ download: "\u4E0B\u8F7D Markdown"
1342
+ },
1247
1343
  mermaid: {
1248
1344
  title: "Mermaid",
1249
1345
  diagram: "\u56FE\u8868",
@@ -1264,7 +1360,58 @@ var zh_CN_default = {
1264
1360
  reasoning: "\u63A8\u7406",
1265
1361
  loading: "\u6B63\u5728\u52A0\u8F7D",
1266
1362
  thinking: "\u6B63\u5728\u601D\u8003",
1267
- answering: "\u6B63\u5728\u751F\u6210"
1363
+ answering: "\u6B63\u5728\u751F\u6210",
1364
+ requestUserInputResult: {
1365
+ title: "\u5DF2\u786E\u8BA4\u9009\u62E9",
1366
+ option: "\u9009\u9879",
1367
+ other: "\u5176\u4ED6"
1368
+ },
1369
+ toolGroup: {
1370
+ status: {
1371
+ running: "\u6B63\u5728\u5904\u7406",
1372
+ success: "\u5DF2\u5904\u7406",
1373
+ fail: "\u5904\u7406\u5931\u8D25"
1374
+ },
1375
+ inputTitle: "\u8F93\u5165",
1376
+ outputTitle: "\u8F93\u51FA",
1377
+ errorTitle: "\u9519\u8BEF",
1378
+ jsonTitle: "JSON",
1379
+ jsonTree: "\u6811\u5F62",
1380
+ jsonRaw: "\u539F\u59CB",
1381
+ copy: "\u590D\u5236",
1382
+ copied: "\u5DF2\u590D\u5236",
1383
+ separator: "\uFF0C",
1384
+ categories: {
1385
+ files: {
1386
+ one: "{{count}} \u4E2A\u6587\u4EF6",
1387
+ other: "{{count}} \u4E2A\u6587\u4EF6"
1388
+ },
1389
+ searches: {
1390
+ one: "{{count}} \u4E2A\u641C\u7D22",
1391
+ other: "{{count}} \u4E2A\u641C\u7D22"
1392
+ },
1393
+ commands: {
1394
+ one: "{{count}} \u4E2A\u547D\u4EE4",
1395
+ other: "{{count}} \u4E2A\u547D\u4EE4"
1396
+ },
1397
+ lists: {
1398
+ one: "{{count}} \u4E2A\u5217\u8868",
1399
+ other: "{{count}} \u4E2A\u5217\u8868"
1400
+ },
1401
+ tasks: {
1402
+ one: "{{count}} \u4E2A\u4EFB\u52A1",
1403
+ other: "{{count}} \u4E2A\u4EFB\u52A1"
1404
+ },
1405
+ knowledges: {
1406
+ one: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C",
1407
+ other: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C"
1408
+ },
1409
+ tools: {
1410
+ one: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528",
1411
+ other: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528"
1412
+ }
1413
+ }
1414
+ }
1268
1415
  }
1269
1416
  };
1270
1417
 
@@ -1700,6 +1847,8 @@ function ComposerMenu({
1700
1847
  onAttachmentClick,
1701
1848
  onToolSelect,
1702
1849
  selectedTool,
1850
+ planModeEnabled = false,
1851
+ onPlanModeChange,
1703
1852
  disabled = false
1704
1853
  }) {
1705
1854
  const { t } = useChatkitTranslation();
@@ -1708,9 +1857,6 @@ function ComposerMenu({
1708
1857
  const roundedClass = getRoundedClass(theme.radius);
1709
1858
  const attachmentsEnabled = composer?.attachments?.enabled ?? false;
1710
1859
  const tools = composer?.tools ?? [];
1711
- if (!attachmentsEnabled && tools.length === 0) {
1712
- return null;
1713
- }
1714
1860
  const handleAttachmentClick = () => {
1715
1861
  onAttachmentClick?.();
1716
1862
  setOpen(false);
@@ -1719,6 +1865,9 @@ function ComposerMenu({
1719
1865
  onToolSelect?.(tool);
1720
1866
  setOpen(false);
1721
1867
  };
1868
+ const handlePlanModeToggle = () => {
1869
+ onPlanModeChange?.(!planModeEnabled);
1870
+ };
1722
1871
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1723
1872
  /* @__PURE__ */ jsx6(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1724
1873
  Button,
@@ -1758,8 +1907,46 @@ function ComposerMenu({
1758
1907
  ]
1759
1908
  }
1760
1909
  ),
1761
- tools.length > 0 && /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" })
1910
+ /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" })
1762
1911
  ] }),
1912
+ /* @__PURE__ */ jsxs(
1913
+ "button",
1914
+ {
1915
+ type: "button",
1916
+ role: "switch",
1917
+ "aria-checked": planModeEnabled,
1918
+ onClick: handlePlanModeToggle,
1919
+ className: cn(
1920
+ "flex items-center gap-3 px-3 py-2 text-sm hover:bg-muted transition-colors",
1921
+ roundedClass,
1922
+ planModeEnabled && "bg-muted"
1923
+ ),
1924
+ children: [
1925
+ /* @__PURE__ */ jsx6("span", { className: "flex h-6 w-6 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx6(ListChecks, { size: 16 }) }),
1926
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 text-left", children: t("composer.planMode") }),
1927
+ /* @__PURE__ */ jsx6(
1928
+ "span",
1929
+ {
1930
+ className: cn(
1931
+ "relative inline-flex h-6 w-10 shrink-0 items-center rounded-full transition-colors",
1932
+ planModeEnabled ? "bg-primary" : "bg-muted-foreground/20"
1933
+ ),
1934
+ "aria-hidden": "true",
1935
+ children: /* @__PURE__ */ jsx6(
1936
+ "span",
1937
+ {
1938
+ className: cn(
1939
+ "inline-block h-5 w-5 rounded-full bg-background shadow-sm transition-transform",
1940
+ planModeEnabled ? "translate-x-[18px]" : "translate-x-0.5"
1941
+ )
1942
+ }
1943
+ )
1944
+ }
1945
+ )
1946
+ ]
1947
+ }
1948
+ ),
1949
+ tools.length > 0 && /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" }),
1763
1950
  tools.map((tool) => /* @__PURE__ */ jsxs(
1764
1951
  "button",
1765
1952
  {
@@ -2082,19 +2269,23 @@ function HistorySidebar({
2082
2269
  setOpen(false);
2083
2270
  };
2084
2271
  return /* @__PURE__ */ jsxs6(Sheet, { open, onOpenChange: setOpen, children: [
2085
- /* @__PURE__ */ jsx11(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
2086
- Button,
2087
- {
2088
- variant: "ghost",
2089
- size: "icon",
2090
- disabled,
2091
- className: "h-8 w-8 cursor-pointer",
2092
- children: [
2093
- /* @__PURE__ */ jsx11(History, { size: 16 }),
2094
- /* @__PURE__ */ jsx11("span", { className: "sr-only", children: t("history.threadHistory") })
2095
- ]
2096
- }
2097
- ) }),
2272
+ /* @__PURE__ */ jsxs6(Tooltip, { children: [
2273
+ /* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx11(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
2274
+ Button,
2275
+ {
2276
+ variant: "ghost",
2277
+ size: "icon",
2278
+ disabled,
2279
+ className: "h-8 w-8 cursor-pointer",
2280
+ "aria-label": t("history.threadHistory"),
2281
+ children: [
2282
+ /* @__PURE__ */ jsx11(History, { size: 16 }),
2283
+ /* @__PURE__ */ jsx11("span", { className: "sr-only", children: t("history.threadHistory") })
2284
+ ]
2285
+ }
2286
+ ) }) }) }),
2287
+ /* @__PURE__ */ jsx11(TooltipContent, { side: "bottom", children: t("history.threadHistory") })
2288
+ ] }),
2098
2289
  /* @__PURE__ */ jsxs6(SheetContent, { side: "right", className: "w-80 p-0", children: [
2099
2290
  /* @__PURE__ */ jsx11(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ jsx11(SheetTitle, { children: t("history.title") }) }),
2100
2291
  /* @__PURE__ */ jsx11("div", { className: "p-4", children: /* @__PURE__ */ jsxs6(
@@ -2571,165 +2762,789 @@ function PendingTodos({
2571
2762
  );
2572
2763
  }
2573
2764
 
2574
- // src/components/thread/messages/ai.tsx
2575
- import * as React16 from "react";
2765
+ // src/components/composer/request-user-input-panel.tsx
2766
+ import * as React12 from "react";
2576
2767
  import {
2577
- ChevronDown as ChevronDown2,
2578
- CheckCircle2 as CheckCircle22,
2579
- Clock3,
2580
- XCircle,
2581
- Loader2 as Loader22
2768
+ ArrowDown,
2769
+ ArrowUp as ArrowUp2,
2770
+ Check,
2771
+ ChevronLeft,
2772
+ ChevronRight,
2773
+ CornerDownLeft as CornerDownLeft2,
2774
+ Info as Info2
2582
2775
  } from "lucide-react";
2583
-
2584
- // src/components/ui/badge.tsx
2585
- import * as React12 from "react";
2586
- import { jsx as jsx14 } from "react/jsx-runtime";
2587
- var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
2588
- var variants = {
2589
- default: "bg-primary text-primary-foreground",
2590
- secondary: "bg-secondary text-secondary-foreground",
2591
- outline: "border-input text-foreground"
2592
- };
2593
- var Badge = React12.forwardRef(
2594
- ({ className, variant = "default", ...props }, ref) => {
2595
- return /* @__PURE__ */ jsx14("span", { ref, className: cn(base, variants[variant], className), ...props });
2596
- }
2597
- );
2598
- Badge.displayName = "Badge";
2599
-
2600
- // src/components/ui/card.tsx
2601
- import * as React13 from "react";
2602
- import { jsx as jsx15 } from "react/jsx-runtime";
2603
- var Card = React13.forwardRef(
2604
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
2605
- "div",
2606
- {
2607
- ref,
2608
- className: cn(
2609
- "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
2610
- className
2611
- ),
2612
- ...props
2776
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2777
+ function useRoundedClasses3() {
2778
+ const { theme } = useTheme();
2779
+ const density = theme.density ?? "normal";
2780
+ const densityClasses = {
2781
+ compact: {
2782
+ section: "px-3.5 py-2",
2783
+ eyebrow: "mb-0 text-[11px]",
2784
+ title: "text-[15px] leading-5",
2785
+ pager: "gap-1.5 text-xs",
2786
+ pagerButton: "h-6 w-6",
2787
+ pagerIcon: "h-3.5 w-3.5",
2788
+ choices: "mt-2.5 space-y-0.5",
2789
+ row: "min-h-8 grid-cols-[28px_minmax(0,1fr)_auto] gap-2 px-2.5 py-1",
2790
+ otherRow: "min-h-8 grid-cols-[28px_minmax(0,1fr)] gap-2 px-2.5 py-1",
2791
+ input: "h-6",
2792
+ footer: "mt-2.5 gap-2",
2793
+ dismissButton: "h-7",
2794
+ continueButton: "h-8 px-3.5",
2795
+ continueIcon: "h-5 min-w-5"
2796
+ },
2797
+ normal: {
2798
+ section: "px-4 py-2.5",
2799
+ eyebrow: "mb-0.5 text-xs",
2800
+ title: "text-base leading-5",
2801
+ pager: "gap-2 text-sm",
2802
+ pagerButton: "h-7 w-7",
2803
+ pagerIcon: "h-4 w-4",
2804
+ choices: "mt-3 space-y-0.5",
2805
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2806
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2807
+ input: "h-6",
2808
+ footer: "mt-3 gap-3",
2809
+ dismissButton: "h-7",
2810
+ continueButton: "h-8 px-4",
2811
+ continueIcon: "h-5 min-w-5"
2812
+ },
2813
+ spacious: {
2814
+ section: "px-5 py-3",
2815
+ eyebrow: "mb-0.5 text-xs",
2816
+ title: "text-base leading-5",
2817
+ pager: "gap-2 text-sm",
2818
+ pagerButton: "h-7 w-7",
2819
+ pagerIcon: "h-4 w-4",
2820
+ choices: "mt-4 space-y-1",
2821
+ row: "min-h-10 grid-cols-[32px_minmax(0,1fr)_auto] gap-3 px-3 py-2",
2822
+ otherRow: "min-h-10 grid-cols-[32px_minmax(0,1fr)] gap-3 px-3 py-2",
2823
+ input: "h-7",
2824
+ footer: "mt-4 gap-3",
2825
+ dismissButton: "h-8",
2826
+ continueButton: "h-9 px-4",
2827
+ continueIcon: "h-5 min-w-5"
2613
2828
  }
2614
- )
2615
- );
2616
- Card.displayName = "Card";
2617
- var CardHeader = React13.forwardRef(
2618
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
2619
- );
2620
- CardHeader.displayName = "CardHeader";
2621
- var CardTitle = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx15("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
2622
- CardTitle.displayName = "CardTitle";
2623
- var CardDescription = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx15("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
2624
- CardDescription.displayName = "CardDescription";
2625
- var CardContent = React13.forwardRef(
2626
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15("div", { ref, className: cn("px-6 pb-6", className), ...props })
2627
- );
2628
- CardContent.displayName = "CardContent";
2629
- var CardFooter = React13.forwardRef(
2630
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
2631
- );
2632
- CardFooter.displayName = "CardFooter";
2633
- var CardAction = React13.forwardRef(
2634
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
2635
- );
2636
- CardAction.displayName = "CardAction";
2637
-
2638
- // src/components/ui/tabs.tsx
2639
- import * as React14 from "react";
2640
- import { jsx as jsx16 } from "react/jsx-runtime";
2641
- var TabsContext = React14.createContext(null);
2642
- function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
2643
- const [internalValue, setInternalValue] = React14.useState(defaultValue ?? "");
2644
- const activeValue = value ?? internalValue;
2645
- const setValue = React14.useCallback(
2646
- (nextValue) => {
2647
- if (value === void 0) setInternalValue(nextValue);
2648
- onValueChange?.(nextValue);
2829
+ }[density] ?? {
2830
+ section: "px-4 py-2.5",
2831
+ eyebrow: "mb-0.5 text-xs",
2832
+ title: "text-base leading-5",
2833
+ pager: "gap-2 text-sm",
2834
+ pagerButton: "h-7 w-7",
2835
+ pagerIcon: "h-4 w-4",
2836
+ choices: "mt-3 space-y-0.5",
2837
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2838
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2839
+ input: "h-6",
2840
+ footer: "mt-3 gap-3",
2841
+ dismissButton: "h-7",
2842
+ continueButton: "h-8 px-4",
2843
+ continueIcon: "h-5 min-w-5"
2844
+ };
2845
+ return {
2846
+ top: theme.radius ? {
2847
+ pill: "rounded-t-3xl",
2848
+ round: "rounded-t-xl",
2849
+ soft: "rounded-t-lg",
2850
+ sharp: "rounded-t-none"
2851
+ }[theme.radius] : "rounded-t-lg",
2852
+ panel: getRoundedClass(theme.radius, "rounded-lg"),
2853
+ control: getRoundedClass(theme.radius, "rounded-md"),
2854
+ density: densityClasses
2855
+ };
2856
+ }
2857
+ function parseRecommendedLabel(label) {
2858
+ const recommendedPattern = /\s*(?:\((?:recommended)\)|(推荐))\s*$/i;
2859
+ return {
2860
+ label: label.replace(recommendedPattern, "").trim() || label,
2861
+ recommended: recommendedPattern.test(label)
2862
+ };
2863
+ }
2864
+ function getAnswerForQuestion(question, draft) {
2865
+ if (!draft) return null;
2866
+ if (draft.type === "other") {
2867
+ const value = draft.otherText.trim();
2868
+ if (!value) return null;
2869
+ return {
2870
+ id: question.id,
2871
+ question: question.question,
2872
+ type: "other",
2873
+ value
2874
+ };
2875
+ }
2876
+ const option = question.options[draft.optionIndex];
2877
+ if (!option) return null;
2878
+ return {
2879
+ id: question.id,
2880
+ question: question.question,
2881
+ type: "option",
2882
+ value: option.label,
2883
+ label: option.label,
2884
+ description: option.description
2885
+ };
2886
+ }
2887
+ function getSelectedChoiceIndex(question, draft) {
2888
+ if (!draft) return -1;
2889
+ if (draft.type === "other") return question.options.length;
2890
+ return draft.optionIndex;
2891
+ }
2892
+ function RequestUserInputPanel({
2893
+ request,
2894
+ onSubmit,
2895
+ onDismiss,
2896
+ attachToComposer = true,
2897
+ className
2898
+ }) {
2899
+ const { t } = useChatkitTranslation();
2900
+ const rounded = useRoundedClasses3();
2901
+ const [drafts, setDrafts] = React12.useState({});
2902
+ const [currentQuestionIndex, setCurrentQuestionIndex] = React12.useState(0);
2903
+ const otherInputRef = React12.useRef(null);
2904
+ const questions = request?.params.questions ?? [];
2905
+ React12.useEffect(() => {
2906
+ setDrafts({});
2907
+ setCurrentQuestionIndex(0);
2908
+ }, [request?.id]);
2909
+ React12.useEffect(() => {
2910
+ if (questions.length === 0) return;
2911
+ setCurrentQuestionIndex(
2912
+ (index) => Math.min(Math.max(index, 0), questions.length - 1)
2913
+ );
2914
+ }, [questions.length]);
2915
+ const setQuestionDraft = React12.useCallback(
2916
+ (questionId, draft) => {
2917
+ setDrafts((previous) => ({
2918
+ ...previous,
2919
+ [questionId]: draft
2920
+ }));
2649
2921
  },
2650
- [onValueChange, value]
2922
+ []
2651
2923
  );
2652
- return /* @__PURE__ */ jsx16(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx16("div", { className: cn("w-full", className), ...props }) });
2653
- }
2654
- var TabsList = React14.forwardRef(
2655
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
2656
- "div",
2657
- {
2658
- ref,
2659
- className: cn(
2660
- "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
2661
- className
2662
- ),
2663
- role: "tablist",
2664
- ...props
2924
+ const focusOtherInput = React12.useCallback(() => {
2925
+ window.setTimeout(() => otherInputRef.current?.focus(), 0);
2926
+ }, []);
2927
+ const selectOption = React12.useCallback(
2928
+ (question, optionIndex) => {
2929
+ const previousDraft = drafts[question.id];
2930
+ setQuestionDraft(question.id, {
2931
+ type: "option",
2932
+ optionIndex,
2933
+ otherText: previousDraft?.otherText ?? ""
2934
+ });
2935
+ },
2936
+ [drafts, setQuestionDraft]
2937
+ );
2938
+ const selectOther = React12.useCallback(
2939
+ (question, otherText2) => {
2940
+ const previousDraft = drafts[question.id];
2941
+ setQuestionDraft(question.id, {
2942
+ type: "other",
2943
+ otherText: otherText2 ?? (previousDraft?.type === "other" ? previousDraft.otherText : previousDraft?.otherText) ?? ""
2944
+ });
2945
+ focusOtherInput();
2946
+ },
2947
+ [drafts, focusOtherInput, setQuestionDraft]
2948
+ );
2949
+ const goToQuestion = React12.useCallback(
2950
+ (index) => {
2951
+ if (questions.length === 0) return;
2952
+ setCurrentQuestionIndex(
2953
+ Math.min(Math.max(index, 0), questions.length - 1)
2954
+ );
2955
+ },
2956
+ [questions.length]
2957
+ );
2958
+ const answers = React12.useMemo(
2959
+ () => questions.map((question) => getAnswerForQuestion(question, drafts[question.id])).filter((answer) => Boolean(answer)),
2960
+ [drafts, questions]
2961
+ );
2962
+ const canSubmit = answers.length === questions.length;
2963
+ const currentQuestion = questions[currentQuestionIndex] ?? null;
2964
+ const currentDraft = currentQuestion ? drafts[currentQuestion.id] : void 0;
2965
+ const currentAnswer = currentQuestion ? getAnswerForQuestion(currentQuestion, currentDraft) : null;
2966
+ const isLastQuestion = currentQuestionIndex === questions.length - 1;
2967
+ const buildAnswersFromDrafts = React12.useCallback(
2968
+ (nextDrafts) => questions.map((question) => getAnswerForQuestion(question, nextDrafts[question.id])).filter((answer) => Boolean(answer)),
2969
+ [questions]
2970
+ );
2971
+ const submitOrFocusFirstMissing = React12.useCallback(
2972
+ (nextDrafts) => {
2973
+ const nextAnswers = buildAnswersFromDrafts(nextDrafts);
2974
+ if (nextAnswers.length === questions.length) {
2975
+ onSubmit(nextAnswers);
2976
+ return;
2977
+ }
2978
+ const firstMissingIndex = questions.findIndex(
2979
+ (question) => !getAnswerForQuestion(question, nextDrafts[question.id])
2980
+ );
2981
+ if (firstMissingIndex >= 0) {
2982
+ goToQuestion(firstMissingIndex);
2983
+ }
2984
+ },
2985
+ [buildAnswersFromDrafts, goToQuestion, onSubmit, questions]
2986
+ );
2987
+ const activateOption = React12.useCallback(
2988
+ (question, optionIndex) => {
2989
+ const previousDraft = drafts[question.id];
2990
+ const nextDrafts = {
2991
+ ...drafts,
2992
+ [question.id]: {
2993
+ type: "option",
2994
+ optionIndex,
2995
+ otherText: previousDraft?.otherText ?? ""
2996
+ }
2997
+ };
2998
+ setDrafts(nextDrafts);
2999
+ if (isLastQuestion) {
3000
+ submitOrFocusFirstMissing(nextDrafts);
3001
+ return;
3002
+ }
3003
+ goToQuestion(currentQuestionIndex + 1);
3004
+ },
3005
+ [
3006
+ currentQuestionIndex,
3007
+ drafts,
3008
+ goToQuestion,
3009
+ isLastQuestion,
3010
+ submitOrFocusFirstMissing
3011
+ ]
3012
+ );
3013
+ const chooseChoiceByIndex = React12.useCallback(
3014
+ (choiceIndex) => {
3015
+ if (!currentQuestion) return;
3016
+ if (choiceIndex < 0) return;
3017
+ if (choiceIndex < currentQuestion.options.length) {
3018
+ selectOption(currentQuestion, choiceIndex);
3019
+ return;
3020
+ }
3021
+ if (choiceIndex === currentQuestion.options.length) {
3022
+ selectOther(currentQuestion);
3023
+ }
3024
+ },
3025
+ [currentQuestion, selectOption, selectOther]
3026
+ );
3027
+ const moveCurrentChoice = React12.useCallback(
3028
+ (direction) => {
3029
+ if (!currentQuestion) return;
3030
+ const choiceCount = currentQuestion.options.length + 1;
3031
+ const currentIndex = getSelectedChoiceIndex(currentQuestion, currentDraft);
3032
+ const nextIndex = currentIndex === -1 ? direction === 1 ? 0 : choiceCount - 1 : (currentIndex + direction + choiceCount) % choiceCount;
3033
+ chooseChoiceByIndex(nextIndex);
3034
+ },
3035
+ [chooseChoiceByIndex, currentDraft, currentQuestion]
3036
+ );
3037
+ const handleContinue = React12.useCallback(() => {
3038
+ if (!currentAnswer) return;
3039
+ if (!isLastQuestion) {
3040
+ goToQuestion(currentQuestionIndex + 1);
3041
+ return;
2665
3042
  }
2666
- )
2667
- );
2668
- TabsList.displayName = "TabsList";
2669
- var TabsTrigger = React14.forwardRef(
2670
- ({ className, value, onClick, ...props }, ref) => {
2671
- const context = React14.useContext(TabsContext);
2672
- if (!context) {
2673
- throw new Error("TabsTrigger must be used within Tabs");
3043
+ if (canSubmit) {
3044
+ onSubmit(answers);
3045
+ return;
2674
3046
  }
2675
- const isActive = context.value === value;
2676
- return /* @__PURE__ */ jsx16(
2677
- "button",
2678
- {
2679
- ref,
2680
- type: "button",
2681
- role: "tab",
2682
- "aria-selected": isActive,
2683
- "data-state": isActive ? "active" : "inactive",
2684
- className: cn(
2685
- "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
2686
- className
2687
- ),
2688
- onClick: (event) => {
2689
- context.setValue(value);
2690
- onClick?.(event);
2691
- },
2692
- ...props
2693
- }
3047
+ const firstMissingIndex = questions.findIndex(
3048
+ (question) => !getAnswerForQuestion(question, drafts[question.id])
2694
3049
  );
2695
- }
2696
- );
2697
- TabsTrigger.displayName = "TabsTrigger";
2698
- var TabsContent = React14.forwardRef(
2699
- ({ className, value, ...props }, ref) => {
2700
- const context = React14.useContext(TabsContext);
2701
- if (!context) {
2702
- throw new Error("TabsContent must be used within Tabs");
3050
+ if (firstMissingIndex >= 0) {
3051
+ goToQuestion(firstMissingIndex);
2703
3052
  }
2704
- if (context.value !== value) return null;
2705
- return /* @__PURE__ */ jsx16(
2706
- "div",
2707
- {
2708
- ref,
2709
- role: "tabpanel",
2710
- className: cn(
2711
- "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
2712
- className
2713
- ),
2714
- ...props
3053
+ }, [
3054
+ answers,
3055
+ canSubmit,
3056
+ currentAnswer,
3057
+ currentQuestionIndex,
3058
+ drafts,
3059
+ goToQuestion,
3060
+ isLastQuestion,
3061
+ onSubmit,
3062
+ questions
3063
+ ]);
3064
+ React12.useEffect(() => {
3065
+ if (!request) return;
3066
+ const handleKeyDown = (event) => {
3067
+ if (event.isComposing) return;
3068
+ const target = event.target;
3069
+ const targetTag = target?.tagName;
3070
+ const isTypingTarget = target?.isContentEditable || targetTag === "INPUT" || targetTag === "TEXTAREA" || targetTag === "SELECT";
3071
+ if (event.key === "Escape" || event.key === "Esc") {
3072
+ if (onDismiss) {
3073
+ event.preventDefault();
3074
+ onDismiss();
3075
+ }
3076
+ return;
2715
3077
  }
2716
- );
2717
- }
2718
- );
2719
- TabsContent.displayName = "TabsContent";
2720
-
2721
- // src/components/thread/markdown-text.tsx
2722
- import ReactMarkdown from "react-markdown";
2723
- import remarkGfm from "remark-gfm";
2724
- import rehypeKatex from "rehype-katex";
2725
- import remarkMath from "remark-math";
2726
- import {
2727
- Children,
2728
- isValidElement,
2729
- memo,
2730
- useState as useState8
2731
- } from "react";
2732
- import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon2 } from "lucide-react";
3078
+ if (isTypingTarget && event.key !== "Enter") {
3079
+ return;
3080
+ }
3081
+ if (event.key === "Enter") {
3082
+ event.preventDefault();
3083
+ handleContinue();
3084
+ return;
3085
+ }
3086
+ if (event.key === "ArrowLeft") {
3087
+ event.preventDefault();
3088
+ goToQuestion(currentQuestionIndex - 1);
3089
+ return;
3090
+ }
3091
+ if (event.key === "ArrowRight") {
3092
+ event.preventDefault();
3093
+ goToQuestion(currentQuestionIndex + 1);
3094
+ return;
3095
+ }
3096
+ if (event.key === "ArrowUp") {
3097
+ event.preventDefault();
3098
+ moveCurrentChoice(-1);
3099
+ return;
3100
+ }
3101
+ if (event.key === "ArrowDown") {
3102
+ event.preventDefault();
3103
+ moveCurrentChoice(1);
3104
+ return;
3105
+ }
3106
+ if (/^[1-9]$/.test(event.key)) {
3107
+ const choiceIndex = Number(event.key) - 1;
3108
+ if (currentQuestion && choiceIndex < currentQuestion.options.length + 1) {
3109
+ event.preventDefault();
3110
+ chooseChoiceByIndex(choiceIndex);
3111
+ }
3112
+ }
3113
+ };
3114
+ document.addEventListener("keydown", handleKeyDown);
3115
+ return () => document.removeEventListener("keydown", handleKeyDown);
3116
+ }, [
3117
+ chooseChoiceByIndex,
3118
+ currentQuestion,
3119
+ currentQuestionIndex,
3120
+ goToQuestion,
3121
+ handleContinue,
3122
+ moveCurrentChoice,
3123
+ onDismiss,
3124
+ request
3125
+ ]);
3126
+ if (!request || !currentQuestion) {
3127
+ return null;
3128
+ }
3129
+ const handleOtherTextChange = (value) => {
3130
+ setDrafts((previous) => ({
3131
+ ...previous,
3132
+ [currentQuestion.id]: {
3133
+ type: "other",
3134
+ otherText: value
3135
+ }
3136
+ }));
3137
+ };
3138
+ const otherText = currentDraft?.otherText ?? "";
3139
+ return /* @__PURE__ */ jsxs9(
3140
+ "section",
3141
+ {
3142
+ "aria-label": t("composer.requestUserInput.title"),
3143
+ "aria-live": "polite",
3144
+ className: cn(
3145
+ "mx-2 border border-border bg-background/95 shadow-sm",
3146
+ rounded.density.section,
3147
+ attachToComposer ? "border-b-0" : null,
3148
+ attachToComposer ? rounded.top : rounded.panel,
3149
+ className
3150
+ ),
3151
+ children: [
3152
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-3", children: [
3153
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
3154
+ /* @__PURE__ */ jsx14(
3155
+ "div",
3156
+ {
3157
+ className: cn(
3158
+ "font-medium text-muted-foreground",
3159
+ rounded.density.eyebrow
3160
+ ),
3161
+ children: currentQuestion.header
3162
+ }
3163
+ ),
3164
+ /* @__PURE__ */ jsx14(
3165
+ "h3",
3166
+ {
3167
+ className: cn(
3168
+ "font-semibold text-foreground",
3169
+ rounded.density.title
3170
+ ),
3171
+ children: currentQuestion.question
3172
+ }
3173
+ )
3174
+ ] }),
3175
+ questions.length > 1 ? /* @__PURE__ */ jsxs9(
3176
+ "div",
3177
+ {
3178
+ className: cn(
3179
+ "flex shrink-0 items-center font-medium text-muted-foreground",
3180
+ rounded.density.pager
3181
+ ),
3182
+ children: [
3183
+ /* @__PURE__ */ jsx14(
3184
+ "button",
3185
+ {
3186
+ type: "button",
3187
+ onClick: () => goToQuestion(currentQuestionIndex - 1),
3188
+ disabled: currentQuestionIndex === 0,
3189
+ className: cn(
3190
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3191
+ rounded.density.pagerButton
3192
+ ),
3193
+ "aria-label": t("composer.requestUserInput.previousQuestion"),
3194
+ children: /* @__PURE__ */ jsx14(ChevronLeft, { className: rounded.density.pagerIcon })
3195
+ }
3196
+ ),
3197
+ /* @__PURE__ */ jsx14("span", { className: "min-w-12 text-center", children: t("composer.requestUserInput.questionProgress", {
3198
+ current: currentQuestionIndex + 1,
3199
+ total: questions.length
3200
+ }) }),
3201
+ /* @__PURE__ */ jsx14(
3202
+ "button",
3203
+ {
3204
+ type: "button",
3205
+ onClick: () => goToQuestion(currentQuestionIndex + 1),
3206
+ disabled: currentQuestionIndex === questions.length - 1,
3207
+ className: cn(
3208
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3209
+ rounded.density.pagerButton
3210
+ ),
3211
+ "aria-label": t("composer.requestUserInput.nextQuestion"),
3212
+ children: /* @__PURE__ */ jsx14(ChevronRight, { className: rounded.density.pagerIcon })
3213
+ }
3214
+ )
3215
+ ]
3216
+ }
3217
+ ) : null
3218
+ ] }),
3219
+ /* @__PURE__ */ jsxs9("div", { className: rounded.density.choices, children: [
3220
+ currentQuestion.options.map((option, optionIndex) => {
3221
+ const selected = currentDraft?.type === "option" && currentDraft.optionIndex === optionIndex;
3222
+ const parsedLabel = parseRecommendedLabel(option.label);
3223
+ return /* @__PURE__ */ jsxs9(
3224
+ "div",
3225
+ {
3226
+ role: "button",
3227
+ tabIndex: 0,
3228
+ onClick: () => activateOption(currentQuestion, optionIndex),
3229
+ onKeyDown: (event) => {
3230
+ if (event.key === "Enter" || event.key === " ") {
3231
+ event.preventDefault();
3232
+ event.stopPropagation();
3233
+ activateOption(currentQuestion, optionIndex);
3234
+ }
3235
+ },
3236
+ "aria-pressed": selected,
3237
+ "aria-label": `${optionIndex + 1}. ${option.label}`,
3238
+ className: cn(
3239
+ "grid cursor-pointer items-center text-left transition-colors",
3240
+ rounded.density.row,
3241
+ rounded.panel,
3242
+ selected ? "bg-muted text-foreground" : "text-foreground/90 hover:bg-muted/55"
3243
+ ),
3244
+ children: [
3245
+ /* @__PURE__ */ jsxs9("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3246
+ optionIndex + 1,
3247
+ "."
3248
+ ] }),
3249
+ /* @__PURE__ */ jsxs9("span", { className: "min-w-0", children: [
3250
+ /* @__PURE__ */ jsx14("span", { className: "inline min-w-0 text-sm font-semibold leading-5", children: parsedLabel.label }),
3251
+ parsedLabel.recommended ? /* @__PURE__ */ jsxs9("span", { className: "ml-1.5 inline-flex items-center gap-1 text-sm font-semibold text-primary", children: [
3252
+ /* @__PURE__ */ jsx14(Check, { className: "h-3.5 w-3.5" }),
3253
+ "(",
3254
+ t("composer.requestUserInput.recommended"),
3255
+ ")"
3256
+ ] }) : null
3257
+ ] }),
3258
+ /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
3259
+ option.description ? /* @__PURE__ */ jsxs9(Tooltip, { children: [
3260
+ /* @__PURE__ */ jsx14(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx14(
3261
+ "button",
3262
+ {
3263
+ type: "button",
3264
+ onClick: (event) => event.stopPropagation(),
3265
+ onKeyDown: (event) => event.stopPropagation(),
3266
+ title: option.description,
3267
+ className: "inline-flex h-7 w-7 items-center justify-center rounded-full hover:bg-background/80 hover:text-foreground",
3268
+ "aria-label": t("composer.requestUserInput.optionInfo", {
3269
+ label: parsedLabel.label
3270
+ }),
3271
+ children: /* @__PURE__ */ jsx14(Info2, { className: "h-4 w-4" })
3272
+ }
3273
+ ) }),
3274
+ /* @__PURE__ */ jsx14(
3275
+ TooltipContent,
3276
+ {
3277
+ side: "top",
3278
+ sideOffset: 6,
3279
+ className: "max-w-72 text-left leading-5",
3280
+ children: option.description
3281
+ }
3282
+ )
3283
+ ] }) : null,
3284
+ selected ? /* @__PURE__ */ jsxs9(
3285
+ "span",
3286
+ {
3287
+ "aria-hidden": "true",
3288
+ className: "hidden items-center gap-0.5 sm:flex",
3289
+ children: [
3290
+ /* @__PURE__ */ jsx14(ArrowUp2, { className: "h-4 w-4 opacity-45" }),
3291
+ /* @__PURE__ */ jsx14(ArrowDown, { className: "h-4 w-4 opacity-45" })
3292
+ ]
3293
+ }
3294
+ ) : null
3295
+ ] })
3296
+ ]
3297
+ },
3298
+ `${currentQuestion.id}-${optionIndex}`
3299
+ );
3300
+ }),
3301
+ /* @__PURE__ */ jsxs9(
3302
+ "label",
3303
+ {
3304
+ className: cn(
3305
+ "grid items-center transition-colors",
3306
+ rounded.density.otherRow,
3307
+ rounded.panel,
3308
+ currentDraft?.type === "other" ? "bg-muted text-foreground" : "hover:bg-muted/55"
3309
+ ),
3310
+ children: [
3311
+ /* @__PURE__ */ jsxs9("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3312
+ currentQuestion.options.length + 1,
3313
+ "."
3314
+ ] }),
3315
+ /* @__PURE__ */ jsx14("span", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: /* @__PURE__ */ jsx14(
3316
+ "input",
3317
+ {
3318
+ ref: otherInputRef,
3319
+ value: otherText,
3320
+ onChange: (event) => handleOtherTextChange(event.target.value),
3321
+ onFocus: () => selectOther(currentQuestion, otherText),
3322
+ placeholder: t("composer.requestUserInput.otherPlaceholder"),
3323
+ className: cn(
3324
+ "min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground",
3325
+ rounded.density.input
3326
+ )
3327
+ }
3328
+ ) })
3329
+ ]
3330
+ }
3331
+ )
3332
+ ] }),
3333
+ /* @__PURE__ */ jsxs9(
3334
+ "div",
3335
+ {
3336
+ className: cn(
3337
+ "flex items-center justify-end",
3338
+ rounded.density.footer
3339
+ ),
3340
+ children: [
3341
+ onDismiss ? /* @__PURE__ */ jsxs9(
3342
+ "button",
3343
+ {
3344
+ type: "button",
3345
+ onClick: onDismiss,
3346
+ className: cn(
3347
+ "inline-flex items-center gap-2 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground",
3348
+ rounded.density.dismissButton
3349
+ ),
3350
+ children: [
3351
+ t("composer.requestUserInput.dismiss"),
3352
+ /* @__PURE__ */ jsx14("kbd", { className: "rounded-full bg-muted px-2 py-1 text-xs font-semibold text-muted-foreground", children: "ESC" })
3353
+ ]
3354
+ }
3355
+ ) : null,
3356
+ /* @__PURE__ */ jsxs9(
3357
+ "button",
3358
+ {
3359
+ type: "button",
3360
+ disabled: !currentAnswer,
3361
+ onClick: handleContinue,
3362
+ className: cn(
3363
+ "inline-flex items-center gap-2 bg-primary text-sm font-semibold text-background transition-all",
3364
+ rounded.density.continueButton,
3365
+ "hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-40",
3366
+ rounded.panel
3367
+ ),
3368
+ children: [
3369
+ t("composer.requestUserInput.continue"),
3370
+ /* @__PURE__ */ jsx14(
3371
+ "span",
3372
+ {
3373
+ className: cn(
3374
+ "inline-flex items-center justify-center rounded-full bg-background/20",
3375
+ rounded.density.continueIcon
3376
+ ),
3377
+ children: /* @__PURE__ */ jsx14(CornerDownLeft2, { className: "h-3.5 w-3.5" })
3378
+ }
3379
+ )
3380
+ ]
3381
+ }
3382
+ )
3383
+ ]
3384
+ }
3385
+ )
3386
+ ]
3387
+ }
3388
+ );
3389
+ }
3390
+
3391
+ // src/components/thread/messages/ai.tsx
3392
+ import * as React19 from "react";
3393
+ import {
3394
+ ChevronDown as ChevronDown2,
3395
+ Clock3,
3396
+ Loader2 as Loader23
3397
+ } from "lucide-react";
3398
+
3399
+ // src/components/ui/badge.tsx
3400
+ import * as React13 from "react";
3401
+ import { jsx as jsx15 } from "react/jsx-runtime";
3402
+ var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
3403
+ var variants = {
3404
+ default: "bg-primary text-primary-foreground",
3405
+ secondary: "bg-secondary text-secondary-foreground",
3406
+ outline: "border-input text-foreground"
3407
+ };
3408
+ var Badge = React13.forwardRef(
3409
+ ({ className, variant = "default", ...props }, ref) => {
3410
+ return /* @__PURE__ */ jsx15("span", { ref, className: cn(base, variants[variant], className), ...props });
3411
+ }
3412
+ );
3413
+ Badge.displayName = "Badge";
3414
+
3415
+ // src/components/ui/card.tsx
3416
+ import * as React14 from "react";
3417
+ import { jsx as jsx16 } from "react/jsx-runtime";
3418
+ var Card = React14.forwardRef(
3419
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
3420
+ "div",
3421
+ {
3422
+ ref,
3423
+ className: cn(
3424
+ "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
3425
+ className
3426
+ ),
3427
+ ...props
3428
+ }
3429
+ )
3430
+ );
3431
+ Card.displayName = "Card";
3432
+ var CardHeader = React14.forwardRef(
3433
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
3434
+ );
3435
+ CardHeader.displayName = "CardHeader";
3436
+ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
3437
+ CardTitle.displayName = "CardTitle";
3438
+ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
3439
+ CardDescription.displayName = "CardDescription";
3440
+ var CardContent = React14.forwardRef(
3441
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("px-6 pb-6", className), ...props })
3442
+ );
3443
+ CardContent.displayName = "CardContent";
3444
+ var CardFooter = React14.forwardRef(
3445
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
3446
+ );
3447
+ CardFooter.displayName = "CardFooter";
3448
+ var CardAction = React14.forwardRef(
3449
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
3450
+ );
3451
+ CardAction.displayName = "CardAction";
3452
+
3453
+ // src/components/ui/tabs.tsx
3454
+ import * as React15 from "react";
3455
+ import { jsx as jsx17 } from "react/jsx-runtime";
3456
+ var TabsContext = React15.createContext(null);
3457
+ function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
3458
+ const [internalValue, setInternalValue] = React15.useState(defaultValue ?? "");
3459
+ const activeValue = value ?? internalValue;
3460
+ const setValue = React15.useCallback(
3461
+ (nextValue) => {
3462
+ if (value === void 0) setInternalValue(nextValue);
3463
+ onValueChange?.(nextValue);
3464
+ },
3465
+ [onValueChange, value]
3466
+ );
3467
+ return /* @__PURE__ */ jsx17(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx17("div", { className: cn("w-full", className), ...props }) });
3468
+ }
3469
+ var TabsList = React15.forwardRef(
3470
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx17(
3471
+ "div",
3472
+ {
3473
+ ref,
3474
+ className: cn(
3475
+ "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
3476
+ className
3477
+ ),
3478
+ role: "tablist",
3479
+ ...props
3480
+ }
3481
+ )
3482
+ );
3483
+ TabsList.displayName = "TabsList";
3484
+ var TabsTrigger = React15.forwardRef(
3485
+ ({ className, value, onClick, ...props }, ref) => {
3486
+ const context = React15.useContext(TabsContext);
3487
+ if (!context) {
3488
+ throw new Error("TabsTrigger must be used within Tabs");
3489
+ }
3490
+ const isActive = context.value === value;
3491
+ return /* @__PURE__ */ jsx17(
3492
+ "button",
3493
+ {
3494
+ ref,
3495
+ type: "button",
3496
+ role: "tab",
3497
+ "aria-selected": isActive,
3498
+ "data-state": isActive ? "active" : "inactive",
3499
+ className: cn(
3500
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
3501
+ className
3502
+ ),
3503
+ onClick: (event) => {
3504
+ context.setValue(value);
3505
+ onClick?.(event);
3506
+ },
3507
+ ...props
3508
+ }
3509
+ );
3510
+ }
3511
+ );
3512
+ TabsTrigger.displayName = "TabsTrigger";
3513
+ var TabsContent = React15.forwardRef(
3514
+ ({ className, value, ...props }, ref) => {
3515
+ const context = React15.useContext(TabsContext);
3516
+ if (!context) {
3517
+ throw new Error("TabsContent must be used within Tabs");
3518
+ }
3519
+ if (context.value !== value) return null;
3520
+ return /* @__PURE__ */ jsx17(
3521
+ "div",
3522
+ {
3523
+ ref,
3524
+ role: "tabpanel",
3525
+ className: cn(
3526
+ "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
3527
+ className
3528
+ ),
3529
+ ...props
3530
+ }
3531
+ );
3532
+ }
3533
+ );
3534
+ TabsContent.displayName = "TabsContent";
3535
+
3536
+ // src/components/thread/markdown-text.tsx
3537
+ import ReactMarkdown from "react-markdown";
3538
+ import remarkGfm from "remark-gfm";
3539
+ import rehypeKatex from "rehype-katex";
3540
+ import remarkMath from "remark-math";
3541
+ import {
3542
+ Children,
3543
+ isValidElement,
3544
+ memo,
3545
+ useState as useState9
3546
+ } from "react";
3547
+ import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon2, DownloadIcon as DownloadIcon2 } from "lucide-react";
2733
3548
 
2734
3549
  // src/components/thread/syntax-highlighter.tsx
2735
3550
  import { PrismAsyncLight as SyntaxHighlighterPrism } from "react-syntax-highlighter";
@@ -2737,7 +3552,7 @@ import tsx from "react-syntax-highlighter/dist/esm/languages/prism/tsx";
2737
3552
  import python from "react-syntax-highlighter/dist/esm/languages/prism/python";
2738
3553
  import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
2739
3554
  import "react";
2740
- import { jsx as jsx17 } from "react/jsx-runtime";
3555
+ import { jsx as jsx18 } from "react/jsx-runtime";
2741
3556
  SyntaxHighlighterPrism.registerLanguage("js", tsx);
2742
3557
  SyntaxHighlighterPrism.registerLanguage("jsx", tsx);
2743
3558
  SyntaxHighlighterPrism.registerLanguage("ts", tsx);
@@ -2748,7 +3563,7 @@ var SyntaxHighlighter = ({
2748
3563
  language,
2749
3564
  className
2750
3565
  }) => {
2751
- return /* @__PURE__ */ jsx17(
3566
+ return /* @__PURE__ */ jsx18(
2752
3567
  SyntaxHighlighterPrism,
2753
3568
  {
2754
3569
  language,
@@ -2778,14 +3593,14 @@ import {
2778
3593
  TriangleAlert,
2779
3594
  X as X2
2780
3595
  } from "lucide-react";
2781
- import * as React15 from "react";
3596
+ import * as React16 from "react";
2782
3597
 
2783
3598
  // src/components/thread/tooltip-icon-button.tsx
2784
3599
  import { forwardRef as forwardRef5 } from "react";
2785
- import { jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
3600
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2786
3601
  var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
2787
- return /* @__PURE__ */ jsx18(TooltipProvider, { children: /* @__PURE__ */ jsxs9(Tooltip, { children: [
2788
- /* @__PURE__ */ jsx18(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
3602
+ return /* @__PURE__ */ jsx19(TooltipProvider, { children: /* @__PURE__ */ jsxs10(Tooltip, { children: [
3603
+ /* @__PURE__ */ jsx19(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
2789
3604
  Button,
2790
3605
  {
2791
3606
  variant: "ghost",
@@ -2795,17 +3610,17 @@ var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", class
2795
3610
  ref,
2796
3611
  children: [
2797
3612
  children,
2798
- /* @__PURE__ */ jsx18("span", { className: "sr-only", children: tooltip })
3613
+ /* @__PURE__ */ jsx19("span", { className: "sr-only", children: tooltip })
2799
3614
  ]
2800
3615
  }
2801
3616
  ) }),
2802
- /* @__PURE__ */ jsx18(TooltipContent, { side, children: tooltip })
3617
+ /* @__PURE__ */ jsx19(TooltipContent, { side, children: tooltip })
2803
3618
  ] }) });
2804
3619
  });
2805
3620
  TooltipIconButton.displayName = "TooltipIconButton";
2806
3621
 
2807
3622
  // src/components/thread/mermaid-block.tsx
2808
- import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
3623
+ import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
2809
3624
  var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
2810
3625
  var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
2811
3626
  var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
@@ -3053,24 +3868,24 @@ function MermaidPreviewDialog({
3053
3868
  svgMarkup,
3054
3869
  title
3055
3870
  }) {
3056
- return /* @__PURE__ */ jsx19(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs10(Dialog.Portal, { children: [
3057
- /* @__PURE__ */ jsx19(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
3058
- /* @__PURE__ */ jsxs10(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
3059
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3060
- /* @__PURE__ */ jsx19(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3061
- /* @__PURE__ */ jsx19(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxs10(
3871
+ return /* @__PURE__ */ jsx20(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs11(Dialog.Portal, { children: [
3872
+ /* @__PURE__ */ jsx20(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
3873
+ /* @__PURE__ */ jsxs11(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
3874
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3875
+ /* @__PURE__ */ jsx20(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3876
+ /* @__PURE__ */ jsx20(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxs11(
3062
3877
  "button",
3063
3878
  {
3064
3879
  type: "button",
3065
3880
  className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
3066
3881
  children: [
3067
- /* @__PURE__ */ jsx19(X2, { className: "size-4" }),
3068
- /* @__PURE__ */ jsx19("span", { className: "sr-only", children: closeLabel })
3882
+ /* @__PURE__ */ jsx20(X2, { className: "size-4" }),
3883
+ /* @__PURE__ */ jsx20("span", { className: "sr-only", children: closeLabel })
3069
3884
  ]
3070
3885
  }
3071
3886
  ) })
3072
3887
  ] }),
3073
- /* @__PURE__ */ jsx19("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ jsx19(
3888
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ jsx20(
3074
3889
  "div",
3075
3890
  {
3076
3891
  "data-slot": "mermaid-preview",
@@ -3084,24 +3899,24 @@ function MermaidPreviewDialog({
3084
3899
  function MermaidBlock({ code }) {
3085
3900
  const { t } = useChatkitTranslation();
3086
3901
  const { theme, isDarkMode } = useTheme();
3087
- const containerRef = React15.useRef(null);
3088
- const renderHostRef = React15.useRef(null);
3089
- const renderSequenceRef = React15.useRef(0);
3090
- const copyResetTimeoutRef = React15.useRef(null);
3091
- const diagramId = React15.useId().replace(/:/g, "");
3092
- const [activeTab, setActiveTab] = React15.useState("diagram");
3093
- const [isCopied, setIsCopied] = React15.useState(false);
3094
- const [isPreviewOpen, setIsPreviewOpen] = React15.useState(false);
3095
- const [isRendering, setIsRendering] = React15.useState(true);
3096
- const [renderError, setRenderError] = React15.useState(null);
3097
- const [svgMarkup, setSvgMarkup] = React15.useState(null);
3098
- const normalizedCode = React15.useMemo(() => normalizeMermaidCode(code), [code]);
3099
- const clearCopyResetTimeout = React15.useCallback(() => {
3902
+ const containerRef = React16.useRef(null);
3903
+ const renderHostRef = React16.useRef(null);
3904
+ const renderSequenceRef = React16.useRef(0);
3905
+ const copyResetTimeoutRef = React16.useRef(null);
3906
+ const diagramId = React16.useId().replace(/:/g, "");
3907
+ const [activeTab, setActiveTab] = React16.useState("diagram");
3908
+ const [isCopied, setIsCopied] = React16.useState(false);
3909
+ const [isPreviewOpen, setIsPreviewOpen] = React16.useState(false);
3910
+ const [isRendering, setIsRendering] = React16.useState(true);
3911
+ const [renderError, setRenderError] = React16.useState(null);
3912
+ const [svgMarkup, setSvgMarkup] = React16.useState(null);
3913
+ const normalizedCode = React16.useMemo(() => normalizeMermaidCode(code), [code]);
3914
+ const clearCopyResetTimeout = React16.useCallback(() => {
3100
3915
  if (copyResetTimeoutRef.current === null) return;
3101
3916
  window.clearTimeout(copyResetTimeoutRef.current);
3102
3917
  copyResetTimeoutRef.current = null;
3103
3918
  }, []);
3104
- React15.useEffect(() => {
3919
+ React16.useEffect(() => {
3105
3920
  let isActive = true;
3106
3921
  async function runRender() {
3107
3922
  const container = containerRef.current;
@@ -3139,17 +3954,17 @@ function MermaidBlock({ code }) {
3139
3954
  }
3140
3955
  };
3141
3956
  }, [diagramId, isDarkMode, normalizedCode, theme]);
3142
- React15.useEffect(() => {
3957
+ React16.useEffect(() => {
3143
3958
  clearCopyResetTimeout();
3144
3959
  setIsCopied(false);
3145
3960
  }, [activeTab, clearCopyResetTimeout, code]);
3146
- React15.useEffect(
3961
+ React16.useEffect(
3147
3962
  () => () => {
3148
3963
  clearCopyResetTimeout();
3149
3964
  },
3150
3965
  [clearCopyResetTimeout]
3151
3966
  );
3152
- const handleDownload = React15.useCallback(() => {
3967
+ const handleDownload = React16.useCallback(() => {
3153
3968
  if (!svgMarkup) return;
3154
3969
  const blob = new Blob([svgMarkup], {
3155
3970
  type: "image/svg+xml;charset=utf-8"
@@ -3163,7 +3978,7 @@ function MermaidBlock({ code }) {
3163
3978
  anchor.remove();
3164
3979
  window.URL.revokeObjectURL(url);
3165
3980
  }, [diagramId, svgMarkup]);
3166
- const handleCopyCode = React15.useCallback(() => {
3981
+ const handleCopyCode = React16.useCallback(() => {
3167
3982
  if (!code || isCopied) return;
3168
3983
  navigator.clipboard.writeText(code).then(() => {
3169
3984
  setIsCopied(true);
@@ -3177,21 +3992,21 @@ function MermaidBlock({ code }) {
3177
3992
  }, [clearCopyResetTimeout, code, isCopied]);
3178
3993
  const hasRenderedDiagram = svgMarkup !== null && !renderError;
3179
3994
  const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
3180
- return /* @__PURE__ */ jsxs10(Fragment2, { children: [
3181
- /* @__PURE__ */ jsx19(
3995
+ return /* @__PURE__ */ jsxs11(Fragment2, { children: [
3996
+ /* @__PURE__ */ jsx20(
3182
3997
  Tabs,
3183
3998
  {
3184
3999
  className: "w-full",
3185
4000
  onValueChange: (value) => setActiveTab(value),
3186
4001
  value: activeTab,
3187
- children: /* @__PURE__ */ jsxs10(
4002
+ children: /* @__PURE__ */ jsxs11(
3188
4003
  "div",
3189
4004
  {
3190
4005
  ref: containerRef,
3191
4006
  "data-slot": "mermaid-block",
3192
4007
  className: "relative overflow-hidden text-card-foreground",
3193
4008
  children: [
3194
- /* @__PURE__ */ jsx19(
4009
+ /* @__PURE__ */ jsx20(
3195
4010
  "div",
3196
4011
  {
3197
4012
  ref: renderHostRef,
@@ -3200,62 +4015,62 @@ function MermaidBlock({ code }) {
3200
4015
  "data-slot": "mermaid-render-host"
3201
4016
  }
3202
4017
  ),
3203
- /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3204
- /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-3", children: [
3205
- /* @__PURE__ */ jsx19("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx19(Code2Icon, { className: "size-4" }) }),
3206
- /* @__PURE__ */ jsx19("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
4018
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
4019
+ /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 items-center gap-3", children: [
4020
+ /* @__PURE__ */ jsx20("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx20(Code2Icon, { className: "size-4" }) }),
4021
+ /* @__PURE__ */ jsx20("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3207
4022
  ] }),
3208
- /* @__PURE__ */ jsxs10("div", { className: "flex shrink-0 items-center gap-2", children: [
3209
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1", children: [
3210
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx19(
4023
+ /* @__PURE__ */ jsxs11("div", { className: "flex shrink-0 items-center gap-2", children: [
4024
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1", children: [
4025
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3211
4026
  TooltipIconButton,
3212
4027
  {
3213
4028
  onClick: handleDownload,
3214
4029
  tooltip: t("markdown.mermaid.download"),
3215
- children: /* @__PURE__ */ jsx19(DownloadIcon, { className: "size-4" })
4030
+ children: /* @__PURE__ */ jsx20(DownloadIcon, { className: "size-4" })
3216
4031
  }
3217
4032
  ) : null,
3218
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx19(
4033
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3219
4034
  TooltipIconButton,
3220
4035
  {
3221
4036
  onClick: () => setIsPreviewOpen(true),
3222
4037
  tooltip: t("markdown.mermaid.fullScreen"),
3223
- children: /* @__PURE__ */ jsx19(ExpandIcon, { className: "size-4" })
4038
+ children: /* @__PURE__ */ jsx20(ExpandIcon, { className: "size-4" })
3224
4039
  }
3225
4040
  ) : null,
3226
- activeTab === "code" ? /* @__PURE__ */ jsx19(
4041
+ activeTab === "code" ? /* @__PURE__ */ jsx20(
3227
4042
  TooltipIconButton,
3228
4043
  {
3229
4044
  onClick: handleCopyCode,
3230
4045
  tooltip: t("markdown.copy"),
3231
- children: isCopied ? /* @__PURE__ */ jsx19(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx19(CopyIcon, { className: "size-4" })
4046
+ children: isCopied ? /* @__PURE__ */ jsx20(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx20(CopyIcon, { className: "size-4" })
3232
4047
  }
3233
4048
  ) : null
3234
4049
  ] }),
3235
- /* @__PURE__ */ jsxs10(TabsList, { children: [
3236
- /* @__PURE__ */ jsx19(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
3237
- /* @__PURE__ */ jsx19(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
4050
+ /* @__PURE__ */ jsxs11(TabsList, { children: [
4051
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
4052
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
3238
4053
  ] })
3239
4054
  ] })
3240
4055
  ] }),
3241
- /* @__PURE__ */ jsxs10("div", { className: "border-t border-border pt-4", children: [
3242
- renderError ? /* @__PURE__ */ jsx19("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
3243
- /* @__PURE__ */ jsx19(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ jsx19(
4056
+ /* @__PURE__ */ jsxs11("div", { className: "border-t border-border pt-4", children: [
4057
+ renderError ? /* @__PURE__ */ jsx20("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
4058
+ /* @__PURE__ */ jsx20(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ jsx20(
3244
4059
  "div",
3245
4060
  {
3246
4061
  className: cn(
3247
4062
  "relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
3248
4063
  hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
3249
4064
  ),
3250
- children: hasRenderedDiagram ? /* @__PURE__ */ jsx19(
4065
+ children: hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3251
4066
  "div",
3252
4067
  {
3253
4068
  "data-slot": "mermaid-diagram",
3254
4069
  dangerouslySetInnerHTML: { __html: svgMarkup }
3255
4070
  }
3256
- ) : /* @__PURE__ */ jsxs10("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
3257
- isRendering ? /* @__PURE__ */ jsx19(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx19(TriangleAlert, { className: "size-5 text-destructive" }),
3258
- /* @__PURE__ */ jsx19(
4071
+ ) : /* @__PURE__ */ jsxs11("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
4072
+ isRendering ? /* @__PURE__ */ jsx20(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx20(TriangleAlert, { className: "size-5 text-destructive" }),
4073
+ /* @__PURE__ */ jsx20(
3259
4074
  "p",
3260
4075
  {
3261
4076
  className: cn("text-sm font-medium", !isRendering && "text-destructive"),
@@ -3266,12 +4081,12 @@ function MermaidBlock({ code }) {
3266
4081
  ] })
3267
4082
  }
3268
4083
  ) }),
3269
- /* @__PURE__ */ jsx19(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ jsx19(
4084
+ /* @__PURE__ */ jsx20(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ jsx20(
3270
4085
  "pre",
3271
4086
  {
3272
4087
  "data-slot": "mermaid-code",
3273
4088
  className: "overflow-x-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-zinc-950 px-4 py-4 text-sm text-zinc-50",
3274
- children: /* @__PURE__ */ jsx19("code", { className: "block whitespace-pre font-mono", children: code })
4089
+ children: /* @__PURE__ */ jsx20("code", { className: "block whitespace-pre font-mono", children: code })
3275
4090
  }
3276
4091
  ) })
3277
4092
  ] })
@@ -3280,7 +4095,7 @@ function MermaidBlock({ code }) {
3280
4095
  )
3281
4096
  }
3282
4097
  ),
3283
- svgMarkup ? /* @__PURE__ */ jsx19(
4098
+ svgMarkup ? /* @__PURE__ */ jsx20(
3284
4099
  MermaidPreviewDialog,
3285
4100
  {
3286
4101
  closeLabel: t("sheet.close"),
@@ -3295,25 +4110,174 @@ function MermaidBlock({ code }) {
3295
4110
 
3296
4111
  // src/components/thread/markdown-text.tsx
3297
4112
  import "katex/dist/katex.min.css";
3298
- import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
4113
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
3299
4114
  var markdownTableMinWidth = "max(7rem, calc(8rem * var(--density-spacing, 1)))";
3300
4115
  var markdownTableCellPaddingInline = "calc(var(--density-padding, 1rem) * 1.25)";
3301
4116
  var markdownTableCellPaddingBlock = "max(0.5rem, calc(var(--density-padding, 1rem) * 0.75))";
3302
4117
  var markdownTableLineHeight = "max(1.375rem, calc(1.5rem * var(--density-spacing, 1)))";
3303
4118
  var markdownInlineCodePaddingInline = "max(0.25rem, calc(var(--density-gap, 0.5rem) * 0.75))";
3304
4119
  var markdownInlineCodePaddingBlock = "max(0.125rem, calc(var(--density-gap, 0.5rem) * 0.5))";
4120
+ var proposedPlanOpenPattern = /^\s*<proposed_plan>\s*$/;
4121
+ var proposedPlanClosePattern = /^\s*<\/proposed_plan>\s*$/;
4122
+ var markdownFencePattern = /^ {0,3}(`{3,}|~{3,})/;
4123
+ var planMarkdownFencePattern = /^\s*(`{3,}|~{3,})[ \t]*(?:markdown|md)[^\n]*\r?\n([\s\S]*?)\r?\n\1[ \t]*\s*$/i;
4124
+ var stripMarkdownNode = (props) => {
4125
+ const elementProps = { ...props };
4126
+ delete elementProps.node;
4127
+ return elementProps;
4128
+ };
3305
4129
  var getTextContent = (children) => Children.toArray(children).map((child) => {
3306
4130
  if (typeof child === "string" || typeof child === "number") {
3307
4131
  return String(child);
3308
4132
  }
3309
4133
  return "";
3310
4134
  }).join("");
4135
+ var getFenceMarker = (line) => {
4136
+ const match = markdownFencePattern.exec(line);
4137
+ if (!match) return null;
4138
+ return {
4139
+ char: match[1][0],
4140
+ length: match[1].length
4141
+ };
4142
+ };
4143
+ var updateFenceMarker = (currentFence, line) => {
4144
+ const marker = getFenceMarker(line);
4145
+ if (!marker) return currentFence;
4146
+ if (!currentFence) {
4147
+ return marker;
4148
+ }
4149
+ if (marker.char === currentFence.char && marker.length >= currentFence.length) {
4150
+ return null;
4151
+ }
4152
+ return currentFence;
4153
+ };
4154
+ var normalizePlanMarkdown = (markdown) => {
4155
+ const trimmed = markdown.trim();
4156
+ const match = planMarkdownFencePattern.exec(trimmed);
4157
+ return match ? match[2].trim() : trimmed;
4158
+ };
4159
+ var downloadMarkdown = (markdown) => {
4160
+ if (!markdown) return;
4161
+ const content = markdown.endsWith("\n") ? markdown : `${markdown}
4162
+ `;
4163
+ const blob = new Blob([content], {
4164
+ type: "text/markdown;charset=utf-8"
4165
+ });
4166
+ const url = URL.createObjectURL(blob);
4167
+ const anchor = document.createElement("a");
4168
+ anchor.href = url;
4169
+ anchor.download = "plan.md";
4170
+ document.body.appendChild(anchor);
4171
+ anchor.click();
4172
+ anchor.remove();
4173
+ URL.revokeObjectURL(url);
4174
+ };
4175
+ var splitProposedPlanSegments = (markdown) => {
4176
+ const segments = [];
4177
+ const markdownLines = [];
4178
+ let planLines = null;
4179
+ let fence = null;
4180
+ const flushMarkdown = () => {
4181
+ if (markdownLines.length === 0) return;
4182
+ segments.push({
4183
+ type: "markdown",
4184
+ content: markdownLines.join("\n")
4185
+ });
4186
+ markdownLines.length = 0;
4187
+ };
4188
+ const flushPlan = () => {
4189
+ if (!planLines) return;
4190
+ segments.push({
4191
+ type: "plan",
4192
+ content: planLines.join("\n")
4193
+ });
4194
+ planLines = null;
4195
+ };
4196
+ for (const line of markdown.split(/\r?\n/)) {
4197
+ if (!fence && !planLines && proposedPlanOpenPattern.test(line)) {
4198
+ flushMarkdown();
4199
+ planLines = [];
4200
+ continue;
4201
+ }
4202
+ if (!fence && planLines && proposedPlanClosePattern.test(line)) {
4203
+ flushPlan();
4204
+ continue;
4205
+ }
4206
+ if (planLines) {
4207
+ planLines.push(line);
4208
+ } else {
4209
+ markdownLines.push(line);
4210
+ }
4211
+ fence = updateFenceMarker(fence, line);
4212
+ }
4213
+ flushPlan();
4214
+ flushMarkdown();
4215
+ return segments;
4216
+ };
4217
+ function MarkdownContent({ children }) {
4218
+ return /* @__PURE__ */ jsx21(
4219
+ ReactMarkdown,
4220
+ {
4221
+ remarkPlugins: [remarkGfm, remarkMath],
4222
+ rehypePlugins: [rehypeKatex],
4223
+ components: defaultComponents,
4224
+ children
4225
+ }
4226
+ );
4227
+ }
4228
+ function PlanCard({ children }) {
4229
+ const { t } = useChatkitTranslation();
4230
+ const planMarkdown = normalizePlanMarkdown(children);
4231
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
4232
+ const onCopy = () => {
4233
+ if (!planMarkdown || isCopied) return;
4234
+ copyToClipboard(planMarkdown);
4235
+ };
4236
+ const onDownload = () => {
4237
+ downloadMarkdown(planMarkdown);
4238
+ };
4239
+ return /* @__PURE__ */ jsxs12(
4240
+ "section",
4241
+ {
4242
+ "data-slot": "markdown-plan-card",
4243
+ className: cn(
4244
+ "relative my-5 max-w-4xl rounded-lg border border-border bg-muted/25"
4245
+ ),
4246
+ children: [
4247
+ /* @__PURE__ */ jsxs12("div", { className: "absolute top-3 right-3 flex items-center gap-1", children: [
4248
+ /* @__PURE__ */ jsx21(
4249
+ TooltipIconButton,
4250
+ {
4251
+ tooltip: t("markdown.plan.download"),
4252
+ onClick: onDownload,
4253
+ className: "bg-background/80 text-muted-foreground hover:text-foreground",
4254
+ children: /* @__PURE__ */ jsx21(DownloadIcon2, { className: "size-4" })
4255
+ }
4256
+ ),
4257
+ /* @__PURE__ */ jsxs12(
4258
+ TooltipIconButton,
4259
+ {
4260
+ tooltip: isCopied ? t("messageActions.copied") : t("markdown.copy"),
4261
+ onClick: onCopy,
4262
+ className: "bg-background/80 text-muted-foreground hover:text-foreground",
4263
+ children: [
4264
+ !isCopied && /* @__PURE__ */ jsx21(CopyIcon2, { className: "size-4" }),
4265
+ isCopied && /* @__PURE__ */ jsx21(CheckIcon2, { className: "size-4" })
4266
+ ]
4267
+ }
4268
+ )
4269
+ ] }),
4270
+ /* @__PURE__ */ jsx21("div", { className: "w-full max-h-[80vh] py-3 pr-4 pl-4 overflow-auto", children: /* @__PURE__ */ jsx21(MarkdownContent, { children: planMarkdown }) })
4271
+ ]
4272
+ }
4273
+ );
4274
+ }
3311
4275
  var isMermaidBlockChild = (child) => isValidElement(child) && child.type === MermaidBlock;
3312
4276
  var isMermaidCodeElement = (child) => isValidElement(child) && typeof child.props.className === "string" && child.props.className.includes("language-mermaid");
3313
- var useCopyToClipboard = ({
4277
+ function useCopyToClipboard({
3314
4278
  copiedDuration = 3e3
3315
- } = {}) => {
3316
- const [isCopied, setIsCopied] = useState8(false);
4279
+ } = {}) {
4280
+ const [isCopied, setIsCopied] = useState9(false);
3317
4281
  const copyToClipboard = (value) => {
3318
4282
  if (!value) return;
3319
4283
  navigator.clipboard.writeText(value).then(() => {
@@ -3322,7 +4286,7 @@ var useCopyToClipboard = ({
3322
4286
  });
3323
4287
  };
3324
4288
  return { isCopied, copyToClipboard };
3325
- };
4289
+ }
3326
4290
  var CodeHeader = ({ language, code }) => {
3327
4291
  const { t } = useChatkitTranslation();
3328
4292
  const { isCopied, copyToClipboard } = useCopyToClipboard();
@@ -3330,87 +4294,80 @@ var CodeHeader = ({ language, code }) => {
3330
4294
  if (!code || isCopied) return;
3331
4295
  copyToClipboard(code);
3332
4296
  };
3333
- return /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
3334
- /* @__PURE__ */ jsx20("span", { className: "lowercase [&>span]:text-xs", children: language }),
3335
- /* @__PURE__ */ jsxs11(
3336
- TooltipIconButton,
3337
- {
3338
- tooltip: t("markdown.copy"),
3339
- onClick: onCopy,
3340
- children: [
3341
- !isCopied && /* @__PURE__ */ jsx20(CopyIcon2, {}),
3342
- isCopied && /* @__PURE__ */ jsx20(CheckIcon2, {})
3343
- ]
3344
- }
3345
- )
4297
+ return /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
4298
+ /* @__PURE__ */ jsx21("span", { className: "lowercase [&>span]:text-xs", children: language }),
4299
+ /* @__PURE__ */ jsxs12(TooltipIconButton, { tooltip: t("markdown.copy"), onClick: onCopy, children: [
4300
+ !isCopied && /* @__PURE__ */ jsx21(CopyIcon2, {}),
4301
+ isCopied && /* @__PURE__ */ jsx21(CheckIcon2, {})
4302
+ ] })
3346
4303
  ] });
3347
4304
  };
3348
4305
  var defaultComponents = {
3349
- h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4306
+ h1: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3350
4307
  "h1",
3351
4308
  {
3352
4309
  className: cn(
3353
4310
  "mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
3354
4311
  className
3355
4312
  ),
3356
- ...props
4313
+ ...stripMarkdownNode(props)
3357
4314
  }
3358
4315
  ),
3359
- h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4316
+ h2: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3360
4317
  "h2",
3361
4318
  {
3362
4319
  className: cn(
3363
4320
  "mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
3364
4321
  className
3365
4322
  ),
3366
- ...props
4323
+ ...stripMarkdownNode(props)
3367
4324
  }
3368
4325
  ),
3369
- h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4326
+ h3: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3370
4327
  "h3",
3371
4328
  {
3372
4329
  className: cn(
3373
4330
  "mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
3374
4331
  className
3375
4332
  ),
3376
- ...props
4333
+ ...stripMarkdownNode(props)
3377
4334
  }
3378
4335
  ),
3379
- h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4336
+ h4: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3380
4337
  "h4",
3381
4338
  {
3382
4339
  className: cn(
3383
4340
  "mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
3384
4341
  className
3385
4342
  ),
3386
- ...props
4343
+ ...stripMarkdownNode(props)
3387
4344
  }
3388
4345
  ),
3389
- h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4346
+ h5: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3390
4347
  "h5",
3391
4348
  {
3392
4349
  className: cn(
3393
4350
  "my-4 text-lg font-semibold first:mt-0 last:mb-0",
3394
4351
  className
3395
4352
  ),
3396
- ...props
4353
+ ...stripMarkdownNode(props)
3397
4354
  }
3398
4355
  ),
3399
- h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4356
+ h6: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3400
4357
  "h6",
3401
4358
  {
3402
4359
  className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
3403
- ...props
4360
+ ...stripMarkdownNode(props)
3404
4361
  }
3405
4362
  ),
3406
- p: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4363
+ p: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3407
4364
  "p",
3408
4365
  {
3409
4366
  className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
3410
- ...props
4367
+ ...stripMarkdownNode(props)
3411
4368
  }
3412
4369
  ),
3413
- a: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4370
+ a: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3414
4371
  "a",
3415
4372
  {
3416
4373
  className: cn(
@@ -3419,55 +4376,49 @@ var defaultComponents = {
3419
4376
  ),
3420
4377
  target: "_blank",
3421
4378
  rel: "noopener noreferrer",
3422
- ...props
4379
+ ...stripMarkdownNode(props)
3423
4380
  }
3424
4381
  ),
3425
- blockquote: ({
3426
- className,
3427
- node: _node,
3428
- ...props
3429
- }) => /* @__PURE__ */ jsx20(
4382
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3430
4383
  "blockquote",
3431
4384
  {
3432
4385
  className: cn(
3433
4386
  "border-l-4 border-border pl-6 italic text-muted-foreground",
3434
4387
  className
3435
4388
  ),
3436
- ...props
4389
+ ...stripMarkdownNode(props)
3437
4390
  }
3438
4391
  ),
3439
- ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4392
+ ul: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3440
4393
  "ul",
3441
4394
  {
3442
4395
  className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
3443
- ...props
4396
+ ...stripMarkdownNode(props)
3444
4397
  }
3445
4398
  ),
3446
- ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4399
+ ol: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3447
4400
  "ol",
3448
4401
  {
3449
- className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
3450
- ...props
4402
+ className: cn(
4403
+ "my-5 list-outside list-decimal pl-8 [&>li]:mt-2",
4404
+ className
4405
+ ),
4406
+ ...stripMarkdownNode(props)
3451
4407
  }
3452
4408
  ),
3453
- hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4409
+ hr: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3454
4410
  "hr",
3455
4411
  {
3456
4412
  className: cn("my-5 border-b", className),
3457
- ...props
4413
+ ...stripMarkdownNode(props)
3458
4414
  }
3459
4415
  ),
3460
- table: ({
3461
- className,
3462
- node: _node,
3463
- style,
3464
- ...props
3465
- }) => /* @__PURE__ */ jsx20(
4416
+ table: ({ className, style, ...props }) => /* @__PURE__ */ jsx21(
3466
4417
  "div",
3467
4418
  {
3468
4419
  "data-slot": "markdown-table-container",
3469
4420
  className: "my-5 max-w-full overflow-x-auto rounded-xl border border-border bg-background",
3470
- children: /* @__PURE__ */ jsx20(
4421
+ children: /* @__PURE__ */ jsx21(
3471
4422
  "table",
3472
4423
  {
3473
4424
  className: cn(
@@ -3478,17 +4429,12 @@ var defaultComponents = {
3478
4429
  lineHeight: markdownTableLineHeight,
3479
4430
  ...style
3480
4431
  },
3481
- ...props
4432
+ ...stripMarkdownNode(props)
3482
4433
  }
3483
4434
  )
3484
4435
  }
3485
4436
  ),
3486
- th: ({
3487
- className,
3488
- node: _node,
3489
- style,
3490
- ...props
3491
- }) => /* @__PURE__ */ jsx20(
4437
+ th: ({ className, style, ...props }) => /* @__PURE__ */ jsx21(
3492
4438
  "th",
3493
4439
  {
3494
4440
  className: cn(
@@ -3501,15 +4447,10 @@ var defaultComponents = {
3501
4447
  paddingBlock: markdownTableCellPaddingBlock,
3502
4448
  ...style
3503
4449
  },
3504
- ...props
4450
+ ...stripMarkdownNode(props)
3505
4451
  }
3506
4452
  ),
3507
- td: ({
3508
- className,
3509
- node: _node,
3510
- style,
3511
- ...props
3512
- }) => /* @__PURE__ */ jsx20(
4453
+ td: ({ className, style, ...props }) => /* @__PURE__ */ jsx21(
3513
4454
  "td",
3514
4455
  {
3515
4456
  className: cn(
@@ -3522,128 +4463,925 @@ var defaultComponents = {
3522
4463
  paddingBlock: markdownTableCellPaddingBlock,
3523
4464
  ...style
3524
4465
  },
3525
- ...props
4466
+ ...stripMarkdownNode(props)
3526
4467
  }
3527
4468
  ),
3528
- tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4469
+ tr: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3529
4470
  "tr",
3530
4471
  {
3531
4472
  className: cn(
3532
4473
  "m-0 p-0 even:bg-muted/30 [&:last-child>td:first-child]:rounded-bl-xl [&:last-child>td:last-child]:rounded-br-xl",
3533
4474
  className
3534
4475
  ),
3535
- ...props
4476
+ ...stripMarkdownNode(props)
3536
4477
  }
3537
4478
  ),
3538
- sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx20(
4479
+ sup: ({ className, ...props }) => /* @__PURE__ */ jsx21(
3539
4480
  "sup",
3540
4481
  {
3541
4482
  className: cn("[&>a]:text-xs [&>a]:no-underline", className),
3542
- ...props
4483
+ ...stripMarkdownNode(props)
3543
4484
  }
3544
4485
  ),
3545
- pre: ({ className, children, node: _node }) => Children.toArray(children).length === 1 && (isMermaidBlockChild(Children.toArray(children)[0]) || isMermaidCodeElement(Children.toArray(children)[0])) ? /* @__PURE__ */ jsx20(Fragment3, { children }) : /* @__PURE__ */ jsx20(
4486
+ pre: ({ className, children }) => Children.toArray(children).length === 1 && (isMermaidBlockChild(Children.toArray(children)[0]) || isMermaidCodeElement(Children.toArray(children)[0])) ? /* @__PURE__ */ jsx21(Fragment3, { children }) : /* @__PURE__ */ jsx21(
3546
4487
  "div",
3547
4488
  {
3548
4489
  className: cn(
3549
- "max-w-4xl overflow-x-auto rounded-lg text-sm bg-black text-white dark:bg-zinc-800",
3550
- className
4490
+ "max-w-4xl overflow-x-auto rounded-lg text-sm bg-black text-white dark:bg-zinc-800",
4491
+ className
4492
+ ),
4493
+ children
4494
+ }
4495
+ ),
4496
+ code: ({
4497
+ className,
4498
+ children,
4499
+ style,
4500
+ ...props
4501
+ }) => {
4502
+ const match = /language-([\w-]+)/.exec(className || "");
4503
+ const code = getTextContent(children);
4504
+ const isBlockCode = code.includes("\n");
4505
+ if (match) {
4506
+ const language = match[1];
4507
+ const normalizedCode = code.replace(/\n$/, "");
4508
+ if (language === "mermaid") {
4509
+ return /* @__PURE__ */ jsx21(MermaidBlock, { code: normalizedCode });
4510
+ }
4511
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
4512
+ /* @__PURE__ */ jsx21(CodeHeader, { language, code: normalizedCode }),
4513
+ /* @__PURE__ */ jsx21(SyntaxHighlighter, { language, className, children: normalizedCode })
4514
+ ] });
4515
+ }
4516
+ if (isBlockCode) {
4517
+ return /* @__PURE__ */ jsx21(
4518
+ "code",
4519
+ {
4520
+ className: cn(
4521
+ "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
4522
+ className
4523
+ ),
4524
+ ...stripMarkdownNode(props),
4525
+ children: code.replace(/\n$/, "")
4526
+ }
4527
+ );
4528
+ }
4529
+ return /* @__PURE__ */ jsx21(
4530
+ "code",
4531
+ {
4532
+ className: cn(
4533
+ "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
4534
+ className
4535
+ ),
4536
+ style: {
4537
+ paddingInline: markdownInlineCodePaddingInline,
4538
+ paddingBlock: markdownInlineCodePaddingBlock,
4539
+ ...style
4540
+ },
4541
+ ...stripMarkdownNode(props),
4542
+ children
4543
+ }
4544
+ );
4545
+ }
4546
+ };
4547
+ var MarkdownTextImpl = ({ children }) => {
4548
+ return /* @__PURE__ */ jsx21("div", { className: "markdown-content", children: splitProposedPlanSegments(children).map(
4549
+ (segment, index) => segment.type === "plan" ? /* @__PURE__ */ jsx21(PlanCard, { children: segment.content }, index) : /* @__PURE__ */ jsx21(MarkdownContent, { children: segment.content }, index)
4550
+ ) });
4551
+ };
4552
+ var MarkdownText = memo(MarkdownTextImpl);
4553
+
4554
+ // src/components/thread/messages/tool-component-group.tsx
4555
+ import * as React17 from "react";
4556
+ import {
4557
+ Check as Check2,
4558
+ CheckCircle2 as CheckCircle22,
4559
+ ChevronRight as ChevronRight2,
4560
+ Copy,
4561
+ Loader2 as Loader22,
4562
+ XCircle
4563
+ } from "lucide-react";
4564
+
4565
+ // src/i18n/localized-text.ts
4566
+ function resolveLocalizedText(value, language) {
4567
+ if (typeof value === "string") {
4568
+ const trimmed = value.trim();
4569
+ return trimmed || null;
4570
+ }
4571
+ if (!value || typeof value !== "object") return null;
4572
+ const localized = value;
4573
+ const normalizedLanguage = language.trim();
4574
+ const underscoredLanguage = normalizedLanguage.replace(/-/g, "_");
4575
+ const languagePrefix = normalizedLanguage.split("-")[0];
4576
+ const preferredKeys = normalizedLanguage.startsWith("zh") ? [
4577
+ normalizedLanguage,
4578
+ underscoredLanguage,
4579
+ "zh_Hans",
4580
+ "zh-Hans",
4581
+ "zh_CN",
4582
+ "zh-CN",
4583
+ "zh",
4584
+ "en_US",
4585
+ "en-US",
4586
+ "en"
4587
+ ] : [
4588
+ normalizedLanguage,
4589
+ underscoredLanguage,
4590
+ "en_US",
4591
+ "en-US",
4592
+ "en",
4593
+ languagePrefix,
4594
+ "zh_Hans",
4595
+ "zh-Hans",
4596
+ "zh_CN",
4597
+ "zh-CN",
4598
+ "zh"
4599
+ ];
4600
+ for (const key of preferredKeys) {
4601
+ const candidate = localized[key];
4602
+ if (typeof candidate === "string" && candidate.trim()) {
4603
+ return candidate.trim();
4604
+ }
4605
+ }
4606
+ for (const candidate of Object.values(localized)) {
4607
+ if (typeof candidate === "string" && candidate.trim()) {
4608
+ return candidate.trim();
4609
+ }
4610
+ }
4611
+ return null;
4612
+ }
4613
+
4614
+ // src/components/thread/messages/tool-component-group.tsx
4615
+ import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
4616
+ var toolStatusConfig = {
4617
+ success: {
4618
+ iconClass: "border-green-500 text-green-700",
4619
+ icon: CheckCircle22
4620
+ },
4621
+ fail: {
4622
+ iconClass: "border-red-500 text-red-700",
4623
+ icon: XCircle
4624
+ },
4625
+ running: {
4626
+ iconClass: "border-blue-500 text-blue-700",
4627
+ icon: Loader22
4628
+ }
4629
+ };
4630
+ var TOOL_GROUP_CATEGORY_ORDER = [
4631
+ "files",
4632
+ "searches",
4633
+ "commands",
4634
+ "lists",
4635
+ "tasks",
4636
+ "knowledges",
4637
+ "tools"
4638
+ ];
4639
+ var TOOL_GROUP_TOKEN_CATEGORY = {
4640
+ file: "files",
4641
+ files: "files",
4642
+ web_search: "searches",
4643
+ search: "searches",
4644
+ searches: "searches",
4645
+ program: "commands",
4646
+ command: "commands",
4647
+ commands: "commands",
4648
+ shell: "commands",
4649
+ terminal: "commands",
4650
+ list: "lists",
4651
+ lists: "lists",
4652
+ task: "tasks",
4653
+ tasks: "tasks",
4654
+ todo: "tasks",
4655
+ todos: "tasks",
4656
+ knowledge: "knowledges",
4657
+ knowledges: "knowledges",
4658
+ retriever: "knowledges",
4659
+ retrieval: "knowledges",
4660
+ tool: "tools",
4661
+ tools: "tools"
4662
+ };
4663
+ var TOOL_CALL_OUTPUT_RENDERERS = {};
4664
+ function getToolStepData(content) {
4665
+ return content.data ?? {};
4666
+ }
4667
+ function safeJson(value) {
4668
+ try {
4669
+ return JSON.stringify(value, null, 2) ?? String(value);
4670
+ } catch {
4671
+ return String(value);
4672
+ }
4673
+ }
4674
+ function formatDisplayValue(value) {
4675
+ return typeof value === "string" ? value : safeJson(value);
4676
+ }
4677
+ function parseStepDate(value) {
4678
+ if (value instanceof Date) {
4679
+ const timestamp2 = value.getTime();
4680
+ return Number.isNaN(timestamp2) ? null : timestamp2;
4681
+ }
4682
+ if (typeof value !== "string") {
4683
+ return null;
4684
+ }
4685
+ const timestamp = Date.parse(value);
4686
+ return Number.isNaN(timestamp) ? null : timestamp;
4687
+ }
4688
+ function formatStepDuration(durationMs) {
4689
+ if (durationMs < 1e3) {
4690
+ return `${durationMs}ms`;
4691
+ }
4692
+ if (durationMs < 1e4) {
4693
+ return `${(durationMs / 1e3).toFixed(1)}s`;
4694
+ }
4695
+ if (durationMs < 6e4) {
4696
+ return `${Math.round(durationMs / 1e3)}s`;
4697
+ }
4698
+ const hours = Math.floor(durationMs / 36e5);
4699
+ const minutes = Math.floor(durationMs % 36e5 / 6e4);
4700
+ const seconds = Math.floor(durationMs % 6e4 / 1e3);
4701
+ if (hours > 0) {
4702
+ return `${hours}h ${minutes}m ${seconds}s`;
4703
+ }
4704
+ return `${minutes}m ${seconds}s`;
4705
+ }
4706
+ function useToolStepDurationLabel(data) {
4707
+ const [durationNow, setDurationNow] = React17.useState(() => Date.now());
4708
+ const createdAt = parseStepDate(data.created_date);
4709
+ const endedAt = parseStepDate(data.end_date);
4710
+ const status = data.status;
4711
+ React17.useEffect(() => {
4712
+ if (status !== "running" || createdAt === null || endedAt !== null) {
4713
+ return;
4714
+ }
4715
+ setDurationNow(Date.now());
4716
+ const timer = window.setInterval(() => {
4717
+ setDurationNow(Date.now());
4718
+ }, 100);
4719
+ return () => {
4720
+ window.clearInterval(timer);
4721
+ };
4722
+ }, [createdAt, endedAt, status]);
4723
+ if (createdAt === null) return null;
4724
+ const durationMs = Math.max(0, (endedAt ?? durationNow) - createdAt);
4725
+ return formatStepDuration(durationMs);
4726
+ }
4727
+ function isJsonObjectValue(value) {
4728
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4729
+ }
4730
+ function canUseAsJsonValue(value) {
4731
+ if (value === null) return true;
4732
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
4733
+ return true;
4734
+ }
4735
+ if (Array.isArray(value)) {
4736
+ return value.every(canUseAsJsonValue);
4737
+ }
4738
+ if (typeof value === "object") {
4739
+ return Object.values(value).every(canUseAsJsonValue);
4740
+ }
4741
+ return false;
4742
+ }
4743
+ function parseJsonString(value) {
4744
+ const trimmed = value.trim();
4745
+ if (!trimmed) return null;
4746
+ const first = trimmed[0];
4747
+ if (first !== "{" && first !== "[") return null;
4748
+ try {
4749
+ const parsed = JSON.parse(trimmed);
4750
+ return canUseAsJsonValue(parsed) ? parsed : null;
4751
+ } catch {
4752
+ return null;
4753
+ }
4754
+ }
4755
+ function detectJsonValue(value) {
4756
+ if (typeof value === "string") {
4757
+ const parsed = parseJsonString(value);
4758
+ if (parsed !== null) {
4759
+ return {
4760
+ kind: "json",
4761
+ value: parsed,
4762
+ raw: safeJson(parsed)
4763
+ };
4764
+ }
4765
+ return { kind: "text", text: value };
4766
+ }
4767
+ if (canUseAsJsonValue(value) && value !== null && typeof value === "object") {
4768
+ return {
4769
+ kind: "json",
4770
+ value,
4771
+ raw: safeJson(value)
4772
+ };
4773
+ }
4774
+ return { kind: "text", text: formatDisplayValue(value) };
4775
+ }
4776
+ function isComponentContent(content) {
4777
+ return content.type === "component";
4778
+ }
4779
+ function isTextContent(content) {
4780
+ return content.type === "text";
4781
+ }
4782
+ function isReasoningContent(content) {
4783
+ return content.type === "reasoning";
4784
+ }
4785
+ function isWidgetComponent(content) {
4786
+ const data = content.data;
4787
+ return data?.type === "Widget" && Array.isArray(data.widgets);
4788
+ }
4789
+ function isGroupableToolComponent(content) {
4790
+ if (!content || typeof content === "string") return false;
4791
+ return isComponentContent(content) && !isWidgetComponent(content) && content.data?.category === "Tool";
4792
+ }
4793
+ function isSkippableToolGroupSeparator(content) {
4794
+ if (typeof content === "string") return !content.trim();
4795
+ if (!content) return true;
4796
+ if (isTextContent(content)) {
4797
+ return !content.text?.trim();
4798
+ }
4799
+ if (isReasoningContent(content)) {
4800
+ return !content.text?.trim();
4801
+ }
4802
+ return false;
4803
+ }
4804
+ function normalizeToolToken(value) {
4805
+ if (typeof value !== "string") return null;
4806
+ const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
4807
+ return normalized || null;
4808
+ }
4809
+ function classifyToolToken(value) {
4810
+ const normalized = normalizeToolToken(
4811
+ typeof value === "string" ? value : resolveLocalizedText(value, "en-US")
4812
+ );
4813
+ if (!normalized) return null;
4814
+ const directMatch = TOOL_GROUP_TOKEN_CATEGORY[normalized];
4815
+ if (directMatch) return directMatch;
4816
+ if (normalized.includes("search")) return "searches";
4817
+ if (normalized.includes("file")) return "files";
4818
+ if (normalized.includes("command") || normalized.includes("cmd") || normalized.includes("program") || normalized.includes("exec") || normalized.startsWith("run_") || normalized.includes("_run")) {
4819
+ return "commands";
4820
+ }
4821
+ if (normalized.includes("list")) return "lists";
4822
+ if (normalized.includes("task") || normalized.includes("todo")) return "tasks";
4823
+ if (normalized.includes("knowledge") || normalized.includes("retriever")) {
4824
+ return "knowledges";
4825
+ }
4826
+ return null;
4827
+ }
4828
+ function getToolGroupCategory(content) {
4829
+ const data = getToolStepData(content);
4830
+ return classifyToolToken(data.type) ?? classifyToolToken(data.tool) ?? classifyToolToken(data.title) ?? classifyToolToken(data.message) ?? "tools";
4831
+ }
4832
+ function getToolGroupCategoryCounts(items) {
4833
+ return items.reduce((counts, item) => {
4834
+ const category = getToolGroupCategory(item);
4835
+ counts[category] = (counts[category] ?? 0) + 1;
4836
+ return counts;
4837
+ }, {});
4838
+ }
4839
+ function getToolGroupDisplayStatus(items) {
4840
+ if (items.some((item) => getToolStepData(item).status === "fail")) {
4841
+ return "fail";
4842
+ }
4843
+ return "success";
4844
+ }
4845
+ function getToolActivityLabel(content, language) {
4846
+ const data = getToolStepData(content);
4847
+ const runningCandidates = [data.message, data.title, data.tool, data.type];
4848
+ const completedCandidates = [data.title, data.message, data.tool, data.type];
4849
+ const candidates = data.status === "running" ? runningCandidates : completedCandidates;
4850
+ for (const candidate of candidates) {
4851
+ const label = resolveLocalizedText(candidate, language);
4852
+ if (label) return label;
4853
+ }
4854
+ return "Tool";
4855
+ }
4856
+ function flushPendingTools(units, pendingTools) {
4857
+ if (pendingTools.length === 0) return;
4858
+ units.push({
4859
+ type: "tool-group",
4860
+ items: pendingTools.map((tool) => tool.item),
4861
+ startIndex: pendingTools[0].index
4862
+ });
4863
+ pendingTools.length = 0;
4864
+ }
4865
+ function buildToolComponentRenderUnits(content, options) {
4866
+ const units = [];
4867
+ const pendingTools = [];
4868
+ content.forEach((item, index) => {
4869
+ if (isGroupableToolComponent(item) && options?.shouldGroupComponent?.(item) !== false) {
4870
+ pendingTools.push({ item, index });
4871
+ return;
4872
+ }
4873
+ if (isSkippableToolGroupSeparator(item)) {
4874
+ return;
4875
+ }
4876
+ if (item === void 0) {
4877
+ return;
4878
+ }
4879
+ flushPendingTools(units, pendingTools);
4880
+ units.push({ type: "item", item, index });
4881
+ });
4882
+ flushPendingTools(units, pendingTools);
4883
+ return units;
4884
+ }
4885
+ function getToolCallOutputRenderer(data) {
4886
+ const keys = [data.tool, data.type].filter(
4887
+ (value) => typeof value === "string" && Boolean(value.trim())
4888
+ );
4889
+ for (const key of keys) {
4890
+ const renderer = TOOL_CALL_OUTPUT_RENDERERS[key];
4891
+ if (renderer) return renderer;
4892
+ }
4893
+ return DefaultToolCallOutput;
4894
+ }
4895
+ function getJsonValueSummary(value) {
4896
+ if (Array.isArray(value)) {
4897
+ return `Array(${value.length})`;
4898
+ }
4899
+ if (isJsonObjectValue(value)) {
4900
+ return `Object(${Object.keys(value).length})`;
4901
+ }
4902
+ return "JSON";
4903
+ }
4904
+ function formatJsonPrimitive(value) {
4905
+ if (value === null) return "null";
4906
+ if (typeof value === "string") return JSON.stringify(value);
4907
+ return String(value);
4908
+ }
4909
+ function JsonTreeNode({
4910
+ label,
4911
+ value,
4912
+ depth = 0
4913
+ }) {
4914
+ const isArray = Array.isArray(value);
4915
+ const isObject = isJsonObjectValue(value);
4916
+ const isExpandable = isArray || isObject;
4917
+ const [isExpanded, setIsExpanded] = React17.useState(depth < 2);
4918
+ if (!isExpandable) {
4919
+ return /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 gap-2 leading-6", children: [
4920
+ label ? /* @__PURE__ */ jsxs13("span", { className: "shrink-0 font-medium text-foreground/80", children: [
4921
+ label,
4922
+ ":"
4923
+ ] }) : null,
4924
+ /* @__PURE__ */ jsx22(
4925
+ "span",
4926
+ {
4927
+ className: cn(
4928
+ "min-w-0 wrap-break-word",
4929
+ typeof value === "string" ? "text-emerald-700" : typeof value === "number" ? "text-blue-700" : typeof value === "boolean" ? "text-purple-700" : "text-muted-foreground"
4930
+ ),
4931
+ children: formatJsonPrimitive(value)
4932
+ }
4933
+ )
4934
+ ] });
4935
+ }
4936
+ const entries = isArray ? value.map((item, index) => [String(index), item]) : Object.entries(value);
4937
+ const summary = isArray ? `Array(${value.length})` : `Object(${entries.length})`;
4938
+ return /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
4939
+ /* @__PURE__ */ jsxs13(
4940
+ "button",
4941
+ {
4942
+ type: "button",
4943
+ className: "flex min-w-0 items-center gap-1 leading-6 text-left hover:text-foreground",
4944
+ "aria-expanded": isExpanded,
4945
+ onClick: () => setIsExpanded((prev) => !prev),
4946
+ children: [
4947
+ /* @__PURE__ */ jsx22(
4948
+ ChevronRight2,
4949
+ {
4950
+ "aria-hidden": "true",
4951
+ className: cn(
4952
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
4953
+ isExpanded && "rotate-90"
4954
+ )
4955
+ }
4956
+ ),
4957
+ label ? /* @__PURE__ */ jsxs13("span", { className: "min-w-0 truncate font-medium text-foreground/80", children: [
4958
+ label,
4959
+ ":"
4960
+ ] }) : null,
4961
+ /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: summary })
4962
+ ]
4963
+ }
4964
+ ),
4965
+ isExpanded ? /* @__PURE__ */ jsx22("div", { className: "ml-4 border-l border-border/70 pl-3", children: entries.map(([entryLabel, entryValue]) => /* @__PURE__ */ jsx22(
4966
+ JsonTreeNode,
4967
+ {
4968
+ label: entryLabel,
4969
+ value: entryValue,
4970
+ depth: depth + 1
4971
+ },
4972
+ entryLabel
4973
+ )) }) : null
4974
+ ] });
4975
+ }
4976
+ function JsonTreeView({ value }) {
4977
+ return /* @__PURE__ */ jsx22("div", { className: "min-w-0 font-mono text-[11px]", children: /* @__PURE__ */ jsx22(JsonTreeNode, { value }) });
4978
+ }
4979
+ function RawJsonBlock({ raw }) {
4980
+ return /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word font-mono text-[11px]", children: raw });
4981
+ }
4982
+ function PlainTextBlock({ value, destructive = false }) {
4983
+ return /* @__PURE__ */ jsx22(
4984
+ "pre",
4985
+ {
4986
+ className: cn(
4987
+ "whitespace-pre-wrap wrap-break-word",
4988
+ destructive && "text-destructive"
3551
4989
  ),
3552
- children
4990
+ children: value
3553
4991
  }
3554
- ),
3555
- code: ({
3556
- className,
3557
- children,
3558
- node: _node,
3559
- style,
3560
- ...props
3561
- }) => {
3562
- const match = /language-([\w-]+)/.exec(className || "");
3563
- const code = getTextContent(children);
3564
- const isBlockCode = code.includes("\n");
3565
- if (match) {
3566
- const language = match[1];
3567
- const normalizedCode = code.replace(/\n$/, "");
3568
- if (language === "mermaid") {
3569
- return /* @__PURE__ */ jsx20(MermaidBlock, { code: normalizedCode });
3570
- }
3571
- return /* @__PURE__ */ jsxs11(Fragment3, { children: [
3572
- /* @__PURE__ */ jsx20(
3573
- CodeHeader,
3574
- {
3575
- language,
3576
- code: normalizedCode
3577
- }
3578
- ),
3579
- /* @__PURE__ */ jsx20(
3580
- SyntaxHighlighter,
3581
- {
3582
- language,
3583
- className,
3584
- children: normalizedCode
3585
- }
3586
- )
3587
- ] });
4992
+ );
4993
+ }
4994
+ function ToolCallCopyButton({ value }) {
4995
+ const { t } = useChatkitTranslation();
4996
+ const [isCopied, setIsCopied] = React17.useState(false);
4997
+ const resetTimeoutRef = React17.useRef(null);
4998
+ const clearResetTimeout = React17.useCallback(() => {
4999
+ if (resetTimeoutRef.current === null) return;
5000
+ window.clearTimeout(resetTimeoutRef.current);
5001
+ resetTimeoutRef.current = null;
5002
+ }, []);
5003
+ React17.useEffect(() => clearResetTimeout, [clearResetTimeout]);
5004
+ const handleCopy = React17.useCallback(() => {
5005
+ if (typeof navigator === "undefined" || !navigator.clipboard) return;
5006
+ void navigator.clipboard.writeText(value).then(() => {
5007
+ setIsCopied(true);
5008
+ clearResetTimeout();
5009
+ resetTimeoutRef.current = window.setTimeout(() => {
5010
+ setIsCopied(false);
5011
+ resetTimeoutRef.current = null;
5012
+ }, 1500);
5013
+ }).catch(() => void 0);
5014
+ }, [clearResetTimeout, value]);
5015
+ const label = isCopied ? t("message.toolGroup.copied") : t("message.toolGroup.copy");
5016
+ return /* @__PURE__ */ jsx22(
5017
+ "button",
5018
+ {
5019
+ type: "button",
5020
+ className: "inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-background hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40",
5021
+ "aria-label": label,
5022
+ title: label,
5023
+ onClick: handleCopy,
5024
+ children: isCopied ? /* @__PURE__ */ jsx22(Check2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx22(Copy, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
3588
5025
  }
3589
- if (isBlockCode) {
3590
- return /* @__PURE__ */ jsx20(
3591
- "code",
3592
- {
3593
- className: cn(
3594
- "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
3595
- className
3596
- ),
3597
- ...props,
3598
- children: code.replace(/\n$/, "")
3599
- }
3600
- );
5026
+ );
5027
+ }
5028
+ function ToolCallValueBlock({
5029
+ value,
5030
+ destructive = false
5031
+ }) {
5032
+ const { t } = useChatkitTranslation();
5033
+ const detected = detectJsonValue(value);
5034
+ if (detected.kind === "text") {
5035
+ return /* @__PURE__ */ jsxs13("div", { className: "min-w-0 space-y-1", children: [
5036
+ /* @__PURE__ */ jsx22("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx22(ToolCallCopyButton, { value: detected.text }) }),
5037
+ /* @__PURE__ */ jsx22(PlainTextBlock, { value: detected.text, destructive })
5038
+ ] });
5039
+ }
5040
+ return /* @__PURE__ */ jsxs13(Tabs, { defaultValue: "tree", className: "min-w-0", children: [
5041
+ /* @__PURE__ */ jsxs13("div", { className: "mb-2 flex min-w-0 items-center justify-between gap-2", children: [
5042
+ /* @__PURE__ */ jsxs13("span", { className: "min-w-0 truncate text-[11px] text-muted-foreground", children: [
5043
+ t("message.toolGroup.jsonTitle"),
5044
+ " \xB7 ",
5045
+ getJsonValueSummary(detected.value)
5046
+ ] }),
5047
+ /* @__PURE__ */ jsxs13("div", { className: "flex shrink-0 items-center gap-1", children: [
5048
+ /* @__PURE__ */ jsx22(ToolCallCopyButton, { value: detected.raw }),
5049
+ /* @__PURE__ */ jsxs13(TabsList, { className: "rounded-md p-0.5", children: [
5050
+ /* @__PURE__ */ jsx22(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "tree", children: t("message.toolGroup.jsonTree") }),
5051
+ /* @__PURE__ */ jsx22(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "raw", children: t("message.toolGroup.jsonRaw") })
5052
+ ] })
5053
+ ] })
5054
+ ] }),
5055
+ /* @__PURE__ */ jsx22(TabsContent, { value: "tree", className: "mt-0", children: /* @__PURE__ */ jsx22(JsonTreeView, { value: detected.value }) }),
5056
+ /* @__PURE__ */ jsx22(TabsContent, { value: "raw", className: "mt-0", children: /* @__PURE__ */ jsx22(RawJsonBlock, { raw: detected.raw }) })
5057
+ ] });
5058
+ }
5059
+ function DefaultToolCallOutput({ data }) {
5060
+ const { t } = useChatkitTranslation();
5061
+ const output = data.output ?? null;
5062
+ const error = data.error ?? null;
5063
+ if (error) {
5064
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
5065
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-destructive", children: t("message.toolGroup.errorTitle") }),
5066
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: error, destructive: true })
5067
+ ] });
5068
+ }
5069
+ if (output === null) return null;
5070
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
5071
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.outputTitle") }),
5072
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: output })
5073
+ ] });
5074
+ }
5075
+ function ToolCallDetails({ content }) {
5076
+ const { t } = useChatkitTranslation();
5077
+ const data = getToolStepData(content);
5078
+ const OutputRenderer = getToolCallOutputRenderer(data);
5079
+ const hasInput = data.input !== void 0 && data.input !== null;
5080
+ const hasOutput = data.error !== void 0 || data.output !== void 0;
5081
+ if (!hasInput && !hasOutput) return null;
5082
+ return /* @__PURE__ */ jsxs13("div", { className: "ml-6 mt-1 max-h-60 overflow-auto rounded-md bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: [
5083
+ hasInput && /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
5084
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.inputTitle") }),
5085
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: data.input })
5086
+ ] }),
5087
+ hasInput && hasOutput ? /* @__PURE__ */ jsx22("div", { className: "h-2" }) : null,
5088
+ hasOutput ? /* @__PURE__ */ jsx22(OutputRenderer, { content, data }) : null
5089
+ ] });
5090
+ }
5091
+ function ToolCallRow({ content }) {
5092
+ const { i18n: i18n2 } = useChatkitTranslation();
5093
+ const data = getToolStepData(content);
5094
+ const status = data.status;
5095
+ const itemConfig = status ? toolStatusConfig[status] : null;
5096
+ const ItemStatusIcon = itemConfig?.icon;
5097
+ const hasError = status === "fail" || Boolean(data.error);
5098
+ const label = getToolActivityLabel(content, i18n2.language);
5099
+ const detailsId = React17.useId();
5100
+ const hasDetails = data.input !== void 0 || data.error !== void 0 || data.output !== void 0;
5101
+ const durationLabel = useToolStepDurationLabel(data);
5102
+ const [isExpanded, setIsExpanded] = React17.useState(false);
5103
+ React17.useEffect(() => {
5104
+ if (status === "running" && data.output !== void 0) {
5105
+ setIsExpanded(true);
3601
5106
  }
3602
- return /* @__PURE__ */ jsx20(
3603
- "code",
5107
+ }, [data.output, status]);
5108
+ return /* @__PURE__ */ jsxs13("li", { className: "min-w-0", children: [
5109
+ /* @__PURE__ */ jsxs13(
5110
+ "button",
3604
5111
  {
5112
+ type: "button",
3605
5113
  className: cn(
3606
- "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
3607
- className
5114
+ "flex w-full min-w-0 items-center gap-2 text-left text-sm leading-6 text-muted-foreground",
5115
+ hasDetails && "cursor-pointer hover:text-foreground",
5116
+ hasError && "text-destructive hover:text-destructive"
3608
5117
  ),
3609
- style: {
3610
- paddingInline: markdownInlineCodePaddingInline,
3611
- paddingBlock: markdownInlineCodePaddingBlock,
3612
- ...style
5118
+ "aria-expanded": hasDetails ? isExpanded : void 0,
5119
+ "aria-controls": hasDetails ? detailsId : void 0,
5120
+ disabled: !hasDetails,
5121
+ onClick: () => {
5122
+ if (hasDetails) setIsExpanded((prev) => !prev);
3613
5123
  },
3614
- ...props,
3615
- children
5124
+ children: [
5125
+ ItemStatusIcon ? /* @__PURE__ */ jsx22(
5126
+ ItemStatusIcon,
5127
+ {
5128
+ className: cn(
5129
+ "h-3.5 w-3.5 shrink-0",
5130
+ itemConfig?.iconClass,
5131
+ status === "running" && "animate-spin"
5132
+ )
5133
+ }
5134
+ ) : /* @__PURE__ */ jsx22("span", { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
5135
+ /* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1 truncate", title: label, children: label }),
5136
+ durationLabel ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground/80", children: durationLabel }) : null,
5137
+ hasDetails ? /* @__PURE__ */ jsx22(
5138
+ ChevronRight2,
5139
+ {
5140
+ "aria-hidden": "true",
5141
+ className: cn(
5142
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
5143
+ isExpanded && "rotate-90"
5144
+ )
5145
+ }
5146
+ ) : null
5147
+ ]
5148
+ }
5149
+ ),
5150
+ hasDetails && isExpanded ? /* @__PURE__ */ jsx22("div", { id: detailsId, children: /* @__PURE__ */ jsx22(ToolCallDetails, { content }) }) : null
5151
+ ] });
5152
+ }
5153
+ function ToolComponentGroup({
5154
+ items,
5155
+ hasFollowingItem
5156
+ }) {
5157
+ const { t } = useChatkitTranslation();
5158
+ const contentId = React17.useId();
5159
+ const groupStatus = getToolGroupDisplayStatus(items);
5160
+ const [isExpanded, setIsExpanded] = React17.useState(!hasFollowingItem);
5161
+ const categoryCounts = getToolGroupCategoryCounts(items);
5162
+ const categorySummary = TOOL_GROUP_CATEGORY_ORDER.flatMap((category) => {
5163
+ const count = categoryCounts[category] ?? 0;
5164
+ if (count === 0) return [];
5165
+ return [
5166
+ t(
5167
+ `message.toolGroup.categories.${category}.${count === 1 ? "one" : "other"}`,
5168
+ { count }
5169
+ )
5170
+ ];
5171
+ }).join(t("message.toolGroup.separator"));
5172
+ const summary = `${t(`message.toolGroup.status.${groupStatus}`)} ${categorySummary}`;
5173
+ const config = toolStatusConfig[groupStatus];
5174
+ const StatusIcon = config.icon;
5175
+ React17.useEffect(() => {
5176
+ setIsExpanded(!hasFollowingItem);
5177
+ }, [hasFollowingItem, items.length]);
5178
+ return /* @__PURE__ */ jsxs13("div", { className: "px-1 py-1", children: [
5179
+ /* @__PURE__ */ jsxs13(
5180
+ "button",
5181
+ {
5182
+ type: "button",
5183
+ className: "flex w-full items-center justify-between gap-3 text-left opacity-60 hover:opacity-100 disabled:pointer-events-none data-[state=open]:bg-muted",
5184
+ "aria-expanded": isExpanded,
5185
+ "aria-controls": contentId,
5186
+ onClick: () => setIsExpanded((prev) => !prev),
5187
+ children: [
5188
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
5189
+ /* @__PURE__ */ jsx22(
5190
+ StatusIcon,
5191
+ {
5192
+ className: cn(
5193
+ "h-4 w-4 shrink-0",
5194
+ config.iconClass
5195
+ )
5196
+ }
5197
+ ),
5198
+ /* @__PURE__ */ jsx22("span", { className: "truncate", children: summary })
5199
+ ] }),
5200
+ /* @__PURE__ */ jsx22(
5201
+ ChevronRight2,
5202
+ {
5203
+ "aria-hidden": "true",
5204
+ className: cn(
5205
+ "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
5206
+ isExpanded && "rotate-90"
5207
+ )
5208
+ }
5209
+ )
5210
+ ]
3616
5211
  }
5212
+ ),
5213
+ isExpanded && /* @__PURE__ */ jsx22("ul", { id: contentId, className: "mt-2 max-h-[200px] space-y-1.5 overflow-y-auto pr-1", children: items.map((item, index) => /* @__PURE__ */ jsx22(ToolCallRow, { content: item }, item.id ?? `tool-item-${index}`)) })
5214
+ ] });
5215
+ }
5216
+
5217
+ // src/components/thread/messages/request-user-input-result-card.tsx
5218
+ import "react";
5219
+ import {
5220
+ REQUEST_USER_INPUT_RESULT_TYPE as REQUEST_USER_INPUT_RESULT_TYPE2,
5221
+ REQUEST_USER_INPUT_TOOL_NAME as REQUEST_USER_INPUT_TOOL_NAME2
5222
+ } from "@xpert-ai/chatkit-types";
5223
+ import { CheckCircle2 as CheckCircle23 } from "lucide-react";
5224
+ import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
5225
+ function isRecord2(value) {
5226
+ return !!value && typeof value === "object" && !Array.isArray(value);
5227
+ }
5228
+ function readString(record, keys) {
5229
+ for (const key of keys) {
5230
+ const value = record[key];
5231
+ if (typeof value === "string" && value.trim()) {
5232
+ return value.trim();
5233
+ }
5234
+ }
5235
+ return null;
5236
+ }
5237
+ function getToolCallId(value) {
5238
+ if (!isRecord2(value)) return null;
5239
+ return readString(value, ["id"]);
5240
+ }
5241
+ function getToolCallName(value) {
5242
+ if (!isRecord2(value)) return null;
5243
+ return readString(value, ["name"]);
5244
+ }
5245
+ function pushClientToolCallsFromRecord(record, calls) {
5246
+ const clientToolCalls = record.clientToolCalls;
5247
+ if (Array.isArray(clientToolCalls)) {
5248
+ calls.push(...clientToolCalls);
5249
+ }
5250
+ }
5251
+ function collectPotentialToolCalls(messages) {
5252
+ const calls = [];
5253
+ const messageList = Array.isArray(messages) ? messages : [messages];
5254
+ for (const message of messageList) {
5255
+ const rawMessage = message;
5256
+ pushClientToolCallsFromRecord(rawMessage, calls);
5257
+ }
5258
+ return calls;
5259
+ }
5260
+ function findRequestUserInputClientToolCallById(messages, id) {
5261
+ if (!id) return null;
5262
+ return collectPotentialToolCalls(messages).find(
5263
+ (call) => getToolCallId(call) === id && getToolCallName(call) === REQUEST_USER_INPUT_TOOL_NAME2
5264
+ ) ?? null;
5265
+ }
5266
+ function normalizeAnswer(value) {
5267
+ if (!isRecord2(value)) return null;
5268
+ const id = readString(value, ["id"]);
5269
+ const question = readString(value, ["question"]);
5270
+ const answerValue = readString(value, ["value"]);
5271
+ const type = readString(value, ["type"]);
5272
+ if (!id || !question || !answerValue || type !== "option" && type !== "other") {
5273
+ return null;
5274
+ }
5275
+ const label = readString(value, ["label"]);
5276
+ const description = readString(value, ["description"]);
5277
+ return {
5278
+ id,
5279
+ question,
5280
+ value: answerValue,
5281
+ type,
5282
+ ...label ? { label } : {},
5283
+ ...description ? { description } : {}
5284
+ };
5285
+ }
5286
+ function parseResultOutput(output) {
5287
+ let result = output;
5288
+ if (typeof output === "string") {
5289
+ try {
5290
+ result = JSON.parse(output);
5291
+ } catch {
5292
+ return null;
5293
+ }
5294
+ }
5295
+ if (!isRecord2(result) || !Array.isArray(result.answers)) {
5296
+ return null;
5297
+ }
5298
+ const hasExplicitType = result.type === REQUEST_USER_INPUT_RESULT_TYPE2;
5299
+ const answers = result.answers.map(normalizeAnswer);
5300
+ if (answers.some((answer) => answer === null)) {
5301
+ return null;
5302
+ }
5303
+ return {
5304
+ answers,
5305
+ hasExplicitType
5306
+ };
5307
+ }
5308
+ function getRequestUserInputResultCardData(content, messages) {
5309
+ const data = isRecord2(content.data) ? content.data : null;
5310
+ if (data?.status !== "success") {
5311
+ return null;
5312
+ }
5313
+ const result = parseResultOutput(data.output);
5314
+ if (!result || result.answers.length === 0) {
5315
+ return null;
5316
+ }
5317
+ if (!result.hasExplicitType) {
5318
+ const toolCall = findRequestUserInputClientToolCallById(
5319
+ messages,
5320
+ content.id
3617
5321
  );
5322
+ if (!toolCall) {
5323
+ return null;
5324
+ }
3618
5325
  }
3619
- };
3620
- var MarkdownTextImpl = ({ children }) => {
3621
- return /* @__PURE__ */ jsx20("div", { className: "markdown-content", children: /* @__PURE__ */ jsx20(
3622
- ReactMarkdown,
5326
+ return {
5327
+ toolCallId: content.id,
5328
+ answers: result.answers
5329
+ };
5330
+ }
5331
+ function RequestUserInputResultCard({
5332
+ result,
5333
+ className
5334
+ }) {
5335
+ const { t } = useChatkitTranslation();
5336
+ return /* @__PURE__ */ jsxs14(
5337
+ "section",
3623
5338
  {
3624
- remarkPlugins: [remarkGfm, remarkMath],
3625
- rehypePlugins: [rehypeKatex],
3626
- components: defaultComponents,
3627
- children
5339
+ "aria-label": t("message.requestUserInputResult.title"),
5340
+ className: cn(
5341
+ "rounded-lg border border-border bg-muted/25 px-3 py-2.5",
5342
+ className
5343
+ ),
5344
+ children: [
5345
+ /* @__PURE__ */ jsxs14("div", { className: "mb-2 flex items-center gap-2 text-sm font-semibold text-foreground", children: [
5346
+ /* @__PURE__ */ jsx23(CheckCircle23, { className: "h-4 w-4 text-primary" }),
5347
+ /* @__PURE__ */ jsx23("span", { children: t("message.requestUserInputResult.title") })
5348
+ ] }),
5349
+ /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: result.answers.map((answer, index) => /* @__PURE__ */ jsxs14(
5350
+ "div",
5351
+ {
5352
+ className: "rounded-md bg-background/70 px-2.5 py-2",
5353
+ children: [
5354
+ /* @__PURE__ */ jsx23("div", { className: "text-xs font-medium leading-5 text-muted-foreground", children: answer.question }),
5355
+ /* @__PURE__ */ jsxs14("div", { className: "mt-0.5 flex min-w-0 flex-wrap items-center gap-1.5", children: [
5356
+ /* @__PURE__ */ jsx23("span", { className: "min-w-0 wrap-break-word text-sm font-semibold text-foreground", children: answer.label ?? answer.value }),
5357
+ /* @__PURE__ */ jsx23("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium text-muted-foreground", children: t(
5358
+ answer.type === "other" ? "message.requestUserInputResult.other" : "message.requestUserInputResult.option"
5359
+ ) })
5360
+ ] }),
5361
+ answer.description ? /* @__PURE__ */ jsx23("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: answer.description }) : null
5362
+ ]
5363
+ },
5364
+ `${answer.id}-${index}`
5365
+ )) })
5366
+ ]
3628
5367
  }
3629
- ) });
3630
- };
3631
- var MarkdownText = memo(MarkdownTextImpl);
5368
+ );
5369
+ }
3632
5370
 
3633
5371
  // src/components/thread/messages/widget.tsx
3634
5372
  import { SurfaceRenderer } from "@xpert-ai/a2ui-react";
3635
- import { jsx as jsx21 } from "react/jsx-runtime";
5373
+ import { jsx as jsx24 } from "react/jsx-runtime";
3636
5374
  function WidgetMessage({ messageId, data }) {
3637
5375
  const widgets = Array.isArray(data.widgets) ? data.widgets : [];
3638
5376
  if (widgets.length === 0) return null;
3639
5377
  const baseSurfaceId = `widget-${messageId}`;
3640
- return /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: widgets.map((widget, index) => {
5378
+ return /* @__PURE__ */ jsx24("div", { className: "space-y-3", children: widgets.map((widget, index) => {
3641
5379
  const config = widget?.config;
3642
5380
  if (!config || typeof config !== "object") {
3643
5381
  return null;
3644
5382
  }
3645
5383
  const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
3646
- return /* @__PURE__ */ jsx21(
5384
+ return /* @__PURE__ */ jsx24(
3647
5385
  SurfaceRenderer,
3648
5386
  {
3649
5387
  surfaceId,
@@ -3655,58 +5393,44 @@ function WidgetMessage({ messageId, data }) {
3655
5393
  }
3656
5394
 
3657
5395
  // src/components/thread/messages/ai.tsx
3658
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
3659
- function isTextContent(content) {
5396
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
5397
+ function isTextContent2(content) {
3660
5398
  return content.type === "text";
3661
5399
  }
3662
- function isReasoningContent(content) {
5400
+ function isReasoningContent2(content) {
3663
5401
  return content.type === "reasoning";
3664
5402
  }
3665
5403
  function isImageContent(content) {
3666
5404
  return content.type === "image_url";
3667
5405
  }
3668
- function isComponentContent(content) {
5406
+ function isComponentContent2(content) {
3669
5407
  return content.type === "component";
3670
5408
  }
3671
- var statusConfig = {
3672
- success: {
3673
- iconClass: "border-green-500 text-green-700",
3674
- icon: CheckCircle22
3675
- },
3676
- fail: {
3677
- iconClass: "border-red-500 text-red-700",
3678
- icon: XCircle
3679
- },
3680
- running: {
3681
- iconClass: "border-blue-500 text-blue-700",
3682
- icon: Loader22
3683
- }
3684
- };
3685
- function isWidgetComponent(content) {
5409
+ function isWidgetComponent2(content) {
3686
5410
  const data = content.data;
3687
5411
  return data?.type === "Widget" && Array.isArray(data.widgets);
3688
5412
  }
3689
5413
  function isMemoryContent(content) {
3690
5414
  return content.type === "memory";
3691
5415
  }
3692
- function safeJson(value) {
5416
+ function safeJson2(value) {
3693
5417
  try {
3694
5418
  return JSON.stringify(value, null, 2);
3695
5419
  } catch {
3696
5420
  return String(value);
3697
5421
  }
3698
5422
  }
3699
- function formatDisplayValue(value) {
3700
- return typeof value === "string" ? value : safeJson(value);
5423
+ function formatDisplayValue2(value) {
5424
+ return typeof value === "string" ? value : safeJson2(value);
3701
5425
  }
3702
5426
  function ReasoningBlock({ reasoning }) {
3703
5427
  const blocks = reasoning.filter((item) => item.text?.trim());
3704
5428
  if (blocks.length === 0) return null;
3705
- return /* @__PURE__ */ jsx22("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx22(
5429
+ return /* @__PURE__ */ jsx25("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx25(
3706
5430
  "div",
3707
5431
  {
3708
5432
  className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
3709
- children: /* @__PURE__ */ jsx22("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
5433
+ children: /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
3710
5434
  },
3711
5435
  item.id ?? `reasoning-${index}`
3712
5436
  )) });
@@ -3714,23 +5438,23 @@ function ReasoningBlock({ reasoning }) {
3714
5438
  function ImageBlock({ content }) {
3715
5439
  const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
3716
5440
  if (!imageUrl) {
3717
- return /* @__PURE__ */ jsxs12(Card, { children: [
3718
- /* @__PURE__ */ jsx22(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx22(CardTitle, { className: "text-sm", children: "Image" }) }),
3719
- /* @__PURE__ */ jsx22(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
5441
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5442
+ /* @__PURE__ */ jsx25(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Image" }) }),
5443
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: safeJson2(content) })
3720
5444
  ] });
3721
5445
  }
3722
- return /* @__PURE__ */ jsx22("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx22("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
5446
+ return /* @__PURE__ */ jsx25("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx25("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
3723
5447
  }
3724
5448
  function MemoryBlock({ content }) {
3725
- return /* @__PURE__ */ jsxs12(Card, { children: [
3726
- /* @__PURE__ */ jsxs12(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3727
- /* @__PURE__ */ jsx22(CardTitle, { className: "text-sm", children: "Memory" }),
3728
- /* @__PURE__ */ jsx22(Badge, { variant: "secondary", children: "Memory" })
5449
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5450
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5451
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Memory" }),
5452
+ /* @__PURE__ */ jsx25(Badge, { variant: "secondary", children: "Memory" })
3729
5453
  ] }),
3730
- /* @__PURE__ */ jsx22(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
5454
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson2(content.data ?? []) }) })
3731
5455
  ] });
3732
5456
  }
3733
- function parseStepDate(value) {
5457
+ function parseStepDate2(value) {
3734
5458
  if (value instanceof Date) {
3735
5459
  const timestamp2 = value.getTime();
3736
5460
  return Number.isNaN(timestamp2) ? null : timestamp2;
@@ -3741,7 +5465,7 @@ function parseStepDate(value) {
3741
5465
  const timestamp = Date.parse(value);
3742
5466
  return Number.isNaN(timestamp) ? null : timestamp;
3743
5467
  }
3744
- function formatStepDuration(durationMs) {
5468
+ function formatStepDuration2(durationMs) {
3745
5469
  if (durationMs < 1e3) {
3746
5470
  return `${durationMs}ms`;
3747
5471
  }
@@ -3760,28 +5484,29 @@ function formatStepDuration(durationMs) {
3760
5484
  return `${minutes}m ${seconds}s`;
3761
5485
  }
3762
5486
  function ComponentBlock({ content }) {
3763
- const [isExpanded, setIsExpanded] = React16.useState(false);
3764
- const contentRef = React16.useRef(null);
3765
- const shouldAutoScrollRef = React16.useRef(true);
3766
- const previousScrollTopRef = React16.useRef(0);
3767
- const [durationNow, setDurationNow] = React16.useState(() => Date.now());
3768
- const data = content.data ?? {};
5487
+ const { i18n: i18n2 } = useChatkitTranslation();
5488
+ const [isExpanded, setIsExpanded] = React19.useState(false);
5489
+ const contentRef = React19.useRef(null);
5490
+ const shouldAutoScrollRef = React19.useRef(true);
5491
+ const previousScrollTopRef = React19.useRef(0);
5492
+ const [durationNow, setDurationNow] = React19.useState(() => Date.now());
5493
+ const data = getToolStepData(content);
3769
5494
  const category = data.category ?? "Component";
3770
- const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
5495
+ const title = getToolActivityLabel(content, i18n2.language);
3771
5496
  const status = data.status ?? null;
3772
5497
  const message = data.message ?? null;
3773
5498
  const output = data.output ?? null;
3774
5499
  const error = data.error ?? null;
3775
5500
  const fallback = message ?? output ?? data.data ?? data;
3776
5501
  const hasOutput = message !== null || output !== null;
3777
- const createdAt = parseStepDate(data.created_date);
3778
- const endedAt = parseStepDate(data.end_date);
5502
+ const createdAt = parseStepDate2(data.created_date);
5503
+ const endedAt = parseStepDate2(data.end_date);
3779
5504
  const durationMs = createdAt === null ? null : Math.max(0, (endedAt ?? durationNow) - createdAt);
3780
- const durationLabel = durationMs === null ? null : formatStepDuration(durationMs);
3781
- React16.useEffect(() => {
5505
+ const durationLabel = durationMs === null ? null : formatStepDuration2(durationMs);
5506
+ React19.useEffect(() => {
3782
5507
  if (status === "running" && output !== null) setIsExpanded(true);
3783
5508
  }, [status, output]);
3784
- React16.useEffect(() => {
5509
+ React19.useEffect(() => {
3785
5510
  if (status !== "running" || createdAt === null || endedAt !== null) {
3786
5511
  return;
3787
5512
  }
@@ -3793,7 +5518,7 @@ function ComponentBlock({ content }) {
3793
5518
  window.clearInterval(timer);
3794
5519
  };
3795
5520
  }, [createdAt, endedAt, status]);
3796
- React16.useEffect(() => {
5521
+ React19.useEffect(() => {
3797
5522
  const element = contentRef.current;
3798
5523
  if (!element) return;
3799
5524
  previousScrollTopRef.current = element.scrollTop;
@@ -3813,7 +5538,7 @@ function ComponentBlock({ content }) {
3813
5538
  element.removeEventListener("scroll", updateAutoScrollState);
3814
5539
  };
3815
5540
  }, [isExpanded]);
3816
- React16.useEffect(() => {
5541
+ React19.useEffect(() => {
3817
5542
  if (status !== "running") {
3818
5543
  shouldAutoScrollRef.current = true;
3819
5544
  return;
@@ -3824,26 +5549,26 @@ function ComponentBlock({ content }) {
3824
5549
  }
3825
5550
  element.scrollTop = element.scrollHeight;
3826
5551
  }, [isExpanded, output, status]);
3827
- const config = status ? statusConfig[status] : null;
5552
+ const config = status ? toolStatusConfig[status] : null;
3828
5553
  const StatusIcon = config?.icon;
3829
- return /* @__PURE__ */ jsxs12(Card, { children: [
3830
- /* @__PURE__ */ jsxs12(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
3831
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
3832
- status && StatusIcon && /* @__PURE__ */ jsx22(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
3833
- /* @__PURE__ */ jsx22(CardTitle, { className: "text-sm truncate", children: title })
5554
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5555
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
5556
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
5557
+ status && StatusIcon && /* @__PURE__ */ jsx25(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
5558
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm truncate", children: title })
3834
5559
  ] }),
3835
- /* @__PURE__ */ jsxs12("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
3836
- durationLabel && /* @__PURE__ */ jsxs12("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
3837
- /* @__PURE__ */ jsx22(Clock3, { className: "h-3 w-3" }),
3838
- /* @__PURE__ */ jsx22("span", { children: durationLabel })
5560
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
5561
+ durationLabel && /* @__PURE__ */ jsxs15("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
5562
+ /* @__PURE__ */ jsx25(Clock3, { className: "h-3 w-3" }),
5563
+ /* @__PURE__ */ jsx25("span", { children: durationLabel })
3839
5564
  ] }),
3840
- /* @__PURE__ */ jsx22(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
3841
- /* @__PURE__ */ jsx22(
5565
+ /* @__PURE__ */ jsx25(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
5566
+ /* @__PURE__ */ jsx25(
3842
5567
  "button",
3843
5568
  {
3844
5569
  className: "text-muted-foreground hover:text-foreground transition-colors",
3845
5570
  "aria-label": isExpanded ? "Collapse" : "Expand",
3846
- children: /* @__PURE__ */ jsx22(
5571
+ children: /* @__PURE__ */ jsx25(
3847
5572
  ChevronDown2,
3848
5573
  {
3849
5574
  className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
@@ -3853,55 +5578,83 @@ function ComponentBlock({ content }) {
3853
5578
  )
3854
5579
  ] })
3855
5580
  ] }),
3856
- isExpanded && /* @__PURE__ */ jsxs12(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
3857
- data.input && /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
3858
- error ? /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
5581
+ isExpanded && /* @__PURE__ */ jsxs15(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
5582
+ data.input && /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(data.input) }),
5583
+ error ? /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue2(error) }) : hasOutput && /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(fallback) })
3859
5584
  ] })
3860
5585
  ] });
3861
5586
  }
3862
5587
  function UnknownBlock({ content }) {
3863
- return /* @__PURE__ */ jsxs12(Card, { children: [
3864
- /* @__PURE__ */ jsxs12(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3865
- /* @__PURE__ */ jsx22(CardTitle, { className: "text-sm", children: "Assistant Content" }),
3866
- /* @__PURE__ */ jsx22(Badge, { variant: "outline", children: content.type ?? "unknown" })
5588
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5589
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5590
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Assistant Content" }),
5591
+ /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: content.type ?? "unknown" })
3867
5592
  ] }),
3868
- /* @__PURE__ */ jsx22(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
5593
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap break-words", children: safeJson2(content) }) })
3869
5594
  ] });
3870
5595
  }
3871
- function renderContentItem(content, index, messageId) {
5596
+ function renderContentItem(content, index, message, lookupMessages) {
5597
+ const messageId = message.id;
3872
5598
  if (typeof content === "string") {
3873
- return /* @__PURE__ */ jsxs12("div", { children: [
3874
- /* @__PURE__ */ jsx22(MarkdownText, { children: content }),
3875
- ";"
3876
- ] }, `text-${index}`);
5599
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MarkdownText, { children: content }) }, `text-${index}`);
3877
5600
  }
3878
- if (isTextContent(content)) {
3879
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
5601
+ if (isTextContent2(content)) {
5602
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
3880
5603
  }
3881
- if (isReasoningContent(content)) {
3882
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
5604
+ if (isReasoningContent2(content)) {
5605
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
3883
5606
  }
3884
5607
  if (isImageContent(content)) {
3885
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(ImageBlock, { content }) }, content.id ?? `image-${index}`);
5608
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ImageBlock, { content }) }, content.id ?? `image-${index}`);
3886
5609
  }
3887
- if (isComponentContent(content)) {
3888
- if (isWidgetComponent(content)) {
3889
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5610
+ if (isComponentContent2(content)) {
5611
+ const requestUserInputResult = getRequestUserInputResultCardData(
5612
+ content,
5613
+ lookupMessages
5614
+ );
5615
+ if (requestUserInputResult) {
5616
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(RequestUserInputResultCard, { result: requestUserInputResult }) }, content.id ?? `request-user-input-result-${index}`);
5617
+ }
5618
+ if (isWidgetComponent2(content)) {
5619
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
3890
5620
  }
3891
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
5621
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
3892
5622
  }
3893
5623
  if (isMemoryContent(content)) {
3894
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5624
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5625
+ }
5626
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5627
+ }
5628
+ function renderContentUnit(unit, message, lookupMessages, hasFollowingItem) {
5629
+ if (unit.type === "item") {
5630
+ return renderContentItem(unit.item, unit.index, message, lookupMessages);
3895
5631
  }
3896
- return /* @__PURE__ */ jsx22("div", { children: /* @__PURE__ */ jsx22(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5632
+ return /* @__PURE__ */ jsx25(
5633
+ "div",
5634
+ {
5635
+ children: /* @__PURE__ */ jsx25(ToolComponentGroup, { items: unit.items, hasFollowingItem })
5636
+ },
5637
+ `tool-group-${unit.startIndex}-${unit.items[0]?.id ?? "tool"}-${unit.items.length}`
5638
+ );
3897
5639
  }
3898
- function renderContent(content, messageId) {
5640
+ function renderContent(message, lookupMessages) {
5641
+ const content = message.content;
3899
5642
  if (typeof content === "string") {
3900
5643
  if (!content.trim()) return null;
3901
- return /* @__PURE__ */ jsx22(MarkdownText, { children: content });
5644
+ return /* @__PURE__ */ jsx25(MarkdownText, { children: content });
3902
5645
  }
3903
5646
  if (!Array.isArray(content) || content.length === 0) return null;
3904
- return /* @__PURE__ */ jsx22("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
5647
+ const renderUnits = buildToolComponentRenderUnits(content, {
5648
+ shouldGroupComponent: (item) => getRequestUserInputResultCardData(item, lookupMessages) === null
5649
+ });
5650
+ return /* @__PURE__ */ jsx25("div", { className: "space-y-3", children: renderUnits.map(
5651
+ (unit, index) => renderContentUnit(
5652
+ unit,
5653
+ message,
5654
+ lookupMessages,
5655
+ index < renderUnits.length - 1
5656
+ )
5657
+ ) });
3905
5658
  }
3906
5659
  function AssistantStreamingIndicator({
3907
5660
  status,
@@ -3913,23 +5666,24 @@ function AssistantStreamingIndicator({
3913
5666
  thinking: t("message.thinking"),
3914
5667
  answering: t("message.answering")
3915
5668
  };
3916
- return /* @__PURE__ */ jsxs12("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
3917
- status === "loading" && /* @__PURE__ */ jsx22(Loader22, { className: "h-3.5 w-3.5 animate-spin" }),
3918
- status === "thinking" && /* @__PURE__ */ jsxs12("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3919
- /* @__PURE__ */ jsx22("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
3920
- /* @__PURE__ */ jsx22("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
3921
- /* @__PURE__ */ jsx22("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
5669
+ return /* @__PURE__ */ jsxs15("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
5670
+ status === "loading" && /* @__PURE__ */ jsx25(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
5671
+ status === "thinking" && /* @__PURE__ */ jsxs15("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5672
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
5673
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
5674
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
3922
5675
  ] }),
3923
- status === "answering" && /* @__PURE__ */ jsxs12("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3924
- /* @__PURE__ */ jsx22("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
3925
- /* @__PURE__ */ jsx22("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
3926
- /* @__PURE__ */ jsx22("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
5676
+ status === "answering" && /* @__PURE__ */ jsxs15("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5677
+ /* @__PURE__ */ jsx25("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
5678
+ /* @__PURE__ */ jsx25("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
5679
+ /* @__PURE__ */ jsx25("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
3927
5680
  ] }),
3928
- /* @__PURE__ */ jsx22("span", { children: labelMap[status] })
5681
+ /* @__PURE__ */ jsx25("span", { children: labelMap[status] })
3929
5682
  ] });
3930
5683
  }
3931
5684
  function AssistantMessage({
3932
5685
  message,
5686
+ messages,
3933
5687
  className,
3934
5688
  isStreaming = false,
3935
5689
  streamingStatus
@@ -3938,43 +5692,44 @@ function AssistantMessage({
3938
5692
  const hasContent = hasRenderableMessageContent(message.content);
3939
5693
  const hasReasoning = hasRenderableReasoning(message.reasoning);
3940
5694
  const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
3941
- const answerNode = renderContent(message.content, message.id);
3942
- const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx22(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
5695
+ const lookupMessages = messages?.length ? messages : [message];
5696
+ const answerNode = renderContent(message, lookupMessages);
5697
+ const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx25(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
3943
5698
  if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
3944
5699
  const streamingClass = isStreaming ? "streaming-active" : "";
3945
5700
  if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
3946
- return /* @__PURE__ */ jsx22("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx22(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
5701
+ return /* @__PURE__ */ jsx25("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
3947
5702
  }
3948
5703
  if (hasContent && hasReasoning) {
3949
- return /* @__PURE__ */ jsxs12("div", { className: cn("space-y-3", streamingClass, className), children: [
3950
- /* @__PURE__ */ jsxs12(
5704
+ return /* @__PURE__ */ jsxs15("div", { className: cn("space-y-3", streamingClass, className), children: [
5705
+ /* @__PURE__ */ jsxs15(
3951
5706
  Tabs,
3952
5707
  {
3953
5708
  defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
3954
5709
  className: "w-full",
3955
5710
  children: [
3956
- /* @__PURE__ */ jsxs12(TabsList, { className: "", children: [
3957
- /* @__PURE__ */ jsx22(TabsTrigger, { value: "answer", children: t("message.answer") }),
3958
- /* @__PURE__ */ jsx22(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
5711
+ /* @__PURE__ */ jsxs15(TabsList, { className: "", children: [
5712
+ /* @__PURE__ */ jsx25(TabsTrigger, { value: "answer", children: t("message.answer") }),
5713
+ /* @__PURE__ */ jsx25(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
3959
5714
  ] }),
3960
- /* @__PURE__ */ jsx22(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
3961
- /* @__PURE__ */ jsx22(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
5715
+ /* @__PURE__ */ jsx25(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
5716
+ /* @__PURE__ */ jsx25(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
3962
5717
  ]
3963
5718
  }
3964
5719
  ),
3965
- resolvedStreamingStatus ? /* @__PURE__ */ jsx22(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5720
+ resolvedStreamingStatus ? /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3966
5721
  ] });
3967
5722
  }
3968
- return /* @__PURE__ */ jsxs12("div", { className: cn("space-y-3", streamingClass, className), children: [
5723
+ return /* @__PURE__ */ jsxs15("div", { className: cn("space-y-3", streamingClass, className), children: [
3969
5724
  hasReasoning ? reasoningNode : answerNode,
3970
- resolvedStreamingStatus ? /* @__PURE__ */ jsx22(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5725
+ resolvedStreamingStatus ? /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3971
5726
  ] });
3972
5727
  }
3973
5728
 
3974
5729
  // src/components/thread/MessageActions.tsx
3975
- import * as React17 from "react";
3976
- import { Check, Copy, RefreshCw } from "lucide-react";
3977
- import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
5730
+ import * as React20 from "react";
5731
+ import { Check as Check3, Copy as Copy2, RefreshCw } from "lucide-react";
5732
+ import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
3978
5733
  function MessageActions({
3979
5734
  content,
3980
5735
  isAssistant = false,
@@ -3983,7 +5738,7 @@ function MessageActions({
3983
5738
  className
3984
5739
  }) {
3985
5740
  const { t } = useChatkitTranslation();
3986
- const [copied, setCopied] = React17.useState(false);
5741
+ const [copied, setCopied] = React20.useState(false);
3987
5742
  const handleCopy = async () => {
3988
5743
  try {
3989
5744
  await navigator.clipboard.writeText(content);
@@ -3996,7 +5751,7 @@ function MessageActions({
3996
5751
  if (isStreaming) {
3997
5752
  return null;
3998
5753
  }
3999
- return /* @__PURE__ */ jsxs13(
5754
+ return /* @__PURE__ */ jsxs16(
4000
5755
  "div",
4001
5756
  {
4002
5757
  className: cn(
@@ -4004,7 +5759,7 @@ function MessageActions({
4004
5759
  className
4005
5760
  ),
4006
5761
  children: [
4007
- /* @__PURE__ */ jsx23(
5762
+ /* @__PURE__ */ jsx26(
4008
5763
  "button",
4009
5764
  {
4010
5765
  type: "button",
@@ -4014,17 +5769,17 @@ function MessageActions({
4014
5769
  copied && "text-green-500"
4015
5770
  ),
4016
5771
  title: copied ? t("messageActions.copied") : t("messageActions.copy"),
4017
- children: copied ? /* @__PURE__ */ jsx23(Check, { size: 14 }) : /* @__PURE__ */ jsx23(Copy, { size: 14 })
5772
+ children: copied ? /* @__PURE__ */ jsx26(Check3, { size: 14 }) : /* @__PURE__ */ jsx26(Copy2, { size: 14 })
4018
5773
  }
4019
5774
  ),
4020
- isAssistant && onRetry && /* @__PURE__ */ jsx23(
5775
+ isAssistant && onRetry && /* @__PURE__ */ jsx26(
4021
5776
  "button",
4022
5777
  {
4023
5778
  type: "button",
4024
5779
  onClick: onRetry,
4025
5780
  className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
4026
5781
  title: t("messageActions.regenerate"),
4027
- children: /* @__PURE__ */ jsx23(RefreshCw, { size: 14 })
5782
+ children: /* @__PURE__ */ jsx26(RefreshCw, { size: 14 })
4028
5783
  }
4029
5784
  )
4030
5785
  ]
@@ -4045,18 +5800,18 @@ import {
4045
5800
  Sparkles as Sparkles2,
4046
5801
  Zap
4047
5802
  } from "lucide-react";
4048
- import { jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
5803
+ import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
4049
5804
  function getIconComponent2(icon) {
4050
5805
  const iconMap = {
4051
- "circle-question": /* @__PURE__ */ jsx24(HelpCircle, { size: 20 }),
4052
- "lightbulb": /* @__PURE__ */ jsx24(Lightbulb2, { size: 20 }),
4053
- "sparkle": /* @__PURE__ */ jsx24(Sparkles2, { size: 20 }),
4054
- "write": /* @__PURE__ */ jsx24(Pencil2, { size: 20 }),
4055
- "search": /* @__PURE__ */ jsx24(Search2, { size: 20 }),
4056
- "globe": /* @__PURE__ */ jsx24(Globe2, { size: 20 }),
4057
- "book-open": /* @__PURE__ */ jsx24(BookOpen, { size: 20 }),
4058
- "compass": /* @__PURE__ */ jsx24(Compass, { size: 20 }),
4059
- "bolt": /* @__PURE__ */ jsx24(Zap, { size: 20 })
5806
+ "circle-question": /* @__PURE__ */ jsx27(HelpCircle, { size: 20 }),
5807
+ "lightbulb": /* @__PURE__ */ jsx27(Lightbulb2, { size: 20 }),
5808
+ "sparkle": /* @__PURE__ */ jsx27(Sparkles2, { size: 20 }),
5809
+ "write": /* @__PURE__ */ jsx27(Pencil2, { size: 20 }),
5810
+ "search": /* @__PURE__ */ jsx27(Search2, { size: 20 }),
5811
+ "globe": /* @__PURE__ */ jsx27(Globe2, { size: 20 }),
5812
+ "book-open": /* @__PURE__ */ jsx27(BookOpen, { size: 20 }),
5813
+ "compass": /* @__PURE__ */ jsx27(Compass, { size: 20 }),
5814
+ "bolt": /* @__PURE__ */ jsx27(Zap, { size: 20 })
4060
5815
  };
4061
5816
  return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
4062
5817
  }
@@ -4064,9 +5819,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4064
5819
  const { t } = useChatkitTranslation();
4065
5820
  const greeting = startScreen?.greeting ?? t("startScreen.greeting");
4066
5821
  const prompts = startScreen?.prompts ?? [];
4067
- return /* @__PURE__ */ jsxs14("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
4068
- /* @__PURE__ */ jsx24("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx24("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
4069
- prompts.length > 0 && /* @__PURE__ */ jsx24("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx24("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs14(
5822
+ return /* @__PURE__ */ jsxs17("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
5823
+ /* @__PURE__ */ jsx27("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx27("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
5824
+ prompts.length > 0 && /* @__PURE__ */ jsx27("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx27("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs17(
4070
5825
  "button",
4071
5826
  {
4072
5827
  type: "button",
@@ -4077,8 +5832,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4077
5832
  "focus:outline-none focus:ring-2 focus:ring-primary/20"
4078
5833
  ),
4079
5834
  children: [
4080
- /* @__PURE__ */ jsx24("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
4081
- /* @__PURE__ */ jsx24("span", { className: "text-sm font-medium text-foreground", children: item.label })
5835
+ /* @__PURE__ */ jsx27("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
5836
+ /* @__PURE__ */ jsx27("span", { className: "text-sm font-medium text-foreground", children: item.label })
4082
5837
  ]
4083
5838
  },
4084
5839
  `prompt-${index}`
@@ -4090,10 +5845,10 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4090
5845
  import "react";
4091
5846
 
4092
5847
  // src/components/ui/avatar.tsx
4093
- import * as React19 from "react";
5848
+ import * as React22 from "react";
4094
5849
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
4095
- import { jsx as jsx25 } from "react/jsx-runtime";
4096
- var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
5850
+ import { jsx as jsx28 } from "react/jsx-runtime";
5851
+ var Avatar = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
4097
5852
  AvatarPrimitive.Root,
4098
5853
  {
4099
5854
  ref,
@@ -4105,7 +5860,7 @@ var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
4105
5860
  }
4106
5861
  ));
4107
5862
  Avatar.displayName = AvatarPrimitive.Root.displayName;
4108
- var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
5863
+ var AvatarImage = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
4109
5864
  AvatarPrimitive.Image,
4110
5865
  {
4111
5866
  ref,
@@ -4114,7 +5869,7 @@ var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PUR
4114
5869
  }
4115
5870
  ));
4116
5871
  AvatarImage.displayName = AvatarPrimitive.Image.displayName;
4117
- var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
5872
+ var AvatarFallback = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
4118
5873
  AvatarPrimitive.Fallback,
4119
5874
  {
4120
5875
  ref,
@@ -4128,7 +5883,7 @@ var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__
4128
5883
  AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
4129
5884
 
4130
5885
  // src/components/ui/chatkit-avatar.tsx
4131
- import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
5886
+ import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
4132
5887
  function asRecord(value) {
4133
5888
  return value && typeof value === "object" ? value : null;
4134
5889
  }
@@ -4201,21 +5956,21 @@ function ChatkitAvatar({
4201
5956
  const fallbackStyle = {
4202
5957
  ...avatar?.background ? { background: avatar.background } : {}
4203
5958
  };
4204
- return /* @__PURE__ */ jsxs15(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
4205
- avatar?.url ? /* @__PURE__ */ jsx26(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
4206
- /* @__PURE__ */ jsx26(
5959
+ return /* @__PURE__ */ jsxs18(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
5960
+ avatar?.url ? /* @__PURE__ */ jsx29(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
5961
+ /* @__PURE__ */ jsx29(
4207
5962
  AvatarFallback,
4208
5963
  {
4209
5964
  className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
4210
5965
  style: fallbackStyle,
4211
- children: emojiCharacter ? /* @__PURE__ */ jsx26("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
5966
+ children: emojiCharacter ? /* @__PURE__ */ jsx29("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
4212
5967
  }
4213
5968
  )
4214
5969
  ] });
4215
5970
  }
4216
5971
 
4217
5972
  // src/hooks/useThreads.ts
4218
- import * as React21 from "react";
5973
+ import * as React24 from "react";
4219
5974
  var DEFAULT_LIMIT = 50;
4220
5975
  var getThreadTitle = (threadRecord) => {
4221
5976
  const title = threadRecord.title?.trim();
@@ -4253,16 +6008,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
4253
6008
  isReady,
4254
6009
  isLoading: isStreamLoading
4255
6010
  } = useStreamContext();
4256
- const [threadRecords, setThreadRecords] = React21.useState([]);
4257
- const [isLoading, setIsLoading] = React21.useState(false);
4258
- const [error, setError] = React21.useState(null);
4259
- const upsertThreadRecord = React21.useCallback((threadRecord) => {
6011
+ const [threadRecords, setThreadRecords] = React24.useState([]);
6012
+ const [isLoading, setIsLoading] = React24.useState(false);
6013
+ const [error, setError] = React24.useState(null);
6014
+ const upsertThreadRecord = React24.useCallback((threadRecord) => {
4260
6015
  setThreadRecords((prev) => {
4261
6016
  const next = prev.filter((item) => item.id !== threadRecord.id);
4262
6017
  return sortThreadRecords([threadRecord, ...next]);
4263
6018
  });
4264
6019
  }, []);
4265
- const refreshThreads = React21.useCallback(async () => {
6020
+ const refreshThreads = React24.useCallback(async () => {
4266
6021
  setIsLoading(true);
4267
6022
  setError(null);
4268
6023
  try {
@@ -4278,7 +6033,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4278
6033
  setIsLoading(false);
4279
6034
  }
4280
6035
  }, [client, limit, assistantId]);
4281
- const createThread = React21.useCallback(
6036
+ const createThread = React24.useCallback(
4282
6037
  async (input) => {
4283
6038
  setError(null);
4284
6039
  const payload = {};
@@ -4292,7 +6047,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4292
6047
  },
4293
6048
  [client, upsertThreadRecord]
4294
6049
  );
4295
- const updateThread = React21.useCallback(
6050
+ const updateThread = React24.useCallback(
4296
6051
  async (recordId, payload) => {
4297
6052
  setError(null);
4298
6053
  const updated = await client.conversations.update(recordId, payload);
@@ -4301,7 +6056,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4301
6056
  },
4302
6057
  [client, upsertThreadRecord]
4303
6058
  );
4304
- const deleteThread = React21.useCallback(
6059
+ const deleteThread = React24.useCallback(
4305
6060
  async (recordId) => {
4306
6061
  setError(null);
4307
6062
  await client.conversations.delete(recordId);
@@ -4309,11 +6064,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
4309
6064
  },
4310
6065
  [client]
4311
6066
  );
4312
- React21.useEffect(() => {
6067
+ React24.useEffect(() => {
4313
6068
  if (!isReady) return;
4314
6069
  void refreshThreads();
4315
6070
  }, [refreshThreads, isReady]);
4316
- React21.useEffect(() => {
6071
+ React24.useEffect(() => {
4317
6072
  if (!threadId || !isStreamLoading) return;
4318
6073
  const now = (/* @__PURE__ */ new Date()).toISOString();
4319
6074
  const busyStatus = "busy";
@@ -4334,7 +6089,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4334
6089
  return changed ? sortThreadRecords(next) : prev;
4335
6090
  });
4336
6091
  }, [threadId, isStreamLoading]);
4337
- React21.useEffect(() => {
6092
+ React24.useEffect(() => {
4338
6093
  if (!isReady || !threadId || isStreamLoading) return;
4339
6094
  let cancelled = false;
4340
6095
  void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
@@ -4348,7 +6103,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4348
6103
  cancelled = true;
4349
6104
  };
4350
6105
  }, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
4351
- const threads = React21.useMemo(
6106
+ const threads = React24.useMemo(
4352
6107
  () => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
4353
6108
  [threadRecords]
4354
6109
  );
@@ -4365,10 +6120,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
4365
6120
  }
4366
6121
 
4367
6122
  // src/components/thread/context-usage-indicator.tsx
4368
- import * as React22 from "react";
6123
+ import * as React25 from "react";
4369
6124
 
4370
6125
  // src/components/ui/progress-circle.tsx
4371
- import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
6126
+ import { jsx as jsx30, jsxs as jsxs19 } from "react/jsx-runtime";
4372
6127
  function clamp2(input, a, b) {
4373
6128
  return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
4374
6129
  }
@@ -4391,7 +6146,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4391
6146
  return (
4392
6147
  // biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
4393
6148
  // biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
4394
- /* @__PURE__ */ jsxs16(
6149
+ /* @__PURE__ */ jsxs19(
4395
6150
  "svg",
4396
6151
  {
4397
6152
  role: "progressbar",
@@ -4402,8 +6157,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4402
6157
  "aria-valuemax": 100,
4403
6158
  ...restSvgProps,
4404
6159
  children: [
4405
- /* @__PURE__ */ jsx27("circle", { ...commonParams, className: "stroke-current/25" }),
4406
- /* @__PURE__ */ jsx27(
6160
+ /* @__PURE__ */ jsx30("circle", { ...commonParams, className: "stroke-current/25" }),
6161
+ /* @__PURE__ */ jsx30(
4407
6162
  "circle",
4408
6163
  {
4409
6164
  ...commonParams,
@@ -4422,7 +6177,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4422
6177
  };
4423
6178
 
4424
6179
  // src/components/thread/context-usage-indicator.tsx
4425
- import { jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
6180
+ import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
4426
6181
  var kNumberFormatter = new Intl.NumberFormat("en-US", {
4427
6182
  minimumFractionDigits: 0,
4428
6183
  maximumFractionDigits: 1
@@ -4455,20 +6210,20 @@ function ContextUsageIndicator({
4455
6210
  }) {
4456
6211
  const { t } = useChatkitTranslation();
4457
6212
  const stream = useStreamContext();
4458
- const [maxContextSize, setMaxContextSize] = React22.useState(null);
4459
- const [usedContextSize, setUsedContextSize] = React22.useState(null);
4460
- const [assistantAgentKey, setAssistantAgentKey] = React22.useState(null);
4461
- const latestRealtimeUsageRef = React22.useRef({
6213
+ const [maxContextSize, setMaxContextSize] = React25.useState(null);
6214
+ const [usedContextSize, setUsedContextSize] = React25.useState(null);
6215
+ const [assistantAgentKey, setAssistantAgentKey] = React25.useState(null);
6216
+ const latestRealtimeUsageRef = React25.useRef({
4462
6217
  threadId: null,
4463
6218
  agentKey: null,
4464
6219
  usedTokens: null
4465
6220
  });
4466
- const realtimeUsage = React22.useMemo(
6221
+ const realtimeUsage = React25.useMemo(
4467
6222
  () => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
4468
6223
  [assistantAgentKey, stream.contextUsageByAgentKey]
4469
6224
  );
4470
6225
  const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
4471
- React22.useEffect(() => {
6226
+ React25.useEffect(() => {
4472
6227
  if (!stream.client || !stream.assistantId) {
4473
6228
  setMaxContextSize(null);
4474
6229
  setAssistantAgentKey(null);
@@ -4488,18 +6243,18 @@ function ContextUsageIndicator({
4488
6243
  cancelled = true;
4489
6244
  };
4490
6245
  }, [stream.client, stream.assistantId]);
4491
- React22.useEffect(() => {
6246
+ React25.useEffect(() => {
4492
6247
  latestRealtimeUsageRef.current = {
4493
6248
  threadId: stream.threadId ?? null,
4494
6249
  agentKey: assistantAgentKey,
4495
6250
  usedTokens: realtimeUsedContextSize
4496
6251
  };
4497
6252
  }, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
4498
- React22.useEffect(() => {
6253
+ React25.useEffect(() => {
4499
6254
  if (realtimeUsedContextSize == null) return;
4500
6255
  setUsedContextSize(realtimeUsedContextSize);
4501
6256
  }, [realtimeUsedContextSize]);
4502
- React22.useEffect(() => {
6257
+ React25.useEffect(() => {
4503
6258
  if (!stream.client) {
4504
6259
  setUsedContextSize(null);
4505
6260
  return;
@@ -4564,8 +6319,8 @@ function ContextUsageIndicator({
4564
6319
  });
4565
6320
  const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
4566
6321
  const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
4567
- return /* @__PURE__ */ jsxs17(Tooltip, { children: [
4568
- /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx28(
6322
+ return /* @__PURE__ */ jsxs20(Tooltip, { children: [
6323
+ /* @__PURE__ */ jsx31(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx31(
4569
6324
  "button",
4570
6325
  {
4571
6326
  type: "button",
@@ -4574,19 +6329,19 @@ function ContextUsageIndicator({
4574
6329
  className
4575
6330
  ),
4576
6331
  "aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
4577
- children: /* @__PURE__ */ jsx28(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
6332
+ children: /* @__PURE__ */ jsx31(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
4578
6333
  }
4579
6334
  ) }),
4580
- /* @__PURE__ */ jsxs17(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
4581
- /* @__PURE__ */ jsx28("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
4582
- /* @__PURE__ */ jsx28("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
4583
- /* @__PURE__ */ jsx28("div", { className: "text-sm font-semibold", children: usageTokensLabel })
6335
+ /* @__PURE__ */ jsxs20(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
6336
+ /* @__PURE__ */ jsx31("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
6337
+ /* @__PURE__ */ jsx31("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
6338
+ /* @__PURE__ */ jsx31("div", { className: "text-sm font-semibold", children: usageTokensLabel })
4584
6339
  ] })
4585
6340
  ] });
4586
6341
  }
4587
6342
 
4588
6343
  // src/components/chat.tsx
4589
- import { Fragment as Fragment4, jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
6344
+ import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs21 } from "react/jsx-runtime";
4590
6345
  var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
4591
6346
  var COMPOSER_INPUT_MAX_HEIGHT = 128;
4592
6347
  var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
@@ -4678,7 +6433,7 @@ function ReferenceChip({
4678
6433
  const metaLine = getReferenceMetaLine(reference);
4679
6434
  const isComposer = variant === "composer";
4680
6435
  const Icon = reference.type === "quote" ? Quote : reference.type === "image" ? ImageIcon : FileText2;
4681
- return /* @__PURE__ */ jsxs18(
6436
+ return /* @__PURE__ */ jsxs21(
4682
6437
  "div",
4683
6438
  {
4684
6439
  className: cn(
@@ -4687,7 +6442,7 @@ function ReferenceChip({
4687
6442
  ),
4688
6443
  title: getReferenceTitle(reference),
4689
6444
  children: [
4690
- /* @__PURE__ */ jsx29(
6445
+ /* @__PURE__ */ jsx32(
4691
6446
  Icon,
4692
6447
  {
4693
6448
  size: isComposer ? 14 : 12,
@@ -4697,8 +6452,8 @@ function ReferenceChip({
4697
6452
  )
4698
6453
  }
4699
6454
  ),
4700
- /* @__PURE__ */ jsxs18("div", { className: "min-w-0 flex-1", children: [
4701
- /* @__PURE__ */ jsx29(
6455
+ /* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
6456
+ /* @__PURE__ */ jsx32(
4702
6457
  "div",
4703
6458
  {
4704
6459
  className: cn(
@@ -4708,7 +6463,7 @@ function ReferenceChip({
4708
6463
  children: getReferenceLabel(reference)
4709
6464
  }
4710
6465
  ),
4711
- metaLine && /* @__PURE__ */ jsx29(
6466
+ metaLine && /* @__PURE__ */ jsx32(
4712
6467
  "div",
4713
6468
  {
4714
6469
  className: cn(
@@ -4719,7 +6474,7 @@ function ReferenceChip({
4719
6474
  }
4720
6475
  )
4721
6476
  ] }),
4722
- onRemove && removeLabel && /* @__PURE__ */ jsx29(
6477
+ onRemove && removeLabel && /* @__PURE__ */ jsx32(
4723
6478
  "button",
4724
6479
  {
4725
6480
  type: "button",
@@ -4730,7 +6485,7 @@ function ReferenceChip({
4730
6485
  ),
4731
6486
  title: removeLabel,
4732
6487
  "aria-label": removeLabel,
4733
- children: /* @__PURE__ */ jsx29(X3, { size: 12 })
6488
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
4734
6489
  }
4735
6490
  )
4736
6491
  ]
@@ -4754,20 +6509,20 @@ function Chat({
4754
6509
  const { setStream } = useStreamManager();
4755
6510
  const stream = useStreamContext();
4756
6511
  const { theme } = useTheme();
4757
- const [isHistoryLoading, setIsHistoryLoading] = React23.useState(false);
4758
- const [historyError, setHistoryError] = React23.useState(null);
4759
- const [assistantName, setAssistantName] = React23.useState(null);
4760
- const [assistantAvatar, setAssistantAvatar] = React23.useState(null);
6512
+ const [isHistoryLoading, setIsHistoryLoading] = React26.useState(false);
6513
+ const [historyError, setHistoryError] = React26.useState(null);
6514
+ const [assistantName, setAssistantName] = React26.useState(null);
6515
+ const [assistantAvatar, setAssistantAvatar] = React26.useState(null);
4761
6516
  const LOADING_DOTS_MIN_DURATION = 800;
4762
6517
  const STREAMING_STATUS_REFRESH_MS = 250;
4763
- const [showLoadingDots, setShowLoadingDots] = React23.useState(false);
4764
- const [streamingNow, setStreamingNow] = React23.useState(() => Date.now());
4765
- const loadingStartTimeRef = React23.useRef(null);
4766
- const lastStreamOutputAtRef = React23.useRef(null);
4767
- React23.useEffect(() => {
6518
+ const [showLoadingDots, setShowLoadingDots] = React26.useState(false);
6519
+ const [streamingNow, setStreamingNow] = React26.useState(() => Date.now());
6520
+ const loadingStartTimeRef = React26.useRef(null);
6521
+ const lastStreamOutputAtRef = React26.useRef(null);
6522
+ React26.useEffect(() => {
4768
6523
  setStream(stream);
4769
6524
  }, [setStream, stream]);
4770
- React23.useEffect(() => {
6525
+ React26.useEffect(() => {
4771
6526
  if (stream.isLoading) {
4772
6527
  if (!loadingStartTimeRef.current) {
4773
6528
  loadingStartTimeRef.current = Date.now();
@@ -4790,7 +6545,7 @@ function Chat({
4790
6545
  }
4791
6546
  }
4792
6547
  }, [stream.isLoading]);
4793
- React23.useEffect(() => {
6548
+ React26.useEffect(() => {
4794
6549
  if (!stream.isLoading) {
4795
6550
  lastStreamOutputAtRef.current = null;
4796
6551
  setStreamingNow(Date.now());
@@ -4800,7 +6555,7 @@ function Chat({
4800
6555
  lastStreamOutputAtRef.current = now;
4801
6556
  setStreamingNow(now);
4802
6557
  }, [stream.messages, stream.isLoading]);
4803
- React23.useEffect(() => {
6558
+ React26.useEffect(() => {
4804
6559
  if (!stream.isLoading) {
4805
6560
  return;
4806
6561
  }
@@ -4809,53 +6564,55 @@ function Chat({
4809
6564
  }, STREAMING_STATUS_REFRESH_MS);
4810
6565
  return () => window.clearInterval(timer);
4811
6566
  }, [stream.isLoading]);
4812
- const [draft, setDraft] = React23.useState("");
4813
- const [selectedTool, setSelectedTool] = React23.useState(
6567
+ const [draft, setDraft] = React26.useState("");
6568
+ const [selectedTool, setSelectedTool] = React26.useState(
4814
6569
  null
4815
6570
  );
4816
- const [attachments, setAttachments] = React23.useState([]);
4817
- const [references, setReferences] = React23.useState([]);
4818
- const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React23.useState(false);
4819
- const [quoteSelection, setQuoteSelection] = React23.useState(null);
4820
- const [isAtBottom, setIsAtBottom] = React23.useState(true);
4821
- const [hasUpdatesBelow, setHasUpdatesBelow] = React23.useState(false);
6571
+ const [planModeEnabled, setPlanModeEnabled] = React26.useState(false);
6572
+ const [attachments, setAttachments] = React26.useState([]);
6573
+ const [references, setReferences] = React26.useState([]);
6574
+ const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React26.useState(false);
6575
+ const [quoteSelection, setQuoteSelection] = React26.useState(null);
6576
+ const [isAtBottom, setIsAtBottom] = React26.useState(true);
6577
+ const [hasUpdatesBelow, setHasUpdatesBelow] = React26.useState(false);
4822
6578
  const {
4823
6579
  threads,
4824
6580
  deleteThread,
4825
6581
  refreshThreads,
4826
6582
  isLoading: isThreadsLoading
4827
6583
  } = useThreads();
4828
- const viewportRef = React23.useRef(null);
4829
- const fileInputRef = React23.useRef(null);
4830
- const composerInputRef = React23.useRef(null);
4831
- const shouldAutoScrollRef = React23.useRef(true);
4832
- const forceFollowRef = React23.useRef(false);
4833
- const previousMessageCountRef = React23.useRef(0);
4834
- const previousScrollTopRef = React23.useRef(0);
4835
- const autoScrollFrameRef = React23.useRef(null);
4836
- const isPointerDownRef = React23.useRef(false);
4837
- const lastTouchYRef = React23.useRef(null);
6584
+ const viewportRef = React26.useRef(null);
6585
+ const fileInputRef = React26.useRef(null);
6586
+ const composerInputRef = React26.useRef(null);
6587
+ const shouldAutoScrollRef = React26.useRef(true);
6588
+ const forceFollowRef = React26.useRef(false);
6589
+ const previousMessageCountRef = React26.useRef(0);
6590
+ const previousScrollTopRef = React26.useRef(0);
6591
+ const autoScrollFrameRef = React26.useRef(null);
6592
+ const isPointerDownRef = React26.useRef(false);
6593
+ const lastTouchYRef = React26.useRef(null);
4838
6594
  const resolvedTitle = title ?? t("chat.title");
4839
6595
  const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
4840
6596
  const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
4841
- const messages = React23.useMemo(
6597
+ const messages = React26.useMemo(
4842
6598
  () => stream.messages ?? [],
4843
6599
  [stream.messages]
4844
6600
  );
4845
6601
  const trimmedDraft = draft.trim();
4846
6602
  const hasReferences = references.length > 0;
4847
- const pendingFollowUps = React23.useMemo(
6603
+ const pendingFollowUps = React26.useMemo(
4848
6604
  () => [...stream.pendingFollowUps ?? []].sort(
4849
6605
  (a, b) => a.createdAt - b.createdAt
4850
6606
  ),
4851
6607
  [stream.pendingFollowUps]
4852
6608
  );
4853
6609
  const hasPendingFollowUps = pendingFollowUps.length > 0;
4854
- const clearQuoteSelection = React23.useCallback(() => {
6610
+ const hasPendingRequestUserInput = Boolean(stream.pendingRequestUserInput);
6611
+ const clearQuoteSelection = React26.useCallback(() => {
4855
6612
  setQuoteSelection(null);
4856
6613
  }, []);
4857
6614
  useParentMessenger({
4858
- onSetComposerValue: React23.useCallback(
6615
+ onSetComposerValue: React26.useCallback(
4859
6616
  (payload) => {
4860
6617
  if (!payload) {
4861
6618
  return;
@@ -4878,11 +6635,11 @@ function Chat({
4878
6635
  },
4879
6636
  [composer?.tools]
4880
6637
  ),
4881
- onFocusComposer: React23.useCallback(() => {
6638
+ onFocusComposer: React26.useCallback(() => {
4882
6639
  composerInputRef.current?.focus();
4883
6640
  }, [])
4884
6641
  });
4885
- const syncQuoteSelection = React23.useCallback(() => {
6642
+ const syncQuoteSelection = React26.useCallback(() => {
4886
6643
  if (typeof window === "undefined") {
4887
6644
  clearQuoteSelection();
4888
6645
  return;
@@ -4927,23 +6684,23 @@ function Chat({
4927
6684
  left
4928
6685
  });
4929
6686
  }, [clearQuoteSelection]);
4930
- const cancelPendingAutoScroll = React23.useCallback(() => {
6687
+ const cancelPendingAutoScroll = React26.useCallback(() => {
4931
6688
  if (autoScrollFrameRef.current !== null) {
4932
6689
  cancelAnimationFrame(autoScrollFrameRef.current);
4933
6690
  autoScrollFrameRef.current = null;
4934
6691
  }
4935
6692
  }, []);
4936
- const disableAutoFollow = React23.useCallback(() => {
6693
+ const disableAutoFollow = React26.useCallback(() => {
4937
6694
  forceFollowRef.current = false;
4938
6695
  shouldAutoScrollRef.current = false;
4939
6696
  cancelPendingAutoScroll();
4940
6697
  }, [cancelPendingAutoScroll]);
4941
- const enableAutoFollow = React23.useCallback(() => {
6698
+ const enableAutoFollow = React26.useCallback(() => {
4942
6699
  forceFollowRef.current = true;
4943
6700
  shouldAutoScrollRef.current = true;
4944
6701
  setHasUpdatesBelow(false);
4945
6702
  }, []);
4946
- const scrollToBottom = React23.useCallback(
6703
+ const scrollToBottom = React26.useCallback(
4947
6704
  (smooth = false, force = false) => {
4948
6705
  if (force) {
4949
6706
  enableAutoFollow();
@@ -4965,7 +6722,7 @@ function Chat({
4965
6722
  },
4966
6723
  [cancelPendingAutoScroll, enableAutoFollow]
4967
6724
  );
4968
- React23.useEffect(() => {
6725
+ React26.useEffect(() => {
4969
6726
  const viewport = viewportRef.current;
4970
6727
  if (!viewport) return;
4971
6728
  previousScrollTopRef.current = viewport.scrollTop;
@@ -5046,14 +6803,14 @@ function Chat({
5046
6803
  window.removeEventListener("pointercancel", stopPointerTracking);
5047
6804
  };
5048
6805
  }, [cancelPendingAutoScroll, disableAutoFollow]);
5049
- React23.useEffect(() => {
6806
+ React26.useEffect(() => {
5050
6807
  shouldAutoScrollRef.current = true;
5051
6808
  forceFollowRef.current = false;
5052
6809
  previousScrollTopRef.current = 0;
5053
6810
  setIsAtBottom(true);
5054
6811
  setHasUpdatesBelow(false);
5055
6812
  }, [stream.threadId]);
5056
- React23.useEffect(() => {
6813
+ React26.useEffect(() => {
5057
6814
  const messageCountChanged = messages.length !== previousMessageCountRef.current;
5058
6815
  previousMessageCountRef.current = messages.length;
5059
6816
  if (!shouldAutoScrollRef.current) {
@@ -5072,7 +6829,7 @@ function Chat({
5072
6829
  clientSecret: effectiveClientSecret
5073
6830
  });
5074
6831
  const missingConfig = Boolean(missingConfigKind);
5075
- const missingConfigShortMessage = React23.useMemo(() => {
6832
+ const missingConfigShortMessage = React26.useMemo(() => {
5076
6833
  switch (missingConfigKind) {
5077
6834
  case "apiUrl":
5078
6835
  return t("chat.missingApiUrlShort");
@@ -5084,7 +6841,7 @@ function Chat({
5084
6841
  return t("chat.missingConfigShort");
5085
6842
  }
5086
6843
  }, [missingConfigKind, t]);
5087
- const missingConfigDetailMessage = React23.useMemo(() => {
6844
+ const missingConfigDetailMessage = React26.useMemo(() => {
5088
6845
  switch (missingConfigKind) {
5089
6846
  case "apiUrl":
5090
6847
  return t("chat.missingApiUrlDetail");
@@ -5098,8 +6855,8 @@ function Chat({
5098
6855
  }, [missingConfigKind, t]);
5099
6856
  const showMissingConfig = !isClientSecretInitializing && missingConfig;
5100
6857
  const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
5101
- const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
5102
- const resizeComposerInput = React23.useCallback(() => {
6858
+ const isSendDisabled = !trimmedDraft && !hasReferences || hasPendingRequestUserInput || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
6859
+ const resizeComposerInput = React26.useCallback(() => {
5103
6860
  const textarea = composerInputRef.current;
5104
6861
  if (!textarea) {
5105
6862
  return;
@@ -5112,16 +6869,16 @@ function Chat({
5112
6869
  textarea.style.height = `${nextHeight}px`;
5113
6870
  textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
5114
6871
  }, []);
5115
- React23.useEffect(() => {
6872
+ React26.useEffect(() => {
5116
6873
  resizeComposerInput();
5117
6874
  }, [draft, resizeComposerInput]);
5118
- React23.useEffect(() => {
6875
+ React26.useEffect(() => {
5119
6876
  document.addEventListener("selectionchange", syncQuoteSelection);
5120
6877
  return () => {
5121
6878
  document.removeEventListener("selectionchange", syncQuoteSelection);
5122
6879
  };
5123
6880
  }, [syncQuoteSelection]);
5124
- React23.useEffect(() => {
6881
+ React26.useEffect(() => {
5125
6882
  const viewport = viewportRef.current;
5126
6883
  if (!viewport) {
5127
6884
  return;
@@ -5138,14 +6895,14 @@ function Chat({
5138
6895
  window.removeEventListener("resize", handleViewportScroll);
5139
6896
  };
5140
6897
  }, [clearQuoteSelection]);
5141
- React23.useEffect(() => {
6898
+ React26.useEffect(() => {
5142
6899
  clearQuoteSelection();
5143
6900
  }, [messages.length, stream.threadId, clearQuoteSelection]);
5144
- React23.useEffect(() => {
6901
+ React26.useEffect(() => {
5145
6902
  if (missingConfig) return;
5146
6903
  void refreshThreads();
5147
6904
  }, [missingConfig, refreshThreads]);
5148
- React23.useEffect(() => {
6905
+ React26.useEffect(() => {
5149
6906
  if (missingConfig || !stream.client || !stream.assistantId) {
5150
6907
  setAssistantName(null);
5151
6908
  setAssistantAvatar(null);
@@ -5176,7 +6933,7 @@ function Chat({
5176
6933
  mimetype: a.storageFile?.mimetype ?? a.file.type,
5177
6934
  size: a.storageFile?.size ?? a.file.size
5178
6935
  }));
5179
- const submitDraft = React23.useCallback(
6936
+ const submitDraft = React26.useCallback(
5180
6937
  (followUpOverride) => {
5181
6938
  if (isSendDisabled) return;
5182
6939
  const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
@@ -5206,6 +6963,9 @@ function Chat({
5206
6963
  if (filesToSend) {
5207
6964
  inputPayload.files = filesToSend;
5208
6965
  }
6966
+ if (planModeEnabled) {
6967
+ inputPayload.planMode = true;
6968
+ }
5209
6969
  const requestOptions = buildInjectedRequestOptions({
5210
6970
  defaults: options?.request,
5211
6971
  humanInput: inputPayload
@@ -5240,6 +7000,7 @@ function Chat({
5240
7000
  references,
5241
7001
  scrollToBottom,
5242
7002
  selectedTool,
7003
+ planModeEnabled,
5243
7004
  stream,
5244
7005
  trimmedDraft,
5245
7006
  uploadedFiles,
@@ -5250,7 +7011,7 @@ function Chat({
5250
7011
  event.preventDefault();
5251
7012
  submitDraft();
5252
7013
  };
5253
- const handleEditPendingFollowUp = React23.useCallback(
7014
+ const handleEditPendingFollowUp = React26.useCallback(
5254
7015
  (id) => {
5255
7016
  const item = pendingFollowUps.find(
5256
7017
  (entry) => entry.id === id && entry.mode === "queue"
@@ -5277,7 +7038,7 @@ function Chat({
5277
7038
  },
5278
7039
  [pendingFollowUps, stream]
5279
7040
  );
5280
- const handleQuoteSelection = React23.useCallback(() => {
7041
+ const handleQuoteSelection = React26.useCallback(() => {
5281
7042
  if (!quoteSelection) {
5282
7043
  return;
5283
7044
  }
@@ -5293,7 +7054,7 @@ function Chat({
5293
7054
  const handleAttachmentClick = () => {
5294
7055
  fileInputRef.current?.click();
5295
7056
  };
5296
- const uploadContextFile = React23.useCallback(
7057
+ const uploadContextFile = React26.useCallback(
5297
7058
  (file) => stream.client.contexts.uploadFile(file),
5298
7059
  [stream.client]
5299
7060
  );
@@ -5319,7 +7080,7 @@ function Chat({
5319
7080
  }
5320
7081
  submitDraft();
5321
7082
  };
5322
- const handleComposerPaste = React23.useCallback(
7083
+ const handleComposerPaste = React26.useCallback(
5323
7084
  (event) => {
5324
7085
  const clipboardData = event.clipboardData;
5325
7086
  if (!clipboardData) {
@@ -5398,18 +7159,18 @@ function Chat({
5398
7159
  uploadContextFile
5399
7160
  ]
5400
7161
  );
5401
- const alternateFollowUpShortcutLabel = React23.useMemo(() => {
7162
+ const alternateFollowUpShortcutLabel = React26.useMemo(() => {
5402
7163
  if (typeof navigator === "undefined") {
5403
7164
  return "\u2318Enter";
5404
7165
  }
5405
7166
  const platform = navigator.platform || navigator.userAgent;
5406
7167
  return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
5407
7168
  }, []);
5408
- const followUpShortcutLabels = React23.useMemo(
7169
+ const followUpShortcutLabels = React26.useMemo(
5409
7170
  () => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
5410
7171
  [alternateFollowUpShortcutLabel]
5411
7172
  );
5412
- const uploadFile = React23.useCallback(
7173
+ const uploadFile = React26.useCallback(
5413
7174
  async (localId, file) => {
5414
7175
  try {
5415
7176
  const result = await uploadContextFile(file);
@@ -5432,7 +7193,7 @@ function Chat({
5432
7193
  },
5433
7194
  [uploadContextFile]
5434
7195
  );
5435
- const handleRetryUpload = React23.useCallback(
7196
+ const handleRetryUpload = React26.useCallback(
5436
7197
  (localId) => {
5437
7198
  const attachment = attachments.find((a) => a.localId === localId);
5438
7199
  if (!attachment || attachment.status !== "error") return;
@@ -5503,10 +7264,23 @@ function Chat({
5503
7264
  content: prompt
5504
7265
  };
5505
7266
  const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
7267
+ const inputPayload = {
7268
+ input: prompt,
7269
+ ...planModeEnabled ? { planMode: true } : {}
7270
+ };
7271
+ const requestOptions = buildInjectedRequestOptions({
7272
+ defaults: options?.request,
7273
+ humanInput: inputPayload
7274
+ });
5506
7275
  stream.submit(
5507
- { input: { input: prompt } },
7276
+ {
7277
+ input: inputPayload,
7278
+ ...requestOptions.state ? { state: requestOptions.state } : {}
7279
+ },
5508
7280
  {
5509
7281
  ...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
7282
+ ...requestOptions.context ? { context: requestOptions.context } : {},
7283
+ ...requestOptions.config ? { config: requestOptions.config } : {},
5510
7284
  ...!nextFollowUpMode ? {
5511
7285
  optimisticValues: (prev) => {
5512
7286
  const prevMessages = prev?.messages ?? [];
@@ -5517,7 +7291,7 @@ function Chat({
5517
7291
  );
5518
7292
  scrollToBottom(true, true);
5519
7293
  };
5520
- const loadConversationMessages = React23.useCallback(
7294
+ const loadConversationMessages = React26.useCallback(
5521
7295
  async (recordId) => {
5522
7296
  if (missingConfig) {
5523
7297
  setHistoryError(missingConfigShortMessage);
@@ -5603,18 +7377,18 @@ function Chat({
5603
7377
  }
5604
7378
  };
5605
7379
  const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
5606
- const currentThread = React23.useMemo(
7380
+ const currentThread = React26.useMemo(
5607
7381
  () => threads.find((item) => item.id === stream.threadId),
5608
7382
  [threads, stream.threadId]
5609
7383
  );
5610
7384
  const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
5611
- const threadErrorMessage = React23.useMemo(() => {
7385
+ const threadErrorMessage = React26.useMemo(() => {
5612
7386
  if (currentThread?.status !== "error") return void 0;
5613
7387
  const message = currentThread.error?.trim();
5614
7388
  return message || t("thread.errorToast");
5615
7389
  }, [currentThread, t]);
5616
7390
  const assistantTitle = assistantName || resolvedTitle;
5617
- return /* @__PURE__ */ jsxs18(
7391
+ return /* @__PURE__ */ jsxs21(
5618
7392
  "div",
5619
7393
  {
5620
7394
  ref: viewportRef,
@@ -5623,10 +7397,10 @@ function Chat({
5623
7397
  className
5624
7398
  ),
5625
7399
  children: [
5626
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
5627
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3 overflow-hidden", children: [
5628
- /* @__PURE__ */ jsxs18("div", { className: "relative shrink-0", children: [
5629
- /* @__PURE__ */ jsx29(
7400
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
7401
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 overflow-hidden", children: [
7402
+ /* @__PURE__ */ jsxs21("div", { className: "relative shrink-0", children: [
7403
+ /* @__PURE__ */ jsx32(
5630
7404
  ChatkitAvatar,
5631
7405
  {
5632
7406
  avatar: assistantAvatar,
@@ -5634,10 +7408,10 @@ function Chat({
5634
7408
  label: assistantTitle
5635
7409
  }
5636
7410
  ),
5637
- /* @__PURE__ */ jsx29("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
7411
+ /* @__PURE__ */ jsx32("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
5638
7412
  ] }),
5639
- /* @__PURE__ */ jsxs18("div", { className: "truncate", children: [
5640
- /* @__PURE__ */ jsx29(
7413
+ /* @__PURE__ */ jsxs21("div", { className: "truncate", children: [
7414
+ /* @__PURE__ */ jsx32(
5641
7415
  "h2",
5642
7416
  {
5643
7417
  className: "text-lg font-semibold truncate",
@@ -5645,27 +7419,30 @@ function Chat({
5645
7419
  children: assistantTitle
5646
7420
  }
5647
7421
  ),
5648
- /* @__PURE__ */ jsx29("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
7422
+ /* @__PURE__ */ jsx32("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
5649
7423
  ] })
5650
7424
  ] }),
5651
- history?.enabled !== false && /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-1", children: [
5652
- /* @__PURE__ */ jsx29(
5653
- "button",
5654
- {
5655
- type: "button",
5656
- onClick: handleNewThread,
5657
- disabled: missingConfig || isHistoryLoading,
5658
- className: cn(
5659
- "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
5660
- "text-muted-foreground hover:text-foreground hover:bg-muted",
5661
- "transition-colors duration-150",
5662
- "disabled:opacity-50 disabled:cursor-not-allowed"
5663
- ),
5664
- title: t("history.newThread"),
5665
- children: /* @__PURE__ */ jsx29(Pencil3, { size: 16 })
5666
- }
5667
- ),
5668
- /* @__PURE__ */ jsx29(
7425
+ history?.enabled !== false && /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-1", children: [
7426
+ /* @__PURE__ */ jsxs21(Tooltip, { children: [
7427
+ /* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx32(
7428
+ "button",
7429
+ {
7430
+ type: "button",
7431
+ onClick: handleNewThread,
7432
+ disabled: missingConfig || isHistoryLoading,
7433
+ className: cn(
7434
+ "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
7435
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
7436
+ "transition-colors duration-150",
7437
+ "disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed"
7438
+ ),
7439
+ "aria-label": t("history.newThread"),
7440
+ children: /* @__PURE__ */ jsx32(Pencil3, { size: 16 })
7441
+ }
7442
+ ) }) }),
7443
+ /* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: t("history.newThread") })
7444
+ ] }),
7445
+ /* @__PURE__ */ jsx32(
5669
7446
  HistorySidebar,
5670
7447
  {
5671
7448
  threads,
@@ -5679,18 +7456,18 @@ function Chat({
5679
7456
  )
5680
7457
  ] })
5681
7458
  ] }),
5682
- /* @__PURE__ */ jsxs18("div", { className: "flex-1 p-4", children: [
5683
- errorMessage && /* @__PURE__ */ jsx29("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
5684
- historyError && /* @__PURE__ */ jsx29("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
5685
- showMissingConfig && /* @__PURE__ */ jsx29("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
5686
- isHistoryLoading && /* @__PURE__ */ jsx29("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
5687
- messages.length === 0 ? /* @__PURE__ */ jsx29(
7459
+ /* @__PURE__ */ jsxs21("div", { className: "flex-1 p-4", children: [
7460
+ errorMessage && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
7461
+ historyError && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
7462
+ showMissingConfig && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
7463
+ isHistoryLoading && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
7464
+ messages.length === 0 ? /* @__PURE__ */ jsx32(
5688
7465
  StartScreen,
5689
7466
  {
5690
7467
  startScreen,
5691
7468
  onPromptClick: handlePromptClick
5692
7469
  }
5693
- ) : /* @__PURE__ */ jsxs18("div", { className: "space-y-4", children: [
7470
+ ) : /* @__PURE__ */ jsxs21("div", { className: "space-y-4", children: [
5694
7471
  messages.map((message, index) => {
5695
7472
  const messageType = String(message.type);
5696
7473
  const isAssistantMessage = messageType === "assistant" || messageType === "ai";
@@ -5717,7 +7494,7 @@ function Chat({
5717
7494
  if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
5718
7495
  return null;
5719
7496
  }
5720
- return /* @__PURE__ */ jsx29(
7497
+ return /* @__PURE__ */ jsx32(
5721
7498
  "div",
5722
7499
  {
5723
7500
  className: cn(
@@ -5725,8 +7502,8 @@ function Chat({
5725
7502
  message.type === "human" ? "justify-end" : "justify-start -ml-1"
5726
7503
  // AI messages: slightly closer to left
5727
7504
  ),
5728
- children: /* @__PURE__ */ jsxs18("div", { className: "flex flex-col px-3 overflow-hidden", children: [
5729
- /* @__PURE__ */ jsx29(
7505
+ children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col px-3 overflow-hidden", children: [
7506
+ /* @__PURE__ */ jsx32(
5730
7507
  "div",
5731
7508
  {
5732
7509
  ...canQuoteMessage ? {
@@ -5738,18 +7515,24 @@ function Chat({
5738
7515
  message.type === "human" ? "bg-primary text-primary-foreground px-4 py-2.5" : message.type === "system" ? "bg-muted text-muted-foreground text-xs px-4 py-2.5" : "py-1 text-chat-foreground"
5739
7516
  // AI messages: use chat-specific foreground color
5740
7517
  ),
5741
- children: isAssistantMessage ? /* @__PURE__ */ jsx29(
7518
+ children: isAssistantMessage ? /* @__PURE__ */ jsx32(
5742
7519
  AssistantMessage,
5743
7520
  {
5744
7521
  message: {
5745
7522
  ...message,
5746
7523
  type: "assistant"
5747
7524
  },
7525
+ messages: messages.slice(0, index + 1).map(
7526
+ (item) => ({
7527
+ ...item,
7528
+ type: String(item.type) === "ai" ? "assistant" : item.type
7529
+ })
7530
+ ),
5748
7531
  isStreaming: isStreamingMessage,
5749
7532
  streamingStatus
5750
7533
  }
5751
- ) : /* @__PURE__ */ jsxs18(Fragment4, { children: [
5752
- message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx29("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx29(
7534
+ ) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
7535
+ message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx32(
5753
7536
  ReferenceChip,
5754
7537
  {
5755
7538
  reference,
@@ -5757,29 +7540,29 @@ function Chat({
5757
7540
  },
5758
7541
  getReferenceKey(reference)
5759
7542
  )) }),
5760
- message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx29("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs18(
7543
+ message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx32("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs21(
5761
7544
  "div",
5762
7545
  {
5763
7546
  className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
5764
7547
  children: [
5765
- /* @__PURE__ */ jsx29(FileText2, { size: 12 }),
5766
- /* @__PURE__ */ jsx29("span", { className: "max-w-[100px] truncate", children: file.originalName })
7548
+ /* @__PURE__ */ jsx32(FileText2, { size: 12 }),
7549
+ /* @__PURE__ */ jsx32("span", { className: "max-w-[100px] truncate", children: file.originalName })
5767
7550
  ]
5768
7551
  },
5769
7552
  fileIndex
5770
7553
  )) }),
5771
- Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx29(
7554
+ Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx32(
5772
7555
  "p",
5773
7556
  {
5774
7557
  className: "wrap-break-word text-sm leading-relaxed",
5775
7558
  children: formatMessageContent(part)
5776
7559
  },
5777
7560
  `${part.type}-${partIndex}`
5778
- )) : /* @__PURE__ */ jsx29("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
7561
+ )) : /* @__PURE__ */ jsx32("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
5779
7562
  ] })
5780
7563
  }
5781
7564
  ),
5782
- /* @__PURE__ */ jsx29(
7565
+ /* @__PURE__ */ jsx32(
5783
7566
  MessageActions,
5784
7567
  {
5785
7568
  content: messageContent,
@@ -5815,7 +7598,7 @@ function Chat({
5815
7598
  stream.isLoading,
5816
7599
  { now: streamingNow }
5817
7600
  );
5818
- return /* @__PURE__ */ jsx29("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx29("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx29(
7601
+ return /* @__PURE__ */ jsx32("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx32("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx32(
5819
7602
  AssistantStreamingIndicator,
5820
7603
  {
5821
7604
  status: fallbackStreamingStatus ?? "loading"
@@ -5824,7 +7607,7 @@ function Chat({
5824
7607
  })()
5825
7608
  ] })
5826
7609
  ] }),
5827
- !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx29("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx29(
7610
+ !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx32("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx32(
5828
7611
  Button,
5829
7612
  {
5830
7613
  type: "button",
@@ -5837,10 +7620,10 @@ function Chat({
5837
7620
  onClick: () => scrollToBottom(true, true),
5838
7621
  "aria-label": t("chat.scrollToBottom"),
5839
7622
  title: t("chat.scrollToBottom"),
5840
- children: /* @__PURE__ */ jsx29(ArrowDown, { size: 16 })
7623
+ children: /* @__PURE__ */ jsx32(ArrowDown2, { size: 16 })
5841
7624
  }
5842
7625
  ) }),
5843
- quoteSelection && /* @__PURE__ */ jsx29(
7626
+ quoteSelection && /* @__PURE__ */ jsx32(
5844
7627
  "div",
5845
7628
  {
5846
7629
  className: "pointer-events-none fixed z-50",
@@ -5849,7 +7632,7 @@ function Chat({
5849
7632
  left: `${quoteSelection.left}px`,
5850
7633
  transform: "translateX(-50%)"
5851
7634
  },
5852
- children: /* @__PURE__ */ jsxs18(
7635
+ children: /* @__PURE__ */ jsxs21(
5853
7636
  Button,
5854
7637
  {
5855
7638
  type: "button",
@@ -5861,16 +7644,16 @@ function Chat({
5861
7644
  "aria-label": t("composer.quoteSelection"),
5862
7645
  title: t("composer.quoteSelection"),
5863
7646
  children: [
5864
- /* @__PURE__ */ jsx29(Quote, { size: 14 }),
7647
+ /* @__PURE__ */ jsx32(Quote, { size: 14 }),
5865
7648
  t("composer.quoteSelection")
5866
7649
  ]
5867
7650
  }
5868
7651
  )
5869
7652
  }
5870
7653
  ),
5871
- /* @__PURE__ */ jsxs18("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
5872
- threadErrorMessage && /* @__PURE__ */ jsx29("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
5873
- /* @__PURE__ */ jsx29(
7654
+ /* @__PURE__ */ jsxs21("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
7655
+ threadErrorMessage && /* @__PURE__ */ jsx32("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
7656
+ /* @__PURE__ */ jsx32(
5874
7657
  "input",
5875
7658
  {
5876
7659
  ref: fileInputRef,
@@ -5881,7 +7664,7 @@ function Chat({
5881
7664
  className: "hidden"
5882
7665
  }
5883
7666
  ),
5884
- attachments.length > 0 && /* @__PURE__ */ jsx29("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs18(
7667
+ attachments.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs21(
5885
7668
  "div",
5886
7669
  {
5887
7670
  className: cn(
@@ -5889,16 +7672,16 @@ function Chat({
5889
7672
  item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
5890
7673
  ),
5891
7674
  children: [
5892
- item.status === "uploading" && /* @__PURE__ */ jsx29(
5893
- Loader23,
7675
+ item.status === "uploading" && /* @__PURE__ */ jsx32(
7676
+ Loader24,
5894
7677
  {
5895
7678
  size: 14,
5896
7679
  className: "animate-spin text-muted-foreground"
5897
7680
  }
5898
7681
  ),
5899
- item.status === "success" && /* @__PURE__ */ jsx29(FileText2, { size: 14, className: "text-muted-foreground" }),
5900
- item.status === "error" && /* @__PURE__ */ jsx29(FileText2, { size: 14, className: "text-destructive" }),
5901
- /* @__PURE__ */ jsx29(
7682
+ item.status === "success" && /* @__PURE__ */ jsx32(FileText2, { size: 14, className: "text-muted-foreground" }),
7683
+ item.status === "error" && /* @__PURE__ */ jsx32(FileText2, { size: 14, className: "text-destructive" }),
7684
+ /* @__PURE__ */ jsx32(
5902
7685
  "span",
5903
7686
  {
5904
7687
  className: cn(
@@ -5908,17 +7691,17 @@ function Chat({
5908
7691
  children: item.file.name
5909
7692
  }
5910
7693
  ),
5911
- item.status === "error" && /* @__PURE__ */ jsx29(
7694
+ item.status === "error" && /* @__PURE__ */ jsx32(
5912
7695
  "button",
5913
7696
  {
5914
7697
  type: "button",
5915
7698
  onClick: () => handleRetryUpload(item.localId),
5916
7699
  className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
5917
7700
  title: t("chat.retryUpload"),
5918
- children: /* @__PURE__ */ jsx29(RefreshCw2, { size: 12 })
7701
+ children: /* @__PURE__ */ jsx32(RefreshCw2, { size: 12 })
5919
7702
  }
5920
7703
  ),
5921
- /* @__PURE__ */ jsx29(
7704
+ /* @__PURE__ */ jsx32(
5922
7705
  "button",
5923
7706
  {
5924
7707
  type: "button",
@@ -5927,14 +7710,14 @@ function Chat({
5927
7710
  "ml-1 rounded-full p-0.5",
5928
7711
  item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
5929
7712
  ),
5930
- children: /* @__PURE__ */ jsx29(X3, { size: 12 })
7713
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
5931
7714
  }
5932
7715
  )
5933
7716
  ]
5934
7717
  },
5935
7718
  item.localId
5936
7719
  )) }),
5937
- references.length > 0 && /* @__PURE__ */ jsx29("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx29(
7720
+ references.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx32(
5938
7721
  ReferenceChip,
5939
7722
  {
5940
7723
  reference,
@@ -5948,19 +7731,19 @@ function Chat({
5948
7731
  },
5949
7732
  getReferenceKey(reference)
5950
7733
  )) }),
5951
- selectedTool && /* @__PURE__ */ jsxs18("div", { className: "mb-2 flex items-center gap-2", children: [
5952
- /* @__PURE__ */ jsx29("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
5953
- /* @__PURE__ */ jsx29(
7734
+ selectedTool && /* @__PURE__ */ jsxs21("div", { className: "mb-2 flex items-center gap-2", children: [
7735
+ /* @__PURE__ */ jsx32("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
7736
+ /* @__PURE__ */ jsx32(
5954
7737
  "button",
5955
7738
  {
5956
7739
  type: "button",
5957
7740
  onClick: () => setSelectedTool(null),
5958
7741
  className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
5959
- children: /* @__PURE__ */ jsx29(X3, { size: 12 })
7742
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
5960
7743
  }
5961
7744
  )
5962
7745
  ] }),
5963
- /* @__PURE__ */ jsx29(
7746
+ /* @__PURE__ */ jsx32(
5964
7747
  PendingTodos,
5965
7748
  {
5966
7749
  snapshot: stream.todos,
@@ -5968,7 +7751,7 @@ function Chat({
5968
7751
  className: hasPendingFollowUps ? "mb-2" : void 0
5969
7752
  }
5970
7753
  ),
5971
- /* @__PURE__ */ jsx29(
7754
+ /* @__PURE__ */ jsx32(
5972
7755
  PendingFollowUps,
5973
7756
  {
5974
7757
  items: pendingFollowUps,
@@ -5983,7 +7766,16 @@ function Chat({
5983
7766
  attachToComposer: true
5984
7767
  }
5985
7768
  ),
5986
- /* @__PURE__ */ jsx29("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs18(
7769
+ /* @__PURE__ */ jsx32(
7770
+ RequestUserInputPanel,
7771
+ {
7772
+ request: stream.pendingRequestUserInput,
7773
+ onSubmit: stream.submitRequestUserInput,
7774
+ onDismiss: stream.stop,
7775
+ attachToComposer: true
7776
+ }
7777
+ ),
7778
+ /* @__PURE__ */ jsx32("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs21(
5987
7779
  "div",
5988
7780
  {
5989
7781
  className: cn(
@@ -5995,17 +7787,19 @@ function Chat({
5995
7787
  getRoundedClass(theme.radius)
5996
7788
  ),
5997
7789
  children: [
5998
- /* @__PURE__ */ jsx29(
7790
+ /* @__PURE__ */ jsx32(
5999
7791
  ComposerMenu,
6000
7792
  {
6001
7793
  composer,
6002
7794
  onAttachmentClick: handleAttachmentClick,
6003
7795
  onToolSelect: handleToolSelect,
6004
7796
  selectedTool,
6005
- disabled: missingConfig || isHistoryLoading
7797
+ planModeEnabled,
7798
+ onPlanModeChange: setPlanModeEnabled,
7799
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput
6006
7800
  }
6007
7801
  ),
6008
- /* @__PURE__ */ jsx29(
7802
+ /* @__PURE__ */ jsx32(
6009
7803
  "textarea",
6010
7804
  {
6011
7805
  ref: composerInputRef,
@@ -6015,7 +7809,7 @@ function Chat({
6015
7809
  onKeyDown: handleComposerKeyDown,
6016
7810
  rows: 1,
6017
7811
  placeholder: inputPlaceholder,
6018
- disabled: missingConfig || isHistoryLoading,
7812
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput,
6019
7813
  className: cn(
6020
7814
  "min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
6021
7815
  "placeholder:text-muted-foreground",
@@ -6023,12 +7817,12 @@ function Chat({
6023
7817
  )
6024
7818
  }
6025
7819
  ),
6026
- /* @__PURE__ */ jsx29(
7820
+ /* @__PURE__ */ jsx32(
6027
7821
  SendButton,
6028
7822
  {
6029
7823
  disabled: isSendDisabled,
6030
7824
  isLoading: stream.isLoading,
6031
- showStop: stream.isLoading && !trimmedDraft,
7825
+ showStop: stream.isLoading && (!trimmedDraft || hasPendingRequestUserInput),
6032
7826
  onStop: () => stream.stop(),
6033
7827
  stopLabel: t("chat.stop"),
6034
7828
  sendLabel: t("chat.send"),
@@ -6047,7 +7841,7 @@ function Chat({
6047
7841
  ]
6048
7842
  }
6049
7843
  ) }),
6050
- disclaimer?.text && /* @__PURE__ */ jsx29(
7844
+ disclaimer?.text && /* @__PURE__ */ jsx32(
6051
7845
  "p",
6052
7846
  {
6053
7847
  className: cn(
@@ -6057,9 +7851,9 @@ function Chat({
6057
7851
  children: disclaimer.text
6058
7852
  }
6059
7853
  ),
6060
- /* @__PURE__ */ jsxs18("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
6061
- /* @__PURE__ */ jsx29("span", { children: t("chat.poweredBy") }),
6062
- /* @__PURE__ */ jsx29(ContextUsageIndicator, { className: "absolute right-4" })
7854
+ /* @__PURE__ */ jsxs21("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
7855
+ /* @__PURE__ */ jsx32("span", { children: t("chat.poweredBy") }),
7856
+ /* @__PURE__ */ jsx32(ContextUsageIndicator, { className: "absolute right-4" })
6063
7857
  ] })
6064
7858
  ] })
6065
7859
  ]
@@ -6068,11 +7862,11 @@ function Chat({
6068
7862
  }
6069
7863
 
6070
7864
  // src/components/ui/input.tsx
6071
- import * as React24 from "react";
6072
- import { jsx as jsx30 } from "react/jsx-runtime";
6073
- var Input = React24.forwardRef(
7865
+ import * as React27 from "react";
7866
+ import { jsx as jsx33 } from "react/jsx-runtime";
7867
+ var Input = React27.forwardRef(
6074
7868
  ({ className, type, ...props }, ref) => {
6075
- return /* @__PURE__ */ jsx30(
7869
+ return /* @__PURE__ */ jsx33(
6076
7870
  "input",
6077
7871
  {
6078
7872
  ref,
@@ -6089,10 +7883,10 @@ var Input = React24.forwardRef(
6089
7883
  Input.displayName = "Input";
6090
7884
 
6091
7885
  // src/components/ui/separator.tsx
6092
- import * as React25 from "react";
6093
- import { jsx as jsx31 } from "react/jsx-runtime";
6094
- var Separator = React25.forwardRef(
6095
- ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx31(
7886
+ import * as React28 from "react";
7887
+ import { jsx as jsx34 } from "react/jsx-runtime";
7888
+ var Separator = React28.forwardRef(
7889
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx34(
6096
7890
  "div",
6097
7891
  {
6098
7892
  ref,