@xpert-ai/chatkit-ui 0.0.20 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/assets/{abap-CabZ0vYL.js → abap-DMqO-Um8.js} +1 -1
- package/dist/app/assets/{abnf-CPoubvVG.js → abnf-CBYpoE1H.js} +1 -1
- package/dist/app/assets/{actionscript-CL1BPQFv.js → actionscript-ieE-wJMz.js} +1 -1
- package/dist/app/assets/{ada-BOt55oS4.js → ada-0-3Dx7g-.js} +1 -1
- package/dist/app/assets/{agda-DKyUkxie.js → agda-uvq9b4Kv.js} +1 -1
- package/dist/app/assets/{al-Jnhqb7P-.js → al-BmajJCAx.js} +1 -1
- package/dist/app/assets/{antlr4-BeT3YbbK.js → antlr4-DnRRgAfR.js} +1 -1
- package/dist/app/assets/{apacheconf-Ck_DRZXY.js → apacheconf-BWoRK3Q3.js} +1 -1
- package/dist/app/assets/{apex-CPjbO0O4.js → apex-u3cbevj3.js} +1 -1
- package/dist/app/assets/{apl-Ccs4_jOU.js → apl-Cifc7IZj.js} +1 -1
- package/dist/app/assets/{applescript-C6i7vo8F.js → applescript-CpHbiQqz.js} +1 -1
- package/dist/app/assets/{aql-D3ZWY-VL.js → aql-C_VCCvUl.js} +1 -1
- package/dist/app/assets/{arduino-xTj3TTXg.js → arduino-CSAc4iDr.js} +1 -1
- package/dist/app/assets/{arff-BOuVccGR.js → arff-B8hSQDyJ.js} +1 -1
- package/dist/app/assets/{asciidoc-BmShvnn0.js → asciidoc-Guc1Uqnw.js} +1 -1
- package/dist/app/assets/{asm6502-6FWPK68i.js → asm6502-CxPqNdV6.js} +1 -1
- package/dist/app/assets/{asmatmel-KLAd82QV.js → asmatmel-C76CHB5e.js} +1 -1
- package/dist/app/assets/{aspnet-vZiSZd1y.js → aspnet-BQFc33QF.js} +1 -1
- package/dist/app/assets/{autohotkey-tcBDP1b7.js → autohotkey-uQeN2mix.js} +1 -1
- package/dist/app/assets/{autoit-Bwt0tLM_.js → autoit-Bmy0PsAQ.js} +1 -1
- package/dist/app/assets/{avisynth-Bzz43Lfu.js → avisynth-BvuIlb62.js} +1 -1
- package/dist/app/assets/{avro-idl-Bt9aSyrD.js → avro-idl-DWeVWQR3.js} +1 -1
- package/dist/app/assets/{bash-BloO3C-T.js → bash-HypWaeXO.js} +1 -1
- package/dist/app/assets/{basic-B-OOkRrw.js → basic-B4YxRCle.js} +1 -1
- package/dist/app/assets/{batch-aOUu2msA.js → batch-B1yKhArW.js} +1 -1
- package/dist/app/assets/{bbcode-C4D8vm8O.js → bbcode-BIDNxh7c.js} +1 -1
- package/dist/app/assets/{bicep-BtBByAYv.js → bicep-DkupOIs7.js} +1 -1
- package/dist/app/assets/{birb-BKXLouTf.js → birb-Jo6NYQYX.js} +1 -1
- package/dist/app/assets/{bison-CniuHJJN.js → bison-BjPiLxuX.js} +1 -1
- package/dist/app/assets/{bnf-CGcuZYv2.js → bnf-BjygHCSE.js} +1 -1
- package/dist/app/assets/{brainfuck-C9dlh056.js → brainfuck-CsnLnGPx.js} +1 -1
- package/dist/app/assets/{brightscript-nhHFw9_4.js → brightscript-CwmmyoHc.js} +1 -1
- package/dist/app/assets/{bro-BTsReVOc.js → bro-BNKXu22N.js} +1 -1
- package/dist/app/assets/{bsl-CmOTwcFR.js → bsl-DOwsbsXU.js} +1 -1
- package/dist/app/assets/{c-Yjfq4oES.js → c-DyedRTs7.js} +1 -1
- package/dist/app/assets/{cfscript-DGhYlgJ7.js → cfscript-DCpmh-J_.js} +1 -1
- package/dist/app/assets/{chaiscript-CpP8bBSU.js → chaiscript-DRaisf-4.js} +1 -1
- package/dist/app/assets/{cil-CZ7j4pcz.js → cil-C5bobqND.js} +1 -1
- package/dist/app/assets/{clike-D581thF2.js → clike-CvmXR497.js} +1 -1
- package/dist/app/assets/{clojure-AXVmar0o.js → clojure-BH_u6xTK.js} +1 -1
- package/dist/app/assets/{cmake-BozSSfax.js → cmake-CZruZSdT.js} +1 -1
- package/dist/app/assets/{cobol-OciN9vwY.js → cobol-qc5xAkcg.js} +1 -1
- package/dist/app/assets/{coffeescript-B9yMzVL5.js → coffeescript-DGM4CLoq.js} +1 -1
- package/dist/app/assets/{concurnas-DeQIM64O.js → concurnas-DFyZRxPp.js} +1 -1
- package/dist/app/assets/{coq-CicPksao.js → coq-DbZe2f_H.js} +1 -1
- package/dist/app/assets/{core-BIcqXTaK.js → core-BWUnDrKt.js} +1 -1
- package/dist/app/assets/{cpp-DKQF7403.js → cpp-CidpRyAJ.js} +1 -1
- package/dist/app/assets/{crystal-Bcau7QFZ.js → crystal-DZE9-h5D.js} +1 -1
- package/dist/app/assets/{csharp-BYghYpTl.js → csharp-Cf2K5CJJ.js} +1 -1
- package/dist/app/assets/{cshtml-BIxIGrsH.js → cshtml-DRjf7C5F.js} +1 -1
- package/dist/app/assets/{csp-CzDOD-m1.js → csp-dEoRcP0N.js} +1 -1
- package/dist/app/assets/{css-CPRwU6oY.js → css-BWUfAyau.js} +1 -1
- package/dist/app/assets/{css-extras-C28yWYxN.js → css-extras-pPY_Crez.js} +1 -1
- package/dist/app/assets/{csv-D8IAZwKO.js → csv-DdkqZn4I.js} +1 -1
- package/dist/app/assets/{cypher-0hMRBt8D.js → cypher-BXQbix41.js} +1 -1
- package/dist/app/assets/{d-B5PQgXXo.js → d-BctgRQp0.js} +1 -1
- package/dist/app/assets/{dart-CvCyf8me.js → dart-DuiikcDB.js} +1 -1
- package/dist/app/assets/{dataweave-Izl0xtz9.js → dataweave-ClZ_D-Ju.js} +1 -1
- package/dist/app/assets/{dax-D-bGAkbS.js → dax-DXNfCTH9.js} +1 -1
- package/dist/app/assets/{dhall-DXIOSM5Q.js → dhall-Cbz5hfMr.js} +1 -1
- package/dist/app/assets/{diff-BE-xKdIi.js → diff-bify6WLh.js} +1 -1
- package/dist/app/assets/{django-DxEZdkeU.js → django-5DdvW3LZ.js} +1 -1
- package/dist/app/assets/{dns-zone-file-D406E4S7.js → dns-zone-file-DIIW7lsW.js} +1 -1
- package/dist/app/assets/{docker-BZkb2U00.js → docker-BxIMVoJD.js} +1 -1
- package/dist/app/assets/{dot-BGJNVmx1.js → dot-DLEHPnum.js} +1 -1
- package/dist/app/assets/{ebnf-_PEATas2.js → ebnf-DHWaG3pk.js} +1 -1
- package/dist/app/assets/{editorconfig-C1UuLwJC.js → editorconfig-D2gTUSqU.js} +1 -1
- package/dist/app/assets/{eiffel-PzXVtlzf.js → eiffel-C3dcM2dq.js} +1 -1
- package/dist/app/assets/{ejs-707c0691.js → ejs-0qd3jtKi.js} +1 -1
- package/dist/app/assets/{elixir-Bd3zWMjP.js → elixir-BbBaHIGe.js} +1 -1
- package/dist/app/assets/{elm-DvEDEOdK.js → elm-KJmeOU7e.js} +1 -1
- package/dist/app/assets/{erb-B6lZT1P9.js → erb-BncgAY0M.js} +1 -1
- package/dist/app/assets/{erlang-BwhqRmQk.js → erlang-DS2SHYdK.js} +1 -1
- package/dist/app/assets/{etlua-Bkg93PrU.js → etlua-CvdrPEPO.js} +1 -1
- package/dist/app/assets/{excel-formula-BD0I0dyD.js → excel-formula-BSj1zROW.js} +1 -1
- package/dist/app/assets/{factor-CiQgOsxY.js → factor-DAbcpTN7.js} +1 -1
- package/dist/app/assets/{false-DlJ-f_Rc.js → false-CI895JmG.js} +1 -1
- package/dist/app/assets/{firestore-security-rules-CxrEhPSm.js → firestore-security-rules-CJ33YIQv.js} +1 -1
- package/dist/app/assets/{flow-DOjTBDi4.js → flow-a2eNz08o.js} +1 -1
- package/dist/app/assets/{fortran-D6uA-pWI.js → fortran-Bt9e6qJa.js} +1 -1
- package/dist/app/assets/{fsharp-CFL1DcvT.js → fsharp-Y0Qf2U16.js} +1 -1
- package/dist/app/assets/{ftl-DzWZwecM.js → ftl-D-TrqPet.js} +1 -1
- package/dist/app/assets/{gap-DatQeRFY.js → gap-CP5bMoJx.js} +1 -1
- package/dist/app/assets/{gcode-5FSxboIT.js → gcode-DQNcGCou.js} +1 -1
- package/dist/app/assets/{gdscript-Dz-OC8bG.js → gdscript-Bxt6W-z5.js} +1 -1
- package/dist/app/assets/{gedcom-BS0539Ys.js → gedcom-Cqgp4wkt.js} +1 -1
- package/dist/app/assets/{gherkin-BJKrWYAT.js → gherkin-D7pNUe8Z.js} +1 -1
- package/dist/app/assets/{git-DCjIevVw.js → git-C4ec-8cM.js} +1 -1
- package/dist/app/assets/{glsl-toSXKJrw.js → glsl-8sVKxech.js} +1 -1
- package/dist/app/assets/{gml-DODsSWU7.js → gml-TuwFoFK6.js} +1 -1
- package/dist/app/assets/{gn-CzmtMWMm.js → gn-BwHrmBhU.js} +1 -1
- package/dist/app/assets/{go-module-BbcV-9oG.js → go-module-cqolzX_W.js} +1 -1
- package/dist/app/assets/{go-BCQUEKVv.js → go-vGJJNlGP.js} +1 -1
- package/dist/app/assets/{graphql-C_KxCYJO.js → graphql-Do6Lisgl.js} +1 -1
- package/dist/app/assets/{groovy-Cj97iKYK.js → groovy--87wZh42.js} +1 -1
- package/dist/app/assets/{haml-tLXJGYDb.js → haml-vhodueeI.js} +1 -1
- package/dist/app/assets/{handlebars-DIdVe3xN.js → handlebars-CNLRaZ5R.js} +1 -1
- package/dist/app/assets/{haskell-DPqw5u4H.js → haskell-BWTsCqP4.js} +1 -1
- package/dist/app/assets/{haxe-AsnHNCIR.js → haxe-CSb0SWYW.js} +1 -1
- package/dist/app/assets/{hcl-C6aoWR34.js → hcl-ftOASTH-.js} +1 -1
- package/dist/app/assets/{hlsl-B2hhU30-.js → hlsl-BnaGHwDi.js} +1 -1
- package/dist/app/assets/{hoon-Bs-KhWO3.js → hoon-wyj1oNzn.js} +1 -1
- package/dist/app/assets/{hpkp-C-J4O-Mp.js → hpkp-Broim0YQ.js} +1 -1
- package/dist/app/assets/{hsts-BNFEkSnm.js → hsts-BSMt-Rhs.js} +1 -1
- package/dist/app/assets/{http-D7UlQANy.js → http-yK1zPe9M.js} +1 -1
- package/dist/app/assets/{ichigojam-B01TJ8BA.js → ichigojam-Bpzuxs1S.js} +1 -1
- package/dist/app/assets/{icon-Ca_ghvQd.js → icon-DjPW0ImK.js} +1 -1
- package/dist/app/assets/{icu-message-format-CkcsJ0ML.js → icu-message-format-CTS86FWW.js} +1 -1
- package/dist/app/assets/{idris-BApVxI9a.js → idris-DkPie8bu.js} +1 -1
- package/dist/app/assets/{iecst-CXLR8sGn.js → iecst-CG1KmB8U.js} +1 -1
- package/dist/app/assets/{ignore-7LzAeAFj.js → ignore-D9eho3CQ.js} +1 -1
- package/dist/app/assets/{index-BUg2yVDW.js → index-4J46qBCc.js} +105 -99
- package/dist/app/assets/{index-om2E9pNd.css → index-DTn9OjqV.css} +1 -1
- package/dist/app/assets/{inform7-CtnRN-Iq.js → inform7-DD1mc6Wh.js} +1 -1
- package/dist/app/assets/{ini-Cjpl6yTL.js → ini-Db6U4nBT.js} +1 -1
- package/dist/app/assets/{io-C6W_EboY.js → io-BRkH6hzB.js} +1 -1
- package/dist/app/assets/{j-BOBDun2W.js → j-CD22iLrA.js} +1 -1
- package/dist/app/assets/{java-CNwVyXY2.js → java-DvhwWZfy.js} +1 -1
- package/dist/app/assets/{javadoc-DS6hxu7_.js → javadoc-Ecoxhe_9.js} +1 -1
- package/dist/app/assets/{javadoclike-J6YT11JS.js → javadoclike-Realhpv4.js} +1 -1
- package/dist/app/assets/{javascript-IbEfuVSB.js → javascript-BBd1k8wl.js} +1 -1
- package/dist/app/assets/{javastacktrace-DjxwGV26.js → javastacktrace-C8QW0vuU.js} +1 -1
- package/dist/app/assets/{jexl-TLHmHaQ5.js → jexl-CT2UXrnH.js} +1 -1
- package/dist/app/assets/{jolie-CLk71kur.js → jolie-qtyDXXST.js} +1 -1
- package/dist/app/assets/{jq-DZKnIQZM.js → jq-CNJQULTZ.js} +1 -1
- package/dist/app/assets/{js-extras-CJab09ti.js → js-extras-DwIZLd4T.js} +1 -1
- package/dist/app/assets/{js-templates-CQGqrHhi.js → js-templates-glA_Un9b.js} +1 -1
- package/dist/app/assets/{jsdoc--ymvl4aq.js → jsdoc-BsXlBBjy.js} +1 -1
- package/dist/app/assets/{json-D9b-V85G.js → json-BC3xmMOU.js} +1 -1
- package/dist/app/assets/{json5-LgA47n7A.js → json5-CiePGcB9.js} +1 -1
- package/dist/app/assets/{jsonp-Cvwp3f8M.js → jsonp-B9HJmhak.js} +1 -1
- package/dist/app/assets/{jsstacktrace-z8t2H6h6.js → jsstacktrace-3xS0eyZd.js} +1 -1
- package/dist/app/assets/{jsx-B71LrwNd.js → jsx-B5kMqxBm.js} +1 -1
- package/dist/app/assets/{julia-DCATdxwO.js → julia-B5Udq0EY.js} +1 -1
- package/dist/app/assets/{keepalived-DVYYbgrL.js → keepalived-CI0hMS1b.js} +1 -1
- package/dist/app/assets/{keyman-DLyOXnhf.js → keyman-BCtXwe5i.js} +1 -1
- package/dist/app/assets/{kotlin-CYoDfyDA.js → kotlin-B3l0V1Fn.js} +1 -1
- package/dist/app/assets/{kumir-CPWiEvmL.js → kumir-BmC_PBOp.js} +1 -1
- package/dist/app/assets/{kusto-BkfRYk0W.js → kusto-B0p1ppsT.js} +1 -1
- package/dist/app/assets/{latex-BEjZ0ppC.js → latex-CHwNDYz_.js} +1 -1
- package/dist/app/assets/{latte-DaZOqdGV.js → latte-DihAtCCl.js} +1 -1
- package/dist/app/assets/{less-BmKsj1gN.js → less-BLGkFSp1.js} +1 -1
- package/dist/app/assets/{lilypond-mmng28aJ.js → lilypond-CCsAc8Nl.js} +1 -1
- package/dist/app/assets/{liquid-BuuJO6_6.js → liquid-jBSQx5I5.js} +1 -1
- package/dist/app/assets/{lisp-DnffFM5N.js → lisp-CgzQXnYE.js} +1 -1
- package/dist/app/assets/{livescript-BSsr00Wr.js → livescript-u96H-zdx.js} +1 -1
- package/dist/app/assets/{llvm-37YjcHN5.js → llvm-WmVcvcNM.js} +1 -1
- package/dist/app/assets/{log-D3l5N3To.js → log-990P-Rch.js} +1 -1
- package/dist/app/assets/{lolcode-C0Q2M_6s.js → lolcode-DdFIjfxs.js} +1 -1
- package/dist/app/assets/{lua-DcLwN4Tg.js → lua-GkhnMu0T.js} +1 -1
- package/dist/app/assets/{magma-CK0Amip9.js → magma-wajb6K9F.js} +1 -1
- package/dist/app/assets/{makefile-CtpS-RoO.js → makefile-CGHjuGaS.js} +1 -1
- package/dist/app/assets/{markdown-BNK3F4ql.js → markdown-BFWQ31vs.js} +1 -1
- package/dist/app/assets/{markup-C9GIL65H.js → markup-1ihI0X17.js} +1 -1
- package/dist/app/assets/{markup-templating-Du1J3ADP.js → markup-templating-DblqKZLi.js} +1 -1
- package/dist/app/assets/{matlab-DEM6O1Ul.js → matlab-CPqo7ZUC.js} +1 -1
- package/dist/app/assets/{maxscript-DMvqa3gf.js → maxscript-CTgVjA7o.js} +1 -1
- package/dist/app/assets/{mel-C8DBIw1g.js → mel-Cxah6vYr.js} +1 -1
- package/dist/app/assets/{mermaid-CVko6NSq.js → mermaid-BAgJSsZ7.js} +1 -1
- package/dist/app/assets/{mizar-CwYm3_It.js → mizar-BL3spn8_.js} +1 -1
- package/dist/app/assets/{mongodb-DRqGwjq6.js → mongodb-DXzP7tR0.js} +1 -1
- package/dist/app/assets/{monkey-BxiKe6Nr.js → monkey-anPtBsfj.js} +1 -1
- package/dist/app/assets/{moonscript-CJyt1xoM.js → moonscript-Y_tcmLfW.js} +1 -1
- package/dist/app/assets/{n1ql-BBmjIGEU.js → n1ql-B7NGFYRY.js} +1 -1
- package/dist/app/assets/{n4js-ByKsJMJL.js → n4js-zh8URwWB.js} +1 -1
- package/dist/app/assets/{nand2tetris-hdl-BTSXj71h.js → nand2tetris-hdl-CDUtzUHw.js} +1 -1
- package/dist/app/assets/{naniscript-C4jykFVF.js → naniscript-CjJGU6C6.js} +1 -1
- package/dist/app/assets/{nasm-DPA0eXtX.js → nasm-D6biC9Vr.js} +1 -1
- package/dist/app/assets/{neon-upN4Ak64.js → neon-C3Z0pCuH.js} +1 -1
- package/dist/app/assets/{nevod-CdttHB8F.js → nevod-BT4Ivkzb.js} +1 -1
- package/dist/app/assets/{nginx-DI1fsQ3j.js → nginx-vHHTRs1B.js} +1 -1
- package/dist/app/assets/{nim-D7kc_mK9.js → nim-Jk1NOWk0.js} +1 -1
- package/dist/app/assets/{nix-BUG5ppr9.js → nix-CEkA_w3B.js} +1 -1
- package/dist/app/assets/{nsis-BnXhmmxO.js → nsis-Du9w_Qb8.js} +1 -1
- package/dist/app/assets/{objectivec-Bu4dOfb9.js → objectivec-BciYUGRR.js} +1 -1
- package/dist/app/assets/{ocaml-aT7VVPiL.js → ocaml-CpZ_M4DP.js} +1 -1
- package/dist/app/assets/{opencl-BzyWcYkI.js → opencl-C-4M-Mvx.js} +1 -1
- package/dist/app/assets/{openqasm-b2yFBJdq.js → openqasm-CilZXlSe.js} +1 -1
- package/dist/app/assets/{oz-D46TtIuw.js → oz-DluYJ10T.js} +1 -1
- package/dist/app/assets/{parigp-BAJyhdut.js → parigp-BlIaVN51.js} +1 -1
- package/dist/app/assets/{parser-B-ALvauC.js → parser-BZVTYRp4.js} +1 -1
- package/dist/app/assets/{pascal-B0ap4FDW.js → pascal-CMz_wkC0.js} +1 -1
- package/dist/app/assets/{pascaligo-ChOneu9-.js → pascaligo-DLQY1QwY.js} +1 -1
- package/dist/app/assets/{pcaxis-DTAmxHgs.js → pcaxis-C-5nzMDp.js} +1 -1
- package/dist/app/assets/{peoplecode-dQfUy8zn.js → peoplecode-BhTicHl8.js} +1 -1
- package/dist/app/assets/{perl-CYk00e1Q.js → perl-BArlZZ8M.js} +1 -1
- package/dist/app/assets/{php-DvSqFnSN.js → php-C6zNUOf5.js} +1 -1
- package/dist/app/assets/{php-extras-BFjUbIU6.js → php-extras-DD5Glhrz.js} +1 -1
- package/dist/app/assets/{phpdoc-Di7rKCNL.js → phpdoc-Buj0qa-9.js} +1 -1
- package/dist/app/assets/{plsql-dX0-BKqD.js → plsql-o2-C-Ezr.js} +1 -1
- package/dist/app/assets/{powerquery-3xq4KaAs.js → powerquery-Cl0Dbp57.js} +1 -1
- package/dist/app/assets/{powershell-BbXooszO.js → powershell-BVFtl1FS.js} +1 -1
- package/dist/app/assets/{processing-GWbfNCzH.js → processing-BHJTqgxZ.js} +1 -1
- package/dist/app/assets/{prolog-Tb2TbunJ.js → prolog-C9gykhtA.js} +1 -1
- package/dist/app/assets/{promql-QS8vHhL7.js → promql-TzYBDR1F.js} +1 -1
- package/dist/app/assets/{properties-BJ8AWlqX.js → properties-Bi8GxxCM.js} +1 -1
- package/dist/app/assets/{protobuf-De-puAg3.js → protobuf-s08U24Jk.js} +1 -1
- package/dist/app/assets/{psl-hZft3C8K.js → psl-By228u9L.js} +1 -1
- package/dist/app/assets/{pug-BcYHdk-i.js → pug-CahxgaMR.js} +1 -1
- package/dist/app/assets/{puppet-BWbqDQJD.js → puppet-BAY6TBQY.js} +1 -1
- package/dist/app/assets/{pure-Bz2pjTxR.js → pure-IA8ihD9R.js} +1 -1
- package/dist/app/assets/{purebasic-BlO48lYx.js → purebasic-B6joY-ZH.js} +1 -1
- package/dist/app/assets/{purescript-BxSMm2Br.js → purescript-DczXEj8E.js} +1 -1
- package/dist/app/assets/{q-DDUTW9aK.js → q-CEXq_tpX.js} +1 -1
- package/dist/app/assets/{qml-DisOV-LV.js → qml-ND31CBLa.js} +1 -1
- package/dist/app/assets/{qore-FNRP4gBF.js → qore-DAjVLL2F.js} +1 -1
- package/dist/app/assets/{qsharp-DhtMV0oO.js → qsharp-jccBvH6Y.js} +1 -1
- package/dist/app/assets/{r-CyiuHjNN.js → r-pv5Xhvsd.js} +1 -1
- package/dist/app/assets/{racket-DFgoSckH.js → racket-xRigDwdL.js} +1 -1
- package/dist/app/assets/{reason-HhYbY7K3.js → reason-DnAP7dec.js} +1 -1
- package/dist/app/assets/{regex-jU5TpvM-.js → regex-Dwkma1bN.js} +1 -1
- package/dist/app/assets/{rego-BCjDPrQO.js → rego-3dHPz-ut.js} +1 -1
- package/dist/app/assets/{renpy-BTSgQi2v.js → renpy-Czxc7hu0.js} +1 -1
- package/dist/app/assets/{rest-BLcZ4e-5.js → rest-BP_JQ_AG.js} +1 -1
- package/dist/app/assets/{rip-SltRJnuI.js → rip-Nredd5kD.js} +1 -1
- package/dist/app/assets/{roboconf-B-GZm2Oe.js → roboconf-CkR4ACer.js} +1 -1
- package/dist/app/assets/{robotframework-BOt8S6cX.js → robotframework-CYYV7JaP.js} +1 -1
- package/dist/app/assets/{ruby-CVfYH0zM.js → ruby-EA_sSyU6.js} +1 -1
- package/dist/app/assets/{rust-B6mEp4Sj.js → rust-BM2hEYJt.js} +1 -1
- package/dist/app/assets/{sas-DvEI8RJ0.js → sas-jaxOWx-0.js} +1 -1
- package/dist/app/assets/{sass-Cv25Jxqq.js → sass-pkiTdYnF.js} +1 -1
- package/dist/app/assets/{scala-CyqNr7Uv.js → scala-lTsQiijh.js} +1 -1
- package/dist/app/assets/{scheme-ji0XoXLf.js → scheme-DkPZYA1o.js} +1 -1
- package/dist/app/assets/{scss-B7_0neO_.js → scss-DZjxUgqE.js} +1 -1
- package/dist/app/assets/{shell-session-CqZEoMQD.js → shell-session-CKXJ0a90.js} +1 -1
- package/dist/app/assets/{smali-DKSzZYkI.js → smali-DVWpHHAX.js} +1 -1
- package/dist/app/assets/{smalltalk-BOA4piuq.js → smalltalk-ChiRh9QF.js} +1 -1
- package/dist/app/assets/{smarty-Du99BSgN.js → smarty-C4i7AVoC.js} +1 -1
- package/dist/app/assets/{sml-BJedIA4B.js → sml-v9dKzil3.js} +1 -1
- package/dist/app/assets/{solidity-DidQwG5Z.js → solidity-DaxM8K8t.js} +1 -1
- package/dist/app/assets/{solution-file-Bx0d9qN8.js → solution-file-Ch7ajMI6.js} +1 -1
- package/dist/app/assets/{soy-BBLv3Cfa.js → soy-CHeWJZPl.js} +1 -1
- package/dist/app/assets/{sparql-Da5WZKbL.js → sparql-f56EhPSR.js} +1 -1
- package/dist/app/assets/{splunk-spl-DbJKl8So.js → splunk-spl-CNX2IshN.js} +1 -1
- package/dist/app/assets/{sqf-CYrx0jxf.js → sqf-B9Z5kTgF.js} +1 -1
- package/dist/app/assets/{sql-Gv-aOlOf.js → sql-PZTLdUd4.js} +1 -1
- package/dist/app/assets/{squirrel-FpIGPPw4.js → squirrel-_QTHEJtD.js} +1 -1
- package/dist/app/assets/{stan-Dq001Nrk.js → stan-y02QaMQQ.js} +1 -1
- package/dist/app/assets/{stylus-aatfgWwe.js → stylus-CGYq1GKp.js} +1 -1
- package/dist/app/assets/{swift-pn7VW95d.js → swift-BBMLpv3H.js} +1 -1
- package/dist/app/assets/{systemd-9capsVJ6.js → systemd-CD7Dfv8Y.js} +1 -1
- package/dist/app/assets/{t4-cs-CKXcczci.js → t4-cs-BtxQixNP.js} +1 -1
- package/dist/app/assets/{t4-templating-1wTayb8u.js → t4-templating-BX2jWZwS.js} +1 -1
- package/dist/app/assets/{t4-vb-B_O7wBow.js → t4-vb-CX3AQUVf.js} +1 -1
- package/dist/app/assets/{tap-D-TV5_gQ.js → tap-BRBB20R0.js} +1 -1
- package/dist/app/assets/{tcl-BaVob1Om.js → tcl-CWrqc_vL.js} +1 -1
- package/dist/app/assets/{textile-COMk-HmI.js → textile-EJMS8IJv.js} +1 -1
- package/dist/app/assets/{toml-D9NJpArC.js → toml-DLWr0_Sd.js} +1 -1
- package/dist/app/assets/{tremor-rCNHwdQL.js → tremor-D0DGH64h.js} +1 -1
- package/dist/app/assets/{tt2-DTDvfOgc.js → tt2-CaSD1IpZ.js} +1 -1
- package/dist/app/assets/{turtle-D8pkqXh1.js → turtle-BtZWKoZ_.js} +1 -1
- package/dist/app/assets/{twig-DxSF8gqH.js → twig-BQ0AWwu3.js} +1 -1
- package/dist/app/assets/{typescript-Caebatmk.js → typescript-sByRs_H7.js} +1 -1
- package/dist/app/assets/{typoscript-B3uk1kES.js → typoscript-Bs3x5DVu.js} +1 -1
- package/dist/app/assets/{unrealscript-ZNoSG8ji.js → unrealscript-BPk-JGuX.js} +1 -1
- package/dist/app/assets/{uorazor-LekoNNOo.js → uorazor-Dxr1B729.js} +1 -1
- package/dist/app/assets/{uri-B8YcIzOv.js → uri-B18d7fGy.js} +1 -1
- package/dist/app/assets/{v-6rOne2a0.js → v-B-4se_c_.js} +1 -1
- package/dist/app/assets/{vala-CjEJEdsP.js → vala-CZJMpckw.js} +1 -1
- package/dist/app/assets/{vbnet-DBPmBm7_.js → vbnet-Bon1nLZm.js} +1 -1
- package/dist/app/assets/{velocity-DOooMwL8.js → velocity-Ck8gHF4B.js} +1 -1
- package/dist/app/assets/{verilog-Cq0ZocvP.js → verilog-zADKtd-6.js} +1 -1
- package/dist/app/assets/{vhdl-Dxs_xidb.js → vhdl-Ce3jhJNh.js} +1 -1
- package/dist/app/assets/{vim-BqsnXwB6.js → vim-CwgyIdo-.js} +1 -1
- package/dist/app/assets/{visual-basic-zAzjvaqP.js → visual-basic-BWQC7pBF.js} +1 -1
- package/dist/app/assets/{warpscript-D9hbfr6_.js → warpscript-CVp7w3zz.js} +1 -1
- package/dist/app/assets/{wasm-C4TU9VDY.js → wasm-yPowz3sM.js} +1 -1
- package/dist/app/assets/{web-idl-DD5JcddQ.js → web-idl-BkghLEob.js} +1 -1
- package/dist/app/assets/{wiki-Des21yVK.js → wiki-TBH4TnLK.js} +1 -1
- package/dist/app/assets/{wolfram-B7enpov1.js → wolfram-BmgF1AlB.js} +1 -1
- package/dist/app/assets/{wren-Rr8h-Ayu.js → wren-CJ8nrMy_.js} +1 -1
- package/dist/app/assets/{xeora-EjcLXBhx.js → xeora-N6_5XQpC.js} +1 -1
- package/dist/app/assets/{xml-doc-uaTxx6-m.js → xml-doc-GBGxTNFc.js} +1 -1
- package/dist/app/assets/{xojo-CX6G8nhh.js → xojo-CmpAfzYO.js} +1 -1
- package/dist/app/assets/{xquery-DvPb3Uw9.js → xquery-BA22D3yp.js} +1 -1
- package/dist/app/assets/{yaml-D-l_Y2hx.js → yaml-CDGmAMpu.js} +1 -1
- package/dist/app/assets/{yang-KBoIIT4_.js → yang-rFKIXOjI.js} +1 -1
- package/dist/app/assets/{zig-_uNXp9cY.js → zig-rH4Tzjve.js} +1 -1
- package/dist/app/index.html +2 -2
- package/dist/index.cjs +1891 -582
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +1926 -591
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
// src/components/chat.tsx
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
2
|
+
import * as React21 from "react";
|
|
3
|
+
import {
|
|
4
|
+
ArrowDown,
|
|
5
|
+
FileText as FileText2,
|
|
6
|
+
Loader2 as Loader22,
|
|
7
|
+
Pencil as Pencil3,
|
|
8
|
+
Quote,
|
|
9
|
+
RefreshCw as RefreshCw2,
|
|
10
|
+
X as X2
|
|
11
|
+
} from "lucide-react";
|
|
4
12
|
|
|
5
13
|
// src/lib/utils.ts
|
|
6
14
|
import { clsx } from "clsx";
|
|
@@ -21,6 +29,64 @@ function createMessageId() {
|
|
|
21
29
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
// src/lib/message.ts
|
|
33
|
+
import { isNil, omitBy } from "lodash-es";
|
|
34
|
+
var ASSISTANT_STREAM_IDLE_TO_THINKING_MS = 2e3;
|
|
35
|
+
function hasRenderableReasoning(reasoning) {
|
|
36
|
+
return Array.isArray(reasoning) && reasoning.some((item) => item.text?.trim());
|
|
37
|
+
}
|
|
38
|
+
function hasRenderableMessageContent(content) {
|
|
39
|
+
if (typeof content === "string") {
|
|
40
|
+
return content.trim().length > 0;
|
|
41
|
+
}
|
|
42
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const items = content;
|
|
46
|
+
return items.some((item) => {
|
|
47
|
+
if (typeof item === "string") {
|
|
48
|
+
return item.trim().length > 0;
|
|
49
|
+
}
|
|
50
|
+
if (!item || typeof item !== "object") {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (item.type === "text") {
|
|
54
|
+
return Boolean(item.text?.trim());
|
|
55
|
+
}
|
|
56
|
+
if (item.type === "reasoning") {
|
|
57
|
+
return Boolean(item.text?.trim());
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function hasRenderableAssistantMessage(message) {
|
|
63
|
+
return hasRenderableMessageContent(message.content) || hasRenderableReasoning(message.reasoning);
|
|
64
|
+
}
|
|
65
|
+
function getAssistantStreamingStatus(message, isStreaming, options) {
|
|
66
|
+
if (!isStreaming) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const now = options?.now ?? Date.now();
|
|
70
|
+
const lastStreamOutputAt = typeof message.lastStreamOutputAt === "number" ? message.lastStreamOutputAt : null;
|
|
71
|
+
const isIdle = lastStreamOutputAt !== null && now - lastStreamOutputAt >= ASSISTANT_STREAM_IDLE_TO_THINKING_MS;
|
|
72
|
+
if (message.status === "reasoning") {
|
|
73
|
+
return "thinking";
|
|
74
|
+
}
|
|
75
|
+
if (message.status === "answering") {
|
|
76
|
+
if (isIdle) {
|
|
77
|
+
return "thinking";
|
|
78
|
+
}
|
|
79
|
+
return "answering";
|
|
80
|
+
}
|
|
81
|
+
if (hasRenderableReasoning(message.reasoning)) {
|
|
82
|
+
return "thinking";
|
|
83
|
+
}
|
|
84
|
+
if (isIdle) {
|
|
85
|
+
return "thinking";
|
|
86
|
+
}
|
|
87
|
+
return "loading";
|
|
88
|
+
}
|
|
89
|
+
|
|
24
90
|
// src/lib/scroll.ts
|
|
25
91
|
var BOTTOM_FOLLOW_THRESHOLD_PX = 48;
|
|
26
92
|
function getDistanceFromBottom(element) {
|
|
@@ -45,7 +111,29 @@ import {
|
|
|
45
111
|
Client
|
|
46
112
|
} from "@xpert-ai/xpert-sdk";
|
|
47
113
|
import "@langchain/core/messages/tool";
|
|
48
|
-
import {
|
|
114
|
+
import {
|
|
115
|
+
ChatMessageEventTypeEnum,
|
|
116
|
+
ChatMessageTypeEnum
|
|
117
|
+
} from "@xpert-ai/chatkit-types";
|
|
118
|
+
|
|
119
|
+
// src/lib/api-config.ts
|
|
120
|
+
function hasConfiguredValue(value) {
|
|
121
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
122
|
+
}
|
|
123
|
+
function getMissingApiConfigurationKind({
|
|
124
|
+
apiUrl,
|
|
125
|
+
clientSecret
|
|
126
|
+
}) {
|
|
127
|
+
const hasApiUrl = hasConfiguredValue(apiUrl);
|
|
128
|
+
const hasClientSecret = hasConfiguredValue(clientSecret);
|
|
129
|
+
if (hasApiUrl && hasClientSecret) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
if (!hasApiUrl && !hasClientSecret) {
|
|
133
|
+
return "apiUrlAndClientSecret";
|
|
134
|
+
}
|
|
135
|
+
return hasApiUrl ? "clientSecret" : "apiUrl";
|
|
136
|
+
}
|
|
49
137
|
|
|
50
138
|
// src/lib/request-options.ts
|
|
51
139
|
import {
|
|
@@ -129,8 +217,16 @@ function buildInjectedRequestOptions(input) {
|
|
|
129
217
|
import { useContext, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
130
218
|
|
|
131
219
|
// src/providers/ParentMessenger.tsx
|
|
132
|
-
import {
|
|
133
|
-
|
|
220
|
+
import {
|
|
221
|
+
createContext,
|
|
222
|
+
useCallback,
|
|
223
|
+
useEffect,
|
|
224
|
+
useMemo,
|
|
225
|
+
useRef
|
|
226
|
+
} from "react";
|
|
227
|
+
import {
|
|
228
|
+
STATE_VARIABLE_HUMAN as STATE_VARIABLE_HUMAN2
|
|
229
|
+
} from "@xpert-ai/chatkit-types";
|
|
134
230
|
|
|
135
231
|
// src/hooks/useStream.ts
|
|
136
232
|
var streamRef = { current: null };
|
|
@@ -144,6 +240,189 @@ function useStreamManager() {
|
|
|
144
240
|
};
|
|
145
241
|
}
|
|
146
242
|
|
|
243
|
+
// src/lib/references.ts
|
|
244
|
+
function isObjectLike(value) {
|
|
245
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
246
|
+
}
|
|
247
|
+
function isNonEmptyString(value) {
|
|
248
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
249
|
+
}
|
|
250
|
+
function toOptionalString(value) {
|
|
251
|
+
return isNonEmptyString(value) ? value.trim() : void 0;
|
|
252
|
+
}
|
|
253
|
+
function toReferenceText(value) {
|
|
254
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
255
|
+
}
|
|
256
|
+
function toLineNumber(value) {
|
|
257
|
+
if (typeof value === "number" && Number.isInteger(value) && value > 0) {
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
function normalizeCodeReference(candidate) {
|
|
263
|
+
const path = toOptionalString(candidate.path);
|
|
264
|
+
const text = toReferenceText(candidate.text);
|
|
265
|
+
const startLine = toLineNumber(candidate.startLine);
|
|
266
|
+
const endLine = toLineNumber(candidate.endLine);
|
|
267
|
+
if (!path || !text || startLine === null || endLine === null) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
type: "code",
|
|
272
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
273
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
274
|
+
path,
|
|
275
|
+
startLine,
|
|
276
|
+
endLine,
|
|
277
|
+
text,
|
|
278
|
+
...toOptionalString(candidate.language) ? { language: toOptionalString(candidate.language) } : {},
|
|
279
|
+
...toOptionalString(candidate.taskId) ? { taskId: toOptionalString(candidate.taskId) } : {}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function normalizeQuoteReference(candidate) {
|
|
283
|
+
const text = toReferenceText(candidate.text);
|
|
284
|
+
if (!text) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
type: "quote",
|
|
289
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
290
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
291
|
+
text,
|
|
292
|
+
...toOptionalString(candidate.messageId) ? { messageId: toOptionalString(candidate.messageId) } : {},
|
|
293
|
+
...toOptionalString(candidate.source) ? { source: toOptionalString(candidate.source) } : {}
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function isLegacyCodeReference(candidate) {
|
|
297
|
+
return isNonEmptyString(candidate.path) && toLineNumber(candidate.startLine) !== null && toLineNumber(candidate.endLine) !== null && toReferenceText(candidate.text) !== null;
|
|
298
|
+
}
|
|
299
|
+
function normalizeReference(value) {
|
|
300
|
+
if (!isObjectLike(value)) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
const candidate = value;
|
|
304
|
+
const type = toOptionalString(candidate.type);
|
|
305
|
+
if (type === "code") {
|
|
306
|
+
return normalizeCodeReference(candidate);
|
|
307
|
+
}
|
|
308
|
+
if (type === "quote") {
|
|
309
|
+
return normalizeQuoteReference(candidate);
|
|
310
|
+
}
|
|
311
|
+
if (type === void 0 && isLegacyCodeReference(candidate)) {
|
|
312
|
+
return normalizeCodeReference(candidate);
|
|
313
|
+
}
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
function normalizeReferences(value) {
|
|
317
|
+
if (!Array.isArray(value)) {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
return value.map((item) => normalizeReference(item)).filter((item) => item !== null);
|
|
321
|
+
}
|
|
322
|
+
function getCodeReferenceRange(reference) {
|
|
323
|
+
return reference.startLine === reference.endLine ? `${reference.startLine}` : `${reference.startLine}-${reference.endLine}`;
|
|
324
|
+
}
|
|
325
|
+
function getQuoteExcerpt(reference) {
|
|
326
|
+
const normalized = reference.text.replace(/\s+/g, " ").trim();
|
|
327
|
+
if (normalized.length <= 32) {
|
|
328
|
+
return normalized;
|
|
329
|
+
}
|
|
330
|
+
return `${normalized.slice(0, 29)}...`;
|
|
331
|
+
}
|
|
332
|
+
function getCodeReferenceLocation(reference) {
|
|
333
|
+
return `${reference.path}:${getCodeReferenceRange(reference)}`;
|
|
334
|
+
}
|
|
335
|
+
function getReferenceKey(reference) {
|
|
336
|
+
if (reference.id && reference.id.trim()) {
|
|
337
|
+
return reference.id.trim();
|
|
338
|
+
}
|
|
339
|
+
if (reference.type === "code") {
|
|
340
|
+
return [
|
|
341
|
+
reference.type,
|
|
342
|
+
reference.path,
|
|
343
|
+
reference.startLine,
|
|
344
|
+
reference.endLine,
|
|
345
|
+
reference.text
|
|
346
|
+
].join(":");
|
|
347
|
+
}
|
|
348
|
+
return [
|
|
349
|
+
reference.type,
|
|
350
|
+
reference.messageId ?? "",
|
|
351
|
+
reference.source ?? "",
|
|
352
|
+
reference.text
|
|
353
|
+
].join(":");
|
|
354
|
+
}
|
|
355
|
+
function mergeReferences(current, incoming) {
|
|
356
|
+
const merged = [...current];
|
|
357
|
+
const seen = new Set(current.map(getReferenceKey));
|
|
358
|
+
incoming.forEach((reference) => {
|
|
359
|
+
const key = getReferenceKey(reference);
|
|
360
|
+
if (seen.has(key)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
seen.add(key);
|
|
364
|
+
merged.push(reference);
|
|
365
|
+
});
|
|
366
|
+
return merged;
|
|
367
|
+
}
|
|
368
|
+
function getReferenceLabel(reference) {
|
|
369
|
+
if (reference.label && reference.label.trim()) {
|
|
370
|
+
return reference.label.trim();
|
|
371
|
+
}
|
|
372
|
+
if (reference.type === "code") {
|
|
373
|
+
const segments = reference.path.split("/");
|
|
374
|
+
const fileName = segments[segments.length - 1] || reference.path;
|
|
375
|
+
return `${fileName} ${getCodeReferenceRange(reference)}`;
|
|
376
|
+
}
|
|
377
|
+
if (reference.source && reference.source.trim()) {
|
|
378
|
+
return reference.source.trim();
|
|
379
|
+
}
|
|
380
|
+
return getQuoteExcerpt(reference);
|
|
381
|
+
}
|
|
382
|
+
function getReferenceMetaLine(reference) {
|
|
383
|
+
if (reference.type === "code") {
|
|
384
|
+
return getCodeReferenceLocation(reference);
|
|
385
|
+
}
|
|
386
|
+
if (reference.source && reference.source.trim()) {
|
|
387
|
+
return getQuoteExcerpt(reference);
|
|
388
|
+
}
|
|
389
|
+
if (reference.messageId && reference.messageId.trim()) {
|
|
390
|
+
return `Message ${reference.messageId.trim()}`;
|
|
391
|
+
}
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
function getReferenceTitle(reference) {
|
|
395
|
+
if (reference.type === "code") {
|
|
396
|
+
return `${getCodeReferenceLocation(reference)}
|
|
397
|
+
|
|
398
|
+
${reference.text}`;
|
|
399
|
+
}
|
|
400
|
+
const header = reference.label?.trim() || reference.source?.trim() || "Quoted text";
|
|
401
|
+
return `${header}
|
|
402
|
+
|
|
403
|
+
${reference.text}`;
|
|
404
|
+
}
|
|
405
|
+
function buildHumanMessageInputPayload(source) {
|
|
406
|
+
const references = normalizeReferences(source.references);
|
|
407
|
+
const nextReferenceComposition = source.referenceComposition ?? (references.length > 0 && typeof source.submittedInput !== "string" ? "compose" : void 0);
|
|
408
|
+
if (typeof source.submittedInput === "string") {
|
|
409
|
+
return {
|
|
410
|
+
input: source.submittedInput.trim(),
|
|
411
|
+
...references.length > 0 ? { references } : {},
|
|
412
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const input = typeof source.content === "string" ? source.content.trim() : "";
|
|
416
|
+
if (!input && references.length === 0) {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
input,
|
|
421
|
+
...references.length > 0 ? { references } : {},
|
|
422
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
147
426
|
// src/providers/ParentMessenger.tsx
|
|
148
427
|
import { jsx } from "react/jsx-runtime";
|
|
149
428
|
var handledSendUserMessageNonces = /* @__PURE__ */ new Set();
|
|
@@ -172,6 +451,10 @@ function ParentMessengerProvider({
|
|
|
172
451
|
/* @__PURE__ */ new Map()
|
|
173
452
|
);
|
|
174
453
|
const onSetOptionsHandlersRef = useRef(/* @__PURE__ */ new Set());
|
|
454
|
+
const onSetComposerValueHandlersRef = useRef(
|
|
455
|
+
/* @__PURE__ */ new Set()
|
|
456
|
+
);
|
|
457
|
+
const onFocusComposerHandlersRef = useRef(/* @__PURE__ */ new Set());
|
|
175
458
|
const latestOptionsRef = useRef(null);
|
|
176
459
|
const isParentAvailable = useMemo(() => {
|
|
177
460
|
return typeof window !== "undefined" && window.parent !== window;
|
|
@@ -185,6 +468,24 @@ function ParentMessengerProvider({
|
|
|
185
468
|
onSetOptionsHandlersRef.current.delete(handler);
|
|
186
469
|
};
|
|
187
470
|
}, []);
|
|
471
|
+
const registerOnSetComposerValue = useCallback(
|
|
472
|
+
(handler) => {
|
|
473
|
+
onSetComposerValueHandlersRef.current.add(handler);
|
|
474
|
+
return () => {
|
|
475
|
+
onSetComposerValueHandlersRef.current.delete(handler);
|
|
476
|
+
};
|
|
477
|
+
},
|
|
478
|
+
[]
|
|
479
|
+
);
|
|
480
|
+
const registerOnFocusComposer = useCallback(
|
|
481
|
+
(handler) => {
|
|
482
|
+
onFocusComposerHandlersRef.current.add(handler);
|
|
483
|
+
return () => {
|
|
484
|
+
onFocusComposerHandlersRef.current.delete(handler);
|
|
485
|
+
};
|
|
486
|
+
},
|
|
487
|
+
[]
|
|
488
|
+
);
|
|
188
489
|
useEffect(() => {
|
|
189
490
|
if (!isParentAvailable) return;
|
|
190
491
|
const sendResponse = (nonce, response, error) => {
|
|
@@ -205,7 +506,7 @@ function ParentMessengerProvider({
|
|
|
205
506
|
}
|
|
206
507
|
const payload = event.data;
|
|
207
508
|
if (payload.__xpaiChatKit !== true) return;
|
|
208
|
-
if (payload.type
|
|
509
|
+
if (payload.type === "command" && payload.command === "onSendUserMessage") {
|
|
209
510
|
const nonce = typeof payload.nonce === "string" ? payload.nonce : null;
|
|
210
511
|
if (nonce) {
|
|
211
512
|
if (handledSendUserMessageNonces.has(nonce)) return;
|
|
@@ -215,34 +516,53 @@ function ParentMessengerProvider({
|
|
|
215
516
|
handledSendUserMessageEvents.add(event);
|
|
216
517
|
}
|
|
217
518
|
const params = payload.data;
|
|
218
|
-
const prompt =
|
|
519
|
+
const prompt = typeof params.text === "string" ? params.text.trim() : typeof params.state?.[STATE_VARIABLE_HUMAN2]?.input === "string" ? params.state[STATE_VARIABLE_HUMAN2].input.trim() : "";
|
|
520
|
+
const references = normalizeReferences(
|
|
521
|
+
params.references ?? params.state?.[STATE_VARIABLE_HUMAN2]?.references
|
|
522
|
+
);
|
|
523
|
+
const referenceComposition = params.referenceComposition ?? params.state?.[STATE_VARIABLE_HUMAN2]?.referenceComposition;
|
|
524
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
525
|
+
content: prompt,
|
|
526
|
+
references,
|
|
527
|
+
referenceComposition
|
|
528
|
+
});
|
|
529
|
+
if (!humanInput) {
|
|
530
|
+
if (payload.nonce) {
|
|
531
|
+
sendResponse(payload.nonce, { ok: true });
|
|
532
|
+
}
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
219
535
|
const newMessage = {
|
|
220
536
|
id: createMessageId(),
|
|
221
537
|
type: "human",
|
|
222
|
-
content: prompt
|
|
538
|
+
content: prompt,
|
|
539
|
+
submittedInput: humanInput.input,
|
|
540
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
541
|
+
...references.length > 0 ? { references } : {}
|
|
223
542
|
};
|
|
543
|
+
const stream = streamRef2.current;
|
|
544
|
+
const activeFollowUpMode = stream?.isLoading ? params.followUpMode && params.followUpMode !== "default" ? params.followUpMode : stream.followUpBehavior ?? "queue" : void 0;
|
|
224
545
|
const requestOptions = buildInjectedRequestOptions({
|
|
225
546
|
defaults: latestOptionsRef.current?.request,
|
|
226
547
|
state: params.state,
|
|
227
|
-
humanInput
|
|
228
|
-
input: prompt
|
|
229
|
-
}
|
|
548
|
+
humanInput
|
|
230
549
|
});
|
|
231
|
-
|
|
550
|
+
stream?.submit(
|
|
232
551
|
{
|
|
233
|
-
input:
|
|
234
|
-
input: prompt
|
|
235
|
-
},
|
|
552
|
+
input: humanInput,
|
|
236
553
|
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
237
554
|
},
|
|
238
555
|
{
|
|
239
556
|
newThread: params.newThread,
|
|
557
|
+
...activeFollowUpMode ? { followUpMode: activeFollowUpMode } : {},
|
|
240
558
|
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
241
559
|
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
560
|
+
...!activeFollowUpMode ? {
|
|
561
|
+
optimisticValues: (prev) => {
|
|
562
|
+
const prevMessages = prev?.messages ?? [];
|
|
563
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
564
|
+
}
|
|
565
|
+
} : {}
|
|
246
566
|
}
|
|
247
567
|
);
|
|
248
568
|
if (payload.nonce) {
|
|
@@ -250,7 +570,28 @@ function ParentMessengerProvider({
|
|
|
250
570
|
}
|
|
251
571
|
return;
|
|
252
572
|
}
|
|
253
|
-
if (payload.type
|
|
573
|
+
if (payload.type === "command" && payload.command === "onSetComposerValue") {
|
|
574
|
+
const nextPayload = payload.data ?? null;
|
|
575
|
+
const normalizedPayload = nextPayload && Array.isArray(nextPayload.references) ? {
|
|
576
|
+
...nextPayload,
|
|
577
|
+
references: normalizeReferences(nextPayload.references)
|
|
578
|
+
} : nextPayload;
|
|
579
|
+
void Promise.all(
|
|
580
|
+
[...onSetComposerValueHandlersRef.current].map(
|
|
581
|
+
(handler2) => Promise.resolve(handler2(normalizedPayload))
|
|
582
|
+
)
|
|
583
|
+
).then(() => {
|
|
584
|
+
if (payload.nonce) {
|
|
585
|
+
sendResponse(payload.nonce, { ok: true });
|
|
586
|
+
}
|
|
587
|
+
}).catch((error) => {
|
|
588
|
+
if (payload.nonce) {
|
|
589
|
+
sendResponse(payload.nonce, void 0, error);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (payload.type === "command" && payload.command === "onSetOptions") {
|
|
254
595
|
latestOptionsRef.current = payload.data ?? null;
|
|
255
596
|
if (onSetOptionsHandlersRef.current.size > 0) {
|
|
256
597
|
onSetOptionsHandlersRef.current.forEach((handler2) => {
|
|
@@ -262,16 +603,41 @@ function ParentMessengerProvider({
|
|
|
262
603
|
}
|
|
263
604
|
return;
|
|
264
605
|
}
|
|
265
|
-
if (payload.type
|
|
606
|
+
if (payload.type === "command" && payload.command === "onFocusComposer") {
|
|
607
|
+
void Promise.all(
|
|
608
|
+
[...onFocusComposerHandlersRef.current].map(
|
|
609
|
+
(handler2) => Promise.resolve(handler2())
|
|
610
|
+
)
|
|
611
|
+
).then(() => {
|
|
612
|
+
if (payload.nonce) {
|
|
613
|
+
sendResponse(payload.nonce, { ok: true });
|
|
614
|
+
}
|
|
615
|
+
}).catch((error) => {
|
|
616
|
+
if (payload.nonce) {
|
|
617
|
+
sendResponse(payload.nonce, void 0, error);
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
if (payload.type === "command" && payload.command === "onSetThreadId") {
|
|
266
623
|
const data = payload.data;
|
|
267
624
|
const nextThreadId = data?.threadId ?? null;
|
|
268
625
|
const stream = streamRef2.current;
|
|
626
|
+
if (stream?.threadId === nextThreadId) {
|
|
627
|
+
if (payload.nonce) {
|
|
628
|
+
sendResponse(payload.nonce, { ok: true });
|
|
629
|
+
}
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
269
632
|
stream?.reset(nextThreadId, void 0, { suppressThreadChange: true });
|
|
270
633
|
if (stream && nextThreadId) {
|
|
271
634
|
stream.loadThread(nextThreadId).catch((err) => {
|
|
272
635
|
console.warn("Failed to load thread messages", err);
|
|
273
636
|
});
|
|
274
637
|
}
|
|
638
|
+
if (payload.nonce) {
|
|
639
|
+
sendResponse(payload.nonce, { ok: true });
|
|
640
|
+
}
|
|
275
641
|
return;
|
|
276
642
|
}
|
|
277
643
|
if (payload.type !== "response") return;
|
|
@@ -332,25 +698,55 @@ function ParentMessengerProvider({
|
|
|
332
698
|
isParentAvailable,
|
|
333
699
|
sendCommand,
|
|
334
700
|
sendEvent,
|
|
335
|
-
registerOnSetOptions
|
|
701
|
+
registerOnSetOptions,
|
|
702
|
+
registerOnSetComposerValue,
|
|
703
|
+
registerOnFocusComposer
|
|
336
704
|
}),
|
|
337
|
-
[
|
|
705
|
+
[
|
|
706
|
+
isParentAvailable,
|
|
707
|
+
sendCommand,
|
|
708
|
+
sendEvent,
|
|
709
|
+
registerOnSetOptions,
|
|
710
|
+
registerOnSetComposerValue,
|
|
711
|
+
registerOnFocusComposer
|
|
712
|
+
]
|
|
338
713
|
);
|
|
339
714
|
return /* @__PURE__ */ jsx(ParentMessengerContext.Provider, { value, children });
|
|
340
715
|
}
|
|
341
716
|
|
|
342
717
|
// src/hooks/useParentMessenger.tsx
|
|
343
|
-
function useParentMessenger({
|
|
718
|
+
function useParentMessenger({
|
|
719
|
+
onSetOptions,
|
|
720
|
+
onSetComposerValue,
|
|
721
|
+
onFocusComposer
|
|
722
|
+
} = {}) {
|
|
344
723
|
const context = useContext(ParentMessengerContext);
|
|
345
724
|
if (!context) {
|
|
346
|
-
throw new Error(
|
|
725
|
+
throw new Error(
|
|
726
|
+
"useParentMessenger must be used within a ParentMessengerProvider"
|
|
727
|
+
);
|
|
347
728
|
}
|
|
348
|
-
const {
|
|
729
|
+
const {
|
|
730
|
+
registerOnSetOptions,
|
|
731
|
+
registerOnSetComposerValue,
|
|
732
|
+
registerOnFocusComposer,
|
|
733
|
+
...messenger
|
|
734
|
+
} = context;
|
|
349
735
|
const onSetOptionsRef = useRef2(onSetOptions);
|
|
736
|
+
const onSetComposerValueRef = useRef2(onSetComposerValue);
|
|
737
|
+
const onFocusComposerRef = useRef2(onFocusComposer);
|
|
350
738
|
useEffect2(() => {
|
|
351
739
|
onSetOptionsRef.current = onSetOptions;
|
|
352
740
|
}, [onSetOptions]);
|
|
741
|
+
useEffect2(() => {
|
|
742
|
+
onSetComposerValueRef.current = onSetComposerValue;
|
|
743
|
+
}, [onSetComposerValue]);
|
|
744
|
+
useEffect2(() => {
|
|
745
|
+
onFocusComposerRef.current = onFocusComposer;
|
|
746
|
+
}, [onFocusComposer]);
|
|
353
747
|
const hasOnSetOptions = Boolean(onSetOptions);
|
|
748
|
+
const hasOnSetComposerValue = Boolean(onSetComposerValue);
|
|
749
|
+
const hasOnFocusComposer = Boolean(onFocusComposer);
|
|
354
750
|
useEffect2(() => {
|
|
355
751
|
if (!hasOnSetOptions) return;
|
|
356
752
|
const handler = (options) => {
|
|
@@ -358,6 +754,20 @@ function useParentMessenger({ onSetOptions } = {}) {
|
|
|
358
754
|
};
|
|
359
755
|
return registerOnSetOptions(handler);
|
|
360
756
|
}, [hasOnSetOptions, registerOnSetOptions]);
|
|
757
|
+
useEffect2(() => {
|
|
758
|
+
if (!hasOnSetComposerValue) return;
|
|
759
|
+
const handler = (payload) => {
|
|
760
|
+
onSetComposerValueRef.current?.(payload);
|
|
761
|
+
};
|
|
762
|
+
return registerOnSetComposerValue(handler);
|
|
763
|
+
}, [hasOnSetComposerValue, registerOnSetComposerValue]);
|
|
764
|
+
useEffect2(() => {
|
|
765
|
+
if (!hasOnFocusComposer) return;
|
|
766
|
+
const handler = () => {
|
|
767
|
+
onFocusComposerRef.current?.();
|
|
768
|
+
};
|
|
769
|
+
return registerOnFocusComposer(handler);
|
|
770
|
+
}, [hasOnFocusComposer, registerOnFocusComposer]);
|
|
361
771
|
return messenger;
|
|
362
772
|
}
|
|
363
773
|
|
|
@@ -522,12 +932,39 @@ var en_US_default = {
|
|
|
522
932
|
statusOnline: "Online",
|
|
523
933
|
missingConfigShort: "Missing ChatKit configuration.",
|
|
524
934
|
missingConfigDetail: "Missing ChatKit configuration. Check `VITE_XPERTAI_API_URL`, and the `clientSecret` prop.",
|
|
935
|
+
missingApiUrlShort: "Missing ChatKit API URL.",
|
|
936
|
+
missingApiUrlDetail: "Missing ChatKit API URL. Check `VITE_XPERTAI_API_URL` or `options.api.apiUrl`.",
|
|
937
|
+
missingClientSecretShort: "Missing ChatKit client secret.",
|
|
938
|
+
missingClientSecretDetail: "Missing ChatKit client secret. Check the `clientSecret` prop or `api.getClientSecret` integration.",
|
|
939
|
+
missingApiUrlAndClientSecretShort: "Missing ChatKit API URL and client secret.",
|
|
940
|
+
missingApiUrlAndClientSecretDetail: "Missing ChatKit API URL and client secret. Check `VITE_XPERTAI_API_URL`, `options.api.apiUrl`, and your client secret integration.",
|
|
525
941
|
loadingThread: "Loading thread...",
|
|
526
942
|
stop: "Stop",
|
|
527
943
|
send: "Send message",
|
|
944
|
+
referencedContentOnly: "Referenced content",
|
|
945
|
+
youLabel: "You",
|
|
528
946
|
scrollToBottom: "Scroll to bottom",
|
|
529
947
|
retryUpload: "Retry upload",
|
|
530
948
|
poweredBy: "Powered by Xpert AI",
|
|
949
|
+
followUps: {
|
|
950
|
+
label: "Follow-up behavior",
|
|
951
|
+
settings: "Settings",
|
|
952
|
+
idleHint: "Used when you send while a run is active.",
|
|
953
|
+
activeHint: "This message will use the selected busy-run behavior.",
|
|
954
|
+
pending: "Pending follow-ups",
|
|
955
|
+
queue: "Queue",
|
|
956
|
+
steer: "Steer",
|
|
957
|
+
steerAction: "Steer",
|
|
958
|
+
promoteToSteer: "Steer now",
|
|
959
|
+
sendNow: "Send now",
|
|
960
|
+
remove: "Remove pending follow-up",
|
|
961
|
+
more: "More actions",
|
|
962
|
+
edit: "Edit message",
|
|
963
|
+
turnOffQueueing: "Turn off queueing",
|
|
964
|
+
queueHint: "Starts after the current run finishes",
|
|
965
|
+
manualQueueHint: "Ready to send as a new run",
|
|
966
|
+
steerHint: "Injects after the current tool call"
|
|
967
|
+
},
|
|
531
968
|
errors: {
|
|
532
969
|
loadMessages: "Failed to load thread messages",
|
|
533
970
|
createThread: "Failed to create thread",
|
|
@@ -558,7 +995,9 @@ var en_US_default = {
|
|
|
558
995
|
},
|
|
559
996
|
composer: {
|
|
560
997
|
openMenu: "Open menu",
|
|
561
|
-
addAttachment: "Add attachment"
|
|
998
|
+
addAttachment: "Add attachment",
|
|
999
|
+
removeReference: "Remove reference",
|
|
1000
|
+
quoteSelection: "Quote selection"
|
|
562
1001
|
},
|
|
563
1002
|
sheet: {
|
|
564
1003
|
close: "Close"
|
|
@@ -573,7 +1012,10 @@ var en_US_default = {
|
|
|
573
1012
|
},
|
|
574
1013
|
message: {
|
|
575
1014
|
answer: "Answer",
|
|
576
|
-
reasoning: "Reasoning"
|
|
1015
|
+
reasoning: "Reasoning",
|
|
1016
|
+
loading: "Loading",
|
|
1017
|
+
thinking: "Thinking",
|
|
1018
|
+
answering: "Answering"
|
|
577
1019
|
}
|
|
578
1020
|
};
|
|
579
1021
|
|
|
@@ -585,12 +1027,39 @@ var zh_CN_default = {
|
|
|
585
1027
|
statusOnline: "\u5728\u7EBF",
|
|
586
1028
|
missingConfigShort: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002",
|
|
587
1029
|
missingConfigDetail: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u548C `clientSecret` \u53C2\u6570\u3002",
|
|
1030
|
+
missingApiUrlShort: "\u7F3A\u5C11 ChatKit API URL\u3002",
|
|
1031
|
+
missingApiUrlDetail: "\u7F3A\u5C11 ChatKit API URL\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u6216 `options.api.apiUrl`\u3002",
|
|
1032
|
+
missingClientSecretShort: "\u7F3A\u5C11 ChatKit client secret\u3002",
|
|
1033
|
+
missingClientSecretDetail: "\u7F3A\u5C11 ChatKit client secret\u3002\u8BF7\u68C0\u67E5 `clientSecret` \u53C2\u6570\u6216 `api.getClientSecret` \u96C6\u6210\u3002",
|
|
1034
|
+
missingApiUrlAndClientSecretShort: "\u7F3A\u5C11 ChatKit API URL \u548C client secret\u3002",
|
|
1035
|
+
missingApiUrlAndClientSecretDetail: "\u7F3A\u5C11 ChatKit API URL \u548C client secret\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL`\u3001`options.api.apiUrl` \u4EE5\u53CA client secret \u96C6\u6210\u3002",
|
|
588
1036
|
loadingThread: "\u6B63\u5728\u52A0\u8F7D\u7EBF\u7A0B...",
|
|
589
1037
|
stop: "\u505C\u6B62",
|
|
590
1038
|
send: "\u53D1\u9001\u6D88\u606F",
|
|
1039
|
+
referencedContentOnly: "\u5DF2\u5F15\u7528\u5185\u5BB9",
|
|
1040
|
+
youLabel: "\u4F60",
|
|
591
1041
|
scrollToBottom: "\u56DE\u5230\u5E95\u90E8",
|
|
592
1042
|
retryUpload: "\u91CD\u65B0\u4E0A\u4F20",
|
|
593
1043
|
poweredBy: "\u7531 Xpert AI \u9A71\u52A8",
|
|
1044
|
+
followUps: {
|
|
1045
|
+
label: "Follow-up \u6A21\u5F0F",
|
|
1046
|
+
settings: "\u8BBE\u7F6E",
|
|
1047
|
+
idleHint: "\u4EC5\u5728\u8FD0\u884C\u4E2D\u53D1\u9001\u6D88\u606F\u65F6\u751F\u6548\u3002",
|
|
1048
|
+
activeHint: "\u5F53\u524D\u6D88\u606F\u4F1A\u6309\u6240\u9009\u7684\u8FD0\u884C\u4E2D\u884C\u4E3A\u5904\u7406\u3002",
|
|
1049
|
+
pending: "\u5F85\u5904\u7406 Follow-up",
|
|
1050
|
+
queue: "\u6392\u961F",
|
|
1051
|
+
steer: "\u5F15\u5BFC",
|
|
1052
|
+
steerAction: "Steer",
|
|
1053
|
+
promoteToSteer: "\u8F6C\u4E3A\u5F15\u5BFC",
|
|
1054
|
+
sendNow: "\u7ACB\u5373\u53D1\u9001",
|
|
1055
|
+
remove: "\u79FB\u9664\u6B64\u5F85\u5904\u7406 Follow-up",
|
|
1056
|
+
more: "\u66F4\u591A\u64CD\u4F5C",
|
|
1057
|
+
edit: "\u7F16\u8F91\u6D88\u606F",
|
|
1058
|
+
turnOffQueueing: "\u5173\u95ED\u6392\u961F",
|
|
1059
|
+
queueHint: "\u5F53\u524D\u8FD0\u884C\u7ED3\u675F\u540E\u5F00\u542F\u4E0B\u4E00\u8F6E",
|
|
1060
|
+
manualQueueHint: "\u4FDD\u7559\u4E3A\u5F85\u53D1\u9001\uFF0C\u53EF\u624B\u52A8\u5F00\u542F\u65B0\u4E00\u8F6E",
|
|
1061
|
+
steerHint: "\u5F53\u524D\u5DE5\u5177\u8C03\u7528\u5B8C\u6210\u540E\u6CE8\u5165"
|
|
1062
|
+
},
|
|
594
1063
|
errors: {
|
|
595
1064
|
loadMessages: "\u52A0\u8F7D\u7EBF\u7A0B\u6D88\u606F\u5931\u8D25",
|
|
596
1065
|
createThread: "\u521B\u5EFA\u7EBF\u7A0B\u5931\u8D25",
|
|
@@ -621,7 +1090,9 @@ var zh_CN_default = {
|
|
|
621
1090
|
},
|
|
622
1091
|
composer: {
|
|
623
1092
|
openMenu: "\u6253\u5F00\u83DC\u5355",
|
|
624
|
-
addAttachment: "\u6DFB\u52A0\u9644\u4EF6"
|
|
1093
|
+
addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1094
|
+
removeReference: "\u79FB\u9664\u5F15\u7528",
|
|
1095
|
+
quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
|
|
625
1096
|
},
|
|
626
1097
|
sheet: {
|
|
627
1098
|
close: "\u5173\u95ED"
|
|
@@ -636,7 +1107,10 @@ var zh_CN_default = {
|
|
|
636
1107
|
},
|
|
637
1108
|
message: {
|
|
638
1109
|
answer: "\u56DE\u7B54",
|
|
639
|
-
reasoning: "\u63A8\u7406"
|
|
1110
|
+
reasoning: "\u63A8\u7406",
|
|
1111
|
+
loading: "\u6B63\u5728\u52A0\u8F7D",
|
|
1112
|
+
thinking: "\u6B63\u5728\u601D\u8003",
|
|
1113
|
+
answering: "\u6B63\u5728\u751F\u6210"
|
|
640
1114
|
}
|
|
641
1115
|
};
|
|
642
1116
|
|
|
@@ -1161,13 +1635,14 @@ import { jsx as jsx7 } from "react/jsx-runtime";
|
|
|
1161
1635
|
function SendButton({
|
|
1162
1636
|
disabled = false,
|
|
1163
1637
|
isLoading = false,
|
|
1638
|
+
showStop = isLoading,
|
|
1164
1639
|
onStop,
|
|
1165
1640
|
stopLabel = "Stop",
|
|
1166
1641
|
sendLabel = "Send"
|
|
1167
1642
|
}) {
|
|
1168
1643
|
const { theme } = useTheme();
|
|
1169
1644
|
const roundedClass = getRoundedClass(theme.radius);
|
|
1170
|
-
if (
|
|
1645
|
+
if (showStop) {
|
|
1171
1646
|
return /* @__PURE__ */ jsx7(
|
|
1172
1647
|
"button",
|
|
1173
1648
|
{
|
|
@@ -1416,103 +1891,471 @@ function HistorySidebar({
|
|
|
1416
1891
|
] });
|
|
1417
1892
|
}
|
|
1418
1893
|
|
|
1419
|
-
// src/components/
|
|
1420
|
-
import * as React13 from "react";
|
|
1421
|
-
import { ChevronDown, CheckCircle2, XCircle, Loader2 } from "lucide-react";
|
|
1422
|
-
|
|
1423
|
-
// src/components/ui/badge.tsx
|
|
1424
|
-
import * as React9 from "react";
|
|
1425
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1426
|
-
var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
|
|
1427
|
-
var variants = {
|
|
1428
|
-
default: "bg-primary text-primary-foreground",
|
|
1429
|
-
secondary: "bg-secondary text-secondary-foreground",
|
|
1430
|
-
outline: "border-input text-foreground"
|
|
1431
|
-
};
|
|
1432
|
-
var Badge = React9.forwardRef(
|
|
1433
|
-
({ className, variant = "default", ...props }, ref) => {
|
|
1434
|
-
return /* @__PURE__ */ jsx11("span", { ref, className: cn(base, variants[variant], className), ...props });
|
|
1435
|
-
}
|
|
1436
|
-
);
|
|
1437
|
-
Badge.displayName = "Badge";
|
|
1438
|
-
|
|
1439
|
-
// src/components/ui/card.tsx
|
|
1894
|
+
// src/components/composer/pending-follow-ups.tsx
|
|
1440
1895
|
import * as React10 from "react";
|
|
1441
|
-
import {
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1896
|
+
import {
|
|
1897
|
+
CornerDownLeft,
|
|
1898
|
+
Ellipsis,
|
|
1899
|
+
Info,
|
|
1900
|
+
PencilLine,
|
|
1901
|
+
SlidersHorizontal as SlidersHorizontal2,
|
|
1902
|
+
Trash2 as Trash22
|
|
1903
|
+
} from "lucide-react";
|
|
1904
|
+
|
|
1905
|
+
// src/components/ui/tooltip.tsx
|
|
1906
|
+
import "react";
|
|
1907
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
1908
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1909
|
+
function TooltipProvider({
|
|
1910
|
+
delayDuration = 0,
|
|
1911
|
+
...props
|
|
1912
|
+
}) {
|
|
1913
|
+
return /* @__PURE__ */ jsx11(
|
|
1914
|
+
TooltipPrimitive.Provider,
|
|
1445
1915
|
{
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
"rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
|
|
1449
|
-
className
|
|
1450
|
-
),
|
|
1916
|
+
"data-slot": "tooltip-provider",
|
|
1917
|
+
delayDuration,
|
|
1451
1918
|
...props
|
|
1452
1919
|
}
|
|
1453
|
-
)
|
|
1454
|
-
);
|
|
1455
|
-
Card.displayName = "Card";
|
|
1456
|
-
var CardHeader = React10.forwardRef(
|
|
1457
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx12("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
|
|
1458
|
-
);
|
|
1459
|
-
CardHeader.displayName = "CardHeader";
|
|
1460
|
-
var CardTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
|
|
1461
|
-
CardTitle.displayName = "CardTitle";
|
|
1462
|
-
var CardDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1463
|
-
CardDescription.displayName = "CardDescription";
|
|
1464
|
-
var CardContent = React10.forwardRef(
|
|
1465
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx12("div", { ref, className: cn("px-6 pb-6", className), ...props })
|
|
1466
|
-
);
|
|
1467
|
-
CardContent.displayName = "CardContent";
|
|
1468
|
-
var CardFooter = React10.forwardRef(
|
|
1469
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx12("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
|
|
1470
|
-
);
|
|
1471
|
-
CardFooter.displayName = "CardFooter";
|
|
1472
|
-
var CardAction = React10.forwardRef(
|
|
1473
|
-
({ className, ...props }, ref) => /* @__PURE__ */ jsx12("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
|
|
1474
|
-
);
|
|
1475
|
-
CardAction.displayName = "CardAction";
|
|
1476
|
-
|
|
1477
|
-
// src/components/ui/tabs.tsx
|
|
1478
|
-
import * as React11 from "react";
|
|
1479
|
-
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1480
|
-
var TabsContext = React11.createContext(null);
|
|
1481
|
-
function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
|
|
1482
|
-
const [internalValue, setInternalValue] = React11.useState(defaultValue ?? "");
|
|
1483
|
-
const activeValue = value ?? internalValue;
|
|
1484
|
-
const setValue = React11.useCallback(
|
|
1485
|
-
(nextValue) => {
|
|
1486
|
-
if (value === void 0) setInternalValue(nextValue);
|
|
1487
|
-
onValueChange?.(nextValue);
|
|
1488
|
-
},
|
|
1489
|
-
[onValueChange, value]
|
|
1490
1920
|
);
|
|
1491
|
-
return /* @__PURE__ */ jsx13(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx13("div", { className: cn("w-full", className), ...props }) });
|
|
1492
1921
|
}
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1922
|
+
function Tooltip({
|
|
1923
|
+
...props
|
|
1924
|
+
}) {
|
|
1925
|
+
return /* @__PURE__ */ jsx11(TooltipProvider, { children: /* @__PURE__ */ jsx11(
|
|
1926
|
+
TooltipPrimitive.Root,
|
|
1496
1927
|
{
|
|
1497
|
-
|
|
1928
|
+
"data-slot": "tooltip",
|
|
1929
|
+
...props
|
|
1930
|
+
}
|
|
1931
|
+
) });
|
|
1932
|
+
}
|
|
1933
|
+
function TooltipTrigger({
|
|
1934
|
+
...props
|
|
1935
|
+
}) {
|
|
1936
|
+
return /* @__PURE__ */ jsx11(
|
|
1937
|
+
TooltipPrimitive.Trigger,
|
|
1938
|
+
{
|
|
1939
|
+
"data-slot": "tooltip-trigger",
|
|
1940
|
+
...props
|
|
1941
|
+
}
|
|
1942
|
+
);
|
|
1943
|
+
}
|
|
1944
|
+
function TooltipContent({
|
|
1945
|
+
className,
|
|
1946
|
+
sideOffset = 0,
|
|
1947
|
+
children,
|
|
1948
|
+
...props
|
|
1949
|
+
}) {
|
|
1950
|
+
return /* @__PURE__ */ jsx11(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs5(
|
|
1951
|
+
TooltipPrimitive.Content,
|
|
1952
|
+
{
|
|
1953
|
+
"data-slot": "tooltip-content",
|
|
1954
|
+
sideOffset,
|
|
1498
1955
|
className: cn(
|
|
1499
|
-
"
|
|
1956
|
+
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance",
|
|
1500
1957
|
className
|
|
1501
1958
|
),
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
TabsList.displayName = "TabsList";
|
|
1508
|
-
var TabsTrigger = React11.forwardRef(
|
|
1509
|
-
({ className, value, onClick, ...props }, ref) => {
|
|
1510
|
-
const context = React11.useContext(TabsContext);
|
|
1511
|
-
if (!context) {
|
|
1512
|
-
throw new Error("TabsTrigger must be used within Tabs");
|
|
1959
|
+
...props,
|
|
1960
|
+
children: [
|
|
1961
|
+
children,
|
|
1962
|
+
/* @__PURE__ */ jsx11(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
1963
|
+
]
|
|
1513
1964
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1965
|
+
) });
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1968
|
+
// src/components/composer/pending-follow-ups.tsx
|
|
1969
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1970
|
+
function getPendingFollowUpText(item, referencedContentFallback) {
|
|
1971
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
1972
|
+
if (text) {
|
|
1973
|
+
return text;
|
|
1974
|
+
}
|
|
1975
|
+
const references = normalizeReferences(item.request?.input?.references);
|
|
1976
|
+
if (references.length === 0) {
|
|
1977
|
+
return referencedContentFallback;
|
|
1978
|
+
}
|
|
1979
|
+
const firstReferenceLabel = getReferenceLabel(references[0]);
|
|
1980
|
+
if (references.length === 1) {
|
|
1981
|
+
return firstReferenceLabel;
|
|
1982
|
+
}
|
|
1983
|
+
return `${firstReferenceLabel} +${references.length - 1}`;
|
|
1984
|
+
}
|
|
1985
|
+
function useRoundedClasses() {
|
|
1986
|
+
const { theme } = useTheme();
|
|
1987
|
+
return {
|
|
1988
|
+
top: theme.radius ? {
|
|
1989
|
+
pill: "rounded-t-full",
|
|
1990
|
+
round: "rounded-t-xl",
|
|
1991
|
+
soft: "rounded-t-lg",
|
|
1992
|
+
sharp: "rounded-t-none"
|
|
1993
|
+
}[theme.radius] : "rounded-t-lg",
|
|
1994
|
+
panel: getRoundedClass(theme.radius, "rounded-lg"),
|
|
1995
|
+
control: getRoundedClass(theme.radius, "rounded-md")
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
function PendingFollowUps({
|
|
1999
|
+
items,
|
|
2000
|
+
isLoading,
|
|
2001
|
+
followUpBehavior,
|
|
2002
|
+
onBehaviorChange,
|
|
2003
|
+
onPromoteToSteer,
|
|
2004
|
+
canSendNow,
|
|
2005
|
+
onSendNow,
|
|
2006
|
+
onEdit,
|
|
2007
|
+
onRemove,
|
|
2008
|
+
className
|
|
2009
|
+
}) {
|
|
2010
|
+
const { t } = useChatkitTranslation();
|
|
2011
|
+
const rounded = useRoundedClasses();
|
|
2012
|
+
const referencedContentFallback = t("chat.referencedContentOnly");
|
|
2013
|
+
const [isSettingsOpen, setIsSettingsOpen] = React10.useState(false);
|
|
2014
|
+
const [openMenuId, setOpenMenuId] = React10.useState(null);
|
|
2015
|
+
React10.useEffect(() => {
|
|
2016
|
+
if (items.length === 0 && isSettingsOpen) {
|
|
2017
|
+
setIsSettingsOpen(false);
|
|
2018
|
+
}
|
|
2019
|
+
if (items.every((item) => item.id !== openMenuId)) {
|
|
2020
|
+
setOpenMenuId(null);
|
|
2021
|
+
}
|
|
2022
|
+
}, [isSettingsOpen, items, openMenuId]);
|
|
2023
|
+
if (items.length === 0) {
|
|
2024
|
+
return null;
|
|
2025
|
+
}
|
|
2026
|
+
return /* @__PURE__ */ jsx12(
|
|
2027
|
+
"div",
|
|
2028
|
+
{
|
|
2029
|
+
className: cn(
|
|
2030
|
+
"space-y-2 mx-2 p-2 border border-border border-b-0",
|
|
2031
|
+
rounded.top,
|
|
2032
|
+
className
|
|
2033
|
+
),
|
|
2034
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "space-y-1", children: [
|
|
2035
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2036
|
+
/* @__PURE__ */ jsx12("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.pending") }),
|
|
2037
|
+
/* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
2038
|
+
/* @__PURE__ */ jsx12(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
|
|
2039
|
+
"button",
|
|
2040
|
+
{
|
|
2041
|
+
type: "button",
|
|
2042
|
+
onClick: () => setIsSettingsOpen((prev) => !prev),
|
|
2043
|
+
className: cn(
|
|
2044
|
+
"inline-flex h-6 w-6 items-center justify-center transition-colors",
|
|
2045
|
+
isSettingsOpen ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground",
|
|
2046
|
+
rounded.control
|
|
2047
|
+
),
|
|
2048
|
+
"aria-label": t("chat.followUps.settings"),
|
|
2049
|
+
"aria-expanded": isSettingsOpen,
|
|
2050
|
+
"aria-controls": "follow-ups-settings-panel",
|
|
2051
|
+
children: [
|
|
2052
|
+
/* @__PURE__ */ jsx12(SlidersHorizontal2, { className: "h-3.5 w-3.5" }),
|
|
2053
|
+
/* @__PURE__ */ jsx12("span", { className: "sr-only", children: t("chat.followUps.settings") })
|
|
2054
|
+
]
|
|
2055
|
+
}
|
|
2056
|
+
) }),
|
|
2057
|
+
/* @__PURE__ */ jsx12(TooltipContent, { side: "top", children: t("chat.followUps.settings") })
|
|
2058
|
+
] })
|
|
2059
|
+
] }),
|
|
2060
|
+
isSettingsOpen && /* @__PURE__ */ jsx12(
|
|
2061
|
+
"div",
|
|
2062
|
+
{
|
|
2063
|
+
id: "follow-ups-settings-panel",
|
|
2064
|
+
className: cn(
|
|
2065
|
+
"border border-border/70 bg-muted/20 px-3 py-2",
|
|
2066
|
+
rounded.panel
|
|
2067
|
+
),
|
|
2068
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2069
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
|
|
2070
|
+
/* @__PURE__ */ jsx12("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.label") }),
|
|
2071
|
+
/* @__PURE__ */ jsx12("div", { className: "text-[11px] text-muted-foreground", children: isLoading ? t("chat.followUps.activeHint") : t("chat.followUps.idleHint") })
|
|
2072
|
+
] }),
|
|
2073
|
+
/* @__PURE__ */ jsx12(
|
|
2074
|
+
"div",
|
|
2075
|
+
{
|
|
2076
|
+
className: cn(
|
|
2077
|
+
"inline-flex shrink-0 border border-border bg-background p-1",
|
|
2078
|
+
rounded.control
|
|
2079
|
+
),
|
|
2080
|
+
children: ["queue", "steer"].map((behavior) => /* @__PURE__ */ jsxs6(Tooltip, { children: [
|
|
2081
|
+
/* @__PURE__ */ jsx12(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2082
|
+
"button",
|
|
2083
|
+
{
|
|
2084
|
+
type: "button",
|
|
2085
|
+
onClick: () => {
|
|
2086
|
+
onBehaviorChange(behavior);
|
|
2087
|
+
setIsSettingsOpen(false);
|
|
2088
|
+
},
|
|
2089
|
+
className: cn(
|
|
2090
|
+
"px-3 py-1 text-xs font-medium transition-colors",
|
|
2091
|
+
rounded.control,
|
|
2092
|
+
followUpBehavior === behavior ? "bg-primary text-background" : "text-muted-foreground hover:text-foreground"
|
|
2093
|
+
),
|
|
2094
|
+
children: behavior === "queue" ? t("chat.followUps.queue") : t("chat.followUps.steer")
|
|
2095
|
+
}
|
|
2096
|
+
) }),
|
|
2097
|
+
/* @__PURE__ */ jsx12(TooltipContent, { side: "top", children: behavior === "queue" ? t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2098
|
+
] }, behavior))
|
|
2099
|
+
}
|
|
2100
|
+
)
|
|
2101
|
+
] })
|
|
2102
|
+
}
|
|
2103
|
+
),
|
|
2104
|
+
items.map((item) => {
|
|
2105
|
+
const canSendItemNow = item.mode === "queue" && canSendNow(item.id);
|
|
2106
|
+
return /* @__PURE__ */ jsx12(
|
|
2107
|
+
"div",
|
|
2108
|
+
{
|
|
2109
|
+
className: cn(
|
|
2110
|
+
"border border-border/50 bg-muted/15 px-2 py-1",
|
|
2111
|
+
rounded.panel
|
|
2112
|
+
),
|
|
2113
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2.5", children: [
|
|
2114
|
+
/* @__PURE__ */ jsx12(CornerDownLeft, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2115
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
2116
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-start gap-2", children: [
|
|
2117
|
+
/* @__PURE__ */ jsx12("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx12(
|
|
2118
|
+
"div",
|
|
2119
|
+
{
|
|
2120
|
+
className: "truncate text-[13px] leading-5 text-foreground",
|
|
2121
|
+
title: getPendingFollowUpText(
|
|
2122
|
+
item,
|
|
2123
|
+
referencedContentFallback
|
|
2124
|
+
),
|
|
2125
|
+
children: getPendingFollowUpText(
|
|
2126
|
+
item,
|
|
2127
|
+
referencedContentFallback
|
|
2128
|
+
)
|
|
2129
|
+
}
|
|
2130
|
+
) }),
|
|
2131
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2132
|
+
item.mode === "queue" && isLoading && /* @__PURE__ */ jsx12(
|
|
2133
|
+
"button",
|
|
2134
|
+
{
|
|
2135
|
+
type: "button",
|
|
2136
|
+
onClick: () => void onPromoteToSteer(item.id),
|
|
2137
|
+
className: cn(
|
|
2138
|
+
"inline-flex h-6 items-center border border-primary/20 bg-primary/5 px-2 text-[11px] font-medium text-primary transition-colors hover:bg-primary/10",
|
|
2139
|
+
rounded.control
|
|
2140
|
+
),
|
|
2141
|
+
"aria-label": t("chat.followUps.steerAction"),
|
|
2142
|
+
title: t("chat.followUps.steerAction"),
|
|
2143
|
+
children: t("chat.followUps.steerAction")
|
|
2144
|
+
}
|
|
2145
|
+
),
|
|
2146
|
+
canSendItemNow && /* @__PURE__ */ jsx12(
|
|
2147
|
+
"button",
|
|
2148
|
+
{
|
|
2149
|
+
type: "button",
|
|
2150
|
+
onClick: () => void onSendNow(item.id),
|
|
2151
|
+
className: cn(
|
|
2152
|
+
"inline-flex h-6 items-center border border-primary/20 bg-primary/5 px-2 text-[11px] font-medium text-primary transition-colors hover:bg-primary/10",
|
|
2153
|
+
rounded.control
|
|
2154
|
+
),
|
|
2155
|
+
"aria-label": t("chat.followUps.sendNow"),
|
|
2156
|
+
title: t("chat.followUps.sendNow"),
|
|
2157
|
+
children: t("chat.followUps.sendNow")
|
|
2158
|
+
}
|
|
2159
|
+
),
|
|
2160
|
+
item.mode === "queue" && /* @__PURE__ */ jsx12(
|
|
2161
|
+
"button",
|
|
2162
|
+
{
|
|
2163
|
+
type: "button",
|
|
2164
|
+
onClick: () => onRemove(item.id),
|
|
2165
|
+
className: cn(
|
|
2166
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2167
|
+
rounded.control
|
|
2168
|
+
),
|
|
2169
|
+
"aria-label": t("chat.followUps.remove"),
|
|
2170
|
+
title: t("chat.followUps.remove"),
|
|
2171
|
+
children: /* @__PURE__ */ jsx12(Trash22, { size: 13 })
|
|
2172
|
+
}
|
|
2173
|
+
),
|
|
2174
|
+
item.mode === "queue" && /* @__PURE__ */ jsxs6(
|
|
2175
|
+
Popover,
|
|
2176
|
+
{
|
|
2177
|
+
open: openMenuId === item.id,
|
|
2178
|
+
onOpenChange: (open) => setOpenMenuId(open ? item.id : null),
|
|
2179
|
+
children: [
|
|
2180
|
+
/* @__PURE__ */ jsx12(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2181
|
+
"button",
|
|
2182
|
+
{
|
|
2183
|
+
type: "button",
|
|
2184
|
+
className: cn(
|
|
2185
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2186
|
+
rounded.control
|
|
2187
|
+
),
|
|
2188
|
+
"aria-label": t("chat.followUps.more"),
|
|
2189
|
+
title: t("chat.followUps.more"),
|
|
2190
|
+
children: /* @__PURE__ */ jsx12(Ellipsis, { size: 13 })
|
|
2191
|
+
}
|
|
2192
|
+
) }),
|
|
2193
|
+
/* @__PURE__ */ jsx12(
|
|
2194
|
+
PopoverContent,
|
|
2195
|
+
{
|
|
2196
|
+
align: "end",
|
|
2197
|
+
side: "bottom",
|
|
2198
|
+
className: cn(
|
|
2199
|
+
"w-52 border-border/70 bg-background p-1.5",
|
|
2200
|
+
rounded.panel
|
|
2201
|
+
),
|
|
2202
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-1", children: [
|
|
2203
|
+
/* @__PURE__ */ jsxs6(
|
|
2204
|
+
"button",
|
|
2205
|
+
{
|
|
2206
|
+
type: "button",
|
|
2207
|
+
onClick: () => {
|
|
2208
|
+
setOpenMenuId(null);
|
|
2209
|
+
onEdit(item.id);
|
|
2210
|
+
},
|
|
2211
|
+
className: cn(
|
|
2212
|
+
"flex items-center gap-2 px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted",
|
|
2213
|
+
rounded.control
|
|
2214
|
+
),
|
|
2215
|
+
children: [
|
|
2216
|
+
/* @__PURE__ */ jsx12(PencilLine, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2217
|
+
/* @__PURE__ */ jsx12("span", { children: t("chat.followUps.edit") })
|
|
2218
|
+
]
|
|
2219
|
+
}
|
|
2220
|
+
),
|
|
2221
|
+
/* @__PURE__ */ jsxs6(
|
|
2222
|
+
"button",
|
|
2223
|
+
{
|
|
2224
|
+
type: "button",
|
|
2225
|
+
onClick: () => {
|
|
2226
|
+
setOpenMenuId(null);
|
|
2227
|
+
onBehaviorChange("steer");
|
|
2228
|
+
},
|
|
2229
|
+
className: cn(
|
|
2230
|
+
"flex items-center gap-2 px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted",
|
|
2231
|
+
rounded.control
|
|
2232
|
+
),
|
|
2233
|
+
children: [
|
|
2234
|
+
/* @__PURE__ */ jsx12(CornerDownLeft, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2235
|
+
/* @__PURE__ */ jsx12("span", { children: t("chat.followUps.turnOffQueueing") })
|
|
2236
|
+
]
|
|
2237
|
+
}
|
|
2238
|
+
)
|
|
2239
|
+
] })
|
|
2240
|
+
}
|
|
2241
|
+
)
|
|
2242
|
+
]
|
|
2243
|
+
}
|
|
2244
|
+
)
|
|
2245
|
+
] })
|
|
2246
|
+
] }),
|
|
2247
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1.5 text-[10px] leading-4 text-muted-foreground", children: [
|
|
2248
|
+
/* @__PURE__ */ jsx12(Info, { className: "h-3 w-3 shrink-0" }),
|
|
2249
|
+
/* @__PURE__ */ jsx12("span", { className: "truncate", children: item.mode === "queue" ? canSendItemNow ? t("chat.followUps.manualQueueHint") : t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2250
|
+
] })
|
|
2251
|
+
] })
|
|
2252
|
+
] })
|
|
2253
|
+
},
|
|
2254
|
+
item.id
|
|
2255
|
+
);
|
|
2256
|
+
})
|
|
2257
|
+
] })
|
|
2258
|
+
}
|
|
2259
|
+
);
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
// src/components/thread/messages/ai.tsx
|
|
2263
|
+
import * as React14 from "react";
|
|
2264
|
+
import { ChevronDown, CheckCircle2, XCircle, Loader2 } from "lucide-react";
|
|
2265
|
+
|
|
2266
|
+
// src/components/ui/badge.tsx
|
|
2267
|
+
import * as React11 from "react";
|
|
2268
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2269
|
+
var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
|
|
2270
|
+
var variants = {
|
|
2271
|
+
default: "bg-primary text-primary-foreground",
|
|
2272
|
+
secondary: "bg-secondary text-secondary-foreground",
|
|
2273
|
+
outline: "border-input text-foreground"
|
|
2274
|
+
};
|
|
2275
|
+
var Badge = React11.forwardRef(
|
|
2276
|
+
({ className, variant = "default", ...props }, ref) => {
|
|
2277
|
+
return /* @__PURE__ */ jsx13("span", { ref, className: cn(base, variants[variant], className), ...props });
|
|
2278
|
+
}
|
|
2279
|
+
);
|
|
2280
|
+
Badge.displayName = "Badge";
|
|
2281
|
+
|
|
2282
|
+
// src/components/ui/card.tsx
|
|
2283
|
+
import * as React12 from "react";
|
|
2284
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2285
|
+
var Card = React12.forwardRef(
|
|
2286
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
|
|
2287
|
+
"div",
|
|
2288
|
+
{
|
|
2289
|
+
ref,
|
|
2290
|
+
className: cn(
|
|
2291
|
+
"rounded-xl border bg-background/80 text-foreground shadow-[0_14px_40px_-30px_rgba(15,23,42,0.5)] backdrop-blur",
|
|
2292
|
+
className
|
|
2293
|
+
),
|
|
2294
|
+
...props
|
|
2295
|
+
}
|
|
2296
|
+
)
|
|
2297
|
+
);
|
|
2298
|
+
Card.displayName = "Card";
|
|
2299
|
+
var CardHeader = React12.forwardRef(
|
|
2300
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
|
|
2301
|
+
);
|
|
2302
|
+
CardHeader.displayName = "CardHeader";
|
|
2303
|
+
var CardTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
|
|
2304
|
+
CardTitle.displayName = "CardTitle";
|
|
2305
|
+
var CardDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
2306
|
+
CardDescription.displayName = "CardDescription";
|
|
2307
|
+
var CardContent = React12.forwardRef(
|
|
2308
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("px-6 pb-6", className), ...props })
|
|
2309
|
+
);
|
|
2310
|
+
CardContent.displayName = "CardContent";
|
|
2311
|
+
var CardFooter = React12.forwardRef(
|
|
2312
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
|
|
2313
|
+
);
|
|
2314
|
+
CardFooter.displayName = "CardFooter";
|
|
2315
|
+
var CardAction = React12.forwardRef(
|
|
2316
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
|
|
2317
|
+
);
|
|
2318
|
+
CardAction.displayName = "CardAction";
|
|
2319
|
+
|
|
2320
|
+
// src/components/ui/tabs.tsx
|
|
2321
|
+
import * as React13 from "react";
|
|
2322
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
2323
|
+
var TabsContext = React13.createContext(null);
|
|
2324
|
+
function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
|
|
2325
|
+
const [internalValue, setInternalValue] = React13.useState(defaultValue ?? "");
|
|
2326
|
+
const activeValue = value ?? internalValue;
|
|
2327
|
+
const setValue = React13.useCallback(
|
|
2328
|
+
(nextValue) => {
|
|
2329
|
+
if (value === void 0) setInternalValue(nextValue);
|
|
2330
|
+
onValueChange?.(nextValue);
|
|
2331
|
+
},
|
|
2332
|
+
[onValueChange, value]
|
|
2333
|
+
);
|
|
2334
|
+
return /* @__PURE__ */ jsx15(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx15("div", { className: cn("w-full", className), ...props }) });
|
|
2335
|
+
}
|
|
2336
|
+
var TabsList = React13.forwardRef(
|
|
2337
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
2338
|
+
"div",
|
|
2339
|
+
{
|
|
2340
|
+
ref,
|
|
2341
|
+
className: cn(
|
|
2342
|
+
"inline-flex h-11 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
2343
|
+
className
|
|
2344
|
+
),
|
|
2345
|
+
role: "tablist",
|
|
2346
|
+
...props
|
|
2347
|
+
}
|
|
2348
|
+
)
|
|
2349
|
+
);
|
|
2350
|
+
TabsList.displayName = "TabsList";
|
|
2351
|
+
var TabsTrigger = React13.forwardRef(
|
|
2352
|
+
({ className, value, onClick, ...props }, ref) => {
|
|
2353
|
+
const context = React13.useContext(TabsContext);
|
|
2354
|
+
if (!context) {
|
|
2355
|
+
throw new Error("TabsTrigger must be used within Tabs");
|
|
2356
|
+
}
|
|
2357
|
+
const isActive = context.value === value;
|
|
2358
|
+
return /* @__PURE__ */ jsx15(
|
|
1516
2359
|
"button",
|
|
1517
2360
|
{
|
|
1518
2361
|
ref,
|
|
@@ -1534,14 +2377,14 @@ var TabsTrigger = React11.forwardRef(
|
|
|
1534
2377
|
}
|
|
1535
2378
|
);
|
|
1536
2379
|
TabsTrigger.displayName = "TabsTrigger";
|
|
1537
|
-
var TabsContent =
|
|
2380
|
+
var TabsContent = React13.forwardRef(
|
|
1538
2381
|
({ className, value, ...props }, ref) => {
|
|
1539
|
-
const context =
|
|
2382
|
+
const context = React13.useContext(TabsContext);
|
|
1540
2383
|
if (!context) {
|
|
1541
2384
|
throw new Error("TabsContent must be used within Tabs");
|
|
1542
2385
|
}
|
|
1543
2386
|
if (context.value !== value) return null;
|
|
1544
|
-
return /* @__PURE__ */
|
|
2387
|
+
return /* @__PURE__ */ jsx15(
|
|
1545
2388
|
"div",
|
|
1546
2389
|
{
|
|
1547
2390
|
ref,
|
|
@@ -1565,7 +2408,7 @@ import remarkMath from "remark-math";
|
|
|
1565
2408
|
import {
|
|
1566
2409
|
Children,
|
|
1567
2410
|
memo,
|
|
1568
|
-
useState as
|
|
2411
|
+
useState as useState6
|
|
1569
2412
|
} from "react";
|
|
1570
2413
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
1571
2414
|
|
|
@@ -1575,7 +2418,7 @@ import tsx from "react-syntax-highlighter/dist/esm/languages/prism/tsx";
|
|
|
1575
2418
|
import python from "react-syntax-highlighter/dist/esm/languages/prism/python";
|
|
1576
2419
|
import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
|
1577
2420
|
import "react";
|
|
1578
|
-
import { jsx as
|
|
2421
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1579
2422
|
SyntaxHighlighterPrism.registerLanguage("js", tsx);
|
|
1580
2423
|
SyntaxHighlighterPrism.registerLanguage("jsx", tsx);
|
|
1581
2424
|
SyntaxHighlighterPrism.registerLanguage("ts", tsx);
|
|
@@ -1586,7 +2429,7 @@ var SyntaxHighlighter = ({
|
|
|
1586
2429
|
language,
|
|
1587
2430
|
className
|
|
1588
2431
|
}) => {
|
|
1589
|
-
return /* @__PURE__ */
|
|
2432
|
+
return /* @__PURE__ */ jsx16(
|
|
1590
2433
|
SyntaxHighlighterPrism,
|
|
1591
2434
|
{
|
|
1592
2435
|
language,
|
|
@@ -1605,75 +2448,10 @@ var SyntaxHighlighter = ({
|
|
|
1605
2448
|
|
|
1606
2449
|
// src/components/thread/tooltip-icon-button.tsx
|
|
1607
2450
|
import { forwardRef as forwardRef5 } from "react";
|
|
1608
|
-
|
|
1609
|
-
// src/components/ui/tooltip.tsx
|
|
1610
|
-
import "react";
|
|
1611
|
-
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
1612
|
-
import { jsx as jsx15, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1613
|
-
function TooltipProvider({
|
|
1614
|
-
delayDuration = 0,
|
|
1615
|
-
...props
|
|
1616
|
-
}) {
|
|
1617
|
-
return /* @__PURE__ */ jsx15(
|
|
1618
|
-
TooltipPrimitive.Provider,
|
|
1619
|
-
{
|
|
1620
|
-
"data-slot": "tooltip-provider",
|
|
1621
|
-
delayDuration,
|
|
1622
|
-
...props
|
|
1623
|
-
}
|
|
1624
|
-
);
|
|
1625
|
-
}
|
|
1626
|
-
function Tooltip({
|
|
1627
|
-
...props
|
|
1628
|
-
}) {
|
|
1629
|
-
return /* @__PURE__ */ jsx15(TooltipProvider, { children: /* @__PURE__ */ jsx15(
|
|
1630
|
-
TooltipPrimitive.Root,
|
|
1631
|
-
{
|
|
1632
|
-
"data-slot": "tooltip",
|
|
1633
|
-
...props
|
|
1634
|
-
}
|
|
1635
|
-
) });
|
|
1636
|
-
}
|
|
1637
|
-
function TooltipTrigger({
|
|
1638
|
-
...props
|
|
1639
|
-
}) {
|
|
1640
|
-
return /* @__PURE__ */ jsx15(
|
|
1641
|
-
TooltipPrimitive.Trigger,
|
|
1642
|
-
{
|
|
1643
|
-
"data-slot": "tooltip-trigger",
|
|
1644
|
-
...props
|
|
1645
|
-
}
|
|
1646
|
-
);
|
|
1647
|
-
}
|
|
1648
|
-
function TooltipContent({
|
|
1649
|
-
className,
|
|
1650
|
-
sideOffset = 0,
|
|
1651
|
-
children,
|
|
1652
|
-
...props
|
|
1653
|
-
}) {
|
|
1654
|
-
return /* @__PURE__ */ jsx15(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs5(
|
|
1655
|
-
TooltipPrimitive.Content,
|
|
1656
|
-
{
|
|
1657
|
-
"data-slot": "tooltip-content",
|
|
1658
|
-
sideOffset,
|
|
1659
|
-
className: cn(
|
|
1660
|
-
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit rounded-md px-3 py-1.5 text-xs text-balance",
|
|
1661
|
-
className
|
|
1662
|
-
),
|
|
1663
|
-
...props,
|
|
1664
|
-
children: [
|
|
1665
|
-
children,
|
|
1666
|
-
/* @__PURE__ */ jsx15(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
1667
|
-
]
|
|
1668
|
-
}
|
|
1669
|
-
) });
|
|
1670
|
-
}
|
|
1671
|
-
|
|
1672
|
-
// src/components/thread/tooltip-icon-button.tsx
|
|
1673
|
-
import { jsx as jsx16, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2451
|
+
import { jsx as jsx17, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1674
2452
|
var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
|
|
1675
|
-
return /* @__PURE__ */
|
|
1676
|
-
/* @__PURE__ */
|
|
2453
|
+
return /* @__PURE__ */ jsx17(TooltipProvider, { children: /* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
2454
|
+
/* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs7(
|
|
1677
2455
|
Button,
|
|
1678
2456
|
{
|
|
1679
2457
|
variant: "ghost",
|
|
@@ -1683,18 +2461,18 @@ var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", class
|
|
|
1683
2461
|
ref,
|
|
1684
2462
|
children: [
|
|
1685
2463
|
children,
|
|
1686
|
-
/* @__PURE__ */
|
|
2464
|
+
/* @__PURE__ */ jsx17("span", { className: "sr-only", children: tooltip })
|
|
1687
2465
|
]
|
|
1688
2466
|
}
|
|
1689
2467
|
) }),
|
|
1690
|
-
/* @__PURE__ */
|
|
2468
|
+
/* @__PURE__ */ jsx17(TooltipContent, { side, children: tooltip })
|
|
1691
2469
|
] }) });
|
|
1692
2470
|
});
|
|
1693
2471
|
TooltipIconButton.displayName = "TooltipIconButton";
|
|
1694
2472
|
|
|
1695
2473
|
// src/components/thread/markdown-text.tsx
|
|
1696
2474
|
import "katex/dist/katex.min.css";
|
|
1697
|
-
import { Fragment as Fragment2, jsx as
|
|
2475
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1698
2476
|
var getTextContent = (children) => Children.toArray(children).map((child) => {
|
|
1699
2477
|
if (typeof child === "string" || typeof child === "number") {
|
|
1700
2478
|
return String(child);
|
|
@@ -1704,7 +2482,7 @@ var getTextContent = (children) => Children.toArray(children).map((child) => {
|
|
|
1704
2482
|
var useCopyToClipboard = ({
|
|
1705
2483
|
copiedDuration = 3e3
|
|
1706
2484
|
} = {}) => {
|
|
1707
|
-
const [isCopied, setIsCopied] =
|
|
2485
|
+
const [isCopied, setIsCopied] = useState6(false);
|
|
1708
2486
|
const copyToClipboard = (value) => {
|
|
1709
2487
|
if (!value) return;
|
|
1710
2488
|
navigator.clipboard.writeText(value).then(() => {
|
|
@@ -1721,23 +2499,23 @@ var CodeHeader = ({ language, code }) => {
|
|
|
1721
2499
|
if (!code || isCopied) return;
|
|
1722
2500
|
copyToClipboard(code);
|
|
1723
2501
|
};
|
|
1724
|
-
return /* @__PURE__ */
|
|
1725
|
-
/* @__PURE__ */
|
|
1726
|
-
/* @__PURE__ */
|
|
2502
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
|
|
2503
|
+
/* @__PURE__ */ jsx18("span", { className: "lowercase [&>span]:text-xs", children: language }),
|
|
2504
|
+
/* @__PURE__ */ jsxs8(
|
|
1727
2505
|
TooltipIconButton,
|
|
1728
2506
|
{
|
|
1729
2507
|
tooltip: t("markdown.copy"),
|
|
1730
2508
|
onClick: onCopy,
|
|
1731
2509
|
children: [
|
|
1732
|
-
!isCopied && /* @__PURE__ */
|
|
1733
|
-
isCopied && /* @__PURE__ */
|
|
2510
|
+
!isCopied && /* @__PURE__ */ jsx18(CopyIcon, {}),
|
|
2511
|
+
isCopied && /* @__PURE__ */ jsx18(CheckIcon, {})
|
|
1734
2512
|
]
|
|
1735
2513
|
}
|
|
1736
2514
|
)
|
|
1737
2515
|
] });
|
|
1738
2516
|
};
|
|
1739
2517
|
var defaultComponents = {
|
|
1740
|
-
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2518
|
+
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1741
2519
|
"h1",
|
|
1742
2520
|
{
|
|
1743
2521
|
className: cn(
|
|
@@ -1747,7 +2525,7 @@ var defaultComponents = {
|
|
|
1747
2525
|
...props
|
|
1748
2526
|
}
|
|
1749
2527
|
),
|
|
1750
|
-
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2528
|
+
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1751
2529
|
"h2",
|
|
1752
2530
|
{
|
|
1753
2531
|
className: cn(
|
|
@@ -1757,7 +2535,7 @@ var defaultComponents = {
|
|
|
1757
2535
|
...props
|
|
1758
2536
|
}
|
|
1759
2537
|
),
|
|
1760
|
-
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2538
|
+
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1761
2539
|
"h3",
|
|
1762
2540
|
{
|
|
1763
2541
|
className: cn(
|
|
@@ -1767,7 +2545,7 @@ var defaultComponents = {
|
|
|
1767
2545
|
...props
|
|
1768
2546
|
}
|
|
1769
2547
|
),
|
|
1770
|
-
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2548
|
+
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1771
2549
|
"h4",
|
|
1772
2550
|
{
|
|
1773
2551
|
className: cn(
|
|
@@ -1777,7 +2555,7 @@ var defaultComponents = {
|
|
|
1777
2555
|
...props
|
|
1778
2556
|
}
|
|
1779
2557
|
),
|
|
1780
|
-
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2558
|
+
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1781
2559
|
"h5",
|
|
1782
2560
|
{
|
|
1783
2561
|
className: cn(
|
|
@@ -1787,21 +2565,21 @@ var defaultComponents = {
|
|
|
1787
2565
|
...props
|
|
1788
2566
|
}
|
|
1789
2567
|
),
|
|
1790
|
-
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2568
|
+
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1791
2569
|
"h6",
|
|
1792
2570
|
{
|
|
1793
2571
|
className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
|
|
1794
2572
|
...props
|
|
1795
2573
|
}
|
|
1796
2574
|
),
|
|
1797
|
-
p: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2575
|
+
p: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1798
2576
|
"p",
|
|
1799
2577
|
{
|
|
1800
2578
|
className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
|
|
1801
2579
|
...props
|
|
1802
2580
|
}
|
|
1803
2581
|
),
|
|
1804
|
-
a: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2582
|
+
a: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1805
2583
|
"a",
|
|
1806
2584
|
{
|
|
1807
2585
|
className: cn(
|
|
@@ -1817,7 +2595,7 @@ var defaultComponents = {
|
|
|
1817
2595
|
className,
|
|
1818
2596
|
node: _node,
|
|
1819
2597
|
...props
|
|
1820
|
-
}) => /* @__PURE__ */
|
|
2598
|
+
}) => /* @__PURE__ */ jsx18(
|
|
1821
2599
|
"blockquote",
|
|
1822
2600
|
{
|
|
1823
2601
|
className: cn(
|
|
@@ -1827,21 +2605,21 @@ var defaultComponents = {
|
|
|
1827
2605
|
...props
|
|
1828
2606
|
}
|
|
1829
2607
|
),
|
|
1830
|
-
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2608
|
+
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1831
2609
|
"ul",
|
|
1832
2610
|
{
|
|
1833
2611
|
className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
|
|
1834
2612
|
...props
|
|
1835
2613
|
}
|
|
1836
2614
|
),
|
|
1837
|
-
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2615
|
+
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1838
2616
|
"ol",
|
|
1839
2617
|
{
|
|
1840
2618
|
className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
|
|
1841
2619
|
...props
|
|
1842
2620
|
}
|
|
1843
2621
|
),
|
|
1844
|
-
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2622
|
+
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1845
2623
|
"hr",
|
|
1846
2624
|
{
|
|
1847
2625
|
className: cn("my-5 border-b", className),
|
|
@@ -1852,7 +2630,7 @@ var defaultComponents = {
|
|
|
1852
2630
|
className,
|
|
1853
2631
|
node: _node,
|
|
1854
2632
|
...props
|
|
1855
|
-
}) => /* @__PURE__ */
|
|
2633
|
+
}) => /* @__PURE__ */ jsx18(
|
|
1856
2634
|
"table",
|
|
1857
2635
|
{
|
|
1858
2636
|
className: cn(
|
|
@@ -1862,7 +2640,7 @@ var defaultComponents = {
|
|
|
1862
2640
|
...props
|
|
1863
2641
|
}
|
|
1864
2642
|
),
|
|
1865
|
-
th: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2643
|
+
th: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1866
2644
|
"th",
|
|
1867
2645
|
{
|
|
1868
2646
|
className: cn(
|
|
@@ -1872,7 +2650,7 @@ var defaultComponents = {
|
|
|
1872
2650
|
...props
|
|
1873
2651
|
}
|
|
1874
2652
|
),
|
|
1875
|
-
td: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2653
|
+
td: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1876
2654
|
"td",
|
|
1877
2655
|
{
|
|
1878
2656
|
className: cn(
|
|
@@ -1882,7 +2660,7 @@ var defaultComponents = {
|
|
|
1882
2660
|
...props
|
|
1883
2661
|
}
|
|
1884
2662
|
),
|
|
1885
|
-
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2663
|
+
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1886
2664
|
"tr",
|
|
1887
2665
|
{
|
|
1888
2666
|
className: cn(
|
|
@@ -1892,14 +2670,14 @@ var defaultComponents = {
|
|
|
1892
2670
|
...props
|
|
1893
2671
|
}
|
|
1894
2672
|
),
|
|
1895
|
-
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2673
|
+
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1896
2674
|
"sup",
|
|
1897
2675
|
{
|
|
1898
2676
|
className: cn("[&>a]:text-xs [&>a]:no-underline", className),
|
|
1899
2677
|
...props
|
|
1900
2678
|
}
|
|
1901
2679
|
),
|
|
1902
|
-
pre: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
2680
|
+
pre: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx18(
|
|
1903
2681
|
"div",
|
|
1904
2682
|
{
|
|
1905
2683
|
className: cn(
|
|
@@ -1921,15 +2699,15 @@ var defaultComponents = {
|
|
|
1921
2699
|
if (match) {
|
|
1922
2700
|
const language = match[1];
|
|
1923
2701
|
const normalizedCode = code.replace(/\n$/, "");
|
|
1924
|
-
return /* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
2702
|
+
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
2703
|
+
/* @__PURE__ */ jsx18(
|
|
1926
2704
|
CodeHeader,
|
|
1927
2705
|
{
|
|
1928
2706
|
language,
|
|
1929
2707
|
code: normalizedCode
|
|
1930
2708
|
}
|
|
1931
2709
|
),
|
|
1932
|
-
/* @__PURE__ */
|
|
2710
|
+
/* @__PURE__ */ jsx18(
|
|
1933
2711
|
SyntaxHighlighter,
|
|
1934
2712
|
{
|
|
1935
2713
|
language,
|
|
@@ -1940,7 +2718,7 @@ var defaultComponents = {
|
|
|
1940
2718
|
] });
|
|
1941
2719
|
}
|
|
1942
2720
|
if (isBlockCode) {
|
|
1943
|
-
return /* @__PURE__ */
|
|
2721
|
+
return /* @__PURE__ */ jsx18(
|
|
1944
2722
|
"code",
|
|
1945
2723
|
{
|
|
1946
2724
|
className: cn(
|
|
@@ -1952,7 +2730,7 @@ var defaultComponents = {
|
|
|
1952
2730
|
}
|
|
1953
2731
|
);
|
|
1954
2732
|
}
|
|
1955
|
-
return /* @__PURE__ */
|
|
2733
|
+
return /* @__PURE__ */ jsx18(
|
|
1956
2734
|
"code",
|
|
1957
2735
|
{
|
|
1958
2736
|
className: cn(
|
|
@@ -1966,7 +2744,7 @@ var defaultComponents = {
|
|
|
1966
2744
|
}
|
|
1967
2745
|
};
|
|
1968
2746
|
var MarkdownTextImpl = ({ children }) => {
|
|
1969
|
-
return /* @__PURE__ */
|
|
2747
|
+
return /* @__PURE__ */ jsx18("div", { className: "markdown-content", children: /* @__PURE__ */ jsx18(
|
|
1970
2748
|
ReactMarkdown,
|
|
1971
2749
|
{
|
|
1972
2750
|
remarkPlugins: [remarkGfm, remarkMath],
|
|
@@ -1980,18 +2758,18 @@ var MarkdownText = memo(MarkdownTextImpl);
|
|
|
1980
2758
|
|
|
1981
2759
|
// src/components/thread/messages/widget.tsx
|
|
1982
2760
|
import { SurfaceRenderer } from "@xpert-ai/a2ui-react";
|
|
1983
|
-
import { jsx as
|
|
2761
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1984
2762
|
function WidgetMessage({ messageId, data }) {
|
|
1985
2763
|
const widgets = Array.isArray(data.widgets) ? data.widgets : [];
|
|
1986
2764
|
if (widgets.length === 0) return null;
|
|
1987
2765
|
const baseSurfaceId = `widget-${messageId}`;
|
|
1988
|
-
return /* @__PURE__ */
|
|
2766
|
+
return /* @__PURE__ */ jsx19("div", { className: "space-y-3", children: widgets.map((widget, index) => {
|
|
1989
2767
|
const config = widget?.config;
|
|
1990
2768
|
if (!config || typeof config !== "object") {
|
|
1991
2769
|
return null;
|
|
1992
2770
|
}
|
|
1993
2771
|
const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
|
|
1994
|
-
return /* @__PURE__ */
|
|
2772
|
+
return /* @__PURE__ */ jsx19(
|
|
1995
2773
|
SurfaceRenderer,
|
|
1996
2774
|
{
|
|
1997
2775
|
surfaceId,
|
|
@@ -2003,7 +2781,7 @@ function WidgetMessage({ messageId, data }) {
|
|
|
2003
2781
|
}
|
|
2004
2782
|
|
|
2005
2783
|
// src/components/thread/messages/ai.tsx
|
|
2006
|
-
import { jsx as
|
|
2784
|
+
import { jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2007
2785
|
function isTextContent(content) {
|
|
2008
2786
|
return content.type === "text";
|
|
2009
2787
|
}
|
|
@@ -2047,11 +2825,11 @@ function safeJson(value) {
|
|
|
2047
2825
|
function ReasoningBlock({ reasoning }) {
|
|
2048
2826
|
const blocks = reasoning.filter((item) => item.text?.trim());
|
|
2049
2827
|
if (blocks.length === 0) return null;
|
|
2050
|
-
return /* @__PURE__ */
|
|
2828
|
+
return /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx20(
|
|
2051
2829
|
"div",
|
|
2052
2830
|
{
|
|
2053
2831
|
className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
|
|
2054
|
-
children: /* @__PURE__ */
|
|
2832
|
+
children: /* @__PURE__ */ jsx20("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
|
|
2055
2833
|
},
|
|
2056
2834
|
item.id ?? `reasoning-${index}`
|
|
2057
2835
|
)) });
|
|
@@ -2059,27 +2837,27 @@ function ReasoningBlock({ reasoning }) {
|
|
|
2059
2837
|
function ImageBlock({ content }) {
|
|
2060
2838
|
const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
|
|
2061
2839
|
if (!imageUrl) {
|
|
2062
|
-
return /* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__PURE__ */
|
|
2840
|
+
return /* @__PURE__ */ jsxs9(Card, { children: [
|
|
2841
|
+
/* @__PURE__ */ jsx20(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx20(CardTitle, { className: "text-sm", children: "Image" }) }),
|
|
2842
|
+
/* @__PURE__ */ jsx20(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
|
|
2065
2843
|
] });
|
|
2066
2844
|
}
|
|
2067
|
-
return /* @__PURE__ */
|
|
2845
|
+
return /* @__PURE__ */ jsx20("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx20("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
|
|
2068
2846
|
}
|
|
2069
2847
|
function MemoryBlock({ content }) {
|
|
2070
|
-
return /* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2072
|
-
/* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
2848
|
+
return /* @__PURE__ */ jsxs9(Card, { children: [
|
|
2849
|
+
/* @__PURE__ */ jsxs9(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
2850
|
+
/* @__PURE__ */ jsx20(CardTitle, { className: "text-sm", children: "Memory" }),
|
|
2851
|
+
/* @__PURE__ */ jsx20(Badge, { variant: "secondary", children: "Memory" })
|
|
2074
2852
|
] }),
|
|
2075
|
-
/* @__PURE__ */
|
|
2853
|
+
/* @__PURE__ */ jsx20(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
|
|
2076
2854
|
] });
|
|
2077
2855
|
}
|
|
2078
2856
|
function ComponentBlock({ content }) {
|
|
2079
|
-
const [isExpanded, setIsExpanded] =
|
|
2080
|
-
const contentRef =
|
|
2081
|
-
const shouldAutoScrollRef =
|
|
2082
|
-
const previousScrollTopRef =
|
|
2857
|
+
const [isExpanded, setIsExpanded] = React14.useState(false);
|
|
2858
|
+
const contentRef = React14.useRef(null);
|
|
2859
|
+
const shouldAutoScrollRef = React14.useRef(true);
|
|
2860
|
+
const previousScrollTopRef = React14.useRef(0);
|
|
2083
2861
|
const data = content.data ?? {};
|
|
2084
2862
|
const category = data.category ?? "Component";
|
|
2085
2863
|
const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
|
|
@@ -2089,10 +2867,10 @@ function ComponentBlock({ content }) {
|
|
|
2089
2867
|
const error = data.error ?? null;
|
|
2090
2868
|
const fallback = message ?? output ?? safeJson(data.data ?? data);
|
|
2091
2869
|
const hasOutput = message !== null || output !== null;
|
|
2092
|
-
|
|
2870
|
+
React14.useEffect(() => {
|
|
2093
2871
|
if (status === "running" && output !== null) setIsExpanded(true);
|
|
2094
2872
|
}, [status, output]);
|
|
2095
|
-
|
|
2873
|
+
React14.useEffect(() => {
|
|
2096
2874
|
const element = contentRef.current;
|
|
2097
2875
|
if (!element) return;
|
|
2098
2876
|
previousScrollTopRef.current = element.scrollTop;
|
|
@@ -2112,7 +2890,7 @@ function ComponentBlock({ content }) {
|
|
|
2112
2890
|
element.removeEventListener("scroll", updateAutoScrollState);
|
|
2113
2891
|
};
|
|
2114
2892
|
}, [isExpanded]);
|
|
2115
|
-
|
|
2893
|
+
React14.useEffect(() => {
|
|
2116
2894
|
if (status !== "running") {
|
|
2117
2895
|
shouldAutoScrollRef.current = true;
|
|
2118
2896
|
return;
|
|
@@ -2125,20 +2903,20 @@ function ComponentBlock({ content }) {
|
|
|
2125
2903
|
}, [isExpanded, output, status]);
|
|
2126
2904
|
const config = status ? statusConfig[status] : null;
|
|
2127
2905
|
const StatusIcon = config?.icon;
|
|
2128
|
-
return /* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
status && StatusIcon && /* @__PURE__ */
|
|
2132
|
-
/* @__PURE__ */
|
|
2906
|
+
return /* @__PURE__ */ jsxs9(Card, { children: [
|
|
2907
|
+
/* @__PURE__ */ jsxs9(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
|
|
2908
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
|
|
2909
|
+
status && StatusIcon && /* @__PURE__ */ jsx20(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
|
|
2910
|
+
/* @__PURE__ */ jsx20(CardTitle, { className: "text-sm truncate", children: title })
|
|
2133
2911
|
] }),
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
2912
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
|
|
2913
|
+
/* @__PURE__ */ jsx20(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
|
|
2914
|
+
/* @__PURE__ */ jsx20(
|
|
2137
2915
|
"button",
|
|
2138
2916
|
{
|
|
2139
2917
|
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
2140
2918
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
2141
|
-
children: /* @__PURE__ */
|
|
2919
|
+
children: /* @__PURE__ */ jsx20(
|
|
2142
2920
|
ChevronDown,
|
|
2143
2921
|
{
|
|
2144
2922
|
className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
|
|
@@ -2148,89 +2926,128 @@ function ComponentBlock({ content }) {
|
|
|
2148
2926
|
)
|
|
2149
2927
|
] })
|
|
2150
2928
|
] }),
|
|
2151
|
-
isExpanded && /* @__PURE__ */
|
|
2152
|
-
data.input && /* @__PURE__ */
|
|
2153
|
-
error ? /* @__PURE__ */
|
|
2929
|
+
isExpanded && /* @__PURE__ */ jsxs9(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
|
|
2930
|
+
data.input && /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap wrap-break-word", children: JSON.stringify(data.input, null, 2) }),
|
|
2931
|
+
error ? /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: typeof error === "string" ? error : safeJson(error) }) : hasOutput && /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap wrap-break-word", children: fallback })
|
|
2154
2932
|
] })
|
|
2155
2933
|
] });
|
|
2156
2934
|
}
|
|
2157
2935
|
function UnknownBlock({ content }) {
|
|
2158
|
-
return /* @__PURE__ */
|
|
2159
|
-
/* @__PURE__ */
|
|
2160
|
-
/* @__PURE__ */
|
|
2161
|
-
/* @__PURE__ */
|
|
2936
|
+
return /* @__PURE__ */ jsxs9(Card, { children: [
|
|
2937
|
+
/* @__PURE__ */ jsxs9(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
2938
|
+
/* @__PURE__ */ jsx20(CardTitle, { className: "text-sm", children: "Assistant Content" }),
|
|
2939
|
+
/* @__PURE__ */ jsx20(Badge, { variant: "outline", children: content.type ?? "unknown" })
|
|
2162
2940
|
] }),
|
|
2163
|
-
/* @__PURE__ */
|
|
2941
|
+
/* @__PURE__ */ jsx20(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
|
|
2164
2942
|
] });
|
|
2165
2943
|
}
|
|
2166
2944
|
function renderContentItem(content, index, messageId) {
|
|
2167
2945
|
if (typeof content === "string") {
|
|
2168
|
-
return /* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
2946
|
+
return /* @__PURE__ */ jsxs9("div", { children: [
|
|
2947
|
+
/* @__PURE__ */ jsx20(MarkdownText, { children: content }),
|
|
2170
2948
|
";"
|
|
2171
2949
|
] }, `text-${index}`);
|
|
2172
2950
|
}
|
|
2173
2951
|
if (isTextContent(content)) {
|
|
2174
|
-
return /* @__PURE__ */
|
|
2952
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
|
|
2175
2953
|
}
|
|
2176
2954
|
if (isReasoningContent(content)) {
|
|
2177
|
-
return /* @__PURE__ */
|
|
2955
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
|
|
2178
2956
|
}
|
|
2179
2957
|
if (isImageContent(content)) {
|
|
2180
|
-
return /* @__PURE__ */
|
|
2958
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(ImageBlock, { content }) }, content.id ?? `image-${index}`);
|
|
2181
2959
|
}
|
|
2182
2960
|
if (isComponentContent(content)) {
|
|
2183
2961
|
if (isWidgetComponent(content)) {
|
|
2184
|
-
return /* @__PURE__ */
|
|
2962
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
|
|
2185
2963
|
}
|
|
2186
|
-
return /* @__PURE__ */
|
|
2964
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
|
|
2187
2965
|
}
|
|
2188
2966
|
if (isMemoryContent(content)) {
|
|
2189
|
-
return /* @__PURE__ */
|
|
2967
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
|
|
2190
2968
|
}
|
|
2191
|
-
return /* @__PURE__ */
|
|
2969
|
+
return /* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
|
|
2192
2970
|
}
|
|
2193
2971
|
function renderContent(content, messageId) {
|
|
2194
2972
|
if (typeof content === "string") {
|
|
2195
2973
|
if (!content.trim()) return null;
|
|
2196
|
-
return /* @__PURE__ */
|
|
2974
|
+
return /* @__PURE__ */ jsx20(MarkdownText, { children: content });
|
|
2197
2975
|
}
|
|
2198
2976
|
if (!Array.isArray(content) || content.length === 0) return null;
|
|
2199
|
-
return /* @__PURE__ */
|
|
2977
|
+
return /* @__PURE__ */ jsx20("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
|
|
2200
2978
|
}
|
|
2201
|
-
function
|
|
2979
|
+
function AssistantStreamingIndicator({
|
|
2980
|
+
status,
|
|
2981
|
+
className
|
|
2982
|
+
}) {
|
|
2202
2983
|
const { t } = useChatkitTranslation();
|
|
2203
|
-
const
|
|
2204
|
-
|
|
2205
|
-
|
|
2984
|
+
const labelMap = {
|
|
2985
|
+
loading: t("message.loading"),
|
|
2986
|
+
thinking: t("message.thinking"),
|
|
2987
|
+
answering: t("message.answering")
|
|
2988
|
+
};
|
|
2989
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
|
|
2990
|
+
status === "loading" && /* @__PURE__ */ jsx20(Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
2991
|
+
status === "thinking" && /* @__PURE__ */ jsxs9("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
2992
|
+
/* @__PURE__ */ jsx20("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
|
|
2993
|
+
/* @__PURE__ */ jsx20("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
|
|
2994
|
+
/* @__PURE__ */ jsx20("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
|
|
2995
|
+
] }),
|
|
2996
|
+
status === "answering" && /* @__PURE__ */ jsxs9("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
2997
|
+
/* @__PURE__ */ jsx20("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
|
|
2998
|
+
/* @__PURE__ */ jsx20("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
|
|
2999
|
+
/* @__PURE__ */ jsx20("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
|
|
3000
|
+
] }),
|
|
3001
|
+
/* @__PURE__ */ jsx20("span", { children: labelMap[status] })
|
|
3002
|
+
] });
|
|
3003
|
+
}
|
|
3004
|
+
function AssistantMessage({
|
|
3005
|
+
message,
|
|
3006
|
+
className,
|
|
3007
|
+
isStreaming = false,
|
|
3008
|
+
streamingStatus
|
|
3009
|
+
}) {
|
|
3010
|
+
const { t } = useChatkitTranslation();
|
|
3011
|
+
const hasContent = hasRenderableMessageContent(message.content);
|
|
3012
|
+
const hasReasoning = hasRenderableReasoning(message.reasoning);
|
|
3013
|
+
const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
|
|
2206
3014
|
const answerNode = renderContent(message.content, message.id);
|
|
2207
|
-
const reasoningNode = hasReasoning ? /* @__PURE__ */
|
|
2208
|
-
if (!
|
|
3015
|
+
const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx20(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
|
|
3016
|
+
if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
|
|
2209
3017
|
const streamingClass = isStreaming ? "streaming-active" : "";
|
|
3018
|
+
if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
|
|
3019
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx20(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
|
|
3020
|
+
}
|
|
2210
3021
|
if (hasContent && hasReasoning) {
|
|
2211
|
-
return /* @__PURE__ */
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
3022
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3023
|
+
/* @__PURE__ */ jsxs9(
|
|
3024
|
+
Tabs,
|
|
3025
|
+
{
|
|
3026
|
+
defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
|
|
3027
|
+
className: "w-full",
|
|
3028
|
+
children: [
|
|
3029
|
+
/* @__PURE__ */ jsxs9(TabsList, { className: "h-9", children: [
|
|
3030
|
+
/* @__PURE__ */ jsx20(TabsTrigger, { value: "answer", children: t("message.answer") }),
|
|
3031
|
+
/* @__PURE__ */ jsx20(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
|
|
3032
|
+
] }),
|
|
3033
|
+
/* @__PURE__ */ jsx20(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
|
|
3034
|
+
/* @__PURE__ */ jsx20(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
|
|
3035
|
+
]
|
|
3036
|
+
}
|
|
3037
|
+
),
|
|
3038
|
+
resolvedStreamingStatus ? /* @__PURE__ */ jsx20(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3039
|
+
] });
|
|
2226
3040
|
}
|
|
2227
|
-
return /* @__PURE__ */
|
|
3041
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3042
|
+
hasReasoning ? reasoningNode : answerNode,
|
|
3043
|
+
resolvedStreamingStatus ? /* @__PURE__ */ jsx20(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3044
|
+
] });
|
|
2228
3045
|
}
|
|
2229
3046
|
|
|
2230
3047
|
// src/components/thread/MessageActions.tsx
|
|
2231
|
-
import * as
|
|
3048
|
+
import * as React15 from "react";
|
|
2232
3049
|
import { Check, Copy, RefreshCw } from "lucide-react";
|
|
2233
|
-
import { jsx as
|
|
3050
|
+
import { jsx as jsx21, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2234
3051
|
function MessageActions({
|
|
2235
3052
|
content,
|
|
2236
3053
|
isAssistant = false,
|
|
@@ -2239,7 +3056,7 @@ function MessageActions({
|
|
|
2239
3056
|
className
|
|
2240
3057
|
}) {
|
|
2241
3058
|
const { t } = useChatkitTranslation();
|
|
2242
|
-
const [copied, setCopied] =
|
|
3059
|
+
const [copied, setCopied] = React15.useState(false);
|
|
2243
3060
|
const handleCopy = async () => {
|
|
2244
3061
|
try {
|
|
2245
3062
|
await navigator.clipboard.writeText(content);
|
|
@@ -2252,7 +3069,7 @@ function MessageActions({
|
|
|
2252
3069
|
if (isStreaming) {
|
|
2253
3070
|
return null;
|
|
2254
3071
|
}
|
|
2255
|
-
return /* @__PURE__ */
|
|
3072
|
+
return /* @__PURE__ */ jsxs10(
|
|
2256
3073
|
"div",
|
|
2257
3074
|
{
|
|
2258
3075
|
className: cn(
|
|
@@ -2260,7 +3077,7 @@ function MessageActions({
|
|
|
2260
3077
|
className
|
|
2261
3078
|
),
|
|
2262
3079
|
children: [
|
|
2263
|
-
/* @__PURE__ */
|
|
3080
|
+
/* @__PURE__ */ jsx21(
|
|
2264
3081
|
"button",
|
|
2265
3082
|
{
|
|
2266
3083
|
type: "button",
|
|
@@ -2270,17 +3087,17 @@ function MessageActions({
|
|
|
2270
3087
|
copied && "text-green-500"
|
|
2271
3088
|
),
|
|
2272
3089
|
title: copied ? t("messageActions.copied") : t("messageActions.copy"),
|
|
2273
|
-
children: copied ? /* @__PURE__ */
|
|
3090
|
+
children: copied ? /* @__PURE__ */ jsx21(Check, { size: 14 }) : /* @__PURE__ */ jsx21(Copy, { size: 14 })
|
|
2274
3091
|
}
|
|
2275
3092
|
),
|
|
2276
|
-
isAssistant && onRetry && /* @__PURE__ */
|
|
3093
|
+
isAssistant && onRetry && /* @__PURE__ */ jsx21(
|
|
2277
3094
|
"button",
|
|
2278
3095
|
{
|
|
2279
3096
|
type: "button",
|
|
2280
3097
|
onClick: onRetry,
|
|
2281
3098
|
className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
2282
3099
|
title: t("messageActions.regenerate"),
|
|
2283
|
-
children: /* @__PURE__ */
|
|
3100
|
+
children: /* @__PURE__ */ jsx21(RefreshCw, { size: 14 })
|
|
2284
3101
|
}
|
|
2285
3102
|
)
|
|
2286
3103
|
]
|
|
@@ -2301,18 +3118,18 @@ import {
|
|
|
2301
3118
|
Sparkles as Sparkles2,
|
|
2302
3119
|
Zap
|
|
2303
3120
|
} from "lucide-react";
|
|
2304
|
-
import { jsx as
|
|
3121
|
+
import { jsx as jsx22, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2305
3122
|
function getIconComponent2(icon) {
|
|
2306
3123
|
const iconMap = {
|
|
2307
|
-
"circle-question": /* @__PURE__ */
|
|
2308
|
-
"lightbulb": /* @__PURE__ */
|
|
2309
|
-
"sparkle": /* @__PURE__ */
|
|
2310
|
-
"write": /* @__PURE__ */
|
|
2311
|
-
"search": /* @__PURE__ */
|
|
2312
|
-
"globe": /* @__PURE__ */
|
|
2313
|
-
"book-open": /* @__PURE__ */
|
|
2314
|
-
"compass": /* @__PURE__ */
|
|
2315
|
-
"bolt": /* @__PURE__ */
|
|
3124
|
+
"circle-question": /* @__PURE__ */ jsx22(HelpCircle, { size: 20 }),
|
|
3125
|
+
"lightbulb": /* @__PURE__ */ jsx22(Lightbulb2, { size: 20 }),
|
|
3126
|
+
"sparkle": /* @__PURE__ */ jsx22(Sparkles2, { size: 20 }),
|
|
3127
|
+
"write": /* @__PURE__ */ jsx22(Pencil2, { size: 20 }),
|
|
3128
|
+
"search": /* @__PURE__ */ jsx22(Search2, { size: 20 }),
|
|
3129
|
+
"globe": /* @__PURE__ */ jsx22(Globe2, { size: 20 }),
|
|
3130
|
+
"book-open": /* @__PURE__ */ jsx22(BookOpen, { size: 20 }),
|
|
3131
|
+
"compass": /* @__PURE__ */ jsx22(Compass, { size: 20 }),
|
|
3132
|
+
"bolt": /* @__PURE__ */ jsx22(Zap, { size: 20 })
|
|
2316
3133
|
};
|
|
2317
3134
|
return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
|
|
2318
3135
|
}
|
|
@@ -2320,9 +3137,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2320
3137
|
const { t } = useChatkitTranslation();
|
|
2321
3138
|
const greeting = startScreen?.greeting ?? t("startScreen.greeting");
|
|
2322
3139
|
const prompts = startScreen?.prompts ?? [];
|
|
2323
|
-
return /* @__PURE__ */
|
|
2324
|
-
/* @__PURE__ */
|
|
2325
|
-
prompts.length > 0 && /* @__PURE__ */
|
|
3140
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
|
|
3141
|
+
/* @__PURE__ */ jsx22("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx22("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
|
|
3142
|
+
prompts.length > 0 && /* @__PURE__ */ jsx22("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx22("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs11(
|
|
2326
3143
|
"button",
|
|
2327
3144
|
{
|
|
2328
3145
|
type: "button",
|
|
@@ -2333,8 +3150,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2333
3150
|
"focus:outline-none focus:ring-2 focus:ring-primary/20"
|
|
2334
3151
|
),
|
|
2335
3152
|
children: [
|
|
2336
|
-
/* @__PURE__ */
|
|
2337
|
-
/* @__PURE__ */
|
|
3153
|
+
/* @__PURE__ */ jsx22("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
|
|
3154
|
+
/* @__PURE__ */ jsx22("span", { className: "text-sm font-medium text-foreground", children: item.label })
|
|
2338
3155
|
]
|
|
2339
3156
|
},
|
|
2340
3157
|
`prompt-${index}`
|
|
@@ -2346,10 +3163,10 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2346
3163
|
import "react";
|
|
2347
3164
|
|
|
2348
3165
|
// src/components/ui/avatar.tsx
|
|
2349
|
-
import * as
|
|
3166
|
+
import * as React17 from "react";
|
|
2350
3167
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
2351
|
-
import { jsx as
|
|
2352
|
-
var Avatar =
|
|
3168
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3169
|
+
var Avatar = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
2353
3170
|
AvatarPrimitive.Root,
|
|
2354
3171
|
{
|
|
2355
3172
|
ref,
|
|
@@ -2361,7 +3178,7 @@ var Avatar = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
2361
3178
|
}
|
|
2362
3179
|
));
|
|
2363
3180
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
2364
|
-
var AvatarImage =
|
|
3181
|
+
var AvatarImage = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
2365
3182
|
AvatarPrimitive.Image,
|
|
2366
3183
|
{
|
|
2367
3184
|
ref,
|
|
@@ -2370,7 +3187,7 @@ var AvatarImage = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
2370
3187
|
}
|
|
2371
3188
|
));
|
|
2372
3189
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
2373
|
-
var AvatarFallback =
|
|
3190
|
+
var AvatarFallback = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx23(
|
|
2374
3191
|
AvatarPrimitive.Fallback,
|
|
2375
3192
|
{
|
|
2376
3193
|
ref,
|
|
@@ -2384,7 +3201,7 @@ var AvatarFallback = React16.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
2384
3201
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
2385
3202
|
|
|
2386
3203
|
// src/components/ui/chatkit-avatar.tsx
|
|
2387
|
-
import { jsx as
|
|
3204
|
+
import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2388
3205
|
function asRecord(value) {
|
|
2389
3206
|
return value && typeof value === "object" ? value : null;
|
|
2390
3207
|
}
|
|
@@ -2457,21 +3274,21 @@ function ChatkitAvatar({
|
|
|
2457
3274
|
const fallbackStyle = {
|
|
2458
3275
|
...avatar?.background ? { background: avatar.background } : {}
|
|
2459
3276
|
};
|
|
2460
|
-
return /* @__PURE__ */
|
|
2461
|
-
avatar?.url ? /* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
3277
|
+
return /* @__PURE__ */ jsxs12(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
|
|
3278
|
+
avatar?.url ? /* @__PURE__ */ jsx24(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
|
|
3279
|
+
/* @__PURE__ */ jsx24(
|
|
2463
3280
|
AvatarFallback,
|
|
2464
3281
|
{
|
|
2465
3282
|
className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
|
|
2466
3283
|
style: fallbackStyle,
|
|
2467
|
-
children: emojiCharacter ? /* @__PURE__ */
|
|
3284
|
+
children: emojiCharacter ? /* @__PURE__ */ jsx24("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
|
|
2468
3285
|
}
|
|
2469
3286
|
)
|
|
2470
3287
|
] });
|
|
2471
3288
|
}
|
|
2472
3289
|
|
|
2473
3290
|
// src/hooks/useThreads.ts
|
|
2474
|
-
import * as
|
|
3291
|
+
import * as React19 from "react";
|
|
2475
3292
|
var DEFAULT_LIMIT = 50;
|
|
2476
3293
|
var getThreadTitle = (threadRecord) => {
|
|
2477
3294
|
const title = threadRecord.title?.trim();
|
|
@@ -2509,16 +3326,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2509
3326
|
isReady,
|
|
2510
3327
|
isLoading: isStreamLoading
|
|
2511
3328
|
} = useStreamContext();
|
|
2512
|
-
const [threadRecords, setThreadRecords] =
|
|
2513
|
-
const [isLoading, setIsLoading] =
|
|
2514
|
-
const [error, setError] =
|
|
2515
|
-
const upsertThreadRecord =
|
|
3329
|
+
const [threadRecords, setThreadRecords] = React19.useState([]);
|
|
3330
|
+
const [isLoading, setIsLoading] = React19.useState(false);
|
|
3331
|
+
const [error, setError] = React19.useState(null);
|
|
3332
|
+
const upsertThreadRecord = React19.useCallback((threadRecord) => {
|
|
2516
3333
|
setThreadRecords((prev) => {
|
|
2517
3334
|
const next = prev.filter((item) => item.id !== threadRecord.id);
|
|
2518
3335
|
return sortThreadRecords([threadRecord, ...next]);
|
|
2519
3336
|
});
|
|
2520
3337
|
}, []);
|
|
2521
|
-
const refreshThreads =
|
|
3338
|
+
const refreshThreads = React19.useCallback(async () => {
|
|
2522
3339
|
setIsLoading(true);
|
|
2523
3340
|
setError(null);
|
|
2524
3341
|
try {
|
|
@@ -2534,7 +3351,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2534
3351
|
setIsLoading(false);
|
|
2535
3352
|
}
|
|
2536
3353
|
}, [client, limit, assistantId]);
|
|
2537
|
-
const createThread =
|
|
3354
|
+
const createThread = React19.useCallback(
|
|
2538
3355
|
async (input) => {
|
|
2539
3356
|
setError(null);
|
|
2540
3357
|
const payload = {};
|
|
@@ -2548,7 +3365,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2548
3365
|
},
|
|
2549
3366
|
[client, upsertThreadRecord]
|
|
2550
3367
|
);
|
|
2551
|
-
const updateThread =
|
|
3368
|
+
const updateThread = React19.useCallback(
|
|
2552
3369
|
async (recordId, payload) => {
|
|
2553
3370
|
setError(null);
|
|
2554
3371
|
const updated = await client.conversations.update(recordId, payload);
|
|
@@ -2557,7 +3374,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2557
3374
|
},
|
|
2558
3375
|
[client, upsertThreadRecord]
|
|
2559
3376
|
);
|
|
2560
|
-
const deleteThread =
|
|
3377
|
+
const deleteThread = React19.useCallback(
|
|
2561
3378
|
async (recordId) => {
|
|
2562
3379
|
setError(null);
|
|
2563
3380
|
await client.conversations.delete(recordId);
|
|
@@ -2565,11 +3382,11 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2565
3382
|
},
|
|
2566
3383
|
[client]
|
|
2567
3384
|
);
|
|
2568
|
-
|
|
3385
|
+
React19.useEffect(() => {
|
|
2569
3386
|
if (!isReady) return;
|
|
2570
3387
|
void refreshThreads();
|
|
2571
3388
|
}, [refreshThreads, isReady]);
|
|
2572
|
-
|
|
3389
|
+
React19.useEffect(() => {
|
|
2573
3390
|
if (!threadId || !isStreamLoading) return;
|
|
2574
3391
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2575
3392
|
setThreadRecords((prev) => {
|
|
@@ -2589,7 +3406,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2589
3406
|
return changed ? sortThreadRecords(next) : prev;
|
|
2590
3407
|
});
|
|
2591
3408
|
}, [threadId, isStreamLoading]);
|
|
2592
|
-
|
|
3409
|
+
React19.useEffect(() => {
|
|
2593
3410
|
if (!isReady || !threadId || isStreamLoading) return;
|
|
2594
3411
|
let cancelled = false;
|
|
2595
3412
|
void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
|
|
@@ -2603,7 +3420,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2603
3420
|
cancelled = true;
|
|
2604
3421
|
};
|
|
2605
3422
|
}, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
|
|
2606
|
-
const threads =
|
|
3423
|
+
const threads = React19.useMemo(
|
|
2607
3424
|
() => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
|
|
2608
3425
|
[threadRecords]
|
|
2609
3426
|
);
|
|
@@ -2620,10 +3437,10 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2620
3437
|
}
|
|
2621
3438
|
|
|
2622
3439
|
// src/components/thread/context-usage-indicator.tsx
|
|
2623
|
-
import * as
|
|
3440
|
+
import * as React20 from "react";
|
|
2624
3441
|
|
|
2625
3442
|
// src/components/ui/progress-circle.tsx
|
|
2626
|
-
import { jsx as
|
|
3443
|
+
import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2627
3444
|
function clamp(input, a, b) {
|
|
2628
3445
|
return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
|
|
2629
3446
|
}
|
|
@@ -2646,7 +3463,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2646
3463
|
return (
|
|
2647
3464
|
// biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
|
|
2648
3465
|
// biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
|
|
2649
|
-
/* @__PURE__ */
|
|
3466
|
+
/* @__PURE__ */ jsxs13(
|
|
2650
3467
|
"svg",
|
|
2651
3468
|
{
|
|
2652
3469
|
role: "progressbar",
|
|
@@ -2657,8 +3474,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2657
3474
|
"aria-valuemax": 100,
|
|
2658
3475
|
...restSvgProps,
|
|
2659
3476
|
children: [
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsx25("circle", { ...commonParams, className: "stroke-current/25" }),
|
|
3478
|
+
/* @__PURE__ */ jsx25(
|
|
2662
3479
|
"circle",
|
|
2663
3480
|
{
|
|
2664
3481
|
...commonParams,
|
|
@@ -2677,7 +3494,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2677
3494
|
};
|
|
2678
3495
|
|
|
2679
3496
|
// src/components/thread/context-usage-indicator.tsx
|
|
2680
|
-
import { jsx as
|
|
3497
|
+
import { jsx as jsx26, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2681
3498
|
var kNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
2682
3499
|
minimumFractionDigits: 0,
|
|
2683
3500
|
maximumFractionDigits: 1
|
|
@@ -2710,20 +3527,20 @@ function ContextUsageIndicator({
|
|
|
2710
3527
|
}) {
|
|
2711
3528
|
const { t } = useChatkitTranslation();
|
|
2712
3529
|
const stream = useStreamContext();
|
|
2713
|
-
const [maxContextSize, setMaxContextSize] =
|
|
2714
|
-
const [usedContextSize, setUsedContextSize] =
|
|
2715
|
-
const [assistantAgentKey, setAssistantAgentKey] =
|
|
2716
|
-
const latestRealtimeUsageRef =
|
|
3530
|
+
const [maxContextSize, setMaxContextSize] = React20.useState(null);
|
|
3531
|
+
const [usedContextSize, setUsedContextSize] = React20.useState(null);
|
|
3532
|
+
const [assistantAgentKey, setAssistantAgentKey] = React20.useState(null);
|
|
3533
|
+
const latestRealtimeUsageRef = React20.useRef({
|
|
2717
3534
|
threadId: null,
|
|
2718
3535
|
agentKey: null,
|
|
2719
3536
|
usedTokens: null
|
|
2720
3537
|
});
|
|
2721
|
-
const realtimeUsage =
|
|
3538
|
+
const realtimeUsage = React20.useMemo(
|
|
2722
3539
|
() => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
|
|
2723
3540
|
[assistantAgentKey, stream.contextUsageByAgentKey]
|
|
2724
3541
|
);
|
|
2725
3542
|
const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
|
|
2726
|
-
|
|
3543
|
+
React20.useEffect(() => {
|
|
2727
3544
|
if (!stream.client || !stream.assistantId) {
|
|
2728
3545
|
setMaxContextSize(null);
|
|
2729
3546
|
setAssistantAgentKey(null);
|
|
@@ -2743,18 +3560,18 @@ function ContextUsageIndicator({
|
|
|
2743
3560
|
cancelled = true;
|
|
2744
3561
|
};
|
|
2745
3562
|
}, [stream.client, stream.assistantId]);
|
|
2746
|
-
|
|
3563
|
+
React20.useEffect(() => {
|
|
2747
3564
|
latestRealtimeUsageRef.current = {
|
|
2748
3565
|
threadId: stream.threadId ?? null,
|
|
2749
3566
|
agentKey: assistantAgentKey,
|
|
2750
3567
|
usedTokens: realtimeUsedContextSize
|
|
2751
3568
|
};
|
|
2752
3569
|
}, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
|
|
2753
|
-
|
|
3570
|
+
React20.useEffect(() => {
|
|
2754
3571
|
if (realtimeUsedContextSize == null) return;
|
|
2755
3572
|
setUsedContextSize(realtimeUsedContextSize);
|
|
2756
3573
|
}, [realtimeUsedContextSize]);
|
|
2757
|
-
|
|
3574
|
+
React20.useEffect(() => {
|
|
2758
3575
|
if (!stream.client) {
|
|
2759
3576
|
setUsedContextSize(null);
|
|
2760
3577
|
return;
|
|
@@ -2819,8 +3636,8 @@ function ContextUsageIndicator({
|
|
|
2819
3636
|
});
|
|
2820
3637
|
const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
|
|
2821
3638
|
const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
|
|
2822
|
-
return /* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
3639
|
+
return /* @__PURE__ */ jsxs14(Tooltip, { children: [
|
|
3640
|
+
/* @__PURE__ */ jsx26(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx26(
|
|
2824
3641
|
"button",
|
|
2825
3642
|
{
|
|
2826
3643
|
type: "button",
|
|
@@ -2829,20 +3646,21 @@ function ContextUsageIndicator({
|
|
|
2829
3646
|
className
|
|
2830
3647
|
),
|
|
2831
3648
|
"aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
|
|
2832
|
-
children: /* @__PURE__ */
|
|
3649
|
+
children: /* @__PURE__ */ jsx26(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
|
|
2833
3650
|
}
|
|
2834
3651
|
) }),
|
|
2835
|
-
/* @__PURE__ */
|
|
2836
|
-
/* @__PURE__ */
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
/* @__PURE__ */
|
|
3652
|
+
/* @__PURE__ */ jsxs14(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
|
|
3653
|
+
/* @__PURE__ */ jsx26("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
|
|
3654
|
+
/* @__PURE__ */ jsx26("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
|
|
3655
|
+
/* @__PURE__ */ jsx26("div", { className: "text-sm font-semibold", children: usageTokensLabel })
|
|
2839
3656
|
] })
|
|
2840
3657
|
] });
|
|
2841
3658
|
}
|
|
2842
3659
|
|
|
2843
3660
|
// src/components/chat.tsx
|
|
2844
|
-
import { Fragment as Fragment3, jsx as
|
|
3661
|
+
import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2845
3662
|
var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
|
|
3663
|
+
var COMPOSER_INPUT_MAX_HEIGHT = 128;
|
|
2846
3664
|
function formatMessageContent(content) {
|
|
2847
3665
|
if (typeof content === "string") {
|
|
2848
3666
|
return content;
|
|
@@ -2864,6 +3682,81 @@ function formatMessageContent(content) {
|
|
|
2864
3682
|
}
|
|
2865
3683
|
return "";
|
|
2866
3684
|
}
|
|
3685
|
+
function getClosestQuoteContainer(node) {
|
|
3686
|
+
if (!node) {
|
|
3687
|
+
return null;
|
|
3688
|
+
}
|
|
3689
|
+
const element = node instanceof HTMLElement ? node : node instanceof Text ? node.parentElement : null;
|
|
3690
|
+
return element?.closest("[data-quote-message-id]") ?? null;
|
|
3691
|
+
}
|
|
3692
|
+
function ReferenceChip({
|
|
3693
|
+
reference,
|
|
3694
|
+
variant,
|
|
3695
|
+
onRemove,
|
|
3696
|
+
removeLabel
|
|
3697
|
+
}) {
|
|
3698
|
+
const metaLine = getReferenceMetaLine(reference);
|
|
3699
|
+
const isComposer = variant === "composer";
|
|
3700
|
+
const Icon = reference.type === "quote" ? Quote : FileText2;
|
|
3701
|
+
return /* @__PURE__ */ jsxs15(
|
|
3702
|
+
"div",
|
|
3703
|
+
{
|
|
3704
|
+
className: cn(
|
|
3705
|
+
"flex items-start gap-2 rounded-md px-2 py-1",
|
|
3706
|
+
isComposer ? "bg-muted text-foreground" : "bg-primary-foreground/20"
|
|
3707
|
+
),
|
|
3708
|
+
title: getReferenceTitle(reference),
|
|
3709
|
+
children: [
|
|
3710
|
+
/* @__PURE__ */ jsx27(
|
|
3711
|
+
Icon,
|
|
3712
|
+
{
|
|
3713
|
+
size: isComposer ? 14 : 12,
|
|
3714
|
+
className: cn(
|
|
3715
|
+
"mt-0.5 shrink-0",
|
|
3716
|
+
isComposer ? "text-muted-foreground" : "text-primary-foreground/80"
|
|
3717
|
+
)
|
|
3718
|
+
}
|
|
3719
|
+
),
|
|
3720
|
+
/* @__PURE__ */ jsxs15("div", { className: "min-w-0 flex-1", children: [
|
|
3721
|
+
/* @__PURE__ */ jsx27(
|
|
3722
|
+
"div",
|
|
3723
|
+
{
|
|
3724
|
+
className: cn(
|
|
3725
|
+
"truncate",
|
|
3726
|
+
isComposer ? "text-sm" : "text-xs font-medium"
|
|
3727
|
+
),
|
|
3728
|
+
children: getReferenceLabel(reference)
|
|
3729
|
+
}
|
|
3730
|
+
),
|
|
3731
|
+
metaLine && /* @__PURE__ */ jsx27(
|
|
3732
|
+
"div",
|
|
3733
|
+
{
|
|
3734
|
+
className: cn(
|
|
3735
|
+
"truncate",
|
|
3736
|
+
isComposer ? "text-xs text-muted-foreground" : "text-[10px] text-primary-foreground/75"
|
|
3737
|
+
),
|
|
3738
|
+
children: metaLine
|
|
3739
|
+
}
|
|
3740
|
+
)
|
|
3741
|
+
] }),
|
|
3742
|
+
onRemove && removeLabel && /* @__PURE__ */ jsx27(
|
|
3743
|
+
"button",
|
|
3744
|
+
{
|
|
3745
|
+
type: "button",
|
|
3746
|
+
onClick: onRemove,
|
|
3747
|
+
className: cn(
|
|
3748
|
+
"ml-1 rounded-full p-0.5",
|
|
3749
|
+
isComposer ? "hover:bg-muted-foreground/20" : "hover:bg-primary-foreground/20"
|
|
3750
|
+
),
|
|
3751
|
+
title: removeLabel,
|
|
3752
|
+
"aria-label": removeLabel,
|
|
3753
|
+
children: /* @__PURE__ */ jsx27(X2, { size: 12 })
|
|
3754
|
+
}
|
|
3755
|
+
)
|
|
3756
|
+
]
|
|
3757
|
+
}
|
|
3758
|
+
);
|
|
3759
|
+
}
|
|
2867
3760
|
function Chat({
|
|
2868
3761
|
className,
|
|
2869
3762
|
options,
|
|
@@ -2880,17 +3773,21 @@ function Chat({
|
|
|
2880
3773
|
const apiUrl = options?.api?.apiUrl || defaultApiUrl2;
|
|
2881
3774
|
const { setStream } = useStreamManager();
|
|
2882
3775
|
const stream = useStreamContext();
|
|
2883
|
-
const
|
|
2884
|
-
const [
|
|
2885
|
-
const [
|
|
2886
|
-
const [
|
|
3776
|
+
const { theme } = useTheme();
|
|
3777
|
+
const [isHistoryLoading, setIsHistoryLoading] = React21.useState(false);
|
|
3778
|
+
const [historyError, setHistoryError] = React21.useState(null);
|
|
3779
|
+
const [assistantName, setAssistantName] = React21.useState(null);
|
|
3780
|
+
const [assistantAvatar, setAssistantAvatar] = React21.useState(null);
|
|
2887
3781
|
const LOADING_DOTS_MIN_DURATION = 800;
|
|
2888
|
-
const
|
|
2889
|
-
const
|
|
2890
|
-
|
|
3782
|
+
const STREAMING_STATUS_REFRESH_MS = 250;
|
|
3783
|
+
const [showLoadingDots, setShowLoadingDots] = React21.useState(false);
|
|
3784
|
+
const [streamingNow, setStreamingNow] = React21.useState(() => Date.now());
|
|
3785
|
+
const loadingStartTimeRef = React21.useRef(null);
|
|
3786
|
+
const lastStreamOutputAtRef = React21.useRef(null);
|
|
3787
|
+
React21.useEffect(() => {
|
|
2891
3788
|
setStream(stream);
|
|
2892
3789
|
}, [setStream, stream]);
|
|
2893
|
-
|
|
3790
|
+
React21.useEffect(() => {
|
|
2894
3791
|
if (stream.isLoading) {
|
|
2895
3792
|
if (!loadingStartTimeRef.current) {
|
|
2896
3793
|
loadingStartTimeRef.current = Date.now();
|
|
@@ -2913,67 +3810,180 @@ function Chat({
|
|
|
2913
3810
|
}
|
|
2914
3811
|
}
|
|
2915
3812
|
}, [stream.isLoading]);
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
3813
|
+
React21.useEffect(() => {
|
|
3814
|
+
if (!stream.isLoading) {
|
|
3815
|
+
lastStreamOutputAtRef.current = null;
|
|
3816
|
+
setStreamingNow(Date.now());
|
|
3817
|
+
return;
|
|
3818
|
+
}
|
|
3819
|
+
const now = Date.now();
|
|
3820
|
+
lastStreamOutputAtRef.current = now;
|
|
3821
|
+
setStreamingNow(now);
|
|
3822
|
+
}, [stream.messages, stream.isLoading]);
|
|
3823
|
+
React21.useEffect(() => {
|
|
3824
|
+
if (!stream.isLoading) {
|
|
3825
|
+
return;
|
|
3826
|
+
}
|
|
3827
|
+
const timer = window.setInterval(() => {
|
|
3828
|
+
setStreamingNow(Date.now());
|
|
3829
|
+
}, STREAMING_STATUS_REFRESH_MS);
|
|
3830
|
+
return () => window.clearInterval(timer);
|
|
3831
|
+
}, [stream.isLoading]);
|
|
3832
|
+
const [draft, setDraft] = React21.useState("");
|
|
3833
|
+
const [selectedTool, setSelectedTool] = React21.useState(
|
|
3834
|
+
null
|
|
3835
|
+
);
|
|
3836
|
+
const [attachments, setAttachments] = React21.useState([]);
|
|
3837
|
+
const [references, setReferences] = React21.useState([]);
|
|
3838
|
+
const [quoteSelection, setQuoteSelection] = React21.useState(null);
|
|
3839
|
+
const [isAtBottom, setIsAtBottom] = React21.useState(true);
|
|
3840
|
+
const [hasUpdatesBelow, setHasUpdatesBelow] = React21.useState(false);
|
|
2921
3841
|
const {
|
|
2922
3842
|
threads,
|
|
2923
3843
|
deleteThread,
|
|
2924
3844
|
refreshThreads,
|
|
2925
3845
|
isLoading: isThreadsLoading
|
|
2926
3846
|
} = useThreads();
|
|
2927
|
-
const viewportRef =
|
|
2928
|
-
const fileInputRef =
|
|
2929
|
-
const
|
|
2930
|
-
const
|
|
2931
|
-
const
|
|
2932
|
-
const
|
|
2933
|
-
const
|
|
2934
|
-
const
|
|
2935
|
-
const
|
|
3847
|
+
const viewportRef = React21.useRef(null);
|
|
3848
|
+
const fileInputRef = React21.useRef(null);
|
|
3849
|
+
const composerInputRef = React21.useRef(null);
|
|
3850
|
+
const shouldAutoScrollRef = React21.useRef(true);
|
|
3851
|
+
const forceFollowRef = React21.useRef(false);
|
|
3852
|
+
const previousMessageCountRef = React21.useRef(0);
|
|
3853
|
+
const previousScrollTopRef = React21.useRef(0);
|
|
3854
|
+
const autoScrollFrameRef = React21.useRef(null);
|
|
3855
|
+
const isPointerDownRef = React21.useRef(false);
|
|
3856
|
+
const lastTouchYRef = React21.useRef(null);
|
|
2936
3857
|
const resolvedTitle = title ?? t("chat.title");
|
|
2937
3858
|
const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
|
|
2938
3859
|
const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
|
|
2939
|
-
const messages =
|
|
3860
|
+
const messages = React21.useMemo(
|
|
3861
|
+
() => stream.messages ?? [],
|
|
3862
|
+
[stream.messages]
|
|
3863
|
+
);
|
|
2940
3864
|
const trimmedDraft = draft.trim();
|
|
2941
|
-
const
|
|
3865
|
+
const hasReferences = references.length > 0;
|
|
3866
|
+
const pendingFollowUps = React21.useMemo(
|
|
3867
|
+
() => [...stream.pendingFollowUps ?? []].sort(
|
|
3868
|
+
(a, b) => a.createdAt - b.createdAt
|
|
3869
|
+
),
|
|
3870
|
+
[stream.pendingFollowUps]
|
|
3871
|
+
);
|
|
3872
|
+
const clearQuoteSelection = React21.useCallback(() => {
|
|
3873
|
+
setQuoteSelection(null);
|
|
3874
|
+
}, []);
|
|
3875
|
+
useParentMessenger({
|
|
3876
|
+
onSetComposerValue: React21.useCallback(
|
|
3877
|
+
(payload) => {
|
|
3878
|
+
if (!payload) {
|
|
3879
|
+
return;
|
|
3880
|
+
}
|
|
3881
|
+
if (typeof payload.text === "string") {
|
|
3882
|
+
setDraft(payload.text);
|
|
3883
|
+
}
|
|
3884
|
+
if (Array.isArray(payload.references)) {
|
|
3885
|
+
const nextReferences = normalizeReferences(payload.references);
|
|
3886
|
+
setReferences(
|
|
3887
|
+
(previous) => payload.appendReferences ? mergeReferences(previous, nextReferences) : nextReferences
|
|
3888
|
+
);
|
|
3889
|
+
}
|
|
3890
|
+
if (payload.selectedToolId !== void 0) {
|
|
3891
|
+
const nextTool = payload.selectedToolId === null ? null : (composer?.tools ?? []).find(
|
|
3892
|
+
(tool) => tool.id === payload.selectedToolId
|
|
3893
|
+
) ?? null;
|
|
3894
|
+
setSelectedTool(nextTool);
|
|
3895
|
+
}
|
|
3896
|
+
},
|
|
3897
|
+
[composer?.tools]
|
|
3898
|
+
),
|
|
3899
|
+
onFocusComposer: React21.useCallback(() => {
|
|
3900
|
+
composerInputRef.current?.focus();
|
|
3901
|
+
}, [])
|
|
3902
|
+
});
|
|
3903
|
+
const syncQuoteSelection = React21.useCallback(() => {
|
|
3904
|
+
if (typeof window === "undefined") {
|
|
3905
|
+
clearQuoteSelection();
|
|
3906
|
+
return;
|
|
3907
|
+
}
|
|
3908
|
+
const selection = window.getSelection();
|
|
3909
|
+
if (!selection || selection.isCollapsed || selection.rangeCount === 0) {
|
|
3910
|
+
clearQuoteSelection();
|
|
3911
|
+
return;
|
|
3912
|
+
}
|
|
3913
|
+
const text = selection.toString().trim();
|
|
3914
|
+
if (!text) {
|
|
3915
|
+
clearQuoteSelection();
|
|
3916
|
+
return;
|
|
3917
|
+
}
|
|
3918
|
+
const anchorContainer = getClosestQuoteContainer(selection.anchorNode);
|
|
3919
|
+
const focusContainer = getClosestQuoteContainer(selection.focusNode);
|
|
3920
|
+
if (!anchorContainer || !focusContainer || anchorContainer !== focusContainer || !viewportRef.current?.contains(anchorContainer)) {
|
|
3921
|
+
clearQuoteSelection();
|
|
3922
|
+
return;
|
|
3923
|
+
}
|
|
3924
|
+
const range = selection.getRangeAt(0);
|
|
3925
|
+
const rect = range.getBoundingClientRect();
|
|
3926
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
3927
|
+
clearQuoteSelection();
|
|
3928
|
+
return;
|
|
3929
|
+
}
|
|
3930
|
+
const top = rect.bottom + 8 > window.innerHeight - 48 ? Math.max(12, rect.top - 44) : rect.bottom + 8;
|
|
3931
|
+
const left = Math.min(
|
|
3932
|
+
Math.max(24, rect.left + rect.width / 2),
|
|
3933
|
+
window.innerWidth - 24
|
|
3934
|
+
);
|
|
3935
|
+
const source = anchorContainer.dataset.quoteSource?.trim() || void 0;
|
|
3936
|
+
const messageId = anchorContainer.dataset.quoteMessageId?.trim() || void 0;
|
|
3937
|
+
setQuoteSelection({
|
|
3938
|
+
reference: {
|
|
3939
|
+
type: "quote",
|
|
3940
|
+
text,
|
|
3941
|
+
...messageId ? { messageId } : {},
|
|
3942
|
+
...source ? { source, label: source } : {}
|
|
3943
|
+
},
|
|
3944
|
+
top,
|
|
3945
|
+
left
|
|
3946
|
+
});
|
|
3947
|
+
}, [clearQuoteSelection]);
|
|
3948
|
+
const cancelPendingAutoScroll = React21.useCallback(() => {
|
|
2942
3949
|
if (autoScrollFrameRef.current !== null) {
|
|
2943
3950
|
cancelAnimationFrame(autoScrollFrameRef.current);
|
|
2944
3951
|
autoScrollFrameRef.current = null;
|
|
2945
3952
|
}
|
|
2946
3953
|
}, []);
|
|
2947
|
-
const disableAutoFollow =
|
|
3954
|
+
const disableAutoFollow = React21.useCallback(() => {
|
|
2948
3955
|
forceFollowRef.current = false;
|
|
2949
3956
|
shouldAutoScrollRef.current = false;
|
|
2950
3957
|
cancelPendingAutoScroll();
|
|
2951
3958
|
}, [cancelPendingAutoScroll]);
|
|
2952
|
-
const enableAutoFollow =
|
|
3959
|
+
const enableAutoFollow = React21.useCallback(() => {
|
|
2953
3960
|
forceFollowRef.current = true;
|
|
2954
3961
|
shouldAutoScrollRef.current = true;
|
|
2955
3962
|
setHasUpdatesBelow(false);
|
|
2956
3963
|
}, []);
|
|
2957
|
-
const scrollToBottom =
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
cancelPendingAutoScroll();
|
|
2962
|
-
autoScrollFrameRef.current = requestAnimationFrame(() => {
|
|
2963
|
-
autoScrollFrameRef.current = null;
|
|
2964
|
-
const viewport = viewportRef.current;
|
|
2965
|
-
if (viewport) {
|
|
2966
|
-
if (!force && !shouldAutoScrollRef.current) {
|
|
2967
|
-
return;
|
|
2968
|
-
}
|
|
2969
|
-
viewport.scrollTo({
|
|
2970
|
-
top: viewport.scrollHeight,
|
|
2971
|
-
behavior: smooth ? "smooth" : "instant"
|
|
2972
|
-
});
|
|
3964
|
+
const scrollToBottom = React21.useCallback(
|
|
3965
|
+
(smooth = false, force = false) => {
|
|
3966
|
+
if (force) {
|
|
3967
|
+
enableAutoFollow();
|
|
2973
3968
|
}
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
3969
|
+
cancelPendingAutoScroll();
|
|
3970
|
+
autoScrollFrameRef.current = requestAnimationFrame(() => {
|
|
3971
|
+
autoScrollFrameRef.current = null;
|
|
3972
|
+
const viewport = viewportRef.current;
|
|
3973
|
+
if (viewport) {
|
|
3974
|
+
if (!force && !shouldAutoScrollRef.current) {
|
|
3975
|
+
return;
|
|
3976
|
+
}
|
|
3977
|
+
viewport.scrollTo({
|
|
3978
|
+
top: viewport.scrollHeight,
|
|
3979
|
+
behavior: smooth ? "smooth" : "instant"
|
|
3980
|
+
});
|
|
3981
|
+
}
|
|
3982
|
+
});
|
|
3983
|
+
},
|
|
3984
|
+
[cancelPendingAutoScroll, enableAutoFollow]
|
|
3985
|
+
);
|
|
3986
|
+
React21.useEffect(() => {
|
|
2977
3987
|
const viewport = viewportRef.current;
|
|
2978
3988
|
if (!viewport) return;
|
|
2979
3989
|
previousScrollTopRef.current = viewport.scrollTop;
|
|
@@ -3025,13 +4035,23 @@ function Chat({
|
|
|
3025
4035
|
};
|
|
3026
4036
|
updateAutoScrollState();
|
|
3027
4037
|
viewport.addEventListener("wheel", handleWheel, { passive: true });
|
|
3028
|
-
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
3029
|
-
|
|
3030
|
-
|
|
4038
|
+
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
4039
|
+
passive: true
|
|
4040
|
+
});
|
|
4041
|
+
viewport.addEventListener("scroll", updateAutoScrollState, {
|
|
4042
|
+
passive: true
|
|
4043
|
+
});
|
|
4044
|
+
viewport.addEventListener("touchstart", handleTouchStart, {
|
|
4045
|
+
passive: true
|
|
4046
|
+
});
|
|
3031
4047
|
viewport.addEventListener("touchmove", handleTouchMove, { passive: true });
|
|
3032
4048
|
viewport.addEventListener("touchend", handleTouchEnd, { passive: true });
|
|
3033
|
-
window.addEventListener("pointerup", stopPointerTracking, {
|
|
3034
|
-
|
|
4049
|
+
window.addEventListener("pointerup", stopPointerTracking, {
|
|
4050
|
+
passive: true
|
|
4051
|
+
});
|
|
4052
|
+
window.addEventListener("pointercancel", stopPointerTracking, {
|
|
4053
|
+
passive: true
|
|
4054
|
+
});
|
|
3035
4055
|
return () => {
|
|
3036
4056
|
cancelPendingAutoScroll();
|
|
3037
4057
|
viewport.removeEventListener("wheel", handleWheel);
|
|
@@ -3044,14 +4064,14 @@ function Chat({
|
|
|
3044
4064
|
window.removeEventListener("pointercancel", stopPointerTracking);
|
|
3045
4065
|
};
|
|
3046
4066
|
}, [cancelPendingAutoScroll, disableAutoFollow]);
|
|
3047
|
-
|
|
4067
|
+
React21.useEffect(() => {
|
|
3048
4068
|
shouldAutoScrollRef.current = true;
|
|
3049
4069
|
forceFollowRef.current = false;
|
|
3050
4070
|
previousScrollTopRef.current = 0;
|
|
3051
4071
|
setIsAtBottom(true);
|
|
3052
4072
|
setHasUpdatesBelow(false);
|
|
3053
4073
|
}, [stream.threadId]);
|
|
3054
|
-
|
|
4074
|
+
React21.useEffect(() => {
|
|
3055
4075
|
const messageCountChanged = messages.length !== previousMessageCountRef.current;
|
|
3056
4076
|
previousMessageCountRef.current = messages.length;
|
|
3057
4077
|
if (!shouldAutoScrollRef.current) {
|
|
@@ -3065,16 +4085,85 @@ function Chat({
|
|
|
3065
4085
|
}
|
|
3066
4086
|
}, [stream.isLoading, messages, scrollToBottom]);
|
|
3067
4087
|
const effectiveClientSecret = stream.apiKey?.trim() ? stream.apiKey : clientSecret;
|
|
3068
|
-
const
|
|
3069
|
-
|
|
4088
|
+
const missingConfigKind = getMissingApiConfigurationKind({
|
|
4089
|
+
apiUrl,
|
|
4090
|
+
clientSecret: effectiveClientSecret
|
|
4091
|
+
});
|
|
4092
|
+
const missingConfig = Boolean(missingConfigKind);
|
|
4093
|
+
const missingConfigShortMessage = React21.useMemo(() => {
|
|
4094
|
+
switch (missingConfigKind) {
|
|
4095
|
+
case "apiUrl":
|
|
4096
|
+
return t("chat.missingApiUrlShort");
|
|
4097
|
+
case "clientSecret":
|
|
4098
|
+
return t("chat.missingClientSecretShort");
|
|
4099
|
+
case "apiUrlAndClientSecret":
|
|
4100
|
+
return t("chat.missingApiUrlAndClientSecretShort");
|
|
4101
|
+
default:
|
|
4102
|
+
return t("chat.missingConfigShort");
|
|
4103
|
+
}
|
|
4104
|
+
}, [missingConfigKind, t]);
|
|
4105
|
+
const missingConfigDetailMessage = React21.useMemo(() => {
|
|
4106
|
+
switch (missingConfigKind) {
|
|
4107
|
+
case "apiUrl":
|
|
4108
|
+
return t("chat.missingApiUrlDetail");
|
|
4109
|
+
case "clientSecret":
|
|
4110
|
+
return t("chat.missingClientSecretDetail");
|
|
4111
|
+
case "apiUrlAndClientSecret":
|
|
4112
|
+
return t("chat.missingApiUrlAndClientSecretDetail");
|
|
4113
|
+
default:
|
|
4114
|
+
return t("chat.missingConfigDetail");
|
|
4115
|
+
}
|
|
4116
|
+
}, [missingConfigKind, t]);
|
|
3070
4117
|
const showMissingConfig = !isClientSecretInitializing && missingConfig;
|
|
3071
4118
|
const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
|
|
3072
|
-
const isSendDisabled = !trimmedDraft
|
|
3073
|
-
|
|
4119
|
+
const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles;
|
|
4120
|
+
const resizeComposerInput = React21.useCallback(() => {
|
|
4121
|
+
const textarea = composerInputRef.current;
|
|
4122
|
+
if (!textarea) {
|
|
4123
|
+
return;
|
|
4124
|
+
}
|
|
4125
|
+
textarea.style.height = "auto";
|
|
4126
|
+
const nextHeight = Math.min(
|
|
4127
|
+
textarea.scrollHeight,
|
|
4128
|
+
COMPOSER_INPUT_MAX_HEIGHT
|
|
4129
|
+
);
|
|
4130
|
+
textarea.style.height = `${nextHeight}px`;
|
|
4131
|
+
textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
|
|
4132
|
+
}, []);
|
|
4133
|
+
React21.useEffect(() => {
|
|
4134
|
+
resizeComposerInput();
|
|
4135
|
+
}, [draft, resizeComposerInput]);
|
|
4136
|
+
React21.useEffect(() => {
|
|
4137
|
+
document.addEventListener("selectionchange", syncQuoteSelection);
|
|
4138
|
+
return () => {
|
|
4139
|
+
document.removeEventListener("selectionchange", syncQuoteSelection);
|
|
4140
|
+
};
|
|
4141
|
+
}, [syncQuoteSelection]);
|
|
4142
|
+
React21.useEffect(() => {
|
|
4143
|
+
const viewport = viewportRef.current;
|
|
4144
|
+
if (!viewport) {
|
|
4145
|
+
return;
|
|
4146
|
+
}
|
|
4147
|
+
const handleViewportScroll = () => {
|
|
4148
|
+
clearQuoteSelection();
|
|
4149
|
+
};
|
|
4150
|
+
viewport.addEventListener("scroll", handleViewportScroll, {
|
|
4151
|
+
passive: true
|
|
4152
|
+
});
|
|
4153
|
+
window.addEventListener("resize", handleViewportScroll, { passive: true });
|
|
4154
|
+
return () => {
|
|
4155
|
+
viewport.removeEventListener("scroll", handleViewportScroll);
|
|
4156
|
+
window.removeEventListener("resize", handleViewportScroll);
|
|
4157
|
+
};
|
|
4158
|
+
}, [clearQuoteSelection]);
|
|
4159
|
+
React21.useEffect(() => {
|
|
4160
|
+
clearQuoteSelection();
|
|
4161
|
+
}, [messages.length, stream.threadId, clearQuoteSelection]);
|
|
4162
|
+
React21.useEffect(() => {
|
|
3074
4163
|
if (missingConfig) return;
|
|
3075
4164
|
void refreshThreads();
|
|
3076
4165
|
}, [missingConfig, refreshThreads]);
|
|
3077
|
-
|
|
4166
|
+
React21.useEffect(() => {
|
|
3078
4167
|
if (missingConfig || !stream.client || !stream.assistantId) {
|
|
3079
4168
|
setAssistantName(null);
|
|
3080
4169
|
setAssistantAvatar(null);
|
|
@@ -3105,80 +4194,186 @@ function Chat({
|
|
|
3105
4194
|
mimetype: a.storageFile?.mimetype ?? a.file.type,
|
|
3106
4195
|
size: a.storageFile?.size ?? a.file.size
|
|
3107
4196
|
}));
|
|
4197
|
+
const submitDraft = React21.useCallback(
|
|
4198
|
+
(followUpOverride) => {
|
|
4199
|
+
if (isSendDisabled) return;
|
|
4200
|
+
const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
|
|
4201
|
+
const referencesToSend = references.length > 0 ? [...references] : void 0;
|
|
4202
|
+
const nextFollowUpMode = stream.isLoading ? followUpOverride ?? stream.followUpBehavior : void 0;
|
|
4203
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
4204
|
+
content: trimmedDraft,
|
|
4205
|
+
references: referencesToSend
|
|
4206
|
+
});
|
|
4207
|
+
if (!humanInput) {
|
|
4208
|
+
return;
|
|
4209
|
+
}
|
|
4210
|
+
const displayContent = trimmedDraft || (referencesToSend ? t("chat.referencedContentOnly") : "");
|
|
4211
|
+
const newMessage = {
|
|
4212
|
+
id: createMessageId(),
|
|
4213
|
+
type: "human",
|
|
4214
|
+
content: displayContent,
|
|
4215
|
+
submittedInput: humanInput.input,
|
|
4216
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
4217
|
+
...filesToSend ? { attachments: filesToSend } : {},
|
|
4218
|
+
...referencesToSend ? { references: referencesToSend } : {}
|
|
4219
|
+
};
|
|
4220
|
+
setDraft("");
|
|
4221
|
+
const inputPayload = {
|
|
4222
|
+
...humanInput
|
|
4223
|
+
};
|
|
4224
|
+
if (filesToSend) {
|
|
4225
|
+
inputPayload.files = filesToSend;
|
|
4226
|
+
}
|
|
4227
|
+
const requestOptions = buildInjectedRequestOptions({
|
|
4228
|
+
defaults: options?.request,
|
|
4229
|
+
humanInput: inputPayload
|
|
4230
|
+
});
|
|
4231
|
+
stream.submit(
|
|
4232
|
+
{
|
|
4233
|
+
input: inputPayload,
|
|
4234
|
+
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
4235
|
+
},
|
|
4236
|
+
{
|
|
4237
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
4238
|
+
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
4239
|
+
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
4240
|
+
...!nextFollowUpMode ? {
|
|
4241
|
+
optimisticValues: (prev) => {
|
|
4242
|
+
const prevMessages = prev?.messages ?? [];
|
|
4243
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
4244
|
+
}
|
|
4245
|
+
} : {}
|
|
4246
|
+
}
|
|
4247
|
+
);
|
|
4248
|
+
scrollToBottom(true, true);
|
|
4249
|
+
if (selectedTool && !selectedTool.pinned) {
|
|
4250
|
+
setSelectedTool(null);
|
|
4251
|
+
}
|
|
4252
|
+
setAttachments([]);
|
|
4253
|
+
setReferences([]);
|
|
4254
|
+
},
|
|
4255
|
+
[
|
|
4256
|
+
isSendDisabled,
|
|
4257
|
+
options?.request,
|
|
4258
|
+
references,
|
|
4259
|
+
scrollToBottom,
|
|
4260
|
+
selectedTool,
|
|
4261
|
+
stream,
|
|
4262
|
+
trimmedDraft,
|
|
4263
|
+
uploadedFiles,
|
|
4264
|
+
t
|
|
4265
|
+
]
|
|
4266
|
+
);
|
|
3108
4267
|
const handleSubmit = (event) => {
|
|
3109
4268
|
event.preventDefault();
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
const inputPayload = {
|
|
3120
|
-
input: trimmedDraft
|
|
3121
|
-
};
|
|
3122
|
-
if (filesToSend) {
|
|
3123
|
-
inputPayload.files = filesToSend;
|
|
3124
|
-
}
|
|
3125
|
-
const requestOptions = buildInjectedRequestOptions({
|
|
3126
|
-
defaults: options?.request,
|
|
3127
|
-
humanInput: inputPayload
|
|
3128
|
-
});
|
|
3129
|
-
stream.submit(
|
|
3130
|
-
{
|
|
3131
|
-
input: inputPayload,
|
|
3132
|
-
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
3133
|
-
},
|
|
3134
|
-
{
|
|
3135
|
-
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
3136
|
-
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
3137
|
-
optimisticValues: (prev) => {
|
|
3138
|
-
const prevMessages = prev?.messages ?? [];
|
|
3139
|
-
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
3140
|
-
}
|
|
4269
|
+
submitDraft();
|
|
4270
|
+
};
|
|
4271
|
+
const handleEditPendingFollowUp = React21.useCallback(
|
|
4272
|
+
(id) => {
|
|
4273
|
+
const item = pendingFollowUps.find(
|
|
4274
|
+
(entry) => entry.id === id && entry.mode === "queue"
|
|
4275
|
+
);
|
|
4276
|
+
if (!item) {
|
|
4277
|
+
return;
|
|
3141
4278
|
}
|
|
4279
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
4280
|
+
const nextReferences = normalizeReferences(
|
|
4281
|
+
item.request?.input?.references
|
|
4282
|
+
);
|
|
4283
|
+
stream.removePendingFollowUp(id);
|
|
4284
|
+
setDraft(text);
|
|
4285
|
+
setReferences(nextReferences);
|
|
4286
|
+
requestAnimationFrame(() => {
|
|
4287
|
+
const input = composerInputRef.current;
|
|
4288
|
+
if (!input) {
|
|
4289
|
+
return;
|
|
4290
|
+
}
|
|
4291
|
+
input.focus();
|
|
4292
|
+
const position = text.length;
|
|
4293
|
+
input.setSelectionRange(position, position);
|
|
4294
|
+
});
|
|
4295
|
+
},
|
|
4296
|
+
[pendingFollowUps, stream]
|
|
4297
|
+
);
|
|
4298
|
+
const handleQuoteSelection = React21.useCallback(() => {
|
|
4299
|
+
if (!quoteSelection) {
|
|
4300
|
+
return;
|
|
4301
|
+
}
|
|
4302
|
+
setReferences(
|
|
4303
|
+
(previous) => mergeReferences(previous, [quoteSelection.reference])
|
|
3142
4304
|
);
|
|
3143
|
-
|
|
3144
|
-
if (
|
|
3145
|
-
|
|
4305
|
+
clearQuoteSelection();
|
|
4306
|
+
if (typeof window !== "undefined") {
|
|
4307
|
+
window.getSelection()?.removeAllRanges();
|
|
3146
4308
|
}
|
|
3147
|
-
|
|
3148
|
-
};
|
|
4309
|
+
composerInputRef.current?.focus();
|
|
4310
|
+
}, [clearQuoteSelection, quoteSelection]);
|
|
3149
4311
|
const handleAttachmentClick = () => {
|
|
3150
4312
|
fileInputRef.current?.click();
|
|
3151
4313
|
};
|
|
3152
|
-
const
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
4314
|
+
const handleComposerKeyDown = (event) => {
|
|
4315
|
+
if (event.key !== "Enter") {
|
|
4316
|
+
return;
|
|
4317
|
+
}
|
|
4318
|
+
if (event.shiftKey && (event.metaKey || event.ctrlKey)) {
|
|
4319
|
+
if (event.nativeEvent.isComposing) {
|
|
4320
|
+
return;
|
|
4321
|
+
}
|
|
4322
|
+
event.preventDefault();
|
|
4323
|
+
if (isSendDisabled) {
|
|
4324
|
+
return;
|
|
4325
|
+
}
|
|
4326
|
+
submitDraft(stream.followUpBehavior === "queue" ? "steer" : "queue");
|
|
4327
|
+
return;
|
|
4328
|
+
}
|
|
4329
|
+
if (event.shiftKey) {
|
|
4330
|
+
return;
|
|
4331
|
+
}
|
|
4332
|
+
if (event.nativeEvent.isComposing) {
|
|
4333
|
+
return;
|
|
4334
|
+
}
|
|
4335
|
+
event.preventDefault();
|
|
4336
|
+
if (isSendDisabled) {
|
|
4337
|
+
return;
|
|
4338
|
+
}
|
|
4339
|
+
submitDraft();
|
|
4340
|
+
};
|
|
4341
|
+
const uploadFile = React21.useCallback(
|
|
4342
|
+
async (localId, file) => {
|
|
4343
|
+
try {
|
|
4344
|
+
const result = await stream.client.contexts.uploadFile(file);
|
|
4345
|
+
setAttachments(
|
|
4346
|
+
(prev) => prev.map(
|
|
4347
|
+
(item) => item.localId === localId ? { ...item, status: "success", storageFile: result } : item
|
|
4348
|
+
)
|
|
4349
|
+
);
|
|
4350
|
+
} catch (error) {
|
|
4351
|
+
setAttachments(
|
|
4352
|
+
(prev) => prev.map(
|
|
4353
|
+
(item) => item.localId === localId ? {
|
|
4354
|
+
...item,
|
|
4355
|
+
status: "error",
|
|
4356
|
+
error: error instanceof Error ? error.message : "Upload failed"
|
|
4357
|
+
} : item
|
|
4358
|
+
)
|
|
4359
|
+
);
|
|
4360
|
+
}
|
|
4361
|
+
},
|
|
4362
|
+
[stream.client]
|
|
4363
|
+
);
|
|
4364
|
+
const handleRetryUpload = React21.useCallback(
|
|
4365
|
+
(localId) => {
|
|
4366
|
+
const attachment = attachments.find((a) => a.localId === localId);
|
|
4367
|
+
if (!attachment || attachment.status !== "error") return;
|
|
3161
4368
|
setAttachments(
|
|
3162
4369
|
(prev) => prev.map(
|
|
3163
|
-
(item) => item.localId === localId ? {
|
|
3164
|
-
...item,
|
|
3165
|
-
status: "error",
|
|
3166
|
-
error: error instanceof Error ? error.message : "Upload failed"
|
|
3167
|
-
} : item
|
|
4370
|
+
(item) => item.localId === localId ? { ...item, status: "uploading", error: void 0 } : item
|
|
3168
4371
|
)
|
|
3169
4372
|
);
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
if (!attachment || attachment.status !== "error") return;
|
|
3175
|
-
setAttachments(
|
|
3176
|
-
(prev) => prev.map(
|
|
3177
|
-
(item) => item.localId === localId ? { ...item, status: "uploading", error: void 0 } : item
|
|
3178
|
-
)
|
|
3179
|
-
);
|
|
3180
|
-
void uploadFile(localId, attachment.file);
|
|
3181
|
-
}, [attachments, uploadFile]);
|
|
4373
|
+
void uploadFile(localId, attachment.file);
|
|
4374
|
+
},
|
|
4375
|
+
[attachments, uploadFile]
|
|
4376
|
+
);
|
|
3182
4377
|
const handleFileChange = (event) => {
|
|
3183
4378
|
const files = event.target.files;
|
|
3184
4379
|
if (!files || files.length === 0) return;
|
|
@@ -3212,12 +4407,15 @@ function Chat({
|
|
|
3212
4407
|
if (!attachment) return;
|
|
3213
4408
|
if (attachment.status === "success" && attachment.storageFile?.id) {
|
|
3214
4409
|
try {
|
|
3215
|
-
await fetch(
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
"
|
|
4410
|
+
await fetch(
|
|
4411
|
+
`${stream.apiUrl}/contexts/file/${attachment.storageFile.id}`,
|
|
4412
|
+
{
|
|
4413
|
+
method: "DELETE",
|
|
4414
|
+
headers: {
|
|
4415
|
+
Authorization: `Bearer ${effectiveClientSecret}`
|
|
4416
|
+
}
|
|
3219
4417
|
}
|
|
3220
|
-
|
|
4418
|
+
);
|
|
3221
4419
|
} catch {
|
|
3222
4420
|
}
|
|
3223
4421
|
}
|
|
@@ -3227,27 +4425,31 @@ function Chat({
|
|
|
3227
4425
|
setSelectedTool((prev) => prev?.id === tool.id ? null : tool);
|
|
3228
4426
|
};
|
|
3229
4427
|
const handlePromptClick = (prompt) => {
|
|
3230
|
-
if (missingConfig ||
|
|
4428
|
+
if (missingConfig || isHistoryLoading) return;
|
|
3231
4429
|
const newMessage = {
|
|
3232
4430
|
id: createMessageId(),
|
|
3233
4431
|
type: "human",
|
|
3234
4432
|
content: prompt
|
|
3235
4433
|
};
|
|
4434
|
+
const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
|
|
3236
4435
|
stream.submit(
|
|
3237
4436
|
{ input: { input: prompt } },
|
|
3238
4437
|
{
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
4438
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
4439
|
+
...!nextFollowUpMode ? {
|
|
4440
|
+
optimisticValues: (prev) => {
|
|
4441
|
+
const prevMessages = prev?.messages ?? [];
|
|
4442
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
4443
|
+
}
|
|
4444
|
+
} : {}
|
|
3243
4445
|
}
|
|
3244
4446
|
);
|
|
3245
4447
|
scrollToBottom(true, true);
|
|
3246
4448
|
};
|
|
3247
|
-
const loadConversationMessages =
|
|
4449
|
+
const loadConversationMessages = React21.useCallback(
|
|
3248
4450
|
async (recordId) => {
|
|
3249
4451
|
if (missingConfig) {
|
|
3250
|
-
setHistoryError(
|
|
4452
|
+
setHistoryError(missingConfigShortMessage);
|
|
3251
4453
|
return;
|
|
3252
4454
|
}
|
|
3253
4455
|
setHistoryError(null);
|
|
@@ -3263,7 +4465,7 @@ function Chat({
|
|
|
3263
4465
|
setIsHistoryLoading(false);
|
|
3264
4466
|
}
|
|
3265
4467
|
},
|
|
3266
|
-
[missingConfig, stream, t]
|
|
4468
|
+
[missingConfig, missingConfigShortMessage, stream, t]
|
|
3267
4469
|
);
|
|
3268
4470
|
const handleNewThread = async () => {
|
|
3269
4471
|
if (missingConfig || isHistoryLoading) return;
|
|
@@ -3306,12 +4508,16 @@ function Chat({
|
|
|
3306
4508
|
};
|
|
3307
4509
|
const handleRetry = (messageIndex) => {
|
|
3308
4510
|
const messagesUpToIndex = messages.slice(0, messageIndex);
|
|
3309
|
-
const lastHumanMessage = [...messagesUpToIndex].reverse().find(
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
4511
|
+
const lastHumanMessage = [...messagesUpToIndex].reverse().find((m) => String(m.type) === "human");
|
|
4512
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
4513
|
+
content: lastHumanMessage && typeof lastHumanMessage.content === "string" ? lastHumanMessage.content : "",
|
|
4514
|
+
submittedInput: lastHumanMessage?.submittedInput,
|
|
4515
|
+
references: lastHumanMessage?.references,
|
|
4516
|
+
referenceComposition: lastHumanMessage?.referenceComposition
|
|
4517
|
+
});
|
|
4518
|
+
if (humanInput) {
|
|
3313
4519
|
stream.submit(
|
|
3314
|
-
{ input:
|
|
4520
|
+
{ input: humanInput },
|
|
3315
4521
|
{
|
|
3316
4522
|
optimisticValues: (prev) => {
|
|
3317
4523
|
const prevMessages = prev?.messages ?? [];
|
|
@@ -3326,18 +4532,18 @@ function Chat({
|
|
|
3326
4532
|
}
|
|
3327
4533
|
};
|
|
3328
4534
|
const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
|
|
3329
|
-
const currentThread =
|
|
4535
|
+
const currentThread = React21.useMemo(
|
|
3330
4536
|
() => threads.find((item) => item.id === stream.threadId),
|
|
3331
4537
|
[threads, stream.threadId]
|
|
3332
4538
|
);
|
|
3333
4539
|
const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
|
|
3334
|
-
const threadErrorMessage =
|
|
4540
|
+
const threadErrorMessage = React21.useMemo(() => {
|
|
3335
4541
|
if (currentThread?.status !== "error") return void 0;
|
|
3336
4542
|
const message = currentThread.error?.trim();
|
|
3337
4543
|
return message || t("thread.errorToast");
|
|
3338
4544
|
}, [currentThread, t]);
|
|
3339
4545
|
const assistantTitle = assistantName || resolvedTitle;
|
|
3340
|
-
return /* @__PURE__ */
|
|
4546
|
+
return /* @__PURE__ */ jsxs15(
|
|
3341
4547
|
"div",
|
|
3342
4548
|
{
|
|
3343
4549
|
ref: viewportRef,
|
|
@@ -3346,10 +4552,10 @@ function Chat({
|
|
|
3346
4552
|
className
|
|
3347
4553
|
),
|
|
3348
4554
|
children: [
|
|
3349
|
-
/* @__PURE__ */
|
|
3350
|
-
/* @__PURE__ */
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
4555
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
|
|
4556
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-3 overflow-hidden", children: [
|
|
4557
|
+
/* @__PURE__ */ jsxs15("div", { className: "relative shrink-0", children: [
|
|
4558
|
+
/* @__PURE__ */ jsx27(
|
|
3353
4559
|
ChatkitAvatar,
|
|
3354
4560
|
{
|
|
3355
4561
|
avatar: assistantAvatar,
|
|
@@ -3357,15 +4563,22 @@ function Chat({
|
|
|
3357
4563
|
label: assistantTitle
|
|
3358
4564
|
}
|
|
3359
4565
|
),
|
|
3360
|
-
/* @__PURE__ */
|
|
4566
|
+
/* @__PURE__ */ jsx27("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
|
|
3361
4567
|
] }),
|
|
3362
|
-
/* @__PURE__ */
|
|
3363
|
-
/* @__PURE__ */
|
|
3364
|
-
|
|
4568
|
+
/* @__PURE__ */ jsxs15("div", { className: "truncate", children: [
|
|
4569
|
+
/* @__PURE__ */ jsx27(
|
|
4570
|
+
"h2",
|
|
4571
|
+
{
|
|
4572
|
+
className: "text-lg font-semibold truncate",
|
|
4573
|
+
title: assistantTitle,
|
|
4574
|
+
children: assistantTitle
|
|
4575
|
+
}
|
|
4576
|
+
),
|
|
4577
|
+
/* @__PURE__ */ jsx27("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
|
|
3365
4578
|
] })
|
|
3366
4579
|
] }),
|
|
3367
|
-
history?.enabled !== false && /* @__PURE__ */
|
|
3368
|
-
/* @__PURE__ */
|
|
4580
|
+
history?.enabled !== false && /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1", children: [
|
|
4581
|
+
/* @__PURE__ */ jsx27(
|
|
3369
4582
|
"button",
|
|
3370
4583
|
{
|
|
3371
4584
|
type: "button",
|
|
@@ -3378,10 +4591,10 @@ function Chat({
|
|
|
3378
4591
|
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
3379
4592
|
),
|
|
3380
4593
|
title: t("history.newThread"),
|
|
3381
|
-
children: /* @__PURE__ */
|
|
4594
|
+
children: /* @__PURE__ */ jsx27(Pencil3, { size: 16 })
|
|
3382
4595
|
}
|
|
3383
4596
|
),
|
|
3384
|
-
/* @__PURE__ */
|
|
4597
|
+
/* @__PURE__ */ jsx27(
|
|
3385
4598
|
HistorySidebar,
|
|
3386
4599
|
{
|
|
3387
4600
|
threads,
|
|
@@ -3395,23 +4608,45 @@ function Chat({
|
|
|
3395
4608
|
)
|
|
3396
4609
|
] })
|
|
3397
4610
|
] }),
|
|
3398
|
-
/* @__PURE__ */
|
|
3399
|
-
errorMessage && /* @__PURE__ */
|
|
3400
|
-
historyError && /* @__PURE__ */
|
|
3401
|
-
showMissingConfig && /* @__PURE__ */
|
|
3402
|
-
isHistoryLoading && /* @__PURE__ */
|
|
3403
|
-
messages.length === 0 ? /* @__PURE__ */
|
|
4611
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex-1 p-4", children: [
|
|
4612
|
+
errorMessage && /* @__PURE__ */ jsx27("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
|
|
4613
|
+
historyError && /* @__PURE__ */ jsx27("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
|
|
4614
|
+
showMissingConfig && /* @__PURE__ */ jsx27("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
|
|
4615
|
+
isHistoryLoading && /* @__PURE__ */ jsx27("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
|
|
4616
|
+
messages.length === 0 ? /* @__PURE__ */ jsx27(
|
|
3404
4617
|
StartScreen,
|
|
3405
4618
|
{
|
|
3406
4619
|
startScreen,
|
|
3407
4620
|
onPromptClick: handlePromptClick
|
|
3408
4621
|
}
|
|
3409
|
-
) : /* @__PURE__ */
|
|
4622
|
+
) : /* @__PURE__ */ jsxs15("div", { className: "space-y-4", children: [
|
|
3410
4623
|
messages.map((message, index) => {
|
|
3411
4624
|
const messageType = String(message.type);
|
|
3412
4625
|
const isAssistantMessage = messageType === "assistant" || messageType === "ai";
|
|
4626
|
+
const isStreamingMessage = stream.isLoading && index === messages.length - 1;
|
|
4627
|
+
const streamingStatus = isAssistantMessage ? getAssistantStreamingStatus(
|
|
4628
|
+
{
|
|
4629
|
+
...message,
|
|
4630
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
4631
|
+
},
|
|
4632
|
+
isStreamingMessage,
|
|
4633
|
+
{ now: streamingNow }
|
|
4634
|
+
) : null;
|
|
4635
|
+
if (isAssistantMessage && !hasRenderableAssistantMessage(message) && !streamingStatus) {
|
|
4636
|
+
return null;
|
|
4637
|
+
}
|
|
3413
4638
|
const messageContent = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.map((part) => formatMessageContent(part)).join("") : formatMessageContent(message.content);
|
|
3414
|
-
|
|
4639
|
+
const hasPlainRenderableContent = messageContent.trim().length > 0;
|
|
4640
|
+
const humanMessage = message;
|
|
4641
|
+
const humanReferences = humanMessage.references ?? [];
|
|
4642
|
+
const humanAttachments = humanMessage.attachments ?? [];
|
|
4643
|
+
const hasHumanAttachments = message.type === "human" && humanAttachments.length > 0;
|
|
4644
|
+
const canQuoteMessage = message.type === "human" || isAssistantMessage;
|
|
4645
|
+
const quoteSource = message.type === "human" ? t("chat.youLabel") : assistantTitle;
|
|
4646
|
+
if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
|
|
4647
|
+
return null;
|
|
4648
|
+
}
|
|
4649
|
+
return /* @__PURE__ */ jsx27(
|
|
3415
4650
|
"div",
|
|
3416
4651
|
{
|
|
3417
4652
|
className: cn(
|
|
@@ -3419,53 +4654,66 @@ function Chat({
|
|
|
3419
4654
|
message.type === "human" ? "justify-end" : "justify-start -ml-1"
|
|
3420
4655
|
// AI messages: slightly closer to left
|
|
3421
4656
|
),
|
|
3422
|
-
children: /* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
4657
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "flex flex-col px-3 overflow-hidden", children: [
|
|
4658
|
+
/* @__PURE__ */ jsx27(
|
|
3424
4659
|
"div",
|
|
3425
4660
|
{
|
|
4661
|
+
...canQuoteMessage ? {
|
|
4662
|
+
"data-quote-message-id": message.id,
|
|
4663
|
+
"data-quote-source": quoteSource
|
|
4664
|
+
} : {},
|
|
3426
4665
|
className: cn(
|
|
3427
4666
|
"max-w-full rounded-2xl",
|
|
3428
4667
|
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"
|
|
3429
4668
|
// AI messages: use chat-specific foreground color
|
|
3430
4669
|
),
|
|
3431
|
-
children: isAssistantMessage ? /* @__PURE__ */
|
|
4670
|
+
children: isAssistantMessage ? /* @__PURE__ */ jsx27(
|
|
3432
4671
|
AssistantMessage,
|
|
3433
4672
|
{
|
|
3434
4673
|
message: {
|
|
3435
4674
|
...message,
|
|
3436
4675
|
type: "assistant"
|
|
3437
4676
|
},
|
|
3438
|
-
isStreaming:
|
|
4677
|
+
isStreaming: isStreamingMessage,
|
|
4678
|
+
streamingStatus
|
|
3439
4679
|
}
|
|
3440
|
-
) : /* @__PURE__ */
|
|
3441
|
-
message.type === "human" &&
|
|
4680
|
+
) : /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
4681
|
+
message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx27("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx27(
|
|
4682
|
+
ReferenceChip,
|
|
4683
|
+
{
|
|
4684
|
+
reference,
|
|
4685
|
+
variant: "message"
|
|
4686
|
+
},
|
|
4687
|
+
getReferenceKey(reference)
|
|
4688
|
+
)) }),
|
|
4689
|
+
message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs15(
|
|
3442
4690
|
"div",
|
|
3443
4691
|
{
|
|
3444
4692
|
className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
|
|
3445
4693
|
children: [
|
|
3446
|
-
/* @__PURE__ */
|
|
3447
|
-
/* @__PURE__ */
|
|
4694
|
+
/* @__PURE__ */ jsx27(FileText2, { size: 12 }),
|
|
4695
|
+
/* @__PURE__ */ jsx27("span", { className: "max-w-[100px] truncate", children: file.originalName })
|
|
3448
4696
|
]
|
|
3449
4697
|
},
|
|
3450
4698
|
fileIndex
|
|
3451
4699
|
)) }),
|
|
3452
|
-
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */
|
|
4700
|
+
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx27(
|
|
3453
4701
|
"p",
|
|
3454
4702
|
{
|
|
3455
4703
|
className: "wrap-break-word text-sm leading-relaxed",
|
|
3456
4704
|
children: formatMessageContent(part)
|
|
3457
4705
|
},
|
|
3458
4706
|
`${part.type}-${partIndex}`
|
|
3459
|
-
)) : /* @__PURE__ */
|
|
4707
|
+
)) : /* @__PURE__ */ jsx27("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
|
|
3460
4708
|
] })
|
|
3461
4709
|
}
|
|
3462
4710
|
),
|
|
3463
|
-
/* @__PURE__ */
|
|
4711
|
+
/* @__PURE__ */ jsx27(
|
|
3464
4712
|
MessageActions,
|
|
3465
4713
|
{
|
|
3466
4714
|
content: messageContent,
|
|
3467
4715
|
isAssistant: isAssistantMessage,
|
|
3468
|
-
isStreaming:
|
|
4716
|
+
isStreaming: isStreamingMessage,
|
|
3469
4717
|
onRetry: isAssistantMessage && !stream.isLoading && index === messages.length - 1 ? () => handleRetry(index) : void 0
|
|
3470
4718
|
}
|
|
3471
4719
|
)
|
|
@@ -3478,18 +4726,34 @@ function Chat({
|
|
|
3478
4726
|
const lastMessage = messages[messages.length - 1];
|
|
3479
4727
|
const lastMessageType = lastMessage ? String(lastMessage.type) : "";
|
|
3480
4728
|
const isLastMessageFromAI = lastMessageType === "ai" || lastMessageType === "assistant";
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
4729
|
+
const lastAssistantStatus = isLastMessageFromAI ? getAssistantStreamingStatus(
|
|
4730
|
+
{
|
|
4731
|
+
...lastMessage,
|
|
4732
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
4733
|
+
},
|
|
4734
|
+
stream.isLoading,
|
|
4735
|
+
{ now: streamingNow }
|
|
4736
|
+
) : null;
|
|
4737
|
+
if (lastAssistantStatus) return null;
|
|
4738
|
+
const fallbackStreamingStatus = getAssistantStreamingStatus(
|
|
4739
|
+
{
|
|
4740
|
+
status: void 0,
|
|
4741
|
+
reasoning: void 0,
|
|
4742
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
4743
|
+
},
|
|
4744
|
+
stream.isLoading,
|
|
4745
|
+
{ now: streamingNow }
|
|
4746
|
+
);
|
|
4747
|
+
return /* @__PURE__ */ jsx27("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx27("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx27(
|
|
4748
|
+
AssistantStreamingIndicator,
|
|
4749
|
+
{
|
|
4750
|
+
status: fallbackStreamingStatus ?? "loading"
|
|
4751
|
+
}
|
|
4752
|
+
) }) });
|
|
3489
4753
|
})()
|
|
3490
4754
|
] })
|
|
3491
4755
|
] }),
|
|
3492
|
-
!isAtBottom && messages.length > 0 && /* @__PURE__ */
|
|
4756
|
+
!isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx27("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx27(
|
|
3493
4757
|
Button,
|
|
3494
4758
|
{
|
|
3495
4759
|
type: "button",
|
|
@@ -3502,12 +4766,40 @@ function Chat({
|
|
|
3502
4766
|
onClick: () => scrollToBottom(true, true),
|
|
3503
4767
|
"aria-label": t("chat.scrollToBottom"),
|
|
3504
4768
|
title: t("chat.scrollToBottom"),
|
|
3505
|
-
children: /* @__PURE__ */
|
|
4769
|
+
children: /* @__PURE__ */ jsx27(ArrowDown, { size: 16 })
|
|
3506
4770
|
}
|
|
3507
4771
|
) }),
|
|
3508
|
-
/* @__PURE__ */
|
|
3509
|
-
|
|
3510
|
-
|
|
4772
|
+
quoteSelection && /* @__PURE__ */ jsx27(
|
|
4773
|
+
"div",
|
|
4774
|
+
{
|
|
4775
|
+
className: "pointer-events-none fixed z-50",
|
|
4776
|
+
style: {
|
|
4777
|
+
top: `${quoteSelection.top}px`,
|
|
4778
|
+
left: `${quoteSelection.left}px`,
|
|
4779
|
+
transform: "translateX(-50%)"
|
|
4780
|
+
},
|
|
4781
|
+
children: /* @__PURE__ */ jsxs15(
|
|
4782
|
+
Button,
|
|
4783
|
+
{
|
|
4784
|
+
type: "button",
|
|
4785
|
+
size: "sm",
|
|
4786
|
+
variant: "secondary",
|
|
4787
|
+
className: "pointer-events-auto shadow-lg",
|
|
4788
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
4789
|
+
onClick: handleQuoteSelection,
|
|
4790
|
+
"aria-label": t("composer.quoteSelection"),
|
|
4791
|
+
title: t("composer.quoteSelection"),
|
|
4792
|
+
children: [
|
|
4793
|
+
/* @__PURE__ */ jsx27(Quote, { size: 14 }),
|
|
4794
|
+
t("composer.quoteSelection")
|
|
4795
|
+
]
|
|
4796
|
+
}
|
|
4797
|
+
)
|
|
4798
|
+
}
|
|
4799
|
+
),
|
|
4800
|
+
/* @__PURE__ */ jsxs15("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
|
|
4801
|
+
threadErrorMessage && /* @__PURE__ */ jsx27("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 }),
|
|
4802
|
+
/* @__PURE__ */ jsx27(
|
|
3511
4803
|
"input",
|
|
3512
4804
|
{
|
|
3513
4805
|
ref: fileInputRef,
|
|
@@ -3518,7 +4810,7 @@ function Chat({
|
|
|
3518
4810
|
className: "hidden"
|
|
3519
4811
|
}
|
|
3520
4812
|
),
|
|
3521
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
4813
|
+
attachments.length > 0 && /* @__PURE__ */ jsx27("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs15(
|
|
3522
4814
|
"div",
|
|
3523
4815
|
{
|
|
3524
4816
|
className: cn(
|
|
@@ -3526,24 +4818,36 @@ function Chat({
|
|
|
3526
4818
|
item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
|
|
3527
4819
|
),
|
|
3528
4820
|
children: [
|
|
3529
|
-
item.status === "uploading" && /* @__PURE__ */
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
),
|
|
3536
|
-
item.status === "
|
|
4821
|
+
item.status === "uploading" && /* @__PURE__ */ jsx27(
|
|
4822
|
+
Loader22,
|
|
4823
|
+
{
|
|
4824
|
+
size: 14,
|
|
4825
|
+
className: "animate-spin text-muted-foreground"
|
|
4826
|
+
}
|
|
4827
|
+
),
|
|
4828
|
+
item.status === "success" && /* @__PURE__ */ jsx27(FileText2, { size: 14, className: "text-muted-foreground" }),
|
|
4829
|
+
item.status === "error" && /* @__PURE__ */ jsx27(FileText2, { size: 14, className: "text-destructive" }),
|
|
4830
|
+
/* @__PURE__ */ jsx27(
|
|
4831
|
+
"span",
|
|
4832
|
+
{
|
|
4833
|
+
className: cn(
|
|
4834
|
+
"max-w-30 truncate",
|
|
4835
|
+
item.status === "error" && "text-destructive"
|
|
4836
|
+
),
|
|
4837
|
+
children: item.file.name
|
|
4838
|
+
}
|
|
4839
|
+
),
|
|
4840
|
+
item.status === "error" && /* @__PURE__ */ jsx27(
|
|
3537
4841
|
"button",
|
|
3538
4842
|
{
|
|
3539
4843
|
type: "button",
|
|
3540
4844
|
onClick: () => handleRetryUpload(item.localId),
|
|
3541
4845
|
className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
|
|
3542
4846
|
title: t("chat.retryUpload"),
|
|
3543
|
-
children: /* @__PURE__ */
|
|
4847
|
+
children: /* @__PURE__ */ jsx27(RefreshCw2, { size: 12 })
|
|
3544
4848
|
}
|
|
3545
4849
|
),
|
|
3546
|
-
/* @__PURE__ */
|
|
4850
|
+
/* @__PURE__ */ jsx27(
|
|
3547
4851
|
"button",
|
|
3548
4852
|
{
|
|
3549
4853
|
type: "button",
|
|
@@ -3552,67 +4856,98 @@ function Chat({
|
|
|
3552
4856
|
"ml-1 rounded-full p-0.5",
|
|
3553
4857
|
item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
|
|
3554
4858
|
),
|
|
3555
|
-
children: /* @__PURE__ */
|
|
4859
|
+
children: /* @__PURE__ */ jsx27(X2, { size: 12 })
|
|
3556
4860
|
}
|
|
3557
4861
|
)
|
|
3558
4862
|
]
|
|
3559
4863
|
},
|
|
3560
4864
|
item.localId
|
|
3561
4865
|
)) }),
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
4866
|
+
references.length > 0 && /* @__PURE__ */ jsx27("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx27(
|
|
4867
|
+
ReferenceChip,
|
|
4868
|
+
{
|
|
4869
|
+
reference,
|
|
4870
|
+
variant: "composer",
|
|
4871
|
+
onRemove: () => setReferences(
|
|
4872
|
+
(previous) => previous.filter(
|
|
4873
|
+
(item) => getReferenceKey(item) !== getReferenceKey(reference)
|
|
4874
|
+
)
|
|
4875
|
+
),
|
|
4876
|
+
removeLabel: t("composer.removeReference")
|
|
4877
|
+
},
|
|
4878
|
+
getReferenceKey(reference)
|
|
4879
|
+
)) }),
|
|
4880
|
+
selectedTool && /* @__PURE__ */ jsxs15("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
4881
|
+
/* @__PURE__ */ jsx27("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
|
|
4882
|
+
/* @__PURE__ */ jsx27(
|
|
3565
4883
|
"button",
|
|
3566
4884
|
{
|
|
3567
4885
|
type: "button",
|
|
3568
4886
|
onClick: () => setSelectedTool(null),
|
|
3569
4887
|
className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
|
|
3570
|
-
children: /* @__PURE__ */
|
|
4888
|
+
children: /* @__PURE__ */ jsx27(X2, { size: 12 })
|
|
3571
4889
|
}
|
|
3572
4890
|
)
|
|
3573
4891
|
] }),
|
|
3574
|
-
/* @__PURE__ */
|
|
4892
|
+
/* @__PURE__ */ jsx27(
|
|
4893
|
+
PendingFollowUps,
|
|
4894
|
+
{
|
|
4895
|
+
items: pendingFollowUps,
|
|
4896
|
+
isLoading: stream.isLoading,
|
|
4897
|
+
followUpBehavior: stream.followUpBehavior,
|
|
4898
|
+
onBehaviorChange: stream.setFollowUpBehavior,
|
|
4899
|
+
onPromoteToSteer: (id) => stream.promotePendingFollowUpToSteer(id),
|
|
4900
|
+
canSendNow: stream.canSendPendingFollowUpNow,
|
|
4901
|
+
onSendNow: (id) => stream.sendPendingFollowUpNow(id),
|
|
4902
|
+
onEdit: handleEditPendingFollowUp,
|
|
4903
|
+
onRemove: stream.removePendingFollowUp
|
|
4904
|
+
}
|
|
4905
|
+
),
|
|
4906
|
+
/* @__PURE__ */ jsx27("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs15(
|
|
3575
4907
|
"div",
|
|
3576
4908
|
{
|
|
3577
4909
|
className: cn(
|
|
3578
|
-
"flex flex-1 items-
|
|
4910
|
+
"flex flex-1 items-end gap-1 rounded-xl",
|
|
3579
4911
|
"bg-background border border-border shadow-sm",
|
|
3580
4912
|
"pl-1.5 pr-1.5 py-1",
|
|
3581
4913
|
"focus-within:border-muted-foreground/30 focus-within:shadow-md",
|
|
3582
|
-
"transition-shadow duration-200"
|
|
4914
|
+
"transition-shadow duration-200",
|
|
4915
|
+
getRoundedClass(theme.radius)
|
|
3583
4916
|
),
|
|
3584
4917
|
children: [
|
|
3585
|
-
/* @__PURE__ */
|
|
4918
|
+
/* @__PURE__ */ jsx27(
|
|
3586
4919
|
ComposerMenu,
|
|
3587
4920
|
{
|
|
3588
4921
|
composer,
|
|
3589
4922
|
onAttachmentClick: handleAttachmentClick,
|
|
3590
4923
|
onToolSelect: handleToolSelect,
|
|
3591
4924
|
selectedTool,
|
|
3592
|
-
disabled:
|
|
4925
|
+
disabled: missingConfig || isHistoryLoading
|
|
3593
4926
|
}
|
|
3594
4927
|
),
|
|
3595
|
-
/* @__PURE__ */
|
|
3596
|
-
"
|
|
4928
|
+
/* @__PURE__ */ jsx27(
|
|
4929
|
+
"textarea",
|
|
3597
4930
|
{
|
|
3598
|
-
|
|
4931
|
+
ref: composerInputRef,
|
|
3599
4932
|
value: draft,
|
|
3600
4933
|
onChange: (event) => setDraft(event.target.value),
|
|
4934
|
+
onKeyDown: handleComposerKeyDown,
|
|
4935
|
+
rows: 1,
|
|
3601
4936
|
placeholder: inputPlaceholder,
|
|
3602
|
-
disabled:
|
|
4937
|
+
disabled: missingConfig || isHistoryLoading,
|
|
3603
4938
|
className: cn(
|
|
3604
|
-
"flex-1 bg-transparent text-sm text-foreground outline-none
|
|
4939
|
+
"min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
|
|
3605
4940
|
"placeholder:text-muted-foreground",
|
|
3606
4941
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
3607
|
-
)
|
|
3608
|
-
autoComplete: "off"
|
|
4942
|
+
)
|
|
3609
4943
|
}
|
|
3610
4944
|
),
|
|
3611
|
-
/* @__PURE__ */
|
|
4945
|
+
/* @__PURE__ */ jsx27(
|
|
3612
4946
|
SendButton,
|
|
3613
4947
|
{
|
|
3614
4948
|
disabled: isSendDisabled,
|
|
3615
4949
|
isLoading: stream.isLoading,
|
|
4950
|
+
showStop: stream.isLoading && !trimmedDraft,
|
|
3616
4951
|
onStop: () => stream.stop(),
|
|
3617
4952
|
stopLabel: t("chat.stop"),
|
|
3618
4953
|
sendLabel: t("chat.send")
|
|
@@ -3621,7 +4956,7 @@ function Chat({
|
|
|
3621
4956
|
]
|
|
3622
4957
|
}
|
|
3623
4958
|
) }),
|
|
3624
|
-
disclaimer?.text && /* @__PURE__ */
|
|
4959
|
+
disclaimer?.text && /* @__PURE__ */ jsx27(
|
|
3625
4960
|
"p",
|
|
3626
4961
|
{
|
|
3627
4962
|
className: cn(
|
|
@@ -3631,9 +4966,9 @@ function Chat({
|
|
|
3631
4966
|
children: disclaimer.text
|
|
3632
4967
|
}
|
|
3633
4968
|
),
|
|
3634
|
-
/* @__PURE__ */
|
|
3635
|
-
/* @__PURE__ */
|
|
3636
|
-
/* @__PURE__ */
|
|
4969
|
+
/* @__PURE__ */ jsxs15("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
|
|
4970
|
+
/* @__PURE__ */ jsx27("span", { children: t("chat.poweredBy") }),
|
|
4971
|
+
/* @__PURE__ */ jsx27(ContextUsageIndicator, { className: "absolute right-4" })
|
|
3637
4972
|
] })
|
|
3638
4973
|
] })
|
|
3639
4974
|
]
|
|
@@ -3642,11 +4977,11 @@ function Chat({
|
|
|
3642
4977
|
}
|
|
3643
4978
|
|
|
3644
4979
|
// src/components/ui/input.tsx
|
|
3645
|
-
import * as
|
|
3646
|
-
import { jsx as
|
|
3647
|
-
var Input =
|
|
4980
|
+
import * as React22 from "react";
|
|
4981
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
4982
|
+
var Input = React22.forwardRef(
|
|
3648
4983
|
({ className, type, ...props }, ref) => {
|
|
3649
|
-
return /* @__PURE__ */
|
|
4984
|
+
return /* @__PURE__ */ jsx28(
|
|
3650
4985
|
"input",
|
|
3651
4986
|
{
|
|
3652
4987
|
ref,
|
|
@@ -3663,10 +4998,10 @@ var Input = React21.forwardRef(
|
|
|
3663
4998
|
Input.displayName = "Input";
|
|
3664
4999
|
|
|
3665
5000
|
// src/components/ui/separator.tsx
|
|
3666
|
-
import * as
|
|
3667
|
-
import { jsx as
|
|
3668
|
-
var Separator =
|
|
3669
|
-
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */
|
|
5001
|
+
import * as React23 from "react";
|
|
5002
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
5003
|
+
var Separator = React23.forwardRef(
|
|
5004
|
+
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx29(
|
|
3670
5005
|
"div",
|
|
3671
5006
|
{
|
|
3672
5007
|
ref,
|