@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.cjs CHANGED
@@ -66,8 +66,8 @@ __export(index_exports, {
66
66
  module.exports = __toCommonJS(index_exports);
67
67
 
68
68
  // src/components/chat.tsx
69
- var React23 = __toESM(require("react"), 1);
70
- var import_lucide_react12 = require("lucide-react");
69
+ var React26 = __toESM(require("react"), 1);
70
+ var import_lucide_react15 = require("lucide-react");
71
71
 
72
72
  // src/lib/utils.ts
73
73
  var import_clsx = require("clsx");
@@ -681,6 +681,10 @@ function ParentMessengerProvider({
681
681
  }
682
682
  return;
683
683
  }
684
+ const requestHumanInput = params.planMode === true || params.state?.[import_chatkit_types2.STATE_VARIABLE_HUMAN]?.planMode === true ? {
685
+ ...humanInput,
686
+ planMode: true
687
+ } : humanInput;
684
688
  const newMessage = {
685
689
  id: createMessageId(),
686
690
  type: "human",
@@ -694,11 +698,11 @@ function ParentMessengerProvider({
694
698
  const requestOptions = buildInjectedRequestOptions({
695
699
  defaults: latestOptionsRef.current?.request,
696
700
  state: params.state,
697
- humanInput
701
+ humanInput: requestHumanInput
698
702
  });
699
703
  stream?.submit(
700
704
  {
701
- input: humanInput,
705
+ input: requestHumanInput,
702
706
  ...requestOptions.state ? { state: requestOptions.state } : {}
703
707
  },
704
708
  {
@@ -1154,14 +1158,31 @@ var en_US_default = {
1154
1158
  composer: {
1155
1159
  openMenu: "Open menu",
1156
1160
  addAttachment: "Add attachment",
1161
+ planMode: "Plan mode",
1157
1162
  removeReference: "Remove reference",
1158
- quoteSelection: "Quote selection"
1163
+ quoteSelection: "Quote selection",
1164
+ requestUserInput: {
1165
+ title: "Input requested",
1166
+ recommended: "Recommended",
1167
+ other: "Other",
1168
+ otherPlaceholder: "Type a custom answer",
1169
+ continue: "Continue",
1170
+ dismiss: "Dismiss",
1171
+ previousQuestion: "Previous question",
1172
+ nextQuestion: "Next question",
1173
+ questionProgress: "{{current}} of {{total}}",
1174
+ optionInfo: "Details for {{label}}",
1175
+ submit: "Continue"
1176
+ }
1159
1177
  },
1160
1178
  sheet: {
1161
1179
  close: "Close"
1162
1180
  },
1163
1181
  markdown: {
1164
1182
  copy: "Copy",
1183
+ plan: {
1184
+ download: "Download Markdown"
1185
+ },
1165
1186
  mermaid: {
1166
1187
  title: "Mermaid",
1167
1188
  diagram: "Diagram",
@@ -1182,7 +1203,58 @@ var en_US_default = {
1182
1203
  reasoning: "Reasoning",
1183
1204
  loading: "Loading",
1184
1205
  thinking: "Thinking",
1185
- answering: "Answering"
1206
+ answering: "Answering",
1207
+ requestUserInputResult: {
1208
+ title: "Selections confirmed",
1209
+ option: "Option",
1210
+ other: "Other"
1211
+ },
1212
+ toolGroup: {
1213
+ status: {
1214
+ running: "Processing",
1215
+ success: "Processed",
1216
+ fail: "Processing failed"
1217
+ },
1218
+ inputTitle: "Input",
1219
+ outputTitle: "Output",
1220
+ errorTitle: "Error",
1221
+ jsonTitle: "JSON",
1222
+ jsonTree: "Tree",
1223
+ jsonRaw: "Raw",
1224
+ copy: "Copy",
1225
+ copied: "Copied",
1226
+ separator: ", ",
1227
+ categories: {
1228
+ files: {
1229
+ one: "{{count}} file",
1230
+ other: "{{count}} files"
1231
+ },
1232
+ searches: {
1233
+ one: "{{count}} search",
1234
+ other: "{{count}} searches"
1235
+ },
1236
+ commands: {
1237
+ one: "{{count}} command",
1238
+ other: "{{count}} commands"
1239
+ },
1240
+ lists: {
1241
+ one: "{{count}} list",
1242
+ other: "{{count}} lists"
1243
+ },
1244
+ tasks: {
1245
+ one: "{{count}} task",
1246
+ other: "{{count}} tasks"
1247
+ },
1248
+ knowledges: {
1249
+ one: "{{count}} knowledge result",
1250
+ other: "{{count}} knowledge results"
1251
+ },
1252
+ tools: {
1253
+ one: "{{count}} tool",
1254
+ other: "{{count}} tools"
1255
+ }
1256
+ }
1257
+ }
1186
1258
  }
1187
1259
  };
1188
1260
 
@@ -1261,14 +1333,31 @@ var zh_CN_default = {
1261
1333
  composer: {
1262
1334
  openMenu: "\u6253\u5F00\u83DC\u5355",
1263
1335
  addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
1336
+ planMode: "\u8BA1\u5212\u6A21\u5F0F",
1264
1337
  removeReference: "\u79FB\u9664\u5F15\u7528",
1265
- quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
1338
+ quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9",
1339
+ requestUserInput: {
1340
+ title: "\u9700\u8981\u4F60\u7684\u8F93\u5165",
1341
+ recommended: "\u63A8\u8350",
1342
+ other: "\u5176\u4ED6",
1343
+ otherPlaceholder: "\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54",
1344
+ continue: "\u7EE7\u7EED",
1345
+ dismiss: "\u5173\u95ED",
1346
+ previousQuestion: "\u4E0A\u4E00\u4E2A\u95EE\u9898",
1347
+ nextQuestion: "\u4E0B\u4E00\u4E2A\u95EE\u9898",
1348
+ questionProgress: "{{current}} / {{total}}",
1349
+ optionInfo: "{{label}} \u7684\u8BF4\u660E",
1350
+ submit: "\u7EE7\u7EED"
1351
+ }
1266
1352
  },
1267
1353
  sheet: {
1268
1354
  close: "\u5173\u95ED"
1269
1355
  },
1270
1356
  markdown: {
1271
1357
  copy: "\u590D\u5236",
1358
+ plan: {
1359
+ download: "\u4E0B\u8F7D Markdown"
1360
+ },
1272
1361
  mermaid: {
1273
1362
  title: "Mermaid",
1274
1363
  diagram: "\u56FE\u8868",
@@ -1289,7 +1378,58 @@ var zh_CN_default = {
1289
1378
  reasoning: "\u63A8\u7406",
1290
1379
  loading: "\u6B63\u5728\u52A0\u8F7D",
1291
1380
  thinking: "\u6B63\u5728\u601D\u8003",
1292
- answering: "\u6B63\u5728\u751F\u6210"
1381
+ answering: "\u6B63\u5728\u751F\u6210",
1382
+ requestUserInputResult: {
1383
+ title: "\u5DF2\u786E\u8BA4\u9009\u62E9",
1384
+ option: "\u9009\u9879",
1385
+ other: "\u5176\u4ED6"
1386
+ },
1387
+ toolGroup: {
1388
+ status: {
1389
+ running: "\u6B63\u5728\u5904\u7406",
1390
+ success: "\u5DF2\u5904\u7406",
1391
+ fail: "\u5904\u7406\u5931\u8D25"
1392
+ },
1393
+ inputTitle: "\u8F93\u5165",
1394
+ outputTitle: "\u8F93\u51FA",
1395
+ errorTitle: "\u9519\u8BEF",
1396
+ jsonTitle: "JSON",
1397
+ jsonTree: "\u6811\u5F62",
1398
+ jsonRaw: "\u539F\u59CB",
1399
+ copy: "\u590D\u5236",
1400
+ copied: "\u5DF2\u590D\u5236",
1401
+ separator: "\uFF0C",
1402
+ categories: {
1403
+ files: {
1404
+ one: "{{count}} \u4E2A\u6587\u4EF6",
1405
+ other: "{{count}} \u4E2A\u6587\u4EF6"
1406
+ },
1407
+ searches: {
1408
+ one: "{{count}} \u4E2A\u641C\u7D22",
1409
+ other: "{{count}} \u4E2A\u641C\u7D22"
1410
+ },
1411
+ commands: {
1412
+ one: "{{count}} \u4E2A\u547D\u4EE4",
1413
+ other: "{{count}} \u4E2A\u547D\u4EE4"
1414
+ },
1415
+ lists: {
1416
+ one: "{{count}} \u4E2A\u5217\u8868",
1417
+ other: "{{count}} \u4E2A\u5217\u8868"
1418
+ },
1419
+ tasks: {
1420
+ one: "{{count}} \u4E2A\u4EFB\u52A1",
1421
+ other: "{{count}} \u4E2A\u4EFB\u52A1"
1422
+ },
1423
+ knowledges: {
1424
+ one: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C",
1425
+ other: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C"
1426
+ },
1427
+ tools: {
1428
+ one: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528",
1429
+ other: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528"
1430
+ }
1431
+ }
1432
+ }
1293
1433
  }
1294
1434
  };
1295
1435
 
@@ -1725,6 +1865,8 @@ function ComposerMenu({
1725
1865
  onAttachmentClick,
1726
1866
  onToolSelect,
1727
1867
  selectedTool,
1868
+ planModeEnabled = false,
1869
+ onPlanModeChange,
1728
1870
  disabled = false
1729
1871
  }) {
1730
1872
  const { t } = useChatkitTranslation();
@@ -1733,9 +1875,6 @@ function ComposerMenu({
1733
1875
  const roundedClass = getRoundedClass(theme.radius);
1734
1876
  const attachmentsEnabled = composer?.attachments?.enabled ?? false;
1735
1877
  const tools = composer?.tools ?? [];
1736
- if (!attachmentsEnabled && tools.length === 0) {
1737
- return null;
1738
- }
1739
1878
  const handleAttachmentClick = () => {
1740
1879
  onAttachmentClick?.();
1741
1880
  setOpen(false);
@@ -1744,6 +1883,9 @@ function ComposerMenu({
1744
1883
  onToolSelect?.(tool);
1745
1884
  setOpen(false);
1746
1885
  };
1886
+ const handlePlanModeToggle = () => {
1887
+ onPlanModeChange?.(!planModeEnabled);
1888
+ };
1747
1889
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
1748
1890
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1749
1891
  Button,
@@ -1783,8 +1925,46 @@ function ComposerMenu({
1783
1925
  ]
1784
1926
  }
1785
1927
  ),
1786
- tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" })
1928
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" })
1787
1929
  ] }),
1930
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1931
+ "button",
1932
+ {
1933
+ type: "button",
1934
+ role: "switch",
1935
+ "aria-checked": planModeEnabled,
1936
+ onClick: handlePlanModeToggle,
1937
+ className: cn(
1938
+ "flex items-center gap-3 px-3 py-2 text-sm hover:bg-muted transition-colors",
1939
+ roundedClass,
1940
+ planModeEnabled && "bg-muted"
1941
+ ),
1942
+ children: [
1943
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "flex h-6 w-6 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.ListChecks, { size: 16 }) }),
1944
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 flex-1 text-left", children: t("composer.planMode") }),
1945
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1946
+ "span",
1947
+ {
1948
+ className: cn(
1949
+ "relative inline-flex h-6 w-10 shrink-0 items-center rounded-full transition-colors",
1950
+ planModeEnabled ? "bg-primary" : "bg-muted-foreground/20"
1951
+ ),
1952
+ "aria-hidden": "true",
1953
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1954
+ "span",
1955
+ {
1956
+ className: cn(
1957
+ "inline-block h-5 w-5 rounded-full bg-background shadow-sm transition-transform",
1958
+ planModeEnabled ? "translate-x-[18px]" : "translate-x-0.5"
1959
+ )
1960
+ }
1961
+ )
1962
+ }
1963
+ )
1964
+ ]
1965
+ }
1966
+ ),
1967
+ tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" }),
1788
1968
  tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1789
1969
  "button",
1790
1970
  {
@@ -2107,19 +2287,23 @@ function HistorySidebar({
2107
2287
  setOpen(false);
2108
2288
  };
2109
2289
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Sheet, { open, onOpenChange: setOpen, children: [
2110
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2111
- Button,
2112
- {
2113
- variant: "ghost",
2114
- size: "icon",
2115
- disabled,
2116
- className: "h-8 w-8 cursor-pointer",
2117
- children: [
2118
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.History, { size: 16 }),
2119
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sr-only", children: t("history.threadHistory") })
2120
- ]
2121
- }
2122
- ) }),
2290
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
2291
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2292
+ Button,
2293
+ {
2294
+ variant: "ghost",
2295
+ size: "icon",
2296
+ disabled,
2297
+ className: "h-8 w-8 cursor-pointer",
2298
+ "aria-label": t("history.threadHistory"),
2299
+ children: [
2300
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.History, { size: 16 }),
2301
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sr-only", children: t("history.threadHistory") })
2302
+ ]
2303
+ }
2304
+ ) }) }) }),
2305
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: "bottom", children: t("history.threadHistory") })
2306
+ ] }),
2123
2307
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SheetContent, { side: "right", className: "w-80 p-0", children: [
2124
2308
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTitle, { children: t("history.title") }) }),
2125
2309
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -2583,162 +2767,780 @@ function PendingTodos({
2583
2767
  );
2584
2768
  }
2585
2769
 
2586
- // src/components/thread/messages/ai.tsx
2587
- var React16 = __toESM(require("react"), 1);
2588
- var import_lucide_react9 = require("lucide-react");
2589
-
2590
- // src/components/ui/badge.tsx
2770
+ // src/components/composer/request-user-input-panel.tsx
2591
2771
  var React12 = __toESM(require("react"), 1);
2772
+ var import_lucide_react7 = require("lucide-react");
2592
2773
  var import_jsx_runtime14 = require("react/jsx-runtime");
