@xpert-ai/chatkit-ui 0.1.2 → 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 (336) hide show
  1. package/dist/app/assets/{_baseUniq-Cjg58ynO.js → _baseUniq-U3ZlyosM.js} +1 -1
  2. package/dist/app/assets/{abap-CaHNU3KZ.js → abap-8X6m4nc9.js} +1 -1
  3. package/dist/app/assets/{abnf-D-YMXYdM.js → abnf-B9FqRK4Q.js} +1 -1
  4. package/dist/app/assets/{actionscript-CrHB5nA4.js → actionscript-BRiggmYG.js} +1 -1
  5. package/dist/app/assets/{ada-Dv2nikaa.js → ada-FFsIKz3W.js} +1 -1
  6. package/dist/app/assets/{agda-DFaAW7Yp.js → agda-CSry7vG2.js} +1 -1
  7. package/dist/app/assets/{al-CgiCJJan.js → al-B86I55sd.js} +1 -1
  8. package/dist/app/assets/{antlr4-BtYcfzHN.js → antlr4-DLdIrmfn.js} +1 -1
  9. package/dist/app/assets/{apacheconf-CQ7_TaHr.js → apacheconf-CyFZwC58.js} +1 -1
  10. package/dist/app/assets/{apex-B4zhZGbX.js → apex-DMVXQx7B.js} +1 -1
  11. package/dist/app/assets/{apl-CYl9UMD4.js → apl-CvxzOn3f.js} +1 -1
  12. package/dist/app/assets/{applescript-CqOg5uaM.js → applescript-D9BsJ4nv.js} +1 -1
  13. package/dist/app/assets/{aql-g4FQmCtN.js → aql-Du46VsVP.js} +1 -1
  14. package/dist/app/assets/{arc-Dg9GdpOd.js → arc-Cgg2Li2V.js} +1 -1
  15. package/dist/app/assets/{architectureDiagram-Q4EWVU46-D_Hf6A9k.js → architectureDiagram-Q4EWVU46-3DQlJdjW.js} +1 -1
  16. package/dist/app/assets/{arduino-CLAoEDGh.js → arduino-Bsv1YPmE.js} +1 -1
  17. package/dist/app/assets/{arff-CkPQOMpJ.js → arff-CJK1I_i3.js} +1 -1
  18. package/dist/app/assets/{asciidoc-D6FBYhU4.js → asciidoc-DxmnfpMK.js} +1 -1
  19. package/dist/app/assets/{asm6502-BNREQutf.js → asm6502-B-ig6A0r.js} +1 -1
  20. package/dist/app/assets/{asmatmel-AsGe04C5.js → asmatmel-DlH3PvMo.js} +1 -1
  21. package/dist/app/assets/{aspnet-BowT6uwS.js → aspnet-D8iv0Uvb.js} +1 -1
  22. package/dist/app/assets/{autohotkey-CYQjpY2v.js → autohotkey-B0J5KM1J.js} +1 -1
  23. package/dist/app/assets/{autoit-DZuwPYYs.js → autoit-DjZ-C8Ct.js} +1 -1
  24. package/dist/app/assets/{avisynth-BApmLDkf.js → avisynth-DBwstp_C.js} +1 -1
  25. package/dist/app/assets/{avro-idl-DTdqv6Sr.js → avro-idl-D2NmTxDF.js} +1 -1
  26. package/dist/app/assets/{bash-COtf9s5e.js → bash-CaYF0XP6.js} +1 -1
  27. package/dist/app/assets/{basic-0Wk0Z9hh.js → basic-CmOS0BPn.js} +1 -1
  28. package/dist/app/assets/{batch-yLGV74r2.js → batch-0uLA_1q6.js} +1 -1
  29. package/dist/app/assets/{bbcode-gj0k8ZdD.js → bbcode-DofDtehq.js} +1 -1
  30. package/dist/app/assets/{bicep-BsCXg-ZU.js → bicep-Csi6HiBf.js} +1 -1
  31. package/dist/app/assets/{birb-CrVXepVH.js → birb-wpSYHdbW.js} +1 -1
  32. package/dist/app/assets/{bison-CEkN9m61.js → bison-B_ycJmsC.js} +1 -1
  33. package/dist/app/assets/{blockDiagram-DXYQGD6D-Cxg7TJzM.js → blockDiagram-DXYQGD6D-C5FR_JeB.js} +1 -1
  34. package/dist/app/assets/{bnf-BNo5FkNz.js → bnf-BFkvwiYp.js} +1 -1
  35. package/dist/app/assets/{brainfuck-Be3VzThb.js → brainfuck-CKXec9xF.js} +1 -1
  36. package/dist/app/assets/{brightscript-DvlnFSog.js → brightscript-da2DAp0M.js} +1 -1
  37. package/dist/app/assets/{bro-v-4Gv7xz.js → bro-CMEOqxCO.js} +1 -1
  38. package/dist/app/assets/{bsl-Ckf08F6h.js → bsl-CcPijGZ5.js} +1 -1
  39. package/dist/app/assets/{c-DzIU03a7.js → c-ypihM29I.js} +1 -1
  40. package/dist/app/assets/{c4Diagram-AHTNJAMY-ClK737fG.js → c4Diagram-AHTNJAMY-CVQ-YBVO.js} +1 -1
  41. package/dist/app/assets/{cfscript-BjMiAM6E.js → cfscript-57UtmCol.js} +1 -1
  42. package/dist/app/assets/{chaiscript-B43Wj-Sh.js → chaiscript-Bzv7uMwl.js} +1 -1
  43. package/dist/app/assets/channel-QFEl2WH8.js +1 -0
  44. package/dist/app/assets/{chunk-4BX2VUAB-CLpouVUP.js → chunk-4BX2VUAB-Dxfd4JRQ.js} +1 -1
  45. package/dist/app/assets/{chunk-4TB4RGXK-Bx935_8R.js → chunk-4TB4RGXK-0tBP8iWY.js} +1 -1
  46. package/dist/app/assets/{chunk-55IACEB6-BBvPym8v.js → chunk-55IACEB6-C6Of3RNV.js} +1 -1
  47. package/dist/app/assets/{chunk-EDXVE4YY-DjPOkQ8M.js → chunk-EDXVE4YY-D9VnbCF6.js} +1 -1
  48. package/dist/app/assets/{chunk-FMBD7UC4-DYYB_Z9z.js → chunk-FMBD7UC4-C-jb70xY.js} +1 -1
  49. package/dist/app/assets/{chunk-OYMX7WX6-D6RNfja3.js → chunk-OYMX7WX6-DHv4g2zF.js} +1 -1
  50. package/dist/app/assets/{chunk-QZHKN3VN-C8ZgdC9O.js → chunk-QZHKN3VN-BVJ1du8l.js} +1 -1
  51. package/dist/app/assets/{chunk-YZCP3GAM-BBgDUOse.js → chunk-YZCP3GAM-C9v1WHTx.js} +1 -1
  52. package/dist/app/assets/{cil-B9ihzdF2.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-CJh4oCgy.js → clike-M17MKmCg.js} +1 -1
  56. package/dist/app/assets/{clojure-TlSbaE4l.js → clojure-BP9wyv_O.js} +1 -1
  57. package/dist/app/assets/clone-BMPaQ6PL.js +1 -0
  58. package/dist/app/assets/{cmake-BSn84SxA.js → cmake-Co2PqOJx.js} +1 -1
  59. package/dist/app/assets/{cobol-CJ6-cTtI.js → cobol-CNBeDco-.js} +1 -1
  60. package/dist/app/assets/{coffeescript-stKJEoMv.js → coffeescript-DdmDPbXl.js} +1 -1
  61. package/dist/app/assets/{concurnas-1ifwVnR3.js → concurnas-C9VRiWa-.js} +1 -1
  62. package/dist/app/assets/{coq-DVFU6UV7.js → coq-CYE7tqZa.js} +1 -1
  63. package/dist/app/assets/{core-Yh44uZBs.js → core-D4MD7_kt.js} +1 -1
  64. package/dist/app/assets/{cose-bilkent-S5V4N54A-Dx7-_QHb.js → cose-bilkent-S5V4N54A-Dxea2bnQ.js} +1 -1
  65. package/dist/app/assets/{cpp-Zzzi5FD8.js → cpp-DWaMOtiP.js} +1 -1
  66. package/dist/app/assets/{crystal-DDbZAA_E.js → crystal-BtBXd6Fx.js} +1 -1
  67. package/dist/app/assets/{csharp-BZcvKq6n.js → csharp-CrOHktb0.js} +1 -1
  68. package/dist/app/assets/{cshtml-9x1DpGIK.js → cshtml-CzjshIvK.js} +1 -1
  69. package/dist/app/assets/{csp-D1hHVDgG.js → csp-DnNBeWw0.js} +1 -1
  70. package/dist/app/assets/{css-extras-COx1Ei_l.js → css-extras-BDArRWv3.js} +1 -1
  71. package/dist/app/assets/{css-BFu7Iqqk.js → css-pohe_YML.js} +1 -1
  72. package/dist/app/assets/{csv-D0CxHXjS.js → csv-BOXRdr2m.js} +1 -1
  73. package/dist/app/assets/{cypher-BsuAyRBu.js → cypher-IsM8Hmhu.js} +1 -1
  74. package/dist/app/assets/{d-CtjOdpDZ.js → d-BUE4Srvp.js} +1 -1
  75. package/dist/app/assets/{dagre-KV5264BT-DjhJCF-B.js → dagre-KV5264BT-D9I1gn5M.js} +1 -1
  76. package/dist/app/assets/{dart-BN9c8RLX.js → dart-DKXx5vmY.js} +1 -1
  77. package/dist/app/assets/{dataweave-DzlUCFjQ.js → dataweave-CZ-IeeGN.js} +1 -1
  78. package/dist/app/assets/{dax-D0KU-54t.js → dax-Cyyg-Qre.js} +1 -1
  79. package/dist/app/assets/{dhall-BZJS2G5U.js → dhall-CI9o_hcQ.js} +1 -1
  80. package/dist/app/assets/{diagram-5BDNPKRD-DSws8TSr.js → diagram-5BDNPKRD-Da8AhEfW.js} +1 -1
  81. package/dist/app/assets/{diagram-G4DWMVQ6-Cx7BBH89.js → diagram-G4DWMVQ6-u5xAUOB1.js} +1 -1
  82. package/dist/app/assets/{diagram-MMDJMWI5-D9n-fpq5.js → diagram-MMDJMWI5-CRedReUg.js} +1 -1
  83. package/dist/app/assets/{diagram-TYMM5635-A2Du0da2.js → diagram-TYMM5635-Btelw9Gj.js} +1 -1
  84. package/dist/app/assets/{diff-2klWb1Uo.js → diff-BaJjRLPC.js} +1 -1
  85. package/dist/app/assets/{django-B2AbqJYz.js → django-DKz8sLSB.js} +1 -1
  86. package/dist/app/assets/{dns-zone-file-CvZSGx-4.js → dns-zone-file-DB4bzm0m.js} +1 -1
  87. package/dist/app/assets/{docker-Cn7U_QhX.js → docker-f9TV7yVV.js} +1 -1
  88. package/dist/app/assets/{dot-B8xtegaK.js → dot-CItfl0YH.js} +1 -1
  89. package/dist/app/assets/{ebnf-oe3GchaY.js → ebnf-4UWkoMwW.js} +1 -1
  90. package/dist/app/assets/{editorconfig-BcXP_CBv.js → editorconfig-DsQRKuSQ.js} +1 -1
  91. package/dist/app/assets/{eiffel-2H-hw0_M.js → eiffel-BKzL5tZy.js} +1 -1
  92. package/dist/app/assets/{ejs-Ba0Dl3hs.js → ejs-FawjQT4F.js} +1 -1
  93. package/dist/app/assets/{elixir-Zqex1hfd.js → elixir-CYrsCeua.js} +1 -1
  94. package/dist/app/assets/{elm-BaLOxH54.js → elm-BQbPKl6Y.js} +1 -1
  95. package/dist/app/assets/{erDiagram-SMLLAGMA-lphP26u7.js → erDiagram-SMLLAGMA-nIXCbdu9.js} +1 -1
  96. package/dist/app/assets/{erb-D4zKB7vm.js → erb-D8td-3qG.js} +1 -1
  97. package/dist/app/assets/{erlang-hK3qlNLz.js → erlang-CVcUIOcL.js} +1 -1
  98. package/dist/app/assets/{etlua-DmORWQ6o.js → etlua-Sp57LMlp.js} +1 -1
  99. package/dist/app/assets/{excel-formula-Dyve7tHx.js → excel-formula-C2xW1VqS.js} +1 -1
  100. package/dist/app/assets/{factor-aKN6m8fH.js → factor-B39cYmXr.js} +1 -1
  101. package/dist/app/assets/{false-CIRDgfm3.js → false-BXc89S7-.js} +1 -1
  102. package/dist/app/assets/{firestore-security-rules-D8Ht8z5e.js → firestore-security-rules-D5XHnYii.js} +1 -1
  103. package/dist/app/assets/{flow-CoMa0rFO.js → flow-DvgodFNT.js} +1 -1
  104. package/dist/app/assets/{flowDiagram-DWJPFMVM-BLg6doOr.js → flowDiagram-DWJPFMVM-BRxtHyqr.js} +1 -1
  105. package/dist/app/assets/{fortran-CN_uZJ_i.js → fortran-C2uXAnB9.js} +1 -1
  106. package/dist/app/assets/{fsharp-C9nE9g7s.js → fsharp-D4MeNJsV.js} +1 -1
  107. package/dist/app/assets/{ftl-DvqhmJFJ.js → ftl-FdK7rzYa.js} +1 -1
  108. package/dist/app/assets/{ganttDiagram-T4ZO3ILL-20MMEZeq.js → ganttDiagram-T4ZO3ILL-CxQPl5RJ.js} +1 -1
  109. package/dist/app/assets/{gap-ChJ4bKbS.js → gap-CqoRmA2e.js} +1 -1
  110. package/dist/app/assets/{gcode-D6-Q_Sls.js → gcode-Cbf6Hq0S.js} +1 -1
  111. package/dist/app/assets/{gdscript-uy9Z57J0.js → gdscript-vUATu21P.js} +1 -1
  112. package/dist/app/assets/{gedcom-DKejVBFQ.js → gedcom-Dq_MXb_u.js} +1 -1
  113. package/dist/app/assets/{gherkin-D309wbrl.js → gherkin-TnW-3H17.js} +1 -1
  114. package/dist/app/assets/{git-CXyU-4Kx.js → git-ChiXZZK3.js} +1 -1
  115. package/dist/app/assets/{gitGraphDiagram-UUTBAWPF-CdbhEKk_.js → gitGraphDiagram-UUTBAWPF-Bcj29y1k.js} +1 -1
  116. package/dist/app/assets/{glsl-CUHcECEi.js → glsl-D73MB7QA.js} +1 -1
  117. package/dist/app/assets/{gml-BYJwp8Mq.js → gml-DKKhoV5Q.js} +1 -1
  118. package/dist/app/assets/{gn-C5jDEgl-.js → gn-xteKZDbd.js} +1 -1
  119. package/dist/app/assets/{go-4DBR4Ukq.js → go-gderB942.js} +1 -1
  120. package/dist/app/assets/{go-module-BDCY5HMb.js → go-module-Cxdn5g6K.js} +1 -1
  121. package/dist/app/assets/{graph-CasqcucB.js → graph-Dr0CyUTm.js} +1 -1
  122. package/dist/app/assets/{graphql-CUOhePaJ.js → graphql-B9ESkh7V.js} +1 -1
  123. package/dist/app/assets/{groovy-C6NRtaMF.js → groovy-D46SaIaB.js} +1 -1
  124. package/dist/app/assets/{haml-CeFDFdq_.js → haml-C-gOKeM2.js} +1 -1
  125. package/dist/app/assets/{handlebars-Diav69MK.js → handlebars-WQgCAz-C.js} +1 -1
  126. package/dist/app/assets/{haskell-BRtS7ZYk.js → haskell-DZKWHhbK.js} +1 -1
  127. package/dist/app/assets/{haxe-okolorzn.js → haxe-Do6EdaWm.js} +1 -1
  128. package/dist/app/assets/{hcl-DUovHBmz.js → hcl-CW6MZD7W.js} +1 -1
  129. package/dist/app/assets/{hlsl-Est_RcA2.js → hlsl-BYgUfMru.js} +1 -1
  130. package/dist/app/assets/{hoon-BiOVdLrI.js → hoon-IqFoeyLn.js} +1 -1
  131. package/dist/app/assets/{hpkp-Bm0WuAFk.js → hpkp-BuV8JDpY.js} +1 -1
  132. package/dist/app/assets/{hsts-CbOaMMM4.js → hsts-DAvq0I49.js} +1 -1
  133. package/dist/app/assets/{http-D0tGKTH_.js → http-CCayShZc.js} +1 -1
  134. package/dist/app/assets/{ichigojam-WTyjHjN0.js → ichigojam-IQlKAhBR.js} +1 -1
  135. package/dist/app/assets/{icon-Bcw6nO7C.js → icon-C1YOMBEH.js} +1 -1
  136. package/dist/app/assets/{icu-message-format-1IVITSOw.js → icu-message-format-CbkLI-kP.js} +1 -1
  137. package/dist/app/assets/{idris-DGiKWxqv.js → idris-Db0sol3G.js} +1 -1
  138. package/dist/app/assets/{iecst-_G6fk-6o.js → iecst-Rp9pN_Ps.js} +1 -1
  139. package/dist/app/assets/{ignore-CGGRjy1I.js → ignore-DSijMN4b.js} +1 -1
  140. package/dist/app/assets/index-EzE2l0pf.css +1 -0
  141. package/dist/app/assets/{index-BnLZxiSt.js → index-izi7yD-m.js} +176 -176
  142. package/dist/app/assets/{infoDiagram-42DDH7IO-DNXFcEYI.js → infoDiagram-42DDH7IO-DP_5_HCg.js} +1 -1
  143. package/dist/app/assets/{inform7-DJNO-7Vs.js → inform7-BdTrQNcW.js} +1 -1
  144. package/dist/app/assets/{ini-BXxeA4dZ.js → ini-BL1YqQPe.js} +1 -1
  145. package/dist/app/assets/{io-CZYqA1fa.js → io-ju4qnY4R.js} +1 -1
  146. package/dist/app/assets/{ishikawaDiagram-UXIWVN3A-1FFzVMOS.js → ishikawaDiagram-UXIWVN3A-c-5weLZu.js} +1 -1
  147. package/dist/app/assets/{j-CLXGTuej.js → j-BNgG1B_8.js} +1 -1
  148. package/dist/app/assets/{java-DgCJQY9_.js → java-BBM8kPUi.js} +1 -1
  149. package/dist/app/assets/{javadoc-rf7ABQVy.js → javadoc-DzqYwIEC.js} +1 -1
  150. package/dist/app/assets/{javadoclike-BhPYSoi1.js → javadoclike-CXHyoMho.js} +1 -1
  151. package/dist/app/assets/{javascript-DOESY9kn.js → javascript-DyOtAE59.js} +1 -1
  152. package/dist/app/assets/{javastacktrace-B40tpYFc.js → javastacktrace-CfTMUgb0.js} +1 -1
  153. package/dist/app/assets/{jexl-CVSwBfWj.js → jexl-BmCWVTv_.js} +1 -1
  154. package/dist/app/assets/{jolie-CuMdzw00.js → jolie-C3BdHGrF.js} +1 -1
  155. package/dist/app/assets/{journeyDiagram-VCZTEJTY-DCh9QB_1.js → journeyDiagram-VCZTEJTY-DAKBW1_0.js} +1 -1
  156. package/dist/app/assets/{jq-rSPG4wjz.js → jq-B4eKQbVT.js} +1 -1
  157. package/dist/app/assets/{js-extras-DtC7d85t.js → js-extras-B9Um65g1.js} +1 -1
  158. package/dist/app/assets/{js-templates-BkzRtF3M.js → js-templates-B8LIGz8d.js} +1 -1
  159. package/dist/app/assets/{jsdoc-CdEDtKIx.js → jsdoc-X69feyNn.js} +1 -1
  160. package/dist/app/assets/{json-DFUISOXb.js → json-Ds9Y6npk.js} +1 -1
  161. package/dist/app/assets/{json5-DDXB8kVt.js → json5-BEpvRyGQ.js} +1 -1
  162. package/dist/app/assets/{jsonp-B6KceYOu.js → jsonp-CI2Vwglg.js} +1 -1
  163. package/dist/app/assets/{jsstacktrace-BmLmkRns.js → jsstacktrace-B_qFrkK8.js} +1 -1
  164. package/dist/app/assets/{jsx-tZerg2PH.js → jsx-C_Wki7pg.js} +1 -1
  165. package/dist/app/assets/{julia-Bc1WscpO.js → julia-CGmxtkB0.js} +1 -1
  166. package/dist/app/assets/{kanban-definition-6JOO6SKY-BG2AO71l.js → kanban-definition-6JOO6SKY-Bj8uidJb.js} +1 -1
  167. package/dist/app/assets/{keepalived-C-VxfNGq.js → keepalived-C8Mk-Wqp.js} +1 -1
  168. package/dist/app/assets/{keyman-EjQIu4mX.js → keyman-CMifeZZV.js} +1 -1
  169. package/dist/app/assets/{kotlin-CQALgAA5.js → kotlin-ogZAOqoN.js} +1 -1
  170. package/dist/app/assets/{kumir-7Nk84McD.js → kumir-BrGxaUVr.js} +1 -1
  171. package/dist/app/assets/{kusto-DaP91ut7.js → kusto-DeyIYXML.js} +1 -1
  172. package/dist/app/assets/{latex-DjQNRo9H.js → latex-DwJWQSKl.js} +1 -1
  173. package/dist/app/assets/{latte-5JEuNRoR.js → latte-DiAT5mgQ.js} +1 -1
  174. package/dist/app/assets/{layout-FVsf45l9.js → layout-Ci0rB0BF.js} +1 -1
  175. package/dist/app/assets/{less-8yUOsL09.js → less-DAct2ixG.js} +1 -1
  176. package/dist/app/assets/{lilypond-COsmQkBk.js → lilypond-CznC99Kp.js} +1 -1
  177. package/dist/app/assets/{linear-C_63YKi4.js → linear-Db4iWNSq.js} +1 -1
  178. package/dist/app/assets/{liquid--Ji9gJSD.js → liquid-BxjgrxHp.js} +1 -1
  179. package/dist/app/assets/{lisp-DuUkFEfd.js → lisp-C4lgit6G.js} +1 -1
  180. package/dist/app/assets/{livescript-Cs6PchSa.js → livescript-BEQgCon6.js} +1 -1
  181. package/dist/app/assets/{llvm-COqWFLYS.js → llvm-Xf0jCPO4.js} +1 -1
  182. package/dist/app/assets/{log-C8QHMZzv.js → log-BiVfEwum.js} +1 -1
  183. package/dist/app/assets/{lolcode-BIsqHJ6H.js → lolcode-BSO8DuGE.js} +1 -1
  184. package/dist/app/assets/{lua-Ds7uGUxB.js → lua-DGW916x5.js} +1 -1
  185. package/dist/app/assets/{magma-DLHoFFMW.js → magma-OhptpZ13.js} +1 -1
  186. package/dist/app/assets/{makefile-CW_5azpn.js → makefile-DBnxpcUU.js} +1 -1
  187. package/dist/app/assets/{markdown-wU5DnlD5.js → markdown-BznySwma.js} +1 -1
  188. package/dist/app/assets/{markup-BjK1nSyh.js → markup-DqRz3LJm.js} +1 -1
  189. package/dist/app/assets/{markup-templating-CfGV0lcD.js → markup-templating-BKB_GGuz.js} +1 -1
  190. package/dist/app/assets/{matlab-Bs2eP0LD.js → matlab-3N0TcL6N.js} +1 -1
  191. package/dist/app/assets/{maxscript-D8jwXiPi.js → maxscript-BZvlaoGH.js} +1 -1
  192. package/dist/app/assets/{mel-Cmbsj11e.js → mel-BSmK0T7H.js} +1 -1
  193. package/dist/app/assets/{mermaid-C-cxdm_P.js → mermaid-Duc2qb5F.js} +1 -1
  194. package/dist/app/assets/{min-BctQ8xDj.js → min-BKNYKdIk.js} +1 -1
  195. package/dist/app/assets/{mindmap-definition-QFDTVHPH-DHcgEjW6.js → mindmap-definition-QFDTVHPH-CnWL0xVD.js} +1 -1
  196. package/dist/app/assets/{mizar-Ca1dbNOh.js → mizar-BI02SHrx.js} +1 -1
  197. package/dist/app/assets/{mongodb-BocaDOlW.js → mongodb-CRQm09Xn.js} +1 -1
  198. package/dist/app/assets/{monkey-BLhpedmj.js → monkey-Dv34nuh4.js} +1 -1
  199. package/dist/app/assets/{moonscript-CElpz-Ug.js → moonscript-50xJ2oId.js} +1 -1
  200. package/dist/app/assets/{n1ql-CwNqjlWA.js → n1ql-Cm4qd43r.js} +1 -1
  201. package/dist/app/assets/{n4js-B1i6cZX9.js → n4js-LXxDuAtT.js} +1 -1
  202. package/dist/app/assets/{nand2tetris-hdl-DO01eHXa.js → nand2tetris-hdl-CkSPhEoK.js} +1 -1
  203. package/dist/app/assets/{naniscript-C86I87cR.js → naniscript-CopSq9dX.js} +1 -1
  204. package/dist/app/assets/{nasm-X9SuO04-.js → nasm-D7A7rGAF.js} +1 -1
  205. package/dist/app/assets/{neon-Cb3VrB_2.js → neon-BAKsC02_.js} +1 -1
  206. package/dist/app/assets/{nevod-BiEf92s6.js → nevod-C-euYOSr.js} +1 -1
  207. package/dist/app/assets/{nginx-CUAldmyK.js → nginx-B9jALad5.js} +1 -1
  208. package/dist/app/assets/{nim-CicsGaXu.js → nim-BBHZHQ5E.js} +1 -1
  209. package/dist/app/assets/{nix-CqX4i_yR.js → nix-DmfkvvNO.js} +1 -1
  210. package/dist/app/assets/{nsis-TyCoq1Up.js → nsis-CiSC6aDO.js} +1 -1
  211. package/dist/app/assets/{objectivec-COzECw8M.js → objectivec-CZ2ovZFJ.js} +1 -1
  212. package/dist/app/assets/{ocaml-CouJ1SZ_.js → ocaml-CyX9uBPK.js} +1 -1
  213. package/dist/app/assets/{opencl-BNCeQsDQ.js → opencl-BSrZYM8c.js} +1 -1
  214. package/dist/app/assets/{openqasm-DX-rtDDv.js → openqasm-DOuul9tf.js} +1 -1
  215. package/dist/app/assets/{oz-CAFaEfY9.js → oz-rsJy_2_r.js} +1 -1
  216. package/dist/app/assets/{parigp-DTj7bCjF.js → parigp-DMZs3sMP.js} +1 -1
  217. package/dist/app/assets/{parser-Dw8xYjDE.js → parser-CLeK_wYt.js} +1 -1
  218. package/dist/app/assets/{pascal-rnwnKrYC.js → pascal-DZ4qTuqN.js} +1 -1
  219. package/dist/app/assets/{pascaligo-x1XdfDyr.js → pascaligo-D6ziPQJn.js} +1 -1
  220. package/dist/app/assets/{pcaxis-2ZAgxxTO.js → pcaxis-Bsa4kJ1N.js} +1 -1
  221. package/dist/app/assets/{peoplecode-pTltM-sq.js → peoplecode-BtULIv-H.js} +1 -1
  222. package/dist/app/assets/{perl-CdAlw2Ho.js → perl-CswAAlfX.js} +1 -1
  223. package/dist/app/assets/{php-C2mFD2oC.js → php-Bv-ALqgC.js} +1 -1
  224. package/dist/app/assets/{php-extras-D7Zt-ImZ.js → php-extras-CGQHigyg.js} +1 -1
  225. package/dist/app/assets/{phpdoc-C1kmfh9i.js → phpdoc-CbRxSWh6.js} +1 -1
  226. package/dist/app/assets/{pieDiagram-DEJITSTG-B_eQU9Uk.js → pieDiagram-DEJITSTG-VWWiVQxO.js} +1 -1
  227. package/dist/app/assets/{plsql-Im5gOG9c.js → plsql-DQRexRDV.js} +1 -1
  228. package/dist/app/assets/{powerquery-poq2eyPm.js → powerquery-B84pC27o.js} +1 -1
  229. package/dist/app/assets/{powershell-DJ56nmEi.js → powershell-CYB8PDOS.js} +1 -1
  230. package/dist/app/assets/{processing-Bn-H7mMf.js → processing-IV7AOKMt.js} +1 -1
  231. package/dist/app/assets/{prolog-BCb-6dWU.js → prolog-C5Umzi6Y.js} +1 -1
  232. package/dist/app/assets/{promql-CtbjoMKF.js → promql-DnQb00nJ.js} +1 -1
  233. package/dist/app/assets/{properties-CU4TDD4l.js → properties-JtX62kym.js} +1 -1
  234. package/dist/app/assets/{protobuf-_Q2Yj86k.js → protobuf-D0u54vfT.js} +1 -1
  235. package/dist/app/assets/{psl-DqN21NC_.js → psl-D2wfxc3N.js} +1 -1
  236. package/dist/app/assets/{pug-DAgKMecD.js → pug-Cfscfbjt.js} +1 -1
  237. package/dist/app/assets/{puppet-Cc2ljXH1.js → puppet-DTE3iXOW.js} +1 -1
  238. package/dist/app/assets/{pure-B0x_E1bn.js → pure-YKO-tWRN.js} +1 -1
  239. package/dist/app/assets/{purebasic-DcsxzNqC.js → purebasic-BjxfhqXa.js} +1 -1
  240. package/dist/app/assets/{purescript-Cc11iskN.js → purescript-BYtsXeuA.js} +1 -1
  241. package/dist/app/assets/{q-SRKQXeFP.js → q-BGBZJwiX.js} +1 -1
  242. package/dist/app/assets/{qml-COWYdH0A.js → qml-DTmpu0_b.js} +1 -1
  243. package/dist/app/assets/{qore-AdoWA6sw.js → qore-DV3zUzln.js} +1 -1
  244. package/dist/app/assets/{qsharp-k5lgGfSV.js → qsharp-BB4ZU4l7.js} +1 -1
  245. package/dist/app/assets/{quadrantDiagram-34T5L4WZ-U_BUH870.js → quadrantDiagram-34T5L4WZ-DZe4FQWm.js} +1 -1
  246. package/dist/app/assets/{r-Bmcjr3EC.js → r-BuRdYuOg.js} +1 -1
  247. package/dist/app/assets/{racket-506ZDFuM.js → racket-BdOLCXmL.js} +1 -1
  248. package/dist/app/assets/{reason-BngsaqkW.js → reason-BCIhgqTr.js} +1 -1
  249. package/dist/app/assets/{regex-BC6jlFZr.js → regex-CeDcXiBn.js} +1 -1
  250. package/dist/app/assets/{rego-BYCQ91X3.js → rego-Bug6Gtky.js} +1 -1
  251. package/dist/app/assets/{renpy-D95h89N9.js → renpy-C1LtsjtW.js} +1 -1
  252. package/dist/app/assets/{requirementDiagram-MS252O5E-CWAV9Lki.js → requirementDiagram-MS252O5E-BYaMMinK.js} +1 -1
  253. package/dist/app/assets/{rest-DiYuUdld.js → rest-Fa9SyY67.js} +1 -1
  254. package/dist/app/assets/{rip-B1Ip8kd2.js → rip-SetkIYoC.js} +1 -1
  255. package/dist/app/assets/{roboconf-DHaw-Q3G.js → roboconf-CRy7RXFK.js} +1 -1
  256. package/dist/app/assets/{robotframework-HN9oBCJd.js → robotframework-DHo4R8pp.js} +1 -1
  257. package/dist/app/assets/{ruby-C42HzAMc.js → ruby-DM2JwZlW.js} +1 -1
  258. package/dist/app/assets/{rust-DJdUDgl0.js → rust-_NNFafik.js} +1 -1
  259. package/dist/app/assets/{sankeyDiagram-XADWPNL6-DzoDqMzU.js → sankeyDiagram-XADWPNL6-DAunyA-1.js} +1 -1
  260. package/dist/app/assets/{sas-EmHkISJg.js → sas-CAllZx8n.js} +1 -1
  261. package/dist/app/assets/{sass-BEWMjvc2.js → sass-Hf4UBtzK.js} +1 -1
  262. package/dist/app/assets/{scala-Y9l-QmB_.js → scala-DkNiERTA.js} +1 -1
  263. package/dist/app/assets/{scheme-oQH0YeM4.js → scheme-cRBlcCac.js} +1 -1
  264. package/dist/app/assets/{scss-DDqkkzfA.js → scss-D8mZ_Za-.js} +1 -1
  265. package/dist/app/assets/{sequenceDiagram-FGHM5R23-BRWyyuf5.js → sequenceDiagram-FGHM5R23-sNXmL4Cw.js} +1 -1
  266. package/dist/app/assets/{shell-session-DUtkYnuZ.js → shell-session-DeKXiekb.js} +1 -1
  267. package/dist/app/assets/{smali-CQN_R6JD.js → smali-DBMpR0WA.js} +1 -1
  268. package/dist/app/assets/{smalltalk-C5vveBjr.js → smalltalk-BPhQ9s3z.js} +1 -1
  269. package/dist/app/assets/{smarty-BF9avlDB.js → smarty-BMg06VgP.js} +1 -1
  270. package/dist/app/assets/{sml-C_smEF_i.js → sml-DLGSWP51.js} +1 -1
  271. package/dist/app/assets/{solidity-CsmKUFUp.js → solidity-DeQT3dsc.js} +1 -1
  272. package/dist/app/assets/{solution-file-5OHlEmXf.js → solution-file-rfNIkT7V.js} +1 -1
  273. package/dist/app/assets/{soy-DHS0rtw_.js → soy-zYtC6_ht.js} +1 -1
  274. package/dist/app/assets/{sparql-BxBq3H35.js → sparql-CGa1CKp5.js} +1 -1
  275. package/dist/app/assets/{splunk-spl-C8VgtuYE.js → splunk-spl-C8v7uxfM.js} +1 -1
  276. package/dist/app/assets/{sqf-hSDek24H.js → sqf-DPaz1Lai.js} +1 -1
  277. package/dist/app/assets/{sql-DYgxUZFA.js → sql-CRZBr2wA.js} +1 -1
  278. package/dist/app/assets/{squirrel-C7uGEJgW.js → squirrel-CrbdCeO4.js} +1 -1
  279. package/dist/app/assets/{stan-CGYqPG3F.js → stan-BKYvxpSb.js} +1 -1
  280. package/dist/app/assets/{stateDiagram-FHFEXIEX-Dj_QL8hp.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-BCrv-hm1.js → stylus-Ci4_F8nK.js} +1 -1
  283. package/dist/app/assets/{swift-3XnbN5uB.js → swift-mmkHLTYT.js} +1 -1
  284. package/dist/app/assets/{systemd-DzUq_PeH.js → systemd-DAUIxyR2.js} +1 -1
  285. package/dist/app/assets/{t4-cs-DaXmHhdA.js → t4-cs-BED2tz-u.js} +1 -1
  286. package/dist/app/assets/{t4-templating-C1pqdj2v.js → t4-templating--ieaosVt.js} +1 -1
  287. package/dist/app/assets/{t4-vb-4wqP1_sy.js → t4-vb-Dq0Puemw.js} +1 -1
  288. package/dist/app/assets/{tap-FHe0A6pH.js → tap-C_XPd1SR.js} +1 -1
  289. package/dist/app/assets/{tcl-DlumdfOH.js → tcl-DJZd1oZX.js} +1 -1
  290. package/dist/app/assets/{textile-BmxrCmib.js → textile-wcSaXbdv.js} +1 -1
  291. package/dist/app/assets/{timeline-definition-GMOUNBTQ-BcI-XOle.js → timeline-definition-GMOUNBTQ-BewoZYzR.js} +1 -1
  292. package/dist/app/assets/{toml-BngAbTT7.js → toml-CKDZZOrE.js} +1 -1
  293. package/dist/app/assets/{tremor-BoVxotcN.js → tremor-B1-Zw3yS.js} +1 -1
  294. package/dist/app/assets/{tt2-BoBfCiJa.js → tt2-BHFaXCZF.js} +1 -1
  295. package/dist/app/assets/{turtle-CJfK17BD.js → turtle-KSw4upem.js} +1 -1
  296. package/dist/app/assets/{twig-BoM58FfM.js → twig-BRBoP8KB.js} +1 -1
  297. package/dist/app/assets/{typescript-BU7mQ9Me.js → typescript-bns4dUtY.js} +1 -1
  298. package/dist/app/assets/{typoscript-BQMBCyle.js → typoscript-BVmk6GiM.js} +1 -1
  299. package/dist/app/assets/{unrealscript-Bly1rszO.js → unrealscript-hTYhevmS.js} +1 -1
  300. package/dist/app/assets/{uorazor-AR6v804j.js → uorazor-BY_i1glx.js} +1 -1
  301. package/dist/app/assets/{uri-DQN5AlR9.js → uri-Cshg9KEA.js} +1 -1
  302. package/dist/app/assets/{v-CzlNjPFF.js → v-2HZBfvBQ.js} +1 -1
  303. package/dist/app/assets/{vala-D4j-TYUj.js → vala-DpwXQy33.js} +1 -1
  304. package/dist/app/assets/{vbnet-BO_zrLTA.js → vbnet-CzcanlBM.js} +1 -1
  305. package/dist/app/assets/{velocity-D14EQjuJ.js → velocity-CV3Erd1R.js} +1 -1
  306. package/dist/app/assets/{vennDiagram-DHZGUBPP-Ct-BJj4e.js → vennDiagram-DHZGUBPP-CYp9O0hw.js} +1 -1
  307. package/dist/app/assets/{verilog-8HBCyzJW.js → verilog-DUFfdhmC.js} +1 -1
  308. package/dist/app/assets/{vhdl-CABoGFHh.js → vhdl-Ehst2swj.js} +1 -1
  309. package/dist/app/assets/{vim-BqejDUiH.js → vim-ChBxD9-s.js} +1 -1
  310. package/dist/app/assets/{visual-basic-BBFqe9IH.js → visual-basic-DhxNPprf.js} +1 -1
  311. package/dist/app/assets/{wardley-RL74JXVD-DF76BHVV.js → wardley-RL74JXVD-ChpRMv2u.js} +1 -1
  312. package/dist/app/assets/{wardleyDiagram-NUSXRM2D-tb9-DpEL.js → wardleyDiagram-NUSXRM2D-CFpThRE-.js} +1 -1
  313. package/dist/app/assets/{warpscript-D8JsH2aH.js → warpscript-Dx1Itmpb.js} +1 -1
  314. package/dist/app/assets/{wasm-usuPS3UI.js → wasm-BvTc7Cyo.js} +1 -1
  315. package/dist/app/assets/{web-idl-CtjhIrn5.js → web-idl-B43dy8xT.js} +1 -1
  316. package/dist/app/assets/{wiki-nE7oYJAm.js → wiki-C0vje4IO.js} +1 -1
  317. package/dist/app/assets/{wolfram-BpCCg-Fp.js → wolfram-B1twTrAy.js} +1 -1
  318. package/dist/app/assets/{wren-Dtkpodh6.js → wren-CpwJ20dT.js} +1 -1
  319. package/dist/app/assets/{xeora-BpTlDPdY.js → xeora-Q9elMskQ.js} +1 -1
  320. package/dist/app/assets/{xml-doc-CcDifcyn.js → xml-doc-eO6FH-U3.js} +1 -1
  321. package/dist/app/assets/{xojo-O-0SvFwZ.js → xojo-1Fr7QqPR.js} +1 -1
  322. package/dist/app/assets/{xquery-UAB2jKQB.js → xquery-BMmMoA1b.js} +1 -1
  323. package/dist/app/assets/{xychartDiagram-5P7HB3ND-d6FXhzUl.js → xychartDiagram-5P7HB3ND-De8Xu1fj.js} +1 -1
  324. package/dist/app/assets/{yaml-eCAjf2lJ.js → yaml-34lcFD2P.js} +1 -1
  325. package/dist/app/assets/{yang-BkCZ0omw.js → yang-DervT_oZ.js} +1 -1
  326. package/dist/app/assets/{zig-DEIPVEHz.js → zig-Cipb22UI.js} +1 -1
  327. package/dist/app/index.html +2 -2
  328. package/dist/index.cjs +2298 -648
  329. package/dist/index.js +2319 -650
  330. package/package.json +4 -4
  331. package/dist/app/assets/channel-SVZNtrjN.js +0 -1
  332. package/dist/app/assets/classDiagram-6PBFFD2Q-BiMmE_Ro.js +0 -1
  333. package/dist/app/assets/classDiagram-v2-HSJHXN6E-BiMmE_Ro.js +0 -1
  334. package/dist/app/assets/clone-E2Stvins.js +0 -1
  335. package/dist/app/assets/index-D58ynlvg.css +0 -1
  336. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-BJgU_5Se.js +0 -1
