@xpert-ai/chatkit-ui 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/dist/app/assets/{_baseUniq-p9H3Gzep.js → _baseUniq-U3ZlyosM.js} +1 -1
  2. package/dist/app/assets/{abap-bJX3iBqH.js → abap-8X6m4nc9.js} +1 -1
  3. package/dist/app/assets/{abnf-BoiZ35EE.js → abnf-B9FqRK4Q.js} +1 -1
  4. package/dist/app/assets/{actionscript-D-H9vZ8b.js → actionscript-BRiggmYG.js} +1 -1
  5. package/dist/app/assets/{ada-Bne3WpOl.js → ada-FFsIKz3W.js} +1 -1
  6. package/dist/app/assets/{agda-C938cagi.js → agda-CSry7vG2.js} +1 -1
  7. package/dist/app/assets/{al-Dcxw3Vj0.js → al-B86I55sd.js} +1 -1
  8. package/dist/app/assets/{antlr4-uTm2QqyV.js → antlr4-DLdIrmfn.js} +1 -1
  9. package/dist/app/assets/{apacheconf-D52D513G.js → apacheconf-CyFZwC58.js} +1 -1
  10. package/dist/app/assets/{apex-B76H7J4g.js → apex-DMVXQx7B.js} +1 -1
  11. package/dist/app/assets/{apl-CzLk42pF.js → apl-CvxzOn3f.js} +1 -1
  12. package/dist/app/assets/{applescript-Dx8Ig-Eo.js → applescript-D9BsJ4nv.js} +1 -1
  13. package/dist/app/assets/{aql-wjx32tAU.js → aql-Du46VsVP.js} +1 -1
  14. package/dist/app/assets/{arc-B32_yhh0.js → arc-Cgg2Li2V.js} +1 -1
  15. package/dist/app/assets/{architectureDiagram-Q4EWVU46-Ba-C8DAI.js → architectureDiagram-Q4EWVU46-3DQlJdjW.js} +1 -1
  16. package/dist/app/assets/{arduino-BwKDxTSS.js → arduino-Bsv1YPmE.js} +1 -1
  17. package/dist/app/assets/{arff-DrkRViyY.js → arff-CJK1I_i3.js} +1 -1
  18. package/dist/app/assets/{asciidoc-BGLZq9v8.js → asciidoc-DxmnfpMK.js} +1 -1
  19. package/dist/app/assets/{asm6502-MsEWIyJj.js → asm6502-B-ig6A0r.js} +1 -1
  20. package/dist/app/assets/{asmatmel-CeHxqS5T.js → asmatmel-DlH3PvMo.js} +1 -1
  21. package/dist/app/assets/{aspnet-CmsQfR5a.js → aspnet-D8iv0Uvb.js} +1 -1
  22. package/dist/app/assets/{autohotkey-Cusm-zTm.js → autohotkey-B0J5KM1J.js} +1 -1
  23. package/dist/app/assets/{autoit-Da8gsEm-.js → autoit-DjZ-C8Ct.js} +1 -1
  24. package/dist/app/assets/{avisynth-C46xLzyo.js → avisynth-DBwstp_C.js} +1 -1
  25. package/dist/app/assets/{avro-idl-D2WmoYBG.js → avro-idl-D2NmTxDF.js} +1 -1
  26. package/dist/app/assets/{bash-BrsKn3za.js → bash-CaYF0XP6.js} +1 -1
  27. package/dist/app/assets/{basic-Dt5oGQ8B.js → basic-CmOS0BPn.js} +1 -1
  28. package/dist/app/assets/{batch-DtrIlfXi.js → batch-0uLA_1q6.js} +1 -1
  29. package/dist/app/assets/{bbcode-BWYlAYoE.js → bbcode-DofDtehq.js} +1 -1
  30. package/dist/app/assets/{bicep-C4sxks0f.js → bicep-Csi6HiBf.js} +1 -1
  31. package/dist/app/assets/{birb-gYyyIZ-F.js → birb-wpSYHdbW.js} +1 -1
  32. package/dist/app/assets/{bison-or-umhj6.js → bison-B_ycJmsC.js} +1 -1
  33. package/dist/app/assets/{blockDiagram-DXYQGD6D-5oqbPp8P.js → blockDiagram-DXYQGD6D-C5FR_JeB.js} +1 -1
  34. package/dist/app/assets/{bnf-BQR7hfk2.js → bnf-BFkvwiYp.js} +1 -1
  35. package/dist/app/assets/{brainfuck-DkQqhNHv.js → brainfuck-CKXec9xF.js} +1 -1
  36. package/dist/app/assets/{brightscript-rGhg0HBT.js → brightscript-da2DAp0M.js} +1 -1
  37. package/dist/app/assets/{bro-CIgtBg0f.js → bro-CMEOqxCO.js} +1 -1
  38. package/dist/app/assets/{bsl-C4geIkQv.js → bsl-CcPijGZ5.js} +1 -1
  39. package/dist/app/assets/{c-Cw5181Rv.js → c-ypihM29I.js} +1 -1
  40. package/dist/app/assets/{c4Diagram-AHTNJAMY-BKyN5n0Y.js → c4Diagram-AHTNJAMY-CVQ-YBVO.js} +1 -1
  41. package/dist/app/assets/{cfscript-DHPNMvWS.js → cfscript-57UtmCol.js} +1 -1
  42. package/dist/app/assets/{chaiscript-Cd8c0hJ8.js → chaiscript-Bzv7uMwl.js} +1 -1
  43. package/dist/app/assets/channel-QFEl2WH8.js +1 -0
  44. package/dist/app/assets/{chunk-4BX2VUAB-CfLubn_X.js → chunk-4BX2VUAB-Dxfd4JRQ.js} +1 -1
  45. package/dist/app/assets/{chunk-4TB4RGXK-Bhehm3S4.js → chunk-4TB4RGXK-0tBP8iWY.js} +1 -1
  46. package/dist/app/assets/{chunk-55IACEB6-D0Zgi2qX.js → chunk-55IACEB6-C6Of3RNV.js} +1 -1
  47. package/dist/app/assets/{chunk-EDXVE4YY-DzMULs0l.js → chunk-EDXVE4YY-D9VnbCF6.js} +1 -1
  48. package/dist/app/assets/{chunk-FMBD7UC4-CEU9agAN.js → chunk-FMBD7UC4-C-jb70xY.js} +1 -1
  49. package/dist/app/assets/{chunk-OYMX7WX6-C-avxOs6.js → chunk-OYMX7WX6-DHv4g2zF.js} +1 -1
  50. package/dist/app/assets/{chunk-QZHKN3VN-C66xsvBW.js → chunk-QZHKN3VN-BVJ1du8l.js} +1 -1
  51. package/dist/app/assets/{chunk-YZCP3GAM-DZlwMcoL.js → chunk-YZCP3GAM-C9v1WHTx.js} +1 -1
  52. package/dist/app/assets/{cil-L3oWT8Nl.js → cil-D9cVdpCd.js} +1 -1
  53. package/dist/app/assets/classDiagram-6PBFFD2Q-CUn8MbgR.js +1 -0
  54. package/dist/app/assets/classDiagram-v2-HSJHXN6E-CUn8MbgR.js +1 -0
  55. package/dist/app/assets/{clike-CHF9NJQa.js → clike-M17MKmCg.js} +1 -1
  56. package/dist/app/assets/{clojure-YgRWUbgr.js → clojure-BP9wyv_O.js} +1 -1
  57. package/dist/app/assets/clone-BMPaQ6PL.js +1 -0
  58. package/dist/app/assets/{cmake-TK-Cvlxu.js → cmake-Co2PqOJx.js} +1 -1
  59. package/dist/app/assets/{cobol-XSbSVVcZ.js → cobol-CNBeDco-.js} +1 -1
  60. package/dist/app/assets/{coffeescript-HxNd9-Ob.js → coffeescript-DdmDPbXl.js} +1 -1
  61. package/dist/app/assets/{concurnas-DK3wUjjD.js → concurnas-C9VRiWa-.js} +1 -1
  62. package/dist/app/assets/{coq-B9Rq7NUE.js → coq-CYE7tqZa.js} +1 -1
  63. package/dist/app/assets/{core-B1vWjEfj.js → core-D4MD7_kt.js} +1 -1
  64. package/dist/app/assets/{cose-bilkent-S5V4N54A-4PebjqsX.js → cose-bilkent-S5V4N54A-Dxea2bnQ.js} +1 -1
  65. package/dist/app/assets/{cpp-DUWMh-8O.js → cpp-DWaMOtiP.js} +1 -1
  66. package/dist/app/assets/{crystal-rYgGF4lS.js → crystal-BtBXd6Fx.js} +1 -1
  67. package/dist/app/assets/{csharp-eqTMyksU.js → csharp-CrOHktb0.js} +1 -1
  68. package/dist/app/assets/{cshtml-DSv9-mpk.js → cshtml-CzjshIvK.js} +1 -1
  69. package/dist/app/assets/{csp-DyZfVzvb.js → csp-DnNBeWw0.js} +1 -1
  70. package/dist/app/assets/{css-extras-FP15zHq8.js → css-extras-BDArRWv3.js} +1 -1
  71. package/dist/app/assets/{css-DYXyUyJe.js → css-pohe_YML.js} +1 -1
  72. package/dist/app/assets/{csv-Bp1iUR7c.js → csv-BOXRdr2m.js} +1 -1
  73. package/dist/app/assets/{cypher-BjXgs7Y3.js → cypher-IsM8Hmhu.js} +1 -1
  74. package/dist/app/assets/{d-Bquc1S6a.js → d-BUE4Srvp.js} +1 -1
  75. package/dist/app/assets/{dagre-KV5264BT-D9OICDLb.js → dagre-KV5264BT-D9I1gn5M.js} +1 -1
  76. package/dist/app/assets/{dart-DrKyO7TC.js → dart-DKXx5vmY.js} +1 -1
  77. package/dist/app/assets/{dataweave-BgpsWzO7.js → dataweave-CZ-IeeGN.js} +1 -1
  78. package/dist/app/assets/{dax-BwP1SyCZ.js → dax-Cyyg-Qre.js} +1 -1
  79. package/dist/app/assets/{dhall-BA5nXB8V.js → dhall-CI9o_hcQ.js} +1 -1
  80. package/dist/app/assets/{diagram-5BDNPKRD-BIFTIy6n.js → diagram-5BDNPKRD-Da8AhEfW.js} +1 -1
  81. package/dist/app/assets/{diagram-G4DWMVQ6-BCVIBrZ2.js → diagram-G4DWMVQ6-u5xAUOB1.js} +1 -1
  82. package/dist/app/assets/{diagram-MMDJMWI5-43z4NaFN.js → diagram-MMDJMWI5-CRedReUg.js} +1 -1
  83. package/dist/app/assets/{diagram-TYMM5635-BDZjM1c_.js → diagram-TYMM5635-Btelw9Gj.js} +1 -1
  84. package/dist/app/assets/{diff-Yc6a7YOT.js → diff-BaJjRLPC.js} +1 -1
  85. package/dist/app/assets/{django-B61BBi1t.js → django-DKz8sLSB.js} +1 -1
  86. package/dist/app/assets/{dns-zone-file-DtXhOJHq.js → dns-zone-file-DB4bzm0m.js} +1 -1
  87. package/dist/app/assets/{docker-BLh9n10i.js → docker-f9TV7yVV.js} +1 -1
  88. package/dist/app/assets/{dot-BbSnn0Ap.js → dot-CItfl0YH.js} +1 -1
  89. package/dist/app/assets/{ebnf-D_ljHBdb.js → ebnf-4UWkoMwW.js} +1 -1
  90. package/dist/app/assets/{editorconfig-BQXrLGC5.js → editorconfig-DsQRKuSQ.js} +1 -1
  91. package/dist/app/assets/{eiffel-Cm3FUI5X.js → eiffel-BKzL5tZy.js} +1 -1
  92. package/dist/app/assets/{ejs-CIp2UdDw.js → ejs-FawjQT4F.js} +1 -1
  93. package/dist/app/assets/{elixir-DXlWBe5R.js → elixir-CYrsCeua.js} +1 -1
  94. package/dist/app/assets/{elm-ECxjLCR-.js → elm-BQbPKl6Y.js} +1 -1
  95. package/dist/app/assets/{erDiagram-SMLLAGMA-B9I89ndp.js → erDiagram-SMLLAGMA-nIXCbdu9.js} +1 -1
  96. package/dist/app/assets/{erb-FzgX8ydn.js → erb-D8td-3qG.js} +1 -1
  97. package/dist/app/assets/{erlang-CzvdSvoz.js → erlang-CVcUIOcL.js} +1 -1
  98. package/dist/app/assets/{etlua-C3Zsz3RA.js → etlua-Sp57LMlp.js} +1 -1
  99. package/dist/app/assets/{excel-formula-Cua38PQJ.js → excel-formula-C2xW1VqS.js} +1 -1
  100. package/dist/app/assets/{factor-CSAzXoQb.js → factor-B39cYmXr.js} +1 -1
  101. package/dist/app/assets/{false-NSFMCUjP.js → false-BXc89S7-.js} +1 -1
  102. package/dist/app/assets/{firestore-security-rules-BjNYwvNe.js → firestore-security-rules-D5XHnYii.js} +1 -1
  103. package/dist/app/assets/{flow-BuZaM8y6.js → flow-DvgodFNT.js} +1 -1
  104. package/dist/app/assets/{flowDiagram-DWJPFMVM-CWmW_muY.js → flowDiagram-DWJPFMVM-BRxtHyqr.js} +1 -1
  105. package/dist/app/assets/{fortran-Cc_f_mSH.js → fortran-C2uXAnB9.js} +1 -1
  106. package/dist/app/assets/{fsharp-IelQ4Z-Z.js → fsharp-D4MeNJsV.js} +1 -1
  107. package/dist/app/assets/{ftl-Ddl9DDyG.js → ftl-FdK7rzYa.js} +1 -1
  108. package/dist/app/assets/{ganttDiagram-T4ZO3ILL-CuR1J7dx.js → ganttDiagram-T4ZO3ILL-CxQPl5RJ.js} +1 -1
  109. package/dist/app/assets/{gap-D3W6p-Jp.js → gap-CqoRmA2e.js} +1 -1
  110. package/dist/app/assets/{gcode-Bn8O4UOx.js → gcode-Cbf6Hq0S.js} +1 -1
  111. package/dist/app/assets/{gdscript-B4nck3Az.js → gdscript-vUATu21P.js} +1 -1
  112. package/dist/app/assets/{gedcom-BCTZRsxn.js → gedcom-Dq_MXb_u.js} +1 -1
  113. package/dist/app/assets/{gherkin-CFCJQug9.js → gherkin-TnW-3H17.js} +1 -1
  114. package/dist/app/assets/{git-Dd2t83_l.js → git-ChiXZZK3.js} +1 -1
  115. package/dist/app/assets/{gitGraphDiagram-UUTBAWPF-DzscVnaS.js → gitGraphDiagram-UUTBAWPF-Bcj29y1k.js} +1 -1
  116. package/dist/app/assets/{glsl-NXGZDuA9.js → glsl-D73MB7QA.js} +1 -1
  117. package/dist/app/assets/{gml-DtS9_99j.js → gml-DKKhoV5Q.js} +1 -1
  118. package/dist/app/assets/{gn-C6VmNt4U.js → gn-xteKZDbd.js} +1 -1
  119. package/dist/app/assets/{go-otK-v_nb.js → go-gderB942.js} +1 -1
  120. package/dist/app/assets/{go-module-CmBM8SA1.js → go-module-Cxdn5g6K.js} +1 -1
  121. package/dist/app/assets/{graph-BelNBDAZ.js → graph-Dr0CyUTm.js} +1 -1
  122. package/dist/app/assets/{graphql-JPlPKrhh.js → graphql-B9ESkh7V.js} +1 -1
  123. package/dist/app/assets/{groovy-CkMUqzIt.js → groovy-D46SaIaB.js} +1 -1
  124. package/dist/app/assets/{haml-DwaIQOGd.js → haml-C-gOKeM2.js} +1 -1
  125. package/dist/app/assets/{handlebars-Ck6RB1iw.js → handlebars-WQgCAz-C.js} +1 -1
  126. package/dist/app/assets/{haskell-BxYLBxBa.js → haskell-DZKWHhbK.js} +1 -1
  127. package/dist/app/assets/{haxe-C4OMV9zJ.js → haxe-Do6EdaWm.js} +1 -1
  128. package/dist/app/assets/{hcl-DVznmODf.js → hcl-CW6MZD7W.js} +1 -1
  129. package/dist/app/assets/{hlsl-Z_ySkish.js → hlsl-BYgUfMru.js} +1 -1
  130. package/dist/app/assets/{hoon-UWT3k4H8.js → hoon-IqFoeyLn.js} +1 -1
  131. package/dist/app/assets/{hpkp-CXa39f7J.js → hpkp-BuV8JDpY.js} +1 -1
  132. package/dist/app/assets/{hsts-CJF4yNvU.js → hsts-DAvq0I49.js} +1 -1
  133. package/dist/app/assets/{http-BxOKxlr4.js → http-CCayShZc.js} +1 -1
  134. package/dist/app/assets/{ichigojam-Csb66zY2.js → ichigojam-IQlKAhBR.js} +1 -1
  135. package/dist/app/assets/{icon-DxphTQI9.js → icon-C1YOMBEH.js} +1 -1
  136. package/dist/app/assets/{icu-message-format-CSZfssuP.js → icu-message-format-CbkLI-kP.js} +1 -1
  137. package/dist/app/assets/{idris-BmXANiaa.js → idris-Db0sol3G.js} +1 -1
  138. package/dist/app/assets/{iecst-FfznJdjL.js → iecst-Rp9pN_Ps.js} +1 -1
  139. package/dist/app/assets/{ignore-C3IKkXMi.js → ignore-DSijMN4b.js} +1 -1
  140. package/dist/app/assets/index-EzE2l0pf.css +1 -0
  141. package/dist/app/assets/index-izi7yD-m.js +747 -0
  142. package/dist/app/assets/{infoDiagram-42DDH7IO-rTeQPEt4.js → infoDiagram-42DDH7IO-DP_5_HCg.js} +1 -1
  143. package/dist/app/assets/{inform7-Dk4gPo4b.js → inform7-BdTrQNcW.js} +1 -1
  144. package/dist/app/assets/{ini-CClGKGMe.js → ini-BL1YqQPe.js} +1 -1
  145. package/dist/app/assets/{io-6YtqLtET.js → io-ju4qnY4R.js} +1 -1
  146. package/dist/app/assets/{ishikawaDiagram-UXIWVN3A-BBnJ9iuN.js → ishikawaDiagram-UXIWVN3A-c-5weLZu.js} +1 -1
  147. package/dist/app/assets/{j-DBPrIcAG.js → j-BNgG1B_8.js} +1 -1
  148. package/dist/app/assets/{java-CopGP3Lu.js → java-BBM8kPUi.js} +1 -1
  149. package/dist/app/assets/{javadoc-C8F3ifW2.js → javadoc-DzqYwIEC.js} +1 -1
  150. package/dist/app/assets/{javadoclike-BNVFpoJC.js → javadoclike-CXHyoMho.js} +1 -1
  151. package/dist/app/assets/{javascript-BMkkas2q.js → javascript-DyOtAE59.js} +1 -1
  152. package/dist/app/assets/{javastacktrace-DuykBujE.js → javastacktrace-CfTMUgb0.js} +1 -1
  153. package/dist/app/assets/{jexl-BSWOm8s5.js → jexl-BmCWVTv_.js} +1 -1
  154. package/dist/app/assets/{jolie-CdkOmKFM.js → jolie-C3BdHGrF.js} +1 -1
  155. package/dist/app/assets/{journeyDiagram-VCZTEJTY-CRDpL_1T.js → journeyDiagram-VCZTEJTY-DAKBW1_0.js} +1 -1
  156. package/dist/app/assets/{jq-Nr0Kxpxc.js → jq-B4eKQbVT.js} +1 -1
  157. package/dist/app/assets/{js-extras-CA8iZ_E5.js → js-extras-B9Um65g1.js} +1 -1
  158. package/dist/app/assets/{js-templates-BoqcQW67.js → js-templates-B8LIGz8d.js} +1 -1
  159. package/dist/app/assets/{jsdoc-CeMFl6xP.js → jsdoc-X69feyNn.js} +1 -1
  160. package/dist/app/assets/{json-CrSHUueM.js → json-Ds9Y6npk.js} +1 -1
  161. package/dist/app/assets/{json5-BBfX460l.js → json5-BEpvRyGQ.js} +1 -1
  162. package/dist/app/assets/{jsonp-DHEqmGWL.js → jsonp-CI2Vwglg.js} +1 -1
  163. package/dist/app/assets/{jsstacktrace-BK3SuvsS.js → jsstacktrace-B_qFrkK8.js} +1 -1
  164. package/dist/app/assets/{jsx-CjR3dp14.js → jsx-C_Wki7pg.js} +1 -1
  165. package/dist/app/assets/{julia-BJJ6LUnI.js → julia-CGmxtkB0.js} +1 -1
  166. package/dist/app/assets/{kanban-definition-6JOO6SKY-Dztk4Auy.js → kanban-definition-6JOO6SKY-Bj8uidJb.js} +1 -1
  167. package/dist/app/assets/{keepalived-CjGUJvsk.js → keepalived-C8Mk-Wqp.js} +1 -1
  168. package/dist/app/assets/{keyman-Bogz-7f0.js → keyman-CMifeZZV.js} +1 -1
  169. package/dist/app/assets/{kotlin-DGdetcAk.js → kotlin-ogZAOqoN.js} +1 -1
  170. package/dist/app/assets/{kumir-Czhml4-j.js → kumir-BrGxaUVr.js} +1 -1
  171. package/dist/app/assets/{kusto-BuL9qwXk.js → kusto-DeyIYXML.js} +1 -1
  172. package/dist/app/assets/{latex-BAc_zS_4.js → latex-DwJWQSKl.js} +1 -1
  173. package/dist/app/assets/{latte-BzZFX_wH.js → latte-DiAT5mgQ.js} +1 -1
  174. package/dist/app/assets/{layout-DOHRtR3x.js → layout-Ci0rB0BF.js} +1 -1
  175. package/dist/app/assets/{less-DATW_Ot3.js → less-DAct2ixG.js} +1 -1
  176. package/dist/app/assets/{lilypond-DSmAdE7B.js → lilypond-CznC99Kp.js} +1 -1
  177. package/dist/app/assets/{linear-rr7FzlEM.js → linear-Db4iWNSq.js} +1 -1
  178. package/dist/app/assets/{liquid-CF8lqz9m.js → liquid-BxjgrxHp.js} +1 -1
  179. package/dist/app/assets/{lisp-BUPAsWUh.js → lisp-C4lgit6G.js} +1 -1
  180. package/dist/app/assets/{livescript-B8CIEQDH.js → livescript-BEQgCon6.js} +1 -1
  181. package/dist/app/assets/{llvm-DGaRc9w0.js → llvm-Xf0jCPO4.js} +1 -1
  182. package/dist/app/assets/{log-XuE3Wqn5.js → log-BiVfEwum.js} +1 -1
  183. package/dist/app/assets/{lolcode-Clk-p_j2.js → lolcode-BSO8DuGE.js} +1 -1
  184. package/dist/app/assets/{lua-BLczZbJa.js → lua-DGW916x5.js} +1 -1
  185. package/dist/app/assets/{magma-DTO3ftgF.js → magma-OhptpZ13.js} +1 -1
  186. package/dist/app/assets/{makefile-OSVaZHmV.js → makefile-DBnxpcUU.js} +1 -1
  187. package/dist/app/assets/{markdown-InD7dXs9.js → markdown-BznySwma.js} +1 -1
  188. package/dist/app/assets/{markup-BN6MlRZT.js → markup-DqRz3LJm.js} +1 -1
  189. package/dist/app/assets/{markup-templating-DRXAmI1c.js → markup-templating-BKB_GGuz.js} +1 -1
  190. package/dist/app/assets/{matlab-CV_q70_G.js → matlab-3N0TcL6N.js} +1 -1
  191. package/dist/app/assets/{maxscript-Ck_8H__C.js → maxscript-BZvlaoGH.js} +1 -1
  192. package/dist/app/assets/{mel-D9MU0rZa.js → mel-BSmK0T7H.js} +1 -1
  193. package/dist/app/assets/{mermaid-DshECBS6.js → mermaid-Duc2qb5F.js} +1 -1
  194. package/dist/app/assets/{min-CfLzpwyh.js → min-BKNYKdIk.js} +1 -1
  195. package/dist/app/assets/{mindmap-definition-QFDTVHPH-C7XGlydX.js → mindmap-definition-QFDTVHPH-CnWL0xVD.js} +1 -1
  196. package/dist/app/assets/{mizar-WBJ-SwIG.js → mizar-BI02SHrx.js} +1 -1
  197. package/dist/app/assets/{mongodb-CmzRTKBq.js → mongodb-CRQm09Xn.js} +1 -1
  198. package/dist/app/assets/{monkey-W1yB--1T.js → monkey-Dv34nuh4.js} +1 -1
  199. package/dist/app/assets/{moonscript-BD5hlCXn.js → moonscript-50xJ2oId.js} +1 -1
  200. package/dist/app/assets/{n1ql-CwugAEoM.js → n1ql-Cm4qd43r.js} +1 -1
  201. package/dist/app/assets/{n4js-tFC-Lsvd.js → n4js-LXxDuAtT.js} +1 -1
  202. package/dist/app/assets/{nand2tetris-hdl-hzvfBJxH.js → nand2tetris-hdl-CkSPhEoK.js} +1 -1
  203. package/dist/app/assets/{naniscript-DUtjoUL1.js → naniscript-CopSq9dX.js} +1 -1
  204. package/dist/app/assets/{nasm-Dcckq6ib.js → nasm-D7A7rGAF.js} +1 -1
  205. package/dist/app/assets/{neon-DeVv09BE.js → neon-BAKsC02_.js} +1 -1
  206. package/dist/app/assets/{nevod-CAq9Kfwt.js → nevod-C-euYOSr.js} +1 -1
  207. package/dist/app/assets/{nginx-C8GHDEqt.js → nginx-B9jALad5.js} +1 -1
  208. package/dist/app/assets/{nim-BqdyUedD.js → nim-BBHZHQ5E.js} +1 -1
  209. package/dist/app/assets/{nix-514mCcjs.js → nix-DmfkvvNO.js} +1 -1
  210. package/dist/app/assets/{nsis-CdKqXn3g.js → nsis-CiSC6aDO.js} +1 -1
  211. package/dist/app/assets/{objectivec-uPp8iMUn.js → objectivec-CZ2ovZFJ.js} +1 -1
  212. package/dist/app/assets/{ocaml-D4EB6rFL.js → ocaml-CyX9uBPK.js} +1 -1
  213. package/dist/app/assets/{opencl-BN8tmrp-.js → opencl-BSrZYM8c.js} +1 -1
  214. package/dist/app/assets/{openqasm-CZT9yVLH.js → openqasm-DOuul9tf.js} +1 -1
  215. package/dist/app/assets/{oz-xEnzbfGI.js → oz-rsJy_2_r.js} +1 -1
  216. package/dist/app/assets/{parigp-PN33G_ZS.js → parigp-DMZs3sMP.js} +1 -1
  217. package/dist/app/assets/{parser-YigtK2Gn.js → parser-CLeK_wYt.js} +1 -1
  218. package/dist/app/assets/{pascal-BSQHqJO2.js → pascal-DZ4qTuqN.js} +1 -1
  219. package/dist/app/assets/{pascaligo-B3om_nlX.js → pascaligo-D6ziPQJn.js} +1 -1
  220. package/dist/app/assets/{pcaxis-B_qwjIH4.js → pcaxis-Bsa4kJ1N.js} +1 -1
  221. package/dist/app/assets/{peoplecode-G3CTxh8q.js → peoplecode-BtULIv-H.js} +1 -1
  222. package/dist/app/assets/{perl-CBvGMSZZ.js → perl-CswAAlfX.js} +1 -1
  223. package/dist/app/assets/{php-DewJLtev.js → php-Bv-ALqgC.js} +1 -1
  224. package/dist/app/assets/{php-extras-BT2DdjGn.js → php-extras-CGQHigyg.js} +1 -1
  225. package/dist/app/assets/{phpdoc-DiQXOd9D.js → phpdoc-CbRxSWh6.js} +1 -1
  226. package/dist/app/assets/{pieDiagram-DEJITSTG-CYXmqIpD.js → pieDiagram-DEJITSTG-VWWiVQxO.js} +1 -1
  227. package/dist/app/assets/{plsql-BzUO3h3t.js → plsql-DQRexRDV.js} +1 -1
  228. package/dist/app/assets/{powerquery-D_713gdU.js → powerquery-B84pC27o.js} +1 -1
  229. package/dist/app/assets/{powershell-D7IGyPyT.js → powershell-CYB8PDOS.js} +1 -1
  230. package/dist/app/assets/{processing-CULfTuKk.js → processing-IV7AOKMt.js} +1 -1
  231. package/dist/app/assets/{prolog-DI8sHw_1.js → prolog-C5Umzi6Y.js} +1 -1
  232. package/dist/app/assets/{promql-DdWPpZzX.js → promql-DnQb00nJ.js} +1 -1
  233. package/dist/app/assets/{properties-UUBptvjg.js → properties-JtX62kym.js} +1 -1
  234. package/dist/app/assets/{protobuf-Yh4lBroy.js → protobuf-D0u54vfT.js} +1 -1
  235. package/dist/app/assets/{psl-CKuqp255.js → psl-D2wfxc3N.js} +1 -1
  236. package/dist/app/assets/{pug-Duz4hJlP.js → pug-Cfscfbjt.js} +1 -1
  237. package/dist/app/assets/{puppet-Tenfq4aE.js → puppet-DTE3iXOW.js} +1 -1
  238. package/dist/app/assets/{pure-CTE3YKFb.js → pure-YKO-tWRN.js} +1 -1
  239. package/dist/app/assets/{purebasic-BzV6ZqWW.js → purebasic-BjxfhqXa.js} +1 -1
  240. package/dist/app/assets/{purescript-CjSCYtGb.js → purescript-BYtsXeuA.js} +1 -1
  241. package/dist/app/assets/{q-BTX8RKFy.js → q-BGBZJwiX.js} +1 -1
  242. package/dist/app/assets/{qml-CGjBjP81.js → qml-DTmpu0_b.js} +1 -1
  243. package/dist/app/assets/{qore-5Gggmt2I.js → qore-DV3zUzln.js} +1 -1
  244. package/dist/app/assets/{qsharp-DhqE1FPx.js → qsharp-BB4ZU4l7.js} +1 -1
  245. package/dist/app/assets/{quadrantDiagram-34T5L4WZ-BbnPMKp-.js → quadrantDiagram-34T5L4WZ-DZe4FQWm.js} +1 -1
  246. package/dist/app/assets/{r-Dr0jr5tD.js → r-BuRdYuOg.js} +1 -1
  247. package/dist/app/assets/{racket-NVUa01EO.js → racket-BdOLCXmL.js} +1 -1
  248. package/dist/app/assets/{reason-Bx5CI0l0.js → reason-BCIhgqTr.js} +1 -1
  249. package/dist/app/assets/{regex-12879jLK.js → regex-CeDcXiBn.js} +1 -1
  250. package/dist/app/assets/{rego-w2Fhvb_N.js → rego-Bug6Gtky.js} +1 -1
  251. package/dist/app/assets/{renpy-gPxX0z3Q.js → renpy-C1LtsjtW.js} +1 -1
  252. package/dist/app/assets/{requirementDiagram-MS252O5E-BhOU7uOd.js → requirementDiagram-MS252O5E-BYaMMinK.js} +1 -1
  253. package/dist/app/assets/{rest-C39bU2b1.js → rest-Fa9SyY67.js} +1 -1
  254. package/dist/app/assets/{rip-RLtTVF0Y.js → rip-SetkIYoC.js} +1 -1
  255. package/dist/app/assets/{roboconf-BJckt4oD.js → roboconf-CRy7RXFK.js} +1 -1
  256. package/dist/app/assets/{robotframework-DCR96jiT.js → robotframework-DHo4R8pp.js} +1 -1
  257. package/dist/app/assets/{ruby-CRs8uxXB.js → ruby-DM2JwZlW.js} +1 -1
  258. package/dist/app/assets/{rust-C0bGL254.js → rust-_NNFafik.js} +1 -1
  259. package/dist/app/assets/{sankeyDiagram-XADWPNL6-CFgkd6GO.js → sankeyDiagram-XADWPNL6-DAunyA-1.js} +1 -1
  260. package/dist/app/assets/{sas-CkLtpL1M.js → sas-CAllZx8n.js} +1 -1
  261. package/dist/app/assets/{sass-FNfCYuQd.js → sass-Hf4UBtzK.js} +1 -1
  262. package/dist/app/assets/{scala-Dy5lip5O.js → scala-DkNiERTA.js} +1 -1
  263. package/dist/app/assets/{scheme-pkKED5As.js → scheme-cRBlcCac.js} +1 -1
  264. package/dist/app/assets/{scss-DrZ4F_S5.js → scss-D8mZ_Za-.js} +1 -1
  265. package/dist/app/assets/{sequenceDiagram-FGHM5R23-t5z2WRg9.js → sequenceDiagram-FGHM5R23-sNXmL4Cw.js} +1 -1
  266. package/dist/app/assets/{shell-session-tfqRzQ64.js → shell-session-DeKXiekb.js} +1 -1
  267. package/dist/app/assets/{smali-D9oJJF_a.js → smali-DBMpR0WA.js} +1 -1
  268. package/dist/app/assets/{smalltalk-FhicZwdZ.js → smalltalk-BPhQ9s3z.js} +1 -1
  269. package/dist/app/assets/{smarty-RTVkhvGe.js → smarty-BMg06VgP.js} +1 -1
  270. package/dist/app/assets/{sml-8jU1U62j.js → sml-DLGSWP51.js} +1 -1
  271. package/dist/app/assets/{solidity-DLvpuywG.js → solidity-DeQT3dsc.js} +1 -1
  272. package/dist/app/assets/{solution-file-BOwCbL9x.js → solution-file-rfNIkT7V.js} +1 -1
  273. package/dist/app/assets/{soy-Dye6FppK.js → soy-zYtC6_ht.js} +1 -1
  274. package/dist/app/assets/{sparql-BRIOTA6e.js → sparql-CGa1CKp5.js} +1 -1
  275. package/dist/app/assets/{splunk-spl-xjEKSM5T.js → splunk-spl-C8v7uxfM.js} +1 -1
  276. package/dist/app/assets/{sqf-BTXRZqz9.js → sqf-DPaz1Lai.js} +1 -1
  277. package/dist/app/assets/{sql-LIGcsz7H.js → sql-CRZBr2wA.js} +1 -1
  278. package/dist/app/assets/{squirrel-D1i-yP9F.js → squirrel-CrbdCeO4.js} +1 -1
  279. package/dist/app/assets/{stan-Bz-MTQlG.js → stan-BKYvxpSb.js} +1 -1
  280. package/dist/app/assets/{stateDiagram-FHFEXIEX-INV79XkW.js → stateDiagram-FHFEXIEX-D36OCRvJ.js} +1 -1
  281. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-DmqGcWux.js +1 -0
  282. package/dist/app/assets/{stylus-CPcHbGGR.js → stylus-Ci4_F8nK.js} +1 -1
  283. package/dist/app/assets/{swift-CMnIAhC_.js → swift-mmkHLTYT.js} +1 -1
  284. package/dist/app/assets/{systemd-CnQ86vtn.js → systemd-DAUIxyR2.js} +1 -1
  285. package/dist/app/assets/{t4-cs-ClADD8kZ.js → t4-cs-BED2tz-u.js} +1 -1
  286. package/dist/app/assets/{t4-templating-BxEXIn9V.js → t4-templating--ieaosVt.js} +1 -1
  287. package/dist/app/assets/{t4-vb-BuQFrDQM.js → t4-vb-Dq0Puemw.js} +1 -1
  288. package/dist/app/assets/{tap-D-OeTv7J.js → tap-C_XPd1SR.js} +1 -1
  289. package/dist/app/assets/{tcl-D4EWmvqA.js → tcl-DJZd1oZX.js} +1 -1
  290. package/dist/app/assets/{textile-vCa5WeBr.js → textile-wcSaXbdv.js} +1 -1
  291. package/dist/app/assets/{timeline-definition-GMOUNBTQ-CZVpkWZR.js → timeline-definition-GMOUNBTQ-BewoZYzR.js} +1 -1
  292. package/dist/app/assets/{toml-CyQfWyMg.js → toml-CKDZZOrE.js} +1 -1
  293. package/dist/app/assets/{tremor-DTpakXR3.js → tremor-B1-Zw3yS.js} +1 -1
  294. package/dist/app/assets/{tt2-I3k-jzpY.js → tt2-BHFaXCZF.js} +1 -1
  295. package/dist/app/assets/{turtle-BjS87MX7.js → turtle-KSw4upem.js} +1 -1
  296. package/dist/app/assets/{twig-BYK2hDMY.js → twig-BRBoP8KB.js} +1 -1
  297. package/dist/app/assets/{typescript-DNEOvUVG.js → typescript-bns4dUtY.js} +1 -1
  298. package/dist/app/assets/{typoscript-hqzFge6d.js → typoscript-BVmk6GiM.js} +1 -1
  299. package/dist/app/assets/{unrealscript-_-NzaZj0.js → unrealscript-hTYhevmS.js} +1 -1
  300. package/dist/app/assets/{uorazor-BMR9qMW5.js → uorazor-BY_i1glx.js} +1 -1
  301. package/dist/app/assets/{uri-BSGWfMxZ.js → uri-Cshg9KEA.js} +1 -1
  302. package/dist/app/assets/{v-CLtdeXIK.js → v-2HZBfvBQ.js} +1 -1
  303. package/dist/app/assets/{vala-wzCcqtKA.js → vala-DpwXQy33.js} +1 -1
  304. package/dist/app/assets/{vbnet-DGCLmXdC.js → vbnet-CzcanlBM.js} +1 -1
  305. package/dist/app/assets/{velocity-DX_5gTOq.js → velocity-CV3Erd1R.js} +1 -1
  306. package/dist/app/assets/{vennDiagram-DHZGUBPP-Dq1FXdcO.js → vennDiagram-DHZGUBPP-CYp9O0hw.js} +1 -1
  307. package/dist/app/assets/{verilog-DeAFTKrK.js → verilog-DUFfdhmC.js} +1 -1
  308. package/dist/app/assets/{vhdl-CgPp3m3I.js → vhdl-Ehst2swj.js} +1 -1
  309. package/dist/app/assets/{vim-ZY6C4NgO.js → vim-ChBxD9-s.js} +1 -1
  310. package/dist/app/assets/{visual-basic-DmV7laqn.js → visual-basic-DhxNPprf.js} +1 -1
  311. package/dist/app/assets/{wardley-RL74JXVD-OqiGOeix.js → wardley-RL74JXVD-ChpRMv2u.js} +1 -1
  312. package/dist/app/assets/{wardleyDiagram-NUSXRM2D-XXEOUAR6.js → wardleyDiagram-NUSXRM2D-CFpThRE-.js} +1 -1
  313. package/dist/app/assets/{warpscript-CST9Acbf.js → warpscript-Dx1Itmpb.js} +1 -1
  314. package/dist/app/assets/{wasm-D44TvCcf.js → wasm-BvTc7Cyo.js} +1 -1
  315. package/dist/app/assets/{web-idl-CUAX3ogm.js → web-idl-B43dy8xT.js} +1 -1
  316. package/dist/app/assets/{wiki-KNEqZQWK.js → wiki-C0vje4IO.js} +1 -1
  317. package/dist/app/assets/{wolfram-CZdD1bRd.js → wolfram-B1twTrAy.js} +1 -1
  318. package/dist/app/assets/{wren-PITvEkQ4.js → wren-CpwJ20dT.js} +1 -1
  319. package/dist/app/assets/{xeora-BM_ABt9y.js → xeora-Q9elMskQ.js} +1 -1
  320. package/dist/app/assets/{xml-doc-249eg8mF.js → xml-doc-eO6FH-U3.js} +1 -1
  321. package/dist/app/assets/{xojo-M3SASV_b.js → xojo-1Fr7QqPR.js} +1 -1
  322. package/dist/app/assets/{xquery-BWv2VkcM.js → xquery-BMmMoA1b.js} +1 -1
  323. package/dist/app/assets/{xychartDiagram-5P7HB3ND-CvXT15VO.js → xychartDiagram-5P7HB3ND-De8Xu1fj.js} +1 -1
  324. package/dist/app/assets/{yaml-B70AwQ7Y.js → yaml-34lcFD2P.js} +1 -1
  325. package/dist/app/assets/{yang-DffrsIpd.js → yang-DervT_oZ.js} +1 -1
  326. package/dist/app/assets/{zig-C9vlYfKL.js → zig-Cipb22UI.js} +1 -1
  327. package/dist/app/index.html +2 -2
  328. package/dist/index.cjs +2523 -635
  329. package/dist/index.js +2555 -636
  330. package/package.json +4 -4
  331. package/dist/app/assets/channel-Cx11sSAI.js +0 -1
  332. package/dist/app/assets/classDiagram-6PBFFD2Q-BQrwJXsB.js +0 -1
  333. package/dist/app/assets/classDiagram-v2-HSJHXN6E-BQrwJXsB.js +0 -1
  334. package/dist/app/assets/clone-DHPdZQ_6.js +0 -1
  335. package/dist/app/assets/index-D972kqET.css +0 -1
  336. package/dist/app/assets/index-DmMWBDJR.js +0 -747
  337. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-DkwGLXRp.js +0 -1
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  // src/components/chat.tsx
2
- import * as React22 from "react";
2
+ import * as React26 from "react";
3
3
  import {
4
- ArrowDown,
4
+ ArrowDown as ArrowDown2,
5
5
  FileText as FileText2,
6
6
  ImageIcon,
7
- Loader2 as Loader23,
7
+ Loader2 as Loader24,
8
8
  Pencil as Pencil3,
9
9
  Quote,
10
10
  RefreshCw as RefreshCw2,
@@ -114,7 +114,10 @@ import {
114
114
  import "@langchain/core/messages/tool";
115
115
  import {
116
116
  ChatMessageEventTypeEnum,
117
- ChatMessageTypeEnum
117
+ ChatMessageTypeEnum,
118
+ REQUEST_USER_INPUT_TOOL_NAME,
119
+ isLangGraphInterruptPayload,
120
+ isClientToolRequest
118
121
  } from "@xpert-ai/chatkit-types";
119
122
 
120
123
  // src/lib/api-config.ts
@@ -646,6 +649,10 @@ function ParentMessengerProvider({
646
649
  }
647
650
  return;
648
651
  }
652
+ const requestHumanInput = params.planMode === true || params.state?.[STATE_VARIABLE_HUMAN2]?.planMode === true ? {
653
+ ...humanInput,
654
+ planMode: true
655
+ } : humanInput;
649
656
  const newMessage = {
650
657
  id: createMessageId(),
651
658
  type: "human",
@@ -659,11 +666,11 @@ function ParentMessengerProvider({
659
666
  const requestOptions = buildInjectedRequestOptions({
660
667
  defaults: latestOptionsRef.current?.request,
661
668
  state: params.state,
662
- humanInput
669
+ humanInput: requestHumanInput
663
670
  });
664
671
  stream?.submit(
665
672
  {
666
- input: humanInput,
673
+ input: requestHumanInput,
667
674
  ...requestOptions.state ? { state: requestOptions.state } : {}
668
675
  },
669
676
  {
@@ -926,6 +933,11 @@ function getBusyComposerShortcutFollowUpMode(useQueueShortcut) {
926
933
  return useQueueShortcut ? "queue" : "steer";
927
934
  }
928
935
 
936
+ // src/lib/todos.ts
937
+ function countCompletedTodos(items) {
938
+ return items.filter((item) => item.status === "completed").length;
939
+ }
940
+
929
941
  // src/providers/Stream.tsx
930
942
  import { jsx as jsx2 } from "react/jsx-runtime";
931
943
  var StreamContext = createContext2(void 0);
@@ -945,6 +957,7 @@ import {
945
957
  Globe,
946
958
  Images,
947
959
  Lightbulb,
960
+ ListChecks,
948
961
  Paperclip,
949
962
  Pencil,
950
963
  Plus,
@@ -1090,6 +1103,9 @@ var en_US_default = {
1090
1103
  manualQueueHint: "Ready to send as a new run",
1091
1104
  steerHint: "Injects after the current tool call"
1092
1105
  },
1106
+ todos: {
1107
+ summary: "{{total}} tasks, {{completed}} completed"
1108
+ },
1093
1109
  errors: {
1094
1110
  loadMessages: "Failed to load thread messages",
1095
1111
  createThread: "Failed to create thread",
@@ -1121,8 +1137,22 @@ var en_US_default = {
1121
1137
  composer: {
1122
1138
  openMenu: "Open menu",
1123
1139
  addAttachment: "Add attachment",
1140
+ planMode: "Plan mode",
1124
1141
  removeReference: "Remove reference",
1125
- quoteSelection: "Quote selection"
1142
+ quoteSelection: "Quote selection",
1143
+ requestUserInput: {
1144
+ title: "Input requested",
1145
+ recommended: "Recommended",
1146
+ other: "Other",
1147
+ otherPlaceholder: "Type a custom answer",
1148
+ continue: "Continue",
1149
+ dismiss: "Dismiss",
1150
+ previousQuestion: "Previous question",
1151
+ nextQuestion: "Next question",
1152
+ questionProgress: "{{current}} of {{total}}",
1153
+ optionInfo: "Details for {{label}}",
1154
+ submit: "Continue"
1155
+ }
1126
1156
  },
1127
1157
  sheet: {
1128
1158
  close: "Close"
@@ -1149,7 +1179,58 @@ var en_US_default = {
1149
1179
  reasoning: "Reasoning",
1150
1180
  loading: "Loading",
1151
1181
  thinking: "Thinking",
1152
- answering: "Answering"
1182
+ answering: "Answering",
1183
+ requestUserInputResult: {
1184
+ title: "Selections confirmed",
1185
+ option: "Option",
1186
+ other: "Other"
1187
+ },
1188
+ toolGroup: {
1189
+ status: {
1190
+ running: "Processing",
1191
+ success: "Processed",
1192
+ fail: "Processing failed"
1193
+ },
1194
+ inputTitle: "Input",
1195
+ outputTitle: "Output",
1196
+ errorTitle: "Error",
1197
+ jsonTitle: "JSON",
1198
+ jsonTree: "Tree",
1199
+ jsonRaw: "Raw",
1200
+ copy: "Copy",
1201
+ copied: "Copied",
1202
+ separator: ", ",
1203
+ categories: {
1204
+ files: {
1205
+ one: "{{count}} file",
1206
+ other: "{{count}} files"
1207
+ },
1208
+ searches: {
1209
+ one: "{{count}} search",
1210
+ other: "{{count}} searches"
1211
+ },
1212
+ commands: {
1213
+ one: "{{count}} command",
1214
+ other: "{{count}} commands"
1215
+ },
1216
+ lists: {
1217
+ one: "{{count}} list",
1218
+ other: "{{count}} lists"
1219
+ },
1220
+ tasks: {
1221
+ one: "{{count}} task",
1222
+ other: "{{count}} tasks"
1223
+ },
1224
+ knowledges: {
1225
+ one: "{{count}} knowledge result",
1226
+ other: "{{count}} knowledge results"
1227
+ },
1228
+ tools: {
1229
+ one: "{{count}} tool",
1230
+ other: "{{count}} tools"
1231
+ }
1232
+ }
1233
+ }
1153
1234
  }
1154
1235
  };
1155
1236
 
@@ -1194,6 +1275,9 @@ var zh_CN_default = {
1194
1275
  manualQueueHint: "\u4FDD\u7559\u4E3A\u5F85\u53D1\u9001\uFF0C\u53EF\u624B\u52A8\u5F00\u542F\u65B0\u4E00\u8F6E",
1195
1276
  steerHint: "\u5F53\u524D\u5DE5\u5177\u8C03\u7528\u5B8C\u6210\u540E\u6CE8\u5165"
1196
1277
  },
1278
+ todos: {
1279
+ summary: "\u5171 {{total}} \u4E2A\u4EFB\u52A1\uFF0C\u5DF2\u7ECF\u5B8C\u6210 {{completed}} \u4E2A"
1280
+ },
1197
1281
  errors: {
1198
1282
  loadMessages: "\u52A0\u8F7D\u7EBF\u7A0B\u6D88\u606F\u5931\u8D25",
1199
1283
  createThread: "\u521B\u5EFA\u7EBF\u7A0B\u5931\u8D25",
@@ -1225,8 +1309,22 @@ var zh_CN_default = {
1225
1309
  composer: {
1226
1310
  openMenu: "\u6253\u5F00\u83DC\u5355",
1227
1311
  addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
1312
+ planMode: "\u8BA1\u5212\u6A21\u5F0F",
1228
1313
  removeReference: "\u79FB\u9664\u5F15\u7528",
1229
- quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
1314
+ quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9",
1315
+ requestUserInput: {
1316
+ title: "\u9700\u8981\u4F60\u7684\u8F93\u5165",
1317
+ recommended: "\u63A8\u8350",
1318
+ other: "\u5176\u4ED6",
1319
+ otherPlaceholder: "\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54",
1320
+ continue: "\u7EE7\u7EED",
1321
+ dismiss: "\u5173\u95ED",
1322
+ previousQuestion: "\u4E0A\u4E00\u4E2A\u95EE\u9898",
1323
+ nextQuestion: "\u4E0B\u4E00\u4E2A\u95EE\u9898",
1324
+ questionProgress: "{{current}} / {{total}}",
1325
+ optionInfo: "{{label}} \u7684\u8BF4\u660E",
1326
+ submit: "\u7EE7\u7EED"
1327
+ }
1230
1328
  },
1231
1329
  sheet: {
1232
1330
  close: "\u5173\u95ED"
@@ -1253,7 +1351,58 @@ var zh_CN_default = {
1253
1351
  reasoning: "\u63A8\u7406",
1254
1352
  loading: "\u6B63\u5728\u52A0\u8F7D",
1255
1353
  thinking: "\u6B63\u5728\u601D\u8003",
1256
- answering: "\u6B63\u5728\u751F\u6210"
1354
+ answering: "\u6B63\u5728\u751F\u6210",
1355
+ requestUserInputResult: {
1356
+ title: "\u5DF2\u786E\u8BA4\u9009\u62E9",
1357
+ option: "\u9009\u9879",
1358
+ other: "\u5176\u4ED6"
1359
+ },
1360
+ toolGroup: {
1361
+ status: {
1362
+ running: "\u6B63\u5728\u5904\u7406",
1363
+ success: "\u5DF2\u5904\u7406",
1364
+ fail: "\u5904\u7406\u5931\u8D25"
1365
+ },
1366
+ inputTitle: "\u8F93\u5165",
1367
+ outputTitle: "\u8F93\u51FA",
1368
+ errorTitle: "\u9519\u8BEF",
1369
+ jsonTitle: "JSON",
1370
+ jsonTree: "\u6811\u5F62",
1371
+ jsonRaw: "\u539F\u59CB",
1372
+ copy: "\u590D\u5236",
1373
+ copied: "\u5DF2\u590D\u5236",
1374
+ separator: "\uFF0C",
1375
+ categories: {
1376
+ files: {
1377
+ one: "{{count}} \u4E2A\u6587\u4EF6",
1378
+ other: "{{count}} \u4E2A\u6587\u4EF6"
1379
+ },
1380
+ searches: {
1381
+ one: "{{count}} \u4E2A\u641C\u7D22",
1382
+ other: "{{count}} \u4E2A\u641C\u7D22"
1383
+ },
1384
+ commands: {
1385
+ one: "{{count}} \u4E2A\u547D\u4EE4",
1386
+ other: "{{count}} \u4E2A\u547D\u4EE4"
1387
+ },
1388
+ lists: {
1389
+ one: "{{count}} \u4E2A\u5217\u8868",
1390
+ other: "{{count}} \u4E2A\u5217\u8868"
1391
+ },
1392
+ tasks: {
1393
+ one: "{{count}} \u4E2A\u4EFB\u52A1",
1394
+ other: "{{count}} \u4E2A\u4EFB\u52A1"
1395
+ },
1396
+ knowledges: {
1397
+ one: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C",
1398
+ other: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C"
1399
+ },
1400
+ tools: {
1401
+ one: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528",
1402
+ other: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528"
1403
+ }
1404
+ }
1405
+ }
1257
1406
  }
1258
1407
  };
1259
1408
 
@@ -1689,6 +1838,8 @@ function ComposerMenu({
1689
1838
  onAttachmentClick,
1690
1839
  onToolSelect,
1691
1840
  selectedTool,
1841
+ planModeEnabled = false,
1842
+ onPlanModeChange,
1692
1843
  disabled = false
1693
1844
  }) {
1694
1845
  const { t } = useChatkitTranslation();
@@ -1697,9 +1848,6 @@ function ComposerMenu({
1697
1848
  const roundedClass = getRoundedClass(theme.radius);
1698
1849
  const attachmentsEnabled = composer?.attachments?.enabled ?? false;
1699
1850
  const tools = composer?.tools ?? [];
1700
- if (!attachmentsEnabled && tools.length === 0) {
1701
- return null;
1702
- }
1703
1851
  const handleAttachmentClick = () => {
1704
1852
  onAttachmentClick?.();
1705
1853
  setOpen(false);
@@ -1708,6 +1856,9 @@ function ComposerMenu({
1708
1856
  onToolSelect?.(tool);
1709
1857
  setOpen(false);
1710
1858
  };
1859
+ const handlePlanModeToggle = () => {
1860
+ onPlanModeChange?.(!planModeEnabled);
1861
+ };
1711
1862
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
1712
1863
  /* @__PURE__ */ jsx6(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1713
1864
  Button,
@@ -1747,8 +1898,46 @@ function ComposerMenu({
1747
1898
  ]
1748
1899
  }
1749
1900
  ),
1750
- tools.length > 0 && /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" })
1901
+ /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" })
1751
1902
  ] }),
1903
+ /* @__PURE__ */ jsxs(
1904
+ "button",
1905
+ {
1906
+ type: "button",
1907
+ role: "switch",
1908
+ "aria-checked": planModeEnabled,
1909
+ onClick: handlePlanModeToggle,
1910
+ className: cn(
1911
+ "flex items-center gap-3 px-3 py-2 text-sm hover:bg-muted transition-colors",
1912
+ roundedClass,
1913
+ planModeEnabled && "bg-muted"
1914
+ ),
1915
+ children: [
1916
+ /* @__PURE__ */ jsx6("span", { className: "flex h-6 w-6 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ jsx6(ListChecks, { size: 16 }) }),
1917
+ /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 text-left", children: t("composer.planMode") }),
1918
+ /* @__PURE__ */ jsx6(
1919
+ "span",
1920
+ {
1921
+ className: cn(
1922
+ "relative inline-flex h-6 w-10 shrink-0 items-center rounded-full transition-colors",
1923
+ planModeEnabled ? "bg-primary" : "bg-muted-foreground/20"
1924
+ ),
1925
+ "aria-hidden": "true",
1926
+ children: /* @__PURE__ */ jsx6(
1927
+ "span",
1928
+ {
1929
+ className: cn(
1930
+ "inline-block h-5 w-5 rounded-full bg-background shadow-sm transition-transform",
1931
+ planModeEnabled ? "translate-x-[18px]" : "translate-x-0.5"
1932
+ )
1933
+ }
1934
+ )
1935
+ }
1936
+ )
1937
+ ]
1938
+ }
1939
+ ),
1940
+ tools.length > 0 && /* @__PURE__ */ jsx6("div", { className: "my-1 h-px bg-border" }),
1752
1941
  tools.map((tool) => /* @__PURE__ */ jsxs(
1753
1942
  "button",
1754
1943
  {
@@ -2071,19 +2260,23 @@ function HistorySidebar({
2071
2260
  setOpen(false);
2072
2261
  };
2073
2262
  return /* @__PURE__ */ jsxs6(Sheet, { open, onOpenChange: setOpen, children: [
2074
- /* @__PURE__ */ jsx11(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
2075
- Button,
2076
- {
2077
- variant: "ghost",
2078
- size: "icon",
2079
- disabled,
2080
- className: "h-8 w-8 cursor-pointer",
2081
- children: [
2082
- /* @__PURE__ */ jsx11(History, { size: 16 }),
2083
- /* @__PURE__ */ jsx11("span", { className: "sr-only", children: t("history.threadHistory") })
2084
- ]
2085
- }
2086
- ) }),
2263
+ /* @__PURE__ */ jsxs6(Tooltip, { children: [
2264
+ /* @__PURE__ */ jsx11(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx11("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx11(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
2265
+ Button,
2266
+ {
2267
+ variant: "ghost",
2268
+ size: "icon",
2269
+ disabled,
2270
+ className: "h-8 w-8 cursor-pointer",
2271
+ "aria-label": t("history.threadHistory"),
2272
+ children: [
2273
+ /* @__PURE__ */ jsx11(History, { size: 16 }),
2274
+ /* @__PURE__ */ jsx11("span", { className: "sr-only", children: t("history.threadHistory") })
2275
+ ]
2276
+ }
2277
+ ) }) }) }),
2278
+ /* @__PURE__ */ jsx11(TooltipContent, { side: "bottom", children: t("history.threadHistory") })
2279
+ ] }),
2087
2280
  /* @__PURE__ */ jsxs6(SheetContent, { side: "right", className: "w-80 p-0", children: [
2088
2281
  /* @__PURE__ */ jsx11(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ jsx11(SheetTitle, { children: t("history.title") }) }),
2089
2282
  /* @__PURE__ */ jsx11("div", { className: "p-4", children: /* @__PURE__ */ jsxs6(
@@ -2179,6 +2372,7 @@ function PendingFollowUps({
2179
2372
  onSendNow,
2180
2373
  onEdit,
2181
2374
  onRemove,
2375
+ attachToComposer = true,
2182
2376
  className
2183
2377
  }) {
2184
2378
  const { t } = useChatkitTranslation();
@@ -2201,8 +2395,9 @@ function PendingFollowUps({
2201
2395
  "div",
2202
2396
  {
2203
2397
  className: cn(
2204
- "space-y-2 mx-2 p-2 border border-border border-b-0",
2205
- rounded.top,
2398
+ "space-y-2 mx-2 p-2 border border-border",
2399
+ attachToComposer ? "border-b-0" : null,
2400
+ attachToComposer ? rounded.top : rounded.panel,
2206
2401
  className
2207
2402
  ),
2208
2403
  children: /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
@@ -2433,158 +2628,913 @@ function PendingFollowUps({
2433
2628
  );
2434
2629
  }
2435
2630
 
2436
- // src/components/thread/messages/ai.tsx
2437
- import * as React15 from "react";
2438
- import { ChevronDown, CheckCircle2, XCircle, Loader2 as Loader22 } from "lucide-react";
2439
-
2440
- // src/components/ui/badge.tsx
2631
+ // src/components/composer/pending-todos.tsx
2441
2632
  import * as React11 from "react";
2442
- import { jsx as jsx13 } from "react/jsx-runtime";
2443
- 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";
2444
- var variants = {
2445
- default: "bg-primary text-primary-foreground",
2446
- secondary: "bg-secondary text-secondary-foreground",
2447
- outline: "border-input text-foreground"
2448
- };
2449
- var Badge = React11.forwardRef(
2450
- ({ className, variant = "default", ...props }, ref) => {
2451
- return /* @__PURE__ */ jsx13("span", { ref, className: cn(base, variants[variant], className), ...props });
2633
+ import {
2634
+ CheckCircle2,
2635
+ ChevronDown,
2636
+ Circle,
2637
+ CircleDashed,
2638
+ ListTodo
2639
+ } from "lucide-react";
2640
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2641
+ function useRoundedClasses2() {
2642
+ const { theme } = useTheme();
2643
+ return {
2644
+ top: theme.radius ? {
2645
+ pill: "rounded-t-full",
2646
+ round: "rounded-t-xl",
2647
+ soft: "rounded-t-lg",
2648
+ sharp: "rounded-t-none"
2649
+ }[theme.radius] : "rounded-t-lg",
2650
+ panel: getRoundedClass(theme.radius, "rounded-lg")
2651
+ };
2652
+ }
2653
+ function TodoStatusIcon({ status }) {
2654
+ if (status === "completed") {
2655
+ return /* @__PURE__ */ jsx13(CheckCircle2, { className: "mt-1 h-4 w-4 shrink-0 text-emerald-600" });
2452
2656
  }
2453
- );
2454
- Badge.displayName = "Badge";
2455
-
2456
- // src/components/ui/card.tsx
2457
- import * as React12 from "react";
2458
- import { jsx as jsx14 } from "react/jsx-runtime";
2459
- var Card = React12.forwardRef(
2460
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
2657
+ if (status === "in_progress") {
2658
+ return /* @__PURE__ */ jsx13(CircleDashed, { className: "mt-1 h-4 w-4 shrink-0 text-foreground/70" });
2659
+ }
2660
+ return /* @__PURE__ */ jsx13(Circle, { className: "mt-1 h-4 w-4 shrink-0 text-muted-foreground" });
2661
+ }
2662
+ function PendingTodos({
2663
+ snapshot,
2664
+ attachToComposer = true,
2665
+ className
2666
+ }) {
2667
+ const { t } = useChatkitTranslation();
2668
+ const rounded = useRoundedClasses2();
2669
+ const listId = React11.useId();
2670
+ const [isCollapsed, setIsCollapsed] = React11.useState(false);
2671
+ React11.useEffect(() => {
2672
+ setIsCollapsed(false);
2673
+ }, [snapshot?.componentId]);
2674
+ if (!snapshot || snapshot.items.length === 0) {
2675
+ return null;
2676
+ }
2677
+ const completedCount = countCompletedTodos(snapshot.items);
2678
+ return /* @__PURE__ */ jsxs8(
2461
2679
  "div",
2462
2680
  {
2463
- ref,
2681
+ "aria-live": "polite",
2464
2682
  className: cn(
2465
- "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
2683
+ "mx-2 border border-border bg-background/95 px-3 py-3 shadow-sm",
2684
+ attachToComposer ? "border-b-0" : null,
2685
+ attachToComposer ? rounded.top : rounded.panel,
2466
2686
  className
2467
2687
  ),
2468
- ...props
2688
+ children: [
2689
+ /* @__PURE__ */ jsxs8(
2690
+ "button",
2691
+ {
2692
+ type: "button",
2693
+ className: "flex w-full items-center justify-between gap-3 text-left",
2694
+ "aria-expanded": !isCollapsed,
2695
+ "aria-controls": listId,
2696
+ onClick: () => setIsCollapsed((prev) => !prev),
2697
+ children: [
2698
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-foreground", children: [
2699
+ /* @__PURE__ */ jsx13(ListTodo, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
2700
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: t("chat.todos.summary", {
2701
+ total: snapshot.items.length,
2702
+ completed: completedCount
2703
+ }) })
2704
+ ] }),
2705
+ /* @__PURE__ */ jsx13("div", { className: "flex items-center shrink-0", children: /* @__PURE__ */ jsx13(
2706
+ ChevronDown,
2707
+ {
2708
+ className: cn(
2709
+ "h-4 w-4 text-muted-foreground transition-transform",
2710
+ isCollapsed ? null : "rotate-180"
2711
+ )
2712
+ }
2713
+ ) })
2714
+ ]
2715
+ }
2716
+ ),
2717
+ !isCollapsed && /* @__PURE__ */ jsx13("ol", { id: listId, className: "mt-3 space-y-2.5", children: snapshot.items.map((item, index) => /* @__PURE__ */ jsxs8(
2718
+ "li",
2719
+ {
2720
+ className: "grid min-w-0 grid-cols-[16px_24px_minmax(0,1fr)] items-start gap-2 overflow-hidden",
2721
+ children: [
2722
+ /* @__PURE__ */ jsx13(TodoStatusIcon, { status: item.status }),
2723
+ /* @__PURE__ */ jsxs8(
2724
+ "span",
2725
+ {
2726
+ className: cn(
2727
+ "text-sm leading-6 text-foreground",
2728
+ item.status === "completed" ? "text-muted-foreground" : null
2729
+ ),
2730
+ children: [
2731
+ index + 1,
2732
+ "."
2733
+ ]
2734
+ }
2735
+ ),
2736
+ /* @__PURE__ */ jsx13(
2737
+ "span",
2738
+ {
2739
+ title: item.content,
2740
+ className: cn(
2741
+ "block min-w-0 truncate text-sm leading-6 text-foreground",
2742
+ item.status === "completed" ? "text-muted-foreground line-through" : item.status === "in_progress" ? "font-medium" : null
2743
+ ),
2744
+ children: item.content
2745
+ }
2746
+ )
2747
+ ]
2748
+ },
2749
+ item.id
2750
+ )) })
2751
+ ]
2469
2752
  }
2470
- )
2471
- );
2472
- Card.displayName = "Card";
2473
- var CardHeader = React12.forwardRef(
2474
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
2475
- );
2476
- CardHeader.displayName = "CardHeader";
2477
- var CardTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
2478
- CardTitle.displayName = "CardTitle";
2479
- var CardDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
2480
- CardDescription.displayName = "CardDescription";
2481
- var CardContent = React12.forwardRef(
2482
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("px-6 pb-6", className), ...props })
2483
- );
2484
- CardContent.displayName = "CardContent";
2485
- var CardFooter = React12.forwardRef(
2486
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
2487
- );
2488
- CardFooter.displayName = "CardFooter";
2489
- var CardAction = React12.forwardRef(
2490
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
2491
- );
2492
- CardAction.displayName = "CardAction";
2493
-
2494
- // src/components/ui/tabs.tsx
2495
- import * as React13 from "react";
2496
- import { jsx as jsx15 } from "react/jsx-runtime";
2497
- var TabsContext = React13.createContext(null);
2498
- function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
2499
- const [internalValue, setInternalValue] = React13.useState(defaultValue ?? "");
2500
- const activeValue = value ?? internalValue;
2501
- const setValue = React13.useCallback(
2502
- (nextValue) => {
2503
- if (value === void 0) setInternalValue(nextValue);
2504
- onValueChange?.(nextValue);
2505
- },
2506
- [onValueChange, value]
2507
2753
  );
2508
- return /* @__PURE__ */ jsx15(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx15("div", { className: cn("w-full", className), ...props }) });
2509
2754
  }
2510
- var TabsList = React13.forwardRef(
2511
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
2512
- "div",
2513
- {
2514
- ref,
2515
- className: cn(
2516
- "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
2517
- className
2518
- ),
2519
- role: "tablist",
2520
- ...props
2521
- }
2522
- )
2523
- );
2524
- TabsList.displayName = "TabsList";
2525
- var TabsTrigger = React13.forwardRef(
2526
- ({ className, value, onClick, ...props }, ref) => {
2527
- const context = React13.useContext(TabsContext);
2528
- if (!context) {
2529
- throw new Error("TabsTrigger must be used within Tabs");
2755
+
2756
+ // src/components/composer/request-user-input-panel.tsx
2757
+ import * as React12 from "react";
2758
+ import {
2759
+ ArrowDown,
2760
+ ArrowUp as ArrowUp2,
2761
+ Check,
2762
+ ChevronLeft,
2763
+ ChevronRight,
2764
+ CornerDownLeft as CornerDownLeft2,
2765
+ Info as Info2
2766
+ } from "lucide-react";
2767
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2768
+ function useRoundedClasses3() {
2769
+ const { theme } = useTheme();
2770
+ const density = theme.density ?? "normal";
2771
+ const densityClasses = {
2772
+ compact: {
2773
+ section: "px-3.5 py-2",
2774
+ eyebrow: "mb-0 text-[11px]",
2775
+ title: "text-[15px] leading-5",
2776
+ pager: "gap-1.5 text-xs",
2777
+ pagerButton: "h-6 w-6",
2778
+ pagerIcon: "h-3.5 w-3.5",
2779
+ choices: "mt-2.5 space-y-0.5",
2780
+ row: "min-h-8 grid-cols-[28px_minmax(0,1fr)_auto] gap-2 px-2.5 py-1",
2781
+ otherRow: "min-h-8 grid-cols-[28px_minmax(0,1fr)] gap-2 px-2.5 py-1",
2782
+ input: "h-6",
2783
+ footer: "mt-2.5 gap-2",
2784
+ dismissButton: "h-7",
2785
+ continueButton: "h-8 px-3.5",
2786
+ continueIcon: "h-5 min-w-5"
2787
+ },
2788
+ normal: {
2789
+ section: "px-4 py-2.5",
2790
+ eyebrow: "mb-0.5 text-xs",
2791
+ title: "text-base leading-5",
2792
+ pager: "gap-2 text-sm",
2793
+ pagerButton: "h-7 w-7",
2794
+ pagerIcon: "h-4 w-4",
2795
+ choices: "mt-3 space-y-0.5",
2796
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2797
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2798
+ input: "h-6",
2799
+ footer: "mt-3 gap-3",
2800
+ dismissButton: "h-7",
2801
+ continueButton: "h-8 px-4",
2802
+ continueIcon: "h-5 min-w-5"
2803
+ },
2804
+ spacious: {
2805
+ section: "px-5 py-3",
2806
+ eyebrow: "mb-0.5 text-xs",
2807
+ title: "text-base leading-5",
2808
+ pager: "gap-2 text-sm",
2809
+ pagerButton: "h-7 w-7",
2810
+ pagerIcon: "h-4 w-4",
2811
+ choices: "mt-4 space-y-1",
2812
+ row: "min-h-10 grid-cols-[32px_minmax(0,1fr)_auto] gap-3 px-3 py-2",
2813
+ otherRow: "min-h-10 grid-cols-[32px_minmax(0,1fr)] gap-3 px-3 py-2",
2814
+ input: "h-7",
2815
+ footer: "mt-4 gap-3",
2816
+ dismissButton: "h-8",
2817
+ continueButton: "h-9 px-4",
2818
+ continueIcon: "h-5 min-w-5"
2530
2819
  }
2531
- const isActive = context.value === value;
2532
- return /* @__PURE__ */ jsx15(
2533
- "button",
2534
- {
2535
- ref,
2536
- type: "button",
2537
- role: "tab",
2538
- "aria-selected": isActive,
2539
- "data-state": isActive ? "active" : "inactive",
2540
- className: cn(
2541
- "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",
2542
- className
2543
- ),
2544
- onClick: (event) => {
2545
- context.setValue(value);
2546
- onClick?.(event);
2547
- },
2548
- ...props
2549
- }
2550
- );
2820
+ }[density] ?? {
2821
+ section: "px-4 py-2.5",
2822
+ eyebrow: "mb-0.5 text-xs",
2823
+ title: "text-base leading-5",
2824
+ pager: "gap-2 text-sm",
2825
+ pagerButton: "h-7 w-7",
2826
+ pagerIcon: "h-4 w-4",
2827
+ choices: "mt-3 space-y-0.5",
2828
+ row: "min-h-9 grid-cols-[30px_minmax(0,1fr)_auto] gap-2.5 px-2.5 py-1.5",
2829
+ otherRow: "min-h-9 grid-cols-[30px_minmax(0,1fr)] gap-2.5 px-2.5 py-1.5",
2830
+ input: "h-6",
2831
+ footer: "mt-3 gap-3",
2832
+ dismissButton: "h-7",
2833
+ continueButton: "h-8 px-4",
2834
+ continueIcon: "h-5 min-w-5"
2835
+ };
2836
+ return {
2837
+ top: theme.radius ? {
2838
+ pill: "rounded-t-3xl",
2839
+ round: "rounded-t-xl",
2840
+ soft: "rounded-t-lg",
2841
+ sharp: "rounded-t-none"
2842
+ }[theme.radius] : "rounded-t-lg",
2843
+ panel: getRoundedClass(theme.radius, "rounded-lg"),
2844
+ control: getRoundedClass(theme.radius, "rounded-md"),
2845
+ density: densityClasses
2846
+ };
2847
+ }
2848
+ function parseRecommendedLabel(label) {
2849
+ const recommendedPattern = /\s*(?:\((?:recommended)\)|(推荐))\s*$/i;
2850
+ return {
2851
+ label: label.replace(recommendedPattern, "").trim() || label,
2852
+ recommended: recommendedPattern.test(label)
2853
+ };
2854
+ }
2855
+ function getAnswerForQuestion(question, draft) {
2856
+ if (!draft) return null;
2857
+ if (draft.type === "other") {
2858
+ const value = draft.otherText.trim();
2859
+ if (!value) return null;
2860
+ return {
2861
+ id: question.id,
2862
+ question: question.question,
2863
+ type: "other",
2864
+ value
2865
+ };
2551
2866
  }
2552
- );
2553
- TabsTrigger.displayName = "TabsTrigger";
2554
- var TabsContent = React13.forwardRef(
2555
- ({ className, value, ...props }, ref) => {
2556
- const context = React13.useContext(TabsContext);
2557
- if (!context) {
2558
- throw new Error("TabsContent must be used within Tabs");
2559
- }
2560
- if (context.value !== value) return null;
2561
- return /* @__PURE__ */ jsx15(
2562
- "div",
2563
- {
2564
- ref,
2565
- role: "tabpanel",
2566
- className: cn(
2567
- "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
2568
- className
2569
- ),
2570
- ...props
2571
- }
2867
+ const option = question.options[draft.optionIndex];
2868
+ if (!option) return null;
2869
+ return {
2870
+ id: question.id,
2871
+ question: question.question,
2872
+ type: "option",
2873
+ value: option.label,
2874
+ label: option.label,
2875
+ description: option.description
2876
+ };
2877
+ }
2878
+ function getSelectedChoiceIndex(question, draft) {
2879
+ if (!draft) return -1;
2880
+ if (draft.type === "other") return question.options.length;
2881
+ return draft.optionIndex;
2882
+ }
2883
+ function RequestUserInputPanel({
2884
+ request,
2885
+ onSubmit,
2886
+ onDismiss,
2887
+ attachToComposer = true,
2888
+ className
2889
+ }) {
2890
+ const { t } = useChatkitTranslation();
2891
+ const rounded = useRoundedClasses3();
2892
+ const [drafts, setDrafts] = React12.useState({});
2893
+ const [currentQuestionIndex, setCurrentQuestionIndex] = React12.useState(0);
2894
+ const otherInputRef = React12.useRef(null);
2895
+ const questions = request?.params.questions ?? [];
2896
+ React12.useEffect(() => {
2897
+ setDrafts({});
2898
+ setCurrentQuestionIndex(0);
2899
+ }, [request?.id]);
2900
+ React12.useEffect(() => {
2901
+ if (questions.length === 0) return;
2902
+ setCurrentQuestionIndex(
2903
+ (index) => Math.min(Math.max(index, 0), questions.length - 1)
2572
2904
  );
2573
- }
2574
- );
2575
- TabsContent.displayName = "TabsContent";
2576
-
2577
- // src/components/thread/markdown-text.tsx
2578
- import ReactMarkdown from "react-markdown";
2579
- import remarkGfm from "remark-gfm";
2580
- import rehypeKatex from "rehype-katex";
2581
- import remarkMath from "remark-math";
2582
- import {
2583
- Children,
2584
- isValidElement,
2585
- memo,
2586
- useState as useState7
2587
- } from "react";
2905
+ }, [questions.length]);
2906
+ const setQuestionDraft = React12.useCallback(
2907
+ (questionId, draft) => {
2908
+ setDrafts((previous) => ({
2909
+ ...previous,
2910
+ [questionId]: draft
2911
+ }));
2912
+ },
2913
+ []
2914
+ );
2915
+ const focusOtherInput = React12.useCallback(() => {
2916
+ window.setTimeout(() => otherInputRef.current?.focus(), 0);
2917
+ }, []);
2918
+ const selectOption = React12.useCallback(
2919
+ (question, optionIndex) => {
2920
+ const previousDraft = drafts[question.id];
2921
+ setQuestionDraft(question.id, {
2922
+ type: "option",
2923
+ optionIndex,
2924
+ otherText: previousDraft?.otherText ?? ""
2925
+ });
2926
+ },
2927
+ [drafts, setQuestionDraft]
2928
+ );
2929
+ const selectOther = React12.useCallback(
2930
+ (question, otherText2) => {
2931
+ const previousDraft = drafts[question.id];
2932
+ setQuestionDraft(question.id, {
2933
+ type: "other",
2934
+ otherText: otherText2 ?? (previousDraft?.type === "other" ? previousDraft.otherText : previousDraft?.otherText) ?? ""
2935
+ });
2936
+ focusOtherInput();
2937
+ },
2938
+ [drafts, focusOtherInput, setQuestionDraft]
2939
+ );
2940
+ const goToQuestion = React12.useCallback(
2941
+ (index) => {
2942
+ if (questions.length === 0) return;
2943
+ setCurrentQuestionIndex(
2944
+ Math.min(Math.max(index, 0), questions.length - 1)
2945
+ );
2946
+ },
2947
+ [questions.length]
2948
+ );
2949
+ const answers = React12.useMemo(
2950
+ () => questions.map((question) => getAnswerForQuestion(question, drafts[question.id])).filter((answer) => Boolean(answer)),
2951
+ [drafts, questions]
2952
+ );
2953
+ const canSubmit = answers.length === questions.length;
2954
+ const currentQuestion = questions[currentQuestionIndex] ?? null;
2955
+ const currentDraft = currentQuestion ? drafts[currentQuestion.id] : void 0;
2956
+ const currentAnswer = currentQuestion ? getAnswerForQuestion(currentQuestion, currentDraft) : null;
2957
+ const isLastQuestion = currentQuestionIndex === questions.length - 1;
2958
+ const buildAnswersFromDrafts = React12.useCallback(
2959
+ (nextDrafts) => questions.map((question) => getAnswerForQuestion(question, nextDrafts[question.id])).filter((answer) => Boolean(answer)),
2960
+ [questions]
2961
+ );
2962
+ const submitOrFocusFirstMissing = React12.useCallback(
2963
+ (nextDrafts) => {
2964
+ const nextAnswers = buildAnswersFromDrafts(nextDrafts);
2965
+ if (nextAnswers.length === questions.length) {
2966
+ onSubmit(nextAnswers);
2967
+ return;
2968
+ }
2969
+ const firstMissingIndex = questions.findIndex(
2970
+ (question) => !getAnswerForQuestion(question, nextDrafts[question.id])
2971
+ );
2972
+ if (firstMissingIndex >= 0) {
2973
+ goToQuestion(firstMissingIndex);
2974
+ }
2975
+ },
2976
+ [buildAnswersFromDrafts, goToQuestion, onSubmit, questions]
2977
+ );
2978
+ const activateOption = React12.useCallback(
2979
+ (question, optionIndex) => {
2980
+ const previousDraft = drafts[question.id];
2981
+ const nextDrafts = {
2982
+ ...drafts,
2983
+ [question.id]: {
2984
+ type: "option",
2985
+ optionIndex,
2986
+ otherText: previousDraft?.otherText ?? ""
2987
+ }
2988
+ };
2989
+ setDrafts(nextDrafts);
2990
+ if (isLastQuestion) {
2991
+ submitOrFocusFirstMissing(nextDrafts);
2992
+ return;
2993
+ }
2994
+ goToQuestion(currentQuestionIndex + 1);
2995
+ },
2996
+ [
2997
+ currentQuestionIndex,
2998
+ drafts,
2999
+ goToQuestion,
3000
+ isLastQuestion,
3001
+ submitOrFocusFirstMissing
3002
+ ]
3003
+ );
3004
+ const chooseChoiceByIndex = React12.useCallback(
3005
+ (choiceIndex) => {
3006
+ if (!currentQuestion) return;
3007
+ if (choiceIndex < 0) return;
3008
+ if (choiceIndex < currentQuestion.options.length) {
3009
+ selectOption(currentQuestion, choiceIndex);
3010
+ return;
3011
+ }
3012
+ if (choiceIndex === currentQuestion.options.length) {
3013
+ selectOther(currentQuestion);
3014
+ }
3015
+ },
3016
+ [currentQuestion, selectOption, selectOther]
3017
+ );
3018
+ const moveCurrentChoice = React12.useCallback(
3019
+ (direction) => {
3020
+ if (!currentQuestion) return;
3021
+ const choiceCount = currentQuestion.options.length + 1;
3022
+ const currentIndex = getSelectedChoiceIndex(currentQuestion, currentDraft);
3023
+ const nextIndex = currentIndex === -1 ? direction === 1 ? 0 : choiceCount - 1 : (currentIndex + direction + choiceCount) % choiceCount;
3024
+ chooseChoiceByIndex(nextIndex);
3025
+ },
3026
+ [chooseChoiceByIndex, currentDraft, currentQuestion]
3027
+ );
3028
+ const handleContinue = React12.useCallback(() => {
3029
+ if (!currentAnswer) return;
3030
+ if (!isLastQuestion) {
3031
+ goToQuestion(currentQuestionIndex + 1);
3032
+ return;
3033
+ }
3034
+ if (canSubmit) {
3035
+ onSubmit(answers);
3036
+ return;
3037
+ }
3038
+ const firstMissingIndex = questions.findIndex(
3039
+ (question) => !getAnswerForQuestion(question, drafts[question.id])
3040
+ );
3041
+ if (firstMissingIndex >= 0) {
3042
+ goToQuestion(firstMissingIndex);
3043
+ }
3044
+ }, [
3045
+ answers,
3046
+ canSubmit,
3047
+ currentAnswer,
3048
+ currentQuestionIndex,
3049
+ drafts,
3050
+ goToQuestion,
3051
+ isLastQuestion,
3052
+ onSubmit,
3053
+ questions
3054
+ ]);
3055
+ React12.useEffect(() => {
3056
+ if (!request) return;
3057
+ const handleKeyDown = (event) => {
3058
+ if (event.isComposing) return;
3059
+ const target = event.target;
3060
+ const targetTag = target?.tagName;
3061
+ const isTypingTarget = target?.isContentEditable || targetTag === "INPUT" || targetTag === "TEXTAREA" || targetTag === "SELECT";
3062
+ if (event.key === "Escape" || event.key === "Esc") {
3063
+ if (onDismiss) {
3064
+ event.preventDefault();
3065
+ onDismiss();
3066
+ }
3067
+ return;
3068
+ }
3069
+ if (isTypingTarget && event.key !== "Enter") {
3070
+ return;
3071
+ }
3072
+ if (event.key === "Enter") {
3073
+ event.preventDefault();
3074
+ handleContinue();
3075
+ return;
3076
+ }
3077
+ if (event.key === "ArrowLeft") {
3078
+ event.preventDefault();
3079
+ goToQuestion(currentQuestionIndex - 1);
3080
+ return;
3081
+ }
3082
+ if (event.key === "ArrowRight") {
3083
+ event.preventDefault();
3084
+ goToQuestion(currentQuestionIndex + 1);
3085
+ return;
3086
+ }
3087
+ if (event.key === "ArrowUp") {
3088
+ event.preventDefault();
3089
+ moveCurrentChoice(-1);
3090
+ return;
3091
+ }
3092
+ if (event.key === "ArrowDown") {
3093
+ event.preventDefault();
3094
+ moveCurrentChoice(1);
3095
+ return;
3096
+ }
3097
+ if (/^[1-9]$/.test(event.key)) {
3098
+ const choiceIndex = Number(event.key) - 1;
3099
+ if (currentQuestion && choiceIndex < currentQuestion.options.length + 1) {
3100
+ event.preventDefault();
3101
+ chooseChoiceByIndex(choiceIndex);
3102
+ }
3103
+ }
3104
+ };
3105
+ document.addEventListener("keydown", handleKeyDown);
3106
+ return () => document.removeEventListener("keydown", handleKeyDown);
3107
+ }, [
3108
+ chooseChoiceByIndex,
3109
+ currentQuestion,
3110
+ currentQuestionIndex,
3111
+ goToQuestion,
3112
+ handleContinue,
3113
+ moveCurrentChoice,
3114
+ onDismiss,
3115
+ request
3116
+ ]);
3117
+ if (!request || !currentQuestion) {
3118
+ return null;
3119
+ }
3120
+ const handleOtherTextChange = (value) => {
3121
+ setDrafts((previous) => ({
3122
+ ...previous,
3123
+ [currentQuestion.id]: {
3124
+ type: "other",
3125
+ otherText: value
3126
+ }
3127
+ }));
3128
+ };
3129
+ const otherText = currentDraft?.otherText ?? "";
3130
+ return /* @__PURE__ */ jsxs9(
3131
+ "section",
3132
+ {
3133
+ "aria-label": t("composer.requestUserInput.title"),
3134
+ "aria-live": "polite",
3135
+ className: cn(
3136
+ "mx-2 border border-border bg-background/95 shadow-sm",
3137
+ rounded.density.section,
3138
+ attachToComposer ? "border-b-0" : null,
3139
+ attachToComposer ? rounded.top : rounded.panel,
3140
+ className
3141
+ ),
3142
+ children: [
3143
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-3", children: [
3144
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
3145
+ /* @__PURE__ */ jsx14(
3146
+ "div",
3147
+ {
3148
+ className: cn(
3149
+ "font-medium text-muted-foreground",
3150
+ rounded.density.eyebrow
3151
+ ),
3152
+ children: currentQuestion.header
3153
+ }
3154
+ ),
3155
+ /* @__PURE__ */ jsx14(
3156
+ "h3",
3157
+ {
3158
+ className: cn(
3159
+ "font-semibold text-foreground",
3160
+ rounded.density.title
3161
+ ),
3162
+ children: currentQuestion.question
3163
+ }
3164
+ )
3165
+ ] }),
3166
+ questions.length > 1 ? /* @__PURE__ */ jsxs9(
3167
+ "div",
3168
+ {
3169
+ className: cn(
3170
+ "flex shrink-0 items-center font-medium text-muted-foreground",
3171
+ rounded.density.pager
3172
+ ),
3173
+ children: [
3174
+ /* @__PURE__ */ jsx14(
3175
+ "button",
3176
+ {
3177
+ type: "button",
3178
+ onClick: () => goToQuestion(currentQuestionIndex - 1),
3179
+ disabled: currentQuestionIndex === 0,
3180
+ className: cn(
3181
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3182
+ rounded.density.pagerButton
3183
+ ),
3184
+ "aria-label": t("composer.requestUserInput.previousQuestion"),
3185
+ children: /* @__PURE__ */ jsx14(ChevronLeft, { className: rounded.density.pagerIcon })
3186
+ }
3187
+ ),
3188
+ /* @__PURE__ */ jsx14("span", { className: "min-w-12 text-center", children: t("composer.requestUserInput.questionProgress", {
3189
+ current: currentQuestionIndex + 1,
3190
+ total: questions.length
3191
+ }) }),
3192
+ /* @__PURE__ */ jsx14(
3193
+ "button",
3194
+ {
3195
+ type: "button",
3196
+ onClick: () => goToQuestion(currentQuestionIndex + 1),
3197
+ disabled: currentQuestionIndex === questions.length - 1,
3198
+ className: cn(
3199
+ "inline-flex items-center justify-center rounded-full hover:bg-muted disabled:pointer-events-none disabled:opacity-35",
3200
+ rounded.density.pagerButton
3201
+ ),
3202
+ "aria-label": t("composer.requestUserInput.nextQuestion"),
3203
+ children: /* @__PURE__ */ jsx14(ChevronRight, { className: rounded.density.pagerIcon })
3204
+ }
3205
+ )
3206
+ ]
3207
+ }
3208
+ ) : null
3209
+ ] }),
3210
+ /* @__PURE__ */ jsxs9("div", { className: rounded.density.choices, children: [
3211
+ currentQuestion.options.map((option, optionIndex) => {
3212
+ const selected = currentDraft?.type === "option" && currentDraft.optionIndex === optionIndex;
3213
+ const parsedLabel = parseRecommendedLabel(option.label);
3214
+ return /* @__PURE__ */ jsxs9(
3215
+ "div",
3216
+ {
3217
+ role: "button",
3218
+ tabIndex: 0,
3219
+ onClick: () => activateOption(currentQuestion, optionIndex),
3220
+ onKeyDown: (event) => {
3221
+ if (event.key === "Enter" || event.key === " ") {
3222
+ event.preventDefault();
3223
+ event.stopPropagation();
3224
+ activateOption(currentQuestion, optionIndex);
3225
+ }
3226
+ },
3227
+ "aria-pressed": selected,
3228
+ "aria-label": `${optionIndex + 1}. ${option.label}`,
3229
+ className: cn(
3230
+ "grid cursor-pointer items-center text-left transition-colors",
3231
+ rounded.density.row,
3232
+ rounded.panel,
3233
+ selected ? "bg-muted text-foreground" : "text-foreground/90 hover:bg-muted/55"
3234
+ ),
3235
+ children: [
3236
+ /* @__PURE__ */ jsxs9("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3237
+ optionIndex + 1,
3238
+ "."
3239
+ ] }),
3240
+ /* @__PURE__ */ jsxs9("span", { className: "min-w-0", children: [
3241
+ /* @__PURE__ */ jsx14("span", { className: "inline min-w-0 text-sm font-semibold leading-5", children: parsedLabel.label }),
3242
+ parsedLabel.recommended ? /* @__PURE__ */ jsxs9("span", { className: "ml-1.5 inline-flex items-center gap-1 text-sm font-semibold text-primary", children: [
3243
+ /* @__PURE__ */ jsx14(Check, { className: "h-3.5 w-3.5" }),
3244
+ "(",
3245
+ t("composer.requestUserInput.recommended"),
3246
+ ")"
3247
+ ] }) : null
3248
+ ] }),
3249
+ /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
3250
+ option.description ? /* @__PURE__ */ jsxs9(Tooltip, { children: [
3251
+ /* @__PURE__ */ jsx14(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx14(
3252
+ "button",
3253
+ {
3254
+ type: "button",
3255
+ onClick: (event) => event.stopPropagation(),
3256
+ onKeyDown: (event) => event.stopPropagation(),
3257
+ title: option.description,
3258
+ className: "inline-flex h-7 w-7 items-center justify-center rounded-full hover:bg-background/80 hover:text-foreground",
3259
+ "aria-label": t("composer.requestUserInput.optionInfo", {
3260
+ label: parsedLabel.label
3261
+ }),
3262
+ children: /* @__PURE__ */ jsx14(Info2, { className: "h-4 w-4" })
3263
+ }
3264
+ ) }),
3265
+ /* @__PURE__ */ jsx14(
3266
+ TooltipContent,
3267
+ {
3268
+ side: "top",
3269
+ sideOffset: 6,
3270
+ className: "max-w-72 text-left leading-5",
3271
+ children: option.description
3272
+ }
3273
+ )
3274
+ ] }) : null,
3275
+ selected ? /* @__PURE__ */ jsxs9(
3276
+ "span",
3277
+ {
3278
+ "aria-hidden": "true",
3279
+ className: "hidden items-center gap-0.5 sm:flex",
3280
+ children: [
3281
+ /* @__PURE__ */ jsx14(ArrowUp2, { className: "h-4 w-4 opacity-45" }),
3282
+ /* @__PURE__ */ jsx14(ArrowDown, { className: "h-4 w-4 opacity-45" })
3283
+ ]
3284
+ }
3285
+ ) : null
3286
+ ] })
3287
+ ]
3288
+ },
3289
+ `${currentQuestion.id}-${optionIndex}`
3290
+ );
3291
+ }),
3292
+ /* @__PURE__ */ jsxs9(
3293
+ "label",
3294
+ {
3295
+ className: cn(
3296
+ "grid items-center transition-colors",
3297
+ rounded.density.otherRow,
3298
+ rounded.panel,
3299
+ currentDraft?.type === "other" ? "bg-muted text-foreground" : "hover:bg-muted/55"
3300
+ ),
3301
+ children: [
3302
+ /* @__PURE__ */ jsxs9("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3303
+ currentQuestion.options.length + 1,
3304
+ "."
3305
+ ] }),
3306
+ /* @__PURE__ */ jsx14("span", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: /* @__PURE__ */ jsx14(
3307
+ "input",
3308
+ {
3309
+ ref: otherInputRef,
3310
+ value: otherText,
3311
+ onChange: (event) => handleOtherTextChange(event.target.value),
3312
+ onFocus: () => selectOther(currentQuestion, otherText),
3313
+ placeholder: t("composer.requestUserInput.otherPlaceholder"),
3314
+ className: cn(
3315
+ "min-w-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground",
3316
+ rounded.density.input
3317
+ )
3318
+ }
3319
+ ) })
3320
+ ]
3321
+ }
3322
+ )
3323
+ ] }),
3324
+ /* @__PURE__ */ jsxs9(
3325
+ "div",
3326
+ {
3327
+ className: cn(
3328
+ "flex items-center justify-end",
3329
+ rounded.density.footer
3330
+ ),
3331
+ children: [
3332
+ onDismiss ? /* @__PURE__ */ jsxs9(
3333
+ "button",
3334
+ {
3335
+ type: "button",
3336
+ onClick: onDismiss,
3337
+ className: cn(
3338
+ "inline-flex items-center gap-2 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground",
3339
+ rounded.density.dismissButton
3340
+ ),
3341
+ children: [
3342
+ t("composer.requestUserInput.dismiss"),
3343
+ /* @__PURE__ */ jsx14("kbd", { className: "rounded-full bg-muted px-2 py-1 text-xs font-semibold text-muted-foreground", children: "ESC" })
3344
+ ]
3345
+ }
3346
+ ) : null,
3347
+ /* @__PURE__ */ jsxs9(
3348
+ "button",
3349
+ {
3350
+ type: "button",
3351
+ disabled: !currentAnswer,
3352
+ onClick: handleContinue,
3353
+ className: cn(
3354
+ "inline-flex items-center gap-2 bg-primary text-sm font-semibold text-background transition-all",
3355
+ rounded.density.continueButton,
3356
+ "hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-40",
3357
+ rounded.panel
3358
+ ),
3359
+ children: [
3360
+ t("composer.requestUserInput.continue"),
3361
+ /* @__PURE__ */ jsx14(
3362
+ "span",
3363
+ {
3364
+ className: cn(
3365
+ "inline-flex items-center justify-center rounded-full bg-background/20",
3366
+ rounded.density.continueIcon
3367
+ ),
3368
+ children: /* @__PURE__ */ jsx14(CornerDownLeft2, { className: "h-3.5 w-3.5" })
3369
+ }
3370
+ )
3371
+ ]
3372
+ }
3373
+ )
3374
+ ]
3375
+ }
3376
+ )
3377
+ ]
3378
+ }
3379
+ );
3380
+ }
3381
+
3382
+ // src/components/thread/messages/ai.tsx
3383
+ import * as React19 from "react";
3384
+ import {
3385
+ ChevronDown as ChevronDown2,
3386
+ Clock3,
3387
+ Loader2 as Loader23
3388
+ } from "lucide-react";
3389
+
3390
+ // src/components/ui/badge.tsx
3391
+ import * as React13 from "react";
3392
+ import { jsx as jsx15 } from "react/jsx-runtime";
3393
+ 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";
3394
+ var variants = {
3395
+ default: "bg-primary text-primary-foreground",
3396
+ secondary: "bg-secondary text-secondary-foreground",
3397
+ outline: "border-input text-foreground"
3398
+ };
3399
+ var Badge = React13.forwardRef(
3400
+ ({ className, variant = "default", ...props }, ref) => {
3401
+ return /* @__PURE__ */ jsx15("span", { ref, className: cn(base, variants[variant], className), ...props });
3402
+ }
3403
+ );
3404
+ Badge.displayName = "Badge";
3405
+
3406
+ // src/components/ui/card.tsx
3407
+ import * as React14 from "react";
3408
+ import { jsx as jsx16 } from "react/jsx-runtime";
3409
+ var Card = React14.forwardRef(
3410
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
3411
+ "div",
3412
+ {
3413
+ ref,
3414
+ className: cn(
3415
+ "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
3416
+ className
3417
+ ),
3418
+ ...props
3419
+ }
3420
+ )
3421
+ );
3422
+ Card.displayName = "Card";
3423
+ var CardHeader = React14.forwardRef(
3424
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
3425
+ );
3426
+ CardHeader.displayName = "CardHeader";
3427
+ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
3428
+ CardTitle.displayName = "CardTitle";
3429
+ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx16("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
3430
+ CardDescription.displayName = "CardDescription";
3431
+ var CardContent = React14.forwardRef(
3432
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("px-6 pb-6", className), ...props })
3433
+ );
3434
+ CardContent.displayName = "CardContent";
3435
+ var CardFooter = React14.forwardRef(
3436
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
3437
+ );
3438
+ CardFooter.displayName = "CardFooter";
3439
+ var CardAction = React14.forwardRef(
3440
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
3441
+ );
3442
+ CardAction.displayName = "CardAction";
3443
+
3444
+ // src/components/ui/tabs.tsx
3445
+ import * as React15 from "react";
3446
+ import { jsx as jsx17 } from "react/jsx-runtime";
3447
+ var TabsContext = React15.createContext(null);
3448
+ function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
3449
+ const [internalValue, setInternalValue] = React15.useState(defaultValue ?? "");
3450
+ const activeValue = value ?? internalValue;
3451
+ const setValue = React15.useCallback(
3452
+ (nextValue) => {
3453
+ if (value === void 0) setInternalValue(nextValue);
3454
+ onValueChange?.(nextValue);
3455
+ },
3456
+ [onValueChange, value]
3457
+ );
3458
+ return /* @__PURE__ */ jsx17(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx17("div", { className: cn("w-full", className), ...props }) });
3459
+ }
3460
+ var TabsList = React15.forwardRef(
3461
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx17(
3462
+ "div",
3463
+ {
3464
+ ref,
3465
+ className: cn(
3466
+ "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
3467
+ className
3468
+ ),
3469
+ role: "tablist",
3470
+ ...props
3471
+ }
3472
+ )
3473
+ );
3474
+ TabsList.displayName = "TabsList";
3475
+ var TabsTrigger = React15.forwardRef(
3476
+ ({ className, value, onClick, ...props }, ref) => {
3477
+ const context = React15.useContext(TabsContext);
3478
+ if (!context) {
3479
+ throw new Error("TabsTrigger must be used within Tabs");
3480
+ }
3481
+ const isActive = context.value === value;
3482
+ return /* @__PURE__ */ jsx17(
3483
+ "button",
3484
+ {
3485
+ ref,
3486
+ type: "button",
3487
+ role: "tab",
3488
+ "aria-selected": isActive,
3489
+ "data-state": isActive ? "active" : "inactive",
3490
+ className: cn(
3491
+ "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",
3492
+ className
3493
+ ),
3494
+ onClick: (event) => {
3495
+ context.setValue(value);
3496
+ onClick?.(event);
3497
+ },
3498
+ ...props
3499
+ }
3500
+ );
3501
+ }
3502
+ );
3503
+ TabsTrigger.displayName = "TabsTrigger";
3504
+ var TabsContent = React15.forwardRef(
3505
+ ({ className, value, ...props }, ref) => {
3506
+ const context = React15.useContext(TabsContext);
3507
+ if (!context) {
3508
+ throw new Error("TabsContent must be used within Tabs");
3509
+ }
3510
+ if (context.value !== value) return null;
3511
+ return /* @__PURE__ */ jsx17(
3512
+ "div",
3513
+ {
3514
+ ref,
3515
+ role: "tabpanel",
3516
+ className: cn(
3517
+ "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
3518
+ className
3519
+ ),
3520
+ ...props
3521
+ }
3522
+ );
3523
+ }
3524
+ );
3525
+ TabsContent.displayName = "TabsContent";
3526
+
3527
+ // src/components/thread/markdown-text.tsx
3528
+ import ReactMarkdown from "react-markdown";
3529
+ import remarkGfm from "remark-gfm";
3530
+ import rehypeKatex from "rehype-katex";
3531
+ import remarkMath from "remark-math";
3532
+ import {
3533
+ Children,
3534
+ isValidElement,
3535
+ memo,
3536
+ useState as useState9
3537
+ } from "react";
2588
3538
  import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon2 } from "lucide-react";
2589
3539
 
2590
3540
  // src/components/thread/syntax-highlighter.tsx
@@ -2593,7 +3543,7 @@ import tsx from "react-syntax-highlighter/dist/esm/languages/prism/tsx";
2593
3543
  import python from "react-syntax-highlighter/dist/esm/languages/prism/python";
2594
3544
  import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
2595
3545
  import "react";
2596
- import { jsx as jsx16 } from "react/jsx-runtime";
3546
+ import { jsx as jsx18 } from "react/jsx-runtime";
2597
3547
  SyntaxHighlighterPrism.registerLanguage("js", tsx);
2598
3548
  SyntaxHighlighterPrism.registerLanguage("jsx", tsx);
2599
3549
  SyntaxHighlighterPrism.registerLanguage("ts", tsx);
@@ -2604,7 +3554,7 @@ var SyntaxHighlighter = ({
2604
3554
  language,
2605
3555
  className
2606
3556
  }) => {
2607
- return /* @__PURE__ */ jsx16(
3557
+ return /* @__PURE__ */ jsx18(
2608
3558
  SyntaxHighlighterPrism,
2609
3559
  {
2610
3560
  language,
@@ -2634,14 +3584,14 @@ import {
2634
3584
  TriangleAlert,
2635
3585
  X as X2
2636
3586
  } from "lucide-react";
2637
- import * as React14 from "react";
3587
+ import * as React16 from "react";
2638
3588
 
2639
3589
  // src/components/thread/tooltip-icon-button.tsx
2640
3590
  import { forwardRef as forwardRef5 } from "react";
2641
- import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
3591
+ import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
2642
3592
  var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
2643
- return /* @__PURE__ */ jsx17(TooltipProvider, { children: /* @__PURE__ */ jsxs8(Tooltip, { children: [
2644
- /* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
3593
+ return /* @__PURE__ */ jsx19(TooltipProvider, { children: /* @__PURE__ */ jsxs10(Tooltip, { children: [
3594
+ /* @__PURE__ */ jsx19(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
2645
3595
  Button,
2646
3596
  {
2647
3597
  variant: "ghost",
@@ -2651,17 +3601,17 @@ var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", class
2651
3601
  ref,
2652
3602
  children: [
2653
3603
  children,
2654
- /* @__PURE__ */ jsx17("span", { className: "sr-only", children: tooltip })
3604
+ /* @__PURE__ */ jsx19("span", { className: "sr-only", children: tooltip })
2655
3605
  ]
2656
3606
  }
2657
3607
  ) }),
2658
- /* @__PURE__ */ jsx17(TooltipContent, { side, children: tooltip })
3608
+ /* @__PURE__ */ jsx19(TooltipContent, { side, children: tooltip })
2659
3609
  ] }) });
2660
3610
  });
2661
3611
  TooltipIconButton.displayName = "TooltipIconButton";
2662
3612
 
2663
3613
  // src/components/thread/mermaid-block.tsx
2664
- import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
3614
+ import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs11 } from "react/jsx-runtime";
2665
3615
  var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
2666
3616
  var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
2667
3617
  var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
@@ -2909,24 +3859,24 @@ function MermaidPreviewDialog({
2909
3859
  svgMarkup,
2910
3860
  title
2911
3861
  }) {
2912
- return /* @__PURE__ */ jsx18(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { children: [
2913
- /* @__PURE__ */ jsx18(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" }),
2914
- /* @__PURE__ */ jsxs9(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: [
2915
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
2916
- /* @__PURE__ */ jsx18(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
2917
- /* @__PURE__ */ jsx18(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxs9(
3862
+ return /* @__PURE__ */ jsx20(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs11(Dialog.Portal, { children: [
3863
+ /* @__PURE__ */ jsx20(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
3864
+ /* @__PURE__ */ jsxs11(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
3865
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3866
+ /* @__PURE__ */ jsx20(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3867
+ /* @__PURE__ */ jsx20(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxs11(
2918
3868
  "button",
2919
3869
  {
2920
3870
  type: "button",
2921
3871
  className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
2922
3872
  children: [
2923
- /* @__PURE__ */ jsx18(X2, { className: "size-4" }),
2924
- /* @__PURE__ */ jsx18("span", { className: "sr-only", children: closeLabel })
3873
+ /* @__PURE__ */ jsx20(X2, { className: "size-4" }),
3874
+ /* @__PURE__ */ jsx20("span", { className: "sr-only", children: closeLabel })
2925
3875
  ]
2926
3876
  }
2927
3877
  ) })
2928
3878
  ] }),
2929
- /* @__PURE__ */ jsx18("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ jsx18(
3879
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ jsx20(
2930
3880
  "div",
2931
3881
  {
2932
3882
  "data-slot": "mermaid-preview",
@@ -2940,24 +3890,24 @@ function MermaidPreviewDialog({
2940
3890
  function MermaidBlock({ code }) {
2941
3891
  const { t } = useChatkitTranslation();
2942
3892
  const { theme, isDarkMode } = useTheme();
2943
- const containerRef = React14.useRef(null);
2944
- const renderHostRef = React14.useRef(null);
2945
- const renderSequenceRef = React14.useRef(0);
2946
- const copyResetTimeoutRef = React14.useRef(null);
2947
- const diagramId = React14.useId().replace(/:/g, "");
2948
- const [activeTab, setActiveTab] = React14.useState("diagram");
2949
- const [isCopied, setIsCopied] = React14.useState(false);
2950
- const [isPreviewOpen, setIsPreviewOpen] = React14.useState(false);
2951
- const [isRendering, setIsRendering] = React14.useState(true);
2952
- const [renderError, setRenderError] = React14.useState(null);
2953
- const [svgMarkup, setSvgMarkup] = React14.useState(null);
2954
- const normalizedCode = React14.useMemo(() => normalizeMermaidCode(code), [code]);
2955
- const clearCopyResetTimeout = React14.useCallback(() => {
3893
+ const containerRef = React16.useRef(null);
3894
+ const renderHostRef = React16.useRef(null);
3895
+ const renderSequenceRef = React16.useRef(0);
3896
+ const copyResetTimeoutRef = React16.useRef(null);
3897
+ const diagramId = React16.useId().replace(/:/g, "");
3898
+ const [activeTab, setActiveTab] = React16.useState("diagram");
3899
+ const [isCopied, setIsCopied] = React16.useState(false);
3900
+ const [isPreviewOpen, setIsPreviewOpen] = React16.useState(false);
3901
+ const [isRendering, setIsRendering] = React16.useState(true);
3902
+ const [renderError, setRenderError] = React16.useState(null);
3903
+ const [svgMarkup, setSvgMarkup] = React16.useState(null);
3904
+ const normalizedCode = React16.useMemo(() => normalizeMermaidCode(code), [code]);
3905
+ const clearCopyResetTimeout = React16.useCallback(() => {
2956
3906
  if (copyResetTimeoutRef.current === null) return;
2957
3907
  window.clearTimeout(copyResetTimeoutRef.current);
2958
3908
  copyResetTimeoutRef.current = null;
2959
3909
  }, []);
2960
- React14.useEffect(() => {
3910
+ React16.useEffect(() => {
2961
3911
  let isActive = true;
2962
3912
  async function runRender() {
2963
3913
  const container = containerRef.current;
@@ -2995,17 +3945,17 @@ function MermaidBlock({ code }) {
2995
3945
  }
2996
3946
  };
2997
3947
  }, [diagramId, isDarkMode, normalizedCode, theme]);
2998
- React14.useEffect(() => {
3948
+ React16.useEffect(() => {
2999
3949
  clearCopyResetTimeout();
3000
3950
  setIsCopied(false);
3001
3951
  }, [activeTab, clearCopyResetTimeout, code]);
3002
- React14.useEffect(
3952
+ React16.useEffect(
3003
3953
  () => () => {
3004
3954
  clearCopyResetTimeout();
3005
3955
  },
3006
3956
  [clearCopyResetTimeout]
3007
3957
  );
3008
- const handleDownload = React14.useCallback(() => {
3958
+ const handleDownload = React16.useCallback(() => {
3009
3959
  if (!svgMarkup) return;
3010
3960
  const blob = new Blob([svgMarkup], {
3011
3961
  type: "image/svg+xml;charset=utf-8"
@@ -3019,7 +3969,7 @@ function MermaidBlock({ code }) {
3019
3969
  anchor.remove();
3020
3970
  window.URL.revokeObjectURL(url);
3021
3971
  }, [diagramId, svgMarkup]);
3022
- const handleCopyCode = React14.useCallback(() => {
3972
+ const handleCopyCode = React16.useCallback(() => {
3023
3973
  if (!code || isCopied) return;
3024
3974
  navigator.clipboard.writeText(code).then(() => {
3025
3975
  setIsCopied(true);
@@ -3033,21 +3983,21 @@ function MermaidBlock({ code }) {
3033
3983
  }, [clearCopyResetTimeout, code, isCopied]);
3034
3984
  const hasRenderedDiagram = svgMarkup !== null && !renderError;
3035
3985
  const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
3036
- return /* @__PURE__ */ jsxs9(Fragment2, { children: [
3037
- /* @__PURE__ */ jsx18(
3986
+ return /* @__PURE__ */ jsxs11(Fragment2, { children: [
3987
+ /* @__PURE__ */ jsx20(
3038
3988
  Tabs,
3039
3989
  {
3040
3990
  className: "w-full",
3041
3991
  onValueChange: (value) => setActiveTab(value),
3042
3992
  value: activeTab,
3043
- children: /* @__PURE__ */ jsxs9(
3993
+ children: /* @__PURE__ */ jsxs11(
3044
3994
  "div",
3045
3995
  {
3046
3996
  ref: containerRef,
3047
3997
  "data-slot": "mermaid-block",
3048
3998
  className: "relative overflow-hidden text-card-foreground",
3049
3999
  children: [
3050
- /* @__PURE__ */ jsx18(
4000
+ /* @__PURE__ */ jsx20(
3051
4001
  "div",
3052
4002
  {
3053
4003
  ref: renderHostRef,
@@ -3056,62 +4006,62 @@ function MermaidBlock({ code }) {
3056
4006
  "data-slot": "mermaid-render-host"
3057
4007
  }
3058
4008
  ),
3059
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3060
- /* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 items-center gap-3", children: [
3061
- /* @__PURE__ */ jsx18("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx18(Code2Icon, { className: "size-4" }) }),
3062
- /* @__PURE__ */ jsx18("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
4009
+ /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
4010
+ /* @__PURE__ */ jsxs11("div", { className: "flex min-w-0 items-center gap-3", children: [
4011
+ /* @__PURE__ */ jsx20("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx20(Code2Icon, { className: "size-4" }) }),
4012
+ /* @__PURE__ */ jsx20("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3063
4013
  ] }),
3064
- /* @__PURE__ */ jsxs9("div", { className: "flex shrink-0 items-center gap-2", children: [
3065
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1", children: [
3066
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx18(
4014
+ /* @__PURE__ */ jsxs11("div", { className: "flex shrink-0 items-center gap-2", children: [
4015
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1", children: [
4016
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3067
4017
  TooltipIconButton,
3068
4018
  {
3069
4019
  onClick: handleDownload,
3070
4020
  tooltip: t("markdown.mermaid.download"),
3071
- children: /* @__PURE__ */ jsx18(DownloadIcon, { className: "size-4" })
4021
+ children: /* @__PURE__ */ jsx20(DownloadIcon, { className: "size-4" })
3072
4022
  }
3073
4023
  ) : null,
3074
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx18(
4024
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3075
4025
  TooltipIconButton,
3076
4026
  {
3077
4027
  onClick: () => setIsPreviewOpen(true),
3078
4028
  tooltip: t("markdown.mermaid.fullScreen"),
3079
- children: /* @__PURE__ */ jsx18(ExpandIcon, { className: "size-4" })
4029
+ children: /* @__PURE__ */ jsx20(ExpandIcon, { className: "size-4" })
3080
4030
  }
3081
4031
  ) : null,
3082
- activeTab === "code" ? /* @__PURE__ */ jsx18(
4032
+ activeTab === "code" ? /* @__PURE__ */ jsx20(
3083
4033
  TooltipIconButton,
3084
4034
  {
3085
4035
  onClick: handleCopyCode,
3086
4036
  tooltip: t("markdown.copy"),
3087
- children: isCopied ? /* @__PURE__ */ jsx18(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx18(CopyIcon, { className: "size-4" })
4037
+ children: isCopied ? /* @__PURE__ */ jsx20(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx20(CopyIcon, { className: "size-4" })
3088
4038
  }
3089
4039
  ) : null
3090
4040
  ] }),
3091
- /* @__PURE__ */ jsxs9(TabsList, { children: [
3092
- /* @__PURE__ */ jsx18(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
3093
- /* @__PURE__ */ jsx18(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
4041
+ /* @__PURE__ */ jsxs11(TabsList, { children: [
4042
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
4043
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
3094
4044
  ] })
3095
4045
  ] })
3096
4046
  ] }),
3097
- /* @__PURE__ */ jsxs9("div", { className: "border-t border-border pt-4", children: [
3098
- renderError ? /* @__PURE__ */ jsx18("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
3099
- /* @__PURE__ */ jsx18(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ jsx18(
4047
+ /* @__PURE__ */ jsxs11("div", { className: "border-t border-border pt-4", children: [
4048
+ renderError ? /* @__PURE__ */ jsx20("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
4049
+ /* @__PURE__ */ jsx20(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ jsx20(
3100
4050
  "div",
3101
4051
  {
3102
4052
  className: cn(
3103
4053
  "relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
3104
4054
  hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
3105
4055
  ),
3106
- children: hasRenderedDiagram ? /* @__PURE__ */ jsx18(
4056
+ children: hasRenderedDiagram ? /* @__PURE__ */ jsx20(
3107
4057
  "div",
3108
4058
  {
3109
4059
  "data-slot": "mermaid-diagram",
3110
4060
  dangerouslySetInnerHTML: { __html: svgMarkup }
3111
4061
  }
3112
- ) : /* @__PURE__ */ jsxs9("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
3113
- isRendering ? /* @__PURE__ */ jsx18(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx18(TriangleAlert, { className: "size-5 text-destructive" }),
3114
- /* @__PURE__ */ jsx18(
4062
+ ) : /* @__PURE__ */ jsxs11("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
4063
+ isRendering ? /* @__PURE__ */ jsx20(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx20(TriangleAlert, { className: "size-5 text-destructive" }),
4064
+ /* @__PURE__ */ jsx20(
3115
4065
  "p",
3116
4066
  {
3117
4067
  className: cn("text-sm font-medium", !isRendering && "text-destructive"),
@@ -3122,12 +4072,12 @@ function MermaidBlock({ code }) {
3122
4072
  ] })
3123
4073
  }
3124
4074
  ) }),
3125
- /* @__PURE__ */ jsx18(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ jsx18(
4075
+ /* @__PURE__ */ jsx20(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ jsx20(
3126
4076
  "pre",
3127
4077
  {
3128
4078
  "data-slot": "mermaid-code",
3129
4079
  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",
3130
- children: /* @__PURE__ */ jsx18("code", { className: "block whitespace-pre font-mono", children: code })
4080
+ children: /* @__PURE__ */ jsx20("code", { className: "block whitespace-pre font-mono", children: code })
3131
4081
  }
3132
4082
  ) })
3133
4083
  ] })
@@ -3136,7 +4086,7 @@ function MermaidBlock({ code }) {
3136
4086
  )
3137
4087
  }
3138
4088
  ),
3139
- svgMarkup ? /* @__PURE__ */ jsx18(
4089
+ svgMarkup ? /* @__PURE__ */ jsx20(
3140
4090
  MermaidPreviewDialog,
3141
4091
  {
3142
4092
  closeLabel: t("sheet.close"),
@@ -3151,7 +4101,13 @@ function MermaidBlock({ code }) {
3151
4101
 
3152
4102
  // src/components/thread/markdown-text.tsx
3153
4103
  import "katex/dist/katex.min.css";
3154
- import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
4104
+ import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
4105
+ var markdownTableMinWidth = "max(7rem, calc(8rem * var(--density-spacing, 1)))";
4106
+ var markdownTableCellPaddingInline = "calc(var(--density-padding, 1rem) * 1.25)";
4107
+ var markdownTableCellPaddingBlock = "max(0.5rem, calc(var(--density-padding, 1rem) * 0.75))";
4108
+ var markdownTableLineHeight = "max(1.375rem, calc(1.5rem * var(--density-spacing, 1)))";
4109
+ var markdownInlineCodePaddingInline = "max(0.25rem, calc(var(--density-gap, 0.5rem) * 0.75))";
4110
+ var markdownInlineCodePaddingBlock = "max(0.125rem, calc(var(--density-gap, 0.5rem) * 0.5))";
3155
4111
  var getTextContent = (children) => Children.toArray(children).map((child) => {
3156
4112
  if (typeof child === "string" || typeof child === "number") {
3157
4113
  return String(child);
@@ -3163,7 +4119,7 @@ var isMermaidCodeElement = (child) => isValidElement(child) && typeof child.prop
3163
4119
  var useCopyToClipboard = ({
3164
4120
  copiedDuration = 3e3
3165
4121
  } = {}) => {
3166
- const [isCopied, setIsCopied] = useState7(false);
4122
+ const [isCopied, setIsCopied] = useState9(false);
3167
4123
  const copyToClipboard = (value) => {
3168
4124
  if (!value) return;
3169
4125
  navigator.clipboard.writeText(value).then(() => {
@@ -3180,23 +4136,23 @@ var CodeHeader = ({ language, code }) => {
3180
4136
  if (!code || isCopied) return;
3181
4137
  copyToClipboard(code);
3182
4138
  };
3183
- return /* @__PURE__ */ jsxs10("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: [
3184
- /* @__PURE__ */ jsx19("span", { className: "lowercase [&>span]:text-xs", children: language }),
3185
- /* @__PURE__ */ jsxs10(
4139
+ return /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
4140
+ /* @__PURE__ */ jsx21("span", { className: "lowercase [&>span]:text-xs", children: language }),
4141
+ /* @__PURE__ */ jsxs12(
3186
4142
  TooltipIconButton,
3187
4143
  {
3188
4144
  tooltip: t("markdown.copy"),
3189
4145
  onClick: onCopy,
3190
4146
  children: [
3191
- !isCopied && /* @__PURE__ */ jsx19(CopyIcon2, {}),
3192
- isCopied && /* @__PURE__ */ jsx19(CheckIcon2, {})
4147
+ !isCopied && /* @__PURE__ */ jsx21(CopyIcon2, {}),
4148
+ isCopied && /* @__PURE__ */ jsx21(CheckIcon2, {})
3193
4149
  ]
3194
4150
  }
3195
4151
  )
3196
4152
  ] });
3197
4153
  };
3198
4154
  var defaultComponents = {
3199
- h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4155
+ h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3200
4156
  "h1",
3201
4157
  {
3202
4158
  className: cn(
@@ -3206,7 +4162,7 @@ var defaultComponents = {
3206
4162
  ...props
3207
4163
  }
3208
4164
  ),
3209
- h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4165
+ h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3210
4166
  "h2",
3211
4167
  {
3212
4168
  className: cn(
@@ -3216,7 +4172,7 @@ var defaultComponents = {
3216
4172
  ...props
3217
4173
  }
3218
4174
  ),
3219
- h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4175
+ h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3220
4176
  "h3",
3221
4177
  {
3222
4178
  className: cn(
@@ -3226,7 +4182,7 @@ var defaultComponents = {
3226
4182
  ...props
3227
4183
  }
3228
4184
  ),
3229
- h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4185
+ h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3230
4186
  "h4",
3231
4187
  {
3232
4188
  className: cn(
@@ -3236,7 +4192,7 @@ var defaultComponents = {
3236
4192
  ...props
3237
4193
  }
3238
4194
  ),
3239
- h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4195
+ h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3240
4196
  "h5",
3241
4197
  {
3242
4198
  className: cn(
@@ -3246,21 +4202,21 @@ var defaultComponents = {
3246
4202
  ...props
3247
4203
  }
3248
4204
  ),
3249
- h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4205
+ h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3250
4206
  "h6",
3251
4207
  {
3252
4208
  className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
3253
4209
  ...props
3254
4210
  }
3255
4211
  ),
3256
- p: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4212
+ p: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3257
4213
  "p",
3258
4214
  {
3259
4215
  className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
3260
4216
  ...props
3261
4217
  }
3262
4218
  ),
3263
- a: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4219
+ a: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3264
4220
  "a",
3265
4221
  {
3266
4222
  className: cn(
@@ -3276,7 +4232,7 @@ var defaultComponents = {
3276
4232
  className,
3277
4233
  node: _node,
3278
4234
  ...props
3279
- }) => /* @__PURE__ */ jsx19(
4235
+ }) => /* @__PURE__ */ jsx21(
3280
4236
  "blockquote",
3281
4237
  {
3282
4238
  className: cn(
@@ -3286,21 +4242,21 @@ var defaultComponents = {
3286
4242
  ...props
3287
4243
  }
3288
4244
  ),
3289
- ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4245
+ ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3290
4246
  "ul",
3291
4247
  {
3292
4248
  className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
3293
4249
  ...props
3294
4250
  }
3295
4251
  ),
3296
- ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4252
+ ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3297
4253
  "ol",
3298
4254
  {
3299
4255
  className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
3300
4256
  ...props
3301
4257
  }
3302
4258
  ),
3303
- hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4259
+ hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3304
4260
  "hr",
3305
4261
  {
3306
4262
  className: cn("my-5 border-b", className),
@@ -3310,55 +4266,89 @@ var defaultComponents = {
3310
4266
  table: ({
3311
4267
  className,
3312
4268
  node: _node,
4269
+ style,
3313
4270
  ...props
3314
- }) => /* @__PURE__ */ jsx19(
3315
- "table",
4271
+ }) => /* @__PURE__ */ jsx21(
4272
+ "div",
3316
4273
  {
3317
- className: cn(
3318
- "my-5 w-full border-separate border-spacing-0 overflow-y-auto",
3319
- className
3320
- ),
3321
- ...props
4274
+ "data-slot": "markdown-table-container",
4275
+ className: "my-5 max-w-full overflow-x-auto rounded-xl border border-border bg-background",
4276
+ children: /* @__PURE__ */ jsx21(
4277
+ "table",
4278
+ {
4279
+ className: cn(
4280
+ "min-w-full w-max border-separate border-spacing-0 text-sm",
4281
+ className
4282
+ ),
4283
+ style: {
4284
+ lineHeight: markdownTableLineHeight,
4285
+ ...style
4286
+ },
4287
+ ...props
4288
+ }
4289
+ )
3322
4290
  }
3323
4291
  ),
3324
- th: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4292
+ th: ({
4293
+ className,
4294
+ node: _node,
4295
+ style,
4296
+ ...props
4297
+ }) => /* @__PURE__ */ jsx21(
3325
4298
  "th",
3326
4299
  {
3327
4300
  className: cn(
3328
- "bg-muted border-border border-y border-l px-4 py-2 text-left font-bold first:rounded-tl-lg last:rounded-tr-lg last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
4301
+ "bg-muted/80 border-border border-l text-left align-top font-semibold whitespace-normal break-words first:border-l-0 first:rounded-tl-xl last:rounded-tr-xl [&[align=center]]:text-center [&[align=right]]:text-right",
3329
4302
  className
3330
4303
  ),
4304
+ style: {
4305
+ minWidth: markdownTableMinWidth,
4306
+ paddingInline: markdownTableCellPaddingInline,
4307
+ paddingBlock: markdownTableCellPaddingBlock,
4308
+ ...style
4309
+ },
3331
4310
  ...props
3332
4311
  }
3333
4312
  ),
3334
- td: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4313
+ td: ({
4314
+ className,
4315
+ node: _node,
4316
+ style,
4317
+ ...props
4318
+ }) => /* @__PURE__ */ jsx21(
3335
4319
  "td",
3336
4320
  {
3337
4321
  className: cn(
3338
- "border-border border-b border-l px-4 py-2 text-left last:border-r [&[align=center]]:text-center [&[align=right]]:text-right",
4322
+ "border-border border-t border-l text-left align-top whitespace-normal break-words first:border-l-0 [&[align=center]]:text-center [&[align=right]]:text-right [&_code]:break-words [&_code]:whitespace-pre-wrap [&_code]:[overflow-wrap:anywhere]",
3339
4323
  className
3340
4324
  ),
4325
+ style: {
4326
+ minWidth: markdownTableMinWidth,
4327
+ paddingInline: markdownTableCellPaddingInline,
4328
+ paddingBlock: markdownTableCellPaddingBlock,
4329
+ ...style
4330
+ },
3341
4331
  ...props
3342
4332
  }
3343
4333
  ),
3344
- tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4334
+ tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3345
4335
  "tr",
3346
4336
  {
3347
4337
  className: cn(
3348
- "m-0 p-0 even:bg-muted/50 [&:last-child>td:first-child]:rounded-bl-lg [&:last-child>td:last-child]:rounded-br-lg",
4338
+ "m-0 p-0 even:bg-muted/30 [&:last-child>td:first-child]:rounded-bl-xl [&:last-child>td:last-child]:rounded-br-xl",
3349
4339
  className
3350
4340
  ),
3351
4341
  ...props
3352
4342
  }
3353
4343
  ),
3354
- sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
4344
+ sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx21(
3355
4345
  "sup",
3356
4346
  {
3357
4347
  className: cn("[&>a]:text-xs [&>a]:no-underline", className),
3358
4348
  ...props
3359
4349
  }
3360
4350
  ),
3361
- pre: ({ className, children, node: _node }) => Children.toArray(children).length === 1 && (isMermaidBlockChild(Children.toArray(children)[0]) || isMermaidCodeElement(Children.toArray(children)[0])) ? /* @__PURE__ */ jsx19(Fragment3, { children }) : /* @__PURE__ */ jsx19(
4351
+ pre: ({ className, children, node: _node }) => Children.toArray(children).length === 1 && (isMermaidBlockChild(Children.toArray(children)[0]) || isMermaidCodeElement(Children.toArray(children)[0])) ? /* @__PURE__ */ jsx21(Fragment3, { children }) : /* @__PURE__ */ jsx21(
3362
4352
  "div",
3363
4353
  {
3364
4354
  className: cn(
@@ -3372,6 +4362,7 @@ var defaultComponents = {
3372
4362
  className,
3373
4363
  children,
3374
4364
  node: _node,
4365
+ style,
3375
4366
  ...props
3376
4367
  }) => {
3377
4368
  const match = /language-([\w-]+)/.exec(className || "");
@@ -3381,17 +4372,17 @@ var defaultComponents = {
3381
4372
  const language = match[1];
3382
4373
  const normalizedCode = code.replace(/\n$/, "");
3383
4374
  if (language === "mermaid") {
3384
- return /* @__PURE__ */ jsx19(MermaidBlock, { code: normalizedCode });
4375
+ return /* @__PURE__ */ jsx21(MermaidBlock, { code: normalizedCode });
3385
4376
  }
3386
- return /* @__PURE__ */ jsxs10(Fragment3, { children: [
3387
- /* @__PURE__ */ jsx19(
4377
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
4378
+ /* @__PURE__ */ jsx21(
3388
4379
  CodeHeader,
3389
4380
  {
3390
4381
  language,
3391
4382
  code: normalizedCode
3392
4383
  }
3393
4384
  ),
3394
- /* @__PURE__ */ jsx19(
4385
+ /* @__PURE__ */ jsx21(
3395
4386
  SyntaxHighlighter,
3396
4387
  {
3397
4388
  language,
@@ -3402,58 +4393,870 @@ var defaultComponents = {
3402
4393
  ] });
3403
4394
  }
3404
4395
  if (isBlockCode) {
3405
- return /* @__PURE__ */ jsx19(
4396
+ return /* @__PURE__ */ jsx21(
3406
4397
  "code",
3407
4398
  {
3408
4399
  className: cn(
3409
- "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
3410
- className
4400
+ "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
4401
+ className
4402
+ ),
4403
+ ...props,
4404
+ children: code.replace(/\n$/, "")
4405
+ }
4406
+ );
4407
+ }
4408
+ return /* @__PURE__ */ jsx21(
4409
+ "code",
4410
+ {
4411
+ className: cn(
4412
+ "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
4413
+ className
4414
+ ),
4415
+ style: {
4416
+ paddingInline: markdownInlineCodePaddingInline,
4417
+ paddingBlock: markdownInlineCodePaddingBlock,
4418
+ ...style
4419
+ },
4420
+ ...props,
4421
+ children
4422
+ }
4423
+ );
4424
+ }
4425
+ };
4426
+ var MarkdownTextImpl = ({ children }) => {
4427
+ return /* @__PURE__ */ jsx21("div", { className: "markdown-content", children: /* @__PURE__ */ jsx21(
4428
+ ReactMarkdown,
4429
+ {
4430
+ remarkPlugins: [remarkGfm, remarkMath],
4431
+ rehypePlugins: [rehypeKatex],
4432
+ components: defaultComponents,
4433
+ children
4434
+ }
4435
+ ) });
4436
+ };
4437
+ var MarkdownText = memo(MarkdownTextImpl);
4438
+
4439
+ // src/components/thread/messages/tool-component-group.tsx
4440
+ import * as React17 from "react";
4441
+ import {
4442
+ Check as Check2,
4443
+ CheckCircle2 as CheckCircle22,
4444
+ ChevronRight as ChevronRight2,
4445
+ Copy,
4446
+ Loader2 as Loader22,
4447
+ XCircle
4448
+ } from "lucide-react";
4449
+
4450
+ // src/i18n/localized-text.ts
4451
+ function resolveLocalizedText(value, language) {
4452
+ if (typeof value === "string") {
4453
+ const trimmed = value.trim();
4454
+ return trimmed || null;
4455
+ }
4456
+ if (!value || typeof value !== "object") return null;
4457
+ const localized = value;
4458
+ const normalizedLanguage = language.trim();
4459
+ const underscoredLanguage = normalizedLanguage.replace(/-/g, "_");
4460
+ const languagePrefix = normalizedLanguage.split("-")[0];
4461
+ const preferredKeys = normalizedLanguage.startsWith("zh") ? [
4462
+ normalizedLanguage,
4463
+ underscoredLanguage,
4464
+ "zh_Hans",
4465
+ "zh-Hans",
4466
+ "zh_CN",
4467
+ "zh-CN",
4468
+ "zh",
4469
+ "en_US",
4470
+ "en-US",
4471
+ "en"
4472
+ ] : [
4473
+ normalizedLanguage,
4474
+ underscoredLanguage,
4475
+ "en_US",
4476
+ "en-US",
4477
+ "en",
4478
+ languagePrefix,
4479
+ "zh_Hans",
4480
+ "zh-Hans",
4481
+ "zh_CN",
4482
+ "zh-CN",
4483
+ "zh"
4484
+ ];
4485
+ for (const key of preferredKeys) {
4486
+ const candidate = localized[key];
4487
+ if (typeof candidate === "string" && candidate.trim()) {
4488
+ return candidate.trim();
4489
+ }
4490
+ }
4491
+ for (const candidate of Object.values(localized)) {
4492
+ if (typeof candidate === "string" && candidate.trim()) {
4493
+ return candidate.trim();
4494
+ }
4495
+ }
4496
+ return null;
4497
+ }
4498
+
4499
+ // src/components/thread/messages/tool-component-group.tsx
4500
+ import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
4501
+ var toolStatusConfig = {
4502
+ success: {
4503
+ iconClass: "border-green-500 text-green-700",
4504
+ icon: CheckCircle22
4505
+ },
4506
+ fail: {
4507
+ iconClass: "border-red-500 text-red-700",
4508
+ icon: XCircle
4509
+ },
4510
+ running: {
4511
+ iconClass: "border-blue-500 text-blue-700",
4512
+ icon: Loader22
4513
+ }
4514
+ };
4515
+ var TOOL_GROUP_CATEGORY_ORDER = [
4516
+ "files",
4517
+ "searches",
4518
+ "commands",
4519
+ "lists",
4520
+ "tasks",
4521
+ "knowledges",
4522
+ "tools"
4523
+ ];
4524
+ var TOOL_GROUP_TOKEN_CATEGORY = {
4525
+ file: "files",
4526
+ files: "files",
4527
+ web_search: "searches",
4528
+ search: "searches",
4529
+ searches: "searches",
4530
+ program: "commands",
4531
+ command: "commands",
4532
+ commands: "commands",
4533
+ shell: "commands",
4534
+ terminal: "commands",
4535
+ list: "lists",
4536
+ lists: "lists",
4537
+ task: "tasks",
4538
+ tasks: "tasks",
4539
+ todo: "tasks",
4540
+ todos: "tasks",
4541
+ knowledge: "knowledges",
4542
+ knowledges: "knowledges",
4543
+ retriever: "knowledges",
4544
+ retrieval: "knowledges",
4545
+ tool: "tools",
4546
+ tools: "tools"
4547
+ };
4548
+ var TOOL_CALL_OUTPUT_RENDERERS = {};
4549
+ function getToolStepData(content) {
4550
+ return content.data ?? {};
4551
+ }
4552
+ function safeJson(value) {
4553
+ try {
4554
+ return JSON.stringify(value, null, 2) ?? String(value);
4555
+ } catch {
4556
+ return String(value);
4557
+ }
4558
+ }
4559
+ function formatDisplayValue(value) {
4560
+ return typeof value === "string" ? value : safeJson(value);
4561
+ }
4562
+ function parseStepDate(value) {
4563
+ if (value instanceof Date) {
4564
+ const timestamp2 = value.getTime();
4565
+ return Number.isNaN(timestamp2) ? null : timestamp2;
4566
+ }
4567
+ if (typeof value !== "string") {
4568
+ return null;
4569
+ }
4570
+ const timestamp = Date.parse(value);
4571
+ return Number.isNaN(timestamp) ? null : timestamp;
4572
+ }
4573
+ function formatStepDuration(durationMs) {
4574
+ if (durationMs < 1e3) {
4575
+ return `${durationMs}ms`;
4576
+ }
4577
+ if (durationMs < 1e4) {
4578
+ return `${(durationMs / 1e3).toFixed(1)}s`;
4579
+ }
4580
+ if (durationMs < 6e4) {
4581
+ return `${Math.round(durationMs / 1e3)}s`;
4582
+ }
4583
+ const hours = Math.floor(durationMs / 36e5);
4584
+ const minutes = Math.floor(durationMs % 36e5 / 6e4);
4585
+ const seconds = Math.floor(durationMs % 6e4 / 1e3);
4586
+ if (hours > 0) {
4587
+ return `${hours}h ${minutes}m ${seconds}s`;
4588
+ }
4589
+ return `${minutes}m ${seconds}s`;
4590
+ }
4591
+ function useToolStepDurationLabel(data) {
4592
+ const [durationNow, setDurationNow] = React17.useState(() => Date.now());
4593
+ const createdAt = parseStepDate(data.created_date);
4594
+ const endedAt = parseStepDate(data.end_date);
4595
+ const status = data.status;
4596
+ React17.useEffect(() => {
4597
+ if (status !== "running" || createdAt === null || endedAt !== null) {
4598
+ return;
4599
+ }
4600
+ setDurationNow(Date.now());
4601
+ const timer = window.setInterval(() => {
4602
+ setDurationNow(Date.now());
4603
+ }, 100);
4604
+ return () => {
4605
+ window.clearInterval(timer);
4606
+ };
4607
+ }, [createdAt, endedAt, status]);
4608
+ if (createdAt === null) return null;
4609
+ const durationMs = Math.max(0, (endedAt ?? durationNow) - createdAt);
4610
+ return formatStepDuration(durationMs);
4611
+ }
4612
+ function isJsonObjectValue(value) {
4613
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4614
+ }
4615
+ function canUseAsJsonValue(value) {
4616
+ if (value === null) return true;
4617
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
4618
+ return true;
4619
+ }
4620
+ if (Array.isArray(value)) {
4621
+ return value.every(canUseAsJsonValue);
4622
+ }
4623
+ if (typeof value === "object") {
4624
+ return Object.values(value).every(canUseAsJsonValue);
4625
+ }
4626
+ return false;
4627
+ }
4628
+ function parseJsonString(value) {
4629
+ const trimmed = value.trim();
4630
+ if (!trimmed) return null;
4631
+ const first = trimmed[0];
4632
+ if (first !== "{" && first !== "[") return null;
4633
+ try {
4634
+ const parsed = JSON.parse(trimmed);
4635
+ return canUseAsJsonValue(parsed) ? parsed : null;
4636
+ } catch {
4637
+ return null;
4638
+ }
4639
+ }
4640
+ function detectJsonValue(value) {
4641
+ if (typeof value === "string") {
4642
+ const parsed = parseJsonString(value);
4643
+ if (parsed !== null) {
4644
+ return {
4645
+ kind: "json",
4646
+ value: parsed,
4647
+ raw: safeJson(parsed)
4648
+ };
4649
+ }
4650
+ return { kind: "text", text: value };
4651
+ }
4652
+ if (canUseAsJsonValue(value) && value !== null && typeof value === "object") {
4653
+ return {
4654
+ kind: "json",
4655
+ value,
4656
+ raw: safeJson(value)
4657
+ };
4658
+ }
4659
+ return { kind: "text", text: formatDisplayValue(value) };
4660
+ }
4661
+ function isComponentContent(content) {
4662
+ return content.type === "component";
4663
+ }
4664
+ function isTextContent(content) {
4665
+ return content.type === "text";
4666
+ }
4667
+ function isReasoningContent(content) {
4668
+ return content.type === "reasoning";
4669
+ }
4670
+ function isWidgetComponent(content) {
4671
+ const data = content.data;
4672
+ return data?.type === "Widget" && Array.isArray(data.widgets);
4673
+ }
4674
+ function isGroupableToolComponent(content) {
4675
+ if (!content || typeof content === "string") return false;
4676
+ return isComponentContent(content) && !isWidgetComponent(content) && content.data?.category === "Tool";
4677
+ }
4678
+ function isSkippableToolGroupSeparator(content) {
4679
+ if (typeof content === "string") return !content.trim();
4680
+ if (!content) return true;
4681
+ if (isTextContent(content)) {
4682
+ return !content.text?.trim();
4683
+ }
4684
+ if (isReasoningContent(content)) {
4685
+ return !content.text?.trim();
4686
+ }
4687
+ return false;
4688
+ }
4689
+ function normalizeToolToken(value) {
4690
+ if (typeof value !== "string") return null;
4691
+ const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
4692
+ return normalized || null;
4693
+ }
4694
+ function classifyToolToken(value) {
4695
+ const normalized = normalizeToolToken(
4696
+ typeof value === "string" ? value : resolveLocalizedText(value, "en-US")
4697
+ );
4698
+ if (!normalized) return null;
4699
+ const directMatch = TOOL_GROUP_TOKEN_CATEGORY[normalized];
4700
+ if (directMatch) return directMatch;
4701
+ if (normalized.includes("search")) return "searches";
4702
+ if (normalized.includes("file")) return "files";
4703
+ if (normalized.includes("command") || normalized.includes("cmd") || normalized.includes("program") || normalized.includes("exec") || normalized.startsWith("run_") || normalized.includes("_run")) {
4704
+ return "commands";
4705
+ }
4706
+ if (normalized.includes("list")) return "lists";
4707
+ if (normalized.includes("task") || normalized.includes("todo")) return "tasks";
4708
+ if (normalized.includes("knowledge") || normalized.includes("retriever")) {
4709
+ return "knowledges";
4710
+ }
4711
+ return null;
4712
+ }
4713
+ function getToolGroupCategory(content) {
4714
+ const data = getToolStepData(content);
4715
+ return classifyToolToken(data.type) ?? classifyToolToken(data.tool) ?? classifyToolToken(data.title) ?? classifyToolToken(data.message) ?? "tools";
4716
+ }
4717
+ function getToolGroupCategoryCounts(items) {
4718
+ return items.reduce((counts, item) => {
4719
+ const category = getToolGroupCategory(item);
4720
+ counts[category] = (counts[category] ?? 0) + 1;
4721
+ return counts;
4722
+ }, {});
4723
+ }
4724
+ function getToolGroupDisplayStatus(items) {
4725
+ if (items.some((item) => getToolStepData(item).status === "fail")) {
4726
+ return "fail";
4727
+ }
4728
+ return "success";
4729
+ }
4730
+ function getToolActivityLabel(content, language) {
4731
+ const data = getToolStepData(content);
4732
+ const runningCandidates = [data.message, data.title, data.tool, data.type];
4733
+ const completedCandidates = [data.title, data.message, data.tool, data.type];
4734
+ const candidates = data.status === "running" ? runningCandidates : completedCandidates;
4735
+ for (const candidate of candidates) {
4736
+ const label = resolveLocalizedText(candidate, language);
4737
+ if (label) return label;
4738
+ }
4739
+ return "Tool";
4740
+ }
4741
+ function flushPendingTools(units, pendingTools) {
4742
+ if (pendingTools.length === 0) return;
4743
+ units.push({
4744
+ type: "tool-group",
4745
+ items: pendingTools.map((tool) => tool.item),
4746
+ startIndex: pendingTools[0].index
4747
+ });
4748
+ pendingTools.length = 0;
4749
+ }
4750
+ function buildToolComponentRenderUnits(content, options) {
4751
+ const units = [];
4752
+ const pendingTools = [];
4753
+ content.forEach((item, index) => {
4754
+ if (isGroupableToolComponent(item) && options?.shouldGroupComponent?.(item) !== false) {
4755
+ pendingTools.push({ item, index });
4756
+ return;
4757
+ }
4758
+ if (isSkippableToolGroupSeparator(item)) {
4759
+ return;
4760
+ }
4761
+ if (item === void 0) {
4762
+ return;
4763
+ }
4764
+ flushPendingTools(units, pendingTools);
4765
+ units.push({ type: "item", item, index });
4766
+ });
4767
+ flushPendingTools(units, pendingTools);
4768
+ return units;
4769
+ }
4770
+ function getToolCallOutputRenderer(data) {
4771
+ const keys = [data.tool, data.type].filter(
4772
+ (value) => typeof value === "string" && Boolean(value.trim())
4773
+ );
4774
+ for (const key of keys) {
4775
+ const renderer = TOOL_CALL_OUTPUT_RENDERERS[key];
4776
+ if (renderer) return renderer;
4777
+ }
4778
+ return DefaultToolCallOutput;
4779
+ }
4780
+ function getJsonValueSummary(value) {
4781
+ if (Array.isArray(value)) {
4782
+ return `Array(${value.length})`;
4783
+ }
4784
+ if (isJsonObjectValue(value)) {
4785
+ return `Object(${Object.keys(value).length})`;
4786
+ }
4787
+ return "JSON";
4788
+ }
4789
+ function formatJsonPrimitive(value) {
4790
+ if (value === null) return "null";
4791
+ if (typeof value === "string") return JSON.stringify(value);
4792
+ return String(value);
4793
+ }
4794
+ function JsonTreeNode({
4795
+ label,
4796
+ value,
4797
+ depth = 0
4798
+ }) {
4799
+ const isArray = Array.isArray(value);
4800
+ const isObject = isJsonObjectValue(value);
4801
+ const isExpandable = isArray || isObject;
4802
+ const [isExpanded, setIsExpanded] = React17.useState(depth < 2);
4803
+ if (!isExpandable) {
4804
+ return /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 gap-2 leading-6", children: [
4805
+ label ? /* @__PURE__ */ jsxs13("span", { className: "shrink-0 font-medium text-foreground/80", children: [
4806
+ label,
4807
+ ":"
4808
+ ] }) : null,
4809
+ /* @__PURE__ */ jsx22(
4810
+ "span",
4811
+ {
4812
+ className: cn(
4813
+ "min-w-0 wrap-break-word",
4814
+ typeof value === "string" ? "text-emerald-700" : typeof value === "number" ? "text-blue-700" : typeof value === "boolean" ? "text-purple-700" : "text-muted-foreground"
3411
4815
  ),
3412
- ...props,
3413
- children: code.replace(/\n$/, "")
4816
+ children: formatJsonPrimitive(value)
3414
4817
  }
3415
- );
4818
+ )
4819
+ ] });
4820
+ }
4821
+ const entries = isArray ? value.map((item, index) => [String(index), item]) : Object.entries(value);
4822
+ const summary = isArray ? `Array(${value.length})` : `Object(${entries.length})`;
4823
+ return /* @__PURE__ */ jsxs13("div", { className: "min-w-0", children: [
4824
+ /* @__PURE__ */ jsxs13(
4825
+ "button",
4826
+ {
4827
+ type: "button",
4828
+ className: "flex min-w-0 items-center gap-1 leading-6 text-left hover:text-foreground",
4829
+ "aria-expanded": isExpanded,
4830
+ onClick: () => setIsExpanded((prev) => !prev),
4831
+ children: [
4832
+ /* @__PURE__ */ jsx22(
4833
+ ChevronRight2,
4834
+ {
4835
+ "aria-hidden": "true",
4836
+ className: cn(
4837
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
4838
+ isExpanded && "rotate-90"
4839
+ )
4840
+ }
4841
+ ),
4842
+ label ? /* @__PURE__ */ jsxs13("span", { className: "min-w-0 truncate font-medium text-foreground/80", children: [
4843
+ label,
4844
+ ":"
4845
+ ] }) : null,
4846
+ /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-muted-foreground", children: summary })
4847
+ ]
4848
+ }
4849
+ ),
4850
+ isExpanded ? /* @__PURE__ */ jsx22("div", { className: "ml-4 border-l border-border/70 pl-3", children: entries.map(([entryLabel, entryValue]) => /* @__PURE__ */ jsx22(
4851
+ JsonTreeNode,
4852
+ {
4853
+ label: entryLabel,
4854
+ value: entryValue,
4855
+ depth: depth + 1
4856
+ },
4857
+ entryLabel
4858
+ )) }) : null
4859
+ ] });
4860
+ }
4861
+ function JsonTreeView({ value }) {
4862
+ return /* @__PURE__ */ jsx22("div", { className: "min-w-0 font-mono text-[11px]", children: /* @__PURE__ */ jsx22(JsonTreeNode, { value }) });
4863
+ }
4864
+ function RawJsonBlock({ raw }) {
4865
+ return /* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap wrap-break-word font-mono text-[11px]", children: raw });
4866
+ }
4867
+ function PlainTextBlock({ value, destructive = false }) {
4868
+ return /* @__PURE__ */ jsx22(
4869
+ "pre",
4870
+ {
4871
+ className: cn(
4872
+ "whitespace-pre-wrap wrap-break-word",
4873
+ destructive && "text-destructive"
4874
+ ),
4875
+ children: value
3416
4876
  }
3417
- return /* @__PURE__ */ jsx19(
3418
- "code",
4877
+ );
4878
+ }
4879
+ function ToolCallCopyButton({ value }) {
4880
+ const { t } = useChatkitTranslation();
4881
+ const [isCopied, setIsCopied] = React17.useState(false);
4882
+ const resetTimeoutRef = React17.useRef(null);
4883
+ const clearResetTimeout = React17.useCallback(() => {
4884
+ if (resetTimeoutRef.current === null) return;
4885
+ window.clearTimeout(resetTimeoutRef.current);
4886
+ resetTimeoutRef.current = null;
4887
+ }, []);
4888
+ React17.useEffect(() => clearResetTimeout, [clearResetTimeout]);
4889
+ const handleCopy = React17.useCallback(() => {
4890
+ if (typeof navigator === "undefined" || !navigator.clipboard) return;
4891
+ void navigator.clipboard.writeText(value).then(() => {
4892
+ setIsCopied(true);
4893
+ clearResetTimeout();
4894
+ resetTimeoutRef.current = window.setTimeout(() => {
4895
+ setIsCopied(false);
4896
+ resetTimeoutRef.current = null;
4897
+ }, 1500);
4898
+ }).catch(() => void 0);
4899
+ }, [clearResetTimeout, value]);
4900
+ const label = isCopied ? t("message.toolGroup.copied") : t("message.toolGroup.copy");
4901
+ return /* @__PURE__ */ jsx22(
4902
+ "button",
4903
+ {
4904
+ type: "button",
4905
+ 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",
4906
+ "aria-label": label,
4907
+ title: label,
4908
+ onClick: handleCopy,
4909
+ children: isCopied ? /* @__PURE__ */ jsx22(Check2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx22(Copy, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
4910
+ }
4911
+ );
4912
+ }
4913
+ function ToolCallValueBlock({
4914
+ value,
4915
+ destructive = false
4916
+ }) {
4917
+ const { t } = useChatkitTranslation();
4918
+ const detected = detectJsonValue(value);
4919
+ if (detected.kind === "text") {
4920
+ return /* @__PURE__ */ jsxs13("div", { className: "min-w-0 space-y-1", children: [
4921
+ /* @__PURE__ */ jsx22("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx22(ToolCallCopyButton, { value: detected.text }) }),
4922
+ /* @__PURE__ */ jsx22(PlainTextBlock, { value: detected.text, destructive })
4923
+ ] });
4924
+ }
4925
+ return /* @__PURE__ */ jsxs13(Tabs, { defaultValue: "tree", className: "min-w-0", children: [
4926
+ /* @__PURE__ */ jsxs13("div", { className: "mb-2 flex min-w-0 items-center justify-between gap-2", children: [
4927
+ /* @__PURE__ */ jsxs13("span", { className: "min-w-0 truncate text-[11px] text-muted-foreground", children: [
4928
+ t("message.toolGroup.jsonTitle"),
4929
+ " \xB7 ",
4930
+ getJsonValueSummary(detected.value)
4931
+ ] }),
4932
+ /* @__PURE__ */ jsxs13("div", { className: "flex shrink-0 items-center gap-1", children: [
4933
+ /* @__PURE__ */ jsx22(ToolCallCopyButton, { value: detected.raw }),
4934
+ /* @__PURE__ */ jsxs13(TabsList, { className: "rounded-md p-0.5", children: [
4935
+ /* @__PURE__ */ jsx22(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "tree", children: t("message.toolGroup.jsonTree") }),
4936
+ /* @__PURE__ */ jsx22(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "raw", children: t("message.toolGroup.jsonRaw") })
4937
+ ] })
4938
+ ] })
4939
+ ] }),
4940
+ /* @__PURE__ */ jsx22(TabsContent, { value: "tree", className: "mt-0", children: /* @__PURE__ */ jsx22(JsonTreeView, { value: detected.value }) }),
4941
+ /* @__PURE__ */ jsx22(TabsContent, { value: "raw", className: "mt-0", children: /* @__PURE__ */ jsx22(RawJsonBlock, { raw: detected.raw }) })
4942
+ ] });
4943
+ }
4944
+ function DefaultToolCallOutput({ data }) {
4945
+ const { t } = useChatkitTranslation();
4946
+ const output = data.output ?? null;
4947
+ const error = data.error ?? null;
4948
+ if (error) {
4949
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
4950
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-destructive", children: t("message.toolGroup.errorTitle") }),
4951
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: error, destructive: true })
4952
+ ] });
4953
+ }
4954
+ if (output === null) return null;
4955
+ return /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
4956
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.outputTitle") }),
4957
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: output })
4958
+ ] });
4959
+ }
4960
+ function ToolCallDetails({ content }) {
4961
+ const { t } = useChatkitTranslation();
4962
+ const data = getToolStepData(content);
4963
+ const OutputRenderer = getToolCallOutputRenderer(data);
4964
+ const hasInput = data.input !== void 0 && data.input !== null;
4965
+ const hasOutput = data.error !== void 0 || data.output !== void 0;
4966
+ if (!hasInput && !hasOutput) return null;
4967
+ return /* @__PURE__ */ jsxs13("div", { className: "ml-6 mt-1 max-h-60 overflow-auto rounded-md bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: [
4968
+ hasInput && /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
4969
+ /* @__PURE__ */ jsx22("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.inputTitle") }),
4970
+ /* @__PURE__ */ jsx22(ToolCallValueBlock, { value: data.input })
4971
+ ] }),
4972
+ hasInput && hasOutput ? /* @__PURE__ */ jsx22("div", { className: "h-2" }) : null,
4973
+ hasOutput ? /* @__PURE__ */ jsx22(OutputRenderer, { content, data }) : null
4974
+ ] });
4975
+ }
4976
+ function ToolCallRow({ content }) {
4977
+ const { i18n: i18n2 } = useChatkitTranslation();
4978
+ const data = getToolStepData(content);
4979
+ const status = data.status;
4980
+ const itemConfig = status ? toolStatusConfig[status] : null;
4981
+ const ItemStatusIcon = itemConfig?.icon;
4982
+ const hasError = status === "fail" || Boolean(data.error);
4983
+ const label = getToolActivityLabel(content, i18n2.language);
4984
+ const detailsId = React17.useId();
4985
+ const hasDetails = data.input !== void 0 || data.error !== void 0 || data.output !== void 0;
4986
+ const durationLabel = useToolStepDurationLabel(data);
4987
+ const [isExpanded, setIsExpanded] = React17.useState(false);
4988
+ React17.useEffect(() => {
4989
+ if (status === "running" && data.output !== void 0) {
4990
+ setIsExpanded(true);
4991
+ }
4992
+ }, [data.output, status]);
4993
+ return /* @__PURE__ */ jsxs13("li", { className: "min-w-0", children: [
4994
+ /* @__PURE__ */ jsxs13(
4995
+ "button",
3419
4996
  {
4997
+ type: "button",
3420
4998
  className: cn(
3421
- "bg-muted rounded px-1.5 py-0.5 font-mono text-[0.9em] font-semibold break-all",
3422
- className
4999
+ "flex w-full min-w-0 items-center gap-2 text-left text-sm leading-6 text-muted-foreground",
5000
+ hasDetails && "cursor-pointer hover:text-foreground",
5001
+ hasError && "text-destructive hover:text-destructive"
3423
5002
  ),
3424
- ...props,
3425
- children
5003
+ "aria-expanded": hasDetails ? isExpanded : void 0,
5004
+ "aria-controls": hasDetails ? detailsId : void 0,
5005
+ disabled: !hasDetails,
5006
+ onClick: () => {
5007
+ if (hasDetails) setIsExpanded((prev) => !prev);
5008
+ },
5009
+ children: [
5010
+ ItemStatusIcon ? /* @__PURE__ */ jsx22(
5011
+ ItemStatusIcon,
5012
+ {
5013
+ className: cn(
5014
+ "h-3.5 w-3.5 shrink-0",
5015
+ itemConfig?.iconClass,
5016
+ status === "running" && "animate-spin"
5017
+ )
5018
+ }
5019
+ ) : /* @__PURE__ */ jsx22("span", { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
5020
+ /* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1 truncate", title: label, children: label }),
5021
+ durationLabel ? /* @__PURE__ */ jsx22("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground/80", children: durationLabel }) : null,
5022
+ hasDetails ? /* @__PURE__ */ jsx22(
5023
+ ChevronRight2,
5024
+ {
5025
+ "aria-hidden": "true",
5026
+ className: cn(
5027
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
5028
+ isExpanded && "rotate-90"
5029
+ )
5030
+ }
5031
+ ) : null
5032
+ ]
3426
5033
  }
3427
- );
5034
+ ),
5035
+ hasDetails && isExpanded ? /* @__PURE__ */ jsx22("div", { id: detailsId, children: /* @__PURE__ */ jsx22(ToolCallDetails, { content }) }) : null
5036
+ ] });
5037
+ }
5038
+ function ToolComponentGroup({
5039
+ items,
5040
+ hasFollowingItem
5041
+ }) {
5042
+ const { t } = useChatkitTranslation();
5043
+ const contentId = React17.useId();
5044
+ const groupStatus = getToolGroupDisplayStatus(items);
5045
+ const [isExpanded, setIsExpanded] = React17.useState(!hasFollowingItem);
5046
+ const categoryCounts = getToolGroupCategoryCounts(items);
5047
+ const categorySummary = TOOL_GROUP_CATEGORY_ORDER.flatMap((category) => {
5048
+ const count = categoryCounts[category] ?? 0;
5049
+ if (count === 0) return [];
5050
+ return [
5051
+ t(
5052
+ `message.toolGroup.categories.${category}.${count === 1 ? "one" : "other"}`,
5053
+ { count }
5054
+ )
5055
+ ];
5056
+ }).join(t("message.toolGroup.separator"));
5057
+ const summary = `${t(`message.toolGroup.status.${groupStatus}`)} ${categorySummary}`;
5058
+ const config = toolStatusConfig[groupStatus];
5059
+ const StatusIcon = config.icon;
5060
+ React17.useEffect(() => {
5061
+ setIsExpanded(!hasFollowingItem);
5062
+ }, [hasFollowingItem, items.length]);
5063
+ return /* @__PURE__ */ jsxs13("div", { className: "px-1 py-1", children: [
5064
+ /* @__PURE__ */ jsxs13(
5065
+ "button",
5066
+ {
5067
+ type: "button",
5068
+ 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",
5069
+ "aria-expanded": isExpanded,
5070
+ "aria-controls": contentId,
5071
+ onClick: () => setIsExpanded((prev) => !prev),
5072
+ children: [
5073
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
5074
+ /* @__PURE__ */ jsx22(
5075
+ StatusIcon,
5076
+ {
5077
+ className: cn(
5078
+ "h-4 w-4 shrink-0",
5079
+ config.iconClass
5080
+ )
5081
+ }
5082
+ ),
5083
+ /* @__PURE__ */ jsx22("span", { className: "truncate", children: summary })
5084
+ ] }),
5085
+ /* @__PURE__ */ jsx22(
5086
+ ChevronRight2,
5087
+ {
5088
+ "aria-hidden": "true",
5089
+ className: cn(
5090
+ "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
5091
+ isExpanded && "rotate-90"
5092
+ )
5093
+ }
5094
+ )
5095
+ ]
5096
+ }
5097
+ ),
5098
+ isExpanded && /* @__PURE__ */ jsx22("ul", { id: contentId, className: "mt-2 max-h-[200px] space-y-1.5 overflow-y-auto pr-1", children: items.map((item, index) => /* @__PURE__ */ jsx22(ToolCallRow, { content: item }, item.id ?? `tool-item-${index}`)) })
5099
+ ] });
5100
+ }
5101
+
5102
+ // src/components/thread/messages/request-user-input-result-card.tsx
5103
+ import "react";
5104
+ import {
5105
+ REQUEST_USER_INPUT_TOOL_NAME as REQUEST_USER_INPUT_TOOL_NAME2
5106
+ } from "@xpert-ai/chatkit-types";
5107
+ import { CheckCircle2 as CheckCircle23 } from "lucide-react";
5108
+ import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
5109
+ function isRecord2(value) {
5110
+ return !!value && typeof value === "object" && !Array.isArray(value);
5111
+ }
5112
+ function readString(record, keys) {
5113
+ for (const key of keys) {
5114
+ const value = record[key];
5115
+ if (typeof value === "string" && value.trim()) {
5116
+ return value.trim();
5117
+ }
3428
5118
  }
3429
- };
3430
- var MarkdownTextImpl = ({ children }) => {
3431
- return /* @__PURE__ */ jsx19("div", { className: "markdown-content", children: /* @__PURE__ */ jsx19(
3432
- ReactMarkdown,
5119
+ return null;
5120
+ }
5121
+ function getToolCallId(value) {
5122
+ if (!isRecord2(value)) return null;
5123
+ return readString(value, ["id"]);
5124
+ }
5125
+ function getToolCallName(value) {
5126
+ if (!isRecord2(value)) return null;
5127
+ return readString(value, ["name"]);
5128
+ }
5129
+ function pushClientToolCallsFromRecord(record, calls) {
5130
+ const clientToolCalls = record.clientToolCalls;
5131
+ if (Array.isArray(clientToolCalls)) {
5132
+ calls.push(...clientToolCalls);
5133
+ }
5134
+ }
5135
+ function collectPotentialToolCalls(messages) {
5136
+ const calls = [];
5137
+ const messageList = Array.isArray(messages) ? messages : [messages];
5138
+ for (const message of messageList) {
5139
+ const rawMessage = message;
5140
+ pushClientToolCallsFromRecord(rawMessage, calls);
5141
+ }
5142
+ return calls;
5143
+ }
5144
+ function findRequestUserInputClientToolCallById(messages, id) {
5145
+ if (!id) return null;
5146
+ return collectPotentialToolCalls(messages).find(
5147
+ (call) => getToolCallId(call) === id && getToolCallName(call) === REQUEST_USER_INPUT_TOOL_NAME2
5148
+ ) ?? null;
5149
+ }
5150
+ function normalizeAnswer(value) {
5151
+ if (!isRecord2(value)) return null;
5152
+ const id = readString(value, ["id"]);
5153
+ const question = readString(value, ["question"]);
5154
+ const answerValue = readString(value, ["value"]);
5155
+ const type = readString(value, ["type"]);
5156
+ if (!id || !question || !answerValue || type !== "option" && type !== "other") {
5157
+ return null;
5158
+ }
5159
+ const label = readString(value, ["label"]);
5160
+ const description = readString(value, ["description"]);
5161
+ return {
5162
+ id,
5163
+ question,
5164
+ value: answerValue,
5165
+ type,
5166
+ ...label ? { label } : {},
5167
+ ...description ? { description } : {}
5168
+ };
5169
+ }
5170
+ function parseResultOutput(output) {
5171
+ let result = output;
5172
+ if (typeof output === "string") {
5173
+ try {
5174
+ result = JSON.parse(output);
5175
+ } catch {
5176
+ return null;
5177
+ }
5178
+ }
5179
+ if (!isRecord2(result) || !Array.isArray(result.answers)) {
5180
+ return null;
5181
+ }
5182
+ const answers = result.answers.map(normalizeAnswer);
5183
+ if (answers.some((answer) => answer === null)) {
5184
+ return null;
5185
+ }
5186
+ return answers;
5187
+ }
5188
+ function getRequestUserInputResultCardData(content, messages) {
5189
+ const data = isRecord2(content.data) ? content.data : null;
5190
+ if (data?.status !== "success") {
5191
+ return null;
5192
+ }
5193
+ const toolCall = findRequestUserInputClientToolCallById(messages, content.id);
5194
+ if (!toolCall) {
5195
+ return null;
5196
+ }
5197
+ const answers = parseResultOutput(data.output);
5198
+ if (!answers || answers.length === 0) {
5199
+ return null;
5200
+ }
5201
+ return {
5202
+ toolCallId: content.id,
5203
+ answers
5204
+ };
5205
+ }
5206
+ function RequestUserInputResultCard({
5207
+ result,
5208
+ className
5209
+ }) {
5210
+ const { t } = useChatkitTranslation();
5211
+ return /* @__PURE__ */ jsxs14(
5212
+ "section",
3433
5213
  {
3434
- remarkPlugins: [remarkGfm, remarkMath],
3435
- rehypePlugins: [rehypeKatex],
3436
- components: defaultComponents,
3437
- children
5214
+ "aria-label": t("message.requestUserInputResult.title"),
5215
+ className: cn(
5216
+ "rounded-lg border border-border bg-muted/25 px-3 py-2.5",
5217
+ className
5218
+ ),
5219
+ children: [
5220
+ /* @__PURE__ */ jsxs14("div", { className: "mb-2 flex items-center gap-2 text-sm font-semibold text-foreground", children: [
5221
+ /* @__PURE__ */ jsx23(CheckCircle23, { className: "h-4 w-4 text-primary" }),
5222
+ /* @__PURE__ */ jsx23("span", { children: t("message.requestUserInputResult.title") })
5223
+ ] }),
5224
+ /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: result.answers.map((answer, index) => /* @__PURE__ */ jsxs14(
5225
+ "div",
5226
+ {
5227
+ className: "rounded-md bg-background/70 px-2.5 py-2",
5228
+ children: [
5229
+ /* @__PURE__ */ jsx23("div", { className: "text-xs font-medium leading-5 text-muted-foreground", children: answer.question }),
5230
+ /* @__PURE__ */ jsxs14("div", { className: "mt-0.5 flex min-w-0 flex-wrap items-center gap-1.5", children: [
5231
+ /* @__PURE__ */ jsx23("span", { className: "min-w-0 wrap-break-word text-sm font-semibold text-foreground", children: answer.label ?? answer.value }),
5232
+ /* @__PURE__ */ jsx23("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium text-muted-foreground", children: t(
5233
+ answer.type === "other" ? "message.requestUserInputResult.other" : "message.requestUserInputResult.option"
5234
+ ) })
5235
+ ] }),
5236
+ answer.description ? /* @__PURE__ */ jsx23("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: answer.description }) : null
5237
+ ]
5238
+ },
5239
+ `${answer.id}-${index}`
5240
+ )) })
5241
+ ]
3438
5242
  }
3439
- ) });
3440
- };
3441
- var MarkdownText = memo(MarkdownTextImpl);
5243
+ );
5244
+ }
3442
5245
 
3443
5246
  // src/components/thread/messages/widget.tsx
3444
5247
  import { SurfaceRenderer } from "@xpert-ai/a2ui-react";
3445
- import { jsx as jsx20 } from "react/jsx-runtime";
5248
+ import { jsx as jsx24 } from "react/jsx-runtime";
3446
5249
  function WidgetMessage({ messageId, data }) {
3447
5250
  const widgets = Array.isArray(data.widgets) ? data.widgets : [];
3448
5251
  if (widgets.length === 0) return null;
3449
5252
  const baseSurfaceId = `widget-${messageId}`;
3450
- return /* @__PURE__ */ jsx20("div", { className: "space-y-3", children: widgets.map((widget, index) => {
5253
+ return /* @__PURE__ */ jsx24("div", { className: "space-y-3", children: widgets.map((widget, index) => {
3451
5254
  const config = widget?.config;
3452
5255
  if (!config || typeof config !== "object") {
3453
5256
  return null;
3454
5257
  }
3455
5258
  const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
3456
- return /* @__PURE__ */ jsx20(
5259
+ return /* @__PURE__ */ jsx24(
3457
5260
  SurfaceRenderer,
3458
5261
  {
3459
5262
  surfaceId,
@@ -3465,58 +5268,44 @@ function WidgetMessage({ messageId, data }) {
3465
5268
  }
3466
5269
 
3467
5270
  // src/components/thread/messages/ai.tsx
3468
- import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
3469
- function isTextContent(content) {
5271
+ import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
5272
+ function isTextContent2(content) {
3470
5273
  return content.type === "text";
3471
5274
  }
3472
- function isReasoningContent(content) {
5275
+ function isReasoningContent2(content) {
3473
5276
  return content.type === "reasoning";
3474
5277
  }
3475
5278
  function isImageContent(content) {
3476
5279
  return content.type === "image_url";
3477
5280
  }
3478
- function isComponentContent(content) {
5281
+ function isComponentContent2(content) {
3479
5282
  return content.type === "component";
3480
5283
  }
3481
- var statusConfig = {
3482
- success: {
3483
- iconClass: "border-green-500 text-green-700",
3484
- icon: CheckCircle2
3485
- },
3486
- fail: {
3487
- iconClass: "border-red-500 text-red-700",
3488
- icon: XCircle
3489
- },
3490
- running: {
3491
- iconClass: "border-blue-500 text-blue-700",
3492
- icon: Loader22
3493
- }
3494
- };
3495
- function isWidgetComponent(content) {
5284
+ function isWidgetComponent2(content) {
3496
5285
  const data = content.data;
3497
5286
  return data?.type === "Widget" && Array.isArray(data.widgets);
3498
5287
  }
3499
5288
  function isMemoryContent(content) {
3500
5289
  return content.type === "memory";
3501
5290
  }
3502
- function safeJson(value) {
5291
+ function safeJson2(value) {
3503
5292
  try {
3504
5293
  return JSON.stringify(value, null, 2);
3505
5294
  } catch {
3506
5295
  return String(value);
3507
5296
  }
3508
5297
  }
3509
- function formatDisplayValue(value) {
3510
- return typeof value === "string" ? value : safeJson(value);
5298
+ function formatDisplayValue2(value) {
5299
+ return typeof value === "string" ? value : safeJson2(value);
3511
5300
  }
3512
5301
  function ReasoningBlock({ reasoning }) {
3513
5302
  const blocks = reasoning.filter((item) => item.text?.trim());
3514
5303
  if (blocks.length === 0) return null;
3515
- return /* @__PURE__ */ jsx21("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx21(
5304
+ return /* @__PURE__ */ jsx25("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx25(
3516
5305
  "div",
3517
5306
  {
3518
5307
  className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
3519
- children: /* @__PURE__ */ jsx21("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
5308
+ children: /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
3520
5309
  },
3521
5310
  item.id ?? `reasoning-${index}`
3522
5311
  )) });
@@ -3524,40 +5313,87 @@ function ReasoningBlock({ reasoning }) {
3524
5313
  function ImageBlock({ content }) {
3525
5314
  const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
3526
5315
  if (!imageUrl) {
3527
- return /* @__PURE__ */ jsxs11(Card, { children: [
3528
- /* @__PURE__ */ jsx21(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Image" }) }),
3529
- /* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
5316
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5317
+ /* @__PURE__ */ jsx25(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Image" }) }),
5318
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: safeJson2(content) })
3530
5319
  ] });
3531
5320
  }
3532
- return /* @__PURE__ */ jsx21("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx21("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
5321
+ return /* @__PURE__ */ jsx25("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx25("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
3533
5322
  }
3534
5323
  function MemoryBlock({ content }) {
3535
- return /* @__PURE__ */ jsxs11(Card, { children: [
3536
- /* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3537
- /* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Memory" }),
3538
- /* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: "Memory" })
5324
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5325
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5326
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Memory" }),
5327
+ /* @__PURE__ */ jsx25(Badge, { variant: "secondary", children: "Memory" })
3539
5328
  ] }),
3540
- /* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
5329
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson2(content.data ?? []) }) })
3541
5330
  ] });
3542
5331
  }
5332
+ function parseStepDate2(value) {
5333
+ if (value instanceof Date) {
5334
+ const timestamp2 = value.getTime();
5335
+ return Number.isNaN(timestamp2) ? null : timestamp2;
5336
+ }
5337
+ if (typeof value !== "string") {
5338
+ return null;
5339
+ }
5340
+ const timestamp = Date.parse(value);
5341
+ return Number.isNaN(timestamp) ? null : timestamp;
5342
+ }
5343
+ function formatStepDuration2(durationMs) {
5344
+ if (durationMs < 1e3) {
5345
+ return `${durationMs}ms`;
5346
+ }
5347
+ if (durationMs < 1e4) {
5348
+ return `${(durationMs / 1e3).toFixed(1)}s`;
5349
+ }
5350
+ if (durationMs < 6e4) {
5351
+ return `${Math.round(durationMs / 1e3)}s`;
5352
+ }
5353
+ const hours = Math.floor(durationMs / 36e5);
5354
+ const minutes = Math.floor(durationMs % 36e5 / 6e4);
5355
+ const seconds = Math.floor(durationMs % 6e4 / 1e3);
5356
+ if (hours > 0) {
5357
+ return `${hours}h ${minutes}m ${seconds}s`;
5358
+ }
5359
+ return `${minutes}m ${seconds}s`;
5360
+ }
3543
5361
  function ComponentBlock({ content }) {
3544
- const [isExpanded, setIsExpanded] = React15.useState(false);
3545
- const contentRef = React15.useRef(null);
3546
- const shouldAutoScrollRef = React15.useRef(true);
3547
- const previousScrollTopRef = React15.useRef(0);
3548
- const data = content.data ?? {};
5362
+ const { i18n: i18n2 } = useChatkitTranslation();
5363
+ const [isExpanded, setIsExpanded] = React19.useState(false);
5364
+ const contentRef = React19.useRef(null);
5365
+ const shouldAutoScrollRef = React19.useRef(true);
5366
+ const previousScrollTopRef = React19.useRef(0);
5367
+ const [durationNow, setDurationNow] = React19.useState(() => Date.now());
5368
+ const data = getToolStepData(content);
3549
5369
  const category = data.category ?? "Component";
3550
- const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
5370
+ const title = getToolActivityLabel(content, i18n2.language);
3551
5371
  const status = data.status ?? null;
3552
5372
  const message = data.message ?? null;
3553
5373
  const output = data.output ?? null;
3554
5374
  const error = data.error ?? null;
3555
5375
  const fallback = message ?? output ?? data.data ?? data;
3556
5376
  const hasOutput = message !== null || output !== null;
3557
- React15.useEffect(() => {
5377
+ const createdAt = parseStepDate2(data.created_date);
5378
+ const endedAt = parseStepDate2(data.end_date);
5379
+ const durationMs = createdAt === null ? null : Math.max(0, (endedAt ?? durationNow) - createdAt);
5380
+ const durationLabel = durationMs === null ? null : formatStepDuration2(durationMs);
5381
+ React19.useEffect(() => {
3558
5382
  if (status === "running" && output !== null) setIsExpanded(true);
3559
5383
  }, [status, output]);
3560
- React15.useEffect(() => {
5384
+ React19.useEffect(() => {
5385
+ if (status !== "running" || createdAt === null || endedAt !== null) {
5386
+ return;
5387
+ }
5388
+ setDurationNow(Date.now());
5389
+ const timer = window.setInterval(() => {
5390
+ setDurationNow(Date.now());
5391
+ }, 100);
5392
+ return () => {
5393
+ window.clearInterval(timer);
5394
+ };
5395
+ }, [createdAt, endedAt, status]);
5396
+ React19.useEffect(() => {
3561
5397
  const element = contentRef.current;
3562
5398
  if (!element) return;
3563
5399
  previousScrollTopRef.current = element.scrollTop;
@@ -3577,7 +5413,7 @@ function ComponentBlock({ content }) {
3577
5413
  element.removeEventListener("scroll", updateAutoScrollState);
3578
5414
  };
3579
5415
  }, [isExpanded]);
3580
- React15.useEffect(() => {
5416
+ React19.useEffect(() => {
3581
5417
  if (status !== "running") {
3582
5418
  shouldAutoScrollRef.current = true;
3583
5419
  return;
@@ -3588,23 +5424,27 @@ function ComponentBlock({ content }) {
3588
5424
  }
3589
5425
  element.scrollTop = element.scrollHeight;
3590
5426
  }, [isExpanded, output, status]);
3591
- const config = status ? statusConfig[status] : null;
5427
+ const config = status ? toolStatusConfig[status] : null;
3592
5428
  const StatusIcon = config?.icon;
3593
- return /* @__PURE__ */ jsxs11(Card, { children: [
3594
- /* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
3595
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
3596
- status && StatusIcon && /* @__PURE__ */ jsx21(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
3597
- /* @__PURE__ */ jsx21(CardTitle, { className: "text-sm truncate", children: title })
5429
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5430
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
5431
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
5432
+ status && StatusIcon && /* @__PURE__ */ jsx25(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
5433
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm truncate", children: title })
3598
5434
  ] }),
3599
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
3600
- /* @__PURE__ */ jsx21(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
3601
- /* @__PURE__ */ jsx21(
5435
+ /* @__PURE__ */ jsxs15("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
5436
+ durationLabel && /* @__PURE__ */ jsxs15("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
5437
+ /* @__PURE__ */ jsx25(Clock3, { className: "h-3 w-3" }),
5438
+ /* @__PURE__ */ jsx25("span", { children: durationLabel })
5439
+ ] }),
5440
+ /* @__PURE__ */ jsx25(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
5441
+ /* @__PURE__ */ jsx25(
3602
5442
  "button",
3603
5443
  {
3604
5444
  className: "text-muted-foreground hover:text-foreground transition-colors",
3605
5445
  "aria-label": isExpanded ? "Collapse" : "Expand",
3606
- children: /* @__PURE__ */ jsx21(
3607
- ChevronDown,
5446
+ children: /* @__PURE__ */ jsx25(
5447
+ ChevronDown2,
3608
5448
  {
3609
5449
  className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
3610
5450
  }
@@ -3613,55 +5453,83 @@ function ComponentBlock({ content }) {
3613
5453
  )
3614
5454
  ] })
3615
5455
  ] }),
3616
- isExpanded && /* @__PURE__ */ jsxs11(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
3617
- data.input && /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
3618
- error ? /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
5456
+ isExpanded && /* @__PURE__ */ jsxs15(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
5457
+ data.input && /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(data.input) }),
5458
+ error ? /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue2(error) }) : hasOutput && /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(fallback) })
3619
5459
  ] })
3620
5460
  ] });
3621
5461
  }
3622
5462
  function UnknownBlock({ content }) {
3623
- return /* @__PURE__ */ jsxs11(Card, { children: [
3624
- /* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3625
- /* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Assistant Content" }),
3626
- /* @__PURE__ */ jsx21(Badge, { variant: "outline", children: content.type ?? "unknown" })
5463
+ return /* @__PURE__ */ jsxs15(Card, { children: [
5464
+ /* @__PURE__ */ jsxs15(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5465
+ /* @__PURE__ */ jsx25(CardTitle, { className: "text-sm", children: "Assistant Content" }),
5466
+ /* @__PURE__ */ jsx25(Badge, { variant: "outline", children: content.type ?? "unknown" })
3627
5467
  ] }),
3628
- /* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
5468
+ /* @__PURE__ */ jsx25(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx25("pre", { className: "whitespace-pre-wrap break-words", children: safeJson2(content) }) })
3629
5469
  ] });
3630
5470
  }
3631
- function renderContentItem(content, index, messageId) {
5471
+ function renderContentItem(content, index, message, lookupMessages) {
5472
+ const messageId = message.id;
3632
5473
  if (typeof content === "string") {
3633
- return /* @__PURE__ */ jsxs11("div", { children: [
3634
- /* @__PURE__ */ jsx21(MarkdownText, { children: content }),
3635
- ";"
3636
- ] }, `text-${index}`);
5474
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MarkdownText, { children: content }) }, `text-${index}`);
3637
5475
  }
3638
- if (isTextContent(content)) {
3639
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
5476
+ if (isTextContent2(content)) {
5477
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
3640
5478
  }
3641
- if (isReasoningContent(content)) {
3642
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
5479
+ if (isReasoningContent2(content)) {
5480
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
3643
5481
  }
3644
5482
  if (isImageContent(content)) {
3645
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ImageBlock, { content }) }, content.id ?? `image-${index}`);
5483
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ImageBlock, { content }) }, content.id ?? `image-${index}`);
3646
5484
  }
3647
- if (isComponentContent(content)) {
3648
- if (isWidgetComponent(content)) {
3649
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5485
+ if (isComponentContent2(content)) {
5486
+ const requestUserInputResult = getRequestUserInputResultCardData(
5487
+ content,
5488
+ lookupMessages
5489
+ );
5490
+ if (requestUserInputResult) {
5491
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(RequestUserInputResultCard, { result: requestUserInputResult }) }, content.id ?? `request-user-input-result-${index}`);
3650
5492
  }
3651
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
5493
+ if (isWidgetComponent2(content)) {
5494
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5495
+ }
5496
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
3652
5497
  }
3653
5498
  if (isMemoryContent(content)) {
3654
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5499
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5500
+ }
5501
+ return /* @__PURE__ */ jsx25("div", { children: /* @__PURE__ */ jsx25(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5502
+ }
5503
+ function renderContentUnit(unit, message, lookupMessages, hasFollowingItem) {
5504
+ if (unit.type === "item") {
5505
+ return renderContentItem(unit.item, unit.index, message, lookupMessages);
3655
5506
  }
3656
- return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5507
+ return /* @__PURE__ */ jsx25(
5508
+ "div",
5509
+ {
5510
+ children: /* @__PURE__ */ jsx25(ToolComponentGroup, { items: unit.items, hasFollowingItem })
5511
+ },
5512
+ `tool-group-${unit.startIndex}-${unit.items[0]?.id ?? "tool"}-${unit.items.length}`
5513
+ );
3657
5514
  }
3658
- function renderContent(content, messageId) {
5515
+ function renderContent(message, lookupMessages) {
5516
+ const content = message.content;
3659
5517
  if (typeof content === "string") {
3660
5518
  if (!content.trim()) return null;
3661
- return /* @__PURE__ */ jsx21(MarkdownText, { children: content });
5519
+ return /* @__PURE__ */ jsx25(MarkdownText, { children: content });
3662
5520
  }
3663
5521
  if (!Array.isArray(content) || content.length === 0) return null;
3664
- return /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
5522
+ const renderUnits = buildToolComponentRenderUnits(content, {
5523
+ shouldGroupComponent: (item) => getRequestUserInputResultCardData(item, lookupMessages) === null
5524
+ });
5525
+ return /* @__PURE__ */ jsx25("div", { className: "space-y-3", children: renderUnits.map(
5526
+ (unit, index) => renderContentUnit(
5527
+ unit,
5528
+ message,
5529
+ lookupMessages,
5530
+ index < renderUnits.length - 1
5531
+ )
5532
+ ) });
3665
5533
  }
3666
5534
  function AssistantStreamingIndicator({
3667
5535
  status,
@@ -3673,23 +5541,24 @@ function AssistantStreamingIndicator({
3673
5541
  thinking: t("message.thinking"),
3674
5542
  answering: t("message.answering")
3675
5543
  };
3676
- return /* @__PURE__ */ jsxs11("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
3677
- status === "loading" && /* @__PURE__ */ jsx21(Loader22, { className: "h-3.5 w-3.5 animate-spin" }),
3678
- status === "thinking" && /* @__PURE__ */ jsxs11("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3679
- /* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
3680
- /* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
3681
- /* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
5544
+ return /* @__PURE__ */ jsxs15("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
5545
+ status === "loading" && /* @__PURE__ */ jsx25(Loader23, { className: "h-3.5 w-3.5 animate-spin" }),
5546
+ status === "thinking" && /* @__PURE__ */ jsxs15("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5547
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
5548
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
5549
+ /* @__PURE__ */ jsx25("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
3682
5550
  ] }),
3683
- status === "answering" && /* @__PURE__ */ jsxs11("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3684
- /* @__PURE__ */ jsx21("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
3685
- /* @__PURE__ */ jsx21("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
3686
- /* @__PURE__ */ jsx21("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
5551
+ status === "answering" && /* @__PURE__ */ jsxs15("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5552
+ /* @__PURE__ */ jsx25("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
5553
+ /* @__PURE__ */ jsx25("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
5554
+ /* @__PURE__ */ jsx25("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
3687
5555
  ] }),
3688
- /* @__PURE__ */ jsx21("span", { children: labelMap[status] })
5556
+ /* @__PURE__ */ jsx25("span", { children: labelMap[status] })
3689
5557
  ] });
3690
5558
  }
3691
5559
  function AssistantMessage({
3692
5560
  message,
5561
+ messages,
3693
5562
  className,
3694
5563
  isStreaming = false,
3695
5564
  streamingStatus
@@ -3698,43 +5567,44 @@ function AssistantMessage({
3698
5567
  const hasContent = hasRenderableMessageContent(message.content);
3699
5568
  const hasReasoning = hasRenderableReasoning(message.reasoning);
3700
5569
  const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
3701
- const answerNode = renderContent(message.content, message.id);
3702
- const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx21(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
5570
+ const lookupMessages = messages?.length ? messages : [message];
5571
+ const answerNode = renderContent(message, lookupMessages);
5572
+ const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx25(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
3703
5573
  if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
3704
5574
  const streamingClass = isStreaming ? "streaming-active" : "";
3705
5575
  if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
3706
- return /* @__PURE__ */ jsx21("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
5576
+ return /* @__PURE__ */ jsx25("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
3707
5577
  }
3708
5578
  if (hasContent && hasReasoning) {
3709
- return /* @__PURE__ */ jsxs11("div", { className: cn("space-y-3", streamingClass, className), children: [
3710
- /* @__PURE__ */ jsxs11(
5579
+ return /* @__PURE__ */ jsxs15("div", { className: cn("space-y-3", streamingClass, className), children: [
5580
+ /* @__PURE__ */ jsxs15(
3711
5581
  Tabs,
3712
5582
  {
3713
5583
  defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
3714
5584
  className: "w-full",
3715
5585
  children: [
3716
- /* @__PURE__ */ jsxs11(TabsList, { className: "", children: [
3717
- /* @__PURE__ */ jsx21(TabsTrigger, { value: "answer", children: t("message.answer") }),
3718
- /* @__PURE__ */ jsx21(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
5586
+ /* @__PURE__ */ jsxs15(TabsList, { className: "", children: [
5587
+ /* @__PURE__ */ jsx25(TabsTrigger, { value: "answer", children: t("message.answer") }),
5588
+ /* @__PURE__ */ jsx25(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
3719
5589
  ] }),
3720
- /* @__PURE__ */ jsx21(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
3721
- /* @__PURE__ */ jsx21(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
5590
+ /* @__PURE__ */ jsx25(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
5591
+ /* @__PURE__ */ jsx25(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
3722
5592
  ]
3723
5593
  }
3724
5594
  ),
3725
- resolvedStreamingStatus ? /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5595
+ resolvedStreamingStatus ? /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3726
5596
  ] });
3727
5597
  }
3728
- return /* @__PURE__ */ jsxs11("div", { className: cn("space-y-3", streamingClass, className), children: [
5598
+ return /* @__PURE__ */ jsxs15("div", { className: cn("space-y-3", streamingClass, className), children: [
3729
5599
  hasReasoning ? reasoningNode : answerNode,
3730
- resolvedStreamingStatus ? /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5600
+ resolvedStreamingStatus ? /* @__PURE__ */ jsx25(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3731
5601
  ] });
3732
5602
  }
3733
5603
 
3734
5604
  // src/components/thread/MessageActions.tsx
3735
- import * as React16 from "react";
3736
- import { Check, Copy, RefreshCw } from "lucide-react";
3737
- import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
5605
+ import * as React20 from "react";
5606
+ import { Check as Check3, Copy as Copy2, RefreshCw } from "lucide-react";
5607
+ import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
3738
5608
  function MessageActions({
3739
5609
  content,
3740
5610
  isAssistant = false,
@@ -3743,7 +5613,7 @@ function MessageActions({
3743
5613
  className
3744
5614
  }) {
3745
5615
  const { t } = useChatkitTranslation();
3746
- const [copied, setCopied] = React16.useState(false);
5616
+ const [copied, setCopied] = React20.useState(false);
3747
5617
  const handleCopy = async () => {
3748
5618
  try {
3749
5619
  await navigator.clipboard.writeText(content);
@@ -3756,7 +5626,7 @@ function MessageActions({
3756
5626
  if (isStreaming) {
3757
5627
  return null;
3758
5628
  }
3759
- return /* @__PURE__ */ jsxs12(
5629
+ return /* @__PURE__ */ jsxs16(
3760
5630
  "div",
3761
5631
  {
3762
5632
  className: cn(
@@ -3764,7 +5634,7 @@ function MessageActions({
3764
5634
  className
3765
5635
  ),
3766
5636
  children: [
3767
- /* @__PURE__ */ jsx22(
5637
+ /* @__PURE__ */ jsx26(
3768
5638
  "button",
3769
5639
  {
3770
5640
  type: "button",
@@ -3774,17 +5644,17 @@ function MessageActions({
3774
5644
  copied && "text-green-500"
3775
5645
  ),
3776
5646
  title: copied ? t("messageActions.copied") : t("messageActions.copy"),
3777
- children: copied ? /* @__PURE__ */ jsx22(Check, { size: 14 }) : /* @__PURE__ */ jsx22(Copy, { size: 14 })
5647
+ children: copied ? /* @__PURE__ */ jsx26(Check3, { size: 14 }) : /* @__PURE__ */ jsx26(Copy2, { size: 14 })
3778
5648
  }
3779
5649
  ),
3780
- isAssistant && onRetry && /* @__PURE__ */ jsx22(
5650
+ isAssistant && onRetry && /* @__PURE__ */ jsx26(
3781
5651
  "button",
3782
5652
  {
3783
5653
  type: "button",
3784
5654
  onClick: onRetry,
3785
5655
  className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
3786
5656
  title: t("messageActions.regenerate"),
3787
- children: /* @__PURE__ */ jsx22(RefreshCw, { size: 14 })
5657
+ children: /* @__PURE__ */ jsx26(RefreshCw, { size: 14 })
3788
5658
  }
3789
5659
  )
3790
5660
  ]
@@ -3805,18 +5675,18 @@ import {
3805
5675
  Sparkles as Sparkles2,
3806
5676
  Zap
3807
5677
  } from "lucide-react";
3808
- import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
5678
+ import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
3809
5679
  function getIconComponent2(icon) {
3810
5680
  const iconMap = {
3811
- "circle-question": /* @__PURE__ */ jsx23(HelpCircle, { size: 20 }),
3812
- "lightbulb": /* @__PURE__ */ jsx23(Lightbulb2, { size: 20 }),
3813
- "sparkle": /* @__PURE__ */ jsx23(Sparkles2, { size: 20 }),
3814
- "write": /* @__PURE__ */ jsx23(Pencil2, { size: 20 }),
3815
- "search": /* @__PURE__ */ jsx23(Search2, { size: 20 }),
3816
- "globe": /* @__PURE__ */ jsx23(Globe2, { size: 20 }),
3817
- "book-open": /* @__PURE__ */ jsx23(BookOpen, { size: 20 }),
3818
- "compass": /* @__PURE__ */ jsx23(Compass, { size: 20 }),
3819
- "bolt": /* @__PURE__ */ jsx23(Zap, { size: 20 })
5681
+ "circle-question": /* @__PURE__ */ jsx27(HelpCircle, { size: 20 }),
5682
+ "lightbulb": /* @__PURE__ */ jsx27(Lightbulb2, { size: 20 }),
5683
+ "sparkle": /* @__PURE__ */ jsx27(Sparkles2, { size: 20 }),
5684
+ "write": /* @__PURE__ */ jsx27(Pencil2, { size: 20 }),
5685
+ "search": /* @__PURE__ */ jsx27(Search2, { size: 20 }),
5686
+ "globe": /* @__PURE__ */ jsx27(Globe2, { size: 20 }),
5687
+ "book-open": /* @__PURE__ */ jsx27(BookOpen, { size: 20 }),
5688
+ "compass": /* @__PURE__ */ jsx27(Compass, { size: 20 }),
5689
+ "bolt": /* @__PURE__ */ jsx27(Zap, { size: 20 })
3820
5690
  };
3821
5691
  return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
3822
5692
  }
@@ -3824,9 +5694,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
3824
5694
  const { t } = useChatkitTranslation();
3825
5695
  const greeting = startScreen?.greeting ?? t("startScreen.greeting");
3826
5696
  const prompts = startScreen?.prompts ?? [];
3827
- return /* @__PURE__ */ jsxs13("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
3828
- /* @__PURE__ */ jsx23("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx23("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
3829
- prompts.length > 0 && /* @__PURE__ */ jsx23("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs13(
5697
+ return /* @__PURE__ */ jsxs17("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
5698
+ /* @__PURE__ */ jsx27("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx27("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
5699
+ prompts.length > 0 && /* @__PURE__ */ jsx27("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx27("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs17(
3830
5700
  "button",
3831
5701
  {
3832
5702
  type: "button",
@@ -3837,8 +5707,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
3837
5707
  "focus:outline-none focus:ring-2 focus:ring-primary/20"
3838
5708
  ),
3839
5709
  children: [
3840
- /* @__PURE__ */ jsx23("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
3841
- /* @__PURE__ */ jsx23("span", { className: "text-sm font-medium text-foreground", children: item.label })
5710
+ /* @__PURE__ */ jsx27("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
5711
+ /* @__PURE__ */ jsx27("span", { className: "text-sm font-medium text-foreground", children: item.label })
3842
5712
  ]
3843
5713
  },
3844
5714
  `prompt-${index}`
@@ -3850,10 +5720,10 @@ function StartScreen({ startScreen, onPromptClick, className }) {
3850
5720
  import "react";
3851
5721
 
3852
5722
  // src/components/ui/avatar.tsx
3853
- import * as React18 from "react";
5723
+ import * as React22 from "react";
3854
5724
  import * as AvatarPrimitive from "@radix-ui/react-avatar";
3855
- import { jsx as jsx24 } from "react/jsx-runtime";
3856
- var Avatar = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
5725
+ import { jsx as jsx28 } from "react/jsx-runtime";
5726
+ var Avatar = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
3857
5727
  AvatarPrimitive.Root,
3858
5728
  {
3859
5729
  ref,
@@ -3865,7 +5735,7 @@ var Avatar = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
3865
5735
  }
3866
5736
  ));
3867
5737
  Avatar.displayName = AvatarPrimitive.Root.displayName;
3868
- var AvatarImage = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
5738
+ var AvatarImage = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
3869
5739
  AvatarPrimitive.Image,
3870
5740
  {
3871
5741
  ref,
@@ -3874,7 +5744,7 @@ var AvatarImage = React18.forwardRef(({ className, ...props }, ref) => /* @__PUR
3874
5744
  }
3875
5745
  ));
3876
5746
  AvatarImage.displayName = AvatarPrimitive.Image.displayName;
3877
- var AvatarFallback = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
5747
+ var AvatarFallback = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
3878
5748
  AvatarPrimitive.Fallback,
3879
5749
  {
3880
5750
  ref,
@@ -3888,7 +5758,7 @@ var AvatarFallback = React18.forwardRef(({ className, ...props }, ref) => /* @__
3888
5758
  AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
3889
5759
 
3890
5760
  // src/components/ui/chatkit-avatar.tsx
3891
- import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
5761
+ import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
3892
5762
  function asRecord(value) {
3893
5763
  return value && typeof value === "object" ? value : null;
3894
5764
  }
@@ -3961,21 +5831,21 @@ function ChatkitAvatar({
3961
5831
  const fallbackStyle = {
3962
5832
  ...avatar?.background ? { background: avatar.background } : {}
3963
5833
  };
3964
- return /* @__PURE__ */ jsxs14(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
3965
- avatar?.url ? /* @__PURE__ */ jsx25(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
3966
- /* @__PURE__ */ jsx25(
5834
+ return /* @__PURE__ */ jsxs18(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
5835
+ avatar?.url ? /* @__PURE__ */ jsx29(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
5836
+ /* @__PURE__ */ jsx29(
3967
5837
  AvatarFallback,
3968
5838
  {
3969
5839
  className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
3970
5840
  style: fallbackStyle,
3971
- children: emojiCharacter ? /* @__PURE__ */ jsx25("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
5841
+ children: emojiCharacter ? /* @__PURE__ */ jsx29("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
3972
5842
  }
3973
5843
  )
3974
5844
  ] });
3975
5845
  }
3976
5846
 
3977
5847
  // src/hooks/useThreads.ts
3978
- import * as React20 from "react";
5848
+ import * as React24 from "react";
3979
5849
  var DEFAULT_LIMIT = 50;
3980
5850
  var getThreadTitle = (threadRecord) => {
3981
5851
  const title = threadRecord.title?.trim();
@@ -4013,16 +5883,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
4013
5883
  isReady,
4014
5884
  isLoading: isStreamLoading
4015
5885
  } = useStreamContext();
4016
- const [threadRecords, setThreadRecords] = React20.useState([]);
4017
- const [isLoading, setIsLoading] = React20.useState(false);
4018
- const [error, setError] = React20.useState(null);
4019
- const upsertThreadRecord = React20.useCallback((threadRecord) => {
5886
+ const [threadRecords, setThreadRecords] = React24.useState([]);
5887
+ const [isLoading, setIsLoading] = React24.useState(false);
5888
+ const [error, setError] = React24.useState(null);
5889
+ const upsertThreadRecord = React24.useCallback((threadRecord) => {
4020
5890
  setThreadRecords((prev) => {
4021
5891
  const next = prev.filter((item) => item.id !== threadRecord.id);
4022
5892
  return sortThreadRecords([threadRecord, ...next]);
4023
5893
  });
4024
5894
  }, []);
4025
- const refreshThreads = React20.useCallback(async () => {
5895
+ const refreshThreads = React24.useCallback(async () => {
4026
5896
  setIsLoading(true);
4027
5897
  setError(null);
4028
5898
  try {
@@ -4038,7 +5908,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4038
5908
  setIsLoading(false);
4039
5909
  }
4040
5910
  }, [client, limit, assistantId]);
4041
- const createThread = React20.useCallback(
5911
+ const createThread = React24.useCallback(
4042
5912
  async (input) => {
4043
5913
  setError(null);
4044
5914
  const payload = {};
@@ -4052,7 +5922,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4052
5922
  },
4053
5923
  [client, upsertThreadRecord]
4054
5924
  );
4055
- const updateThread = React20.useCallback(
5925
+ const updateThread = React24.useCallback(
4056
5926
  async (recordId, payload) => {
4057
5927
  setError(null);
4058
5928
  const updated = await client.conversations.update(recordId, payload);
@@ -4061,7 +5931,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4061
5931
  },
4062
5932
  [client, upsertThreadRecord]
4063
5933
  );
4064
- const deleteThread = React20.useCallback(
5934
+ const deleteThread = React24.useCallback(
4065
5935
  async (recordId) => {
4066
5936
  setError(null);
4067
5937
  await client.conversations.delete(recordId);
@@ -4069,11 +5939,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
4069
5939
  },
4070
5940
  [client]
4071
5941
  );
4072
- React20.useEffect(() => {
5942
+ React24.useEffect(() => {
4073
5943
  if (!isReady) return;
4074
5944
  void refreshThreads();
4075
5945
  }, [refreshThreads, isReady]);
4076
- React20.useEffect(() => {
5946
+ React24.useEffect(() => {
4077
5947
  if (!threadId || !isStreamLoading) return;
4078
5948
  const now = (/* @__PURE__ */ new Date()).toISOString();
4079
5949
  const busyStatus = "busy";
@@ -4094,7 +5964,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4094
5964
  return changed ? sortThreadRecords(next) : prev;
4095
5965
  });
4096
5966
  }, [threadId, isStreamLoading]);
4097
- React20.useEffect(() => {
5967
+ React24.useEffect(() => {
4098
5968
  if (!isReady || !threadId || isStreamLoading) return;
4099
5969
  let cancelled = false;
4100
5970
  void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
@@ -4108,7 +5978,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4108
5978
  cancelled = true;
4109
5979
  };
4110
5980
  }, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
4111
- const threads = React20.useMemo(
5981
+ const threads = React24.useMemo(
4112
5982
  () => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
4113
5983
  [threadRecords]
4114
5984
  );
@@ -4125,10 +5995,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
4125
5995
  }
4126
5996
 
4127
5997
  // src/components/thread/context-usage-indicator.tsx
4128
- import * as React21 from "react";
5998
+ import * as React25 from "react";
4129
5999
 
4130
6000
  // src/components/ui/progress-circle.tsx
4131
- import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
6001
+ import { jsx as jsx30, jsxs as jsxs19 } from "react/jsx-runtime";
4132
6002
  function clamp2(input, a, b) {
4133
6003
  return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
4134
6004
  }
@@ -4151,7 +6021,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4151
6021
  return (
4152
6022
  // biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
4153
6023
  // biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
4154
- /* @__PURE__ */ jsxs15(
6024
+ /* @__PURE__ */ jsxs19(
4155
6025
  "svg",
4156
6026
  {
4157
6027
  role: "progressbar",
@@ -4162,8 +6032,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4162
6032
  "aria-valuemax": 100,
4163
6033
  ...restSvgProps,
4164
6034
  children: [
4165
- /* @__PURE__ */ jsx26("circle", { ...commonParams, className: "stroke-current/25" }),
4166
- /* @__PURE__ */ jsx26(
6035
+ /* @__PURE__ */ jsx30("circle", { ...commonParams, className: "stroke-current/25" }),
6036
+ /* @__PURE__ */ jsx30(
4167
6037
  "circle",
4168
6038
  {
4169
6039
  ...commonParams,
@@ -4182,7 +6052,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4182
6052
  };
4183
6053
 
4184
6054
  // src/components/thread/context-usage-indicator.tsx
4185
- import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
6055
+ import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
4186
6056
  var kNumberFormatter = new Intl.NumberFormat("en-US", {
4187
6057
  minimumFractionDigits: 0,
4188
6058
  maximumFractionDigits: 1
@@ -4215,20 +6085,20 @@ function ContextUsageIndicator({
4215
6085
  }) {
4216
6086
  const { t } = useChatkitTranslation();
4217
6087
  const stream = useStreamContext();
4218
- const [maxContextSize, setMaxContextSize] = React21.useState(null);
4219
- const [usedContextSize, setUsedContextSize] = React21.useState(null);
4220
- const [assistantAgentKey, setAssistantAgentKey] = React21.useState(null);
4221
- const latestRealtimeUsageRef = React21.useRef({
6088
+ const [maxContextSize, setMaxContextSize] = React25.useState(null);
6089
+ const [usedContextSize, setUsedContextSize] = React25.useState(null);
6090
+ const [assistantAgentKey, setAssistantAgentKey] = React25.useState(null);
6091
+ const latestRealtimeUsageRef = React25.useRef({
4222
6092
  threadId: null,
4223
6093
  agentKey: null,
4224
6094
  usedTokens: null
4225
6095
  });
4226
- const realtimeUsage = React21.useMemo(
6096
+ const realtimeUsage = React25.useMemo(
4227
6097
  () => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
4228
6098
  [assistantAgentKey, stream.contextUsageByAgentKey]
4229
6099
  );
4230
6100
  const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
4231
- React21.useEffect(() => {
6101
+ React25.useEffect(() => {
4232
6102
  if (!stream.client || !stream.assistantId) {
4233
6103
  setMaxContextSize(null);
4234
6104
  setAssistantAgentKey(null);
@@ -4248,18 +6118,18 @@ function ContextUsageIndicator({
4248
6118
  cancelled = true;
4249
6119
  };
4250
6120
  }, [stream.client, stream.assistantId]);
4251
- React21.useEffect(() => {
6121
+ React25.useEffect(() => {
4252
6122
  latestRealtimeUsageRef.current = {
4253
6123
  threadId: stream.threadId ?? null,
4254
6124
  agentKey: assistantAgentKey,
4255
6125
  usedTokens: realtimeUsedContextSize
4256
6126
  };
4257
6127
  }, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
4258
- React21.useEffect(() => {
6128
+ React25.useEffect(() => {
4259
6129
  if (realtimeUsedContextSize == null) return;
4260
6130
  setUsedContextSize(realtimeUsedContextSize);
4261
6131
  }, [realtimeUsedContextSize]);
4262
- React21.useEffect(() => {
6132
+ React25.useEffect(() => {
4263
6133
  if (!stream.client) {
4264
6134
  setUsedContextSize(null);
4265
6135
  return;
@@ -4324,8 +6194,8 @@ function ContextUsageIndicator({
4324
6194
  });
4325
6195
  const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
4326
6196
  const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
4327
- return /* @__PURE__ */ jsxs16(Tooltip, { children: [
4328
- /* @__PURE__ */ jsx27(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx27(
6197
+ return /* @__PURE__ */ jsxs20(Tooltip, { children: [
6198
+ /* @__PURE__ */ jsx31(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx31(
4329
6199
  "button",
4330
6200
  {
4331
6201
  type: "button",
@@ -4334,19 +6204,19 @@ function ContextUsageIndicator({
4334
6204
  className
4335
6205
  ),
4336
6206
  "aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
4337
- children: /* @__PURE__ */ jsx27(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
6207
+ children: /* @__PURE__ */ jsx31(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
4338
6208
  }
4339
6209
  ) }),
4340
- /* @__PURE__ */ jsxs16(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
4341
- /* @__PURE__ */ jsx27("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
4342
- /* @__PURE__ */ jsx27("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
4343
- /* @__PURE__ */ jsx27("div", { className: "text-sm font-semibold", children: usageTokensLabel })
6210
+ /* @__PURE__ */ jsxs20(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
6211
+ /* @__PURE__ */ jsx31("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
6212
+ /* @__PURE__ */ jsx31("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
6213
+ /* @__PURE__ */ jsx31("div", { className: "text-sm font-semibold", children: usageTokensLabel })
4344
6214
  ] })
4345
6215
  ] });
4346
6216
  }
4347
6217
 
4348
6218
  // src/components/chat.tsx
4349
- import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
6219
+ import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs21 } from "react/jsx-runtime";
4350
6220
  var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
4351
6221
  var COMPOSER_INPUT_MAX_HEIGHT = 128;
4352
6222
  var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
@@ -4438,7 +6308,7 @@ function ReferenceChip({
4438
6308
  const metaLine = getReferenceMetaLine(reference);
4439
6309
  const isComposer = variant === "composer";
4440
6310
  const Icon = reference.type === "quote" ? Quote : reference.type === "image" ? ImageIcon : FileText2;
4441
- return /* @__PURE__ */ jsxs17(
6311
+ return /* @__PURE__ */ jsxs21(
4442
6312
  "div",
4443
6313
  {
4444
6314
  className: cn(
@@ -4447,7 +6317,7 @@ function ReferenceChip({
4447
6317
  ),
4448
6318
  title: getReferenceTitle(reference),
4449
6319
  children: [
4450
- /* @__PURE__ */ jsx28(
6320
+ /* @__PURE__ */ jsx32(
4451
6321
  Icon,
4452
6322
  {
4453
6323
  size: isComposer ? 14 : 12,
@@ -4457,8 +6327,8 @@ function ReferenceChip({
4457
6327
  )
4458
6328
  }
4459
6329
  ),
4460
- /* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
4461
- /* @__PURE__ */ jsx28(
6330
+ /* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
6331
+ /* @__PURE__ */ jsx32(
4462
6332
  "div",
4463
6333
  {
4464
6334
  className: cn(
@@ -4468,7 +6338,7 @@ function ReferenceChip({
4468
6338
  children: getReferenceLabel(reference)
4469
6339
  }
4470
6340
  ),
4471
- metaLine && /* @__PURE__ */ jsx28(
6341
+ metaLine && /* @__PURE__ */ jsx32(
4472
6342
  "div",
4473
6343
  {
4474
6344
  className: cn(
@@ -4479,7 +6349,7 @@ function ReferenceChip({
4479
6349
  }
4480
6350
  )
4481
6351
  ] }),
4482
- onRemove && removeLabel && /* @__PURE__ */ jsx28(
6352
+ onRemove && removeLabel && /* @__PURE__ */ jsx32(
4483
6353
  "button",
4484
6354
  {
4485
6355
  type: "button",
@@ -4490,7 +6360,7 @@ function ReferenceChip({
4490
6360
  ),
4491
6361
  title: removeLabel,
4492
6362
  "aria-label": removeLabel,
4493
- children: /* @__PURE__ */ jsx28(X3, { size: 12 })
6363
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
4494
6364
  }
4495
6365
  )
4496
6366
  ]
@@ -4514,20 +6384,20 @@ function Chat({
4514
6384
  const { setStream } = useStreamManager();
4515
6385
  const stream = useStreamContext();
4516
6386
  const { theme } = useTheme();
4517
- const [isHistoryLoading, setIsHistoryLoading] = React22.useState(false);
4518
- const [historyError, setHistoryError] = React22.useState(null);
4519
- const [assistantName, setAssistantName] = React22.useState(null);
4520
- const [assistantAvatar, setAssistantAvatar] = React22.useState(null);
6387
+ const [isHistoryLoading, setIsHistoryLoading] = React26.useState(false);
6388
+ const [historyError, setHistoryError] = React26.useState(null);
6389
+ const [assistantName, setAssistantName] = React26.useState(null);
6390
+ const [assistantAvatar, setAssistantAvatar] = React26.useState(null);
4521
6391
  const LOADING_DOTS_MIN_DURATION = 800;
4522
6392
  const STREAMING_STATUS_REFRESH_MS = 250;
4523
- const [showLoadingDots, setShowLoadingDots] = React22.useState(false);
4524
- const [streamingNow, setStreamingNow] = React22.useState(() => Date.now());
4525
- const loadingStartTimeRef = React22.useRef(null);
4526
- const lastStreamOutputAtRef = React22.useRef(null);
4527
- React22.useEffect(() => {
6393
+ const [showLoadingDots, setShowLoadingDots] = React26.useState(false);
6394
+ const [streamingNow, setStreamingNow] = React26.useState(() => Date.now());
6395
+ const loadingStartTimeRef = React26.useRef(null);
6396
+ const lastStreamOutputAtRef = React26.useRef(null);
6397
+ React26.useEffect(() => {
4528
6398
  setStream(stream);
4529
6399
  }, [setStream, stream]);
4530
- React22.useEffect(() => {
6400
+ React26.useEffect(() => {
4531
6401
  if (stream.isLoading) {
4532
6402
  if (!loadingStartTimeRef.current) {
4533
6403
  loadingStartTimeRef.current = Date.now();
@@ -4550,7 +6420,7 @@ function Chat({
4550
6420
  }
4551
6421
  }
4552
6422
  }, [stream.isLoading]);
4553
- React22.useEffect(() => {
6423
+ React26.useEffect(() => {
4554
6424
  if (!stream.isLoading) {
4555
6425
  lastStreamOutputAtRef.current = null;
4556
6426
  setStreamingNow(Date.now());
@@ -4560,7 +6430,7 @@ function Chat({
4560
6430
  lastStreamOutputAtRef.current = now;
4561
6431
  setStreamingNow(now);
4562
6432
  }, [stream.messages, stream.isLoading]);
4563
- React22.useEffect(() => {
6433
+ React26.useEffect(() => {
4564
6434
  if (!stream.isLoading) {
4565
6435
  return;
4566
6436
  }
@@ -4569,52 +6439,55 @@ function Chat({
4569
6439
  }, STREAMING_STATUS_REFRESH_MS);
4570
6440
  return () => window.clearInterval(timer);
4571
6441
  }, [stream.isLoading]);
4572
- const [draft, setDraft] = React22.useState("");
4573
- const [selectedTool, setSelectedTool] = React22.useState(
6442
+ const [draft, setDraft] = React26.useState("");
6443
+ const [selectedTool, setSelectedTool] = React26.useState(
4574
6444
  null
4575
6445
  );
4576
- const [attachments, setAttachments] = React22.useState([]);
4577
- const [references, setReferences] = React22.useState([]);
4578
- const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React22.useState(false);
4579
- const [quoteSelection, setQuoteSelection] = React22.useState(null);
4580
- const [isAtBottom, setIsAtBottom] = React22.useState(true);
4581
- const [hasUpdatesBelow, setHasUpdatesBelow] = React22.useState(false);
6446
+ const [planModeEnabled, setPlanModeEnabled] = React26.useState(false);
6447
+ const [attachments, setAttachments] = React26.useState([]);
6448
+ const [references, setReferences] = React26.useState([]);
6449
+ const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React26.useState(false);
6450
+ const [quoteSelection, setQuoteSelection] = React26.useState(null);
6451
+ const [isAtBottom, setIsAtBottom] = React26.useState(true);
6452
+ const [hasUpdatesBelow, setHasUpdatesBelow] = React26.useState(false);
4582
6453
  const {
4583
6454
  threads,
4584
6455
  deleteThread,
4585
6456
  refreshThreads,
4586
6457
  isLoading: isThreadsLoading
4587
6458
  } = useThreads();
4588
- const viewportRef = React22.useRef(null);
4589
- const fileInputRef = React22.useRef(null);
4590
- const composerInputRef = React22.useRef(null);
4591
- const shouldAutoScrollRef = React22.useRef(true);
4592
- const forceFollowRef = React22.useRef(false);
4593
- const previousMessageCountRef = React22.useRef(0);
4594
- const previousScrollTopRef = React22.useRef(0);
4595
- const autoScrollFrameRef = React22.useRef(null);
4596
- const isPointerDownRef = React22.useRef(false);
4597
- const lastTouchYRef = React22.useRef(null);
6459
+ const viewportRef = React26.useRef(null);
6460
+ const fileInputRef = React26.useRef(null);
6461
+ const composerInputRef = React26.useRef(null);
6462
+ const shouldAutoScrollRef = React26.useRef(true);
6463
+ const forceFollowRef = React26.useRef(false);
6464
+ const previousMessageCountRef = React26.useRef(0);
6465
+ const previousScrollTopRef = React26.useRef(0);
6466
+ const autoScrollFrameRef = React26.useRef(null);
6467
+ const isPointerDownRef = React26.useRef(false);
6468
+ const lastTouchYRef = React26.useRef(null);
4598
6469
  const resolvedTitle = title ?? t("chat.title");
4599
6470
  const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
4600
6471
  const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
4601
- const messages = React22.useMemo(
6472
+ const messages = React26.useMemo(
4602
6473
  () => stream.messages ?? [],
4603
6474
  [stream.messages]
4604
6475
  );
4605
6476
  const trimmedDraft = draft.trim();
4606
6477
  const hasReferences = references.length > 0;
4607
- const pendingFollowUps = React22.useMemo(
6478
+ const pendingFollowUps = React26.useMemo(
4608
6479
  () => [...stream.pendingFollowUps ?? []].sort(
4609
6480
  (a, b) => a.createdAt - b.createdAt
4610
6481
  ),
4611
6482
  [stream.pendingFollowUps]
4612
6483
  );
4613
- const clearQuoteSelection = React22.useCallback(() => {
6484
+ const hasPendingFollowUps = pendingFollowUps.length > 0;
6485
+ const hasPendingRequestUserInput = Boolean(stream.pendingRequestUserInput);
6486
+ const clearQuoteSelection = React26.useCallback(() => {
4614
6487
  setQuoteSelection(null);
4615
6488
  }, []);
4616
6489
  useParentMessenger({
4617
- onSetComposerValue: React22.useCallback(
6490
+ onSetComposerValue: React26.useCallback(
4618
6491
  (payload) => {
4619
6492
  if (!payload) {
4620
6493
  return;
@@ -4637,11 +6510,11 @@ function Chat({
4637
6510
  },
4638
6511
  [composer?.tools]
4639
6512
  ),
4640
- onFocusComposer: React22.useCallback(() => {
6513
+ onFocusComposer: React26.useCallback(() => {
4641
6514
  composerInputRef.current?.focus();
4642
6515
  }, [])
4643
6516
  });
4644
- const syncQuoteSelection = React22.useCallback(() => {
6517
+ const syncQuoteSelection = React26.useCallback(() => {
4645
6518
  if (typeof window === "undefined") {
4646
6519
  clearQuoteSelection();
4647
6520
  return;
@@ -4686,23 +6559,23 @@ function Chat({
4686
6559
  left
4687
6560
  });
4688
6561
  }, [clearQuoteSelection]);
4689
- const cancelPendingAutoScroll = React22.useCallback(() => {
6562
+ const cancelPendingAutoScroll = React26.useCallback(() => {
4690
6563
  if (autoScrollFrameRef.current !== null) {
4691
6564
  cancelAnimationFrame(autoScrollFrameRef.current);
4692
6565
  autoScrollFrameRef.current = null;
4693
6566
  }
4694
6567
  }, []);
4695
- const disableAutoFollow = React22.useCallback(() => {
6568
+ const disableAutoFollow = React26.useCallback(() => {
4696
6569
  forceFollowRef.current = false;
4697
6570
  shouldAutoScrollRef.current = false;
4698
6571
  cancelPendingAutoScroll();
4699
6572
  }, [cancelPendingAutoScroll]);
4700
- const enableAutoFollow = React22.useCallback(() => {
6573
+ const enableAutoFollow = React26.useCallback(() => {
4701
6574
  forceFollowRef.current = true;
4702
6575
  shouldAutoScrollRef.current = true;
4703
6576
  setHasUpdatesBelow(false);
4704
6577
  }, []);
4705
- const scrollToBottom = React22.useCallback(
6578
+ const scrollToBottom = React26.useCallback(
4706
6579
  (smooth = false, force = false) => {
4707
6580
  if (force) {
4708
6581
  enableAutoFollow();
@@ -4724,7 +6597,7 @@ function Chat({
4724
6597
  },
4725
6598
  [cancelPendingAutoScroll, enableAutoFollow]
4726
6599
  );
4727
- React22.useEffect(() => {
6600
+ React26.useEffect(() => {
4728
6601
  const viewport = viewportRef.current;
4729
6602
  if (!viewport) return;
4730
6603
  previousScrollTopRef.current = viewport.scrollTop;
@@ -4805,14 +6678,14 @@ function Chat({
4805
6678
  window.removeEventListener("pointercancel", stopPointerTracking);
4806
6679
  };
4807
6680
  }, [cancelPendingAutoScroll, disableAutoFollow]);
4808
- React22.useEffect(() => {
6681
+ React26.useEffect(() => {
4809
6682
  shouldAutoScrollRef.current = true;
4810
6683
  forceFollowRef.current = false;
4811
6684
  previousScrollTopRef.current = 0;
4812
6685
  setIsAtBottom(true);
4813
6686
  setHasUpdatesBelow(false);
4814
6687
  }, [stream.threadId]);
4815
- React22.useEffect(() => {
6688
+ React26.useEffect(() => {
4816
6689
  const messageCountChanged = messages.length !== previousMessageCountRef.current;
4817
6690
  previousMessageCountRef.current = messages.length;
4818
6691
  if (!shouldAutoScrollRef.current) {
@@ -4831,7 +6704,7 @@ function Chat({
4831
6704
  clientSecret: effectiveClientSecret
4832
6705
  });
4833
6706
  const missingConfig = Boolean(missingConfigKind);
4834
- const missingConfigShortMessage = React22.useMemo(() => {
6707
+ const missingConfigShortMessage = React26.useMemo(() => {
4835
6708
  switch (missingConfigKind) {
4836
6709
  case "apiUrl":
4837
6710
  return t("chat.missingApiUrlShort");
@@ -4843,7 +6716,7 @@ function Chat({
4843
6716
  return t("chat.missingConfigShort");
4844
6717
  }
4845
6718
  }, [missingConfigKind, t]);
4846
- const missingConfigDetailMessage = React22.useMemo(() => {
6719
+ const missingConfigDetailMessage = React26.useMemo(() => {
4847
6720
  switch (missingConfigKind) {
4848
6721
  case "apiUrl":
4849
6722
  return t("chat.missingApiUrlDetail");
@@ -4857,8 +6730,8 @@ function Chat({
4857
6730
  }, [missingConfigKind, t]);
4858
6731
  const showMissingConfig = !isClientSecretInitializing && missingConfig;
4859
6732
  const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
4860
- const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
4861
- const resizeComposerInput = React22.useCallback(() => {
6733
+ const isSendDisabled = !trimmedDraft && !hasReferences || hasPendingRequestUserInput || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
6734
+ const resizeComposerInput = React26.useCallback(() => {
4862
6735
  const textarea = composerInputRef.current;
4863
6736
  if (!textarea) {
4864
6737
  return;
@@ -4871,16 +6744,16 @@ function Chat({
4871
6744
  textarea.style.height = `${nextHeight}px`;
4872
6745
  textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
4873
6746
  }, []);
4874
- React22.useEffect(() => {
6747
+ React26.useEffect(() => {
4875
6748
  resizeComposerInput();
4876
6749
  }, [draft, resizeComposerInput]);
4877
- React22.useEffect(() => {
6750
+ React26.useEffect(() => {
4878
6751
  document.addEventListener("selectionchange", syncQuoteSelection);
4879
6752
  return () => {
4880
6753
  document.removeEventListener("selectionchange", syncQuoteSelection);
4881
6754
  };
4882
6755
  }, [syncQuoteSelection]);
4883
- React22.useEffect(() => {
6756
+ React26.useEffect(() => {
4884
6757
  const viewport = viewportRef.current;
4885
6758
  if (!viewport) {
4886
6759
  return;
@@ -4897,14 +6770,14 @@ function Chat({
4897
6770
  window.removeEventListener("resize", handleViewportScroll);
4898
6771
  };
4899
6772
  }, [clearQuoteSelection]);
4900
- React22.useEffect(() => {
6773
+ React26.useEffect(() => {
4901
6774
  clearQuoteSelection();
4902
6775
  }, [messages.length, stream.threadId, clearQuoteSelection]);
4903
- React22.useEffect(() => {
6776
+ React26.useEffect(() => {
4904
6777
  if (missingConfig) return;
4905
6778
  void refreshThreads();
4906
6779
  }, [missingConfig, refreshThreads]);
4907
- React22.useEffect(() => {
6780
+ React26.useEffect(() => {
4908
6781
  if (missingConfig || !stream.client || !stream.assistantId) {
4909
6782
  setAssistantName(null);
4910
6783
  setAssistantAvatar(null);
@@ -4935,7 +6808,7 @@ function Chat({
4935
6808
  mimetype: a.storageFile?.mimetype ?? a.file.type,
4936
6809
  size: a.storageFile?.size ?? a.file.size
4937
6810
  }));
4938
- const submitDraft = React22.useCallback(
6811
+ const submitDraft = React26.useCallback(
4939
6812
  (followUpOverride) => {
4940
6813
  if (isSendDisabled) return;
4941
6814
  const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
@@ -4965,6 +6838,9 @@ function Chat({
4965
6838
  if (filesToSend) {
4966
6839
  inputPayload.files = filesToSend;
4967
6840
  }
6841
+ if (planModeEnabled) {
6842
+ inputPayload.planMode = true;
6843
+ }
4968
6844
  const requestOptions = buildInjectedRequestOptions({
4969
6845
  defaults: options?.request,
4970
6846
  humanInput: inputPayload
@@ -4999,6 +6875,7 @@ function Chat({
4999
6875
  references,
5000
6876
  scrollToBottom,
5001
6877
  selectedTool,
6878
+ planModeEnabled,
5002
6879
  stream,
5003
6880
  trimmedDraft,
5004
6881
  uploadedFiles,
@@ -5009,7 +6886,7 @@ function Chat({
5009
6886
  event.preventDefault();
5010
6887
  submitDraft();
5011
6888
  };
5012
- const handleEditPendingFollowUp = React22.useCallback(
6889
+ const handleEditPendingFollowUp = React26.useCallback(
5013
6890
  (id) => {
5014
6891
  const item = pendingFollowUps.find(
5015
6892
  (entry) => entry.id === id && entry.mode === "queue"
@@ -5036,7 +6913,7 @@ function Chat({
5036
6913
  },
5037
6914
  [pendingFollowUps, stream]
5038
6915
  );
5039
- const handleQuoteSelection = React22.useCallback(() => {
6916
+ const handleQuoteSelection = React26.useCallback(() => {
5040
6917
  if (!quoteSelection) {
5041
6918
  return;
5042
6919
  }
@@ -5052,7 +6929,7 @@ function Chat({
5052
6929
  const handleAttachmentClick = () => {
5053
6930
  fileInputRef.current?.click();
5054
6931
  };
5055
- const uploadContextFile = React22.useCallback(
6932
+ const uploadContextFile = React26.useCallback(
5056
6933
  (file) => stream.client.contexts.uploadFile(file),
5057
6934
  [stream.client]
5058
6935
  );
@@ -5078,7 +6955,7 @@ function Chat({
5078
6955
  }
5079
6956
  submitDraft();
5080
6957
  };
5081
- const handleComposerPaste = React22.useCallback(
6958
+ const handleComposerPaste = React26.useCallback(
5082
6959
  (event) => {
5083
6960
  const clipboardData = event.clipboardData;
5084
6961
  if (!clipboardData) {
@@ -5157,18 +7034,18 @@ function Chat({
5157
7034
  uploadContextFile
5158
7035
  ]
5159
7036
  );
5160
- const alternateFollowUpShortcutLabel = React22.useMemo(() => {
7037
+ const alternateFollowUpShortcutLabel = React26.useMemo(() => {
5161
7038
  if (typeof navigator === "undefined") {
5162
7039
  return "\u2318Enter";
5163
7040
  }
5164
7041
  const platform = navigator.platform || navigator.userAgent;
5165
7042
  return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
5166
7043
  }, []);
5167
- const followUpShortcutLabels = React22.useMemo(
7044
+ const followUpShortcutLabels = React26.useMemo(
5168
7045
  () => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
5169
7046
  [alternateFollowUpShortcutLabel]
5170
7047
  );
5171
- const uploadFile = React22.useCallback(
7048
+ const uploadFile = React26.useCallback(
5172
7049
  async (localId, file) => {
5173
7050
  try {
5174
7051
  const result = await uploadContextFile(file);
@@ -5191,7 +7068,7 @@ function Chat({
5191
7068
  },
5192
7069
  [uploadContextFile]
5193
7070
  );
5194
- const handleRetryUpload = React22.useCallback(
7071
+ const handleRetryUpload = React26.useCallback(
5195
7072
  (localId) => {
5196
7073
  const attachment = attachments.find((a) => a.localId === localId);
5197
7074
  if (!attachment || attachment.status !== "error") return;
@@ -5262,10 +7139,23 @@ function Chat({
5262
7139
  content: prompt
5263
7140
  };
5264
7141
  const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
7142
+ const inputPayload = {
7143
+ input: prompt,
7144
+ ...planModeEnabled ? { planMode: true } : {}
7145
+ };
7146
+ const requestOptions = buildInjectedRequestOptions({
7147
+ defaults: options?.request,
7148
+ humanInput: inputPayload
7149
+ });
5265
7150
  stream.submit(
5266
- { input: { input: prompt } },
7151
+ {
7152
+ input: inputPayload,
7153
+ ...requestOptions.state ? { state: requestOptions.state } : {}
7154
+ },
5267
7155
  {
5268
7156
  ...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
7157
+ ...requestOptions.context ? { context: requestOptions.context } : {},
7158
+ ...requestOptions.config ? { config: requestOptions.config } : {},
5269
7159
  ...!nextFollowUpMode ? {
5270
7160
  optimisticValues: (prev) => {
5271
7161
  const prevMessages = prev?.messages ?? [];
@@ -5276,7 +7166,7 @@ function Chat({
5276
7166
  );
5277
7167
  scrollToBottom(true, true);
5278
7168
  };
5279
- const loadConversationMessages = React22.useCallback(
7169
+ const loadConversationMessages = React26.useCallback(
5280
7170
  async (recordId) => {
5281
7171
  if (missingConfig) {
5282
7172
  setHistoryError(missingConfigShortMessage);
@@ -5362,18 +7252,18 @@ function Chat({
5362
7252
  }
5363
7253
  };
5364
7254
  const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
5365
- const currentThread = React22.useMemo(
7255
+ const currentThread = React26.useMemo(
5366
7256
  () => threads.find((item) => item.id === stream.threadId),
5367
7257
  [threads, stream.threadId]
5368
7258
  );
5369
7259
  const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
5370
- const threadErrorMessage = React22.useMemo(() => {
7260
+ const threadErrorMessage = React26.useMemo(() => {
5371
7261
  if (currentThread?.status !== "error") return void 0;
5372
7262
  const message = currentThread.error?.trim();
5373
7263
  return message || t("thread.errorToast");
5374
7264
  }, [currentThread, t]);
5375
7265
  const assistantTitle = assistantName || resolvedTitle;
5376
- return /* @__PURE__ */ jsxs17(
7266
+ return /* @__PURE__ */ jsxs21(
5377
7267
  "div",
5378
7268
  {
5379
7269
  ref: viewportRef,
@@ -5382,10 +7272,10 @@ function Chat({
5382
7272
  className
5383
7273
  ),
5384
7274
  children: [
5385
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
5386
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3 overflow-hidden", children: [
5387
- /* @__PURE__ */ jsxs17("div", { className: "relative shrink-0", children: [
5388
- /* @__PURE__ */ jsx28(
7275
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
7276
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 overflow-hidden", children: [
7277
+ /* @__PURE__ */ jsxs21("div", { className: "relative shrink-0", children: [
7278
+ /* @__PURE__ */ jsx32(
5389
7279
  ChatkitAvatar,
5390
7280
  {
5391
7281
  avatar: assistantAvatar,
@@ -5393,10 +7283,10 @@ function Chat({
5393
7283
  label: assistantTitle
5394
7284
  }
5395
7285
  ),
5396
- /* @__PURE__ */ jsx28("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
7286
+ /* @__PURE__ */ jsx32("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
5397
7287
  ] }),
5398
- /* @__PURE__ */ jsxs17("div", { className: "truncate", children: [
5399
- /* @__PURE__ */ jsx28(
7288
+ /* @__PURE__ */ jsxs21("div", { className: "truncate", children: [
7289
+ /* @__PURE__ */ jsx32(
5400
7290
  "h2",
5401
7291
  {
5402
7292
  className: "text-lg font-semibold truncate",
@@ -5404,27 +7294,30 @@ function Chat({
5404
7294
  children: assistantTitle
5405
7295
  }
5406
7296
  ),
5407
- /* @__PURE__ */ jsx28("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
7297
+ /* @__PURE__ */ jsx32("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
5408
7298
  ] })
5409
7299
  ] }),
5410
- history?.enabled !== false && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
5411
- /* @__PURE__ */ jsx28(
5412
- "button",
5413
- {
5414
- type: "button",
5415
- onClick: handleNewThread,
5416
- disabled: missingConfig || isHistoryLoading,
5417
- className: cn(
5418
- "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
5419
- "text-muted-foreground hover:text-foreground hover:bg-muted",
5420
- "transition-colors duration-150",
5421
- "disabled:opacity-50 disabled:cursor-not-allowed"
5422
- ),
5423
- title: t("history.newThread"),
5424
- children: /* @__PURE__ */ jsx28(Pencil3, { size: 16 })
5425
- }
5426
- ),
5427
- /* @__PURE__ */ jsx28(
7300
+ history?.enabled !== false && /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-1", children: [
7301
+ /* @__PURE__ */ jsxs21(Tooltip, { children: [
7302
+ /* @__PURE__ */ jsx32(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx32("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx32(
7303
+ "button",
7304
+ {
7305
+ type: "button",
7306
+ onClick: handleNewThread,
7307
+ disabled: missingConfig || isHistoryLoading,
7308
+ className: cn(
7309
+ "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
7310
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
7311
+ "transition-colors duration-150",
7312
+ "disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed"
7313
+ ),
7314
+ "aria-label": t("history.newThread"),
7315
+ children: /* @__PURE__ */ jsx32(Pencil3, { size: 16 })
7316
+ }
7317
+ ) }) }),
7318
+ /* @__PURE__ */ jsx32(TooltipContent, { side: "bottom", children: t("history.newThread") })
7319
+ ] }),
7320
+ /* @__PURE__ */ jsx32(
5428
7321
  HistorySidebar,
5429
7322
  {
5430
7323
  threads,
@@ -5438,18 +7331,18 @@ function Chat({
5438
7331
  )
5439
7332
  ] })
5440
7333
  ] }),
5441
- /* @__PURE__ */ jsxs17("div", { className: "flex-1 p-4", children: [
5442
- errorMessage && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
5443
- historyError && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
5444
- showMissingConfig && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
5445
- isHistoryLoading && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
5446
- messages.length === 0 ? /* @__PURE__ */ jsx28(
7334
+ /* @__PURE__ */ jsxs21("div", { className: "flex-1 p-4", children: [
7335
+ errorMessage && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
7336
+ historyError && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
7337
+ showMissingConfig && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
7338
+ isHistoryLoading && /* @__PURE__ */ jsx32("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
7339
+ messages.length === 0 ? /* @__PURE__ */ jsx32(
5447
7340
  StartScreen,
5448
7341
  {
5449
7342
  startScreen,
5450
7343
  onPromptClick: handlePromptClick
5451
7344
  }
5452
- ) : /* @__PURE__ */ jsxs17("div", { className: "space-y-4", children: [
7345
+ ) : /* @__PURE__ */ jsxs21("div", { className: "space-y-4", children: [
5453
7346
  messages.map((message, index) => {
5454
7347
  const messageType = String(message.type);
5455
7348
  const isAssistantMessage = messageType === "assistant" || messageType === "ai";
@@ -5476,7 +7369,7 @@ function Chat({
5476
7369
  if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
5477
7370
  return null;
5478
7371
  }
5479
- return /* @__PURE__ */ jsx28(
7372
+ return /* @__PURE__ */ jsx32(
5480
7373
  "div",
5481
7374
  {
5482
7375
  className: cn(
@@ -5484,8 +7377,8 @@ function Chat({
5484
7377
  message.type === "human" ? "justify-end" : "justify-start -ml-1"
5485
7378
  // AI messages: slightly closer to left
5486
7379
  ),
5487
- children: /* @__PURE__ */ jsxs17("div", { className: "flex flex-col px-3 overflow-hidden", children: [
5488
- /* @__PURE__ */ jsx28(
7380
+ children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col px-3 overflow-hidden", children: [
7381
+ /* @__PURE__ */ jsx32(
5489
7382
  "div",
5490
7383
  {
5491
7384
  ...canQuoteMessage ? {
@@ -5497,18 +7390,24 @@ function Chat({
5497
7390
  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"
5498
7391
  // AI messages: use chat-specific foreground color
5499
7392
  ),
5500
- children: isAssistantMessage ? /* @__PURE__ */ jsx28(
7393
+ children: isAssistantMessage ? /* @__PURE__ */ jsx32(
5501
7394
  AssistantMessage,
5502
7395
  {
5503
7396
  message: {
5504
7397
  ...message,
5505
7398
  type: "assistant"
5506
7399
  },
7400
+ messages: messages.slice(0, index + 1).map(
7401
+ (item) => ({
7402
+ ...item,
7403
+ type: String(item.type) === "ai" ? "assistant" : item.type
7404
+ })
7405
+ ),
5507
7406
  isStreaming: isStreamingMessage,
5508
7407
  streamingStatus
5509
7408
  }
5510
- ) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
5511
- message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx28(
7409
+ ) : /* @__PURE__ */ jsxs21(Fragment4, { children: [
7410
+ message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx32(
5512
7411
  ReferenceChip,
5513
7412
  {
5514
7413
  reference,
@@ -5516,29 +7415,29 @@ function Chat({
5516
7415
  },
5517
7416
  getReferenceKey(reference)
5518
7417
  )) }),
5519
- message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx28("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs17(
7418
+ message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx32("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs21(
5520
7419
  "div",
5521
7420
  {
5522
7421
  className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
5523
7422
  children: [
5524
- /* @__PURE__ */ jsx28(FileText2, { size: 12 }),
5525
- /* @__PURE__ */ jsx28("span", { className: "max-w-[100px] truncate", children: file.originalName })
7423
+ /* @__PURE__ */ jsx32(FileText2, { size: 12 }),
7424
+ /* @__PURE__ */ jsx32("span", { className: "max-w-[100px] truncate", children: file.originalName })
5526
7425
  ]
5527
7426
  },
5528
7427
  fileIndex
5529
7428
  )) }),
5530
- Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx28(
7429
+ Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx32(
5531
7430
  "p",
5532
7431
  {
5533
7432
  className: "wrap-break-word text-sm leading-relaxed",
5534
7433
  children: formatMessageContent(part)
5535
7434
  },
5536
7435
  `${part.type}-${partIndex}`
5537
- )) : /* @__PURE__ */ jsx28("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
7436
+ )) : /* @__PURE__ */ jsx32("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
5538
7437
  ] })
5539
7438
  }
5540
7439
  ),
5541
- /* @__PURE__ */ jsx28(
7440
+ /* @__PURE__ */ jsx32(
5542
7441
  MessageActions,
5543
7442
  {
5544
7443
  content: messageContent,
@@ -5574,7 +7473,7 @@ function Chat({
5574
7473
  stream.isLoading,
5575
7474
  { now: streamingNow }
5576
7475
  );
5577
- return /* @__PURE__ */ jsx28("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx28("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx28(
7476
+ return /* @__PURE__ */ jsx32("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx32("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx32(
5578
7477
  AssistantStreamingIndicator,
5579
7478
  {
5580
7479
  status: fallbackStreamingStatus ?? "loading"
@@ -5583,7 +7482,7 @@ function Chat({
5583
7482
  })()
5584
7483
  ] })
5585
7484
  ] }),
5586
- !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx28("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx28(
7485
+ !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx32("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx32(
5587
7486
  Button,
5588
7487
  {
5589
7488
  type: "button",
@@ -5596,10 +7495,10 @@ function Chat({
5596
7495
  onClick: () => scrollToBottom(true, true),
5597
7496
  "aria-label": t("chat.scrollToBottom"),
5598
7497
  title: t("chat.scrollToBottom"),
5599
- children: /* @__PURE__ */ jsx28(ArrowDown, { size: 16 })
7498
+ children: /* @__PURE__ */ jsx32(ArrowDown2, { size: 16 })
5600
7499
  }
5601
7500
  ) }),
5602
- quoteSelection && /* @__PURE__ */ jsx28(
7501
+ quoteSelection && /* @__PURE__ */ jsx32(
5603
7502
  "div",
5604
7503
  {
5605
7504
  className: "pointer-events-none fixed z-50",
@@ -5608,7 +7507,7 @@ function Chat({
5608
7507
  left: `${quoteSelection.left}px`,
5609
7508
  transform: "translateX(-50%)"
5610
7509
  },
5611
- children: /* @__PURE__ */ jsxs17(
7510
+ children: /* @__PURE__ */ jsxs21(
5612
7511
  Button,
5613
7512
  {
5614
7513
  type: "button",
@@ -5620,16 +7519,16 @@ function Chat({
5620
7519
  "aria-label": t("composer.quoteSelection"),
5621
7520
  title: t("composer.quoteSelection"),
5622
7521
  children: [
5623
- /* @__PURE__ */ jsx28(Quote, { size: 14 }),
7522
+ /* @__PURE__ */ jsx32(Quote, { size: 14 }),
5624
7523
  t("composer.quoteSelection")
5625
7524
  ]
5626
7525
  }
5627
7526
  )
5628
7527
  }
5629
7528
  ),
5630
- /* @__PURE__ */ jsxs17("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
5631
- threadErrorMessage && /* @__PURE__ */ jsx28("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 }),
5632
- /* @__PURE__ */ jsx28(
7529
+ /* @__PURE__ */ jsxs21("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
7530
+ threadErrorMessage && /* @__PURE__ */ jsx32("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
7531
+ /* @__PURE__ */ jsx32(
5633
7532
  "input",
5634
7533
  {
5635
7534
  ref: fileInputRef,
@@ -5640,7 +7539,7 @@ function Chat({
5640
7539
  className: "hidden"
5641
7540
  }
5642
7541
  ),
5643
- attachments.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs17(
7542
+ attachments.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs21(
5644
7543
  "div",
5645
7544
  {
5646
7545
  className: cn(
@@ -5648,16 +7547,16 @@ function Chat({
5648
7547
  item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
5649
7548
  ),
5650
7549
  children: [
5651
- item.status === "uploading" && /* @__PURE__ */ jsx28(
5652
- Loader23,
7550
+ item.status === "uploading" && /* @__PURE__ */ jsx32(
7551
+ Loader24,
5653
7552
  {
5654
7553
  size: 14,
5655
7554
  className: "animate-spin text-muted-foreground"
5656
7555
  }
5657
7556
  ),
5658
- item.status === "success" && /* @__PURE__ */ jsx28(FileText2, { size: 14, className: "text-muted-foreground" }),
5659
- item.status === "error" && /* @__PURE__ */ jsx28(FileText2, { size: 14, className: "text-destructive" }),
5660
- /* @__PURE__ */ jsx28(
7557
+ item.status === "success" && /* @__PURE__ */ jsx32(FileText2, { size: 14, className: "text-muted-foreground" }),
7558
+ item.status === "error" && /* @__PURE__ */ jsx32(FileText2, { size: 14, className: "text-destructive" }),
7559
+ /* @__PURE__ */ jsx32(
5661
7560
  "span",
5662
7561
  {
5663
7562
  className: cn(
@@ -5667,17 +7566,17 @@ function Chat({
5667
7566
  children: item.file.name
5668
7567
  }
5669
7568
  ),
5670
- item.status === "error" && /* @__PURE__ */ jsx28(
7569
+ item.status === "error" && /* @__PURE__ */ jsx32(
5671
7570
  "button",
5672
7571
  {
5673
7572
  type: "button",
5674
7573
  onClick: () => handleRetryUpload(item.localId),
5675
7574
  className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
5676
7575
  title: t("chat.retryUpload"),
5677
- children: /* @__PURE__ */ jsx28(RefreshCw2, { size: 12 })
7576
+ children: /* @__PURE__ */ jsx32(RefreshCw2, { size: 12 })
5678
7577
  }
5679
7578
  ),
5680
- /* @__PURE__ */ jsx28(
7579
+ /* @__PURE__ */ jsx32(
5681
7580
  "button",
5682
7581
  {
5683
7582
  type: "button",
@@ -5686,14 +7585,14 @@ function Chat({
5686
7585
  "ml-1 rounded-full p-0.5",
5687
7586
  item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
5688
7587
  ),
5689
- children: /* @__PURE__ */ jsx28(X3, { size: 12 })
7588
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
5690
7589
  }
5691
7590
  )
5692
7591
  ]
5693
7592
  },
5694
7593
  item.localId
5695
7594
  )) }),
5696
- references.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx28(
7595
+ references.length > 0 && /* @__PURE__ */ jsx32("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx32(
5697
7596
  ReferenceChip,
5698
7597
  {
5699
7598
  reference,
@@ -5707,19 +7606,27 @@ function Chat({
5707
7606
  },
5708
7607
  getReferenceKey(reference)
5709
7608
  )) }),
5710
- selectedTool && /* @__PURE__ */ jsxs17("div", { className: "mb-2 flex items-center gap-2", children: [
5711
- /* @__PURE__ */ jsx28("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
5712
- /* @__PURE__ */ jsx28(
7609
+ selectedTool && /* @__PURE__ */ jsxs21("div", { className: "mb-2 flex items-center gap-2", children: [
7610
+ /* @__PURE__ */ jsx32("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
7611
+ /* @__PURE__ */ jsx32(
5713
7612
  "button",
5714
7613
  {
5715
7614
  type: "button",
5716
7615
  onClick: () => setSelectedTool(null),
5717
7616
  className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
5718
- children: /* @__PURE__ */ jsx28(X3, { size: 12 })
7617
+ children: /* @__PURE__ */ jsx32(X3, { size: 12 })
5719
7618
  }
5720
7619
  )
5721
7620
  ] }),
5722
- /* @__PURE__ */ jsx28(
7621
+ /* @__PURE__ */ jsx32(
7622
+ PendingTodos,
7623
+ {
7624
+ snapshot: stream.todos,
7625
+ attachToComposer: !hasPendingFollowUps,
7626
+ className: hasPendingFollowUps ? "mb-2" : void 0
7627
+ }
7628
+ ),
7629
+ /* @__PURE__ */ jsx32(
5723
7630
  PendingFollowUps,
5724
7631
  {
5725
7632
  items: pendingFollowUps,
@@ -5730,10 +7637,20 @@ function Chat({
5730
7637
  canSendNow: stream.canSendPendingFollowUpNow,
5731
7638
  onSendNow: (id) => stream.sendPendingFollowUpNow(id),
5732
7639
  onEdit: handleEditPendingFollowUp,
5733
- onRemove: stream.removePendingFollowUp
7640
+ onRemove: stream.removePendingFollowUp,
7641
+ attachToComposer: true
5734
7642
  }
5735
7643
  ),
5736
- /* @__PURE__ */ jsx28("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs17(
7644
+ /* @__PURE__ */ jsx32(
7645
+ RequestUserInputPanel,
7646
+ {
7647
+ request: stream.pendingRequestUserInput,
7648
+ onSubmit: stream.submitRequestUserInput,
7649
+ onDismiss: stream.stop,
7650
+ attachToComposer: true
7651
+ }
7652
+ ),
7653
+ /* @__PURE__ */ jsx32("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs21(
5737
7654
  "div",
5738
7655
  {
5739
7656
  className: cn(
@@ -5745,17 +7662,19 @@ function Chat({
5745
7662
  getRoundedClass(theme.radius)
5746
7663
  ),
5747
7664
  children: [
5748
- /* @__PURE__ */ jsx28(
7665
+ /* @__PURE__ */ jsx32(
5749
7666
  ComposerMenu,
5750
7667
  {
5751
7668
  composer,
5752
7669
  onAttachmentClick: handleAttachmentClick,
5753
7670
  onToolSelect: handleToolSelect,
5754
7671
  selectedTool,
5755
- disabled: missingConfig || isHistoryLoading
7672
+ planModeEnabled,
7673
+ onPlanModeChange: setPlanModeEnabled,
7674
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput
5756
7675
  }
5757
7676
  ),
5758
- /* @__PURE__ */ jsx28(
7677
+ /* @__PURE__ */ jsx32(
5759
7678
  "textarea",
5760
7679
  {
5761
7680
  ref: composerInputRef,
@@ -5765,7 +7684,7 @@ function Chat({
5765
7684
  onKeyDown: handleComposerKeyDown,
5766
7685
  rows: 1,
5767
7686
  placeholder: inputPlaceholder,
5768
- disabled: missingConfig || isHistoryLoading,
7687
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput,
5769
7688
  className: cn(
5770
7689
  "min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
5771
7690
  "placeholder:text-muted-foreground",
@@ -5773,12 +7692,12 @@ function Chat({
5773
7692
  )
5774
7693
  }
5775
7694
  ),
5776
- /* @__PURE__ */ jsx28(
7695
+ /* @__PURE__ */ jsx32(
5777
7696
  SendButton,
5778
7697
  {
5779
7698
  disabled: isSendDisabled,
5780
7699
  isLoading: stream.isLoading,
5781
- showStop: stream.isLoading && !trimmedDraft,
7700
+ showStop: stream.isLoading && (!trimmedDraft || hasPendingRequestUserInput),
5782
7701
  onStop: () => stream.stop(),
5783
7702
  stopLabel: t("chat.stop"),
5784
7703
  sendLabel: t("chat.send"),
@@ -5797,7 +7716,7 @@ function Chat({
5797
7716
  ]
5798
7717
  }
5799
7718
  ) }),
5800
- disclaimer?.text && /* @__PURE__ */ jsx28(
7719
+ disclaimer?.text && /* @__PURE__ */ jsx32(
5801
7720
  "p",
5802
7721
  {
5803
7722
  className: cn(
@@ -5807,9 +7726,9 @@ function Chat({
5807
7726
  children: disclaimer.text
5808
7727
  }
5809
7728
  ),
5810
- /* @__PURE__ */ jsxs17("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
5811
- /* @__PURE__ */ jsx28("span", { children: t("chat.poweredBy") }),
5812
- /* @__PURE__ */ jsx28(ContextUsageIndicator, { className: "absolute right-4" })
7729
+ /* @__PURE__ */ jsxs21("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
7730
+ /* @__PURE__ */ jsx32("span", { children: t("chat.poweredBy") }),
7731
+ /* @__PURE__ */ jsx32(ContextUsageIndicator, { className: "absolute right-4" })
5813
7732
  ] })
5814
7733
  ] })
5815
7734
  ]
@@ -5818,11 +7737,11 @@ function Chat({
5818
7737
  }
5819
7738
 
5820
7739
  // src/components/ui/input.tsx
5821
- import * as React23 from "react";
5822
- import { jsx as jsx29 } from "react/jsx-runtime";
5823
- var Input = React23.forwardRef(
7740
+ import * as React27 from "react";
7741
+ import { jsx as jsx33 } from "react/jsx-runtime";
7742
+ var Input = React27.forwardRef(
5824
7743
  ({ className, type, ...props }, ref) => {
5825
- return /* @__PURE__ */ jsx29(
7744
+ return /* @__PURE__ */ jsx33(
5826
7745
  "input",
5827
7746
  {
5828
7747
  ref,
@@ -5839,10 +7758,10 @@ var Input = React23.forwardRef(
5839
7758
  Input.displayName = "Input";
5840
7759
 
5841
7760
  // src/components/ui/separator.tsx
5842
- import * as React24 from "react";
5843
- import { jsx as jsx30 } from "react/jsx-runtime";
5844
- var Separator = React24.forwardRef(
5845
- ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx30(
7761
+ import * as React28 from "react";
7762
+ import { jsx as jsx34 } from "react/jsx-runtime";
7763
+ var Separator = React28.forwardRef(
7764
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx34(
5846
7765
  "div",
5847
7766
  {
5848
7767
  ref,