2593
- 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";
2594
- var variants = {
2595
- default: "bg-primary text-primary-foreground",
2596
- secondary: "bg-secondary text-secondary-foreground",
2597
- outline: "border-input text-foreground"
2598
- };
2599
- var Badge = React12.forwardRef(
2600
- ({ className, variant = "default", ...props }, ref) => {
2601
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { ref, className: cn(base, variants[variant], className), ...props });
2602
- }
2603
- );
2604
- Badge.displayName = "Badge";
2605
-
2606
- // src/components/ui/card.tsx
2607
- var React13 = __toESM(require("react"), 1);
2608
- var import_jsx_runtime15 = require("react/jsx-runtime");
2609
- var Card = React13.forwardRef(
2610
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2611
- "div",
2612
- {
2613
- ref,
2614
- className: cn(
2615
- "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
2616
- className
2617
- ),
2618
- ...props
2774
+ function useRoundedClasses3() {
2775
+ const { theme } = useTheme();
2776
+ const density = theme.density ?? "normal";
2777
+ const densityClasses = {
2778
+ compact: {
2779
+ section: "px-3.5 py-2",
2780
+ eyebrow: "mb-0 text-[11px]",
2781
+ title: "text-[15px] leading-5",
2782
+ pager: "gap-1.5 text-xs",
2783
+ pagerButton: "h-6 w-6",
2784
+ pagerIcon: "h-3.5 w-3.5",
2785
+ choices: "mt-2.5 space-y-0.5",
2786
+ row: "min-h-8 grid-cols-[28px_minmax(0,1fr)_auto] gap-2 px-2.5 py-1",
2787
+ otherRow: "min-h-8 grid-cols-[28px_minmax(0,1fr)] gap-2 px-2.5 py-1",
2788
+ input: "h-6",
2789
+ footer: "mt-2.5 gap-2",
2790
+ dismissButton: "h-7",
2791
+ continueButton: "h-8 px-3.5",
2792
+ continueIcon: "h-5 min-w-5"
2793
+ },
2794
+ normal: {
2795
+ section: "px-4 py-2.5",
2796
+ eyebrow: "mb-0.5 text-xs",
2797
+ title: "text-base leading-5",
2798
+ pager: "gap-2 text-sm",
2799
+ pagerButton: "h-7 w-7",
2800
+ pagerIcon: "h-4 w-4",
2801
+ choices: "mt-3 space-y-0.5",
2802
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2803
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2804
+ input: "h-6",
2805
+ footer: "mt-3 gap-3",
2806
+ dismissButton: "h-7",
2807
+ continueButton: "h-8 px-4",
2808
+ continueIcon: "h-5 min-w-5"
2809
+ },
2810
+ spacious: {
2811
+ section: "px-5 py-3",
2812
+ eyebrow: "mb-0.5 text-xs",
2813
+ title: "text-base leading-5",
2814
+ pager: "gap-2 text-sm",
2815
+ pagerButton: "h-7 w-7",
2816
+ pagerIcon: "h-4 w-4",
2817
+ choices: "mt-4 space-y-1",
2818
+ row: "min-h-10 grid-cols-[32px_minmax(0,1fr)_auto] gap-3 px-3 py-2",
2819
+ otherRow: "min-h-10 grid-cols-[32px_minmax(0,1fr)] gap-3 px-3 py-2",
2820
+ input: "h-7",
2821
+ footer: "mt-4 gap-3",
2822
+ dismissButton: "h-8",
2823
+ continueButton: "h-9 px-4",
2824
+ continueIcon: "h-5 min-w-5"
2619
2825
  }
2620
- )
2621
- );
2622
- Card.displayName = "Card";
2623
- var CardHeader = React13.forwardRef(
2624
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
2625
- );
2626
- CardHeader.displayName = "CardHeader";
2627
- var CardTitle = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
2628
- CardTitle.displayName = "CardTitle";
2629
- var CardDescription = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
2630
- CardDescription.displayName = "CardDescription";
2631
- var CardContent = React13.forwardRef(
2632
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("px-6 pb-6", className), ...props })
2633
- );
2634
- CardContent.displayName = "CardContent";
2635
- var CardFooter = React13.forwardRef(
2636
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
2637
- );
2638
- CardFooter.displayName = "CardFooter";
2639
- var CardAction = React13.forwardRef(
2640
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
2641
- );
2642
- CardAction.displayName = "CardAction";
2643
-
2644
- // src/components/ui/tabs.tsx
2645
- var React14 = __toESM(require("react"), 1);
2646
- var import_jsx_runtime16 = require("react/jsx-runtime");
2647
- var TabsContext = React14.createContext(null);
2648
- function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
2649
- const [internalValue, setInternalValue] = React14.useState(defaultValue ?? "");
2650
- const activeValue = value ?? internalValue;
2651
- const setValue = React14.useCallback(
2652
- (nextValue) => {
2653
- if (value === void 0) setInternalValue(nextValue);
2654
- onValueChange?.(nextValue);
2826
+ }[density] ?? {
2827
+ section: "px-4 py-2.5",
2828
+ eyebrow: "mb-0.5 text-xs",
2829
+ title: "text-base leading-5",
2830
+ pager: "gap-2 text-sm",
2831
+ pagerButton: "h-7 w-7",
2832
+ pagerIcon: "h-4 w-4",
2833
+ choices: "mt-3 space-y-0.5",
2834
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2835
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2836
+ input: "h-6",
2837
+ footer: "mt-3 gap-3",
2838
+ dismissButton: "h-7",
2839
+ continueButton: "h-8 px-4",
2840
+ continueIcon: "h-5 min-w-5"
2841
+ };
2842
+ return {
2843
+ top: theme.radius ? {
2844
+ pill: "rounded-t-3xl",
2845
+ round: "rounded-t-xl",
2846
+ soft: "rounded-t-lg",
2847
+ sharp: "rounded-t-none"
2848
+ }[theme.radius] : "rounded-t-lg",
2849
+ panel: getRoundedClass(theme.radius, "rounded-lg"),
2850
+ control: getRoundedClass(theme.radius, "rounded-md"),
2851
+ density: densityClasses
2852
+ };
2853
+ }
2854
+ function parseRecommendedLabel(label) {
2855
+ const recommendedPattern = /\s*(?:\((?:recommended)\)|(推荐))\s*$/i;
2856
+ return {
2857
+ label: label.replace(recommendedPattern, "").trim() || label,
2858
+ recommended: recommendedPattern.test(label)
2859
+ };
2860
+ }
2861
+ function getAnswerForQuestion(question, draft) {
2862
+ if (!draft) return null;
2863
+ if (draft.type === "other") {
2864
+ const value = draft.otherText.trim();
2865
+ if (!value) return null;
2866
+ return {
2867
+ id: question.id,
2868
+ question: question.question,
2869
+ type: "other",
2870
+ value
2871
+ };
2872
+ }
2873
+ const option = question.options[draft.optionIndex];
2874
+ if (!option) return null;
2875
+ return {
2876
+ id: question.id,
2877
+ question: question.question,
2878
+ type: "option",
2879
+ value: option.label,
2880
+ label: option.label,
2881
+ description: option.description
2882
+ };
2883
+ }
2884
+ function getSelectedChoiceIndex(question, draft) {
2885
+ if (!draft) return -1;
2886
+ if (draft.type === "other") return question.options.length;
2887
+ return draft.optionIndex;
2888
+ }
2889
+ function RequestUserInputPanel({
2890
+ request,
2891
+ onSubmit,
2892
+ onDismiss,
2893
+ attachToComposer = true,
2894
+ className
2895
+ }) {
2896
+ const { t } = useChatkitTranslation();
2897
+ const rounded = useRoundedClasses3();
2898
+ const [drafts, setDrafts] = React12.useState({});
2899
+ const [currentQuestionIndex, setCurrentQuestionIndex] = React12.useState(0);
2900
+ const otherInputRef = React12.useRef(null);
2901
+ const questions = request?.params.questions ?? [];
2902
+ React12.useEffect(() => {
2903
+ setDrafts({});
2904
+ setCurrentQuestionIndex(0);
2905
+ }, [request?.id]);
2906
+ React12.useEffect(() => {
2907
+ if (questions.length === 0) return;
2908
+ setCurrentQuestionIndex(
2909
+ (index) => Math.min(Math.max(index, 0), questions.length - 1)
2910
+ );
2911
+ }, [questions.length]);
2912
+ const setQuestionDraft = React12.useCallback(
2913
+ (questionId, draft) => {
2914
+ setDrafts((previous) => ({
2915
+ ...previous,
2916
+ [questionId]: draft
2917
+ }));
2655
2918
  },
2656
- [onValueChange, value]
2919
+ []
2657
2920
  );
2658
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn("w-full", className), ...props }) });
2659
- }
2660
- var TabsList = React14.forwardRef(
2661
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2662
- "div",
2663
- {
2664
- ref,
2665
- className: cn(
2666
- "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
2667
- className
2668
- ),
2669
- role: "tablist",
2670
- ...props
2921
+ const focusOtherInput = React12.useCallback(() => {
2922
+ window.setTimeout(() => otherInputRef.current?.focus(), 0);
2923
+ }, []);
2924
+ const selectOption = React12.useCallback(
2925
+ (question, optionIndex) => {
2926
+ const previousDraft = drafts[question.id];
2927
+ setQuestionDraft(question.id, {
2928
+ type: "option",
2929
+ optionIndex,
2930
+ otherText: previousDraft?.otherText ?? ""
2931
+ });
2932
+ },
2933
+ [drafts, setQuestionDraft]
2934
+ );
2935
+ const selectOther = React12.useCallback(
2936
+ (question, otherText2) => {
2937
+ const previousDraft = drafts[question.id];
2938
+ setQuestionDraft(question.id, {
2939
+ type: "other",
2940
+ otherText: otherText2 ?? (previousDraft?.type === "other" ? previousDraft.otherText : previousDraft?.otherText) ?? ""
2941
+ });
2942
+ focusOtherInput();
2943
+ },
2944
+ [drafts, focusOtherInput, setQuestionDraft]
2945
+ );
2946
+ const goToQuestion = React12.useCallback(
2947
+ (index) => {
2948
+ if (questions.length === 0) return;
2949
+ setCurrentQuestionIndex(
2950
+ Math.min(Math.max(index, 0), questions.length - 1)
2951
+ );
2952
+ },
2953
+ [questions.length]
2954
+ );
2955
+ const answers = React12.useMemo(
2956
+ () => questions.map((question) => getAnswerForQuestion(question, drafts[question.id])).filter((answer) => Boolean(answer)),
2957
+ [drafts, questions]
2958
+ );
2959
+ const canSubmit = answers.length === questions.length;
2960
+ const currentQuestion = questions[currentQuestionIndex] ?? null;
2961
+ const currentDraft = currentQuestion ? drafts[currentQuestion.id] : void 0;
2962
+ const currentAnswer = currentQuestion ? getAnswerForQuestion(currentQuestion, currentDraft) : null;
2963
+ const isLastQuestion = currentQuestionIndex === questions.length - 1;
2964
+ const buildAnswersFromDrafts = React12.useCallback(
2965
+ (nextDrafts) => questions.map((question) => getAnswerForQuestion(question, nextDrafts[question.id])).filter((answer) => Boolean(answer)),
2966
+ [questions]
2967
+ );
2968
+ const submitOrFocusFirstMissing = React12.useCallback(
2969
+ (nextDrafts) => {
2970
+ const nextAnswers = buildAnswersFromDrafts(nextDrafts);
2971
+ if (nextAnswers.length === questions.length) {
2972
+ onSubmit(nextAnswers);
2973
+ return;
2974
+ }
2975
+ const firstMissingIndex = questions.findIndex(
2976
+ (question) => !getAnswerForQuestion(question, nextDrafts[question.id])
2977
+ );
2978
+ if (firstMissingIndex >= 0) {
2979
+ goToQuestion(firstMissingIndex);
2980
+ }
2981
+ },
2982
+ [buildAnswersFromDrafts, goToQuestion, onSubmit, questions]
2983
+ );
2984
+ const activateOption = React12.useCallback(
2985
+ (question, optionIndex) => {
2986
+ const previousDraft = drafts[question.id];
2987
+ const nextDrafts = {
2988
+ ...drafts,
2989
+ [question.id]: {
2990
+ type: "option",
2991
+ optionIndex,
2992
+ otherText: previousDraft?.otherText ?? ""
2993
+ }
2994
+ };
2995
+ setDrafts(nextDrafts);
2996
+ if (isLastQuestion) {
2997
+ submitOrFocusFirstMissing(nextDrafts);
2998
+ return;
2999
+ }
3000
+ goToQuestion(currentQuestionIndex + 1);
3001
+ },
3002
+ [
3003
+ currentQuestionIndex,
3004
+ drafts,
3005
+ goToQuestion,
3006
+ isLastQuestion,
3007
+ submitOrFocusFirstMissing
3008
+ ]
3009
+ );
3010
+ const chooseChoiceByIndex = React12.useCallback(
3011
+ (choiceIndex) => {
3012
+ if (!currentQuestion) return;
3013
+ if (choiceIndex < 0) return;
3014
+ if (choiceIndex < currentQuestion.options.length) {
3015
+ selectOption(currentQuestion, choiceIndex);
3016
+ return;
3017
+ }
3018
+ if (choiceIndex === currentQuestion.options.length) {
3019
+ selectOther(currentQuestion);
3020
+ }
3021
+ },
3022
+ [currentQuestion, selectOption, selectOther]
3023
+ );
3024
+ const moveCurrentChoice = React12.useCallback(
3025
+ (direction) => {
3026
+ if (!currentQuestion) return;
3027
+ const choiceCount = currentQuestion.options.length + 1;
3028
+ const currentIndex = getSelectedChoiceIndex(currentQuestion, currentDraft);
3029
+ const nextIndex = currentIndex === -1 ? direction === 1 ? 0 : choiceCount - 1 : (currentIndex + direction + choiceCount) % choiceCount;
3030
+ chooseChoiceByIndex(nextIndex);
3031
+ },
3032
+ [chooseChoiceByIndex, currentDraft, currentQuestion]
3033
+ );
3034
+ const handleContinue = React12.useCallback(() => {
3035
+ if (!currentAnswer) return;
3036
+ if (!isLastQuestion) {
3037
+ goToQuestion(currentQuestionIndex + 1);
3038
+ return;
2671
3039
  }
2672
- )
2673
- );
2674
- TabsList.displayName = "TabsList";
2675
- var TabsTrigger = React14.forwardRef(
2676
- ({ className, value, onClick, ...props }, ref) => {
2677
- const context = React14.useContext(TabsContext);
2678
- if (!context) {
2679
- throw new Error("TabsTrigger must be used within Tabs");
3040
+ if (canSubmit) {
3041
+ onSubmit(answers);
3042
+ return;
2680
3043
  }
2681
- const isActive = context.value === value;
2682
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2683
- "button",
2684
- {
2685
- ref,
2686
- type: "button",
2687
- role: "tab",
2688
- "aria-selected": isActive,
2689
- "data-state": isActive ? "active" : "inactive",
2690
- className: cn(
2691
- "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",
2692
- className
2693
- ),
2694
- onClick: (event) => {
2695
- context.setValue(value);
2696
- onClick?.(event);
2697
- },
2698
- ...props
2699
- }
3044
+ const firstMissingIndex = questions.findIndex(
3045
+ (question) => !getAnswerForQuestion(question, drafts[question.id])
2700
3046
  );
2701
- }
2702
- );
2703
- TabsTrigger.displayName = "TabsTrigger";
2704
- var TabsContent = React14.forwardRef(
2705
- ({ className, value, ...props }, ref) => {
2706
- const context = React14.useContext(TabsContext);
2707
- if (!context) {
2708
- throw new Error("TabsContent must be used within Tabs");
3047
+ if (firstMissingIndex >= 0) {
3048
+ goToQuestion(firstMissingIndex);
2709
3049
  }
2710
- if (context.value !== value) return null;
2711
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2712
- "div",
2713
- {
2714
- ref,
2715
- role: "tabpanel",
2716
- className: cn(
2717
- "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
2718
- className
2719
- ),
2720
- ...props
3050
+ }, [
3051
+ answers,
3052
+ canSubmit,
3053
+ currentAnswer,
3054
+ currentQuestionIndex,
3055
+ drafts,
3056
+ goToQuestion,
3057
+ isLastQuestion,
3058
+ onSubmit,
3059
+ questions
3060
+ ]);
3061
+ React12.useEffect(() => {
3062
+ if (!request) return;
3063
+ const handleKeyDown = (event) => {
3064
+ if (event.isComposing) return;
3065
+ const target = event.target;
3066
+ const targetTag = target?.tagName;
3067
+ const isTypingTarget = target?.isContentEditable || targetTag === "INPUT" || targetTag === "TEXTAREA" || targetTag === "SELECT";
3068
+ if (event.key === "Escape" || event.key === "Esc") {
3069
+ if (onDismiss) {
3070
+ event.preventDefault();
3071
+ onDismiss();
3072
+ }
3073
+ return;
2721
3074
  }
2722
- );
2723
- }
2724
- );
2725
- TabsContent.displayName = "TabsContent";
2726
-
2727
- // src/components/thread/markdown-text.tsx
2728
- var import_react_markdown = __toESM(require("react-markdown"), 1);
2729
- var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2730
- var import_rehype_katex = __toESM(require("rehype-katex"), 1);
2731
- var import_remark_math = __toESM(require("remark-math"), 1);
2732
- var import_react6 = require("react");
2733
- var import_lucide_react8 = require("lucide-react");
2734
-
2735
- // src/components/thread/syntax-highlighter.tsx
2736
- var import_react_syntax_highlighter = require("react-syntax-highlighter");
2737
- var import_tsx = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/tsx"), 1);
2738
- var import_python = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/python"), 1);
2739
- var import_prism = require("react-syntax-highlighter/dist/cjs/styles/prism");
2740
- var import_react4 = require("react");
3075
+ if (isTypingTarget && event.key !== "Enter") {
3076
+ return;
3077
+ }
3078
+ if (event.key === "Enter") {
3079
+ event.preventDefault();
3080
+ handleContinue();
3081
+ return;
3082
+ }
3083
+ if (event.key === "ArrowLeft") {
3084
+ event.preventDefault();
3085
+ goToQuestion(currentQuestionIndex - 1);
3086
+ return;
3087
+ }
3088
+ if (event.key === "ArrowRight") {
3089
+ event.preventDefault();
3090
+ goToQuestion(currentQuestionIndex + 1);
3091
+ return;
3092
+ }
3093
+ if (event.key === "ArrowUp") {
3094
+ event.preventDefault();
3095
+ moveCurrentChoice(-1);
3096
+ return;
3097
+ }
3098
+ if (event.key === "ArrowDown") {
3099
+ event.preventDefault();
3100
+ moveCurrentChoice(1);
3101
+ return;
3102
+ }
3103
+ if (/^[1-9]$/.test(event.key)) {
3104
+ const choiceIndex = Number(event.key) - 1;
3105
+ if (currentQuestion && choiceIndex < currentQuestion.options.length + 1) {
3106
+ event.preventDefault();
3107
+ chooseChoiceByIndex(choiceIndex);
3108
+ }
3109
+ }
3110
+ };
3111
+ document.addEventListener("keydown", handleKeyDown);
3112
+ return () => document.removeEventListener("keydown", handleKeyDown);
3113
+ }, [
3114
+ chooseChoiceByIndex,
3115
+ currentQuestion,
3116
+ currentQuestionIndex,
3117
+ goToQuestion,
3118
+ handleContinue,
3119
+ moveCurrentChoice,
3120
+ onDismiss,
3121
+ request
3122
+ ]);
3123
+ if (!request || !currentQuestion) {
3124
+ return null;
3125
+ }
3126
+ const handleOtherTextChange = (value) => {
3127
+ setDrafts((previous) => ({
3128
+ ...previous,
3129
+ [currentQuestion.id]: {
3130
+ type: "other",
3131
+ otherText: value
3132
+ }
3133
+ }));
3134
+ };
3135
+ const otherText = currentDraft?.otherText ?? "";
3136
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3137
+ "section",
3138
+ {
3139
+ "aria-label": t("composer.requestUserInput.title"),
3140
+ "aria-live": "polite",
3141
+ className: cn(
3142
+ "mx-2 border border-border bg-background/95 shadow-sm",
3143
+ rounded.density.section,
3144
+ attachToComposer ? "border-b-0" : null,
3145
+ attachToComposer ? rounded.top : rounded.panel,
3146
+ className
3147
+ ),
3148
+ children: [
3149
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
3150
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "min-w-0", children: [
3151
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3152
+ "div",
3153
+ {
3154
+ className: cn(
3155
+ "font-medium text-muted-foreground",
3156
+ rounded.density.eyebrow
3157
+ ),
3158
+ children: currentQuestion.header
3159
+ }
3160
+ ),
3161
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3162
+ "h3",
3163
+ {
3164
+ className: cn(
3165
+ "font-semibold text-foreground",
3166
+ rounded.density.title
3167
+ ),
3168
+ children: currentQuestion.question
3169
+ }
3170
+ )
3171
+ ] }),
3172
+ questions.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3173
+ "div",
3174
+ {
3175
+ className: cn(
3176
+ "flex shrink-0 items-center font-medium text-muted-foreground",
3177
+ rounded.density.pager
3178
+ ),
3179
+ children: [
3180
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3181
+ "button",
3182
+ {
3183
+ type: "button",
3184
+ onClick: () => goToQuestion(currentQuestionIndex - 1),
3185
+ disabled: currentQuestionIndex === 0,
3186
+ className: cn(
3187
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3188
+ rounded.density.pagerButton
3189
+ ),
3190
+ "aria-label": t("composer.requestUserInput.previousQuestion"),
3191
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ChevronLeft, { className: rounded.density.pagerIcon })
3192
+ }
3193
+ ),
3194
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "min-w-12 text-center", children: t("composer.requestUserInput.questionProgress", {
3195
+ current: currentQuestionIndex + 1,
3196
+ total: questions.length
3197
+ }) }),
3198
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3199
+ "button",
3200
+ {
3201
+ type: "button",
3202
+ onClick: () => goToQuestion(currentQuestionIndex + 1),
3203
+ disabled: currentQuestionIndex === questions.length - 1,
3204
+ className: cn(
3205
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3206
+ rounded.density.pagerButton
3207
+ ),
3208
+ "aria-label": t("composer.requestUserInput.nextQuestion"),
3209
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ChevronRight, { className: rounded.density.pagerIcon })
3210
+ }
3211
+ )
3212
+ ]
3213
+ }
3214
+ ) : null
3215
+ ] }),
3216
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: rounded.density.choices, children: [
3217
+ currentQuestion.options.map((option, optionIndex) => {
3218
+ const selected = currentDraft?.type === "option" && currentDraft.optionIndex === optionIndex;
3219
+ const parsedLabel = parseRecommendedLabel(option.label);
3220
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3221
+ "div",
3222
+ {
3223
+ role: "button",
3224
+ tabIndex: 0,
3225
+ onClick: () => activateOption(currentQuestion, optionIndex),
3226
+ onKeyDown: (event) => {
3227
+ if (event.key === "Enter" || event.key === " ") {
3228
+ event.preventDefault();
3229
+ event.stopPropagation();
3230
+ activateOption(currentQuestion, optionIndex);
3231
+ }
3232
+ },
3233
+ "aria-pressed": selected,
3234
+ "aria-label": `${optionIndex + 1}. ${option.label}`,
3235
+ className: cn(
3236
+ "grid cursor-pointer items-center text-left transition-colors",
3237
+ rounded.density.row,
3238
+ rounded.panel,
3239
+ selected ? "bg-muted text-foreground" : "text-foreground/90 hover:bg-muted/55"
3240
+ ),
3241
+ children: [
3242
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3243
+ optionIndex + 1,
3244
+ "."
3245
+ ] }),
3246
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "min-w-0", children: [
3247
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "inline min-w-0 text-sm font-semibold leading-5", children: parsedLabel.label }),
3248
+ parsedLabel.recommended ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ml-1.5 inline-flex items-center gap-1 text-sm font-semibold text-primary", children: [
3249
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Check, { className: "h-3.5 w-3.5" }),
3250
+ "(",
3251
+ t("composer.requestUserInput.recommended"),
3252
+ ")"
3253
+ ] }) : null
3254
+ ] }),
3255
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
3256
+ option.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Tooltip, { children: [
3257
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3258
+ "button",
3259
+ {
3260
+ type: "button",
3261
+ onClick: (event) => event.stopPropagation(),
3262
+ onKeyDown: (event) => event.stopPropagation(),
3263
+ title: option.description,
3264
+ className: "inline-flex h-7 w-7 items-center justify-center rounded-full hover:bg-background/80 hover:text-foreground",
3265
+ "aria-label": t("composer.requestUserInput.optionInfo", {
3266
+ label: parsedLabel.label
3267
+ }),
3268
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Info, { className: "h-4 w-4" })
3269
+ }
3270
+ ) }),
3271
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3272
+ TooltipContent,
3273
+ {
3274
+ side: "top",
3275
+ sideOffset: 6,
3276
+ className: "max-w-72 text-left leading-5",
3277
+ children: option.description
3278
+ }
3279
+ )
3280
+ ] }) : null,
3281
+ selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3282
+ "span",
3283
+ {
3284
+ "aria-hidden": "true",
3285
+ className: "hidden items-center gap-0.5 sm:flex",
3286
+ children: [
3287
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowUp, { className: "h-4 w-4 opacity-45" }),
3288
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowDown, { className: "h-4 w-4 opacity-45" })
3289
+ ]
3290
+ }
3291
+ ) : null
3292
+ ] })
3293
+ ]
3294
+ },
3295
+ `${currentQuestion.id}-${optionIndex}`
3296
+ );
3297
+ }),
3298
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3299
+ "label",
3300
+ {
3301
+ className: cn(
3302
+ "grid items-center transition-colors",
3303
+ rounded.density.otherRow,
3304
+ rounded.panel,
3305
+ currentDraft?.type === "other" ? "bg-muted text-foreground" : "hover:bg-muted/55"
3306
+ ),
3307
+ children: [
3308
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3309
+ currentQuestion.options.length + 1,
3310
+ "."
3311
+ ] }),
3312
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3313
+ "input",
3314
+ {
3315
+ ref: otherInputRef,
3316
+ value: otherText,
3317
+ onChange: (event) => handleOtherTextChange(event.target.value),
3318
+ onFocus: () => selectOther(currentQuestion, otherText),
3319
+ placeholder: t("composer.requestUserInput.otherPlaceholder"),
3320
+ className: cn(
3321
+ "min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground",
3322
+ rounded.density.input
3323
+ )
3324
+ }
3325
+ ) })
3326
+ ]
3327
+ }
3328
+ )
3329
+ ] }),
3330
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3331
+ "div",
3332
+ {
3333
+ className: cn(
3334
+ "flex items-center justify-end",
3335
+ rounded.density.footer
3336
+ ),
3337
+ children: [
3338
+ onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3339
+ "button",
3340
+ {
3341
+ type: "button",
3342
+ onClick: onDismiss,
3343
+ className: cn(
3344
+ "inline-flex items-center gap-2 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground",
3345
+ rounded.density.dismissButton
3346
+ ),
3347
+ children: [
3348
+ t("composer.requestUserInput.dismiss"),
3349
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("kbd", { className: "rounded-full bg-muted px-2 py-1 text-xs font-semibold text-muted-foreground", children: "ESC" })
3350
+ ]
3351
+ }
3352
+ ) : null,
3353
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
3354
+ "button",
3355
+ {
3356
+ type: "button",
3357
+ disabled: !currentAnswer,
3358
+ onClick: handleContinue,
3359
+ className: cn(
3360
+ "inline-flex items-center gap-2 bg-primary text-sm font-semibold text-background transition-all",
3361
+ rounded.density.continueButton,
3362
+ "hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-40",
3363
+ rounded.panel
3364
+ ),
3365
+ children: [
3366
+ t("composer.requestUserInput.continue"),
3367
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
3368
+ "span",
3369
+ {
3370
+ className: cn(
3371
+ "inline-flex items-center justify-center rounded-full bg-background/20",
3372
+ rounded.density.continueIcon
3373
+ ),
3374
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.CornerDownLeft, { className: "h-3.5 w-3.5" })
3375
+ }
3376
+ )
3377
+ ]
3378
+ }
3379
+ )
3380
+ ]
3381
+ }
3382
+ )
3383
+ ]
3384
+ }
3385
+ );
3386
+ }
3387
+
3388
+ // src/components/thread/messages/ai.tsx
3389
+ var React19 = __toESM(require("react"), 1);
3390
+ var import_lucide_react12 = require("lucide-react");
3391
+
3392
+ // src/components/ui/badge.tsx
3393
+ var React13 = __toESM(require("react"), 1);
3394
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3395
+ 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";
3396
+ var variants = {
3397
+ default: "bg-primary text-primary-foreground",
3398
+ secondary: "bg-secondary text-secondary-foreground",
3399
+ outline: "border-input text-foreground"
3400
+ };
3401
+ var Badge = React13.forwardRef(
3402
+ ({ className, variant = "default", ...props }, ref) => {
3403
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { ref, className: cn(base, variants[variant], className), ...props });
3404
+ }
3405
+ );
3406
+ Badge.displayName = "Badge";
3407
+
3408
+ // src/components/ui/card.tsx
3409
+ var React14 = __toESM(require("react"), 1);
3410
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3411
+ var Card = React14.forwardRef(
3412
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3413
+ "div",
3414
+ {
3415
+ ref,
3416
+ className: cn(
3417
+ "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
3418
+ className
3419
+ ),
3420
+ ...props
3421
+ }
3422
+ )
3423
+ );
3424
+ Card.displayName = "Card";
3425
+ var CardHeader = React14.forwardRef(
3426
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
3427
+ );
3428
+ CardHeader.displayName = "CardHeader";
3429
+ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
3430
+ CardTitle.displayName = "CardTitle";
3431
+ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
3432
+ CardDescription.displayName = "CardDescription";
3433
+ var CardContent = React14.forwardRef(
3434
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("px-6 pb-6", className), ...props })
3435
+ );
3436
+ CardContent.displayName = "CardContent";
3437
+ var CardFooter = React14.forwardRef(
3438
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
3439
+ );
3440
+ CardFooter.displayName = "CardFooter";
3441
+ var CardAction = React14.forwardRef(
3442
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
3443
+ );
3444
+ CardAction.displayName = "CardAction";
3445
+
3446
+ // src/components/ui/tabs.tsx
3447
+ var React15 = __toESM(require("react"), 1);
2741
3448
  var import_jsx_runtime17 = require("react/jsx-runtime");