package/dist/index.cjs CHANGED
@@ -66,8 +66,8 @@ __export(index_exports, {
66
66
  module.exports = __toCommonJS(index_exports);
67
67
 
68
68
  // src/components/chat.tsx
69
- var React23 = __toESM(require("react"), 1);
70
- var import_lucide_react12 = require("lucide-react");
69
+ var React26 = __toESM(require("react"), 1);
70
+ var import_lucide_react15 = require("lucide-react");
71
71
 
72
72
  // src/lib/utils.ts
73
73
  var import_clsx = require("clsx");
@@ -681,6 +681,10 @@ function ParentMessengerProvider({
681
681
  }
682
682
  return;
683
683
  }
684
+ const requestHumanInput = params.planMode === true || params.state?.[import_chatkit_types2.STATE_VARIABLE_HUMAN]?.planMode === true ? {
685
+ ...humanInput,
686
+ planMode: true
687
+ } : humanInput;
684
688
  const newMessage = {
685
689
  id: createMessageId(),
686
690
  type: "human",
@@ -694,11 +698,11 @@ function ParentMessengerProvider({
694
698
  const requestOptions = buildInjectedRequestOptions({
695
699
  defaults: latestOptionsRef.current?.request,
696
700
  state: params.state,
697
- humanInput
701
+ humanInput: requestHumanInput
698
702
  });
699
703
  stream?.submit(
700
704
  {
701
- input: humanInput,
705
+ input: requestHumanInput,
702
706
  ...requestOptions.state ? { state: requestOptions.state } : {}
703
707
  },
704
708
  {
@@ -1154,8 +1158,22 @@ var en_US_default = {
1154
1158
  composer: {
1155
1159
  openMenu: "Open menu",
1156
1160
  addAttachment: "Add attachment",
1161
+ planMode: "Plan mode",
1157
1162
  removeReference: "Remove reference",
1158
- quoteSelection: "Quote selection"
1163
+ quoteSelection: "Quote selection",
1164
+ requestUserInput: {
1165
+ title: "Input requested",
1166
+ recommended: "Recommended",
1167
+ other: "Other",
1168
+ otherPlaceholder: "Type a custom answer",
1169
+ continue: "Continue",
1170
+ dismiss: "Dismiss",
1171
+ previousQuestion: "Previous question",
1172
+ nextQuestion: "Next question",
1173
+ questionProgress: "{{current}} of {{total}}",
1174
+ optionInfo: "Details for {{label}}",
1175
+ submit: "Continue"
1176
+ }
1159
1177
  },
1160
1178
  sheet: {
1161
1179
  close: "Close"
@@ -1182,7 +1200,58 @@ var en_US_default = {
1182
1200
  reasoning: "Reasoning",
1183
1201
  loading: "Loading",
1184
1202
  thinking: "Thinking",
1185
- answering: "Answering"
1203
+ answering: "Answering",
1204
+ requestUserInputResult: {
1205
+ title: "Selections confirmed",
1206
+ option: "Option",
1207
+ other: "Other"
1208
+ },
1209
+ toolGroup: {
1210
+ status: {
1211
+ running: "Processing",
1212
+ success: "Processed",
1213
+ fail: "Processing failed"
1214
+ },
1215
+ inputTitle: "Input",
1216
+ outputTitle: "Output",
1217
+ errorTitle: "Error",
1218
+ jsonTitle: "JSON",
1219
+ jsonTree: "Tree",
1220
+ jsonRaw: "Raw",
1221
+ copy: "Copy",
1222
+ copied: "Copied",
1223
+ separator: ", ",
1224
+ categories: {
1225
+ files: {
1226
+ one: "{{count}} file",
1227
+ other: "{{count}} files"
1228
+ },
1229
+ searches: {
1230
+ one: "{{count}} search",
1231
+ other: "{{count}} searches"
1232
+ },
1233
+ commands: {
1234
+ one: "{{count}} command",
1235
+ other: "{{count}} commands"
1236
+ },
1237
+ lists: {
1238
+ one: "{{count}} list",
1239
+ other: "{{count}} lists"
1240
+ },
1241
+ tasks: {
1242
+ one: "{{count}} task",
1243
+ other: "{{count}} tasks"
1244
+ },
1245
+ knowledges: {
1246
+ one: "{{count}} knowledge result",
1247
+ other: "{{count}} knowledge results"
1248
+ },
1249
+ tools: {
1250
+ one: "{{count}} tool",
1251
+ other: "{{count}} tools"
1252
+ }
1253
+ }
1254
+ }
1186
1255
  }
1187
1256
  };
1188
1257
 
@@ -1261,8 +1330,22 @@ var zh_CN_default = {
1261
1330
  composer: {
1262
1331
  openMenu: "\u6253\u5F00\u83DC\u5355",
1263
1332
  addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
1333
+ planMode: "\u8BA1\u5212\u6A21\u5F0F",
1264
1334
  removeReference: "\u79FB\u9664\u5F15\u7528",
1265
- quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
1335
+ quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9",
1336
+ requestUserInput: {
1337
+ title: "\u9700\u8981\u4F60\u7684\u8F93\u5165",
1338
+ recommended: "\u63A8\u8350",
1339
+ other: "\u5176\u4ED6",
1340
+ otherPlaceholder: "\u8F93\u5165\u81EA\u5B9A\u4E49\u56DE\u7B54",
1341
+ continue: "\u7EE7\u7EED",
1342
+ dismiss: "\u5173\u95ED",
1343
+ previousQuestion: "\u4E0A\u4E00\u4E2A\u95EE\u9898",
1344
+ nextQuestion: "\u4E0B\u4E00\u4E2A\u95EE\u9898",
1345
+ questionProgress: "{{current}} / {{total}}",
1346
+ optionInfo: "{{label}} \u7684\u8BF4\u660E",
1347
+ submit: "\u7EE7\u7EED"
1348
+ }
1266
1349
  },
1267
1350
  sheet: {
1268
1351
  close: "\u5173\u95ED"
@@ -1289,7 +1372,58 @@ var zh_CN_default = {
1289
1372
  reasoning: "\u63A8\u7406",
1290
1373
  loading: "\u6B63\u5728\u52A0\u8F7D",
1291
1374
  thinking: "\u6B63\u5728\u601D\u8003",
1292
- answering: "\u6B63\u5728\u751F\u6210"
1375
+ answering: "\u6B63\u5728\u751F\u6210",
1376
+ requestUserInputResult: {
1377
+ title: "\u5DF2\u786E\u8BA4\u9009\u62E9",
1378
+ option: "\u9009\u9879",
1379
+ other: "\u5176\u4ED6"
1380
+ },
1381
+ toolGroup: {
1382
+ status: {
1383
+ running: "\u6B63\u5728\u5904\u7406",
1384
+ success: "\u5DF2\u5904\u7406",
1385
+ fail: "\u5904\u7406\u5931\u8D25"
1386
+ },
1387
+ inputTitle: "\u8F93\u5165",
1388
+ outputTitle: "\u8F93\u51FA",
1389
+ errorTitle: "\u9519\u8BEF",
1390
+ jsonTitle: "JSON",
1391
+ jsonTree: "\u6811\u5F62",
1392
+ jsonRaw: "\u539F\u59CB",
1393
+ copy: "\u590D\u5236",
1394
+ copied: "\u5DF2\u590D\u5236",
1395
+ separator: "\uFF0C",
1396
+ categories: {
1397
+ files: {
1398
+ one: "{{count}} \u4E2A\u6587\u4EF6",
1399
+ other: "{{count}} \u4E2A\u6587\u4EF6"
1400
+ },
1401
+ searches: {
1402
+ one: "{{count}} \u4E2A\u641C\u7D22",
1403
+ other: "{{count}} \u4E2A\u641C\u7D22"
1404
+ },
1405
+ commands: {
1406
+ one: "{{count}} \u4E2A\u547D\u4EE4",
1407
+ other: "{{count}} \u4E2A\u547D\u4EE4"
1408
+ },
1409
+ lists: {
1410
+ one: "{{count}} \u4E2A\u5217\u8868",
1411
+ other: "{{count}} \u4E2A\u5217\u8868"
1412
+ },
1413
+ tasks: {
1414
+ one: "{{count}} \u4E2A\u4EFB\u52A1",
1415
+ other: "{{count}} \u4E2A\u4EFB\u52A1"
1416
+ },
1417
+ knowledges: {
1418
+ one: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C",
1419
+ other: "{{count}} \u4E2A\u77E5\u8BC6\u7ED3\u679C"
1420
+ },
1421
+ tools: {
1422
+ one: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528",
1423
+ other: "{{count}} \u4E2A\u5DE5\u5177\u8C03\u7528"
1424
+ }
1425
+ }
1426
+ }
1293
1427
  }
1294
1428
  };
1295
1429
 
@@ -1725,6 +1859,8 @@ function ComposerMenu({
1725
1859
  onAttachmentClick,
1726
1860
  onToolSelect,
1727
1861
  selectedTool,
1862
+ planModeEnabled = false,
1863
+ onPlanModeChange,
1728
1864
  disabled = false
1729
1865
  }) {
1730
1866
  const { t } = useChatkitTranslation();
@@ -1733,9 +1869,6 @@ function ComposerMenu({
1733
1869
  const roundedClass = getRoundedClass(theme.radius);
1734
1870
  const attachmentsEnabled = composer?.attachments?.enabled ?? false;
1735
1871
  const tools = composer?.tools ?? [];
1736
- if (!attachmentsEnabled && tools.length === 0) {
1737
- return null;
1738
- }
1739
1872
  const handleAttachmentClick = () => {
1740
1873
  onAttachmentClick?.();
1741
1874
  setOpen(false);
@@ -1744,6 +1877,9 @@ function ComposerMenu({
1744
1877
  onToolSelect?.(tool);
1745
1878
  setOpen(false);
1746
1879
  };
1880
+ const handlePlanModeToggle = () => {
1881
+ onPlanModeChange?.(!planModeEnabled);
1882
+ };
1747
1883
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Popover, { open, onOpenChange: setOpen, children: [
1748
1884
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1749
1885
  Button,
@@ -1783,8 +1919,46 @@ function ComposerMenu({
1783
1919
  ]
1784
1920
  }
1785
1921
  ),
1786
- tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" })
1922
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" })
1787
1923
  ] }),
1924
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1925
+ "button",
1926
+ {
1927
+ type: "button",
1928
+ role: "switch",
1929
+ "aria-checked": planModeEnabled,
1930
+ onClick: handlePlanModeToggle,
1931
+ className: cn(
1932
+ "flex items-center gap-3 px-3 py-2 text-sm hover:bg-muted transition-colors",
1933
+ roundedClass,
1934
+ planModeEnabled && "bg-muted"
1935
+ ),
1936
+ children: [
1937
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "flex h-6 w-6 items-center justify-center text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.ListChecks, { size: 16 }) }),
1938
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "min-w-0 flex-1 text-left", children: t("composer.planMode") }),
1939
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1940
+ "span",
1941
+ {
1942
+ className: cn(
1943
+ "relative inline-flex h-6 w-10 shrink-0 items-center rounded-full transition-colors",
1944
+ planModeEnabled ? "bg-primary" : "bg-muted-foreground/20"
1945
+ ),
1946
+ "aria-hidden": "true",
1947
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1948
+ "span",
1949
+ {
1950
+ className: cn(
1951
+ "inline-block h-5 w-5 rounded-full bg-background shadow-sm transition-transform",
1952
+ planModeEnabled ? "translate-x-[18px]" : "translate-x-0.5"
1953
+ )
1954
+ }
1955
+ )
1956
+ }
1957
+ )
1958
+ ]
1959
+ }
1960
+ ),
1961
+ tools.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "my-1 h-px bg-border" }),
1788
1962
  tools.map((tool) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1789
1963
  "button",
1790
1964
  {
@@ -2107,19 +2281,23 @@ function HistorySidebar({
2107
2281
  setOpen(false);
2108
2282
  };
2109
2283
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Sheet, { open, onOpenChange: setOpen, children: [
2110
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2111
- Button,
2112
- {
2113
- variant: "ghost",
2114
- size: "icon",
2115
- disabled,
2116
- className: "h-8 w-8 cursor-pointer",
2117
- children: [
2118
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.History, { size: 16 }),
2119
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sr-only", children: t("history.threadHistory") })
2120
- ]
2121
- }
2122
- ) }),
2284
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Tooltip, { children: [
2285
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2286
+ Button,
2287
+ {
2288
+ variant: "ghost",
2289
+ size: "icon",
2290
+ disabled,
2291
+ className: "h-8 w-8 cursor-pointer",
2292
+ "aria-label": t("history.threadHistory"),
2293
+ children: [
2294
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.History, { size: 16 }),
2295
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sr-only", children: t("history.threadHistory") })
2296
+ ]
2297
+ }
2298
+ ) }) }) }),
2299
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipContent, { side: "bottom", children: t("history.threadHistory") })
2300
+ ] }),
2123
2301
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SheetContent, { side: "right", className: "w-80 p-0", children: [
2124
2302
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTitle, { children: t("history.title") }) }),
2125
2303
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
@@ -2583,163 +2761,781 @@ function PendingTodos({
2583
2761
  );
2584
2762
  }
