@xpert-ai/chatkit-ui 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/dist/app/assets/{_baseUniq-TMxiHmEt.js → _baseUniq-e0n3oxgY.js} +1 -1
  2. package/dist/app/assets/{abap-Ck-A--kS.js → abap-C2m1gMh_.js} +1 -1
  3. package/dist/app/assets/{abnf-ETC1zUJ3.js → abnf-DFzlHNVB.js} +1 -1
  4. package/dist/app/assets/{actionscript-D--OP--K.js → actionscript-Dxmvc3AF.js} +1 -1
  5. package/dist/app/assets/{ada-CDetVdj6.js → ada-CVO_O52N.js} +1 -1
  6. package/dist/app/assets/{agda-BMJYMk52.js → agda-CGEI8apm.js} +1 -1
  7. package/dist/app/assets/{al-Db9ENOd3.js → al-CXBctxHE.js} +1 -1
  8. package/dist/app/assets/{antlr4-BW8d6D2N.js → antlr4-BzGyc1GG.js} +1 -1
  9. package/dist/app/assets/{apacheconf-BQPffoZs.js → apacheconf-DhdeJg1U.js} +1 -1
  10. package/dist/app/assets/{apex-BDhwAKiF.js → apex-Dfprst0f.js} +1 -1
  11. package/dist/app/assets/{apl-BS9tU3lX.js → apl-D3zvQCsG.js} +1 -1
  12. package/dist/app/assets/{applescript-CAuteGTO.js → applescript-DWkUa8Ap.js} +1 -1
  13. package/dist/app/assets/{aql-DlV09MnJ.js → aql-DrfLox7L.js} +1 -1
  14. package/dist/app/assets/{arc-D3dvEiRa.js → arc-25X_4Lt9.js} +1 -1
  15. package/dist/app/assets/{architectureDiagram-Q4EWVU46-BJNOb03u.js → architectureDiagram-Q4EWVU46-CyF28k-b.js} +1 -1
  16. package/dist/app/assets/{arduino-Fwp0Gqjn.js → arduino-Qd3e6Ok1.js} +1 -1
  17. package/dist/app/assets/{arff-D1ze2M6G.js → arff-CRZ9puZK.js} +1 -1
  18. package/dist/app/assets/{asciidoc-DuSG0rE-.js → asciidoc-DUiwgtuK.js} +1 -1
  19. package/dist/app/assets/{asm6502-DiyS793s.js → asm6502-zG1dqL1m.js} +1 -1
  20. package/dist/app/assets/{asmatmel-BgPjOvKk.js → asmatmel-Cm9zpYMv.js} +1 -1
  21. package/dist/app/assets/{aspnet-DS6cVlO8.js → aspnet-CX5-L7Ct.js} +1 -1
  22. package/dist/app/assets/{autohotkey-BhOfSyb7.js → autohotkey-C4JfPrSd.js} +1 -1
  23. package/dist/app/assets/{autoit-qharvHka.js → autoit-g5o6EGhy.js} +1 -1
  24. package/dist/app/assets/{avisynth-DuYY8hq9.js → avisynth-BzCOBA3x.js} +1 -1
  25. package/dist/app/assets/{avro-idl-CVlpaCRn.js → avro-idl-e0tKOc6E.js} +1 -1
  26. package/dist/app/assets/{bash-CRdlMYvM.js → bash-CHd7M7ii.js} +1 -1
  27. package/dist/app/assets/{basic-DupsYiAg.js → basic-DvEnfVvI.js} +1 -1
  28. package/dist/app/assets/{batch-SuJmV6In.js → batch-CT5xgq8J.js} +1 -1
  29. package/dist/app/assets/{bbcode-BS6lj-GP.js → bbcode-DJ7OKysr.js} +1 -1
  30. package/dist/app/assets/{bicep-rkAfEJ7t.js → bicep-BXw_45Yz.js} +1 -1
  31. package/dist/app/assets/{birb-iXd4GkHj.js → birb-XpBgzzS8.js} +1 -1
  32. package/dist/app/assets/{bison-DXF-YZke.js → bison-D-7QCu9c.js} +1 -1
  33. package/dist/app/assets/{blockDiagram-DXYQGD6D-FJZrsqQ2.js → blockDiagram-DXYQGD6D-6aWNcctV.js} +1 -1
  34. package/dist/app/assets/{bnf-H9nHTWOC.js → bnf-98JsAWJD.js} +1 -1
  35. package/dist/app/assets/{brainfuck-6HhEdVzI.js → brainfuck-DtvgC7Uz.js} +1 -1
  36. package/dist/app/assets/{brightscript-B00Ory-q.js → brightscript-CiZLD50k.js} +1 -1
  37. package/dist/app/assets/{bro-BguB8PwR.js → bro-rbJDq64_.js} +1 -1
  38. package/dist/app/assets/{bsl-CnoKMnh1.js → bsl-BS-cDrod.js} +1 -1
  39. package/dist/app/assets/{c-BLZaQSul.js → c-DQDTErL9.js} +1 -1
  40. package/dist/app/assets/{c4Diagram-AHTNJAMY-aFMpHsr7.js → c4Diagram-AHTNJAMY-aTcQy0xE.js} +1 -1
  41. package/dist/app/assets/{cfscript-Dj3sn5qb.js → cfscript-CkR3O7sU.js} +1 -1
  42. package/dist/app/assets/{chaiscript-B2Li8_Xi.js → chaiscript-DvxvIu7v.js} +1 -1
  43. package/dist/app/assets/channel-CVWoJuYf.js +1 -0
  44. package/dist/app/assets/{chunk-4BX2VUAB-mNkmACgc.js → chunk-4BX2VUAB-qfDhreDf.js} +1 -1
  45. package/dist/app/assets/{chunk-4TB4RGXK-UImL1Qph.js → chunk-4TB4RGXK-BBVzKpce.js} +1 -1
  46. package/dist/app/assets/{chunk-55IACEB6-BrbuP7ej.js → chunk-55IACEB6-CcY9LJAj.js} +1 -1
  47. package/dist/app/assets/{chunk-EDXVE4YY-nIuwelfS.js → chunk-EDXVE4YY-B-Dzr-Dh.js} +1 -1
  48. package/dist/app/assets/{chunk-FMBD7UC4-BcWvK3ua.js → chunk-FMBD7UC4-8CUKOSAc.js} +1 -1
  49. package/dist/app/assets/{chunk-OYMX7WX6-NFSrvN2K.js → chunk-OYMX7WX6-D9Cq7hwT.js} +1 -1
  50. package/dist/app/assets/{chunk-QZHKN3VN-A-S7sUFp.js → chunk-QZHKN3VN-C2tBz9o2.js} +1 -1
  51. package/dist/app/assets/{chunk-YZCP3GAM-NsOgLJm6.js → chunk-YZCP3GAM-C4jyodPd.js} +1 -1
  52. package/dist/app/assets/{cil-BSYlNEvs.js → cil-C5ON7F53.js} +1 -1
  53. package/dist/app/assets/classDiagram-6PBFFD2Q-CgDPDKKT.js +1 -0
  54. package/dist/app/assets/classDiagram-v2-HSJHXN6E-CgDPDKKT.js +1 -0
  55. package/dist/app/assets/{clike-DaoHXpYs.js → clike-DLdxAZKH.js} +1 -1
  56. package/dist/app/assets/{clojure-CtOotL0u.js → clojure-DvSYmO9X.js} +1 -1
  57. package/dist/app/assets/clone-DyTJ9PSE.js +1 -0
  58. package/dist/app/assets/{cmake-BSiUfJHf.js → cmake-DO0txDE3.js} +1 -1
  59. package/dist/app/assets/{cobol-Blq62nOS.js → cobol-BTJpVfTH.js} +1 -1
  60. package/dist/app/assets/{coffeescript-wfCQi2dy.js → coffeescript-BtIXNHF3.js} +1 -1
  61. package/dist/app/assets/{concurnas-BptxXLM6.js → concurnas-B531692C.js} +1 -1
  62. package/dist/app/assets/{coq-m0xx6QVk.js → coq-Cp47Wwsa.js} +1 -1
  63. package/dist/app/assets/{core-BlK5liku.js → core-BoWyhl5n.js} +1 -1
  64. package/dist/app/assets/{cose-bilkent-S5V4N54A-BVlJJjjG.js → cose-bilkent-S5V4N54A-BjosQjhT.js} +1 -1
  65. package/dist/app/assets/{cpp-DrIwjXt4.js → cpp-B6wt8k5c.js} +1 -1
  66. package/dist/app/assets/{crystal-B2OownN0.js → crystal-B3XldzUm.js} +1 -1
  67. package/dist/app/assets/{csharp-C8hT9u31.js → csharp-BKQFTidP.js} +1 -1
  68. package/dist/app/assets/{cshtml-Bqk4UcKH.js → cshtml-BH26d1cx.js} +1 -1
  69. package/dist/app/assets/{csp-B23dqIVk.js → csp-DSghTOt2.js} +1 -1
  70. package/dist/app/assets/{css-C7bAsgCD.js → css-B5pRG057.js} +1 -1
  71. package/dist/app/assets/{css-extras-BxAj6HIM.js → css-extras-DD0ErmT4.js} +1 -1
  72. package/dist/app/assets/{csv-CITuvdZl.js → csv-C8WNOOiS.js} +1 -1
  73. package/dist/app/assets/{cypher-BdWaNEPh.js → cypher-C72ppWfI.js} +1 -1
  74. package/dist/app/assets/{d-DWzNEoy_.js → d-DCkT0MnL.js} +1 -1
  75. package/dist/app/assets/{dagre-KV5264BT-Cwq32s4A.js → dagre-KV5264BT-Dz0XIZ_d.js} +1 -1
  76. package/dist/app/assets/{dart-Cct8-2Yi.js → dart-ov_L9JbZ.js} +1 -1
  77. package/dist/app/assets/{dataweave-sykaGSqb.js → dataweave-ER8iZYvy.js} +1 -1
  78. package/dist/app/assets/{dax-CZ69LQsy.js → dax-DftfdAbZ.js} +1 -1
  79. package/dist/app/assets/{dhall-DThgzXZx.js → dhall-B_Ag7Ugu.js} +1 -1
  80. package/dist/app/assets/{diagram-5BDNPKRD-BfciTHMz.js → diagram-5BDNPKRD-LXVUQ6at.js} +1 -1
  81. package/dist/app/assets/{diagram-G4DWMVQ6-Q37x31io.js → diagram-G4DWMVQ6-DFJO-kg5.js} +1 -1
  82. package/dist/app/assets/{diagram-MMDJMWI5-Cyyx6ZUw.js → diagram-MMDJMWI5-BKfZyNwr.js} +1 -1
  83. package/dist/app/assets/{diagram-TYMM5635-BUh40K6u.js → diagram-TYMM5635-B0QF8FRs.js} +1 -1
  84. package/dist/app/assets/{diff-UDoi3FBV.js → diff-ByjoU1do.js} +1 -1
  85. package/dist/app/assets/{django-CUQxRbf9.js → django-D8OuMIol.js} +1 -1
  86. package/dist/app/assets/{dns-zone-file-9UmAuR-l.js → dns-zone-file-NMG4vugk.js} +1 -1
  87. package/dist/app/assets/{docker-vhZ6HugE.js → docker-D6vmqJmV.js} +1 -1
  88. package/dist/app/assets/{dot-Dlao8ZwH.js → dot-QLisXVDc.js} +1 -1
  89. package/dist/app/assets/{ebnf-BfWJycwn.js → ebnf-BmUuiQBV.js} +1 -1
  90. package/dist/app/assets/{editorconfig-DsrBDVtJ.js → editorconfig-RZmDBUFH.js} +1 -1
  91. package/dist/app/assets/{eiffel-ZZ7Z0b2_.js → eiffel-rnFzeEWt.js} +1 -1
  92. package/dist/app/assets/{ejs-SLmpmzms.js → ejs-DN7eCZMZ.js} +1 -1
  93. package/dist/app/assets/{elixir-BdkxsFt4.js → elixir-DQP09Ude.js} +1 -1
  94. package/dist/app/assets/{elm-DSgkBbD-.js → elm-DoxD8V5-.js} +1 -1
  95. package/dist/app/assets/{erDiagram-SMLLAGMA-CKj18meA.js → erDiagram-SMLLAGMA-PLYN-yt7.js} +1 -1
  96. package/dist/app/assets/{erb-AX38416h.js → erb-D7QWryDV.js} +1 -1
  97. package/dist/app/assets/{erlang-DY2BVWMP.js → erlang-6MIAP3z1.js} +1 -1
  98. package/dist/app/assets/{etlua-BSaUvZH7.js → etlua-CXOpuEX0.js} +1 -1
  99. package/dist/app/assets/{excel-formula-CGTOeZhB.js → excel-formula-Bvelfqoq.js} +1 -1
  100. package/dist/app/assets/{factor-CtvOHq60.js → factor-B_LwIu1T.js} +1 -1
  101. package/dist/app/assets/{false-C4FtFKhi.js → false-DaXIsDj9.js} +1 -1
  102. package/dist/app/assets/{firestore-security-rules-Z8TPJQpU.js → firestore-security-rules-vhtcxmz8.js} +1 -1
  103. package/dist/app/assets/{flow-0LSCeVxZ.js → flow-CbnzGhcW.js} +1 -1
  104. package/dist/app/assets/{flowDiagram-DWJPFMVM-CmW1pCPp.js → flowDiagram-DWJPFMVM-D46jZeCj.js} +1 -1
  105. package/dist/app/assets/{fortran-DR7--sEx.js → fortran-D21zPhTt.js} +1 -1
  106. package/dist/app/assets/{fsharp-CoiFf2ek.js → fsharp-CaguYUvm.js} +1 -1
  107. package/dist/app/assets/{ftl-BsfZdglK.js → ftl-DpFi23p_.js} +1 -1
  108. package/dist/app/assets/{ganttDiagram-T4ZO3ILL-C1vWI0vT.js → ganttDiagram-T4ZO3ILL-DiFD8eiM.js} +1 -1
  109. package/dist/app/assets/{gap-D5rs685K.js → gap-DTH0dhv0.js} +1 -1
  110. package/dist/app/assets/{gcode-ioide_II.js → gcode-Ti0MqAbc.js} +1 -1
  111. package/dist/app/assets/{gdscript-C1ZWRkkr.js → gdscript-B4c1zB7G.js} +1 -1
  112. package/dist/app/assets/{gedcom-DS1yKzLz.js → gedcom-Bm-gxba2.js} +1 -1
  113. package/dist/app/assets/{gherkin-uIhE-MbH.js → gherkin-CRUiP4ua.js} +1 -1
  114. package/dist/app/assets/{git-B5BRNNT7.js → git-DDSxUgmV.js} +1 -1
  115. package/dist/app/assets/{gitGraphDiagram-UUTBAWPF-DEg-duQZ.js → gitGraphDiagram-UUTBAWPF-BkD66s-m.js} +1 -1
  116. package/dist/app/assets/{glsl-B9fhkctz.js → glsl-BWGO0hEu.js} +1 -1
  117. package/dist/app/assets/{gml-offEglBU.js → gml-OfBxxn4Y.js} +1 -1
  118. package/dist/app/assets/{gn-FZ0bWEld.js → gn-D1i8XGRO.js} +1 -1
  119. package/dist/app/assets/{go-BIRlaT1a.js → go-CQxEjXj6.js} +1 -1
  120. package/dist/app/assets/{go-module-SjD6zijS.js → go-module-DJVIXWOE.js} +1 -1
  121. package/dist/app/assets/{graph-sBvKxujm.js → graph-xy46XkDv.js} +1 -1
  122. package/dist/app/assets/{graphql-Be74WDAY.js → graphql-DOWBew5y.js} +1 -1
  123. package/dist/app/assets/{groovy-ChbEq3v0.js → groovy-D4SOqf4f.js} +1 -1
  124. package/dist/app/assets/{haml-C6FObrUo.js → haml-Cs-NR_00.js} +1 -1
  125. package/dist/app/assets/{handlebars-36OFp0YX.js → handlebars-L33c899L.js} +1 -1
  126. package/dist/app/assets/{haskell-DuohgBoX.js → haskell-jnyZSPIm.js} +1 -1
  127. package/dist/app/assets/{haxe-CNMh78ZV.js → haxe-CEcS1fRW.js} +1 -1
  128. package/dist/app/assets/{hcl-BpxVSY5Z.js → hcl-CFVBh1rZ.js} +1 -1
  129. package/dist/app/assets/{hlsl-DnxGKW3m.js → hlsl-BGDcbOGU.js} +1 -1
  130. package/dist/app/assets/{hoon-XUklDmVn.js → hoon-DbE0jHD1.js} +1 -1
  131. package/dist/app/assets/{hpkp-Did6vsrG.js → hpkp-FsJh7gNB.js} +1 -1
  132. package/dist/app/assets/{hsts-DS9blmxt.js → hsts-q26NxKTf.js} +1 -1
  133. package/dist/app/assets/{http-DA2WLFiQ.js → http-DG-5h-eO.js} +1 -1
  134. package/dist/app/assets/{ichigojam-DdOMt5rE.js → ichigojam-CuYDdsGF.js} +1 -1
  135. package/dist/app/assets/{icon-PVJAVx5C.js → icon-B3Om0MSf.js} +1 -1
  136. package/dist/app/assets/{icu-message-format-6jii1RVV.js → icu-message-format-DN2g3klg.js} +1 -1
  137. package/dist/app/assets/{idris-UxX24g1J.js → idris-BOt2MkOk.js} +1 -1
  138. package/dist/app/assets/{iecst-BynNGYT2.js → iecst-CuBx11EN.js} +1 -1
  139. package/dist/app/assets/{ignore-4EVq7-cE.js → ignore-cviNNAUS.js} +1 -1
  140. package/dist/app/assets/{index-CAfb2sup.js → index-B0wzBY_g.js} +210 -210
  141. package/dist/app/assets/index-CmKBuFcH.css +1 -0
  142. package/dist/app/assets/{infoDiagram-42DDH7IO-BfATVLk8.js → infoDiagram-42DDH7IO-D20xP3z-.js} +1 -1
  143. package/dist/app/assets/{inform7-BXb820VQ.js → inform7-Ba3iGRkz.js} +1 -1
  144. package/dist/app/assets/{ini-Cmr0cBrX.js → ini-D1qPbzhi.js} +1 -1
  145. package/dist/app/assets/{io-BdLksOc2.js → io-DxDg_PHG.js} +1 -1
  146. package/dist/app/assets/{ishikawaDiagram-UXIWVN3A-B6I8Yqfq.js → ishikawaDiagram-UXIWVN3A-cYl8p5Z1.js} +1 -1
  147. package/dist/app/assets/{j-CAftgdTa.js → j-LY0FoFmS.js} +1 -1
  148. package/dist/app/assets/{java-fwAzePp5.js → java-BqooSNxs.js} +1 -1
  149. package/dist/app/assets/{javadoc-BcYkNCK0.js → javadoc-BqcBR3v0.js} +1 -1
  150. package/dist/app/assets/{javadoclike-B57hwpBc.js → javadoclike-C4mjzqku.js} +1 -1
  151. package/dist/app/assets/{javascript-u1gm812-.js → javascript-N5ua9HdK.js} +1 -1
  152. package/dist/app/assets/{javastacktrace-cj9BHFXH.js → javastacktrace-v7dElDBR.js} +1 -1
  153. package/dist/app/assets/{jexl-DrO8YpRi.js → jexl-QnOdFFuN.js} +1 -1
  154. package/dist/app/assets/{jolie-C5CF-EiA.js → jolie-CJ-3s01g.js} +1 -1
  155. package/dist/app/assets/{journeyDiagram-VCZTEJTY-62Da_9fB.js → journeyDiagram-VCZTEJTY-BYX8q3Vt.js} +1 -1
  156. package/dist/app/assets/{jq-BQS35fYF.js → jq-CWSEYqle.js} +1 -1
  157. package/dist/app/assets/{js-extras-Dc8Ge9lP.js → js-extras-BAnnOfzU.js} +1 -1
  158. package/dist/app/assets/{js-templates-BChMs7zu.js → js-templates-C4pUn2It.js} +1 -1
  159. package/dist/app/assets/{jsdoc-Dsh0OaeE.js → jsdoc-KAXMzacX.js} +1 -1
  160. package/dist/app/assets/{json-DSLB2HLl.js → json-D82-G59c.js} +1 -1
  161. package/dist/app/assets/{json5-cRfUF1uJ.js → json5-6tkCkwy4.js} +1 -1
  162. package/dist/app/assets/{jsonp-DXOWbjE0.js → jsonp-CJLh9FtV.js} +1 -1
  163. package/dist/app/assets/{jsstacktrace-DlgtDbr8.js → jsstacktrace-DtzF790j.js} +1 -1
  164. package/dist/app/assets/{jsx-CyFeFIQM.js → jsx-HBfJ0kvY.js} +1 -1
  165. package/dist/app/assets/{julia-vGoL8D9z.js → julia-qgsTf-aE.js} +1 -1
  166. package/dist/app/assets/{kanban-definition-6JOO6SKY-JAtH1H2c.js → kanban-definition-6JOO6SKY-lNjZrvli.js} +1 -1
  167. package/dist/app/assets/{keepalived-u6JnaMHj.js → keepalived-CxQ8kQHh.js} +1 -1
  168. package/dist/app/assets/{keyman-C2x0si7Y.js → keyman-QQ5F7jKU.js} +1 -1
  169. package/dist/app/assets/{kotlin-l8__XfWl.js → kotlin-CHGD50lP.js} +1 -1
  170. package/dist/app/assets/{kumir-CaQaIRBf.js → kumir-Bu9SM23C.js} +1 -1
  171. package/dist/app/assets/{kusto-DYDxqji-.js → kusto-mt_hZCSq.js} +1 -1
  172. package/dist/app/assets/{latex-D2qjbQmB.js → latex-CICDtHjj.js} +1 -1
  173. package/dist/app/assets/{latte-CmbmgbPe.js → latte-BAR0mT7a.js} +1 -1
  174. package/dist/app/assets/{layout-BMTuSUP-.js → layout-DEyJKhDK.js} +1 -1
  175. package/dist/app/assets/{less-DpljErLD.js → less-CHNPhcod.js} +1 -1
  176. package/dist/app/assets/{lilypond-DAeqUsI_.js → lilypond-CSUOMwf6.js} +1 -1
  177. package/dist/app/assets/{linear-CqSIeBnp.js → linear-D9VvUwfa.js} +1 -1
  178. package/dist/app/assets/{liquid-Bo11FNrj.js → liquid-Cz7TW2oY.js} +1 -1
  179. package/dist/app/assets/{lisp-BNBGpNSq.js → lisp-Du6y1304.js} +1 -1
  180. package/dist/app/assets/{livescript-CNBuUGwr.js → livescript-BtG5DGcF.js} +1 -1
  181. package/dist/app/assets/{llvm-BCQgrmMc.js → llvm-BDPUo2hX.js} +1 -1
  182. package/dist/app/assets/{log-7C67ffIH.js → log--N5sUe_u.js} +1 -1
  183. package/dist/app/assets/{lolcode-tyVOf0-i.js → lolcode-ClqwJSko.js} +1 -1
  184. package/dist/app/assets/{lua-D1tjiZGJ.js → lua-DbeZ1IVc.js} +1 -1
  185. package/dist/app/assets/{magma-DvpErL5E.js → magma-Whq-4iou.js} +1 -1
  186. package/dist/app/assets/{makefile-DVopM6_I.js → makefile-pSKDqMc6.js} +1 -1
  187. package/dist/app/assets/{markdown-zDaJjBqz.js → markdown-B1xgmDWp.js} +1 -1
  188. package/dist/app/assets/{markup-Dn7T0Xgl.js → markup-DzLXw8Rh.js} +1 -1
  189. package/dist/app/assets/{markup-templating-jmwD3Mv5.js → markup-templating-DPDS9QM5.js} +1 -1
  190. package/dist/app/assets/{matlab-Dmd8VzKM.js → matlab-DJRo_vuN.js} +1 -1
  191. package/dist/app/assets/{maxscript-FjCyY0j5.js → maxscript-BvZXFCmD.js} +1 -1
  192. package/dist/app/assets/{mel-BDzXY19C.js → mel-CyILQ25B.js} +1 -1
  193. package/dist/app/assets/{mermaid-lu-_cgAH.js → mermaid-CwNV2n0M.js} +1 -1
  194. package/dist/app/assets/{min-DYtuudAi.js → min-W152sZHe.js} +1 -1
  195. package/dist/app/assets/{mindmap-definition-QFDTVHPH-C0LlKYnG.js → mindmap-definition-QFDTVHPH-C-UOvSVV.js} +1 -1
  196. package/dist/app/assets/{mizar-BDWlOEMd.js → mizar-C0hSTRmd.js} +1 -1
  197. package/dist/app/assets/{mongodb-BqhqCTUF.js → mongodb-D_b-CoC-.js} +1 -1
  198. package/dist/app/assets/{monkey-DD_wkxjO.js → monkey-PvQu5Vd6.js} +1 -1
  199. package/dist/app/assets/{moonscript-5BliHqu8.js → moonscript-CoP1dq0Z.js} +1 -1
  200. package/dist/app/assets/{n1ql-BI9d8-dk.js → n1ql-3QuCoAIN.js} +1 -1
  201. package/dist/app/assets/{n4js-CiGP0jcT.js → n4js-DZHeRyua.js} +1 -1
  202. package/dist/app/assets/{nand2tetris-hdl-h4B9YPVX.js → nand2tetris-hdl-dS8crO2g.js} +1 -1
  203. package/dist/app/assets/{naniscript-0FP5ZgNv.js → naniscript-DwYGbK5q.js} +1 -1
  204. package/dist/app/assets/{nasm-CfsxN3sz.js → nasm-CM1zvD-3.js} +1 -1
  205. package/dist/app/assets/{neon-Ds1qWnTS.js → neon-DFFyEzDC.js} +1 -1
  206. package/dist/app/assets/{nevod-CpogMq0t.js → nevod-D2FYTpnK.js} +1 -1
  207. package/dist/app/assets/{nginx-CBAywKyc.js → nginx-CdY-14q6.js} +1 -1
  208. package/dist/app/assets/{nim-CKndoR7P.js → nim-CG1iSWGV.js} +1 -1
  209. package/dist/app/assets/{nix-C2aGN04i.js → nix-D0-Pu9rL.js} +1 -1
  210. package/dist/app/assets/{nsis-BS2FD5Ui.js → nsis-dtDOvjH7.js} +1 -1
  211. package/dist/app/assets/{objectivec-BV3I8zfq.js → objectivec-CptpH-1d.js} +1 -1
  212. package/dist/app/assets/{ocaml-CumNTZrg.js → ocaml-Dv1ea-ld.js} +1 -1
  213. package/dist/app/assets/{opencl-BA7HxeS1.js → opencl-BvMmG6YR.js} +1 -1
  214. package/dist/app/assets/{openqasm-CVlYcfEb.js → openqasm-CwSFop47.js} +1 -1
  215. package/dist/app/assets/{oz-BgNzyTQm.js → oz-CEJrdpA7.js} +1 -1
  216. package/dist/app/assets/{parigp-HAeKHx70.js → parigp-DViKd8pj.js} +1 -1
  217. package/dist/app/assets/{parser-DBm9W7gH.js → parser-DgiwG_pC.js} +1 -1
  218. package/dist/app/assets/{pascal-DVVWX7c3.js → pascal-j68rLfD9.js} +1 -1
  219. package/dist/app/assets/{pascaligo-9sC0JINE.js → pascaligo-DUem4H6l.js} +1 -1
  220. package/dist/app/assets/{pcaxis-BExTG1b5.js → pcaxis-DvgzQxqD.js} +1 -1
  221. package/dist/app/assets/{peoplecode-BYMaBssU.js → peoplecode-C3Bxx6ZR.js} +1 -1
  222. package/dist/app/assets/{perl-BnEaJyRt.js → perl-FujE7XeE.js} +1 -1
  223. package/dist/app/assets/{php-DTvaAe6L.js → php-CNsXpF9V.js} +1 -1
  224. package/dist/app/assets/{php-extras-BryvmqOr.js → php-extras-C32YwHEb.js} +1 -1
  225. package/dist/app/assets/{phpdoc-DNQcJB7n.js → phpdoc-DGWozCi2.js} +1 -1
  226. package/dist/app/assets/{pieDiagram-DEJITSTG-CNyUzOEA.js → pieDiagram-DEJITSTG-Dqtbtugf.js} +1 -1
  227. package/dist/app/assets/{plsql-C53Rqwl3.js → plsql-C2VV-t97.js} +1 -1
  228. package/dist/app/assets/{powerquery-CBDVLr0E.js → powerquery-PRRUJzFT.js} +1 -1
  229. package/dist/app/assets/{powershell-BTjXHGcn.js → powershell-bb1HIydt.js} +1 -1
  230. package/dist/app/assets/{processing-LU1Q4Xrp.js → processing-DjcO4gZ4.js} +1 -1
  231. package/dist/app/assets/{prolog-CAkqp_8e.js → prolog-BYubkdm0.js} +1 -1
  232. package/dist/app/assets/{promql-qm_oe_qq.js → promql-C1R9989z.js} +1 -1
  233. package/dist/app/assets/{properties-CkopXTtp.js → properties-6E8geRjW.js} +1 -1
  234. package/dist/app/assets/{protobuf-Y8NjvM3i.js → protobuf-NbKEUq-0.js} +1 -1
  235. package/dist/app/assets/{psl-C6tOp1_K.js → psl-CCIboIeA.js} +1 -1
  236. package/dist/app/assets/{pug-CS_9WzOj.js → pug-B6XaxAxB.js} +1 -1
  237. package/dist/app/assets/{puppet-CUp_EgdL.js → puppet-sYeWToAm.js} +1 -1
  238. package/dist/app/assets/{pure-Blo1Mo0B.js → pure-MigBUlto.js} +1 -1
  239. package/dist/app/assets/{purebasic-Ca8-6hSG.js → purebasic-CbK5sM8J.js} +1 -1
  240. package/dist/app/assets/{purescript-NTJk_TqU.js → purescript-D4syOBjO.js} +1 -1
  241. package/dist/app/assets/{q-B6Zcp4zx.js → q-BQLn2JzW.js} +1 -1
  242. package/dist/app/assets/{qml-BWFD-5NF.js → qml-Be1u_eEw.js} +1 -1
  243. package/dist/app/assets/{qore-CDatToXb.js → qore-B1z7c7Yg.js} +1 -1
  244. package/dist/app/assets/{qsharp-D7nj5IOf.js → qsharp-BWsfMLkJ.js} +1 -1
  245. package/dist/app/assets/{quadrantDiagram-34T5L4WZ-DhG4JpPn.js → quadrantDiagram-34T5L4WZ-DdFjuBtK.js} +1 -1
  246. package/dist/app/assets/{r-B1QI-AqR.js → r-BER2AggK.js} +1 -1
  247. package/dist/app/assets/{racket-B4nDtIWF.js → racket-DOZRNhck.js} +1 -1
  248. package/dist/app/assets/{reason-JWfMNNZ5.js → reason-1KJbYmkA.js} +1 -1
  249. package/dist/app/assets/{regex-CJNXHeEg.js → regex-SdGLwvq5.js} +1 -1
  250. package/dist/app/assets/{rego-LQxbhCWr.js → rego-D-mLsW7j.js} +1 -1
  251. package/dist/app/assets/{renpy-BDFd6l-h.js → renpy-CYj4XzkD.js} +1 -1
  252. package/dist/app/assets/{requirementDiagram-MS252O5E-VIZnTHe_.js → requirementDiagram-MS252O5E-B5KgDzYF.js} +1 -1
  253. package/dist/app/assets/{rest-CGwOWaqn.js → rest-Do-kum26.js} +1 -1
  254. package/dist/app/assets/{rip-BIv3Yp6n.js → rip-CZ7hy7Rc.js} +1 -1
  255. package/dist/app/assets/{roboconf-DGg8AzxQ.js → roboconf-CrOlOF2e.js} +1 -1
  256. package/dist/app/assets/{robotframework-Cu4U-LJt.js → robotframework-SFMU6Wwy.js} +1 -1
  257. package/dist/app/assets/{ruby-jJNeRq1e.js → ruby-DSiktnDP.js} +1 -1
  258. package/dist/app/assets/{rust-DBMO8o-k.js → rust-BEq861Tj.js} +1 -1
  259. package/dist/app/assets/{sankeyDiagram-XADWPNL6-D109kLbO.js → sankeyDiagram-XADWPNL6-B_ju-fsT.js} +1 -1
  260. package/dist/app/assets/{sas-BXMgxJ5D.js → sas-Cxt3LAYG.js} +1 -1
  261. package/dist/app/assets/{sass-BXkCPsxr.js → sass-C0QOivil.js} +1 -1
  262. package/dist/app/assets/{scala-A2dbBlRv.js → scala-CBIhwVR7.js} +1 -1
  263. package/dist/app/assets/{scheme-5YfcUkz6.js → scheme-BQ8vJpEk.js} +1 -1
  264. package/dist/app/assets/{scss-CKQrod7s.js → scss-9ZztaO09.js} +1 -1
  265. package/dist/app/assets/{sequenceDiagram-FGHM5R23-BWFRA3S4.js → sequenceDiagram-FGHM5R23-BNRlgM_o.js} +1 -1
  266. package/dist/app/assets/{shell-session-7xRIeziW.js → shell-session-CEjfbC-4.js} +1 -1
  267. package/dist/app/assets/{smali-Dp3s5TDa.js → smali-wTZoo5Ck.js} +1 -1
  268. package/dist/app/assets/{smalltalk-Cn6dJ_DR.js → smalltalk-CtdEepu4.js} +1 -1
  269. package/dist/app/assets/{smarty-B62Phcz3.js → smarty-DCOaiyVN.js} +1 -1
  270. package/dist/app/assets/{sml-CRGJcRiK.js → sml-CRIi_5FN.js} +1 -1
  271. package/dist/app/assets/{solidity-CmijFrY5.js → solidity-C-sunTbM.js} +1 -1
  272. package/dist/app/assets/{solution-file-CMlGbfWf.js → solution-file-BMcD_yBD.js} +1 -1
  273. package/dist/app/assets/{soy-DfV0L1AX.js → soy-CrHujpjx.js} +1 -1
  274. package/dist/app/assets/{sparql-UU0JEsJN.js → sparql-_nkh51Oo.js} +1 -1
  275. package/dist/app/assets/{splunk-spl-CoMa2odZ.js → splunk-spl-BV0yJuZ3.js} +1 -1
  276. package/dist/app/assets/{sqf-BK0u4w1w.js → sqf-CTR3G-sn.js} +1 -1
  277. package/dist/app/assets/{sql-DNyh2fmD.js → sql-CK8LhvZf.js} +1 -1
  278. package/dist/app/assets/{squirrel-inCt7JHG.js → squirrel-BrWr7Sn4.js} +1 -1
  279. package/dist/app/assets/{stan-Doi4GinI.js → stan-CEC_j0Vp.js} +1 -1
  280. package/dist/app/assets/{stateDiagram-FHFEXIEX-BrDgd0rD.js → stateDiagram-FHFEXIEX-CD5PsxTo.js} +1 -1
  281. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-CZ_oJSeJ.js +1 -0
  282. package/dist/app/assets/{stylus-B--PyNIy.js → stylus-DAsiIRIp.js} +1 -1
  283. package/dist/app/assets/{swift-CzynVDjb.js → swift-BAaG4GYN.js} +1 -1
  284. package/dist/app/assets/{systemd-BzRtQaxY.js → systemd-DzS1CHBe.js} +1 -1
  285. package/dist/app/assets/{t4-cs-DRmWJZc9.js → t4-cs-ggnb3aeJ.js} +1 -1
  286. package/dist/app/assets/{t4-templating-DPZ7hNhf.js → t4-templating-Bu_GLHIZ.js} +1 -1
  287. package/dist/app/assets/{t4-vb-DJ-j33dQ.js → t4-vb-C9FmkhvR.js} +1 -1
  288. package/dist/app/assets/{tap-Cxx_PgyE.js → tap-CoKAR-fO.js} +1 -1
  289. package/dist/app/assets/{tcl-Bs4a0Dfs.js → tcl-C2ZkJvLb.js} +1 -1
  290. package/dist/app/assets/{textile-BoRmwUMy.js → textile-DZALIJzT.js} +1 -1
  291. package/dist/app/assets/{timeline-definition-GMOUNBTQ-CzfKhXYm.js → timeline-definition-GMOUNBTQ-CDhxUnOk.js} +1 -1
  292. package/dist/app/assets/{toml-Dt03eQXy.js → toml-C2smfO8e.js} +1 -1
  293. package/dist/app/assets/{tremor-DAjHRWBi.js → tremor-BjkZp6il.js} +1 -1
  294. package/dist/app/assets/{tt2-BeNFgyN2.js → tt2-CHuxOCBz.js} +1 -1
  295. package/dist/app/assets/{turtle-BzI8BWIV.js → turtle-BRML1nbK.js} +1 -1
  296. package/dist/app/assets/{twig-Df--35lw.js → twig-BXTsXQgH.js} +1 -1
  297. package/dist/app/assets/{typescript-BAKA2fdq.js → typescript-D97Flp8j.js} +1 -1
  298. package/dist/app/assets/{typoscript-r0z-RS5y.js → typoscript-DSeb0eJ9.js} +1 -1
  299. package/dist/app/assets/{unrealscript-dT1dIQam.js → unrealscript-DlHhyJiH.js} +1 -1
  300. package/dist/app/assets/{uorazor-C4wimjxD.js → uorazor-DAgFaaw5.js} +1 -1
  301. package/dist/app/assets/{uri-D7oE-PoJ.js → uri-DAISB2-y.js} +1 -1
  302. package/dist/app/assets/{v-DwJtB8Vm.js → v-BI1fSl4s.js} +1 -1
  303. package/dist/app/assets/{vala-D0mTgP2k.js → vala-B0O9FrwQ.js} +1 -1
  304. package/dist/app/assets/{vbnet-BJfu6o8X.js → vbnet-C8BBfsv6.js} +1 -1
  305. package/dist/app/assets/{velocity-BJB5m8fQ.js → velocity-DxEPgCJp.js} +1 -1
  306. package/dist/app/assets/{vennDiagram-DHZGUBPP-Cgb8-zyn.js → vennDiagram-DHZGUBPP-ByTJSjE_.js} +1 -1
  307. package/dist/app/assets/{verilog-Ci2D8dFC.js → verilog-thVOd-Xa.js} +1 -1
  308. package/dist/app/assets/{vhdl-DcEoROdo.js → vhdl-92ZsOrFg.js} +1 -1
  309. package/dist/app/assets/{vim-BzWQ6rL0.js → vim-WSNLk7dA.js} +1 -1
  310. package/dist/app/assets/{visual-basic-C9jUzYfG.js → visual-basic-C47_Fl8T.js} +1 -1
  311. package/dist/app/assets/{wardley-RL74JXVD-Btw_ODEd.js → wardley-RL74JXVD-wQHV1kk0.js} +1 -1
  312. package/dist/app/assets/{wardleyDiagram-NUSXRM2D-B84YCqkj.js → wardleyDiagram-NUSXRM2D-DDdoQZLn.js} +1 -1
  313. package/dist/app/assets/{warpscript-BVhze8vt.js → warpscript-CauvLjrk.js} +1 -1
  314. package/dist/app/assets/{wasm-zAS-bEPo.js → wasm-DieX6uKz.js} +1 -1
  315. package/dist/app/assets/{web-idl-G3r7q-fK.js → web-idl-GqldvVwc.js} +1 -1
  316. package/dist/app/assets/{wiki-exG7pUTP.js → wiki-D070zFKu.js} +1 -1
  317. package/dist/app/assets/{wolfram-C_Mj1MJG.js → wolfram-COSn3nGG.js} +1 -1
  318. package/dist/app/assets/{wren-CdV44Tnx.js → wren-Cs5-Z4d-.js} +1 -1
  319. package/dist/app/assets/{xeora-2KKn4X5q.js → xeora-Dblnaflg.js} +1 -1
  320. package/dist/app/assets/{xml-doc-DLPYHfMi.js → xml-doc-Cw5SW8IO.js} +1 -1
  321. package/dist/app/assets/{xojo-B6ggSUBg.js → xojo-BOGyzB1N.js} +1 -1
  322. package/dist/app/assets/{xquery-B2tHFdf8.js → xquery-Dss_lg3A.js} +1 -1
  323. package/dist/app/assets/{xychartDiagram-5P7HB3ND-CWuLJaAz.js → xychartDiagram-5P7HB3ND-B6sz9HXS.js} +1 -1
  324. package/dist/app/assets/{yaml-BkS8H31d.js → yaml-BX2rP5GJ.js} +1 -1
  325. package/dist/app/assets/{yang-DT_nuuZI.js → yang-CIW2FsLC.js} +1 -1
  326. package/dist/app/assets/{zig-B0zYSJvR.js → zig-DqhZPLNT.js} +1 -1
  327. package/dist/app/index.html +2 -2
  328. package/dist/index.cjs +1750 -893
  329. package/dist/index.d.cts +22 -2
  330. package/dist/index.d.ts +22 -2
  331. package/dist/index.js +1755 -898
  332. package/package.json +3 -3
  333. package/dist/app/assets/channel-DYgM_zKD.js +0 -1
  334. package/dist/app/assets/classDiagram-6PBFFD2Q-G-7-i5lY.js +0 -1
  335. package/dist/app/assets/classDiagram-v2-HSJHXN6E-G-7-i5lY.js +0 -1
  336. package/dist/app/assets/clone-4Dzzc8I_.js +0 -1
  337. package/dist/app/assets/index-E0F-_Dk8.css +0 -1
  338. package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-DrNQuVcu.js +0 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/chat.tsx