3449
+ var TabsContext = React15.createContext(null);
3450
+ function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
3451
+ const [internalValue, setInternalValue] = React15.useState(defaultValue ?? "");
3452
+ const activeValue = value ?? internalValue;
3453
+ const setValue = React15.useCallback(
3454
+ (nextValue) => {
3455
+ if (value === void 0) setInternalValue(nextValue);
3456
+ onValueChange?.(nextValue);
3457
+ },
3458
+ [onValueChange, value]
3459
+ );
3460
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: cn("w-full", className), ...props }) });
3461
+ }
3462
+ var TabsList = React15.forwardRef(
3463
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3464
+ "div",
3465
+ {
3466
+ ref,
3467
+ className: cn(
3468
+ "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
3469
+ className
3470
+ ),
3471
+ role: "tablist",
3472
+ ...props
3473
+ }
3474
+ )
3475
+ );
3476
+ TabsList.displayName = "TabsList";
3477
+ var TabsTrigger = React15.forwardRef(
3478
+ ({ className, value, onClick, ...props }, ref) => {
3479
+ const context = React15.useContext(TabsContext);
3480
+ if (!context) {
3481
+ throw new Error("TabsTrigger must be used within Tabs");
3482
+ }
3483
+ const isActive = context.value === value;
3484
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3485
+ "button",
3486
+ {
3487
+ ref,
3488
+ type: "button",
3489
+ role: "tab",
3490
+ "aria-selected": isActive,
3491
+ "data-state": isActive ? "active" : "inactive",
3492
+ className: cn(
3493
+ "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",
3494
+ className
3495
+ ),
3496
+ onClick: (event) => {
3497
+ context.setValue(value);
3498
+ onClick?.(event);
3499
+ },
3500
+ ...props
3501
+ }
3502
+ );
3503
+ }
3504
+ );
3505
+ TabsTrigger.displayName = "TabsTrigger";
3506
+ var TabsContent = React15.forwardRef(
3507
+ ({ className, value, ...props }, ref) => {
3508
+ const context = React15.useContext(TabsContext);
3509
+ if (!context) {
3510
+ throw new Error("TabsContent must be used within Tabs");
3511
+ }
3512
+ if (context.value !== value) return null;
3513
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3514
+ "div",
3515
+ {
3516
+ ref,
3517
+ role: "tabpanel",
3518
+ className: cn(
3519
+ "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
3520
+ className
3521
+ ),
3522
+ ...props
3523
+ }
3524
+ );
3525
+ }
3526
+ );
3527
+ TabsContent.displayName = "TabsContent";
3528
+
3529
+ // src/components/thread/markdown-text.tsx
3530
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
3531
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
3532
+ var import_rehype_katex = __toESM(require("rehype-katex"), 1);
3533
+ var import_remark_math = __toESM(require("remark-math"), 1);
3534
+ var import_react6 = require("react");
3535
+ var import_lucide_react9 = require("lucide-react");
3536
+
3537
+ // src/components/thread/syntax-highlighter.tsx
3538
+ var import_react_syntax_highlighter = require("react-syntax-highlighter");
3539
+ var import_tsx = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/tsx"), 1);
3540
+ var import_python = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/python"), 1);
3541
+ var import_prism = require("react-syntax-highlighter/dist/cjs/styles/prism");
3542
+ var import_react4 = require("react");
3543
+ var import_jsx_runtime18 = require("react/jsx-runtime");
2742
3544
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("js", import_tsx.default);
2743
3545
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("jsx", import_tsx.default);
2744
3546
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("ts", import_tsx.default);
@@ -2749,7 +3551,7 @@ var SyntaxHighlighter = ({
2749
3551
  language,
2750
3552
  className
2751
3553
  }) => {
2752
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3554
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2753
3555
  import_react_syntax_highlighter.PrismAsyncLight,
2754
3556
  {
2755
3557
  language,
@@ -2769,15 +3571,15 @@ var SyntaxHighlighter = ({
2769
3571
  // src/components/thread/mermaid-block.tsx
2770
3572
  var Dialog = __toESM(require("@radix-ui/react-dialog"), 1);
2771
3573
  var import_mermaid = __toESM(require("mermaid"), 1);
2772
- var import_lucide_react7 = require("lucide-react");
2773
- var React15 = __toESM(require("react"), 1);
3574
+ var import_lucide_react8 = require("lucide-react");
3575
+ var React16 = __toESM(require("react"), 1);
2774
3576
 
2775
3577
  // src/components/thread/tooltip-icon-button.tsx
2776
3578
  var import_react5 = require("react");
2777
- var import_jsx_runtime18 = require("react/jsx-runtime");
3579
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2778
3580
  var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
2779
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Tooltip, { children: [
2780
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3581
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Tooltip, { children: [
3582
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2781
3583
  Button,
2782
3584
  {
2783
3585
  variant: "ghost",
@@ -2787,17 +3589,17 @@ var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side
2787
3589
  ref,
2788
3590
  children: [
2789
3591
  children,
2790
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sr-only", children: tooltip })
3592
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sr-only", children: tooltip })
2791
3593
  ]
2792
3594
  }
2793
3595
  ) }),
2794
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipContent, { side, children: tooltip })
3596
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipContent, { side, children: tooltip })
2795
3597
  ] }) });
2796
3598
  });
2797
3599
  TooltipIconButton.displayName = "TooltipIconButton";
2798
3600
 
2799
3601
  // src/components/thread/mermaid-block.tsx
2800
- var import_jsx_runtime19 = require("react/jsx-runtime");
3602
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2801
3603
  var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
2802
3604
  var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
2803
3605
  var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
@@ -3045,24 +3847,24 @@ function MermaidPreviewDialog({
3045
3847
  svgMarkup,
3046
3848
  title
3047
3849
  }) {
3048
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Dialog.Portal, { children: [
3049
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(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" }),
3050
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(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: [
3051
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3052
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3053
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3850
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Dialog.Portal, { children: [
3851
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(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" }),
3852
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(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: [
3853
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3854
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3855
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3054
3856
  "button",
3055
3857
  {
3056
3858
  type: "button",
3057
3859
  className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
3058
3860
  children: [
3059
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.X, { className: "size-4" }),
3060
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sr-only", children: closeLabel })
3861
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { className: "size-4" }),
3862
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sr-only", children: closeLabel })
3061
3863
  ]
3062
3864
  }
3063
3865
  ) })
3064
3866
  ] }),
3065
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3867
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3066
3868
  "div",
3067
3869
  {
3068
3870
  "data-slot": "mermaid-preview",
@@ -3076,24 +3878,24 @@ function MermaidPreviewDialog({
3076
3878
  function MermaidBlock({ code }) {
3077
3879
  const { t } = useChatkitTranslation();
3078
3880
  const { theme, isDarkMode } = useTheme();
3079
- const containerRef = React15.useRef(null);
3080
- const renderHostRef = React15.useRef(null);
3081
- const renderSequenceRef = React15.useRef(0);
3082
- const copyResetTimeoutRef = React15.useRef(null);
3083
- const diagramId = React15.useId().replace(/:/g, "");
3084
- const [activeTab, setActiveTab] = React15.useState("diagram");
3085
- const [isCopied, setIsCopied] = React15.useState(false);
3086
- const [isPreviewOpen, setIsPreviewOpen] = React15.useState(false);
3087
- const [isRendering, setIsRendering] = React15.useState(true);
3088
- const [renderError, setRenderError] = React15.useState(null);
3089
- const [svgMarkup, setSvgMarkup] = React15.useState(null);
3090
- const normalizedCode = React15.useMemo(() => normalizeMermaidCode(code), [code]);
3091
- const clearCopyResetTimeout = React15.useCallback(() => {
3881
+ const containerRef = React16.useRef(null);
3882
+ const renderHostRef = React16.useRef(null);
3883
+ const renderSequenceRef = React16.useRef(0);
3884
+ const copyResetTimeoutRef = React16.useRef(null);
3885
+ const diagramId = React16.useId().replace(/:/g, "");
3886
+ const [activeTab, setActiveTab] = React16.useState("diagram");
3887
+ const [isCopied, setIsCopied] = React16.useState(false);
3888
+ const [isPreviewOpen, setIsPreviewOpen] = React16.useState(false);
3889
+ const [isRendering, setIsRendering] = React16.useState(true);
3890
+ const [renderError, setRenderError] = React16.useState(null);
3891
+ const [svgMarkup, setSvgMarkup] = React16.useState(null);
3892
+ const normalizedCode = React16.useMemo(() => normalizeMermaidCode(code), [code]);
3893
+ const clearCopyResetTimeout = React16.useCallback(() => {
3092
3894
  if (copyResetTimeoutRef.current === null) return;
3093
3895
  window.clearTimeout(copyResetTimeoutRef.current);
3094
3896
  copyResetTimeoutRef.current = null;
3095
3897
  }, []);
3096
- React15.useEffect(() => {
3898
+ React16.useEffect(() => {
3097
3899
  let isActive = true;
3098
3900
  async function runRender() {
3099
3901
  const container = containerRef.current;
@@ -3131,17 +3933,17 @@ function MermaidBlock({ code }) {
3131
3933
  }
3132
3934
  };
3133
3935
  }, [diagramId, isDarkMode, normalizedCode, theme]);
3134
- React15.useEffect(() => {
3936
+ React16.useEffect(() => {
3135
3937
  clearCopyResetTimeout();
3136
3938
  setIsCopied(false);
3137
3939
  }, [activeTab, clearCopyResetTimeout, code]);
3138
- React15.useEffect(
3940
+ React16.useEffect(
3139
3941
  () => () => {
3140
3942
  clearCopyResetTimeout();
3141
3943
  },
3142
3944
  [clearCopyResetTimeout]
3143
3945
  );
3144
- const handleDownload = React15.useCallback(() => {
3946
+ const handleDownload = React16.useCallback(() => {
3145
3947
  if (!svgMarkup) return;
3146
3948
  const blob = new Blob([svgMarkup], {
3147
3949
  type: "image/svg+xml;charset=utf-8"
@@ -3155,7 +3957,7 @@ function MermaidBlock({ code }) {
3155
3957
  anchor.remove();
3156
3958
  window.URL.revokeObjectURL(url);
3157
3959
  }, [diagramId, svgMarkup]);
3158
- const handleCopyCode = React15.useCallback(() => {
3960
+ const handleCopyCode = React16.useCallback(() => {
3159
3961
  if (!code || isCopied) return;
3160
3962
  navigator.clipboard.writeText(code).then(() => {
3161
3963
  setIsCopied(true);
@@ -3169,21 +3971,21 @@ function MermaidBlock({ code }) {
3169
3971
  }, [clearCopyResetTimeout, code, isCopied]);
3170
3972
  const hasRenderedDiagram = svgMarkup !== null && !renderError;
3171
3973
  const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
3172
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3173
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3974
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3975
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3174
3976
  Tabs,
3175
3977
  {
3176
3978
  className: "w-full",
3177
3979
  onValueChange: (value) => setActiveTab(value),
3178
3980
  value: activeTab,
3179
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3981
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3180
3982
  "div",
3181
3983
  {
3182
3984
  ref: containerRef,
3183
3985
  "data-slot": "mermaid-block",
3184
3986
  className: "relative overflow-hidden text-card-foreground",
3185
3987
  children: [
3186
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3988
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3187
3989
  "div",
3188
3990
  {
3189
3991
  ref: renderHostRef,
@@ -3192,62 +3994,62 @@ function MermaidBlock({ code }) {
3192
3994
  "data-slot": "mermaid-render-host"
3193
3995
  }
3194
3996
  ),
3195
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3196
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
3197
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.Code2Icon, { className: "size-4" }) }),
3198
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3997
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3998
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
3999
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Code2Icon, { className: "size-4" }) }),
4000
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3199
4001
  ] }),
3200
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
3201
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1", children: [
3202
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4002
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
4003
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1", children: [
4004
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3203
4005
  TooltipIconButton,
3204
4006
  {
3205
4007
  onClick: handleDownload,
3206
4008
  tooltip: t("markdown.mermaid.download"),
3207
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.DownloadIcon, { className: "size-4" })
4009
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.DownloadIcon, { className: "size-4" })
3208
4010
  }
3209
4011
  ) : null,
3210
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4012
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3211
4013
  TooltipIconButton,
3212
4014
  {
3213
4015
  onClick: () => setIsPreviewOpen(true),
3214
4016
  tooltip: t("markdown.mermaid.fullScreen"),
3215
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.ExpandIcon, { className: "size-4" })
4017
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.ExpandIcon, { className: "size-4" })
3216
4018
  }
3217
4019
  ) : null,
3218
- activeTab === "code" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4020
+ activeTab === "code" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3219
4021
  TooltipIconButton,
3220
4022
  {
3221
4023
  onClick: handleCopyCode,
3222
4024
  tooltip: t("markdown.copy"),
3223
- children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CopyIcon, { className: "size-4" })
4025
+ children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CopyIcon, { className: "size-4" })
3224
4026
  }
3225
4027
  ) : null
3226
4028
  ] }),
3227
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(TabsList, { children: [
3228
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
3229
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
4029
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(TabsList, { children: [
4030
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
4031
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
3230
4032
  ] })
3231
4033
  ] })
3232
4034
  ] }),
3233
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "border-t border-border pt-4", children: [
3234
- renderError ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
3235
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4035
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "border-t border-border pt-4", children: [
4036
+ renderError ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
4037
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3236
4038
  "div",
3237
4039
  {
3238
4040
  className: cn(
3239
4041
  "relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
3240
4042
  hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
3241
4043
  ),
3242
- children: hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4044
+ children: hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3243
4045
  "div",
3244
4046
  {
3245
4047
  "data-slot": "mermaid-diagram",
3246
4048
  dangerouslySetInnerHTML: { __html: svgMarkup }
3247
4049
  }
3248
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
3249
- isRendering ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.TriangleAlert, { className: "size-5 text-destructive" }),
3250
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4050
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
4051
+ isRendering ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.TriangleAlert, { className: "size-5 text-destructive" }),
4052
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3251
4053
  "p",
3252
4054
  {
3253
4055
  className: cn("text-sm font-medium", !isRendering && "text-destructive"),
@@ -3258,12 +4060,12 @@ function MermaidBlock({ code }) {
3258
4060
  ] })
3259
4061
  }
3260
4062
  ) }),
3261
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4063
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3262
4064
  "pre",
3263
4065
  {
3264
4066
  "data-slot": "mermaid-code",
3265
4067
  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",
3266
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { className: "block whitespace-pre font-mono", children: code })
4068
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("code", { className: "block whitespace-pre font-mono", children: code })
3267
4069
  }
3268
4070
  ) })
3269
4071
  ] })
@@ -3272,7 +4074,7 @@ function MermaidBlock({ code }) {
3272
4074
  )
3273
4075
  }
3274
4076
  ),
3275
- svgMarkup ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4077
+ svgMarkup ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3276
4078
  MermaidPreviewDialog,
3277
4079
  {
3278
4080
  closeLabel: t("sheet.close"),
@@ -3284,27 +4086,176 @@ function MermaidBlock({ code }) {
3284
4086
  ) : null
3285
4087
  ] });
3286
4088
  }
3287
-
3288
- // src/components/thread/markdown-text.tsx
3289
- var import_katex_min = require("katex/dist/katex.min.css");
3290
- var import_jsx_runtime20 = require("react/jsx-runtime");
3291
- var markdownTableMinWidth = "max(7rem, calc(8rem * var(--density-spacing, 1)))";
3292
- var markdownTableCellPaddingInline = "calc(var(--density-padding, 1rem) * 1.25)";
3293
- var markdownTableCellPaddingBlock = "max(0.5rem, calc(var(--density-padding, 1rem) * 0.75))";
3294
- var markdownTableLineHeight = "max(1.375rem, calc(1.5rem * var(--density-spacing, 1)))";
3295
- var markdownInlineCodePaddingInline = "max(0.25rem, calc(var(--density-gap, 0.5rem) * 0.75))";
3296
- var markdownInlineCodePaddingBlock = "max(0.125rem, calc(var(--density-gap, 0.5rem) * 0.5))";
3297
- var getTextContent = (children) => import_react6.Children.toArray(children).map((child) => {
3298
- if (typeof child === "string" || typeof child === "number") {
3299
- return String(child);
3300
- }
3301
- return "";
3302
- }).join("");
4089
+
4090
+ // src/components/thread/markdown-text.tsx
4091
+ var import_katex_min = require("katex/dist/katex.min.css");
4092
+ var import_jsx_runtime21 = require("react/jsx-runtime");
4093
+ var markdownTableMinWidth = "max(7rem, calc(8rem * var(--density-spacing, 1)))";
4094
+ var markdownTableCellPaddingInline = "calc(var(--density-padding, 1rem) * 1.25)";
4095
+ var markdownTableCellPaddingBlock = "max(0.5rem, calc(var(--density-padding, 1rem) * 0.75))";
4096
+ var markdownTableLineHeight = "max(1.375rem, calc(1.5rem * var(--density-spacing, 1)))";
4097
+ var markdownInlineCodePaddingInline = "max(0.25rem, calc(var(--density-gap, 0.5rem) * 0.75))";
4098
+ var markdownInlineCodePaddingBlock = "max(0.125rem, calc(var(--density-gap, 0.5rem) * 0.5))";
4099
+ var proposedPlanOpenPattern = /^\s*<proposed_plan>\s*$/;
4100
+ var proposedPlanClosePattern = /^\s*<\/proposed_plan>\s*$/;
4101
+ var markdownFencePattern = /^ {0,3}(`{3,}|~{3,})/;
4102
+ var planMarkdownFencePattern = /^\s*(`{3,}|~{3,})[ \t]*(?:markdown|md)[^\n]*\r?\n([\s\S]*?)\r?\n\1[ \t]*\s*$/i;
4103
+ var stripMarkdownNode = (props) => {
4104
+ const elementProps = { ...props };
4105
+ delete elementProps.node;
4106
+ return elementProps;
4107
+ };
4108
+ var getTextContent = (children) => import_react6.Children.toArray(children).map((child) => {
4109
+ if (typeof child === "string" || typeof child === "number") {
4110
+ return String(child);
4111
+ }
4112
+ return "";
4113
+ }).join("");
4114
+ var getFenceMarker = (line) => {
4115
+ const match = markdownFencePattern.exec(line);
4116
+ if (!match) return null;
4117
+ return {
4118
+ char: match[1][0],
4119
+ length: match[1].length
4120
+ };
4121
+ };
4122
+ var updateFenceMarker = (currentFence, line) => {
4123
+ const marker = getFenceMarker(line);
4124
+ if (!marker) return currentFence;
4125
+ if (!currentFence) {
4126
+ return marker;
4127
+ }
4128
+ if (marker.char === currentFence.char && marker.length >= currentFence.length) {
4129
+ return null;
4130
+ }
4131
+ return currentFence;
4132
+ };
4133
+ var normalizePlanMarkdown = (markdown) => {
4134
+ const trimmed = markdown.trim();
4135
+ const match = planMarkdownFencePattern.exec(trimmed);
4136
+ return match ? match[2].trim() : trimmed;
4137
+ };
4138
+ var downloadMarkdown = (markdown) => {
4139
+ if (!markdown) return;
4140
+ const content = markdown.endsWith("\n") ? markdown : `${markdown}
4141
+ `;
4142
+ const blob = new Blob([content], {
4143
+ type: "text/markdown;charset=utf-8"
4144
+ });
4145
+ const url = URL.createObjectURL(blob);
4146
+ const anchor = document.createElement("a");
4147
+ anchor.href = url;
4148
+ anchor.download = "plan.md";
4149
+ document.body.appendChild(anchor);
4150
+ anchor.click();
4151
+ anchor.remove();
4152
+ URL.revokeObjectURL(url);
4153
+ };
4154
+ var splitProposedPlanSegments = (markdown) => {
4155
+ const segments = [];
4156
+ const markdownLines = [];
4157
+ let planLines = null;
4158
+ let fence = null;
4159
+ const flushMarkdown = () => {
4160
+ if (markdownLines.length === 0) return;
4161
+ segments.push({
4162
+ type: "markdown",
4163
+ content: markdownLines.join("\n")
4164
+ });
4165
+ markdownLines.length = 0;
4166
+ };
4167
+ const flushPlan = () => {
4168
+ if (!planLines) return;
4169
+ segments.push({
4170
+ type: "plan",
4171
+ content: planLines.join("\n")
4172
+ });
4173
+ planLines = null;
4174
+ };
4175
+ for (const line of markdown.split(/\r?\n/)) {
4176
+ if (!fence && !planLines && proposedPlanOpenPattern.test(line)) {
4177
+ flushMarkdown();
4178
+ planLines = [];
4179
+ continue;
4180
+ }
4181
+ if (!fence && planLines && proposedPlanClosePattern.test(line)) {
4182
+ flushPlan();
4183
+ continue;
4184
+ }
4185
+ if (planLines) {
4186
+ planLines.push(line);
4187
+ } else {
4188
+ markdownLines.push(line);
4189
+ }
4190
+ fence = updateFenceMarker(fence, line);
4191
+ }
4192
+ flushPlan();
4193
+ flushMarkdown();
4194
+ return segments;
4195
+ };
4196
+ function MarkdownContent({ children }) {
4197
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4198
+ import_react_markdown.default,
4199
+ {
4200
+ remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
4201
+ rehypePlugins: [import_rehype_katex.default],
4202
+ components: defaultComponents,
4203
+ children
4204
+ }
4205
+ );
4206
+ }
4207
+ function PlanCard({ children }) {
4208
+ const { t } = useChatkitTranslation();
4209
+ const planMarkdown = normalizePlanMarkdown(children);
4210
+ const { isCopied, copyToClipboard } = useCopyToClipboard();
4211
+ const onCopy = () => {
4212
+ if (!planMarkdown || isCopied) return;
4213
+ copyToClipboard(planMarkdown);
4214
+ };
4215
+ const onDownload = () => {
4216
+ downloadMarkdown(planMarkdown);
4217
+ };
4218
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4219
+ "section",
4220
+ {
4221
+ "data-slot": "markdown-plan-card",
4222
+ className: cn(
4223
+ "relative my-5 max-w-4xl rounded-lg border border-border bg-muted/25"
4224
+ ),
4225
+ children: [
4226
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "absolute top-3 right-3 flex items-center gap-1", children: [
4227
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4228
+ TooltipIconButton,
4229
+ {
4230
+ tooltip: t("markdown.plan.download"),
4231
+ onClick: onDownload,
4232
+ className: "bg-background/80 text-muted-foreground hover:text-foreground",
4233
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.DownloadIcon, { className: "size-4" })
4234
+ }
4235
+ ),
4236
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4237
+ TooltipIconButton,
4238
+ {
4239
+ tooltip: isCopied ? t("messageActions.copied") : t("markdown.copy"),
4240
+ onClick: onCopy,
4241
+ className: "bg-background/80 text-muted-foreground hover:text-foreground",
4242
+ children: [
4243
+ !isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CopyIcon, { className: "size-4" }),
4244
+ isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CheckIcon, { className: "size-4" })
4245
+ ]
4246
+ }
4247
+ )
4248
+ ] }),
4249
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "w-full max-h-[80vh] py-3 pr-4 pl-4 overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MarkdownContent, { children: planMarkdown }) })
4250
+ ]
4251
+ }
4252
+ );
4253
+ }
3303
4254
  var isMermaidBlockChild = (child) => (0, import_react6.isValidElement)(child) && child.type === MermaidBlock;
3304
4255
  var isMermaidCodeElement = (child) => (0, import_react6.isValidElement)(child) && typeof child.props.className === "string" && child.props.className.includes("language-mermaid");