2585
2763
 
2586
- // src/components/thread/messages/ai.tsx
2587
- var React16 = __toESM(require("react"), 1);
2588
- var import_lucide_react9 = require("lucide-react");
2589
-
2590
- // src/components/ui/badge.tsx
2764
+ // src/components/composer/request-user-input-panel.tsx
2591
2765
  var React12 = __toESM(require("react"), 1);
2766
+ var import_lucide_react7 = require("lucide-react");
2592
2767
  var import_jsx_runtime14 = require("react/jsx-runtime");
2593
- var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
2594
- var variants = {
2595
- default: "bg-primary text-primary-foreground",
2596
- secondary: "bg-secondary text-secondary-foreground",
2597
- outline: "border-input text-foreground"
2598
- };
2599
- var Badge = React12.forwardRef(
2600
- ({ className, variant = "default", ...props }, ref) => {
2601
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { ref, className: cn(base, variants[variant], className), ...props });
2602
- }
2603
- );
2604
- Badge.displayName = "Badge";
2605
-
2606
- // src/components/ui/card.tsx
2607
- var React13 = __toESM(require("react"), 1);
2608
- var import_jsx_runtime15 = require("react/jsx-runtime");
2609
- var Card = React13.forwardRef(
2610
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2611
- "div",
2612
- {
2613
- ref,
2614
- className: cn(
2615
- "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
2616
- className
2617
- ),
2618
- ...props
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"
2619
2819
  }
2620
- )
2621
- );
2622
- Card.displayName = "Card";
2623
- var CardHeader = React13.forwardRef(
2624
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
2625
- );
2626
- CardHeader.displayName = "CardHeader";
2627
- var CardTitle = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
2628
- CardTitle.displayName = "CardTitle";
2629
- var CardDescription = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
2630
- CardDescription.displayName = "CardDescription";
2631
- var CardContent = React13.forwardRef(
2632
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("px-6 pb-6", className), ...props })
2633
- );
2634
- CardContent.displayName = "CardContent";
2635
- var CardFooter = React13.forwardRef(
2636
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
2637
- );
2638
- CardFooter.displayName = "CardFooter";
2639
- var CardAction = React13.forwardRef(
2640
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
2641
- );
2642
- CardAction.displayName = "CardAction";
2643
-
2644
- // src/components/ui/tabs.tsx
2645
- var React14 = __toESM(require("react"), 1);
2646
- var import_jsx_runtime16 = require("react/jsx-runtime");
2647
- var TabsContext = React14.createContext(null);
2648
- function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
2649
- const [internalValue, setInternalValue] = React14.useState(defaultValue ?? "");
2650
- const activeValue = value ?? internalValue;
2651
- const setValue = React14.useCallback(
2652
- (nextValue) => {
2653
- if (value === void 0) setInternalValue(nextValue);
2654
- onValueChange?.(nextValue);
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
+ };
2866
+ }
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)
2904
+ );
2905
+ }, [questions.length]);
2906
+ const setQuestionDraft = React12.useCallback(
2907
+ (questionId, draft) => {
2908
+ setDrafts((previous) => ({
2909
+ ...previous,
2910
+ [questionId]: draft
2911
+ }));
2655
2912
  },
2656
- [onValueChange, value]
2913
+ []
2657
2914
  );
2658
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn("w-full", className), ...props }) });
2659
- }
2660
- var TabsList = React14.forwardRef(
2661
- ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2662
- "div",
2663
- {
2664
- ref,
2665
- className: cn(
2666
- "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
2667
- className
2668
- ),
2669
- role: "tablist",
2670
- ...props
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;
2671
3033
  }
2672
- )
2673
- );
2674
- TabsList.displayName = "TabsList";
2675
- var TabsTrigger = React14.forwardRef(
2676
- ({ className, value, onClick, ...props }, ref) => {
2677
- const context = React14.useContext(TabsContext);
2678
- if (!context) {
2679
- throw new Error("TabsTrigger must be used within Tabs");
3034
+ if (canSubmit) {
3035
+ onSubmit(answers);
3036
+ return;
2680
3037
  }
2681
- const isActive = context.value === value;
2682
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2683
- "button",
2684
- {
2685
- ref,
2686
- type: "button",
2687
- role: "tab",
2688
- "aria-selected": isActive,
2689
- "data-state": isActive ? "active" : "inactive",
2690
- className: cn(
2691
- "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
2692
- className
2693
- ),
2694
- onClick: (event) => {
2695
- context.setValue(value);
2696
- onClick?.(event);
2697
- },
2698
- ...props
2699
- }
3038
+ const firstMissingIndex = questions.findIndex(
3039
+ (question) => !getAnswerForQuestion(question, drafts[question.id])
2700
3040
  );
2701
- }
2702
- );
2703
- TabsTrigger.displayName = "TabsTrigger";
2704
- var TabsContent = React14.forwardRef(
2705
- ({ className, value, ...props }, ref) => {
2706
- const context = React14.useContext(TabsContext);
2707
- if (!context) {
2708
- throw new Error("TabsContent must be used within Tabs");
3041
+ if (firstMissingIndex >= 0) {
3042
+ goToQuestion(firstMissingIndex);
2709
3043
  }
2710
- if (context.value !== value) return null;
2711
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2712
- "div",
2713
- {
2714
- ref,
2715
- role: "tabpanel",
2716
- className: cn(
2717
- "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
2718
- className
2719
- ),
2720
- ...props
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;
2721
3068
  }
2722
- );
2723
- }
2724
- );
2725
- TabsContent.displayName = "TabsContent";
2726
-
2727
- // src/components/thread/markdown-text.tsx
2728
- var import_react_markdown = __toESM(require("react-markdown"), 1);
2729
- var import_remark_gfm = __toESM(require("remark-gfm"), 1);
2730
- var import_rehype_katex = __toESM(require("rehype-katex"), 1);
2731
- var import_remark_math = __toESM(require("remark-math"), 1);
2732
- var import_react6 = require("react");
2733
- var import_lucide_react8 = require("lucide-react");
2734
-
2735
- // src/components/thread/syntax-highlighter.tsx
2736
- var import_react_syntax_highlighter = require("react-syntax-highlighter");
2737
- var import_tsx = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/tsx"), 1);
2738
- var import_python = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/python"), 1);
2739
- var import_prism = require("react-syntax-highlighter/dist/cjs/styles/prism");
2740
- var import_react4 = require("react");
2741
- var import_jsx_runtime17 = require("react/jsx-runtime");
2742
- import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("js", import_tsx.default);
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__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
3144
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "min-w-0", children: [
3145
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ChevronLeft, { className: rounded.density.pagerIcon })
3186
+ }
3187
+ ),
3188
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "min-w-12 text-center", children: t("composer.requestUserInput.questionProgress", {
3189
+ current: currentQuestionIndex + 1,
3190
+ total: questions.length
3191
+ }) }),
3192
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ChevronRight, { className: rounded.density.pagerIcon })
3204
+ }
3205
+ )
3206
+ ]
3207
+ }
3208
+ ) : null
3209
+ ] }),
3210
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("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__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3237
+ optionIndex + 1,
3238
+ "."
3239
+ ] }),
3240
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "min-w-0", children: [
3241
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "inline min-w-0 text-sm font-semibold leading-5", children: parsedLabel.label }),
3242
+ parsedLabel.recommended ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "ml-1.5 inline-flex items-center gap-1 text-sm font-semibold text-primary", children: [
3243
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Check, { className: "h-3.5 w-3.5" }),
3244
+ "(",
3245
+ t("composer.requestUserInput.recommended"),
3246
+ ")"
3247
+ ] }) : null
3248
+ ] }),
3249
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "flex items-center gap-2 text-muted-foreground", children: [
3250
+ option.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Tooltip, { children: [
3251
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.Info, { className: "h-4 w-4" })
3263
+ }
3264
+ ) }),
3265
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsxs)(
3276
+ "span",
3277
+ {
3278
+ "aria-hidden": "true",
3279
+ className: "hidden items-center gap-0.5 sm:flex",
3280
+ children: [
3281
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowUp, { className: "h-4 w-4 opacity-45" }),
3282
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.ArrowDown, { className: "h-4 w-4 opacity-45" })
3283
+ ]
3284
+ }
3285
+ ) : null
3286
+ ] })
3287
+ ]
3288
+ },
3289
+ `${currentQuestion.id}-${optionIndex}`
3290
+ );
3291
+ }),
3292
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "text-sm font-semibold text-muted-foreground", children: [
3303
+ currentQuestion.options.length + 1,
3304
+ "."
3305
+ ] }),
3306
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-center gap-3", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsxs)(
3325
+ "div",
3326
+ {
3327
+ className: cn(
3328
+ "flex items-center justify-end",
3329
+ rounded.density.footer
3330
+ ),
3331
+ children: [
3332
+ onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsx)("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__ */ (0, import_jsx_runtime14.jsxs)(
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__ */ (0, import_jsx_runtime14.jsx)(
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__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react7.CornerDownLeft, { 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
+ var React19 = __toESM(require("react"), 1);
3384
+ var import_lucide_react12 = require("lucide-react");
3385
+
3386
+ // src/components/ui/badge.tsx
3387
+ var React13 = __toESM(require("react"), 1);
3388
+ var import_jsx_runtime15 = require("react/jsx-runtime");
3389
+ 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";
3390
+ var variants = {
3391
+ default: "bg-primary text-primary-foreground",
3392
+ secondary: "bg-secondary text-secondary-foreground",
3393
+ outline: "border-input text-foreground"
3394
+ };
3395
+ var Badge = React13.forwardRef(
3396
+ ({ className, variant = "default", ...props }, ref) => {
3397
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { ref, className: cn(base, variants[variant], className), ...props });
3398
+ }
3399
+ );
3400
+ Badge.displayName = "Badge";
3401
+
3402
+ // src/components/ui/card.tsx
3403
+ var React14 = __toESM(require("react"), 1);
3404
+ var import_jsx_runtime16 = require("react/jsx-runtime");
3405
+ var Card = React14.forwardRef(
3406
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3407
+ "div",
3408
+ {
3409
+ ref,
3410
+ className: cn(
3411
+ "rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
3412
+ className
3413
+ ),
3414
+ ...props
3415
+ }
3416
+ )
3417
+ );
3418
+ Card.displayName = "Card";
3419
+ var CardHeader = React14.forwardRef(
3420
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
3421
+ );
3422
+ CardHeader.displayName = "CardHeader";
3423
+ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
3424
+ CardTitle.displayName = "CardTitle";
3425
+ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
3426
+ CardDescription.displayName = "CardDescription";
3427
+ var CardContent = React14.forwardRef(
3428
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("px-6 pb-6", className), ...props })
3429
+ );
3430
+ CardContent.displayName = "CardContent";
3431
+ var CardFooter = React14.forwardRef(
3432
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
3433
+ );
3434
+ CardFooter.displayName = "CardFooter";
3435
+ var CardAction = React14.forwardRef(
3436
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
3437
+ );
3438
+ CardAction.displayName = "CardAction";
3439
+
3440
+ // src/components/ui/tabs.tsx
3441
+ var React15 = __toESM(require("react"), 1);
3442
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3443
+ var TabsContext = React15.createContext(null);
3444
+ function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
3445
+ const [internalValue, setInternalValue] = React15.useState(defaultValue ?? "");
3446
+ const activeValue = value ?? internalValue;
3447
+ const setValue = React15.useCallback(
3448
+ (nextValue) => {
3449
+ if (value === void 0) setInternalValue(nextValue);
3450
+ onValueChange?.(nextValue);
3451
+ },
3452
+ [onValueChange, value]
3453
+ );
3454
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: cn("w-full", className), ...props }) });
3455
+ }
3456
+ var TabsList = React15.forwardRef(
3457
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3458
+ "div",
3459
+ {
3460
+ ref,
3461
+ className: cn(
3462
+ "inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
3463
+ className
3464
+ ),
3465
+ role: "tablist",
3466
+ ...props
3467
+ }
3468
+ )
3469
+ );
3470
+ TabsList.displayName = "TabsList";
3471
+ var TabsTrigger = React15.forwardRef(
3472
+ ({ className, value, onClick, ...props }, ref) => {
3473
+ const context = React15.useContext(TabsContext);
3474
+ if (!context) {
3475
+ throw new Error("TabsTrigger must be used within Tabs");
3476
+ }
3477
+ const isActive = context.value === value;
3478
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3479
+ "button",
3480
+ {
3481
+ ref,
3482
+ type: "button",
3483
+ role: "tab",
3484
+ "aria-selected": isActive,
3485
+ "data-state": isActive ? "active" : "inactive",
3486
+ className: cn(
3487
+ "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",
3488
+ className
3489
+ ),
3490
+ onClick: (event) => {
3491
+ context.setValue(value);
3492
+ onClick?.(event);
3493
+ },
3494
+ ...props
3495
+ }
3496
+ );
3497
+ }
3498
+ );
3499
+ TabsTrigger.displayName = "TabsTrigger";
3500
+ var TabsContent = React15.forwardRef(
3501
+ ({ className, value, ...props }, ref) => {
3502
+ const context = React15.useContext(TabsContext);
3503
+ if (!context) {
3504
+ throw new Error("TabsContent must be used within Tabs");
3505
+ }
3506
+ if (context.value !== value) return null;
3507
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3508
+ "div",
3509
+ {
3510
+ ref,
3511
+ role: "tabpanel",
3512
+ className: cn(
3513
+ "mt-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background",
3514
+ className
3515
+ ),
3516
+ ...props
3517
+ }
3518
+ );
3519
+ }
3520
+ );
3521
+ TabsContent.displayName = "TabsContent";
3522
+
3523
+ // src/components/thread/markdown-text.tsx
3524
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
3525
+ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
3526
+ var import_rehype_katex = __toESM(require("rehype-katex"), 1);
3527
+ var import_remark_math = __toESM(require("remark-math"), 1);
3528
+ var import_react6 = require("react");
3529
+ var import_lucide_react9 = require("lucide-react");
3530
+
3531
+ // src/components/thread/syntax-highlighter.tsx
3532
+ var import_react_syntax_highlighter = require("react-syntax-highlighter");
3533
+ var import_tsx = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/tsx"), 1);
3534
+ var import_python = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/python"), 1);
3535
+ var import_prism = require("react-syntax-highlighter/dist/cjs/styles/prism");
3536
+ var import_react4 = require("react");
3537
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3538
+ import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("js", import_tsx.default);
2743
3539
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("jsx", import_tsx.default);
2744
3540
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("ts", import_tsx.default);
2745
3541
  import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("tsx", import_tsx.default);
@@ -2749,7 +3545,7 @@ var SyntaxHighlighter = ({
2749
3545
  language,
2750
3546
  className
2751
3547
  }) => {
2752
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3548
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2753
3549
  import_react_syntax_highlighter.PrismAsyncLight,
2754
3550
  {
2755
3551
  language,
@@ -2769,15 +3565,15 @@ var SyntaxHighlighter = ({
2769
3565
  // src/components/thread/mermaid-block.tsx
2770
3566
  var Dialog = __toESM(require("@radix-ui/react-dialog"), 1);
2771
3567
  var import_mermaid = __toESM(require("mermaid"), 1);
2772
- var import_lucide_react7 = require("lucide-react");
2773
- var React15 = __toESM(require("react"), 1);
3568
+ var import_lucide_react8 = require("lucide-react");
3569
+ var React16 = __toESM(require("react"), 1);
2774
3570
 
2775
3571
  // src/components/thread/tooltip-icon-button.tsx
2776
3572
  var import_react5 = require("react");
2777
- var import_jsx_runtime18 = require("react/jsx-runtime");
3573
+ var import_jsx_runtime19 = require("react/jsx-runtime");
2778
3574
  var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
2779
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Tooltip, { children: [
2780
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3575
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Tooltip, { children: [
3576
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2781
3577
  Button,
2782
3578
  {
2783
3579
  variant: "ghost",
@@ -2787,17 +3583,17 @@ var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side
2787
3583
  ref,
2788
3584
  children: [
2789
3585
  children,
2790
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sr-only", children: tooltip })
3586
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sr-only", children: tooltip })
2791
3587
  ]
2792
3588
  }
2793
3589
  ) }),
2794
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TooltipContent, { side, children: tooltip })
3590
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipContent, { side, children: tooltip })
2795
3591
  ] }) });
2796
3592
  });
2797
3593
  TooltipIconButton.displayName = "TooltipIconButton";
2798
3594
 
2799
3595
  // src/components/thread/mermaid-block.tsx
2800
- var import_jsx_runtime19 = require("react/jsx-runtime");
3596
+ var import_jsx_runtime20 = require("react/jsx-runtime");
2801
3597
  var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
2802
3598
  var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
2803
3599
  var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
@@ -3045,24 +3841,24 @@ function MermaidPreviewDialog({
3045
3841
  svgMarkup,
3046
3842
  title
3047
3843
  }) {
3048
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Dialog.Portal, { children: [
3049
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
3050
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
3051
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3052
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3053
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3844
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Dialog.Portal, { children: [
3845
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
3846
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
3847
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
3848
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
3849
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3054
3850
  "button",
3055
3851
  {
3056
3852
  type: "button",
3057
3853
  className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
3058
3854
  children: [
3059
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.X, { className: "size-4" }),
3060
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "sr-only", children: closeLabel })
3855
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { className: "size-4" }),
3856
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "sr-only", children: closeLabel })
3061
3857
  ]
3062
3858
  }
3063
3859
  ) })
3064
3860
  ] }),
3065
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3861
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3066
3862
  "div",
