@xpert-ai/chatkit-ui 0.0.20 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/assets/_baseUniq-p9H3Gzep.js +1 -0
- package/dist/app/assets/abap-bJX3iBqH.js +1 -0
- package/dist/app/assets/abnf-BoiZ35EE.js +1 -0
- package/dist/app/assets/actionscript-D-H9vZ8b.js +1 -0
- package/dist/app/assets/ada-Bne3WpOl.js +1 -0
- package/dist/app/assets/agda-C938cagi.js +1 -0
- package/dist/app/assets/al-Dcxw3Vj0.js +1 -0
- package/dist/app/assets/antlr4-uTm2QqyV.js +1 -0
- package/dist/app/assets/apacheconf-D52D513G.js +1 -0
- package/dist/app/assets/apex-B76H7J4g.js +1 -0
- package/dist/app/assets/apl-CzLk42pF.js +1 -0
- package/dist/app/assets/applescript-Dx8Ig-Eo.js +1 -0
- package/dist/app/assets/aql-wjx32tAU.js +1 -0
- package/dist/app/assets/arc-B32_yhh0.js +1 -0
- package/dist/app/assets/architectureDiagram-Q4EWVU46-Ba-C8DAI.js +36 -0
- package/dist/app/assets/arduino-BwKDxTSS.js +1 -0
- package/dist/app/assets/arff-DrkRViyY.js +1 -0
- package/dist/app/assets/asciidoc-BGLZq9v8.js +1 -0
- package/dist/app/assets/asm6502-MsEWIyJj.js +1 -0
- package/dist/app/assets/asmatmel-CeHxqS5T.js +1 -0
- package/dist/app/assets/aspnet-CmsQfR5a.js +1 -0
- package/dist/app/assets/autohotkey-Cusm-zTm.js +1 -0
- package/dist/app/assets/autoit-Da8gsEm-.js +1 -0
- package/dist/app/assets/avisynth-C46xLzyo.js +1 -0
- package/dist/app/assets/avro-idl-D2WmoYBG.js +1 -0
- package/dist/app/assets/{basic-B-OOkRrw.js → bash-BrsKn3za.js} +1 -1
- package/dist/app/assets/basic-Dt5oGQ8B.js +1 -0
- package/dist/app/assets/batch-DtrIlfXi.js +1 -0
- package/dist/app/assets/bbcode-BWYlAYoE.js +1 -0
- package/dist/app/assets/bicep-C4sxks0f.js +1 -0
- package/dist/app/assets/birb-gYyyIZ-F.js +1 -0
- package/dist/app/assets/bison-or-umhj6.js +1 -0
- package/dist/app/assets/blockDiagram-DXYQGD6D-5oqbPp8P.js +132 -0
- package/dist/app/assets/bnf-BQR7hfk2.js +1 -0
- package/dist/app/assets/brainfuck-DkQqhNHv.js +1 -0
- package/dist/app/assets/brightscript-rGhg0HBT.js +1 -0
- package/dist/app/assets/bro-CIgtBg0f.js +1 -0
- package/dist/app/assets/bsl-C4geIkQv.js +1 -0
- package/dist/app/assets/c-Cw5181Rv.js +1 -0
- package/dist/app/assets/c4Diagram-AHTNJAMY-BKyN5n0Y.js +10 -0
- package/dist/app/assets/cfscript-DHPNMvWS.js +1 -0
- package/dist/app/assets/chaiscript-Cd8c0hJ8.js +1 -0
- package/dist/app/assets/channel-Cx11sSAI.js +1 -0
- package/dist/app/assets/chunk-4BX2VUAB-CfLubn_X.js +1 -0
- package/dist/app/assets/chunk-4TB4RGXK-Bhehm3S4.js +206 -0
- package/dist/app/assets/chunk-55IACEB6-D0Zgi2qX.js +1 -0
- package/dist/app/assets/chunk-EDXVE4YY-DzMULs0l.js +1 -0
- package/dist/app/assets/chunk-FMBD7UC4-CEU9agAN.js +15 -0
- package/dist/app/assets/chunk-OYMX7WX6-C-avxOs6.js +231 -0
- package/dist/app/assets/chunk-QZHKN3VN-C66xsvBW.js +1 -0
- package/dist/app/assets/chunk-YZCP3GAM-DZlwMcoL.js +1 -0
- package/dist/app/assets/cil-L3oWT8Nl.js +1 -0
- package/dist/app/assets/classDiagram-6PBFFD2Q-BQrwJXsB.js +1 -0
- package/dist/app/assets/classDiagram-v2-HSJHXN6E-BQrwJXsB.js +1 -0
- package/dist/app/assets/clike-CHF9NJQa.js +1 -0
- package/dist/app/assets/clojure-YgRWUbgr.js +1 -0
- package/dist/app/assets/clone-DHPdZQ_6.js +1 -0
- package/dist/app/assets/cmake-TK-Cvlxu.js +1 -0
- package/dist/app/assets/cobol-XSbSVVcZ.js +1 -0
- package/dist/app/assets/coffeescript-HxNd9-Ob.js +1 -0
- package/dist/app/assets/concurnas-DK3wUjjD.js +1 -0
- package/dist/app/assets/coq-B9Rq7NUE.js +1 -0
- package/dist/app/assets/core-B1vWjEfj.js +1 -0
- package/dist/app/assets/cose-bilkent-S5V4N54A-4PebjqsX.js +1 -0
- package/dist/app/assets/cpp-DUWMh-8O.js +1 -0
- package/dist/app/assets/crystal-rYgGF4lS.js +1 -0
- package/dist/app/assets/csharp-eqTMyksU.js +1 -0
- package/dist/app/assets/cshtml-DSv9-mpk.js +1 -0
- package/dist/app/assets/csp-DyZfVzvb.js +1 -0
- package/dist/app/assets/css-DYXyUyJe.js +1 -0
- package/dist/app/assets/css-extras-FP15zHq8.js +1 -0
- package/dist/app/assets/csv-Bp1iUR7c.js +1 -0
- package/dist/app/assets/cypher-BjXgs7Y3.js +1 -0
- package/dist/app/assets/cytoscape.esm-DkOyvmE4.js +321 -0
- package/dist/app/assets/d-Bquc1S6a.js +1 -0
- package/dist/app/assets/dagre-KV5264BT-D9OICDLb.js +4 -0
- package/dist/app/assets/dart-DrKyO7TC.js +1 -0
- package/dist/app/assets/dataweave-BgpsWzO7.js +1 -0
- package/dist/app/assets/dax-BwP1SyCZ.js +1 -0
- package/dist/app/assets/defaultLocale-DX6XiGOO.js +1 -0
- package/dist/app/assets/dhall-BA5nXB8V.js +1 -0
- package/dist/app/assets/diagram-5BDNPKRD-BIFTIy6n.js +10 -0
- package/dist/app/assets/diagram-G4DWMVQ6-BCVIBrZ2.js +24 -0
- package/dist/app/assets/diagram-MMDJMWI5-43z4NaFN.js +43 -0
- package/dist/app/assets/diagram-TYMM5635-BDZjM1c_.js +24 -0
- package/dist/app/assets/diff-Yc6a7YOT.js +3 -0
- package/dist/app/assets/django-B61BBi1t.js +1 -0
- package/dist/app/assets/dns-zone-file-DtXhOJHq.js +1 -0
- package/dist/app/assets/docker-BLh9n10i.js +1 -0
- package/dist/app/assets/dot-BbSnn0Ap.js +1 -0
- package/dist/app/assets/ebnf-D_ljHBdb.js +1 -0
- package/dist/app/assets/editorconfig-BQXrLGC5.js +1 -0
- package/dist/app/assets/eiffel-Cm3FUI5X.js +1 -0
- package/dist/app/assets/ejs-CIp2UdDw.js +1 -0
- package/dist/app/assets/elixir-DXlWBe5R.js +1 -0
- package/dist/app/assets/elm-ECxjLCR-.js +1 -0
- package/dist/app/assets/erDiagram-SMLLAGMA-B9I89ndp.js +85 -0
- package/dist/app/assets/erb-FzgX8ydn.js +1 -0
- package/dist/app/assets/erlang-CzvdSvoz.js +1 -0
- package/dist/app/assets/etlua-C3Zsz3RA.js +1 -0
- package/dist/app/assets/excel-formula-Cua38PQJ.js +1 -0
- package/dist/app/assets/factor-CSAzXoQb.js +1 -0
- package/dist/app/assets/false-NSFMCUjP.js +1 -0
- package/dist/app/assets/firestore-security-rules-BjNYwvNe.js +1 -0
- package/dist/app/assets/flow-BuZaM8y6.js +1 -0
- package/dist/app/assets/flowDiagram-DWJPFMVM-CWmW_muY.js +162 -0
- package/dist/app/assets/fortran-Cc_f_mSH.js +1 -0
- package/dist/app/assets/fsharp-IelQ4Z-Z.js +1 -0
- package/dist/app/assets/ftl-Ddl9DDyG.js +1 -0
- package/dist/app/assets/ganttDiagram-T4ZO3ILL-CuR1J7dx.js +292 -0
- package/dist/app/assets/gap-D3W6p-Jp.js +1 -0
- package/dist/app/assets/gcode-Bn8O4UOx.js +1 -0
- package/dist/app/assets/gdscript-B4nck3Az.js +1 -0
- package/dist/app/assets/gedcom-BCTZRsxn.js +1 -0
- package/dist/app/assets/gherkin-CFCJQug9.js +1 -0
- package/dist/app/assets/git-Dd2t83_l.js +1 -0
- package/dist/app/assets/gitGraphDiagram-UUTBAWPF-DzscVnaS.js +106 -0
- package/dist/app/assets/glsl-NXGZDuA9.js +1 -0
- package/dist/app/assets/gml-DtS9_99j.js +1 -0
- package/dist/app/assets/gn-C6VmNt4U.js +1 -0
- package/dist/app/assets/go-module-CmBM8SA1.js +1 -0
- package/dist/app/assets/go-otK-v_nb.js +1 -0
- package/dist/app/assets/graph-BelNBDAZ.js +1 -0
- package/dist/app/assets/graphql-JPlPKrhh.js +1 -0
- package/dist/app/assets/groovy-CkMUqzIt.js +1 -0
- package/dist/app/assets/haml-DwaIQOGd.js +1 -0
- package/dist/app/assets/handlebars-Ck6RB1iw.js +1 -0
- package/dist/app/assets/haskell-BxYLBxBa.js +1 -0
- package/dist/app/assets/haxe-C4OMV9zJ.js +1 -0
- package/dist/app/assets/hcl-DVznmODf.js +1 -0
- package/dist/app/assets/hlsl-Z_ySkish.js +1 -0
- package/dist/app/assets/hoon-UWT3k4H8.js +1 -0
- package/dist/app/assets/hpkp-CXa39f7J.js +1 -0
- package/dist/app/assets/hsts-CJF4yNvU.js +1 -0
- package/dist/app/assets/http-BxOKxlr4.js +1 -0
- package/dist/app/assets/ichigojam-Csb66zY2.js +1 -0
- package/dist/app/assets/icon-DxphTQI9.js +1 -0
- package/dist/app/assets/icu-message-format-CSZfssuP.js +1 -0
- package/dist/app/assets/idris-BmXANiaa.js +1 -0
- package/dist/app/assets/iecst-FfznJdjL.js +1 -0
- package/dist/app/assets/ignore-C3IKkXMi.js +1 -0
- package/dist/app/assets/index-D972kqET.css +1 -0
- package/dist/app/assets/index-DmMWBDJR.js +747 -0
- package/dist/app/assets/infoDiagram-42DDH7IO-rTeQPEt4.js +2 -0
- package/dist/app/assets/inform7-Dk4gPo4b.js +1 -0
- package/dist/app/assets/ini-CClGKGMe.js +1 -0
- package/dist/app/assets/init-Gi6I4Gst.js +1 -0
- package/dist/app/assets/io-6YtqLtET.js +1 -0
- package/dist/app/assets/ishikawaDiagram-UXIWVN3A-BBnJ9iuN.js +70 -0
- package/dist/app/assets/j-DBPrIcAG.js +1 -0
- package/dist/app/assets/java-CopGP3Lu.js +1 -0
- package/dist/app/assets/javadoc-C8F3ifW2.js +1 -0
- package/dist/app/assets/javadoclike-BNVFpoJC.js +1 -0
- package/dist/app/assets/javascript-BMkkas2q.js +1 -0
- package/dist/app/assets/javastacktrace-DuykBujE.js +1 -0
- package/dist/app/assets/jexl-BSWOm8s5.js +1 -0
- package/dist/app/assets/jolie-CdkOmKFM.js +1 -0
- package/dist/app/assets/journeyDiagram-VCZTEJTY-CRDpL_1T.js +139 -0
- package/dist/app/assets/jq-Nr0Kxpxc.js +1 -0
- package/dist/app/assets/js-extras-CA8iZ_E5.js +1 -0
- package/dist/app/assets/js-templates-BoqcQW67.js +1 -0
- package/dist/app/assets/jsdoc-CeMFl6xP.js +1 -0
- package/dist/app/assets/json-CrSHUueM.js +1 -0
- package/dist/app/assets/json5-BBfX460l.js +1 -0
- package/dist/app/assets/jsonp-DHEqmGWL.js +1 -0
- package/dist/app/assets/jsstacktrace-BK3SuvsS.js +1 -0
- package/dist/app/assets/jsx-CjR3dp14.js +1 -0
- package/dist/app/assets/julia-BJJ6LUnI.js +1 -0
- package/dist/app/assets/kanban-definition-6JOO6SKY-Dztk4Auy.js +89 -0
- package/dist/app/assets/keepalived-CjGUJvsk.js +1 -0
- package/dist/app/assets/keyman-Bogz-7f0.js +1 -0
- package/dist/app/assets/kotlin-DGdetcAk.js +1 -0
- package/dist/app/assets/kumir-Czhml4-j.js +1 -0
- package/dist/app/assets/kusto-BuL9qwXk.js +1 -0
- package/dist/app/assets/latex-BAc_zS_4.js +1 -0
- package/dist/app/assets/latte-BzZFX_wH.js +1 -0
- package/dist/app/assets/layout-DOHRtR3x.js +1 -0
- package/dist/app/assets/less-DATW_Ot3.js +1 -0
- package/dist/app/assets/lilypond-DSmAdE7B.js +1 -0
- package/dist/app/assets/linear-rr7FzlEM.js +1 -0
- package/dist/app/assets/liquid-CF8lqz9m.js +1 -0
- package/dist/app/assets/lisp-BUPAsWUh.js +1 -0
- package/dist/app/assets/livescript-B8CIEQDH.js +1 -0
- package/dist/app/assets/llvm-DGaRc9w0.js +1 -0
- package/dist/app/assets/log-XuE3Wqn5.js +1 -0
- package/dist/app/assets/lolcode-Clk-p_j2.js +1 -0
- package/dist/app/assets/{java-CNwVyXY2.js → lua-BLczZbJa.js} +1 -1
- package/dist/app/assets/magma-DTO3ftgF.js +1 -0
- package/dist/app/assets/makefile-OSVaZHmV.js +1 -0
- package/dist/app/assets/markdown-InD7dXs9.js +1 -0
- package/dist/app/assets/markup-BN6MlRZT.js +1 -0
- package/dist/app/assets/markup-templating-DRXAmI1c.js +1 -0
- package/dist/app/assets/matlab-CV_q70_G.js +1 -0
- package/dist/app/assets/maxscript-Ck_8H__C.js +1 -0
- package/dist/app/assets/mel-D9MU0rZa.js +1 -0
- package/dist/app/assets/mermaid-DshECBS6.js +1 -0
- package/dist/app/assets/min-CfLzpwyh.js +1 -0
- package/dist/app/assets/mindmap-definition-QFDTVHPH-C7XGlydX.js +96 -0
- package/dist/app/assets/mizar-WBJ-SwIG.js +1 -0
- package/dist/app/assets/mongodb-CmzRTKBq.js +1 -0
- package/dist/app/assets/monkey-W1yB--1T.js +1 -0
- package/dist/app/assets/moonscript-BD5hlCXn.js +1 -0
- package/dist/app/assets/n1ql-CwugAEoM.js +1 -0
- package/dist/app/assets/n4js-tFC-Lsvd.js +1 -0
- package/dist/app/assets/nand2tetris-hdl-hzvfBJxH.js +1 -0
- package/dist/app/assets/naniscript-DUtjoUL1.js +1 -0
- package/dist/app/assets/nasm-Dcckq6ib.js +1 -0
- package/dist/app/assets/neon-DeVv09BE.js +1 -0
- package/dist/app/assets/nevod-CAq9Kfwt.js +1 -0
- package/dist/app/assets/nginx-C8GHDEqt.js +1 -0
- package/dist/app/assets/nim-BqdyUedD.js +1 -0
- package/dist/app/assets/nix-514mCcjs.js +1 -0
- package/dist/app/assets/nsis-CdKqXn3g.js +1 -0
- package/dist/app/assets/objectivec-uPp8iMUn.js +1 -0
- package/dist/app/assets/ocaml-D4EB6rFL.js +1 -0
- package/dist/app/assets/opencl-BN8tmrp-.js +1 -0
- package/dist/app/assets/openqasm-CZT9yVLH.js +1 -0
- package/dist/app/assets/ordinal-Cboi1Yqb.js +1 -0
- package/dist/app/assets/oz-xEnzbfGI.js +1 -0
- package/dist/app/assets/parigp-PN33G_ZS.js +1 -0
- package/dist/app/assets/parser-YigtK2Gn.js +1 -0
- package/dist/app/assets/pascal-BSQHqJO2.js +1 -0
- package/dist/app/assets/pascaligo-B3om_nlX.js +1 -0
- package/dist/app/assets/pcaxis-B_qwjIH4.js +1 -0
- package/dist/app/assets/peoplecode-G3CTxh8q.js +1 -0
- package/dist/app/assets/perl-CBvGMSZZ.js +1 -0
- package/dist/app/assets/php-DewJLtev.js +1 -0
- package/dist/app/assets/php-extras-BT2DdjGn.js +1 -0
- package/dist/app/assets/phpdoc-DiQXOd9D.js +1 -0
- package/dist/app/assets/pieDiagram-DEJITSTG-CYXmqIpD.js +30 -0
- package/dist/app/assets/plsql-BzUO3h3t.js +1 -0
- package/dist/app/assets/powerquery-D_713gdU.js +1 -0
- package/dist/app/assets/powershell-D7IGyPyT.js +1 -0
- package/dist/app/assets/processing-CULfTuKk.js +1 -0
- package/dist/app/assets/prolog-DI8sHw_1.js +1 -0
- package/dist/app/assets/promql-DdWPpZzX.js +1 -0
- package/dist/app/assets/properties-UUBptvjg.js +1 -0
- package/dist/app/assets/protobuf-Yh4lBroy.js +1 -0
- package/dist/app/assets/psl-CKuqp255.js +1 -0
- package/dist/app/assets/pug-Duz4hJlP.js +1 -0
- package/dist/app/assets/puppet-Tenfq4aE.js +1 -0
- package/dist/app/assets/pure-CTE3YKFb.js +1 -0
- package/dist/app/assets/purebasic-BzV6ZqWW.js +1 -0
- package/dist/app/assets/purescript-CjSCYtGb.js +1 -0
- package/dist/app/assets/q-BTX8RKFy.js +1 -0
- package/dist/app/assets/qml-CGjBjP81.js +1 -0
- package/dist/app/assets/qore-5Gggmt2I.js +1 -0
- package/dist/app/assets/qsharp-DhqE1FPx.js +1 -0
- package/dist/app/assets/quadrantDiagram-34T5L4WZ-BbnPMKp-.js +7 -0
- package/dist/app/assets/r-Dr0jr5tD.js +1 -0
- package/dist/app/assets/racket-NVUa01EO.js +1 -0
- package/dist/app/assets/reason-Bx5CI0l0.js +1 -0
- package/dist/app/assets/regex-12879jLK.js +1 -0
- package/dist/app/assets/rego-w2Fhvb_N.js +1 -0
- package/dist/app/assets/renpy-gPxX0z3Q.js +1 -0
- package/dist/app/assets/requirementDiagram-MS252O5E-BhOU7uOd.js +84 -0
- package/dist/app/assets/rest-C39bU2b1.js +1 -0
- package/dist/app/assets/rip-RLtTVF0Y.js +1 -0
- package/dist/app/assets/roboconf-BJckt4oD.js +1 -0
- package/dist/app/assets/robotframework-DCR96jiT.js +1 -0
- package/dist/app/assets/ruby-CRs8uxXB.js +1 -0
- package/dist/app/assets/rust-C0bGL254.js +1 -0
- package/dist/app/assets/sankeyDiagram-XADWPNL6-CFgkd6GO.js +10 -0
- package/dist/app/assets/sas-CkLtpL1M.js +1 -0
- package/dist/app/assets/sass-FNfCYuQd.js +1 -0
- package/dist/app/assets/scala-Dy5lip5O.js +1 -0
- package/dist/app/assets/scheme-pkKED5As.js +1 -0
- package/dist/app/assets/scss-DrZ4F_S5.js +1 -0
- package/dist/app/assets/sequenceDiagram-FGHM5R23-t5z2WRg9.js +157 -0
- package/dist/app/assets/shell-session-tfqRzQ64.js +1 -0
- package/dist/app/assets/smali-D9oJJF_a.js +1 -0
- package/dist/app/assets/smalltalk-FhicZwdZ.js +1 -0
- package/dist/app/assets/smarty-RTVkhvGe.js +1 -0
- package/dist/app/assets/sml-8jU1U62j.js +1 -0
- package/dist/app/assets/solidity-DLvpuywG.js +1 -0
- package/dist/app/assets/solution-file-BOwCbL9x.js +1 -0
- package/dist/app/assets/soy-Dye6FppK.js +1 -0
- package/dist/app/assets/sparql-BRIOTA6e.js +1 -0
- package/dist/app/assets/splunk-spl-xjEKSM5T.js +1 -0
- package/dist/app/assets/sqf-BTXRZqz9.js +1 -0
- package/dist/app/assets/sql-LIGcsz7H.js +1 -0
- package/dist/app/assets/squirrel-D1i-yP9F.js +1 -0
- package/dist/app/assets/stan-Bz-MTQlG.js +1 -0
- package/dist/app/assets/stateDiagram-FHFEXIEX-INV79XkW.js +1 -0
- package/dist/app/assets/stateDiagram-v2-QKLJ7IA2-DkwGLXRp.js +1 -0
- package/dist/app/assets/stylus-CPcHbGGR.js +1 -0
- package/dist/app/assets/swift-CMnIAhC_.js +1 -0
- package/dist/app/assets/systemd-CnQ86vtn.js +2 -0
- package/dist/app/assets/t4-cs-ClADD8kZ.js +1 -0
- package/dist/app/assets/t4-templating-BxEXIn9V.js +1 -0
- package/dist/app/assets/t4-vb-BuQFrDQM.js +1 -0
- package/dist/app/assets/tap-D-OeTv7J.js +1 -0
- package/dist/app/assets/tcl-D4EWmvqA.js +1 -0
- package/dist/app/assets/textile-vCa5WeBr.js +1 -0
- package/dist/app/assets/timeline-definition-GMOUNBTQ-CZVpkWZR.js +120 -0
- package/dist/app/assets/toml-CyQfWyMg.js +1 -0
- package/dist/app/assets/tremor-DTpakXR3.js +1 -0
- package/dist/app/assets/tt2-I3k-jzpY.js +1 -0
- package/dist/app/assets/turtle-BjS87MX7.js +1 -0
- package/dist/app/assets/twig-BYK2hDMY.js +1 -0
- package/dist/app/assets/typescript-DNEOvUVG.js +1 -0
- package/dist/app/assets/typoscript-hqzFge6d.js +1 -0
- package/dist/app/assets/unrealscript-_-NzaZj0.js +1 -0
- package/dist/app/assets/uorazor-BMR9qMW5.js +1 -0
- package/dist/app/assets/uri-BSGWfMxZ.js +1 -0
- package/dist/app/assets/v-CLtdeXIK.js +1 -0
- package/dist/app/assets/vala-wzCcqtKA.js +1 -0
- package/dist/app/assets/{turtle-D8pkqXh1.js → vbnet-DGCLmXdC.js} +1 -1
- package/dist/app/assets/velocity-DX_5gTOq.js +1 -0
- package/dist/app/assets/vennDiagram-DHZGUBPP-Dq1FXdcO.js +34 -0
- package/dist/app/assets/verilog-DeAFTKrK.js +1 -0
- package/dist/app/assets/vhdl-CgPp3m3I.js +1 -0
- package/dist/app/assets/vim-ZY6C4NgO.js +1 -0
- package/dist/app/assets/visual-basic-DmV7laqn.js +1 -0
- package/dist/app/assets/wardley-RL74JXVD-OqiGOeix.js +162 -0
- package/dist/app/assets/wardleyDiagram-NUSXRM2D-XXEOUAR6.js +20 -0
- package/dist/app/assets/warpscript-CST9Acbf.js +1 -0
- package/dist/app/assets/wasm-D44TvCcf.js +1 -0
- package/dist/app/assets/web-idl-CUAX3ogm.js +1 -0
- package/dist/app/assets/wiki-KNEqZQWK.js +1 -0
- package/dist/app/assets/wolfram-CZdD1bRd.js +1 -0
- package/dist/app/assets/wren-PITvEkQ4.js +1 -0
- package/dist/app/assets/xeora-BM_ABt9y.js +1 -0
- package/dist/app/assets/xml-doc-249eg8mF.js +1 -0
- package/dist/app/assets/xojo-M3SASV_b.js +1 -0
- package/dist/app/assets/xquery-BWv2VkcM.js +1 -0
- package/dist/app/assets/xychartDiagram-5P7HB3ND-CvXT15VO.js +7 -0
- package/dist/app/assets/yaml-B70AwQ7Y.js +1 -0
- package/dist/app/assets/yang-DffrsIpd.js +1 -0
- package/dist/app/assets/zig-C9vlYfKL.js +1 -0
- package/dist/app/index.html +2 -2
- package/dist/index.cjs +2734 -595
- package/dist/index.d.cts +20 -5
- package/dist/index.d.ts +20 -5
- package/dist/index.js +2768 -592
- package/package.json +8 -4
- package/dist/app/assets/abap-CabZ0vYL.js +0 -1
- package/dist/app/assets/abnf-CPoubvVG.js +0 -1
- package/dist/app/assets/actionscript-CL1BPQFv.js +0 -1
- package/dist/app/assets/ada-BOt55oS4.js +0 -1
- package/dist/app/assets/agda-DKyUkxie.js +0 -1
- package/dist/app/assets/al-Jnhqb7P-.js +0 -1
- package/dist/app/assets/antlr4-BeT3YbbK.js +0 -1
- package/dist/app/assets/apacheconf-Ck_DRZXY.js +0 -1
- package/dist/app/assets/apex-CPjbO0O4.js +0 -1
- package/dist/app/assets/apl-Ccs4_jOU.js +0 -1
- package/dist/app/assets/applescript-C6i7vo8F.js +0 -1
- package/dist/app/assets/aql-D3ZWY-VL.js +0 -1
- package/dist/app/assets/arduino-xTj3TTXg.js +0 -1
- package/dist/app/assets/arff-BOuVccGR.js +0 -1
- package/dist/app/assets/asciidoc-BmShvnn0.js +0 -1
- package/dist/app/assets/asm6502-6FWPK68i.js +0 -1
- package/dist/app/assets/asmatmel-KLAd82QV.js +0 -1
- package/dist/app/assets/aspnet-vZiSZd1y.js +0 -1
- package/dist/app/assets/autohotkey-tcBDP1b7.js +0 -1
- package/dist/app/assets/autoit-Bwt0tLM_.js +0 -1
- package/dist/app/assets/avisynth-Bzz43Lfu.js +0 -1
- package/dist/app/assets/avro-idl-Bt9aSyrD.js +0 -1
- package/dist/app/assets/bash-BloO3C-T.js +0 -1
- package/dist/app/assets/batch-aOUu2msA.js +0 -1
- package/dist/app/assets/bbcode-C4D8vm8O.js +0 -1
- package/dist/app/assets/bicep-BtBByAYv.js +0 -1
- package/dist/app/assets/birb-BKXLouTf.js +0 -1
- package/dist/app/assets/bison-CniuHJJN.js +0 -1
- package/dist/app/assets/bnf-CGcuZYv2.js +0 -1
- package/dist/app/assets/brainfuck-C9dlh056.js +0 -1
- package/dist/app/assets/brightscript-nhHFw9_4.js +0 -1
- package/dist/app/assets/bro-BTsReVOc.js +0 -1
- package/dist/app/assets/bsl-CmOTwcFR.js +0 -1
- package/dist/app/assets/c-Yjfq4oES.js +0 -1
- package/dist/app/assets/cfscript-DGhYlgJ7.js +0 -1
- package/dist/app/assets/chaiscript-CpP8bBSU.js +0 -1
- package/dist/app/assets/cil-CZ7j4pcz.js +0 -1
- package/dist/app/assets/clike-D581thF2.js +0 -1
- package/dist/app/assets/clojure-AXVmar0o.js +0 -1
- package/dist/app/assets/cmake-BozSSfax.js +0 -1
- package/dist/app/assets/cobol-OciN9vwY.js +0 -1
- package/dist/app/assets/coffeescript-B9yMzVL5.js +0 -1
- package/dist/app/assets/concurnas-DeQIM64O.js +0 -1
- package/dist/app/assets/coq-CicPksao.js +0 -1
- package/dist/app/assets/core-BIcqXTaK.js +0 -1
- package/dist/app/assets/cpp-DKQF7403.js +0 -1
- package/dist/app/assets/crystal-Bcau7QFZ.js +0 -1
- package/dist/app/assets/csharp-BYghYpTl.js +0 -1
- package/dist/app/assets/cshtml-BIxIGrsH.js +0 -1
- package/dist/app/assets/csp-CzDOD-m1.js +0 -1
- package/dist/app/assets/css-CPRwU6oY.js +0 -1
- package/dist/app/assets/css-extras-C28yWYxN.js +0 -1
- package/dist/app/assets/csv-D8IAZwKO.js +0 -1
- package/dist/app/assets/cypher-0hMRBt8D.js +0 -1
- package/dist/app/assets/d-B5PQgXXo.js +0 -1
- package/dist/app/assets/dart-CvCyf8me.js +0 -1
- package/dist/app/assets/dataweave-Izl0xtz9.js +0 -1
- package/dist/app/assets/dax-D-bGAkbS.js +0 -1
- package/dist/app/assets/dhall-DXIOSM5Q.js +0 -1
- package/dist/app/assets/diff-BE-xKdIi.js +0 -3
- package/dist/app/assets/django-DxEZdkeU.js +0 -1
- package/dist/app/assets/dns-zone-file-D406E4S7.js +0 -1
- package/dist/app/assets/docker-BZkb2U00.js +0 -1
- package/dist/app/assets/dot-BGJNVmx1.js +0 -1
- package/dist/app/assets/ebnf-_PEATas2.js +0 -1
- package/dist/app/assets/editorconfig-C1UuLwJC.js +0 -1
- package/dist/app/assets/eiffel-PzXVtlzf.js +0 -1
- package/dist/app/assets/ejs-707c0691.js +0 -1
- package/dist/app/assets/elixir-Bd3zWMjP.js +0 -1
- package/dist/app/assets/elm-DvEDEOdK.js +0 -1
- package/dist/app/assets/erb-B6lZT1P9.js +0 -1
- package/dist/app/assets/erlang-BwhqRmQk.js +0 -1
- package/dist/app/assets/etlua-Bkg93PrU.js +0 -1
- package/dist/app/assets/excel-formula-BD0I0dyD.js +0 -1
- package/dist/app/assets/factor-CiQgOsxY.js +0 -1
- package/dist/app/assets/false-DlJ-f_Rc.js +0 -1
- package/dist/app/assets/firestore-security-rules-CxrEhPSm.js +0 -1
- package/dist/app/assets/flow-DOjTBDi4.js +0 -1
- package/dist/app/assets/fortran-D6uA-pWI.js +0 -1
- package/dist/app/assets/fsharp-CFL1DcvT.js +0 -1
- package/dist/app/assets/ftl-DzWZwecM.js +0 -1
- package/dist/app/assets/gap-DatQeRFY.js +0 -1
- package/dist/app/assets/gcode-5FSxboIT.js +0 -1
- package/dist/app/assets/gdscript-Dz-OC8bG.js +0 -1
- package/dist/app/assets/gedcom-BS0539Ys.js +0 -1
- package/dist/app/assets/gherkin-BJKrWYAT.js +0 -1
- package/dist/app/assets/git-DCjIevVw.js +0 -1
- package/dist/app/assets/glsl-toSXKJrw.js +0 -1
- package/dist/app/assets/gml-DODsSWU7.js +0 -1
- package/dist/app/assets/gn-CzmtMWMm.js +0 -1
- package/dist/app/assets/go-BCQUEKVv.js +0 -1
- package/dist/app/assets/go-module-BbcV-9oG.js +0 -1
- package/dist/app/assets/graphql-C_KxCYJO.js +0 -1
- package/dist/app/assets/groovy-Cj97iKYK.js +0 -1
- package/dist/app/assets/haml-tLXJGYDb.js +0 -1
- package/dist/app/assets/handlebars-DIdVe3xN.js +0 -1
- package/dist/app/assets/haskell-DPqw5u4H.js +0 -1
- package/dist/app/assets/haxe-AsnHNCIR.js +0 -1
- package/dist/app/assets/hcl-C6aoWR34.js +0 -1
- package/dist/app/assets/hlsl-B2hhU30-.js +0 -1
- package/dist/app/assets/hoon-Bs-KhWO3.js +0 -1
- package/dist/app/assets/hpkp-C-J4O-Mp.js +0 -1
- package/dist/app/assets/hsts-BNFEkSnm.js +0 -1
- package/dist/app/assets/http-D7UlQANy.js +0 -1
- package/dist/app/assets/ichigojam-B01TJ8BA.js +0 -1
- package/dist/app/assets/icon-Ca_ghvQd.js +0 -1
- package/dist/app/assets/icu-message-format-CkcsJ0ML.js +0 -1
- package/dist/app/assets/idris-BApVxI9a.js +0 -1
- package/dist/app/assets/iecst-CXLR8sGn.js +0 -1
- package/dist/app/assets/ignore-7LzAeAFj.js +0 -1
- package/dist/app/assets/index-BUg2yVDW.js +0 -439
- package/dist/app/assets/index-om2E9pNd.css +0 -1
- package/dist/app/assets/inform7-CtnRN-Iq.js +0 -1
- package/dist/app/assets/ini-Cjpl6yTL.js +0 -1
- package/dist/app/assets/io-C6W_EboY.js +0 -1
- package/dist/app/assets/j-BOBDun2W.js +0 -1
- package/dist/app/assets/javadoc-DS6hxu7_.js +0 -1
- package/dist/app/assets/javadoclike-J6YT11JS.js +0 -1
- package/dist/app/assets/javascript-IbEfuVSB.js +0 -1
- package/dist/app/assets/javastacktrace-DjxwGV26.js +0 -1
- package/dist/app/assets/jexl-TLHmHaQ5.js +0 -1
- package/dist/app/assets/jolie-CLk71kur.js +0 -1
- package/dist/app/assets/jq-DZKnIQZM.js +0 -1
- package/dist/app/assets/js-extras-CJab09ti.js +0 -1
- package/dist/app/assets/js-templates-CQGqrHhi.js +0 -1
- package/dist/app/assets/jsdoc--ymvl4aq.js +0 -1
- package/dist/app/assets/json-D9b-V85G.js +0 -1
- package/dist/app/assets/json5-LgA47n7A.js +0 -1
- package/dist/app/assets/jsonp-Cvwp3f8M.js +0 -1
- package/dist/app/assets/jsstacktrace-z8t2H6h6.js +0 -1
- package/dist/app/assets/jsx-B71LrwNd.js +0 -1
- package/dist/app/assets/julia-DCATdxwO.js +0 -1
- package/dist/app/assets/keepalived-DVYYbgrL.js +0 -1
- package/dist/app/assets/keyman-DLyOXnhf.js +0 -1
- package/dist/app/assets/kotlin-CYoDfyDA.js +0 -1
- package/dist/app/assets/kumir-CPWiEvmL.js +0 -1
- package/dist/app/assets/kusto-BkfRYk0W.js +0 -1
- package/dist/app/assets/latex-BEjZ0ppC.js +0 -1
- package/dist/app/assets/latte-DaZOqdGV.js +0 -1
- package/dist/app/assets/less-BmKsj1gN.js +0 -1
- package/dist/app/assets/lilypond-mmng28aJ.js +0 -1
- package/dist/app/assets/liquid-BuuJO6_6.js +0 -1
- package/dist/app/assets/lisp-DnffFM5N.js +0 -1
- package/dist/app/assets/livescript-BSsr00Wr.js +0 -1
- package/dist/app/assets/llvm-37YjcHN5.js +0 -1
- package/dist/app/assets/log-D3l5N3To.js +0 -1
- package/dist/app/assets/lolcode-C0Q2M_6s.js +0 -1
- package/dist/app/assets/lua-DcLwN4Tg.js +0 -1
- package/dist/app/assets/magma-CK0Amip9.js +0 -1
- package/dist/app/assets/makefile-CtpS-RoO.js +0 -1
- package/dist/app/assets/markdown-BNK3F4ql.js +0 -1
- package/dist/app/assets/markup-C9GIL65H.js +0 -1
- package/dist/app/assets/markup-templating-Du1J3ADP.js +0 -1
- package/dist/app/assets/matlab-DEM6O1Ul.js +0 -1
- package/dist/app/assets/maxscript-DMvqa3gf.js +0 -1
- package/dist/app/assets/mel-C8DBIw1g.js +0 -1
- package/dist/app/assets/mermaid-CVko6NSq.js +0 -1
- package/dist/app/assets/mizar-CwYm3_It.js +0 -1
- package/dist/app/assets/mongodb-DRqGwjq6.js +0 -1
- package/dist/app/assets/monkey-BxiKe6Nr.js +0 -1
- package/dist/app/assets/moonscript-CJyt1xoM.js +0 -1
- package/dist/app/assets/n1ql-BBmjIGEU.js +0 -1
- package/dist/app/assets/n4js-ByKsJMJL.js +0 -1
- package/dist/app/assets/nand2tetris-hdl-BTSXj71h.js +0 -1
- package/dist/app/assets/naniscript-C4jykFVF.js +0 -1
- package/dist/app/assets/nasm-DPA0eXtX.js +0 -1
- package/dist/app/assets/neon-upN4Ak64.js +0 -1
- package/dist/app/assets/nevod-CdttHB8F.js +0 -1
- package/dist/app/assets/nginx-DI1fsQ3j.js +0 -1
- package/dist/app/assets/nim-D7kc_mK9.js +0 -1
- package/dist/app/assets/nix-BUG5ppr9.js +0 -1
- package/dist/app/assets/nsis-BnXhmmxO.js +0 -1
- package/dist/app/assets/objectivec-Bu4dOfb9.js +0 -1
- package/dist/app/assets/ocaml-aT7VVPiL.js +0 -1
- package/dist/app/assets/opencl-BzyWcYkI.js +0 -1
- package/dist/app/assets/openqasm-b2yFBJdq.js +0 -1
- package/dist/app/assets/oz-D46TtIuw.js +0 -1
- package/dist/app/assets/parigp-BAJyhdut.js +0 -1
- package/dist/app/assets/parser-B-ALvauC.js +0 -1
- package/dist/app/assets/pascal-B0ap4FDW.js +0 -1
- package/dist/app/assets/pascaligo-ChOneu9-.js +0 -1
- package/dist/app/assets/pcaxis-DTAmxHgs.js +0 -1
- package/dist/app/assets/peoplecode-dQfUy8zn.js +0 -1
- package/dist/app/assets/perl-CYk00e1Q.js +0 -1
- package/dist/app/assets/php-DvSqFnSN.js +0 -1
- package/dist/app/assets/php-extras-BFjUbIU6.js +0 -1
- package/dist/app/assets/phpdoc-Di7rKCNL.js +0 -1
- package/dist/app/assets/plsql-dX0-BKqD.js +0 -1
- package/dist/app/assets/powerquery-3xq4KaAs.js +0 -1
- package/dist/app/assets/powershell-BbXooszO.js +0 -1
- package/dist/app/assets/processing-GWbfNCzH.js +0 -1
- package/dist/app/assets/prolog-Tb2TbunJ.js +0 -1
- package/dist/app/assets/promql-QS8vHhL7.js +0 -1
- package/dist/app/assets/properties-BJ8AWlqX.js +0 -1
- package/dist/app/assets/protobuf-De-puAg3.js +0 -1
- package/dist/app/assets/psl-hZft3C8K.js +0 -1
- package/dist/app/assets/pug-BcYHdk-i.js +0 -1
- package/dist/app/assets/puppet-BWbqDQJD.js +0 -1
- package/dist/app/assets/pure-Bz2pjTxR.js +0 -1
- package/dist/app/assets/purebasic-BlO48lYx.js +0 -1
- package/dist/app/assets/purescript-BxSMm2Br.js +0 -1
- package/dist/app/assets/q-DDUTW9aK.js +0 -1
- package/dist/app/assets/qml-DisOV-LV.js +0 -1
- package/dist/app/assets/qore-FNRP4gBF.js +0 -1
- package/dist/app/assets/qsharp-DhtMV0oO.js +0 -1
- package/dist/app/assets/r-CyiuHjNN.js +0 -1
- package/dist/app/assets/racket-DFgoSckH.js +0 -1
- package/dist/app/assets/reason-HhYbY7K3.js +0 -1
- package/dist/app/assets/regex-jU5TpvM-.js +0 -1
- package/dist/app/assets/rego-BCjDPrQO.js +0 -1
- package/dist/app/assets/renpy-BTSgQi2v.js +0 -1
- package/dist/app/assets/rest-BLcZ4e-5.js +0 -1
- package/dist/app/assets/rip-SltRJnuI.js +0 -1
- package/dist/app/assets/roboconf-B-GZm2Oe.js +0 -1
- package/dist/app/assets/robotframework-BOt8S6cX.js +0 -1
- package/dist/app/assets/ruby-CVfYH0zM.js +0 -1
- package/dist/app/assets/rust-B6mEp4Sj.js +0 -1
- package/dist/app/assets/sas-DvEI8RJ0.js +0 -1
- package/dist/app/assets/sass-Cv25Jxqq.js +0 -1
- package/dist/app/assets/scala-CyqNr7Uv.js +0 -1
- package/dist/app/assets/scheme-ji0XoXLf.js +0 -1
- package/dist/app/assets/scss-B7_0neO_.js +0 -1
- package/dist/app/assets/shell-session-CqZEoMQD.js +0 -1
- package/dist/app/assets/smali-DKSzZYkI.js +0 -1
- package/dist/app/assets/smalltalk-BOA4piuq.js +0 -1
- package/dist/app/assets/smarty-Du99BSgN.js +0 -1
- package/dist/app/assets/sml-BJedIA4B.js +0 -1
- package/dist/app/assets/solidity-DidQwG5Z.js +0 -1
- package/dist/app/assets/solution-file-Bx0d9qN8.js +0 -1
- package/dist/app/assets/soy-BBLv3Cfa.js +0 -1
- package/dist/app/assets/sparql-Da5WZKbL.js +0 -1
- package/dist/app/assets/splunk-spl-DbJKl8So.js +0 -1
- package/dist/app/assets/sqf-CYrx0jxf.js +0 -1
- package/dist/app/assets/sql-Gv-aOlOf.js +0 -1
- package/dist/app/assets/squirrel-FpIGPPw4.js +0 -1
- package/dist/app/assets/stan-Dq001Nrk.js +0 -1
- package/dist/app/assets/stylus-aatfgWwe.js +0 -1
- package/dist/app/assets/swift-pn7VW95d.js +0 -1
- package/dist/app/assets/systemd-9capsVJ6.js +0 -2
- package/dist/app/assets/t4-cs-CKXcczci.js +0 -1
- package/dist/app/assets/t4-templating-1wTayb8u.js +0 -1
- package/dist/app/assets/t4-vb-B_O7wBow.js +0 -1
- package/dist/app/assets/tap-D-TV5_gQ.js +0 -1
- package/dist/app/assets/tcl-BaVob1Om.js +0 -1
- package/dist/app/assets/textile-COMk-HmI.js +0 -1
- package/dist/app/assets/toml-D9NJpArC.js +0 -1
- package/dist/app/assets/tremor-rCNHwdQL.js +0 -1
- package/dist/app/assets/tt2-DTDvfOgc.js +0 -1
- package/dist/app/assets/twig-DxSF8gqH.js +0 -1
- package/dist/app/assets/typescript-Caebatmk.js +0 -1
- package/dist/app/assets/typoscript-B3uk1kES.js +0 -1
- package/dist/app/assets/unrealscript-ZNoSG8ji.js +0 -1
- package/dist/app/assets/uorazor-LekoNNOo.js +0 -1
- package/dist/app/assets/uri-B8YcIzOv.js +0 -1
- package/dist/app/assets/v-6rOne2a0.js +0 -1
- package/dist/app/assets/vala-CjEJEdsP.js +0 -1
- package/dist/app/assets/vbnet-DBPmBm7_.js +0 -1
- package/dist/app/assets/velocity-DOooMwL8.js +0 -1
- package/dist/app/assets/verilog-Cq0ZocvP.js +0 -1
- package/dist/app/assets/vhdl-Dxs_xidb.js +0 -1
- package/dist/app/assets/vim-BqsnXwB6.js +0 -1
- package/dist/app/assets/visual-basic-zAzjvaqP.js +0 -1
- package/dist/app/assets/warpscript-D9hbfr6_.js +0 -1
- package/dist/app/assets/wasm-C4TU9VDY.js +0 -1
- package/dist/app/assets/web-idl-DD5JcddQ.js +0 -1
- package/dist/app/assets/wiki-Des21yVK.js +0 -1
- package/dist/app/assets/wolfram-B7enpov1.js +0 -1
- package/dist/app/assets/wren-Rr8h-Ayu.js +0 -1
- package/dist/app/assets/xeora-EjcLXBhx.js +0 -1
- package/dist/app/assets/xml-doc-uaTxx6-m.js +0 -1
- package/dist/app/assets/xojo-CX6G8nhh.js +0 -1
- package/dist/app/assets/xquery-DvPb3Uw9.js +0 -1
- package/dist/app/assets/yaml-D-l_Y2hx.js +0 -1
- package/dist/app/assets/yang-KBoIIT4_.js +0 -1
- package/dist/app/assets/zig-_uNXp9cY.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
// src/components/chat.tsx
|
|
2
|
-
import * as
|
|
3
|
-
import {
|
|
2
|
+
import * as React22 from "react";
|
|
3
|
+
import {
|
|
4
|
+
ArrowDown,
|
|
5
|
+
FileText as FileText2,
|
|
6
|
+
ImageIcon,
|
|
7
|
+
Loader2 as Loader23,
|
|
8
|
+
Pencil as Pencil3,
|
|
9
|
+
Quote,
|
|
10
|
+
RefreshCw as RefreshCw2,
|
|
11
|
+
X as X3
|
|
12
|
+
} from "lucide-react";
|
|
4
13
|
|
|
5
14
|
// src/lib/utils.ts
|
|
6
15
|
import { clsx } from "clsx";
|
|
@@ -21,6 +30,64 @@ function createMessageId() {
|
|
|
21
30
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
22
31
|
}
|
|
23
32
|
|
|
33
|
+
// src/lib/message.ts
|
|
34
|
+
import { isNil, omitBy } from "lodash-es";
|
|
35
|
+
var ASSISTANT_STREAM_IDLE_TO_THINKING_MS = 2e3;
|
|
36
|
+
function hasRenderableReasoning(reasoning) {
|
|
37
|
+
return Array.isArray(reasoning) && reasoning.some((item) => item.text?.trim());
|
|
38
|
+
}
|
|
39
|
+
function hasRenderableMessageContent(content) {
|
|
40
|
+
if (typeof content === "string") {
|
|
41
|
+
return content.trim().length > 0;
|
|
42
|
+
}
|
|
43
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const items = content;
|
|
47
|
+
return items.some((item) => {
|
|
48
|
+
if (typeof item === "string") {
|
|
49
|
+
return item.trim().length > 0;
|
|
50
|
+
}
|
|
51
|
+
if (!item || typeof item !== "object") {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (item.type === "text") {
|
|
55
|
+
return Boolean(item.text?.trim());
|
|
56
|
+
}
|
|
57
|
+
if (item.type === "reasoning") {
|
|
58
|
+
return Boolean(item.text?.trim());
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function hasRenderableAssistantMessage(message) {
|
|
64
|
+
return hasRenderableMessageContent(message.content) || hasRenderableReasoning(message.reasoning);
|
|
65
|
+
}
|
|
66
|
+
function getAssistantStreamingStatus(message, isStreaming, options) {
|
|
67
|
+
if (!isStreaming) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const now = options?.now ?? Date.now();
|
|
71
|
+
const lastStreamOutputAt = typeof message.lastStreamOutputAt === "number" ? message.lastStreamOutputAt : null;
|
|
72
|
+
const isIdle = lastStreamOutputAt !== null && now - lastStreamOutputAt >= ASSISTANT_STREAM_IDLE_TO_THINKING_MS;
|
|
73
|
+
if (message.status === "reasoning") {
|
|
74
|
+
return "thinking";
|
|
75
|
+
}
|
|
76
|
+
if (message.status === "answering") {
|
|
77
|
+
if (isIdle) {
|
|
78
|
+
return "thinking";
|
|
79
|
+
}
|
|
80
|
+
return "answering";
|
|
81
|
+
}
|
|
82
|
+
if (hasRenderableReasoning(message.reasoning)) {
|
|
83
|
+
return "thinking";
|
|
84
|
+
}
|
|
85
|
+
if (isIdle) {
|
|
86
|
+
return "thinking";
|
|
87
|
+
}
|
|
88
|
+
return "loading";
|
|
89
|
+
}
|
|
90
|
+
|
|
24
91
|
// src/lib/scroll.ts
|
|
25
92
|
var BOTTOM_FOLLOW_THRESHOLD_PX = 48;
|
|
26
93
|
function getDistanceFromBottom(element) {
|
|
@@ -45,7 +112,29 @@ import {
|
|
|
45
112
|
Client
|
|
46
113
|
} from "@xpert-ai/xpert-sdk";
|
|
47
114
|
import "@langchain/core/messages/tool";
|
|
48
|
-
import {
|
|
115
|
+
import {
|
|
116
|
+
ChatMessageEventTypeEnum,
|
|
117
|
+
ChatMessageTypeEnum
|
|
118
|
+
} from "@xpert-ai/chatkit-types";
|
|
119
|
+
|
|
120
|
+
// src/lib/api-config.ts
|
|
121
|
+
function hasConfiguredValue(value) {
|
|
122
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
123
|
+
}
|
|
124
|
+
function getMissingApiConfigurationKind({
|
|
125
|
+
apiUrl,
|
|
126
|
+
clientSecret
|
|
127
|
+
}) {
|
|
128
|
+
const hasApiUrl = hasConfiguredValue(apiUrl);
|
|
129
|
+
const hasClientSecret = hasConfiguredValue(clientSecret);
|
|
130
|
+
if (hasApiUrl && hasClientSecret) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
if (!hasApiUrl && !hasClientSecret) {
|
|
134
|
+
return "apiUrlAndClientSecret";
|
|
135
|
+
}
|
|
136
|
+
return hasApiUrl ? "clientSecret" : "apiUrl";
|
|
137
|
+
}
|
|
49
138
|
|
|
50
139
|
// src/lib/request-options.ts
|
|
51
140
|
import {
|
|
@@ -129,8 +218,16 @@ function buildInjectedRequestOptions(input) {
|
|
|
129
218
|
import { useContext, useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
130
219
|
|
|
131
220
|
// src/providers/ParentMessenger.tsx
|
|
132
|
-
import {
|
|
133
|
-
|
|
221
|
+
import {
|
|
222
|
+
createContext,
|
|
223
|
+
useCallback,
|
|
224
|
+
useEffect,
|
|
225
|
+
useMemo,
|
|
226
|
+
useRef
|
|
227
|
+
} from "react";
|
|
228
|
+
import {
|
|
229
|
+
STATE_VARIABLE_HUMAN as STATE_VARIABLE_HUMAN2
|
|
230
|
+
} from "@xpert-ai/chatkit-types";
|
|
134
231
|
|
|
135
232
|
// src/hooks/useStream.ts
|
|
136
233
|
var streamRef = { current: null };
|
|
@@ -144,6 +241,302 @@ function useStreamManager() {
|
|
|
144
241
|
};
|
|
145
242
|
}
|
|
146
243
|
|
|
244
|
+
// src/lib/references.ts
|
|
245
|
+
function isObjectLike(value) {
|
|
246
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
247
|
+
}
|
|
248
|
+
function isNonEmptyString(value) {
|
|
249
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
250
|
+
}
|
|
251
|
+
function isOptionalString(value) {
|
|
252
|
+
return value === void 0 || typeof value === "string";
|
|
253
|
+
}
|
|
254
|
+
function toOptionalString(value) {
|
|
255
|
+
return isNonEmptyString(value) ? value.trim() : void 0;
|
|
256
|
+
}
|
|
257
|
+
function toReferenceText(value) {
|
|
258
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
259
|
+
}
|
|
260
|
+
function toLineNumber(value) {
|
|
261
|
+
if (typeof value === "number" && Number.isInteger(value) && value > 0) {
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
function isOptionalNumber(value) {
|
|
267
|
+
return value === void 0 || Number.isFinite(value);
|
|
268
|
+
}
|
|
269
|
+
function toOptionalNumber(value, options) {
|
|
270
|
+
const allowZero = options?.allowZero ?? false;
|
|
271
|
+
if (!Number.isFinite(value)) {
|
|
272
|
+
return void 0;
|
|
273
|
+
}
|
|
274
|
+
const numberValue = value;
|
|
275
|
+
if (numberValue > 0 || allowZero && numberValue === 0) {
|
|
276
|
+
return numberValue;
|
|
277
|
+
}
|
|
278
|
+
return void 0;
|
|
279
|
+
}
|
|
280
|
+
function hasImageReferenceLocator(candidate) {
|
|
281
|
+
return isNonEmptyString(candidate.fileId) || isNonEmptyString(candidate.url) || isNonEmptyString(candidate.name) || isNonEmptyString(candidate.label) || isNonEmptyString(candidate.text);
|
|
282
|
+
}
|
|
283
|
+
function isCodeReferenceCandidate(value) {
|
|
284
|
+
if (!isObjectLike(value)) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
const candidate = value;
|
|
288
|
+
return isNonEmptyString(candidate.path) && toLineNumber(candidate.startLine) !== null && toLineNumber(candidate.endLine) !== null && toReferenceText(candidate.text) !== null && isOptionalString(candidate.id) && isOptionalString(candidate.label) && isOptionalString(candidate.language) && isOptionalString(candidate.taskId);
|
|
289
|
+
}
|
|
290
|
+
function isQuoteReferenceCandidate(value) {
|
|
291
|
+
if (!isObjectLike(value)) {
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
const candidate = value;
|
|
295
|
+
return candidate.type === "quote" && toReferenceText(candidate.text) !== null && isOptionalString(candidate.id) && isOptionalString(candidate.label) && isOptionalString(candidate.messageId) && isOptionalString(candidate.source);
|
|
296
|
+
}
|
|
297
|
+
function isImageReferenceCandidate(value) {
|
|
298
|
+
if (!isObjectLike(value)) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
const candidate = value;
|
|
302
|
+
return candidate.type === "image" && isOptionalString(candidate.id) && isOptionalString(candidate.label) && isOptionalString(candidate.text) && isOptionalString(candidate.fileId) && isOptionalString(candidate.url) && isOptionalString(candidate.mimeType) && isOptionalString(candidate.name) && isOptionalNumber(candidate.size) && isOptionalNumber(candidate.width) && isOptionalNumber(candidate.height) && hasImageReferenceLocator(candidate);
|
|
303
|
+
}
|
|
304
|
+
function toCodeReference(candidate) {
|
|
305
|
+
return {
|
|
306
|
+
type: "code",
|
|
307
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
308
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
309
|
+
path: candidate.path.trim(),
|
|
310
|
+
startLine: candidate.startLine,
|
|
311
|
+
endLine: candidate.endLine,
|
|
312
|
+
text: candidate.text,
|
|
313
|
+
...toOptionalString(candidate.language) ? { language: toOptionalString(candidate.language) } : {},
|
|
314
|
+
...toOptionalString(candidate.taskId) ? { taskId: toOptionalString(candidate.taskId) } : {}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
function toQuoteReference(candidate) {
|
|
318
|
+
return {
|
|
319
|
+
type: "quote",
|
|
320
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
321
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
322
|
+
text: candidate.text,
|
|
323
|
+
...toOptionalString(candidate.messageId) ? { messageId: toOptionalString(candidate.messageId) } : {},
|
|
324
|
+
...toOptionalString(candidate.source) ? { source: toOptionalString(candidate.source) } : {}
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
function toImageReference(candidate) {
|
|
328
|
+
const fileId = toOptionalString(candidate.fileId);
|
|
329
|
+
const url = toOptionalString(candidate.url);
|
|
330
|
+
const name = toOptionalString(candidate.name);
|
|
331
|
+
const label = toOptionalString(candidate.label);
|
|
332
|
+
const rawText = toReferenceText(candidate.text);
|
|
333
|
+
const text = rawText ?? name ?? label ?? "Pasted image";
|
|
334
|
+
return {
|
|
335
|
+
type: "image",
|
|
336
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
337
|
+
...label ? { label } : {},
|
|
338
|
+
text,
|
|
339
|
+
...fileId ? { fileId } : {},
|
|
340
|
+
...url ? { url } : {},
|
|
341
|
+
...toOptionalString(candidate.mimeType) ? { mimeType: toOptionalString(candidate.mimeType) } : {},
|
|
342
|
+
...name ? { name } : {},
|
|
343
|
+
...toOptionalNumber(candidate.size, { allowZero: true }) !== void 0 ? { size: toOptionalNumber(candidate.size, { allowZero: true }) } : {},
|
|
344
|
+
...toOptionalNumber(candidate.width) !== void 0 ? { width: toOptionalNumber(candidate.width) } : {},
|
|
345
|
+
...toOptionalNumber(candidate.height) !== void 0 ? { height: toOptionalNumber(candidate.height) } : {}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function isLegacyCodeReference(candidate) {
|
|
349
|
+
return candidate.type === void 0 && isNonEmptyString(candidate.path) && toLineNumber(candidate.startLine) !== null && toLineNumber(candidate.endLine) !== null && toReferenceText(candidate.text) !== null;
|
|
350
|
+
}
|
|
351
|
+
function normalizeReference(value) {
|
|
352
|
+
if (!isObjectLike(value)) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
const candidate = value;
|
|
356
|
+
const type = toOptionalString(candidate.type);
|
|
357
|
+
if (type === "code" && isCodeReferenceCandidate(candidate)) {
|
|
358
|
+
return toCodeReference(candidate);
|
|
359
|
+
}
|
|
360
|
+
if (isQuoteReferenceCandidate(candidate)) {
|
|
361
|
+
return toQuoteReference(candidate);
|
|
362
|
+
}
|
|
363
|
+
if (isImageReferenceCandidate(candidate)) {
|
|
364
|
+
return toImageReference(candidate);
|
|
365
|
+
}
|
|
366
|
+
if (type === void 0 && isLegacyCodeReference(candidate)) {
|
|
367
|
+
return toCodeReference(candidate);
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
function normalizeReferences(value) {
|
|
372
|
+
if (!Array.isArray(value)) {
|
|
373
|
+
return [];
|
|
374
|
+
}
|
|
375
|
+
return value.map((item) => normalizeReference(item)).filter((item) => item !== null);
|
|
376
|
+
}
|
|
377
|
+
function getCodeReferenceRange(reference) {
|
|
378
|
+
return reference.startLine === reference.endLine ? `${reference.startLine}` : `${reference.startLine}-${reference.endLine}`;
|
|
379
|
+
}
|
|
380
|
+
function getQuoteExcerpt(reference) {
|
|
381
|
+
const normalized = reference.text.replace(/\s+/g, " ").trim();
|
|
382
|
+
if (normalized.length <= 32) {
|
|
383
|
+
return normalized;
|
|
384
|
+
}
|
|
385
|
+
return `${normalized.slice(0, 29)}...`;
|
|
386
|
+
}
|
|
387
|
+
function getCodeReferenceLocation(reference) {
|
|
388
|
+
return `${reference.path}:${getCodeReferenceRange(reference)}`;
|
|
389
|
+
}
|
|
390
|
+
function formatReferenceSize(size2) {
|
|
391
|
+
if (size2 < 1024) {
|
|
392
|
+
return `${size2} B`;
|
|
393
|
+
}
|
|
394
|
+
if (size2 < 1024 * 1024) {
|
|
395
|
+
return `${(size2 / 1024).toFixed(size2 < 10 * 1024 ? 1 : 0)} KB`;
|
|
396
|
+
}
|
|
397
|
+
return `${(size2 / (1024 * 1024)).toFixed(size2 < 10 * 1024 * 1024 ? 1 : 0)} MB`;
|
|
398
|
+
}
|
|
399
|
+
function getImageReferenceDimensions(reference) {
|
|
400
|
+
if (!reference.width || !reference.height) {
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
return `${reference.width}x${reference.height}`;
|
|
404
|
+
}
|
|
405
|
+
function getImageReferenceMetaParts(reference) {
|
|
406
|
+
return [
|
|
407
|
+
reference.mimeType?.trim() || null,
|
|
408
|
+
getImageReferenceDimensions(reference),
|
|
409
|
+
typeof reference.size === "number" ? formatReferenceSize(reference.size) : null
|
|
410
|
+
].filter((part) => Boolean(part));
|
|
411
|
+
}
|
|
412
|
+
function getReferenceKey(reference) {
|
|
413
|
+
if (reference.type === "image" && reference.fileId?.trim()) {
|
|
414
|
+
return `image:${reference.fileId.trim()}`;
|
|
415
|
+
}
|
|
416
|
+
if (reference.id && reference.id.trim()) {
|
|
417
|
+
return reference.id.trim();
|
|
418
|
+
}
|
|
419
|
+
if (reference.type === "code") {
|
|
420
|
+
return [
|
|
421
|
+
reference.type,
|
|
422
|
+
reference.path,
|
|
423
|
+
reference.startLine,
|
|
424
|
+
reference.endLine,
|
|
425
|
+
reference.text
|
|
426
|
+
].join(":");
|
|
427
|
+
}
|
|
428
|
+
if (reference.type === "image") {
|
|
429
|
+
return [
|
|
430
|
+
reference.type,
|
|
431
|
+
reference.url ?? "",
|
|
432
|
+
reference.name ?? "",
|
|
433
|
+
reference.mimeType ?? "",
|
|
434
|
+
reference.size ?? "",
|
|
435
|
+
reference.width ?? "",
|
|
436
|
+
reference.height ?? "",
|
|
437
|
+
reference.text
|
|
438
|
+
].join(":");
|
|
439
|
+
}
|
|
440
|
+
return [
|
|
441
|
+
reference.type,
|
|
442
|
+
reference.messageId ?? "",
|
|
443
|
+
reference.source ?? "",
|
|
444
|
+
reference.text
|
|
445
|
+
].join(":");
|
|
446
|
+
}
|
|
447
|
+
function mergeReferences(current, incoming) {
|
|
448
|
+
const merged = [...current];
|
|
449
|
+
const seen = new Set(current.map(getReferenceKey));
|
|
450
|
+
incoming.forEach((reference) => {
|
|
451
|
+
const key = getReferenceKey(reference);
|
|
452
|
+
if (seen.has(key)) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
seen.add(key);
|
|
456
|
+
merged.push(reference);
|
|
457
|
+
});
|
|
458
|
+
return merged;
|
|
459
|
+
}
|
|
460
|
+
function getReferenceLabel(reference) {
|
|
461
|
+
if (reference.label && reference.label.trim()) {
|
|
462
|
+
return reference.label.trim();
|
|
463
|
+
}
|
|
464
|
+
if (reference.type === "code") {
|
|
465
|
+
const segments = reference.path.split("/");
|
|
466
|
+
const fileName = segments[segments.length - 1] || reference.path;
|
|
467
|
+
return `${fileName} ${getCodeReferenceRange(reference)}`;
|
|
468
|
+
}
|
|
469
|
+
if (reference.type === "image") {
|
|
470
|
+
return reference.name?.trim() || "Pasted image";
|
|
471
|
+
}
|
|
472
|
+
if (reference.source && reference.source.trim()) {
|
|
473
|
+
return reference.source.trim();
|
|
474
|
+
}
|
|
475
|
+
return getQuoteExcerpt(reference);
|
|
476
|
+
}
|
|
477
|
+
function getReferenceMetaLine(reference) {
|
|
478
|
+
if (reference.type === "code") {
|
|
479
|
+
return getCodeReferenceLocation(reference);
|
|
480
|
+
}
|
|
481
|
+
if (reference.type === "image") {
|
|
482
|
+
const parts = getImageReferenceMetaParts(reference);
|
|
483
|
+
return parts.length ? parts.join(" \u2022 ") : null;
|
|
484
|
+
}
|
|
485
|
+
if (reference.source && reference.source.trim()) {
|
|
486
|
+
return getQuoteExcerpt(reference);
|
|
487
|
+
}
|
|
488
|
+
if (reference.messageId && reference.messageId.trim()) {
|
|
489
|
+
return `Message ${reference.messageId.trim()}`;
|
|
490
|
+
}
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
function getReferenceTitle(reference) {
|
|
494
|
+
if (reference.type === "code") {
|
|
495
|
+
return `${getCodeReferenceLocation(reference)}
|
|
496
|
+
|
|
497
|
+
${reference.text}`;
|
|
498
|
+
}
|
|
499
|
+
if (reference.type === "image") {
|
|
500
|
+
const titleLines = [getReferenceLabel(reference)];
|
|
501
|
+
const metaLine = getReferenceMetaLine(reference);
|
|
502
|
+
const url = reference.url?.trim() && !reference.url.trim().startsWith("data:") ? reference.url.trim() : null;
|
|
503
|
+
if (metaLine) {
|
|
504
|
+
titleLines.push(metaLine);
|
|
505
|
+
}
|
|
506
|
+
if (url) {
|
|
507
|
+
titleLines.push(url);
|
|
508
|
+
}
|
|
509
|
+
if (reference.text.trim() && reference.text.trim() !== getReferenceLabel(reference)) {
|
|
510
|
+
titleLines.push("", reference.text.trim());
|
|
511
|
+
}
|
|
512
|
+
return titleLines.join("\n");
|
|
513
|
+
}
|
|
514
|
+
const header = reference.label?.trim() || reference.source?.trim() || "Quoted text";
|
|
515
|
+
return `${header}
|
|
516
|
+
|
|
517
|
+
${reference.text}`;
|
|
518
|
+
}
|
|
519
|
+
function buildHumanMessageInputPayload(source) {
|
|
520
|
+
const references = normalizeReferences(source.references);
|
|
521
|
+
const nextReferenceComposition = source.referenceComposition ?? (references.length > 0 && typeof source.submittedInput !== "string" ? "compose" : void 0);
|
|
522
|
+
if (typeof source.submittedInput === "string") {
|
|
523
|
+
return {
|
|
524
|
+
input: source.submittedInput.trim(),
|
|
525
|
+
...references.length > 0 ? { references } : {},
|
|
526
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
const input = typeof source.content === "string" ? source.content.trim() : "";
|
|
530
|
+
if (!input && references.length === 0) {
|
|
531
|
+
return null;
|
|
532
|
+
}
|
|
533
|
+
return {
|
|
534
|
+
input,
|
|
535
|
+
...references.length > 0 ? { references } : {},
|
|
536
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
147
540
|
// src/providers/ParentMessenger.tsx
|
|
148
541
|
import { jsx } from "react/jsx-runtime";
|
|
149
542
|
var handledSendUserMessageNonces = /* @__PURE__ */ new Set();
|
|
@@ -172,6 +565,10 @@ function ParentMessengerProvider({
|
|
|
172
565
|
/* @__PURE__ */ new Map()
|
|
173
566
|
);
|
|
174
567
|
const onSetOptionsHandlersRef = useRef(/* @__PURE__ */ new Set());
|
|
568
|
+
const onSetComposerValueHandlersRef = useRef(
|
|
569
|
+
/* @__PURE__ */ new Set()
|
|
570
|
+
);
|
|
571
|
+
const onFocusComposerHandlersRef = useRef(/* @__PURE__ */ new Set());
|
|
175
572
|
const latestOptionsRef = useRef(null);
|
|
176
573
|
const isParentAvailable = useMemo(() => {
|
|
177
574
|
return typeof window !== "undefined" && window.parent !== window;
|
|
@@ -185,6 +582,24 @@ function ParentMessengerProvider({
|
|
|
185
582
|
onSetOptionsHandlersRef.current.delete(handler);
|
|
186
583
|
};
|
|
187
584
|
}, []);
|
|
585
|
+
const registerOnSetComposerValue = useCallback(
|
|
586
|
+
(handler) => {
|
|
587
|
+
onSetComposerValueHandlersRef.current.add(handler);
|
|
588
|
+
return () => {
|
|
589
|
+
onSetComposerValueHandlersRef.current.delete(handler);
|
|
590
|
+
};
|
|
591
|
+
},
|
|
592
|
+
[]
|
|
593
|
+
);
|
|
594
|
+
const registerOnFocusComposer = useCallback(
|
|
595
|
+
(handler) => {
|
|
596
|
+
onFocusComposerHandlersRef.current.add(handler);
|
|
597
|
+
return () => {
|
|
598
|
+
onFocusComposerHandlersRef.current.delete(handler);
|
|
599
|
+
};
|
|
600
|
+
},
|
|
601
|
+
[]
|
|
602
|
+
);
|
|
188
603
|
useEffect(() => {
|
|
189
604
|
if (!isParentAvailable) return;
|
|
190
605
|
const sendResponse = (nonce, response, error) => {
|
|
@@ -205,7 +620,7 @@ function ParentMessengerProvider({
|
|
|
205
620
|
}
|
|
206
621
|
const payload = event.data;
|
|
207
622
|
if (payload.__xpaiChatKit !== true) return;
|
|
208
|
-
if (payload.type
|
|
623
|
+
if (payload.type === "command" && payload.command === "onSendUserMessage") {
|
|
209
624
|
const nonce = typeof payload.nonce === "string" ? payload.nonce : null;
|
|
210
625
|
if (nonce) {
|
|
211
626
|
if (handledSendUserMessageNonces.has(nonce)) return;
|
|
@@ -215,34 +630,53 @@ function ParentMessengerProvider({
|
|
|
215
630
|
handledSendUserMessageEvents.add(event);
|
|
216
631
|
}
|
|
217
632
|
const params = payload.data;
|
|
218
|
-
const prompt =
|
|
633
|
+
const prompt = typeof params.text === "string" ? params.text.trim() : typeof params.state?.[STATE_VARIABLE_HUMAN2]?.input === "string" ? params.state[STATE_VARIABLE_HUMAN2].input.trim() : "";
|
|
634
|
+
const references = normalizeReferences(
|
|
635
|
+
params.references ?? params.state?.[STATE_VARIABLE_HUMAN2]?.references
|
|
636
|
+
);
|
|
637
|
+
const referenceComposition = params.referenceComposition ?? params.state?.[STATE_VARIABLE_HUMAN2]?.referenceComposition;
|
|
638
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
639
|
+
content: prompt,
|
|
640
|
+
references,
|
|
641
|
+
referenceComposition
|
|
642
|
+
});
|
|
643
|
+
if (!humanInput) {
|
|
644
|
+
if (payload.nonce) {
|
|
645
|
+
sendResponse(payload.nonce, { ok: true });
|
|
646
|
+
}
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
219
649
|
const newMessage = {
|
|
220
650
|
id: createMessageId(),
|
|
221
651
|
type: "human",
|
|
222
|
-
content: prompt
|
|
652
|
+
content: prompt,
|
|
653
|
+
submittedInput: humanInput.input,
|
|
654
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
655
|
+
...references.length > 0 ? { references } : {}
|
|
223
656
|
};
|
|
657
|
+
const stream = streamRef2.current;
|
|
658
|
+
const activeFollowUpMode = stream?.isLoading ? params.followUpMode && params.followUpMode !== "default" ? params.followUpMode : stream.followUpBehavior ?? "queue" : void 0;
|
|
224
659
|
const requestOptions = buildInjectedRequestOptions({
|
|
225
660
|
defaults: latestOptionsRef.current?.request,
|
|
226
661
|
state: params.state,
|
|
227
|
-
humanInput
|
|
228
|
-
input: prompt
|
|
229
|
-
}
|
|
662
|
+
humanInput
|
|
230
663
|
});
|
|
231
|
-
|
|
664
|
+
stream?.submit(
|
|
232
665
|
{
|
|
233
|
-
input:
|
|
234
|
-
input: prompt
|
|
235
|
-
},
|
|
666
|
+
input: humanInput,
|
|
236
667
|
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
237
668
|
},
|
|
238
669
|
{
|
|
239
670
|
newThread: params.newThread,
|
|
671
|
+
...activeFollowUpMode ? { followUpMode: activeFollowUpMode } : {},
|
|
240
672
|
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
241
673
|
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
674
|
+
...!activeFollowUpMode ? {
|
|
675
|
+
optimisticValues: (prev) => {
|
|
676
|
+
const prevMessages = prev?.messages ?? [];
|
|
677
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
678
|
+
}
|
|
679
|
+
} : {}
|
|
246
680
|
}
|
|
247
681
|
);
|
|
248
682
|
if (payload.nonce) {
|
|
@@ -250,7 +684,28 @@ function ParentMessengerProvider({
|
|
|
250
684
|
}
|
|
251
685
|
return;
|
|
252
686
|
}
|
|
253
|
-
if (payload.type
|
|
687
|
+
if (payload.type === "command" && payload.command === "onSetComposerValue") {
|
|
688
|
+
const nextPayload = payload.data ?? null;
|
|
689
|
+
const normalizedPayload = nextPayload && Array.isArray(nextPayload.references) ? {
|
|
690
|
+
...nextPayload,
|
|
691
|
+
references: normalizeReferences(nextPayload.references)
|
|
692
|
+
} : nextPayload;
|
|
693
|
+
void Promise.all(
|
|
694
|
+
[...onSetComposerValueHandlersRef.current].map(
|
|
695
|
+
(handler2) => Promise.resolve(handler2(normalizedPayload))
|
|
696
|
+
)
|
|
697
|
+
).then(() => {
|
|
698
|
+
if (payload.nonce) {
|
|
699
|
+
sendResponse(payload.nonce, { ok: true });
|
|
700
|
+
}
|
|
701
|
+
}).catch((error) => {
|
|
702
|
+
if (payload.nonce) {
|
|
703
|
+
sendResponse(payload.nonce, void 0, error);
|
|
704
|
+
}
|
|
705
|
+
});
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (payload.type === "command" && payload.command === "onSetOptions") {
|
|
254
709
|
latestOptionsRef.current = payload.data ?? null;
|
|
255
710
|
if (onSetOptionsHandlersRef.current.size > 0) {
|
|
256
711
|
onSetOptionsHandlersRef.current.forEach((handler2) => {
|
|
@@ -262,16 +717,41 @@ function ParentMessengerProvider({
|
|
|
262
717
|
}
|
|
263
718
|
return;
|
|
264
719
|
}
|
|
265
|
-
if (payload.type
|
|
720
|
+
if (payload.type === "command" && payload.command === "onFocusComposer") {
|
|
721
|
+
void Promise.all(
|
|
722
|
+
[...onFocusComposerHandlersRef.current].map(
|
|
723
|
+
(handler2) => Promise.resolve(handler2())
|
|
724
|
+
)
|
|
725
|
+
).then(() => {
|
|
726
|
+
if (payload.nonce) {
|
|
727
|
+
sendResponse(payload.nonce, { ok: true });
|
|
728
|
+
}
|
|
729
|
+
}).catch((error) => {
|
|
730
|
+
if (payload.nonce) {
|
|
731
|
+
sendResponse(payload.nonce, void 0, error);
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
736
|
+
if (payload.type === "command" && payload.command === "onSetThreadId") {
|
|
266
737
|
const data = payload.data;
|
|
267
738
|
const nextThreadId = data?.threadId ?? null;
|
|
268
739
|
const stream = streamRef2.current;
|
|
740
|
+
if (stream?.threadId === nextThreadId) {
|
|
741
|
+
if (payload.nonce) {
|
|
742
|
+
sendResponse(payload.nonce, { ok: true });
|
|
743
|
+
}
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
269
746
|
stream?.reset(nextThreadId, void 0, { suppressThreadChange: true });
|
|
270
747
|
if (stream && nextThreadId) {
|
|
271
748
|
stream.loadThread(nextThreadId).catch((err) => {
|
|
272
749
|
console.warn("Failed to load thread messages", err);
|
|
273
750
|
});
|
|
274
751
|
}
|
|
752
|
+
if (payload.nonce) {
|
|
753
|
+
sendResponse(payload.nonce, { ok: true });
|
|
754
|
+
}
|
|
275
755
|
return;
|
|
276
756
|
}
|
|
277
757
|
if (payload.type !== "response") return;
|
|
@@ -332,25 +812,55 @@ function ParentMessengerProvider({
|
|
|
332
812
|
isParentAvailable,
|
|
333
813
|
sendCommand,
|
|
334
814
|
sendEvent,
|
|
335
|
-
registerOnSetOptions
|
|
815
|
+
registerOnSetOptions,
|
|
816
|
+
registerOnSetComposerValue,
|
|
817
|
+
registerOnFocusComposer
|
|
336
818
|
}),
|
|
337
|
-
[
|
|
819
|
+
[
|
|
820
|
+
isParentAvailable,
|
|
821
|
+
sendCommand,
|
|
822
|
+
sendEvent,
|
|
823
|
+
registerOnSetOptions,
|
|
824
|
+
registerOnSetComposerValue,
|
|
825
|
+
registerOnFocusComposer
|
|
826
|
+
]
|
|
338
827
|
);
|
|
339
828
|
return /* @__PURE__ */ jsx(ParentMessengerContext.Provider, { value, children });
|
|
340
829
|
}
|
|
341
830
|
|
|
342
831
|
// src/hooks/useParentMessenger.tsx
|
|
343
|
-
function useParentMessenger({
|
|
832
|
+
function useParentMessenger({
|
|
833
|
+
onSetOptions,
|
|
834
|
+
onSetComposerValue,
|
|
835
|
+
onFocusComposer
|
|
836
|
+
} = {}) {
|
|
344
837
|
const context = useContext(ParentMessengerContext);
|
|
345
838
|
if (!context) {
|
|
346
|
-
throw new Error(
|
|
839
|
+
throw new Error(
|
|
840
|
+
"useParentMessenger must be used within a ParentMessengerProvider"
|
|
841
|
+
);
|
|
347
842
|
}
|
|
348
|
-
const {
|
|
843
|
+
const {
|
|
844
|
+
registerOnSetOptions,
|
|
845
|
+
registerOnSetComposerValue,
|
|
846
|
+
registerOnFocusComposer,
|
|
847
|
+
...messenger
|
|
848
|
+
} = context;
|
|
349
849
|
const onSetOptionsRef = useRef2(onSetOptions);
|
|
850
|
+
const onSetComposerValueRef = useRef2(onSetComposerValue);
|
|
851
|
+
const onFocusComposerRef = useRef2(onFocusComposer);
|
|
350
852
|
useEffect2(() => {
|
|
351
853
|
onSetOptionsRef.current = onSetOptions;
|
|
352
854
|
}, [onSetOptions]);
|
|
855
|
+
useEffect2(() => {
|
|
856
|
+
onSetComposerValueRef.current = onSetComposerValue;
|
|
857
|
+
}, [onSetComposerValue]);
|
|
858
|
+
useEffect2(() => {
|
|
859
|
+
onFocusComposerRef.current = onFocusComposer;
|
|
860
|
+
}, [onFocusComposer]);
|
|
353
861
|
const hasOnSetOptions = Boolean(onSetOptions);
|
|
862
|
+
const hasOnSetComposerValue = Boolean(onSetComposerValue);
|
|
863
|
+
const hasOnFocusComposer = Boolean(onFocusComposer);
|
|
354
864
|
useEffect2(() => {
|
|
355
865
|
if (!hasOnSetOptions) return;
|
|
356
866
|
const handler = (options) => {
|
|
@@ -358,6 +868,20 @@ function useParentMessenger({ onSetOptions } = {}) {
|
|
|
358
868
|
};
|
|
359
869
|
return registerOnSetOptions(handler);
|
|
360
870
|
}, [hasOnSetOptions, registerOnSetOptions]);
|
|
871
|
+
useEffect2(() => {
|
|
872
|
+
if (!hasOnSetComposerValue) return;
|
|
873
|
+
const handler = (payload) => {
|
|
874
|
+
onSetComposerValueRef.current?.(payload);
|
|
875
|
+
};
|
|
876
|
+
return registerOnSetComposerValue(handler);
|
|
877
|
+
}, [hasOnSetComposerValue, registerOnSetComposerValue]);
|
|
878
|
+
useEffect2(() => {
|
|
879
|
+
if (!hasOnFocusComposer) return;
|
|
880
|
+
const handler = () => {
|
|
881
|
+
onFocusComposerRef.current?.();
|
|
882
|
+
};
|
|
883
|
+
return registerOnFocusComposer(handler);
|
|
884
|
+
}, [hasOnFocusComposer, registerOnFocusComposer]);
|
|
361
885
|
return messenger;
|
|
362
886
|
}
|
|
363
887
|
|
|
@@ -391,6 +915,17 @@ function resolveUsedContextSize(options) {
|
|
|
391
915
|
return normalizeContextUsageNumber(options.fallbackUsedTokens) ?? 0;
|
|
392
916
|
}
|
|
393
917
|
|
|
918
|
+
// src/lib/follow-ups.ts
|
|
919
|
+
function getComposerFollowUpShortcutLabels(queueShortcutLabel) {
|
|
920
|
+
return {
|
|
921
|
+
steer: "Enter",
|
|
922
|
+
queue: queueShortcutLabel
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
function getBusyComposerShortcutFollowUpMode(useQueueShortcut) {
|
|
926
|
+
return useQueueShortcut ? "queue" : "steer";
|
|
927
|
+
}
|
|
928
|
+
|
|
394
929
|
// src/providers/Stream.tsx
|
|
395
930
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
396
931
|
var StreamContext = createContext2(void 0);
|
|
@@ -522,12 +1057,39 @@ var en_US_default = {
|
|
|
522
1057
|
statusOnline: "Online",
|
|
523
1058
|
missingConfigShort: "Missing ChatKit configuration.",
|
|
524
1059
|
missingConfigDetail: "Missing ChatKit configuration. Check `VITE_XPERTAI_API_URL`, and the `clientSecret` prop.",
|
|
1060
|
+
missingApiUrlShort: "Missing ChatKit API URL.",
|
|
1061
|
+
missingApiUrlDetail: "Missing ChatKit API URL. Check `VITE_XPERTAI_API_URL` or `options.api.apiUrl`.",
|
|
1062
|
+
missingClientSecretShort: "Missing ChatKit client secret.",
|
|
1063
|
+
missingClientSecretDetail: "Missing ChatKit client secret. Check the `clientSecret` prop or `api.getClientSecret` integration.",
|
|
1064
|
+
missingApiUrlAndClientSecretShort: "Missing ChatKit API URL and client secret.",
|
|
1065
|
+
missingApiUrlAndClientSecretDetail: "Missing ChatKit API URL and client secret. Check `VITE_XPERTAI_API_URL`, `options.api.apiUrl`, and your client secret integration.",
|
|
525
1066
|
loadingThread: "Loading thread...",
|
|
526
1067
|
stop: "Stop",
|
|
527
1068
|
send: "Send message",
|
|
1069
|
+
referencedContentOnly: "Referenced content",
|
|
1070
|
+
youLabel: "You",
|
|
528
1071
|
scrollToBottom: "Scroll to bottom",
|
|
529
1072
|
retryUpload: "Retry upload",
|
|
530
1073
|
poweredBy: "Powered by Xpert AI",
|
|
1074
|
+
followUps: {
|
|
1075
|
+
label: "Follow-up behavior",
|
|
1076
|
+
settings: "Settings",
|
|
1077
|
+
idleHint: "Used when you send while a run is active.",
|
|
1078
|
+
activeHint: "This message will use the selected busy-run behavior.",
|
|
1079
|
+
pending: "Pending follow-ups",
|
|
1080
|
+
queue: "Queue",
|
|
1081
|
+
steer: "Steer",
|
|
1082
|
+
steerAction: "Steer",
|
|
1083
|
+
promoteToSteer: "Steer now",
|
|
1084
|
+
sendNow: "Send now",
|
|
1085
|
+
remove: "Remove pending follow-up",
|
|
1086
|
+
more: "More actions",
|
|
1087
|
+
edit: "Edit message",
|
|
1088
|
+
turnOffQueueing: "Turn off queueing",
|
|
1089
|
+
queueHint: "Starts after the current run finishes",
|
|
1090
|
+
manualQueueHint: "Ready to send as a new run",
|
|
1091
|
+
steerHint: "Injects after the current tool call"
|
|
1092
|
+
},
|
|
531
1093
|
errors: {
|
|
532
1094
|
loadMessages: "Failed to load thread messages",
|
|
533
1095
|
createThread: "Failed to create thread",
|
|
@@ -558,13 +1120,24 @@ var en_US_default = {
|
|
|
558
1120
|
},
|
|
559
1121
|
composer: {
|
|
560
1122
|
openMenu: "Open menu",
|
|
561
|
-
addAttachment: "Add attachment"
|
|
1123
|
+
addAttachment: "Add attachment",
|
|
1124
|
+
removeReference: "Remove reference",
|
|
1125
|
+
quoteSelection: "Quote selection"
|
|
562
1126
|
},
|
|
563
1127
|
sheet: {
|
|
564
1128
|
close: "Close"
|
|
565
1129
|
},
|
|
566
1130
|
markdown: {
|
|
567
|
-
copy: "Copy"
|
|
1131
|
+
copy: "Copy",
|
|
1132
|
+
mermaid: {
|
|
1133
|
+
title: "Mermaid",
|
|
1134
|
+
diagram: "Diagram",
|
|
1135
|
+
code: "Code",
|
|
1136
|
+
download: "Download SVG",
|
|
1137
|
+
fullScreen: "Open full screen",
|
|
1138
|
+
rendering: "Rendering diagram",
|
|
1139
|
+
failed: "Failed to render diagram"
|
|
1140
|
+
}
|
|
568
1141
|
},
|
|
569
1142
|
thread: {
|
|
570
1143
|
errorToast: "An error occurred. Please try again.",
|
|
@@ -573,7 +1146,10 @@ var en_US_default = {
|
|
|
573
1146
|
},
|
|
574
1147
|
message: {
|
|
575
1148
|
answer: "Answer",
|
|
576
|
-
reasoning: "Reasoning"
|
|
1149
|
+
reasoning: "Reasoning",
|
|
1150
|
+
loading: "Loading",
|
|
1151
|
+
thinking: "Thinking",
|
|
1152
|
+
answering: "Answering"
|
|
577
1153
|
}
|
|
578
1154
|
};
|
|
579
1155
|
|
|
@@ -585,12 +1161,39 @@ var zh_CN_default = {
|
|
|
585
1161
|
statusOnline: "\u5728\u7EBF",
|
|
586
1162
|
missingConfigShort: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002",
|
|
587
1163
|
missingConfigDetail: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u548C `clientSecret` \u53C2\u6570\u3002",
|
|
1164
|
+
missingApiUrlShort: "\u7F3A\u5C11 ChatKit API URL\u3002",
|
|
1165
|
+
missingApiUrlDetail: "\u7F3A\u5C11 ChatKit API URL\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u6216 `options.api.apiUrl`\u3002",
|
|
1166
|
+
missingClientSecretShort: "\u7F3A\u5C11 ChatKit client secret\u3002",
|
|
1167
|
+
missingClientSecretDetail: "\u7F3A\u5C11 ChatKit client secret\u3002\u8BF7\u68C0\u67E5 `clientSecret` \u53C2\u6570\u6216 `api.getClientSecret` \u96C6\u6210\u3002",
|
|
1168
|
+
missingApiUrlAndClientSecretShort: "\u7F3A\u5C11 ChatKit API URL \u548C client secret\u3002",
|
|
1169
|
+
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
1170
|
loadingThread: "\u6B63\u5728\u52A0\u8F7D\u7EBF\u7A0B...",
|
|
589
1171
|
stop: "\u505C\u6B62",
|
|
590
1172
|
send: "\u53D1\u9001\u6D88\u606F",
|
|
1173
|
+
referencedContentOnly: "\u5DF2\u5F15\u7528\u5185\u5BB9",
|
|
1174
|
+
youLabel: "\u4F60",
|
|
591
1175
|
scrollToBottom: "\u56DE\u5230\u5E95\u90E8",
|
|
592
1176
|
retryUpload: "\u91CD\u65B0\u4E0A\u4F20",
|
|
593
1177
|
poweredBy: "\u7531 Xpert AI \u9A71\u52A8",
|
|
1178
|
+
followUps: {
|
|
1179
|
+
label: "Follow-up \u6A21\u5F0F",
|
|
1180
|
+
settings: "\u8BBE\u7F6E",
|
|
1181
|
+
idleHint: "\u4EC5\u5728\u8FD0\u884C\u4E2D\u53D1\u9001\u6D88\u606F\u65F6\u751F\u6548\u3002",
|
|
1182
|
+
activeHint: "\u5F53\u524D\u6D88\u606F\u4F1A\u6309\u6240\u9009\u7684\u8FD0\u884C\u4E2D\u884C\u4E3A\u5904\u7406\u3002",
|
|
1183
|
+
pending: "\u5F85\u5904\u7406 Follow-up",
|
|
1184
|
+
queue: "\u6392\u961F",
|
|
1185
|
+
steer: "\u5F15\u5BFC",
|
|
1186
|
+
steerAction: "\u5F15\u5BFC",
|
|
1187
|
+
promoteToSteer: "\u8F6C\u4E3A\u5F15\u5BFC",
|
|
1188
|
+
sendNow: "\u7ACB\u5373\u53D1\u9001",
|
|
1189
|
+
remove: "\u79FB\u9664\u6B64\u5F85\u5904\u7406 Follow-up",
|
|
1190
|
+
more: "\u66F4\u591A\u64CD\u4F5C",
|
|
1191
|
+
edit: "\u7F16\u8F91\u6D88\u606F",
|
|
1192
|
+
turnOffQueueing: "\u5173\u95ED\u6392\u961F",
|
|
1193
|
+
queueHint: "\u5F53\u524D\u8FD0\u884C\u7ED3\u675F\u540E\u5F00\u542F\u4E0B\u4E00\u8F6E",
|
|
1194
|
+
manualQueueHint: "\u4FDD\u7559\u4E3A\u5F85\u53D1\u9001\uFF0C\u53EF\u624B\u52A8\u5F00\u542F\u65B0\u4E00\u8F6E",
|
|
1195
|
+
steerHint: "\u5F53\u524D\u5DE5\u5177\u8C03\u7528\u5B8C\u6210\u540E\u6CE8\u5165"
|
|
1196
|
+
},
|
|
594
1197
|
errors: {
|
|
595
1198
|
loadMessages: "\u52A0\u8F7D\u7EBF\u7A0B\u6D88\u606F\u5931\u8D25",
|
|
596
1199
|
createThread: "\u521B\u5EFA\u7EBF\u7A0B\u5931\u8D25",
|
|
@@ -621,13 +1224,24 @@ var zh_CN_default = {
|
|
|
621
1224
|
},
|
|
622
1225
|
composer: {
|
|
623
1226
|
openMenu: "\u6253\u5F00\u83DC\u5355",
|
|
624
|
-
addAttachment: "\u6DFB\u52A0\u9644\u4EF6"
|
|
1227
|
+
addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1228
|
+
removeReference: "\u79FB\u9664\u5F15\u7528",
|
|
1229
|
+
quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
|
|
625
1230
|
},
|
|
626
1231
|
sheet: {
|
|
627
1232
|
close: "\u5173\u95ED"
|
|
628
1233
|
},
|
|
629
1234
|
markdown: {
|
|
630
|
-
copy: "\u590D\u5236"
|
|
1235
|
+
copy: "\u590D\u5236",
|
|
1236
|
+
mermaid: {
|
|
1237
|
+
title: "Mermaid",
|
|
1238
|
+
diagram: "\u56FE\u8868",
|
|
1239
|
+
code: "\u4EE3\u7801",
|
|
1240
|
+
download: "\u4E0B\u8F7D SVG",
|
|
1241
|
+
fullScreen: "\u5168\u5C4F\u67E5\u770B",
|
|
1242
|
+
rendering: "\u6B63\u5728\u6E32\u67D3\u56FE\u8868",
|
|
1243
|
+
failed: "\u56FE\u8868\u6E32\u67D3\u5931\u8D25"
|
|
1244
|
+
}
|
|
631
1245
|
},
|
|
632
1246
|
thread: {
|
|
633
1247
|
errorToast: "\u53D1\u751F\u9519\u8BEF\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
@@ -636,7 +1250,10 @@ var zh_CN_default = {
|
|
|
636
1250
|
},
|
|
637
1251
|
message: {
|
|
638
1252
|
answer: "\u56DE\u7B54",
|
|
639
|
-
reasoning: "\u63A8\u7406"
|
|
1253
|
+
reasoning: "\u63A8\u7406",
|
|
1254
|
+
loading: "\u6B63\u5728\u52A0\u8F7D",
|
|
1255
|
+
thinking: "\u6B63\u5728\u601D\u8003",
|
|
1256
|
+
answering: "\u6B63\u5728\u751F\u6210"
|
|
640
1257
|
}
|
|
641
1258
|
};
|
|
642
1259
|
|
|
@@ -1157,18 +1774,86 @@ function ComposerMenu({
|
|
|
1157
1774
|
|
|
1158
1775
|
// src/components/composer/SendButton.tsx
|
|
1159
1776
|
import { ArrowUp, Square } from "lucide-react";
|
|
1160
|
-
|
|
1777
|
+
|
|
1778
|
+
// src/components/ui/tooltip.tsx
|
|
1779
|
+
import "react";
|
|
1780
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
1781
|
+
import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1782
|
+
function TooltipProvider({
|
|
1783
|
+
delayDuration = 0,
|
|
1784
|
+
...props
|
|
1785
|
+
}) {
|
|
1786
|
+
return /* @__PURE__ */ jsx7(
|
|
1787
|
+
TooltipPrimitive.Provider,
|
|
1788
|
+
{
|
|
1789
|
+
"data-slot": "tooltip-provider",
|
|
1790
|
+
delayDuration,
|
|
1791
|
+
...props
|
|
1792
|
+
}
|
|
1793
|
+
);
|
|
1794
|
+
}
|
|
1795
|
+
function Tooltip({
|
|
1796
|
+
...props
|
|
1797
|
+
}) {
|
|
1798
|
+
return /* @__PURE__ */ jsx7(TooltipProvider, { children: /* @__PURE__ */ jsx7(
|
|
1799
|
+
TooltipPrimitive.Root,
|
|
1800
|
+
{
|
|
1801
|
+
"data-slot": "tooltip",
|
|
1802
|
+
...props
|
|
1803
|
+
}
|
|
1804
|
+
) });
|
|
1805
|
+
}
|
|
1806
|
+
function TooltipTrigger({
|
|
1807
|
+
...props
|
|
1808
|
+
}) {
|
|
1809
|
+
return /* @__PURE__ */ jsx7(
|
|
1810
|
+
TooltipPrimitive.Trigger,
|
|
1811
|
+
{
|
|
1812
|
+
"data-slot": "tooltip-trigger",
|
|
1813
|
+
...props
|
|
1814
|
+
}
|
|
1815
|
+
);
|
|
1816
|
+
}
|
|
1817
|
+
function TooltipContent({
|
|
1818
|
+
className,
|
|
1819
|
+
sideOffset = 0,
|
|
1820
|
+
hideArrow = false,
|
|
1821
|
+
children,
|
|
1822
|
+
...props
|
|
1823
|
+
}) {
|
|
1824
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs2(
|
|
1825
|
+
TooltipPrimitive.Content,
|
|
1826
|
+
{
|
|
1827
|
+
"data-slot": "tooltip-content",
|
|
1828
|
+
sideOffset,
|
|
1829
|
+
className: cn(
|
|
1830
|
+
"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",
|
|
1831
|
+
className
|
|
1832
|
+
),
|
|
1833
|
+
...props,
|
|
1834
|
+
children: [
|
|
1835
|
+
children,
|
|
1836
|
+
!hideArrow ? /* @__PURE__ */ jsx7(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" }) : null
|
|
1837
|
+
]
|
|
1838
|
+
}
|
|
1839
|
+
) });
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
// src/components/composer/SendButton.tsx
|
|
1843
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1161
1844
|
function SendButton({
|
|
1162
1845
|
disabled = false,
|
|
1163
1846
|
isLoading = false,
|
|
1847
|
+
showStop = isLoading,
|
|
1164
1848
|
onStop,
|
|
1165
1849
|
stopLabel = "Stop",
|
|
1166
|
-
sendLabel = "Send"
|
|
1850
|
+
sendLabel = "Send",
|
|
1851
|
+
shortcuts
|
|
1167
1852
|
}) {
|
|
1168
1853
|
const { theme } = useTheme();
|
|
1169
1854
|
const roundedClass = getRoundedClass(theme.radius);
|
|
1170
|
-
if (
|
|
1171
|
-
return /* @__PURE__ */
|
|
1855
|
+
if (showStop) {
|
|
1856
|
+
return /* @__PURE__ */ jsx8(
|
|
1172
1857
|
"button",
|
|
1173
1858
|
{
|
|
1174
1859
|
type: "button",
|
|
@@ -1181,11 +1866,11 @@ function SendButton({
|
|
|
1181
1866
|
"hover:scale-105 active:scale-95"
|
|
1182
1867
|
),
|
|
1183
1868
|
"aria-label": stopLabel,
|
|
1184
|
-
children: /* @__PURE__ */
|
|
1869
|
+
children: /* @__PURE__ */ jsx8(Square, { size: 14, fill: "currentColor", stroke: "currentColor", strokeWidth: 0 })
|
|
1185
1870
|
}
|
|
1186
1871
|
);
|
|
1187
1872
|
}
|
|
1188
|
-
|
|
1873
|
+
const button = /* @__PURE__ */ jsx8(
|
|
1189
1874
|
"button",
|
|
1190
1875
|
{
|
|
1191
1876
|
type: "submit",
|
|
@@ -1199,34 +1884,63 @@ function SendButton({
|
|
|
1199
1884
|
"disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100"
|
|
1200
1885
|
),
|
|
1201
1886
|
"aria-label": sendLabel,
|
|
1202
|
-
children: /* @__PURE__ */
|
|
1887
|
+
children: /* @__PURE__ */ jsx8(ArrowUp, { size: 18, strokeWidth: 2.5 })
|
|
1203
1888
|
}
|
|
1204
1889
|
);
|
|
1890
|
+
if (!shortcuts?.length || disabled) {
|
|
1891
|
+
return button;
|
|
1892
|
+
}
|
|
1893
|
+
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
1894
|
+
/* @__PURE__ */ jsx8(TooltipTrigger, { asChild: true, children: button }),
|
|
1895
|
+
/* @__PURE__ */ jsx8(
|
|
1896
|
+
TooltipContent,
|
|
1897
|
+
{
|
|
1898
|
+
side: "top",
|
|
1899
|
+
sideOffset: 10,
|
|
1900
|
+
hideArrow: true,
|
|
1901
|
+
className: cn(
|
|
1902
|
+
"min-w-36 border border-border/70 bg-background px-3 py-2 text-foreground shadow-lg",
|
|
1903
|
+
roundedClass
|
|
1904
|
+
),
|
|
1905
|
+
children: /* @__PURE__ */ jsx8("div", { className: "space-y-1", children: shortcuts.map((shortcut) => /* @__PURE__ */ jsxs3(
|
|
1906
|
+
"div",
|
|
1907
|
+
{
|
|
1908
|
+
className: "flex items-center justify-between gap-4 text-sm",
|
|
1909
|
+
children: [
|
|
1910
|
+
/* @__PURE__ */ jsx8("span", { className: "font-medium", children: shortcut.label }),
|
|
1911
|
+
/* @__PURE__ */ jsx8("kbd", { className: "inline-flex min-w-16 items-center justify-center rounded-full bg-muted px-2.5 py-0.5 text-xs font-medium text-muted-foreground", children: shortcut.keys })
|
|
1912
|
+
]
|
|
1913
|
+
},
|
|
1914
|
+
`${shortcut.label}-${shortcut.keys}`
|
|
1915
|
+
)) })
|
|
1916
|
+
}
|
|
1917
|
+
)
|
|
1918
|
+
] });
|
|
1205
1919
|
}
|
|
1206
1920
|
|
|
1207
1921
|
// src/components/history/HistorySidebar.tsx
|
|
1208
|
-
import * as
|
|
1922
|
+
import * as React9 from "react";
|
|
1209
1923
|
import { History, MessageSquare, PlusCircle, Trash2 } from "lucide-react";
|
|
1210
1924
|
|
|
1211
1925
|
// src/components/ui/scroll-area.tsx
|
|
1212
|
-
import * as
|
|
1926
|
+
import * as React7 from "react";
|
|
1213
1927
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
1214
|
-
import { jsx as
|
|
1215
|
-
var ScrollArea =
|
|
1928
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1929
|
+
var ScrollArea = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
1216
1930
|
ScrollAreaPrimitive.Root,
|
|
1217
1931
|
{
|
|
1218
1932
|
ref,
|
|
1219
1933
|
className: cn("relative overflow-hidden", className),
|
|
1220
1934
|
...props,
|
|
1221
1935
|
children: [
|
|
1222
|
-
/* @__PURE__ */
|
|
1223
|
-
/* @__PURE__ */
|
|
1224
|
-
/* @__PURE__ */
|
|
1936
|
+
/* @__PURE__ */ jsx9(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
1937
|
+
/* @__PURE__ */ jsx9(ScrollBar, {}),
|
|
1938
|
+
/* @__PURE__ */ jsx9(ScrollAreaPrimitive.Corner, {})
|
|
1225
1939
|
]
|
|
1226
1940
|
}
|
|
1227
1941
|
));
|
|
1228
1942
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
1229
|
-
var ScrollBar =
|
|
1943
|
+
var ScrollBar = React7.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx9(
|
|
1230
1944
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
1231
1945
|
{
|
|
1232
1946
|
ref,
|
|
@@ -1238,7 +1952,7 @@ var ScrollBar = React6.forwardRef(({ className, orientation = "vertical", ...pro
|
|
|
1238
1952
|
className
|
|
1239
1953
|
),
|
|
1240
1954
|
...props,
|
|
1241
|
-
children: /* @__PURE__ */
|
|
1955
|
+
children: /* @__PURE__ */ jsx9(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
1242
1956
|
}
|
|
1243
1957
|
));
|
|
1244
1958
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
@@ -1247,21 +1961,21 @@ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
|
1247
1961
|
import "react";
|
|
1248
1962
|
import { X } from "lucide-react";
|
|
1249
1963
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
1250
|
-
import { jsx as
|
|
1964
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1251
1965
|
function Sheet({ ...props }) {
|
|
1252
|
-
return /* @__PURE__ */
|
|
1966
|
+
return /* @__PURE__ */ jsx10(SheetPrimitive.Root, { ...props });
|
|
1253
1967
|
}
|
|
1254
1968
|
function SheetTrigger({ ...props }) {
|
|
1255
|
-
return /* @__PURE__ */
|
|
1969
|
+
return /* @__PURE__ */ jsx10(SheetPrimitive.Trigger, { ...props });
|
|
1256
1970
|
}
|
|
1257
1971
|
function SheetPortal({ ...props }) {
|
|
1258
|
-
return /* @__PURE__ */
|
|
1972
|
+
return /* @__PURE__ */ jsx10(SheetPrimitive.Portal, { ...props });
|
|
1259
1973
|
}
|
|
1260
1974
|
function SheetOverlay({
|
|
1261
1975
|
className,
|
|
1262
1976
|
...props
|
|
1263
1977
|
}) {
|
|
1264
|
-
return /* @__PURE__ */
|
|
1978
|
+
return /* @__PURE__ */ jsx10(
|
|
1265
1979
|
SheetPrimitive.Overlay,
|
|
1266
1980
|
{
|
|
1267
1981
|
className: cn(
|
|
@@ -1285,9 +1999,9 @@ function SheetContent({
|
|
|
1285
1999
|
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
|
|
1286
2000
|
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm"
|
|
1287
2001
|
};
|
|
1288
|
-
return /* @__PURE__ */
|
|
1289
|
-
/* @__PURE__ */
|
|
1290
|
-
/* @__PURE__ */
|
|
2002
|
+
return /* @__PURE__ */ jsxs5(SheetPortal, { children: [
|
|
2003
|
+
/* @__PURE__ */ jsx10(SheetOverlay, {}),
|
|
2004
|
+
/* @__PURE__ */ jsxs5(
|
|
1291
2005
|
SheetPrimitive.Content,
|
|
1292
2006
|
{
|
|
1293
2007
|
className: cn(
|
|
@@ -1298,9 +2012,9 @@ function SheetContent({
|
|
|
1298
2012
|
...props,
|
|
1299
2013
|
children: [
|
|
1300
2014
|
children,
|
|
1301
|
-
/* @__PURE__ */
|
|
1302
|
-
/* @__PURE__ */
|
|
1303
|
-
/* @__PURE__ */
|
|
2015
|
+
/* @__PURE__ */ jsxs5(SheetPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary", children: [
|
|
2016
|
+
/* @__PURE__ */ jsx10(X, { size: 16 }),
|
|
2017
|
+
/* @__PURE__ */ jsx10("span", { className: "sr-only", children: t("sheet.close") })
|
|
1304
2018
|
] })
|
|
1305
2019
|
]
|
|
1306
2020
|
}
|
|
@@ -1311,7 +2025,7 @@ function SheetHeader({
|
|
|
1311
2025
|
className,
|
|
1312
2026
|
...props
|
|
1313
2027
|
}) {
|
|
1314
|
-
return /* @__PURE__ */
|
|
2028
|
+
return /* @__PURE__ */ jsx10(
|
|
1315
2029
|
"div",
|
|
1316
2030
|
{
|
|
1317
2031
|
className: cn(
|
|
@@ -1326,7 +2040,7 @@ function SheetTitle({
|
|
|
1326
2040
|
className,
|
|
1327
2041
|
...props
|
|
1328
2042
|
}) {
|
|
1329
|
-
return /* @__PURE__ */
|
|
2043
|
+
return /* @__PURE__ */ jsx10(
|
|
1330
2044
|
SheetPrimitive.Title,
|
|
1331
2045
|
{
|
|
1332
2046
|
className: cn("text-lg font-semibold text-foreground", className),
|
|
@@ -1336,7 +2050,7 @@ function SheetTitle({
|
|
|
1336
2050
|
}
|
|
1337
2051
|
|
|
1338
2052
|
// src/components/history/HistorySidebar.tsx
|
|
1339
|
-
import { jsx as
|
|
2053
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1340
2054
|
function HistorySidebar({
|
|
1341
2055
|
threads = [],
|
|
1342
2056
|
currentThreadId,
|
|
@@ -1347,7 +2061,7 @@ function HistorySidebar({
|
|
|
1347
2061
|
disabled = false
|
|
1348
2062
|
}) {
|
|
1349
2063
|
const { t } = useChatkitTranslation();
|
|
1350
|
-
const [open, setOpen] =
|
|
2064
|
+
const [open, setOpen] = React9.useState(false);
|
|
1351
2065
|
const handleNewThread = () => {
|
|
1352
2066
|
onNewThread?.();
|
|
1353
2067
|
setOpen(false);
|
|
@@ -1356,8 +2070,8 @@ function HistorySidebar({
|
|
|
1356
2070
|
onSelectThread?.(id);
|
|
1357
2071
|
setOpen(false);
|
|
1358
2072
|
};
|
|
1359
|
-
return /* @__PURE__ */
|
|
1360
|
-
/* @__PURE__ */
|
|
2073
|
+
return /* @__PURE__ */ jsxs6(Sheet, { open, onOpenChange: setOpen, children: [
|
|
2074
|
+
/* @__PURE__ */ jsx11(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
|
|
1361
2075
|
Button,
|
|
1362
2076
|
{
|
|
1363
2077
|
variant: "ghost",
|
|
@@ -1365,26 +2079,26 @@ function HistorySidebar({
|
|
|
1365
2079
|
disabled,
|
|
1366
2080
|
className: "h-8 w-8 cursor-pointer",
|
|
1367
2081
|
children: [
|
|
1368
|
-
/* @__PURE__ */
|
|
1369
|
-
/* @__PURE__ */
|
|
2082
|
+
/* @__PURE__ */ jsx11(History, { size: 16 }),
|
|
2083
|
+
/* @__PURE__ */ jsx11("span", { className: "sr-only", children: t("history.threadHistory") })
|
|
1370
2084
|
]
|
|
1371
2085
|
}
|
|
1372
2086
|
) }),
|
|
1373
|
-
/* @__PURE__ */
|
|
1374
|
-
/* @__PURE__ */
|
|
1375
|
-
/* @__PURE__ */
|
|
2087
|
+
/* @__PURE__ */ jsxs6(SheetContent, { side: "right", className: "w-80 p-0", children: [
|
|
2088
|
+
/* @__PURE__ */ jsx11(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ jsx11(SheetTitle, { children: t("history.title") }) }),
|
|
2089
|
+
/* @__PURE__ */ jsx11("div", { className: "p-4", children: /* @__PURE__ */ jsxs6(
|
|
1376
2090
|
Button,
|
|
1377
2091
|
{
|
|
1378
2092
|
onClick: handleNewThread,
|
|
1379
2093
|
className: "w-full justify-start gap-2",
|
|
1380
2094
|
variant: "secondary",
|
|
1381
2095
|
children: [
|
|
1382
|
-
/* @__PURE__ */
|
|
2096
|
+
/* @__PURE__ */ jsx11(PlusCircle, { size: 16 }),
|
|
1383
2097
|
t("history.newThread")
|
|
1384
2098
|
]
|
|
1385
2099
|
}
|
|
1386
2100
|
) }),
|
|
1387
|
-
/* @__PURE__ */
|
|
2101
|
+
/* @__PURE__ */ jsx11(ScrollArea, { className: "h-[calc(100vh-140px)]", children: /* @__PURE__ */ jsx11("div", { className: "px-4 pb-4", children: threads.length === 0 ? /* @__PURE__ */ jsx11("div", { className: "py-8 text-center text-sm text-muted-foreground", children: t("history.empty") }) : /* @__PURE__ */ jsx11("div", { className: "space-y-1", children: threads.map((thread) => /* @__PURE__ */ jsxs6(
|
|
1388
2102
|
"div",
|
|
1389
2103
|
{
|
|
1390
2104
|
className: cn(
|
|
@@ -1394,9 +2108,9 @@ function HistorySidebar({
|
|
|
1394
2108
|
),
|
|
1395
2109
|
onClick: () => handleSelectThread(thread.id),
|
|
1396
2110
|
children: [
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
showDelete && onDeleteThread && /* @__PURE__ */
|
|
2111
|
+
/* @__PURE__ */ jsx11("span", { className: "text-muted-foreground", children: /* @__PURE__ */ jsx11(MessageSquare, { size: 16 }) }),
|
|
2112
|
+
/* @__PURE__ */ jsx11("span", { className: "flex-1 truncate", children: thread.title }),
|
|
2113
|
+
showDelete && onDeleteThread && /* @__PURE__ */ jsx11(
|
|
1400
2114
|
"button",
|
|
1401
2115
|
{
|
|
1402
2116
|
type: "button",
|
|
@@ -1405,7 +2119,7 @@ function HistorySidebar({
|
|
|
1405
2119
|
onDeleteThread(thread.id);
|
|
1406
2120
|
},
|
|
1407
2121
|
className: "opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-destructive/10 hover:text-destructive transition-all",
|
|
1408
|
-
children: /* @__PURE__ */
|
|
2122
|
+
children: /* @__PURE__ */ jsx11(Trash2, { size: 14 })
|
|
1409
2123
|
}
|
|
1410
2124
|
)
|
|
1411
2125
|
]
|
|
@@ -1416,31 +2130,334 @@ function HistorySidebar({
|
|
|
1416
2130
|
] });
|
|
1417
2131
|
}
|
|
1418
2132
|
|
|
2133
|
+
// src/components/composer/pending-follow-ups.tsx
|
|
2134
|
+
import * as React10 from "react";
|
|
2135
|
+
import {
|
|
2136
|
+
CornerDownLeft,
|
|
2137
|
+
Ellipsis,
|
|
2138
|
+
Info,
|
|
2139
|
+
PencilLine,
|
|
2140
|
+
SlidersHorizontal as SlidersHorizontal2,
|
|
2141
|
+
Trash2 as Trash22
|
|
2142
|
+
} from "lucide-react";
|
|
2143
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2144
|
+
function getPendingFollowUpText(item, referencedContentFallback) {
|
|
2145
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
2146
|
+
if (text) {
|
|
2147
|
+
return text;
|
|
2148
|
+
}
|
|
2149
|
+
const references = normalizeReferences(item.request?.input?.references);
|
|
2150
|
+
if (references.length === 0) {
|
|
2151
|
+
return referencedContentFallback;
|
|
2152
|
+
}
|
|
2153
|
+
const firstReferenceLabel = getReferenceLabel(references[0]);
|
|
2154
|
+
if (references.length === 1) {
|
|
2155
|
+
return firstReferenceLabel;
|
|
2156
|
+
}
|
|
2157
|
+
return `${firstReferenceLabel} +${references.length - 1}`;
|
|
2158
|
+
}
|
|
2159
|
+
function useRoundedClasses() {
|
|
2160
|
+
const { theme } = useTheme();
|
|
2161
|
+
return {
|
|
2162
|
+
top: theme.radius ? {
|
|
2163
|
+
pill: "rounded-t-full",
|
|
2164
|
+
round: "rounded-t-xl",
|
|
2165
|
+
soft: "rounded-t-lg",
|
|
2166
|
+
sharp: "rounded-t-none"
|
|
2167
|
+
}[theme.radius] : "rounded-t-lg",
|
|
2168
|
+
panel: getRoundedClass(theme.radius, "rounded-lg"),
|
|
2169
|
+
control: getRoundedClass(theme.radius, "rounded-md")
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
function PendingFollowUps({
|
|
2173
|
+
items,
|
|
2174
|
+
isLoading,
|
|
2175
|
+
followUpBehavior,
|
|
2176
|
+
onBehaviorChange,
|
|
2177
|
+
onPromoteToSteer,
|
|
2178
|
+
canSendNow,
|
|
2179
|
+
onSendNow,
|
|
2180
|
+
onEdit,
|
|
2181
|
+
onRemove,
|
|
2182
|
+
className
|
|
2183
|
+
}) {
|
|
2184
|
+
const { t } = useChatkitTranslation();
|
|
2185
|
+
const rounded = useRoundedClasses();
|
|
2186
|
+
const referencedContentFallback = t("chat.referencedContentOnly");
|
|
2187
|
+
const [isSettingsOpen, setIsSettingsOpen] = React10.useState(false);
|
|
2188
|
+
const [openMenuId, setOpenMenuId] = React10.useState(null);
|
|
2189
|
+
React10.useEffect(() => {
|
|
2190
|
+
if (items.length === 0 && isSettingsOpen) {
|
|
2191
|
+
setIsSettingsOpen(false);
|
|
2192
|
+
}
|
|
2193
|
+
if (items.every((item) => item.id !== openMenuId)) {
|
|
2194
|
+
setOpenMenuId(null);
|
|
2195
|
+
}
|
|
2196
|
+
}, [isSettingsOpen, items, openMenuId]);
|
|
2197
|
+
if (items.length === 0) {
|
|
2198
|
+
return null;
|
|
2199
|
+
}
|
|
2200
|
+
return /* @__PURE__ */ jsx12(
|
|
2201
|
+
"div",
|
|
2202
|
+
{
|
|
2203
|
+
className: cn(
|
|
2204
|
+
"space-y-2 mx-2 p-2 border border-border border-b-0",
|
|
2205
|
+
rounded.top,
|
|
2206
|
+
className
|
|
2207
|
+
),
|
|
2208
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "space-y-1", children: [
|
|
2209
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2210
|
+
/* @__PURE__ */ jsx12("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.pending") }),
|
|
2211
|
+
/* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
2212
|
+
/* @__PURE__ */ jsx12(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs7(
|
|
2213
|
+
"button",
|
|
2214
|
+
{
|
|
2215
|
+
type: "button",
|
|
2216
|
+
onClick: () => setIsSettingsOpen((prev) => !prev),
|
|
2217
|
+
className: cn(
|
|
2218
|
+
"inline-flex h-6 w-6 items-center justify-center transition-colors",
|
|
2219
|
+
isSettingsOpen ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground",
|
|
2220
|
+
rounded.control
|
|
2221
|
+
),
|
|
2222
|
+
"aria-label": t("chat.followUps.settings"),
|
|
2223
|
+
"aria-expanded": isSettingsOpen,
|
|
2224
|
+
"aria-controls": "follow-ups-settings-panel",
|
|
2225
|
+
children: [
|
|
2226
|
+
/* @__PURE__ */ jsx12(SlidersHorizontal2, { className: "h-3.5 w-3.5" }),
|
|
2227
|
+
/* @__PURE__ */ jsx12("span", { className: "sr-only", children: t("chat.followUps.settings") })
|
|
2228
|
+
]
|
|
2229
|
+
}
|
|
2230
|
+
) }),
|
|
2231
|
+
/* @__PURE__ */ jsx12(TooltipContent, { side: "top", children: t("chat.followUps.settings") })
|
|
2232
|
+
] })
|
|
2233
|
+
] }),
|
|
2234
|
+
isSettingsOpen && /* @__PURE__ */ jsx12(
|
|
2235
|
+
"div",
|
|
2236
|
+
{
|
|
2237
|
+
id: "follow-ups-settings-panel",
|
|
2238
|
+
className: cn(
|
|
2239
|
+
"border border-border/70 bg-muted/20 px-3 py-2",
|
|
2240
|
+
rounded.panel
|
|
2241
|
+
),
|
|
2242
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2243
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
2244
|
+
/* @__PURE__ */ jsx12("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.label") }),
|
|
2245
|
+
/* @__PURE__ */ jsx12("div", { className: "text-[11px] text-muted-foreground", children: isLoading ? t("chat.followUps.activeHint") : t("chat.followUps.idleHint") })
|
|
2246
|
+
] }),
|
|
2247
|
+
/* @__PURE__ */ jsx12(
|
|
2248
|
+
"div",
|
|
2249
|
+
{
|
|
2250
|
+
className: cn(
|
|
2251
|
+
"inline-flex shrink-0 border border-border bg-background p-1",
|
|
2252
|
+
rounded.control
|
|
2253
|
+
),
|
|
2254
|
+
children: ["queue", "steer"].map((behavior) => /* @__PURE__ */ jsxs7(Tooltip, { children: [
|
|
2255
|
+
/* @__PURE__ */ jsx12(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2256
|
+
"button",
|
|
2257
|
+
{
|
|
2258
|
+
type: "button",
|
|
2259
|
+
onClick: () => {
|
|
2260
|
+
onBehaviorChange(behavior);
|
|
2261
|
+
setIsSettingsOpen(false);
|
|
2262
|
+
},
|
|
2263
|
+
className: cn(
|
|
2264
|
+
"px-3 py-1 text-xs font-medium transition-colors",
|
|
2265
|
+
rounded.control,
|
|
2266
|
+
followUpBehavior === behavior ? "bg-primary text-background" : "text-muted-foreground hover:text-foreground"
|
|
2267
|
+
),
|
|
2268
|
+
children: behavior === "queue" ? t("chat.followUps.queue") : t("chat.followUps.steer")
|
|
2269
|
+
}
|
|
2270
|
+
) }),
|
|
2271
|
+
/* @__PURE__ */ jsx12(TooltipContent, { side: "top", children: behavior === "queue" ? t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2272
|
+
] }, behavior))
|
|
2273
|
+
}
|
|
2274
|
+
)
|
|
2275
|
+
] })
|
|
2276
|
+
}
|
|
2277
|
+
),
|
|
2278
|
+
items.map((item) => {
|
|
2279
|
+
const canSendItemNow = item.mode === "queue" && canSendNow(item.id);
|
|
2280
|
+
return /* @__PURE__ */ jsx12(
|
|
2281
|
+
"div",
|
|
2282
|
+
{
|
|
2283
|
+
className: cn(
|
|
2284
|
+
"border border-border/50 bg-muted/15 px-2 py-1",
|
|
2285
|
+
rounded.panel
|
|
2286
|
+
),
|
|
2287
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2.5", children: [
|
|
2288
|
+
/* @__PURE__ */ jsx12(CornerDownLeft, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2289
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
2290
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2", children: [
|
|
2291
|
+
/* @__PURE__ */ jsx12("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx12(
|
|
2292
|
+
"div",
|
|
2293
|
+
{
|
|
2294
|
+
className: "truncate text-[13px] leading-5 text-foreground",
|
|
2295
|
+
title: getPendingFollowUpText(
|
|
2296
|
+
item,
|
|
2297
|
+
referencedContentFallback
|
|
2298
|
+
),
|
|
2299
|
+
children: getPendingFollowUpText(
|
|
2300
|
+
item,
|
|
2301
|
+
referencedContentFallback
|
|
2302
|
+
)
|
|
2303
|
+
}
|
|
2304
|
+
) }),
|
|
2305
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2306
|
+
item.mode === "queue" && isLoading && /* @__PURE__ */ jsx12(
|
|
2307
|
+
"button",
|
|
2308
|
+
{
|
|
2309
|
+
type: "button",
|
|
2310
|
+
onClick: () => void onPromoteToSteer(item.id),
|
|
2311
|
+
className: cn(
|
|
2312
|
+
"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",
|
|
2313
|
+
rounded.control
|
|
2314
|
+
),
|
|
2315
|
+
"aria-label": t("chat.followUps.steerAction"),
|
|
2316
|
+
title: t("chat.followUps.steerAction"),
|
|
2317
|
+
children: t("chat.followUps.steerAction")
|
|
2318
|
+
}
|
|
2319
|
+
),
|
|
2320
|
+
canSendItemNow && /* @__PURE__ */ jsx12(
|
|
2321
|
+
"button",
|
|
2322
|
+
{
|
|
2323
|
+
type: "button",
|
|
2324
|
+
onClick: () => void onSendNow(item.id),
|
|
2325
|
+
className: cn(
|
|
2326
|
+
"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",
|
|
2327
|
+
rounded.control
|
|
2328
|
+
),
|
|
2329
|
+
"aria-label": t("chat.followUps.sendNow"),
|
|
2330
|
+
title: t("chat.followUps.sendNow"),
|
|
2331
|
+
children: t("chat.followUps.sendNow")
|
|
2332
|
+
}
|
|
2333
|
+
),
|
|
2334
|
+
item.mode === "queue" && /* @__PURE__ */ jsx12(
|
|
2335
|
+
"button",
|
|
2336
|
+
{
|
|
2337
|
+
type: "button",
|
|
2338
|
+
onClick: () => onRemove(item.id),
|
|
2339
|
+
className: cn(
|
|
2340
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2341
|
+
rounded.control
|
|
2342
|
+
),
|
|
2343
|
+
"aria-label": t("chat.followUps.remove"),
|
|
2344
|
+
title: t("chat.followUps.remove"),
|
|
2345
|
+
children: /* @__PURE__ */ jsx12(Trash22, { size: 13 })
|
|
2346
|
+
}
|
|
2347
|
+
),
|
|
2348
|
+
item.mode === "queue" && /* @__PURE__ */ jsxs7(
|
|
2349
|
+
Popover,
|
|
2350
|
+
{
|
|
2351
|
+
open: openMenuId === item.id,
|
|
2352
|
+
onOpenChange: (open) => setOpenMenuId(open ? item.id : null),
|
|
2353
|
+
children: [
|
|
2354
|
+
/* @__PURE__ */ jsx12(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx12(
|
|
2355
|
+
"button",
|
|
2356
|
+
{
|
|
2357
|
+
type: "button",
|
|
2358
|
+
className: cn(
|
|
2359
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2360
|
+
rounded.control
|
|
2361
|
+
),
|
|
2362
|
+
"aria-label": t("chat.followUps.more"),
|
|
2363
|
+
title: t("chat.followUps.more"),
|
|
2364
|
+
children: /* @__PURE__ */ jsx12(Ellipsis, { size: 13 })
|
|
2365
|
+
}
|
|
2366
|
+
) }),
|
|
2367
|
+
/* @__PURE__ */ jsx12(
|
|
2368
|
+
PopoverContent,
|
|
2369
|
+
{
|
|
2370
|
+
align: "end",
|
|
2371
|
+
side: "bottom",
|
|
2372
|
+
className: cn(
|
|
2373
|
+
"w-52 border-border/70 bg-background p-1.5",
|
|
2374
|
+
rounded.panel
|
|
2375
|
+
),
|
|
2376
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1", children: [
|
|
2377
|
+
/* @__PURE__ */ jsxs7(
|
|
2378
|
+
"button",
|
|
2379
|
+
{
|
|
2380
|
+
type: "button",
|
|
2381
|
+
onClick: () => {
|
|
2382
|
+
setOpenMenuId(null);
|
|
2383
|
+
onEdit(item.id);
|
|
2384
|
+
},
|
|
2385
|
+
className: cn(
|
|
2386
|
+
"flex items-center gap-2 px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted",
|
|
2387
|
+
rounded.control
|
|
2388
|
+
),
|
|
2389
|
+
children: [
|
|
2390
|
+
/* @__PURE__ */ jsx12(PencilLine, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2391
|
+
/* @__PURE__ */ jsx12("span", { children: t("chat.followUps.edit") })
|
|
2392
|
+
]
|
|
2393
|
+
}
|
|
2394
|
+
),
|
|
2395
|
+
/* @__PURE__ */ jsxs7(
|
|
2396
|
+
"button",
|
|
2397
|
+
{
|
|
2398
|
+
type: "button",
|
|
2399
|
+
onClick: () => {
|
|
2400
|
+
setOpenMenuId(null);
|
|
2401
|
+
onBehaviorChange("steer");
|
|
2402
|
+
},
|
|
2403
|
+
className: cn(
|
|
2404
|
+
"flex items-center gap-2 px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted",
|
|
2405
|
+
rounded.control
|
|
2406
|
+
),
|
|
2407
|
+
children: [
|
|
2408
|
+
/* @__PURE__ */ jsx12(CornerDownLeft, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2409
|
+
/* @__PURE__ */ jsx12("span", { children: t("chat.followUps.turnOffQueueing") })
|
|
2410
|
+
]
|
|
2411
|
+
}
|
|
2412
|
+
)
|
|
2413
|
+
] })
|
|
2414
|
+
}
|
|
2415
|
+
)
|
|
2416
|
+
]
|
|
2417
|
+
}
|
|
2418
|
+
)
|
|
2419
|
+
] })
|
|
2420
|
+
] }),
|
|
2421
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5 text-[10px] leading-4 text-muted-foreground", children: [
|
|
2422
|
+
/* @__PURE__ */ jsx12(Info, { className: "h-3 w-3 shrink-0" }),
|
|
2423
|
+
/* @__PURE__ */ jsx12("span", { className: "truncate", children: item.mode === "queue" ? canSendItemNow ? t("chat.followUps.manualQueueHint") : t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2424
|
+
] })
|
|
2425
|
+
] })
|
|
2426
|
+
] })
|
|
2427
|
+
},
|
|
2428
|
+
item.id
|
|
2429
|
+
);
|
|
2430
|
+
})
|
|
2431
|
+
] })
|
|
2432
|
+
}
|
|
2433
|
+
);
|
|
2434
|
+
}
|
|
2435
|
+
|
|
1419
2436
|
// src/components/thread/messages/ai.tsx
|
|
1420
|
-
import * as
|
|
1421
|
-
import { ChevronDown, CheckCircle2, XCircle, Loader2 } from "lucide-react";
|
|
2437
|
+
import * as React15 from "react";
|
|
2438
|
+
import { ChevronDown, CheckCircle2, XCircle, Loader2 as Loader22 } from "lucide-react";
|
|
1422
2439
|
|
|
1423
2440
|
// src/components/ui/badge.tsx
|
|
1424
|
-
import * as
|
|
1425
|
-
import { jsx as
|
|
2441
|
+
import * as React11 from "react";
|
|
2442
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1426
2443
|
var base = "inline-flex items-center rounded-full border border-transparent px-2.5 py-0.5 text-xs font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background";
|
|
1427
2444
|
var variants = {
|
|
1428
2445
|
default: "bg-primary text-primary-foreground",
|
|
1429
2446
|
secondary: "bg-secondary text-secondary-foreground",
|
|
1430
2447
|
outline: "border-input text-foreground"
|
|
1431
2448
|
};
|
|
1432
|
-
var Badge =
|
|
2449
|
+
var Badge = React11.forwardRef(
|
|
1433
2450
|
({ className, variant = "default", ...props }, ref) => {
|
|
1434
|
-
return /* @__PURE__ */
|
|
2451
|
+
return /* @__PURE__ */ jsx13("span", { ref, className: cn(base, variants[variant], className), ...props });
|
|
1435
2452
|
}
|
|
1436
2453
|
);
|
|
1437
2454
|
Badge.displayName = "Badge";
|
|
1438
2455
|
|
|
1439
2456
|
// src/components/ui/card.tsx
|
|
1440
|
-
import * as
|
|
1441
|
-
import { jsx as
|
|
1442
|
-
var Card =
|
|
1443
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2457
|
+
import * as React12 from "react";
|
|
2458
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2459
|
+
var Card = React12.forwardRef(
|
|
2460
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14(
|
|
1444
2461
|
"div",
|
|
1445
2462
|
{
|
|
1446
2463
|
ref,
|
|
@@ -1453,50 +2470,50 @@ var Card = React10.forwardRef(
|
|
|
1453
2470
|
)
|
|
1454
2471
|
);
|
|
1455
2472
|
Card.displayName = "Card";
|
|
1456
|
-
var CardHeader =
|
|
1457
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2473
|
+
var CardHeader = React12.forwardRef(
|
|
2474
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
|
|
1458
2475
|
);
|
|
1459
2476
|
CardHeader.displayName = "CardHeader";
|
|
1460
|
-
var CardTitle =
|
|
2477
|
+
var CardTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
|
|
1461
2478
|
CardTitle.displayName = "CardTitle";
|
|
1462
|
-
var CardDescription =
|
|
2479
|
+
var CardDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx14("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1463
2480
|
CardDescription.displayName = "CardDescription";
|
|
1464
|
-
var CardContent =
|
|
1465
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2481
|
+
var CardContent = React12.forwardRef(
|
|
2482
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("px-6 pb-6", className), ...props })
|
|
1466
2483
|
);
|
|
1467
2484
|
CardContent.displayName = "CardContent";
|
|
1468
|
-
var CardFooter =
|
|
1469
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2485
|
+
var CardFooter = React12.forwardRef(
|
|
2486
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
|
|
1470
2487
|
);
|
|
1471
2488
|
CardFooter.displayName = "CardFooter";
|
|
1472
|
-
var CardAction =
|
|
1473
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2489
|
+
var CardAction = React12.forwardRef(
|
|
2490
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx14("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
|
|
1474
2491
|
);
|
|
1475
2492
|
CardAction.displayName = "CardAction";
|
|
1476
2493
|
|
|
1477
2494
|
// src/components/ui/tabs.tsx
|
|
1478
|
-
import * as
|
|
1479
|
-
import { jsx as
|
|
1480
|
-
var TabsContext =
|
|
2495
|
+
import * as React13 from "react";
|
|
2496
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
2497
|
+
var TabsContext = React13.createContext(null);
|
|
1481
2498
|
function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
|
|
1482
|
-
const [internalValue, setInternalValue] =
|
|
2499
|
+
const [internalValue, setInternalValue] = React13.useState(defaultValue ?? "");
|
|
1483
2500
|
const activeValue = value ?? internalValue;
|
|
1484
|
-
const setValue =
|
|
2501
|
+
const setValue = React13.useCallback(
|
|
1485
2502
|
(nextValue) => {
|
|
1486
2503
|
if (value === void 0) setInternalValue(nextValue);
|
|
1487
2504
|
onValueChange?.(nextValue);
|
|
1488
2505
|
},
|
|
1489
2506
|
[onValueChange, value]
|
|
1490
2507
|
);
|
|
1491
|
-
return /* @__PURE__ */
|
|
2508
|
+
return /* @__PURE__ */ jsx15(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ jsx15("div", { className: cn("w-full", className), ...props }) });
|
|
1492
2509
|
}
|
|
1493
|
-
var TabsList =
|
|
1494
|
-
({ className, ...props }, ref) => /* @__PURE__ */
|
|
2510
|
+
var TabsList = React13.forwardRef(
|
|
2511
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
1495
2512
|
"div",
|
|
1496
2513
|
{
|
|
1497
2514
|
ref,
|
|
1498
2515
|
className: cn(
|
|
1499
|
-
"inline-flex
|
|
2516
|
+
"inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
1500
2517
|
className
|
|
1501
2518
|
),
|
|
1502
2519
|
role: "tablist",
|
|
@@ -1505,14 +2522,14 @@ var TabsList = React11.forwardRef(
|
|
|
1505
2522
|
)
|
|
1506
2523
|
);
|
|
1507
2524
|
TabsList.displayName = "TabsList";
|
|
1508
|
-
var TabsTrigger =
|
|
2525
|
+
var TabsTrigger = React13.forwardRef(
|
|
1509
2526
|
({ className, value, onClick, ...props }, ref) => {
|
|
1510
|
-
const context =
|
|
2527
|
+
const context = React13.useContext(TabsContext);
|
|
1511
2528
|
if (!context) {
|
|
1512
2529
|
throw new Error("TabsTrigger must be used within Tabs");
|
|
1513
2530
|
}
|
|
1514
2531
|
const isActive = context.value === value;
|
|
1515
|
-
return /* @__PURE__ */
|
|
2532
|
+
return /* @__PURE__ */ jsx15(
|
|
1516
2533
|
"button",
|
|
1517
2534
|
{
|
|
1518
2535
|
ref,
|
|
@@ -1521,7 +2538,7 @@ var TabsTrigger = React11.forwardRef(
|
|
|
1521
2538
|
"aria-selected": isActive,
|
|
1522
2539
|
"data-state": isActive ? "active" : "inactive",
|
|
1523
2540
|
className: cn(
|
|
1524
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-
|
|
2541
|
+
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
1525
2542
|
className
|
|
1526
2543
|
),
|
|
1527
2544
|
onClick: (event) => {
|
|
@@ -1534,14 +2551,14 @@ var TabsTrigger = React11.forwardRef(
|
|
|
1534
2551
|
}
|
|
1535
2552
|
);
|
|
1536
2553
|
TabsTrigger.displayName = "TabsTrigger";
|
|
1537
|
-
var TabsContent =
|
|
2554
|
+
var TabsContent = React13.forwardRef(
|
|
1538
2555
|
({ className, value, ...props }, ref) => {
|
|
1539
|
-
const context =
|
|
2556
|
+
const context = React13.useContext(TabsContext);
|
|
1540
2557
|
if (!context) {
|
|
1541
2558
|
throw new Error("TabsContent must be used within Tabs");
|
|
1542
2559
|
}
|
|
1543
2560
|
if (context.value !== value) return null;
|
|
1544
|
-
return /* @__PURE__ */
|
|
2561
|
+
return /* @__PURE__ */ jsx15(
|
|
1545
2562
|
"div",
|
|
1546
2563
|
{
|
|
1547
2564
|
ref,
|
|
@@ -1564,10 +2581,11 @@ import rehypeKatex from "rehype-katex";
|
|
|
1564
2581
|
import remarkMath from "remark-math";
|
|
1565
2582
|
import {
|
|
1566
2583
|
Children,
|
|
2584
|
+
isValidElement,
|
|
1567
2585
|
memo,
|
|
1568
|
-
useState as
|
|
2586
|
+
useState as useState7
|
|
1569
2587
|
} from "react";
|
|
1570
|
-
import { CheckIcon, CopyIcon } from "lucide-react";
|
|
2588
|
+
import { CheckIcon as CheckIcon2, CopyIcon as CopyIcon2 } from "lucide-react";
|
|
1571
2589
|
|
|
1572
2590
|
// src/components/thread/syntax-highlighter.tsx
|
|
1573
2591
|
import { PrismAsyncLight as SyntaxHighlighterPrism } from "react-syntax-highlighter";
|
|
@@ -1575,7 +2593,7 @@ import tsx from "react-syntax-highlighter/dist/esm/languages/prism/tsx";
|
|
|
1575
2593
|
import python from "react-syntax-highlighter/dist/esm/languages/prism/python";
|
|
1576
2594
|
import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
|
|
1577
2595
|
import "react";
|
|
1578
|
-
import { jsx as
|
|
2596
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1579
2597
|
SyntaxHighlighterPrism.registerLanguage("js", tsx);
|
|
1580
2598
|
SyntaxHighlighterPrism.registerLanguage("jsx", tsx);
|
|
1581
2599
|
SyntaxHighlighterPrism.registerLanguage("ts", tsx);
|
|
@@ -1586,7 +2604,7 @@ var SyntaxHighlighter = ({
|
|
|
1586
2604
|
language,
|
|
1587
2605
|
className
|
|
1588
2606
|
}) => {
|
|
1589
|
-
return /* @__PURE__ */
|
|
2607
|
+
return /* @__PURE__ */ jsx16(
|
|
1590
2608
|
SyntaxHighlighterPrism,
|
|
1591
2609
|
{
|
|
1592
2610
|
language,
|
|
@@ -1603,77 +2621,27 @@ var SyntaxHighlighter = ({
|
|
|
1603
2621
|
);
|
|
1604
2622
|
};
|
|
1605
2623
|
|
|
1606
|
-
// src/components/thread/
|
|
1607
|
-
import
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
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
|
-
}
|
|
2624
|
+
// src/components/thread/mermaid-block.tsx
|
|
2625
|
+
import * as Dialog from "@radix-ui/react-dialog";
|
|
2626
|
+
import mermaid from "mermaid";
|
|
2627
|
+
import {
|
|
2628
|
+
CheckIcon,
|
|
2629
|
+
Code2Icon,
|
|
2630
|
+
CopyIcon,
|
|
2631
|
+
DownloadIcon,
|
|
2632
|
+
ExpandIcon,
|
|
2633
|
+
Loader2,
|
|
2634
|
+
TriangleAlert,
|
|
2635
|
+
X as X2
|
|
2636
|
+
} from "lucide-react";
|
|
2637
|
+
import * as React14 from "react";
|
|
1671
2638
|
|
|
1672
2639
|
// src/components/thread/tooltip-icon-button.tsx
|
|
1673
|
-
import {
|
|
2640
|
+
import { forwardRef as forwardRef5 } from "react";
|
|
2641
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1674
2642
|
var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
|
|
1675
|
-
return /* @__PURE__ */
|
|
1676
|
-
/* @__PURE__ */
|
|
2643
|
+
return /* @__PURE__ */ jsx17(TooltipProvider, { children: /* @__PURE__ */ jsxs8(Tooltip, { children: [
|
|
2644
|
+
/* @__PURE__ */ jsx17(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
|
|
1677
2645
|
Button,
|
|
1678
2646
|
{
|
|
1679
2647
|
variant: "ghost",
|
|
@@ -1683,28 +2651,519 @@ var TooltipIconButton = forwardRef5(({ children, tooltip, side = "bottom", class
|
|
|
1683
2651
|
ref,
|
|
1684
2652
|
children: [
|
|
1685
2653
|
children,
|
|
1686
|
-
/* @__PURE__ */
|
|
2654
|
+
/* @__PURE__ */ jsx17("span", { className: "sr-only", children: tooltip })
|
|
1687
2655
|
]
|
|
1688
2656
|
}
|
|
1689
2657
|
) }),
|
|
1690
|
-
/* @__PURE__ */
|
|
2658
|
+
/* @__PURE__ */ jsx17(TooltipContent, { side, children: tooltip })
|
|
1691
2659
|
] }) });
|
|
1692
2660
|
});
|
|
1693
2661
|
TooltipIconButton.displayName = "TooltipIconButton";
|
|
1694
2662
|
|
|
2663
|
+
// src/components/thread/mermaid-block.tsx
|
|
2664
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2665
|
+
var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
|
|
2666
|
+
var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
|
|
2667
|
+
var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
|
|
2668
|
+
var OKLCH_COLOR_PATTERN = /^oklch\((.+)\)$/i;
|
|
2669
|
+
var RGB_COLOR_PATTERN = /^rgba?\((.+)\)$/i;
|
|
2670
|
+
var MERMAID_SECURE_KEYS = [
|
|
2671
|
+
"fontFamily",
|
|
2672
|
+
"maxEdges",
|
|
2673
|
+
"maxTextSize",
|
|
2674
|
+
"securityLevel",
|
|
2675
|
+
"secure",
|
|
2676
|
+
"startOnLoad",
|
|
2677
|
+
"suppressErrorRendering",
|
|
2678
|
+
"theme",
|
|
2679
|
+
"themeVariables"
|
|
2680
|
+
];
|
|
2681
|
+
function clamp(value, min, max) {
|
|
2682
|
+
return Math.min(max, Math.max(min, value));
|
|
2683
|
+
}
|
|
2684
|
+
function normalizeMermaidCode(code) {
|
|
2685
|
+
return code.replace(MERMAID_FRONTMATTER_PATTERN, "").replace(MERMAID_DIRECTIVE_PATTERN, "").trim();
|
|
2686
|
+
}
|
|
2687
|
+
function parseAlpha(value) {
|
|
2688
|
+
if (!value) return 1;
|
|
2689
|
+
const normalized = value.trim();
|
|
2690
|
+
if (!normalized) return 1;
|
|
2691
|
+
if (normalized.endsWith("%")) {
|
|
2692
|
+
return clamp(Number.parseFloat(normalized) / 100, 0, 1);
|
|
2693
|
+
}
|
|
2694
|
+
return clamp(Number.parseFloat(normalized), 0, 1);
|
|
2695
|
+
}
|
|
2696
|
+
function parseHexColor(value) {
|
|
2697
|
+
const match = value.trim().match(HEX_COLOR_PATTERN);
|
|
2698
|
+
if (!match) return null;
|
|
2699
|
+
const hex = match[1];
|
|
2700
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
2701
|
+
const [r, g, b, a = "f"] = hex.split("");
|
|
2702
|
+
return {
|
|
2703
|
+
r: Number.parseInt(r + r, 16),
|
|
2704
|
+
g: Number.parseInt(g + g, 16),
|
|
2705
|
+
b: Number.parseInt(b + b, 16),
|
|
2706
|
+
a: Number.parseInt(a + a, 16) / 255
|
|
2707
|
+
};
|
|
2708
|
+
}
|
|
2709
|
+
if (hex.length === 6 || hex.length === 8) {
|
|
2710
|
+
const alphaHex = hex.length === 8 ? hex.slice(6, 8) : "ff";
|
|
2711
|
+
return {
|
|
2712
|
+
r: Number.parseInt(hex.slice(0, 2), 16),
|
|
2713
|
+
g: Number.parseInt(hex.slice(2, 4), 16),
|
|
2714
|
+
b: Number.parseInt(hex.slice(4, 6), 16),
|
|
2715
|
+
a: Number.parseInt(alphaHex, 16) / 255
|
|
2716
|
+
};
|
|
2717
|
+
}
|
|
2718
|
+
return null;
|
|
2719
|
+
}
|
|
2720
|
+
function parseRgbChannel(value) {
|
|
2721
|
+
const normalized = value.trim();
|
|
2722
|
+
if (normalized.endsWith("%")) {
|
|
2723
|
+
return clamp(Math.round(Number.parseFloat(normalized) / 100 * 255), 0, 255);
|
|
2724
|
+
}
|
|
2725
|
+
return clamp(Math.round(Number.parseFloat(normalized)), 0, 255);
|
|
2726
|
+
}
|
|
2727
|
+
function parseRgbColor(value) {
|
|
2728
|
+
const match = value.trim().match(RGB_COLOR_PATTERN);
|
|
2729
|
+
if (!match) return null;
|
|
2730
|
+
const parts = match[1].split(/[,\s/]+/).map((part) => part.trim()).filter(Boolean);
|
|
2731
|
+
if (parts.length < 3) return null;
|
|
2732
|
+
return {
|
|
2733
|
+
r: parseRgbChannel(parts[0]),
|
|
2734
|
+
g: parseRgbChannel(parts[1]),
|
|
2735
|
+
b: parseRgbChannel(parts[2]),
|
|
2736
|
+
a: parseAlpha(parts[3])
|
|
2737
|
+
};
|
|
2738
|
+
}
|
|
2739
|
+
function parseOklchLightness(value) {
|
|
2740
|
+
const normalized = value.trim();
|
|
2741
|
+
if (normalized.endsWith("%")) {
|
|
2742
|
+
return clamp(Number.parseFloat(normalized) / 100, 0, 1);
|
|
2743
|
+
}
|
|
2744
|
+
return clamp(Number.parseFloat(normalized), 0, 1);
|
|
2745
|
+
}
|
|
2746
|
+
function parseHue(value) {
|
|
2747
|
+
const normalized = value.trim().toLowerCase();
|
|
2748
|
+
const numeric = Number.parseFloat(normalized);
|
|
2749
|
+
if (Number.isNaN(numeric)) return 0;
|
|
2750
|
+
if (normalized.endsWith("turn")) return numeric * 360;
|
|
2751
|
+
if (normalized.endsWith("rad")) return numeric * (180 / Math.PI);
|
|
2752
|
+
if (normalized.endsWith("grad")) return numeric * 0.9;
|
|
2753
|
+
return numeric;
|
|
2754
|
+
}
|
|
2755
|
+
function linearToSrgb(linear) {
|
|
2756
|
+
if (linear <= 31308e-7) {
|
|
2757
|
+
return 12.92 * linear;
|
|
2758
|
+
}
|
|
2759
|
+
return 1.055 * Math.pow(linear, 1 / 2.4) - 0.055;
|
|
2760
|
+
}
|
|
2761
|
+
function parseOklchColor(value) {
|
|
2762
|
+
const match = value.trim().match(OKLCH_COLOR_PATTERN);
|
|
2763
|
+
if (!match) return null;
|
|
2764
|
+
const [base2, alphaSegment] = match[1].split("/");
|
|
2765
|
+
const parts = base2.trim().split(/\s+/).map((part) => part.trim()).filter(Boolean);
|
|
2766
|
+
if (parts.length < 3) return null;
|
|
2767
|
+
const lightness = parseOklchLightness(parts[0]);
|
|
2768
|
+
const chroma = Number.parseFloat(parts[1]);
|
|
2769
|
+
const hueRadians = parseHue(parts[2]) * Math.PI / 180;
|
|
2770
|
+
const alpha = parseAlpha(alphaSegment);
|
|
2771
|
+
const a = chroma * Math.cos(hueRadians);
|
|
2772
|
+
const b = chroma * Math.sin(hueRadians);
|
|
2773
|
+
const l_ = lightness + 0.3963377774 * a + 0.2158037573 * b;
|
|
2774
|
+
const m_ = lightness - 0.1055613458 * a - 0.0638541728 * b;
|
|
2775
|
+
const s_ = lightness - 0.0894841775 * a - 1.291485548 * b;
|
|
2776
|
+
const l = l_ * l_ * l_;
|
|
2777
|
+
const m = m_ * m_ * m_;
|
|
2778
|
+
const s = s_ * s_ * s_;
|
|
2779
|
+
const linearR = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
|
|
2780
|
+
const linearG = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
|
|
2781
|
+
const linearB = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
|
|
2782
|
+
return {
|
|
2783
|
+
r: clamp(Math.round(linearToSrgb(linearR) * 255), 0, 255),
|
|
2784
|
+
g: clamp(Math.round(linearToSrgb(linearG) * 255), 0, 255),
|
|
2785
|
+
b: clamp(Math.round(linearToSrgb(linearB) * 255), 0, 255),
|
|
2786
|
+
a: alpha
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
function parseCssColor(value) {
|
|
2790
|
+
const normalized = value.trim();
|
|
2791
|
+
if (!normalized) return null;
|
|
2792
|
+
return parseHexColor(normalized) ?? parseRgbColor(normalized) ?? parseOklchColor(normalized);
|
|
2793
|
+
}
|
|
2794
|
+
function compositeColor(foreground, background) {
|
|
2795
|
+
const alpha = foreground.a + background.a * (1 - foreground.a);
|
|
2796
|
+
if (alpha <= 0) {
|
|
2797
|
+
return { r: 0, g: 0, b: 0, a: 0 };
|
|
2798
|
+
}
|
|
2799
|
+
const r = (foreground.r * foreground.a + background.r * background.a * (1 - foreground.a)) / alpha;
|
|
2800
|
+
const g = (foreground.g * foreground.a + background.g * background.a * (1 - foreground.a)) / alpha;
|
|
2801
|
+
const b = (foreground.b * foreground.a + background.b * background.a * (1 - foreground.a)) / alpha;
|
|
2802
|
+
return {
|
|
2803
|
+
r: clamp(Math.round(r), 0, 255),
|
|
2804
|
+
g: clamp(Math.round(g), 0, 255),
|
|
2805
|
+
b: clamp(Math.round(b), 0, 255),
|
|
2806
|
+
a: clamp(alpha, 0, 1)
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
function toHexChannel(value) {
|
|
2810
|
+
return value.toString(16).padStart(2, "0");
|
|
2811
|
+
}
|
|
2812
|
+
function rgbaToHex(value) {
|
|
2813
|
+
return `#${toHexChannel(value.r)}${toHexChannel(value.g)}${toHexChannel(value.b)}`;
|
|
2814
|
+
}
|
|
2815
|
+
function getFallbackPalette(isDarkMode) {
|
|
2816
|
+
if (isDarkMode) {
|
|
2817
|
+
return {
|
|
2818
|
+
background: "#171717",
|
|
2819
|
+
border: "#52525b",
|
|
2820
|
+
fontFamily: "Inter Variable, sans-serif",
|
|
2821
|
+
line: "#a1a1aa",
|
|
2822
|
+
surface: "#262626",
|
|
2823
|
+
surfaceAlt: "#3f3f46",
|
|
2824
|
+
text: "#fafafa"
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
return {
|
|
2828
|
+
background: "#ffffff",
|
|
2829
|
+
border: "#e4e4e7",
|
|
2830
|
+
fontFamily: "Inter Variable, sans-serif",
|
|
2831
|
+
line: "#71717a",
|
|
2832
|
+
surface: "#ffffff",
|
|
2833
|
+
surfaceAlt: "#f4f4f5",
|
|
2834
|
+
text: "#18181b"
|
|
2835
|
+
};
|
|
2836
|
+
}
|
|
2837
|
+
function resolveColor(styles, property, fallback, background) {
|
|
2838
|
+
const parsed = parseCssColor(styles.getPropertyValue(property));
|
|
2839
|
+
if (!parsed) return fallback;
|
|
2840
|
+
if (parsed.a < 1 && background) {
|
|
2841
|
+
return rgbaToHex(compositeColor(parsed, background));
|
|
2842
|
+
}
|
|
2843
|
+
return rgbaToHex(parsed);
|
|
2844
|
+
}
|
|
2845
|
+
function resolvePalette(element, isDarkMode) {
|
|
2846
|
+
const fallback = getFallbackPalette(isDarkMode);
|
|
2847
|
+
const styles = window.getComputedStyle(element);
|
|
2848
|
+
const backgroundColor = parseCssColor(styles.getPropertyValue("--card")) ?? parseCssColor(styles.getPropertyValue("--background")) ?? parseCssColor(fallback.surface);
|
|
2849
|
+
return {
|
|
2850
|
+
background: resolveColor(styles, "--background", fallback.background, backgroundColor),
|
|
2851
|
+
border: resolveColor(styles, "--border", fallback.border, backgroundColor),
|
|
2852
|
+
fontFamily: styles.getPropertyValue("font-family").trim() || fallback.fontFamily,
|
|
2853
|
+
line: resolveColor(styles, "--muted-foreground", fallback.line, backgroundColor),
|
|
2854
|
+
surface: resolveColor(styles, "--card", fallback.surface, backgroundColor),
|
|
2855
|
+
surfaceAlt: resolveColor(styles, "--muted", fallback.surfaceAlt, backgroundColor),
|
|
2856
|
+
text: resolveColor(styles, "--foreground", fallback.text, backgroundColor)
|
|
2857
|
+
};
|
|
2858
|
+
}
|
|
2859
|
+
function buildThemeVariables(palette) {
|
|
2860
|
+
return {
|
|
2861
|
+
background: palette.background,
|
|
2862
|
+
clusterBkg: palette.surfaceAlt,
|
|
2863
|
+
clusterBorder: palette.border,
|
|
2864
|
+
edgeLabelBackground: palette.surface,
|
|
2865
|
+
fontFamily: palette.fontFamily,
|
|
2866
|
+
lineColor: palette.line,
|
|
2867
|
+
mainBkg: palette.surface,
|
|
2868
|
+
nodeBorder: palette.border,
|
|
2869
|
+
nodeTextColor: palette.text,
|
|
2870
|
+
primaryBorderColor: palette.border,
|
|
2871
|
+
primaryColor: palette.surfaceAlt,
|
|
2872
|
+
primaryTextColor: palette.text,
|
|
2873
|
+
secondaryBorderColor: palette.border,
|
|
2874
|
+
secondaryColor: palette.surface,
|
|
2875
|
+
secondaryTextColor: palette.text,
|
|
2876
|
+
tertiaryBorderColor: palette.border,
|
|
2877
|
+
tertiaryColor: palette.surface,
|
|
2878
|
+
tertiaryTextColor: palette.text,
|
|
2879
|
+
textColor: palette.text
|
|
2880
|
+
};
|
|
2881
|
+
}
|
|
2882
|
+
async function renderMermaidDiagram({
|
|
2883
|
+
code,
|
|
2884
|
+
host,
|
|
2885
|
+
id,
|
|
2886
|
+
palette
|
|
2887
|
+
}) {
|
|
2888
|
+
host.innerHTML = "";
|
|
2889
|
+
mermaid.initialize({
|
|
2890
|
+
flowchart: {
|
|
2891
|
+
htmlLabels: false,
|
|
2892
|
+
useMaxWidth: true
|
|
2893
|
+
},
|
|
2894
|
+
fontFamily: palette.fontFamily,
|
|
2895
|
+
secure: [...MERMAID_SECURE_KEYS],
|
|
2896
|
+
securityLevel: "strict",
|
|
2897
|
+
startOnLoad: false,
|
|
2898
|
+
theme: "base",
|
|
2899
|
+
themeVariables: buildThemeVariables(palette)
|
|
2900
|
+
});
|
|
2901
|
+
const { svg } = await mermaid.render(id, code, host);
|
|
2902
|
+
host.innerHTML = "";
|
|
2903
|
+
return svg;
|
|
2904
|
+
}
|
|
2905
|
+
function MermaidPreviewDialog({
|
|
2906
|
+
closeLabel,
|
|
2907
|
+
onOpenChange,
|
|
2908
|
+
open,
|
|
2909
|
+
svgMarkup,
|
|
2910
|
+
title
|
|
2911
|
+
}) {
|
|
2912
|
+
return /* @__PURE__ */ jsx18(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ jsxs9(Dialog.Portal, { children: [
|
|
2913
|
+
/* @__PURE__ */ jsx18(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
|
|
2914
|
+
/* @__PURE__ */ jsxs9(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
|
|
2915
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
|
|
2916
|
+
/* @__PURE__ */ jsx18(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
|
|
2917
|
+
/* @__PURE__ */ jsx18(Dialog.Close, { asChild: true, children: /* @__PURE__ */ jsxs9(
|
|
2918
|
+
"button",
|
|
2919
|
+
{
|
|
2920
|
+
type: "button",
|
|
2921
|
+
className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
|
|
2922
|
+
children: [
|
|
2923
|
+
/* @__PURE__ */ jsx18(X2, { className: "size-4" }),
|
|
2924
|
+
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: closeLabel })
|
|
2925
|
+
]
|
|
2926
|
+
}
|
|
2927
|
+
) })
|
|
2928
|
+
] }),
|
|
2929
|
+
/* @__PURE__ */ jsx18("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ jsx18(
|
|
2930
|
+
"div",
|
|
2931
|
+
{
|
|
2932
|
+
"data-slot": "mermaid-preview",
|
|
2933
|
+
className: "min-h-full rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-6 [&_svg]:mx-auto [&_svg]:h-auto [&_svg]:max-w-none",
|
|
2934
|
+
dangerouslySetInnerHTML: { __html: svgMarkup }
|
|
2935
|
+
}
|
|
2936
|
+
) })
|
|
2937
|
+
] })
|
|
2938
|
+
] }) });
|
|
2939
|
+
}
|
|
2940
|
+
function MermaidBlock({ code }) {
|
|
2941
|
+
const { t } = useChatkitTranslation();
|
|
2942
|
+
const { theme, isDarkMode } = useTheme();
|
|
2943
|
+
const containerRef = React14.useRef(null);
|
|
2944
|
+
const renderHostRef = React14.useRef(null);
|
|
2945
|
+
const renderSequenceRef = React14.useRef(0);
|
|
2946
|
+
const copyResetTimeoutRef = React14.useRef(null);
|
|
2947
|
+
const diagramId = React14.useId().replace(/:/g, "");
|
|
2948
|
+
const [activeTab, setActiveTab] = React14.useState("diagram");
|
|
2949
|
+
const [isCopied, setIsCopied] = React14.useState(false);
|
|
2950
|
+
const [isPreviewOpen, setIsPreviewOpen] = React14.useState(false);
|
|
2951
|
+
const [isRendering, setIsRendering] = React14.useState(true);
|
|
2952
|
+
const [renderError, setRenderError] = React14.useState(null);
|
|
2953
|
+
const [svgMarkup, setSvgMarkup] = React14.useState(null);
|
|
2954
|
+
const normalizedCode = React14.useMemo(() => normalizeMermaidCode(code), [code]);
|
|
2955
|
+
const clearCopyResetTimeout = React14.useCallback(() => {
|
|
2956
|
+
if (copyResetTimeoutRef.current === null) return;
|
|
2957
|
+
window.clearTimeout(copyResetTimeoutRef.current);
|
|
2958
|
+
copyResetTimeoutRef.current = null;
|
|
2959
|
+
}, []);
|
|
2960
|
+
React14.useEffect(() => {
|
|
2961
|
+
let isActive = true;
|
|
2962
|
+
async function runRender() {
|
|
2963
|
+
const container = containerRef.current;
|
|
2964
|
+
const renderHost = renderHostRef.current;
|
|
2965
|
+
if (!container || !renderHost) return;
|
|
2966
|
+
setIsRendering(true);
|
|
2967
|
+
setRenderError(null);
|
|
2968
|
+
try {
|
|
2969
|
+
renderSequenceRef.current += 1;
|
|
2970
|
+
const svg = await renderMermaidDiagram({
|
|
2971
|
+
code: normalizedCode,
|
|
2972
|
+
host: renderHost,
|
|
2973
|
+
id: `mermaid-${diagramId}-${renderSequenceRef.current}`,
|
|
2974
|
+
palette: resolvePalette(container, isDarkMode)
|
|
2975
|
+
});
|
|
2976
|
+
if (!isActive) return;
|
|
2977
|
+
setSvgMarkup(svg);
|
|
2978
|
+
} catch (error) {
|
|
2979
|
+
if (!isActive) return;
|
|
2980
|
+
setSvgMarkup(null);
|
|
2981
|
+
setRenderError(error instanceof Error ? error.message : "render_failed");
|
|
2982
|
+
setActiveTab((currentTab) => currentTab === "diagram" ? "code" : currentTab);
|
|
2983
|
+
} finally {
|
|
2984
|
+
if (isActive) {
|
|
2985
|
+
setIsRendering(false);
|
|
2986
|
+
renderHost.innerHTML = "";
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
void runRender();
|
|
2991
|
+
return () => {
|
|
2992
|
+
isActive = false;
|
|
2993
|
+
if (renderHostRef.current) {
|
|
2994
|
+
renderHostRef.current.innerHTML = "";
|
|
2995
|
+
}
|
|
2996
|
+
};
|
|
2997
|
+
}, [diagramId, isDarkMode, normalizedCode, theme]);
|
|
2998
|
+
React14.useEffect(() => {
|
|
2999
|
+
clearCopyResetTimeout();
|
|
3000
|
+
setIsCopied(false);
|
|
3001
|
+
}, [activeTab, clearCopyResetTimeout, code]);
|
|
3002
|
+
React14.useEffect(
|
|
3003
|
+
() => () => {
|
|
3004
|
+
clearCopyResetTimeout();
|
|
3005
|
+
},
|
|
3006
|
+
[clearCopyResetTimeout]
|
|
3007
|
+
);
|
|
3008
|
+
const handleDownload = React14.useCallback(() => {
|
|
3009
|
+
if (!svgMarkup) return;
|
|
3010
|
+
const blob = new Blob([svgMarkup], {
|
|
3011
|
+
type: "image/svg+xml;charset=utf-8"
|
|
3012
|
+
});
|
|
3013
|
+
const url = window.URL.createObjectURL(blob);
|
|
3014
|
+
const anchor = document.createElement("a");
|
|
3015
|
+
anchor.href = url;
|
|
3016
|
+
anchor.download = `mermaid-diagram-${diagramId}.svg`;
|
|
3017
|
+
document.body.append(anchor);
|
|
3018
|
+
anchor.click();
|
|
3019
|
+
anchor.remove();
|
|
3020
|
+
window.URL.revokeObjectURL(url);
|
|
3021
|
+
}, [diagramId, svgMarkup]);
|
|
3022
|
+
const handleCopyCode = React14.useCallback(() => {
|
|
3023
|
+
if (!code || isCopied) return;
|
|
3024
|
+
navigator.clipboard.writeText(code).then(() => {
|
|
3025
|
+
setIsCopied(true);
|
|
3026
|
+
clearCopyResetTimeout();
|
|
3027
|
+
copyResetTimeoutRef.current = window.setTimeout(() => {
|
|
3028
|
+
setIsCopied(false);
|
|
3029
|
+
copyResetTimeoutRef.current = null;
|
|
3030
|
+
}, 3e3);
|
|
3031
|
+
}).catch(() => {
|
|
3032
|
+
});
|
|
3033
|
+
}, [clearCopyResetTimeout, code, isCopied]);
|
|
3034
|
+
const hasRenderedDiagram = svgMarkup !== null && !renderError;
|
|
3035
|
+
const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
|
|
3036
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
3037
|
+
/* @__PURE__ */ jsx18(
|
|
3038
|
+
Tabs,
|
|
3039
|
+
{
|
|
3040
|
+
className: "w-full",
|
|
3041
|
+
onValueChange: (value) => setActiveTab(value),
|
|
3042
|
+
value: activeTab,
|
|
3043
|
+
children: /* @__PURE__ */ jsxs9(
|
|
3044
|
+
"div",
|
|
3045
|
+
{
|
|
3046
|
+
ref: containerRef,
|
|
3047
|
+
"data-slot": "mermaid-block",
|
|
3048
|
+
className: "relative overflow-hidden text-card-foreground",
|
|
3049
|
+
children: [
|
|
3050
|
+
/* @__PURE__ */ jsx18(
|
|
3051
|
+
"div",
|
|
3052
|
+
{
|
|
3053
|
+
ref: renderHostRef,
|
|
3054
|
+
"aria-hidden": "true",
|
|
3055
|
+
className: "pointer-events-none absolute inset-0 -z-10 overflow-hidden opacity-0",
|
|
3056
|
+
"data-slot": "mermaid-render-host"
|
|
3057
|
+
}
|
|
3058
|
+
),
|
|
3059
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
|
|
3060
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
3061
|
+
/* @__PURE__ */ jsx18("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ jsx18(Code2Icon, { className: "size-4" }) }),
|
|
3062
|
+
/* @__PURE__ */ jsx18("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
|
|
3063
|
+
] }),
|
|
3064
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
3065
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1", children: [
|
|
3066
|
+
activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx18(
|
|
3067
|
+
TooltipIconButton,
|
|
3068
|
+
{
|
|
3069
|
+
onClick: handleDownload,
|
|
3070
|
+
tooltip: t("markdown.mermaid.download"),
|
|
3071
|
+
children: /* @__PURE__ */ jsx18(DownloadIcon, { className: "size-4" })
|
|
3072
|
+
}
|
|
3073
|
+
) : null,
|
|
3074
|
+
activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ jsx18(
|
|
3075
|
+
TooltipIconButton,
|
|
3076
|
+
{
|
|
3077
|
+
onClick: () => setIsPreviewOpen(true),
|
|
3078
|
+
tooltip: t("markdown.mermaid.fullScreen"),
|
|
3079
|
+
children: /* @__PURE__ */ jsx18(ExpandIcon, { className: "size-4" })
|
|
3080
|
+
}
|
|
3081
|
+
) : null,
|
|
3082
|
+
activeTab === "code" ? /* @__PURE__ */ jsx18(
|
|
3083
|
+
TooltipIconButton,
|
|
3084
|
+
{
|
|
3085
|
+
onClick: handleCopyCode,
|
|
3086
|
+
tooltip: t("markdown.copy"),
|
|
3087
|
+
children: isCopied ? /* @__PURE__ */ jsx18(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx18(CopyIcon, { className: "size-4" })
|
|
3088
|
+
}
|
|
3089
|
+
) : null
|
|
3090
|
+
] }),
|
|
3091
|
+
/* @__PURE__ */ jsxs9(TabsList, { children: [
|
|
3092
|
+
/* @__PURE__ */ jsx18(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
|
|
3093
|
+
/* @__PURE__ */ jsx18(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
|
|
3094
|
+
] })
|
|
3095
|
+
] })
|
|
3096
|
+
] }),
|
|
3097
|
+
/* @__PURE__ */ jsxs9("div", { className: "border-t border-border pt-4", children: [
|
|
3098
|
+
renderError ? /* @__PURE__ */ jsx18("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
|
|
3099
|
+
/* @__PURE__ */ jsx18(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ jsx18(
|
|
3100
|
+
"div",
|
|
3101
|
+
{
|
|
3102
|
+
className: cn(
|
|
3103
|
+
"relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
|
|
3104
|
+
hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
|
|
3105
|
+
),
|
|
3106
|
+
children: hasRenderedDiagram ? /* @__PURE__ */ jsx18(
|
|
3107
|
+
"div",
|
|
3108
|
+
{
|
|
3109
|
+
"data-slot": "mermaid-diagram",
|
|
3110
|
+
dangerouslySetInnerHTML: { __html: svgMarkup }
|
|
3111
|
+
}
|
|
3112
|
+
) : /* @__PURE__ */ jsxs9("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
|
|
3113
|
+
isRendering ? /* @__PURE__ */ jsx18(Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ jsx18(TriangleAlert, { className: "size-5 text-destructive" }),
|
|
3114
|
+
/* @__PURE__ */ jsx18(
|
|
3115
|
+
"p",
|
|
3116
|
+
{
|
|
3117
|
+
className: cn("text-sm font-medium", !isRendering && "text-destructive"),
|
|
3118
|
+
role: renderError ? "alert" : void 0,
|
|
3119
|
+
children: statusMessage
|
|
3120
|
+
}
|
|
3121
|
+
)
|
|
3122
|
+
] })
|
|
3123
|
+
}
|
|
3124
|
+
) }),
|
|
3125
|
+
/* @__PURE__ */ jsx18(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ jsx18(
|
|
3126
|
+
"pre",
|
|
3127
|
+
{
|
|
3128
|
+
"data-slot": "mermaid-code",
|
|
3129
|
+
className: "overflow-x-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-zinc-950 px-4 py-4 text-sm text-zinc-50",
|
|
3130
|
+
children: /* @__PURE__ */ jsx18("code", { className: "block whitespace-pre font-mono", children: code })
|
|
3131
|
+
}
|
|
3132
|
+
) })
|
|
3133
|
+
] })
|
|
3134
|
+
]
|
|
3135
|
+
}
|
|
3136
|
+
)
|
|
3137
|
+
}
|
|
3138
|
+
),
|
|
3139
|
+
svgMarkup ? /* @__PURE__ */ jsx18(
|
|
3140
|
+
MermaidPreviewDialog,
|
|
3141
|
+
{
|
|
3142
|
+
closeLabel: t("sheet.close"),
|
|
3143
|
+
onOpenChange: setIsPreviewOpen,
|
|
3144
|
+
open: isPreviewOpen,
|
|
3145
|
+
svgMarkup,
|
|
3146
|
+
title: t("markdown.mermaid.title")
|
|
3147
|
+
}
|
|
3148
|
+
) : null
|
|
3149
|
+
] });
|
|
3150
|
+
}
|
|
3151
|
+
|
|
1695
3152
|
// src/components/thread/markdown-text.tsx
|
|
1696
3153
|
import "katex/dist/katex.min.css";
|
|
1697
|
-
import { Fragment as
|
|
3154
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1698
3155
|
var getTextContent = (children) => Children.toArray(children).map((child) => {
|
|
1699
3156
|
if (typeof child === "string" || typeof child === "number") {
|
|
1700
3157
|
return String(child);
|
|
1701
3158
|
}
|
|
1702
3159
|
return "";
|
|
1703
3160
|
}).join("");
|
|
3161
|
+
var isMermaidBlockChild = (child) => isValidElement(child) && child.type === MermaidBlock;
|
|
3162
|
+
var isMermaidCodeElement = (child) => isValidElement(child) && typeof child.props.className === "string" && child.props.className.includes("language-mermaid");
|
|
1704
3163
|
var useCopyToClipboard = ({
|
|
1705
3164
|
copiedDuration = 3e3
|
|
1706
3165
|
} = {}) => {
|
|
1707
|
-
const [isCopied, setIsCopied] =
|
|
3166
|
+
const [isCopied, setIsCopied] = useState7(false);
|
|
1708
3167
|
const copyToClipboard = (value) => {
|
|
1709
3168
|
if (!value) return;
|
|
1710
3169
|
navigator.clipboard.writeText(value).then(() => {
|
|
@@ -1721,23 +3180,23 @@ var CodeHeader = ({ language, code }) => {
|
|
|
1721
3180
|
if (!code || isCopied) return;
|
|
1722
3181
|
copyToClipboard(code);
|
|
1723
3182
|
};
|
|
1724
|
-
return /* @__PURE__ */
|
|
1725
|
-
/* @__PURE__ */
|
|
1726
|
-
/* @__PURE__ */
|
|
3183
|
+
return /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
|
|
3184
|
+
/* @__PURE__ */ jsx19("span", { className: "lowercase [&>span]:text-xs", children: language }),
|
|
3185
|
+
/* @__PURE__ */ jsxs10(
|
|
1727
3186
|
TooltipIconButton,
|
|
1728
3187
|
{
|
|
1729
3188
|
tooltip: t("markdown.copy"),
|
|
1730
3189
|
onClick: onCopy,
|
|
1731
3190
|
children: [
|
|
1732
|
-
!isCopied && /* @__PURE__ */
|
|
1733
|
-
isCopied && /* @__PURE__ */
|
|
3191
|
+
!isCopied && /* @__PURE__ */ jsx19(CopyIcon2, {}),
|
|
3192
|
+
isCopied && /* @__PURE__ */ jsx19(CheckIcon2, {})
|
|
1734
3193
|
]
|
|
1735
3194
|
}
|
|
1736
3195
|
)
|
|
1737
3196
|
] });
|
|
1738
3197
|
};
|
|
1739
3198
|
var defaultComponents = {
|
|
1740
|
-
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3199
|
+
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1741
3200
|
"h1",
|
|
1742
3201
|
{
|
|
1743
3202
|
className: cn(
|
|
@@ -1747,7 +3206,7 @@ var defaultComponents = {
|
|
|
1747
3206
|
...props
|
|
1748
3207
|
}
|
|
1749
3208
|
),
|
|
1750
|
-
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3209
|
+
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1751
3210
|
"h2",
|
|
1752
3211
|
{
|
|
1753
3212
|
className: cn(
|
|
@@ -1757,7 +3216,7 @@ var defaultComponents = {
|
|
|
1757
3216
|
...props
|
|
1758
3217
|
}
|
|
1759
3218
|
),
|
|
1760
|
-
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3219
|
+
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1761
3220
|
"h3",
|
|
1762
3221
|
{
|
|
1763
3222
|
className: cn(
|
|
@@ -1767,7 +3226,7 @@ var defaultComponents = {
|
|
|
1767
3226
|
...props
|
|
1768
3227
|
}
|
|
1769
3228
|
),
|
|
1770
|
-
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3229
|
+
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1771
3230
|
"h4",
|
|
1772
3231
|
{
|
|
1773
3232
|
className: cn(
|
|
@@ -1777,7 +3236,7 @@ var defaultComponents = {
|
|
|
1777
3236
|
...props
|
|
1778
3237
|
}
|
|
1779
3238
|
),
|
|
1780
|
-
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3239
|
+
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1781
3240
|
"h5",
|
|
1782
3241
|
{
|
|
1783
3242
|
className: cn(
|
|
@@ -1787,21 +3246,21 @@ var defaultComponents = {
|
|
|
1787
3246
|
...props
|
|
1788
3247
|
}
|
|
1789
3248
|
),
|
|
1790
|
-
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3249
|
+
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1791
3250
|
"h6",
|
|
1792
3251
|
{
|
|
1793
3252
|
className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
|
|
1794
3253
|
...props
|
|
1795
3254
|
}
|
|
1796
3255
|
),
|
|
1797
|
-
p: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3256
|
+
p: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1798
3257
|
"p",
|
|
1799
3258
|
{
|
|
1800
3259
|
className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
|
|
1801
3260
|
...props
|
|
1802
3261
|
}
|
|
1803
3262
|
),
|
|
1804
|
-
a: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3263
|
+
a: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1805
3264
|
"a",
|
|
1806
3265
|
{
|
|
1807
3266
|
className: cn(
|
|
@@ -1817,7 +3276,7 @@ var defaultComponents = {
|
|
|
1817
3276
|
className,
|
|
1818
3277
|
node: _node,
|
|
1819
3278
|
...props
|
|
1820
|
-
}) => /* @__PURE__ */
|
|
3279
|
+
}) => /* @__PURE__ */ jsx19(
|
|
1821
3280
|
"blockquote",
|
|
1822
3281
|
{
|
|
1823
3282
|
className: cn(
|
|
@@ -1827,21 +3286,21 @@ var defaultComponents = {
|
|
|
1827
3286
|
...props
|
|
1828
3287
|
}
|
|
1829
3288
|
),
|
|
1830
|
-
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3289
|
+
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1831
3290
|
"ul",
|
|
1832
3291
|
{
|
|
1833
3292
|
className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
|
|
1834
3293
|
...props
|
|
1835
3294
|
}
|
|
1836
3295
|
),
|
|
1837
|
-
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3296
|
+
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1838
3297
|
"ol",
|
|
1839
3298
|
{
|
|
1840
3299
|
className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
|
|
1841
3300
|
...props
|
|
1842
3301
|
}
|
|
1843
3302
|
),
|
|
1844
|
-
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3303
|
+
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1845
3304
|
"hr",
|
|
1846
3305
|
{
|
|
1847
3306
|
className: cn("my-5 border-b", className),
|
|
@@ -1852,7 +3311,7 @@ var defaultComponents = {
|
|
|
1852
3311
|
className,
|
|
1853
3312
|
node: _node,
|
|
1854
3313
|
...props
|
|
1855
|
-
}) => /* @__PURE__ */
|
|
3314
|
+
}) => /* @__PURE__ */ jsx19(
|
|
1856
3315
|
"table",
|
|
1857
3316
|
{
|
|
1858
3317
|
className: cn(
|
|
@@ -1862,7 +3321,7 @@ var defaultComponents = {
|
|
|
1862
3321
|
...props
|
|
1863
3322
|
}
|
|
1864
3323
|
),
|
|
1865
|
-
th: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3324
|
+
th: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1866
3325
|
"th",
|
|
1867
3326
|
{
|
|
1868
3327
|
className: cn(
|
|
@@ -1872,7 +3331,7 @@ var defaultComponents = {
|
|
|
1872
3331
|
...props
|
|
1873
3332
|
}
|
|
1874
3333
|
),
|
|
1875
|
-
td: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3334
|
+
td: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1876
3335
|
"td",
|
|
1877
3336
|
{
|
|
1878
3337
|
className: cn(
|
|
@@ -1882,7 +3341,7 @@ var defaultComponents = {
|
|
|
1882
3341
|
...props
|
|
1883
3342
|
}
|
|
1884
3343
|
),
|
|
1885
|
-
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3344
|
+
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1886
3345
|
"tr",
|
|
1887
3346
|
{
|
|
1888
3347
|
className: cn(
|
|
@@ -1892,21 +3351,21 @@ var defaultComponents = {
|
|
|
1892
3351
|
...props
|
|
1893
3352
|
}
|
|
1894
3353
|
),
|
|
1895
|
-
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */
|
|
3354
|
+
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ jsx19(
|
|
1896
3355
|
"sup",
|
|
1897
3356
|
{
|
|
1898
3357
|
className: cn("[&>a]:text-xs [&>a]:no-underline", className),
|
|
1899
3358
|
...props
|
|
1900
3359
|
}
|
|
1901
3360
|
),
|
|
1902
|
-
pre: ({ className, node: _node,
|
|
3361
|
+
pre: ({ className, children, node: _node }) => Children.toArray(children).length === 1 && (isMermaidBlockChild(Children.toArray(children)[0]) || isMermaidCodeElement(Children.toArray(children)[0])) ? /* @__PURE__ */ jsx19(Fragment3, { children }) : /* @__PURE__ */ jsx19(
|
|
1903
3362
|
"div",
|
|
1904
3363
|
{
|
|
1905
3364
|
className: cn(
|
|
1906
3365
|
"max-w-4xl overflow-x-auto rounded-lg text-sm bg-black text-white dark:bg-zinc-800",
|
|
1907
3366
|
className
|
|
1908
3367
|
),
|
|
1909
|
-
|
|
3368
|
+
children
|
|
1910
3369
|
}
|
|
1911
3370
|
),
|
|
1912
3371
|
code: ({
|
|
@@ -1915,21 +3374,24 @@ var defaultComponents = {
|
|
|
1915
3374
|
node: _node,
|
|
1916
3375
|
...props
|
|
1917
3376
|
}) => {
|
|
1918
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
3377
|
+
const match = /language-([\w-]+)/.exec(className || "");
|
|
1919
3378
|
const code = getTextContent(children);
|
|
1920
3379
|
const isBlockCode = code.includes("\n");
|
|
1921
3380
|
if (match) {
|
|
1922
3381
|
const language = match[1];
|
|
1923
3382
|
const normalizedCode = code.replace(/\n$/, "");
|
|
1924
|
-
|
|
1925
|
-
/* @__PURE__ */
|
|
3383
|
+
if (language === "mermaid") {
|
|
3384
|
+
return /* @__PURE__ */ jsx19(MermaidBlock, { code: normalizedCode });
|
|
3385
|
+
}
|
|
3386
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
3387
|
+
/* @__PURE__ */ jsx19(
|
|
1926
3388
|
CodeHeader,
|
|
1927
3389
|
{
|
|
1928
3390
|
language,
|
|
1929
3391
|
code: normalizedCode
|
|
1930
3392
|
}
|
|
1931
3393
|
),
|
|
1932
|
-
/* @__PURE__ */
|
|
3394
|
+
/* @__PURE__ */ jsx19(
|
|
1933
3395
|
SyntaxHighlighter,
|
|
1934
3396
|
{
|
|
1935
3397
|
language,
|
|
@@ -1940,7 +3402,7 @@ var defaultComponents = {
|
|
|
1940
3402
|
] });
|
|
1941
3403
|
}
|
|
1942
3404
|
if (isBlockCode) {
|
|
1943
|
-
return /* @__PURE__ */
|
|
3405
|
+
return /* @__PURE__ */ jsx19(
|
|
1944
3406
|
"code",
|
|
1945
3407
|
{
|
|
1946
3408
|
className: cn(
|
|
@@ -1952,7 +3414,7 @@ var defaultComponents = {
|
|
|
1952
3414
|
}
|
|
1953
3415
|
);
|
|
1954
3416
|
}
|
|
1955
|
-
return /* @__PURE__ */
|
|
3417
|
+
return /* @__PURE__ */ jsx19(
|
|
1956
3418
|
"code",
|
|
1957
3419
|
{
|
|
1958
3420
|
className: cn(
|
|
@@ -1966,7 +3428,7 @@ var defaultComponents = {
|
|
|
1966
3428
|
}
|
|
1967
3429
|
};
|
|
1968
3430
|
var MarkdownTextImpl = ({ children }) => {
|
|
1969
|
-
return /* @__PURE__ */
|
|
3431
|
+
return /* @__PURE__ */ jsx19("div", { className: "markdown-content", children: /* @__PURE__ */ jsx19(
|
|
1970
3432
|
ReactMarkdown,
|
|
1971
3433
|
{
|
|
1972
3434
|
remarkPlugins: [remarkGfm, remarkMath],
|
|
@@ -1980,18 +3442,18 @@ var MarkdownText = memo(MarkdownTextImpl);
|
|
|
1980
3442
|
|
|
1981
3443
|
// src/components/thread/messages/widget.tsx
|
|
1982
3444
|
import { SurfaceRenderer } from "@xpert-ai/a2ui-react";
|
|
1983
|
-
import { jsx as
|
|
3445
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1984
3446
|
function WidgetMessage({ messageId, data }) {
|
|
1985
3447
|
const widgets = Array.isArray(data.widgets) ? data.widgets : [];
|
|
1986
3448
|
if (widgets.length === 0) return null;
|
|
1987
3449
|
const baseSurfaceId = `widget-${messageId}`;
|
|
1988
|
-
return /* @__PURE__ */
|
|
3450
|
+
return /* @__PURE__ */ jsx20("div", { className: "space-y-3", children: widgets.map((widget, index) => {
|
|
1989
3451
|
const config = widget?.config;
|
|
1990
3452
|
if (!config || typeof config !== "object") {
|
|
1991
3453
|
return null;
|
|
1992
3454
|
}
|
|
1993
3455
|
const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
|
|
1994
|
-
return /* @__PURE__ */
|
|
3456
|
+
return /* @__PURE__ */ jsx20(
|
|
1995
3457
|
SurfaceRenderer,
|
|
1996
3458
|
{
|
|
1997
3459
|
surfaceId,
|
|
@@ -2003,7 +3465,7 @@ function WidgetMessage({ messageId, data }) {
|
|
|
2003
3465
|
}
|
|
2004
3466
|
|
|
2005
3467
|
// src/components/thread/messages/ai.tsx
|
|
2006
|
-
import { jsx as
|
|
3468
|
+
import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2007
3469
|
function isTextContent(content) {
|
|
2008
3470
|
return content.type === "text";
|
|
2009
3471
|
}
|
|
@@ -2027,7 +3489,7 @@ var statusConfig = {
|
|
|
2027
3489
|
},
|
|
2028
3490
|
running: {
|
|
2029
3491
|
iconClass: "border-blue-500 text-blue-700",
|
|
2030
|
-
icon:
|
|
3492
|
+
icon: Loader22
|
|
2031
3493
|
}
|
|
2032
3494
|
};
|
|
2033
3495
|
function isWidgetComponent(content) {
|
|
@@ -2044,14 +3506,17 @@ function safeJson(value) {
|
|
|
2044
3506
|
return String(value);
|
|
2045
3507
|
}
|
|
2046
3508
|
}
|
|
3509
|
+
function formatDisplayValue(value) {
|
|
3510
|
+
return typeof value === "string" ? value : safeJson(value);
|
|
3511
|
+
}
|
|
2047
3512
|
function ReasoningBlock({ reasoning }) {
|
|
2048
3513
|
const blocks = reasoning.filter((item) => item.text?.trim());
|
|
2049
3514
|
if (blocks.length === 0) return null;
|
|
2050
|
-
return /* @__PURE__ */
|
|
3515
|
+
return /* @__PURE__ */ jsx21("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ jsx21(
|
|
2051
3516
|
"div",
|
|
2052
3517
|
{
|
|
2053
3518
|
className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
|
|
2054
|
-
children: /* @__PURE__ */
|
|
3519
|
+
children: /* @__PURE__ */ jsx21("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
|
|
2055
3520
|
},
|
|
2056
3521
|
item.id ?? `reasoning-${index}`
|
|
2057
3522
|
)) });
|
|
@@ -2059,27 +3524,27 @@ function ReasoningBlock({ reasoning }) {
|
|
|
2059
3524
|
function ImageBlock({ content }) {
|
|
2060
3525
|
const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
|
|
2061
3526
|
if (!imageUrl) {
|
|
2062
|
-
return /* @__PURE__ */
|
|
2063
|
-
/* @__PURE__ */
|
|
2064
|
-
/* @__PURE__ */
|
|
3527
|
+
return /* @__PURE__ */ jsxs11(Card, { children: [
|
|
3528
|
+
/* @__PURE__ */ jsx21(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Image" }) }),
|
|
3529
|
+
/* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
|
|
2065
3530
|
] });
|
|
2066
3531
|
}
|
|
2067
|
-
return /* @__PURE__ */
|
|
3532
|
+
return /* @__PURE__ */ jsx21("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ jsx21("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
|
|
2068
3533
|
}
|
|
2069
3534
|
function MemoryBlock({ content }) {
|
|
2070
|
-
return /* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2072
|
-
/* @__PURE__ */
|
|
2073
|
-
/* @__PURE__ */
|
|
3535
|
+
return /* @__PURE__ */ jsxs11(Card, { children: [
|
|
3536
|
+
/* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
3537
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Memory" }),
|
|
3538
|
+
/* @__PURE__ */ jsx21(Badge, { variant: "secondary", children: "Memory" })
|
|
2074
3539
|
] }),
|
|
2075
|
-
/* @__PURE__ */
|
|
3540
|
+
/* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
|
|
2076
3541
|
] });
|
|
2077
3542
|
}
|
|
2078
3543
|
function ComponentBlock({ content }) {
|
|
2079
|
-
const [isExpanded, setIsExpanded] =
|
|
2080
|
-
const contentRef =
|
|
2081
|
-
const shouldAutoScrollRef =
|
|
2082
|
-
const previousScrollTopRef =
|
|
3544
|
+
const [isExpanded, setIsExpanded] = React15.useState(false);
|
|
3545
|
+
const contentRef = React15.useRef(null);
|
|
3546
|
+
const shouldAutoScrollRef = React15.useRef(true);
|
|
3547
|
+
const previousScrollTopRef = React15.useRef(0);
|
|
2083
3548
|
const data = content.data ?? {};
|
|
2084
3549
|
const category = data.category ?? "Component";
|
|
2085
3550
|
const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
|
|
@@ -2087,12 +3552,12 @@ function ComponentBlock({ content }) {
|
|
|
2087
3552
|
const message = data.message ?? null;
|
|
2088
3553
|
const output = data.output ?? null;
|
|
2089
3554
|
const error = data.error ?? null;
|
|
2090
|
-
const fallback = message ?? output ??
|
|
3555
|
+
const fallback = message ?? output ?? data.data ?? data;
|
|
2091
3556
|
const hasOutput = message !== null || output !== null;
|
|
2092
|
-
|
|
3557
|
+
React15.useEffect(() => {
|
|
2093
3558
|
if (status === "running" && output !== null) setIsExpanded(true);
|
|
2094
3559
|
}, [status, output]);
|
|
2095
|
-
|
|
3560
|
+
React15.useEffect(() => {
|
|
2096
3561
|
const element = contentRef.current;
|
|
2097
3562
|
if (!element) return;
|
|
2098
3563
|
previousScrollTopRef.current = element.scrollTop;
|
|
@@ -2112,7 +3577,7 @@ function ComponentBlock({ content }) {
|
|
|
2112
3577
|
element.removeEventListener("scroll", updateAutoScrollState);
|
|
2113
3578
|
};
|
|
2114
3579
|
}, [isExpanded]);
|
|
2115
|
-
|
|
3580
|
+
React15.useEffect(() => {
|
|
2116
3581
|
if (status !== "running") {
|
|
2117
3582
|
shouldAutoScrollRef.current = true;
|
|
2118
3583
|
return;
|
|
@@ -2125,20 +3590,20 @@ function ComponentBlock({ content }) {
|
|
|
2125
3590
|
}, [isExpanded, output, status]);
|
|
2126
3591
|
const config = status ? statusConfig[status] : null;
|
|
2127
3592
|
const StatusIcon = config?.icon;
|
|
2128
|
-
return /* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
status && StatusIcon && /* @__PURE__ */
|
|
2132
|
-
/* @__PURE__ */
|
|
3593
|
+
return /* @__PURE__ */ jsxs11(Card, { children: [
|
|
3594
|
+
/* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
|
|
3595
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
|
|
3596
|
+
status && StatusIcon && /* @__PURE__ */ jsx21(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
|
|
3597
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm truncate", children: title })
|
|
2133
3598
|
] }),
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */
|
|
2136
|
-
/* @__PURE__ */
|
|
3599
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
|
|
3600
|
+
/* @__PURE__ */ jsx21(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
|
|
3601
|
+
/* @__PURE__ */ jsx21(
|
|
2137
3602
|
"button",
|
|
2138
3603
|
{
|
|
2139
3604
|
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
2140
3605
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
2141
|
-
children: /* @__PURE__ */
|
|
3606
|
+
children: /* @__PURE__ */ jsx21(
|
|
2142
3607
|
ChevronDown,
|
|
2143
3608
|
{
|
|
2144
3609
|
className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
|
|
@@ -2148,89 +3613,128 @@ function ComponentBlock({ content }) {
|
|
|
2148
3613
|
)
|
|
2149
3614
|
] })
|
|
2150
3615
|
] }),
|
|
2151
|
-
isExpanded && /* @__PURE__ */
|
|
2152
|
-
data.input && /* @__PURE__ */
|
|
2153
|
-
error ? /* @__PURE__ */
|
|
3616
|
+
isExpanded && /* @__PURE__ */ jsxs11(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
|
|
3617
|
+
data.input && /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
|
|
3618
|
+
error ? /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
|
|
2154
3619
|
] })
|
|
2155
3620
|
] });
|
|
2156
3621
|
}
|
|
2157
3622
|
function UnknownBlock({ content }) {
|
|
2158
|
-
return /* @__PURE__ */
|
|
2159
|
-
/* @__PURE__ */
|
|
2160
|
-
/* @__PURE__ */
|
|
2161
|
-
/* @__PURE__ */
|
|
3623
|
+
return /* @__PURE__ */ jsxs11(Card, { children: [
|
|
3624
|
+
/* @__PURE__ */ jsxs11(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
3625
|
+
/* @__PURE__ */ jsx21(CardTitle, { className: "text-sm", children: "Assistant Content" }),
|
|
3626
|
+
/* @__PURE__ */ jsx21(Badge, { variant: "outline", children: content.type ?? "unknown" })
|
|
2162
3627
|
] }),
|
|
2163
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsx21(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ jsx21("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
|
|
2164
3629
|
] });
|
|
2165
3630
|
}
|
|
2166
3631
|
function renderContentItem(content, index, messageId) {
|
|
2167
3632
|
if (typeof content === "string") {
|
|
2168
|
-
return /* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */
|
|
3633
|
+
return /* @__PURE__ */ jsxs11("div", { children: [
|
|
3634
|
+
/* @__PURE__ */ jsx21(MarkdownText, { children: content }),
|
|
2170
3635
|
";"
|
|
2171
3636
|
] }, `text-${index}`);
|
|
2172
3637
|
}
|
|
2173
3638
|
if (isTextContent(content)) {
|
|
2174
|
-
return /* @__PURE__ */
|
|
3639
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
|
|
2175
3640
|
}
|
|
2176
3641
|
if (isReasoningContent(content)) {
|
|
2177
|
-
return /* @__PURE__ */
|
|
3642
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
|
|
2178
3643
|
}
|
|
2179
3644
|
if (isImageContent(content)) {
|
|
2180
|
-
return /* @__PURE__ */
|
|
3645
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ImageBlock, { content }) }, content.id ?? `image-${index}`);
|
|
2181
3646
|
}
|
|
2182
3647
|
if (isComponentContent(content)) {
|
|
2183
3648
|
if (isWidgetComponent(content)) {
|
|
2184
|
-
return /* @__PURE__ */
|
|
3649
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
|
|
2185
3650
|
}
|
|
2186
|
-
return /* @__PURE__ */
|
|
3651
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
|
|
2187
3652
|
}
|
|
2188
3653
|
if (isMemoryContent(content)) {
|
|
2189
|
-
return /* @__PURE__ */
|
|
3654
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
|
|
2190
3655
|
}
|
|
2191
|
-
return /* @__PURE__ */
|
|
3656
|
+
return /* @__PURE__ */ jsx21("div", { children: /* @__PURE__ */ jsx21(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
|
|
2192
3657
|
}
|
|
2193
3658
|
function renderContent(content, messageId) {
|
|
2194
3659
|
if (typeof content === "string") {
|
|
2195
3660
|
if (!content.trim()) return null;
|
|
2196
|
-
return /* @__PURE__ */
|
|
3661
|
+
return /* @__PURE__ */ jsx21(MarkdownText, { children: content });
|
|
2197
3662
|
}
|
|
2198
3663
|
if (!Array.isArray(content) || content.length === 0) return null;
|
|
2199
|
-
return /* @__PURE__ */
|
|
3664
|
+
return /* @__PURE__ */ jsx21("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
|
|
2200
3665
|
}
|
|
2201
|
-
function
|
|
3666
|
+
function AssistantStreamingIndicator({
|
|
3667
|
+
status,
|
|
3668
|
+
className
|
|
3669
|
+
}) {
|
|
2202
3670
|
const { t } = useChatkitTranslation();
|
|
2203
|
-
const
|
|
2204
|
-
|
|
2205
|
-
|
|
3671
|
+
const labelMap = {
|
|
3672
|
+
loading: t("message.loading"),
|
|
3673
|
+
thinking: t("message.thinking"),
|
|
3674
|
+
answering: t("message.answering")
|
|
3675
|
+
};
|
|
3676
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
|
|
3677
|
+
status === "loading" && /* @__PURE__ */ jsx21(Loader22, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
3678
|
+
status === "thinking" && /* @__PURE__ */ jsxs11("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
3679
|
+
/* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
|
|
3680
|
+
/* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
|
|
3681
|
+
/* @__PURE__ */ jsx21("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
|
|
3682
|
+
] }),
|
|
3683
|
+
status === "answering" && /* @__PURE__ */ jsxs11("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
3684
|
+
/* @__PURE__ */ jsx21("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
|
|
3685
|
+
/* @__PURE__ */ jsx21("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
|
|
3686
|
+
/* @__PURE__ */ jsx21("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
|
|
3687
|
+
] }),
|
|
3688
|
+
/* @__PURE__ */ jsx21("span", { children: labelMap[status] })
|
|
3689
|
+
] });
|
|
3690
|
+
}
|
|
3691
|
+
function AssistantMessage({
|
|
3692
|
+
message,
|
|
3693
|
+
className,
|
|
3694
|
+
isStreaming = false,
|
|
3695
|
+
streamingStatus
|
|
3696
|
+
}) {
|
|
3697
|
+
const { t } = useChatkitTranslation();
|
|
3698
|
+
const hasContent = hasRenderableMessageContent(message.content);
|
|
3699
|
+
const hasReasoning = hasRenderableReasoning(message.reasoning);
|
|
3700
|
+
const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
|
|
2206
3701
|
const answerNode = renderContent(message.content, message.id);
|
|
2207
|
-
const reasoningNode = hasReasoning ? /* @__PURE__ */
|
|
2208
|
-
if (!
|
|
3702
|
+
const reasoningNode = hasReasoning ? /* @__PURE__ */ jsx21(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
|
|
3703
|
+
if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
|
|
2209
3704
|
const streamingClass = isStreaming ? "streaming-active" : "";
|
|
3705
|
+
if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
|
|
3706
|
+
return /* @__PURE__ */ jsx21("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
|
|
3707
|
+
}
|
|
2210
3708
|
if (hasContent && hasReasoning) {
|
|
2211
|
-
return /* @__PURE__ */
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
3709
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3710
|
+
/* @__PURE__ */ jsxs11(
|
|
3711
|
+
Tabs,
|
|
3712
|
+
{
|
|
3713
|
+
defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
|
|
3714
|
+
className: "w-full",
|
|
3715
|
+
children: [
|
|
3716
|
+
/* @__PURE__ */ jsxs11(TabsList, { className: "", children: [
|
|
3717
|
+
/* @__PURE__ */ jsx21(TabsTrigger, { value: "answer", children: t("message.answer") }),
|
|
3718
|
+
/* @__PURE__ */ jsx21(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
|
|
3719
|
+
] }),
|
|
3720
|
+
/* @__PURE__ */ jsx21(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
|
|
3721
|
+
/* @__PURE__ */ jsx21(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
|
|
3722
|
+
]
|
|
3723
|
+
}
|
|
3724
|
+
),
|
|
3725
|
+
resolvedStreamingStatus ? /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3726
|
+
] });
|
|
2226
3727
|
}
|
|
2227
|
-
return /* @__PURE__ */
|
|
3728
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3729
|
+
hasReasoning ? reasoningNode : answerNode,
|
|
3730
|
+
resolvedStreamingStatus ? /* @__PURE__ */ jsx21(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3731
|
+
] });
|
|
2228
3732
|
}
|
|
2229
3733
|
|
|
2230
3734
|
// src/components/thread/MessageActions.tsx
|
|
2231
|
-
import * as
|
|
3735
|
+
import * as React16 from "react";
|
|
2232
3736
|
import { Check, Copy, RefreshCw } from "lucide-react";
|
|
2233
|
-
import { jsx as
|
|
3737
|
+
import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2234
3738
|
function MessageActions({
|
|
2235
3739
|
content,
|
|
2236
3740
|
isAssistant = false,
|
|
@@ -2239,7 +3743,7 @@ function MessageActions({
|
|
|
2239
3743
|
className
|
|
2240
3744
|
}) {
|
|
2241
3745
|
const { t } = useChatkitTranslation();
|
|
2242
|
-
const [copied, setCopied] =
|
|
3746
|
+
const [copied, setCopied] = React16.useState(false);
|
|
2243
3747
|
const handleCopy = async () => {
|
|
2244
3748
|
try {
|
|
2245
3749
|
await navigator.clipboard.writeText(content);
|
|
@@ -2252,7 +3756,7 @@ function MessageActions({
|
|
|
2252
3756
|
if (isStreaming) {
|
|
2253
3757
|
return null;
|
|
2254
3758
|
}
|
|
2255
|
-
return /* @__PURE__ */
|
|
3759
|
+
return /* @__PURE__ */ jsxs12(
|
|
2256
3760
|
"div",
|
|
2257
3761
|
{
|
|
2258
3762
|
className: cn(
|
|
@@ -2260,7 +3764,7 @@ function MessageActions({
|
|
|
2260
3764
|
className
|
|
2261
3765
|
),
|
|
2262
3766
|
children: [
|
|
2263
|
-
/* @__PURE__ */
|
|
3767
|
+
/* @__PURE__ */ jsx22(
|
|
2264
3768
|
"button",
|
|
2265
3769
|
{
|
|
2266
3770
|
type: "button",
|
|
@@ -2270,17 +3774,17 @@ function MessageActions({
|
|
|
2270
3774
|
copied && "text-green-500"
|
|
2271
3775
|
),
|
|
2272
3776
|
title: copied ? t("messageActions.copied") : t("messageActions.copy"),
|
|
2273
|
-
children: copied ? /* @__PURE__ */
|
|
3777
|
+
children: copied ? /* @__PURE__ */ jsx22(Check, { size: 14 }) : /* @__PURE__ */ jsx22(Copy, { size: 14 })
|
|
2274
3778
|
}
|
|
2275
3779
|
),
|
|
2276
|
-
isAssistant && onRetry && /* @__PURE__ */
|
|
3780
|
+
isAssistant && onRetry && /* @__PURE__ */ jsx22(
|
|
2277
3781
|
"button",
|
|
2278
3782
|
{
|
|
2279
3783
|
type: "button",
|
|
2280
3784
|
onClick: onRetry,
|
|
2281
3785
|
className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
2282
3786
|
title: t("messageActions.regenerate"),
|
|
2283
|
-
children: /* @__PURE__ */
|
|
3787
|
+
children: /* @__PURE__ */ jsx22(RefreshCw, { size: 14 })
|
|
2284
3788
|
}
|
|
2285
3789
|
)
|
|
2286
3790
|
]
|
|
@@ -2301,18 +3805,18 @@ import {
|
|
|
2301
3805
|
Sparkles as Sparkles2,
|
|
2302
3806
|
Zap
|
|
2303
3807
|
} from "lucide-react";
|
|
2304
|
-
import { jsx as
|
|
3808
|
+
import { jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2305
3809
|
function getIconComponent2(icon) {
|
|
2306
3810
|
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__ */
|
|
3811
|
+
"circle-question": /* @__PURE__ */ jsx23(HelpCircle, { size: 20 }),
|
|
3812
|
+
"lightbulb": /* @__PURE__ */ jsx23(Lightbulb2, { size: 20 }),
|
|
3813
|
+
"sparkle": /* @__PURE__ */ jsx23(Sparkles2, { size: 20 }),
|
|
3814
|
+
"write": /* @__PURE__ */ jsx23(Pencil2, { size: 20 }),
|
|
3815
|
+
"search": /* @__PURE__ */ jsx23(Search2, { size: 20 }),
|
|
3816
|
+
"globe": /* @__PURE__ */ jsx23(Globe2, { size: 20 }),
|
|
3817
|
+
"book-open": /* @__PURE__ */ jsx23(BookOpen, { size: 20 }),
|
|
3818
|
+
"compass": /* @__PURE__ */ jsx23(Compass, { size: 20 }),
|
|
3819
|
+
"bolt": /* @__PURE__ */ jsx23(Zap, { size: 20 })
|
|
2316
3820
|
};
|
|
2317
3821
|
return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
|
|
2318
3822
|
}
|
|
@@ -2320,9 +3824,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2320
3824
|
const { t } = useChatkitTranslation();
|
|
2321
3825
|
const greeting = startScreen?.greeting ?? t("startScreen.greeting");
|
|
2322
3826
|
const prompts = startScreen?.prompts ?? [];
|
|
2323
|
-
return /* @__PURE__ */
|
|
2324
|
-
/* @__PURE__ */
|
|
2325
|
-
prompts.length > 0 && /* @__PURE__ */
|
|
3827
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
|
|
3828
|
+
/* @__PURE__ */ jsx23("div", { className: "mb-8 text-center", children: /* @__PURE__ */ jsx23("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
|
|
3829
|
+
prompts.length > 0 && /* @__PURE__ */ jsx23("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ jsxs13(
|
|
2326
3830
|
"button",
|
|
2327
3831
|
{
|
|
2328
3832
|
type: "button",
|
|
@@ -2333,8 +3837,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2333
3837
|
"focus:outline-none focus:ring-2 focus:ring-primary/20"
|
|
2334
3838
|
),
|
|
2335
3839
|
children: [
|
|
2336
|
-
/* @__PURE__ */
|
|
2337
|
-
/* @__PURE__ */
|
|
3840
|
+
/* @__PURE__ */ jsx23("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
|
|
3841
|
+
/* @__PURE__ */ jsx23("span", { className: "text-sm font-medium text-foreground", children: item.label })
|
|
2338
3842
|
]
|
|
2339
3843
|
},
|
|
2340
3844
|
`prompt-${index}`
|
|
@@ -2346,10 +3850,10 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2346
3850
|
import "react";
|
|
2347
3851
|
|
|
2348
3852
|
// src/components/ui/avatar.tsx
|
|
2349
|
-
import * as
|
|
3853
|
+
import * as React18 from "react";
|
|
2350
3854
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
2351
|
-
import { jsx as
|
|
2352
|
-
var Avatar =
|
|
3855
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3856
|
+
var Avatar = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
2353
3857
|
AvatarPrimitive.Root,
|
|
2354
3858
|
{
|
|
2355
3859
|
ref,
|
|
@@ -2361,7 +3865,7 @@ var Avatar = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
2361
3865
|
}
|
|
2362
3866
|
));
|
|
2363
3867
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
2364
|
-
var AvatarImage =
|
|
3868
|
+
var AvatarImage = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
2365
3869
|
AvatarPrimitive.Image,
|
|
2366
3870
|
{
|
|
2367
3871
|
ref,
|
|
@@ -2370,7 +3874,7 @@ var AvatarImage = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
2370
3874
|
}
|
|
2371
3875
|
));
|
|
2372
3876
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
2373
|
-
var AvatarFallback =
|
|
3877
|
+
var AvatarFallback = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
2374
3878
|
AvatarPrimitive.Fallback,
|
|
2375
3879
|
{
|
|
2376
3880
|
ref,
|
|
@@ -2384,7 +3888,7 @@ var AvatarFallback = React16.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
2384
3888
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
2385
3889
|
|
|
2386
3890
|
// src/components/ui/chatkit-avatar.tsx
|
|
2387
|
-
import { jsx as
|
|
3891
|
+
import { jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2388
3892
|
function asRecord(value) {
|
|
2389
3893
|
return value && typeof value === "object" ? value : null;
|
|
2390
3894
|
}
|
|
@@ -2457,21 +3961,21 @@ function ChatkitAvatar({
|
|
|
2457
3961
|
const fallbackStyle = {
|
|
2458
3962
|
...avatar?.background ? { background: avatar.background } : {}
|
|
2459
3963
|
};
|
|
2460
|
-
return /* @__PURE__ */
|
|
2461
|
-
avatar?.url ? /* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
3964
|
+
return /* @__PURE__ */ jsxs14(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
|
|
3965
|
+
avatar?.url ? /* @__PURE__ */ jsx25(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
|
|
3966
|
+
/* @__PURE__ */ jsx25(
|
|
2463
3967
|
AvatarFallback,
|
|
2464
3968
|
{
|
|
2465
3969
|
className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
|
|
2466
3970
|
style: fallbackStyle,
|
|
2467
|
-
children: emojiCharacter ? /* @__PURE__ */
|
|
3971
|
+
children: emojiCharacter ? /* @__PURE__ */ jsx25("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
|
|
2468
3972
|
}
|
|
2469
3973
|
)
|
|
2470
3974
|
] });
|
|
2471
3975
|
}
|
|
2472
3976
|
|
|
2473
3977
|
// src/hooks/useThreads.ts
|
|
2474
|
-
import * as
|
|
3978
|
+
import * as React20 from "react";
|
|
2475
3979
|
var DEFAULT_LIMIT = 50;
|
|
2476
3980
|
var getThreadTitle = (threadRecord) => {
|
|
2477
3981
|
const title = threadRecord.title?.trim();
|
|
@@ -2509,16 +4013,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2509
4013
|
isReady,
|
|
2510
4014
|
isLoading: isStreamLoading
|
|
2511
4015
|
} = useStreamContext();
|
|
2512
|
-
const [threadRecords, setThreadRecords] =
|
|
2513
|
-
const [isLoading, setIsLoading] =
|
|
2514
|
-
const [error, setError] =
|
|
2515
|
-
const upsertThreadRecord =
|
|
4016
|
+
const [threadRecords, setThreadRecords] = React20.useState([]);
|
|
4017
|
+
const [isLoading, setIsLoading] = React20.useState(false);
|
|
4018
|
+
const [error, setError] = React20.useState(null);
|
|
4019
|
+
const upsertThreadRecord = React20.useCallback((threadRecord) => {
|
|
2516
4020
|
setThreadRecords((prev) => {
|
|
2517
4021
|
const next = prev.filter((item) => item.id !== threadRecord.id);
|
|
2518
4022
|
return sortThreadRecords([threadRecord, ...next]);
|
|
2519
4023
|
});
|
|
2520
4024
|
}, []);
|
|
2521
|
-
const refreshThreads =
|
|
4025
|
+
const refreshThreads = React20.useCallback(async () => {
|
|
2522
4026
|
setIsLoading(true);
|
|
2523
4027
|
setError(null);
|
|
2524
4028
|
try {
|
|
@@ -2534,7 +4038,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2534
4038
|
setIsLoading(false);
|
|
2535
4039
|
}
|
|
2536
4040
|
}, [client, limit, assistantId]);
|
|
2537
|
-
const createThread =
|
|
4041
|
+
const createThread = React20.useCallback(
|
|
2538
4042
|
async (input) => {
|
|
2539
4043
|
setError(null);
|
|
2540
4044
|
const payload = {};
|
|
@@ -2548,7 +4052,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2548
4052
|
},
|
|
2549
4053
|
[client, upsertThreadRecord]
|
|
2550
4054
|
);
|
|
2551
|
-
const updateThread =
|
|
4055
|
+
const updateThread = React20.useCallback(
|
|
2552
4056
|
async (recordId, payload) => {
|
|
2553
4057
|
setError(null);
|
|
2554
4058
|
const updated = await client.conversations.update(recordId, payload);
|
|
@@ -2557,7 +4061,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2557
4061
|
},
|
|
2558
4062
|
[client, upsertThreadRecord]
|
|
2559
4063
|
);
|
|
2560
|
-
const deleteThread =
|
|
4064
|
+
const deleteThread = React20.useCallback(
|
|
2561
4065
|
async (recordId) => {
|
|
2562
4066
|
setError(null);
|
|
2563
4067
|
await client.conversations.delete(recordId);
|
|
@@ -2565,23 +4069,24 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2565
4069
|
},
|
|
2566
4070
|
[client]
|
|
2567
4071
|
);
|
|
2568
|
-
|
|
4072
|
+
React20.useEffect(() => {
|
|
2569
4073
|
if (!isReady) return;
|
|
2570
4074
|
void refreshThreads();
|
|
2571
4075
|
}, [refreshThreads, isReady]);
|
|
2572
|
-
|
|
4076
|
+
React20.useEffect(() => {
|
|
2573
4077
|
if (!threadId || !isStreamLoading) return;
|
|
2574
4078
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4079
|
+
const busyStatus = "busy";
|
|
2575
4080
|
setThreadRecords((prev) => {
|
|
2576
4081
|
let changed = false;
|
|
2577
4082
|
const next = prev.map((item) => {
|
|
2578
4083
|
const isCurrentThread = item.threadId === threadId || item.id === threadId;
|
|
2579
4084
|
if (!isCurrentThread) return item;
|
|
2580
|
-
if (item.status ===
|
|
4085
|
+
if (item.status === busyStatus && !item.error) return item;
|
|
2581
4086
|
changed = true;
|
|
2582
4087
|
return {
|
|
2583
4088
|
...item,
|
|
2584
|
-
status:
|
|
4089
|
+
status: busyStatus,
|
|
2585
4090
|
error: void 0,
|
|
2586
4091
|
updatedAt: now
|
|
2587
4092
|
};
|
|
@@ -2589,7 +4094,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2589
4094
|
return changed ? sortThreadRecords(next) : prev;
|
|
2590
4095
|
});
|
|
2591
4096
|
}, [threadId, isStreamLoading]);
|
|
2592
|
-
|
|
4097
|
+
React20.useEffect(() => {
|
|
2593
4098
|
if (!isReady || !threadId || isStreamLoading) return;
|
|
2594
4099
|
let cancelled = false;
|
|
2595
4100
|
void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
|
|
@@ -2603,7 +4108,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2603
4108
|
cancelled = true;
|
|
2604
4109
|
};
|
|
2605
4110
|
}, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
|
|
2606
|
-
const threads =
|
|
4111
|
+
const threads = React20.useMemo(
|
|
2607
4112
|
() => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
|
|
2608
4113
|
[threadRecords]
|
|
2609
4114
|
);
|
|
@@ -2620,18 +4125,18 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2620
4125
|
}
|
|
2621
4126
|
|
|
2622
4127
|
// src/components/thread/context-usage-indicator.tsx
|
|
2623
|
-
import * as
|
|
4128
|
+
import * as React21 from "react";
|
|
2624
4129
|
|
|
2625
4130
|
// src/components/ui/progress-circle.tsx
|
|
2626
|
-
import { jsx as
|
|
2627
|
-
function
|
|
4131
|
+
import { jsx as jsx26, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4132
|
+
function clamp2(input, a, b) {
|
|
2628
4133
|
return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
|
|
2629
4134
|
}
|
|
2630
4135
|
var size = 24;
|
|
2631
4136
|
var strokeWidth = 4;
|
|
2632
4137
|
var total = 100;
|
|
2633
4138
|
var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
2634
|
-
const normalizedValue =
|
|
4139
|
+
const normalizedValue = clamp2(value, 0, total);
|
|
2635
4140
|
const radius = (size - strokeWidth) / 2;
|
|
2636
4141
|
const circumference = 2 * Math.PI * radius;
|
|
2637
4142
|
const progress = normalizedValue / total * circumference;
|
|
@@ -2646,7 +4151,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2646
4151
|
return (
|
|
2647
4152
|
// biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
|
|
2648
4153
|
// biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
|
|
2649
|
-
/* @__PURE__ */
|
|
4154
|
+
/* @__PURE__ */ jsxs15(
|
|
2650
4155
|
"svg",
|
|
2651
4156
|
{
|
|
2652
4157
|
role: "progressbar",
|
|
@@ -2657,8 +4162,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2657
4162
|
"aria-valuemax": 100,
|
|
2658
4163
|
...restSvgProps,
|
|
2659
4164
|
children: [
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
4165
|
+
/* @__PURE__ */ jsx26("circle", { ...commonParams, className: "stroke-current/25" }),
|
|
4166
|
+
/* @__PURE__ */ jsx26(
|
|
2662
4167
|
"circle",
|
|
2663
4168
|
{
|
|
2664
4169
|
...commonParams,
|
|
@@ -2677,7 +4182,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2677
4182
|
};
|
|
2678
4183
|
|
|
2679
4184
|
// src/components/thread/context-usage-indicator.tsx
|
|
2680
|
-
import { jsx as
|
|
4185
|
+
import { jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2681
4186
|
var kNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
2682
4187
|
minimumFractionDigits: 0,
|
|
2683
4188
|
maximumFractionDigits: 1
|
|
@@ -2710,20 +4215,20 @@ function ContextUsageIndicator({
|
|
|
2710
4215
|
}) {
|
|
2711
4216
|
const { t } = useChatkitTranslation();
|
|
2712
4217
|
const stream = useStreamContext();
|
|
2713
|
-
const [maxContextSize, setMaxContextSize] =
|
|
2714
|
-
const [usedContextSize, setUsedContextSize] =
|
|
2715
|
-
const [assistantAgentKey, setAssistantAgentKey] =
|
|
2716
|
-
const latestRealtimeUsageRef =
|
|
4218
|
+
const [maxContextSize, setMaxContextSize] = React21.useState(null);
|
|
4219
|
+
const [usedContextSize, setUsedContextSize] = React21.useState(null);
|
|
4220
|
+
const [assistantAgentKey, setAssistantAgentKey] = React21.useState(null);
|
|
4221
|
+
const latestRealtimeUsageRef = React21.useRef({
|
|
2717
4222
|
threadId: null,
|
|
2718
4223
|
agentKey: null,
|
|
2719
4224
|
usedTokens: null
|
|
2720
4225
|
});
|
|
2721
|
-
const realtimeUsage =
|
|
4226
|
+
const realtimeUsage = React21.useMemo(
|
|
2722
4227
|
() => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
|
|
2723
4228
|
[assistantAgentKey, stream.contextUsageByAgentKey]
|
|
2724
4229
|
);
|
|
2725
4230
|
const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
|
|
2726
|
-
|
|
4231
|
+
React21.useEffect(() => {
|
|
2727
4232
|
if (!stream.client || !stream.assistantId) {
|
|
2728
4233
|
setMaxContextSize(null);
|
|
2729
4234
|
setAssistantAgentKey(null);
|
|
@@ -2743,18 +4248,18 @@ function ContextUsageIndicator({
|
|
|
2743
4248
|
cancelled = true;
|
|
2744
4249
|
};
|
|
2745
4250
|
}, [stream.client, stream.assistantId]);
|
|
2746
|
-
|
|
4251
|
+
React21.useEffect(() => {
|
|
2747
4252
|
latestRealtimeUsageRef.current = {
|
|
2748
4253
|
threadId: stream.threadId ?? null,
|
|
2749
4254
|
agentKey: assistantAgentKey,
|
|
2750
4255
|
usedTokens: realtimeUsedContextSize
|
|
2751
4256
|
};
|
|
2752
4257
|
}, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
|
|
2753
|
-
|
|
4258
|
+
React21.useEffect(() => {
|
|
2754
4259
|
if (realtimeUsedContextSize == null) return;
|
|
2755
4260
|
setUsedContextSize(realtimeUsedContextSize);
|
|
2756
4261
|
}, [realtimeUsedContextSize]);
|
|
2757
|
-
|
|
4262
|
+
React21.useEffect(() => {
|
|
2758
4263
|
if (!stream.client) {
|
|
2759
4264
|
setUsedContextSize(null);
|
|
2760
4265
|
return;
|
|
@@ -2819,8 +4324,8 @@ function ContextUsageIndicator({
|
|
|
2819
4324
|
});
|
|
2820
4325
|
const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
|
|
2821
4326
|
const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
|
|
2822
|
-
return /* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
4327
|
+
return /* @__PURE__ */ jsxs16(Tooltip, { children: [
|
|
4328
|
+
/* @__PURE__ */ jsx27(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx27(
|
|
2824
4329
|
"button",
|
|
2825
4330
|
{
|
|
2826
4331
|
type: "button",
|
|
@@ -2829,20 +4334,73 @@ function ContextUsageIndicator({
|
|
|
2829
4334
|
className
|
|
2830
4335
|
),
|
|
2831
4336
|
"aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
|
|
2832
|
-
children: /* @__PURE__ */
|
|
4337
|
+
children: /* @__PURE__ */ jsx27(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
|
|
2833
4338
|
}
|
|
2834
4339
|
) }),
|
|
2835
|
-
/* @__PURE__ */
|
|
2836
|
-
/* @__PURE__ */
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
/* @__PURE__ */
|
|
4340
|
+
/* @__PURE__ */ jsxs16(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
|
|
4341
|
+
/* @__PURE__ */ jsx27("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
|
|
4342
|
+
/* @__PURE__ */ jsx27("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
|
|
4343
|
+
/* @__PURE__ */ jsx27("div", { className: "text-sm font-semibold", children: usageTokensLabel })
|
|
2839
4344
|
] })
|
|
2840
4345
|
] });
|
|
2841
4346
|
}
|
|
2842
4347
|
|
|
2843
4348
|
// src/components/chat.tsx
|
|
2844
|
-
import { Fragment as
|
|
4349
|
+
import { Fragment as Fragment4, jsx as jsx28, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2845
4350
|
var defaultApiUrl2 = import.meta.env.VITE_XPERTAI_API_URL;
|
|
4351
|
+
var COMPOSER_INPUT_MAX_HEIGHT = 128;
|
|
4352
|
+
var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
|
|
4353
|
+
async function readImageDimensions(file) {
|
|
4354
|
+
if (typeof window === "undefined" || typeof URL === "undefined") {
|
|
4355
|
+
return {};
|
|
4356
|
+
}
|
|
4357
|
+
return new Promise((resolve) => {
|
|
4358
|
+
const objectUrl = URL.createObjectURL(file);
|
|
4359
|
+
const image = new window.Image();
|
|
4360
|
+
const cleanup = () => {
|
|
4361
|
+
URL.revokeObjectURL(objectUrl);
|
|
4362
|
+
};
|
|
4363
|
+
image.onload = () => {
|
|
4364
|
+
resolve({
|
|
4365
|
+
width: image.naturalWidth || void 0,
|
|
4366
|
+
height: image.naturalHeight || void 0
|
|
4367
|
+
});
|
|
4368
|
+
cleanup();
|
|
4369
|
+
};
|
|
4370
|
+
image.onerror = () => {
|
|
4371
|
+
resolve({});
|
|
4372
|
+
cleanup();
|
|
4373
|
+
};
|
|
4374
|
+
image.src = objectUrl;
|
|
4375
|
+
});
|
|
4376
|
+
}
|
|
4377
|
+
function getStorageFileUrl(file) {
|
|
4378
|
+
return file.url ?? file.fileUrl ?? file.thumbUrl;
|
|
4379
|
+
}
|
|
4380
|
+
function buildPastedImageReference(file, storageFile, dimensions) {
|
|
4381
|
+
const name = storageFile.originalName?.trim() || file.name.trim() || "Pasted image";
|
|
4382
|
+
const mimeType = storageFile.mimetype?.trim() || file.type.trim() || "image/*";
|
|
4383
|
+
const size2 = storageFile.size ?? file.size;
|
|
4384
|
+
const width = dimensions?.width;
|
|
4385
|
+
const height = dimensions?.height;
|
|
4386
|
+
const metaParts = [
|
|
4387
|
+
mimeType,
|
|
4388
|
+
width && height ? `${width}x${height}` : null,
|
|
4389
|
+
typeof size2 === "number" ? `${size2} bytes` : null
|
|
4390
|
+
].filter((part) => Boolean(part));
|
|
4391
|
+
return {
|
|
4392
|
+
type: "image",
|
|
4393
|
+
id: storageFile.id,
|
|
4394
|
+
fileId: storageFile.id,
|
|
4395
|
+
url: getStorageFileUrl(storageFile),
|
|
4396
|
+
mimeType,
|
|
4397
|
+
name,
|
|
4398
|
+
...typeof size2 === "number" ? { size: size2 } : {},
|
|
4399
|
+
...width ? { width } : {},
|
|
4400
|
+
...height ? { height } : {},
|
|
4401
|
+
text: `Pasted image${metaParts.length ? ` (${metaParts.join(", ")})` : ""}: ${name}`
|
|
4402
|
+
};
|
|
4403
|
+
}
|
|
2846
4404
|
function formatMessageContent(content) {
|
|
2847
4405
|
if (typeof content === "string") {
|
|
2848
4406
|
return content;
|
|
@@ -2864,6 +4422,81 @@ function formatMessageContent(content) {
|
|
|
2864
4422
|
}
|
|
2865
4423
|
return "";
|
|
2866
4424
|
}
|
|
4425
|
+
function getClosestQuoteContainer(node) {
|
|
4426
|
+
if (!node) {
|
|
4427
|
+
return null;
|
|
4428
|
+
}
|
|
4429
|
+
const element = node instanceof HTMLElement ? node : node instanceof Text ? node.parentElement : null;
|
|
4430
|
+
return element?.closest("[data-quote-message-id]") ?? null;
|
|
4431
|
+
}
|
|
4432
|
+
function ReferenceChip({
|
|
4433
|
+
reference,
|
|
4434
|
+
variant,
|
|
4435
|
+
onRemove,
|
|
4436
|
+
removeLabel
|
|
4437
|
+
}) {
|
|
4438
|
+
const metaLine = getReferenceMetaLine(reference);
|
|
4439
|
+
const isComposer = variant === "composer";
|
|
4440
|
+
const Icon = reference.type === "quote" ? Quote : reference.type === "image" ? ImageIcon : FileText2;
|
|
4441
|
+
return /* @__PURE__ */ jsxs17(
|
|
4442
|
+
"div",
|
|
4443
|
+
{
|
|
4444
|
+
className: cn(
|
|
4445
|
+
"flex items-start gap-2 rounded-md px-2 py-1",
|
|
4446
|
+
isComposer ? "bg-muted text-foreground" : "bg-primary-foreground/20"
|
|
4447
|
+
),
|
|
4448
|
+
title: getReferenceTitle(reference),
|
|
4449
|
+
children: [
|
|
4450
|
+
/* @__PURE__ */ jsx28(
|
|
4451
|
+
Icon,
|
|
4452
|
+
{
|
|
4453
|
+
size: isComposer ? 14 : 12,
|
|
4454
|
+
className: cn(
|
|
4455
|
+
"mt-0.5 shrink-0",
|
|
4456
|
+
isComposer ? "text-muted-foreground" : "text-primary-foreground/80"
|
|
4457
|
+
)
|
|
4458
|
+
}
|
|
4459
|
+
),
|
|
4460
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
|
|
4461
|
+
/* @__PURE__ */ jsx28(
|
|
4462
|
+
"div",
|
|
4463
|
+
{
|
|
4464
|
+
className: cn(
|
|
4465
|
+
"truncate whitespace-pre-wrap",
|
|
4466
|
+
isComposer ? "text-sm" : "text-xs font-medium"
|
|
4467
|
+
),
|
|
4468
|
+
children: getReferenceLabel(reference)
|
|
4469
|
+
}
|
|
4470
|
+
),
|
|
4471
|
+
metaLine && /* @__PURE__ */ jsx28(
|
|
4472
|
+
"div",
|
|
4473
|
+
{
|
|
4474
|
+
className: cn(
|
|
4475
|
+
"truncate whitespace-pre-wrap",
|
|
4476
|
+
isComposer ? "text-xs text-muted-foreground" : "text-[10px] text-primary-foreground/75"
|
|
4477
|
+
),
|
|
4478
|
+
children: metaLine
|
|
4479
|
+
}
|
|
4480
|
+
)
|
|
4481
|
+
] }),
|
|
4482
|
+
onRemove && removeLabel && /* @__PURE__ */ jsx28(
|
|
4483
|
+
"button",
|
|
4484
|
+
{
|
|
4485
|
+
type: "button",
|
|
4486
|
+
onClick: onRemove,
|
|
4487
|
+
className: cn(
|
|
4488
|
+
"ml-1 rounded-full p-0.5",
|
|
4489
|
+
isComposer ? "hover:bg-muted-foreground/20" : "hover:bg-primary-foreground/20"
|
|
4490
|
+
),
|
|
4491
|
+
title: removeLabel,
|
|
4492
|
+
"aria-label": removeLabel,
|
|
4493
|
+
children: /* @__PURE__ */ jsx28(X3, { size: 12 })
|
|
4494
|
+
}
|
|
4495
|
+
)
|
|
4496
|
+
]
|
|
4497
|
+
}
|
|
4498
|
+
);
|
|
4499
|
+
}
|
|
2867
4500
|
function Chat({
|
|
2868
4501
|
className,
|
|
2869
4502
|
options,
|
|
@@ -2880,17 +4513,21 @@ function Chat({
|
|
|
2880
4513
|
const apiUrl = options?.api?.apiUrl || defaultApiUrl2;
|
|
2881
4514
|
const { setStream } = useStreamManager();
|
|
2882
4515
|
const stream = useStreamContext();
|
|
2883
|
-
const
|
|
2884
|
-
const [
|
|
2885
|
-
const [
|
|
2886
|
-
const [
|
|
4516
|
+
const { theme } = useTheme();
|
|
4517
|
+
const [isHistoryLoading, setIsHistoryLoading] = React22.useState(false);
|
|
4518
|
+
const [historyError, setHistoryError] = React22.useState(null);
|
|
4519
|
+
const [assistantName, setAssistantName] = React22.useState(null);
|
|
4520
|
+
const [assistantAvatar, setAssistantAvatar] = React22.useState(null);
|
|
2887
4521
|
const LOADING_DOTS_MIN_DURATION = 800;
|
|
2888
|
-
const
|
|
2889
|
-
const
|
|
2890
|
-
|
|
4522
|
+
const STREAMING_STATUS_REFRESH_MS = 250;
|
|
4523
|
+
const [showLoadingDots, setShowLoadingDots] = React22.useState(false);
|
|
4524
|
+
const [streamingNow, setStreamingNow] = React22.useState(() => Date.now());
|
|
4525
|
+
const loadingStartTimeRef = React22.useRef(null);
|
|
4526
|
+
const lastStreamOutputAtRef = React22.useRef(null);
|
|
4527
|
+
React22.useEffect(() => {
|
|
2891
4528
|
setStream(stream);
|
|
2892
4529
|
}, [setStream, stream]);
|
|
2893
|
-
|
|
4530
|
+
React22.useEffect(() => {
|
|
2894
4531
|
if (stream.isLoading) {
|
|
2895
4532
|
if (!loadingStartTimeRef.current) {
|
|
2896
4533
|
loadingStartTimeRef.current = Date.now();
|
|
@@ -2913,67 +4550,181 @@ function Chat({
|
|
|
2913
4550
|
}
|
|
2914
4551
|
}
|
|
2915
4552
|
}, [stream.isLoading]);
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
4553
|
+
React22.useEffect(() => {
|
|
4554
|
+
if (!stream.isLoading) {
|
|
4555
|
+
lastStreamOutputAtRef.current = null;
|
|
4556
|
+
setStreamingNow(Date.now());
|
|
4557
|
+
return;
|
|
4558
|
+
}
|
|
4559
|
+
const now = Date.now();
|
|
4560
|
+
lastStreamOutputAtRef.current = now;
|
|
4561
|
+
setStreamingNow(now);
|
|
4562
|
+
}, [stream.messages, stream.isLoading]);
|
|
4563
|
+
React22.useEffect(() => {
|
|
4564
|
+
if (!stream.isLoading) {
|
|
4565
|
+
return;
|
|
4566
|
+
}
|
|
4567
|
+
const timer = window.setInterval(() => {
|
|
4568
|
+
setStreamingNow(Date.now());
|
|
4569
|
+
}, STREAMING_STATUS_REFRESH_MS);
|
|
4570
|
+
return () => window.clearInterval(timer);
|
|
4571
|
+
}, [stream.isLoading]);
|
|
4572
|
+
const [draft, setDraft] = React22.useState("");
|
|
4573
|
+
const [selectedTool, setSelectedTool] = React22.useState(
|
|
4574
|
+
null
|
|
4575
|
+
);
|
|
4576
|
+
const [attachments, setAttachments] = React22.useState([]);
|
|
4577
|
+
const [references, setReferences] = React22.useState([]);
|
|
4578
|
+
const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React22.useState(false);
|
|
4579
|
+
const [quoteSelection, setQuoteSelection] = React22.useState(null);
|
|
4580
|
+
const [isAtBottom, setIsAtBottom] = React22.useState(true);
|
|
4581
|
+
const [hasUpdatesBelow, setHasUpdatesBelow] = React22.useState(false);
|
|
2921
4582
|
const {
|
|
2922
4583
|
threads,
|
|
2923
4584
|
deleteThread,
|
|
2924
4585
|
refreshThreads,
|
|
2925
4586
|
isLoading: isThreadsLoading
|
|
2926
4587
|
} = useThreads();
|
|
2927
|
-
const viewportRef =
|
|
2928
|
-
const fileInputRef =
|
|
2929
|
-
const
|
|
2930
|
-
const
|
|
2931
|
-
const
|
|
2932
|
-
const
|
|
2933
|
-
const
|
|
2934
|
-
const
|
|
2935
|
-
const
|
|
4588
|
+
const viewportRef = React22.useRef(null);
|
|
4589
|
+
const fileInputRef = React22.useRef(null);
|
|
4590
|
+
const composerInputRef = React22.useRef(null);
|
|
4591
|
+
const shouldAutoScrollRef = React22.useRef(true);
|
|
4592
|
+
const forceFollowRef = React22.useRef(false);
|
|
4593
|
+
const previousMessageCountRef = React22.useRef(0);
|
|
4594
|
+
const previousScrollTopRef = React22.useRef(0);
|
|
4595
|
+
const autoScrollFrameRef = React22.useRef(null);
|
|
4596
|
+
const isPointerDownRef = React22.useRef(false);
|
|
4597
|
+
const lastTouchYRef = React22.useRef(null);
|
|
2936
4598
|
const resolvedTitle = title ?? t("chat.title");
|
|
2937
4599
|
const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
|
|
2938
4600
|
const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
|
|
2939
|
-
const messages =
|
|
4601
|
+
const messages = React22.useMemo(
|
|
4602
|
+
() => stream.messages ?? [],
|
|
4603
|
+
[stream.messages]
|
|
4604
|
+
);
|
|
2940
4605
|
const trimmedDraft = draft.trim();
|
|
2941
|
-
const
|
|
4606
|
+
const hasReferences = references.length > 0;
|
|
4607
|
+
const pendingFollowUps = React22.useMemo(
|
|
4608
|
+
() => [...stream.pendingFollowUps ?? []].sort(
|
|
4609
|
+
(a, b) => a.createdAt - b.createdAt
|
|
4610
|
+
),
|
|
4611
|
+
[stream.pendingFollowUps]
|
|
4612
|
+
);
|
|
4613
|
+
const clearQuoteSelection = React22.useCallback(() => {
|
|
4614
|
+
setQuoteSelection(null);
|
|
4615
|
+
}, []);
|
|
4616
|
+
useParentMessenger({
|
|
4617
|
+
onSetComposerValue: React22.useCallback(
|
|
4618
|
+
(payload) => {
|
|
4619
|
+
if (!payload) {
|
|
4620
|
+
return;
|
|
4621
|
+
}
|
|
4622
|
+
if (typeof payload.text === "string") {
|
|
4623
|
+
setDraft(payload.text);
|
|
4624
|
+
}
|
|
4625
|
+
if (Array.isArray(payload.references)) {
|
|
4626
|
+
const nextReferences = normalizeReferences(payload.references);
|
|
4627
|
+
setReferences(
|
|
4628
|
+
(previous) => payload.appendReferences ? mergeReferences(previous, nextReferences) : nextReferences
|
|
4629
|
+
);
|
|
4630
|
+
}
|
|
4631
|
+
if (payload.selectedToolId !== void 0) {
|
|
4632
|
+
const nextTool = payload.selectedToolId === null ? null : (composer?.tools ?? []).find(
|
|
4633
|
+
(tool) => tool.id === payload.selectedToolId
|
|
4634
|
+
) ?? null;
|
|
4635
|
+
setSelectedTool(nextTool);
|
|
4636
|
+
}
|
|
4637
|
+
},
|
|
4638
|
+
[composer?.tools]
|
|
4639
|
+
),
|
|
4640
|
+
onFocusComposer: React22.useCallback(() => {
|
|
4641
|
+
composerInputRef.current?.focus();
|
|
4642
|
+
}, [])
|
|
4643
|
+
});
|
|
4644
|
+
const syncQuoteSelection = React22.useCallback(() => {
|
|
4645
|
+
if (typeof window === "undefined") {
|
|
4646
|
+
clearQuoteSelection();
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
const selection = window.getSelection();
|
|
4650
|
+
if (!selection || selection.isCollapsed || selection.rangeCount === 0) {
|
|
4651
|
+
clearQuoteSelection();
|
|
4652
|
+
return;
|
|
4653
|
+
}
|
|
4654
|
+
const text = selection.toString().trim();
|
|
4655
|
+
if (!text) {
|
|
4656
|
+
clearQuoteSelection();
|
|
4657
|
+
return;
|
|
4658
|
+
}
|
|
4659
|
+
const anchorContainer = getClosestQuoteContainer(selection.anchorNode);
|
|
4660
|
+
const focusContainer = getClosestQuoteContainer(selection.focusNode);
|
|
4661
|
+
if (!anchorContainer || !focusContainer || anchorContainer !== focusContainer || !viewportRef.current?.contains(anchorContainer)) {
|
|
4662
|
+
clearQuoteSelection();
|
|
4663
|
+
return;
|
|
4664
|
+
}
|
|
4665
|
+
const range = selection.getRangeAt(0);
|
|
4666
|
+
const rect = range.getBoundingClientRect();
|
|
4667
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
4668
|
+
clearQuoteSelection();
|
|
4669
|
+
return;
|
|
4670
|
+
}
|
|
4671
|
+
const top = rect.bottom + 8 > window.innerHeight - 48 ? Math.max(12, rect.top - 44) : rect.bottom + 8;
|
|
4672
|
+
const left = Math.min(
|
|
4673
|
+
Math.max(24, rect.left + rect.width / 2),
|
|
4674
|
+
window.innerWidth - 24
|
|
4675
|
+
);
|
|
4676
|
+
const source = anchorContainer.dataset.quoteSource?.trim() || void 0;
|
|
4677
|
+
const messageId = anchorContainer.dataset.quoteMessageId?.trim() || void 0;
|
|
4678
|
+
setQuoteSelection({
|
|
4679
|
+
reference: {
|
|
4680
|
+
type: "quote",
|
|
4681
|
+
text,
|
|
4682
|
+
...messageId ? { messageId } : {},
|
|
4683
|
+
...source ? { source, label: source } : {}
|
|
4684
|
+
},
|
|
4685
|
+
top,
|
|
4686
|
+
left
|
|
4687
|
+
});
|
|
4688
|
+
}, [clearQuoteSelection]);
|
|
4689
|
+
const cancelPendingAutoScroll = React22.useCallback(() => {
|
|
2942
4690
|
if (autoScrollFrameRef.current !== null) {
|
|
2943
4691
|
cancelAnimationFrame(autoScrollFrameRef.current);
|
|
2944
4692
|
autoScrollFrameRef.current = null;
|
|
2945
4693
|
}
|
|
2946
4694
|
}, []);
|
|
2947
|
-
const disableAutoFollow =
|
|
4695
|
+
const disableAutoFollow = React22.useCallback(() => {
|
|
2948
4696
|
forceFollowRef.current = false;
|
|
2949
4697
|
shouldAutoScrollRef.current = false;
|
|
2950
4698
|
cancelPendingAutoScroll();
|
|
2951
4699
|
}, [cancelPendingAutoScroll]);
|
|
2952
|
-
const enableAutoFollow =
|
|
4700
|
+
const enableAutoFollow = React22.useCallback(() => {
|
|
2953
4701
|
forceFollowRef.current = true;
|
|
2954
4702
|
shouldAutoScrollRef.current = true;
|
|
2955
4703
|
setHasUpdatesBelow(false);
|
|
2956
4704
|
}, []);
|
|
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
|
-
});
|
|
4705
|
+
const scrollToBottom = React22.useCallback(
|
|
4706
|
+
(smooth = false, force = false) => {
|
|
4707
|
+
if (force) {
|
|
4708
|
+
enableAutoFollow();
|
|
2973
4709
|
}
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
4710
|
+
cancelPendingAutoScroll();
|
|
4711
|
+
autoScrollFrameRef.current = requestAnimationFrame(() => {
|
|
4712
|
+
autoScrollFrameRef.current = null;
|
|
4713
|
+
const viewport = viewportRef.current;
|
|
4714
|
+
if (viewport) {
|
|
4715
|
+
if (!force && !shouldAutoScrollRef.current) {
|
|
4716
|
+
return;
|
|
4717
|
+
}
|
|
4718
|
+
viewport.scrollTo({
|
|
4719
|
+
top: viewport.scrollHeight,
|
|
4720
|
+
behavior: smooth ? "smooth" : "instant"
|
|
4721
|
+
});
|
|
4722
|
+
}
|
|
4723
|
+
});
|
|
4724
|
+
},
|
|
4725
|
+
[cancelPendingAutoScroll, enableAutoFollow]
|
|
4726
|
+
);
|
|
4727
|
+
React22.useEffect(() => {
|
|
2977
4728
|
const viewport = viewportRef.current;
|
|
2978
4729
|
if (!viewport) return;
|
|
2979
4730
|
previousScrollTopRef.current = viewport.scrollTop;
|
|
@@ -3025,13 +4776,23 @@ function Chat({
|
|
|
3025
4776
|
};
|
|
3026
4777
|
updateAutoScrollState();
|
|
3027
4778
|
viewport.addEventListener("wheel", handleWheel, { passive: true });
|
|
3028
|
-
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
3029
|
-
|
|
3030
|
-
|
|
4779
|
+
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
4780
|
+
passive: true
|
|
4781
|
+
});
|
|
4782
|
+
viewport.addEventListener("scroll", updateAutoScrollState, {
|
|
4783
|
+
passive: true
|
|
4784
|
+
});
|
|
4785
|
+
viewport.addEventListener("touchstart", handleTouchStart, {
|
|
4786
|
+
passive: true
|
|
4787
|
+
});
|
|
3031
4788
|
viewport.addEventListener("touchmove", handleTouchMove, { passive: true });
|
|
3032
4789
|
viewport.addEventListener("touchend", handleTouchEnd, { passive: true });
|
|
3033
|
-
window.addEventListener("pointerup", stopPointerTracking, {
|
|
3034
|
-
|
|
4790
|
+
window.addEventListener("pointerup", stopPointerTracking, {
|
|
4791
|
+
passive: true
|
|
4792
|
+
});
|
|
4793
|
+
window.addEventListener("pointercancel", stopPointerTracking, {
|
|
4794
|
+
passive: true
|
|
4795
|
+
});
|
|
3035
4796
|
return () => {
|
|
3036
4797
|
cancelPendingAutoScroll();
|
|
3037
4798
|
viewport.removeEventListener("wheel", handleWheel);
|
|
@@ -3044,14 +4805,14 @@ function Chat({
|
|
|
3044
4805
|
window.removeEventListener("pointercancel", stopPointerTracking);
|
|
3045
4806
|
};
|
|
3046
4807
|
}, [cancelPendingAutoScroll, disableAutoFollow]);
|
|
3047
|
-
|
|
4808
|
+
React22.useEffect(() => {
|
|
3048
4809
|
shouldAutoScrollRef.current = true;
|
|
3049
4810
|
forceFollowRef.current = false;
|
|
3050
4811
|
previousScrollTopRef.current = 0;
|
|
3051
4812
|
setIsAtBottom(true);
|
|
3052
4813
|
setHasUpdatesBelow(false);
|
|
3053
4814
|
}, [stream.threadId]);
|
|
3054
|
-
|
|
4815
|
+
React22.useEffect(() => {
|
|
3055
4816
|
const messageCountChanged = messages.length !== previousMessageCountRef.current;
|
|
3056
4817
|
previousMessageCountRef.current = messages.length;
|
|
3057
4818
|
if (!shouldAutoScrollRef.current) {
|
|
@@ -3065,16 +4826,85 @@ function Chat({
|
|
|
3065
4826
|
}
|
|
3066
4827
|
}, [stream.isLoading, messages, scrollToBottom]);
|
|
3067
4828
|
const effectiveClientSecret = stream.apiKey?.trim() ? stream.apiKey : clientSecret;
|
|
3068
|
-
const
|
|
3069
|
-
|
|
4829
|
+
const missingConfigKind = getMissingApiConfigurationKind({
|
|
4830
|
+
apiUrl,
|
|
4831
|
+
clientSecret: effectiveClientSecret
|
|
4832
|
+
});
|
|
4833
|
+
const missingConfig = Boolean(missingConfigKind);
|
|
4834
|
+
const missingConfigShortMessage = React22.useMemo(() => {
|
|
4835
|
+
switch (missingConfigKind) {
|
|
4836
|
+
case "apiUrl":
|
|
4837
|
+
return t("chat.missingApiUrlShort");
|
|
4838
|
+
case "clientSecret":
|
|
4839
|
+
return t("chat.missingClientSecretShort");
|
|
4840
|
+
case "apiUrlAndClientSecret":
|
|
4841
|
+
return t("chat.missingApiUrlAndClientSecretShort");
|
|
4842
|
+
default:
|
|
4843
|
+
return t("chat.missingConfigShort");
|
|
4844
|
+
}
|
|
4845
|
+
}, [missingConfigKind, t]);
|
|
4846
|
+
const missingConfigDetailMessage = React22.useMemo(() => {
|
|
4847
|
+
switch (missingConfigKind) {
|
|
4848
|
+
case "apiUrl":
|
|
4849
|
+
return t("chat.missingApiUrlDetail");
|
|
4850
|
+
case "clientSecret":
|
|
4851
|
+
return t("chat.missingClientSecretDetail");
|
|
4852
|
+
case "apiUrlAndClientSecret":
|
|
4853
|
+
return t("chat.missingApiUrlAndClientSecretDetail");
|
|
4854
|
+
default:
|
|
4855
|
+
return t("chat.missingConfigDetail");
|
|
4856
|
+
}
|
|
4857
|
+
}, [missingConfigKind, t]);
|
|
3070
4858
|
const showMissingConfig = !isClientSecretInitializing && missingConfig;
|
|
3071
4859
|
const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
|
|
3072
|
-
const isSendDisabled = !trimmedDraft
|
|
3073
|
-
|
|
4860
|
+
const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
|
|
4861
|
+
const resizeComposerInput = React22.useCallback(() => {
|
|
4862
|
+
const textarea = composerInputRef.current;
|
|
4863
|
+
if (!textarea) {
|
|
4864
|
+
return;
|
|
4865
|
+
}
|
|
4866
|
+
textarea.style.height = "auto";
|
|
4867
|
+
const nextHeight = Math.min(
|
|
4868
|
+
textarea.scrollHeight,
|
|
4869
|
+
COMPOSER_INPUT_MAX_HEIGHT
|
|
4870
|
+
);
|
|
4871
|
+
textarea.style.height = `${nextHeight}px`;
|
|
4872
|
+
textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
|
|
4873
|
+
}, []);
|
|
4874
|
+
React22.useEffect(() => {
|
|
4875
|
+
resizeComposerInput();
|
|
4876
|
+
}, [draft, resizeComposerInput]);
|
|
4877
|
+
React22.useEffect(() => {
|
|
4878
|
+
document.addEventListener("selectionchange", syncQuoteSelection);
|
|
4879
|
+
return () => {
|
|
4880
|
+
document.removeEventListener("selectionchange", syncQuoteSelection);
|
|
4881
|
+
};
|
|
4882
|
+
}, [syncQuoteSelection]);
|
|
4883
|
+
React22.useEffect(() => {
|
|
4884
|
+
const viewport = viewportRef.current;
|
|
4885
|
+
if (!viewport) {
|
|
4886
|
+
return;
|
|
4887
|
+
}
|
|
4888
|
+
const handleViewportScroll = () => {
|
|
4889
|
+
clearQuoteSelection();
|
|
4890
|
+
};
|
|
4891
|
+
viewport.addEventListener("scroll", handleViewportScroll, {
|
|
4892
|
+
passive: true
|
|
4893
|
+
});
|
|
4894
|
+
window.addEventListener("resize", handleViewportScroll, { passive: true });
|
|
4895
|
+
return () => {
|
|
4896
|
+
viewport.removeEventListener("scroll", handleViewportScroll);
|
|
4897
|
+
window.removeEventListener("resize", handleViewportScroll);
|
|
4898
|
+
};
|
|
4899
|
+
}, [clearQuoteSelection]);
|
|
4900
|
+
React22.useEffect(() => {
|
|
4901
|
+
clearQuoteSelection();
|
|
4902
|
+
}, [messages.length, stream.threadId, clearQuoteSelection]);
|
|
4903
|
+
React22.useEffect(() => {
|
|
3074
4904
|
if (missingConfig) return;
|
|
3075
4905
|
void refreshThreads();
|
|
3076
4906
|
}, [missingConfig, refreshThreads]);
|
|
3077
|
-
|
|
4907
|
+
React22.useEffect(() => {
|
|
3078
4908
|
if (missingConfig || !stream.client || !stream.assistantId) {
|
|
3079
4909
|
setAssistantName(null);
|
|
3080
4910
|
setAssistantAvatar(null);
|
|
@@ -3105,80 +4935,275 @@ function Chat({
|
|
|
3105
4935
|
mimetype: a.storageFile?.mimetype ?? a.file.type,
|
|
3106
4936
|
size: a.storageFile?.size ?? a.file.size
|
|
3107
4937
|
}));
|
|
4938
|
+
const submitDraft = React22.useCallback(
|
|
4939
|
+
(followUpOverride) => {
|
|
4940
|
+
if (isSendDisabled) return;
|
|
4941
|
+
const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
|
|
4942
|
+
const referencesToSend = references.length > 0 ? [...references] : void 0;
|
|
4943
|
+
const nextFollowUpMode = stream.isLoading ? followUpOverride ?? stream.followUpBehavior : void 0;
|
|
4944
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
4945
|
+
content: trimmedDraft,
|
|
4946
|
+
references: referencesToSend
|
|
4947
|
+
});
|
|
4948
|
+
if (!humanInput) {
|
|
4949
|
+
return;
|
|
4950
|
+
}
|
|
4951
|
+
const displayContent = trimmedDraft || (referencesToSend ? t("chat.referencedContentOnly") : "");
|
|
4952
|
+
const newMessage = {
|
|
4953
|
+
id: createMessageId(),
|
|
4954
|
+
type: "human",
|
|
4955
|
+
content: displayContent,
|
|
4956
|
+
submittedInput: humanInput.input,
|
|
4957
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
4958
|
+
...filesToSend ? { attachments: filesToSend } : {},
|
|
4959
|
+
...referencesToSend ? { references: referencesToSend } : {}
|
|
4960
|
+
};
|
|
4961
|
+
setDraft("");
|
|
4962
|
+
const inputPayload = {
|
|
4963
|
+
...humanInput
|
|
4964
|
+
};
|
|
4965
|
+
if (filesToSend) {
|
|
4966
|
+
inputPayload.files = filesToSend;
|
|
4967
|
+
}
|
|
4968
|
+
const requestOptions = buildInjectedRequestOptions({
|
|
4969
|
+
defaults: options?.request,
|
|
4970
|
+
humanInput: inputPayload
|
|
4971
|
+
});
|
|
4972
|
+
stream.submit(
|
|
4973
|
+
{
|
|
4974
|
+
input: inputPayload,
|
|
4975
|
+
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
4976
|
+
},
|
|
4977
|
+
{
|
|
4978
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
4979
|
+
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
4980
|
+
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
4981
|
+
...!nextFollowUpMode ? {
|
|
4982
|
+
optimisticValues: (prev) => {
|
|
4983
|
+
const prevMessages = prev?.messages ?? [];
|
|
4984
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
4985
|
+
}
|
|
4986
|
+
} : {}
|
|
4987
|
+
}
|
|
4988
|
+
);
|
|
4989
|
+
scrollToBottom(true, true);
|
|
4990
|
+
if (selectedTool && !selectedTool.pinned) {
|
|
4991
|
+
setSelectedTool(null);
|
|
4992
|
+
}
|
|
4993
|
+
setAttachments([]);
|
|
4994
|
+
setReferences([]);
|
|
4995
|
+
},
|
|
4996
|
+
[
|
|
4997
|
+
isSendDisabled,
|
|
4998
|
+
options?.request,
|
|
4999
|
+
references,
|
|
5000
|
+
scrollToBottom,
|
|
5001
|
+
selectedTool,
|
|
5002
|
+
stream,
|
|
5003
|
+
trimmedDraft,
|
|
5004
|
+
uploadedFiles,
|
|
5005
|
+
t
|
|
5006
|
+
]
|
|
5007
|
+
);
|
|
3108
5008
|
const handleSubmit = (event) => {
|
|
3109
5009
|
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
|
-
}
|
|
5010
|
+
submitDraft();
|
|
5011
|
+
};
|
|
5012
|
+
const handleEditPendingFollowUp = React22.useCallback(
|
|
5013
|
+
(id) => {
|
|
5014
|
+
const item = pendingFollowUps.find(
|
|
5015
|
+
(entry) => entry.id === id && entry.mode === "queue"
|
|
5016
|
+
);
|
|
5017
|
+
if (!item) {
|
|
5018
|
+
return;
|
|
3141
5019
|
}
|
|
5020
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
5021
|
+
const nextReferences = normalizeReferences(
|
|
5022
|
+
item.request?.input?.references
|
|
5023
|
+
);
|
|
5024
|
+
stream.removePendingFollowUp(id);
|
|
5025
|
+
setDraft(text);
|
|
5026
|
+
setReferences(nextReferences);
|
|
5027
|
+
requestAnimationFrame(() => {
|
|
5028
|
+
const input = composerInputRef.current;
|
|
5029
|
+
if (!input) {
|
|
5030
|
+
return;
|
|
5031
|
+
}
|
|
5032
|
+
input.focus();
|
|
5033
|
+
const position = text.length;
|
|
5034
|
+
input.setSelectionRange(position, position);
|
|
5035
|
+
});
|
|
5036
|
+
},
|
|
5037
|
+
[pendingFollowUps, stream]
|
|
5038
|
+
);
|
|
5039
|
+
const handleQuoteSelection = React22.useCallback(() => {
|
|
5040
|
+
if (!quoteSelection) {
|
|
5041
|
+
return;
|
|
5042
|
+
}
|
|
5043
|
+
setReferences(
|
|
5044
|
+
(previous) => mergeReferences(previous, [quoteSelection.reference])
|
|
3142
5045
|
);
|
|
3143
|
-
|
|
3144
|
-
if (
|
|
3145
|
-
|
|
5046
|
+
clearQuoteSelection();
|
|
5047
|
+
if (typeof window !== "undefined") {
|
|
5048
|
+
window.getSelection()?.removeAllRanges();
|
|
3146
5049
|
}
|
|
3147
|
-
|
|
3148
|
-
};
|
|
5050
|
+
composerInputRef.current?.focus();
|
|
5051
|
+
}, [clearQuoteSelection, quoteSelection]);
|
|
3149
5052
|
const handleAttachmentClick = () => {
|
|
3150
5053
|
fileInputRef.current?.click();
|
|
3151
5054
|
};
|
|
3152
|
-
const
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
5055
|
+
const uploadContextFile = React22.useCallback(
|
|
5056
|
+
(file) => stream.client.contexts.uploadFile(file),
|
|
5057
|
+
[stream.client]
|
|
5058
|
+
);
|
|
5059
|
+
const handleComposerKeyDown = (event) => {
|
|
5060
|
+
if (event.key !== "Enter") {
|
|
5061
|
+
return;
|
|
5062
|
+
}
|
|
5063
|
+
if (event.shiftKey) {
|
|
5064
|
+
return;
|
|
5065
|
+
}
|
|
5066
|
+
if (event.nativeEvent.isComposing) {
|
|
5067
|
+
return;
|
|
5068
|
+
}
|
|
5069
|
+
event.preventDefault();
|
|
5070
|
+
if (isSendDisabled) {
|
|
5071
|
+
return;
|
|
5072
|
+
}
|
|
5073
|
+
if (stream.isLoading) {
|
|
5074
|
+
submitDraft(
|
|
5075
|
+
getBusyComposerShortcutFollowUpMode(event.metaKey || event.ctrlKey)
|
|
5076
|
+
);
|
|
5077
|
+
return;
|
|
5078
|
+
}
|
|
5079
|
+
submitDraft();
|
|
5080
|
+
};
|
|
5081
|
+
const handleComposerPaste = React22.useCallback(
|
|
5082
|
+
(event) => {
|
|
5083
|
+
const clipboardData = event.clipboardData;
|
|
5084
|
+
if (!clipboardData) {
|
|
5085
|
+
return;
|
|
5086
|
+
}
|
|
5087
|
+
const imageFiles = Array.from(clipboardData.items).filter(
|
|
5088
|
+
(item) => item.kind === "file" && item.type.startsWith("image/")
|
|
5089
|
+
).map((item) => item.getAsFile()).filter((item) => Boolean(item));
|
|
5090
|
+
if (imageFiles.length > 0) {
|
|
5091
|
+
event.preventDefault();
|
|
5092
|
+
const maxCount = composer?.attachments?.maxCount ?? 10;
|
|
5093
|
+
const maxSize = composer?.attachments?.maxSize ?? 100 * 1024 * 1024;
|
|
5094
|
+
const currentImageReferenceCount = references.filter(
|
|
5095
|
+
(reference) => reference.type === "image"
|
|
5096
|
+
).length;
|
|
5097
|
+
const availableSlots = Math.max(
|
|
5098
|
+
0,
|
|
5099
|
+
maxCount - currentImageReferenceCount
|
|
5100
|
+
);
|
|
5101
|
+
const nextFiles = imageFiles.filter((file) => file.size <= maxSize).slice(0, availableSlots);
|
|
5102
|
+
if (nextFiles.length === 0) {
|
|
5103
|
+
return;
|
|
5104
|
+
}
|
|
5105
|
+
setIsUploadingReferenceImages(true);
|
|
5106
|
+
void Promise.allSettled(
|
|
5107
|
+
nextFiles.map(async (file) => {
|
|
5108
|
+
const [dimensions, storageFile] = await Promise.all([
|
|
5109
|
+
readImageDimensions(file),
|
|
5110
|
+
uploadContextFile(file)
|
|
5111
|
+
]);
|
|
5112
|
+
return buildPastedImageReference(file, storageFile, dimensions);
|
|
5113
|
+
})
|
|
5114
|
+
).then((results) => {
|
|
5115
|
+
const nextReferences = results.filter(
|
|
5116
|
+
(result) => result.status === "fulfilled"
|
|
5117
|
+
).map((result) => result.value);
|
|
5118
|
+
if (nextReferences.length > 0) {
|
|
5119
|
+
setReferences(
|
|
5120
|
+
(previous) => mergeReferences(previous, nextReferences)
|
|
5121
|
+
);
|
|
5122
|
+
composerInputRef.current?.focus();
|
|
5123
|
+
}
|
|
5124
|
+
results.filter(
|
|
5125
|
+
(result) => result.status === "rejected"
|
|
5126
|
+
).forEach((result) => {
|
|
5127
|
+
console.warn(
|
|
5128
|
+
"[Chat] Failed to upload pasted image reference:",
|
|
5129
|
+
result.reason
|
|
5130
|
+
);
|
|
5131
|
+
});
|
|
5132
|
+
}).finally(() => {
|
|
5133
|
+
setIsUploadingReferenceImages(false);
|
|
5134
|
+
});
|
|
5135
|
+
return;
|
|
5136
|
+
}
|
|
5137
|
+
const pastedText = clipboardData.getData("text/plain");
|
|
5138
|
+
if (pastedText.trim().length <= LONG_TEXT_REFERENCE_THRESHOLD) {
|
|
5139
|
+
return;
|
|
5140
|
+
}
|
|
5141
|
+
event.preventDefault();
|
|
5142
|
+
setReferences(
|
|
5143
|
+
(previous) => mergeReferences(previous, [
|
|
5144
|
+
{
|
|
5145
|
+
type: "quote",
|
|
5146
|
+
source: "Pasted text",
|
|
5147
|
+
text: pastedText
|
|
5148
|
+
}
|
|
5149
|
+
])
|
|
3159
5150
|
);
|
|
3160
|
-
|
|
5151
|
+
composerInputRef.current?.focus();
|
|
5152
|
+
},
|
|
5153
|
+
[
|
|
5154
|
+
composer?.attachments?.maxCount,
|
|
5155
|
+
composer?.attachments?.maxSize,
|
|
5156
|
+
references,
|
|
5157
|
+
uploadContextFile
|
|
5158
|
+
]
|
|
5159
|
+
);
|
|
5160
|
+
const alternateFollowUpShortcutLabel = React22.useMemo(() => {
|
|
5161
|
+
if (typeof navigator === "undefined") {
|
|
5162
|
+
return "\u2318Enter";
|
|
5163
|
+
}
|
|
5164
|
+
const platform = navigator.platform || navigator.userAgent;
|
|
5165
|
+
return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
|
|
5166
|
+
}, []);
|
|
5167
|
+
const followUpShortcutLabels = React22.useMemo(
|
|
5168
|
+
() => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
|
|
5169
|
+
[alternateFollowUpShortcutLabel]
|
|
5170
|
+
);
|
|
5171
|
+
const uploadFile = React22.useCallback(
|
|
5172
|
+
async (localId, file) => {
|
|
5173
|
+
try {
|
|
5174
|
+
const result = await uploadContextFile(file);
|
|
5175
|
+
setAttachments(
|
|
5176
|
+
(prev) => prev.map(
|
|
5177
|
+
(item) => item.localId === localId ? { ...item, status: "success", storageFile: result } : item
|
|
5178
|
+
)
|
|
5179
|
+
);
|
|
5180
|
+
} catch (error) {
|
|
5181
|
+
setAttachments(
|
|
5182
|
+
(prev) => prev.map(
|
|
5183
|
+
(item) => item.localId === localId ? {
|
|
5184
|
+
...item,
|
|
5185
|
+
status: "error",
|
|
5186
|
+
error: error instanceof Error ? error.message : "Upload failed"
|
|
5187
|
+
} : item
|
|
5188
|
+
)
|
|
5189
|
+
);
|
|
5190
|
+
}
|
|
5191
|
+
},
|
|
5192
|
+
[uploadContextFile]
|
|
5193
|
+
);
|
|
5194
|
+
const handleRetryUpload = React22.useCallback(
|
|
5195
|
+
(localId) => {
|
|
5196
|
+
const attachment = attachments.find((a) => a.localId === localId);
|
|
5197
|
+
if (!attachment || attachment.status !== "error") return;
|
|
3161
5198
|
setAttachments(
|
|
3162
5199
|
(prev) => prev.map(
|
|
3163
|
-
(item) => item.localId === localId ? {
|
|
3164
|
-
...item,
|
|
3165
|
-
status: "error",
|
|
3166
|
-
error: error instanceof Error ? error.message : "Upload failed"
|
|
3167
|
-
} : item
|
|
5200
|
+
(item) => item.localId === localId ? { ...item, status: "uploading", error: void 0 } : item
|
|
3168
5201
|
)
|
|
3169
5202
|
);
|
|
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]);
|
|
5203
|
+
void uploadFile(localId, attachment.file);
|
|
5204
|
+
},
|
|
5205
|
+
[attachments, uploadFile]
|
|
5206
|
+
);
|
|
3182
5207
|
const handleFileChange = (event) => {
|
|
3183
5208
|
const files = event.target.files;
|
|
3184
5209
|
if (!files || files.length === 0) return;
|
|
@@ -3212,12 +5237,15 @@ function Chat({
|
|
|
3212
5237
|
if (!attachment) return;
|
|
3213
5238
|
if (attachment.status === "success" && attachment.storageFile?.id) {
|
|
3214
5239
|
try {
|
|
3215
|
-
await fetch(
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
"
|
|
5240
|
+
await fetch(
|
|
5241
|
+
`${stream.apiUrl}/contexts/file/${attachment.storageFile.id}`,
|
|
5242
|
+
{
|
|
5243
|
+
method: "DELETE",
|
|
5244
|
+
headers: {
|
|
5245
|
+
Authorization: `Bearer ${effectiveClientSecret}`
|
|
5246
|
+
}
|
|
3219
5247
|
}
|
|
3220
|
-
|
|
5248
|
+
);
|
|
3221
5249
|
} catch {
|
|
3222
5250
|
}
|
|
3223
5251
|
}
|
|
@@ -3227,27 +5255,31 @@ function Chat({
|
|
|
3227
5255
|
setSelectedTool((prev) => prev?.id === tool.id ? null : tool);
|
|
3228
5256
|
};
|
|
3229
5257
|
const handlePromptClick = (prompt) => {
|
|
3230
|
-
if (missingConfig ||
|
|
5258
|
+
if (missingConfig || isHistoryLoading) return;
|
|
3231
5259
|
const newMessage = {
|
|
3232
5260
|
id: createMessageId(),
|
|
3233
5261
|
type: "human",
|
|
3234
5262
|
content: prompt
|
|
3235
5263
|
};
|
|
5264
|
+
const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
|
|
3236
5265
|
stream.submit(
|
|
3237
5266
|
{ input: { input: prompt } },
|
|
3238
5267
|
{
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
5268
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
5269
|
+
...!nextFollowUpMode ? {
|
|
5270
|
+
optimisticValues: (prev) => {
|
|
5271
|
+
const prevMessages = prev?.messages ?? [];
|
|
5272
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
5273
|
+
}
|
|
5274
|
+
} : {}
|
|
3243
5275
|
}
|
|
3244
5276
|
);
|
|
3245
5277
|
scrollToBottom(true, true);
|
|
3246
5278
|
};
|
|
3247
|
-
const loadConversationMessages =
|
|
5279
|
+
const loadConversationMessages = React22.useCallback(
|
|
3248
5280
|
async (recordId) => {
|
|
3249
5281
|
if (missingConfig) {
|
|
3250
|
-
setHistoryError(
|
|
5282
|
+
setHistoryError(missingConfigShortMessage);
|
|
3251
5283
|
return;
|
|
3252
5284
|
}
|
|
3253
5285
|
setHistoryError(null);
|
|
@@ -3263,7 +5295,7 @@ function Chat({
|
|
|
3263
5295
|
setIsHistoryLoading(false);
|
|
3264
5296
|
}
|
|
3265
5297
|
},
|
|
3266
|
-
[missingConfig, stream, t]
|
|
5298
|
+
[missingConfig, missingConfigShortMessage, stream, t]
|
|
3267
5299
|
);
|
|
3268
5300
|
const handleNewThread = async () => {
|
|
3269
5301
|
if (missingConfig || isHistoryLoading) return;
|
|
@@ -3306,12 +5338,16 @@ function Chat({
|
|
|
3306
5338
|
};
|
|
3307
5339
|
const handleRetry = (messageIndex) => {
|
|
3308
5340
|
const messagesUpToIndex = messages.slice(0, messageIndex);
|
|
3309
|
-
const lastHumanMessage = [...messagesUpToIndex].reverse().find(
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
5341
|
+
const lastHumanMessage = [...messagesUpToIndex].reverse().find((m) => String(m.type) === "human");
|
|
5342
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
5343
|
+
content: lastHumanMessage && typeof lastHumanMessage.content === "string" ? lastHumanMessage.content : "",
|
|
5344
|
+
submittedInput: lastHumanMessage?.submittedInput,
|
|
5345
|
+
references: lastHumanMessage?.references,
|
|
5346
|
+
referenceComposition: lastHumanMessage?.referenceComposition
|
|
5347
|
+
});
|
|
5348
|
+
if (humanInput) {
|
|
3313
5349
|
stream.submit(
|
|
3314
|
-
{ input:
|
|
5350
|
+
{ input: humanInput },
|
|
3315
5351
|
{
|
|
3316
5352
|
optimisticValues: (prev) => {
|
|
3317
5353
|
const prevMessages = prev?.messages ?? [];
|
|
@@ -3326,18 +5362,18 @@ function Chat({
|
|
|
3326
5362
|
}
|
|
3327
5363
|
};
|
|
3328
5364
|
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 =
|
|
5365
|
+
const currentThread = React22.useMemo(
|
|
3330
5366
|
() => threads.find((item) => item.id === stream.threadId),
|
|
3331
5367
|
[threads, stream.threadId]
|
|
3332
5368
|
);
|
|
3333
5369
|
const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
|
|
3334
|
-
const threadErrorMessage =
|
|
5370
|
+
const threadErrorMessage = React22.useMemo(() => {
|
|
3335
5371
|
if (currentThread?.status !== "error") return void 0;
|
|
3336
5372
|
const message = currentThread.error?.trim();
|
|
3337
5373
|
return message || t("thread.errorToast");
|
|
3338
5374
|
}, [currentThread, t]);
|
|
3339
5375
|
const assistantTitle = assistantName || resolvedTitle;
|
|
3340
|
-
return /* @__PURE__ */
|
|
5376
|
+
return /* @__PURE__ */ jsxs17(
|
|
3341
5377
|
"div",
|
|
3342
5378
|
{
|
|
3343
5379
|
ref: viewportRef,
|
|
@@ -3346,10 +5382,10 @@ function Chat({
|
|
|
3346
5382
|
className
|
|
3347
5383
|
),
|
|
3348
5384
|
children: [
|
|
3349
|
-
/* @__PURE__ */
|
|
3350
|
-
/* @__PURE__ */
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
5385
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
|
|
5386
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3 overflow-hidden", children: [
|
|
5387
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative shrink-0", children: [
|
|
5388
|
+
/* @__PURE__ */ jsx28(
|
|
3353
5389
|
ChatkitAvatar,
|
|
3354
5390
|
{
|
|
3355
5391
|
avatar: assistantAvatar,
|
|
@@ -3357,15 +5393,22 @@ function Chat({
|
|
|
3357
5393
|
label: assistantTitle
|
|
3358
5394
|
}
|
|
3359
5395
|
),
|
|
3360
|
-
/* @__PURE__ */
|
|
5396
|
+
/* @__PURE__ */ jsx28("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
|
|
3361
5397
|
] }),
|
|
3362
|
-
/* @__PURE__ */
|
|
3363
|
-
/* @__PURE__ */
|
|
3364
|
-
|
|
5398
|
+
/* @__PURE__ */ jsxs17("div", { className: "truncate", children: [
|
|
5399
|
+
/* @__PURE__ */ jsx28(
|
|
5400
|
+
"h2",
|
|
5401
|
+
{
|
|
5402
|
+
className: "text-lg font-semibold truncate",
|
|
5403
|
+
title: assistantTitle,
|
|
5404
|
+
children: assistantTitle
|
|
5405
|
+
}
|
|
5406
|
+
),
|
|
5407
|
+
/* @__PURE__ */ jsx28("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
|
|
3365
5408
|
] })
|
|
3366
5409
|
] }),
|
|
3367
|
-
history?.enabled !== false && /* @__PURE__ */
|
|
3368
|
-
/* @__PURE__ */
|
|
5410
|
+
history?.enabled !== false && /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1", children: [
|
|
5411
|
+
/* @__PURE__ */ jsx28(
|
|
3369
5412
|
"button",
|
|
3370
5413
|
{
|
|
3371
5414
|
type: "button",
|
|
@@ -3378,10 +5421,10 @@ function Chat({
|
|
|
3378
5421
|
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
3379
5422
|
),
|
|
3380
5423
|
title: t("history.newThread"),
|
|
3381
|
-
children: /* @__PURE__ */
|
|
5424
|
+
children: /* @__PURE__ */ jsx28(Pencil3, { size: 16 })
|
|
3382
5425
|
}
|
|
3383
5426
|
),
|
|
3384
|
-
/* @__PURE__ */
|
|
5427
|
+
/* @__PURE__ */ jsx28(
|
|
3385
5428
|
HistorySidebar,
|
|
3386
5429
|
{
|
|
3387
5430
|
threads,
|
|
@@ -3395,23 +5438,45 @@ function Chat({
|
|
|
3395
5438
|
)
|
|
3396
5439
|
] })
|
|
3397
5440
|
] }),
|
|
3398
|
-
/* @__PURE__ */
|
|
3399
|
-
errorMessage && /* @__PURE__ */
|
|
3400
|
-
historyError && /* @__PURE__ */
|
|
3401
|
-
showMissingConfig && /* @__PURE__ */
|
|
3402
|
-
isHistoryLoading && /* @__PURE__ */
|
|
3403
|
-
messages.length === 0 ? /* @__PURE__ */
|
|
5441
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex-1 p-4", children: [
|
|
5442
|
+
errorMessage && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
|
|
5443
|
+
historyError && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
|
|
5444
|
+
showMissingConfig && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
|
|
5445
|
+
isHistoryLoading && /* @__PURE__ */ jsx28("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
|
|
5446
|
+
messages.length === 0 ? /* @__PURE__ */ jsx28(
|
|
3404
5447
|
StartScreen,
|
|
3405
5448
|
{
|
|
3406
5449
|
startScreen,
|
|
3407
5450
|
onPromptClick: handlePromptClick
|
|
3408
5451
|
}
|
|
3409
|
-
) : /* @__PURE__ */
|
|
5452
|
+
) : /* @__PURE__ */ jsxs17("div", { className: "space-y-4", children: [
|
|
3410
5453
|
messages.map((message, index) => {
|
|
3411
5454
|
const messageType = String(message.type);
|
|
3412
5455
|
const isAssistantMessage = messageType === "assistant" || messageType === "ai";
|
|
5456
|
+
const isStreamingMessage = stream.isLoading && index === messages.length - 1;
|
|
5457
|
+
const streamingStatus = isAssistantMessage ? getAssistantStreamingStatus(
|
|
5458
|
+
{
|
|
5459
|
+
...message,
|
|
5460
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5461
|
+
},
|
|
5462
|
+
isStreamingMessage,
|
|
5463
|
+
{ now: streamingNow }
|
|
5464
|
+
) : null;
|
|
5465
|
+
if (isAssistantMessage && !hasRenderableAssistantMessage(message) && !streamingStatus) {
|
|
5466
|
+
return null;
|
|
5467
|
+
}
|
|
3413
5468
|
const messageContent = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.map((part) => formatMessageContent(part)).join("") : formatMessageContent(message.content);
|
|
3414
|
-
|
|
5469
|
+
const hasPlainRenderableContent = messageContent.trim().length > 0;
|
|
5470
|
+
const humanMessage = message;
|
|
5471
|
+
const humanReferences = humanMessage.references ?? [];
|
|
5472
|
+
const humanAttachments = humanMessage.attachments ?? [];
|
|
5473
|
+
const hasHumanAttachments = message.type === "human" && humanAttachments.length > 0;
|
|
5474
|
+
const canQuoteMessage = message.type === "human" || isAssistantMessage;
|
|
5475
|
+
const quoteSource = message.type === "human" ? t("chat.youLabel") : assistantTitle;
|
|
5476
|
+
if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
|
|
5477
|
+
return null;
|
|
5478
|
+
}
|
|
5479
|
+
return /* @__PURE__ */ jsx28(
|
|
3415
5480
|
"div",
|
|
3416
5481
|
{
|
|
3417
5482
|
className: cn(
|
|
@@ -3419,53 +5484,66 @@ function Chat({
|
|
|
3419
5484
|
message.type === "human" ? "justify-end" : "justify-start -ml-1"
|
|
3420
5485
|
// AI messages: slightly closer to left
|
|
3421
5486
|
),
|
|
3422
|
-
children: /* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
5487
|
+
children: /* @__PURE__ */ jsxs17("div", { className: "flex flex-col px-3 overflow-hidden", children: [
|
|
5488
|
+
/* @__PURE__ */ jsx28(
|
|
3424
5489
|
"div",
|
|
3425
5490
|
{
|
|
5491
|
+
...canQuoteMessage ? {
|
|
5492
|
+
"data-quote-message-id": message.id,
|
|
5493
|
+
"data-quote-source": quoteSource
|
|
5494
|
+
} : {},
|
|
3426
5495
|
className: cn(
|
|
3427
5496
|
"max-w-full rounded-2xl",
|
|
3428
5497
|
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
5498
|
// AI messages: use chat-specific foreground color
|
|
3430
5499
|
),
|
|
3431
|
-
children: isAssistantMessage ? /* @__PURE__ */
|
|
5500
|
+
children: isAssistantMessage ? /* @__PURE__ */ jsx28(
|
|
3432
5501
|
AssistantMessage,
|
|
3433
5502
|
{
|
|
3434
5503
|
message: {
|
|
3435
5504
|
...message,
|
|
3436
5505
|
type: "assistant"
|
|
3437
5506
|
},
|
|
3438
|
-
isStreaming:
|
|
5507
|
+
isStreaming: isStreamingMessage,
|
|
5508
|
+
streamingStatus
|
|
3439
5509
|
}
|
|
3440
|
-
) : /* @__PURE__ */
|
|
3441
|
-
message.type === "human" &&
|
|
5510
|
+
) : /* @__PURE__ */ jsxs17(Fragment4, { children: [
|
|
5511
|
+
message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ jsx28(
|
|
5512
|
+
ReferenceChip,
|
|
5513
|
+
{
|
|
5514
|
+
reference,
|
|
5515
|
+
variant: "message"
|
|
5516
|
+
},
|
|
5517
|
+
getReferenceKey(reference)
|
|
5518
|
+
)) }),
|
|
5519
|
+
message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ jsx28("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ jsxs17(
|
|
3442
5520
|
"div",
|
|
3443
5521
|
{
|
|
3444
5522
|
className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
|
|
3445
5523
|
children: [
|
|
3446
|
-
/* @__PURE__ */
|
|
3447
|
-
/* @__PURE__ */
|
|
5524
|
+
/* @__PURE__ */ jsx28(FileText2, { size: 12 }),
|
|
5525
|
+
/* @__PURE__ */ jsx28("span", { className: "max-w-[100px] truncate", children: file.originalName })
|
|
3448
5526
|
]
|
|
3449
5527
|
},
|
|
3450
5528
|
fileIndex
|
|
3451
5529
|
)) }),
|
|
3452
|
-
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */
|
|
5530
|
+
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ jsx28(
|
|
3453
5531
|
"p",
|
|
3454
5532
|
{
|
|
3455
5533
|
className: "wrap-break-word text-sm leading-relaxed",
|
|
3456
5534
|
children: formatMessageContent(part)
|
|
3457
5535
|
},
|
|
3458
5536
|
`${part.type}-${partIndex}`
|
|
3459
|
-
)) : /* @__PURE__ */
|
|
5537
|
+
)) : /* @__PURE__ */ jsx28("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
|
|
3460
5538
|
] })
|
|
3461
5539
|
}
|
|
3462
5540
|
),
|
|
3463
|
-
/* @__PURE__ */
|
|
5541
|
+
/* @__PURE__ */ jsx28(
|
|
3464
5542
|
MessageActions,
|
|
3465
5543
|
{
|
|
3466
5544
|
content: messageContent,
|
|
3467
5545
|
isAssistant: isAssistantMessage,
|
|
3468
|
-
isStreaming:
|
|
5546
|
+
isStreaming: isStreamingMessage,
|
|
3469
5547
|
onRetry: isAssistantMessage && !stream.isLoading && index === messages.length - 1 ? () => handleRetry(index) : void 0
|
|
3470
5548
|
}
|
|
3471
5549
|
)
|
|
@@ -3478,18 +5556,34 @@ function Chat({
|
|
|
3478
5556
|
const lastMessage = messages[messages.length - 1];
|
|
3479
5557
|
const lastMessageType = lastMessage ? String(lastMessage.type) : "";
|
|
3480
5558
|
const isLastMessageFromAI = lastMessageType === "ai" || lastMessageType === "assistant";
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
5559
|
+
const lastAssistantStatus = isLastMessageFromAI ? getAssistantStreamingStatus(
|
|
5560
|
+
{
|
|
5561
|
+
...lastMessage,
|
|
5562
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5563
|
+
},
|
|
5564
|
+
stream.isLoading,
|
|
5565
|
+
{ now: streamingNow }
|
|
5566
|
+
) : null;
|
|
5567
|
+
if (lastAssistantStatus) return null;
|
|
5568
|
+
const fallbackStreamingStatus = getAssistantStreamingStatus(
|
|
5569
|
+
{
|
|
5570
|
+
status: void 0,
|
|
5571
|
+
reasoning: void 0,
|
|
5572
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5573
|
+
},
|
|
5574
|
+
stream.isLoading,
|
|
5575
|
+
{ now: streamingNow }
|
|
5576
|
+
);
|
|
5577
|
+
return /* @__PURE__ */ jsx28("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ jsx28("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ jsx28(
|
|
5578
|
+
AssistantStreamingIndicator,
|
|
5579
|
+
{
|
|
5580
|
+
status: fallbackStreamingStatus ?? "loading"
|
|
5581
|
+
}
|
|
5582
|
+
) }) });
|
|
3489
5583
|
})()
|
|
3490
5584
|
] })
|
|
3491
5585
|
] }),
|
|
3492
|
-
!isAtBottom && messages.length > 0 && /* @__PURE__ */
|
|
5586
|
+
!isAtBottom && messages.length > 0 && /* @__PURE__ */ jsx28("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ jsx28(
|
|
3493
5587
|
Button,
|
|
3494
5588
|
{
|
|
3495
5589
|
type: "button",
|
|
@@ -3502,12 +5596,40 @@ function Chat({
|
|
|
3502
5596
|
onClick: () => scrollToBottom(true, true),
|
|
3503
5597
|
"aria-label": t("chat.scrollToBottom"),
|
|
3504
5598
|
title: t("chat.scrollToBottom"),
|
|
3505
|
-
children: /* @__PURE__ */
|
|
5599
|
+
children: /* @__PURE__ */ jsx28(ArrowDown, { size: 16 })
|
|
3506
5600
|
}
|
|
3507
5601
|
) }),
|
|
3508
|
-
/* @__PURE__ */
|
|
3509
|
-
|
|
3510
|
-
|
|
5602
|
+
quoteSelection && /* @__PURE__ */ jsx28(
|
|
5603
|
+
"div",
|
|
5604
|
+
{
|
|
5605
|
+
className: "pointer-events-none fixed z-50",
|
|
5606
|
+
style: {
|
|
5607
|
+
top: `${quoteSelection.top}px`,
|
|
5608
|
+
left: `${quoteSelection.left}px`,
|
|
5609
|
+
transform: "translateX(-50%)"
|
|
5610
|
+
},
|
|
5611
|
+
children: /* @__PURE__ */ jsxs17(
|
|
5612
|
+
Button,
|
|
5613
|
+
{
|
|
5614
|
+
type: "button",
|
|
5615
|
+
size: "sm",
|
|
5616
|
+
variant: "secondary",
|
|
5617
|
+
className: "pointer-events-auto shadow-lg",
|
|
5618
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5619
|
+
onClick: handleQuoteSelection,
|
|
5620
|
+
"aria-label": t("composer.quoteSelection"),
|
|
5621
|
+
title: t("composer.quoteSelection"),
|
|
5622
|
+
children: [
|
|
5623
|
+
/* @__PURE__ */ jsx28(Quote, { size: 14 }),
|
|
5624
|
+
t("composer.quoteSelection")
|
|
5625
|
+
]
|
|
5626
|
+
}
|
|
5627
|
+
)
|
|
5628
|
+
}
|
|
5629
|
+
),
|
|
5630
|
+
/* @__PURE__ */ jsxs17("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
|
|
5631
|
+
threadErrorMessage && /* @__PURE__ */ jsx28("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
|
|
5632
|
+
/* @__PURE__ */ jsx28(
|
|
3511
5633
|
"input",
|
|
3512
5634
|
{
|
|
3513
5635
|
ref: fileInputRef,
|
|
@@ -3518,7 +5640,7 @@ function Chat({
|
|
|
3518
5640
|
className: "hidden"
|
|
3519
5641
|
}
|
|
3520
5642
|
),
|
|
3521
|
-
attachments.length > 0 && /* @__PURE__ */
|
|
5643
|
+
attachments.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ jsxs17(
|
|
3522
5644
|
"div",
|
|
3523
5645
|
{
|
|
3524
5646
|
className: cn(
|
|
@@ -3526,24 +5648,36 @@ function Chat({
|
|
|
3526
5648
|
item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
|
|
3527
5649
|
),
|
|
3528
5650
|
children: [
|
|
3529
|
-
item.status === "uploading" && /* @__PURE__ */
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
),
|
|
3536
|
-
item.status === "
|
|
5651
|
+
item.status === "uploading" && /* @__PURE__ */ jsx28(
|
|
5652
|
+
Loader23,
|
|
5653
|
+
{
|
|
5654
|
+
size: 14,
|
|
5655
|
+
className: "animate-spin text-muted-foreground"
|
|
5656
|
+
}
|
|
5657
|
+
),
|
|
5658
|
+
item.status === "success" && /* @__PURE__ */ jsx28(FileText2, { size: 14, className: "text-muted-foreground" }),
|
|
5659
|
+
item.status === "error" && /* @__PURE__ */ jsx28(FileText2, { size: 14, className: "text-destructive" }),
|
|
5660
|
+
/* @__PURE__ */ jsx28(
|
|
5661
|
+
"span",
|
|
5662
|
+
{
|
|
5663
|
+
className: cn(
|
|
5664
|
+
"max-w-30 truncate",
|
|
5665
|
+
item.status === "error" && "text-destructive"
|
|
5666
|
+
),
|
|
5667
|
+
children: item.file.name
|
|
5668
|
+
}
|
|
5669
|
+
),
|
|
5670
|
+
item.status === "error" && /* @__PURE__ */ jsx28(
|
|
3537
5671
|
"button",
|
|
3538
5672
|
{
|
|
3539
5673
|
type: "button",
|
|
3540
5674
|
onClick: () => handleRetryUpload(item.localId),
|
|
3541
5675
|
className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
|
|
3542
5676
|
title: t("chat.retryUpload"),
|
|
3543
|
-
children: /* @__PURE__ */
|
|
5677
|
+
children: /* @__PURE__ */ jsx28(RefreshCw2, { size: 12 })
|
|
3544
5678
|
}
|
|
3545
5679
|
),
|
|
3546
|
-
/* @__PURE__ */
|
|
5680
|
+
/* @__PURE__ */ jsx28(
|
|
3547
5681
|
"button",
|
|
3548
5682
|
{
|
|
3549
5683
|
type: "button",
|
|
@@ -3552,76 +5686,118 @@ function Chat({
|
|
|
3552
5686
|
"ml-1 rounded-full p-0.5",
|
|
3553
5687
|
item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
|
|
3554
5688
|
),
|
|
3555
|
-
children: /* @__PURE__ */
|
|
5689
|
+
children: /* @__PURE__ */ jsx28(X3, { size: 12 })
|
|
3556
5690
|
}
|
|
3557
5691
|
)
|
|
3558
5692
|
]
|
|
3559
5693
|
},
|
|
3560
5694
|
item.localId
|
|
3561
5695
|
)) }),
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
5696
|
+
references.length > 0 && /* @__PURE__ */ jsx28("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ jsx28(
|
|
5697
|
+
ReferenceChip,
|
|
5698
|
+
{
|
|
5699
|
+
reference,
|
|
5700
|
+
variant: "composer",
|
|
5701
|
+
onRemove: () => setReferences(
|
|
5702
|
+
(previous) => previous.filter(
|
|
5703
|
+
(item) => getReferenceKey(item) !== getReferenceKey(reference)
|
|
5704
|
+
)
|
|
5705
|
+
),
|
|
5706
|
+
removeLabel: t("composer.removeReference")
|
|
5707
|
+
},
|
|
5708
|
+
getReferenceKey(reference)
|
|
5709
|
+
)) }),
|
|
5710
|
+
selectedTool && /* @__PURE__ */ jsxs17("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
5711
|
+
/* @__PURE__ */ jsx28("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
|
|
5712
|
+
/* @__PURE__ */ jsx28(
|
|
3565
5713
|
"button",
|
|
3566
5714
|
{
|
|
3567
5715
|
type: "button",
|
|
3568
5716
|
onClick: () => setSelectedTool(null),
|
|
3569
5717
|
className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
|
|
3570
|
-
children: /* @__PURE__ */
|
|
5718
|
+
children: /* @__PURE__ */ jsx28(X3, { size: 12 })
|
|
3571
5719
|
}
|
|
3572
5720
|
)
|
|
3573
5721
|
] }),
|
|
3574
|
-
/* @__PURE__ */
|
|
5722
|
+
/* @__PURE__ */ jsx28(
|
|
5723
|
+
PendingFollowUps,
|
|
5724
|
+
{
|
|
5725
|
+
items: pendingFollowUps,
|
|
5726
|
+
isLoading: stream.isLoading,
|
|
5727
|
+
followUpBehavior: stream.followUpBehavior,
|
|
5728
|
+
onBehaviorChange: stream.setFollowUpBehavior,
|
|
5729
|
+
onPromoteToSteer: (id) => stream.promotePendingFollowUpToSteer(id),
|
|
5730
|
+
canSendNow: stream.canSendPendingFollowUpNow,
|
|
5731
|
+
onSendNow: (id) => stream.sendPendingFollowUpNow(id),
|
|
5732
|
+
onEdit: handleEditPendingFollowUp,
|
|
5733
|
+
onRemove: stream.removePendingFollowUp
|
|
5734
|
+
}
|
|
5735
|
+
),
|
|
5736
|
+
/* @__PURE__ */ jsx28("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs17(
|
|
3575
5737
|
"div",
|
|
3576
5738
|
{
|
|
3577
5739
|
className: cn(
|
|
3578
|
-
"flex flex-1 items-
|
|
5740
|
+
"flex flex-1 items-end gap-1 rounded-xl",
|
|
3579
5741
|
"bg-background border border-border shadow-sm",
|
|
3580
5742
|
"pl-1.5 pr-1.5 py-1",
|
|
3581
5743
|
"focus-within:border-muted-foreground/30 focus-within:shadow-md",
|
|
3582
|
-
"transition-shadow duration-200"
|
|
5744
|
+
"transition-shadow duration-200",
|
|
5745
|
+
getRoundedClass(theme.radius)
|
|
3583
5746
|
),
|
|
3584
5747
|
children: [
|
|
3585
|
-
/* @__PURE__ */
|
|
5748
|
+
/* @__PURE__ */ jsx28(
|
|
3586
5749
|
ComposerMenu,
|
|
3587
5750
|
{
|
|
3588
5751
|
composer,
|
|
3589
5752
|
onAttachmentClick: handleAttachmentClick,
|
|
3590
5753
|
onToolSelect: handleToolSelect,
|
|
3591
5754
|
selectedTool,
|
|
3592
|
-
disabled:
|
|
5755
|
+
disabled: missingConfig || isHistoryLoading
|
|
3593
5756
|
}
|
|
3594
5757
|
),
|
|
3595
|
-
/* @__PURE__ */
|
|
3596
|
-
"
|
|
5758
|
+
/* @__PURE__ */ jsx28(
|
|
5759
|
+
"textarea",
|
|
3597
5760
|
{
|
|
3598
|
-
|
|
5761
|
+
ref: composerInputRef,
|
|
3599
5762
|
value: draft,
|
|
3600
5763
|
onChange: (event) => setDraft(event.target.value),
|
|
5764
|
+
onPaste: handleComposerPaste,
|
|
5765
|
+
onKeyDown: handleComposerKeyDown,
|
|
5766
|
+
rows: 1,
|
|
3601
5767
|
placeholder: inputPlaceholder,
|
|
3602
|
-
disabled:
|
|
5768
|
+
disabled: missingConfig || isHistoryLoading,
|
|
3603
5769
|
className: cn(
|
|
3604
|
-
"flex-1 bg-transparent text-sm text-foreground outline-none
|
|
5770
|
+
"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
5771
|
"placeholder:text-muted-foreground",
|
|
3606
5772
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
3607
|
-
)
|
|
3608
|
-
autoComplete: "off"
|
|
5773
|
+
)
|
|
3609
5774
|
}
|
|
3610
5775
|
),
|
|
3611
|
-
/* @__PURE__ */
|
|
5776
|
+
/* @__PURE__ */ jsx28(
|
|
3612
5777
|
SendButton,
|
|
3613
5778
|
{
|
|
3614
5779
|
disabled: isSendDisabled,
|
|
3615
5780
|
isLoading: stream.isLoading,
|
|
5781
|
+
showStop: stream.isLoading && !trimmedDraft,
|
|
3616
5782
|
onStop: () => stream.stop(),
|
|
3617
5783
|
stopLabel: t("chat.stop"),
|
|
3618
|
-
sendLabel: t("chat.send")
|
|
5784
|
+
sendLabel: t("chat.send"),
|
|
5785
|
+
shortcuts: stream.isLoading && trimmedDraft ? [
|
|
5786
|
+
{
|
|
5787
|
+
label: t("chat.followUps.steer"),
|
|
5788
|
+
keys: followUpShortcutLabels.steer
|
|
5789
|
+
},
|
|
5790
|
+
{
|
|
5791
|
+
label: t("chat.followUps.queue"),
|
|
5792
|
+
keys: followUpShortcutLabels.queue
|
|
5793
|
+
}
|
|
5794
|
+
] : void 0
|
|
3619
5795
|
}
|
|
3620
5796
|
)
|
|
3621
5797
|
]
|
|
3622
5798
|
}
|
|
3623
5799
|
) }),
|
|
3624
|
-
disclaimer?.text && /* @__PURE__ */
|
|
5800
|
+
disclaimer?.text && /* @__PURE__ */ jsx28(
|
|
3625
5801
|
"p",
|
|
3626
5802
|
{
|
|
3627
5803
|
className: cn(
|
|
@@ -3631,9 +5807,9 @@ function Chat({
|
|
|
3631
5807
|
children: disclaimer.text
|
|
3632
5808
|
}
|
|
3633
5809
|
),
|
|
3634
|
-
/* @__PURE__ */
|
|
3635
|
-
/* @__PURE__ */
|
|
3636
|
-
/* @__PURE__ */
|
|
5810
|
+
/* @__PURE__ */ jsxs17("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
|
|
5811
|
+
/* @__PURE__ */ jsx28("span", { children: t("chat.poweredBy") }),
|
|
5812
|
+
/* @__PURE__ */ jsx28(ContextUsageIndicator, { className: "absolute right-4" })
|
|
3637
5813
|
] })
|
|
3638
5814
|
] })
|
|
3639
5815
|
]
|
|
@@ -3642,11 +5818,11 @@ function Chat({
|
|
|
3642
5818
|
}
|
|
3643
5819
|
|
|
3644
5820
|
// src/components/ui/input.tsx
|
|
3645
|
-
import * as
|
|
3646
|
-
import { jsx as
|
|
3647
|
-
var Input =
|
|
5821
|
+
import * as React23 from "react";
|
|
5822
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
5823
|
+
var Input = React23.forwardRef(
|
|
3648
5824
|
({ className, type, ...props }, ref) => {
|
|
3649
|
-
return /* @__PURE__ */
|
|
5825
|
+
return /* @__PURE__ */ jsx29(
|
|
3650
5826
|
"input",
|
|
3651
5827
|
{
|
|
3652
5828
|
ref,
|
|
@@ -3663,10 +5839,10 @@ var Input = React21.forwardRef(
|
|
|
3663
5839
|
Input.displayName = "Input";
|
|
3664
5840
|
|
|
3665
5841
|
// src/components/ui/separator.tsx
|
|
3666
|
-
import * as
|
|
3667
|
-
import { jsx as
|
|
3668
|
-
var Separator =
|
|
3669
|
-
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */
|
|
5842
|
+
import * as React24 from "react";
|
|
5843
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
5844
|
+
var Separator = React24.forwardRef(
|
|
5845
|
+
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ jsx30(
|
|
3670
5846
|
"div",
|
|
3671
5847
|
{
|
|
3672
5848
|
ref,
|