3305
- var useCopyToClipboard = ({
4256
+ function useCopyToClipboard({
3306
4257
  copiedDuration = 3e3
3307
- } = {}) => {
4258
+ } = {}) {
3308
4259
  const [isCopied, setIsCopied] = (0, import_react6.useState)(false);
3309
4260
  const copyToClipboard = (value) => {
3310
4261
  if (!value) return;
@@ -3314,7 +4265,7 @@ var useCopyToClipboard = ({
3314
4265
  });
3315
4266
  };
3316
4267
  return { isCopied, copyToClipboard };
3317
- };
4268
+ }
3318
4269
  var CodeHeader = ({ language, code }) => {
3319
4270
  const { t } = useChatkitTranslation();
3320
4271
  const { isCopied, copyToClipboard } = useCopyToClipboard();
@@ -3322,87 +4273,80 @@ var CodeHeader = ({ language, code }) => {
3322
4273
  if (!code || isCopied) return;
3323
4274
  copyToClipboard(code);
3324
4275
  };
3325
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("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: [
3326
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "lowercase [&>span]:text-xs", children: language }),
3327
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3328
- TooltipIconButton,
3329
- {
3330
- tooltip: t("markdown.copy"),
3331
- onClick: onCopy,
3332
- children: [
3333
- !isCopied && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CopyIcon, {}),
3334
- isCopied && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CheckIcon, {})
3335
- ]
3336
- }
3337
- )
4276
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("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: [
4277
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "lowercase [&>span]:text-xs", children: language }),
4278
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(TooltipIconButton, { tooltip: t("markdown.copy"), onClick: onCopy, children: [
4279
+ !isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CopyIcon, {}),
4280
+ isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CheckIcon, {})
4281
+ ] })
3338
4282
  ] });
3339
4283
  };
3340
4284
  var defaultComponents = {
3341
- h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4285
+ h1: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3342
4286
  "h1",
3343
4287
  {
3344
4288
  className: cn(
3345
4289
  "mb-8 scroll-m-20 text-4xl font-extrabold tracking-tight last:mb-0",
3346
4290
  className
3347
4291
  ),
3348
- ...props
4292
+ ...stripMarkdownNode(props)
3349
4293
  }
3350
4294
  ),
3351
- h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4295
+ h2: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3352
4296
  "h2",
3353
4297
  {
3354
4298
  className: cn(
3355
4299
  "mt-8 mb-4 scroll-m-20 text-3xl font-semibold tracking-tight first:mt-0 last:mb-0",
3356
4300
  className
3357
4301
  ),
3358
- ...props
4302
+ ...stripMarkdownNode(props)
3359
4303
  }
3360
4304
  ),
3361
- h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4305
+ h3: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3362
4306
  "h3",
3363
4307
  {
3364
4308
  className: cn(
3365
4309
  "mt-6 mb-4 scroll-m-20 text-2xl font-semibold tracking-tight first:mt-0 last:mb-0",
3366
4310
  className
3367
4311
  ),
3368
- ...props
4312
+ ...stripMarkdownNode(props)
3369
4313
  }
3370
4314
  ),
3371
- h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4315
+ h4: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3372
4316
  "h4",
3373
4317
  {
3374
4318
  className: cn(
3375
4319
  "mt-6 mb-4 scroll-m-20 text-xl font-semibold tracking-tight first:mt-0 last:mb-0",
3376
4320
  className
3377
4321
  ),
3378
- ...props
4322
+ ...stripMarkdownNode(props)
3379
4323
  }
3380
4324
  ),
3381
- h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4325
+ h5: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3382
4326
  "h5",
3383
4327
  {
3384
4328
  className: cn(
3385
4329
  "my-4 text-lg font-semibold first:mt-0 last:mb-0",
3386
4330
  className
3387
4331
  ),
3388
- ...props
4332
+ ...stripMarkdownNode(props)
3389
4333
  }
3390
4334
  ),
3391
- h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4335
+ h6: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3392
4336
  "h6",
3393
4337
  {
3394
4338
  className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
3395
- ...props
4339
+ ...stripMarkdownNode(props)
3396
4340
  }
3397
4341
  ),
3398
- p: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4342
+ p: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3399
4343
  "p",
3400
4344
  {
3401
4345
  className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
3402
- ...props
4346
+ ...stripMarkdownNode(props)
3403
4347
  }
3404
4348
  ),
3405
- a: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4349
+ a: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3406
4350
  "a",
3407
4351
  {
3408
4352
  className: cn(
@@ -3411,55 +4355,49 @@ var defaultComponents = {
3411
4355
  ),
3412
4356
  target: "_blank",
3413
4357
  rel: "noopener noreferrer",
3414
- ...props
4358
+ ...stripMarkdownNode(props)
3415
4359
  }
3416
4360
  ),
3417
- blockquote: ({
3418
- className,
3419
- node: _node,
3420
- ...props
3421
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4361
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3422
4362
  "blockquote",
3423
4363
  {
3424
4364
  className: cn(
3425
4365
  "border-l-4 border-border pl-6 italic text-muted-foreground",
3426
4366
  className
3427
4367
  ),
3428
- ...props
4368
+ ...stripMarkdownNode(props)
3429
4369
  }
3430
4370
  ),
3431
- ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4371
+ ul: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3432
4372
  "ul",
3433
4373
  {
3434
4374
  className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
3435
- ...props
4375
+ ...stripMarkdownNode(props)
3436
4376
  }
3437
4377
  ),
3438
- ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4378
+ ol: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3439
4379
  "ol",
3440
4380
  {
3441
- className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
3442
- ...props
4381
+ className: cn(
4382
+ "my-5 list-outside list-decimal pl-8 [&>li]:mt-2",
4383
+ className
4384
+ ),
4385
+ ...stripMarkdownNode(props)
3443
4386
  }
3444
4387
  ),
3445
- hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4388
+ hr: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3446
4389
  "hr",
3447
4390
  {
3448
4391
  className: cn("my-5 border-b", className),
3449
- ...props
4392
+ ...stripMarkdownNode(props)
3450
4393
  }
3451
4394
  ),
3452
- table: ({
3453
- className,
3454
- node: _node,
3455
- style,
3456
- ...props
3457
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4395
+ table: ({ className, style, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3458
4396
  "div",
3459
4397
  {
3460
4398
  "data-slot": "markdown-table-container",
3461
4399
  className: "my-5 max-w-full overflow-x-auto rounded-xl border border-border bg-background",
3462
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4400
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3463
4401
  "table",
3464
4402
  {
3465
4403
  className: cn(
@@ -3470,17 +4408,12 @@ var defaultComponents = {
3470
4408
  lineHeight: markdownTableLineHeight,
3471
4409
  ...style
3472
4410
  },
3473
- ...props
4411
+ ...stripMarkdownNode(props)
3474
4412
  }
3475
4413
  )
3476
4414
  }
3477
4415
  ),
3478
- th: ({
3479
- className,
3480
- node: _node,
3481
- style,
3482
- ...props
3483
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4416
+ th: ({ className, style, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3484
4417
  "th",
3485
4418
  {
3486
4419
  className: cn(
@@ -3493,15 +4426,10 @@ var defaultComponents = {
3493
4426
  paddingBlock: markdownTableCellPaddingBlock,
3494
4427
  ...style
3495
4428
  },
3496
- ...props
4429
+ ...stripMarkdownNode(props)
3497
4430
  }
3498
4431
  ),
3499
- td: ({
3500
- className,
3501
- node: _node,
3502
- style,
3503
- ...props
3504
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4432
+ td: ({ className, style, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3505
4433
  "td",
3506
4434
  {
3507
4435
  className: cn(
@@ -3514,27 +4442,27 @@ var defaultComponents = {
3514
4442
  paddingBlock: markdownTableCellPaddingBlock,
3515
4443
  ...style
3516
4444
  },
3517
- ...props
4445
+ ...stripMarkdownNode(props)
3518
4446
  }
3519
4447
  ),
3520
- tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4448
+ tr: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3521
4449
  "tr",
3522
4450
  {
3523
4451
  className: cn(
3524
4452
  "m-0 p-0 even:bg-muted/30 [&:last-child>td:first-child]:rounded-bl-xl [&:last-child>td:last-child]:rounded-br-xl",
3525
4453
  className
3526
4454
  ),
3527
- ...props
4455
+ ...stripMarkdownNode(props)
3528
4456
  }
3529
4457
  ),
3530
- sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4458
+ sup: ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3531
4459
  "sup",
3532
4460
  {
3533
4461
  className: cn("[&>a]:text-xs [&>a]:no-underline", className),
3534
- ...props
4462
+ ...stripMarkdownNode(props)
3535
4463
  }
3536
4464
  ),
3537
- pre: ({ className, children, node: _node }) => import_react6.Children.toArray(children).length === 1 && (isMermaidBlockChild(import_react6.Children.toArray(children)[0]) || isMermaidCodeElement(import_react6.Children.toArray(children)[0])) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_jsx_runtime20.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4465
+ pre: ({ className, children }) => import_react6.Children.toArray(children).length === 1 && (isMermaidBlockChild(import_react6.Children.toArray(children)[0]) || isMermaidCodeElement(import_react6.Children.toArray(children)[0])) ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3538
4466
  "div",
3539
4467
  {
3540
4468
  className: cn(
@@ -3547,7 +4475,6 @@ var defaultComponents = {
3547
4475
  code: ({
3548
4476
  className,
3549
4477
  children,
3550
- node: _node,
3551
4478
  style,
3552
4479
  ...props
3553
4480
  }) => {
@@ -3558,84 +4485,872 @@ var defaultComponents = {
3558
4485
  const language = match[1];
3559
4486
  const normalizedCode = code.replace(/\n$/, "");
3560
4487
  if (language === "mermaid") {
3561
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(MermaidBlock, { code: normalizedCode });
4488
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MermaidBlock, { code: normalizedCode });
3562
4489
  }
3563
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3564
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3565
- CodeHeader,
3566
- {
3567
- language,
3568
- code: normalizedCode
3569
- }
3570
- ),
3571
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3572
- SyntaxHighlighter,
3573
- {
3574
- language,
3575
- className,
3576
- children: normalizedCode
3577
- }
3578
- )
4490
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4491
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CodeHeader, { language, code: normalizedCode }),
4492
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SyntaxHighlighter, { language, className, children: normalizedCode })
3579
4493
  ] });
3580
4494
  }
3581
4495
  if (isBlockCode) {
3582
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4496
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3583
4497
  "code",
3584
4498
  {
3585
4499
  className: cn(
3586
4500
  "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
3587
4501
  className
3588
4502
  ),
3589
- ...props,
3590
- children: code.replace(/\n$/, "")
3591
- }
3592
- );
4503
+ ...stripMarkdownNode(props),
4504
+ children: code.replace(/\n$/, "")
4505
+ }
4506
+ );
4507
+ }
4508
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4509
+ "code",
4510
+ {
4511
+ className: cn(
4512
+ "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
4513
+ className
4514
+ ),
4515
+ style: {
4516
+ paddingInline: markdownInlineCodePaddingInline,
4517
+ paddingBlock: markdownInlineCodePaddingBlock,
4518
+ ...style
4519
+ },
4520
+ ...stripMarkdownNode(props),
4521
+ children
4522
+ }
4523
+ );
4524
+ }
4525
+ };
4526
+ var MarkdownTextImpl = ({ children }) => {
4527
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "markdown-content", children: splitProposedPlanSegments(children).map(
4528
+ (segment, index) => segment.type === "plan" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PlanCard, { children: segment.content }, index) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MarkdownContent, { children: segment.content }, index)
4529
+ ) });
4530
+ };
4531
+ var MarkdownText = (0, import_react6.memo)(MarkdownTextImpl);
4532
+
4533
+ // src/components/thread/messages/tool-component-group.tsx
4534
+ var React17 = __toESM(require("react"), 1);
4535
+ var import_lucide_react10 = require("lucide-react");
4536
+
4537
+ // src/i18n/localized-text.ts
4538
+ function resolveLocalizedText(value, language) {
4539
+ if (typeof value === "string") {
4540
+ const trimmed = value.trim();
4541
+ return trimmed || null;
4542
+ }
4543
+ if (!value || typeof value !== "object") return null;
4544
+ const localized = value;
4545
+ const normalizedLanguage = language.trim();
4546
+ const underscoredLanguage = normalizedLanguage.replace(/-/g, "_");
4547
+ const languagePrefix = normalizedLanguage.split("-")[0];
4548
+ const preferredKeys = normalizedLanguage.startsWith("zh") ? [
4549
+ normalizedLanguage,
4550
+ underscoredLanguage,
4551
+ "zh_Hans",
4552
+ "zh-Hans",
4553
+ "zh_CN",
4554
+ "zh-CN",
4555
+ "zh",
4556
+ "en_US",
4557
+ "en-US",
4558
+ "en"
4559
+ ] : [
4560
+ normalizedLanguage,
4561
+ underscoredLanguage,
4562
+ "en_US",
4563
+ "en-US",
4564
+ "en",
4565
+ languagePrefix,
4566
+ "zh_Hans",
4567
+ "zh-Hans",
4568
+ "zh_CN",
4569
+ "zh-CN",
4570
+ "zh"
4571
+ ];
4572
+ for (const key of preferredKeys) {
4573
+ const candidate = localized[key];
4574
+ if (typeof candidate === "string" && candidate.trim()) {
4575
+ return candidate.trim();
4576
+ }
4577
+ }
4578
+ for (const candidate of Object.values(localized)) {
4579
+ if (typeof candidate === "string" && candidate.trim()) {
4580
+ return candidate.trim();
4581
+ }
4582
+ }
4583
+ return null;
4584
+ }
4585
+
4586
+ // src/components/thread/messages/tool-component-group.tsx
4587
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4588
+ var toolStatusConfig = {
4589
+ success: {
4590
+ iconClass: "border-green-500 text-green-700",
4591
+ icon: import_lucide_react10.CheckCircle2
4592
+ },
4593
+ fail: {
4594
+ iconClass: "border-red-500 text-red-700",
4595
+ icon: import_lucide_react10.XCircle
4596
+ },
4597
+ running: {
4598
+ iconClass: "border-blue-500 text-blue-700",
4599
+ icon: import_lucide_react10.Loader2
4600
+ }
4601
+ };
4602
+ var TOOL_GROUP_CATEGORY_ORDER = [
4603
+ "files",
4604
+ "searches",
4605
+ "commands",
4606
+ "lists",
4607
+ "tasks",
4608
+ "knowledges",
4609
+ "tools"
4610
+ ];
4611
+ var TOOL_GROUP_TOKEN_CATEGORY = {
4612
+ file: "files",
4613
+ files: "files",
4614
+ web_search: "searches",
4615
+ search: "searches",
4616
+ searches: "searches",
4617
+ program: "commands",
4618
+ command: "commands",
4619
+ commands: "commands",
4620
+ shell: "commands",
4621
+ terminal: "commands",
4622
+ list: "lists",
4623
+ lists: "lists",
4624
+ task: "tasks",
4625
+ tasks: "tasks",
4626
+ todo: "tasks",
4627
+ todos: "tasks",
4628
+ knowledge: "knowledges",
4629
+ knowledges: "knowledges",
4630
+ retriever: "knowledges",
4631
+ retrieval: "knowledges",
4632
+ tool: "tools",
4633
+ tools: "tools"
4634
+ };
4635
+ var TOOL_CALL_OUTPUT_RENDERERS = {};
4636
+ function getToolStepData(content) {
4637
+ return content.data ?? {};
4638
+ }
4639
+ function safeJson(value) {
4640
+ try {
4641
+ return JSON.stringify(value, null, 2) ?? String(value);
4642
+ } catch {
4643
+ return String(value);
4644
+ }
4645
+ }
4646
+ function formatDisplayValue(value) {
4647
+ return typeof value === "string" ? value : safeJson(value);
4648
+ }
4649
+ function parseStepDate(value) {
4650
+ if (value instanceof Date) {
4651
+ const timestamp2 = value.getTime();
4652
+ return Number.isNaN(timestamp2) ? null : timestamp2;
4653
+ }
4654
+ if (typeof value !== "string") {
4655
+ return null;
4656
+ }
4657
+ const timestamp = Date.parse(value);
4658
+ return Number.isNaN(timestamp) ? null : timestamp;
4659
+ }
4660
+ function formatStepDuration(durationMs) {
4661
+ if (durationMs < 1e3) {
4662
+ return `${durationMs}ms`;
4663
+ }
4664
+ if (durationMs < 1e4) {
4665
+ return `${(durationMs / 1e3).toFixed(1)}s`;
4666
+ }
4667
+ if (durationMs < 6e4) {
4668
+ return `${Math.round(durationMs / 1e3)}s`;
4669
+ }
4670
+ const hours = Math.floor(durationMs / 36e5);
4671
+ const minutes = Math.floor(durationMs % 36e5 / 6e4);
4672
+ const seconds = Math.floor(durationMs % 6e4 / 1e3);
4673
+ if (hours > 0) {
4674
+ return `${hours}h ${minutes}m ${seconds}s`;
4675
+ }
4676
+ return `${minutes}m ${seconds}s`;
4677
+ }
4678
+ function useToolStepDurationLabel(data) {
4679
+ const [durationNow, setDurationNow] = React17.useState(() => Date.now());
4680
+ const createdAt = parseStepDate(data.created_date);
4681
+ const endedAt = parseStepDate(data.end_date);
4682
+ const status = data.status;
4683
+ React17.useEffect(() => {
4684
+ if (status !== "running" || createdAt === null || endedAt !== null) {
4685
+ return;
4686
+ }
4687
+ setDurationNow(Date.now());
4688
+ const timer = window.setInterval(() => {
4689
+ setDurationNow(Date.now());
4690
+ }, 100);
4691
+ return () => {
4692
+ window.clearInterval(timer);
4693
+ };
4694
+ }, [createdAt, endedAt, status]);
4695
+ if (createdAt === null) return null;
4696
+ const durationMs = Math.max(0, (endedAt ?? durationNow) - createdAt);
4697
+ return formatStepDuration(durationMs);
4698
+ }
4699
+ function isJsonObjectValue(value) {
4700
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4701
+ }
4702
+ function canUseAsJsonValue(value) {
4703
+ if (value === null) return true;
4704
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
4705
+ return true;
4706
+ }
4707
+ if (Array.isArray(value)) {
4708
+ return value.every(canUseAsJsonValue);
4709
+ }
4710
+ if (typeof value === "object") {
4711
+ return Object.values(value).every(canUseAsJsonValue);
4712
+ }
4713
+ return false;
4714
+ }
4715
+ function parseJsonString(value) {
4716
+ const trimmed = value.trim();
4717
+ if (!trimmed) return null;
4718
+ const first = trimmed[0];
4719
+ if (first !== "{" && first !== "[") return null;
4720
+ try {
4721
+ const parsed = JSON.parse(trimmed);
4722
+ return canUseAsJsonValue(parsed) ? parsed : null;
4723
+ } catch {
4724
+ return null;
4725
+ }
4726
+ }
4727
+ function detectJsonValue(value) {
4728
+ if (typeof value === "string") {
4729
+ const parsed = parseJsonString(value);
4730
+ if (parsed !== null) {
4731
+ return {
4732
+ kind: "json",
4733
+ value: parsed,
4734
+ raw: safeJson(parsed)
4735
+ };
4736
+ }
4737
+ return { kind: "text", text: value };
4738
+ }
4739
+ if (canUseAsJsonValue(value) && value !== null && typeof value === "object") {
4740
+ return {
4741
+ kind: "json",
4742
+ value,
4743
+ raw: safeJson(value)
4744
+ };
4745
+ }
4746
+ return { kind: "text", text: formatDisplayValue(value) };
4747
+ }
4748
+ function isComponentContent(content) {
4749
+ return content.type === "component";
4750
+ }
4751
+ function isTextContent(content) {
4752
+ return content.type === "text";
4753
+ }
4754
+ function isReasoningContent(content) {
4755
+ return content.type === "reasoning";
4756
+ }
4757
+ function isWidgetComponent(content) {
4758
+ const data = content.data;
4759
+ return data?.type === "Widget" && Array.isArray(data.widgets);
4760
+ }
4761
+ function isGroupableToolComponent(content) {
4762
+ if (!content || typeof content === "string") return false;
4763
+ return isComponentContent(content) && !isWidgetComponent(content) && content.data?.category === "Tool";
4764
+ }
4765
+ function isSkippableToolGroupSeparator(content) {
4766
+ if (typeof content === "string") return !content.trim();
4767
+ if (!content) return true;
4768
+ if (isTextContent(content)) {
4769
+ return !content.text?.trim();
4770
+ }
4771
+ if (isReasoningContent(content)) {
4772
+ return !content.text?.trim();
4773
+ }
4774
+ return false;
4775
+ }
4776
+ function normalizeToolToken(value) {
4777
+ if (typeof value !== "string") return null;
4778
+ const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
4779
+ return normalized || null;
4780
+ }
4781
+ function classifyToolToken(value) {
4782
+ const normalized = normalizeToolToken(
4783
+ typeof value === "string" ? value : resolveLocalizedText(value, "en-US")
4784
+ );
4785
+ if (!normalized) return null;
4786
+ const directMatch = TOOL_GROUP_TOKEN_CATEGORY[normalized];
4787
+ if (directMatch) return directMatch;
4788
+ if (normalized.includes("search")) return "searches";
4789
+ if (normalized.includes("file")) return "files";
4790
+ if (normalized.includes("command") || normalized.includes("cmd") || normalized.includes("program") || normalized.includes("exec") || normalized.startsWith("run_") || normalized.includes("_run")) {
4791
+ return "commands";
4792
+ }
4793
+ if (normalized.includes("list")) return "lists";
4794
+ if (normalized.includes("task") || normalized.includes("todo")) return "tasks";
4795
+ if (normalized.includes("knowledge") || normalized.includes("retriever")) {
4796
+ return "knowledges";
4797
+ }
4798
+ return null;
4799
+ }
4800
+ function getToolGroupCategory(content) {
4801
+ const data = getToolStepData(content);
4802
+ return classifyToolToken(data.type) ?? classifyToolToken(data.tool) ?? classifyToolToken(data.title) ?? classifyToolToken(data.message) ?? "tools";
4803
+ }
4804
+ function getToolGroupCategoryCounts(items) {
4805
+ return items.reduce((counts, item) => {
4806
+ const category = getToolGroupCategory(item);
4807
+ counts[category] = (counts[category] ?? 0) + 1;
4808
+ return counts;
4809
+ }, {});
4810
+ }
4811
+ function getToolGroupDisplayStatus(items) {
4812
+ if (items.some((item) => getToolStepData(item).status === "fail")) {
4813
+ return "fail";
4814
+ }
4815
+ return "success";
4816
+ }
4817
+ function getToolActivityLabel(content, language) {
4818
+ const data = getToolStepData(content);
4819
+ const runningCandidates = [data.message, data.title, data.tool, data.type];
4820
+ const completedCandidates = [data.title, data.message, data.tool, data.type];
4821
+ const candidates = data.status === "running" ? runningCandidates : completedCandidates;
4822
+ for (const candidate of candidates) {
4823
+ const label = resolveLocalizedText(candidate, language);
4824
+ if (label) return label;
4825
+ }
4826
+ return "Tool";
4827
+ }
4828
+ function flushPendingTools(units, pendingTools) {
4829
+ if (pendingTools.length === 0) return;
4830
+ units.push({
4831
+ type: "tool-group",
4832
+ items: pendingTools.map((tool) => tool.item),
4833
+ startIndex: pendingTools[0].index
4834
+ });
4835
+ pendingTools.length = 0;
4836
+ }
4837
+ function buildToolComponentRenderUnits(content, options) {
4838
+ const units = [];
4839
+ const pendingTools = [];
4840
+ content.forEach((item, index) => {
4841
+ if (isGroupableToolComponent(item) && options?.shouldGroupComponent?.(item) !== false) {
4842
+ pendingTools.push({ item, index });
4843
+ return;
4844
+ }
4845
+ if (isSkippableToolGroupSeparator(item)) {
4846
+ return;
4847
+ }
4848
+ if (item === void 0) {
4849
+ return;
4850
+ }
4851
+ flushPendingTools(units, pendingTools);
4852
+ units.push({ type: "item", item, index });
4853
+ });
4854
+ flushPendingTools(units, pendingTools);
4855
+ return units;
4856
+ }
4857
+ function getToolCallOutputRenderer(data) {
4858
+ const keys = [data.tool, data.type].filter(
4859
+ (value) => typeof value === "string" && Boolean(value.trim())
4860
+ );
4861
+ for (const key of keys) {
4862
+ const renderer = TOOL_CALL_OUTPUT_RENDERERS[key];
4863
+ if (renderer) return renderer;
4864
+ }
4865
+ return DefaultToolCallOutput;
4866
+ }
4867
+ function getJsonValueSummary(value) {
4868
+ if (Array.isArray(value)) {
4869
+ return `Array(${value.length})`;
4870
+ }
4871
+ if (isJsonObjectValue(value)) {
4872
+ return `Object(${Object.keys(value).length})`;
4873
+ }
4874
+ return "JSON";
4875
+ }
4876
+ function formatJsonPrimitive(value) {
4877
+ if (value === null) return "null";
4878
+ if (typeof value === "string") return JSON.stringify(value);
4879
+ return String(value);
4880
+ }
4881
+ function JsonTreeNode({
4882
+ label,
4883
+ value,
4884
+ depth = 0
4885
+ }) {
4886
+ const isArray = Array.isArray(value);
4887
+ const isObject = isJsonObjectValue(value);
4888
+ const isExpandable = isArray || isObject;
4889
+ const [isExpanded, setIsExpanded] = React17.useState(depth < 2);
4890
+ if (!isExpandable) {
4891
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 gap-2 leading-6", children: [
4892
+ label ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "shrink-0 font-medium text-foreground/80", children: [
4893
+ label,
4894
+ ":"
4895
+ ] }) : null,
4896
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4897
+ "span",
4898
+ {
4899
+ className: cn(
4900
+ "min-w-0 wrap-break-word",
4901
+ typeof value === "string" ? "text-emerald-700" : typeof value === "number" ? "text-blue-700" : typeof value === "boolean" ? "text-purple-700" : "text-muted-foreground"
4902
+ ),
4903
+ children: formatJsonPrimitive(value)
4904
+ }
4905
+ )
4906
+ ] });
4907
+ }
4908
+ const entries = isArray ? value.map((item, index) => [String(index), item]) : Object.entries(value);
4909
+ const summary = isArray ? `Array(${value.length})` : `Object(${entries.length})`;
4910
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "min-w-0", children: [
4911
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4912
+ "button",
4913
+ {
4914
+ type: "button",
4915
+ className: "flex min-w-0 items-center gap-1 leading-6 text-left hover:text-foreground",
4916
+ "aria-expanded": isExpanded,
4917
+ onClick: () => setIsExpanded((prev) => !prev),
4918
+ children: [
4919
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4920
+ import_lucide_react10.ChevronRight,
4921
+ {
4922
+ "aria-hidden": "true",
4923
+ className: cn(
4924
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
4925
+ isExpanded && "rotate-90"
4926
+ )
4927
+ }
4928
+ ),
4929
+ label ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "min-w-0 truncate font-medium text-foreground/80", children: [
4930
+ label,
4931
+ ":"
4932
+ ] }) : null,
4933
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-muted-foreground", children: summary })
4934
+ ]
4935
+ }
4936
+ ),
4937
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ml-4 border-l border-border/70 pl-3", children: entries.map(([entryLabel, entryValue]) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4938
+ JsonTreeNode,
4939
+ {
4940
+ label: entryLabel,
4941
+ value: entryValue,
4942
+ depth: depth + 1
4943
+ },
4944
+ entryLabel
4945
+ )) }) : null
4946
+ ] });
4947
+ }
4948
+ function JsonTreeView({ value }) {
4949
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "min-w-0 font-mono text-[11px]", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(JsonTreeNode, { value }) });
4950
+ }
4951
+ function RawJsonBlock({ raw }) {
4952
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word font-mono text-[11px]", children: raw });
4953
+ }
4954
+ function PlainTextBlock({ value, destructive = false }) {
4955
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4956
+ "pre",
4957
+ {
4958
+ className: cn(
4959
+ "whitespace-pre-wrap wrap-break-word",
4960
+ destructive && "text-destructive"
4961
+ ),
4962
+ children: value
3593
4963
  }
3594
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3595
- "code",
4964
+ );
4965
+ }
4966
+ function ToolCallCopyButton({ value }) {
4967
+ const { t } = useChatkitTranslation();
4968
+ const [isCopied, setIsCopied] = React17.useState(false);
4969
+ const resetTimeoutRef = React17.useRef(null);
4970
+ const clearResetTimeout = React17.useCallback(() => {
4971
+ if (resetTimeoutRef.current === null) return;
4972
+ window.clearTimeout(resetTimeoutRef.current);
4973
+ resetTimeoutRef.current = null;
4974
+ }, []);
4975
+ React17.useEffect(() => clearResetTimeout, [clearResetTimeout]);
4976
+ const handleCopy = React17.useCallback(() => {
4977
+ if (typeof navigator === "undefined" || !navigator.clipboard) return;
4978
+ void navigator.clipboard.writeText(value).then(() => {
4979
+ setIsCopied(true);
4980
+ clearResetTimeout();
4981
+ resetTimeoutRef.current = window.setTimeout(() => {
4982
+ setIsCopied(false);
4983
+ resetTimeoutRef.current = null;
4984
+ }, 1500);
4985
+ }).catch(() => void 0);
4986
+ }, [clearResetTimeout, value]);
4987
+ const label = isCopied ? t("message.toolGroup.copied") : t("message.toolGroup.copy");
4988
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4989
+ "button",
4990
+ {
4991
+ type: "button",
4992
+ 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",
4993
+ "aria-label": label,
4994
+ title: label,
4995
+ onClick: handleCopy,
4996
+ children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Check, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Copy, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
4997
+ }
4998
+ );
4999
+ }
5000
+ function ToolCallValueBlock({
5001
+ value,
5002
+ destructive = false
5003
+ }) {
5004
+ const { t } = useChatkitTranslation();
5005
+ const detected = detectJsonValue(value);
5006
+ if (detected.kind === "text") {
5007
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "min-w-0 space-y-1", children: [
5008
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallCopyButton, { value: detected.text }) }),
5009
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PlainTextBlock, { value: detected.text, destructive })
5010
+ ] });
5011
+ }
5012
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tabs, { defaultValue: "tree", className: "min-w-0", children: [
5013
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mb-2 flex min-w-0 items-center justify-between gap-2", children: [
5014
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "min-w-0 truncate text-[11px] text-muted-foreground", children: [
5015
+ t("message.toolGroup.jsonTitle"),
5016
+ " \xB7 ",
5017
+ getJsonValueSummary(detected.value)
5018
+ ] }),
5019
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex shrink-0 items-center gap-1", children: [
5020
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallCopyButton, { value: detected.raw }),
5021
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(TabsList, { className: "rounded-md p-0.5", children: [
5022
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "tree", children: t("message.toolGroup.jsonTree") }),
5023
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "raw", children: t("message.toolGroup.jsonRaw") })
5024
+ ] })
5025
+ ] })
5026
+ ] }),
5027
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "tree", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(JsonTreeView, { value: detected.value }) }),
5028
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "raw", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RawJsonBlock, { raw: detected.raw }) })
5029
+ ] });
5030
+ }
5031
+ function DefaultToolCallOutput({ data }) {
5032
+ const { t } = useChatkitTranslation();
5033
+ const output = data.output ?? null;
5034
+ const error = data.error ?? null;
5035
+ if (error) {
5036
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
5037
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-destructive", children: t("message.toolGroup.errorTitle") }),
5038
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: error, destructive: true })
5039
+ ] });
5040
+ }
5041
+ if (output === null) return null;
5042
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
5043
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.outputTitle") }),
5044
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: output })
5045
+ ] });
5046
+ }
5047
+ function ToolCallDetails({ content }) {
5048
+ const { t } = useChatkitTranslation();
5049
+ const data = getToolStepData(content);
5050
+ const OutputRenderer = getToolCallOutputRenderer(data);
5051
+ const hasInput = data.input !== void 0 && data.input !== null;
5052
+ const hasOutput = data.error !== void 0 || data.output !== void 0;
5053
+ if (!hasInput && !hasOutput) return null;
5054
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("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: [
5055
+ hasInput && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
5056
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.inputTitle") }),
5057
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: data.input })
5058
+ ] }),
5059
+ hasInput && hasOutput ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "h-2" }) : null,
5060
+ hasOutput ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(OutputRenderer, { content, data }) : null
5061
+ ] });
5062
+ }
5063
+ function ToolCallRow({ content }) {
5064
+ const { i18n: i18n2 } = useChatkitTranslation();
5065
+ const data = getToolStepData(content);
5066
+ const status = data.status;
5067
+ const itemConfig = status ? toolStatusConfig[status] : null;
5068
+ const ItemStatusIcon = itemConfig?.icon;
5069
+ const hasError = status === "fail" || Boolean(data.error);
5070
+ const label = getToolActivityLabel(content, i18n2.language);
5071
+ const detailsId = React17.useId();
5072
+ const hasDetails = data.input !== void 0 || data.error !== void 0 || data.output !== void 0;
5073
+ const durationLabel = useToolStepDurationLabel(data);
5074
+ const [isExpanded, setIsExpanded] = React17.useState(false);
5075
+ React17.useEffect(() => {
5076
+ if (status === "running" && data.output !== void 0) {
5077
+ setIsExpanded(true);
5078
+ }
5079
+ }, [data.output, status]);
5080
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: "min-w-0", children: [
5081
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5082
+ "button",
3596
5083
  {
5084
+ type: "button",
3597
5085
  className: cn(
3598
- "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
3599
- className
5086
+ "flex w-full min-w-0 items-center gap-2 text-left text-sm leading-6 text-muted-foreground",
5087
+ hasDetails && "cursor-pointer hover:text-foreground",
5088
+ hasError && "text-destructive hover:text-destructive"
3600
5089
  ),
3601
- style: {
3602
- paddingInline: markdownInlineCodePaddingInline,
3603
- paddingBlock: markdownInlineCodePaddingBlock,
3604
- ...style
5090
+ "aria-expanded": hasDetails ? isExpanded : void 0,
5091
+ "aria-controls": hasDetails ? detailsId : void 0,
5092
+ disabled: !hasDetails,
5093
+ onClick: () => {
5094
+ if (hasDetails) setIsExpanded((prev) => !prev);
3605
5095
  },
3606
- ...props,
3607
- children
5096
+ children: [
5097
+ ItemStatusIcon ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5098
+ ItemStatusIcon,
5099
+ {
5100
+ className: cn(
5101
+ "h-3.5 w-3.5 shrink-0",
5102
+ itemConfig?.iconClass,
5103
+ status === "running" && "animate-spin"
5104
+ )
5105
+ }
5106
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
5107
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "min-w-0 flex-1 truncate", title: label, children: label }),
5108
+ durationLabel ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground/80", children: durationLabel }) : null,
5109
+ hasDetails ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5110
+ import_lucide_react10.ChevronRight,
5111
+ {
5112
+ "aria-hidden": "true",
5113
+ className: cn(
5114
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
5115
+ isExpanded && "rotate-90"
5116
+ )
5117
+ }
5118
+ ) : null
5119
+ ]
5120
+ }
5121
+ ),
5122
+ hasDetails && isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { id: detailsId, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallDetails, { content }) }) : null
5123
+ ] });
5124
+ }
5125
+ function ToolComponentGroup({
5126
+ items,
5127
+ hasFollowingItem
5128
+ }) {
5129
+ const { t } = useChatkitTranslation();
5130
+ const contentId = React17.useId();
5131
+ const groupStatus = getToolGroupDisplayStatus(items);
5132
+ const [isExpanded, setIsExpanded] = React17.useState(!hasFollowingItem);
5133
+ const categoryCounts = getToolGroupCategoryCounts(items);
5134
+ const categorySummary = TOOL_GROUP_CATEGORY_ORDER.flatMap((category) => {
5135
+ const count = categoryCounts[category] ?? 0;
5136
+ if (count === 0) return [];
5137
+ return [
5138
+ t(
5139
+ `message.toolGroup.categories.${category}.${count === 1 ? "one" : "other"}`,
5140
+ { count }
5141
+ )
5142
+ ];
5143
+ }).join(t("message.toolGroup.separator"));
5144
+ const summary = `${t(`message.toolGroup.status.${groupStatus}`)} ${categorySummary}`;
5145
+ const config = toolStatusConfig[groupStatus];
5146
+ const StatusIcon = config.icon;
5147
+ React17.useEffect(() => {
5148
+ setIsExpanded(!hasFollowingItem);
5149
+ }, [hasFollowingItem, items.length]);
5150
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "px-1 py-1", children: [
5151
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5152
+ "button",
5153
+ {
5154
+ type: "button",
5155
+ 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",
5156
+ "aria-expanded": isExpanded,
5157
+ "aria-controls": contentId,
5158
+ onClick: () => setIsExpanded((prev) => !prev),
5159
+ children: [
5160
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
5161
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5162
+ StatusIcon,
5163
+ {
5164
+ className: cn(
5165
+ "h-4 w-4 shrink-0",
5166
+ config.iconClass
5167
+ )
5168
+ }
5169
+ ),
5170
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: summary })
5171
+ ] }),
5172
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5173
+ import_lucide_react10.ChevronRight,
5174
+ {
5175
+ "aria-hidden": "true",
5176
+ className: cn(
5177
+ "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
5178
+ isExpanded && "rotate-90"
5179
+ )
5180
+ }
5181
+ )
5182
+ ]
3608
5183
  }