3067
3863
  {
3068
3864
  "data-slot": "mermaid-preview",
@@ -3076,24 +3872,24 @@ function MermaidPreviewDialog({
3076
3872
  function MermaidBlock({ code }) {
3077
3873
  const { t } = useChatkitTranslation();
3078
3874
  const { theme, isDarkMode } = useTheme();
3079
- const containerRef = React15.useRef(null);
3080
- const renderHostRef = React15.useRef(null);
3081
- const renderSequenceRef = React15.useRef(0);
3082
- const copyResetTimeoutRef = React15.useRef(null);
3083
- const diagramId = React15.useId().replace(/:/g, "");
3084
- const [activeTab, setActiveTab] = React15.useState("diagram");
3085
- const [isCopied, setIsCopied] = React15.useState(false);
3086
- const [isPreviewOpen, setIsPreviewOpen] = React15.useState(false);
3087
- const [isRendering, setIsRendering] = React15.useState(true);
3088
- const [renderError, setRenderError] = React15.useState(null);
3089
- const [svgMarkup, setSvgMarkup] = React15.useState(null);
3090
- const normalizedCode = React15.useMemo(() => normalizeMermaidCode(code), [code]);
3091
- const clearCopyResetTimeout = React15.useCallback(() => {
3875
+ const containerRef = React16.useRef(null);
3876
+ const renderHostRef = React16.useRef(null);
3877
+ const renderSequenceRef = React16.useRef(0);
3878
+ const copyResetTimeoutRef = React16.useRef(null);
3879
+ const diagramId = React16.useId().replace(/:/g, "");
3880
+ const [activeTab, setActiveTab] = React16.useState("diagram");
3881
+ const [isCopied, setIsCopied] = React16.useState(false);
3882
+ const [isPreviewOpen, setIsPreviewOpen] = React16.useState(false);
3883
+ const [isRendering, setIsRendering] = React16.useState(true);
3884
+ const [renderError, setRenderError] = React16.useState(null);
3885
+ const [svgMarkup, setSvgMarkup] = React16.useState(null);
3886
+ const normalizedCode = React16.useMemo(() => normalizeMermaidCode(code), [code]);
3887
+ const clearCopyResetTimeout = React16.useCallback(() => {
3092
3888
  if (copyResetTimeoutRef.current === null) return;
3093
3889
  window.clearTimeout(copyResetTimeoutRef.current);
3094
3890
  copyResetTimeoutRef.current = null;
3095
3891
  }, []);
3096
- React15.useEffect(() => {
3892
+ React16.useEffect(() => {
3097
3893
  let isActive = true;
3098
3894
  async function runRender() {
3099
3895
  const container = containerRef.current;
@@ -3131,17 +3927,17 @@ function MermaidBlock({ code }) {
3131
3927
  }
3132
3928
  };
3133
3929
  }, [diagramId, isDarkMode, normalizedCode, theme]);
3134
- React15.useEffect(() => {
3930
+ React16.useEffect(() => {
3135
3931
  clearCopyResetTimeout();
3136
3932
  setIsCopied(false);
3137
3933
  }, [activeTab, clearCopyResetTimeout, code]);
3138
- React15.useEffect(
3934
+ React16.useEffect(
3139
3935
  () => () => {
3140
3936
  clearCopyResetTimeout();
3141
3937
  },
3142
3938
  [clearCopyResetTimeout]
3143
3939
  );
3144
- const handleDownload = React15.useCallback(() => {
3940
+ const handleDownload = React16.useCallback(() => {
3145
3941
  if (!svgMarkup) return;
3146
3942
  const blob = new Blob([svgMarkup], {
3147
3943
  type: "image/svg+xml;charset=utf-8"
@@ -3155,7 +3951,7 @@ function MermaidBlock({ code }) {
3155
3951
  anchor.remove();
3156
3952
  window.URL.revokeObjectURL(url);
3157
3953
  }, [diagramId, svgMarkup]);
3158
- const handleCopyCode = React15.useCallback(() => {
3954
+ const handleCopyCode = React16.useCallback(() => {
3159
3955
  if (!code || isCopied) return;
3160
3956
  navigator.clipboard.writeText(code).then(() => {
3161
3957
  setIsCopied(true);
@@ -3169,21 +3965,21 @@ function MermaidBlock({ code }) {
3169
3965
  }, [clearCopyResetTimeout, code, isCopied]);
3170
3966
  const hasRenderedDiagram = svgMarkup !== null && !renderError;
3171
3967
  const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
3172
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
3173
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3968
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3969
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3174
3970
  Tabs,
3175
3971
  {
3176
3972
  className: "w-full",
3177
3973
  onValueChange: (value) => setActiveTab(value),
3178
3974
  value: activeTab,
3179
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3975
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3180
3976
  "div",
3181
3977
  {
3182
3978
  ref: containerRef,
3183
3979
  "data-slot": "mermaid-block",
3184
3980
  className: "relative overflow-hidden text-card-foreground",
3185
3981
  children: [
3186
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3982
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3187
3983
  "div",
3188
3984
  {
3189
3985
  ref: renderHostRef,
@@ -3192,62 +3988,62 @@ function MermaidBlock({ code }) {
3192
3988
  "data-slot": "mermaid-render-host"
3193
3989
  }
3194
3990
  ),
3195
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3196
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
3197
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.Code2Icon, { className: "size-4" }) }),
3198
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3991
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
3992
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
3993
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Code2Icon, { className: "size-4" }) }),
3994
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
3199
3995
  ] }),
3200
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
3201
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1", children: [
3202
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3996
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
3997
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1", children: [
3998
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3203
3999
  TooltipIconButton,
3204
4000
  {
3205
4001
  onClick: handleDownload,
3206
4002
  tooltip: t("markdown.mermaid.download"),
3207
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.DownloadIcon, { className: "size-4" })
4003
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.DownloadIcon, { className: "size-4" })
3208
4004
  }
3209
4005
  ) : null,
3210
- activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4006
+ activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3211
4007
  TooltipIconButton,
3212
4008
  {
3213
4009
  onClick: () => setIsPreviewOpen(true),
3214
4010
  tooltip: t("markdown.mermaid.fullScreen"),
3215
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.ExpandIcon, { className: "size-4" })
4011
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.ExpandIcon, { className: "size-4" })
3216
4012
  }
3217
4013
  ) : null,
3218
- activeTab === "code" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4014
+ activeTab === "code" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3219
4015
  TooltipIconButton,
3220
4016
  {
3221
4017
  onClick: handleCopyCode,
3222
4018
  tooltip: t("markdown.copy"),
3223
- children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CopyIcon, { className: "size-4" })
4019
+ children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CopyIcon, { className: "size-4" })
3224
4020
  }
3225
4021
  ) : null
3226
4022
  ] }),
3227
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(TabsList, { children: [
3228
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
3229
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
4023
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(TabsList, { children: [
4024
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
4025
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
3230
4026
  ] })
3231
4027
  ] })
3232
4028
  ] }),
3233
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "border-t border-border pt-4", children: [
3234
- renderError ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
3235
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4029
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "border-t border-border pt-4", children: [
4030
+ renderError ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
4031
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3236
4032
  "div",
3237
4033
  {
3238
4034
  className: cn(
3239
4035
  "relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
3240
4036
  hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
3241
4037
  ),
3242
- children: hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4038
+ children: hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3243
4039
  "div",
3244
4040
  {
3245
4041
  "data-slot": "mermaid-diagram",
3246
4042
  dangerouslySetInnerHTML: { __html: svgMarkup }
3247
4043
  }
3248
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
3249
- isRendering ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.TriangleAlert, { className: "size-5 text-destructive" }),
3250
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4044
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
4045
+ isRendering ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.TriangleAlert, { className: "size-5 text-destructive" }),
4046
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3251
4047
  "p",
3252
4048
  {
3253
4049
  className: cn("text-sm font-medium", !isRendering && "text-destructive"),
@@ -3258,12 +4054,12 @@ function MermaidBlock({ code }) {
3258
4054
  ] })
3259
4055
  }
3260
4056
  ) }),
3261
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4057
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3262
4058
  "pre",
3263
4059
  {
3264
4060
  "data-slot": "mermaid-code",
3265
4061
  className: "overflow-x-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-zinc-950 px-4 py-4 text-sm text-zinc-50",
3266
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("code", { className: "block whitespace-pre font-mono", children: code })
4062
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("code", { className: "block whitespace-pre font-mono", children: code })
3267
4063
  }
3268
4064
  ) })
3269
4065
  ] })
@@ -3272,7 +4068,7 @@ function MermaidBlock({ code }) {
3272
4068
  )
3273
4069
  }
3274
4070
  ),
3275
- svgMarkup ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
4071
+ svgMarkup ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3276
4072
  MermaidPreviewDialog,
3277
4073
  {
3278
4074
  closeLabel: t("sheet.close"),
@@ -3287,7 +4083,7 @@ function MermaidBlock({ code }) {
3287
4083
 
3288
4084
  // src/components/thread/markdown-text.tsx
3289
4085
  var import_katex_min = require("katex/dist/katex.min.css");
3290
- var import_jsx_runtime20 = require("react/jsx-runtime");
4086
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3291
4087
  var markdownTableMinWidth = "max(7rem, calc(8rem * var(--density-spacing, 1)))";
3292
4088
  var markdownTableCellPaddingInline = "calc(var(--density-padding, 1rem) * 1.25)";
3293
4089
  var markdownTableCellPaddingBlock = "max(0.5rem, calc(var(--density-padding, 1rem) * 0.75))";
@@ -3322,23 +4118,23 @@ var CodeHeader = ({ language, code }) => {
3322
4118
  if (!code || isCopied) return;
3323
4119
  copyToClipboard(code);
3324
4120
  };
3325
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
3326
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "lowercase [&>span]:text-xs", children: language }),
3327
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4121
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
4122
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "lowercase [&>span]:text-xs", children: language }),
4123
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
3328
4124
  TooltipIconButton,
3329
4125
  {
3330
4126
  tooltip: t("markdown.copy"),
3331
4127
  onClick: onCopy,
3332
4128
  children: [
3333
- !isCopied && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CopyIcon, {}),
3334
- isCopied && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.CheckIcon, {})
4129
+ !isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CopyIcon, {}),
4130
+ isCopied && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.CheckIcon, {})
3335
4131
  ]
3336
4132
  }
3337
4133
  )
3338
4134
  ] });
3339
4135
  };