2
- import * as React49 from "react";
2
+ import * as React51 from "react";
3
3
  import {
4
4
  ArrowDown as ArrowDown2,
5
5
  ChevronDown as ChevronDown5,
@@ -14,7 +14,7 @@ import {
14
14
  Settings as Settings2,
15
15
  Target as Target2,
16
16
  Trash2 as Trash23,
17
- X as X6
17
+ X as X7
18
18
  } from "lucide-react";
19
19
 
20
20
  // src/lib/utils.ts
@@ -723,6 +723,9 @@ function ParentMessengerProvider({
723
723
  const onSetComposerValueHandlersRef = useRef(
724
724
  /* @__PURE__ */ new Set()
725
725
  );
726
+ const onSetRuntimeCapabilitiesHandlersRef = useRef(
727
+ /* @__PURE__ */ new Set()
728
+ );
726
729
  const onFocusComposerHandlersRef = useRef(/* @__PURE__ */ new Set());
727
730
  const latestOptionsRef = useRef(null);
728
731
  const isParentAvailable = useMemo(() => {
@@ -755,6 +758,15 @@ function ParentMessengerProvider({
755
758
  },
756
759
  []
757
760
  );
761
+ const registerOnSetRuntimeCapabilities = useCallback(
762
+ (handler) => {
763
+ onSetRuntimeCapabilitiesHandlersRef.current.add(handler);
764
+ return () => {
765
+ onSetRuntimeCapabilitiesHandlersRef.current.delete(handler);
766
+ };
767
+ },
768
+ []
769
+ );
758
770
  const registerOnFocusComposer = useCallback(
759
771
  (handler) => {
760
772
  onFocusComposerHandlersRef.current.add(handler);
@@ -879,6 +891,23 @@ function ParentMessengerProvider({
879
891
  });
880
892
  return;
881
893
  }
894
+ if (payload.type === "command" && payload.command === "onSetRuntimeCapabilities") {
895
+ const selection = isRuntimeCapabilitiesSelection(payload.data) ? payload.data : null;
896
+ void Promise.all(
897
+ [...onSetRuntimeCapabilitiesHandlersRef.current].map(
898
+ (handler2) => Promise.resolve(handler2(selection))
899
+ )
900
+ ).then(() => {
901
+ if (payload.nonce) {
902
+ sendResponse(payload.nonce, { ok: true });
903
+ }
904
+ }).catch((error) => {
905
+ if (payload.nonce) {
906
+ sendResponse(payload.nonce, void 0, error);
907
+ }
908
+ });
909
+ return;
910
+ }
882
911
  if (payload.type === "command" && payload.command === "onSetOptions") {
883
912
  latestOptionsRef.current = payload.data ?? null;
884
913
  if (onSetOptionsHandlersRef.current.size > 0) {
@@ -1000,6 +1029,7 @@ function ParentMessengerProvider({
1000
1029
  registerOnSetOptions,
1001
1030
  registerOnSetPetEnabled,
1002
1031
  registerOnSetComposerValue,
1032
+ registerOnSetRuntimeCapabilities,
1003
1033
  registerOnFocusComposer
1004
1034
  }),
1005
1035
  [
@@ -1009,6 +1039,7 @@ function ParentMessengerProvider({
1009
1039
  registerOnSetOptions,
1010
1040
  registerOnSetPetEnabled,
1011
1041
  registerOnSetComposerValue,
1042
+ registerOnSetRuntimeCapabilities,
1012
1043
  registerOnFocusComposer
1013
1044
  ]
1014
1045
  );
@@ -1020,6 +1051,7 @@ function useParentMessenger({
1020
1051
  onSetOptions,
1021
1052
  onSetPetEnabled,
1022
1053
  onSetComposerValue,
1054
+ onSetRuntimeCapabilities,
1023
1055
  onFocusComposer
1024
1056
  } = {}) {
1025
1057
  const context = useContext(ParentMessengerContext);
@@ -1032,12 +1064,14 @@ function useParentMessenger({
1032
1064
  registerOnSetOptions,
1033
1065
  registerOnSetPetEnabled,
1034
1066
  registerOnSetComposerValue,
1067
+ registerOnSetRuntimeCapabilities,
1035
1068
  registerOnFocusComposer,
1036
1069
  ...messenger
1037
1070
  } = context;
1038
1071
  const onSetOptionsRef = useRef2(onSetOptions);
1039
1072
  const onSetPetEnabledRef = useRef2(onSetPetEnabled);
1040
1073
  const onSetComposerValueRef = useRef2(onSetComposerValue);
1074
+ const onSetRuntimeCapabilitiesRef = useRef2(onSetRuntimeCapabilities);
1041
1075
  const onFocusComposerRef = useRef2(onFocusComposer);
1042
1076
  useEffect2(() => {
1043
1077
  onSetOptionsRef.current = onSetOptions;
@@ -1048,12 +1082,16 @@ function useParentMessenger({
1048
1082
  useEffect2(() => {
1049
1083
  onSetComposerValueRef.current = onSetComposerValue;
1050
1084
  }, [onSetComposerValue]);
1085
+ useEffect2(() => {
1086
+ onSetRuntimeCapabilitiesRef.current = onSetRuntimeCapabilities;
1087
+ }, [onSetRuntimeCapabilities]);
1051
1088
  useEffect2(() => {
1052
1089
  onFocusComposerRef.current = onFocusComposer;
1053
1090
  }, [onFocusComposer]);
1054
1091
  const hasOnSetOptions = Boolean(onSetOptions);
1055
1092
  const hasOnSetPetEnabled = Boolean(onSetPetEnabled);
1056
1093
  const hasOnSetComposerValue = Boolean(onSetComposerValue);
1094
+ const hasOnSetRuntimeCapabilities = Boolean(onSetRuntimeCapabilities);
1057
1095
  const hasOnFocusComposer = Boolean(onFocusComposer);
1058
1096
  useEffect2(() => {
1059
1097
  if (!hasOnSetOptions) return;
@@ -1076,6 +1114,13 @@ function useParentMessenger({
1076
1114
  };
1077
1115
  return registerOnSetComposerValue(handler);
1078
1116
  }, [hasOnSetComposerValue, registerOnSetComposerValue]);
1117
+ useEffect2(() => {
1118
+ if (!hasOnSetRuntimeCapabilities) return;
1119
+ const handler = (selection) => {
1120
+ onSetRuntimeCapabilitiesRef.current?.(selection);
1121
+ };
1122
+ return registerOnSetRuntimeCapabilities(handler);
1123
+ }, [hasOnSetRuntimeCapabilities, registerOnSetRuntimeCapabilities]);
1079
1124
  useEffect2(() => {
1080
1125
  if (!hasOnFocusComposer) return;
1081
1126
  const handler = () => {
@@ -1680,6 +1725,21 @@ var en_US_default = {
1680
1725
  loading: "Loading",
1681
1726
  thinking: "Thinking",
1682
1727
  answering: "Answering",
1728
+ navigation: {
1729
+ label: "Message navigation",
1730
+ system: "System",
1731
+ tool: "Tool",
1732
+ event: "Event",
1733
+ message: "Message",
1734
+ image: "Image",
1735
+ memory: "Memory",
1736
+ widget: "Widget",
1737
+ mcpApp: "MCP App",
1738
+ attachment: "Attachment",
1739
+ reference: "Reference",
1740
+ capability: "Capability",
1741
+ moreTags: "+{{count}}"
1742
+ },
1683
1743
  mcpApp: {
1684
1744
  loading: "Loading MCP App"
1685
1745
  },
@@ -2073,6 +2133,21 @@ var zh_CN_default = {
2073
2133
  loading: "\u6B63\u5728\u52A0\u8F7D",
2074
2134
  thinking: "\u6B63\u5728\u601D\u8003",
2075
2135
  answering: "\u6B63\u5728\u751F\u6210",
2136
+ navigation: {
2137
+ label: "\u6D88\u606F\u5BFC\u822A",
2138
+ system: "\u7CFB\u7EDF",
2139
+ tool: "\u5DE5\u5177",
2140
+ event: "\u4E8B\u4EF6",
2141
+ message: "\u6D88\u606F",
2142
+ image: "\u56FE\u7247",
2143
+ memory: "\u8BB0\u5FC6",
2144
+ widget: "\u7EC4\u4EF6",
2145
+ mcpApp: "MCP App",
2146
+ attachment: "\u9644\u4EF6",
2147
+ reference: "\u5F15\u7528",
2148
+ capability: "\u80FD\u529B",
2149
+ moreTags: "+{{count}}"
2150
+ },
2076
2151
  mcpApp: {
2077
2152
  loading: "\u6B63\u5728\u52A0\u8F7D MCP App"
2078
2153
  },
@@ -13226,10 +13301,179 @@ function AssistantMessage({
13226
13301
  ] });
13227
13302
  }
13228
13303
 
13229
- // src/components/thread/MessageActions.tsx
13304
+ // src/components/thread/MessageNavigator.tsx
13230
13305
  import * as React37 from "react";
13231
- import { Check as Check5, Copy as Copy3, RefreshCw as RefreshCw2 } from "lucide-react";
13232
13306
  import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
13307
+ var ACTIVE_OFFSET_PX = 12;
13308
+ function getMarkerWidthClass(index, active, interactionIndex) {
13309
+ if (interactionIndex >= 0) {
13310
+ const distance = Math.abs(index - interactionIndex);
13311
+ if (distance === 0) return "w-7";
13312
+ if (distance === 1) return "w-5";
13313
+ if (distance === 2) return "w-3.5";
13314
+ return "w-2";
13315
+ }
13316
+ return active ? "w-5" : "w-2";
13317
+ }
13318
+ function getAnchorTop(viewport, anchor) {
13319
+ return anchor.offsetTop - viewport.offsetTop;
13320
+ }
13321
+ function resolveActiveItemId(items, viewport, getAnchor) {
13322
+ if (!viewport || items.length === 0) return null;
13323
+ const targetTop = viewport.scrollTop + ACTIVE_OFFSET_PX;
13324
+ let activeId = items[0]?.id ?? null;
13325
+ for (const item of items) {
13326
+ const anchor = getAnchor(item);
13327
+ if (!anchor) continue;
13328
+ if (getAnchorTop(viewport, anchor) <= targetTop) {
13329
+ activeId = item.id;
13330
+ continue;
13331
+ }
13332
+ break;
13333
+ }
13334
+ return activeId;
13335
+ }
13336
+ function scrollToAnchor(viewport, anchor) {
13337
+ const top = Math.max(0, getAnchorTop(viewport, anchor) - ACTIVE_OFFSET_PX);
13338
+ if (typeof viewport.scrollTo === "function") {
13339
+ viewport.scrollTo({ top, behavior: "smooth" });
13340
+ return;
13341
+ }
13342
+ viewport.scrollTop = top;
13343
+ }
13344
+ function MessageNavigator({
13345
+ items,
13346
+ viewportRef,
13347
+ getAnchor,
13348
+ onNavigate,
13349
+ className,
13350
+ label,
13351
+ tagsOverflowLabel
13352
+ }) {
13353
+ const [hoveredId, setHoveredId] = React37.useState(null);
13354
+ const [focusedId, setFocusedId] = React37.useState(null);
13355
+ const [activeId, setActiveId] = React37.useState(null);
13356
+ const updateActiveItem = React37.useCallback(() => {
13357
+ const viewport = viewportRef.current;
13358
+ setActiveId(resolveActiveItemId(items, viewport, getAnchor));
13359
+ }, [getAnchor, items, viewportRef]);
13360
+ React37.useLayoutEffect(() => {
13361
+ updateActiveItem();
13362
+ }, [updateActiveItem]);
13363
+ React37.useEffect(() => {
13364
+ const viewport = viewportRef.current;
13365
+ if (!viewport) return;
13366
+ let frame = null;
13367
+ const scheduleUpdate = () => {
13368
+ if (frame !== null) return;
13369
+ frame = requestAnimationFrame(() => {
13370
+ frame = null;
13371
+ updateActiveItem();
13372
+ });
13373
+ };
13374
+ viewport.addEventListener("scroll", scheduleUpdate, { passive: true });
13375
+ window.addEventListener("resize", scheduleUpdate, { passive: true });
13376
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(scheduleUpdate) : null;
13377
+ resizeObserver?.observe(viewport);
13378
+ return () => {
13379
+ if (frame !== null) {
13380
+ cancelAnimationFrame(frame);
13381
+ }
13382
+ viewport.removeEventListener("scroll", scheduleUpdate);
13383
+ window.removeEventListener("resize", scheduleUpdate);
13384
+ resizeObserver?.disconnect();
13385
+ };
13386
+ }, [updateActiveItem, viewportRef]);
13387
+ const handleNavigate = React37.useCallback(
13388
+ (item) => {
13389
+ const viewport = viewportRef.current;
13390
+ const anchor = getAnchor(item);
13391
+ if (!viewport || !anchor) return;
13392
+ onNavigate?.();
13393
+ scrollToAnchor(viewport, anchor);
13394
+ setActiveId(item.id);
13395
+ },
13396
+ [getAnchor, onNavigate, viewportRef]
13397
+ );
13398
+ if (items.length === 0) return null;
13399
+ const interactionId = focusedId ?? hoveredId;
13400
+ const interactionIndex = interactionId ? items.findIndex((item) => item.id === interactionId) : -1;
13401
+ return /* @__PURE__ */ jsx43(
13402
+ "nav",
13403
+ {
13404
+ "aria-label": label,
13405
+ className: cn(
13406
+ "pointer-events-none sticky top-16 z-20 hidden h-0 w-0 shrink-0 self-start md:block",
13407
+ className
13408
+ ),
13409
+ "data-slot": "chatkit-message-navigator",
13410
+ children: /* @__PURE__ */ jsx43("div", { className: "group/nav relative h-[calc(100vh-9rem)] w-12", children: /* @__PURE__ */ jsx43("div", { className: "absolute left-2 top-1/2 flex max-h-full w-10 -translate-y-1/2 flex-col gap-0.5 py-1", children: items.map((item, index) => {
13411
+ const isActive = item.id === activeId;
13412
+ const isPreviewed = item.id === hoveredId || item.id === focusedId;
13413
+ return /* @__PURE__ */ jsxs30("div", { className: "relative h-3.5 w-10 shrink-0", children: [
13414
+ /* @__PURE__ */ jsx43(
13415
+ "button",
13416
+ {
13417
+ type: "button",
13418
+ "aria-label": `${item.title}: ${item.preview}`,
13419
+ "aria-current": isActive ? "location" : void 0,
13420
+ className: cn(
13421
+ "pointer-events-auto flex h-3.5 w-10 items-center justify-start rounded-sm outline-none",
13422
+ "focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
13423
+ ),
13424
+ onClick: () => handleNavigate(item),
13425
+ onMouseEnter: () => setHoveredId(item.id),
13426
+ onMouseLeave: () => setHoveredId((id) => id === item.id ? null : id),
13427
+ onFocus: () => setFocusedId(item.id),
13428
+ onBlur: () => setFocusedId((id) => id === item.id ? null : id),
13429
+ children: /* @__PURE__ */ jsx43(
13430
+ "span",
13431
+ {
13432
+ className: cn(
13433
+ "block h-0.5 rounded-full bg-muted-foreground/25 transition-all duration-150",
13434
+ getMarkerWidthClass(index, isActive, interactionIndex),
13435
+ isActive && "bg-foreground",
13436
+ isPreviewed && "bg-foreground",
13437
+ interactionIndex >= 0 && !isActive && !isPreviewed && "bg-muted-foreground/35"
13438
+ )
13439
+ }
13440
+ )
13441
+ }
13442
+ ),
13443
+ isPreviewed && /* @__PURE__ */ jsxs30(
13444
+ "div",
13445
+ {
13446
+ className: cn(
13447
+ "pointer-events-none absolute left-9 top-1/2 z-30 w-80 max-w-[min(20rem,calc(100vw-6rem))] -translate-y-1/2",
13448
+ "rounded-lg border border-border bg-background/95 p-3 text-left shadow-xl backdrop-blur"
13449
+ ),
13450
+ children: [
13451
+ /* @__PURE__ */ jsx43("div", { className: "mb-1 truncate text-sm font-medium text-foreground", children: item.title }),
13452
+ /* @__PURE__ */ jsx43("div", { className: "line-clamp-2 text-sm leading-5 text-muted-foreground", children: item.preview }),
13453
+ item.tags.length > 0 && /* @__PURE__ */ jsxs30("div", { className: "mt-2 flex flex-wrap gap-1.5", children: [
13454
+ item.tags.slice(0, 3).map((tag) => /* @__PURE__ */ jsx43(
13455
+ "span",
13456
+ {
13457
+ className: "max-w-[8rem] truncate rounded-md bg-muted px-1.5 py-0.5 text-[11px] leading-4 text-muted-foreground",
13458
+ children: tag
13459
+ },
13460
+ tag
13461
+ )),
13462
+ item.tags.length > 3 && /* @__PURE__ */ jsx43("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-[11px] leading-4 text-muted-foreground", children: tagsOverflowLabel(item.tags.length - 3) })
13463
+ ] })
13464
+ ]
13465
+ }
13466
+ )
13467
+ ] }, item.id);
13468
+ }) }) })
13469
+ }
13470
+ );
13471
+ }
13472
+
13473
+ // src/components/thread/MessageActions.tsx
13474
+ import * as React38 from "react";
13475
+ import { Check as Check5, Copy as Copy3, RefreshCw as RefreshCw2 } from "lucide-react";
13476
+ import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
13233
13477
  function MessageActions({
13234
13478
  content,
13235
13479
  isAssistant = false,
@@ -13238,7 +13482,7 @@ function MessageActions({
13238
13482
  className
13239
13483
  }) {
13240
13484
  const { t } = useChatkitTranslation();
13241
- const [copied, setCopied] = React37.useState(false);
13485
+ const [copied, setCopied] = React38.useState(false);
13242
13486
  const handleCopy = async () => {
13243
13487
  try {
13244
13488
  await navigator.clipboard.writeText(content);
@@ -13251,7 +13495,7 @@ function MessageActions({
13251
13495
  if (isStreaming) {
13252
13496
  return null;
13253
13497
  }
13254
- return /* @__PURE__ */ jsxs30(
13498
+ return /* @__PURE__ */ jsxs31(
13255
13499
  "div",
13256
13500
  {
13257
13501
  className: cn(
@@ -13259,7 +13503,7 @@ function MessageActions({
13259
13503
  className
13260
13504
  ),
13261
13505
  children: [
13262
- /* @__PURE__ */ jsx43(
13506
+ /* @__PURE__ */ jsx44(
13263
13507
  "button",
13264
13508
  {
13265
13509
  type: "button",
@@ -13269,17 +13513,17 @@ function MessageActions({
13269
13513
  copied && "text-green-500"
13270
13514
  ),
13271
13515
  title: copied ? t("messageActions.copied") : t("messageActions.copy"),
13272
- children: copied ? /* @__PURE__ */ jsx43(Check5, { size: 14 }) : /* @__PURE__ */ jsx43(Copy3, { size: 14 })
13516
+ children: copied ? /* @__PURE__ */ jsx44(Check5, { size: 14 }) : /* @__PURE__ */ jsx44(Copy3, { size: 14 })
13273
13517
  }
13274
13518
  ),
13275
- isAssistant && onRetry && /* @__PURE__ */ jsx43(
13519
+ isAssistant && onRetry && /* @__PURE__ */ jsx44(
13276
13520
  "button",
13277
13521
  {
13278
13522
  type: "button",
13279
13523
  onClick: onRetry,
13280
13524
  className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
13281
13525
  title: t("messageActions.regenerate"),
13282
- children: /* @__PURE__ */ jsx43(RefreshCw2, { size: 14 })
13526
+ children: /* @__PURE__ */ jsx44(RefreshCw2, { size: 14 })
13283
13527
  }
13284
13528
  )
13285
13529
  ]
@@ -13300,18 +13544,18 @@ import {
13300
13544
  Sparkles as Sparkles3,
13301
13545
  Zap
13302
13546
  } from "lucide-react";
13303
- import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
13547
+ import { jsx as jsx45, jsxs as jsxs32 } from "react/jsx-runtime";
13304
13548
  function getIconComponent2(icon) {
13305
13549
  const iconMap = {
13306
- "circle-question": /* @__PURE__ */ jsx44(HelpCircle, { size: 20 }),
13307
- "lightbulb": /* @__PURE__ */ jsx44(Lightbulb2, { size: 20 }),
13308
- "sparkle": /* @__PURE__ */ jsx44(Sparkles3, { size: 20 }),
13309
- "write": /* @__PURE__ */ jsx44(Pencil3, { size: 20 }),
13310
- "search": /* @__PURE__ */ jsx44(Search3, { size: 20 }),
13311
- "globe": /* @__PURE__ */ jsx44(Globe2, { size: 20 }),
13312
- "book-open": /* @__PURE__ */ jsx44(BookOpen2, { size: 20 }),
13313
- "compass": /* @__PURE__ */ jsx44(Compass, { size: 20 }),
13314
- "bolt": /* @__PURE__ */ jsx44(Zap, { size: 20 })
13550
+ "circle-question": /* @__PURE__ */ jsx45(HelpCircle, { size: 20 }),
13551
+ "lightbulb": /* @__PURE__ */ jsx45(Lightbulb2, { size: 20 }),
13552
+ "sparkle": /* @__PURE__ */ jsx45(Sparkles3, { size: 20 }),
13553
+ "write": /* @__PURE__ */ jsx45(Pencil3, { size: 20 }),
13554
+ "search": /* @__PURE__ */ jsx45(Search3, { size: 20 }),
13555
+ "globe": /* @__PURE__ */ jsx45(Globe2, { size: 20 }),
13556
+ "book-open": /* @__PURE__ */ jsx45(BookOpen2, { size: 20 }),
13557
+ "compass": /* @__PURE__ */ jsx45(Compass, { size: 20 }),
13558
+ "bolt": /* @__PURE__ */ jsx45(Zap, { size: 20 })
13315
13559
  };
13316
13560
  return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
13317
13561
  }
@@ -13327,7 +13571,7 @@ function StartScreen({
13327
13571
  const greeting = startScreen?.greeting ?? t("startScreen.greeting");
13328
13572
  const prompts = startScreen?.prompts ?? [];
13329
13573
  const editPromptLabel = t("startScreen.editPrompt");
13330
- return /* @__PURE__ */ jsxs31(
13574
+ return /* @__PURE__ */ jsxs32(
13331
13575
  "div",
13332
13576
  {
13333
13577
  className: cn(
@@ -13335,8 +13579,8 @@ function StartScreen({
13335
13579
  className
13336
13580
  ),
13337
13581
  children: [
13338
- /* @__PURE__ */ jsx44("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx44("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
13339
- prompts.length > 0 && /* @__PURE__ */ jsx44("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx44("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs31(
13582
+ /* @__PURE__ */ jsx45("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx45("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
13583
+ prompts.length > 0 && /* @__PURE__ */ jsx45("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx45("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs32(
13340
13584
  "div",
13341
13585
  {
13342
13586
  className: cn(
@@ -13345,7 +13589,7 @@ function StartScreen({
13345
13589
  "focus-within:ring-2 focus-within:ring-primary/20"
13346
13590
  ),
13347
13591
  children: [
13348
- /* @__PURE__ */ jsxs31(
13592
+ /* @__PURE__ */ jsxs32(
13349
13593
  "button",
13350
13594
  {
13351
13595
  type: "button",
@@ -13356,12 +13600,12 @@ function StartScreen({
13356
13600
  "focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
13357
13601
  ),
13358
13602
  children: [
13359
- /* @__PURE__ */ jsx44("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
13360
- /* @__PURE__ */ jsx44("span", { className: "text-sm font-medium text-foreground", children: item.label })
13603
+ /* @__PURE__ */ jsx45("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
13604
+ /* @__PURE__ */ jsx45("span", { className: "text-sm font-medium text-foreground", children: item.label })
13361
13605
  ]
13362
13606
  }
13363
13607
  ),
13364
- /* @__PURE__ */ jsx44(
13608
+ /* @__PURE__ */ jsx45(
13365
13609
  "button",
13366
13610
  {
13367
13611
  type: "button",
@@ -13374,7 +13618,7 @@ function StartScreen({
13374
13618
  "rounded-r-xl transition-colors hover:bg-muted hover:text-foreground",
13375
13619
  "focus:outline-none disabled:cursor-not-allowed disabled:opacity-50"
13376
13620
  ),
13377
- children: /* @__PURE__ */ jsx44(Pencil3, { size: 16 })
13621
+ children: /* @__PURE__ */ jsx45(Pencil3, { size: 16 })
13378
13622
  }
13379
13623
  )
13380
13624
  ]
@@ -13387,7 +13631,7 @@ function StartScreen({
13387
13631
  }
13388
13632
 
13389
13633
  // src/hooks/useThreads.ts
13390
- import * as React39 from "react";
13634
+ import * as React40 from "react";
13391
13635
  var DEFAULT_LIMIT = 50;
13392
13636
  var getThreadTitle = (threadRecord) => {
13393
13637
  const title = threadRecord.title?.trim();
@@ -13440,16 +13684,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
13440
13684
  isLoading: isStreamLoading,
13441
13685
  error: streamError
13442
13686
  } = useStreamContext();
13443
- const [threadRecords, setThreadRecords] = React39.useState([]);
13444
- const [isLoading, setIsLoading] = React39.useState(false);
13445
- const [error, setError] = React39.useState(null);
13446
- const upsertThreadRecord = React39.useCallback((threadRecord) => {
13687
+ const [threadRecords, setThreadRecords] = React40.useState([]);
13688
+ const [isLoading, setIsLoading] = React40.useState(false);
13689
+ const [error, setError] = React40.useState(null);
13690
+ const upsertThreadRecord = React40.useCallback((threadRecord) => {
13447
13691
  setThreadRecords((prev) => {
13448
13692
  const next = prev.filter((item) => item.id !== threadRecord.id);
13449
13693
  return sortThreadRecords([threadRecord, ...next]);
13450
13694
  });
13451
13695
  }, []);
13452
- const refreshThreads = React39.useCallback(async () => {
13696
+ const refreshThreads = React40.useCallback(async () => {
13453
13697
  setIsLoading(true);
13454
13698
  setError(null);
13455
13699
  try {
@@ -13465,7 +13709,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13465
13709
  setIsLoading(false);
13466
13710
  }
13467
13711
  }, [client, limit, assistantId]);
13468
- const createThread = React39.useCallback(
13712
+ const createThread = React40.useCallback(
13469
13713
  async (input) => {
13470
13714
  setError(null);
13471
13715
  const payload = {};
@@ -13479,7 +13723,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13479
13723
  },
13480
13724
  [client, upsertThreadRecord]
13481
13725
  );
13482
- const updateThread = React39.useCallback(
13726
+ const updateThread = React40.useCallback(
13483
13727
  async (recordId, payload) => {
13484
13728
  setError(null);
13485
13729
  const updated = await client.conversations.update(recordId, payload);
@@ -13488,7 +13732,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13488
13732
  },
13489
13733
  [client, upsertThreadRecord]
13490
13734
  );
13491
- const deleteThread = React39.useCallback(
13735
+ const deleteThread = React40.useCallback(
13492
13736
  async (recordId) => {
13493
13737
  setError(null);
13494
13738
  await client.conversations.delete(recordId);
@@ -13496,11 +13740,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
13496
13740
  },
13497
13741
  [client]
13498
13742
  );
13499
- React39.useEffect(() => {
13743
+ React40.useEffect(() => {
13500
13744
  if (!isReady) return;
13501
13745
  void refreshThreads();
13502
13746
  }, [refreshThreads, isReady]);
13503
- React39.useEffect(() => {
13747
+ React40.useEffect(() => {
13504
13748
  if (!threadId || !isStreamLoading) return;
13505
13749
  const now = (/* @__PURE__ */ new Date()).toISOString();
13506
13750
  const busyStatus = "busy";
@@ -13521,7 +13765,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13521
13765
  return changed ? sortThreadRecords(next) : prev;
13522
13766
  });
13523
13767
  }, [threadId, isStreamLoading]);
13524
- React39.useEffect(() => {
13768
+ React40.useEffect(() => {
13525
13769
  const message = getErrorMessage2(streamError)?.trim();
13526
13770
  if (!threadId || !message) return;
13527
13771
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -13543,7 +13787,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13543
13787
  return changed ? sortThreadRecords(next) : prev;
13544
13788
  });
13545
13789
  }, [threadId, streamError]);
13546
- React39.useEffect(() => {
13790
+ React40.useEffect(() => {
13547
13791
  if (!isReady || !threadId || isStreamLoading) return;
13548
13792
  let cancelled = false;
13549
13793
  void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
@@ -13557,7 +13801,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
13557
13801
  cancelled = true;
13558
13802
  };
13559
13803
  }, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
13560
- const threads = React39.useMemo(
13804
+ const threads = React40.useMemo(
13561
13805
  () => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
13562
13806
  [threadRecords]
13563
13807
  );
@@ -13574,10 +13818,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
13574
13818
  }
13575
13819
 
13576
13820
  // src/components/thread/context-usage-indicator.tsx
13577
- import * as React40 from "react";
13821
+ import * as React41 from "react";
13578
13822
 
13579
13823
  // src/components/ui/progress-circle.tsx
13580
- import { jsx as jsx45, jsxs as jsxs32 } from "react/jsx-runtime";
13824
+ import { jsx as jsx46, jsxs as jsxs33 } from "react/jsx-runtime";
13581
13825
  function clamp2(input, a, b) {
13582
13826
  return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
13583
13827
  }
@@ -13600,7 +13844,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
13600
13844
  return (
13601
13845
  // biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
13602
13846
  // biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
13603
- /* @__PURE__ */ jsxs32(
13847
+ /* @__PURE__ */ jsxs33(
13604
13848
  "svg",
13605
13849
  {
13606
13850
  role: "progressbar",
@@ -13611,8 +13855,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
13611
13855
  "aria-valuemax": 100,
13612
13856
  ...restSvgProps,
13613
13857
  children: [
13614
- /* @__PURE__ */ jsx45("circle", { ...commonParams, className: "stroke-current/25" }),
13615
- /* @__PURE__ */ jsx45(
13858
+ /* @__PURE__ */ jsx46("circle", { ...commonParams, className: "stroke-current/25" }),
13859
+ /* @__PURE__ */ jsx46(
13616
13860
  "circle",
13617
13861
  {
13618
13862
  ...commonParams,
@@ -13631,7 +13875,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
13631
13875
  };
13632
13876
 
13633
13877
  // src/components/thread/context-usage-indicator.tsx
13634
- import { jsx as jsx46, jsxs as jsxs33 } from "react/jsx-runtime";
13878
+ import { jsx as jsx47, jsxs as jsxs34 } from "react/jsx-runtime";
13635
13879
  var kNumberFormatter = new Intl.NumberFormat("en-US", {
13636
13880
  minimumFractionDigits: 0,
13637
13881
  maximumFractionDigits: 1
@@ -13664,21 +13908,21 @@ function ContextUsageIndicator({
13664
13908
  }) {
13665
13909
  const { t } = useChatkitTranslation();
13666
13910
  const stream = useStreamContext();
13667
- const [maxContextSize, setMaxContextSize] = React40.useState(null);
13668
- const [usedContextSize, setUsedContextSize] = React40.useState(null);
13669
- const [assistantAgentKey, setAssistantAgentKey] = React40.useState(null);
13670
- const latestRealtimeUsageRef = React40.useRef({
13911
+ const [maxContextSize, setMaxContextSize] = React41.useState(null);
13912
+ const [usedContextSize, setUsedContextSize] = React41.useState(null);
13913
+ const [assistantAgentKey, setAssistantAgentKey] = React41.useState(null);
13914
+ const latestRealtimeUsageRef = React41.useRef({
13671
13915
  threadId: null,
13672
13916
  agentKey: null,
13673
13917
  usedTokens: null
13674
13918
  });
13675
- const realtimeUsage = React40.useMemo(
13919
+ const realtimeUsage = React41.useMemo(
13676
13920
  () => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
13677
13921
  [assistantAgentKey, stream.contextUsageByAgentKey]
13678
13922
  );
13679
13923
  const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
13680
13924
  const hasApiConfiguration = Boolean(stream.apiUrl?.trim() && stream.apiKey?.trim());
13681
- React40.useEffect(() => {
13925
+ React41.useEffect(() => {
13682
13926
  if (!hasApiConfiguration || !stream.client || !stream.assistantId) {
13683
13927
  setMaxContextSize(null);
13684
13928
  setAssistantAgentKey(null);
@@ -13698,18 +13942,18 @@ function ContextUsageIndicator({
13698
13942
  cancelled = true;
13699
13943
  };
13700
13944
  }, [hasApiConfiguration, stream.client, stream.assistantId]);
13701
- React40.useEffect(() => {
13945
+ React41.useEffect(() => {
13702
13946
  latestRealtimeUsageRef.current = {
13703
13947
  threadId: stream.threadId ?? null,
13704
13948
  agentKey: assistantAgentKey,
13705
13949
  usedTokens: realtimeUsedContextSize
13706
13950
  };
13707
13951
  }, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
13708
- React40.useEffect(() => {
13952
+ React41.useEffect(() => {
13709
13953
  if (realtimeUsedContextSize == null) return;
13710
13954
  setUsedContextSize(realtimeUsedContextSize);
13711
13955
  }, [realtimeUsedContextSize]);
13712
- React40.useEffect(() => {
13956
+ React41.useEffect(() => {
13713
13957
  if (!hasApiConfiguration || !stream.client) {
13714
13958
  setUsedContextSize(null);
13715
13959
  return;
@@ -13775,8 +14019,8 @@ function ContextUsageIndicator({
13775
14019
  });
13776
14020
  const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
13777
14021
  const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
13778
- return /* @__PURE__ */ jsxs33(Tooltip, { children: [
13779
- /* @__PURE__ */ jsx46(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx46(
14022
+ return /* @__PURE__ */ jsxs34(Tooltip, { children: [
14023
+ /* @__PURE__ */ jsx47(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx47(
13780
14024
  "button",
13781
14025
  {
13782
14026
  type: "button",
@@ -13785,31 +14029,31 @@ function ContextUsageIndicator({
13785
14029
  className
13786
14030
  ),
13787
14031
  "aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
13788
- children: /* @__PURE__ */ jsx46(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
14032
+ children: /* @__PURE__ */ jsx47(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
13789
14033
  }
13790
14034
  ) }),
13791
- /* @__PURE__ */ jsxs33(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
13792
- /* @__PURE__ */ jsx46("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
13793
- /* @__PURE__ */ jsx46("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
13794
- /* @__PURE__ */ jsx46("div", { className: "text-sm font-semibold", children: usageTokensLabel })
14035
+ /* @__PURE__ */ jsxs34(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
14036
+ /* @__PURE__ */ jsx47("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
14037
+ /* @__PURE__ */ jsx47("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
14038
+ /* @__PURE__ */ jsx47("div", { className: "text-sm font-semibold", children: usageTokensLabel })
13795
14039
  ] })
13796
14040
  ] });
13797
14041
  }
13798
14042
 
13799
14043
  // src/components/pet/PetBridge.tsx
13800
- import * as React41 from "react";
14044
+ import * as React42 from "react";
13801
14045
  import { normalizePetOptions } from "@xpert-ai/chatkit-types";
13802
14046
  function PetBridge({ pet, state }) {
13803
14047
  const parentMessenger = useParentMessenger();
13804
14048
  const sendEvent = parentMessenger?.sendEvent;
13805
- const options = React41.useMemo(() => normalizePetOptions(pet), [pet]);
13806
- React41.useEffect(() => {
14049
+ const options = React42.useMemo(() => normalizePetOptions(pet), [pet]);
14050
+ React42.useEffect(() => {
13807
14051
  if (!sendEvent) {
13808
14052
  return;
13809
14053
  }
13810
14054
  sendEvent("pet_options_change", { pet: pet ?? null });
13811
14055
  }, [sendEvent, pet]);
13812
- React41.useEffect(() => {
14056
+ React42.useEffect(() => {
13813
14057
  if (!sendEvent || !options) {
13814
14058
  return;
13815
14059
  }
@@ -13819,15 +14063,15 @@ function PetBridge({ pet, state }) {
13819
14063
  }
13820
14064
 
13821
14065
  // src/components/settings/SettingsSheet.tsx
13822
- import * as React48 from "react";
14066
+ import * as React49 from "react";
13823
14067
  import { PawPrint, Settings } from "lucide-react";
13824
14068
 
13825
14069
  // src/components/ui/input.tsx
13826
- import * as React42 from "react";
13827
- import { jsx as jsx47 } from "react/jsx-runtime";
13828
- var Input = React42.forwardRef(
14070
+ import * as React43 from "react";
14071
+ import { jsx as jsx48 } from "react/jsx-runtime";
14072
+ var Input = React43.forwardRef(
13829
14073
  ({ className, type, ...props }, ref) => {
13830
- return /* @__PURE__ */ jsx47(
14074
+ return /* @__PURE__ */ jsx48(
13831
14075
  "input",
13832
14076
  {
13833
14077
  ref,
@@ -13847,17 +14091,17 @@ Input.displayName = "Input";
13847
14091
  import "react";
13848
14092
  import { Select as SelectPrimitive } from "radix-ui";
13849
14093
  import { ChevronDownIcon as ChevronDownIcon2, CheckIcon as CheckIcon4, ChevronUpIcon } from "lucide-react";
13850
- import { jsx as jsx48, jsxs as jsxs34 } from "react/jsx-runtime";
14094
+ import { jsx as jsx49, jsxs as jsxs35 } from "react/jsx-runtime";
13851
14095
  function Select({
13852
14096
  ...props
13853
14097
  }) {
13854
- return /* @__PURE__ */ jsx48(SelectPrimitive.Root, { "data-slot": "select", ...props });
14098
+ return /* @__PURE__ */ jsx49(SelectPrimitive.Root, { "data-slot": "select", ...props });
13855
14099
  }
13856
14100
  function SelectGroup({
13857
14101
  className,
13858
14102
  ...props
13859
14103
  }) {
13860
- return /* @__PURE__ */ jsx48(
14104
+ return /* @__PURE__ */ jsx49(
13861
14105
  SelectPrimitive.Group,
13862
14106
  {
13863
14107
  "data-slot": "select-group",
@@ -13869,7 +14113,7 @@ function SelectGroup({
13869
14113
  function SelectValue({
13870
14114
  ...props
13871
14115
  }) {
13872
- return /* @__PURE__ */ jsx48(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
14116
+ return /* @__PURE__ */ jsx49(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
13873
14117
  }
13874
14118
  function SelectTrigger({
13875
14119
  className,
@@ -13877,7 +14121,7 @@ function SelectTrigger({
13877
14121
  children,
13878
14122
  ...props
13879
14123
  }) {
13880
- return /* @__PURE__ */ jsxs34(
14124
+ return /* @__PURE__ */ jsxs35(
13881
14125
  SelectPrimitive.Trigger,
13882
14126
  {
13883
14127
  "data-slot": "select-trigger",
@@ -13889,7 +14133,7 @@ function SelectTrigger({
13889
14133
  ...props,
13890
14134
  children: [
13891
14135
  children,
13892
- /* @__PURE__ */ jsx48(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx48(ChevronDownIcon2, { className: "pointer-events-none size-4 text-muted-foreground" }) })
14136
+ /* @__PURE__ */ jsx49(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx49(ChevronDownIcon2, { className: "pointer-events-none size-4 text-muted-foreground" }) })
13893
14137
  ]
13894
14138
  }
13895
14139
  );
@@ -13901,7 +14145,7 @@ function SelectContent({
13901
14145
  align = "center",
13902
14146
  ...props
13903
14147
  }) {
13904
- return /* @__PURE__ */ jsx48(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs34(
14148
+ return /* @__PURE__ */ jsx49(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs35(
13905
14149
  SelectPrimitive.Content,
13906
14150
  {
13907
14151
  "data-slot": "select-content",
@@ -13911,8 +14155,8 @@ function SelectContent({
13911
14155
  align,
13912
14156
  ...props,
13913
14157
  children: [
13914
- /* @__PURE__ */ jsx48(SelectScrollUpButton, {}),
13915
- /* @__PURE__ */ jsx48(
14158
+ /* @__PURE__ */ jsx49(SelectScrollUpButton, {}),
14159
+ /* @__PURE__ */ jsx49(
13916
14160
  SelectPrimitive.Viewport,
13917
14161
  {
13918
14162
  "data-position": position,
@@ -13923,7 +14167,7 @@ function SelectContent({
13923
14167
  children
13924
14168
  }
13925
14169
  ),
13926
- /* @__PURE__ */ jsx48(SelectScrollDownButton, {})
14170
+ /* @__PURE__ */ jsx49(SelectScrollDownButton, {})
13927
14171
  ]
13928
14172
  }
13929
14173
  ) });
@@ -13933,7 +14177,7 @@ function SelectItem({
13933
14177
  children,
13934
14178
  ...props
13935
14179
  }) {
13936
- return /* @__PURE__ */ jsxs34(
14180
+ return /* @__PURE__ */ jsxs35(
13937
14181
  SelectPrimitive.Item,
13938
14182
  {
13939
14183
  "data-slot": "select-item",
@@ -13943,8 +14187,8 @@ function SelectItem({
13943
14187
  ),
13944
14188
  ...props,
13945
14189
  children: [
13946
- /* @__PURE__ */ jsx48("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsx48(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx48(CheckIcon4, { className: "pointer-events-none" }) }) }),
13947
- /* @__PURE__ */ jsx48(SelectPrimitive.ItemText, { children })
14190
+ /* @__PURE__ */ jsx49("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsx49(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx49(CheckIcon4, { className: "pointer-events-none" }) }) }),
14191
+ /* @__PURE__ */ jsx49(SelectPrimitive.ItemText, { children })
13948
14192
  ]
13949
14193
  }
13950
14194
  );
@@ -13953,7 +14197,7 @@ function SelectScrollUpButton({
13953
14197
  className,
13954
14198
  ...props
13955
14199
  }) {
13956
- return /* @__PURE__ */ jsx48(
14200
+ return /* @__PURE__ */ jsx49(
13957
14201
  SelectPrimitive.ScrollUpButton,
13958
14202
  {
13959
14203
  "data-slot": "select-scroll-up-button",
@@ -13962,7 +14206,7 @@ function SelectScrollUpButton({
13962
14206
  className
13963
14207
  ),
13964
14208
  ...props,
13965
- children: /* @__PURE__ */ jsx48(
14209
+ children: /* @__PURE__ */ jsx49(
13966
14210
  ChevronUpIcon,
13967
14211
  {}
13968
14212
  )
@@ -13973,7 +14217,7 @@ function SelectScrollDownButton({
13973
14217
  className,
13974
14218
  ...props
13975
14219
  }) {
13976
- return /* @__PURE__ */ jsx48(
14220
+ return /* @__PURE__ */ jsx49(
13977
14221
  SelectPrimitive.ScrollDownButton,
13978
14222
  {
13979
14223
  "data-slot": "select-scroll-down-button",
@@ -13982,7 +14226,7 @@ function SelectScrollDownButton({
13982
14226
  className
13983
14227
  ),
13984
14228
  ...props,
13985
- children: /* @__PURE__ */ jsx48(
14229
+ children: /* @__PURE__ */ jsx49(
13986
14230
  ChevronDownIcon2,
13987
14231
  {}
13988
14232
  )
@@ -13991,9 +14235,9 @@ function SelectScrollDownButton({
13991
14235
  }
13992
14236
 
13993
14237
  // src/components/ui/slider.tsx
13994
- import * as React44 from "react";
14238
+ import * as React45 from "react";
13995
14239
  import { Slider as SliderPrimitive } from "radix-ui";
13996
- import { jsx as jsx49, jsxs as jsxs35 } from "react/jsx-runtime";
14240
+ import { jsx as jsx50, jsxs as jsxs36 } from "react/jsx-runtime";
13997
14241
  function Slider({
13998
14242
  className,
13999
14243
  defaultValue,
@@ -14002,11 +14246,11 @@ function Slider({
14002
14246
  max = 100,
14003
14247
  ...props
14004
14248
  }) {
14005
- const _values = React44.useMemo(
14249
+ const _values = React45.useMemo(
14006
14250
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
14007
14251
  [value, defaultValue, min, max]
14008
14252
  );
14009
- return /* @__PURE__ */ jsxs35(
14253
+ return /* @__PURE__ */ jsxs36(
14010
14254
  SliderPrimitive.Root,
14011
14255
  {
14012
14256
  "data-slot": "slider",
@@ -14020,12 +14264,12 @@ function Slider({
14020
14264
  ),
14021
14265
  ...props,
14022
14266
  children: [
14023
- /* @__PURE__ */ jsx49(
14267
+ /* @__PURE__ */ jsx50(
14024
14268
  SliderPrimitive.Track,
14025
14269
  {
14026
14270
  "data-slot": "slider-track",
14027
14271
  className: "relative grow overflow-hidden rounded-full bg-muted data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1",
14028
- children: /* @__PURE__ */ jsx49(
14272
+ children: /* @__PURE__ */ jsx50(
14029
14273
  SliderPrimitive.Range,
14030
14274
  {
14031
14275
  "data-slot": "slider-range",
@@ -14034,7 +14278,7 @@ function Slider({
14034
14278
  )
14035
14279
  }
14036
14280
  ),
14037
- Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx49(
14281
+ Array.from({ length: _values.length }, (_, index) => /* @__PURE__ */ jsx50(
14038
14282
  SliderPrimitive.Thumb,
14039
14283
  {
14040
14284
  "data-slot": "slider-thumb",
@@ -14048,7 +14292,7 @@ function Slider({
14048
14292
  }
14049
14293
 
14050
14294
  // src/components/ui/toggle-group.tsx
14051
- import * as React46 from "react";
14295
+ import * as React47 from "react";
14052
14296
  import "class-variance-authority";
14053
14297
  import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
14054
14298
 
@@ -14056,7 +14300,7 @@ import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui";
14056
14300
  import "react";
14057
14301
  import { cva as cva2 } from "class-variance-authority";
14058
14302
  import { Toggle as TogglePrimitive } from "radix-ui";
14059
- import { jsx as jsx50 } from "react/jsx-runtime";
14303
+ import { jsx as jsx51 } from "react/jsx-runtime";
14060
14304
  var toggleVariants = cva2(
14061
14305
  "group/toggle inline-flex items-center justify-center gap-1 rounded-lg text-sm font-medium whitespace-nowrap transition-all outline-none hover:bg-muted hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-pressed:bg-muted data-[state=on]:bg-muted dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
14062
14306
  {
@@ -14079,8 +14323,8 @@ var toggleVariants = cva2(
14079
14323
  );
14080
14324
 
14081
14325
  // src/components/ui/toggle-group.tsx
14082
- import { jsx as jsx51 } from "react/jsx-runtime";
14083
- var ToggleGroupContext = React46.createContext({
14326
+ import { jsx as jsx52 } from "react/jsx-runtime";
14327
+ var ToggleGroupContext = React47.createContext({
14084
14328
  size: "default",
14085
14329
  variant: "default",
14086
14330
  spacing: 0,
@@ -14095,7 +14339,7 @@ function ToggleGroup({
14095
14339
  children,
14096
14340
  ...props
14097
14341
  }) {
14098
- return /* @__PURE__ */ jsx51(
14342
+ return /* @__PURE__ */ jsx52(
14099
14343
  ToggleGroupPrimitive.Root,
14100
14344
  {
14101
14345
  "data-slot": "toggle-group",
@@ -14109,7 +14353,7 @@ function ToggleGroup({
14109
14353
  className
14110
14354
  ),
14111
14355
  ...props,
14112
- children: /* @__PURE__ */ jsx51(
14356
+ children: /* @__PURE__ */ jsx52(
14113
14357
  ToggleGroupContext.Provider,
14114
14358
  {
14115
14359
  value: { variant, size: size2, spacing, orientation },
@@ -14126,8 +14370,8 @@ function ToggleGroupItem({
14126
14370
  size: size2 = "default",
14127
14371
  ...props
14128
14372
  }) {
14129
- const context = React46.useContext(ToggleGroupContext);
14130
- return /* @__PURE__ */ jsx51(
14373
+ const context = React47.useContext(ToggleGroupContext);
14374
+ return /* @__PURE__ */ jsx52(
14131
14375
  ToggleGroupPrimitive.Item,
14132
14376
  {
14133
14377
  "data-slot": "toggle-group-item",
@@ -14367,7 +14611,7 @@ import {
14367
14611
  } from "@xpert-ai/chatkit-types";
14368
14612
 
14369
14613
  // src/components/pet/PetPreview.tsx
14370
- import { jsx as jsx52 } from "react/jsx-runtime";
14614
+ import { jsx as jsx53 } from "react/jsx-runtime";
14371
14615
  function escapeCssUrl(value) {
14372
14616
  return value.replace(/["\\]/g, "\\$&");
14373
14617
  }
@@ -14375,7 +14619,7 @@ function PetPreview({ src, label, className }) {
14375
14619
  const scale = 0.13;
14376
14620
  const width = petSpriteAtlas.cellWidth;
14377
14621
  const height = petSpriteAtlas.cellHeight;
14378
- return /* @__PURE__ */ jsx52(
14622
+ return /* @__PURE__ */ jsx53(
14379
14623
  "span",
14380
14624
  {
14381
14625
  className: cn(
@@ -14384,7 +14628,7 @@ function PetPreview({ src, label, className }) {
14384
14628
  ),
14385
14629
  "aria-hidden": "true",
14386
14630
  title: label,
14387
- children: /* @__PURE__ */ jsx52(
14631
+ children: /* @__PURE__ */ jsx53(
14388
14632
  "span",
14389
14633
  {
14390
14634
  className: "absolute left-1/2 top-1/2 block",
@@ -14406,7 +14650,7 @@ function PetPreview({ src, label, className }) {
14406
14650
  }
14407
14651
 
14408
14652
  // src/components/settings/SettingsSheet.tsx
14409
- import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
14653
+ import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
14410
14654
  var CHARACTER_TYPES2 = [
14411
14655
  "builtin",
14412
14656
  "atlas"
@@ -14422,13 +14666,13 @@ function SettingsSheet({
14422
14666
  onSave
14423
14667
  }) {
14424
14668
  const { t } = useChatkitTranslation();
14425
- const [draft, setDraft] = React48.useState(settings);
14426
- React48.useEffect(() => {
14669
+ const [draft, setDraft] = React49.useState(settings);
14670
+ React49.useEffect(() => {
14427
14671
  if (open) {
14428
14672
  setDraft(petRequired ? { ...settings, enabled: true } : settings);
14429
14673
  }
14430
14674
  }, [open, petRequired, settings]);
14431
- const updateDraft = React48.useCallback(
14675
+ const updateDraft = React49.useCallback(
14432
14676
  (patch) => {
14433
14677
  setDraft((previous) => ({ ...previous, ...patch }));
14434
14678
  },
@@ -14446,23 +14690,23 @@ function SettingsSheet({
14446
14690
  defaultValue: selectedBuiltinPet.label
14447
14691
  }
14448
14692
  );
14449
- return /* @__PURE__ */ jsx53(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs36(SheetContent, { side: "right", className: "w-[min(92vw,26rem)] overflow-y-auto", children: [
14450
- /* @__PURE__ */ jsx53(SheetHeader, { children: /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
14451
- /* @__PURE__ */ jsx53("span", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsx53(Settings, { size: 16 }) }),
14452
- /* @__PURE__ */ jsx53(SheetTitle, { children: t("settings.title") })
14693
+ return /* @__PURE__ */ jsx54(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxs37(SheetContent, { side: "right", className: "w-[min(92vw,26rem)] overflow-y-auto", children: [
14694
+ /* @__PURE__ */ jsx54(SheetHeader, { children: /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
14695
+ /* @__PURE__ */ jsx54("span", { className: "flex h-8 w-8 items-center justify-center rounded-md bg-primary/10 text-primary", children: /* @__PURE__ */ jsx54(Settings, { size: 16 }) }),
14696
+ /* @__PURE__ */ jsx54(SheetTitle, { children: t("settings.title") })
14453
14697
  ] }) }),
14454
- /* @__PURE__ */ jsxs36("form", { className: "mt-6 space-y-5", onSubmit: handleSubmit, children: [
14455
- /* @__PURE__ */ jsxs36("section", { className: "space-y-5", children: [
14456
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2", children: [
14457
- /* @__PURE__ */ jsx53("span", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx53(PawPrint, { size: 15 }) }),
14458
- /* @__PURE__ */ jsx53("h3", { className: "text-sm font-semibold", children: t("pet.settings.title") })
14698
+ /* @__PURE__ */ jsxs37("form", { className: "mt-6 space-y-5", onSubmit: handleSubmit, children: [
14699
+ /* @__PURE__ */ jsxs37("section", { className: "space-y-5", children: [
14700
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2", children: [
14701
+ /* @__PURE__ */ jsx54("span", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx54(PawPrint, { size: 15 }) }),
14702
+ /* @__PURE__ */ jsx54("h3", { className: "text-sm font-semibold", children: t("pet.settings.title") })
14459
14703
  ] }),
14460
- /* @__PURE__ */ jsxs36("label", { className: "flex items-center justify-between gap-4 rounded-md border border-border px-3 py-2", children: [
14461
- /* @__PURE__ */ jsxs36("span", { className: "min-w-0", children: [
14462
- /* @__PURE__ */ jsx53("span", { className: "block text-sm font-medium", children: t("pet.settings.enabled") }),
14463
- petRequired && /* @__PURE__ */ jsx53("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: t("pet.settings.requiredHint") })
14704
+ /* @__PURE__ */ jsxs37("label", { className: "flex items-center justify-between gap-4 rounded-md border border-border px-3 py-2", children: [
14705
+ /* @__PURE__ */ jsxs37("span", { className: "min-w-0", children: [
14706
+ /* @__PURE__ */ jsx54("span", { className: "block text-sm font-medium", children: t("pet.settings.enabled") }),
14707
+ petRequired && /* @__PURE__ */ jsx54("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: t("pet.settings.requiredHint") })
14464
14708
  ] }),
14465
- /* @__PURE__ */ jsx53(
14709
+ /* @__PURE__ */ jsx54(
14466
14710
  "button",
14467
14711
  {
14468
14712
  type: "button",
@@ -14475,7 +14719,7 @@ function SettingsSheet({
14475
14719
  draft.enabled ? "bg-primary" : "bg-muted-foreground/20",
14476
14720
  petRequired ? "cursor-not-allowed opacity-70" : ""
14477
14721
  ].join(" "),
14478
- children: /* @__PURE__ */ jsx53(
14722
+ children: /* @__PURE__ */ jsx54(
14479
14723
  "span",
14480
14724
  {
14481
14725
  className: [
@@ -14488,9 +14732,9 @@ function SettingsSheet({
14488
14732
  )
14489
14733
  ] })
14490
14734
  ] }),
14491
- /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
14492
- /* @__PURE__ */ jsx53("span", { id: "chatkit-pet-type-label", className: "text-sm font-medium", children: t("pet.settings.characterType") }),
14493
- /* @__PURE__ */ jsx53(
14735
+ /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
14736
+ /* @__PURE__ */ jsx54("span", { id: "chatkit-pet-type-label", className: "text-sm font-medium", children: t("pet.settings.characterType") }),
14737
+ /* @__PURE__ */ jsx54(
14494
14738
  ToggleGroup,
14495
14739
  {
14496
14740
  id: "chatkit-pet-type",
@@ -14505,7 +14749,7 @@ function SettingsSheet({
14505
14749
  variant: "outline",
14506
14750
  spacing: 2,
14507
14751
  className: "!w-full",
14508
- children: CHARACTER_TYPES2.map((type) => /* @__PURE__ */ jsx53(
14752
+ children: CHARACTER_TYPES2.map((type) => /* @__PURE__ */ jsx54(
14509
14753
  ToggleGroupItem,
14510
14754
  {
14511
14755
  value: type,
@@ -14517,8 +14761,8 @@ function SettingsSheet({
14517
14761
  }
14518
14762
  )
14519
14763
  ] }),
14520
- draft.characterType === "builtin" && /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
14521
- /* @__PURE__ */ jsx53(
14764
+ draft.characterType === "builtin" && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
14765
+ /* @__PURE__ */ jsx54(
14522
14766
  "label",
14523
14767
  {
14524
14768
  htmlFor: "chatkit-pet-builtin",
@@ -14526,7 +14770,7 @@ function SettingsSheet({
14526
14770
  children: t("pet.settings.builtin")
14527
14771
  }
14528
14772
  ),
14529
- /* @__PURE__ */ jsxs36(
14773
+ /* @__PURE__ */ jsxs37(
14530
14774
  Select,
14531
14775
  {
14532
14776
  value: selectedBuiltinPet.id,
@@ -14537,26 +14781,26 @@ function SettingsSheet({
14537
14781
  }
14538
14782
  },
14539
14783
  children: [
14540
- /* @__PURE__ */ jsx53(
14784
+ /* @__PURE__ */ jsx54(
14541
14785
  SelectTrigger,
14542
14786
  {
14543
14787
  id: "chatkit-pet-builtin",
14544
14788
  className: "min-h-12 w-full px-3 py-2",
14545
- children: /* @__PURE__ */ jsx53(SelectValue, { placeholder: selectedBuiltinPetLabel })
14789
+ children: /* @__PURE__ */ jsx54(SelectValue, { placeholder: selectedBuiltinPetLabel })
14546
14790
  }
14547
14791
  ),
14548
- /* @__PURE__ */ jsx53(SelectContent, { className: "w-[var(--radix-select-trigger-width)]", children: /* @__PURE__ */ jsx53(SelectGroup, { children: INCLUDED_PET_OPTIONS.map((pet) => {
14792
+ /* @__PURE__ */ jsx54(SelectContent, { className: "w-[var(--radix-select-trigger-width)]", children: /* @__PURE__ */ jsx54(SelectGroup, { children: INCLUDED_PET_OPTIONS.map((pet) => {
14549
14793
  const label = t(`pet.settings.builtins.${pet.id}`, {
14550
14794
  defaultValue: pet.label
14551
14795
  });
14552
- return /* @__PURE__ */ jsx53(
14796
+ return /* @__PURE__ */ jsx54(
14553
14797
  SelectItem,
14554
14798
  {
14555
14799
  value: pet.id,
14556
14800
  className: "min-h-10 py-1.5 pl-2 pr-8",
14557
- children: /* @__PURE__ */ jsxs36("span", { className: "flex min-w-0 items-center gap-2", children: [
14558
- /* @__PURE__ */ jsx53(PetPreview, { src: pet.previewSrc, label }),
14559
- /* @__PURE__ */ jsx53("span", { className: "min-w-0 truncate", children: label })
14801
+ children: /* @__PURE__ */ jsxs37("span", { className: "flex min-w-0 items-center gap-2", children: [
14802
+ /* @__PURE__ */ jsx54(PetPreview, { src: pet.previewSrc, label }),
14803
+ /* @__PURE__ */ jsx54("span", { className: "min-w-0 truncate", children: label })
14560
14804
  ] })
14561
14805
  },
14562
14806
  pet.id
@@ -14566,8 +14810,8 @@ function SettingsSheet({
14566
14810
  }
14567
14811
  )
14568
14812
  ] }),
14569
- draft.characterType === "atlas" && /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
14570
- /* @__PURE__ */ jsx53(
14813
+ draft.characterType === "atlas" && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
14814
+ /* @__PURE__ */ jsx54(
14571
14815
  "label",
14572
14816
  {
14573
14817
  className: "text-sm font-medium",
@@ -14575,7 +14819,7 @@ function SettingsSheet({
14575
14819
  children: t("pet.settings.atlasUrl")
14576
14820
  }
14577
14821
  ),
14578
- /* @__PURE__ */ jsx53(
14822
+ /* @__PURE__ */ jsx54(
14579
14823
  Input,
14580
14824
  {
14581
14825
  id: "chatkit-pet-atlas",
@@ -14585,15 +14829,15 @@ function SettingsSheet({
14585
14829
  }
14586
14830
  )
14587
14831
  ] }),
14588
- /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
14589
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between gap-4", children: [
14590
- /* @__PURE__ */ jsx53("label", { className: "text-sm font-medium", htmlFor: "chatkit-pet-scale", children: t("pet.settings.scale") }),
14591
- /* @__PURE__ */ jsxs36("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
14832
+ /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
14833
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between gap-4", children: [
14834
+ /* @__PURE__ */ jsx54("label", { className: "text-sm font-medium", htmlFor: "chatkit-pet-scale", children: t("pet.settings.scale") }),
14835
+ /* @__PURE__ */ jsxs37("span", { className: "text-xs tabular-nums text-muted-foreground", children: [
14592
14836
  draft.scale.toFixed(2),
14593
14837
  "x"
14594
14838
  ] })
14595
14839
  ] }),
14596
- /* @__PURE__ */ jsx53(
14840
+ /* @__PURE__ */ jsx54(
14597
14841
  Slider,
14598
14842
  {
14599
14843
  id: "chatkit-pet-scale",
@@ -14607,8 +14851,8 @@ function SettingsSheet({
14607
14851
  }
14608
14852
  )
14609
14853
  ] }),
14610
- /* @__PURE__ */ jsxs36("label", { className: "flex items-center gap-2 text-sm", children: [
14611
- /* @__PURE__ */ jsx53(
14854
+ /* @__PURE__ */ jsxs37("label", { className: "flex items-center gap-2 text-sm", children: [
14855
+ /* @__PURE__ */ jsx54(
14612
14856
  "input",
14613
14857
  {
14614
14858
  type: "checkbox",
@@ -14619,8 +14863,8 @@ function SettingsSheet({
14619
14863
  ),
14620
14864
  t("pet.settings.draggable")
14621
14865
  ] }),
14622
- /* @__PURE__ */ jsxs36("label", { className: "flex items-center gap-2 text-sm", children: [
14623
- /* @__PURE__ */ jsx53(
14866
+ /* @__PURE__ */ jsxs37("label", { className: "flex items-center gap-2 text-sm", children: [
14867
+ /* @__PURE__ */ jsx54(
14624
14868
  "input",
14625
14869
  {
14626
14870
  type: "checkbox",
@@ -14631,8 +14875,8 @@ function SettingsSheet({
14631
14875
  ),
14632
14876
  t("pet.settings.persistPosition")
14633
14877
  ] }),
14634
- /* @__PURE__ */ jsxs36("div", { className: "flex justify-end gap-2 pt-2", children: [
14635
- /* @__PURE__ */ jsx53(
14878
+ /* @__PURE__ */ jsxs37("div", { className: "flex justify-end gap-2 pt-2", children: [
14879
+ /* @__PURE__ */ jsx54(
14636
14880
  Button,
14637
14881
  {
14638
14882
  type: "button",
@@ -14641,7 +14885,7 @@ function SettingsSheet({
14641
14885
  children: t("pet.settings.cancel")
14642
14886
  }
14643
14887
  ),
14644
- /* @__PURE__ */ jsx53(Button, { type: "submit", children: t("pet.settings.save") })
14888
+ /* @__PURE__ */ jsx54(Button, { type: "submit", children: t("pet.settings.save") })
14645
14889
  ] })
14646
14890
  ] })
14647
14891
  ] }) });
@@ -15267,24 +15511,27 @@ function findDomPointForComposerOffset(root, offset) {
15267
15511
  return result ?? { node: lastNode, offset: lastOffset };
15268
15512
  }
15269
15513
 
15270
- // src/components/chat.tsx
15271
- import { Fragment as Fragment9, jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
15272
- var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
15273
- var COMPOSER_INPUT_MAX_HEIGHT = 128;
15274
- var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
15275
- var GOAL_RUN_INPUT = "Continue working toward the active goal.";
15276
- function isGoalAdapter(value) {
15277
- return Boolean(value) && typeof value === "object" && typeof value.getGoal === "function" && typeof value.setGoal === "function" && typeof value.updateGoal === "function" && typeof value.clearGoal === "function";
15514
+ // src/components/chat/runtime-capabilities.tsx
15515
+ import * as React50 from "react";
15516
+ import { X as X6 } from "lucide-react";
15517
+ import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
15518
+ function getHttpStatus(error) {
15519
+ if (!error || typeof error !== "object" || !("status" in error)) {
15520
+ return null;
15521
+ }
15522
+ const status = error.status;
15523
+ return typeof status === "number" ? status : null;
15278
15524
  }
15279
- function formatGoalElapsed(seconds) {
15280
- if (seconds < 60) {
15281
- return `${seconds}s`;
15525
+ function warnMissingRuntimeCapabilityReferences(action, missing) {
15526
+ if (!hasMissingRuntimeCapabilityReferences(missing)) {
15527
+ return;
15282
15528
  }
15283
- const minutes = Math.floor(seconds / 60);
15284
- const remainingSeconds = seconds % 60;
15285
- return remainingSeconds ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
15529
+ console.warn(
15530
+ `[Chat] Runtime capabilities ${action} include unavailable references:`,
15531
+ missing
15532
+ );
15286
15533
  }
15287
- function getSlashPaletteEmptyLabelKey(palette, runtimeCapabilitiesReady) {
15534
+ function getRuntimeCapabilityPaletteEmptyLabelKey(palette, runtimeCapabilitiesReady) {
15288
15535
  if (!palette.capabilityTypes || palette.capabilityTypes.length !== 1) {
15289
15536
  return "composer.capabilities.emptySearch";
15290
15537
  }
@@ -15301,23 +15548,7 @@ function getSlashPaletteEmptyLabelKey(palette, runtimeCapabilitiesReady) {
15301
15548
  }
15302
15549
  return hasQuery ? "composer.slashCommands.empty.matchingSubAgents" : "composer.slashCommands.empty.subAgents";
15303
15550
  }
15304
- function getHttpStatus(error) {
15305
- if (!error || typeof error !== "object" || !("status" in error)) {
15306
- return null;
15307
- }
15308
- const status = error.status;
15309
- return typeof status === "number" ? status : null;
15310
- }
15311
- function warnMissingRuntimeCapabilityReferences(action, missing) {
15312
- if (!hasMissingRuntimeCapabilityReferences(missing)) {
15313
- return;
15314
- }
15315
- console.warn(
15316
- `[Chat] Runtime capabilities ${action} include unavailable references:`,
15317
- missing
15318
- );
15319
- }
15320
- function getSelectedRuntimeCapabilityOptions(selection, options) {
15551
+ function getRuntimeCapabilityOptionsForSelection(selection, options) {
15321
15552
  if (!selection) {
15322
15553
  return [];
15323
15554
  }
@@ -15325,77 +15556,915 @@ function getSelectedRuntimeCapabilityOptions(selection, options) {
15325
15556
  (option) => isRuntimeCapabilitySelected(selection, option.type, option.id)
15326
15557
  );
15327
15558
  }
15328
- async function readImageDimensions(file) {
15329
- if (typeof window === "undefined" || typeof URL === "undefined") {
15330
- return {};
15559
+ function removeComposerCapabilityPartsFromSelection(selection, removedCapabilities) {
15560
+ let nextSelection = selection;
15561
+ for (const part of removedCapabilities) {
15562
+ nextSelection = toggleRuntimeCapabilitySelection(
15563
+ nextSelection,
15564
+ part.capability.type,
15565
+ part.capability.id,
15566
+ false
15567
+ );
15331
15568
  }
15332
- return new Promise((resolve) => {
15333
- const objectUrl = URL.createObjectURL(file);
15334
- const image = new window.Image();
15335
- const cleanup = () => {
15336
- URL.revokeObjectURL(objectUrl);
15337
- };
15338
- image.onload = () => {
15339
- resolve({
15340
- width: image.naturalWidth || void 0,
15341
- height: image.naturalHeight || void 0
15342
- });
15343
- cleanup();
15344
- };
15345
- image.onerror = () => {
15346
- resolve({});
15347
- cleanup();
15348
- };
15349
- image.src = objectUrl;
15350
- });
15351
- }
15352
- function getUploadedFileUrl(file) {
15353
- return file.url ?? file.fileUrl ?? file.thumbUrl;
15569
+ return nextSelection;
15354
15570
  }
15355
- function buildPastedImageReference(file, uploadedFile, dimensions) {
15356
- const name = uploadedFile.originalName?.trim() || file.name.trim() || "Pasted image";
15357
- const mimeType = uploadedFile.mimeType?.trim() || file.type.trim() || "image/*";
15358
- const size2 = uploadedFile.size ?? file.size;
15359
- const width = dimensions?.width;
15360
- const height = dimensions?.height;
15361
- const metaParts = [
15362
- mimeType,
15363
- width && height ? `${width}x${height}` : null,
15364
- typeof size2 === "number" ? `${size2} bytes` : null
15365
- ].filter((part) => Boolean(part));
15366
- return {
15367
- type: "image",
15368
- id: uploadedFile.id,
15369
- fileId: uploadedFile.storageFileId,
15370
- url: getUploadedFileUrl(uploadedFile),
15371
- mimeType,
15372
- name,
15373
- ...typeof size2 === "number" ? { size: size2 } : {},
15374
- ...width ? { width } : {},
15375
- ...height ? { height } : {},
15376
- text: `Pasted image${metaParts.length ? ` (${metaParts.join(", ")})` : ""}: ${name}`
15377
- };
15571
+ function getRemovedComposerCapabilityParts(previousParts, nextParts) {
15572
+ const nextKeys = getComposerCapabilityKeys(nextParts);
15573
+ return previousParts.filter(
15574
+ (part) => part.type === "capability" && !nextKeys.has(part.key)
15575
+ );
15378
15576
  }
15379
- function formatMessageContent(content) {
15380
- if (typeof content === "string") {
15381
- return content;
15382
- }
15383
- if (Array.isArray(content)) {
15384
- return content.map((part) => {
15385
- if (typeof part === "string") return part;
15386
- if (part && typeof part === "object" && "text" in part) {
15387
- const textValue = part.text;
15388
- return typeof textValue === "string" ? textValue : "";
15389
- }
15390
- return "";
15391
- }).join("");
15392
- }
15393
- if (content == null) return "";
15394
- if (typeof content === "object" && "text" in content) {
15395
- const textValue = content.text;
15396
- return typeof textValue === "string" ? textValue : "";
15397
- }
15398
- return "";
15577
+ function useRuntimeCapabilitiesState({
15578
+ client,
15579
+ assistantId,
15580
+ threadId,
15581
+ disabled,
15582
+ composerParts
15583
+ }) {
15584
+ const [runtimeCapabilities, setRuntimeCapabilities] = React50.useState(null);
15585
+ const [runtimeCapabilitiesReady, setRuntimeCapabilitiesReady] = React50.useState(false);
15586
+ const [sessionRuntimeCapabilities, setSessionRuntimeCapabilities] = React50.useState(
15587
+ () => createEmptyRuntimeCapabilitiesSelection()
15588
+ );
15589
+ const [runRuntimeCapabilities, setRunRuntimeCapabilities] = React50.useState(
15590
+ () => createEmptyRuntimeCapabilitiesSelection()
15591
+ );
15592
+ const [runtimeCapabilityPalette, setRuntimeCapabilityPalette] = React50.useState(null);
15593
+ const runtimeCapabilityPreferenceLoadRef = React50.useRef(0);
15594
+ const pendingExternalRuntimeCapabilitiesRef = React50.useRef(null);
15595
+ const runtimeCapabilityOptions = React50.useMemo(
15596
+ () => getRuntimeCapabilityOptions(runtimeCapabilities),
15597
+ [runtimeCapabilities]
15598
+ );
15599
+ const effectiveSessionRuntimeCapabilities = React50.useMemo(
15600
+ () => runtimeCapabilitiesReady && runtimeCapabilities ? mergeRuntimeCapabilitiesSelections(
15601
+ runtimeCapabilities,
15602
+ sessionRuntimeCapabilities
15603
+ ) : null,
15604
+ [runtimeCapabilities, runtimeCapabilitiesReady, sessionRuntimeCapabilities]
15605
+ );
15606
+ const runRuntimeCapabilityOptions = React50.useMemo(
15607
+ () => runtimeCapabilityOptions.filter(
15608
+ (option) => isRuntimeCapabilitySelected(
15609
+ runRuntimeCapabilities,
15610
+ option.type,
15611
+ option.id
15612
+ )
15613
+ ),
15614
+ [runRuntimeCapabilities, runtimeCapabilityOptions]
15615
+ );
15616
+ const composerRuntimeCapabilitySelectionKeys = React50.useMemo(
15617
+ () => getComposerCapabilitySelectionKeys(composerParts),
15618
+ [composerParts]
15619
+ );
15620
+ const detachedRunRuntimeCapabilityOptions = React50.useMemo(
15621
+ () => runRuntimeCapabilityOptions.filter(
15622
+ (option) => !composerRuntimeCapabilitySelectionKeys.has(
15623
+ getRuntimeCapabilityOptionKey(option)
15624
+ )
15625
+ ),
15626
+ [composerRuntimeCapabilitySelectionKeys, runRuntimeCapabilityOptions]
15627
+ );
15628
+ const persistSessionRuntimeCapabilities = React50.useCallback(
15629
+ async (nextThreadId, selection) => {
15630
+ if (!runtimeCapabilities || !selection || !client) {
15631
+ return;
15632
+ }
15633
+ try {
15634
+ const result = await persistConversationRuntimeCapabilities({
15635
+ client,
15636
+ threadId: nextThreadId,
15637
+ capabilities: runtimeCapabilities,
15638
+ selection
15639
+ });
15640
+ warnMissingRuntimeCapabilityReferences(
15641
+ "persisted selection",
15642
+ result.missing
15643
+ );
15644
+ } catch (error) {
15645
+ console.warn(
15646
+ "[Chat] Failed to persist runtime capabilities selection:",
15647
+ error
15648
+ );
15649
+ }
15650
+ },
15651
+ [client, runtimeCapabilities]
15652
+ );
15653
+ const applyExternalRuntimeCapabilities = React50.useCallback(
15654
+ (selection) => {
15655
+ pendingExternalRuntimeCapabilitiesRef.current = selection;
15656
+ setRunRuntimeCapabilities(() => {
15657
+ const emptySelection = createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities);
15658
+ if (!selection) {
15659
+ return emptySelection;
15660
+ }
15661
+ if (!runtimeCapabilities) {
15662
+ return selection;
15663
+ }
15664
+ pendingExternalRuntimeCapabilitiesRef.current = null;
15665
+ return mergeRuntimeCapabilitiesSelections(
15666
+ runtimeCapabilities,
15667
+ emptySelection,
15668
+ selection
15669
+ );
15670
+ });
15671
+ },
15672
+ [runtimeCapabilities]
15673
+ );
15674
+ const handleSessionRuntimeCapabilityToggle = React50.useCallback(
15675
+ (type, id, selected) => {
15676
+ setSessionRuntimeCapabilities((previous) => {
15677
+ const nextSelection = toggleRuntimeCapabilitySelection(
15678
+ previous,
15679
+ type,
15680
+ id,
15681
+ selected
15682
+ );
15683
+ const normalizedThreadId = threadId?.trim();
15684
+ if (normalizedThreadId) {
15685
+ void persistSessionRuntimeCapabilities(
15686
+ normalizedThreadId,
15687
+ nextSelection
15688
+ );
15689
+ }
15690
+ return nextSelection;
15691
+ });
15692
+ },
15693
+ [persistSessionRuntimeCapabilities, threadId]
15694
+ );
15695
+ const addRunRuntimeCapabilities = React50.useCallback(
15696
+ (selection) => {
15697
+ setRunRuntimeCapabilities(
15698
+ (previous) => runtimeCapabilities ? mergeRuntimeCapabilitiesSelections(
15699
+ runtimeCapabilities,
15700
+ previous,
15701
+ selection
15702
+ ) : previous
15703
+ );
15704
+ },
15705
+ [runtimeCapabilities]
15706
+ );
15707
+ const resetRunRuntimeCapabilities = React50.useCallback(() => {
15708
+ setRunRuntimeCapabilities(
15709
+ createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities)
15710
+ );
15711
+ setRuntimeCapabilityPalette(null);
15712
+ }, [runtimeCapabilities]);
15713
+ const getRuntimeCapabilitiesForSubmit = React50.useCallback(
15714
+ (recommended) => {
15715
+ const recommendedRuntimeCapabilitiesForSubmit = recommended && runtimeCapabilities && runtimeCapabilitiesReady ? mergeRuntimeCapabilitiesSelections(
15716
+ runtimeCapabilities,
15717
+ runRuntimeCapabilities,
15718
+ recommended
15719
+ ) : runRuntimeCapabilities;
15720
+ const runtimeCapabilitiesForSubmit = runtimeCapabilities && runtimeCapabilitiesReady ? createRuntimeCapabilitiesForSubmit({
15721
+ capabilities: runtimeCapabilities,
15722
+ available: effectiveSessionRuntimeCapabilities,
15723
+ recommended: recommendedRuntimeCapabilitiesForSubmit
15724
+ }) : null;
15725
+ const runtimeCapabilityOptionsForMessage = getRuntimeCapabilityOptionsForSelection(
15726
+ getRecommendedRuntimeCapabilitiesSelection(
15727
+ runtimeCapabilitiesForSubmit
15728
+ ),
15729
+ runtimeCapabilityOptions
15730
+ );
15731
+ return {
15732
+ runtimeCapabilitiesForSubmit,
15733
+ runtimeCapabilityOptionsForMessage
15734
+ };
15735
+ },
15736
+ [
15737
+ effectiveSessionRuntimeCapabilities,
15738
+ runRuntimeCapabilities,
15739
+ runtimeCapabilities,
15740
+ runtimeCapabilitiesReady,
15741
+ runtimeCapabilityOptions
15742
+ ]
15743
+ );
15744
+ const getRuntimeCapabilitiesForCommand = React50.useCallback(
15745
+ (recommended) => runtimeCapabilities && runtimeCapabilitiesReady ? createRuntimeCapabilitiesForSubmit({
15746
+ capabilities: runtimeCapabilities,
15747
+ available: effectiveSessionRuntimeCapabilities,
15748
+ recommended
15749
+ }) : recommended ?? null,
15750
+ [
15751
+ effectiveSessionRuntimeCapabilities,
15752
+ runtimeCapabilities,
15753
+ runtimeCapabilitiesReady
15754
+ ]
15755
+ );
15756
+ React50.useEffect(() => {
15757
+ if (disabled || !client || !assistantId) {
15758
+ pendingExternalRuntimeCapabilitiesRef.current = null;
15759
+ setRuntimeCapabilities(null);
15760
+ setRuntimeCapabilitiesReady(false);
15761
+ setSessionRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
15762
+ setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
15763
+ setRuntimeCapabilityPalette(null);
15764
+ return;
15765
+ }
15766
+ const controller = new AbortController();
15767
+ setRuntimeCapabilitiesReady(false);
15768
+ setRuntimeCapabilities(null);
15769
+ setRuntimeCapabilityPalette(null);
15770
+ void client.assistants.getRuntimeCapabilities(assistantId, {
15771
+ signal: controller.signal
15772
+ }).then((payload) => {
15773
+ setRuntimeCapabilities(payload);
15774
+ setRuntimeCapabilitiesReady(true);
15775
+ setSessionRuntimeCapabilities(
15776
+ createDefaultRuntimeCapabilitiesSelection(payload)
15777
+ );
15778
+ setRunRuntimeCapabilities(
15779
+ createEmptyRuntimeCapabilitiesSelection(payload)
15780
+ );
15781
+ }).catch((error) => {
15782
+ if (controller.signal.aborted) {
15783
+ return;
15784
+ }
15785
+ if (getHttpStatus(error) === 404) {
15786
+ setRuntimeCapabilities(null);
15787
+ setRuntimeCapabilitiesReady(false);
15788
+ setSessionRuntimeCapabilities(
15789
+ createEmptyRuntimeCapabilitiesSelection()
15790
+ );
15791
+ setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
15792
+ return;
15793
+ }
15794
+ console.warn("[Chat] Failed to load runtime capabilities:", error);
15795
+ setRuntimeCapabilities(null);
15796
+ setRuntimeCapabilitiesReady(false);
15797
+ setSessionRuntimeCapabilities(
15798
+ createEmptyRuntimeCapabilitiesSelection()
15799
+ );
15800
+ setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
15801
+ });
15802
+ return () => controller.abort();
15803
+ }, [assistantId, client, disabled]);
15804
+ React50.useEffect(() => {
15805
+ const emptyRunSelection = createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities);
15806
+ const pendingExternalSelection = pendingExternalRuntimeCapabilitiesRef.current;
15807
+ if (pendingExternalSelection && runtimeCapabilities) {
15808
+ setRunRuntimeCapabilities(
15809
+ mergeRuntimeCapabilitiesSelections(
15810
+ runtimeCapabilities,
15811
+ emptyRunSelection,
15812
+ pendingExternalSelection
15813
+ )
15814
+ );
15815
+ pendingExternalRuntimeCapabilitiesRef.current = null;
15816
+ } else {
15817
+ setRunRuntimeCapabilities(pendingExternalSelection ?? emptyRunSelection);
15818
+ }
15819
+ if (!runtimeCapabilitiesReady || !runtimeCapabilities || !client) {
15820
+ setSessionRuntimeCapabilities(
15821
+ createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities)
15822
+ );
15823
+ return;
15824
+ }
15825
+ const defaultSelection = createDefaultRuntimeCapabilitiesSelection(runtimeCapabilities);
15826
+ const normalizedThreadId = threadId?.trim();
15827
+ if (!normalizedThreadId) {
15828
+ setSessionRuntimeCapabilities(defaultSelection);
15829
+ return;
15830
+ }
15831
+ let cancelled = false;
15832
+ const requestId = runtimeCapabilityPreferenceLoadRef.current + 1;
15833
+ runtimeCapabilityPreferenceLoadRef.current = requestId;
15834
+ setSessionRuntimeCapabilities(defaultSelection);
15835
+ void loadConversationRuntimeCapabilities({
15836
+ client,
15837
+ threadId: normalizedThreadId,
15838
+ capabilities: runtimeCapabilities
15839
+ }).then(({ selection, missing }) => {
15840
+ if (cancelled || runtimeCapabilityPreferenceLoadRef.current !== requestId) {
15841
+ return;
15842
+ }
15843
+ warnMissingRuntimeCapabilityReferences("loaded selection", missing);
15844
+ setSessionRuntimeCapabilities(selection ?? defaultSelection);
15845
+ }).catch((error) => {
15846
+ if (cancelled || runtimeCapabilityPreferenceLoadRef.current !== requestId) {
15847
+ return;
15848
+ }
15849
+ console.warn(
15850
+ "[Chat] Failed to load persisted runtime capabilities selection:",
15851
+ error
15852
+ );
15853
+ setSessionRuntimeCapabilities(defaultSelection);
15854
+ });
15855
+ return () => {
15856
+ cancelled = true;
15857
+ };
15858
+ }, [
15859
+ client,
15860
+ runtimeCapabilities,
15861
+ runtimeCapabilitiesReady,
15862
+ threadId
15863
+ ]);
15864
+ return {
15865
+ runtimeCapabilities,
15866
+ runtimeCapabilitiesReady,
15867
+ runtimeCapabilityOptions,
15868
+ effectiveSessionRuntimeCapabilities,
15869
+ runRuntimeCapabilities,
15870
+ runRuntimeCapabilityOptions,
15871
+ detachedRunRuntimeCapabilityOptions,
15872
+ runtimeCapabilityPalette,
15873
+ setRunRuntimeCapabilities,
15874
+ setRuntimeCapabilityPalette,
15875
+ applyExternalRuntimeCapabilities,
15876
+ handleSessionRuntimeCapabilityToggle,
15877
+ addRunRuntimeCapabilities,
15878
+ resetRunRuntimeCapabilities,
15879
+ getRuntimeCapabilitiesForSubmit,
15880
+ getRuntimeCapabilitiesForCommand,
15881
+ persistSessionRuntimeCapabilities
15882
+ };
15883
+ }
15884
+ function useRuntimeCapabilityComposerActions({
15885
+ runtimeCapabilities,
15886
+ runtimeCapabilitiesReady,
15887
+ runtimeCapabilityOptions,
15888
+ setRunRuntimeCapabilities,
15889
+ setRuntimeCapabilityPalette,
15890
+ applyExternalRuntimeCapabilities,
15891
+ composerInputRef,
15892
+ composerPartsRef,
15893
+ commitComposerParts,
15894
+ focusComposerAt
15895
+ }) {
15896
+ const pendingExternalRuntimeCapabilityInsertRef = React50.useRef(null);
15897
+ const insertExternalRuntimeCapabilities = React50.useCallback(
15898
+ (selection) => {
15899
+ applyExternalRuntimeCapabilities(selection);
15900
+ if (!selection) {
15901
+ pendingExternalRuntimeCapabilityInsertRef.current = null;
15902
+ return;
15903
+ }
15904
+ if (!runtimeCapabilitiesReady || !runtimeCapabilities) {
15905
+ pendingExternalRuntimeCapabilityInsertRef.current = selection;
15906
+ return;
15907
+ }
15908
+ pendingExternalRuntimeCapabilityInsertRef.current = null;
15909
+ const existingKeys = getComposerCapabilitySelectionKeys(
15910
+ composerPartsRef.current
15911
+ );
15912
+ const selectedOptions = runtimeCapabilityOptions.filter(
15913
+ (option) => isRuntimeCapabilitySelected(selection, option.type, option.id) && !existingKeys.has(getRuntimeCapabilityOptionKey(option))
15914
+ );
15915
+ if (selectedOptions.length === 0) {
15916
+ focusComposerAt();
15917
+ return;
15918
+ }
15919
+ const currentParts = composerPartsRef.current;
15920
+ const insertAt = getComposerEditingLength(currentParts);
15921
+ const nextParts = replaceComposerRange(
15922
+ currentParts,
15923
+ insertAt,
15924
+ insertAt,
15925
+ selectedOptions.map(
15926
+ (option) => createComposerCapabilityPart(option, createMessageId())
15927
+ )
15928
+ );
15929
+ const nextCaretOffset = insertAt + selectedOptions.length;
15930
+ commitComposerParts(nextParts, {
15931
+ caretOffset: nextCaretOffset,
15932
+ resetDom: true,
15933
+ syncRemovedCapabilityTokens: true
15934
+ });
15935
+ setRuntimeCapabilityPalette(null);
15936
+ focusComposerAt(nextCaretOffset);
15937
+ },
15938
+ [
15939
+ applyExternalRuntimeCapabilities,
15940
+ commitComposerParts,
15941
+ composerPartsRef,
15942
+ focusComposerAt,
15943
+ runtimeCapabilities,
15944
+ runtimeCapabilitiesReady,
15945
+ runtimeCapabilityOptions,
15946
+ setRuntimeCapabilityPalette
15947
+ ]
15948
+ );
15949
+ const applyComposerValueRuntimeCapabilities = React50.useCallback(
15950
+ (payload) => {
15951
+ const runtimeCapabilitiesPayload = isRuntimeCapabilitiesSelection(payload.runtimeCapabilities) ? payload.runtimeCapabilities : payload.runtimeCapabilities === null ? null : void 0;
15952
+ if (runtimeCapabilitiesPayload === void 0) {
15953
+ return;
15954
+ }
15955
+ if (payload.insertRuntimeCapabilities === true) {
15956
+ insertExternalRuntimeCapabilities(runtimeCapabilitiesPayload);
15957
+ } else {
15958
+ applyExternalRuntimeCapabilities(runtimeCapabilitiesPayload);
15959
+ }
15960
+ },
15961
+ [applyExternalRuntimeCapabilities, insertExternalRuntimeCapabilities]
15962
+ );
15963
+ const updateRuntimeCapabilityPalette = React50.useCallback(
15964
+ (parts, selectionStart) => {
15965
+ const input = composerInputRef.current;
15966
+ const editingText = getComposerEditingText(parts);
15967
+ const nextPalette = resolveRuntimeCapabilityPalette(
15968
+ editingText,
15969
+ typeof selectionStart === "number" ? selectionStart : input ? getComposerSelectionOffset(input) : getComposerEditingLength(parts)
15970
+ );
15971
+ setRuntimeCapabilityPalette(nextPalette);
15972
+ },
15973
+ [composerInputRef, setRuntimeCapabilityPalette]
15974
+ );
15975
+ const removeRunRuntimeCapability = React50.useCallback(
15976
+ (option) => {
15977
+ setRunRuntimeCapabilities(
15978
+ (previous) => toggleRuntimeCapabilitySelection(
15979
+ previous,
15980
+ option.type,
15981
+ option.id,
15982
+ false
15983
+ )
15984
+ );
15985
+ commitComposerParts(
15986
+ removeComposerCapabilityTokens(composerPartsRef.current, option),
15987
+ {
15988
+ resetDom: true,
15989
+ syncRemovedCapabilityTokens: false
15990
+ }
15991
+ );
15992
+ },
15993
+ [commitComposerParts, composerPartsRef, setRunRuntimeCapabilities]
15994
+ );
15995
+ const insertComposerCapabilityToken = React50.useCallback(
15996
+ (capability, range) => {
15997
+ const token = createComposerCapabilityPart(capability, createMessageId());
15998
+ const currentParts = composerPartsRef.current;
15999
+ const replaceRange = range ?? {
16000
+ start: getComposerEditingLength(currentParts),
16001
+ end: getComposerEditingLength(currentParts)
16002
+ };
16003
+ const nextParts = replaceComposerRange(
16004
+ currentParts,
16005
+ replaceRange.start,
16006
+ replaceRange.end,
16007
+ [token]
16008
+ );
16009
+ commitComposerParts(nextParts, {
16010
+ caretOffset: replaceRange.start + 1,
16011
+ resetDom: true,
16012
+ syncRemovedCapabilityTokens: true
16013
+ });
16014
+ setRunRuntimeCapabilities(
16015
+ (previous) => toggleRuntimeCapabilitySelection(
16016
+ previous,
16017
+ capability.type,
16018
+ capability.id,
16019
+ true
16020
+ )
16021
+ );
16022
+ setRuntimeCapabilityPalette(null);
16023
+ focusComposerAt(replaceRange.start + 1);
16024
+ },
16025
+ [
16026
+ commitComposerParts,
16027
+ composerPartsRef,
16028
+ focusComposerAt,
16029
+ setRunRuntimeCapabilities,
16030
+ setRuntimeCapabilityPalette
16031
+ ]
16032
+ );
16033
+ React50.useEffect(() => {
16034
+ if (!runtimeCapabilitiesReady || !runtimeCapabilities) {
16035
+ return;
16036
+ }
16037
+ const pendingSelection = pendingExternalRuntimeCapabilityInsertRef.current;
16038
+ if (!pendingSelection) {
16039
+ return;
16040
+ }
16041
+ insertExternalRuntimeCapabilities(pendingSelection);
16042
+ }, [
16043
+ insertExternalRuntimeCapabilities,
16044
+ runtimeCapabilities,
16045
+ runtimeCapabilitiesReady
16046
+ ]);
16047
+ return {
16048
+ applyComposerValueRuntimeCapabilities,
16049
+ insertExternalRuntimeCapabilities,
16050
+ updateRuntimeCapabilityPalette,
16051
+ removeRunRuntimeCapability,
16052
+ insertComposerCapabilityToken
16053
+ };
16054
+ }
16055
+ function HumanRuntimeCapabilityChips({
16056
+ options
16057
+ }) {
16058
+ if (options.length === 0) {
16059
+ return null;
16060
+ }
16061
+ return /* @__PURE__ */ jsx55("div", { className: "mb-2 flex flex-wrap gap-1.5", children: options.map((option) => /* @__PURE__ */ jsxs38(
16062
+ "span",
16063
+ {
16064
+ className: "inline-flex max-w-full items-center gap-1 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs font-medium text-primary-foreground",
16065
+ children: [
16066
+ /* @__PURE__ */ jsx55(RuntimeCapabilityIcon, { option, variant: "chip" }),
16067
+ /* @__PURE__ */ jsx55("span", { className: "max-w-[9rem] truncate", children: option.label })
16068
+ ]
16069
+ },
16070
+ `${option.type}:${option.id}`
16071
+ )) });
16072
+ }
16073
+ function DetachedRunRuntimeCapabilities({
16074
+ options,
16075
+ runOnlyLabel,
16076
+ removeLabel,
16077
+ onRemove
16078
+ }) {
16079
+ if (options.length === 0) {
16080
+ return null;
16081
+ }
16082
+ return /* @__PURE__ */ jsxs38("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: [
16083
+ /* @__PURE__ */ jsx55("span", { className: "text-xs text-muted-foreground", children: runOnlyLabel }),
16084
+ options.map((option) => /* @__PURE__ */ jsxs38(
16085
+ "span",
16086
+ {
16087
+ className: "inline-flex max-w-full items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary",
16088
+ children: [
16089
+ /* @__PURE__ */ jsx55(RuntimeCapabilityIcon, { option, variant: "chip" }),
16090
+ /* @__PURE__ */ jsx55("span", { className: "max-w-40 truncate", children: option.label }),
16091
+ /* @__PURE__ */ jsx55(
16092
+ "button",
16093
+ {
16094
+ type: "button",
16095
+ onClick: () => onRemove(option),
16096
+ className: "rounded-full p-0.5 hover:bg-primary/15",
16097
+ title: removeLabel,
16098
+ "aria-label": removeLabel,
16099
+ children: /* @__PURE__ */ jsx55(X6, { size: 11 })
16100
+ }
16101
+ )
16102
+ ]
16103
+ },
16104
+ `${option.type}:${option.id}`
16105
+ ))
16106
+ ] });
16107
+ }
16108
+ function ComposerCapabilityToken({
16109
+ part
16110
+ }) {
16111
+ return /* @__PURE__ */ jsxs38(
16112
+ "span",
16113
+ {
16114
+ "data-composer-capability-key": part.key,
16115
+ "data-capability-type": part.capability.type,
16116
+ "data-capability-id": part.capability.id,
16117
+ contentEditable: false,
16118
+ className: "mx-0.5 inline-flex max-w-[14rem] select-none items-center gap-1 text-sm font-semibold text-primary align-baseline",
16119
+ children: [
16120
+ /* @__PURE__ */ jsx55(RuntimeCapabilityIcon, { option: part.capability, variant: "chip" }),
16121
+ /* @__PURE__ */ jsx55("span", { className: "truncate", children: part.capability.label })
16122
+ ]
16123
+ },
16124
+ part.key
16125
+ );
16126
+ }
16127
+
16128
+ // src/lib/message-navigation.ts
16129
+ var MESSAGE_NAVIGATION_MIN_ITEMS = 3;
16130
+ var MAX_PREVIEW_LENGTH = 180;
16131
+ var MAX_TAG_LENGTH = 40;
16132
+ function isRecord6(value) {
16133
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
16134
+ }
16135
+ function readString4(value) {
16136
+ return typeof value === "string" && value.trim() ? value.trim() : null;
16137
+ }
16138
+ function normalizeWhitespace(value) {
16139
+ return value.replace(/\s+/g, " ").trim();
16140
+ }
16141
+ function truncate(value, maxLength) {
16142
+ const normalized = normalizeWhitespace(value);
16143
+ if (normalized.length <= maxLength) return normalized;
16144
+ return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}...`;
16145
+ }
16146
+ function pushText(draft, value) {
16147
+ const text = readString4(value);
16148
+ if (text) draft.text.push(text);
16149
+ }
16150
+ function pushTag(draft, value) {
16151
+ const tag = readString4(value);
16152
+ if (!tag) return;
16153
+ const normalized = truncate(tag, MAX_TAG_LENGTH);
16154
+ if (!draft.tags.includes(normalized)) {
16155
+ draft.tags.push(normalized);
16156
+ }
16157
+ }
16158
+ function mergeTags(...tagGroups) {
16159
+ const tags = [];
16160
+ for (const group of tagGroups) {
16161
+ for (const tag of group) {
16162
+ if (!tags.includes(tag)) tags.push(tag);
16163
+ }
16164
+ }
16165
+ return tags;
16166
+ }
16167
+ function getMessageNavigationItemId(message, index) {
16168
+ const messageId = readString4(message.id);
16169
+ if (messageId) return messageId;
16170
+ const type = readString4(message.type) ?? "message";
16171
+ return `${type}-${index}`;
16172
+ }
16173
+ function getMessageNavigationRole(type) {
16174
+ const normalized = readString4(type)?.toLowerCase();
16175
+ if (normalized === "human" || normalized === "user") return "user";
16176
+ if (normalized === "ai" || normalized === "assistant") return "assistant";
16177
+ if (normalized === "system") return "system";
16178
+ if (normalized === "tool") return "tool";
16179
+ if (normalized === "event") return "event";
16180
+ return "message";
16181
+ }
16182
+ function isTextContent4(content) {
16183
+ return content.type === "text";
16184
+ }
16185
+ function isReasoningContent4(content) {
16186
+ return content.type === "reasoning";
16187
+ }
16188
+ function isComponentContent4(content) {
16189
+ return content.type === "component";
16190
+ }
16191
+ function isMemoryContent2(content) {
16192
+ return content.type === "memory";
16193
+ }
16194
+ function isWidgetComponent3(content) {
16195
+ const data = content.data;
16196
+ return data?.type === "Widget" && Array.isArray(data.widgets);
16197
+ }
16198
+ function isMcpAppComponent2(content) {
16199
+ const data = content.data;
16200
+ return data?.type === "McpApp" && typeof data.appInstanceId === "string";
16201
+ }
16202
+ function collectWidgetContent(draft, content, labels) {
16203
+ const names = content.data.widgets.map((widget) => readString4(widget.name)).filter((name) => Boolean(name));
16204
+ if (names.length === 0) {
16205
+ pushTag(draft, labels.widget);
16206
+ return;
16207
+ }
16208
+ for (const name of names) {
16209
+ pushTag(draft, name);
16210
+ }
16211
+ }
16212
+ function collectMcpAppContent(draft, content, labels, language) {
16213
+ const title = readString4(resolveLocalizedText(content.data.title, language)) ?? readString4(content.data.toolName) ?? labels.mcpApp;
16214
+ pushTag(draft, title);
16215
+ pushText(draft, resolveLocalizedText(content.data.description, language));
16216
+ }
16217
+ function collectComponentContent(draft, content, labels, language, options) {
16218
+ if (isWidgetComponent3(content)) {
16219
+ collectWidgetContent(draft, content, labels);
16220
+ return;
16221
+ }
16222
+ if (isMcpAppComponent2(content)) {
16223
+ collectMcpAppContent(draft, content, labels, language);
16224
+ return;
16225
+ }
16226
+ const data = getToolStepData(content);
16227
+ pushTag(
16228
+ draft,
16229
+ resolveLocalizedText(data.message, language) ?? getToolActivityLabel(content, language)
16230
+ );
16231
+ if (options.includeComponentText !== false) {
16232
+ pushText(draft, resolveLocalizedText(data.message, language));
16233
+ pushText(draft, resolveLocalizedText(data.title, language));
16234
+ pushText(draft, resolveLocalizedText(data.tool, language));
16235
+ pushText(draft, resolveLocalizedText(data.type, language));
16236
+ }
16237
+ }
16238
+ function collectContentItem(draft, item, labels, language, options) {
16239
+ if (item === void 0 || isThreadContextUsageRenderArtifact(item)) return;
16240
+ if (typeof item === "string") {
16241
+ pushText(draft, item);
16242
+ return;
16243
+ }
16244
+ if (isTextContent4(item) || isReasoningContent4(item)) {
16245
+ pushText(draft, item.text);
16246
+ if (isReasoningContent4(item)) pushTag(draft, labels.reasoning);
16247
+ return;
16248
+ }
16249
+ if (item.type === "image_url") {
16250
+ pushTag(draft, labels.image);
16251
+ return;
16252
+ }
16253
+ if (isComponentContent4(item)) {
16254
+ collectComponentContent(draft, item, labels, language, options);
16255
+ return;
16256
+ }
16257
+ if (isMemoryContent2(item)) {
16258
+ pushTag(draft, labels.memory);
16259
+ }
16260
+ }
16261
+ function collectContent(draft, content, labels, language, options = {}) {
16262
+ if (typeof content === "string") {
16263
+ pushText(draft, content);
16264
+ return;
16265
+ }
16266
+ if (!Array.isArray(content)) {
16267
+ return;
16268
+ }
16269
+ for (const item of content) {
16270
+ collectContentItem(
16271
+ draft,
16272
+ item,
16273
+ labels,
16274
+ language,
16275
+ options
16276
+ );
16277
+ }
16278
+ }
16279
+ function collectReasoning(draft, reasoning, labels) {
16280
+ if (!Array.isArray(reasoning)) return;
16281
+ for (const item of reasoning) {
16282
+ if (!isRecord6(item)) continue;
16283
+ pushText(draft, item.text);
16284
+ if (readString4(item.text)) pushTag(draft, labels.reasoning);
16285
+ }
16286
+ }
16287
+ function collectFiles(draft, value, fallbackLabel) {
16288
+ if (!Array.isArray(value)) return;
16289
+ for (const file of value) {
16290
+ if (!isRecord6(file)) continue;
16291
+ pushTag(
16292
+ draft,
16293
+ file.originalName ?? file.name ?? file.fileName ?? file.id ?? fallbackLabel
16294
+ );
16295
+ }
16296
+ }
16297
+ function collectReferences(draft, value) {
16298
+ for (const reference of normalizeReferences(value)) {
16299
+ pushTag(draft, getReferenceLabel(reference));
16300
+ }
16301
+ }
16302
+ function collectRuntimeCapabilities(draft, value) {
16303
+ if (!Array.isArray(value)) return;
16304
+ for (const option of value) {
16305
+ if (!isRecord6(option)) continue;
16306
+ pushTag(draft, option.label ?? option.id ?? option.type);
16307
+ }
16308
+ }
16309
+ function getTitle(role, labels, assistantTitle) {
16310
+ if (role === "assistant" && assistantTitle?.trim()) {
16311
+ return assistantTitle.trim();
16312
+ }
16313
+ return labels[role];
16314
+ }
16315
+ function buildMessageNavigationItemSummary(message, index, options, collectOptions = {}) {
16316
+ const role = getMessageNavigationRole(message.type);
16317
+ const draft = {
16318
+ text: [],
16319
+ tags: []
16320
+ };
16321
+ const language = options.language ?? "en-US";
16322
+ const labels = options.labels;
16323
+ if (role === "user") {
16324
+ pushText(draft, message.submittedInput);
16325
+ }
16326
+ collectContent(draft, message.content, labels, language, collectOptions);
16327
+ collectReasoning(draft, message.reasoning, labels);
16328
+ collectFiles(draft, message.fileAssets, labels.attachment);
16329
+ collectFiles(draft, message.attachments, labels.attachment);
16330
+ collectReferences(draft, message.references);
16331
+ collectRuntimeCapabilities(draft, message.runtimeCapabilityOptions);
16332
+ const text = draft.text.map(normalizeWhitespace).filter(Boolean).join(" ");
16333
+ const preview = truncate(text, MAX_PREVIEW_LENGTH) || draft.tags.slice(0, 2).join(" \xB7 ");
16334
+ if (!preview && draft.tags.length === 0) {
16335
+ return null;
16336
+ }
16337
+ const messageId = readString4(message.id) ?? void 0;
16338
+ return {
16339
+ id: getMessageNavigationItemId(message, index),
16340
+ ...messageId ? { messageId } : {},
16341
+ index,
16342
+ role,
16343
+ title: getTitle(role, labels, options.assistantTitle),
16344
+ preview,
16345
+ tags: draft.tags
16346
+ };
16347
+ }
16348
+ function buildMessageNavigationItems(messages, options) {
16349
+ const items = [];
16350
+ let pendingUser = null;
16351
+ messages.forEach((message, messageIndex) => {
16352
+ const item = buildMessageNavigationItemSummary(
16353
+ message,
16354
+ messageIndex,
16355
+ options,
16356
+ { includeComponentText: false }
16357
+ );
16358
+ if (!item) return;
16359
+ if (item.role === "user") {
16360
+ pendingUser = { item };
16361
+ return;
16362
+ }
16363
+ if (item.role !== "assistant" || !pendingUser) {
16364
+ return;
16365
+ }
16366
+ items.push({
16367
+ id: pendingUser.item.id,
16368
+ ...pendingUser.item.messageId ? { messageId: pendingUser.item.messageId } : {},
16369
+ index: items.length,
16370
+ role: "user",
16371
+ title: pendingUser.item.preview,
16372
+ preview: item.preview,
16373
+ tags: mergeTags(item.tags, pendingUser.item.tags)
16374
+ });
16375
+ pendingUser = null;
16376
+ });
16377
+ return items;
16378
+ }
16379
+
16380
+ // src/components/chat.tsx
16381
+ import { Fragment as Fragment9, jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
16382
+ var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
16383
+ var COMPOSER_INPUT_MAX_HEIGHT = 128;
16384
+ var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
16385
+ var GOAL_RUN_INPUT = "Continue working toward the active goal.";
16386
+ function isGoalAdapter(value) {
16387
+ return Boolean(value) && typeof value === "object" && typeof value.getGoal === "function" && typeof value.setGoal === "function" && typeof value.updateGoal === "function" && typeof value.clearGoal === "function";
16388
+ }
16389
+ function formatGoalElapsed(seconds) {
16390
+ if (seconds < 60) {
16391
+ return `${seconds}s`;
16392
+ }
16393
+ const minutes = Math.floor(seconds / 60);
16394
+ const remainingSeconds = seconds % 60;
16395
+ return remainingSeconds ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
16396
+ }
16397
+ async function readImageDimensions(file) {
16398
+ if (typeof window === "undefined" || typeof URL === "undefined") {
16399
+ return {};
16400
+ }
16401
+ return new Promise((resolve) => {
16402
+ const objectUrl = URL.createObjectURL(file);
16403
+ const image = new window.Image();
16404
+ const cleanup = () => {
16405
+ URL.revokeObjectURL(objectUrl);
16406
+ };
16407
+ image.onload = () => {
16408
+ resolve({
16409
+ width: image.naturalWidth || void 0,
16410
+ height: image.naturalHeight || void 0
16411
+ });
16412
+ cleanup();
16413
+ };
16414
+ image.onerror = () => {
16415
+ resolve({});
16416
+ cleanup();
16417
+ };
16418
+ image.src = objectUrl;
16419
+ });
16420
+ }
16421
+ function getUploadedFileUrl(file) {
16422
+ return file.url ?? file.fileUrl ?? file.thumbUrl;
16423
+ }
16424
+ function buildPastedImageReference(file, uploadedFile, dimensions) {
16425
+ const name = uploadedFile.originalName?.trim() || file.name.trim() || "Pasted image";
16426
+ const mimeType = uploadedFile.mimeType?.trim() || file.type.trim() || "image/*";
16427
+ const size2 = uploadedFile.size ?? file.size;
16428
+ const width = dimensions?.width;
16429
+ const height = dimensions?.height;
16430
+ const metaParts = [
16431
+ mimeType,
16432
+ width && height ? `${width}x${height}` : null,
16433
+ typeof size2 === "number" ? `${size2} bytes` : null
16434
+ ].filter((part) => Boolean(part));
16435
+ return {
16436
+ type: "image",
16437
+ id: uploadedFile.id,
16438
+ fileId: uploadedFile.storageFileId,
16439
+ url: getUploadedFileUrl(uploadedFile),
16440
+ mimeType,
16441
+ name,
16442
+ ...typeof size2 === "number" ? { size: size2 } : {},
16443
+ ...width ? { width } : {},
16444
+ ...height ? { height } : {},
16445
+ text: `Pasted image${metaParts.length ? ` (${metaParts.join(", ")})` : ""}: ${name}`
16446
+ };
16447
+ }
16448
+ function formatMessageContent(content) {
16449
+ if (typeof content === "string") {
16450
+ return content;
16451
+ }
16452
+ if (Array.isArray(content)) {
16453
+ return content.map((part) => {
16454
+ if (typeof part === "string") return part;
16455
+ if (part && typeof part === "object" && "text" in part) {
16456
+ const textValue = part.text;
16457
+ return typeof textValue === "string" ? textValue : "";
16458
+ }
16459
+ return "";
16460
+ }).join("");
16461
+ }
16462
+ if (content == null) return "";
16463
+ if (typeof content === "object" && "text" in content) {
16464
+ const textValue = content.text;
16465
+ return typeof textValue === "string" ? textValue : "";
16466
+ }
16467
+ return "";
15399
16468
  }
15400
16469
  function getClosestQuoteContainer(node) {
15401
16470
  if (!node) {
@@ -15413,7 +16482,7 @@ function ReferenceChip({
15413
16482
  const metaLine = getReferenceMetaLine(reference);
15414
16483
  const isComposer = variant === "composer";
15415
16484
  const Icon = reference.type === "quote" ? Quote : reference.type === "image" ? ImageIcon : FileText5;
15416
- return /* @__PURE__ */ jsxs37(
16485
+ return /* @__PURE__ */ jsxs39(
15417
16486
  "div",
15418
16487
  {
15419
16488
  className: cn(
@@ -15422,7 +16491,7 @@ function ReferenceChip({
15422
16491
  ),
15423
16492
  title: getReferenceTitle(reference),
15424
16493
  children: [
15425
- /* @__PURE__ */ jsx54(
16494
+ /* @__PURE__ */ jsx56(
15426
16495
  Icon,
15427
16496
  {
15428
16497
  size: isComposer ? 14 : 12,
@@ -15432,8 +16501,8 @@ function ReferenceChip({
15432
16501
  )
15433
16502
  }
15434
16503
  ),
15435
- /* @__PURE__ */ jsxs37("div", { className: "min-w-0 flex-1", children: [
15436
- /* @__PURE__ */ jsx54(
16504
+ /* @__PURE__ */ jsxs39("div", { className: "min-w-0 flex-1", children: [
16505
+ /* @__PURE__ */ jsx56(
15437
16506
  "div",
15438
16507
  {
15439
16508
  className: cn(
@@ -15443,7 +16512,7 @@ function ReferenceChip({
15443
16512
  children: getReferenceLabel(reference)
15444
16513
  }
15445
16514
  ),
15446
- metaLine && /* @__PURE__ */ jsx54(
16515
+ metaLine && /* @__PURE__ */ jsx56(
15447
16516
  "div",
15448
16517
  {
15449
16518
  className: cn(
@@ -15454,7 +16523,7 @@ function ReferenceChip({
15454
16523
  }
15455
16524
  )
15456
16525
  ] }),
15457
- onRemove && removeLabel && /* @__PURE__ */ jsx54(
16526
+ onRemove && removeLabel && /* @__PURE__ */ jsx56(
15458
16527
  "button",
15459
16528
  {
15460
16529
  type: "button",
@@ -15465,7 +16534,7 @@ function ReferenceChip({
15465
16534
  ),
15466
16535
  title: removeLabel,
15467
16536
  "aria-label": removeLabel,
15468
- children: /* @__PURE__ */ jsx54(X6, { size: 12 })
16537
+ children: /* @__PURE__ */ jsx56(X7, { size: 12 })
15469
16538
  }
15470
16539
  )
15471
16540
  ]
@@ -15480,35 +16549,66 @@ function Chat({
15480
16549
  clientSecret = "",
15481
16550
  isClientSecretInitializing = false
15482
16551
  }) {
15483
- const { t } = useChatkitTranslation();
16552
+ const { t, i18n: i18n2 } = useChatkitTranslation();
15484
16553
  const composer = options?.composer;
15485
16554
  const startScreen = options?.startScreen;
15486
16555
  const history = options?.history;
15487
16556
  const disclaimer = options?.disclaimer;
15488
16557
  const apiUrl = options?.api?.apiUrl || defaultApiUrl2;
16558
+ const messageNavigationEnabled = options?.messageNavigation?.enabled !== false;
15489
16559
  const { setStream } = useStreamManager();
15490
16560
  const stream = useStreamContext();
15491
16561
  const { theme } = useTheme();
15492
- const [isHistoryLoading, setIsHistoryLoading] = React49.useState(false);
15493
- const [historyError, setHistoryError] = React49.useState(null);
15494
- const [assistantName, setAssistantName] = React49.useState(null);
15495
- const [assistantAvatar, setAssistantAvatar] = React49.useState(null);
15496
- const [threadGoal, setThreadGoal] = React49.useState(null);
15497
- const [goalError, setGoalError] = React49.useState(null);
15498
- const [isGoalLoading, setIsGoalLoading] = React49.useState(false);
15499
- const [isGoalPanelOpen, setIsGoalPanelOpen] = React49.useState(false);
15500
- const [isGoalObjectiveExpanded, setIsGoalObjectiveExpanded] = React49.useState(false);
15501
- const [goalElapsedStartedAt, setGoalElapsedStartedAt] = React49.useState(null);
16562
+ const effectiveClientSecret = stream.apiKey?.trim() ? stream.apiKey : clientSecret;
16563
+ const missingConfigKind = getMissingApiConfigurationKind({
16564
+ apiUrl,
16565
+ clientSecret: effectiveClientSecret
16566
+ });
16567
+ const missingConfig = Boolean(missingConfigKind);
16568
+ const missingConfigShortMessage = React51.useMemo(() => {
16569
+ switch (missingConfigKind) {
16570
+ case "apiUrl":
16571
+ return t("chat.missingApiUrlShort");
16572
+ case "clientSecret":
16573
+ return t("chat.missingClientSecretShort");
16574
+ case "apiUrlAndClientSecret":
16575
+ return t("chat.missingApiUrlAndClientSecretShort");
16576
+ default:
16577
+ return t("chat.missingConfigShort");
16578
+ }
16579
+ }, [missingConfigKind, t]);
16580
+ const missingConfigDetailMessage = React51.useMemo(() => {
16581
+ switch (missingConfigKind) {
16582
+ case "apiUrl":
16583
+ return t("chat.missingApiUrlDetail");
16584
+ case "clientSecret":
16585
+ return t("chat.missingClientSecretDetail");
16586
+ case "apiUrlAndClientSecret":
16587
+ return t("chat.missingApiUrlAndClientSecretDetail");
16588
+ default:
16589
+ return t("chat.missingConfigDetail");
16590
+ }
16591
+ }, [missingConfigKind, t]);
16592
+ const [isHistoryLoading, setIsHistoryLoading] = React51.useState(false);
16593
+ const [historyError, setHistoryError] = React51.useState(null);
16594
+ const [assistantName, setAssistantName] = React51.useState(null);
16595
+ const [assistantAvatar, setAssistantAvatar] = React51.useState(null);
16596
+ const [threadGoal, setThreadGoal] = React51.useState(null);
16597
+ const [goalError, setGoalError] = React51.useState(null);
16598
+ const [isGoalLoading, setIsGoalLoading] = React51.useState(false);
16599
+ const [isGoalPanelOpen, setIsGoalPanelOpen] = React51.useState(false);
16600
+ const [isGoalObjectiveExpanded, setIsGoalObjectiveExpanded] = React51.useState(false);
16601
+ const [goalElapsedStartedAt, setGoalElapsedStartedAt] = React51.useState(null);
15502
16602
  const LOADING_DOTS_MIN_DURATION = 800;
15503
16603
  const STREAMING_STATUS_REFRESH_MS = 250;
15504
- const [showLoadingDots, setShowLoadingDots] = React49.useState(false);
15505
- const [streamingNow, setStreamingNow] = React49.useState(() => Date.now());
15506
- const loadingStartTimeRef = React49.useRef(null);
15507
- const lastStreamOutputAtRef = React49.useRef(null);
15508
- React49.useEffect(() => {
16604
+ const [showLoadingDots, setShowLoadingDots] = React51.useState(false);
16605
+ const [streamingNow, setStreamingNow] = React51.useState(() => Date.now());
16606
+ const loadingStartTimeRef = React51.useRef(null);
16607
+ const lastStreamOutputAtRef = React51.useRef(null);
16608
+ React51.useEffect(() => {
15509
16609
  setStream(stream);
15510
16610
  }, [setStream, stream]);
15511
- React49.useEffect(() => {
16611
+ React51.useEffect(() => {
15512
16612
  if (stream.isLoading) {
15513
16613
  if (!loadingStartTimeRef.current) {
15514
16614
  loadingStartTimeRef.current = Date.now();
@@ -15531,7 +16631,7 @@ function Chat({
15531
16631
  }
15532
16632
  }
15533
16633
  }, [stream.isLoading]);
15534
- React49.useEffect(() => {
16634
+ React51.useEffect(() => {
15535
16635
  if (!stream.isLoading) {
15536
16636
  lastStreamOutputAtRef.current = null;
15537
16637
  setStreamingNow(Date.now());
@@ -15541,7 +16641,7 @@ function Chat({
15541
16641
  lastStreamOutputAtRef.current = now;
15542
16642
  setStreamingNow(now);
15543
16643
  }, [stream.messages, stream.isLoading]);
15544
- React49.useEffect(() => {
16644
+ React51.useEffect(() => {
15545
16645
  if (!stream.isLoading) {
15546
16646
  return;
15547
16647
  }
@@ -15550,7 +16650,7 @@ function Chat({
15550
16650
  }, STREAMING_STATUS_REFRESH_MS);
15551
16651
  return () => window.clearInterval(timer);
15552
16652
  }, [stream.isLoading]);
15553
- React49.useEffect(() => {
16653
+ React51.useEffect(() => {
15554
16654
  if (threadGoal?.status === "active" && stream.isLoading) {
15555
16655
  setGoalElapsedStartedAt(Date.now());
15556
16656
  return;
@@ -15562,82 +16662,100 @@ function Chat({
15562
16662
  threadGoal?.id,
15563
16663
  threadGoal?.status
15564
16664
  ]);
15565
- React49.useEffect(() => {
16665
+ React51.useEffect(() => {
15566
16666
  setIsGoalObjectiveExpanded(false);
15567
16667
  }, [threadGoal?.id]);
15568
- const [composerParts, setComposerParts] = React49.useState([]);
15569
- const [renderedComposerParts, setRenderedComposerParts] = React49.useState([]);
15570
- const [composerDomVersion, setComposerDomVersion] = React49.useState(0);
15571
- const [selectedTool, setSelectedTool] = React49.useState(
16668
+ const [composerParts, setComposerParts] = React51.useState([]);
16669
+ const [renderedComposerParts, setRenderedComposerParts] = React51.useState([]);
16670
+ const [composerDomVersion, setComposerDomVersion] = React51.useState(0);
16671
+ const [selectedTool, setSelectedTool] = React51.useState(
15572
16672
  null
15573
16673
  );
15574
- const [planModeEnabled, setPlanModeEnabled] = React49.useState(false);
15575
- const [petSettingsOpen, setPetSettingsOpen] = React49.useState(false);
15576
- const [petLocalSettings, setPetLocalSettings] = React49.useState(() => readPetLocalSettings());
15577
- const [runtimeCapabilities, setRuntimeCapabilities] = React49.useState(null);
15578
- const [runtimeCapabilitiesReady, setRuntimeCapabilitiesReady] = React49.useState(false);
15579
- const [sessionRuntimeCapabilities, setSessionRuntimeCapabilities] = React49.useState(
15580
- () => createEmptyRuntimeCapabilitiesSelection()
15581
- );
15582
- const [runRuntimeCapabilities, setRunRuntimeCapabilities] = React49.useState(
15583
- () => createEmptyRuntimeCapabilitiesSelection()
15584
- );
15585
- const [runtimeCapabilityPalette, setRuntimeCapabilityPalette] = React49.useState(null);
15586
- const [attachmentState, setAttachmentState] = React49.useState({
16674
+ const [planModeEnabled, setPlanModeEnabled] = React51.useState(false);
16675
+ const [petSettingsOpen, setPetSettingsOpen] = React51.useState(false);
16676
+ const [petLocalSettings, setPetLocalSettings] = React51.useState(() => readPetLocalSettings());
16677
+ const [attachmentState, setAttachmentState] = React51.useState({
15587
16678
  uploadedFiles: [],
15588
16679
  hasUploadingFiles: false,
15589
16680
  hasParsingFiles: false
15590
16681
  });
15591
- const [references, setReferences] = React49.useState([]);
15592
- const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React49.useState(false);
15593
- const [quoteSelection, setQuoteSelection] = React49.useState(null);
15594
- const [isAtBottom, setIsAtBottom] = React49.useState(true);
15595
- const [hasUpdatesBelow, setHasUpdatesBelow] = React49.useState(false);
16682
+ const [references, setReferences] = React51.useState([]);
16683
+ const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React51.useState(false);
16684
+ const [quoteSelection, setQuoteSelection] = React51.useState(null);
16685
+ const [isAtBottom, setIsAtBottom] = React51.useState(true);
16686
+ const [hasUpdatesBelow, setHasUpdatesBelow] = React51.useState(false);
15596
16687
  const {
15597
16688
  threads,
15598
16689
  deleteThread,
15599
16690
  refreshThreads,
15600
16691
  isLoading: isThreadsLoading
15601
16692
  } = useThreads();
15602
- const viewportRef = React49.useRef(null);
15603
- const attachmentsRef = React49.useRef(null);
15604
- const composerInputRef = React49.useRef(null);
15605
- const slashPaletteRef = React49.useRef(null);
15606
- const slashPaletteOptionRefs = React49.useRef(
16693
+ const viewportRef = React51.useRef(null);
16694
+ const messageNavigationAnchorsRef = React51.useRef(
16695
+ /* @__PURE__ */ new Map()
16696
+ );
16697
+ const attachmentsRef = React51.useRef(null);
16698
+ const composerInputRef = React51.useRef(null);
16699
+ const slashPaletteRef = React51.useRef(null);
16700
+ const slashPaletteOptionRefs = React51.useRef(
15607
16701
  []
15608
16702
  );
15609
- const composerPartsRef = React49.useRef([]);
15610
- const pendingComposerCaretOffsetRef = React49.useRef(null);
15611
- const shouldAutoScrollRef = React49.useRef(true);
15612
- const forceFollowRef = React49.useRef(false);
15613
- const previousMessageCountRef = React49.useRef(0);
15614
- const previousScrollTopRef = React49.useRef(0);
15615
- const isPrependingHistoryMessagesRef = React49.useRef(false);
15616
- const autoScrollFrameRef = React49.useRef(null);
15617
- const isPointerDownRef = React49.useRef(false);
15618
- const lastTouchYRef = React49.useRef(null);
15619
- const runtimeCapabilityPreferenceLoadRef = React49.useRef(0);
16703
+ const composerPartsRef = React51.useRef([]);
16704
+ const pendingComposerCaretOffsetRef = React51.useRef(null);
16705
+ const shouldAutoScrollRef = React51.useRef(true);
16706
+ const forceFollowRef = React51.useRef(false);
16707
+ const previousMessageCountRef = React51.useRef(0);
16708
+ const previousScrollTopRef = React51.useRef(0);
16709
+ const isPrependingHistoryMessagesRef = React51.useRef(false);
16710
+ const autoScrollFrameRef = React51.useRef(null);
16711
+ const isPointerDownRef = React51.useRef(false);
16712
+ const lastTouchYRef = React51.useRef(null);
16713
+ const {
16714
+ runtimeCapabilities,
16715
+ runtimeCapabilitiesReady,
16716
+ runtimeCapabilityOptions,
16717
+ effectiveSessionRuntimeCapabilities,
16718
+ runRuntimeCapabilities,
16719
+ detachedRunRuntimeCapabilityOptions,
16720
+ runtimeCapabilityPalette,
16721
+ setRunRuntimeCapabilities,
16722
+ setRuntimeCapabilityPalette,
16723
+ applyExternalRuntimeCapabilities,
16724
+ handleSessionRuntimeCapabilityToggle,
16725
+ addRunRuntimeCapabilities,
16726
+ resetRunRuntimeCapabilities,
16727
+ getRuntimeCapabilitiesForSubmit,
16728
+ getRuntimeCapabilitiesForCommand,
16729
+ persistSessionRuntimeCapabilities
16730
+ } = useRuntimeCapabilitiesState({
16731
+ client: stream.client,
16732
+ assistantId: stream.assistantId,
16733
+ threadId: stream.threadId,
16734
+ disabled: missingConfig || !stream.client || !stream.assistantId,
16735
+ composerParts
16736
+ });
15620
16737
  const resolvedTitle = title ?? t("chat.title");
15621
16738
  const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
16739
+ const assistantTitle = assistantName || resolvedTitle;
15622
16740
  const petRequired = options?.displayMode === "pet";
15623
- const basePetSettings = React49.useMemo(
16741
+ const basePetSettings = React51.useMemo(
15624
16742
  () => derivePetLocalSettings(options?.pet),
15625
16743
  [options?.pet]
15626
16744
  );
15627
- const displayedPetSettings = React49.useMemo(
16745
+ const displayedPetSettings = React51.useMemo(
15628
16746
  () => ({
15629
16747
  ...petLocalSettings ?? basePetSettings,
15630
16748
  ...petRequired ? { enabled: true } : {}
15631
16749
  }),
15632
16750
  [basePetSettings, petLocalSettings, petRequired]
15633
16751
  );
15634
- const effectivePet = React49.useMemo(() => {
16752
+ const effectivePet = React51.useMemo(() => {
15635
16753
  if (petRequired || petLocalSettings) {
15636
16754
  return buildPetOptionsFromLocalSettings(displayedPetSettings);
15637
16755
  }
15638
16756
  return options?.pet ?? null;
15639
16757
  }, [displayedPetSettings, options?.pet, petLocalSettings, petRequired]);
15640
- const savePetLocalSettings = React49.useCallback(
16758
+ const savePetLocalSettings = React51.useCallback(
15641
16759
  (settings) => {
15642
16760
  const nextSettings = petRequired ? { ...settings, enabled: true } : settings;
15643
16761
  setPetLocalSettings(nextSettings);
@@ -15645,7 +16763,7 @@ function Chat({
15645
16763
  },
15646
16764
  [petRequired]
15647
16765
  );
15648
- const handlePetCommand = React49.useCallback(
16766
+ const handlePetCommand = React51.useCallback(
15649
16767
  (mode) => {
15650
16768
  if (mode === "settings") {
15651
16769
  setPetSettingsOpen(true);
@@ -15667,16 +16785,53 @@ function Chat({
15667
16785
  [displayedPetSettings, effectivePet, petRequired, savePetLocalSettings]
15668
16786
  );
15669
16787
  const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
15670
- const messages = React49.useMemo(
16788
+ const messages = React51.useMemo(
15671
16789
  () => stream.messages ?? [],
15672
16790
  [stream.messages]
15673
16791
  );
16792
+ const messageNavigationLabels = React51.useMemo(
16793
+ () => ({
16794
+ user: t("chat.youLabel"),
16795
+ assistant: assistantTitle,
16796
+ system: t("message.navigation.system"),
16797
+ tool: t("message.navigation.tool"),
16798
+ event: t("message.navigation.event"),
16799
+ message: t("message.navigation.message"),
16800
+ image: t("message.navigation.image"),
16801
+ memory: t("message.navigation.memory"),
16802
+ widget: t("message.navigation.widget"),
16803
+ mcpApp: t("message.navigation.mcpApp"),
16804
+ attachment: t("message.navigation.attachment"),
16805
+ reference: t("message.navigation.reference"),
16806
+ capability: t("message.navigation.capability"),
16807
+ reasoning: t("message.reasoning")
16808
+ }),
16809
+ [assistantTitle, t]
16810
+ );
16811
+ const messageNavigationItems = React51.useMemo(
16812
+ () => messageNavigationEnabled ? buildMessageNavigationItems(
16813
+ messages,
16814
+ {
16815
+ labels: messageNavigationLabels,
16816
+ language: i18n2.language,
16817
+ assistantTitle
16818
+ }
16819
+ ) : [],
16820
+ [
16821
+ assistantTitle,
16822
+ i18n2.language,
16823
+ messageNavigationEnabled,
16824
+ messageNavigationLabels,
16825
+ messages
16826
+ ]
16827
+ );
16828
+ const showMessageNavigation = messageNavigationItems.length >= MESSAGE_NAVIGATION_MIN_ITEMS;
15674
16829
  const historyMessagePagination = stream.historyMessagePagination;
15675
16830
  const isLoadingMoreMessages = Boolean(
15676
16831
  historyMessagePagination?.isLoadingMore
15677
16832
  );
15678
16833
  const canLoadMoreMessages = Boolean(historyMessagePagination?.hasMore);
15679
- const draft = React49.useMemo(
16834
+ const draft = React51.useMemo(
15680
16835
  () => getComposerPlainText(composerParts),
15681
16836
  [composerParts]
15682
16837
  );
@@ -15690,7 +16845,7 @@ function Chat({
15690
16845
  isEmpty: isComposerInputEmpty,
15691
16846
  isStacked: isComposerStacked
15692
16847
  });
15693
- const pendingFollowUps = React49.useMemo(
16848
+ const pendingFollowUps = React51.useMemo(
15694
16849
  () => sortVisiblePendingFollowUps(stream.pendingFollowUps ?? []),
15695
16850
  [stream.pendingFollowUps]
15696
16851
  );
@@ -15699,84 +16854,23 @@ function Chat({
15699
16854
  const hasPendingHITLRequest = Boolean(stream.pendingHITLRequest);
15700
16855
  const hasPendingInteractiveRequest = hasPendingRequestUserInput || hasPendingHITLRequest;
15701
16856
  const hasPendingTodos = Boolean(stream.todos?.items.length);
15702
- const runtimeCapabilityOptions = React49.useMemo(
15703
- () => getRuntimeCapabilityOptions(runtimeCapabilities),
15704
- [runtimeCapabilities]
15705
- );
15706
- const goalAdapter = React49.useMemo(
15707
- () => {
15708
- if (isGoalAdapter(options?.goal)) {
15709
- return options.goal;
15710
- }
15711
- return supportsXpertThreadGoalAdapter(stream.client) ? createXpertThreadGoalAdapter(stream.client) : null;
15712
- },
15713
- [options?.goal, stream.client]
15714
- );
16857
+ const goalAdapter = React51.useMemo(() => {
16858
+ if (isGoalAdapter(options?.goal)) {
16859
+ return options.goal;
16860
+ }
16861
+ return supportsXpertThreadGoalAdapter(stream.client) ? createXpertThreadGoalAdapter(stream.client) : null;
16862
+ }, [options?.goal, stream.client]);
15715
16863
  const displayedGoalElapsedSeconds = threadGoal ? (threadGoal.elapsedSeconds ?? 0) + (goalElapsedStartedAt ? Math.max(0, Math.floor((streamingNow - goalElapsedStartedAt) / 1e3)) : 0) : 0;
15716
- const effectiveSessionRuntimeCapabilities = React49.useMemo(
15717
- () => runtimeCapabilitiesReady && runtimeCapabilities ? mergeRuntimeCapabilitiesSelections(
15718
- runtimeCapabilities,
15719
- sessionRuntimeCapabilities
15720
- ) : null,
15721
- [runtimeCapabilities, runtimeCapabilitiesReady, sessionRuntimeCapabilities]
15722
- );
15723
16864
  const goalCommandAvailable = hasSelectedRuntimeSlashCommand(
15724
16865
  runtimeCapabilities,
15725
16866
  effectiveSessionRuntimeCapabilities,
15726
16867
  "goal"
15727
16868
  );
15728
16869
  const showGoalStatus = goalCommandAvailable && !hasCompletedGoal && (Boolean(goalError) || threadGoal?.status === "active" && stream.isLoading);
15729
- const runRuntimeCapabilityOptions = React49.useMemo(
15730
- () => runtimeCapabilityOptions.filter(
15731
- (option) => isRuntimeCapabilitySelected(
15732
- runRuntimeCapabilities,
15733
- option.type,
15734
- option.id
15735
- )
15736
- ),
15737
- [runRuntimeCapabilities, runtimeCapabilityOptions]
15738
- );
15739
- const composerRuntimeCapabilitySelectionKeys = React49.useMemo(
15740
- () => getComposerCapabilitySelectionKeys(composerParts),
15741
- [composerParts]
15742
- );
15743
- const detachedRunRuntimeCapabilityOptions = React49.useMemo(
15744
- () => runRuntimeCapabilityOptions.filter(
15745
- (option) => !composerRuntimeCapabilitySelectionKeys.has(
15746
- getRuntimeCapabilityOptionKey(option)
15747
- )
15748
- ),
15749
- [composerRuntimeCapabilitySelectionKeys, runRuntimeCapabilityOptions]
15750
- );
15751
- const persistSessionRuntimeCapabilities = React49.useCallback(
15752
- async (threadId, selection) => {
15753
- if (!runtimeCapabilities || !selection) {
15754
- return;
15755
- }
15756
- try {
15757
- const result = await persistConversationRuntimeCapabilities({
15758
- client: stream.client,
15759
- threadId,
15760
- capabilities: runtimeCapabilities,
15761
- selection
15762
- });
15763
- warnMissingRuntimeCapabilityReferences(
15764
- "persisted selection",
15765
- result.missing
15766
- );
15767
- } catch (error) {
15768
- console.warn(
15769
- "[Chat] Failed to persist runtime capabilities selection:",
15770
- error
15771
- );
15772
- }
15773
- },
15774
- [runtimeCapabilities, stream.client]
15775
- );
15776
- const clearQuoteSelection = React49.useCallback(() => {
16870
+ const clearQuoteSelection = React51.useCallback(() => {
15777
16871
  setQuoteSelection(null);
15778
16872
  }, []);
15779
- const commitComposerParts = React49.useCallback(
16873
+ const commitComposerParts = React51.useCallback(
15780
16874
  (nextParts, options2) => {
15781
16875
  const normalized = normalizeComposerParts(nextParts);
15782
16876
  const previous = composerPartsRef.current;
@@ -15785,23 +16879,17 @@ function Chat({
15785
16879
  pendingComposerCaretOffsetRef.current = options2.caretOffset;
15786
16880
  }
15787
16881
  if (options2?.syncRemovedCapabilityTokens ?? true) {
15788
- const nextKeys = getComposerCapabilityKeys(normalized);
15789
- const removedCapabilities = previous.filter(
15790
- (part) => part.type === "capability" && !nextKeys.has(part.key)
16882
+ const removedCapabilities = getRemovedComposerCapabilityParts(
16883
+ previous,
16884
+ normalized
15791
16885
  );
15792
16886
  if (removedCapabilities.length > 0) {
15793
- setRunRuntimeCapabilities((selection) => {
15794
- let nextSelection = selection;
15795
- for (const part of removedCapabilities) {
15796
- nextSelection = toggleRuntimeCapabilitySelection(
15797
- nextSelection,
15798
- part.capability.type,
15799
- part.capability.id,
15800
- false
15801
- );
15802
- }
15803
- return nextSelection;
15804
- });
16887
+ setRunRuntimeCapabilities(
16888
+ (selection) => removeComposerCapabilityPartsFromSelection(
16889
+ selection,
16890
+ removedCapabilities
16891
+ )
16892
+ );
15805
16893
  }
15806
16894
  }
15807
16895
  setComposerParts(normalized);
@@ -15810,9 +16898,9 @@ function Chat({
15810
16898
  setComposerDomVersion((version) => version + 1);
15811
16899
  }
15812
16900
  },
15813
- []
16901
+ [setRunRuntimeCapabilities]
15814
16902
  );
15815
- const setComposerText = React49.useCallback(
16903
+ const setComposerText = React51.useCallback(
15816
16904
  (text, caretOffset = text.length) => {
15817
16905
  commitComposerParts(createComposerTextParts(text), {
15818
16906
  caretOffset,
@@ -15822,7 +16910,7 @@ function Chat({
15822
16910
  },
15823
16911
  [commitComposerParts]
15824
16912
  );
15825
- const focusComposerAt = React49.useCallback((position) => {
16913
+ const focusComposerAt = React51.useCallback((position) => {
15826
16914
  const nextPosition = position ?? getComposerEditingLength(composerPartsRef.current);
15827
16915
  pendingComposerCaretOffsetRef.current = nextPosition;
15828
16916
  requestAnimationFrame(() => {
@@ -15833,8 +16921,25 @@ function Chat({
15833
16921
  setComposerSelectionOffset(input, nextPosition);
15834
16922
  });
15835
16923
  }, []);
16924
+ const {
16925
+ applyComposerValueRuntimeCapabilities,
16926
+ updateRuntimeCapabilityPalette,
16927
+ removeRunRuntimeCapability,
16928
+ insertComposerCapabilityToken
16929
+ } = useRuntimeCapabilityComposerActions({
16930
+ runtimeCapabilities,
16931
+ runtimeCapabilitiesReady,
16932
+ runtimeCapabilityOptions,
16933
+ setRunRuntimeCapabilities,
16934
+ setRuntimeCapabilityPalette,
16935
+ applyExternalRuntimeCapabilities,
16936
+ composerInputRef,
16937
+ composerPartsRef,
16938
+ commitComposerParts,
16939
+ focusComposerAt
16940
+ });
15836
16941
  const parentMessenger = useParentMessenger({
15837
- onSetComposerValue: React49.useCallback(
16942
+ onSetComposerValue: React51.useCallback(
15838
16943
  (payload) => {
15839
16944
  if (!payload) {
15840
16945
  return;
@@ -15854,13 +16959,24 @@ function Chat({
15854
16959
  ) ?? null;
15855
16960
  setSelectedTool(nextTool);
15856
16961
  }
16962
+ applyComposerValueRuntimeCapabilities(payload);
16963
+ },
16964
+ [
16965
+ applyComposerValueRuntimeCapabilities,
16966
+ composer?.tools,
16967
+ setComposerText
16968
+ ]
16969
+ ),
16970
+ onSetRuntimeCapabilities: React51.useCallback(
16971
+ (selection) => {
16972
+ applyExternalRuntimeCapabilities(selection);
15857
16973
  },
15858
- [composer?.tools, setComposerText]
16974
+ [applyExternalRuntimeCapabilities]
15859
16975
  ),
15860
- onFocusComposer: React49.useCallback(() => {
16976
+ onFocusComposer: React51.useCallback(() => {
15861
16977
  composerInputRef.current?.focus();
15862
16978
  }, []),
15863
- onSetPetEnabled: React49.useCallback(
16979
+ onSetPetEnabled: React51.useCallback(
15864
16980
  (enabled) => {
15865
16981
  if (petRequired) {
15866
16982
  return;
@@ -15874,10 +16990,10 @@ function Chat({
15874
16990
  )
15875
16991
  });
15876
16992
  const canMinimizeToPet = parentMessenger?.isParentAvailable === true && isPetEnabled(effectivePet);
15877
- const handleMinimizeToPet = React49.useCallback(() => {
16993
+ const handleMinimizeToPet = React51.useCallback(() => {
15878
16994
  parentMessenger?.sendEvent("chat_minimize_change", { minimized: true });
15879
16995
  }, [parentMessenger]);
15880
- const syncQuoteSelection = React49.useCallback(() => {
16996
+ const syncQuoteSelection = React51.useCallback(() => {
15881
16997
  if (typeof window === "undefined") {
15882
16998
  clearQuoteSelection();
15883
16999
  return;
@@ -15922,23 +17038,23 @@ function Chat({
15922
17038
  left
15923
17039
  });
15924
17040
  }, [clearQuoteSelection]);
15925
- const cancelPendingAutoScroll = React49.useCallback(() => {
17041
+ const cancelPendingAutoScroll = React51.useCallback(() => {
15926
17042
  if (autoScrollFrameRef.current !== null) {
15927
17043
  cancelAnimationFrame(autoScrollFrameRef.current);
15928
17044
  autoScrollFrameRef.current = null;
15929
17045
  }
15930
17046
  }, []);
15931
- const disableAutoFollow = React49.useCallback(() => {
17047
+ const disableAutoFollow = React51.useCallback(() => {
15932
17048
  forceFollowRef.current = false;
15933
17049
  shouldAutoScrollRef.current = false;
15934
17050
  cancelPendingAutoScroll();
15935
17051
  }, [cancelPendingAutoScroll]);
15936
- const enableAutoFollow = React49.useCallback(() => {
17052
+ const enableAutoFollow = React51.useCallback(() => {
15937
17053
  forceFollowRef.current = true;
15938
17054
  shouldAutoScrollRef.current = true;
15939
17055
  setHasUpdatesBelow(false);
15940
17056
  }, []);
15941
- const scrollToBottom = React49.useCallback(
17057
+ const scrollToBottom = React51.useCallback(
15942
17058
  (smooth = false, force = false) => {
15943
17059
  if (force) {
15944
17060
  enableAutoFollow();
@@ -15965,7 +17081,25 @@ function Chat({
15965
17081
  },
15966
17082
  [cancelPendingAutoScroll, enableAutoFollow]
15967
17083
  );
15968
- React49.useEffect(() => {
17084
+ const setMessageNavigationAnchor = React51.useCallback(
17085
+ (id, node) => {
17086
+ if (node) {
17087
+ messageNavigationAnchorsRef.current.set(id, node);
17088
+ return;
17089
+ }
17090
+ messageNavigationAnchorsRef.current.delete(id);
17091
+ },
17092
+ []
17093
+ );
17094
+ const getMessageNavigationAnchor = React51.useCallback(
17095
+ (item) => messageNavigationAnchorsRef.current.get(item.id) ?? null,
17096
+ []
17097
+ );
17098
+ const handleMessageNavigationNavigate = React51.useCallback(() => {
17099
+ disableAutoFollow();
17100
+ clearQuoteSelection();
17101
+ }, [clearQuoteSelection, disableAutoFollow]);
17102
+ React51.useEffect(() => {
15969
17103
  const viewport = viewportRef.current;
15970
17104
  if (!viewport) return;
15971
17105
  previousScrollTopRef.current = viewport.scrollTop;
@@ -16046,14 +17180,14 @@ function Chat({
16046
17180
  window.removeEventListener("pointercancel", stopPointerTracking);
16047
17181
  };
16048
17182
  }, [cancelPendingAutoScroll, disableAutoFollow]);
16049
- React49.useEffect(() => {
17183
+ React51.useEffect(() => {
16050
17184
  shouldAutoScrollRef.current = true;
16051
17185
  forceFollowRef.current = false;
16052
17186
  previousScrollTopRef.current = 0;
16053
17187
  setIsAtBottom(true);
16054
17188
  setHasUpdatesBelow(false);
16055
17189
  }, [stream.threadId]);
16056
- React49.useEffect(() => {
17190
+ React51.useEffect(() => {
16057
17191
  const messageCountChanged = messages.length !== previousMessageCountRef.current;
16058
17192
  previousMessageCountRef.current = messages.length;
16059
17193
  if (isPrependingHistoryMessagesRef.current) {
@@ -16066,46 +17200,16 @@ function Chat({
16066
17200
  }
16067
17201
  return;
16068
17202
  }
16069
- if (messageCountChanged || stream.isLoading) {
16070
- scrollToBottom();
16071
- }
16072
- }, [stream.isLoading, messages, scrollToBottom]);
16073
- const effectiveClientSecret = stream.apiKey?.trim() ? stream.apiKey : clientSecret;
16074
- const missingConfigKind = getMissingApiConfigurationKind({
16075
- apiUrl,
16076
- clientSecret: effectiveClientSecret
16077
- });
16078
- const missingConfig = Boolean(missingConfigKind);
16079
- const missingConfigShortMessage = React49.useMemo(() => {
16080
- switch (missingConfigKind) {
16081
- case "apiUrl":
16082
- return t("chat.missingApiUrlShort");
16083
- case "clientSecret":
16084
- return t("chat.missingClientSecretShort");
16085
- case "apiUrlAndClientSecret":
16086
- return t("chat.missingApiUrlAndClientSecretShort");
16087
- default:
16088
- return t("chat.missingConfigShort");
16089
- }
16090
- }, [missingConfigKind, t]);
16091
- const missingConfigDetailMessage = React49.useMemo(() => {
16092
- switch (missingConfigKind) {
16093
- case "apiUrl":
16094
- return t("chat.missingApiUrlDetail");
16095
- case "clientSecret":
16096
- return t("chat.missingClientSecretDetail");
16097
- case "apiUrlAndClientSecret":
16098
- return t("chat.missingApiUrlAndClientSecretDetail");
16099
- default:
16100
- return t("chat.missingConfigDetail");
16101
- }
16102
- }, [missingConfigKind, t]);
17203
+ if (messageCountChanged || stream.isLoading) {
17204
+ scrollToBottom();
17205
+ }
17206
+ }, [stream.isLoading, messages, scrollToBottom]);
16103
17207
  const showMissingConfig = !isClientSecretInitializing && missingConfig;
16104
17208
  const hasUploadingFiles = attachmentState.hasUploadingFiles;
16105
17209
  const isSubmissionBlocked = hasPendingInteractiveRequest || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
16106
17210
  const isSendDisabled = !trimmedDraft && !hasReferences || isSubmissionBlocked;
16107
17211
  const isPromptEditDisabled = hasPendingInteractiveRequest || missingConfig || isHistoryLoading;
16108
- const resizeComposerInput = React49.useCallback(() => {
17212
+ const resizeComposerInput = React51.useCallback(() => {
16109
17213
  const input = composerInputRef.current;
16110
17214
  if (!input) {
16111
17215
  return;
@@ -16113,7 +17217,7 @@ function Chat({
16113
17217
  input.style.maxHeight = `${COMPOSER_INPUT_MAX_HEIGHT}px`;
16114
17218
  input.style.overflowY = input.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
16115
17219
  }, []);
16116
- React49.useLayoutEffect(() => {
17220
+ React51.useLayoutEffect(() => {
16117
17221
  composerPartsRef.current = composerParts;
16118
17222
  resizeComposerInput();
16119
17223
  const caretOffset = pendingComposerCaretOffsetRef.current;
@@ -16125,13 +17229,13 @@ function Chat({
16125
17229
  }
16126
17230
  }
16127
17231
  }, [composerDomVersion, composerParts, resizeComposerInput]);
16128
- React49.useEffect(() => {
17232
+ React51.useEffect(() => {
16129
17233
  document.addEventListener("selectionchange", syncQuoteSelection);
16130
17234
  return () => {
16131
17235
  document.removeEventListener("selectionchange", syncQuoteSelection);
16132
17236
  };
16133
17237
  }, [syncQuoteSelection]);
16134
- React49.useEffect(() => {
17238
+ React51.useEffect(() => {
16135
17239
  const viewport = viewportRef.current;
16136
17240
  if (!viewport) {
16137
17241
  return;
@@ -16148,14 +17252,14 @@ function Chat({
16148
17252
  window.removeEventListener("resize", handleViewportScroll);
16149
17253
  };
16150
17254
  }, [clearQuoteSelection]);
16151
- React49.useEffect(() => {
17255
+ React51.useEffect(() => {
16152
17256
  clearQuoteSelection();
16153
17257
  }, [messages.length, stream.threadId, clearQuoteSelection]);
16154
- React49.useEffect(() => {
17258
+ React51.useEffect(() => {
16155
17259
  if (missingConfig) return;
16156
17260
  void refreshThreads();
16157
17261
  }, [missingConfig, refreshThreads]);
16158
- React49.useEffect(() => {
17262
+ React51.useEffect(() => {
16159
17263
  if (missingConfig || !stream.client || !stream.assistantId) {
16160
17264
  setAssistantName(null);
16161
17265
  setAssistantAvatar(null);
@@ -16178,106 +17282,10 @@ function Chat({
16178
17282
  cancelled = true;
16179
17283
  };
16180
17284
  }, [missingConfig, stream.client, stream.assistantId]);
16181
- React49.useEffect(() => {
16182
- if (missingConfig || !stream.client || !stream.assistantId) {
16183
- setRuntimeCapabilities(null);
16184
- setRuntimeCapabilitiesReady(false);
16185
- setSessionRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
16186
- setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
16187
- setRuntimeCapabilityPalette(null);
16188
- return;
16189
- }
16190
- const controller = new AbortController();
16191
- setRuntimeCapabilitiesReady(false);
16192
- setRuntimeCapabilities(null);
16193
- setRuntimeCapabilityPalette(null);
16194
- void stream.client.assistants.getRuntimeCapabilities(stream.assistantId, {
16195
- signal: controller.signal
16196
- }).then((payload) => {
16197
- setRuntimeCapabilities(payload);
16198
- setRuntimeCapabilitiesReady(true);
16199
- setSessionRuntimeCapabilities(
16200
- createDefaultRuntimeCapabilitiesSelection(payload)
16201
- );
16202
- setRunRuntimeCapabilities(
16203
- createEmptyRuntimeCapabilitiesSelection(payload)
16204
- );
16205
- }).catch((error) => {
16206
- if (controller.signal.aborted) {
16207
- return;
16208
- }
16209
- if (getHttpStatus(error) === 404) {
16210
- setRuntimeCapabilities(null);
16211
- setRuntimeCapabilitiesReady(false);
16212
- setSessionRuntimeCapabilities(
16213
- createEmptyRuntimeCapabilitiesSelection()
16214
- );
16215
- setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
16216
- return;
16217
- }
16218
- console.warn("[Chat] Failed to load runtime capabilities:", error);
16219
- setRuntimeCapabilities(null);
16220
- setRuntimeCapabilitiesReady(false);
16221
- setSessionRuntimeCapabilities(
16222
- createEmptyRuntimeCapabilitiesSelection()
16223
- );
16224
- setRunRuntimeCapabilities(createEmptyRuntimeCapabilitiesSelection());
16225
- });
16226
- return () => controller.abort();
16227
- }, [missingConfig, stream.client, stream.assistantId]);
16228
- React49.useEffect(() => {
16229
- setRunRuntimeCapabilities(
16230
- createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities)
16231
- );
16232
- if (!runtimeCapabilitiesReady || !runtimeCapabilities) {
16233
- setSessionRuntimeCapabilities(
16234
- createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities)
16235
- );
16236
- return;
16237
- }
16238
- const defaultSelection = createDefaultRuntimeCapabilitiesSelection(runtimeCapabilities);
16239
- const threadId = stream.threadId?.trim();
16240
- if (!threadId) {
16241
- setSessionRuntimeCapabilities(defaultSelection);
16242
- return;
16243
- }
16244
- let cancelled = false;
16245
- const requestId = runtimeCapabilityPreferenceLoadRef.current + 1;
16246
- runtimeCapabilityPreferenceLoadRef.current = requestId;
16247
- setSessionRuntimeCapabilities(defaultSelection);
16248
- void loadConversationRuntimeCapabilities({
16249
- client: stream.client,
16250
- threadId,
16251
- capabilities: runtimeCapabilities
16252
- }).then(({ selection, missing }) => {
16253
- if (cancelled || runtimeCapabilityPreferenceLoadRef.current !== requestId) {
16254
- return;
16255
- }
16256
- warnMissingRuntimeCapabilityReferences("loaded selection", missing);
16257
- setSessionRuntimeCapabilities(selection ?? defaultSelection);
16258
- }).catch((error) => {
16259
- if (cancelled || runtimeCapabilityPreferenceLoadRef.current !== requestId) {
16260
- return;
16261
- }
16262
- console.warn(
16263
- "[Chat] Failed to load persisted runtime capabilities selection:",
16264
- error
16265
- );
16266
- setSessionRuntimeCapabilities(defaultSelection);
16267
- });
16268
- return () => {
16269
- cancelled = true;
16270
- };
16271
- }, [
16272
- runtimeCapabilities,
16273
- runtimeCapabilitiesReady,
16274
- stream.client,
16275
- stream.threadId
16276
- ]);
16277
- React49.useEffect(() => {
17285
+ React51.useEffect(() => {
16278
17286
  setThreadGoal(stream.threadGoal);
16279
17287
  }, [stream.threadGoal]);
16280
- React49.useEffect(() => {
17288
+ React51.useEffect(() => {
16281
17289
  const threadId = stream.threadId?.trim();
16282
17290
  if (!threadId || !goalCommandAvailable) {
16283
17291
  setThreadGoal(null);
@@ -16318,37 +17326,7 @@ function Chat({
16318
17326
  return () => controller.abort();
16319
17327
  }, [goalAdapter, goalCommandAvailable, stream.threadId]);
16320
17328
  const uploadedFiles = attachmentState.uploadedFiles;
16321
- const handleSessionRuntimeCapabilityToggle = React49.useCallback(
16322
- (type, id, selected) => {
16323
- setSessionRuntimeCapabilities((previous) => {
16324
- const nextSelection = toggleRuntimeCapabilitySelection(
16325
- previous,
16326
- type,
16327
- id,
16328
- selected
16329
- );
16330
- const threadId = stream.threadId?.trim();
16331
- if (threadId) {
16332
- void persistSessionRuntimeCapabilities(threadId, nextSelection);
16333
- }
16334
- return nextSelection;
16335
- });
16336
- },
16337
- [persistSessionRuntimeCapabilities, stream.threadId]
16338
- );
16339
- const updateRuntimeCapabilityPalette = React49.useCallback(
16340
- (parts, selectionStart) => {
16341
- const input = composerInputRef.current;
16342
- const editingText = getComposerEditingText(parts);
16343
- const nextPalette = resolveRuntimeCapabilityPalette(
16344
- editingText,
16345
- typeof selectionStart === "number" ? selectionStart : input ? getComposerSelectionOffset(input) : getComposerEditingLength(parts)
16346
- );
16347
- setRuntimeCapabilityPalette(nextPalette);
16348
- },
16349
- []
16350
- );
16351
- const syncComposerInputFromElement = React49.useCallback(
17329
+ const syncComposerInputFromElement = React51.useCallback(
16352
17330
  (input) => {
16353
17331
  const previousCapabilities = getComposerCapabilityPartMap(
16354
17332
  composerPartsRef.current
@@ -16366,45 +17344,25 @@ function Chat({
16366
17344
  },
16367
17345
  [commitComposerParts, updateRuntimeCapabilityPalette]
16368
17346
  );
16369
- const handleComposerInput = React49.useCallback(
17347
+ const handleComposerInput = React51.useCallback(
16370
17348
  (event) => {
16371
17349
  syncComposerInputFromElement(event.currentTarget);
16372
17350
  },
16373
17351
  [syncComposerInputFromElement]
16374
17352
  );
16375
- const handleComposerCompositionEnd = React49.useCallback(
17353
+ const handleComposerCompositionEnd = React51.useCallback(
16376
17354
  (event) => {
16377
17355
  syncComposerInputFromElement(event.currentTarget);
16378
17356
  },
16379
17357
  [syncComposerInputFromElement]
16380
17358
  );
16381
- const handleComposerSelect = React49.useCallback(() => {
17359
+ const handleComposerSelect = React51.useCallback(() => {
16382
17360
  updateRuntimeCapabilityPalette(
16383
17361
  composerPartsRef.current,
16384
17362
  composerInputRef.current ? getComposerSelectionOffset(composerInputRef.current) : void 0
16385
17363
  );
16386
17364
  }, [updateRuntimeCapabilityPalette]);
16387
- const removeRunRuntimeCapability = React49.useCallback(
16388
- (option) => {
16389
- setRunRuntimeCapabilities(
16390
- (previous) => toggleRuntimeCapabilitySelection(
16391
- previous,
16392
- option.type,
16393
- option.id,
16394
- false
16395
- )
16396
- );
16397
- commitComposerParts(
16398
- removeComposerCapabilityTokens(composerPartsRef.current, option),
16399
- {
16400
- resetDom: true,
16401
- syncRemovedCapabilityTokens: false
16402
- }
16403
- );
16404
- },
16405
- [commitComposerParts]
16406
- );
16407
- const submitDraft = React49.useCallback(
17365
+ const submitDraft = React51.useCallback(
16408
17366
  (submitOptions = {}) => {
16409
17367
  if (isSubmissionBlocked) return;
16410
17368
  const contentToSubmit = (submitOptions.inputText ?? trimmedDraft).trim();
@@ -16419,22 +17377,10 @@ function Chat({
16419
17377
  if (!humanInput) {
16420
17378
  return;
16421
17379
  }
16422
- const recommendedRuntimeCapabilitiesForSubmit = submitOptions.runtimeCapabilities && runtimeCapabilities && runtimeCapabilitiesReady ? mergeRuntimeCapabilitiesSelections(
16423
- runtimeCapabilities,
16424
- runRuntimeCapabilities,
16425
- submitOptions.runtimeCapabilities
16426
- ) : runRuntimeCapabilities;
16427
- const runtimeCapabilitiesForSubmit = runtimeCapabilities && runtimeCapabilitiesReady ? createRuntimeCapabilitiesForSubmit({
16428
- capabilities: runtimeCapabilities,
16429
- available: effectiveSessionRuntimeCapabilities,
16430
- recommended: recommendedRuntimeCapabilitiesForSubmit
16431
- }) : null;
16432
- const runtimeCapabilityOptionsForMessage = getSelectedRuntimeCapabilityOptions(
16433
- getRecommendedRuntimeCapabilitiesSelection(
16434
- runtimeCapabilitiesForSubmit
16435
- ),
16436
- runtimeCapabilityOptions
16437
- );
17380
+ const {
17381
+ runtimeCapabilitiesForSubmit,
17382
+ runtimeCapabilityOptionsForMessage
17383
+ } = getRuntimeCapabilitiesForSubmit(submitOptions.runtimeCapabilities);
16438
17384
  const displayContent = submitOptions.displayText || contentToSubmit || (referencesToSend ? t("chat.referencedContentOnly") : "");
16439
17385
  const newMessage = {
16440
17386
  id: createMessageId(),
@@ -16502,21 +17448,16 @@ function Chat({
16502
17448
  }
16503
17449
  attachmentsRef.current?.clear();
16504
17450
  setReferences([]);
16505
- setRunRuntimeCapabilities(
16506
- createEmptyRuntimeCapabilitiesSelection(runtimeCapabilities)
16507
- );
16508
- setRuntimeCapabilityPalette(null);
17451
+ resetRunRuntimeCapabilities();
16509
17452
  },
16510
17453
  [
16511
17454
  effectiveSessionRuntimeCapabilities,
17455
+ getRuntimeCapabilitiesForSubmit,
16512
17456
  isSubmissionBlocked,
16513
17457
  options?.request,
16514
17458
  persistSessionRuntimeCapabilities,
16515
17459
  references,
16516
- runtimeCapabilities,
16517
- runtimeCapabilitiesReady,
16518
- runtimeCapabilityOptions,
16519
- runRuntimeCapabilities,
17460
+ resetRunRuntimeCapabilities,
16520
17461
  scrollToBottom,
16521
17462
  selectedTool,
16522
17463
  commitComposerParts,
@@ -16527,7 +17468,7 @@ function Chat({
16527
17468
  t
16528
17469
  ]
16529
17470
  );
16530
- const handleGoalCommand = React49.useCallback(
17471
+ const handleGoalCommand = React51.useCallback(
16531
17472
  async ({
16532
17473
  args,
16533
17474
  commandSource,
@@ -16572,11 +17513,7 @@ function Chat({
16572
17513
  }
16573
17514
  if (startsGoalRun) {
16574
17515
  const goalRunThreadId = result.threadId ?? threadId;
16575
- const runtimeCapabilitiesForGoalRun = runtimeCapabilities && runtimeCapabilitiesReady ? createRuntimeCapabilitiesForSubmit({
16576
- capabilities: runtimeCapabilities,
16577
- available: effectiveSessionRuntimeCapabilities,
16578
- recommended: commandRuntimeCapabilities
16579
- }) : commandRuntimeCapabilities ?? null;
17516
+ const runtimeCapabilitiesForGoalRun = getRuntimeCapabilitiesForCommand(commandRuntimeCapabilities);
16580
17517
  const inputPayload = {
16581
17518
  input: GOAL_RUN_INPUT,
16582
17519
  commandSource,
@@ -16629,66 +17566,17 @@ function Chat({
16629
17566
  }
16630
17567
  },
16631
17568
  [
16632
- effectiveSessionRuntimeCapabilities,
17569
+ getRuntimeCapabilitiesForCommand,
16633
17570
  goalAdapter,
16634
17571
  options?.request,
16635
17572
  refreshThreads,
16636
- runtimeCapabilities,
16637
- runtimeCapabilitiesReady,
16638
17573
  stream,
16639
17574
  t
16640
17575
  ]
16641
17576
  );
16642
- const handleGoalPanelOpenChange = React49.useCallback(
16643
- (open) => {
16644
- setIsGoalPanelOpen(open);
16645
- },
16646
- []
16647
- );
16648
- const addRunRuntimeCapabilities = React49.useCallback(
16649
- (selection) => {
16650
- setRunRuntimeCapabilities(
16651
- (previous) => runtimeCapabilities ? mergeRuntimeCapabilitiesSelections(
16652
- runtimeCapabilities,
16653
- previous,
16654
- selection
16655
- ) : previous
16656
- );
16657
- },
16658
- [runtimeCapabilities]
16659
- );
16660
- const insertComposerCapabilityToken = React49.useCallback(
16661
- (capability, range) => {
16662
- const token = createComposerCapabilityPart(capability, createMessageId());
16663
- const currentParts = composerPartsRef.current;
16664
- const replaceRange = range ?? {
16665
- start: getComposerEditingLength(currentParts),
16666
- end: getComposerEditingLength(currentParts)
16667
- };
16668
- const nextParts = replaceComposerRange(
16669
- currentParts,
16670
- replaceRange.start,
16671
- replaceRange.end,
16672
- [token]
16673
- );
16674
- commitComposerParts(nextParts, {
16675
- caretOffset: replaceRange.start + 1,
16676
- resetDom: true,
16677
- syncRemovedCapabilityTokens: true
16678
- });
16679
- setRunRuntimeCapabilities(
16680
- (previous) => toggleRuntimeCapabilitySelection(
16681
- previous,
16682
- capability.type,
16683
- capability.id,
16684
- true
16685
- )
16686
- );
16687
- setRuntimeCapabilityPalette(null);
16688
- focusComposerAt(replaceRange.start + 1);
16689
- },
16690
- [commitComposerParts, focusComposerAt]
16691
- );
17577
+ const handleGoalPanelOpenChange = React51.useCallback((open) => {
17578
+ setIsGoalPanelOpen(open);
17579
+ }, []);
16692
17580
  const {
16693
17581
  slashPaletteOptions,
16694
17582
  executeSlashCommandFromDraft,
@@ -16716,7 +17604,7 @@ function Chat({
16716
17604
  submitPrompt: submitDraft
16717
17605
  });
16718
17606
  const slashPaletteEmptyLabel = runtimeCapabilityPalette ? t(
16719
- getSlashPaletteEmptyLabelKey(
17607
+ getRuntimeCapabilityPaletteEmptyLabelKey(
16720
17608
  runtimeCapabilityPalette,
16721
17609
  runtimeCapabilitiesReady
16722
17610
  )
@@ -16730,7 +17618,7 @@ function Chat({
16730
17618
  plugin: t("composer.slashCommands.empty.loadingCapabilities"),
16731
17619
  subAgent: t("composer.slashCommands.empty.loadingCapabilities")
16732
17620
  };
16733
- React49.useEffect(() => {
17621
+ React51.useEffect(() => {
16734
17622
  if (!runtimeCapabilityPalette) {
16735
17623
  return;
16736
17624
  }
@@ -16749,7 +17637,7 @@ function Chat({
16749
17637
  );
16750
17638
  }
16751
17639
  }, [slashPaletteOptions.length, runtimeCapabilityPalette]);
16752
- React49.useLayoutEffect(() => {
17640
+ React51.useLayoutEffect(() => {
16753
17641
  if (!runtimeCapabilityPalette) {
16754
17642
  return;
16755
17643
  }
@@ -16766,7 +17654,7 @@ function Chat({
16766
17654
  container.scrollTop += optionRect.bottom - containerRect.bottom;
16767
17655
  }
16768
17656
  }, [runtimeCapabilityPalette, slashPaletteOptions.length]);
16769
- const submitGoalModeDraft = React49.useCallback(() => {
17657
+ const submitGoalModeDraft = React51.useCallback(() => {
16770
17658
  const objective = getComposerPlainText(composerPartsRef.current).trim();
16771
17659
  if (!isGoalModeOpen || !goalCommandAvailable || !objective) {
16772
17660
  return false;
@@ -16804,7 +17692,7 @@ function Chat({
16804
17692
  }
16805
17693
  submitDraft();
16806
17694
  };
16807
- const handleEditPendingFollowUp = React49.useCallback(
17695
+ const handleEditPendingFollowUp = React51.useCallback(
16808
17696
  (id) => {
16809
17697
  const item = pendingFollowUps.find(
16810
17698
  (entry) => entry.id === id && entry.mode === "queue"
@@ -16831,7 +17719,7 @@ function Chat({
16831
17719
  },
16832
17720
  [pendingFollowUps, setComposerText, stream]
16833
17721
  );
16834
- const handleQuoteSelection = React49.useCallback(() => {
17722
+ const handleQuoteSelection = React51.useCallback(() => {
16835
17723
  if (!quoteSelection) {
16836
17724
  return;
16837
17725
  }
@@ -16847,7 +17735,7 @@ function Chat({
16847
17735
  const handleAttachmentClick = () => {
16848
17736
  attachmentsRef.current?.openFilePicker();
16849
17737
  };
16850
- const uploadContextFile = React49.useCallback(
17738
+ const uploadContextFile = React51.useCallback(
16851
17739
  (file) => {
16852
17740
  const formData = new FormData();
16853
17741
  formData.append("file", file, file.name || "upload");
@@ -16866,13 +17754,13 @@ function Chat({
16866
17754
  },
16867
17755
  [stream.assistantId, stream.client, stream.threadId]
16868
17756
  );
16869
- const getContextFileStatus = React49.useCallback(
17757
+ const getContextFileStatus = React51.useCallback(
16870
17758
  (fileId) => stream.client.contexts.fetch(`/files/${fileId}/status`, {
16871
17759
  method: "GET"
16872
17760
  }),
16873
17761
  [stream.client]
16874
17762
  );
16875
- const deleteContextFile = React49.useCallback(
17763
+ const deleteContextFile = React51.useCallback(
16876
17764
  (storageFileId) => stream.client.contexts.deleteFile(storageFileId),
16877
17765
  [stream.client]
16878
17766
  );
@@ -16980,7 +17868,7 @@ function Chat({
16980
17868
  }
16981
17869
  submitDraft();
16982
17870
  };
16983
- const handleComposerPaste = React49.useCallback(
17871
+ const handleComposerPaste = React51.useCallback(
16984
17872
  (event) => {
16985
17873
  const clipboardData = event.clipboardData;
16986
17874
  if (!clipboardData) {
@@ -17082,13 +17970,13 @@ function Chat({
17082
17970
  const handleToolSelect = (tool) => {
17083
17971
  setSelectedTool((prev) => prev?.id === tool.id ? null : tool);
17084
17972
  };
17085
- const handlePromptClick = React49.useCallback(
17973
+ const handlePromptClick = React51.useCallback(
17086
17974
  (prompt) => {
17087
17975
  submitDraft({ inputText: prompt, displayText: prompt });
17088
17976
  },
17089
17977
  [submitDraft]
17090
17978
  );
17091
- const handlePromptEdit = React49.useCallback(
17979
+ const handlePromptEdit = React51.useCallback(
17092
17980
  (prompt) => {
17093
17981
  if (isPromptEditDisabled) return;
17094
17982
  setComposerText(prompt, prompt.length);
@@ -17097,7 +17985,7 @@ function Chat({
17097
17985
  },
17098
17986
  [focusComposerAt, isPromptEditDisabled, setComposerText]
17099
17987
  );
17100
- const loadConversationMessages = React49.useCallback(
17988
+ const loadConversationMessages = React51.useCallback(
17101
17989
  async (recordId) => {
17102
17990
  if (missingConfig) {
17103
17991
  setHistoryError(missingConfigShortMessage);
@@ -17118,7 +18006,7 @@ function Chat({
17118
18006
  },
17119
18007
  [missingConfig, missingConfigShortMessage, stream, t]
17120
18008
  );
17121
- const handleLoadMoreMessages = React49.useCallback(async () => {
18009
+ const handleLoadMoreMessages = React51.useCallback(async () => {
17122
18010
  if (!canLoadMoreMessages || isLoadingMoreMessages) {
17123
18011
  return;
17124
18012
  }
@@ -17227,15 +18115,15 @@ function Chat({
17227
18115
  };
17228
18116
  const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
17229
18117
  const canUploadDroppedFiles = composer?.attachments?.enabled === true && !missingConfig && !isHistoryLoading && !hasPendingInteractiveRequest;
17230
- const handleDroppedFiles = React49.useCallback((files) => {
18118
+ const handleDroppedFiles = React51.useCallback((files) => {
17231
18119
  return attachmentsRef.current?.queueFiles(files) ?? false;
17232
18120
  }, []);
17233
- const currentThread = React49.useMemo(
18121
+ const currentThread = React51.useMemo(
17234
18122
  () => threads.find((item) => item.id === stream.threadId),
17235
18123
  [threads, stream.threadId]
17236
18124
  );
17237
18125
  const streamErrorMessage = stream.error instanceof Error ? stream.error.message : void 0;
17238
- const threadErrorMessage = React49.useMemo(() => {
18126
+ const threadErrorMessage = React51.useMemo(() => {
17239
18127
  if (streamErrorMessage?.trim()) return streamErrorMessage.trim();
17240
18128
  if (currentThread?.status !== "error") return void 0;
17241
18129
  const message = currentThread.error?.trim();
@@ -17265,15 +18153,14 @@ function Chat({
17265
18153
  historyMessageLoadVersion: stream.historyMessageLoadVersion ?? 0,
17266
18154
  fallbackTitle: t("history.threadFallback")
17267
18155
  });
17268
- const assistantTitle = assistantName || resolvedTitle;
17269
18156
  const layoutMaxWidth = options?.layout?.maxWidth;
17270
- const chatColumnStyle = React49.useMemo(() => {
18157
+ const chatColumnStyle = React51.useMemo(() => {
17271
18158
  if (layoutMaxWidth === void 0 || layoutMaxWidth === null || layoutMaxWidth === "") {
17272
18159
  return void 0;
17273
18160
  }
17274
18161
  return { maxWidth: layoutMaxWidth };
17275
18162
  }, [layoutMaxWidth]);
17276
- return /* @__PURE__ */ jsxs37(
18163
+ return /* @__PURE__ */ jsxs39(
17277
18164
  UploadDroppedFiles,
17278
18165
  {
17279
18166
  ref: viewportRef,
@@ -17288,16 +18175,16 @@ function Chat({
17288
18175
  className
17289
18176
  ),
17290
18177
  children: [
17291
- /* @__PURE__ */ jsxs37(
18178
+ /* @__PURE__ */ jsxs39(
17292
18179
  "div",
17293
18180
  {
17294
18181
  "data-slot": "chatkit-chat-header",
17295
18182
  className: "mx-auto flex w-full items-center justify-between border-b p-2 sticky top-0 z-10 bg-background",
17296
18183
  style: chatColumnStyle,
17297
18184
  children: [
17298
- /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-3 overflow-hidden", children: [
17299
- /* @__PURE__ */ jsxs37("div", { className: "relative shrink-0", children: [
17300
- /* @__PURE__ */ jsx54(
18185
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-3 overflow-hidden", children: [
18186
+ /* @__PURE__ */ jsxs39("div", { className: "relative shrink-0", children: [
18187
+ /* @__PURE__ */ jsx56(
17301
18188
  ChatkitAvatar,
17302
18189
  {
17303
18190
  avatar: assistantAvatar,
@@ -17305,10 +18192,10 @@ function Chat({
17305
18192
  label: assistantTitle
17306
18193
  }
17307
18194
  ),
17308
- /* @__PURE__ */ jsx54("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
18195
+ /* @__PURE__ */ jsx56("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
17309
18196
  ] }),
17310
- /* @__PURE__ */ jsxs37("div", { className: "truncate", children: [
17311
- /* @__PURE__ */ jsx54(
18197
+ /* @__PURE__ */ jsxs39("div", { className: "truncate", children: [
18198
+ /* @__PURE__ */ jsx56(
17312
18199
  "h2",
17313
18200
  {
17314
18201
  className: "text-lg font-semibold truncate",
@@ -17316,12 +18203,12 @@ function Chat({
17316
18203
  children: assistantTitle
17317
18204
  }
17318
18205
  ),
17319
- /* @__PURE__ */ jsx54("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
18206
+ /* @__PURE__ */ jsx56("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
17320
18207
  ] })
17321
18208
  ] }),
17322
- /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-1", children: [
17323
- canMinimizeToPet && /* @__PURE__ */ jsxs37(Tooltip, { children: [
17324
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx54(
18209
+ /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-1", children: [
18210
+ canMinimizeToPet && /* @__PURE__ */ jsxs39(Tooltip, { children: [
18211
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx56(
17325
18212
  "button",
17326
18213
  {
17327
18214
  type: "button",
@@ -17332,13 +18219,13 @@ function Chat({
17332
18219
  "transition-colors duration-150"
17333
18220
  ),
17334
18221
  "aria-label": t("chat.minimizeToPet"),
17335
- children: /* @__PURE__ */ jsx54(Minus, { size: 16 })
18222
+ children: /* @__PURE__ */ jsx56(Minus, { size: 16 })
17336
18223
  }
17337
18224
  ) }) }),
17338
- /* @__PURE__ */ jsx54(TooltipContent, { side: "bottom", children: t("chat.minimizeToPet") })
18225
+ /* @__PURE__ */ jsx56(TooltipContent, { side: "bottom", children: t("chat.minimizeToPet") })
17339
18226
  ] }),
17340
- /* @__PURE__ */ jsxs37(Tooltip, { children: [
17341
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx54(
18227
+ /* @__PURE__ */ jsxs39(Tooltip, { children: [
18228
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx56(
17342
18229
  "button",
17343
18230
  {
17344
18231
  type: "button",
@@ -17349,14 +18236,14 @@ function Chat({
17349
18236
  "transition-colors duration-150"
17350
18237
  ),
17351
18238
  "aria-label": t("settings.open"),
17352
- children: /* @__PURE__ */ jsx54(Settings2, { size: 16 })
18239
+ children: /* @__PURE__ */ jsx56(Settings2, { size: 16 })
17353
18240
  }
17354
18241
  ) }) }),
17355
- /* @__PURE__ */ jsx54(TooltipContent, { side: "bottom", children: t("settings.open") })
18242
+ /* @__PURE__ */ jsx56(TooltipContent, { side: "bottom", children: t("settings.open") })
17356
18243
  ] }),
17357
- history?.enabled !== false && /* @__PURE__ */ jsxs37(Fragment9, { children: [
17358
- /* @__PURE__ */ jsxs37(Tooltip, { children: [
17359
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx54(
18244
+ history?.enabled !== false && /* @__PURE__ */ jsxs39(Fragment9, { children: [
18245
+ /* @__PURE__ */ jsxs39(Tooltip, { children: [
18246
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56("span", { className: "inline-flex h-8 w-8", children: /* @__PURE__ */ jsx56(
17360
18247
  "button",
17361
18248
  {
17362
18249
  type: "button",
@@ -17369,12 +18256,12 @@ function Chat({
17369
18256
  "disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed"
17370
18257
  ),
17371
18258
  "aria-label": t("history.newThread"),
17372
- children: /* @__PURE__ */ jsx54(Pencil4, { size: 16 })
18259
+ children: /* @__PURE__ */ jsx56(Pencil4, { size: 16 })
17373
18260
  }
17374
18261
  ) }) }),
17375
- /* @__PURE__ */ jsx54(TooltipContent, { side: "bottom", children: t("history.newThread") })
18262
+ /* @__PURE__ */ jsx56(TooltipContent, { side: "bottom", children: t("history.newThread") })
17376
18263
  ] }),
17377
- /* @__PURE__ */ jsx54(
18264
+ /* @__PURE__ */ jsx56(
17378
18265
  HistorySidebar,
17379
18266
  {
17380
18267
  threads,
@@ -17391,18 +18278,29 @@ function Chat({
17391
18278
  ]
17392
18279
  }
17393
18280
  ),
17394
- /* @__PURE__ */ jsxs37(
18281
+ showMessageNavigation && /* @__PURE__ */ jsx56(
18282
+ MessageNavigator,
18283
+ {
18284
+ items: messageNavigationItems,
18285
+ viewportRef,
18286
+ getAnchor: getMessageNavigationAnchor,
18287
+ onNavigate: handleMessageNavigationNavigate,
18288
+ label: t("message.navigation.label"),
18289
+ tagsOverflowLabel: (count) => t("message.navigation.moreTags", { count })
18290
+ }
18291
+ ),
18292
+ /* @__PURE__ */ jsxs39(
17395
18293
  "div",
17396
18294
  {
17397
18295
  "data-slot": "chatkit-chat-content",
17398
18296
  className: "mx-auto w-full flex-1 p-4",
17399
18297
  style: chatColumnStyle,
17400
18298
  children: [
17401
- errorMessage && /* @__PURE__ */ jsx54("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
17402
- historyError && /* @__PURE__ */ jsx54("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
17403
- showMissingConfig && /* @__PURE__ */ jsx54("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
17404
- isHistoryLoading && /* @__PURE__ */ jsx54("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
17405
- messages.length === 0 && !canLoadMoreMessages ? /* @__PURE__ */ jsx54(
18299
+ errorMessage && /* @__PURE__ */ jsx56("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
18300
+ historyError && /* @__PURE__ */ jsx56("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
18301
+ showMissingConfig && /* @__PURE__ */ jsx56("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
18302
+ isHistoryLoading && /* @__PURE__ */ jsx56("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
18303
+ messages.length === 0 && !canLoadMoreMessages ? /* @__PURE__ */ jsx56(
17406
18304
  StartScreen,
17407
18305
  {
17408
18306
  startScreen,
@@ -17411,10 +18309,10 @@ function Chat({
17411
18309
  promptSendDisabled: isSubmissionBlocked,
17412
18310
  promptEditDisabled: isPromptEditDisabled
17413
18311
  }
17414
- ) : /* @__PURE__ */ jsxs37("div", { className: "space-y-4", children: [
17415
- canLoadMoreMessages && /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-3 py-1", children: [
17416
- /* @__PURE__ */ jsx54("div", { className: "h-px min-w-8 flex-1 bg-border" }),
17417
- /* @__PURE__ */ jsx54(
18312
+ ) : /* @__PURE__ */ jsxs39("div", { className: "space-y-4", children: [
18313
+ canLoadMoreMessages && /* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-3 py-1", children: [
18314
+ /* @__PURE__ */ jsx56("div", { className: "h-px min-w-8 flex-1 bg-border" }),
18315
+ /* @__PURE__ */ jsx56(
17418
18316
  Button,
17419
18317
  {
17420
18318
  type: "button",
@@ -17426,7 +18324,7 @@ function Chat({
17426
18324
  children: isLoadingMoreMessages ? t("chat.loadingMoreMessages") : t("chat.loadMoreMessages")
17427
18325
  }
17428
18326
  ),
17429
- /* @__PURE__ */ jsx54("div", { className: "h-px min-w-8 flex-1 bg-border" })
18327
+ /* @__PURE__ */ jsx56("div", { className: "h-px min-w-8 flex-1 bg-border" })
17430
18328
  ] }),
17431
18329
  messages.map((message, index) => {
17432
18330
  const messageType = String(message.type);
@@ -17451,7 +18349,7 @@ function Chat({
17451
18349
  ...humanMessage.fileAssets ?? [],
17452
18350
  ...humanMessage.attachments ?? []
17453
18351
  ];
17454
- const humanRuntimeCapabilityOptions = message.type === "human" ? humanMessage.runtimeCapabilityOptions ?? getSelectedRuntimeCapabilityOptions(
18352
+ const humanRuntimeCapabilityOptions = message.type === "human" ? humanMessage.runtimeCapabilityOptions ?? getRuntimeCapabilityOptionsForSelection(
17455
18353
  getRecommendedRuntimeCapabilitiesSelection(
17456
18354
  humanMessage.runtimeCapabilities
17457
18355
  ),
@@ -17460,18 +18358,24 @@ function Chat({
17460
18358
  const hasHumanAttachments = message.type === "human" && humanAttachments.length > 0;
17461
18359
  const canQuoteMessage = message.type === "human" || isAssistantMessage;
17462
18360
  const quoteSource = message.type === "human" ? t("chat.youLabel") : assistantTitle;
18361
+ const messageNavigationId = getMessageNavigationItemId(
18362
+ message,
18363
+ index
18364
+ );
17463
18365
  if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanRuntimeCapabilityOptions.length === 0 && humanReferences.length === 0) {
17464
18366
  return null;
17465
18367
  }
17466
- return /* @__PURE__ */ jsx54(
18368
+ return /* @__PURE__ */ jsx56(
17467
18369
  "div",
17468
18370
  {
18371
+ ref: (node) => setMessageNavigationAnchor(messageNavigationId, node),
18372
+ "data-message-navigation-id": messageNavigationId,
17469
18373
  className: cn(
17470
18374
  "group flex gap-3",
17471
18375
  message.type === "human" ? "justify-end" : "justify-start -ml-1"
17472
18376
  // AI messages: slightly closer to left
17473
18377
  ),
17474
- children: /* @__PURE__ */ jsxs37(
18378
+ children: /* @__PURE__ */ jsxs39(
17475
18379
  "div",
17476
18380
  {
17477
18381
  className: cn(
@@ -17479,7 +18383,7 @@ function Chat({
17479
18383
  isAssistantMessage && "min-w-0 flex-1"
17480
18384
  ),
17481
18385
  children: [
17482
- /* @__PURE__ */ jsx54(
18386
+ /* @__PURE__ */ jsx56(
17483
18387
  "div",
17484
18388
  {
17485
18389
  ...canQuoteMessage ? {
@@ -17491,7 +18395,7 @@ function Chat({
17491
18395
  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"
17492
18396
  // AI messages: use chat-specific foreground color
17493
18397
  ),
17494
- children: isAssistantMessage ? /* @__PURE__ */ jsx54(
18398
+ children: isAssistantMessage ? /* @__PURE__ */ jsx56(
17495
18399
  AssistantMessage,
17496
18400
  {
17497
18401
  message: {
@@ -17510,25 +18414,14 @@ function Chat({
17510
18414
  organizationId: stream.organizationId,
17511
18415
  apiUrl: stream.apiUrl
17512
18416
  }
17513
- ) : /* @__PURE__ */ jsxs37(Fragment9, { children: [
17514
- message.type === "human" && humanRuntimeCapabilityOptions.length > 0 && /* @__PURE__ */ jsx54("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanRuntimeCapabilityOptions.map((option) => /* @__PURE__ */ jsxs37(
17515
- "span",
18417
+ ) : /* @__PURE__ */ jsxs39(Fragment9, { children: [
18418
+ message.type === "human" && humanRuntimeCapabilityOptions.length > 0 && /* @__PURE__ */ jsx56(
18419
+ HumanRuntimeCapabilityChips,
17516
18420
  {
17517
- className: "inline-flex max-w-full items-center gap-1 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs font-medium text-primary-foreground",
17518
- children: [
17519
- /* @__PURE__ */ jsx54(
17520
- RuntimeCapabilityIcon,
17521
- {
17522
- option,
17523
- variant: "chip"
17524
- }
17525
- ),
17526
- /* @__PURE__ */ jsx54("span", { className: "max-w-[9rem] truncate", children: option.label })
17527
- ]
17528
- },
17529
- `${option.type}:${option.id}`
17530
- )) }),
17531
- message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx54("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx54(
18421
+ options: humanRuntimeCapabilityOptions
18422
+ }
18423
+ ),
18424
+ message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx56("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx56(
17532
18425
  ReferenceChip,
17533
18426
  {
17534
18427
  reference,
@@ -17536,29 +18429,29 @@ function Chat({
17536
18429
  },
17537
18430
  getReferenceKey(reference)
17538
18431
  )) }),
17539
- message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx54("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs37(
18432
+ message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx56("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs39(
17540
18433
  "div",
17541
18434
  {
17542
18435
  className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
17543
18436
  children: [
17544
- /* @__PURE__ */ jsx54(FileText5, { size: 12 }),
17545
- /* @__PURE__ */ jsx54("span", { className: "max-w-[100px] truncate", children: file.originalName ?? file.id })
18437
+ /* @__PURE__ */ jsx56(FileText5, { size: 12 }),
18438
+ /* @__PURE__ */ jsx56("span", { className: "max-w-[100px] truncate", children: file.originalName ?? file.id })
17546
18439
  ]
17547
18440
  },
17548
18441
  fileIndex
17549
18442
  )) }),
17550
- Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx54(
18443
+ Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx56(
17551
18444
  "p",
17552
18445
  {
17553
18446
  className: "wrap-break-word text-sm leading-relaxed",
17554
18447
  children: formatMessageContent(part)
17555
18448
  },
17556
18449
  `${part.type}-${partIndex}`
17557
- )) : /* @__PURE__ */ jsx54("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
18450
+ )) : /* @__PURE__ */ jsx56("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
17558
18451
  ] })
17559
18452
  }
17560
18453
  ),
17561
- /* @__PURE__ */ jsx54(
18454
+ /* @__PURE__ */ jsx56(
17562
18455
  MessageActions,
17563
18456
  {
17564
18457
  content: messageContent,
@@ -17596,7 +18489,7 @@ function Chat({
17596
18489
  stream.isLoading,
17597
18490
  { now: streamingNow }
17598
18491
  );
17599
- return /* @__PURE__ */ jsx54("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx54("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx54(
18492
+ return /* @__PURE__ */ jsx56("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx56("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx56(
17600
18493
  AssistantStreamingIndicator,
17601
18494
  {
17602
18495
  status: fallbackStreamingStatus ?? "loading"
@@ -17607,7 +18500,7 @@ function Chat({
17607
18500
  ]
17608
18501
  }
17609
18502
  ),
17610
- !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx54("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx54(
18503
+ !isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx56("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx56(
17611
18504
  Button,
17612
18505
  {
17613
18506
  type: "button",
@@ -17620,10 +18513,10 @@ function Chat({
17620
18513
  onClick: () => scrollToBottom(true, true),
17621
18514
  "aria-label": t("chat.scrollToBottom"),
17622
18515
  title: t("chat.scrollToBottom"),
17623
- children: /* @__PURE__ */ jsx54(ArrowDown2, { size: 16 })
18516
+ children: /* @__PURE__ */ jsx56(ArrowDown2, { size: 16 })
17624
18517
  }
17625
18518
  ) }),
17626
- quoteSelection && /* @__PURE__ */ jsx54(
18519
+ quoteSelection && /* @__PURE__ */ jsx56(
17627
18520
  "div",
17628
18521
  {
17629
18522
  className: "pointer-events-none fixed z-50",
@@ -17632,7 +18525,7 @@ function Chat({
17632
18525
  left: `${quoteSelection.left}px`,
17633
18526
  transform: "translateX(-50%)"
17634
18527
  },
17635
- children: /* @__PURE__ */ jsxs37(
18528
+ children: /* @__PURE__ */ jsxs39(
17636
18529
  Button,
17637
18530
  {
17638
18531
  type: "button",
@@ -17644,22 +18537,22 @@ function Chat({
17644
18537
  "aria-label": t("composer.quoteSelection"),
17645
18538
  title: t("composer.quoteSelection"),
17646
18539
  children: [
17647
- /* @__PURE__ */ jsx54(Quote, { size: 14 }),
18540
+ /* @__PURE__ */ jsx56(Quote, { size: 14 }),
17648
18541
  t("composer.quoteSelection")
17649
18542
  ]
17650
18543
  }
17651
18544
  )
17652
18545
  }
17653
18546
  ),
17654
- /* @__PURE__ */ jsxs37(
18547
+ /* @__PURE__ */ jsxs39(
17655
18548
  "div",
17656
18549
  {
17657
18550
  "data-slot": "chatkit-chat-composer",
17658
18551
  className: "mx-auto w-full p-2 sticky bottom-0 z-10 bg-background",
17659
18552
  style: chatColumnStyle,
17660
18553
  children: [
17661
- threadErrorMessage && /* @__PURE__ */ jsx54("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 }),
17662
- /* @__PURE__ */ jsx54(
18554
+ threadErrorMessage && /* @__PURE__ */ jsx56("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 }),
18555
+ /* @__PURE__ */ jsx56(
17663
18556
  ChatAttachments,
17664
18557
  {
17665
18558
  ref: attachmentsRef,
@@ -17673,7 +18566,7 @@ function Chat({
17673
18566
  onStateChange: setAttachmentState
17674
18567
  }
17675
18568
  ),
17676
- references.length > 0 && /* @__PURE__ */ jsx54("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx54(
18569
+ references.length > 0 && /* @__PURE__ */ jsx56("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx56(
17677
18570
  ReferenceChip,
17678
18571
  {
17679
18572
  reference,
@@ -17687,32 +18580,16 @@ function Chat({
17687
18580
  },
17688
18581
  getReferenceKey(reference)
17689
18582
  )) }),
17690
- detachedRunRuntimeCapabilityOptions.length > 0 && /* @__PURE__ */ jsxs37("div", { className: "mb-2 flex flex-wrap items-center gap-2", children: [
17691
- /* @__PURE__ */ jsx54("span", { className: "text-xs text-muted-foreground", children: t("composer.capabilities.runOnly") }),
17692
- detachedRunRuntimeCapabilityOptions.map((option) => /* @__PURE__ */ jsxs37(
17693
- "span",
17694
- {
17695
- className: "inline-flex max-w-full items-center gap-1 rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary",
17696
- children: [
17697
- /* @__PURE__ */ jsx54(RuntimeCapabilityIcon, { option, variant: "chip" }),
17698
- /* @__PURE__ */ jsx54("span", { className: "max-w-40 truncate", children: option.label }),
17699
- /* @__PURE__ */ jsx54(
17700
- "button",
17701
- {
17702
- type: "button",
17703
- onClick: () => removeRunRuntimeCapability(option),
17704
- className: "rounded-full p-0.5 hover:bg-primary/15",
17705
- title: t("composer.capabilities.removeRunCapability"),
17706
- "aria-label": t("composer.capabilities.removeRunCapability"),
17707
- children: /* @__PURE__ */ jsx54(X6, { size: 11 })
17708
- }
17709
- )
17710
- ]
17711
- },
17712
- `${option.type}:${option.id}`
17713
- ))
17714
- ] }),
17715
- showGoalStatus && /* @__PURE__ */ jsxs37(
18583
+ /* @__PURE__ */ jsx56(
18584
+ DetachedRunRuntimeCapabilities,
18585
+ {
18586
+ options: detachedRunRuntimeCapabilityOptions,
18587
+ runOnlyLabel: t("composer.capabilities.runOnly"),
18588
+ removeLabel: t("composer.capabilities.removeRunCapability"),
18589
+ onRemove: removeRunRuntimeCapability
18590
+ }
18591
+ ),
18592
+ showGoalStatus && /* @__PURE__ */ jsxs39(
17716
18593
  "div",
17717
18594
  {
17718
18595
  className: cn(
@@ -17720,7 +18597,7 @@ function Chat({
17720
18597
  isGoalObjectiveExpanded ? "items-start" : "items-center"
17721
18598
  ),
17722
18599
  children: [
17723
- /* @__PURE__ */ jsx54(
18600
+ /* @__PURE__ */ jsx56(
17724
18601
  Target2,
17725
18602
  {
17726
18603
  className: cn(
@@ -17729,13 +18606,13 @@ function Chat({
17729
18606
  )
17730
18607
  }
17731
18608
  ),
17732
- /* @__PURE__ */ jsxs37("div", { className: "min-w-0 flex-1", children: [
17733
- /* @__PURE__ */ jsxs37("div", { className: "flex min-w-0 items-center gap-2", children: [
17734
- /* @__PURE__ */ jsx54("span", { className: "font-medium", children: t("chat.goal.label") }),
17735
- threadGoal && /* @__PURE__ */ jsx54("span", { className: "shrink-0 rounded-md bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: t(`chat.goal.status.${threadGoal.status}`) }),
17736
- isGoalLoading && /* @__PURE__ */ jsx54(Loader29, { className: "size-3 animate-spin text-muted-foreground" })
18609
+ /* @__PURE__ */ jsxs39("div", { className: "min-w-0 flex-1", children: [
18610
+ /* @__PURE__ */ jsxs39("div", { className: "flex min-w-0 items-center gap-2", children: [
18611
+ /* @__PURE__ */ jsx56("span", { className: "font-medium", children: t("chat.goal.label") }),
18612
+ threadGoal && /* @__PURE__ */ jsx56("span", { className: "shrink-0 rounded-md bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground", children: t(`chat.goal.status.${threadGoal.status}`) }),
18613
+ isGoalLoading && /* @__PURE__ */ jsx56(Loader29, { className: "size-3 animate-spin text-muted-foreground" })
17737
18614
  ] }),
17738
- /* @__PURE__ */ jsx54(
18615
+ /* @__PURE__ */ jsx56(
17739
18616
  "div",
17740
18617
  {
17741
18618
  className: cn(
@@ -17745,13 +18622,13 @@ function Chat({
17745
18622
  children: goalError || threadGoal?.objective
17746
18623
  }
17747
18624
  ),
17748
- threadGoal && /* @__PURE__ */ jsx54("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: /* @__PURE__ */ jsx54("span", { children: t("chat.goal.elapsed", {
18625
+ threadGoal && /* @__PURE__ */ jsx56("div", { className: "mt-1 flex flex-wrap gap-x-3 gap-y-1 text-[11px] text-muted-foreground", children: /* @__PURE__ */ jsx56("span", { children: t("chat.goal.elapsed", {
17749
18626
  elapsed: formatGoalElapsed(displayedGoalElapsedSeconds)
17750
18627
  }) }) })
17751
18628
  ] }),
17752
- threadGoal && /* @__PURE__ */ jsxs37("div", { className: "flex shrink-0 items-center gap-1", children: [
17753
- /* @__PURE__ */ jsxs37(Tooltip, { children: [
17754
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54(
18629
+ threadGoal && /* @__PURE__ */ jsxs39("div", { className: "flex shrink-0 items-center gap-1", children: [
18630
+ /* @__PURE__ */ jsxs39(Tooltip, { children: [
18631
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56(
17755
18632
  Button,
17756
18633
  {
17757
18634
  type: "button",
@@ -17762,13 +18639,13 @@ function Chat({
17762
18639
  const prefix = "/goal edit ";
17763
18640
  setComposerText(`${prefix}${threadGoal.objective}`);
17764
18641
  },
17765
- children: /* @__PURE__ */ jsx54(Pencil4, { className: "size-3" })
18642
+ children: /* @__PURE__ */ jsx56(Pencil4, { className: "size-3" })
17766
18643
  }
17767
18644
  ) }),
17768
- /* @__PURE__ */ jsx54(TooltipContent, { children: t("chat.goal.edit") })
18645
+ /* @__PURE__ */ jsx56(TooltipContent, { children: t("chat.goal.edit") })
17769
18646
  ] }),
17770
- /* @__PURE__ */ jsxs37(Tooltip, { children: [
17771
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54(
18647
+ /* @__PURE__ */ jsxs39(Tooltip, { children: [
18648
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56(
17772
18649
  Button,
17773
18650
  {
17774
18651
  type: "button",
@@ -17784,13 +18661,13 @@ function Chat({
17784
18661
  executionType: "insert_invocation"
17785
18662
  }
17786
18663
  }),
17787
- children: threadGoal.status === "paused" ? /* @__PURE__ */ jsx54(Play, { className: "size-3" }) : /* @__PURE__ */ jsx54(Pause, { className: "size-3" })
18664
+ children: threadGoal.status === "paused" ? /* @__PURE__ */ jsx56(Play, { className: "size-3" }) : /* @__PURE__ */ jsx56(Pause, { className: "size-3" })
17788
18665
  }
17789
18666
  ) }),
17790
- /* @__PURE__ */ jsx54(TooltipContent, { children: threadGoal.status === "paused" ? t("chat.goal.resume") : t("chat.goal.pause") })
18667
+ /* @__PURE__ */ jsx56(TooltipContent, { children: threadGoal.status === "paused" ? t("chat.goal.resume") : t("chat.goal.pause") })
17791
18668
  ] }),
17792
- /* @__PURE__ */ jsxs37(Tooltip, { children: [
17793
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54(
18669
+ /* @__PURE__ */ jsxs39(Tooltip, { children: [
18670
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56(
17794
18671
  Button,
17795
18672
  {
17796
18673
  type: "button",
@@ -17806,13 +18683,13 @@ function Chat({
17806
18683
  executionType: "insert_invocation"
17807
18684
  }
17808
18685
  }),
17809
- children: /* @__PURE__ */ jsx54(Trash23, { className: "size-3" })
18686
+ children: /* @__PURE__ */ jsx56(Trash23, { className: "size-3" })
17810
18687
  }
17811
18688
  ) }),
17812
- /* @__PURE__ */ jsx54(TooltipContent, { children: t("chat.goal.clear") })
18689
+ /* @__PURE__ */ jsx56(TooltipContent, { children: t("chat.goal.clear") })
17813
18690
  ] }),
17814
- threadGoal.objective && !goalError && /* @__PURE__ */ jsxs37(Tooltip, { children: [
17815
- /* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54(
18691
+ threadGoal.objective && !goalError && /* @__PURE__ */ jsxs39(Tooltip, { children: [
18692
+ /* @__PURE__ */ jsx56(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx56(
17816
18693
  Button,
17817
18694
  {
17818
18695
  type: "button",
@@ -17821,7 +18698,7 @@ function Chat({
17821
18698
  "aria-expanded": isGoalObjectiveExpanded,
17822
18699
  "aria-label": isGoalObjectiveExpanded ? t("chat.goal.collapseObjective") : t("chat.goal.expandObjective"),
17823
18700
  onClick: () => setIsGoalObjectiveExpanded((expanded) => !expanded),
17824
- children: /* @__PURE__ */ jsx54(
18701
+ children: /* @__PURE__ */ jsx56(
17825
18702
  ChevronDown5,
17826
18703
  {
17827
18704
  className: cn(
@@ -17832,13 +18709,13 @@ function Chat({
17832
18709
  )
17833
18710
  }
17834
18711
  ) }),
17835
- /* @__PURE__ */ jsx54(TooltipContent, { children: isGoalObjectiveExpanded ? t("chat.goal.collapseObjective") : t("chat.goal.expandObjective") })
18712
+ /* @__PURE__ */ jsx56(TooltipContent, { children: isGoalObjectiveExpanded ? t("chat.goal.collapseObjective") : t("chat.goal.expandObjective") })
17836
18713
  ] })
17837
18714
  ] })
17838
18715
  ]
17839
18716
  }
17840
18717
  ),
17841
- /* @__PURE__ */ jsx54(
18718
+ /* @__PURE__ */ jsx56(
17842
18719
  PendingRuntimeServices,
17843
18720
  {
17844
18721
  state: stream.runtimeActivities.sandboxServices,
@@ -17847,7 +18724,7 @@ function Chat({
17847
18724
  className: hasPendingTodos || hasPendingFollowUps ? "mb-2" : void 0
17848
18725
  }
17849
18726
  ),
17850
- /* @__PURE__ */ jsx54(
18727
+ /* @__PURE__ */ jsx56(
17851
18728
  PendingTodos,
17852
18729
  {
17853
18730
  snapshot: stream.todos,
@@ -17855,7 +18732,7 @@ function Chat({
17855
18732
  className: hasPendingFollowUps ? "mb-2" : void 0
17856
18733
  }
17857
18734
  ),
17858
- /* @__PURE__ */ jsx54(
18735
+ /* @__PURE__ */ jsx56(
17859
18736
  PendingFollowUps,
17860
18737
  {
17861
18738
  items: pendingFollowUps,
@@ -17868,7 +18745,7 @@ function Chat({
17868
18745
  attachToComposer: true
17869
18746
  }
17870
18747
  ),
17871
- /* @__PURE__ */ jsx54(
18748
+ /* @__PURE__ */ jsx56(
17872
18749
  RequestUserInputPanel,
17873
18750
  {
17874
18751
  request: stream.pendingRequestUserInput,
@@ -17877,7 +18754,7 @@ function Chat({
17877
18754
  attachToComposer: true
17878
18755
  }
17879
18756
  ),
17880
- /* @__PURE__ */ jsx54(
18757
+ /* @__PURE__ */ jsx56(
17881
18758
  HITLApprovalPanel,
17882
18759
  {
17883
18760
  request: stream.pendingHITLRequest,
@@ -17886,7 +18763,7 @@ function Chat({
17886
18763
  attachToComposer: true
17887
18764
  }
17888
18765
  ),
17889
- runtimeCapabilityPalette && /* @__PURE__ */ jsx54(
18766
+ runtimeCapabilityPalette && /* @__PURE__ */ jsx56(
17890
18767
  SlashPalette,
17891
18768
  {
17892
18769
  palette: runtimeCapabilityPalette,
@@ -17900,7 +18777,7 @@ function Chat({
17900
18777
  onSelect: selectSlashPaletteOption
17901
18778
  }
17902
18779
  ),
17903
- /* @__PURE__ */ jsx54("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs37(
18780
+ /* @__PURE__ */ jsx56("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs39(
17904
18781
  "div",
17905
18782
  {
17906
18783
  "data-slot": "composer-input-shell",
@@ -17914,7 +18791,7 @@ function Chat({
17914
18791
  composerInputRoundedClass
17915
18792
  ),
17916
18793
  children: [
17917
- /* @__PURE__ */ jsx54(
18794
+ /* @__PURE__ */ jsx56(
17918
18795
  "div",
17919
18796
  {
17920
18797
  ref: composerInputRef,
@@ -17936,39 +18813,19 @@ function Chat({
17936
18813
  (missingConfig || isHistoryLoading || hasPendingInteractiveRequest) && "cursor-not-allowed opacity-50"
17937
18814
  ),
17938
18815
  children: renderedComposerParts.map(
17939
- (part, index) => part.type === "text" ? /* @__PURE__ */ jsx54(React49.Fragment, { children: part.text }, `text-${index}`) : /* @__PURE__ */ jsxs37(
17940
- "span",
17941
- {
17942
- "data-composer-capability-key": part.key,
17943
- "data-capability-type": part.capability.type,
17944
- "data-capability-id": part.capability.id,
17945
- contentEditable: false,
17946
- className: "mx-0.5 inline-flex max-w-[14rem] select-none items-center gap-1 text-sm font-semibold text-primary align-baseline",
17947
- children: [
17948
- /* @__PURE__ */ jsx54(
17949
- RuntimeCapabilityIcon,
17950
- {
17951
- option: part.capability,
17952
- variant: "chip"
17953
- }
17954
- ),
17955
- /* @__PURE__ */ jsx54("span", { className: "truncate", children: part.capability.label })
17956
- ]
17957
- },
17958
- part.key
17959
- )
18816
+ (part, index) => part.type === "text" ? /* @__PURE__ */ jsx56(React51.Fragment, { children: part.text }, `text-${index}`) : /* @__PURE__ */ jsx56(ComposerCapabilityToken, { part }, part.key)
17960
18817
  )
17961
18818
  },
17962
18819
  composerDomVersion
17963
18820
  ),
17964
- /* @__PURE__ */ jsxs37(
18821
+ /* @__PURE__ */ jsxs39(
17965
18822
  "div",
17966
18823
  {
17967
18824
  "data-slot": "composer-action-bar",
17968
18825
  className: "pointer-events-none absolute inset-x-1.5 bottom-1 flex min-h-10 items-center justify-between gap-2",
17969
18826
  children: [
17970
- /* @__PURE__ */ jsxs37("div", { className: "pointer-events-none flex min-w-0 flex-1 items-center gap-1.5", children: [
17971
- /* @__PURE__ */ jsx54("div", { className: "pointer-events-auto flex shrink-0 items-center gap-1.5", children: /* @__PURE__ */ jsx54(
18827
+ /* @__PURE__ */ jsxs39("div", { className: "pointer-events-none flex min-w-0 flex-1 items-center gap-1.5", children: [
18828
+ /* @__PURE__ */ jsx56("div", { className: "pointer-events-auto flex shrink-0 items-center gap-1.5", children: /* @__PURE__ */ jsx56(
17972
18829
  ComposerMenu,
17973
18830
  {
17974
18831
  composer,
@@ -17986,20 +18843,20 @@ function Chat({
17986
18843
  disabled: missingConfig || isHistoryLoading || hasPendingInteractiveRequest
17987
18844
  }
17988
18845
  ) }),
17989
- selectedTool && /* @__PURE__ */ jsxs37("span", { className: "pointer-events-auto inline-flex h-8 min-w-0 max-w-[14rem] shrink items-center gap-1.5 rounded-full bg-primary/10 px-2 text-xs font-medium text-primary transition-all duration-200", children: [
17990
- /* @__PURE__ */ jsx54("span", { className: "truncate", children: selectedTool.shortLabel ?? selectedTool.label }),
17991
- /* @__PURE__ */ jsx54(
18846
+ selectedTool && /* @__PURE__ */ jsxs39("span", { className: "pointer-events-auto inline-flex h-8 min-w-0 max-w-[14rem] shrink items-center gap-1.5 rounded-full bg-primary/10 px-2 text-xs font-medium text-primary transition-all duration-200", children: [
18847
+ /* @__PURE__ */ jsx56("span", { className: "truncate", children: selectedTool.shortLabel ?? selectedTool.label }),
18848
+ /* @__PURE__ */ jsx56(
17992
18849
  "button",
17993
18850
  {
17994
18851
  type: "button",
17995
18852
  onClick: () => setSelectedTool(null),
17996
18853
  className: "shrink-0 rounded-full p-0.5 text-primary/70 hover:bg-primary/10 hover:text-primary",
17997
- children: /* @__PURE__ */ jsx54(X6, { size: 12 })
18854
+ children: /* @__PURE__ */ jsx56(X7, { size: 12 })
17998
18855
  }
17999
18856
  )
18000
18857
  ] })
18001
18858
  ] }),
18002
- /* @__PURE__ */ jsx54("div", { className: "pointer-events-auto shrink-0", children: /* @__PURE__ */ jsx54(
18859
+ /* @__PURE__ */ jsx56("div", { className: "pointer-events-auto shrink-0", children: /* @__PURE__ */ jsx56(
18003
18860
  SendButton,
18004
18861
  {
18005
18862
  disabled: isSendDisabled,
@@ -18022,7 +18879,7 @@ function Chat({
18022
18879
  ]
18023
18880
  }
18024
18881
  ) }),
18025
- disclaimer?.text && /* @__PURE__ */ jsx54(
18882
+ disclaimer?.text && /* @__PURE__ */ jsx56(
18026
18883
  "p",
18027
18884
  {
18028
18885
  className: cn(
@@ -18032,14 +18889,14 @@ function Chat({
18032
18889
  children: disclaimer.text
18033
18890
  }
18034
18891
  ),
18035
- /* @__PURE__ */ jsxs37("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
18036
- /* @__PURE__ */ jsx54("span", { children: t("chat.poweredBy") }),
18037
- /* @__PURE__ */ jsx54(ContextUsageIndicator, { className: "absolute right-4" })
18892
+ /* @__PURE__ */ jsxs39("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
18893
+ /* @__PURE__ */ jsx56("span", { children: t("chat.poweredBy") }),
18894
+ /* @__PURE__ */ jsx56(ContextUsageIndicator, { className: "absolute right-4" })
18038
18895
  ] })
18039
18896
  ]
18040
18897
  }
18041
18898
  ),
18042
- /* @__PURE__ */ jsx54(
18899
+ /* @__PURE__ */ jsx56(
18043
18900
  SettingsSheet,
18044
18901
  {
18045
18902
  open: petSettingsOpen,
@@ -18049,17 +18906,17 @@ function Chat({
18049
18906
  onSave: savePetLocalSettings
18050
18907
  }
18051
18908
  ),
18052
- /* @__PURE__ */ jsx54(PetBridge, { pet: effectivePet, state: petAutoState })
18909
+ /* @__PURE__ */ jsx56(PetBridge, { pet: effectivePet, state: petAutoState })
18053
18910
  ]
18054
18911
  }
18055
18912
  );
18056
18913
  }
18057
18914
 
18058
18915
  // src/components/ui/separator.tsx
18059
- import * as React50 from "react";
18060
- import { jsx as jsx55 } from "react/jsx-runtime";
18061
- var Separator = React50.forwardRef(
18062
- ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx55(
18916
+ import * as React52 from "react";
18917
+ import { jsx as jsx57 } from "react/jsx-runtime";
18918
+ var Separator = React52.forwardRef(
18919
+ ({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx57(
18063
18920
  "div",
18064
18921
  {
18065
18922
  ref,