5184
+ ),
5185
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { id: contentId, className: "mt-2 max-h-[200px] space-y-1.5 overflow-y-auto pr-1", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallRow, { content: item }, item.id ?? `tool-item-${index}`)) })
5186
+ ] });
5187
+ }
5188
+
5189
+ // src/components/thread/messages/request-user-input-result-card.tsx
5190
+ var React18 = require("react");
5191
+ var import_chatkit_types4 = require("@xpert-ai/chatkit-types");
5192
+ var import_lucide_react11 = require("lucide-react");
5193
+ var import_jsx_runtime23 = require("react/jsx-runtime");
5194
+ function isRecord2(value) {
5195
+ return !!value && typeof value === "object" && !Array.isArray(value);
5196
+ }
5197
+ function readString(record, keys) {
5198
+ for (const key of keys) {
5199
+ const value = record[key];
5200
+ if (typeof value === "string" && value.trim()) {
5201
+ return value.trim();
5202
+ }
5203
+ }
5204
+ return null;
5205
+ }
5206
+ function getToolCallId(value) {
5207
+ if (!isRecord2(value)) return null;
5208
+ return readString(value, ["id"]);
5209
+ }
5210
+ function getToolCallName(value) {
5211
+ if (!isRecord2(value)) return null;
5212
+ return readString(value, ["name"]);
5213
+ }
5214
+ function pushClientToolCallsFromRecord(record, calls) {
5215
+ const clientToolCalls = record.clientToolCalls;
5216
+ if (Array.isArray(clientToolCalls)) {
5217
+ calls.push(...clientToolCalls);
5218
+ }
5219
+ }
5220
+ function collectPotentialToolCalls(messages) {
5221
+ const calls = [];
5222
+ const messageList = Array.isArray(messages) ? messages : [messages];
5223
+ for (const message of messageList) {
5224
+ const rawMessage = message;
5225
+ pushClientToolCallsFromRecord(rawMessage, calls);
5226
+ }
5227
+ return calls;
5228
+ }
5229
+ function findRequestUserInputClientToolCallById(messages, id) {
5230
+ if (!id) return null;
5231
+ return collectPotentialToolCalls(messages).find(
5232
+ (call) => getToolCallId(call) === id && getToolCallName(call) === import_chatkit_types4.REQUEST_USER_INPUT_TOOL_NAME
5233
+ ) ?? null;
5234
+ }
5235
+ function normalizeAnswer(value) {
5236
+ if (!isRecord2(value)) return null;
5237
+ const id = readString(value, ["id"]);
5238
+ const question = readString(value, ["question"]);
5239
+ const answerValue = readString(value, ["value"]);
5240
+ const type = readString(value, ["type"]);
5241
+ if (!id || !question || !answerValue || type !== "option" && type !== "other") {
5242
+ return null;
5243
+ }
5244
+ const label = readString(value, ["label"]);
5245
+ const description = readString(value, ["description"]);
5246
+ return {
5247
+ id,
5248
+ question,
5249
+ value: answerValue,
5250
+ type,
5251
+ ...label ? { label } : {},
5252
+ ...description ? { description } : {}
5253
+ };
5254
+ }
5255
+ function parseResultOutput(output) {
5256
+ let result = output;
5257
+ if (typeof output === "string") {
5258
+ try {
5259
+ result = JSON.parse(output);
5260
+ } catch {
5261
+ return null;
5262
+ }
5263
+ }
5264
+ if (!isRecord2(result) || !Array.isArray(result.answers)) {
5265
+ return null;
5266
+ }
5267
+ const hasExplicitType = result.type === import_chatkit_types4.REQUEST_USER_INPUT_RESULT_TYPE;
5268
+ const answers = result.answers.map(normalizeAnswer);
5269
+ if (answers.some((answer) => answer === null)) {
5270
+ return null;
5271
+ }
5272
+ return {
5273
+ answers,
5274
+ hasExplicitType
5275
+ };
5276
+ }
5277
+ function getRequestUserInputResultCardData(content, messages) {
5278
+ const data = isRecord2(content.data) ? content.data : null;
5279
+ if (data?.status !== "success") {
5280
+ return null;
5281
+ }
5282
+ const result = parseResultOutput(data.output);
5283
+ if (!result || result.answers.length === 0) {
5284
+ return null;
5285
+ }
5286
+ if (!result.hasExplicitType) {
5287
+ const toolCall = findRequestUserInputClientToolCallById(
5288
+ messages,
5289
+ content.id
3609
5290
  );
5291
+ if (!toolCall) {
5292
+ return null;
5293
+ }
3610
5294
  }
3611
- };
3612
- var MarkdownTextImpl = ({ children }) => {
3613
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "markdown-content", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3614
- import_react_markdown.default,
5295
+ return {
5296
+ toolCallId: content.id,
5297
+ answers: result.answers
5298
+ };
5299
+ }
5300
+ function RequestUserInputResultCard({
5301
+ result,
5302
+ className
5303
+ }) {
5304
+ const { t } = useChatkitTranslation();
5305
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5306
+ "section",
3615
5307
  {
3616
- remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
3617
- rehypePlugins: [import_rehype_katex.default],
3618
- components: defaultComponents,
3619
- children
5308
+ "aria-label": t("message.requestUserInputResult.title"),
5309
+ className: cn(
5310
+ "rounded-lg border border-border bg-muted/25 px-3 py-2.5",
5311
+ className
5312
+ ),
5313
+ children: [
5314
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "mb-2 flex items-center gap-2 text-sm font-semibold text-foreground", children: [
5315
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.CheckCircle2, { className: "h-4 w-4 text-primary" }),
5316
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: t("message.requestUserInputResult.title") })
5317
+ ] }),
5318
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: result.answers.map((answer, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5319
+ "div",
5320
+ {
5321
+ className: "rounded-md bg-background/70 px-2.5 py-2",
5322
+ children: [
5323
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-xs font-medium leading-5 text-muted-foreground", children: answer.question }),
5324
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "mt-0.5 flex min-w-0 flex-wrap items-center gap-1.5", children: [
5325
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "min-w-0 wrap-break-word text-sm font-semibold text-foreground", children: answer.label ?? answer.value }),
5326
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium text-muted-foreground", children: t(
5327
+ answer.type === "other" ? "message.requestUserInputResult.other" : "message.requestUserInputResult.option"
5328
+ ) })
5329
+ ] }),
5330
+ answer.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: answer.description }) : null
5331
+ ]
5332
+ },
5333
+ `${answer.id}-${index}`
5334
+ )) })
5335
+ ]
3620
5336
  }
3621
- ) });
3622
- };
3623
- var MarkdownText = (0, import_react6.memo)(MarkdownTextImpl);
5337
+ );
5338
+ }
3624
5339
 
3625
5340
  // src/components/thread/messages/widget.tsx
3626
5341
  var import_a2ui_react = require("@xpert-ai/a2ui-react");