3340
4136
  var defaultComponents = {
3341
- h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4137
+ h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3342
4138
  "h1",
3343
4139
  {
3344
4140
  className: cn(
@@ -3348,7 +4144,7 @@ var defaultComponents = {
3348
4144
  ...props
3349
4145
  }
3350
4146
  ),
3351
- h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4147
+ h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3352
4148
  "h2",
3353
4149
  {
3354
4150
  className: cn(
@@ -3358,7 +4154,7 @@ var defaultComponents = {
3358
4154
  ...props
3359
4155
  }
3360
4156
  ),
3361
- h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4157
+ h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3362
4158
  "h3",
3363
4159
  {
3364
4160
  className: cn(
@@ -3368,7 +4164,7 @@ var defaultComponents = {
3368
4164
  ...props
3369
4165
  }
3370
4166
  ),
3371
- h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4167
+ h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3372
4168
  "h4",
3373
4169
  {
3374
4170
  className: cn(
@@ -3378,7 +4174,7 @@ var defaultComponents = {
3378
4174
  ...props
3379
4175
  }
3380
4176
  ),
3381
- h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4177
+ h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3382
4178
  "h5",
3383
4179
  {
3384
4180
  className: cn(
@@ -3388,21 +4184,21 @@ var defaultComponents = {
3388
4184
  ...props
3389
4185
  }
3390
4186
  ),
3391
- h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4187
+ h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3392
4188
  "h6",
3393
4189
  {
3394
4190
  className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
3395
4191
  ...props
3396
4192
  }
3397
4193
  ),
3398
- p: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4194
+ p: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3399
4195
  "p",
3400
4196
  {
3401
4197
  className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
3402
4198
  ...props
3403
4199
  }
3404
4200
  ),
3405
- a: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4201
+ a: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3406
4202
  "a",
3407
4203
  {
3408
4204
  className: cn(
@@ -3418,7 +4214,7 @@ var defaultComponents = {
3418
4214
  className,
3419
4215
  node: _node,
3420
4216
  ...props
3421
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4217
+ }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3422
4218
  "blockquote",
3423
4219
  {
3424
4220
  className: cn(
@@ -3428,21 +4224,21 @@ var defaultComponents = {
3428
4224
  ...props
3429
4225
  }
3430
4226
  ),
3431
- ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4227
+ ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3432
4228
  "ul",
3433
4229
  {
3434
4230
  className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
3435
4231
  ...props
3436
4232
  }
3437
4233
  ),
3438
- ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4234
+ ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3439
4235
  "ol",
3440
4236
  {
3441
4237
  className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
3442
4238
  ...props
3443
4239
  }
3444
4240
  ),
3445
- hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4241
+ hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3446
4242
  "hr",
3447
4243
  {
3448
4244
  className: cn("my-5 border-b", className),
@@ -3454,12 +4250,12 @@ var defaultComponents = {
3454
4250
  node: _node,
3455
4251
  style,
3456
4252
  ...props
3457
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4253
+ }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3458
4254
  "div",
3459
4255
  {
3460
4256
  "data-slot": "markdown-table-container",
3461
4257
  className: "my-5 max-w-full overflow-x-auto rounded-xl border border-border bg-background",
3462
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4258
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3463
4259
  "table",
3464
4260
  {
3465
4261
  className: cn(
@@ -3480,7 +4276,7 @@ var defaultComponents = {
3480
4276
  node: _node,
3481
4277
  style,
3482
4278
  ...props
3483
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4279
+ }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3484
4280
  "th",
3485
4281
  {
3486
4282
  className: cn(
@@ -3501,7 +4297,7 @@ var defaultComponents = {
3501
4297
  node: _node,
3502
4298
  style,
3503
4299
  ...props
3504
- }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4300
+ }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3505
4301
  "td",
3506
4302
  {
3507
4303
  className: cn(
@@ -3517,7 +4313,7 @@ var defaultComponents = {
3517
4313
  ...props
3518
4314
  }
3519
4315
  ),
3520
- tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4316
+ tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3521
4317
  "tr",
3522
4318
  {
3523
4319
  className: cn(
@@ -3527,14 +4323,14 @@ var defaultComponents = {
3527
4323
  ...props
3528
4324
  }
3529
4325
  ),
3530
- sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4326
+ sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3531
4327
  "sup",
3532
4328
  {
3533
4329
  className: cn("[&>a]:text-xs [&>a]:no-underline", className),
3534
4330
  ...props
3535
4331
  }
3536
4332
  ),
3537
- pre: ({ className, children, node: _node }) => import_react6.Children.toArray(children).length === 1 && (isMermaidBlockChild(import_react6.Children.toArray(children)[0]) || isMermaidCodeElement(import_react6.Children.toArray(children)[0])) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_jsx_runtime20.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4333
+ pre: ({ className, children, node: _node }) => import_react6.Children.toArray(children).length === 1 && (isMermaidBlockChild(import_react6.Children.toArray(children)[0]) || isMermaidCodeElement(import_react6.Children.toArray(children)[0])) ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_jsx_runtime21.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3538
4334
  "div",
3539
4335
  {
3540
4336
  className: cn(
@@ -3558,17 +4354,17 @@ var defaultComponents = {
3558
4354
  const language = match[1];
3559
4355
  const normalizedCode = code.replace(/\n$/, "");
3560
4356
  if (language === "mermaid") {
3561
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(MermaidBlock, { code: normalizedCode });
4357
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MermaidBlock, { code: normalizedCode });
3562
4358
  }
3563
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
3564
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4359
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
4360
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3565
4361
  CodeHeader,
3566
4362
  {
3567
4363
  language,
3568
4364
  code: normalizedCode
3569
4365
  }
3570
4366
  ),
3571
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4367
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3572
4368
  SyntaxHighlighter,
3573
4369
  {
3574
4370
  language,
@@ -3579,63 +4375,861 @@ var defaultComponents = {
3579
4375
  ] });
3580
4376
  }
3581
4377
  if (isBlockCode) {
3582
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4378
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3583
4379
  "code",
3584
4380
  {
3585
4381
  className: cn(
3586
4382
  "block min-w-full whitespace-pre px-4 py-4 font-mono text-inherit",
3587
4383
  className
3588
4384
  ),
3589
- ...props,
3590
- children: code.replace(/\n$/, "")
3591
- }
3592
- );
4385
+ ...props,
4386
+ children: code.replace(/\n$/, "")
4387
+ }
4388
+ );
4389
+ }
4390
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4391
+ "code",
4392
+ {
4393
+ className: cn(
4394
+ "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
4395
+ className
4396
+ ),
4397
+ style: {
4398
+ paddingInline: markdownInlineCodePaddingInline,
4399
+ paddingBlock: markdownInlineCodePaddingBlock,
4400
+ ...style
4401
+ },
4402
+ ...props,
4403
+ children
4404
+ }
4405
+ );
4406
+ }
4407
+ };
4408
+ var MarkdownTextImpl = ({ children }) => {
4409
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "markdown-content", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4410
+ import_react_markdown.default,
4411
+ {
4412
+ remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
4413
+ rehypePlugins: [import_rehype_katex.default],
4414
+ components: defaultComponents,
4415
+ children
4416
+ }
4417
+ ) });
4418
+ };
4419
+ var MarkdownText = (0, import_react6.memo)(MarkdownTextImpl);
4420
+
4421
+ // src/components/thread/messages/tool-component-group.tsx
4422
+ var React17 = __toESM(require("react"), 1);
4423
+ var import_lucide_react10 = require("lucide-react");
4424
+
4425
+ // src/i18n/localized-text.ts
4426
+ function resolveLocalizedText(value, language) {
4427
+ if (typeof value === "string") {
4428
+ const trimmed = value.trim();
4429
+ return trimmed || null;
4430
+ }
4431
+ if (!value || typeof value !== "object") return null;
4432
+ const localized = value;
4433
+ const normalizedLanguage = language.trim();
4434
+ const underscoredLanguage = normalizedLanguage.replace(/-/g, "_");
4435
+ const languagePrefix = normalizedLanguage.split("-")[0];
4436
+ const preferredKeys = normalizedLanguage.startsWith("zh") ? [
4437
+ normalizedLanguage,
4438
+ underscoredLanguage,
4439
+ "zh_Hans",
4440
+ "zh-Hans",
4441
+ "zh_CN",
4442
+ "zh-CN",
4443
+ "zh",
4444
+ "en_US",
4445
+ "en-US",
4446
+ "en"
4447
+ ] : [
4448
+ normalizedLanguage,
4449
+ underscoredLanguage,
4450
+ "en_US",
4451
+ "en-US",
4452
+ "en",
4453
+ languagePrefix,
4454
+ "zh_Hans",
4455
+ "zh-Hans",
4456
+ "zh_CN",
4457
+ "zh-CN",
4458
+ "zh"
4459
+ ];
4460
+ for (const key of preferredKeys) {
4461
+ const candidate = localized[key];
4462
+ if (typeof candidate === "string" && candidate.trim()) {
4463
+ return candidate.trim();
4464
+ }
4465
+ }
4466
+ for (const candidate of Object.values(localized)) {
4467
+ if (typeof candidate === "string" && candidate.trim()) {
4468
+ return candidate.trim();
4469
+ }
4470
+ }
4471
+ return null;
4472
+ }
4473
+
4474
+ // src/components/thread/messages/tool-component-group.tsx
4475
+ var import_jsx_runtime22 = require("react/jsx-runtime");
4476
+ var toolStatusConfig = {
4477
+ success: {
4478
+ iconClass: "border-green-500 text-green-700",
4479
+ icon: import_lucide_react10.CheckCircle2
4480
+ },
4481
+ fail: {
4482
+ iconClass: "border-red-500 text-red-700",
4483
+ icon: import_lucide_react10.XCircle
4484
+ },
4485
+ running: {
4486
+ iconClass: "border-blue-500 text-blue-700",
4487
+ icon: import_lucide_react10.Loader2
4488
+ }
4489
+ };
4490
+ var TOOL_GROUP_CATEGORY_ORDER = [
4491
+ "files",
4492
+ "searches",
4493
+ "commands",
4494
+ "lists",
4495
+ "tasks",
4496
+ "knowledges",
4497
+ "tools"
4498
+ ];
4499
+ var TOOL_GROUP_TOKEN_CATEGORY = {
4500
+ file: "files",
4501
+ files: "files",
4502
+ web_search: "searches",
4503
+ search: "searches",
4504
+ searches: "searches",
4505
+ program: "commands",
4506
+ command: "commands",
4507
+ commands: "commands",
4508
+ shell: "commands",
4509
+ terminal: "commands",
4510
+ list: "lists",
4511
+ lists: "lists",
4512
+ task: "tasks",
4513
+ tasks: "tasks",
4514
+ todo: "tasks",
4515
+ todos: "tasks",
4516
+ knowledge: "knowledges",
4517
+ knowledges: "knowledges",
4518
+ retriever: "knowledges",
4519
+ retrieval: "knowledges",
4520
+ tool: "tools",
4521
+ tools: "tools"
4522
+ };
4523
+ var TOOL_CALL_OUTPUT_RENDERERS = {};
4524
+ function getToolStepData(content) {
4525
+ return content.data ?? {};
4526
+ }
4527
+ function safeJson(value) {
4528
+ try {
4529
+ return JSON.stringify(value, null, 2) ?? String(value);
4530
+ } catch {
4531
+ return String(value);
4532
+ }
4533
+ }
4534
+ function formatDisplayValue(value) {
4535
+ return typeof value === "string" ? value : safeJson(value);
4536
+ }
4537
+ function parseStepDate(value) {
4538
+ if (value instanceof Date) {
4539
+ const timestamp2 = value.getTime();
4540
+ return Number.isNaN(timestamp2) ? null : timestamp2;
4541
+ }
4542
+ if (typeof value !== "string") {
4543
+ return null;
4544
+ }
4545
+ const timestamp = Date.parse(value);
4546
+ return Number.isNaN(timestamp) ? null : timestamp;
4547
+ }
4548
+ function formatStepDuration(durationMs) {
4549
+ if (durationMs < 1e3) {
4550
+ return `${durationMs}ms`;
4551
+ }
4552
+ if (durationMs < 1e4) {
4553
+ return `${(durationMs / 1e3).toFixed(1)}s`;
4554
+ }
4555
+ if (durationMs < 6e4) {
4556
+ return `${Math.round(durationMs / 1e3)}s`;
4557
+ }
4558
+ const hours = Math.floor(durationMs / 36e5);
4559
+ const minutes = Math.floor(durationMs % 36e5 / 6e4);
4560
+ const seconds = Math.floor(durationMs % 6e4 / 1e3);
4561
+ if (hours > 0) {
4562
+ return `${hours}h ${minutes}m ${seconds}s`;
4563
+ }
4564
+ return `${minutes}m ${seconds}s`;
4565
+ }
4566
+ function useToolStepDurationLabel(data) {
4567
+ const [durationNow, setDurationNow] = React17.useState(() => Date.now());
4568
+ const createdAt = parseStepDate(data.created_date);
4569
+ const endedAt = parseStepDate(data.end_date);
4570
+ const status = data.status;
4571
+ React17.useEffect(() => {
4572
+ if (status !== "running" || createdAt === null || endedAt !== null) {
4573
+ return;
4574
+ }
4575
+ setDurationNow(Date.now());
4576
+ const timer = window.setInterval(() => {
4577
+ setDurationNow(Date.now());
4578
+ }, 100);
4579
+ return () => {
4580
+ window.clearInterval(timer);
4581
+ };
4582
+ }, [createdAt, endedAt, status]);
4583
+ if (createdAt === null) return null;
4584
+ const durationMs = Math.max(0, (endedAt ?? durationNow) - createdAt);
4585
+ return formatStepDuration(durationMs);
4586
+ }
4587
+ function isJsonObjectValue(value) {
4588
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4589
+ }
4590
+ function canUseAsJsonValue(value) {
4591
+ if (value === null) return true;
4592
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
4593
+ return true;
4594
+ }
4595
+ if (Array.isArray(value)) {
4596
+ return value.every(canUseAsJsonValue);
4597
+ }
4598
+ if (typeof value === "object") {
4599
+ return Object.values(value).every(canUseAsJsonValue);
4600
+ }
4601
+ return false;
4602
+ }
4603
+ function parseJsonString(value) {
4604
+ const trimmed = value.trim();
4605
+ if (!trimmed) return null;
4606
+ const first = trimmed[0];
4607
+ if (first !== "{" && first !== "[") return null;
4608
+ try {
4609
+ const parsed = JSON.parse(trimmed);
4610
+ return canUseAsJsonValue(parsed) ? parsed : null;
4611
+ } catch {
4612
+ return null;
4613
+ }
4614
+ }
4615
+ function detectJsonValue(value) {
4616
+ if (typeof value === "string") {
4617
+ const parsed = parseJsonString(value);
4618
+ if (parsed !== null) {
4619
+ return {
4620
+ kind: "json",
4621
+ value: parsed,
4622
+ raw: safeJson(parsed)
4623
+ };
4624
+ }
4625
+ return { kind: "text", text: value };
4626
+ }
4627
+ if (canUseAsJsonValue(value) && value !== null && typeof value === "object") {
4628
+ return {
4629
+ kind: "json",
4630
+ value,
4631
+ raw: safeJson(value)
4632
+ };
4633
+ }
4634
+ return { kind: "text", text: formatDisplayValue(value) };
4635
+ }
4636
+ function isComponentContent(content) {
4637
+ return content.type === "component";
4638
+ }
4639
+ function isTextContent(content) {
4640
+ return content.type === "text";
4641
+ }
4642
+ function isReasoningContent(content) {
4643
+ return content.type === "reasoning";
4644
+ }
4645
+ function isWidgetComponent(content) {
4646
+ const data = content.data;
4647
+ return data?.type === "Widget" && Array.isArray(data.widgets);
4648
+ }
4649
+ function isGroupableToolComponent(content) {
4650
+ if (!content || typeof content === "string") return false;
4651
+ return isComponentContent(content) && !isWidgetComponent(content) && content.data?.category === "Tool";
4652
+ }
4653
+ function isSkippableToolGroupSeparator(content) {
4654
+ if (typeof content === "string") return !content.trim();
4655
+ if (!content) return true;
4656
+ if (isTextContent(content)) {
4657
+ return !content.text?.trim();
4658
+ }
4659
+ if (isReasoningContent(content)) {
4660
+ return !content.text?.trim();
4661
+ }
4662
+ return false;
4663
+ }
4664
+ function normalizeToolToken(value) {
4665
+ if (typeof value !== "string") return null;
4666
+ const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_");
4667
+ return normalized || null;
4668
+ }
4669
+ function classifyToolToken(value) {
4670
+ const normalized = normalizeToolToken(
4671
+ typeof value === "string" ? value : resolveLocalizedText(value, "en-US")
4672
+ );
4673
+ if (!normalized) return null;
4674
+ const directMatch = TOOL_GROUP_TOKEN_CATEGORY[normalized];
4675
+ if (directMatch) return directMatch;
4676
+ if (normalized.includes("search")) return "searches";
4677
+ if (normalized.includes("file")) return "files";
4678
+ if (normalized.includes("command") || normalized.includes("cmd") || normalized.includes("program") || normalized.includes("exec") || normalized.startsWith("run_") || normalized.includes("_run")) {
4679
+ return "commands";
4680
+ }
4681
+ if (normalized.includes("list")) return "lists";
4682
+ if (normalized.includes("task") || normalized.includes("todo")) return "tasks";
4683
+ if (normalized.includes("knowledge") || normalized.includes("retriever")) {
4684
+ return "knowledges";
4685
+ }
4686
+ return null;
4687
+ }
4688
+ function getToolGroupCategory(content) {
4689
+ const data = getToolStepData(content);
4690
+ return classifyToolToken(data.type) ?? classifyToolToken(data.tool) ?? classifyToolToken(data.title) ?? classifyToolToken(data.message) ?? "tools";
4691
+ }
4692
+ function getToolGroupCategoryCounts(items) {
4693
+ return items.reduce((counts, item) => {
4694
+ const category = getToolGroupCategory(item);
4695
+ counts[category] = (counts[category] ?? 0) + 1;
4696
+ return counts;
4697
+ }, {});
4698
+ }
4699
+ function getToolGroupDisplayStatus(items) {
4700
+ if (items.some((item) => getToolStepData(item).status === "fail")) {
4701
+ return "fail";
4702
+ }
4703
+ return "success";
4704
+ }
4705
+ function getToolActivityLabel(content, language) {
4706
+ const data = getToolStepData(content);
4707
+ const runningCandidates = [data.message, data.title, data.tool, data.type];
4708
+ const completedCandidates = [data.title, data.message, data.tool, data.type];
4709
+ const candidates = data.status === "running" ? runningCandidates : completedCandidates;
4710
+ for (const candidate of candidates) {
4711
+ const label = resolveLocalizedText(candidate, language);
4712
+ if (label) return label;
4713
+ }
4714
+ return "Tool";
4715
+ }
4716
+ function flushPendingTools(units, pendingTools) {
4717
+ if (pendingTools.length === 0) return;
4718
+ units.push({
4719
+ type: "tool-group",
4720
+ items: pendingTools.map((tool) => tool.item),
4721
+ startIndex: pendingTools[0].index
4722
+ });
4723
+ pendingTools.length = 0;
4724
+ }
4725
+ function buildToolComponentRenderUnits(content, options) {
4726
+ const units = [];
4727
+ const pendingTools = [];
4728
+ content.forEach((item, index) => {
4729
+ if (isGroupableToolComponent(item) && options?.shouldGroupComponent?.(item) !== false) {
4730
+ pendingTools.push({ item, index });
4731
+ return;
4732
+ }
4733
+ if (isSkippableToolGroupSeparator(item)) {
4734
+ return;
4735
+ }
4736
+ if (item === void 0) {
4737
+ return;
4738
+ }
4739
+ flushPendingTools(units, pendingTools);
4740
+ units.push({ type: "item", item, index });
4741
+ });
4742
+ flushPendingTools(units, pendingTools);
4743
+ return units;
4744
+ }
4745
+ function getToolCallOutputRenderer(data) {
4746
+ const keys = [data.tool, data.type].filter(
4747
+ (value) => typeof value === "string" && Boolean(value.trim())
4748
+ );
4749
+ for (const key of keys) {
4750
+ const renderer = TOOL_CALL_OUTPUT_RENDERERS[key];
4751
+ if (renderer) return renderer;
4752
+ }
4753
+ return DefaultToolCallOutput;
4754
+ }
4755
+ function getJsonValueSummary(value) {
4756
+ if (Array.isArray(value)) {
4757
+ return `Array(${value.length})`;
4758
+ }
4759
+ if (isJsonObjectValue(value)) {
4760
+ return `Object(${Object.keys(value).length})`;
4761
+ }
4762
+ return "JSON";
4763
+ }
4764
+ function formatJsonPrimitive(value) {
4765
+ if (value === null) return "null";
4766
+ if (typeof value === "string") return JSON.stringify(value);
4767
+ return String(value);
4768
+ }
4769
+ function JsonTreeNode({
4770
+ label,
4771
+ value,
4772
+ depth = 0
4773
+ }) {
4774
+ const isArray = Array.isArray(value);
4775
+ const isObject = isJsonObjectValue(value);
4776
+ const isExpandable = isArray || isObject;
4777
+ const [isExpanded, setIsExpanded] = React17.useState(depth < 2);
4778
+ if (!isExpandable) {
4779
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 gap-2 leading-6", children: [
4780
+ label ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "shrink-0 font-medium text-foreground/80", children: [
4781
+ label,
4782
+ ":"
4783
+ ] }) : null,
4784
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4785
+ "span",
4786
+ {
4787
+ className: cn(
4788
+ "min-w-0 wrap-break-word",
4789
+ typeof value === "string" ? "text-emerald-700" : typeof value === "number" ? "text-blue-700" : typeof value === "boolean" ? "text-purple-700" : "text-muted-foreground"
4790
+ ),
4791
+ children: formatJsonPrimitive(value)
4792
+ }
4793
+ )
4794
+ ] });
4795
+ }
4796
+ const entries = isArray ? value.map((item, index) => [String(index), item]) : Object.entries(value);
4797
+ const summary = isArray ? `Array(${value.length})` : `Object(${entries.length})`;
4798
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "min-w-0", children: [
4799
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4800
+ "button",
4801
+ {
4802
+ type: "button",
4803
+ className: "flex min-w-0 items-center gap-1 leading-6 text-left hover:text-foreground",
4804
+ "aria-expanded": isExpanded,
4805
+ onClick: () => setIsExpanded((prev) => !prev),
4806
+ children: [
4807
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4808
+ import_lucide_react10.ChevronRight,
4809
+ {
4810
+ "aria-hidden": "true",
4811
+ className: cn(
4812
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
4813
+ isExpanded && "rotate-90"
4814
+ )
4815
+ }
4816
+ ),
4817
+ label ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "min-w-0 truncate font-medium text-foreground/80", children: [
4818
+ label,
4819
+ ":"
4820
+ ] }) : null,
4821
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-muted-foreground", children: summary })
4822
+ ]
4823
+ }
4824
+ ),
4825
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "ml-4 border-l border-border/70 pl-3", children: entries.map(([entryLabel, entryValue]) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4826
+ JsonTreeNode,
4827
+ {
4828
+ label: entryLabel,
4829
+ value: entryValue,
4830
+ depth: depth + 1
4831
+ },
4832
+ entryLabel
4833
+ )) }) : null
4834
+ ] });
4835
+ }
4836
+ function JsonTreeView({ value }) {
4837
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "min-w-0 font-mono text-[11px]", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(JsonTreeNode, { value }) });
4838
+ }
4839
+ function RawJsonBlock({ raw }) {
4840
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word font-mono text-[11px]", children: raw });
4841
+ }
4842
+ function PlainTextBlock({ value, destructive = false }) {
4843
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4844
+ "pre",
4845
+ {
4846
+ className: cn(
4847
+ "whitespace-pre-wrap wrap-break-word",
4848
+ destructive && "text-destructive"
4849
+ ),
4850
+ children: value
3593
4851
  }
3594
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3595
- "code",
4852
+ );
4853
+ }
4854
+ function ToolCallCopyButton({ value }) {
4855
+ const { t } = useChatkitTranslation();
4856
+ const [isCopied, setIsCopied] = React17.useState(false);
4857
+ const resetTimeoutRef = React17.useRef(null);
4858
+ const clearResetTimeout = React17.useCallback(() => {
4859
+ if (resetTimeoutRef.current === null) return;
4860
+ window.clearTimeout(resetTimeoutRef.current);
4861
+ resetTimeoutRef.current = null;
4862
+ }, []);
4863
+ React17.useEffect(() => clearResetTimeout, [clearResetTimeout]);
4864
+ const handleCopy = React17.useCallback(() => {
4865
+ if (typeof navigator === "undefined" || !navigator.clipboard) return;
4866
+ void navigator.clipboard.writeText(value).then(() => {
4867
+ setIsCopied(true);
4868
+ clearResetTimeout();
4869
+ resetTimeoutRef.current = window.setTimeout(() => {
4870
+ setIsCopied(false);
4871
+ resetTimeoutRef.current = null;
4872
+ }, 1500);
4873
+ }).catch(() => void 0);
4874
+ }, [clearResetTimeout, value]);
4875
+ const label = isCopied ? t("message.toolGroup.copied") : t("message.toolGroup.copy");
4876
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4877
+ "button",
4878
+ {
4879
+ type: "button",
4880
+ 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",
4881
+ "aria-label": label,
4882
+ title: label,
4883
+ onClick: handleCopy,
4884
+ children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Check, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Copy, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
4885
+ }
4886
+ );
4887
+ }
4888
+ function ToolCallValueBlock({
4889
+ value,
4890
+ destructive = false
4891
+ }) {
4892
+ const { t } = useChatkitTranslation();
4893
+ const detected = detectJsonValue(value);
4894
+ if (detected.kind === "text") {
4895
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "min-w-0 space-y-1", children: [
4896
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallCopyButton, { value: detected.text }) }),
4897
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(PlainTextBlock, { value: detected.text, destructive })
4898
+ ] });
4899
+ }
4900
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tabs, { defaultValue: "tree", className: "min-w-0", children: [
4901
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "mb-2 flex min-w-0 items-center justify-between gap-2", children: [
4902
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "min-w-0 truncate text-[11px] text-muted-foreground", children: [
4903
+ t("message.toolGroup.jsonTitle"),
4904
+ " \xB7 ",
4905
+ getJsonValueSummary(detected.value)
4906
+ ] }),
4907
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex shrink-0 items-center gap-1", children: [
4908
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallCopyButton, { value: detected.raw }),
4909
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(TabsList, { className: "rounded-md p-0.5", children: [
4910
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "tree", children: t("message.toolGroup.jsonTree") }),
4911
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { className: "px-2 py-0.5 text-[11px]", value: "raw", children: t("message.toolGroup.jsonRaw") })
4912
+ ] })
4913
+ ] })
4914
+ ] }),
4915
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "tree", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(JsonTreeView, { value: detected.value }) }),
4916
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "raw", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(RawJsonBlock, { raw: detected.raw }) })
4917
+ ] });
4918
+ }
4919
+ function DefaultToolCallOutput({ data }) {
4920
+ const { t } = useChatkitTranslation();
4921
+ const output = data.output ?? null;
4922
+ const error = data.error ?? null;
4923
+ if (error) {
4924
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
4925
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-destructive", children: t("message.toolGroup.errorTitle") }),
4926
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: error, destructive: true })
4927
+ ] });
4928
+ }
4929
+ if (output === null) return null;
4930
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
4931
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.outputTitle") }),
4932
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: output })
4933
+ ] });
4934
+ }
4935
+ function ToolCallDetails({ content }) {
4936
+ const { t } = useChatkitTranslation();
4937
+ const data = getToolStepData(content);
4938
+ const OutputRenderer = getToolCallOutputRenderer(data);
4939
+ const hasInput = data.input !== void 0 && data.input !== null;
4940
+ const hasOutput = data.error !== void 0 || data.output !== void 0;
4941
+ if (!hasInput && !hasOutput) return null;
4942
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ml-6 mt-1 max-h-60 overflow-auto rounded-md bg-muted/30 px-3 py-2 text-xs text-muted-foreground", children: [
4943
+ hasInput && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
4944
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "text-[11px] font-medium text-muted-foreground", children: t("message.toolGroup.inputTitle") }),
4945
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallValueBlock, { value: data.input })
4946
+ ] }),
4947
+ hasInput && hasOutput ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "h-2" }) : null,
4948
+ hasOutput ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(OutputRenderer, { content, data }) : null
4949
+ ] });
4950
+ }
4951
+ function ToolCallRow({ content }) {
4952
+ const { i18n: i18n2 } = useChatkitTranslation();
4953
+ const data = getToolStepData(content);
4954
+ const status = data.status;
4955
+ const itemConfig = status ? toolStatusConfig[status] : null;
4956
+ const ItemStatusIcon = itemConfig?.icon;
4957
+ const hasError = status === "fail" || Boolean(data.error);
4958
+ const label = getToolActivityLabel(content, i18n2.language);
4959
+ const detailsId = React17.useId();
4960
+ const hasDetails = data.input !== void 0 || data.error !== void 0 || data.output !== void 0;
4961
+ const durationLabel = useToolStepDurationLabel(data);
4962
+ const [isExpanded, setIsExpanded] = React17.useState(false);
4963
+ React17.useEffect(() => {
4964
+ if (status === "running" && data.output !== void 0) {
4965
+ setIsExpanded(true);
4966
+ }
4967
+ }, [data.output, status]);
4968
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("li", { className: "min-w-0", children: [
4969
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
4970
+ "button",
3596
4971
  {
4972
+ type: "button",
3597
4973
  className: cn(
3598
- "bg-muted rounded font-mono text-[0.9em] font-semibold whitespace-pre-wrap [overflow-wrap:anywhere]",
3599
- className
4974
+ "flex w-full min-w-0 items-center gap-2 text-left text-sm leading-6 text-muted-foreground",
4975
+ hasDetails && "cursor-pointer hover:text-foreground",
4976
+ hasError && "text-destructive hover:text-destructive"
3600
4977
  ),
3601
- style: {
3602
- paddingInline: markdownInlineCodePaddingInline,
3603
- paddingBlock: markdownInlineCodePaddingBlock,
3604
- ...style
4978
+ "aria-expanded": hasDetails ? isExpanded : void 0,
4979
+ "aria-controls": hasDetails ? detailsId : void 0,
4980
+ disabled: !hasDetails,
4981
+ onClick: () => {
4982
+ if (hasDetails) setIsExpanded((prev) => !prev);
3605
4983
  },
3606
- ...props,
3607
- children
4984
+ children: [
4985
+ ItemStatusIcon ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4986
+ ItemStatusIcon,
4987
+ {
4988
+ className: cn(
4989
+ "h-3.5 w-3.5 shrink-0",
4990
+ itemConfig?.iconClass,
4991
+ status === "running" && "animate-spin"
4992
+ )
4993
+ }
4994
+ ) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-3.5 w-3.5 shrink-0", "aria-hidden": "true" }),
4995
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "min-w-0 flex-1 truncate", title: label, children: label }),
4996
+ durationLabel ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "shrink-0 text-[11px] tabular-nums text-muted-foreground/80", children: durationLabel }) : null,
4997
+ hasDetails ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
4998
+ import_lucide_react10.ChevronRight,
4999
+ {
5000
+ "aria-hidden": "true",
5001
+ className: cn(
5002
+ "h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform",
5003
+ isExpanded && "rotate-90"
5004
+ )
5005
+ }
5006
+ ) : null
5007
+ ]
3608
5008
  }
3609
- );
5009
+ ),
5010
+ hasDetails && isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { id: detailsId, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallDetails, { content }) }) : null
5011
+ ] });
5012
+ }
5013
+ function ToolComponentGroup({
5014
+ items,
5015
+ hasFollowingItem
5016
+ }) {
5017
+ const { t } = useChatkitTranslation();
5018
+ const contentId = React17.useId();
5019
+ const groupStatus = getToolGroupDisplayStatus(items);
5020
+ const [isExpanded, setIsExpanded] = React17.useState(!hasFollowingItem);
5021
+ const categoryCounts = getToolGroupCategoryCounts(items);
5022
+ const categorySummary = TOOL_GROUP_CATEGORY_ORDER.flatMap((category) => {
5023
+ const count = categoryCounts[category] ?? 0;
5024
+ if (count === 0) return [];
5025
+ return [
5026
+ t(
5027
+ `message.toolGroup.categories.${category}.${count === 1 ? "one" : "other"}`,
5028
+ { count }
5029
+ )
5030
+ ];
5031
+ }).join(t("message.toolGroup.separator"));
5032
+ const summary = `${t(`message.toolGroup.status.${groupStatus}`)} ${categorySummary}`;
5033
+ const config = toolStatusConfig[groupStatus];
5034
+ const StatusIcon = config.icon;
5035
+ React17.useEffect(() => {
5036
+ setIsExpanded(!hasFollowingItem);
5037
+ }, [hasFollowingItem, items.length]);
5038
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "px-1 py-1", children: [
5039
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5040
+ "button",
5041
+ {
5042
+ type: "button",
5043
+ 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",
5044
+ "aria-expanded": isExpanded,
5045
+ "aria-controls": contentId,
5046
+ onClick: () => setIsExpanded((prev) => !prev),
5047
+ children: [
5048
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex min-w-0 items-center gap-2 text-sm font-medium text-muted-foreground", children: [
5049
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5050
+ StatusIcon,
5051
+ {
5052
+ className: cn(
5053
+ "h-4 w-4 shrink-0",
5054
+ config.iconClass
5055
+ )
5056
+ }
5057
+ ),
5058
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "truncate", children: summary })
5059
+ ] }),
5060
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5061
+ import_lucide_react10.ChevronRight,
5062
+ {
5063
+ "aria-hidden": "true",
5064
+ className: cn(
5065
+ "h-4 w-4 shrink-0 text-muted-foreground transition-transform",
5066
+ isExpanded && "rotate-90"
5067
+ )
5068
+ }
5069
+ )
5070
+ ]
5071
+ }
5072
+ ),
5073
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("ul", { id: contentId, className: "mt-2 max-h-[200px] space-y-1.5 overflow-y-auto pr-1", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToolCallRow, { content: item }, item.id ?? `tool-item-${index}`)) })
5074
+ ] });
5075
+ }
5076
+
5077
+ // src/components/thread/messages/request-user-input-result-card.tsx
5078
+ var React18 = require("react");
5079
+ var import_chatkit_types4 = require("@xpert-ai/chatkit-types");
5080
+ var import_lucide_react11 = require("lucide-react");
5081
+ var import_jsx_runtime23 = require("react/jsx-runtime");
5082
+ function isRecord2(value) {
5083
+ return !!value && typeof value === "object" && !Array.isArray(value);
5084
+ }
5085
+ function readString(record, keys) {
5086
+ for (const key of keys) {
5087
+ const value = record[key];
5088
+ if (typeof value === "string" && value.trim()) {
5089
+ return value.trim();
5090
+ }
3610
5091
  }
3611
- };
3612
- var MarkdownTextImpl = ({ children }) => {
3613
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "markdown-content", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3614
- import_react_markdown.default,
5092
+ return null;
5093
+ }
5094
+ function getToolCallId(value) {
5095
+ if (!isRecord2(value)) return null;
5096
+ return readString(value, ["id"]);
5097
+ }
5098
+ function getToolCallName(value) {
5099
+ if (!isRecord2(value)) return null;
5100
+ return readString(value, ["name"]);
5101
+ }
5102
+ function pushClientToolCallsFromRecord(record, calls) {
5103
+ const clientToolCalls = record.clientToolCalls;
5104
+ if (Array.isArray(clientToolCalls)) {
5105
+ calls.push(...clientToolCalls);
5106
+ }
5107
+ }
5108
+ function collectPotentialToolCalls(messages) {
5109
+ const calls = [];
5110
+ const messageList = Array.isArray(messages) ? messages : [messages];
5111
+ for (const message of messageList) {
5112
+ const rawMessage = message;
5113
+ pushClientToolCallsFromRecord(rawMessage, calls);
5114
+ }
5115
+ return calls;
5116
+ }
5117
+ function findRequestUserInputClientToolCallById(messages, id) {
5118
+ if (!id) return null;
5119
+ return collectPotentialToolCalls(messages).find(
5120
+ (call) => getToolCallId(call) === id && getToolCallName(call) === import_chatkit_types4.REQUEST_USER_INPUT_TOOL_NAME
5121
+ ) ?? null;
5122
+ }
5123
+ function normalizeAnswer(value) {
5124
+ if (!isRecord2(value)) return null;
5125
+ const id = readString(value, ["id"]);
5126
+ const question = readString(value, ["question"]);
5127
+ const answerValue = readString(value, ["value"]);
5128
+ const type = readString(value, ["type"]);
5129
+ if (!id || !question || !answerValue || type !== "option" && type !== "other") {
5130
+ return null;
5131
+ }
5132
+ const label = readString(value, ["label"]);
5133
+ const description = readString(value, ["description"]);
5134
+ return {
5135
+ id,
5136
+ question,
5137
+ value: answerValue,
5138
+ type,
5139
+ ...label ? { label } : {},
5140
+ ...description ? { description } : {}
5141
+ };
5142
+ }
5143
+ function parseResultOutput(output) {
5144
+ let result = output;
5145
+ if (typeof output === "string") {
5146
+ try {
5147
+ result = JSON.parse(output);
5148
+ } catch {
5149
+ return null;
5150
+ }
5151
+ }
5152
+ if (!isRecord2(result) || !Array.isArray(result.answers)) {
5153
+ return null;
5154
+ }
5155
+ const answers = result.answers.map(normalizeAnswer);
5156
+ if (answers.some((answer) => answer === null)) {
5157
+ return null;
5158
+ }
5159
+ return answers;
5160
+ }
5161
+ function getRequestUserInputResultCardData(content, messages) {
5162
+ const data = isRecord2(content.data) ? content.data : null;
5163
+ if (data?.status !== "success") {
5164
+ return null;
5165
+ }
5166
+ const toolCall = findRequestUserInputClientToolCallById(messages, content.id);
5167
+ if (!toolCall) {
5168
+ return null;
5169
+ }
5170
+ const answers = parseResultOutput(data.output);
5171
+ if (!answers || answers.length === 0) {
5172
+ return null;
5173
+ }
5174
+ return {
5175
+ toolCallId: content.id,
5176
+ answers
5177
+ };
5178
+ }
5179
+ function RequestUserInputResultCard({
5180
+ result,
5181
+ className
5182
+ }) {
5183
+ const { t } = useChatkitTranslation();
5184
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5185
+ "section",
3615
5186
  {
3616
- remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
3617
- rehypePlugins: [import_rehype_katex.default],
3618
- components: defaultComponents,
3619
- children
5187
+ "aria-label": t("message.requestUserInputResult.title"),
5188
+ className: cn(
5189
+ "rounded-lg border border-border bg-muted/25 px-3 py-2.5",
5190
+ className
5191
+ ),
5192
+ children: [
5193
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "mb-2 flex items-center gap-2 text-sm font-semibold text-foreground", children: [
5194
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.CheckCircle2, { className: "h-4 w-4 text-primary" }),
5195
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: t("message.requestUserInputResult.title") })
5196
+ ] }),
5197
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "space-y-2", children: result.answers.map((answer, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5198
+ "div",
5199
+ {
5200
+ className: "rounded-md bg-background/70 px-2.5 py-2",
5201
+ children: [
5202
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-xs font-medium leading-5 text-muted-foreground", children: answer.question }),
5203
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "mt-0.5 flex min-w-0 flex-wrap items-center gap-1.5", children: [
5204
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "min-w-0 wrap-break-word text-sm font-semibold text-foreground", children: answer.label ?? answer.value }),
5205
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "rounded-full bg-muted px-1.5 py-0.5 text-[11px] font-medium text-muted-foreground", children: t(
5206
+ answer.type === "other" ? "message.requestUserInputResult.other" : "message.requestUserInputResult.option"
5207
+ ) })
5208
+ ] }),
5209
+ answer.description ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-1 text-xs leading-5 text-muted-foreground", children: answer.description }) : null
5210
+ ]
5211
+ },
5212
+ `${answer.id}-${index}`
5213
+ )) })
5214
+ ]
3620
5215
  }