3627
- var import_jsx_runtime21 = require("react/jsx-runtime");
5342
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3628
5343
  function WidgetMessage({ messageId, data }) {
3629
5344
  const widgets = Array.isArray(data.widgets) ? data.widgets : [];
3630
5345
  if (widgets.length === 0) return null;
3631
5346
  const baseSurfaceId = `widget-${messageId}`;
3632
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-3", children: widgets.map((widget, index) => {
5347
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-3", children: widgets.map((widget, index) => {
3633
5348
  const config = widget?.config;
3634
5349
  if (!config || typeof config !== "object") {
3635
5350
  return null;
3636
5351
  }
3637
5352
  const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
3638
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5353
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3639
5354
  import_a2ui_react.SurfaceRenderer,
3640
5355
  {
3641
5356
  surfaceId,
@@ -3647,58 +5362,44 @@ function WidgetMessage({ messageId, data }) {
3647
5362
  }
3648
5363
 
3649
5364
  // src/components/thread/messages/ai.tsx
3650
- var import_jsx_runtime22 = require("react/jsx-runtime");
3651
- function isTextContent(content) {
5365
+ var import_jsx_runtime25 = require("react/jsx-runtime");
5366
+ function isTextContent2(content) {
3652
5367
  return content.type === "text";
3653
5368
  }
3654
- function isReasoningContent(content) {
5369
+ function isReasoningContent2(content) {
3655
5370
  return content.type === "reasoning";
3656
5371
  }
3657
5372
  function isImageContent(content) {
3658
5373
  return content.type === "image_url";
3659
5374
  }
3660
- function isComponentContent(content) {
5375
+ function isComponentContent2(content) {
3661
5376
  return content.type === "component";
3662
5377
  }
3663
- var statusConfig = {
3664
- success: {
3665
- iconClass: "border-green-500 text-green-700",
3666
- icon: import_lucide_react9.CheckCircle2
3667
- },
3668
- fail: {
3669
- iconClass: "border-red-500 text-red-700",
3670
- icon: import_lucide_react9.XCircle
3671
- },
3672
- running: {
3673
- iconClass: "border-blue-500 text-blue-700",
3674
- icon: import_lucide_react9.Loader2
3675
- }
3676
- };
3677
- function isWidgetComponent(content) {
5378
+ function isWidgetComponent2(content) {
3678
5379
  const data = content.data;
3679
5380
  return data?.type === "Widget" && Array.isArray(data.widgets);
3680
5381
  }
3681
5382
  function isMemoryContent(content) {
3682
5383
  return content.type === "memory";
3683
5384
  }
3684
- function safeJson(value) {
5385
+ function safeJson2(value) {
3685
5386
  try {
3686
5387
  return JSON.stringify(value, null, 2);
3687
5388
  } catch {
3688
5389
  return String(value);
3689
5390
  }
3690
5391
  }
3691
- function formatDisplayValue(value) {
3692
- return typeof value === "string" ? value : safeJson(value);
5392
+ function formatDisplayValue2(value) {
5393
+ return typeof value === "string" ? value : safeJson2(value);
3693
5394
  }
3694
5395
  function ReasoningBlock({ reasoning }) {
3695
5396
  const blocks = reasoning.filter((item) => item.text?.trim());
3696
5397
  if (blocks.length === 0) return null;
3697
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5398
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3698
5399
  "div",
3699
5400
  {
3700
5401
  className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
3701
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
5402
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
3702
5403
  },
3703
5404
  item.id ?? `reasoning-${index}`
3704
5405
  )) });
@@ -3706,23 +5407,23 @@ function ReasoningBlock({ reasoning }) {
3706
5407
  function ImageBlock({ content }) {
3707
5408
  const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
3708
5409
  if (!imageUrl) {
3709
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3710
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Image" }) }),
3711
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
5410
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5411
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Image" }) }),
5412
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: safeJson2(content) })
3712
5413
  ] });
3713
5414
  }
3714
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
5415
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
3715
5416
  }
3716
5417
  function MemoryBlock({ content }) {
3717
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3718
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3719
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Memory" }),
3720
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "secondary", children: "Memory" })
5418
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5419
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5420
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Memory" }),
5421
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "secondary", children: "Memory" })
3721
5422
  ] }),
3722
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
5423
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson2(content.data ?? []) }) })
3723
5424
  ] });
3724
5425
  }
3725
- function parseStepDate(value) {
5426
+ function parseStepDate2(value) {
3726
5427
  if (value instanceof Date) {
3727
5428
  const timestamp2 = value.getTime();
3728
5429
  return Number.isNaN(timestamp2) ? null : timestamp2;
@@ -3733,7 +5434,7 @@ function parseStepDate(value) {
3733
5434
  const timestamp = Date.parse(value);
3734
5435
  return Number.isNaN(timestamp) ? null : timestamp;
3735
5436
  }
3736
- function formatStepDuration(durationMs) {
5437
+ function formatStepDuration2(durationMs) {
3737
5438
  if (durationMs < 1e3) {
3738
5439
  return `${durationMs}ms`;
3739
5440
  }
@@ -3752,28 +5453,29 @@ function formatStepDuration(durationMs) {
3752
5453
  return `${minutes}m ${seconds}s`;
3753
5454
  }
3754
5455
  function ComponentBlock({ content }) {
3755
- const [isExpanded, setIsExpanded] = React16.useState(false);
3756
- const contentRef = React16.useRef(null);
3757
- const shouldAutoScrollRef = React16.useRef(true);
3758
- const previousScrollTopRef = React16.useRef(0);
3759
- const [durationNow, setDurationNow] = React16.useState(() => Date.now());
3760
- const data = content.data ?? {};
5456
+ const { i18n: i18n2 } = useChatkitTranslation();
5457
+ const [isExpanded, setIsExpanded] = React19.useState(false);
5458
+ const contentRef = React19.useRef(null);
5459
+ const shouldAutoScrollRef = React19.useRef(true);
5460
+ const previousScrollTopRef = React19.useRef(0);
5461
+ const [durationNow, setDurationNow] = React19.useState(() => Date.now());
5462
+ const data = getToolStepData(content);
3761
5463
  const category = data.category ?? "Component";
3762
- const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
5464
+ const title = getToolActivityLabel(content, i18n2.language);
3763
5465
  const status = data.status ?? null;
3764
5466
  const message = data.message ?? null;
3765
5467
  const output = data.output ?? null;
3766
5468
  const error = data.error ?? null;
3767
5469
  const fallback = message ?? output ?? data.data ?? data;
3768
5470
  const hasOutput = message !== null || output !== null;
3769
- const createdAt = parseStepDate(data.created_date);
3770
- const endedAt = parseStepDate(data.end_date);
5471
+ const createdAt = parseStepDate2(data.created_date);
5472
+ const endedAt = parseStepDate2(data.end_date);
3771
5473
  const durationMs = createdAt === null ? null : Math.max(0, (endedAt ?? durationNow) - createdAt);
3772
- const durationLabel = durationMs === null ? null : formatStepDuration(durationMs);
3773
- React16.useEffect(() => {
5474
+ const durationLabel = durationMs === null ? null : formatStepDuration2(durationMs);
5475
+ React19.useEffect(() => {
3774
5476
  if (status === "running" && output !== null) setIsExpanded(true);
3775
5477
  }, [status, output]);
3776
- React16.useEffect(() => {
5478
+ React19.useEffect(() => {
3777
5479
  if (status !== "running" || createdAt === null || endedAt !== null) {
3778
5480
  return;
3779
5481
  }
@@ -3785,7 +5487,7 @@ function ComponentBlock({ content }) {
3785
5487
  window.clearInterval(timer);
3786
5488
  };
3787
5489
  }, [createdAt, endedAt, status]);
3788
- React16.useEffect(() => {
5490
+ React19.useEffect(() => {
3789
5491
  const element = contentRef.current;
3790
5492
  if (!element) return;
3791
5493
  previousScrollTopRef.current = element.scrollTop;
@@ -3805,7 +5507,7 @@ function ComponentBlock({ content }) {
3805
5507
  element.removeEventListener("scroll", updateAutoScrollState);
3806
5508
  };
3807
5509
  }, [isExpanded]);
3808
- React16.useEffect(() => {
5510
+ React19.useEffect(() => {
3809
5511
  if (status !== "running") {
3810
5512
  shouldAutoScrollRef.current = true;
3811
5513
  return;
@@ -3816,27 +5518,27 @@ function ComponentBlock({ content }) {
3816
5518
  }
3817
5519
  element.scrollTop = element.scrollHeight;
3818
5520
  }, [isExpanded, output, status]);
3819
- const config = status ? statusConfig[status] : null;
5521
+ const config = status ? toolStatusConfig[status] : null;
3820
5522
  const StatusIcon = config?.icon;
3821
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3822
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
3823
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
3824
- status && StatusIcon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
3825
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm truncate", children: title })
5523
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5524
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
5526
+ status && StatusIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
5527
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm truncate", children: title })
3826
5528
  ] }),
3827
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
3828
- durationLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
3829
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Clock3, { className: "h-3 w-3" }),
3830
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: durationLabel })
5529
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
5530
+ durationLabel && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
5531
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Clock3, { className: "h-3 w-3" }),
5532
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: durationLabel })
3831
5533
  ] }),
3832
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
3833
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5534
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
5535
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3834
5536
  "button",
3835
5537
  {
3836
5538
  className: "text-muted-foreground hover:text-foreground transition-colors",
3837
5539
  "aria-label": isExpanded ? "Collapse" : "Expand",
3838
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3839
- import_lucide_react9.ChevronDown,
5540
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5541
+ import_lucide_react12.ChevronDown,
3840
5542
  {
3841
5543
  className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
3842
5544
  }
@@ -3845,55 +5547,83 @@ function ComponentBlock({ content }) {
3845
5547
  )
3846
5548
  ] })
3847
5549
  ] }),
3848
- isExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
3849
- data.input && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
3850
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
5550
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
5551
+ data.input && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(data.input) }),
5552
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue2(error) }) : hasOutput && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(fallback) })
3851
5553
  ] })
3852
5554
  ] });
3853
5555
  }
3854
5556
  function UnknownBlock({ content }) {
3855
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3856
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3857
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Assistant Content" }),
3858
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "outline", children: content.type ?? "unknown" })
5557
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5558
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5559
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Assistant Content" }),
5560
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "outline", children: content.type ?? "unknown" })
3859
5561
  ] }),
3860
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
5562
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap break-words", children: safeJson2(content) }) })
3861
5563
  ] });
3862
5564
  }
3863
- function renderContentItem(content, index, messageId) {
5565
+ function renderContentItem(content, index, message, lookupMessages) {
5566
+ const messageId = message.id;
3864
5567
  if (typeof content === "string") {
3865
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
3866
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content }),
3867
- ";"
3868
- ] }, `text-${index}`);
5568
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content }) }, `text-${index}`);
3869
5569
  }
3870
- if (isTextContent(content)) {
3871
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
5570
+ if (isTextContent2(content)) {
5571
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
3872
5572
  }
3873
- if (isReasoningContent(content)) {
3874
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
5573
+ if (isReasoningContent2(content)) {
5574
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
3875
5575
  }
3876
5576
  if (isImageContent(content)) {
3877
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ImageBlock, { content }) }, content.id ?? `image-${index}`);
5577
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ImageBlock, { content }) }, content.id ?? `image-${index}`);
3878
5578
  }
3879
- if (isComponentContent(content)) {
3880
- if (isWidgetComponent(content)) {
3881
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5579
+ if (isComponentContent2(content)) {
5580
+ const requestUserInputResult = getRequestUserInputResultCardData(
5581
+ content,
5582
+ lookupMessages
5583
+ );
5584
+ if (requestUserInputResult) {
5585
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RequestUserInputResultCard, { result: requestUserInputResult }) }, content.id ?? `request-user-input-result-${index}`);
3882
5586
  }
3883
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
5587
+ if (isWidgetComponent2(content)) {
5588
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5589
+ }
5590
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
3884
5591
  }
3885
5592
  if (isMemoryContent(content)) {
3886
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5593
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5594
+ }
5595
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5596
+ }
5597
+ function renderContentUnit(unit, message, lookupMessages, hasFollowingItem) {
5598
+ if (unit.type === "item") {
5599
+ return renderContentItem(unit.item, unit.index, message, lookupMessages);
3887
5600
  }
3888
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5601
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5602
+ "div",
5603
+ {
5604
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToolComponentGroup, { items: unit.items, hasFollowingItem })
5605
+ },
5606
+ `tool-group-${unit.startIndex}-${unit.items[0]?.id ?? "tool"}-${unit.items.length}`
5607
+ );
3889
5608
  }
3890
- function renderContent(content, messageId) {
5609
+ function renderContent(message, lookupMessages) {
5610
+ const content = message.content;
3891
5611
  if (typeof content === "string") {
3892
5612
  if (!content.trim()) return null;
3893
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content });
5613
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content });
3894
5614
  }
3895
5615
  if (!Array.isArray(content) || content.length === 0) return null;
3896
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
5616
+ const renderUnits = buildToolComponentRenderUnits(content, {
5617
+ shouldGroupComponent: (item) => getRequestUserInputResultCardData(item, lookupMessages) === null
5618
+ });
5619
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-3", children: renderUnits.map(
5620
+ (unit, index) => renderContentUnit(
5621
+ unit,
5622
+ message,
5623
+ lookupMessages,
5624
+ index < renderUnits.length - 1
5625
+ )
5626
+ ) });
3897
5627
  }
3898
5628
  function AssistantStreamingIndicator({
3899
5629
  status,
@@ -3905,23 +5635,24 @@ function AssistantStreamingIndicator({
3905
5635
  thinking: t("message.thinking"),
3906
5636
  answering: t("message.answering")
3907
5637
  };
3908
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
3909
- status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
3910
- status === "thinking" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3911
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
3912
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
3913
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
5638
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
5639
+ status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
5640
+ status === "thinking" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5641
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
5642
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
5643
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
3914
5644
  ] }),
3915
- status === "answering" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3916
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
3917
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
3918
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
5645
+ status === "answering" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5646
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
5647
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
5648
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
3919
5649
  ] }),
3920
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: labelMap[status] })
5650
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: labelMap[status] })
3921
5651
  ] });
3922
5652
  }
3923
5653
  function AssistantMessage({
3924
5654
  message,
5655
+ messages,
3925
5656
  className,
3926
5657
  isStreaming = false,
3927
5658
  streamingStatus
@@ -3930,43 +5661,44 @@ function AssistantMessage({
3930
5661
  const hasContent = hasRenderableMessageContent(message.content);
3931
5662
  const hasReasoning = hasRenderableReasoning(message.reasoning);
3932
5663
  const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
3933
- const answerNode = renderContent(message.content, message.id);
3934
- const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
5664
+ const lookupMessages = messages?.length ? messages : [message];
5665
+ const answerNode = renderContent(message, lookupMessages);
5666
+ const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
3935
5667
  if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
3936
5668
  const streamingClass = isStreaming ? "streaming-active" : "";
3937
5669
  if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
3938
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
5670
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
3939
5671
  }
3940
5672
  if (hasContent && hasReasoning) {
3941
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
3942
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5673
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
5674
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3943
5675
  Tabs,
3944
5676
  {
3945
5677
  defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
3946
5678
  className: "w-full",
3947
5679
  children: [
3948
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(TabsList, { className: "", children: [
3949
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { value: "answer", children: t("message.answer") }),
3950
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
5680
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(TabsList, { className: "", children: [
5681
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsTrigger, { value: "answer", children: t("message.answer") }),
5682
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
3951
5683
  ] }),
3952
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
3953
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
5684
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
5685
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
3954
5686
  ]
3955
5687
  }
3956
5688
  ),
3957
- resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5689
+ resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3958
5690
  ] });
3959
5691
  }
3960
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
5692
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
3961
5693
  hasReasoning ? reasoningNode : answerNode,
3962
- resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5694
+ resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3963
5695
  ] });
3964
5696
  }
3965
5697
 
3966
5698
  // src/components/thread/MessageActions.tsx
3967
- var React17 = __toESM(require("react"), 1);
3968
- var import_lucide_react10 = require("lucide-react");
3969
- var import_jsx_runtime23 = require("react/jsx-runtime");
5699
+ var React20 = __toESM(require("react"), 1);
5700
+ var import_lucide_react13 = require("lucide-react");
5701
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3970
5702
  function MessageActions({
3971
5703
  content,
3972
5704
  isAssistant = false,
@@ -3975,7 +5707,7 @@ function MessageActions({
3975
5707
  className
3976
5708
  }) {
3977
5709
  const { t } = useChatkitTranslation();
3978
- const [copied, setCopied] = React17.useState(false);
5710
+ const [copied, setCopied] = React20.useState(false);
3979
5711
  const handleCopy = async () => {
3980
5712
  try {
3981
5713
  await navigator.clipboard.writeText(content);
@@ -3988,7 +5720,7 @@ function MessageActions({
3988
5720
  if (isStreaming) {
3989
5721
  return null;
3990
5722
  }
3991
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5723
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3992
5724
  "div",
3993
5725
  {
3994
5726
  className: cn(
@@ -3996,7 +5728,7 @@ function MessageActions({
3996
5728
  className
3997
5729
  ),
3998
5730
  children: [
3999
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5731
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4000
5732
  "button",
4001
5733
  {
4002
5734
  type: "button",
@@ -4006,17 +5738,17 @@ function MessageActions({
4006
5738
  copied && "text-green-500"
4007
5739
  ),
4008
5740
  title: copied ? t("messageActions.copied") : t("messageActions.copy"),
4009
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Copy, { size: 14 })
5741
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Copy, { size: 14 })
4010
5742
  }
4011
5743
  ),
4012
- isAssistant && onRetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5744
+ isAssistant && onRetry && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4013
5745
  "button",
4014
5746
  {
4015
5747
  type: "button",
4016
5748
  onClick: onRetry,
4017
5749
  className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
4018
5750
  title: t("messageActions.regenerate"),
4019
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.RefreshCw, { size: 14 })
5751
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.RefreshCw, { size: 14 })
4020
5752
  }
4021
5753
  )
4022
5754
  ]
@@ -4025,20 +5757,20 @@ function MessageActions({
4025
5757
  }
4026
5758
 
4027
5759
  // src/components/thread/StartScreen.tsx
4028
- var React18 = require("react");
4029
- var import_lucide_react11 = require("lucide-react");
4030
- var import_jsx_runtime24 = require("react/jsx-runtime");
5760
+ var React21 = require("react");
5761
+ var import_lucide_react14 = require("lucide-react");
5762
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4031
5763
  function getIconComponent2(icon) {
4032
5764
  const iconMap = {
4033
- "circle-question": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.HelpCircle, { size: 20 }),
4034
- "lightbulb": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Lightbulb, { size: 20 }),
4035
- "sparkle": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Sparkles, { size: 20 }),
4036
- "write": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Pencil, { size: 20 }),
4037
- "search": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Search, { size: 20 }),
4038
- "globe": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { size: 20 }),
4039
- "book-open": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.BookOpen, { size: 20 }),
4040
- "compass": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Compass, { size: 20 }),
4041
- "bolt": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Zap, { size: 20 })
5765
+ "circle-question": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.HelpCircle, { size: 20 }),
5766
+ "lightbulb": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Lightbulb, { size: 20 }),
5767
+ "sparkle": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Sparkles, { size: 20 }),
5768
+ "write": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Pencil, { size: 20 }),
5769
+ "search": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Search, { size: 20 }),
5770
+ "globe": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Globe, { size: 20 }),
5771
+ "book-open": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.BookOpen, { size: 20 }),
5772
+ "compass": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Compass, { size: 20 }),
5773
+ "bolt": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Zap, { size: 20 })
4042
5774
  };
4043
5775
  return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
4044
5776
  }
@@ -4046,9 +5778,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4046
5778
  const { t } = useChatkitTranslation();
4047
5779
  const greeting = startScreen?.greeting ?? t("startScreen.greeting");
4048
5780
  const prompts = startScreen?.prompts ?? [];
4049
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
4050
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mb-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
4051
- prompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5781
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
5782
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mb-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
5783
+ prompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4052
5784
  "button",
4053
5785
  {
4054
5786
  type: "button",
@@ -4059,8 +5791,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4059
5791
  "focus:outline-none focus:ring-2 focus:ring-primary/20"
4060
5792
  ),
4061
5793
  children: [
4062
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
4063
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-sm font-medium text-foreground", children: item.label })
5794
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
5795
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-sm font-medium text-foreground", children: item.label })
4064
5796
  ]
4065
5797
  },
4066
5798
  `prompt-${index}`
@@ -4069,13 +5801,13 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4069
5801
  }
4070
5802
 
4071
5803
  // src/components/ui/chatkit-avatar.tsx
4072
- var React20 = require("react");
5804
+ var React23 = require("react");
4073
5805
 
4074
5806
  // src/components/ui/avatar.tsx
4075
- var React19 = __toESM(require("react"), 1);
5807
+ var React22 = __toESM(require("react"), 1);
4076
5808
  var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
4077
- var import_jsx_runtime25 = require("react/jsx-runtime");
4078
- var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5809
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5810
+ var Avatar = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4079
5811
  AvatarPrimitive.Root,
4080
5812
  {
4081
5813
  ref,
@@ -4087,7 +5819,7 @@ var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
4087
5819
  }
4088
5820
  ));
4089
5821
  Avatar.displayName = AvatarPrimitive.Root.displayName;
4090
- var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5822
+ var AvatarImage = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4091
5823
  AvatarPrimitive.Image,
4092
5824
  {
4093
5825
  ref,
@@ -4096,7 +5828,7 @@ var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PUR
4096
5828
  }
4097
5829
  ));
4098
5830
  AvatarImage.displayName = AvatarPrimitive.Image.displayName;
4099
- var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5831
+ var AvatarFallback = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4100
5832
  AvatarPrimitive.Fallback,
4101
5833
  {
4102
5834
  ref,
@@ -4110,7 +5842,7 @@ var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__
4110
5842
  AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
4111
5843
 
4112
5844
  // src/components/ui/chatkit-avatar.tsx
4113
- var import_jsx_runtime26 = require("react/jsx-runtime");
5845
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4114
5846
  function asRecord(value) {
4115
5847
  return value && typeof value === "object" ? value : null;
4116
5848
  }
@@ -4183,21 +5915,21 @@ function ChatkitAvatar({
4183
5915
  const fallbackStyle = {
4184
5916
  ...avatar?.background ? { background: avatar.background } : {}
4185
5917
  };
4186
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
4187
- avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
4188
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5918
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
5919
+ avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
5920
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4189
5921
  AvatarFallback,
4190
5922
  {
4191
5923
  className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
4192
5924
  style: fallbackStyle,
4193
- children: emojiCharacter ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
5925
+ children: emojiCharacter ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
4194
5926
  }
4195
5927
  )
4196
5928
  ] });
4197
5929
  }
4198
5930
 
4199
5931
  // src/hooks/useThreads.ts
4200
- var React21 = __toESM(require("react"), 1);
5932
+ var React24 = __toESM(require("react"), 1);
4201
5933
  var DEFAULT_LIMIT = 50;
4202
5934
  var getThreadTitle = (threadRecord) => {
4203
5935
  const title = threadRecord.title?.trim();
@@ -4235,16 +5967,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
4235
5967
  isReady,
4236
5968
  isLoading: isStreamLoading
4237
5969
  } = useStreamContext();
4238
- const [threadRecords, setThreadRecords] = React21.useState([]);
4239
- const [isLoading, setIsLoading] = React21.useState(false);
4240
- const [error, setError] = React21.useState(null);
4241
- const upsertThreadRecord = React21.useCallback((threadRecord) => {
5970
+ const [threadRecords, setThreadRecords] = React24.useState([]);
5971
+ const [isLoading, setIsLoading] = React24.useState(false);
5972
+ const [error, setError] = React24.useState(null);
5973
+ const upsertThreadRecord = React24.useCallback((threadRecord) => {
4242
5974
  setThreadRecords((prev) => {
4243
5975
  const next = prev.filter((item) => item.id !== threadRecord.id);
4244
5976
  return sortThreadRecords([threadRecord, ...next]);
4245
5977
  });
4246
5978
  }, []);
4247
- const refreshThreads = React21.useCallback(async () => {
5979
+ const refreshThreads = React24.useCallback(async () => {
4248
5980
  setIsLoading(true);
4249
5981
  setError(null);
4250
5982
  try {
@@ -4260,7 +5992,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4260
5992
  setIsLoading(false);
4261
5993
  }
4262
5994
  }, [client, limit, assistantId]);
4263
- const createThread = React21.useCallback(
5995
+ const createThread = React24.useCallback(
4264
5996
  async (input) => {
4265
5997
  setError(null);
4266
5998
  const payload = {};
@@ -4274,7 +6006,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4274
6006
  },
4275
6007
  [client, upsertThreadRecord]
4276
6008
  );
4277
- const updateThread = React21.useCallback(
6009
+ const updateThread = React24.useCallback(
4278
6010
  async (recordId, payload) => {
4279
6011
  setError(null);
4280
6012
  const updated = await client.conversations.update(recordId, payload);
@@ -4283,7 +6015,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4283
6015
  },
4284
6016
  [client, upsertThreadRecord]
4285
6017
  );
4286
- const deleteThread = React21.useCallback(
6018
+ const deleteThread = React24.useCallback(
4287
6019
  async (recordId) => {
4288
6020
  setError(null);
4289
6021
  await client.conversations.delete(recordId);
@@ -4291,11 +6023,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
4291
6023
  },
4292
6024
  [client]
4293
6025
  );
4294
- React21.useEffect(() => {
6026
+ React24.useEffect(() => {
4295
6027
  if (!isReady) return;
4296
6028
  void refreshThreads();
4297
6029
  }, [refreshThreads, isReady]);
4298
- React21.useEffect(() => {
6030
+ React24.useEffect(() => {
4299
6031
  if (!threadId || !isStreamLoading) return;
4300
6032
  const now = (/* @__PURE__ */ new Date()).toISOString();
4301
6033
  const busyStatus = "busy";
@@ -4316,7 +6048,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4316
6048
  return changed ? sortThreadRecords(next) : prev;
4317
6049
  });
4318
6050
  }, [threadId, isStreamLoading]);
4319
- React21.useEffect(() => {
6051
+ React24.useEffect(() => {
4320
6052
  if (!isReady || !threadId || isStreamLoading) return;
4321
6053
  let cancelled = false;
4322
6054
  void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
@@ -4330,7 +6062,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4330
6062
  cancelled = true;
4331
6063
  };
4332
6064
  }, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
4333
- const threads = React21.useMemo(
6065
+ const threads = React24.useMemo(
4334
6066
  () => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
4335
6067
  [threadRecords]
4336
6068
  );
@@ -4347,10 +6079,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
4347
6079
  }
4348
6080
 
4349
6081
  // src/components/thread/context-usage-indicator.tsx
4350
- var React22 = __toESM(require("react"), 1);
6082
+ var React25 = __toESM(require("react"), 1);
4351
6083
 
4352
6084
  // src/components/ui/progress-circle.tsx
4353
- var import_jsx_runtime27 = (
6085
+ var import_jsx_runtime30 = (
4354
6086
  // biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
4355
6087
  // biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
4356
6088
  require("react/jsx-runtime")
@@ -4374,7 +6106,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4374
6106
  fill: "none",
4375
6107
  strokeWidth
4376
6108
  };
4377
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
6109
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4378
6110
  "svg",
4379
6111
  {
4380
6112
  role: "progressbar",
@@ -4385,8 +6117,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4385
6117
  "aria-valuemax": 100,
4386
6118
  ...restSvgProps,
4387
6119
  children: [
4388
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("circle", { ...commonParams, className: "stroke-current/25" }),
4389
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
6120
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { ...commonParams, className: "stroke-current/25" }),
6121
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4390
6122
  "circle",
4391
6123
  {
4392
6124
  ...commonParams,
@@ -4404,7 +6136,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4404
6136
  };
4405
6137
 
4406
6138
  // src/components/thread/context-usage-indicator.tsx
4407
- var import_jsx_runtime28 = require("react/jsx-runtime");
6139
+ var import_jsx_runtime31 = require("react/jsx-runtime");
4408
6140
  var kNumberFormatter = new Intl.NumberFormat("en-US", {
4409
6141
  minimumFractionDigits: 0,
4410
6142
  maximumFractionDigits: 1
@@ -4437,20 +6169,20 @@ function ContextUsageIndicator({
4437
6169
  }) {
4438
6170
  const { t } = useChatkitTranslation();
4439
6171
  const stream = useStreamContext();
4440
- const [maxContextSize, setMaxContextSize] = React22.useState(null);
4441
- const [usedContextSize, setUsedContextSize] = React22.useState(null);
4442
- const [assistantAgentKey, setAssistantAgentKey] = React22.useState(null);
4443
- const latestRealtimeUsageRef = React22.useRef({
6172
+ const [maxContextSize, setMaxContextSize] = React25.useState(null);
6173
+ const [usedContextSize, setUsedContextSize] = React25.useState(null);
6174
+ const [assistantAgentKey, setAssistantAgentKey] = React25.useState(null);
6175
+ const latestRealtimeUsageRef = React25.useRef({
4444
6176
  threadId: null,
4445
6177
  agentKey: null,
4446
6178
  usedTokens: null
4447
6179
  });
4448
- const realtimeUsage = React22.useMemo(
6180
+ const realtimeUsage = React25.useMemo(
4449
6181
  () => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
4450
6182
  [assistantAgentKey, stream.contextUsageByAgentKey]
4451
6183
  );
4452
6184
  const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
4453
- React22.useEffect(() => {
6185
+ React25.useEffect(() => {
4454
6186
  if (!stream.client || !stream.assistantId) {
4455
6187
  setMaxContextSize(null);
4456
6188
  setAssistantAgentKey(null);
@@ -4470,18 +6202,18 @@ function ContextUsageIndicator({
4470
6202
  cancelled = true;
4471
6203
  };
4472
6204
  }, [stream.client, stream.assistantId]);
4473
- React22.useEffect(() => {
6205
+ React25.useEffect(() => {
4474
6206
  latestRealtimeUsageRef.current = {
4475
6207
  threadId: stream.threadId ?? null,
4476
6208
  agentKey: assistantAgentKey,
4477
6209
  usedTokens: realtimeUsedContextSize
4478
6210
  };
4479
6211
  }, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
4480
- React22.useEffect(() => {
6212
+ React25.useEffect(() => {
4481
6213
  if (realtimeUsedContextSize == null) return;
4482
6214
  setUsedContextSize(realtimeUsedContextSize);
4483
6215
  }, [realtimeUsedContextSize]);
4484
- React22.useEffect(() => {
6216
+ React25.useEffect(() => {
4485
6217
  if (!stream.client) {
4486
6218
  setUsedContextSize(null);
4487
6219
  return;
@@ -4546,8 +6278,8 @@ function ContextUsageIndicator({
4546
6278
  });
4547
6279
  const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
4548
6280
  const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
4549
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Tooltip, { children: [
4550
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6281
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Tooltip, { children: [
6282
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4551
6283
  "button",
4552
6284
  {
4553
6285
  type: "button",
@@ -4556,19 +6288,19 @@ function ContextUsageIndicator({
4556
6288
  className
4557
6289
  ),
4558
6290
  "aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
4559
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
6291
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
4560
6292
  }
4561
6293
  ) }),
4562
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
4563
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
4564
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
4565
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "text-sm font-semibold", children: usageTokensLabel })
6294
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
6295
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
6296
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
6297
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-sm font-semibold", children: usageTokensLabel })
4566
6298
  ] })
4567
6299
  ] });
4568
6300
  }
4569
6301
 
4570
6302
  // src/components/chat.tsx
4571
- var import_jsx_runtime29 = require("react/jsx-runtime");
6303
+ var import_jsx_runtime32 = require("react/jsx-runtime");
4572
6304
  var import_meta2 = {};
4573
6305
  var defaultApiUrl2 = import_meta2.env.VITE_XPERTAI_API_URL;
4574
6306
  var COMPOSER_INPUT_MAX_HEIGHT = 128;
@@ -4660,8 +6392,8 @@ function ReferenceChip({
4660
6392
  }) {
4661
6393
  const metaLine = getReferenceMetaLine(reference);
4662
6394
  const isComposer = variant === "composer";
4663
- const Icon = reference.type === "quote" ? import_lucide_react12.Quote : reference.type === "image" ? import_lucide_react12.ImageIcon : import_lucide_react12.FileText;
4664
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6395
+ const Icon = reference.type === "quote" ? import_lucide_react15.Quote : reference.type === "image" ? import_lucide_react15.ImageIcon : import_lucide_react15.FileText;
6396
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
4665
6397
  "div",
4666
6398
  {
4667
6399
  className: cn(
@@ -4670,7 +6402,7 @@ function ReferenceChip({
4670
6402
  ),
4671
6403
  title: getReferenceTitle(reference),
4672
6404
  children: [
4673
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6405
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4674
6406
  Icon,
4675
6407
  {
4676
6408
  size: isComposer ? 14 : 12,
@@ -4680,8 +6412,8 @@ function ReferenceChip({
4680
6412
  )
4681
6413
  }
4682
6414
  ),
4683
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0 flex-1", children: [
4684
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6415
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "min-w-0 flex-1", children: [
6416
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4685
6417
  "div",
4686
6418
  {
4687
6419
  className: cn(
@@ -4691,7 +6423,7 @@ function ReferenceChip({
4691
6423
  children: getReferenceLabel(reference)
4692
6424
  }
4693
6425
  ),
4694
- metaLine && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6426
+ metaLine && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4695
6427
  "div",
4696
6428
  {
4697
6429
  className: cn(
@@ -4702,7 +6434,7 @@ function ReferenceChip({
4702
6434
  }
4703
6435
  )
4704
6436
  ] }),
4705
- onRemove && removeLabel && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6437
+ onRemove && removeLabel && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4706
6438
  "button",
4707
6439
  {
4708
6440
  type: "button",
@@ -4713,7 +6445,7 @@ function ReferenceChip({
4713
6445
  ),
4714
6446
  title: removeLabel,
4715
6447
  "aria-label": removeLabel,
4716
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
6448
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
4717
6449
  }
4718
6450
  )
4719
6451
  ]
@@ -4737,20 +6469,20 @@ function Chat({
4737
6469
  const { setStream } = useStreamManager();
4738
6470
  const stream = useStreamContext();
4739
6471
  const { theme } = useTheme();
4740
- const [isHistoryLoading, setIsHistoryLoading] = React23.useState(false);
4741
- const [historyError, setHistoryError] = React23.useState(null);
4742
- const [assistantName, setAssistantName] = React23.useState(null);
4743
- const [assistantAvatar, setAssistantAvatar] = React23.useState(null);
6472
+ const [isHistoryLoading, setIsHistoryLoading] = React26.useState(false);
6473
+ const [historyError, setHistoryError] = React26.useState(null);
6474
+ const [assistantName, setAssistantName] = React26.useState(null);
6475
+ const [assistantAvatar, setAssistantAvatar] = React26.useState(null);
4744
6476
  const LOADING_DOTS_MIN_DURATION = 800;
4745
6477
  const STREAMING_STATUS_REFRESH_MS = 250;
4746
- const [showLoadingDots, setShowLoadingDots] = React23.useState(false);
4747
- const [streamingNow, setStreamingNow] = React23.useState(() => Date.now());
4748
- const loadingStartTimeRef = React23.useRef(null);
4749
- const lastStreamOutputAtRef = React23.useRef(null);
4750
- React23.useEffect(() => {
6478
+ const [showLoadingDots, setShowLoadingDots] = React26.useState(false);
6479
+ const [streamingNow, setStreamingNow] = React26.useState(() => Date.now());
6480
+ const loadingStartTimeRef = React26.useRef(null);
6481
+ const lastStreamOutputAtRef = React26.useRef(null);
6482
+ React26.useEffect(() => {
4751
6483
  setStream(stream);
4752
6484
  }, [setStream, stream]);
4753
- React23.useEffect(() => {
6485
+ React26.useEffect(() => {
4754
6486
  if (stream.isLoading) {
4755
6487
  if (!loadingStartTimeRef.current) {
4756
6488
  loadingStartTimeRef.current = Date.now();
@@ -4773,7 +6505,7 @@ function Chat({
4773
6505
  }
4774
6506
  }
4775
6507
  }, [stream.isLoading]);
4776
- React23.useEffect(() => {
6508
+ React26.useEffect(() => {
4777
6509
  if (!stream.isLoading) {
4778
6510
  lastStreamOutputAtRef.current = null;
4779
6511
  setStreamingNow(Date.now());
@@ -4783,7 +6515,7 @@ function Chat({
4783
6515
  lastStreamOutputAtRef.current = now;
4784
6516
  setStreamingNow(now);
4785
6517
  }, [stream.messages, stream.isLoading]);
4786
- React23.useEffect(() => {
6518
+ React26.useEffect(() => {
4787
6519
  if (!stream.isLoading) {
4788
6520
  return;
4789
6521
  }
@@ -4792,53 +6524,55 @@ function Chat({
4792
6524
  }, STREAMING_STATUS_REFRESH_MS);
4793
6525
  return () => window.clearInterval(timer);
4794
6526
  }, [stream.isLoading]);
4795
- const [draft, setDraft] = React23.useState("");
4796
- const [selectedTool, setSelectedTool] = React23.useState(
6527
+ const [draft, setDraft] = React26.useState("");
6528
+ const [selectedTool, setSelectedTool] = React26.useState(
4797
6529
  null
4798
6530
  );
4799
- const [attachments, setAttachments] = React23.useState([]);
4800
- const [references, setReferences] = React23.useState([]);
4801
- const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React23.useState(false);
4802
- const [quoteSelection, setQuoteSelection] = React23.useState(null);
4803
- const [isAtBottom, setIsAtBottom] = React23.useState(true);
4804
- const [hasUpdatesBelow, setHasUpdatesBelow] = React23.useState(false);
6531
+ const [planModeEnabled, setPlanModeEnabled] = React26.useState(false);
6532
+ const [attachments, setAttachments] = React26.useState([]);
6533
+ const [references, setReferences] = React26.useState([]);
6534
+ const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React26.useState(false);
6535
+ const [quoteSelection, setQuoteSelection] = React26.useState(null);
6536
+ const [isAtBottom, setIsAtBottom] = React26.useState(true);
6537
+ const [hasUpdatesBelow, setHasUpdatesBelow] = React26.useState(false);
4805
6538
  const {
4806
6539
  threads,
4807
6540
  deleteThread,
4808
6541
  refreshThreads,
4809
6542
  isLoading: isThreadsLoading
4810
6543
  } = useThreads();
4811
- const viewportRef = React23.useRef(null);
4812
- const fileInputRef = React23.useRef(null);
4813
- const composerInputRef = React23.useRef(null);
4814
- const shouldAutoScrollRef = React23.useRef(true);
4815
- const forceFollowRef = React23.useRef(false);
4816
- const previousMessageCountRef = React23.useRef(0);
4817
- const previousScrollTopRef = React23.useRef(0);
4818
- const autoScrollFrameRef = React23.useRef(null);
4819
- const isPointerDownRef = React23.useRef(false);
4820
- const lastTouchYRef = React23.useRef(null);
6544
+ const viewportRef = React26.useRef(null);
6545
+ const fileInputRef = React26.useRef(null);
6546
+ const composerInputRef = React26.useRef(null);
6547
+ const shouldAutoScrollRef = React26.useRef(true);
6548
+ const forceFollowRef = React26.useRef(false);
6549
+ const previousMessageCountRef = React26.useRef(0);
6550
+ const previousScrollTopRef = React26.useRef(0);
6551
+ const autoScrollFrameRef = React26.useRef(null);
6552
+ const isPointerDownRef = React26.useRef(false);
6553
+ const lastTouchYRef = React26.useRef(null);
4821
6554
  const resolvedTitle = title ?? t("chat.title");
4822
6555
  const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
4823
6556
  const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
4824
- const messages = React23.useMemo(
6557
+ const messages = React26.useMemo(
4825
6558
  () => stream.messages ?? [],
4826
6559
  [stream.messages]
4827
6560
  );
4828
6561
  const trimmedDraft = draft.trim();
4829
6562
  const hasReferences = references.length > 0;
4830
- const pendingFollowUps = React23.useMemo(
6563
+ const pendingFollowUps = React26.useMemo(
4831
6564
  () => [...stream.pendingFollowUps ?? []].sort(
4832
6565
  (a, b) => a.createdAt - b.createdAt
4833
6566
  ),
4834
6567
  [stream.pendingFollowUps]
4835
6568
  );
4836
6569
  const hasPendingFollowUps = pendingFollowUps.length > 0;
4837
- const clearQuoteSelection = React23.useCallback(() => {
6570
+ const hasPendingRequestUserInput = Boolean(stream.pendingRequestUserInput);
6571
+ const clearQuoteSelection = React26.useCallback(() => {
4838
6572
  setQuoteSelection(null);
4839
6573
  }, []);
4840
6574
  useParentMessenger({
4841
- onSetComposerValue: React23.useCallback(
6575
+ onSetComposerValue: React26.useCallback(
4842
6576
  (payload) => {
4843
6577
  if (!payload) {
4844
6578
  return;
@@ -4861,11 +6595,11 @@ function Chat({
4861
6595
  },
4862
6596
  [composer?.tools]
4863
6597
  ),
4864
- onFocusComposer: React23.useCallback(() => {
6598
+ onFocusComposer: React26.useCallback(() => {
4865
6599
  composerInputRef.current?.focus();
4866
6600
  }, [])
4867
6601
  });
4868
- const syncQuoteSelection = React23.useCallback(() => {
6602
+ const syncQuoteSelection = React26.useCallback(() => {
4869
6603
  if (typeof window === "undefined") {
4870
6604
  clearQuoteSelection();
4871
6605
  return;
@@ -4910,23 +6644,23 @@ function Chat({
4910
6644
  left
4911
6645
  });
4912
6646
  }, [clearQuoteSelection]);
4913
- const cancelPendingAutoScroll = React23.useCallback(() => {
6647
+ const cancelPendingAutoScroll = React26.useCallback(() => {
4914
6648
  if (autoScrollFrameRef.current !== null) {
4915
6649
  cancelAnimationFrame(autoScrollFrameRef.current);
4916
6650
  autoScrollFrameRef.current = null;
4917
6651
  }
4918
6652
  }, []);
4919
- const disableAutoFollow = React23.useCallback(() => {
6653
+ const disableAutoFollow = React26.useCallback(() => {
4920
6654
  forceFollowRef.current = false;
4921
6655
  shouldAutoScrollRef.current = false;
4922
6656
  cancelPendingAutoScroll();
4923
6657
  }, [cancelPendingAutoScroll]);
4924
- const enableAutoFollow = React23.useCallback(() => {
6658
+ const enableAutoFollow = React26.useCallback(() => {
4925
6659
  forceFollowRef.current = true;
4926
6660
  shouldAutoScrollRef.current = true;
4927
6661
  setHasUpdatesBelow(false);
4928
6662
  }, []);
4929
- const scrollToBottom = React23.useCallback(
6663
+ const scrollToBottom = React26.useCallback(
4930
6664
  (smooth = false, force = false) => {
4931
6665
  if (force) {
4932
6666
  enableAutoFollow();
@@ -4948,7 +6682,7 @@ function Chat({
4948
6682
  },
4949
6683
  [cancelPendingAutoScroll, enableAutoFollow]
4950
6684
  );
4951
- React23.useEffect(() => {
6685
+ React26.useEffect(() => {
4952
6686
  const viewport = viewportRef.current;
4953
6687
  if (!viewport) return;
4954
6688
  previousScrollTopRef.current = viewport.scrollTop;
@@ -5029,14 +6763,14 @@ function Chat({
5029
6763
  window.removeEventListener("pointercancel", stopPointerTracking);
5030
6764
  };
5031
6765
  }, [cancelPendingAutoScroll, disableAutoFollow]);
5032
- React23.useEffect(() => {
6766
+ React26.useEffect(() => {
5033
6767
  shouldAutoScrollRef.current = true;
5034
6768
  forceFollowRef.current = false;
5035
6769
  previousScrollTopRef.current = 0;
5036
6770
  setIsAtBottom(true);
5037
6771
  setHasUpdatesBelow(false);
5038
6772
  }, [stream.threadId]);
5039
- React23.useEffect(() => {
6773
+ React26.useEffect(() => {
5040
6774
  const messageCountChanged = messages.length !== previousMessageCountRef.current;
5041
6775
  previousMessageCountRef.current = messages.length;
5042
6776
  if (!shouldAutoScrollRef.current) {
@@ -5055,7 +6789,7 @@ function Chat({
5055
6789
  clientSecret: effectiveClientSecret
5056
6790
  });
5057
6791
  const missingConfig = Boolean(missingConfigKind);
5058
- const missingConfigShortMessage = React23.useMemo(() => {
6792
+ const missingConfigShortMessage = React26.useMemo(() => {
5059
6793
  switch (missingConfigKind) {
5060
6794
  case "apiUrl":
5061
6795
  return t("chat.missingApiUrlShort");
@@ -5067,7 +6801,7 @@ function Chat({
5067
6801
  return t("chat.missingConfigShort");
5068
6802
  }
5069
6803
  }, [missingConfigKind, t]);
5070
- const missingConfigDetailMessage = React23.useMemo(() => {
6804
+ const missingConfigDetailMessage = React26.useMemo(() => {
5071
6805
  switch (missingConfigKind) {
5072
6806
  case "apiUrl":
5073
6807
  return t("chat.missingApiUrlDetail");
@@ -5081,8 +6815,8 @@ function Chat({
5081
6815
  }, [missingConfigKind, t]);
5082
6816
  const showMissingConfig = !isClientSecretInitializing && missingConfig;
5083
6817
  const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
5084
- const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
5085
- const resizeComposerInput = React23.useCallback(() => {
6818
+ const isSendDisabled = !trimmedDraft && !hasReferences || hasPendingRequestUserInput || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
6819
+ const resizeComposerInput = React26.useCallback(() => {
5086
6820
  const textarea = composerInputRef.current;
5087
6821
  if (!textarea) {
5088
6822
  return;
@@ -5095,16 +6829,16 @@ function Chat({
5095
6829
  textarea.style.height = `${nextHeight}px`;
5096
6830
  textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
5097
6831
  }, []);
5098
- React23.useEffect(() => {
6832
+ React26.useEffect(() => {
5099
6833
  resizeComposerInput();
5100
6834
  }, [draft, resizeComposerInput]);
5101
- React23.useEffect(() => {
6835
+ React26.useEffect(() => {
5102
6836
  document.addEventListener("selectionchange", syncQuoteSelection);
5103
6837
  return () => {
5104
6838
  document.removeEventListener("selectionchange", syncQuoteSelection);
5105
6839
  };
5106
6840
  }, [syncQuoteSelection]);
5107
- React23.useEffect(() => {
6841
+ React26.useEffect(() => {
5108
6842
  const viewport = viewportRef.current;
5109
6843
  if (!viewport) {
5110
6844
  return;
@@ -5121,14 +6855,14 @@ function Chat({
5121
6855
  window.removeEventListener("resize", handleViewportScroll);
5122
6856
  };
5123
6857
  }, [clearQuoteSelection]);
5124
- React23.useEffect(() => {
6858
+ React26.useEffect(() => {
5125
6859
  clearQuoteSelection();
5126
6860
  }, [messages.length, stream.threadId, clearQuoteSelection]);
5127
- React23.useEffect(() => {
6861
+ React26.useEffect(() => {
5128
6862
  if (missingConfig) return;
5129
6863
  void refreshThreads();
5130
6864
  }, [missingConfig, refreshThreads]);
5131
- React23.useEffect(() => {
6865
+ React26.useEffect(() => {
5132
6866
  if (missingConfig || !stream.client || !stream.assistantId) {
5133
6867
  setAssistantName(null);
5134
6868
  setAssistantAvatar(null);
@@ -5159,7 +6893,7 @@ function Chat({
5159
6893
  mimetype: a.storageFile?.mimetype ?? a.file.type,
5160
6894
  size: a.storageFile?.size ?? a.file.size
5161
6895
  }));
5162
- const submitDraft = React23.useCallback(
6896
+ const submitDraft = React26.useCallback(
5163
6897
  (followUpOverride) => {
5164
6898
  if (isSendDisabled) return;
5165
6899
  const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
@@ -5189,6 +6923,9 @@ function Chat({
5189
6923
  if (filesToSend) {
5190
6924
  inputPayload.files = filesToSend;
5191
6925
  }
6926
+ if (planModeEnabled) {
6927
+ inputPayload.planMode = true;
6928
+ }
5192
6929
  const requestOptions = buildInjectedRequestOptions({
5193
6930
  defaults: options?.request,
5194
6931
  humanInput: inputPayload
@@ -5223,6 +6960,7 @@ function Chat({
5223
6960
  references,
5224
6961
  scrollToBottom,
5225
6962
  selectedTool,
6963
+ planModeEnabled,
5226
6964
  stream,
5227
6965
  trimmedDraft,
5228
6966
  uploadedFiles,
@@ -5233,7 +6971,7 @@ function Chat({
5233
6971
  event.preventDefault();
5234
6972
  submitDraft();
5235
6973
  };
5236
- const handleEditPendingFollowUp = React23.useCallback(
6974
+ const handleEditPendingFollowUp = React26.useCallback(
5237
6975
  (id) => {
5238
6976
  const item = pendingFollowUps.find(
5239
6977
  (entry) => entry.id === id && entry.mode === "queue"
@@ -5260,7 +6998,7 @@ function Chat({
5260
6998
  },
5261
6999
  [pendingFollowUps, stream]
5262
7000
  );
5263
- const handleQuoteSelection = React23.useCallback(() => {
7001
+ const handleQuoteSelection = React26.useCallback(() => {
5264
7002
  if (!quoteSelection) {
5265
7003
  return;
5266
7004
  }
@@ -5276,7 +7014,7 @@ function Chat({
5276
7014
  const handleAttachmentClick = () => {
5277
7015
  fileInputRef.current?.click();
5278
7016
  };
5279
- const uploadContextFile = React23.useCallback(
7017
+ const uploadContextFile = React26.useCallback(
5280
7018
  (file) => stream.client.contexts.uploadFile(file),
5281
7019
  [stream.client]
5282
7020
  );
@@ -5302,7 +7040,7 @@ function Chat({
5302
7040
  }
5303
7041
  submitDraft();
5304
7042
  };
5305
- const handleComposerPaste = React23.useCallback(
7043
+ const handleComposerPaste = React26.useCallback(
5306
7044
  (event) => {
5307
7045
  const clipboardData = event.clipboardData;
5308
7046
  if (!clipboardData) {
@@ -5381,18 +7119,18 @@ function Chat({
5381
7119
  uploadContextFile
5382
7120
  ]
5383
7121
  );
5384
- const alternateFollowUpShortcutLabel = React23.useMemo(() => {
7122
+ const alternateFollowUpShortcutLabel = React26.useMemo(() => {
5385
7123
  if (typeof navigator === "undefined") {
5386
7124
  return "\u2318Enter";
5387
7125
  }
5388
7126
  const platform = navigator.platform || navigator.userAgent;
5389
7127
  return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
5390
7128
  }, []);
5391
- const followUpShortcutLabels = React23.useMemo(
7129
+ const followUpShortcutLabels = React26.useMemo(
5392
7130
  () => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
5393
7131
  [alternateFollowUpShortcutLabel]
5394
7132
  );
5395
- const uploadFile = React23.useCallback(
7133
+ const uploadFile = React26.useCallback(
5396
7134
  async (localId, file) => {
5397
7135
  try {
5398
7136
  const result = await uploadContextFile(file);
@@ -5415,7 +7153,7 @@ function Chat({
5415
7153
  },
5416
7154
  [uploadContextFile]
5417
7155
  );
5418
- const handleRetryUpload = React23.useCallback(
7156
+ const handleRetryUpload = React26.useCallback(
5419
7157
  (localId) => {
5420
7158
  const attachment = attachments.find((a) => a.localId === localId);
5421
7159
  if (!attachment || attachment.status !== "error") return;
@@ -5486,10 +7224,23 @@ function Chat({
5486
7224
  content: prompt
5487
7225
  };
5488
7226
  const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
7227
+ const inputPayload = {
7228
+ input: prompt,
7229
+ ...planModeEnabled ? { planMode: true } : {}
7230
+ };
7231
+ const requestOptions = buildInjectedRequestOptions({
7232
+ defaults: options?.request,
7233
+ humanInput: inputPayload
7234
+ });
5489
7235
  stream.submit(
5490
- { input: { input: prompt } },
7236
+ {
7237
+ input: inputPayload,
7238
+ ...requestOptions.state ? { state: requestOptions.state } : {}
7239
+ },
5491
7240
  {
5492
7241
  ...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
7242
+ ...requestOptions.context ? { context: requestOptions.context } : {},
7243
+ ...requestOptions.config ? { config: requestOptions.config } : {},
5493
7244
  ...!nextFollowUpMode ? {
5494
7245
  optimisticValues: (prev) => {
5495
7246
  const prevMessages = prev?.messages ?? [];
@@ -5500,7 +7251,7 @@ function Chat({
5500
7251
  );
5501
7252
  scrollToBottom(true, true);
5502
7253
  };
5503
- const loadConversationMessages = React23.useCallback(
7254
+ const loadConversationMessages = React26.useCallback(
5504
7255
  async (recordId) => {
5505
7256
  if (missingConfig) {
5506
7257
  setHistoryError(missingConfigShortMessage);
@@ -5586,18 +7337,18 @@ function Chat({
5586
7337
  }
5587
7338
  };
5588
7339
  const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
5589
- const currentThread = React23.useMemo(
7340
+ const currentThread = React26.useMemo(
5590
7341
  () => threads.find((item) => item.id === stream.threadId),
5591
7342
  [threads, stream.threadId]
5592
7343
  );
5593
7344
  const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
5594
- const threadErrorMessage = React23.useMemo(() => {
7345
+ const threadErrorMessage = React26.useMemo(() => {
5595
7346
  if (currentThread?.status !== "error") return void 0;
5596
7347
  const message = currentThread.error?.trim();
5597
7348
  return message || t("thread.errorToast");
5598
7349
  }, [currentThread, t]);
5599
7350
  const assistantTitle = assistantName || resolvedTitle;
5600
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7351
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5601
7352
  "div",
5602
7353
  {
5603
7354
  ref: viewportRef,
@@ -5606,10 +7357,10 @@ function Chat({
5606
7357
  className
5607
7358
  ),
5608
7359
  children: [
5609
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
5610
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
5611
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "relative shrink-0", children: [
5612
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7360
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
7361
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
7362
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative shrink-0", children: [
7363
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5613
7364
  ChatkitAvatar,
5614
7365
  {
5615
7366
  avatar: assistantAvatar,
@@ -5617,10 +7368,10 @@ function Chat({
5617
7368
  label: assistantTitle
5618
7369
  }
5619
7370
  ),
5620
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
7371
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
5621
7372
  ] }),
5622
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "truncate", children: [
5623
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7373
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "truncate", children: [
7374
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5624
7375
  "h2",
5625
7376
  {
5626
7377
  className: "text-lg font-semibold truncate",
@@ -5628,27 +7379,30 @@ function Chat({
5628
7379
  children: assistantTitle
5629
7380
  }
5630
7381
  ),
5631
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
7382
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
5632
7383
  ] })
5633
7384
  ] }),
5634
- history?.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-1", children: [
5635
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5636
- "button",
5637
- {
5638
- type: "button",
5639
- onClick: handleNewThread,
5640
- disabled: missingConfig || isHistoryLoading,
5641
- className: cn(
5642
- "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
5643
- "text-muted-foreground hover:text-foreground hover:bg-muted",
5644
- "transition-colors duration-150",
5645
- "disabled:opacity-50 disabled:cursor-not-allowed"
5646
- ),
5647
- title: t("history.newThread"),
5648
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.Pencil, { size: 16 })
5649
- }
5650
- ),
5651
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7385
+ history?.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1", children: [
7386
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Tooltip, { children: [
7387
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7388
+ "button",
7389
+ {
7390
+ type: "button",
7391
+ onClick: handleNewThread,
7392
+ disabled: missingConfig || isHistoryLoading,
7393
+ className: cn(
7394
+ "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
7395
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
7396
+ "transition-colors duration-150",
7397
+ "disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed"
7398
+ ),
7399
+ "aria-label": t("history.newThread"),
7400
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.Pencil, { size: 16 })
7401
+ }
7402
+ ) }) }),
7403
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipContent, { side: "bottom", children: t("history.newThread") })
7404
+ ] }),
7405
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5652
7406
  HistorySidebar,
5653
7407
  {
5654
7408
  threads,
@@ -5662,18 +7416,18 @@ function Chat({
5662
7416
  )
5663
7417
  ] })
5664
7418
  ] }),
5665
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 p-4", children: [
5666
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
5667
- historyError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
5668
- showMissingConfig && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
5669
- isHistoryLoading && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
5670
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7419
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex-1 p-4", children: [
7420
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
7421
+ historyError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
7422
+ showMissingConfig && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
7423
+ isHistoryLoading && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
7424
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5671
7425
  StartScreen,
5672
7426
  {
5673
7427
  startScreen,
5674
7428
  onPromptClick: handlePromptClick
5675
7429
  }
5676
- ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "space-y-4", children: [
7430
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "space-y-4", children: [
5677
7431
  messages.map((message, index) => {
5678
7432
  const messageType = String(message.type);
5679
7433
  const isAssistantMessage = messageType === "assistant" || messageType === "ai";
@@ -5700,7 +7454,7 @@ function Chat({
5700
7454
  if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
5701
7455
  return null;
5702
7456
  }
5703
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7457
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5704
7458
  "div",
5705
7459
  {
5706
7460
  className: cn(
@@ -5708,8 +7462,8 @@ function Chat({
5708
7462
  message.type === "human" ? "justify-end" : "justify-start -ml-1"
5709
7463
  // AI messages: slightly closer to left
5710
7464
  ),
5711
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col px-3 overflow-hidden", children: [
5712
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7465
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col px-3 overflow-hidden", children: [
7466
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5713
7467
  "div",
5714
7468
  {
5715
7469
  ...canQuoteMessage ? {
@@ -5721,18 +7475,24 @@ function Chat({
5721
7475
  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"
5722
7476
  // AI messages: use chat-specific foreground color
5723
7477
  ),
5724
- children: isAssistantMessage ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7478
+ children: isAssistantMessage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5725
7479
  AssistantMessage,
5726
7480
  {
5727
7481
  message: {
5728
7482
  ...message,
5729
7483
  type: "assistant"
5730
7484
  },
7485
+ messages: messages.slice(0, index + 1).map(
7486
+ (item) => ({
7487
+ ...item,
7488
+ type: String(item.type) === "ai" ? "assistant" : item.type
7489
+ })
7490
+ ),
5731
7491
  isStreaming: isStreamingMessage,
5732
7492
  streamingStatus
5733
7493
  }
5734
- ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
5735
- message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7494
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7495
+ message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5736
7496
  ReferenceChip,
5737
7497
  {
5738
7498
  reference,
@@ -5740,29 +7500,29 @@ function Chat({
5740
7500
  },
5741
7501
  getReferenceKey(reference)
5742
7502
  )) }),
5743
- message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7503
+ message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5744
7504
  "div",
5745
7505
  {
5746
7506
  className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
5747
7507
  children: [
5748
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 12 }),
5749
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "max-w-[100px] truncate", children: file.originalName })
7508
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 12 }),
7509
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "max-w-[100px] truncate", children: file.originalName })
5750
7510
  ]
5751
7511
  },
5752
7512
  fileIndex
5753
7513
  )) }),
5754
- Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7514
+ Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5755
7515
  "p",
5756
7516
  {
5757
7517
  className: "wrap-break-word text-sm leading-relaxed",
5758
7518
  children: formatMessageContent(part)
5759
7519
  },
5760
7520
  `${part.type}-${partIndex}`
5761
- )) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
7521
+ )) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
5762
7522
  ] })
5763
7523
  }
5764
7524
  ),
5765
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7525
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5766
7526
  MessageActions,
5767
7527
  {
5768
7528
  content: messageContent,
@@ -5798,7 +7558,7 @@ function Chat({
5798
7558
  stream.isLoading,
5799
7559
  { now: streamingNow }
5800
7560
  );
5801
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7561
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5802
7562
  AssistantStreamingIndicator,
5803
7563
  {
5804
7564
  status: fallbackStreamingStatus ?? "loading"
@@ -5807,7 +7567,7 @@ function Chat({
5807
7567
  })()
5808
7568
  ] })
5809
7569
  ] }),
5810
- !isAtBottom && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7570
+ !isAtBottom && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5811
7571
  Button,
5812
7572
  {
5813
7573
  type: "button",
@@ -5820,10 +7580,10 @@ function Chat({
5820
7580
  onClick: () => scrollToBottom(true, true),
5821
7581
  "aria-label": t("chat.scrollToBottom"),
5822
7582
  title: t("chat.scrollToBottom"),
5823
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.ArrowDown, { size: 16 })
7583
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.ArrowDown, { size: 16 })
5824
7584
  }
5825
7585
  ) }),
5826
- quoteSelection && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7586
+ quoteSelection && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5827
7587
  "div",
5828
7588
  {
5829
7589
  className: "pointer-events-none fixed z-50",
@@ -5832,7 +7592,7 @@ function Chat({
5832
7592
  left: `${quoteSelection.left}px`,
5833
7593
  transform: "translateX(-50%)"
5834
7594
  },
5835
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7595
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5836
7596
  Button,
5837
7597
  {
5838
7598
  type: "button",
@@ -5844,16 +7604,16 @@ function Chat({
5844
7604
  "aria-label": t("composer.quoteSelection"),
5845
7605
  title: t("composer.quoteSelection"),
5846
7606
  children: [
5847
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.Quote, { size: 14 }),
7607
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.Quote, { size: 14 }),
5848
7608
  t("composer.quoteSelection")
5849
7609
  ]
5850
7610
  }
5851
7611
  )
5852
7612
  }
5853
7613
  ),
5854
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
5855
- threadErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("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 }),
5856
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7614
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
7615
+ threadErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("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 }),
7616
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5857
7617
  "input",
5858
7618
  {
5859
7619
  ref: fileInputRef,
@@ -5864,7 +7624,7 @@ function Chat({
5864
7624
  className: "hidden"
5865
7625
  }
5866
7626
  ),
5867
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7627
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5868
7628
  "div",
5869
7629
  {
5870
7630
  className: cn(
@@ -5872,16 +7632,16 @@ function Chat({
5872
7632
  item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
5873
7633
  ),
5874
7634
  children: [
5875
- item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5876
- import_lucide_react12.Loader2,
7635
+ item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7636
+ import_lucide_react15.Loader2,
5877
7637
  {
5878
7638
  size: 14,
5879
7639
  className: "animate-spin text-muted-foreground"
5880
7640
  }
5881
7641
  ),
5882
- item.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 14, className: "text-muted-foreground" }),
5883
- item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 14, className: "text-destructive" }),
5884
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7642
+ item.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 14, className: "text-muted-foreground" }),
7643
+ item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 14, className: "text-destructive" }),
7644
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5885
7645
  "span",
5886
7646
  {
5887
7647
  className: cn(
@@ -5891,17 +7651,17 @@ function Chat({
5891
7651
  children: item.file.name
5892
7652
  }
5893
7653
  ),
5894
- item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7654
+ item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5895
7655
  "button",
5896
7656
  {
5897
7657
  type: "button",
5898
7658
  onClick: () => handleRetryUpload(item.localId),
5899
7659
  className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
5900
7660
  title: t("chat.retryUpload"),
5901
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.RefreshCw, { size: 12 })
7661
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.RefreshCw, { size: 12 })
5902
7662
  }
5903
7663
  ),
5904
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7664
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5905
7665
  "button",
5906
7666
  {
5907
7667
  type: "button",
@@ -5910,14 +7670,14 @@ function Chat({
5910
7670
  "ml-1 rounded-full p-0.5",
5911
7671
  item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
5912
7672
  ),
5913
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
7673
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
5914
7674
  }
5915
7675
  )
5916
7676
  ]
5917
7677
  },
5918
7678
  item.localId
5919
7679
  )) }),
5920
- references.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7680
+ references.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5921
7681
  ReferenceChip,
5922
7682
  {
5923
7683
  reference,
@@ -5931,19 +7691,19 @@ function Chat({
5931
7691
  },
5932
7692
  getReferenceKey(reference)
5933
7693
  )) }),
5934
- selectedTool && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [
5935
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
5936
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7694
+ selectedTool && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [
7695
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
7696
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5937
7697
  "button",
5938
7698
  {
5939
7699
  type: "button",
5940
7700
  onClick: () => setSelectedTool(null),
5941
7701
  className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
5942
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
7702
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
5943
7703
  }
5944
7704
  )
5945
7705
  ] }),
5946
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7706
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5947
7707
  PendingTodos,
5948
7708
  {
5949
7709
  snapshot: stream.todos,
@@ -5951,7 +7711,7 @@ function Chat({
5951
7711
  className: hasPendingFollowUps ? "mb-2" : void 0
5952
7712
  }
5953
7713
  ),
5954
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7714
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5955
7715
  PendingFollowUps,
5956
7716
  {
5957
7717
  items: pendingFollowUps,
@@ -5966,7 +7726,16 @@ function Chat({
5966
7726
  attachToComposer: true
5967
7727
  }
5968
7728
  ),
5969
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7729
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7730
+ RequestUserInputPanel,
7731
+ {
7732
+ request: stream.pendingRequestUserInput,
7733
+ onSubmit: stream.submitRequestUserInput,
7734
+ onDismiss: stream.stop,
7735
+ attachToComposer: true
7736
+ }
7737
+ ),
7738
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5970
7739
  "div",
5971
7740
  {
5972
7741
  className: cn(
@@ -5978,17 +7747,19 @@ function Chat({
5978
7747
  getRoundedClass(theme.radius)
5979
7748
  ),
5980
7749
  children: [
5981
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7750
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5982
7751
  ComposerMenu,
5983
7752
  {
5984
7753
  composer,
5985
7754
  onAttachmentClick: handleAttachmentClick,
5986
7755
  onToolSelect: handleToolSelect,
5987
7756
  selectedTool,
5988
- disabled: missingConfig || isHistoryLoading
7757
+ planModeEnabled,
7758
+ onPlanModeChange: setPlanModeEnabled,
7759
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput
5989
7760
  }
5990
7761
  ),
5991
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7762
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5992
7763
  "textarea",
5993
7764
  {
5994
7765
  ref: composerInputRef,
@@ -5998,7 +7769,7 @@ function Chat({
5998
7769
  onKeyDown: handleComposerKeyDown,
5999
7770
  rows: 1,
6000
7771
  placeholder: inputPlaceholder,
6001
- disabled: missingConfig || isHistoryLoading,
7772
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput,
6002
7773
  className: cn(
6003
7774
  "min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
6004
7775
  "placeholder:text-muted-foreground",
@@ -6006,12 +7777,12 @@ function Chat({
6006
7777
  )
6007
7778
  }
6008
7779
  ),
6009
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7780
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6010
7781
  SendButton,
6011
7782
  {
6012
7783
  disabled: isSendDisabled,
6013
7784
  isLoading: stream.isLoading,
6014
- showStop: stream.isLoading && !trimmedDraft,
7785
+ showStop: stream.isLoading && (!trimmedDraft || hasPendingRequestUserInput),
6015
7786
  onStop: () => stream.stop(),
6016
7787
  stopLabel: t("chat.stop"),
6017
7788
  sendLabel: t("chat.send"),
@@ -6030,7 +7801,7 @@ function Chat({
6030
7801
  ]
6031
7802
  }
6032
7803
  ) }),
6033
- disclaimer?.text && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7804
+ disclaimer?.text && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6034
7805
  "p",
6035
7806
  {
6036
7807
  className: cn(
@@ -6040,9 +7811,9 @@ function Chat({
6040
7811
  children: disclaimer.text
6041
7812
  }
6042
7813
  ),
6043
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
6044
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: t("chat.poweredBy") }),
6045
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ContextUsageIndicator, { className: "absolute right-4" })
7814
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
7815
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: t("chat.poweredBy") }),
7816
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ContextUsageIndicator, { className: "absolute right-4" })
6046
7817
  ] })
6047
7818
  ] })
6048
7819
  ]
@@ -6051,11 +7822,11 @@ function Chat({
6051
7822
  }
6052
7823
 
6053
7824
  // src/components/ui/input.tsx
6054
- var React24 = __toESM(require("react"), 1);
6055
- var import_jsx_runtime30 = require("react/jsx-runtime");
6056
- var Input = React24.forwardRef(
7825
+ var React27 = __toESM(require("react"), 1);
7826
+ var import_jsx_runtime33 = require("react/jsx-runtime");
7827
+ var Input = React27.forwardRef(
6057
7828
  ({ className, type, ...props }, ref) => {
6058
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7829
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6059
7830
  "input",
6060
7831
  {
6061
7832
  ref,
@@ -6072,10 +7843,10 @@ var Input = React24.forwardRef(
6072
7843
  Input.displayName = "Input";
6073
7844
 
6074
7845
  // src/components/ui/separator.tsx
6075
- var React25 = __toESM(require("react"), 1);
6076
- var import_jsx_runtime31 = require("react/jsx-runtime");
6077
- var Separator = React25.forwardRef(
6078
- ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7846
+ var React28 = __toESM(require("react"), 1);
7847
+ var import_jsx_runtime34 = require("react/jsx-runtime");
7848
+ var Separator = React28.forwardRef(
7849
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6079
7850
  "div",
6080
7851
  {
6081
7852
  ref,