3621
- ) });
3622
- };
3623
- var MarkdownText = (0, import_react6.memo)(MarkdownTextImpl);
5216
+ );
5217
+ }
3624
5218
 
3625
5219
  // src/components/thread/messages/widget.tsx
3626
5220
  var import_a2ui_react = require("@xpert-ai/a2ui-react");
3627
- var import_jsx_runtime21 = require("react/jsx-runtime");
5221
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3628
5222
  function WidgetMessage({ messageId, data }) {
3629
5223
  const widgets = Array.isArray(data.widgets) ? data.widgets : [];
3630
5224
  if (widgets.length === 0) return null;
3631
5225
  const baseSurfaceId = `widget-${messageId}`;
3632
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-3", children: widgets.map((widget, index) => {
5226
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "space-y-3", children: widgets.map((widget, index) => {
3633
5227
  const config = widget?.config;
3634
5228
  if (!config || typeof config !== "object") {
3635
5229
  return null;
3636
5230
  }
3637
5231
  const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
3638
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5232
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3639
5233
  import_a2ui_react.SurfaceRenderer,
3640
5234
  {
3641
5235
  surfaceId,
@@ -3647,58 +5241,44 @@ function WidgetMessage({ messageId, data }) {
3647
5241
  }
3648
5242
 
3649
5243
  // src/components/thread/messages/ai.tsx
3650
- var import_jsx_runtime22 = require("react/jsx-runtime");
3651
- function isTextContent(content) {
5244
+ var import_jsx_runtime25 = require("react/jsx-runtime");
5245
+ function isTextContent2(content) {
3652
5246
  return content.type === "text";
3653
5247
  }
3654
- function isReasoningContent(content) {
5248
+ function isReasoningContent2(content) {
3655
5249
  return content.type === "reasoning";
3656
5250
  }
3657
5251
  function isImageContent(content) {
3658
5252
  return content.type === "image_url";
3659
5253
  }
3660
- function isComponentContent(content) {
5254
+ function isComponentContent2(content) {
3661
5255
  return content.type === "component";
3662
5256
  }
3663
- var statusConfig = {
3664
- success: {
3665
- iconClass: "border-green-500 text-green-700",
3666
- icon: import_lucide_react9.CheckCircle2
3667
- },
3668
- fail: {
3669
- iconClass: "border-red-500 text-red-700",
3670
- icon: import_lucide_react9.XCircle
3671
- },
3672
- running: {
3673
- iconClass: "border-blue-500 text-blue-700",
3674
- icon: import_lucide_react9.Loader2
3675
- }
3676
- };
3677
- function isWidgetComponent(content) {
5257
+ function isWidgetComponent2(content) {
3678
5258
  const data = content.data;
3679
5259
  return data?.type === "Widget" && Array.isArray(data.widgets);
3680
5260
  }
3681
5261
  function isMemoryContent(content) {
3682
5262
  return content.type === "memory";
3683
5263
  }
3684
- function safeJson(value) {
5264
+ function safeJson2(value) {
3685
5265
  try {
3686
5266
  return JSON.stringify(value, null, 2);
3687
5267
  } catch {
3688
5268
  return String(value);
3689
5269
  }
3690
5270
  }
3691
- function formatDisplayValue(value) {
3692
- return typeof value === "string" ? value : safeJson(value);
5271
+ function formatDisplayValue2(value) {
5272
+ return typeof value === "string" ? value : safeJson2(value);
3693
5273
  }
3694
5274
  function ReasoningBlock({ reasoning }) {
3695
5275
  const blocks = reasoning.filter((item) => item.text?.trim());
3696
5276
  if (blocks.length === 0) return null;
3697
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5277
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3698
5278
  "div",
3699
5279
  {
3700
5280
  className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
3701
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
5281
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
3702
5282
  },
3703
5283
  item.id ?? `reasoning-${index}`
3704
5284
  )) });
@@ -3706,23 +5286,23 @@ function ReasoningBlock({ reasoning }) {
3706
5286
  function ImageBlock({ content }) {
3707
5287
  const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
3708
5288
  if (!imageUrl) {
3709
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3710
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Image" }) }),
3711
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
5289
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5290
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Image" }) }),
5291
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: safeJson2(content) })
3712
5292
  ] });
3713
5293
  }
3714
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
5294
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
3715
5295
  }
3716
5296
  function MemoryBlock({ content }) {
3717
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3718
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3719
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Memory" }),
3720
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "secondary", children: "Memory" })
5297
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5298
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5299
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Memory" }),
5300
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "secondary", children: "Memory" })
3721
5301
  ] }),
3722
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
5302
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson2(content.data ?? []) }) })
3723
5303
  ] });
3724
5304
  }
3725
- function parseStepDate(value) {
5305
+ function parseStepDate2(value) {
3726
5306
  if (value instanceof Date) {
3727
5307
  const timestamp2 = value.getTime();
3728
5308
  return Number.isNaN(timestamp2) ? null : timestamp2;
@@ -3733,7 +5313,7 @@ function parseStepDate(value) {
3733
5313
  const timestamp = Date.parse(value);
3734
5314
  return Number.isNaN(timestamp) ? null : timestamp;
3735
5315
  }
3736
- function formatStepDuration(durationMs) {
5316
+ function formatStepDuration2(durationMs) {
3737
5317
  if (durationMs < 1e3) {
3738
5318
  return `${durationMs}ms`;
3739
5319
  }
@@ -3752,28 +5332,29 @@ function formatStepDuration(durationMs) {
3752
5332
  return `${minutes}m ${seconds}s`;
3753
5333
  }
3754
5334
  function ComponentBlock({ content }) {
3755
- const [isExpanded, setIsExpanded] = React16.useState(false);
3756
- const contentRef = React16.useRef(null);
3757
- const shouldAutoScrollRef = React16.useRef(true);
3758
- const previousScrollTopRef = React16.useRef(0);
3759
- const [durationNow, setDurationNow] = React16.useState(() => Date.now());
3760
- const data = content.data ?? {};
5335
+ const { i18n: i18n2 } = useChatkitTranslation();
5336
+ const [isExpanded, setIsExpanded] = React19.useState(false);
5337
+ const contentRef = React19.useRef(null);
5338
+ const shouldAutoScrollRef = React19.useRef(true);
5339
+ const previousScrollTopRef = React19.useRef(0);
5340
+ const [durationNow, setDurationNow] = React19.useState(() => Date.now());
5341
+ const data = getToolStepData(content);
3761
5342
  const category = data.category ?? "Component";
3762
- const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
5343
+ const title = getToolActivityLabel(content, i18n2.language);
3763
5344
  const status = data.status ?? null;
3764
5345
  const message = data.message ?? null;
3765
5346
  const output = data.output ?? null;
3766
5347
  const error = data.error ?? null;
3767
5348
  const fallback = message ?? output ?? data.data ?? data;
3768
5349
  const hasOutput = message !== null || output !== null;
3769
- const createdAt = parseStepDate(data.created_date);
3770
- const endedAt = parseStepDate(data.end_date);
5350
+ const createdAt = parseStepDate2(data.created_date);
5351
+ const endedAt = parseStepDate2(data.end_date);
3771
5352
  const durationMs = createdAt === null ? null : Math.max(0, (endedAt ?? durationNow) - createdAt);
3772
- const durationLabel = durationMs === null ? null : formatStepDuration(durationMs);
3773
- React16.useEffect(() => {
5353
+ const durationLabel = durationMs === null ? null : formatStepDuration2(durationMs);
5354
+ React19.useEffect(() => {
3774
5355
  if (status === "running" && output !== null) setIsExpanded(true);
3775
5356
  }, [status, output]);
3776
- React16.useEffect(() => {
5357
+ React19.useEffect(() => {
3777
5358
  if (status !== "running" || createdAt === null || endedAt !== null) {
3778
5359
  return;
3779
5360
  }
@@ -3785,7 +5366,7 @@ function ComponentBlock({ content }) {
3785
5366
  window.clearInterval(timer);
3786
5367
  };
3787
5368
  }, [createdAt, endedAt, status]);
3788
- React16.useEffect(() => {
5369
+ React19.useEffect(() => {
3789
5370
  const element = contentRef.current;
3790
5371
  if (!element) return;
3791
5372
  previousScrollTopRef.current = element.scrollTop;
@@ -3805,7 +5386,7 @@ function ComponentBlock({ content }) {
3805
5386
  element.removeEventListener("scroll", updateAutoScrollState);
3806
5387
  };
3807
5388
  }, [isExpanded]);
3808
- React16.useEffect(() => {
5389
+ React19.useEffect(() => {
3809
5390
  if (status !== "running") {
3810
5391
  shouldAutoScrollRef.current = true;
3811
5392
  return;
@@ -3816,27 +5397,27 @@ function ComponentBlock({ content }) {
3816
5397
  }
3817
5398
  element.scrollTop = element.scrollHeight;
3818
5399
  }, [isExpanded, output, status]);
3819
- const config = status ? statusConfig[status] : null;
5400
+ const config = status ? toolStatusConfig[status] : null;
3820
5401
  const StatusIcon = config?.icon;
3821
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3822
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
3823
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
3824
- status && StatusIcon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
3825
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm truncate", children: title })
5402
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5403
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
5404
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
5405
+ status && StatusIcon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
5406
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm truncate", children: title })
3826
5407
  ] }),
3827
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
3828
- durationLabel && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
3829
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Clock3, { className: "h-3 w-3" }),
3830
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: durationLabel })
5408
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
5409
+ durationLabel && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "inline-flex items-center gap-1 text-[11px] text-muted-foreground tabular-nums", children: [
5410
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Clock3, { className: "h-3 w-3" }),
5411
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: durationLabel })
3831
5412
  ] }),
3832
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
3833
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
5413
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
5414
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3834
5415
  "button",
3835
5416
  {
3836
5417
  className: "text-muted-foreground hover:text-foreground transition-colors",
3837
5418
  "aria-label": isExpanded ? "Collapse" : "Expand",
3838
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3839
- import_lucide_react9.ChevronDown,
5419
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5420
+ import_lucide_react12.ChevronDown,
3840
5421
  {
3841
5422
  className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
3842
5423
  }
@@ -3845,55 +5426,83 @@ function ComponentBlock({ content }) {
3845
5426
  )
3846
5427
  ] })
3847
5428
  ] }),
3848
- isExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
3849
- data.input && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
3850
- error ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
5429
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
5430
+ data.input && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(data.input) }),
5431
+ error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue2(error) }) : hasOutput && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue2(fallback) })
3851
5432
  ] })
3852
5433
  ] });
3853
5434
  }
3854
5435
  function UnknownBlock({ content }) {
3855
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Card, { children: [
3856
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
3857
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardTitle, { className: "text-sm", children: "Assistant Content" }),
3858
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Badge, { variant: "outline", children: content.type ?? "unknown" })
5436
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Card, { children: [
5437
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
5438
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardTitle, { className: "text-sm", children: "Assistant Content" }),
5439
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Badge, { variant: "outline", children: content.type ?? "unknown" })
3859
5440
  ] }),
3860
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
5441
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("pre", { className: "whitespace-pre-wrap break-words", children: safeJson2(content) }) })
3861
5442
  ] });
3862
5443
  }
3863
- function renderContentItem(content, index, messageId) {
5444
+ function renderContentItem(content, index, message, lookupMessages) {
5445
+ const messageId = message.id;
3864
5446
  if (typeof content === "string") {
3865
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { children: [
3866
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content }),
3867
- ";"
3868
- ] }, `text-${index}`);
5447
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content }) }, `text-${index}`);
3869
5448
  }
3870
- if (isTextContent(content)) {
3871
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
5449
+ if (isTextContent2(content)) {
5450
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
3872
5451
  }
3873
- if (isReasoningContent(content)) {
3874
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
5452
+ if (isReasoningContent2(content)) {
5453
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
3875
5454
  }
3876
5455
  if (isImageContent(content)) {
3877
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ImageBlock, { content }) }, content.id ?? `image-${index}`);
5456
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ImageBlock, { content }) }, content.id ?? `image-${index}`);
3878
5457
  }
3879
- if (isComponentContent(content)) {
3880
- if (isWidgetComponent(content)) {
3881
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5458
+ if (isComponentContent2(content)) {
5459
+ const requestUserInputResult = getRequestUserInputResultCardData(
5460
+ content,
5461
+ lookupMessages
5462
+ );
5463
+ if (requestUserInputResult) {
5464
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(RequestUserInputResultCard, { result: requestUserInputResult }) }, content.id ?? `request-user-input-result-${index}`);
3882
5465
  }
3883
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
5466
+ if (isWidgetComponent2(content)) {
5467
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
5468
+ }
5469
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
3884
5470
  }
3885
5471
  if (isMemoryContent(content)) {
3886
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5472
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
5473
+ }
5474
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5475
+ }
5476
+ function renderContentUnit(unit, message, lookupMessages, hasFollowingItem) {
5477
+ if (unit.type === "item") {
5478
+ return renderContentItem(unit.item, unit.index, message, lookupMessages);
3887
5479
  }
3888
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
5480
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5481
+ "div",
5482
+ {
5483
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ToolComponentGroup, { items: unit.items, hasFollowingItem })
5484
+ },
5485
+ `tool-group-${unit.startIndex}-${unit.items[0]?.id ?? "tool"}-${unit.items.length}`
5486
+ );
3889
5487
  }
3890
- function renderContent(content, messageId) {
5488
+ function renderContent(message, lookupMessages) {
5489
+ const content = message.content;
3891
5490
  if (typeof content === "string") {
3892
5491
  if (!content.trim()) return null;
3893
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MarkdownText, { children: content });
5492
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(MarkdownText, { children: content });
3894
5493
  }
3895
5494
  if (!Array.isArray(content) || content.length === 0) return null;
3896
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
5495
+ const renderUnits = buildToolComponentRenderUnits(content, {
5496
+ shouldGroupComponent: (item) => getRequestUserInputResultCardData(item, lookupMessages) === null
5497
+ });
5498
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-3", children: renderUnits.map(
5499
+ (unit, index) => renderContentUnit(
5500
+ unit,
5501
+ message,
5502
+ lookupMessages,
5503
+ index < renderUnits.length - 1
5504
+ )
5505
+ ) });
3897
5506
  }
3898
5507
  function AssistantStreamingIndicator({
3899
5508
  status,
@@ -3905,23 +5514,24 @@ function AssistantStreamingIndicator({
3905
5514
  thinking: t("message.thinking"),
3906
5515
  answering: t("message.answering")
3907
5516
  };
3908
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
3909
- status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
3910
- status === "thinking" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3911
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
3912
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
3913
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
5517
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
5518
+ status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
5519
+ status === "thinking" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5520
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
5521
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
5522
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
3914
5523
  ] }),
3915
- status === "answering" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
3916
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
3917
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
3918
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
5524
+ status === "answering" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
5526
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
5527
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
3919
5528
  ] }),
3920
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: labelMap[status] })
5529
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: labelMap[status] })
3921
5530
  ] });
3922
5531
  }
3923
5532
  function AssistantMessage({
3924
5533
  message,
5534
+ messages,
3925
5535
  className,
3926
5536
  isStreaming = false,
3927
5537
  streamingStatus
@@ -3930,43 +5540,44 @@ function AssistantMessage({
3930
5540
  const hasContent = hasRenderableMessageContent(message.content);
3931
5541
  const hasReasoning = hasRenderableReasoning(message.reasoning);
3932
5542
  const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
3933
- const answerNode = renderContent(message.content, message.id);
3934
- const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
5543
+ const lookupMessages = messages?.length ? messages : [message];
5544
+ const answerNode = renderContent(message, lookupMessages);
5545
+ const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
3935
5546
  if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
3936
5547
  const streamingClass = isStreaming ? "streaming-active" : "";
3937
5548
  if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
3938
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
5549
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
3939
5550
  }
3940
5551
  if (hasContent && hasReasoning) {
3941
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
3942
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
5552
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
5553
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3943
5554
  Tabs,
3944
5555
  {
3945
5556
  defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
3946
5557
  className: "w-full",
3947
5558
  children: [
3948
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(TabsList, { className: "", children: [
3949
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { value: "answer", children: t("message.answer") }),
3950
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
5559
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(TabsList, { className: "", children: [
5560
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsTrigger, { value: "answer", children: t("message.answer") }),
5561
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
3951
5562
  ] }),
3952
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
3953
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
5563
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
5564
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
3954
5565
  ]
3955
5566
  }
3956
5567
  ),
3957
- resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5568
+ resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3958
5569
  ] });
3959
5570
  }
3960
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
5571
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
3961
5572
  hasReasoning ? reasoningNode : answerNode,
3962
- resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
5573
+ resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
3963
5574
  ] });
3964
5575
  }
3965
5576
 
3966
5577
  // src/components/thread/MessageActions.tsx
3967
- var React17 = __toESM(require("react"), 1);
3968
- var import_lucide_react10 = require("lucide-react");
3969
- var import_jsx_runtime23 = require("react/jsx-runtime");
5578
+ var React20 = __toESM(require("react"), 1);
5579
+ var import_lucide_react13 = require("lucide-react");
5580
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3970
5581
  function MessageActions({
3971
5582
  content,
3972
5583
  isAssistant = false,
@@ -3975,7 +5586,7 @@ function MessageActions({
3975
5586
  className
3976
5587
  }) {
3977
5588
  const { t } = useChatkitTranslation();
3978
- const [copied, setCopied] = React17.useState(false);
5589
+ const [copied, setCopied] = React20.useState(false);
3979
5590
  const handleCopy = async () => {
3980
5591
  try {
3981
5592
  await navigator.clipboard.writeText(content);
@@ -3988,7 +5599,7 @@ function MessageActions({
3988
5599
  if (isStreaming) {
3989
5600
  return null;
3990
5601
  }
3991
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
5602
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3992
5603
  "div",
3993
5604
  {
3994
5605
  className: cn(
@@ -3996,7 +5607,7 @@ function MessageActions({
3996
5607
  className
3997
5608
  ),
3998
5609
  children: [
3999
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5610
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4000
5611
  "button",
4001
5612
  {
4002
5613
  type: "button",
@@ -4006,17 +5617,17 @@ function MessageActions({
4006
5617
  copied && "text-green-500"
4007
5618
  ),
4008
5619
  title: copied ? t("messageActions.copied") : t("messageActions.copy"),
4009
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Copy, { size: 14 })
5620
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Copy, { size: 14 })
4010
5621
  }
4011
5622
  ),
4012
- isAssistant && onRetry && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
5623
+ isAssistant && onRetry && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4013
5624
  "button",
4014
5625
  {
4015
5626
  type: "button",
4016
5627
  onClick: onRetry,
4017
5628
  className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
4018
5629
  title: t("messageActions.regenerate"),
4019
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.RefreshCw, { size: 14 })
5630
+ children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.RefreshCw, { size: 14 })
4020
5631
  }
4021
5632
  )
4022
5633
  ]
@@ -4025,20 +5636,20 @@ function MessageActions({
4025
5636
  }
4026
5637
 
4027
5638
  // src/components/thread/StartScreen.tsx
4028
- var React18 = require("react");
4029
- var import_lucide_react11 = require("lucide-react");
4030
- var import_jsx_runtime24 = require("react/jsx-runtime");
5639
+ var React21 = require("react");
5640
+ var import_lucide_react14 = require("lucide-react");
5641
+ var import_jsx_runtime27 = require("react/jsx-runtime");
4031
5642
  function getIconComponent2(icon) {
4032
5643
  const iconMap = {
4033
- "circle-question": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.HelpCircle, { size: 20 }),
4034
- "lightbulb": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Lightbulb, { size: 20 }),
4035
- "sparkle": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Sparkles, { size: 20 }),
4036
- "write": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Pencil, { size: 20 }),
4037
- "search": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Search, { size: 20 }),
4038
- "globe": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Globe, { size: 20 }),
4039
- "book-open": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.BookOpen, { size: 20 }),
4040
- "compass": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Compass, { size: 20 }),
4041
- "bolt": /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Zap, { size: 20 })
5644
+ "circle-question": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.HelpCircle, { size: 20 }),
5645
+ "lightbulb": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Lightbulb, { size: 20 }),
5646
+ "sparkle": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Sparkles, { size: 20 }),
5647
+ "write": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Pencil, { size: 20 }),
5648
+ "search": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Search, { size: 20 }),
5649
+ "globe": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Globe, { size: 20 }),
5650
+ "book-open": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.BookOpen, { size: 20 }),
5651
+ "compass": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Compass, { size: 20 }),
5652
+ "bolt": /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Zap, { size: 20 })
4042
5653
  };
4043
5654
  return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
4044
5655
  }
@@ -4046,9 +5657,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4046
5657
  const { t } = useChatkitTranslation();
4047
5658
  const greeting = startScreen?.greeting ?? t("startScreen.greeting");
4048
5659
  const prompts = startScreen?.prompts ?? [];
4049
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
4050
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mb-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
4051
- prompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
5660
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
5661
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mb-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
5662
+ prompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4052
5663
  "button",
4053
5664
  {
4054
5665
  type: "button",
@@ -4059,8 +5670,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4059
5670
  "focus:outline-none focus:ring-2 focus:ring-primary/20"
4060
5671
  ),
4061
5672
  children: [
4062
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
4063
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-sm font-medium text-foreground", children: item.label })
5673
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
5674
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-sm font-medium text-foreground", children: item.label })
4064
5675
  ]
4065
5676
  },
4066
5677
  `prompt-${index}`
@@ -4069,13 +5680,13 @@ function StartScreen({ startScreen, onPromptClick, className }) {
4069
5680
  }
4070
5681
 
4071
5682
  // src/components/ui/chatkit-avatar.tsx
4072
- var React20 = require("react");
5683
+ var React23 = require("react");
4073
5684
 
4074
5685
  // src/components/ui/avatar.tsx
4075
- var React19 = __toESM(require("react"), 1);
5686
+ var React22 = __toESM(require("react"), 1);
4076
5687
  var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
4077
- var import_jsx_runtime25 = require("react/jsx-runtime");
4078
- var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5688
+ var import_jsx_runtime28 = require("react/jsx-runtime");
5689
+ var Avatar = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4079
5690
  AvatarPrimitive.Root,
4080
5691
  {
4081
5692
  ref,
@@ -4087,7 +5698,7 @@ var Avatar = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
4087
5698
  }
4088
5699
  ));
4089
5700
  Avatar.displayName = AvatarPrimitive.Root.displayName;
4090
- var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5701
+ var AvatarImage = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4091
5702
  AvatarPrimitive.Image,
4092
5703
  {
4093
5704
  ref,
@@ -4096,7 +5707,7 @@ var AvatarImage = React19.forwardRef(({ className, ...props }, ref) => /* @__PUR
4096
5707
  }
4097
5708
  ));
4098
5709
  AvatarImage.displayName = AvatarPrimitive.Image.displayName;
4099
- var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5710
+ var AvatarFallback = React22.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4100
5711
  AvatarPrimitive.Fallback,
4101
5712
  {
4102
5713
  ref,
@@ -4110,7 +5721,7 @@ var AvatarFallback = React19.forwardRef(({ className, ...props }, ref) => /* @__
4110
5721
  AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
4111
5722
 
4112
5723
  // src/components/ui/chatkit-avatar.tsx
4113
- var import_jsx_runtime26 = require("react/jsx-runtime");
5724
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4114
5725
  function asRecord(value) {
4115
5726
  return value && typeof value === "object" ? value : null;
4116
5727
  }
@@ -4183,21 +5794,21 @@ function ChatkitAvatar({
4183
5794
  const fallbackStyle = {
4184
5795
  ...avatar?.background ? { background: avatar.background } : {}
4185
5796
  };
4186
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
4187
- avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
4188
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5797
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
5798
+ avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
5799
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4189
5800
  AvatarFallback,
4190
5801
  {
4191
5802
  className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
4192
5803
  style: fallbackStyle,
4193
- children: emojiCharacter ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
5804
+ children: emojiCharacter ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
4194
5805
  }
4195
5806
  )
4196
5807
  ] });
4197
5808
  }
4198
5809
 
4199
5810
  // src/hooks/useThreads.ts
4200
- var React21 = __toESM(require("react"), 1);
5811
+ var React24 = __toESM(require("react"), 1);
4201
5812
  var DEFAULT_LIMIT = 50;
4202
5813
  var getThreadTitle = (threadRecord) => {
4203
5814
  const title = threadRecord.title?.trim();
@@ -4235,16 +5846,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
4235
5846
  isReady,
4236
5847
  isLoading: isStreamLoading
4237
5848
  } = useStreamContext();
4238
- const [threadRecords, setThreadRecords] = React21.useState([]);
4239
- const [isLoading, setIsLoading] = React21.useState(false);
4240
- const [error, setError] = React21.useState(null);
4241
- const upsertThreadRecord = React21.useCallback((threadRecord) => {
5849
+ const [threadRecords, setThreadRecords] = React24.useState([]);
5850
+ const [isLoading, setIsLoading] = React24.useState(false);
5851
+ const [error, setError] = React24.useState(null);
5852
+ const upsertThreadRecord = React24.useCallback((threadRecord) => {
4242
5853
  setThreadRecords((prev) => {
4243
5854
  const next = prev.filter((item) => item.id !== threadRecord.id);
4244
5855
  return sortThreadRecords([threadRecord, ...next]);
4245
5856
  });
4246
5857
  }, []);
4247
- const refreshThreads = React21.useCallback(async () => {
5858
+ const refreshThreads = React24.useCallback(async () => {
4248
5859
  setIsLoading(true);
4249
5860
  setError(null);
4250
5861
  try {
@@ -4260,7 +5871,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4260
5871
  setIsLoading(false);
4261
5872
  }
4262
5873
  }, [client, limit, assistantId]);
4263
- const createThread = React21.useCallback(
5874
+ const createThread = React24.useCallback(
4264
5875
  async (input) => {
4265
5876
  setError(null);
4266
5877
  const payload = {};
@@ -4274,7 +5885,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4274
5885
  },
4275
5886
  [client, upsertThreadRecord]
4276
5887
  );
4277
- const updateThread = React21.useCallback(
5888
+ const updateThread = React24.useCallback(
4278
5889
  async (recordId, payload) => {
4279
5890
  setError(null);
4280
5891
  const updated = await client.conversations.update(recordId, payload);
@@ -4283,7 +5894,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4283
5894
  },
4284
5895
  [client, upsertThreadRecord]
4285
5896
  );
4286
- const deleteThread = React21.useCallback(
5897
+ const deleteThread = React24.useCallback(
4287
5898
  async (recordId) => {
4288
5899
  setError(null);
4289
5900
  await client.conversations.delete(recordId);
@@ -4291,11 +5902,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
4291
5902
  },
4292
5903
  [client]
4293
5904
  );
4294
- React21.useEffect(() => {
5905
+ React24.useEffect(() => {
4295
5906
  if (!isReady) return;
4296
5907
  void refreshThreads();
4297
5908
  }, [refreshThreads, isReady]);
4298
- React21.useEffect(() => {
5909
+ React24.useEffect(() => {
4299
5910
  if (!threadId || !isStreamLoading) return;
4300
5911
  const now = (/* @__PURE__ */ new Date()).toISOString();
4301
5912
  const busyStatus = "busy";
@@ -4316,7 +5927,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4316
5927
  return changed ? sortThreadRecords(next) : prev;
4317
5928
  });
4318
5929
  }, [threadId, isStreamLoading]);
4319
- React21.useEffect(() => {
5930
+ React24.useEffect(() => {
4320
5931
  if (!isReady || !threadId || isStreamLoading) return;
4321
5932
  let cancelled = false;
4322
5933
  void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
@@ -4330,7 +5941,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
4330
5941
  cancelled = true;
4331
5942
  };
4332
5943
  }, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
4333
- const threads = React21.useMemo(
5944
+ const threads = React24.useMemo(
4334
5945
  () => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
4335
5946
  [threadRecords]
4336
5947
  );
@@ -4347,10 +5958,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
4347
5958
  }
4348
5959
 
4349
5960
  // src/components/thread/context-usage-indicator.tsx
4350
- var React22 = __toESM(require("react"), 1);
5961
+ var React25 = __toESM(require("react"), 1);
4351
5962
 
4352
5963
  // src/components/ui/progress-circle.tsx
4353
- var import_jsx_runtime27 = (
5964
+ var import_jsx_runtime30 = (
4354
5965
  // biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
4355
5966
  // biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
4356
5967
  require("react/jsx-runtime")
@@ -4374,7 +5985,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4374
5985
  fill: "none",
4375
5986
  strokeWidth
4376
5987
  };
4377
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
5988
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4378
5989
  "svg",
4379
5990
  {
4380
5991
  role: "progressbar",
@@ -4385,8 +5996,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4385
5996
  "aria-valuemax": 100,
4386
5997
  ...restSvgProps,
4387
5998
  children: [
4388
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("circle", { ...commonParams, className: "stroke-current/25" }),
4389
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
5999
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { ...commonParams, className: "stroke-current/25" }),
6000
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4390
6001
  "circle",
4391
6002
  {
4392
6003
  ...commonParams,
@@ -4404,7 +6015,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
4404
6015
  };
4405
6016
 
4406
6017
  // src/components/thread/context-usage-indicator.tsx
4407
- var import_jsx_runtime28 = require("react/jsx-runtime");
6018
+ var import_jsx_runtime31 = require("react/jsx-runtime");
4408
6019
  var kNumberFormatter = new Intl.NumberFormat("en-US", {
4409
6020
  minimumFractionDigits: 0,
4410
6021
  maximumFractionDigits: 1
@@ -4437,20 +6048,20 @@ function ContextUsageIndicator({
4437
6048
  }) {
4438
6049
  const { t } = useChatkitTranslation();
4439
6050
  const stream = useStreamContext();
4440
- const [maxContextSize, setMaxContextSize] = React22.useState(null);
4441
- const [usedContextSize, setUsedContextSize] = React22.useState(null);
4442
- const [assistantAgentKey, setAssistantAgentKey] = React22.useState(null);
4443
- const latestRealtimeUsageRef = React22.useRef({
6051
+ const [maxContextSize, setMaxContextSize] = React25.useState(null);
6052
+ const [usedContextSize, setUsedContextSize] = React25.useState(null);
6053
+ const [assistantAgentKey, setAssistantAgentKey] = React25.useState(null);
6054
+ const latestRealtimeUsageRef = React25.useRef({
4444
6055
  threadId: null,
4445
6056
  agentKey: null,
4446
6057
  usedTokens: null
4447
6058
  });
4448
- const realtimeUsage = React22.useMemo(
6059
+ const realtimeUsage = React25.useMemo(
4449
6060
  () => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
4450
6061
  [assistantAgentKey, stream.contextUsageByAgentKey]
4451
6062
  );
4452
6063
  const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
4453
- React22.useEffect(() => {
6064
+ React25.useEffect(() => {
4454
6065
  if (!stream.client || !stream.assistantId) {
4455
6066
  setMaxContextSize(null);
4456
6067
  setAssistantAgentKey(null);
@@ -4470,18 +6081,18 @@ function ContextUsageIndicator({
4470
6081
  cancelled = true;
4471
6082
  };
4472
6083
  }, [stream.client, stream.assistantId]);
4473
- React22.useEffect(() => {
6084
+ React25.useEffect(() => {
4474
6085
  latestRealtimeUsageRef.current = {
4475
6086
  threadId: stream.threadId ?? null,
4476
6087
  agentKey: assistantAgentKey,
4477
6088
  usedTokens: realtimeUsedContextSize
4478
6089
  };
4479
6090
  }, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
4480
- React22.useEffect(() => {
6091
+ React25.useEffect(() => {
4481
6092
  if (realtimeUsedContextSize == null) return;
4482
6093
  setUsedContextSize(realtimeUsedContextSize);
4483
6094
  }, [realtimeUsedContextSize]);
4484
- React22.useEffect(() => {
6095
+ React25.useEffect(() => {
4485
6096
  if (!stream.client) {
4486
6097
  setUsedContextSize(null);
4487
6098
  return;
@@ -4546,8 +6157,8 @@ function ContextUsageIndicator({
4546
6157
  });
4547
6158
  const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
4548
6159
  const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
4549
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Tooltip, { children: [
4550
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
6160
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Tooltip, { children: [
6161
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4551
6162
  "button",
4552
6163
  {
4553
6164
  type: "button",
@@ -4556,19 +6167,19 @@ function ContextUsageIndicator({
4556
6167
  className
4557
6168
  ),
4558
6169
  "aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
4559
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
6170
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
4560
6171
  }
4561
6172
  ) }),
4562
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
4563
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
4564
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
4565
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "text-sm font-semibold", children: usageTokensLabel })
6173
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
6174
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
6175
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
6176
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "text-sm font-semibold", children: usageTokensLabel })
4566
6177
  ] })
4567
6178
  ] });
4568
6179
  }
4569
6180
 
4570
6181
  // src/components/chat.tsx
4571
- var import_jsx_runtime29 = require("react/jsx-runtime");
6182
+ var import_jsx_runtime32 = require("react/jsx-runtime");
4572
6183
  var import_meta2 = {};
4573
6184
  var defaultApiUrl2 = import_meta2.env.VITE_XPERTAI_API_URL;
4574
6185
  var COMPOSER_INPUT_MAX_HEIGHT = 128;
@@ -4660,8 +6271,8 @@ function ReferenceChip({
4660
6271
  }) {
4661
6272
  const metaLine = getReferenceMetaLine(reference);
4662
6273
  const isComposer = variant === "composer";
4663
- const Icon = reference.type === "quote" ? import_lucide_react12.Quote : reference.type === "image" ? import_lucide_react12.ImageIcon : import_lucide_react12.FileText;
4664
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
6274
+ const Icon = reference.type === "quote" ? import_lucide_react15.Quote : reference.type === "image" ? import_lucide_react15.ImageIcon : import_lucide_react15.FileText;
6275
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
4665
6276
  "div",
4666
6277
  {
4667
6278
  className: cn(
@@ -4670,7 +6281,7 @@ function ReferenceChip({
4670
6281
  ),
4671
6282
  title: getReferenceTitle(reference),
4672
6283
  children: [
4673
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6284
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4674
6285
  Icon,
4675
6286
  {
4676
6287
  size: isComposer ? 14 : 12,
@@ -4680,8 +6291,8 @@ function ReferenceChip({
4680
6291
  )
4681
6292
  }
4682
6293
  ),
4683
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0 flex-1", children: [
4684
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6294
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "min-w-0 flex-1", children: [
6295
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4685
6296
  "div",
4686
6297
  {
4687
6298
  className: cn(
@@ -4691,7 +6302,7 @@ function ReferenceChip({
4691
6302
  children: getReferenceLabel(reference)
4692
6303
  }
4693
6304
  ),
4694
- metaLine && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6305
+ metaLine && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4695
6306
  "div",
4696
6307
  {
4697
6308
  className: cn(
@@ -4702,7 +6313,7 @@ function ReferenceChip({
4702
6313
  }
4703
6314
  )
4704
6315
  ] }),
4705
- onRemove && removeLabel && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
6316
+ onRemove && removeLabel && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4706
6317
  "button",
4707
6318
  {
4708
6319
  type: "button",
@@ -4713,7 +6324,7 @@ function ReferenceChip({
4713
6324
  ),
4714
6325
  title: removeLabel,
4715
6326
  "aria-label": removeLabel,
4716
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
6327
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
4717
6328
  }
4718
6329
  )
4719
6330
  ]
@@ -4737,20 +6348,20 @@ function Chat({
4737
6348
  const { setStream } = useStreamManager();
4738
6349
  const stream = useStreamContext();
4739
6350
  const { theme } = useTheme();
4740
- const [isHistoryLoading, setIsHistoryLoading] = React23.useState(false);
4741
- const [historyError, setHistoryError] = React23.useState(null);
4742
- const [assistantName, setAssistantName] = React23.useState(null);
4743
- const [assistantAvatar, setAssistantAvatar] = React23.useState(null);
6351
+ const [isHistoryLoading, setIsHistoryLoading] = React26.useState(false);
6352
+ const [historyError, setHistoryError] = React26.useState(null);
6353
+ const [assistantName, setAssistantName] = React26.useState(null);
6354
+ const [assistantAvatar, setAssistantAvatar] = React26.useState(null);
4744
6355
  const LOADING_DOTS_MIN_DURATION = 800;
4745
6356
  const STREAMING_STATUS_REFRESH_MS = 250;
4746
- const [showLoadingDots, setShowLoadingDots] = React23.useState(false);
4747
- const [streamingNow, setStreamingNow] = React23.useState(() => Date.now());
4748
- const loadingStartTimeRef = React23.useRef(null);
4749
- const lastStreamOutputAtRef = React23.useRef(null);
4750
- React23.useEffect(() => {
6357
+ const [showLoadingDots, setShowLoadingDots] = React26.useState(false);
6358
+ const [streamingNow, setStreamingNow] = React26.useState(() => Date.now());
6359
+ const loadingStartTimeRef = React26.useRef(null);
6360
+ const lastStreamOutputAtRef = React26.useRef(null);
6361
+ React26.useEffect(() => {
4751
6362
  setStream(stream);
4752
6363
  }, [setStream, stream]);
4753
- React23.useEffect(() => {
6364
+ React26.useEffect(() => {
4754
6365
  if (stream.isLoading) {
4755
6366
  if (!loadingStartTimeRef.current) {
4756
6367
  loadingStartTimeRef.current = Date.now();
@@ -4773,7 +6384,7 @@ function Chat({
4773
6384
  }
4774
6385
  }
4775
6386
  }, [stream.isLoading]);
4776
- React23.useEffect(() => {
6387
+ React26.useEffect(() => {
4777
6388
  if (!stream.isLoading) {
4778
6389
  lastStreamOutputAtRef.current = null;
4779
6390
  setStreamingNow(Date.now());
@@ -4783,7 +6394,7 @@ function Chat({
4783
6394
  lastStreamOutputAtRef.current = now;
4784
6395
  setStreamingNow(now);
4785
6396
  }, [stream.messages, stream.isLoading]);
4786
- React23.useEffect(() => {
6397
+ React26.useEffect(() => {
4787
6398
  if (!stream.isLoading) {
4788
6399
  return;
4789
6400
  }
@@ -4792,53 +6403,55 @@ function Chat({
4792
6403
  }, STREAMING_STATUS_REFRESH_MS);
4793
6404
  return () => window.clearInterval(timer);
4794
6405
  }, [stream.isLoading]);
4795
- const [draft, setDraft] = React23.useState("");
4796
- const [selectedTool, setSelectedTool] = React23.useState(
6406
+ const [draft, setDraft] = React26.useState("");
6407
+ const [selectedTool, setSelectedTool] = React26.useState(
4797
6408
  null
4798
6409
  );
4799
- const [attachments, setAttachments] = React23.useState([]);
4800
- const [references, setReferences] = React23.useState([]);
4801
- const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React23.useState(false);
4802
- const [quoteSelection, setQuoteSelection] = React23.useState(null);
4803
- const [isAtBottom, setIsAtBottom] = React23.useState(true);
4804
- const [hasUpdatesBelow, setHasUpdatesBelow] = React23.useState(false);
6410
+ const [planModeEnabled, setPlanModeEnabled] = React26.useState(false);
6411
+ const [attachments, setAttachments] = React26.useState([]);
6412
+ const [references, setReferences] = React26.useState([]);
6413
+ const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React26.useState(false);
6414
+ const [quoteSelection, setQuoteSelection] = React26.useState(null);
6415
+ const [isAtBottom, setIsAtBottom] = React26.useState(true);
6416
+ const [hasUpdatesBelow, setHasUpdatesBelow] = React26.useState(false);
4805
6417
  const {
4806
6418
  threads,
4807
6419
  deleteThread,
4808
6420
  refreshThreads,
4809
6421
  isLoading: isThreadsLoading
4810
6422
  } = useThreads();
4811
- const viewportRef = React23.useRef(null);
4812
- const fileInputRef = React23.useRef(null);
4813
- const composerInputRef = React23.useRef(null);
4814
- const shouldAutoScrollRef = React23.useRef(true);
4815
- const forceFollowRef = React23.useRef(false);
4816
- const previousMessageCountRef = React23.useRef(0);
4817
- const previousScrollTopRef = React23.useRef(0);
4818
- const autoScrollFrameRef = React23.useRef(null);
4819
- const isPointerDownRef = React23.useRef(false);
4820
- const lastTouchYRef = React23.useRef(null);
6423
+ const viewportRef = React26.useRef(null);
6424
+ const fileInputRef = React26.useRef(null);
6425
+ const composerInputRef = React26.useRef(null);
6426
+ const shouldAutoScrollRef = React26.useRef(true);
6427
+ const forceFollowRef = React26.useRef(false);
6428
+ const previousMessageCountRef = React26.useRef(0);
6429
+ const previousScrollTopRef = React26.useRef(0);
6430
+ const autoScrollFrameRef = React26.useRef(null);
6431
+ const isPointerDownRef = React26.useRef(false);
6432
+ const lastTouchYRef = React26.useRef(null);
4821
6433
  const resolvedTitle = title ?? t("chat.title");
4822
6434
  const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
4823
6435
  const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
4824
- const messages = React23.useMemo(
6436
+ const messages = React26.useMemo(
4825
6437
  () => stream.messages ?? [],
4826
6438
  [stream.messages]
4827
6439
  );
4828
6440
  const trimmedDraft = draft.trim();
4829
6441
  const hasReferences = references.length > 0;
4830
- const pendingFollowUps = React23.useMemo(
6442
+ const pendingFollowUps = React26.useMemo(
4831
6443
  () => [...stream.pendingFollowUps ?? []].sort(
4832
6444
  (a, b) => a.createdAt - b.createdAt
4833
6445
  ),
4834
6446
  [stream.pendingFollowUps]
4835
6447
  );
4836
6448
  const hasPendingFollowUps = pendingFollowUps.length > 0;
4837
- const clearQuoteSelection = React23.useCallback(() => {
6449
+ const hasPendingRequestUserInput = Boolean(stream.pendingRequestUserInput);
6450
+ const clearQuoteSelection = React26.useCallback(() => {
4838
6451
  setQuoteSelection(null);
4839
6452
  }, []);
4840
6453
  useParentMessenger({
4841
- onSetComposerValue: React23.useCallback(
6454
+ onSetComposerValue: React26.useCallback(
4842
6455
  (payload) => {
4843
6456
  if (!payload) {
4844
6457
  return;
@@ -4861,11 +6474,11 @@ function Chat({
4861
6474
  },
4862
6475
  [composer?.tools]
4863
6476
  ),
4864
- onFocusComposer: React23.useCallback(() => {
6477
+ onFocusComposer: React26.useCallback(() => {
4865
6478
  composerInputRef.current?.focus();
4866
6479
  }, [])
4867
6480
  });
4868
- const syncQuoteSelection = React23.useCallback(() => {
6481
+ const syncQuoteSelection = React26.useCallback(() => {
4869
6482
  if (typeof window === "undefined") {
4870
6483
  clearQuoteSelection();
4871
6484
  return;
@@ -4910,23 +6523,23 @@ function Chat({
4910
6523
  left
4911
6524
  });
4912
6525
  }, [clearQuoteSelection]);
4913
- const cancelPendingAutoScroll = React23.useCallback(() => {
6526
+ const cancelPendingAutoScroll = React26.useCallback(() => {
4914
6527
  if (autoScrollFrameRef.current !== null) {
4915
6528
  cancelAnimationFrame(autoScrollFrameRef.current);
4916
6529
  autoScrollFrameRef.current = null;
4917
6530
  }
4918
6531
  }, []);
4919
- const disableAutoFollow = React23.useCallback(() => {
6532
+ const disableAutoFollow = React26.useCallback(() => {
4920
6533
  forceFollowRef.current = false;
4921
6534
  shouldAutoScrollRef.current = false;
4922
6535
  cancelPendingAutoScroll();
4923
6536
  }, [cancelPendingAutoScroll]);
4924
- const enableAutoFollow = React23.useCallback(() => {
6537
+ const enableAutoFollow = React26.useCallback(() => {
4925
6538
  forceFollowRef.current = true;
4926
6539
  shouldAutoScrollRef.current = true;
4927
6540
  setHasUpdatesBelow(false);
4928
6541
  }, []);
4929
- const scrollToBottom = React23.useCallback(
6542
+ const scrollToBottom = React26.useCallback(
4930
6543
  (smooth = false, force = false) => {
4931
6544
  if (force) {
4932
6545
  enableAutoFollow();
@@ -4948,7 +6561,7 @@ function Chat({
4948
6561
  },
4949
6562
  [cancelPendingAutoScroll, enableAutoFollow]
4950
6563
  );
4951
- React23.useEffect(() => {
6564
+ React26.useEffect(() => {
4952
6565
  const viewport = viewportRef.current;
4953
6566
  if (!viewport) return;
4954
6567
  previousScrollTopRef.current = viewport.scrollTop;
@@ -5029,14 +6642,14 @@ function Chat({
5029
6642
  window.removeEventListener("pointercancel", stopPointerTracking);
5030
6643
  };
5031
6644
  }, [cancelPendingAutoScroll, disableAutoFollow]);
5032
- React23.useEffect(() => {
6645
+ React26.useEffect(() => {
5033
6646
  shouldAutoScrollRef.current = true;
5034
6647
  forceFollowRef.current = false;
5035
6648
  previousScrollTopRef.current = 0;
5036
6649
  setIsAtBottom(true);
5037
6650
  setHasUpdatesBelow(false);
5038
6651
  }, [stream.threadId]);
5039
- React23.useEffect(() => {
6652
+ React26.useEffect(() => {
5040
6653
  const messageCountChanged = messages.length !== previousMessageCountRef.current;
5041
6654
  previousMessageCountRef.current = messages.length;
5042
6655
  if (!shouldAutoScrollRef.current) {
@@ -5055,7 +6668,7 @@ function Chat({
5055
6668
  clientSecret: effectiveClientSecret
5056
6669
  });
5057
6670
  const missingConfig = Boolean(missingConfigKind);
5058
- const missingConfigShortMessage = React23.useMemo(() => {
6671
+ const missingConfigShortMessage = React26.useMemo(() => {
5059
6672
  switch (missingConfigKind) {
5060
6673
  case "apiUrl":
5061
6674
  return t("chat.missingApiUrlShort");
@@ -5067,7 +6680,7 @@ function Chat({
5067
6680
  return t("chat.missingConfigShort");
5068
6681
  }
5069
6682
  }, [missingConfigKind, t]);
5070
- const missingConfigDetailMessage = React23.useMemo(() => {
6683
+ const missingConfigDetailMessage = React26.useMemo(() => {
5071
6684
  switch (missingConfigKind) {
5072
6685
  case "apiUrl":
5073
6686
  return t("chat.missingApiUrlDetail");
@@ -5081,8 +6694,8 @@ function Chat({
5081
6694
  }, [missingConfigKind, t]);
5082
6695
  const showMissingConfig = !isClientSecretInitializing && missingConfig;
5083
6696
  const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
5084
- const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
5085
- const resizeComposerInput = React23.useCallback(() => {
6697
+ const isSendDisabled = !trimmedDraft && !hasReferences || hasPendingRequestUserInput || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
6698
+ const resizeComposerInput = React26.useCallback(() => {
5086
6699
  const textarea = composerInputRef.current;
5087
6700
  if (!textarea) {
5088
6701
  return;
@@ -5095,16 +6708,16 @@ function Chat({
5095
6708
  textarea.style.height = `${nextHeight}px`;
5096
6709
  textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
5097
6710
  }, []);
5098
- React23.useEffect(() => {
6711
+ React26.useEffect(() => {
5099
6712
  resizeComposerInput();
5100
6713
  }, [draft, resizeComposerInput]);
5101
- React23.useEffect(() => {
6714
+ React26.useEffect(() => {
5102
6715
  document.addEventListener("selectionchange", syncQuoteSelection);
5103
6716
  return () => {
5104
6717
  document.removeEventListener("selectionchange", syncQuoteSelection);
5105
6718
  };
5106
6719
  }, [syncQuoteSelection]);
5107
- React23.useEffect(() => {
6720
+ React26.useEffect(() => {
5108
6721
  const viewport = viewportRef.current;
5109
6722
  if (!viewport) {
5110
6723
  return;
@@ -5121,14 +6734,14 @@ function Chat({
5121
6734
  window.removeEventListener("resize", handleViewportScroll);
5122
6735
  };
5123
6736
  }, [clearQuoteSelection]);
5124
- React23.useEffect(() => {
6737
+ React26.useEffect(() => {
5125
6738
  clearQuoteSelection();
5126
6739
  }, [messages.length, stream.threadId, clearQuoteSelection]);
5127
- React23.useEffect(() => {
6740
+ React26.useEffect(() => {
5128
6741
  if (missingConfig) return;
5129
6742
  void refreshThreads();
5130
6743
  }, [missingConfig, refreshThreads]);
5131
- React23.useEffect(() => {
6744
+ React26.useEffect(() => {
5132
6745
  if (missingConfig || !stream.client || !stream.assistantId) {
5133
6746
  setAssistantName(null);
5134
6747
  setAssistantAvatar(null);
@@ -5159,7 +6772,7 @@ function Chat({
5159
6772
  mimetype: a.storageFile?.mimetype ?? a.file.type,
5160
6773
  size: a.storageFile?.size ?? a.file.size
5161
6774
  }));
5162
- const submitDraft = React23.useCallback(
6775
+ const submitDraft = React26.useCallback(
5163
6776
  (followUpOverride) => {
5164
6777
  if (isSendDisabled) return;
5165
6778
  const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
@@ -5189,6 +6802,9 @@ function Chat({
5189
6802
  if (filesToSend) {
5190
6803
  inputPayload.files = filesToSend;
5191
6804
  }
6805
+ if (planModeEnabled) {
6806
+ inputPayload.planMode = true;
6807
+ }
5192
6808
  const requestOptions = buildInjectedRequestOptions({
5193
6809
  defaults: options?.request,
5194
6810
  humanInput: inputPayload
@@ -5223,6 +6839,7 @@ function Chat({
5223
6839
  references,
5224
6840
  scrollToBottom,
5225
6841
  selectedTool,
6842
+ planModeEnabled,
5226
6843
  stream,
5227
6844
  trimmedDraft,
5228
6845
  uploadedFiles,
@@ -5233,7 +6850,7 @@ function Chat({
5233
6850
  event.preventDefault();
5234
6851
  submitDraft();
5235
6852
  };
5236
- const handleEditPendingFollowUp = React23.useCallback(
6853
+ const handleEditPendingFollowUp = React26.useCallback(
5237
6854
  (id) => {
5238
6855
  const item = pendingFollowUps.find(
5239
6856
  (entry) => entry.id === id && entry.mode === "queue"
@@ -5260,7 +6877,7 @@ function Chat({
5260
6877
  },
5261
6878
  [pendingFollowUps, stream]
5262
6879
  );
5263
- const handleQuoteSelection = React23.useCallback(() => {
6880
+ const handleQuoteSelection = React26.useCallback(() => {
5264
6881
  if (!quoteSelection) {
5265
6882
  return;
5266
6883
  }
@@ -5276,7 +6893,7 @@ function Chat({
5276
6893
  const handleAttachmentClick = () => {
5277
6894
  fileInputRef.current?.click();
5278
6895
  };
5279
- const uploadContextFile = React23.useCallback(
6896
+ const uploadContextFile = React26.useCallback(
5280
6897
  (file) => stream.client.contexts.uploadFile(file),
5281
6898
  [stream.client]
5282
6899
  );
@@ -5302,7 +6919,7 @@ function Chat({
5302
6919
  }
5303
6920
  submitDraft();
5304
6921
  };
5305
- const handleComposerPaste = React23.useCallback(
6922
+ const handleComposerPaste = React26.useCallback(
5306
6923
  (event) => {
5307
6924
  const clipboardData = event.clipboardData;
5308
6925
  if (!clipboardData) {
@@ -5381,18 +6998,18 @@ function Chat({
5381
6998
  uploadContextFile
5382
6999
  ]
5383
7000
  );
5384
- const alternateFollowUpShortcutLabel = React23.useMemo(() => {
7001
+ const alternateFollowUpShortcutLabel = React26.useMemo(() => {
5385
7002
  if (typeof navigator === "undefined") {
5386
7003
  return "\u2318Enter";
5387
7004
  }
5388
7005
  const platform = navigator.platform || navigator.userAgent;
5389
7006
  return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
5390
7007
  }, []);
5391
- const followUpShortcutLabels = React23.useMemo(
7008
+ const followUpShortcutLabels = React26.useMemo(
5392
7009
  () => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
5393
7010
  [alternateFollowUpShortcutLabel]
5394
7011
  );
5395
- const uploadFile = React23.useCallback(
7012
+ const uploadFile = React26.useCallback(
5396
7013
  async (localId, file) => {
5397
7014
  try {
5398
7015
  const result = await uploadContextFile(file);
@@ -5415,7 +7032,7 @@ function Chat({
5415
7032
  },
5416
7033
  [uploadContextFile]
5417
7034
  );
5418
- const handleRetryUpload = React23.useCallback(
7035
+ const handleRetryUpload = React26.useCallback(
5419
7036
  (localId) => {
5420
7037
  const attachment = attachments.find((a) => a.localId === localId);
5421
7038
  if (!attachment || attachment.status !== "error") return;
@@ -5486,10 +7103,23 @@ function Chat({
5486
7103
  content: prompt
5487
7104
  };
5488
7105
  const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
7106
+ const inputPayload = {
7107
+ input: prompt,
7108
+ ...planModeEnabled ? { planMode: true } : {}
7109
+ };
7110
+ const requestOptions = buildInjectedRequestOptions({
7111
+ defaults: options?.request,
7112
+ humanInput: inputPayload
7113
+ });
5489
7114
  stream.submit(
5490
- { input: { input: prompt } },
7115
+ {
7116
+ input: inputPayload,
7117
+ ...requestOptions.state ? { state: requestOptions.state } : {}
7118
+ },
5491
7119
  {
5492
7120
  ...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
7121
+ ...requestOptions.context ? { context: requestOptions.context } : {},
7122
+ ...requestOptions.config ? { config: requestOptions.config } : {},
5493
7123
  ...!nextFollowUpMode ? {
5494
7124
  optimisticValues: (prev) => {
5495
7125
  const prevMessages = prev?.messages ?? [];
@@ -5500,7 +7130,7 @@ function Chat({
5500
7130
  );
5501
7131
  scrollToBottom(true, true);
5502
7132
  };
5503
- const loadConversationMessages = React23.useCallback(
7133
+ const loadConversationMessages = React26.useCallback(
5504
7134
  async (recordId) => {
5505
7135
  if (missingConfig) {
5506
7136
  setHistoryError(missingConfigShortMessage);
@@ -5586,18 +7216,18 @@ function Chat({
5586
7216
  }
5587
7217
  };
5588
7218
  const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
5589
- const currentThread = React23.useMemo(
7219
+ const currentThread = React26.useMemo(
5590
7220
  () => threads.find((item) => item.id === stream.threadId),
5591
7221
  [threads, stream.threadId]
5592
7222
  );
5593
7223
  const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
5594
- const threadErrorMessage = React23.useMemo(() => {
7224
+ const threadErrorMessage = React26.useMemo(() => {
5595
7225
  if (currentThread?.status !== "error") return void 0;
5596
7226
  const message = currentThread.error?.trim();
5597
7227
  return message || t("thread.errorToast");
5598
7228
  }, [currentThread, t]);
5599
7229
  const assistantTitle = assistantName || resolvedTitle;
5600
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7230
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5601
7231
  "div",
5602
7232
  {
5603
7233
  ref: viewportRef,
@@ -5606,10 +7236,10 @@ function Chat({
5606
7236
  className
5607
7237
  ),
5608
7238
  children: [
5609
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
5610
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
5611
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "relative shrink-0", children: [
5612
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7239
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
7240
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
7241
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "relative shrink-0", children: [
7242
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5613
7243
  ChatkitAvatar,
5614
7244
  {
5615
7245
  avatar: assistantAvatar,
@@ -5617,10 +7247,10 @@ function Chat({
5617
7247
  label: assistantTitle
5618
7248
  }
5619
7249
  ),
5620
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
7250
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
5621
7251
  ] }),
5622
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "truncate", children: [
5623
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7252
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "truncate", children: [
7253
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5624
7254
  "h2",
5625
7255
  {
5626
7256
  className: "text-lg font-semibold truncate",
@@ -5628,27 +7258,30 @@ function Chat({
5628
7258
  children: assistantTitle
5629
7259
  }
5630
7260
  ),
5631
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
7261
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
5632
7262
  ] })
5633
7263
  ] }),
5634
- history?.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-1", children: [
5635
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5636
- "button",
5637
- {
5638
- type: "button",
5639
- onClick: handleNewThread,
5640
- disabled: missingConfig || isHistoryLoading,
5641
- className: cn(
5642
- "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
5643
- "text-muted-foreground hover:text-foreground hover:bg-muted",
5644
- "transition-colors duration-150",
5645
- "disabled:opacity-50 disabled:cursor-not-allowed"
5646
- ),
5647
- title: t("history.newThread"),
5648
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.Pencil, { size: 16 })
5649
- }
5650
- ),
5651
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7264
+ history?.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex items-center gap-1", children: [
7265
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Tooltip, { children: [
7266
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7267
+ "button",
7268
+ {
7269
+ type: "button",
7270
+ onClick: handleNewThread,
7271
+ disabled: missingConfig || isHistoryLoading,
7272
+ className: cn(
7273
+ "flex h-8 w-8 cursor-pointer items-center justify-center rounded-md",
7274
+ "text-muted-foreground hover:text-foreground hover:bg-muted",
7275
+ "transition-colors duration-150",
7276
+ "disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed"
7277
+ ),
7278
+ "aria-label": t("history.newThread"),
7279
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.Pencil, { size: 16 })
7280
+ }
7281
+ ) }) }),
7282
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(TooltipContent, { side: "bottom", children: t("history.newThread") })
7283
+ ] }),
7284
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5652
7285
  HistorySidebar,
5653
7286
  {
5654
7287
  threads,
@@ -5662,18 +7295,18 @@ function Chat({
5662
7295
  )
5663
7296
  ] })
5664
7297
  ] }),
5665
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex-1 p-4", children: [
5666
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
5667
- historyError && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
5668
- showMissingConfig && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
5669
- isHistoryLoading && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
5670
- messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7298
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex-1 p-4", children: [
7299
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
7300
+ historyError && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
7301
+ showMissingConfig && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
7302
+ isHistoryLoading && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
7303
+ messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5671
7304
  StartScreen,
5672
7305
  {
5673
7306
  startScreen,
5674
7307
  onPromptClick: handlePromptClick
5675
7308
  }
5676
- ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "space-y-4", children: [
7309
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "space-y-4", children: [
5677
7310
  messages.map((message, index) => {
5678
7311
  const messageType = String(message.type);
5679
7312
  const isAssistantMessage = messageType === "assistant" || messageType === "ai";
@@ -5700,7 +7333,7 @@ function Chat({
5700
7333
  if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
5701
7334
  return null;
5702
7335
  }
5703
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7336
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5704
7337
  "div",
5705
7338
  {
5706
7339
  className: cn(
@@ -5708,8 +7341,8 @@ function Chat({
5708
7341
  message.type === "human" ? "justify-end" : "justify-start -ml-1"
5709
7342
  // AI messages: slightly closer to left
5710
7343
  ),
5711
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-col px-3 overflow-hidden", children: [
5712
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7344
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-col px-3 overflow-hidden", children: [
7345
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5713
7346
  "div",
5714
7347
  {
5715
7348
  ...canQuoteMessage ? {
@@ -5721,18 +7354,24 @@ function Chat({
5721
7354
  message.type === "human" ? "bg-primary text-primary-foreground px-4 py-2.5" : message.type === "system" ? "bg-muted text-muted-foreground text-xs px-4 py-2.5" : "py-1 text-chat-foreground"
5722
7355
  // AI messages: use chat-specific foreground color
5723
7356
  ),
5724
- children: isAssistantMessage ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7357
+ children: isAssistantMessage ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5725
7358
  AssistantMessage,
5726
7359
  {
5727
7360
  message: {
5728
7361
  ...message,
5729
7362
  type: "assistant"
5730
7363
  },
7364
+ messages: messages.slice(0, index + 1).map(
7365
+ (item) => ({
7366
+ ...item,
7367
+ type: String(item.type) === "ai" ? "assistant" : item.type
7368
+ })
7369
+ ),
5731
7370
  isStreaming: isStreamingMessage,
5732
7371
  streamingStatus
5733
7372
  }
5734
- ) : /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_jsx_runtime29.Fragment, { children: [
5735
- message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7373
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
7374
+ message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5736
7375
  ReferenceChip,
5737
7376
  {
5738
7377
  reference,
@@ -5740,29 +7379,29 @@ function Chat({
5740
7379
  },
5741
7380
  getReferenceKey(reference)
5742
7381
  )) }),
5743
- message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7382
+ message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5744
7383
  "div",
5745
7384
  {
5746
7385
  className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
5747
7386
  children: [
5748
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 12 }),
5749
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "max-w-[100px] truncate", children: file.originalName })
7387
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 12 }),
7388
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "max-w-[100px] truncate", children: file.originalName })
5750
7389
  ]
5751
7390
  },
5752
7391
  fileIndex
5753
7392
  )) }),
5754
- Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7393
+ Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5755
7394
  "p",
5756
7395
  {
5757
7396
  className: "wrap-break-word text-sm leading-relaxed",
5758
7397
  children: formatMessageContent(part)
5759
7398
  },
5760
7399
  `${part.type}-${partIndex}`
5761
- )) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
7400
+ )) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
5762
7401
  ] })
5763
7402
  }
5764
7403
  ),
5765
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7404
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5766
7405
  MessageActions,
5767
7406
  {
5768
7407
  content: messageContent,
@@ -5798,7 +7437,7 @@ function Chat({
5798
7437
  stream.isLoading,
5799
7438
  { now: streamingNow }
5800
7439
  );
5801
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7440
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5802
7441
  AssistantStreamingIndicator,
5803
7442
  {
5804
7443
  status: fallbackStreamingStatus ?? "loading"
@@ -5807,7 +7446,7 @@ function Chat({
5807
7446
  })()
5808
7447
  ] })
5809
7448
  ] }),
5810
- !isAtBottom && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7449
+ !isAtBottom && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5811
7450
  Button,
5812
7451
  {
5813
7452
  type: "button",
@@ -5820,10 +7459,10 @@ function Chat({
5820
7459
  onClick: () => scrollToBottom(true, true),
5821
7460
  "aria-label": t("chat.scrollToBottom"),
5822
7461
  title: t("chat.scrollToBottom"),
5823
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.ArrowDown, { size: 16 })
7462
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.ArrowDown, { size: 16 })
5824
7463
  }
5825
7464
  ) }),
5826
- quoteSelection && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7465
+ quoteSelection && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5827
7466
  "div",
5828
7467
  {
5829
7468
  className: "pointer-events-none fixed z-50",
@@ -5832,7 +7471,7 @@ function Chat({
5832
7471
  left: `${quoteSelection.left}px`,
5833
7472
  transform: "translateX(-50%)"
5834
7473
  },
5835
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7474
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5836
7475
  Button,
5837
7476
  {
5838
7477
  type: "button",
@@ -5844,16 +7483,16 @@ function Chat({
5844
7483
  "aria-label": t("composer.quoteSelection"),
5845
7484
  title: t("composer.quoteSelection"),
5846
7485
  children: [
5847
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.Quote, { size: 14 }),
7486
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.Quote, { size: 14 }),
5848
7487
  t("composer.quoteSelection")
5849
7488
  ]
5850
7489
  }
5851
7490
  )
5852
7491
  }
5853
7492
  ),
5854
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
5855
- threadErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
5856
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7493
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
7494
+ threadErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
7495
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5857
7496
  "input",
5858
7497
  {
5859
7498
  ref: fileInputRef,
@@ -5864,7 +7503,7 @@ function Chat({
5864
7503
  className: "hidden"
5865
7504
  }
5866
7505
  ),
5867
- attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7506
+ attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5868
7507
  "div",
5869
7508
  {
5870
7509
  className: cn(
@@ -5872,16 +7511,16 @@ function Chat({
5872
7511
  item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
5873
7512
  ),
5874
7513
  children: [
5875
- item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5876
- import_lucide_react12.Loader2,
7514
+ item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7515
+ import_lucide_react15.Loader2,
5877
7516
  {
5878
7517
  size: 14,
5879
7518
  className: "animate-spin text-muted-foreground"
5880
7519
  }
5881
7520
  ),
5882
- item.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 14, className: "text-muted-foreground" }),
5883
- item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.FileText, { size: 14, className: "text-destructive" }),
5884
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7521
+ item.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 14, className: "text-muted-foreground" }),
7522
+ item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.FileText, { size: 14, className: "text-destructive" }),
7523
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5885
7524
  "span",
5886
7525
  {
5887
7526
  className: cn(
@@ -5891,17 +7530,17 @@ function Chat({
5891
7530
  children: item.file.name
5892
7531
  }
5893
7532
  ),
5894
- item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7533
+ item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5895
7534
  "button",
5896
7535
  {
5897
7536
  type: "button",
5898
7537
  onClick: () => handleRetryUpload(item.localId),
5899
7538
  className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
5900
7539
  title: t("chat.retryUpload"),
5901
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.RefreshCw, { size: 12 })
7540
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.RefreshCw, { size: 12 })
5902
7541
  }
5903
7542
  ),
5904
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7543
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5905
7544
  "button",
5906
7545
  {
5907
7546
  type: "button",
@@ -5910,14 +7549,14 @@ function Chat({
5910
7549
  "ml-1 rounded-full p-0.5",
5911
7550
  item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
5912
7551
  ),
5913
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
7552
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
5914
7553
  }
5915
7554
  )
5916
7555
  ]
5917
7556
  },
5918
7557
  item.localId
5919
7558
  )) }),
5920
- references.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7559
+ references.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5921
7560
  ReferenceChip,
5922
7561
  {
5923
7562
  reference,
@@ -5931,19 +7570,19 @@ function Chat({
5931
7570
  },
5932
7571
  getReferenceKey(reference)
5933
7572
  )) }),
5934
- selectedTool && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [
5935
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
5936
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7573
+ selectedTool && /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [
7574
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
7575
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5937
7576
  "button",
5938
7577
  {
5939
7578
  type: "button",
5940
7579
  onClick: () => setSelectedTool(null),
5941
7580
  className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
5942
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react12.X, { size: 12 })
7581
+ children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_lucide_react15.X, { size: 12 })
5943
7582
  }
5944
7583
  )
5945
7584
  ] }),
5946
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7585
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5947
7586
  PendingTodos,
5948
7587
  {
5949
7588
  snapshot: stream.todos,
@@ -5951,7 +7590,7 @@ function Chat({
5951
7590
  className: hasPendingFollowUps ? "mb-2" : void 0
5952
7591
  }
5953
7592
  ),
5954
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7593
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5955
7594
  PendingFollowUps,
5956
7595
  {
5957
7596
  items: pendingFollowUps,
@@ -5966,7 +7605,16 @@ function Chat({
5966
7605
  attachToComposer: true
5967
7606
  }
5968
7607
  ),
5969
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
7608
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
7609
+ RequestUserInputPanel,
7610
+ {
7611
+ request: stream.pendingRequestUserInput,
7612
+ onSubmit: stream.submitRequestUserInput,
7613
+ onDismiss: stream.stop,
7614
+ attachToComposer: true
7615
+ }
7616
+ ),
7617
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
5970
7618
  "div",
5971
7619
  {
5972
7620
  className: cn(
@@ -5978,17 +7626,19 @@ function Chat({
5978
7626
  getRoundedClass(theme.radius)
5979
7627
  ),
5980
7628
  children: [
5981
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7629
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5982
7630
  ComposerMenu,
5983
7631
  {
5984
7632
  composer,
5985
7633
  onAttachmentClick: handleAttachmentClick,
5986
7634
  onToolSelect: handleToolSelect,
5987
7635
  selectedTool,
5988
- disabled: missingConfig || isHistoryLoading
7636
+ planModeEnabled,
7637
+ onPlanModeChange: setPlanModeEnabled,
7638
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput
5989
7639
  }
5990
7640
  ),
5991
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7641
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
5992
7642
  "textarea",
5993
7643
  {
5994
7644
  ref: composerInputRef,
@@ -5998,7 +7648,7 @@ function Chat({
5998
7648
  onKeyDown: handleComposerKeyDown,
5999
7649
  rows: 1,
6000
7650
  placeholder: inputPlaceholder,
6001
- disabled: missingConfig || isHistoryLoading,
7651
+ disabled: missingConfig || isHistoryLoading || hasPendingRequestUserInput,
6002
7652
  className: cn(
6003
7653
  "min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
6004
7654
  "placeholder:text-muted-foreground",
@@ -6006,12 +7656,12 @@ function Chat({
6006
7656
  )
6007
7657
  }
6008
7658
  ),
6009
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7659
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6010
7660
  SendButton,
6011
7661
  {
6012
7662
  disabled: isSendDisabled,
6013
7663
  isLoading: stream.isLoading,
6014
- showStop: stream.isLoading && !trimmedDraft,
7664
+ showStop: stream.isLoading && (!trimmedDraft || hasPendingRequestUserInput),
6015
7665
  onStop: () => stream.stop(),
6016
7666
  stopLabel: t("chat.stop"),
6017
7667
  sendLabel: t("chat.send"),
@@ -6030,7 +7680,7 @@ function Chat({
6030
7680
  ]
6031
7681
  }
6032
7682
  ) }),
6033
- disclaimer?.text && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
7683
+ disclaimer?.text && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6034
7684
  "p",
6035
7685
  {
6036
7686
  className: cn(
@@ -6040,9 +7690,9 @@ function Chat({
6040
7690
  children: disclaimer.text
6041
7691
  }
6042
7692
  ),
6043
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
6044
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: t("chat.poweredBy") }),
6045
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ContextUsageIndicator, { className: "absolute right-4" })
7693
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
7694
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { children: t("chat.poweredBy") }),
7695
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ContextUsageIndicator, { className: "absolute right-4" })
6046
7696
  ] })
6047
7697
  ] })
6048
7698
  ]
@@ -6051,11 +7701,11 @@ function Chat({
6051
7701
  }
6052
7702
 
6053
7703
  // src/components/ui/input.tsx
6054
- var React24 = __toESM(require("react"), 1);
6055
- var import_jsx_runtime30 = require("react/jsx-runtime");
6056
- var Input = React24.forwardRef(
7704
+ var React27 = __toESM(require("react"), 1);
7705
+ var import_jsx_runtime33 = require("react/jsx-runtime");
7706
+ var Input = React27.forwardRef(
6057
7707
  ({ className, type, ...props }, ref) => {
6058
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
7708
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
6059
7709
  "input",
6060
7710
  {
6061
7711
  ref,
@@ -6072,10 +7722,10 @@ var Input = React24.forwardRef(
6072
7722
  Input.displayName = "Input";
6073
7723
 
6074
7724
  // src/components/ui/separator.tsx
6075
- var React25 = __toESM(require("react"), 1);
6076
- var import_jsx_runtime31 = require("react/jsx-runtime");
6077
- var Separator = React25.forwardRef(
6078
- ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
7725
+ var React28 = __toESM(require("react"), 1);
7726
+ var import_jsx_runtime34 = require("react/jsx-runtime");
7727
+ var Separator = React28.forwardRef(
7728
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6079
7729
  "div",
6080
7730
  {
6081
7731
  ref,