@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.cjs
CHANGED
|
@@ -66,8 +66,8 @@ __export(index_exports, {
|
|
|
66
66
|
module.exports = __toCommonJS(index_exports);
|
|
67
67
|
|
|
68
68
|
// src/components/chat.tsx
|
|
69
|
-
var
|
|
70
|
-
var
|
|
69
|
+
var React22 = __toESM(require("react"), 1);
|
|
70
|
+
var import_lucide_react11 = require("lucide-react");
|
|
71
71
|
|
|
72
72
|
// src/lib/utils.ts
|
|
73
73
|
var import_clsx = require("clsx");
|
|
@@ -88,6 +88,64 @@ function createMessageId() {
|
|
|
88
88
|
return globalThis.crypto?.randomUUID?.() ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
// src/lib/message.ts
|
|
92
|
+
var import_lodash_es = require("lodash-es");
|
|
93
|
+
var ASSISTANT_STREAM_IDLE_TO_THINKING_MS = 2e3;
|
|
94
|
+
function hasRenderableReasoning(reasoning) {
|
|
95
|
+
return Array.isArray(reasoning) && reasoning.some((item) => item.text?.trim());
|
|
96
|
+
}
|
|
97
|
+
function hasRenderableMessageContent(content) {
|
|
98
|
+
if (typeof content === "string") {
|
|
99
|
+
return content.trim().length > 0;
|
|
100
|
+
}
|
|
101
|
+
if (!Array.isArray(content) || content.length === 0) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const items = content;
|
|
105
|
+
return items.some((item) => {
|
|
106
|
+
if (typeof item === "string") {
|
|
107
|
+
return item.trim().length > 0;
|
|
108
|
+
}
|
|
109
|
+
if (!item || typeof item !== "object") {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (item.type === "text") {
|
|
113
|
+
return Boolean(item.text?.trim());
|
|
114
|
+
}
|
|
115
|
+
if (item.type === "reasoning") {
|
|
116
|
+
return Boolean(item.text?.trim());
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function hasRenderableAssistantMessage(message) {
|
|
122
|
+
return hasRenderableMessageContent(message.content) || hasRenderableReasoning(message.reasoning);
|
|
123
|
+
}
|
|
124
|
+
function getAssistantStreamingStatus(message, isStreaming, options) {
|
|
125
|
+
if (!isStreaming) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
const now = options?.now ?? Date.now();
|
|
129
|
+
const lastStreamOutputAt = typeof message.lastStreamOutputAt === "number" ? message.lastStreamOutputAt : null;
|
|
130
|
+
const isIdle = lastStreamOutputAt !== null && now - lastStreamOutputAt >= ASSISTANT_STREAM_IDLE_TO_THINKING_MS;
|
|
131
|
+
if (message.status === "reasoning") {
|
|
132
|
+
return "thinking";
|
|
133
|
+
}
|
|
134
|
+
if (message.status === "answering") {
|
|
135
|
+
if (isIdle) {
|
|
136
|
+
return "thinking";
|
|
137
|
+
}
|
|
138
|
+
return "answering";
|
|
139
|
+
}
|
|
140
|
+
if (hasRenderableReasoning(message.reasoning)) {
|
|
141
|
+
return "thinking";
|
|
142
|
+
}
|
|
143
|
+
if (isIdle) {
|
|
144
|
+
return "thinking";
|
|
145
|
+
}
|
|
146
|
+
return "loading";
|
|
147
|
+
}
|
|
148
|
+
|
|
91
149
|
// src/lib/scroll.ts
|
|
92
150
|
var BOTTOM_FOLLOW_THRESHOLD_PX = 48;
|
|
93
151
|
function getDistanceFromBottom(element) {
|
|
@@ -104,6 +162,25 @@ var import_xpert_sdk = require("@xpert-ai/xpert-sdk");
|
|
|
104
162
|
var import_tool = require("@langchain/core/messages/tool");
|
|
105
163
|
var import_chatkit_types3 = require("@xpert-ai/chatkit-types");
|
|
106
164
|
|
|
165
|
+
// src/lib/api-config.ts
|
|
166
|
+
function hasConfiguredValue(value) {
|
|
167
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
168
|
+
}
|
|
169
|
+
function getMissingApiConfigurationKind({
|
|
170
|
+
apiUrl,
|
|
171
|
+
clientSecret
|
|
172
|
+
}) {
|
|
173
|
+
const hasApiUrl = hasConfiguredValue(apiUrl);
|
|
174
|
+
const hasClientSecret = hasConfiguredValue(clientSecret);
|
|
175
|
+
if (hasApiUrl && hasClientSecret) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
if (!hasApiUrl && !hasClientSecret) {
|
|
179
|
+
return "apiUrlAndClientSecret";
|
|
180
|
+
}
|
|
181
|
+
return hasApiUrl ? "clientSecret" : "apiUrl";
|
|
182
|
+
}
|
|
183
|
+
|
|
107
184
|
// src/lib/request-options.ts
|
|
108
185
|
var import_chatkit_types = require("@xpert-ai/chatkit-types");
|
|
109
186
|
function isRecord(value) {
|
|
@@ -199,6 +276,302 @@ function useStreamManager() {
|
|
|
199
276
|
};
|
|
200
277
|
}
|
|
201
278
|
|
|
279
|
+
// src/lib/references.ts
|
|
280
|
+
function isObjectLike(value) {
|
|
281
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
282
|
+
}
|
|
283
|
+
function isNonEmptyString(value) {
|
|
284
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
285
|
+
}
|
|
286
|
+
function isOptionalString(value) {
|
|
287
|
+
return value === void 0 || typeof value === "string";
|
|
288
|
+
}
|
|
289
|
+
function toOptionalString(value) {
|
|
290
|
+
return isNonEmptyString(value) ? value.trim() : void 0;
|
|
291
|
+
}
|
|
292
|
+
function toReferenceText(value) {
|
|
293
|
+
return typeof value === "string" && value.trim().length > 0 ? value : null;
|
|
294
|
+
}
|
|
295
|
+
function toLineNumber(value) {
|
|
296
|
+
if (typeof value === "number" && Number.isInteger(value) && value > 0) {
|
|
297
|
+
return value;
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
function isOptionalNumber(value) {
|
|
302
|
+
return value === void 0 || Number.isFinite(value);
|
|
303
|
+
}
|
|
304
|
+
function toOptionalNumber(value, options) {
|
|
305
|
+
const allowZero = options?.allowZero ?? false;
|
|
306
|
+
if (!Number.isFinite(value)) {
|
|
307
|
+
return void 0;
|
|
308
|
+
}
|
|
309
|
+
const numberValue = value;
|
|
310
|
+
if (numberValue > 0 || allowZero && numberValue === 0) {
|
|
311
|
+
return numberValue;
|
|
312
|
+
}
|
|
313
|
+
return void 0;
|
|
314
|
+
}
|
|
315
|
+
function hasImageReferenceLocator(candidate) {
|
|
316
|
+
return isNonEmptyString(candidate.fileId) || isNonEmptyString(candidate.url) || isNonEmptyString(candidate.name) || isNonEmptyString(candidate.label) || isNonEmptyString(candidate.text);
|
|
317
|
+
}
|
|
318
|
+
function isCodeReferenceCandidate(value) {
|
|
319
|
+
if (!isObjectLike(value)) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
const candidate = value;
|
|
323
|
+
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);
|
|
324
|
+
}
|
|
325
|
+
function isQuoteReferenceCandidate(value) {
|
|
326
|
+
if (!isObjectLike(value)) {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
const candidate = value;
|
|
330
|
+
return candidate.type === "quote" && toReferenceText(candidate.text) !== null && isOptionalString(candidate.id) && isOptionalString(candidate.label) && isOptionalString(candidate.messageId) && isOptionalString(candidate.source);
|
|
331
|
+
}
|
|
332
|
+
function isImageReferenceCandidate(value) {
|
|
333
|
+
if (!isObjectLike(value)) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
const candidate = value;
|
|
337
|
+
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);
|
|
338
|
+
}
|
|
339
|
+
function toCodeReference(candidate) {
|
|
340
|
+
return {
|
|
341
|
+
type: "code",
|
|
342
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
343
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
344
|
+
path: candidate.path.trim(),
|
|
345
|
+
startLine: candidate.startLine,
|
|
346
|
+
endLine: candidate.endLine,
|
|
347
|
+
text: candidate.text,
|
|
348
|
+
...toOptionalString(candidate.language) ? { language: toOptionalString(candidate.language) } : {},
|
|
349
|
+
...toOptionalString(candidate.taskId) ? { taskId: toOptionalString(candidate.taskId) } : {}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function toQuoteReference(candidate) {
|
|
353
|
+
return {
|
|
354
|
+
type: "quote",
|
|
355
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
356
|
+
...toOptionalString(candidate.label) ? { label: toOptionalString(candidate.label) } : {},
|
|
357
|
+
text: candidate.text,
|
|
358
|
+
...toOptionalString(candidate.messageId) ? { messageId: toOptionalString(candidate.messageId) } : {},
|
|
359
|
+
...toOptionalString(candidate.source) ? { source: toOptionalString(candidate.source) } : {}
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
function toImageReference(candidate) {
|
|
363
|
+
const fileId = toOptionalString(candidate.fileId);
|
|
364
|
+
const url = toOptionalString(candidate.url);
|
|
365
|
+
const name = toOptionalString(candidate.name);
|
|
366
|
+
const label = toOptionalString(candidate.label);
|
|
367
|
+
const rawText = toReferenceText(candidate.text);
|
|
368
|
+
const text = rawText ?? name ?? label ?? "Pasted image";
|
|
369
|
+
return {
|
|
370
|
+
type: "image",
|
|
371
|
+
...toOptionalString(candidate.id) ? { id: toOptionalString(candidate.id) } : {},
|
|
372
|
+
...label ? { label } : {},
|
|
373
|
+
text,
|
|
374
|
+
...fileId ? { fileId } : {},
|
|
375
|
+
...url ? { url } : {},
|
|
376
|
+
...toOptionalString(candidate.mimeType) ? { mimeType: toOptionalString(candidate.mimeType) } : {},
|
|
377
|
+
...name ? { name } : {},
|
|
378
|
+
...toOptionalNumber(candidate.size, { allowZero: true }) !== void 0 ? { size: toOptionalNumber(candidate.size, { allowZero: true }) } : {},
|
|
379
|
+
...toOptionalNumber(candidate.width) !== void 0 ? { width: toOptionalNumber(candidate.width) } : {},
|
|
380
|
+
...toOptionalNumber(candidate.height) !== void 0 ? { height: toOptionalNumber(candidate.height) } : {}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function isLegacyCodeReference(candidate) {
|
|
384
|
+
return candidate.type === void 0 && isNonEmptyString(candidate.path) && toLineNumber(candidate.startLine) !== null && toLineNumber(candidate.endLine) !== null && toReferenceText(candidate.text) !== null;
|
|
385
|
+
}
|
|
386
|
+
function normalizeReference(value) {
|
|
387
|
+
if (!isObjectLike(value)) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
const candidate = value;
|
|
391
|
+
const type = toOptionalString(candidate.type);
|
|
392
|
+
if (type === "code" && isCodeReferenceCandidate(candidate)) {
|
|
393
|
+
return toCodeReference(candidate);
|
|
394
|
+
}
|
|
395
|
+
if (isQuoteReferenceCandidate(candidate)) {
|
|
396
|
+
return toQuoteReference(candidate);
|
|
397
|
+
}
|
|
398
|
+
if (isImageReferenceCandidate(candidate)) {
|
|
399
|
+
return toImageReference(candidate);
|
|
400
|
+
}
|
|
401
|
+
if (type === void 0 && isLegacyCodeReference(candidate)) {
|
|
402
|
+
return toCodeReference(candidate);
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
function normalizeReferences(value) {
|
|
407
|
+
if (!Array.isArray(value)) {
|
|
408
|
+
return [];
|
|
409
|
+
}
|
|
410
|
+
return value.map((item) => normalizeReference(item)).filter((item) => item !== null);
|
|
411
|
+
}
|
|
412
|
+
function getCodeReferenceRange(reference) {
|
|
413
|
+
return reference.startLine === reference.endLine ? `${reference.startLine}` : `${reference.startLine}-${reference.endLine}`;
|
|
414
|
+
}
|
|
415
|
+
function getQuoteExcerpt(reference) {
|
|
416
|
+
const normalized = reference.text.replace(/\s+/g, " ").trim();
|
|
417
|
+
if (normalized.length <= 32) {
|
|
418
|
+
return normalized;
|
|
419
|
+
}
|
|
420
|
+
return `${normalized.slice(0, 29)}...`;
|
|
421
|
+
}
|
|
422
|
+
function getCodeReferenceLocation(reference) {
|
|
423
|
+
return `${reference.path}:${getCodeReferenceRange(reference)}`;
|
|
424
|
+
}
|
|
425
|
+
function formatReferenceSize(size2) {
|
|
426
|
+
if (size2 < 1024) {
|
|
427
|
+
return `${size2} B`;
|
|
428
|
+
}
|
|
429
|
+
if (size2 < 1024 * 1024) {
|
|
430
|
+
return `${(size2 / 1024).toFixed(size2 < 10 * 1024 ? 1 : 0)} KB`;
|
|
431
|
+
}
|
|
432
|
+
return `${(size2 / (1024 * 1024)).toFixed(size2 < 10 * 1024 * 1024 ? 1 : 0)} MB`;
|
|
433
|
+
}
|
|
434
|
+
function getImageReferenceDimensions(reference) {
|
|
435
|
+
if (!reference.width || !reference.height) {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
438
|
+
return `${reference.width}x${reference.height}`;
|
|
439
|
+
}
|
|
440
|
+
function getImageReferenceMetaParts(reference) {
|
|
441
|
+
return [
|
|
442
|
+
reference.mimeType?.trim() || null,
|
|
443
|
+
getImageReferenceDimensions(reference),
|
|
444
|
+
typeof reference.size === "number" ? formatReferenceSize(reference.size) : null
|
|
445
|
+
].filter((part) => Boolean(part));
|
|
446
|
+
}
|
|
447
|
+
function getReferenceKey(reference) {
|
|
448
|
+
if (reference.type === "image" && reference.fileId?.trim()) {
|
|
449
|
+
return `image:${reference.fileId.trim()}`;
|
|
450
|
+
}
|
|
451
|
+
if (reference.id && reference.id.trim()) {
|
|
452
|
+
return reference.id.trim();
|
|
453
|
+
}
|
|
454
|
+
if (reference.type === "code") {
|
|
455
|
+
return [
|
|
456
|
+
reference.type,
|
|
457
|
+
reference.path,
|
|
458
|
+
reference.startLine,
|
|
459
|
+
reference.endLine,
|
|
460
|
+
reference.text
|
|
461
|
+
].join(":");
|
|
462
|
+
}
|
|
463
|
+
if (reference.type === "image") {
|
|
464
|
+
return [
|
|
465
|
+
reference.type,
|
|
466
|
+
reference.url ?? "",
|
|
467
|
+
reference.name ?? "",
|
|
468
|
+
reference.mimeType ?? "",
|
|
469
|
+
reference.size ?? "",
|
|
470
|
+
reference.width ?? "",
|
|
471
|
+
reference.height ?? "",
|
|
472
|
+
reference.text
|
|
473
|
+
].join(":");
|
|
474
|
+
}
|
|
475
|
+
return [
|
|
476
|
+
reference.type,
|
|
477
|
+
reference.messageId ?? "",
|
|
478
|
+
reference.source ?? "",
|
|
479
|
+
reference.text
|
|
480
|
+
].join(":");
|
|
481
|
+
}
|
|
482
|
+
function mergeReferences(current, incoming) {
|
|
483
|
+
const merged = [...current];
|
|
484
|
+
const seen = new Set(current.map(getReferenceKey));
|
|
485
|
+
incoming.forEach((reference) => {
|
|
486
|
+
const key = getReferenceKey(reference);
|
|
487
|
+
if (seen.has(key)) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
seen.add(key);
|
|
491
|
+
merged.push(reference);
|
|
492
|
+
});
|
|
493
|
+
return merged;
|
|
494
|
+
}
|
|
495
|
+
function getReferenceLabel(reference) {
|
|
496
|
+
if (reference.label && reference.label.trim()) {
|
|
497
|
+
return reference.label.trim();
|
|
498
|
+
}
|
|
499
|
+
if (reference.type === "code") {
|
|
500
|
+
const segments = reference.path.split("/");
|
|
501
|
+
const fileName = segments[segments.length - 1] || reference.path;
|
|
502
|
+
return `${fileName} ${getCodeReferenceRange(reference)}`;
|
|
503
|
+
}
|
|
504
|
+
if (reference.type === "image") {
|
|
505
|
+
return reference.name?.trim() || "Pasted image";
|
|
506
|
+
}
|
|
507
|
+
if (reference.source && reference.source.trim()) {
|
|
508
|
+
return reference.source.trim();
|
|
509
|
+
}
|
|
510
|
+
return getQuoteExcerpt(reference);
|
|
511
|
+
}
|
|
512
|
+
function getReferenceMetaLine(reference) {
|
|
513
|
+
if (reference.type === "code") {
|
|
514
|
+
return getCodeReferenceLocation(reference);
|
|
515
|
+
}
|
|
516
|
+
if (reference.type === "image") {
|
|
517
|
+
const parts = getImageReferenceMetaParts(reference);
|
|
518
|
+
return parts.length ? parts.join(" \u2022 ") : null;
|
|
519
|
+
}
|
|
520
|
+
if (reference.source && reference.source.trim()) {
|
|
521
|
+
return getQuoteExcerpt(reference);
|
|
522
|
+
}
|
|
523
|
+
if (reference.messageId && reference.messageId.trim()) {
|
|
524
|
+
return `Message ${reference.messageId.trim()}`;
|
|
525
|
+
}
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
function getReferenceTitle(reference) {
|
|
529
|
+
if (reference.type === "code") {
|
|
530
|
+
return `${getCodeReferenceLocation(reference)}
|
|
531
|
+
|
|
532
|
+
${reference.text}`;
|
|
533
|
+
}
|
|
534
|
+
if (reference.type === "image") {
|
|
535
|
+
const titleLines = [getReferenceLabel(reference)];
|
|
536
|
+
const metaLine = getReferenceMetaLine(reference);
|
|
537
|
+
const url = reference.url?.trim() && !reference.url.trim().startsWith("data:") ? reference.url.trim() : null;
|
|
538
|
+
if (metaLine) {
|
|
539
|
+
titleLines.push(metaLine);
|
|
540
|
+
}
|
|
541
|
+
if (url) {
|
|
542
|
+
titleLines.push(url);
|
|
543
|
+
}
|
|
544
|
+
if (reference.text.trim() && reference.text.trim() !== getReferenceLabel(reference)) {
|
|
545
|
+
titleLines.push("", reference.text.trim());
|
|
546
|
+
}
|
|
547
|
+
return titleLines.join("\n");
|
|
548
|
+
}
|
|
549
|
+
const header = reference.label?.trim() || reference.source?.trim() || "Quoted text";
|
|
550
|
+
return `${header}
|
|
551
|
+
|
|
552
|
+
${reference.text}`;
|
|
553
|
+
}
|
|
554
|
+
function buildHumanMessageInputPayload(source) {
|
|
555
|
+
const references = normalizeReferences(source.references);
|
|
556
|
+
const nextReferenceComposition = source.referenceComposition ?? (references.length > 0 && typeof source.submittedInput !== "string" ? "compose" : void 0);
|
|
557
|
+
if (typeof source.submittedInput === "string") {
|
|
558
|
+
return {
|
|
559
|
+
input: source.submittedInput.trim(),
|
|
560
|
+
...references.length > 0 ? { references } : {},
|
|
561
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
const input = typeof source.content === "string" ? source.content.trim() : "";
|
|
565
|
+
if (!input && references.length === 0) {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
return {
|
|
569
|
+
input,
|
|
570
|
+
...references.length > 0 ? { references } : {},
|
|
571
|
+
...nextReferenceComposition ? { referenceComposition: nextReferenceComposition } : {}
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
202
575
|
// src/providers/ParentMessenger.tsx
|
|
203
576
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
204
577
|
var handledSendUserMessageNonces = /* @__PURE__ */ new Set();
|
|
@@ -227,6 +600,10 @@ function ParentMessengerProvider({
|
|
|
227
600
|
/* @__PURE__ */ new Map()
|
|
228
601
|
);
|
|
229
602
|
const onSetOptionsHandlersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
603
|
+
const onSetComposerValueHandlersRef = (0, import_react.useRef)(
|
|
604
|
+
/* @__PURE__ */ new Set()
|
|
605
|
+
);
|
|
606
|
+
const onFocusComposerHandlersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
230
607
|
const latestOptionsRef = (0, import_react.useRef)(null);
|
|
231
608
|
const isParentAvailable = (0, import_react.useMemo)(() => {
|
|
232
609
|
return typeof window !== "undefined" && window.parent !== window;
|
|
@@ -240,6 +617,24 @@ function ParentMessengerProvider({
|
|
|
240
617
|
onSetOptionsHandlersRef.current.delete(handler);
|
|
241
618
|
};
|
|
242
619
|
}, []);
|
|
620
|
+
const registerOnSetComposerValue = (0, import_react.useCallback)(
|
|
621
|
+
(handler) => {
|
|
622
|
+
onSetComposerValueHandlersRef.current.add(handler);
|
|
623
|
+
return () => {
|
|
624
|
+
onSetComposerValueHandlersRef.current.delete(handler);
|
|
625
|
+
};
|
|
626
|
+
},
|
|
627
|
+
[]
|
|
628
|
+
);
|
|
629
|
+
const registerOnFocusComposer = (0, import_react.useCallback)(
|
|
630
|
+
(handler) => {
|
|
631
|
+
onFocusComposerHandlersRef.current.add(handler);
|
|
632
|
+
return () => {
|
|
633
|
+
onFocusComposerHandlersRef.current.delete(handler);
|
|
634
|
+
};
|
|
635
|
+
},
|
|
636
|
+
[]
|
|
637
|
+
);
|
|
243
638
|
(0, import_react.useEffect)(() => {
|
|
244
639
|
if (!isParentAvailable) return;
|
|
245
640
|
const sendResponse = (nonce, response, error) => {
|
|
@@ -260,7 +655,7 @@ function ParentMessengerProvider({
|
|
|
260
655
|
}
|
|
261
656
|
const payload = event.data;
|
|
262
657
|
if (payload.__xpaiChatKit !== true) return;
|
|
263
|
-
if (payload.type
|
|
658
|
+
if (payload.type === "command" && payload.command === "onSendUserMessage") {
|
|
264
659
|
const nonce = typeof payload.nonce === "string" ? payload.nonce : null;
|
|
265
660
|
if (nonce) {
|
|
266
661
|
if (handledSendUserMessageNonces.has(nonce)) return;
|
|
@@ -270,34 +665,53 @@ function ParentMessengerProvider({
|
|
|
270
665
|
handledSendUserMessageEvents.add(event);
|
|
271
666
|
}
|
|
272
667
|
const params = payload.data;
|
|
273
|
-
const prompt =
|
|
668
|
+
const prompt = typeof params.text === "string" ? params.text.trim() : typeof params.state?.[import_chatkit_types2.STATE_VARIABLE_HUMAN]?.input === "string" ? params.state[import_chatkit_types2.STATE_VARIABLE_HUMAN].input.trim() : "";
|
|
669
|
+
const references = normalizeReferences(
|
|
670
|
+
params.references ?? params.state?.[import_chatkit_types2.STATE_VARIABLE_HUMAN]?.references
|
|
671
|
+
);
|
|
672
|
+
const referenceComposition = params.referenceComposition ?? params.state?.[import_chatkit_types2.STATE_VARIABLE_HUMAN]?.referenceComposition;
|
|
673
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
674
|
+
content: prompt,
|
|
675
|
+
references,
|
|
676
|
+
referenceComposition
|
|
677
|
+
});
|
|
678
|
+
if (!humanInput) {
|
|
679
|
+
if (payload.nonce) {
|
|
680
|
+
sendResponse(payload.nonce, { ok: true });
|
|
681
|
+
}
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
274
684
|
const newMessage = {
|
|
275
685
|
id: createMessageId(),
|
|
276
686
|
type: "human",
|
|
277
|
-
content: prompt
|
|
687
|
+
content: prompt,
|
|
688
|
+
submittedInput: humanInput.input,
|
|
689
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
690
|
+
...references.length > 0 ? { references } : {}
|
|
278
691
|
};
|
|
692
|
+
const stream = streamRef2.current;
|
|
693
|
+
const activeFollowUpMode = stream?.isLoading ? params.followUpMode && params.followUpMode !== "default" ? params.followUpMode : stream.followUpBehavior ?? "queue" : void 0;
|
|
279
694
|
const requestOptions = buildInjectedRequestOptions({
|
|
280
695
|
defaults: latestOptionsRef.current?.request,
|
|
281
696
|
state: params.state,
|
|
282
|
-
humanInput
|
|
283
|
-
input: prompt
|
|
284
|
-
}
|
|
697
|
+
humanInput
|
|
285
698
|
});
|
|
286
|
-
|
|
699
|
+
stream?.submit(
|
|
287
700
|
{
|
|
288
|
-
input:
|
|
289
|
-
input: prompt
|
|
290
|
-
},
|
|
701
|
+
input: humanInput,
|
|
291
702
|
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
292
703
|
},
|
|
293
704
|
{
|
|
294
705
|
newThread: params.newThread,
|
|
706
|
+
...activeFollowUpMode ? { followUpMode: activeFollowUpMode } : {},
|
|
295
707
|
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
296
708
|
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
709
|
+
...!activeFollowUpMode ? {
|
|
710
|
+
optimisticValues: (prev) => {
|
|
711
|
+
const prevMessages = prev?.messages ?? [];
|
|
712
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
713
|
+
}
|
|
714
|
+
} : {}
|
|
301
715
|
}
|
|
302
716
|
);
|
|
303
717
|
if (payload.nonce) {
|
|
@@ -305,7 +719,28 @@ function ParentMessengerProvider({
|
|
|
305
719
|
}
|
|
306
720
|
return;
|
|
307
721
|
}
|
|
308
|
-
if (payload.type
|
|
722
|
+
if (payload.type === "command" && payload.command === "onSetComposerValue") {
|
|
723
|
+
const nextPayload = payload.data ?? null;
|
|
724
|
+
const normalizedPayload = nextPayload && Array.isArray(nextPayload.references) ? {
|
|
725
|
+
...nextPayload,
|
|
726
|
+
references: normalizeReferences(nextPayload.references)
|
|
727
|
+
} : nextPayload;
|
|
728
|
+
void Promise.all(
|
|
729
|
+
[...onSetComposerValueHandlersRef.current].map(
|
|
730
|
+
(handler2) => Promise.resolve(handler2(normalizedPayload))
|
|
731
|
+
)
|
|
732
|
+
).then(() => {
|
|
733
|
+
if (payload.nonce) {
|
|
734
|
+
sendResponse(payload.nonce, { ok: true });
|
|
735
|
+
}
|
|
736
|
+
}).catch((error) => {
|
|
737
|
+
if (payload.nonce) {
|
|
738
|
+
sendResponse(payload.nonce, void 0, error);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
if (payload.type === "command" && payload.command === "onSetOptions") {
|
|
309
744
|
latestOptionsRef.current = payload.data ?? null;
|
|
310
745
|
if (onSetOptionsHandlersRef.current.size > 0) {
|
|
311
746
|
onSetOptionsHandlersRef.current.forEach((handler2) => {
|
|
@@ -317,16 +752,41 @@ function ParentMessengerProvider({
|
|
|
317
752
|
}
|
|
318
753
|
return;
|
|
319
754
|
}
|
|
320
|
-
if (payload.type
|
|
755
|
+
if (payload.type === "command" && payload.command === "onFocusComposer") {
|
|
756
|
+
void Promise.all(
|
|
757
|
+
[...onFocusComposerHandlersRef.current].map(
|
|
758
|
+
(handler2) => Promise.resolve(handler2())
|
|
759
|
+
)
|
|
760
|
+
).then(() => {
|
|
761
|
+
if (payload.nonce) {
|
|
762
|
+
sendResponse(payload.nonce, { ok: true });
|
|
763
|
+
}
|
|
764
|
+
}).catch((error) => {
|
|
765
|
+
if (payload.nonce) {
|
|
766
|
+
sendResponse(payload.nonce, void 0, error);
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
if (payload.type === "command" && payload.command === "onSetThreadId") {
|
|
321
772
|
const data = payload.data;
|
|
322
773
|
const nextThreadId = data?.threadId ?? null;
|
|
323
774
|
const stream = streamRef2.current;
|
|
775
|
+
if (stream?.threadId === nextThreadId) {
|
|
776
|
+
if (payload.nonce) {
|
|
777
|
+
sendResponse(payload.nonce, { ok: true });
|
|
778
|
+
}
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
324
781
|
stream?.reset(nextThreadId, void 0, { suppressThreadChange: true });
|
|
325
782
|
if (stream && nextThreadId) {
|
|
326
783
|
stream.loadThread(nextThreadId).catch((err) => {
|
|
327
784
|
console.warn("Failed to load thread messages", err);
|
|
328
785
|
});
|
|
329
786
|
}
|
|
787
|
+
if (payload.nonce) {
|
|
788
|
+
sendResponse(payload.nonce, { ok: true });
|
|
789
|
+
}
|
|
330
790
|
return;
|
|
331
791
|
}
|
|
332
792
|
if (payload.type !== "response") return;
|
|
@@ -387,25 +847,55 @@ function ParentMessengerProvider({
|
|
|
387
847
|
isParentAvailable,
|
|
388
848
|
sendCommand,
|
|
389
849
|
sendEvent,
|
|
390
|
-
registerOnSetOptions
|
|
850
|
+
registerOnSetOptions,
|
|
851
|
+
registerOnSetComposerValue,
|
|
852
|
+
registerOnFocusComposer
|
|
391
853
|
}),
|
|
392
|
-
[
|
|
854
|
+
[
|
|
855
|
+
isParentAvailable,
|
|
856
|
+
sendCommand,
|
|
857
|
+
sendEvent,
|
|
858
|
+
registerOnSetOptions,
|
|
859
|
+
registerOnSetComposerValue,
|
|
860
|
+
registerOnFocusComposer
|
|
861
|
+
]
|
|
393
862
|
);
|
|
394
863
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ParentMessengerContext.Provider, { value, children });
|
|
395
864
|
}
|
|
396
865
|
|
|
397
866
|
// src/hooks/useParentMessenger.tsx
|
|
398
|
-
function useParentMessenger({
|
|
867
|
+
function useParentMessenger({
|
|
868
|
+
onSetOptions,
|
|
869
|
+
onSetComposerValue,
|
|
870
|
+
onFocusComposer
|
|
871
|
+
} = {}) {
|
|
399
872
|
const context = (0, import_react2.useContext)(ParentMessengerContext);
|
|
400
873
|
if (!context) {
|
|
401
|
-
throw new Error(
|
|
874
|
+
throw new Error(
|
|
875
|
+
"useParentMessenger must be used within a ParentMessengerProvider"
|
|
876
|
+
);
|
|
402
877
|
}
|
|
403
|
-
const {
|
|
878
|
+
const {
|
|
879
|
+
registerOnSetOptions,
|
|
880
|
+
registerOnSetComposerValue,
|
|
881
|
+
registerOnFocusComposer,
|
|
882
|
+
...messenger
|
|
883
|
+
} = context;
|
|
404
884
|
const onSetOptionsRef = (0, import_react2.useRef)(onSetOptions);
|
|
885
|
+
const onSetComposerValueRef = (0, import_react2.useRef)(onSetComposerValue);
|
|
886
|
+
const onFocusComposerRef = (0, import_react2.useRef)(onFocusComposer);
|
|
405
887
|
(0, import_react2.useEffect)(() => {
|
|
406
888
|
onSetOptionsRef.current = onSetOptions;
|
|
407
889
|
}, [onSetOptions]);
|
|
890
|
+
(0, import_react2.useEffect)(() => {
|
|
891
|
+
onSetComposerValueRef.current = onSetComposerValue;
|
|
892
|
+
}, [onSetComposerValue]);
|
|
893
|
+
(0, import_react2.useEffect)(() => {
|
|
894
|
+
onFocusComposerRef.current = onFocusComposer;
|
|
895
|
+
}, [onFocusComposer]);
|
|
408
896
|
const hasOnSetOptions = Boolean(onSetOptions);
|
|
897
|
+
const hasOnSetComposerValue = Boolean(onSetComposerValue);
|
|
898
|
+
const hasOnFocusComposer = Boolean(onFocusComposer);
|
|
409
899
|
(0, import_react2.useEffect)(() => {
|
|
410
900
|
if (!hasOnSetOptions) return;
|
|
411
901
|
const handler = (options) => {
|
|
@@ -413,6 +903,20 @@ function useParentMessenger({ onSetOptions } = {}) {
|
|
|
413
903
|
};
|
|
414
904
|
return registerOnSetOptions(handler);
|
|
415
905
|
}, [hasOnSetOptions, registerOnSetOptions]);
|
|
906
|
+
(0, import_react2.useEffect)(() => {
|
|
907
|
+
if (!hasOnSetComposerValue) return;
|
|
908
|
+
const handler = (payload) => {
|
|
909
|
+
onSetComposerValueRef.current?.(payload);
|
|
910
|
+
};
|
|
911
|
+
return registerOnSetComposerValue(handler);
|
|
912
|
+
}, [hasOnSetComposerValue, registerOnSetComposerValue]);
|
|
913
|
+
(0, import_react2.useEffect)(() => {
|
|
914
|
+
if (!hasOnFocusComposer) return;
|
|
915
|
+
const handler = () => {
|
|
916
|
+
onFocusComposerRef.current?.();
|
|
917
|
+
};
|
|
918
|
+
return registerOnFocusComposer(handler);
|
|
919
|
+
}, [hasOnFocusComposer, registerOnFocusComposer]);
|
|
416
920
|
return messenger;
|
|
417
921
|
}
|
|
418
922
|
|
|
@@ -446,6 +950,17 @@ function resolveUsedContextSize(options) {
|
|
|
446
950
|
return normalizeContextUsageNumber(options.fallbackUsedTokens) ?? 0;
|
|
447
951
|
}
|
|
448
952
|
|
|
953
|
+
// src/lib/follow-ups.ts
|
|
954
|
+
function getComposerFollowUpShortcutLabels(queueShortcutLabel) {
|
|
955
|
+
return {
|
|
956
|
+
steer: "Enter",
|
|
957
|
+
queue: queueShortcutLabel
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
function getBusyComposerShortcutFollowUpMode(useQueueShortcut) {
|
|
961
|
+
return useQueueShortcut ? "queue" : "steer";
|
|
962
|
+
}
|
|
963
|
+
|
|
449
964
|
// src/providers/Stream.tsx
|
|
450
965
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
451
966
|
var import_meta = {};
|
|
@@ -567,12 +1082,39 @@ var en_US_default = {
|
|
|
567
1082
|
statusOnline: "Online",
|
|
568
1083
|
missingConfigShort: "Missing ChatKit configuration.",
|
|
569
1084
|
missingConfigDetail: "Missing ChatKit configuration. Check `VITE_XPERTAI_API_URL`, and the `clientSecret` prop.",
|
|
1085
|
+
missingApiUrlShort: "Missing ChatKit API URL.",
|
|
1086
|
+
missingApiUrlDetail: "Missing ChatKit API URL. Check `VITE_XPERTAI_API_URL` or `options.api.apiUrl`.",
|
|
1087
|
+
missingClientSecretShort: "Missing ChatKit client secret.",
|
|
1088
|
+
missingClientSecretDetail: "Missing ChatKit client secret. Check the `clientSecret` prop or `api.getClientSecret` integration.",
|
|
1089
|
+
missingApiUrlAndClientSecretShort: "Missing ChatKit API URL and client secret.",
|
|
1090
|
+
missingApiUrlAndClientSecretDetail: "Missing ChatKit API URL and client secret. Check `VITE_XPERTAI_API_URL`, `options.api.apiUrl`, and your client secret integration.",
|
|
570
1091
|
loadingThread: "Loading thread...",
|
|
571
1092
|
stop: "Stop",
|
|
572
1093
|
send: "Send message",
|
|
1094
|
+
referencedContentOnly: "Referenced content",
|
|
1095
|
+
youLabel: "You",
|
|
573
1096
|
scrollToBottom: "Scroll to bottom",
|
|
574
1097
|
retryUpload: "Retry upload",
|
|
575
1098
|
poweredBy: "Powered by Xpert AI",
|
|
1099
|
+
followUps: {
|
|
1100
|
+
label: "Follow-up behavior",
|
|
1101
|
+
settings: "Settings",
|
|
1102
|
+
idleHint: "Used when you send while a run is active.",
|
|
1103
|
+
activeHint: "This message will use the selected busy-run behavior.",
|
|
1104
|
+
pending: "Pending follow-ups",
|
|
1105
|
+
queue: "Queue",
|
|
1106
|
+
steer: "Steer",
|
|
1107
|
+
steerAction: "Steer",
|
|
1108
|
+
promoteToSteer: "Steer now",
|
|
1109
|
+
sendNow: "Send now",
|
|
1110
|
+
remove: "Remove pending follow-up",
|
|
1111
|
+
more: "More actions",
|
|
1112
|
+
edit: "Edit message",
|
|
1113
|
+
turnOffQueueing: "Turn off queueing",
|
|
1114
|
+
queueHint: "Starts after the current run finishes",
|
|
1115
|
+
manualQueueHint: "Ready to send as a new run",
|
|
1116
|
+
steerHint: "Injects after the current tool call"
|
|
1117
|
+
},
|
|
576
1118
|
errors: {
|
|
577
1119
|
loadMessages: "Failed to load thread messages",
|
|
578
1120
|
createThread: "Failed to create thread",
|
|
@@ -603,13 +1145,24 @@ var en_US_default = {
|
|
|
603
1145
|
},
|
|
604
1146
|
composer: {
|
|
605
1147
|
openMenu: "Open menu",
|
|
606
|
-
addAttachment: "Add attachment"
|
|
1148
|
+
addAttachment: "Add attachment",
|
|
1149
|
+
removeReference: "Remove reference",
|
|
1150
|
+
quoteSelection: "Quote selection"
|
|
607
1151
|
},
|
|
608
1152
|
sheet: {
|
|
609
1153
|
close: "Close"
|
|
610
1154
|
},
|
|
611
1155
|
markdown: {
|
|
612
|
-
copy: "Copy"
|
|
1156
|
+
copy: "Copy",
|
|
1157
|
+
mermaid: {
|
|
1158
|
+
title: "Mermaid",
|
|
1159
|
+
diagram: "Diagram",
|
|
1160
|
+
code: "Code",
|
|
1161
|
+
download: "Download SVG",
|
|
1162
|
+
fullScreen: "Open full screen",
|
|
1163
|
+
rendering: "Rendering diagram",
|
|
1164
|
+
failed: "Failed to render diagram"
|
|
1165
|
+
}
|
|
613
1166
|
},
|
|
614
1167
|
thread: {
|
|
615
1168
|
errorToast: "An error occurred. Please try again.",
|
|
@@ -618,7 +1171,10 @@ var en_US_default = {
|
|
|
618
1171
|
},
|
|
619
1172
|
message: {
|
|
620
1173
|
answer: "Answer",
|
|
621
|
-
reasoning: "Reasoning"
|
|
1174
|
+
reasoning: "Reasoning",
|
|
1175
|
+
loading: "Loading",
|
|
1176
|
+
thinking: "Thinking",
|
|
1177
|
+
answering: "Answering"
|
|
622
1178
|
}
|
|
623
1179
|
};
|
|
624
1180
|
|
|
@@ -630,12 +1186,39 @@ var zh_CN_default = {
|
|
|
630
1186
|
statusOnline: "\u5728\u7EBF",
|
|
631
1187
|
missingConfigShort: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002",
|
|
632
1188
|
missingConfigDetail: "\u7F3A\u5C11 ChatKit \u914D\u7F6E\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u548C `clientSecret` \u53C2\u6570\u3002",
|
|
1189
|
+
missingApiUrlShort: "\u7F3A\u5C11 ChatKit API URL\u3002",
|
|
1190
|
+
missingApiUrlDetail: "\u7F3A\u5C11 ChatKit API URL\u3002\u8BF7\u68C0\u67E5 `VITE_XPERTAI_API_URL` \u6216 `options.api.apiUrl`\u3002",
|
|
1191
|
+
missingClientSecretShort: "\u7F3A\u5C11 ChatKit client secret\u3002",
|
|
1192
|
+
missingClientSecretDetail: "\u7F3A\u5C11 ChatKit client secret\u3002\u8BF7\u68C0\u67E5 `clientSecret` \u53C2\u6570\u6216 `api.getClientSecret` \u96C6\u6210\u3002",
|
|
1193
|
+
missingApiUrlAndClientSecretShort: "\u7F3A\u5C11 ChatKit API URL \u548C client secret\u3002",
|
|
1194
|
+
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",
|
|
633
1195
|
loadingThread: "\u6B63\u5728\u52A0\u8F7D\u7EBF\u7A0B...",
|
|
634
1196
|
stop: "\u505C\u6B62",
|
|
635
1197
|
send: "\u53D1\u9001\u6D88\u606F",
|
|
1198
|
+
referencedContentOnly: "\u5DF2\u5F15\u7528\u5185\u5BB9",
|
|
1199
|
+
youLabel: "\u4F60",
|
|
636
1200
|
scrollToBottom: "\u56DE\u5230\u5E95\u90E8",
|
|
637
1201
|
retryUpload: "\u91CD\u65B0\u4E0A\u4F20",
|
|
638
1202
|
poweredBy: "\u7531 Xpert AI \u9A71\u52A8",
|
|
1203
|
+
followUps: {
|
|
1204
|
+
label: "Follow-up \u6A21\u5F0F",
|
|
1205
|
+
settings: "\u8BBE\u7F6E",
|
|
1206
|
+
idleHint: "\u4EC5\u5728\u8FD0\u884C\u4E2D\u53D1\u9001\u6D88\u606F\u65F6\u751F\u6548\u3002",
|
|
1207
|
+
activeHint: "\u5F53\u524D\u6D88\u606F\u4F1A\u6309\u6240\u9009\u7684\u8FD0\u884C\u4E2D\u884C\u4E3A\u5904\u7406\u3002",
|
|
1208
|
+
pending: "\u5F85\u5904\u7406 Follow-up",
|
|
1209
|
+
queue: "\u6392\u961F",
|
|
1210
|
+
steer: "\u5F15\u5BFC",
|
|
1211
|
+
steerAction: "\u5F15\u5BFC",
|
|
1212
|
+
promoteToSteer: "\u8F6C\u4E3A\u5F15\u5BFC",
|
|
1213
|
+
sendNow: "\u7ACB\u5373\u53D1\u9001",
|
|
1214
|
+
remove: "\u79FB\u9664\u6B64\u5F85\u5904\u7406 Follow-up",
|
|
1215
|
+
more: "\u66F4\u591A\u64CD\u4F5C",
|
|
1216
|
+
edit: "\u7F16\u8F91\u6D88\u606F",
|
|
1217
|
+
turnOffQueueing: "\u5173\u95ED\u6392\u961F",
|
|
1218
|
+
queueHint: "\u5F53\u524D\u8FD0\u884C\u7ED3\u675F\u540E\u5F00\u542F\u4E0B\u4E00\u8F6E",
|
|
1219
|
+
manualQueueHint: "\u4FDD\u7559\u4E3A\u5F85\u53D1\u9001\uFF0C\u53EF\u624B\u52A8\u5F00\u542F\u65B0\u4E00\u8F6E",
|
|
1220
|
+
steerHint: "\u5F53\u524D\u5DE5\u5177\u8C03\u7528\u5B8C\u6210\u540E\u6CE8\u5165"
|
|
1221
|
+
},
|
|
639
1222
|
errors: {
|
|
640
1223
|
loadMessages: "\u52A0\u8F7D\u7EBF\u7A0B\u6D88\u606F\u5931\u8D25",
|
|
641
1224
|
createThread: "\u521B\u5EFA\u7EBF\u7A0B\u5931\u8D25",
|
|
@@ -666,13 +1249,24 @@ var zh_CN_default = {
|
|
|
666
1249
|
},
|
|
667
1250
|
composer: {
|
|
668
1251
|
openMenu: "\u6253\u5F00\u83DC\u5355",
|
|
669
|
-
addAttachment: "\u6DFB\u52A0\u9644\u4EF6"
|
|
1252
|
+
addAttachment: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1253
|
+
removeReference: "\u79FB\u9664\u5F15\u7528",
|
|
1254
|
+
quoteSelection: "\u5F15\u7528\u9009\u4E2D\u5185\u5BB9"
|
|
670
1255
|
},
|
|
671
1256
|
sheet: {
|
|
672
1257
|
close: "\u5173\u95ED"
|
|
673
1258
|
},
|
|
674
1259
|
markdown: {
|
|
675
|
-
copy: "\u590D\u5236"
|
|
1260
|
+
copy: "\u590D\u5236",
|
|
1261
|
+
mermaid: {
|
|
1262
|
+
title: "Mermaid",
|
|
1263
|
+
diagram: "\u56FE\u8868",
|
|
1264
|
+
code: "\u4EE3\u7801",
|
|
1265
|
+
download: "\u4E0B\u8F7D SVG",
|
|
1266
|
+
fullScreen: "\u5168\u5C4F\u67E5\u770B",
|
|
1267
|
+
rendering: "\u6B63\u5728\u6E32\u67D3\u56FE\u8868",
|
|
1268
|
+
failed: "\u56FE\u8868\u6E32\u67D3\u5931\u8D25"
|
|
1269
|
+
}
|
|
676
1270
|
},
|
|
677
1271
|
thread: {
|
|
678
1272
|
errorToast: "\u53D1\u751F\u9519\u8BEF\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
@@ -681,7 +1275,10 @@ var zh_CN_default = {
|
|
|
681
1275
|
},
|
|
682
1276
|
message: {
|
|
683
1277
|
answer: "\u56DE\u7B54",
|
|
684
|
-
reasoning: "\u63A8\u7406"
|
|
1278
|
+
reasoning: "\u63A8\u7406",
|
|
1279
|
+
loading: "\u6B63\u5728\u52A0\u8F7D",
|
|
1280
|
+
thinking: "\u6B63\u5728\u601D\u8003",
|
|
1281
|
+
answering: "\u6B63\u5728\u751F\u6210"
|
|
685
1282
|
}
|
|
686
1283
|
};
|
|
687
1284
|
|
|
@@ -1202,18 +1799,86 @@ function ComposerMenu({
|
|
|
1202
1799
|
|
|
1203
1800
|
// src/components/composer/SendButton.tsx
|
|
1204
1801
|
var import_lucide_react2 = require("lucide-react");
|
|
1802
|
+
|
|
1803
|
+
// src/components/ui/tooltip.tsx
|
|
1804
|
+
var React6 = require("react");
|
|
1805
|
+
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
|
|
1205
1806
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1807
|
+
function TooltipProvider({
|
|
1808
|
+
delayDuration = 0,
|
|
1809
|
+
...props
|
|
1810
|
+
}) {
|
|
1811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1812
|
+
TooltipPrimitive.Provider,
|
|
1813
|
+
{
|
|
1814
|
+
"data-slot": "tooltip-provider",
|
|
1815
|
+
delayDuration,
|
|
1816
|
+
...props
|
|
1817
|
+
}
|
|
1818
|
+
);
|
|
1819
|
+
}
|
|
1820
|
+
function Tooltip({
|
|
1821
|
+
...props
|
|
1822
|
+
}) {
|
|
1823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1824
|
+
TooltipPrimitive.Root,
|
|
1825
|
+
{
|
|
1826
|
+
"data-slot": "tooltip",
|
|
1827
|
+
...props
|
|
1828
|
+
}
|
|
1829
|
+
) });
|
|
1830
|
+
}
|
|
1831
|
+
function TooltipTrigger({
|
|
1832
|
+
...props
|
|
1833
|
+
}) {
|
|
1834
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1835
|
+
TooltipPrimitive.Trigger,
|
|
1836
|
+
{
|
|
1837
|
+
"data-slot": "tooltip-trigger",
|
|
1838
|
+
...props
|
|
1839
|
+
}
|
|
1840
|
+
);
|
|
1841
|
+
}
|
|
1842
|
+
function TooltipContent({
|
|
1843
|
+
className,
|
|
1844
|
+
sideOffset = 0,
|
|
1845
|
+
hideArrow = false,
|
|
1846
|
+
children,
|
|
1847
|
+
...props
|
|
1848
|
+
}) {
|
|
1849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1850
|
+
TooltipPrimitive.Content,
|
|
1851
|
+
{
|
|
1852
|
+
"data-slot": "tooltip-content",
|
|
1853
|
+
sideOffset,
|
|
1854
|
+
className: cn(
|
|
1855
|
+
"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",
|
|
1856
|
+
className
|
|
1857
|
+
),
|
|
1858
|
+
...props,
|
|
1859
|
+
children: [
|
|
1860
|
+
children,
|
|
1861
|
+
!hideArrow ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" }) : null
|
|
1862
|
+
]
|
|
1863
|
+
}
|
|
1864
|
+
) });
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
// src/components/composer/SendButton.tsx
|
|
1868
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1206
1869
|
function SendButton({
|
|
1207
1870
|
disabled = false,
|
|
1208
1871
|
isLoading = false,
|
|
1872
|
+
showStop = isLoading,
|
|
1209
1873
|
onStop,
|
|
1210
1874
|
stopLabel = "Stop",
|
|
1211
|
-
sendLabel = "Send"
|
|
1875
|
+
sendLabel = "Send",
|
|
1876
|
+
shortcuts
|
|
1212
1877
|
}) {
|
|
1213
1878
|
const { theme } = useTheme();
|
|
1214
1879
|
const roundedClass = getRoundedClass(theme.radius);
|
|
1215
|
-
if (
|
|
1216
|
-
return /* @__PURE__ */ (0,
|
|
1880
|
+
if (showStop) {
|
|
1881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1217
1882
|
"button",
|
|
1218
1883
|
{
|
|
1219
1884
|
type: "button",
|
|
@@ -1226,11 +1891,11 @@ function SendButton({
|
|
|
1226
1891
|
"hover:scale-105 active:scale-95"
|
|
1227
1892
|
),
|
|
1228
1893
|
"aria-label": stopLabel,
|
|
1229
|
-
children: /* @__PURE__ */ (0,
|
|
1894
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Square, { size: 14, fill: "currentColor", stroke: "currentColor", strokeWidth: 0 })
|
|
1230
1895
|
}
|
|
1231
1896
|
);
|
|
1232
1897
|
}
|
|
1233
|
-
|
|
1898
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1234
1899
|
"button",
|
|
1235
1900
|
{
|
|
1236
1901
|
type: "submit",
|
|
@@ -1244,34 +1909,63 @@ function SendButton({
|
|
|
1244
1909
|
"disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:scale-100"
|
|
1245
1910
|
),
|
|
1246
1911
|
"aria-label": sendLabel,
|
|
1247
|
-
children: /* @__PURE__ */ (0,
|
|
1912
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.ArrowUp, { size: 18, strokeWidth: 2.5 })
|
|
1248
1913
|
}
|
|
1249
1914
|
);
|
|
1915
|
+
if (!shortcuts?.length || disabled) {
|
|
1916
|
+
return button;
|
|
1917
|
+
}
|
|
1918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: button }),
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1921
|
+
TooltipContent,
|
|
1922
|
+
{
|
|
1923
|
+
side: "top",
|
|
1924
|
+
sideOffset: 10,
|
|
1925
|
+
hideArrow: true,
|
|
1926
|
+
className: cn(
|
|
1927
|
+
"min-w-36 border border-border/70 bg-background px-3 py-2 text-foreground shadow-lg",
|
|
1928
|
+
roundedClass
|
|
1929
|
+
),
|
|
1930
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "space-y-1", children: shortcuts.map((shortcut) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1931
|
+
"div",
|
|
1932
|
+
{
|
|
1933
|
+
className: "flex items-center justify-between gap-4 text-sm",
|
|
1934
|
+
children: [
|
|
1935
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "font-medium", children: shortcut.label }),
|
|
1936
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("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 })
|
|
1937
|
+
]
|
|
1938
|
+
},
|
|
1939
|
+
`${shortcut.label}-${shortcut.keys}`
|
|
1940
|
+
)) })
|
|
1941
|
+
}
|
|
1942
|
+
)
|
|
1943
|
+
] });
|
|
1250
1944
|
}
|
|
1251
1945
|
|
|
1252
1946
|
// src/components/history/HistorySidebar.tsx
|
|
1253
|
-
var
|
|
1947
|
+
var React9 = __toESM(require("react"), 1);
|
|
1254
1948
|
var import_lucide_react4 = require("lucide-react");
|
|
1255
1949
|
|
|
1256
1950
|
// src/components/ui/scroll-area.tsx
|
|
1257
|
-
var
|
|
1951
|
+
var React7 = __toESM(require("react"), 1);
|
|
1258
1952
|
var ScrollAreaPrimitive = __toESM(require("@radix-ui/react-scroll-area"), 1);
|
|
1259
|
-
var
|
|
1260
|
-
var ScrollArea =
|
|
1953
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1954
|
+
var ScrollArea = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1261
1955
|
ScrollAreaPrimitive.Root,
|
|
1262
1956
|
{
|
|
1263
1957
|
ref,
|
|
1264
1958
|
className: cn("relative overflow-hidden", className),
|
|
1265
1959
|
...props,
|
|
1266
1960
|
children: [
|
|
1267
|
-
/* @__PURE__ */ (0,
|
|
1268
|
-
/* @__PURE__ */ (0,
|
|
1269
|
-
/* @__PURE__ */ (0,
|
|
1961
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
1962
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollBar, {}),
|
|
1963
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollAreaPrimitive.Corner, {})
|
|
1270
1964
|
]
|
|
1271
1965
|
}
|
|
1272
1966
|
));
|
|
1273
1967
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
1274
|
-
var ScrollBar =
|
|
1968
|
+
var ScrollBar = React7.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1275
1969
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
1276
1970
|
{
|
|
1277
1971
|
ref,
|
|
@@ -1283,30 +1977,30 @@ var ScrollBar = React6.forwardRef(({ className, orientation = "vertical", ...pro
|
|
|
1283
1977
|
className
|
|
1284
1978
|
),
|
|
1285
1979
|
...props,
|
|
1286
|
-
children: /* @__PURE__ */ (0,
|
|
1980
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
1287
1981
|
}
|
|
1288
1982
|
));
|
|
1289
1983
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
1290
1984
|
|
|
1291
1985
|
// src/components/ui/sheet.tsx
|
|
1292
|
-
var
|
|
1986
|
+
var React8 = require("react");
|
|
1293
1987
|
var import_lucide_react3 = require("lucide-react");
|
|
1294
1988
|
var SheetPrimitive = __toESM(require("@radix-ui/react-dialog"), 1);
|
|
1295
|
-
var
|
|
1989
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1296
1990
|
function Sheet({ ...props }) {
|
|
1297
|
-
return /* @__PURE__ */ (0,
|
|
1991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SheetPrimitive.Root, { ...props });
|
|
1298
1992
|
}
|
|
1299
1993
|
function SheetTrigger({ ...props }) {
|
|
1300
|
-
return /* @__PURE__ */ (0,
|
|
1994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SheetPrimitive.Trigger, { ...props });
|
|
1301
1995
|
}
|
|
1302
1996
|
function SheetPortal({ ...props }) {
|
|
1303
|
-
return /* @__PURE__ */ (0,
|
|
1997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SheetPrimitive.Portal, { ...props });
|
|
1304
1998
|
}
|
|
1305
1999
|
function SheetOverlay({
|
|
1306
2000
|
className,
|
|
1307
2001
|
...props
|
|
1308
2002
|
}) {
|
|
1309
|
-
return /* @__PURE__ */ (0,
|
|
2003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1310
2004
|
SheetPrimitive.Overlay,
|
|
1311
2005
|
{
|
|
1312
2006
|
className: cn(
|
|
@@ -1330,9 +2024,9 @@ function SheetContent({
|
|
|
1330
2024
|
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",
|
|
1331
2025
|
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"
|
|
1332
2026
|
};
|
|
1333
|
-
return /* @__PURE__ */ (0,
|
|
1334
|
-
/* @__PURE__ */ (0,
|
|
1335
|
-
/* @__PURE__ */ (0,
|
|
2027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(SheetPortal, { children: [
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SheetOverlay, {}),
|
|
2029
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1336
2030
|
SheetPrimitive.Content,
|
|
1337
2031
|
{
|
|
1338
2032
|
className: cn(
|
|
@@ -1343,9 +2037,9 @@ function SheetContent({
|
|
|
1343
2037
|
...props,
|
|
1344
2038
|
children: [
|
|
1345
2039
|
children,
|
|
1346
|
-
/* @__PURE__ */ (0,
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1348
|
-
/* @__PURE__ */ (0,
|
|
2040
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(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: [
|
|
2041
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react3.X, { size: 16 }),
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "sr-only", children: t("sheet.close") })
|
|
1349
2043
|
] })
|
|
1350
2044
|
]
|
|
1351
2045
|
}
|
|
@@ -1356,7 +2050,7 @@ function SheetHeader({
|
|
|
1356
2050
|
className,
|
|
1357
2051
|
...props
|
|
1358
2052
|
}) {
|
|
1359
|
-
return /* @__PURE__ */ (0,
|
|
2053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1360
2054
|
"div",
|
|
1361
2055
|
{
|
|
1362
2056
|
className: cn(
|
|
@@ -1371,7 +2065,7 @@ function SheetTitle({
|
|
|
1371
2065
|
className,
|
|
1372
2066
|
...props
|
|
1373
2067
|
}) {
|
|
1374
|
-
return /* @__PURE__ */ (0,
|
|
2068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1375
2069
|
SheetPrimitive.Title,
|
|
1376
2070
|
{
|
|
1377
2071
|
className: cn("text-lg font-semibold text-foreground", className),
|
|
@@ -1381,7 +2075,7 @@ function SheetTitle({
|
|
|
1381
2075
|
}
|
|
1382
2076
|
|
|
1383
2077
|
// src/components/history/HistorySidebar.tsx
|
|
1384
|
-
var
|
|
2078
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1385
2079
|
function HistorySidebar({
|
|
1386
2080
|
threads = [],
|
|
1387
2081
|
currentThreadId,
|
|
@@ -1392,7 +2086,7 @@ function HistorySidebar({
|
|
|
1392
2086
|
disabled = false
|
|
1393
2087
|
}) {
|
|
1394
2088
|
const { t } = useChatkitTranslation();
|
|
1395
|
-
const [open, setOpen] =
|
|
2089
|
+
const [open, setOpen] = React9.useState(false);
|
|
1396
2090
|
const handleNewThread = () => {
|
|
1397
2091
|
onNewThread?.();
|
|
1398
2092
|
setOpen(false);
|
|
@@ -1401,8 +2095,8 @@ function HistorySidebar({
|
|
|
1401
2095
|
onSelectThread?.(id);
|
|
1402
2096
|
setOpen(false);
|
|
1403
2097
|
};
|
|
1404
|
-
return /* @__PURE__ */ (0,
|
|
1405
|
-
/* @__PURE__ */ (0,
|
|
2098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Sheet, { open, onOpenChange: setOpen, children: [
|
|
2099
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1406
2100
|
Button,
|
|
1407
2101
|
{
|
|
1408
2102
|
variant: "ghost",
|
|
@@ -1410,26 +2104,26 @@ function HistorySidebar({
|
|
|
1410
2104
|
disabled,
|
|
1411
2105
|
className: "h-8 w-8 cursor-pointer",
|
|
1412
2106
|
children: [
|
|
1413
|
-
/* @__PURE__ */ (0,
|
|
1414
|
-
/* @__PURE__ */ (0,
|
|
2107
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.History, { size: 16 }),
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "sr-only", children: t("history.threadHistory") })
|
|
1415
2109
|
]
|
|
1416
2110
|
}
|
|
1417
2111
|
) }),
|
|
1418
|
-
/* @__PURE__ */ (0,
|
|
1419
|
-
/* @__PURE__ */ (0,
|
|
1420
|
-
/* @__PURE__ */ (0,
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(SheetContent, { side: "right", className: "w-80 p-0", children: [
|
|
2113
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetHeader, { className: "border-b p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SheetTitle, { children: t("history.title") }) }),
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "p-4", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1421
2115
|
Button,
|
|
1422
2116
|
{
|
|
1423
2117
|
onClick: handleNewThread,
|
|
1424
2118
|
className: "w-full justify-start gap-2",
|
|
1425
2119
|
variant: "secondary",
|
|
1426
2120
|
children: [
|
|
1427
|
-
/* @__PURE__ */ (0,
|
|
2121
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.PlusCircle, { size: 16 }),
|
|
1428
2122
|
t("history.newThread")
|
|
1429
2123
|
]
|
|
1430
2124
|
}
|
|
1431
2125
|
) }),
|
|
1432
|
-
/* @__PURE__ */ (0,
|
|
2126
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ScrollArea, { className: "h-[calc(100vh-140px)]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "px-4 pb-4", children: threads.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "py-8 text-center text-sm text-muted-foreground", children: t("history.empty") }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "space-y-1", children: threads.map((thread) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1433
2127
|
"div",
|
|
1434
2128
|
{
|
|
1435
2129
|
className: cn(
|
|
@@ -1439,9 +2133,9 @@ function HistorySidebar({
|
|
|
1439
2133
|
),
|
|
1440
2134
|
onClick: () => handleSelectThread(thread.id),
|
|
1441
2135
|
children: [
|
|
1442
|
-
/* @__PURE__ */ (0,
|
|
1443
|
-
/* @__PURE__ */ (0,
|
|
1444
|
-
showDelete && onDeleteThread && /* @__PURE__ */ (0,
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.MessageSquare, { size: 16 }) }),
|
|
2137
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "flex-1 truncate", children: thread.title }),
|
|
2138
|
+
showDelete && onDeleteThread && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1445
2139
|
"button",
|
|
1446
2140
|
{
|
|
1447
2141
|
type: "button",
|
|
@@ -1450,7 +2144,7 @@ function HistorySidebar({
|
|
|
1450
2144
|
onDeleteThread(thread.id);
|
|
1451
2145
|
},
|
|
1452
2146
|
className: "opacity-0 group-hover:opacity-100 p-1 rounded hover:bg-destructive/10 hover:text-destructive transition-all",
|
|
1453
|
-
children: /* @__PURE__ */ (0,
|
|
2147
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react4.Trash2, { size: 14 })
|
|
1454
2148
|
}
|
|
1455
2149
|
)
|
|
1456
2150
|
]
|
|
@@ -1461,31 +2155,327 @@ function HistorySidebar({
|
|
|
1461
2155
|
] });
|
|
1462
2156
|
}
|
|
1463
2157
|
|
|
1464
|
-
// src/components/
|
|
1465
|
-
var
|
|
1466
|
-
var
|
|
2158
|
+
// src/components/composer/pending-follow-ups.tsx
|
|
2159
|
+
var React10 = __toESM(require("react"), 1);
|
|
2160
|
+
var import_lucide_react5 = require("lucide-react");
|
|
2161
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2162
|
+
function getPendingFollowUpText(item, referencedContentFallback) {
|
|
2163
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
2164
|
+
if (text) {
|
|
2165
|
+
return text;
|
|
2166
|
+
}
|
|
2167
|
+
const references = normalizeReferences(item.request?.input?.references);
|
|
2168
|
+
if (references.length === 0) {
|
|
2169
|
+
return referencedContentFallback;
|
|
2170
|
+
}
|
|
2171
|
+
const firstReferenceLabel = getReferenceLabel(references[0]);
|
|
2172
|
+
if (references.length === 1) {
|
|
2173
|
+
return firstReferenceLabel;
|
|
2174
|
+
}
|
|
2175
|
+
return `${firstReferenceLabel} +${references.length - 1}`;
|
|
2176
|
+
}
|
|
2177
|
+
function useRoundedClasses() {
|
|
2178
|
+
const { theme } = useTheme();
|
|
2179
|
+
return {
|
|
2180
|
+
top: theme.radius ? {
|
|
2181
|
+
pill: "rounded-t-full",
|
|
2182
|
+
round: "rounded-t-xl",
|
|
2183
|
+
soft: "rounded-t-lg",
|
|
2184
|
+
sharp: "rounded-t-none"
|
|
2185
|
+
}[theme.radius] : "rounded-t-lg",
|
|
2186
|
+
panel: getRoundedClass(theme.radius, "rounded-lg"),
|
|
2187
|
+
control: getRoundedClass(theme.radius, "rounded-md")
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
function PendingFollowUps({
|
|
2191
|
+
items,
|
|
2192
|
+
isLoading,
|
|
2193
|
+
followUpBehavior,
|
|
2194
|
+
onBehaviorChange,
|
|
2195
|
+
onPromoteToSteer,
|
|
2196
|
+
canSendNow,
|
|
2197
|
+
onSendNow,
|
|
2198
|
+
onEdit,
|
|
2199
|
+
onRemove,
|
|
2200
|
+
className
|
|
2201
|
+
}) {
|
|
2202
|
+
const { t } = useChatkitTranslation();
|
|
2203
|
+
const rounded = useRoundedClasses();
|
|
2204
|
+
const referencedContentFallback = t("chat.referencedContentOnly");
|
|
2205
|
+
const [isSettingsOpen, setIsSettingsOpen] = React10.useState(false);
|
|
2206
|
+
const [openMenuId, setOpenMenuId] = React10.useState(null);
|
|
2207
|
+
React10.useEffect(() => {
|
|
2208
|
+
if (items.length === 0 && isSettingsOpen) {
|
|
2209
|
+
setIsSettingsOpen(false);
|
|
2210
|
+
}
|
|
2211
|
+
if (items.every((item) => item.id !== openMenuId)) {
|
|
2212
|
+
setOpenMenuId(null);
|
|
2213
|
+
}
|
|
2214
|
+
}, [isSettingsOpen, items, openMenuId]);
|
|
2215
|
+
if (items.length === 0) {
|
|
2216
|
+
return null;
|
|
2217
|
+
}
|
|
2218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2219
|
+
"div",
|
|
2220
|
+
{
|
|
2221
|
+
className: cn(
|
|
2222
|
+
"space-y-2 mx-2 p-2 border border-border border-b-0",
|
|
2223
|
+
rounded.top,
|
|
2224
|
+
className
|
|
2225
|
+
),
|
|
2226
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1", children: [
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.pending") }),
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Tooltip, { children: [
|
|
2230
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2231
|
+
"button",
|
|
2232
|
+
{
|
|
2233
|
+
type: "button",
|
|
2234
|
+
onClick: () => setIsSettingsOpen((prev) => !prev),
|
|
2235
|
+
className: cn(
|
|
2236
|
+
"inline-flex h-6 w-6 items-center justify-center transition-colors",
|
|
2237
|
+
isSettingsOpen ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/60 hover:text-foreground",
|
|
2238
|
+
rounded.control
|
|
2239
|
+
),
|
|
2240
|
+
"aria-label": t("chat.followUps.settings"),
|
|
2241
|
+
"aria-expanded": isSettingsOpen,
|
|
2242
|
+
"aria-controls": "follow-ups-settings-panel",
|
|
2243
|
+
children: [
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.SlidersHorizontal, { className: "h-3.5 w-3.5" }),
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "sr-only", children: t("chat.followUps.settings") })
|
|
2246
|
+
]
|
|
2247
|
+
}
|
|
2248
|
+
) }),
|
|
2249
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipContent, { side: "top", children: t("chat.followUps.settings") })
|
|
2250
|
+
] })
|
|
2251
|
+
] }),
|
|
2252
|
+
isSettingsOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2253
|
+
"div",
|
|
2254
|
+
{
|
|
2255
|
+
id: "follow-ups-settings-panel",
|
|
2256
|
+
className: cn(
|
|
2257
|
+
"border border-border/70 bg-muted/20 px-3 py-2",
|
|
2258
|
+
rounded.panel
|
|
2259
|
+
),
|
|
2260
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2261
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "min-w-0", children: [
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-xs font-medium text-foreground", children: t("chat.followUps.label") }),
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-[11px] text-muted-foreground", children: isLoading ? t("chat.followUps.activeHint") : t("chat.followUps.idleHint") })
|
|
2264
|
+
] }),
|
|
2265
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2266
|
+
"div",
|
|
2267
|
+
{
|
|
2268
|
+
className: cn(
|
|
2269
|
+
"inline-flex shrink-0 border border-border bg-background p-1",
|
|
2270
|
+
rounded.control
|
|
2271
|
+
),
|
|
2272
|
+
children: ["queue", "steer"].map((behavior) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Tooltip, { children: [
|
|
2273
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2274
|
+
"button",
|
|
2275
|
+
{
|
|
2276
|
+
type: "button",
|
|
2277
|
+
onClick: () => {
|
|
2278
|
+
onBehaviorChange(behavior);
|
|
2279
|
+
setIsSettingsOpen(false);
|
|
2280
|
+
},
|
|
2281
|
+
className: cn(
|
|
2282
|
+
"px-3 py-1 text-xs font-medium transition-colors",
|
|
2283
|
+
rounded.control,
|
|
2284
|
+
followUpBehavior === behavior ? "bg-primary text-background" : "text-muted-foreground hover:text-foreground"
|
|
2285
|
+
),
|
|
2286
|
+
children: behavior === "queue" ? t("chat.followUps.queue") : t("chat.followUps.steer")
|
|
2287
|
+
}
|
|
2288
|
+
) }),
|
|
2289
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipContent, { side: "top", children: behavior === "queue" ? t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2290
|
+
] }, behavior))
|
|
2291
|
+
}
|
|
2292
|
+
)
|
|
2293
|
+
] })
|
|
2294
|
+
}
|
|
2295
|
+
),
|
|
2296
|
+
items.map((item) => {
|
|
2297
|
+
const canSendItemNow = item.mode === "queue" && canSendNow(item.id);
|
|
2298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2299
|
+
"div",
|
|
2300
|
+
{
|
|
2301
|
+
className: cn(
|
|
2302
|
+
"border border-border/50 bg-muted/15 px-2 py-1",
|
|
2303
|
+
rounded.panel
|
|
2304
|
+
),
|
|
2305
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start gap-2.5", children: [
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.CornerDownLeft, { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
2308
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start gap-2", children: [
|
|
2309
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2310
|
+
"div",
|
|
2311
|
+
{
|
|
2312
|
+
className: "truncate text-[13px] leading-5 text-foreground",
|
|
2313
|
+
title: getPendingFollowUpText(
|
|
2314
|
+
item,
|
|
2315
|
+
referencedContentFallback
|
|
2316
|
+
),
|
|
2317
|
+
children: getPendingFollowUpText(
|
|
2318
|
+
item,
|
|
2319
|
+
referencedContentFallback
|
|
2320
|
+
)
|
|
2321
|
+
}
|
|
2322
|
+
) }),
|
|
2323
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
2324
|
+
item.mode === "queue" && isLoading && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2325
|
+
"button",
|
|
2326
|
+
{
|
|
2327
|
+
type: "button",
|
|
2328
|
+
onClick: () => void onPromoteToSteer(item.id),
|
|
2329
|
+
className: cn(
|
|
2330
|
+
"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",
|
|
2331
|
+
rounded.control
|
|
2332
|
+
),
|
|
2333
|
+
"aria-label": t("chat.followUps.steerAction"),
|
|
2334
|
+
title: t("chat.followUps.steerAction"),
|
|
2335
|
+
children: t("chat.followUps.steerAction")
|
|
2336
|
+
}
|
|
2337
|
+
),
|
|
2338
|
+
canSendItemNow && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2339
|
+
"button",
|
|
2340
|
+
{
|
|
2341
|
+
type: "button",
|
|
2342
|
+
onClick: () => void onSendNow(item.id),
|
|
2343
|
+
className: cn(
|
|
2344
|
+
"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",
|
|
2345
|
+
rounded.control
|
|
2346
|
+
),
|
|
2347
|
+
"aria-label": t("chat.followUps.sendNow"),
|
|
2348
|
+
title: t("chat.followUps.sendNow"),
|
|
2349
|
+
children: t("chat.followUps.sendNow")
|
|
2350
|
+
}
|
|
2351
|
+
),
|
|
2352
|
+
item.mode === "queue" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2353
|
+
"button",
|
|
2354
|
+
{
|
|
2355
|
+
type: "button",
|
|
2356
|
+
onClick: () => onRemove(item.id),
|
|
2357
|
+
className: cn(
|
|
2358
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2359
|
+
rounded.control
|
|
2360
|
+
),
|
|
2361
|
+
"aria-label": t("chat.followUps.remove"),
|
|
2362
|
+
title: t("chat.followUps.remove"),
|
|
2363
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Trash2, { size: 13 })
|
|
2364
|
+
}
|
|
2365
|
+
),
|
|
2366
|
+
item.mode === "queue" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2367
|
+
Popover,
|
|
2368
|
+
{
|
|
2369
|
+
open: openMenuId === item.id,
|
|
2370
|
+
onOpenChange: (open) => setOpenMenuId(open ? item.id : null),
|
|
2371
|
+
children: [
|
|
2372
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2373
|
+
"button",
|
|
2374
|
+
{
|
|
2375
|
+
type: "button",
|
|
2376
|
+
className: cn(
|
|
2377
|
+
"inline-flex h-6 w-6 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
2378
|
+
rounded.control
|
|
2379
|
+
),
|
|
2380
|
+
"aria-label": t("chat.followUps.more"),
|
|
2381
|
+
title: t("chat.followUps.more"),
|
|
2382
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Ellipsis, { size: 13 })
|
|
2383
|
+
}
|
|
2384
|
+
) }),
|
|
2385
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2386
|
+
PopoverContent,
|
|
2387
|
+
{
|
|
2388
|
+
align: "end",
|
|
2389
|
+
side: "bottom",
|
|
2390
|
+
className: cn(
|
|
2391
|
+
"w-52 border-border/70 bg-background p-1.5",
|
|
2392
|
+
rounded.panel
|
|
2393
|
+
),
|
|
2394
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
2395
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2396
|
+
"button",
|
|
2397
|
+
{
|
|
2398
|
+
type: "button",
|
|
2399
|
+
onClick: () => {
|
|
2400
|
+
setOpenMenuId(null);
|
|
2401
|
+
onEdit(item.id);
|
|
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__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.PencilLine, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2409
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t("chat.followUps.edit") })
|
|
2410
|
+
]
|
|
2411
|
+
}
|
|
2412
|
+
),
|
|
2413
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2414
|
+
"button",
|
|
2415
|
+
{
|
|
2416
|
+
type: "button",
|
|
2417
|
+
onClick: () => {
|
|
2418
|
+
setOpenMenuId(null);
|
|
2419
|
+
onBehaviorChange("steer");
|
|
2420
|
+
},
|
|
2421
|
+
className: cn(
|
|
2422
|
+
"flex items-center gap-2 px-2 py-1.5 text-left text-sm text-foreground transition-colors hover:bg-muted",
|
|
2423
|
+
rounded.control
|
|
2424
|
+
),
|
|
2425
|
+
children: [
|
|
2426
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.CornerDownLeft, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
2427
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t("chat.followUps.turnOffQueueing") })
|
|
2428
|
+
]
|
|
2429
|
+
}
|
|
2430
|
+
)
|
|
2431
|
+
] })
|
|
2432
|
+
}
|
|
2433
|
+
)
|
|
2434
|
+
]
|
|
2435
|
+
}
|
|
2436
|
+
)
|
|
2437
|
+
] })
|
|
2438
|
+
] }),
|
|
2439
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-1.5 text-[10px] leading-4 text-muted-foreground", children: [
|
|
2440
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react5.Info, { className: "h-3 w-3 shrink-0" }),
|
|
2441
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: item.mode === "queue" ? canSendItemNow ? t("chat.followUps.manualQueueHint") : t("chat.followUps.queueHint") : t("chat.followUps.steerHint") })
|
|
2442
|
+
] })
|
|
2443
|
+
] })
|
|
2444
|
+
] })
|
|
2445
|
+
},
|
|
2446
|
+
item.id
|
|
2447
|
+
);
|
|
2448
|
+
})
|
|
2449
|
+
] })
|
|
2450
|
+
}
|
|
2451
|
+
);
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
// src/components/thread/messages/ai.tsx
|
|
2455
|
+
var React15 = __toESM(require("react"), 1);
|
|
2456
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1467
2457
|
|
|
1468
2458
|
// src/components/ui/badge.tsx
|
|
1469
|
-
var
|
|
1470
|
-
var
|
|
2459
|
+
var React11 = __toESM(require("react"), 1);
|
|
2460
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1471
2461
|
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";
|
|
1472
2462
|
var variants = {
|
|
1473
2463
|
default: "bg-primary text-primary-foreground",
|
|
1474
2464
|
secondary: "bg-secondary text-secondary-foreground",
|
|
1475
2465
|
outline: "border-input text-foreground"
|
|
1476
2466
|
};
|
|
1477
|
-
var Badge =
|
|
2467
|
+
var Badge = React11.forwardRef(
|
|
1478
2468
|
({ className, variant = "default", ...props }, ref) => {
|
|
1479
|
-
return /* @__PURE__ */ (0,
|
|
2469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { ref, className: cn(base, variants[variant], className), ...props });
|
|
1480
2470
|
}
|
|
1481
2471
|
);
|
|
1482
2472
|
Badge.displayName = "Badge";
|
|
1483
2473
|
|
|
1484
2474
|
// src/components/ui/card.tsx
|
|
1485
|
-
var
|
|
1486
|
-
var
|
|
1487
|
-
var Card =
|
|
1488
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2475
|
+
var React12 = __toESM(require("react"), 1);
|
|
2476
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2477
|
+
var Card = React12.forwardRef(
|
|
2478
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1489
2479
|
"div",
|
|
1490
2480
|
{
|
|
1491
2481
|
ref,
|
|
@@ -1498,50 +2488,50 @@ var Card = React10.forwardRef(
|
|
|
1498
2488
|
)
|
|
1499
2489
|
);
|
|
1500
2490
|
Card.displayName = "Card";
|
|
1501
|
-
var CardHeader =
|
|
1502
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2491
|
+
var CardHeader = React12.forwardRef(
|
|
2492
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref, className: cn("flex flex-col gap-1.5 px-6 pt-6", className), ...props })
|
|
1503
2493
|
);
|
|
1504
2494
|
CardHeader.displayName = "CardHeader";
|
|
1505
|
-
var CardTitle =
|
|
2495
|
+
var CardTitle = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { ref, className: cn("text-lg font-semibold leading-tight", className), ...props }));
|
|
1506
2496
|
CardTitle.displayName = "CardTitle";
|
|
1507
|
-
var CardDescription =
|
|
2497
|
+
var CardDescription = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
1508
2498
|
CardDescription.displayName = "CardDescription";
|
|
1509
|
-
var CardContent =
|
|
1510
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2499
|
+
var CardContent = React12.forwardRef(
|
|
2500
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref, className: cn("px-6 pb-6", className), ...props })
|
|
1511
2501
|
);
|
|
1512
2502
|
CardContent.displayName = "CardContent";
|
|
1513
|
-
var CardFooter =
|
|
1514
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2503
|
+
var CardFooter = React12.forwardRef(
|
|
2504
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref, className: cn("flex items-center px-6 pb-6", className), ...props })
|
|
1515
2505
|
);
|
|
1516
2506
|
CardFooter.displayName = "CardFooter";
|
|
1517
|
-
var CardAction =
|
|
1518
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2507
|
+
var CardAction = React12.forwardRef(
|
|
2508
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { ref, className: cn("ml-auto flex items-center", className), ...props })
|
|
1519
2509
|
);
|
|
1520
2510
|
CardAction.displayName = "CardAction";
|
|
1521
2511
|
|
|
1522
2512
|
// src/components/ui/tabs.tsx
|
|
1523
|
-
var
|
|
1524
|
-
var
|
|
1525
|
-
var TabsContext =
|
|
2513
|
+
var React13 = __toESM(require("react"), 1);
|
|
2514
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2515
|
+
var TabsContext = React13.createContext(null);
|
|
1526
2516
|
function Tabs({ className, defaultValue, value, onValueChange, ...props }) {
|
|
1527
|
-
const [internalValue, setInternalValue] =
|
|
2517
|
+
const [internalValue, setInternalValue] = React13.useState(defaultValue ?? "");
|
|
1528
2518
|
const activeValue = value ?? internalValue;
|
|
1529
|
-
const setValue =
|
|
2519
|
+
const setValue = React13.useCallback(
|
|
1530
2520
|
(nextValue) => {
|
|
1531
2521
|
if (value === void 0) setInternalValue(nextValue);
|
|
1532
2522
|
onValueChange?.(nextValue);
|
|
1533
2523
|
},
|
|
1534
2524
|
[onValueChange, value]
|
|
1535
2525
|
);
|
|
1536
|
-
return /* @__PURE__ */ (0,
|
|
2526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TabsContext.Provider, { value: { value: activeValue, setValue }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn("w-full", className), ...props }) });
|
|
1537
2527
|
}
|
|
1538
|
-
var TabsList =
|
|
1539
|
-
({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
2528
|
+
var TabsList = React13.forwardRef(
|
|
2529
|
+
({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1540
2530
|
"div",
|
|
1541
2531
|
{
|
|
1542
2532
|
ref,
|
|
1543
2533
|
className: cn(
|
|
1544
|
-
"inline-flex
|
|
2534
|
+
"inline-flex items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
|
1545
2535
|
className
|
|
1546
2536
|
),
|
|
1547
2537
|
role: "tablist",
|
|
@@ -1550,14 +2540,14 @@ var TabsList = React11.forwardRef(
|
|
|
1550
2540
|
)
|
|
1551
2541
|
);
|
|
1552
2542
|
TabsList.displayName = "TabsList";
|
|
1553
|
-
var TabsTrigger =
|
|
2543
|
+
var TabsTrigger = React13.forwardRef(
|
|
1554
2544
|
({ className, value, onClick, ...props }, ref) => {
|
|
1555
|
-
const context =
|
|
2545
|
+
const context = React13.useContext(TabsContext);
|
|
1556
2546
|
if (!context) {
|
|
1557
2547
|
throw new Error("TabsTrigger must be used within Tabs");
|
|
1558
2548
|
}
|
|
1559
2549
|
const isActive = context.value === value;
|
|
1560
|
-
return /* @__PURE__ */ (0,
|
|
2550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1561
2551
|
"button",
|
|
1562
2552
|
{
|
|
1563
2553
|
ref,
|
|
@@ -1566,7 +2556,7 @@ var TabsTrigger = React11.forwardRef(
|
|
|
1566
2556
|
"aria-selected": isActive,
|
|
1567
2557
|
"data-state": isActive ? "active" : "inactive",
|
|
1568
2558
|
className: cn(
|
|
1569
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-
|
|
2559
|
+
"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",
|
|
1570
2560
|
className
|
|
1571
2561
|
),
|
|
1572
2562
|
onClick: (event) => {
|
|
@@ -1579,14 +2569,14 @@ var TabsTrigger = React11.forwardRef(
|
|
|
1579
2569
|
}
|
|
1580
2570
|
);
|
|
1581
2571
|
TabsTrigger.displayName = "TabsTrigger";
|
|
1582
|
-
var TabsContent =
|
|
2572
|
+
var TabsContent = React13.forwardRef(
|
|
1583
2573
|
({ className, value, ...props }, ref) => {
|
|
1584
|
-
const context =
|
|
2574
|
+
const context = React13.useContext(TabsContext);
|
|
1585
2575
|
if (!context) {
|
|
1586
2576
|
throw new Error("TabsContent must be used within Tabs");
|
|
1587
2577
|
}
|
|
1588
2578
|
if (context.value !== value) return null;
|
|
1589
|
-
return /* @__PURE__ */ (0,
|
|
2579
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1590
2580
|
"div",
|
|
1591
2581
|
{
|
|
1592
2582
|
ref,
|
|
@@ -1608,7 +2598,7 @@ var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
|
1608
2598
|
var import_rehype_katex = __toESM(require("rehype-katex"), 1);
|
|
1609
2599
|
var import_remark_math = __toESM(require("remark-math"), 1);
|
|
1610
2600
|
var import_react6 = require("react");
|
|
1611
|
-
var
|
|
2601
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1612
2602
|
|
|
1613
2603
|
// src/components/thread/syntax-highlighter.tsx
|
|
1614
2604
|
var import_react_syntax_highlighter = require("react-syntax-highlighter");
|
|
@@ -1616,7 +2606,7 @@ var import_tsx = __toESM(require("react-syntax-highlighter/dist/esm/languages/pr
|
|
|
1616
2606
|
var import_python = __toESM(require("react-syntax-highlighter/dist/esm/languages/prism/python"), 1);
|
|
1617
2607
|
var import_prism = require("react-syntax-highlighter/dist/cjs/styles/prism");
|
|
1618
2608
|
var import_react4 = require("react");
|
|
1619
|
-
var
|
|
2609
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1620
2610
|
import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("js", import_tsx.default);
|
|
1621
2611
|
import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("jsx", import_tsx.default);
|
|
1622
2612
|
import_react_syntax_highlighter.PrismAsyncLight.registerLanguage("ts", import_tsx.default);
|
|
@@ -1627,7 +2617,7 @@ var SyntaxHighlighter = ({
|
|
|
1627
2617
|
language,
|
|
1628
2618
|
className
|
|
1629
2619
|
}) => {
|
|
1630
|
-
return /* @__PURE__ */ (0,
|
|
2620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1631
2621
|
import_react_syntax_highlighter.PrismAsyncLight,
|
|
1632
2622
|
{
|
|
1633
2623
|
language,
|
|
@@ -1644,77 +2634,18 @@ var SyntaxHighlighter = ({
|
|
|
1644
2634
|
);
|
|
1645
2635
|
};
|
|
1646
2636
|
|
|
1647
|
-
// src/components/thread/
|
|
1648
|
-
var
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
var
|
|
1652
|
-
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
|
|
1653
|
-
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1654
|
-
function TooltipProvider({
|
|
1655
|
-
delayDuration = 0,
|
|
1656
|
-
...props
|
|
1657
|
-
}) {
|
|
1658
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1659
|
-
TooltipPrimitive.Provider,
|
|
1660
|
-
{
|
|
1661
|
-
"data-slot": "tooltip-provider",
|
|
1662
|
-
delayDuration,
|
|
1663
|
-
...props
|
|
1664
|
-
}
|
|
1665
|
-
);
|
|
1666
|
-
}
|
|
1667
|
-
function Tooltip({
|
|
1668
|
-
...props
|
|
1669
|
-
}) {
|
|
1670
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1671
|
-
TooltipPrimitive.Root,
|
|
1672
|
-
{
|
|
1673
|
-
"data-slot": "tooltip",
|
|
1674
|
-
...props
|
|
1675
|
-
}
|
|
1676
|
-
) });
|
|
1677
|
-
}
|
|
1678
|
-
function TooltipTrigger({
|
|
1679
|
-
...props
|
|
1680
|
-
}) {
|
|
1681
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1682
|
-
TooltipPrimitive.Trigger,
|
|
1683
|
-
{
|
|
1684
|
-
"data-slot": "tooltip-trigger",
|
|
1685
|
-
...props
|
|
1686
|
-
}
|
|
1687
|
-
);
|
|
1688
|
-
}
|
|
1689
|
-
function TooltipContent({
|
|
1690
|
-
className,
|
|
1691
|
-
sideOffset = 0,
|
|
1692
|
-
children,
|
|
1693
|
-
...props
|
|
1694
|
-
}) {
|
|
1695
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1696
|
-
TooltipPrimitive.Content,
|
|
1697
|
-
{
|
|
1698
|
-
"data-slot": "tooltip-content",
|
|
1699
|
-
sideOffset,
|
|
1700
|
-
className: cn(
|
|
1701
|
-
"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",
|
|
1702
|
-
className
|
|
1703
|
-
),
|
|
1704
|
-
...props,
|
|
1705
|
-
children: [
|
|
1706
|
-
children,
|
|
1707
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(TooltipPrimitive.Arrow, { className: "bg-primary fill-primary z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
|
|
1708
|
-
]
|
|
1709
|
-
}
|
|
1710
|
-
) });
|
|
1711
|
-
}
|
|
2637
|
+
// src/components/thread/mermaid-block.tsx
|
|
2638
|
+
var Dialog = __toESM(require("@radix-ui/react-dialog"), 1);
|
|
2639
|
+
var import_mermaid = __toESM(require("mermaid"), 1);
|
|
2640
|
+
var import_lucide_react6 = require("lucide-react");
|
|
2641
|
+
var React14 = __toESM(require("react"), 1);
|
|
1712
2642
|
|
|
1713
2643
|
// src/components/thread/tooltip-icon-button.tsx
|
|
1714
|
-
var
|
|
2644
|
+
var import_react5 = require("react");
|
|
2645
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1715
2646
|
var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side = "bottom", className, ...rest }, ref) => {
|
|
1716
|
-
return /* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
2647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Tooltip, { children: [
|
|
2648
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
1718
2649
|
Button,
|
|
1719
2650
|
{
|
|
1720
2651
|
variant: "ghost",
|
|
@@ -1724,24 +2655,515 @@ var TooltipIconButton = (0, import_react5.forwardRef)(({ children, tooltip, side
|
|
|
1724
2655
|
ref,
|
|
1725
2656
|
children: [
|
|
1726
2657
|
children,
|
|
1727
|
-
/* @__PURE__ */ (0,
|
|
2658
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "sr-only", children: tooltip })
|
|
1728
2659
|
]
|
|
1729
2660
|
}
|
|
1730
2661
|
) }),
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipContent, { side, children: tooltip })
|
|
1732
2663
|
] }) });
|
|
1733
2664
|
});
|
|
1734
2665
|
TooltipIconButton.displayName = "TooltipIconButton";
|
|
1735
2666
|
|
|
2667
|
+
// src/components/thread/mermaid-block.tsx
|
|
2668
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2669
|
+
var HEX_COLOR_PATTERN = /^#([\da-f]{3,8})$/i;
|
|
2670
|
+
var MERMAID_DIRECTIVE_PATTERN = /%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi;
|
|
2671
|
+
var MERMAID_FRONTMATTER_PATTERN = /^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;
|
|
2672
|
+
var OKLCH_COLOR_PATTERN = /^oklch\((.+)\)$/i;
|
|
2673
|
+
var RGB_COLOR_PATTERN = /^rgba?\((.+)\)$/i;
|
|
2674
|
+
var MERMAID_SECURE_KEYS = [
|
|
2675
|
+
"fontFamily",
|
|
2676
|
+
"maxEdges",
|
|
2677
|
+
"maxTextSize",
|
|
2678
|
+
"securityLevel",
|
|
2679
|
+
"secure",
|
|
2680
|
+
"startOnLoad",
|
|
2681
|
+
"suppressErrorRendering",
|
|
2682
|
+
"theme",
|
|
2683
|
+
"themeVariables"
|
|
2684
|
+
];
|
|
2685
|
+
function clamp(value, min, max) {
|
|
2686
|
+
return Math.min(max, Math.max(min, value));
|
|
2687
|
+
}
|
|
2688
|
+
function normalizeMermaidCode(code) {
|
|
2689
|
+
return code.replace(MERMAID_FRONTMATTER_PATTERN, "").replace(MERMAID_DIRECTIVE_PATTERN, "").trim();
|
|
2690
|
+
}
|
|
2691
|
+
function parseAlpha(value) {
|
|
2692
|
+
if (!value) return 1;
|
|
2693
|
+
const normalized = value.trim();
|
|
2694
|
+
if (!normalized) return 1;
|
|
2695
|
+
if (normalized.endsWith("%")) {
|
|
2696
|
+
return clamp(Number.parseFloat(normalized) / 100, 0, 1);
|
|
2697
|
+
}
|
|
2698
|
+
return clamp(Number.parseFloat(normalized), 0, 1);
|
|
2699
|
+
}
|
|
2700
|
+
function parseHexColor(value) {
|
|
2701
|
+
const match = value.trim().match(HEX_COLOR_PATTERN);
|
|
2702
|
+
if (!match) return null;
|
|
2703
|
+
const hex = match[1];
|
|
2704
|
+
if (hex.length === 3 || hex.length === 4) {
|
|
2705
|
+
const [r, g, b, a = "f"] = hex.split("");
|
|
2706
|
+
return {
|
|
2707
|
+
r: Number.parseInt(r + r, 16),
|
|
2708
|
+
g: Number.parseInt(g + g, 16),
|
|
2709
|
+
b: Number.parseInt(b + b, 16),
|
|
2710
|
+
a: Number.parseInt(a + a, 16) / 255
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2713
|
+
if (hex.length === 6 || hex.length === 8) {
|
|
2714
|
+
const alphaHex = hex.length === 8 ? hex.slice(6, 8) : "ff";
|
|
2715
|
+
return {
|
|
2716
|
+
r: Number.parseInt(hex.slice(0, 2), 16),
|
|
2717
|
+
g: Number.parseInt(hex.slice(2, 4), 16),
|
|
2718
|
+
b: Number.parseInt(hex.slice(4, 6), 16),
|
|
2719
|
+
a: Number.parseInt(alphaHex, 16) / 255
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
return null;
|
|
2723
|
+
}
|
|
2724
|
+
function parseRgbChannel(value) {
|
|
2725
|
+
const normalized = value.trim();
|
|
2726
|
+
if (normalized.endsWith("%")) {
|
|
2727
|
+
return clamp(Math.round(Number.parseFloat(normalized) / 100 * 255), 0, 255);
|
|
2728
|
+
}
|
|
2729
|
+
return clamp(Math.round(Number.parseFloat(normalized)), 0, 255);
|
|
2730
|
+
}
|
|
2731
|
+
function parseRgbColor(value) {
|
|
2732
|
+
const match = value.trim().match(RGB_COLOR_PATTERN);
|
|
2733
|
+
if (!match) return null;
|
|
2734
|
+
const parts = match[1].split(/[,\s/]+/).map((part) => part.trim()).filter(Boolean);
|
|
2735
|
+
if (parts.length < 3) return null;
|
|
2736
|
+
return {
|
|
2737
|
+
r: parseRgbChannel(parts[0]),
|
|
2738
|
+
g: parseRgbChannel(parts[1]),
|
|
2739
|
+
b: parseRgbChannel(parts[2]),
|
|
2740
|
+
a: parseAlpha(parts[3])
|
|
2741
|
+
};
|
|
2742
|
+
}
|
|
2743
|
+
function parseOklchLightness(value) {
|
|
2744
|
+
const normalized = value.trim();
|
|
2745
|
+
if (normalized.endsWith("%")) {
|
|
2746
|
+
return clamp(Number.parseFloat(normalized) / 100, 0, 1);
|
|
2747
|
+
}
|
|
2748
|
+
return clamp(Number.parseFloat(normalized), 0, 1);
|
|
2749
|
+
}
|
|
2750
|
+
function parseHue(value) {
|
|
2751
|
+
const normalized = value.trim().toLowerCase();
|
|
2752
|
+
const numeric = Number.parseFloat(normalized);
|
|
2753
|
+
if (Number.isNaN(numeric)) return 0;
|
|
2754
|
+
if (normalized.endsWith("turn")) return numeric * 360;
|
|
2755
|
+
if (normalized.endsWith("rad")) return numeric * (180 / Math.PI);
|
|
2756
|
+
if (normalized.endsWith("grad")) return numeric * 0.9;
|
|
2757
|
+
return numeric;
|
|
2758
|
+
}
|
|
2759
|
+
function linearToSrgb(linear) {
|
|
2760
|
+
if (linear <= 31308e-7) {
|
|
2761
|
+
return 12.92 * linear;
|
|
2762
|
+
}
|
|
2763
|
+
return 1.055 * Math.pow(linear, 1 / 2.4) - 0.055;
|
|
2764
|
+
}
|
|
2765
|
+
function parseOklchColor(value) {
|
|
2766
|
+
const match = value.trim().match(OKLCH_COLOR_PATTERN);
|
|
2767
|
+
if (!match) return null;
|
|
2768
|
+
const [base2, alphaSegment] = match[1].split("/");
|
|
2769
|
+
const parts = base2.trim().split(/\s+/).map((part) => part.trim()).filter(Boolean);
|
|
2770
|
+
if (parts.length < 3) return null;
|
|
2771
|
+
const lightness = parseOklchLightness(parts[0]);
|
|
2772
|
+
const chroma = Number.parseFloat(parts[1]);
|
|
2773
|
+
const hueRadians = parseHue(parts[2]) * Math.PI / 180;
|
|
2774
|
+
const alpha = parseAlpha(alphaSegment);
|
|
2775
|
+
const a = chroma * Math.cos(hueRadians);
|
|
2776
|
+
const b = chroma * Math.sin(hueRadians);
|
|
2777
|
+
const l_ = lightness + 0.3963377774 * a + 0.2158037573 * b;
|
|
2778
|
+
const m_ = lightness - 0.1055613458 * a - 0.0638541728 * b;
|
|
2779
|
+
const s_ = lightness - 0.0894841775 * a - 1.291485548 * b;
|
|
2780
|
+
const l = l_ * l_ * l_;
|
|
2781
|
+
const m = m_ * m_ * m_;
|
|
2782
|
+
const s = s_ * s_ * s_;
|
|
2783
|
+
const linearR = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
|
|
2784
|
+
const linearG = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
|
|
2785
|
+
const linearB = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
|
|
2786
|
+
return {
|
|
2787
|
+
r: clamp(Math.round(linearToSrgb(linearR) * 255), 0, 255),
|
|
2788
|
+
g: clamp(Math.round(linearToSrgb(linearG) * 255), 0, 255),
|
|
2789
|
+
b: clamp(Math.round(linearToSrgb(linearB) * 255), 0, 255),
|
|
2790
|
+
a: alpha
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
function parseCssColor(value) {
|
|
2794
|
+
const normalized = value.trim();
|
|
2795
|
+
if (!normalized) return null;
|
|
2796
|
+
return parseHexColor(normalized) ?? parseRgbColor(normalized) ?? parseOklchColor(normalized);
|
|
2797
|
+
}
|
|
2798
|
+
function compositeColor(foreground, background) {
|
|
2799
|
+
const alpha = foreground.a + background.a * (1 - foreground.a);
|
|
2800
|
+
if (alpha <= 0) {
|
|
2801
|
+
return { r: 0, g: 0, b: 0, a: 0 };
|
|
2802
|
+
}
|
|
2803
|
+
const r = (foreground.r * foreground.a + background.r * background.a * (1 - foreground.a)) / alpha;
|
|
2804
|
+
const g = (foreground.g * foreground.a + background.g * background.a * (1 - foreground.a)) / alpha;
|
|
2805
|
+
const b = (foreground.b * foreground.a + background.b * background.a * (1 - foreground.a)) / alpha;
|
|
2806
|
+
return {
|
|
2807
|
+
r: clamp(Math.round(r), 0, 255),
|
|
2808
|
+
g: clamp(Math.round(g), 0, 255),
|
|
2809
|
+
b: clamp(Math.round(b), 0, 255),
|
|
2810
|
+
a: clamp(alpha, 0, 1)
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
function toHexChannel(value) {
|
|
2814
|
+
return value.toString(16).padStart(2, "0");
|
|
2815
|
+
}
|
|
2816
|
+
function rgbaToHex(value) {
|
|
2817
|
+
return `#${toHexChannel(value.r)}${toHexChannel(value.g)}${toHexChannel(value.b)}`;
|
|
2818
|
+
}
|
|
2819
|
+
function getFallbackPalette(isDarkMode) {
|
|
2820
|
+
if (isDarkMode) {
|
|
2821
|
+
return {
|
|
2822
|
+
background: "#171717",
|
|
2823
|
+
border: "#52525b",
|
|
2824
|
+
fontFamily: "Inter Variable, sans-serif",
|
|
2825
|
+
line: "#a1a1aa",
|
|
2826
|
+
surface: "#262626",
|
|
2827
|
+
surfaceAlt: "#3f3f46",
|
|
2828
|
+
text: "#fafafa"
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
return {
|
|
2832
|
+
background: "#ffffff",
|
|
2833
|
+
border: "#e4e4e7",
|
|
2834
|
+
fontFamily: "Inter Variable, sans-serif",
|
|
2835
|
+
line: "#71717a",
|
|
2836
|
+
surface: "#ffffff",
|
|
2837
|
+
surfaceAlt: "#f4f4f5",
|
|
2838
|
+
text: "#18181b"
|
|
2839
|
+
};
|
|
2840
|
+
}
|
|
2841
|
+
function resolveColor(styles, property, fallback, background) {
|
|
2842
|
+
const parsed = parseCssColor(styles.getPropertyValue(property));
|
|
2843
|
+
if (!parsed) return fallback;
|
|
2844
|
+
if (parsed.a < 1 && background) {
|
|
2845
|
+
return rgbaToHex(compositeColor(parsed, background));
|
|
2846
|
+
}
|
|
2847
|
+
return rgbaToHex(parsed);
|
|
2848
|
+
}
|
|
2849
|
+
function resolvePalette(element, isDarkMode) {
|
|
2850
|
+
const fallback = getFallbackPalette(isDarkMode);
|
|
2851
|
+
const styles = window.getComputedStyle(element);
|
|
2852
|
+
const backgroundColor = parseCssColor(styles.getPropertyValue("--card")) ?? parseCssColor(styles.getPropertyValue("--background")) ?? parseCssColor(fallback.surface);
|
|
2853
|
+
return {
|
|
2854
|
+
background: resolveColor(styles, "--background", fallback.background, backgroundColor),
|
|
2855
|
+
border: resolveColor(styles, "--border", fallback.border, backgroundColor),
|
|
2856
|
+
fontFamily: styles.getPropertyValue("font-family").trim() || fallback.fontFamily,
|
|
2857
|
+
line: resolveColor(styles, "--muted-foreground", fallback.line, backgroundColor),
|
|
2858
|
+
surface: resolveColor(styles, "--card", fallback.surface, backgroundColor),
|
|
2859
|
+
surfaceAlt: resolveColor(styles, "--muted", fallback.surfaceAlt, backgroundColor),
|
|
2860
|
+
text: resolveColor(styles, "--foreground", fallback.text, backgroundColor)
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2863
|
+
function buildThemeVariables(palette) {
|
|
2864
|
+
return {
|
|
2865
|
+
background: palette.background,
|
|
2866
|
+
clusterBkg: palette.surfaceAlt,
|
|
2867
|
+
clusterBorder: palette.border,
|
|
2868
|
+
edgeLabelBackground: palette.surface,
|
|
2869
|
+
fontFamily: palette.fontFamily,
|
|
2870
|
+
lineColor: palette.line,
|
|
2871
|
+
mainBkg: palette.surface,
|
|
2872
|
+
nodeBorder: palette.border,
|
|
2873
|
+
nodeTextColor: palette.text,
|
|
2874
|
+
primaryBorderColor: palette.border,
|
|
2875
|
+
primaryColor: palette.surfaceAlt,
|
|
2876
|
+
primaryTextColor: palette.text,
|
|
2877
|
+
secondaryBorderColor: palette.border,
|
|
2878
|
+
secondaryColor: palette.surface,
|
|
2879
|
+
secondaryTextColor: palette.text,
|
|
2880
|
+
tertiaryBorderColor: palette.border,
|
|
2881
|
+
tertiaryColor: palette.surface,
|
|
2882
|
+
tertiaryTextColor: palette.text,
|
|
2883
|
+
textColor: palette.text
|
|
2884
|
+
};
|
|
2885
|
+
}
|
|
2886
|
+
async function renderMermaidDiagram({
|
|
2887
|
+
code,
|
|
2888
|
+
host,
|
|
2889
|
+
id,
|
|
2890
|
+
palette
|
|
2891
|
+
}) {
|
|
2892
|
+
host.innerHTML = "";
|
|
2893
|
+
import_mermaid.default.initialize({
|
|
2894
|
+
flowchart: {
|
|
2895
|
+
htmlLabels: false,
|
|
2896
|
+
useMaxWidth: true
|
|
2897
|
+
},
|
|
2898
|
+
fontFamily: palette.fontFamily,
|
|
2899
|
+
secure: [...MERMAID_SECURE_KEYS],
|
|
2900
|
+
securityLevel: "strict",
|
|
2901
|
+
startOnLoad: false,
|
|
2902
|
+
theme: "base",
|
|
2903
|
+
themeVariables: buildThemeVariables(palette)
|
|
2904
|
+
});
|
|
2905
|
+
const { svg } = await import_mermaid.default.render(id, code, host);
|
|
2906
|
+
host.innerHTML = "";
|
|
2907
|
+
return svg;
|
|
2908
|
+
}
|
|
2909
|
+
function MermaidPreviewDialog({
|
|
2910
|
+
closeLabel,
|
|
2911
|
+
onOpenChange,
|
|
2912
|
+
open,
|
|
2913
|
+
svgMarkup,
|
|
2914
|
+
title
|
|
2915
|
+
}) {
|
|
2916
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Dialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Dialog.Portal, { children: [
|
|
2917
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" }),
|
|
2918
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Dialog.Content, { className: "fixed inset-[5vh] z-50 flex flex-col overflow-hidden rounded-3xl border border-border bg-background shadow-2xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", children: [
|
|
2919
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between gap-4 border-b border-border px-5 py-4", children: [
|
|
2920
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Dialog.Title, { className: "text-base font-semibold text-foreground", children: title }),
|
|
2921
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
2922
|
+
"button",
|
|
2923
|
+
{
|
|
2924
|
+
type: "button",
|
|
2925
|
+
className: "inline-flex size-10 items-center justify-center rounded-full border border-border bg-card text-muted-foreground transition-colors hover:text-foreground",
|
|
2926
|
+
children: [
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.X, { className: "size-4" }),
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "sr-only", children: closeLabel })
|
|
2929
|
+
]
|
|
2930
|
+
}
|
|
2931
|
+
) })
|
|
2932
|
+
] }),
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex-1 overflow-auto bg-card p-6", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
2934
|
+
"div",
|
|
2935
|
+
{
|
|
2936
|
+
"data-slot": "mermaid-preview",
|
|
2937
|
+
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",
|
|
2938
|
+
dangerouslySetInnerHTML: { __html: svgMarkup }
|
|
2939
|
+
}
|
|
2940
|
+
) })
|
|
2941
|
+
] })
|
|
2942
|
+
] }) });
|
|
2943
|
+
}
|
|
2944
|
+
function MermaidBlock({ code }) {
|
|
2945
|
+
const { t } = useChatkitTranslation();
|
|
2946
|
+
const { theme, isDarkMode } = useTheme();
|
|
2947
|
+
const containerRef = React14.useRef(null);
|
|
2948
|
+
const renderHostRef = React14.useRef(null);
|
|
2949
|
+
const renderSequenceRef = React14.useRef(0);
|
|
2950
|
+
const copyResetTimeoutRef = React14.useRef(null);
|
|
2951
|
+
const diagramId = React14.useId().replace(/:/g, "");
|
|
2952
|
+
const [activeTab, setActiveTab] = React14.useState("diagram");
|
|
2953
|
+
const [isCopied, setIsCopied] = React14.useState(false);
|
|
2954
|
+
const [isPreviewOpen, setIsPreviewOpen] = React14.useState(false);
|
|
2955
|
+
const [isRendering, setIsRendering] = React14.useState(true);
|
|
2956
|
+
const [renderError, setRenderError] = React14.useState(null);
|
|
2957
|
+
const [svgMarkup, setSvgMarkup] = React14.useState(null);
|
|
2958
|
+
const normalizedCode = React14.useMemo(() => normalizeMermaidCode(code), [code]);
|
|
2959
|
+
const clearCopyResetTimeout = React14.useCallback(() => {
|
|
2960
|
+
if (copyResetTimeoutRef.current === null) return;
|
|
2961
|
+
window.clearTimeout(copyResetTimeoutRef.current);
|
|
2962
|
+
copyResetTimeoutRef.current = null;
|
|
2963
|
+
}, []);
|
|
2964
|
+
React14.useEffect(() => {
|
|
2965
|
+
let isActive = true;
|
|
2966
|
+
async function runRender() {
|
|
2967
|
+
const container = containerRef.current;
|
|
2968
|
+
const renderHost = renderHostRef.current;
|
|
2969
|
+
if (!container || !renderHost) return;
|
|
2970
|
+
setIsRendering(true);
|
|
2971
|
+
setRenderError(null);
|
|
2972
|
+
try {
|
|
2973
|
+
renderSequenceRef.current += 1;
|
|
2974
|
+
const svg = await renderMermaidDiagram({
|
|
2975
|
+
code: normalizedCode,
|
|
2976
|
+
host: renderHost,
|
|
2977
|
+
id: `mermaid-${diagramId}-${renderSequenceRef.current}`,
|
|
2978
|
+
palette: resolvePalette(container, isDarkMode)
|
|
2979
|
+
});
|
|
2980
|
+
if (!isActive) return;
|
|
2981
|
+
setSvgMarkup(svg);
|
|
2982
|
+
} catch (error) {
|
|
2983
|
+
if (!isActive) return;
|
|
2984
|
+
setSvgMarkup(null);
|
|
2985
|
+
setRenderError(error instanceof Error ? error.message : "render_failed");
|
|
2986
|
+
setActiveTab((currentTab) => currentTab === "diagram" ? "code" : currentTab);
|
|
2987
|
+
} finally {
|
|
2988
|
+
if (isActive) {
|
|
2989
|
+
setIsRendering(false);
|
|
2990
|
+
renderHost.innerHTML = "";
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
void runRender();
|
|
2995
|
+
return () => {
|
|
2996
|
+
isActive = false;
|
|
2997
|
+
if (renderHostRef.current) {
|
|
2998
|
+
renderHostRef.current.innerHTML = "";
|
|
2999
|
+
}
|
|
3000
|
+
};
|
|
3001
|
+
}, [diagramId, isDarkMode, normalizedCode, theme]);
|
|
3002
|
+
React14.useEffect(() => {
|
|
3003
|
+
clearCopyResetTimeout();
|
|
3004
|
+
setIsCopied(false);
|
|
3005
|
+
}, [activeTab, clearCopyResetTimeout, code]);
|
|
3006
|
+
React14.useEffect(
|
|
3007
|
+
() => () => {
|
|
3008
|
+
clearCopyResetTimeout();
|
|
3009
|
+
},
|
|
3010
|
+
[clearCopyResetTimeout]
|
|
3011
|
+
);
|
|
3012
|
+
const handleDownload = React14.useCallback(() => {
|
|
3013
|
+
if (!svgMarkup) return;
|
|
3014
|
+
const blob = new Blob([svgMarkup], {
|
|
3015
|
+
type: "image/svg+xml;charset=utf-8"
|
|
3016
|
+
});
|
|
3017
|
+
const url = window.URL.createObjectURL(blob);
|
|
3018
|
+
const anchor = document.createElement("a");
|
|
3019
|
+
anchor.href = url;
|
|
3020
|
+
anchor.download = `mermaid-diagram-${diagramId}.svg`;
|
|
3021
|
+
document.body.append(anchor);
|
|
3022
|
+
anchor.click();
|
|
3023
|
+
anchor.remove();
|
|
3024
|
+
window.URL.revokeObjectURL(url);
|
|
3025
|
+
}, [diagramId, svgMarkup]);
|
|
3026
|
+
const handleCopyCode = React14.useCallback(() => {
|
|
3027
|
+
if (!code || isCopied) return;
|
|
3028
|
+
navigator.clipboard.writeText(code).then(() => {
|
|
3029
|
+
setIsCopied(true);
|
|
3030
|
+
clearCopyResetTimeout();
|
|
3031
|
+
copyResetTimeoutRef.current = window.setTimeout(() => {
|
|
3032
|
+
setIsCopied(false);
|
|
3033
|
+
copyResetTimeoutRef.current = null;
|
|
3034
|
+
}, 3e3);
|
|
3035
|
+
}).catch(() => {
|
|
3036
|
+
});
|
|
3037
|
+
}, [clearCopyResetTimeout, code, isCopied]);
|
|
3038
|
+
const hasRenderedDiagram = svgMarkup !== null && !renderError;
|
|
3039
|
+
const statusMessage = isRendering ? t("markdown.mermaid.rendering") : t("markdown.mermaid.failed");
|
|
3040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
3041
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3042
|
+
Tabs,
|
|
3043
|
+
{
|
|
3044
|
+
className: "w-full",
|
|
3045
|
+
onValueChange: (value) => setActiveTab(value),
|
|
3046
|
+
value: activeTab,
|
|
3047
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3048
|
+
"div",
|
|
3049
|
+
{
|
|
3050
|
+
ref: containerRef,
|
|
3051
|
+
"data-slot": "mermaid-block",
|
|
3052
|
+
className: "relative overflow-hidden text-card-foreground",
|
|
3053
|
+
children: [
|
|
3054
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3055
|
+
"div",
|
|
3056
|
+
{
|
|
3057
|
+
ref: renderHostRef,
|
|
3058
|
+
"aria-hidden": "true",
|
|
3059
|
+
className: "pointer-events-none absolute inset-0 -z-10 overflow-hidden opacity-0",
|
|
3060
|
+
"data-slot": "mermaid-render-host"
|
|
3061
|
+
}
|
|
3062
|
+
),
|
|
3063
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3 px-4 py-3", children: [
|
|
3064
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
3065
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "inline-flex size-9 shrink-0 items-center justify-center rounded-full bg-muted text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.Code2Icon, { className: "size-4" }) }),
|
|
3066
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate text-base font-semibold text-foreground", children: t("markdown.mermaid.title") })
|
|
3067
|
+
] }),
|
|
3068
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
3069
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
3070
|
+
activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3071
|
+
TooltipIconButton,
|
|
3072
|
+
{
|
|
3073
|
+
onClick: handleDownload,
|
|
3074
|
+
tooltip: t("markdown.mermaid.download"),
|
|
3075
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.DownloadIcon, { className: "size-4" })
|
|
3076
|
+
}
|
|
3077
|
+
) : null,
|
|
3078
|
+
activeTab === "diagram" && hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3079
|
+
TooltipIconButton,
|
|
3080
|
+
{
|
|
3081
|
+
onClick: () => setIsPreviewOpen(true),
|
|
3082
|
+
tooltip: t("markdown.mermaid.fullScreen"),
|
|
3083
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.ExpandIcon, { className: "size-4" })
|
|
3084
|
+
}
|
|
3085
|
+
) : null,
|
|
3086
|
+
activeTab === "code" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3087
|
+
TooltipIconButton,
|
|
3088
|
+
{
|
|
3089
|
+
onClick: handleCopyCode,
|
|
3090
|
+
tooltip: t("markdown.copy"),
|
|
3091
|
+
children: isCopied ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.CheckIcon, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.CopyIcon, { className: "size-4" })
|
|
3092
|
+
}
|
|
3093
|
+
) : null
|
|
3094
|
+
] }),
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(TabsList, { children: [
|
|
3096
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsTrigger, { value: "diagram", children: t("markdown.mermaid.diagram") }),
|
|
3097
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsTrigger, { value: "code", children: t("markdown.mermaid.code") })
|
|
3098
|
+
] })
|
|
3099
|
+
] })
|
|
3100
|
+
] }),
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "border-t border-border pt-4", children: [
|
|
3102
|
+
renderError ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { role: "alert", className: "mb-4 text-sm font-medium text-destructive", children: t("markdown.mermaid.failed") }) : null,
|
|
3103
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsContent, { value: "diagram", className: "mt-0 space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3104
|
+
"div",
|
|
3105
|
+
{
|
|
3106
|
+
className: cn(
|
|
3107
|
+
"relative overflow-auto rounded-[calc(var(--radius)+0.5rem)] border border-border bg-background p-4",
|
|
3108
|
+
hasRenderedDiagram ? "[&_svg]:mx-auto [&_svg]:h-auto [&_svg]:w-full [&_svg]:max-w-none" : "min-h-[14rem]"
|
|
3109
|
+
),
|
|
3110
|
+
children: hasRenderedDiagram ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3111
|
+
"div",
|
|
3112
|
+
{
|
|
3113
|
+
"data-slot": "mermaid-diagram",
|
|
3114
|
+
dangerouslySetInnerHTML: { __html: svgMarkup }
|
|
3115
|
+
}
|
|
3116
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex min-h-[12rem] flex-col items-center justify-center gap-3 text-center text-muted-foreground", children: [
|
|
3117
|
+
isRendering ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.Loader2, { className: "size-5 animate-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react6.TriangleAlert, { className: "size-5 text-destructive" }),
|
|
3118
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3119
|
+
"p",
|
|
3120
|
+
{
|
|
3121
|
+
className: cn("text-sm font-medium", !isRendering && "text-destructive"),
|
|
3122
|
+
role: renderError ? "alert" : void 0,
|
|
3123
|
+
children: statusMessage
|
|
3124
|
+
}
|
|
3125
|
+
)
|
|
3126
|
+
] })
|
|
3127
|
+
}
|
|
3128
|
+
) }),
|
|
3129
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TabsContent, { value: "code", className: "mt-0", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3130
|
+
"pre",
|
|
3131
|
+
{
|
|
3132
|
+
"data-slot": "mermaid-code",
|
|
3133
|
+
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",
|
|
3134
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("code", { className: "block whitespace-pre font-mono", children: code })
|
|
3135
|
+
}
|
|
3136
|
+
) })
|
|
3137
|
+
] })
|
|
3138
|
+
]
|
|
3139
|
+
}
|
|
3140
|
+
)
|
|
3141
|
+
}
|
|
3142
|
+
),
|
|
3143
|
+
svgMarkup ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3144
|
+
MermaidPreviewDialog,
|
|
3145
|
+
{
|
|
3146
|
+
closeLabel: t("sheet.close"),
|
|
3147
|
+
onOpenChange: setIsPreviewOpen,
|
|
3148
|
+
open: isPreviewOpen,
|
|
3149
|
+
svgMarkup,
|
|
3150
|
+
title: t("markdown.mermaid.title")
|
|
3151
|
+
}
|
|
3152
|
+
) : null
|
|
3153
|
+
] });
|
|
3154
|
+
}
|
|
3155
|
+
|
|
1736
3156
|
// src/components/thread/markdown-text.tsx
|
|
1737
3157
|
var import_katex_min = require("katex/dist/katex.min.css");
|
|
1738
|
-
var
|
|
3158
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1739
3159
|
var getTextContent = (children) => import_react6.Children.toArray(children).map((child) => {
|
|
1740
3160
|
if (typeof child === "string" || typeof child === "number") {
|
|
1741
3161
|
return String(child);
|
|
1742
3162
|
}
|
|
1743
3163
|
return "";
|
|
1744
3164
|
}).join("");
|
|
3165
|
+
var isMermaidBlockChild = (child) => (0, import_react6.isValidElement)(child) && child.type === MermaidBlock;
|
|
3166
|
+
var isMermaidCodeElement = (child) => (0, import_react6.isValidElement)(child) && typeof child.props.className === "string" && child.props.className.includes("language-mermaid");
|
|
1745
3167
|
var useCopyToClipboard = ({
|
|
1746
3168
|
copiedDuration = 3e3
|
|
1747
3169
|
} = {}) => {
|
|
@@ -1762,23 +3184,23 @@ var CodeHeader = ({ language, code }) => {
|
|
|
1762
3184
|
if (!code || isCopied) return;
|
|
1763
3185
|
copyToClipboard(code);
|
|
1764
3186
|
};
|
|
1765
|
-
return /* @__PURE__ */ (0,
|
|
1766
|
-
/* @__PURE__ */ (0,
|
|
1767
|
-
/* @__PURE__ */ (0,
|
|
3187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center justify-between gap-4 rounded-t-lg bg-zinc-900 px-4 py-2 text-sm font-semibold text-white", children: [
|
|
3188
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "lowercase [&>span]:text-xs", children: language }),
|
|
3189
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1768
3190
|
TooltipIconButton,
|
|
1769
3191
|
{
|
|
1770
3192
|
tooltip: t("markdown.copy"),
|
|
1771
3193
|
onClick: onCopy,
|
|
1772
3194
|
children: [
|
|
1773
|
-
!isCopied && /* @__PURE__ */ (0,
|
|
1774
|
-
isCopied && /* @__PURE__ */ (0,
|
|
3195
|
+
!isCopied && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CopyIcon, {}),
|
|
3196
|
+
isCopied && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react7.CheckIcon, {})
|
|
1775
3197
|
]
|
|
1776
3198
|
}
|
|
1777
3199
|
)
|
|
1778
3200
|
] });
|
|
1779
3201
|
};
|
|
1780
3202
|
var defaultComponents = {
|
|
1781
|
-
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3203
|
+
h1: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1782
3204
|
"h1",
|
|
1783
3205
|
{
|
|
1784
3206
|
className: cn(
|
|
@@ -1788,7 +3210,7 @@ var defaultComponents = {
|
|
|
1788
3210
|
...props
|
|
1789
3211
|
}
|
|
1790
3212
|
),
|
|
1791
|
-
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3213
|
+
h2: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1792
3214
|
"h2",
|
|
1793
3215
|
{
|
|
1794
3216
|
className: cn(
|
|
@@ -1798,7 +3220,7 @@ var defaultComponents = {
|
|
|
1798
3220
|
...props
|
|
1799
3221
|
}
|
|
1800
3222
|
),
|
|
1801
|
-
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3223
|
+
h3: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1802
3224
|
"h3",
|
|
1803
3225
|
{
|
|
1804
3226
|
className: cn(
|
|
@@ -1808,7 +3230,7 @@ var defaultComponents = {
|
|
|
1808
3230
|
...props
|
|
1809
3231
|
}
|
|
1810
3232
|
),
|
|
1811
|
-
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3233
|
+
h4: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1812
3234
|
"h4",
|
|
1813
3235
|
{
|
|
1814
3236
|
className: cn(
|
|
@@ -1818,7 +3240,7 @@ var defaultComponents = {
|
|
|
1818
3240
|
...props
|
|
1819
3241
|
}
|
|
1820
3242
|
),
|
|
1821
|
-
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3243
|
+
h5: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1822
3244
|
"h5",
|
|
1823
3245
|
{
|
|
1824
3246
|
className: cn(
|
|
@@ -1828,21 +3250,21 @@ var defaultComponents = {
|
|
|
1828
3250
|
...props
|
|
1829
3251
|
}
|
|
1830
3252
|
),
|
|
1831
|
-
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3253
|
+
h6: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1832
3254
|
"h6",
|
|
1833
3255
|
{
|
|
1834
3256
|
className: cn("my-4 font-semibold first:mt-0 last:mb-0", className),
|
|
1835
3257
|
...props
|
|
1836
3258
|
}
|
|
1837
3259
|
),
|
|
1838
|
-
p: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3260
|
+
p: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1839
3261
|
"p",
|
|
1840
3262
|
{
|
|
1841
3263
|
className: cn("mt-5 mb-5 leading-7 first:mt-0 last:mb-0", className),
|
|
1842
3264
|
...props
|
|
1843
3265
|
}
|
|
1844
3266
|
),
|
|
1845
|
-
a: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3267
|
+
a: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1846
3268
|
"a",
|
|
1847
3269
|
{
|
|
1848
3270
|
className: cn(
|
|
@@ -1858,7 +3280,7 @@ var defaultComponents = {
|
|
|
1858
3280
|
className,
|
|
1859
3281
|
node: _node,
|
|
1860
3282
|
...props
|
|
1861
|
-
}) => /* @__PURE__ */ (0,
|
|
3283
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1862
3284
|
"blockquote",
|
|
1863
3285
|
{
|
|
1864
3286
|
className: cn(
|
|
@@ -1868,21 +3290,21 @@ var defaultComponents = {
|
|
|
1868
3290
|
...props
|
|
1869
3291
|
}
|
|
1870
3292
|
),
|
|
1871
|
-
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3293
|
+
ul: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1872
3294
|
"ul",
|
|
1873
3295
|
{
|
|
1874
3296
|
className: cn("my-5 list-outside list-disc pl-6 [&>li]:mt-2", className),
|
|
1875
3297
|
...props
|
|
1876
3298
|
}
|
|
1877
3299
|
),
|
|
1878
|
-
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3300
|
+
ol: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1879
3301
|
"ol",
|
|
1880
3302
|
{
|
|
1881
3303
|
className: cn("my-5 list-outside list-decimal pl-8 [&>li]:mt-2", className),
|
|
1882
3304
|
...props
|
|
1883
3305
|
}
|
|
1884
3306
|
),
|
|
1885
|
-
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3307
|
+
hr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1886
3308
|
"hr",
|
|
1887
3309
|
{
|
|
1888
3310
|
className: cn("my-5 border-b", className),
|
|
@@ -1893,7 +3315,7 @@ var defaultComponents = {
|
|
|
1893
3315
|
className,
|
|
1894
3316
|
node: _node,
|
|
1895
3317
|
...props
|
|
1896
|
-
}) => /* @__PURE__ */ (0,
|
|
3318
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1897
3319
|
"table",
|
|
1898
3320
|
{
|
|
1899
3321
|
className: cn(
|
|
@@ -1903,7 +3325,7 @@ var defaultComponents = {
|
|
|
1903
3325
|
...props
|
|
1904
3326
|
}
|
|
1905
3327
|
),
|
|
1906
|
-
th: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3328
|
+
th: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1907
3329
|
"th",
|
|
1908
3330
|
{
|
|
1909
3331
|
className: cn(
|
|
@@ -1913,7 +3335,7 @@ var defaultComponents = {
|
|
|
1913
3335
|
...props
|
|
1914
3336
|
}
|
|
1915
3337
|
),
|
|
1916
|
-
td: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3338
|
+
td: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1917
3339
|
"td",
|
|
1918
3340
|
{
|
|
1919
3341
|
className: cn(
|
|
@@ -1923,7 +3345,7 @@ var defaultComponents = {
|
|
|
1923
3345
|
...props
|
|
1924
3346
|
}
|
|
1925
3347
|
),
|
|
1926
|
-
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3348
|
+
tr: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1927
3349
|
"tr",
|
|
1928
3350
|
{
|
|
1929
3351
|
className: cn(
|
|
@@ -1933,21 +3355,21 @@ var defaultComponents = {
|
|
|
1933
3355
|
...props
|
|
1934
3356
|
}
|
|
1935
3357
|
),
|
|
1936
|
-
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0,
|
|
3358
|
+
sup: ({ className, node: _node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1937
3359
|
"sup",
|
|
1938
3360
|
{
|
|
1939
3361
|
className: cn("[&>a]:text-xs [&>a]:no-underline", className),
|
|
1940
3362
|
...props
|
|
1941
3363
|
}
|
|
1942
3364
|
),
|
|
1943
|
-
pre: ({ className, node: _node,
|
|
3365
|
+
pre: ({ className, children, node: _node }) => import_react6.Children.toArray(children).length === 1 && (isMermaidBlockChild(import_react6.Children.toArray(children)[0]) || isMermaidCodeElement(import_react6.Children.toArray(children)[0])) ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_jsx_runtime19.Fragment, { children }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1944
3366
|
"div",
|
|
1945
3367
|
{
|
|
1946
3368
|
className: cn(
|
|
1947
3369
|
"max-w-4xl overflow-x-auto rounded-lg text-sm bg-black text-white dark:bg-zinc-800",
|
|
1948
3370
|
className
|
|
1949
3371
|
),
|
|
1950
|
-
|
|
3372
|
+
children
|
|
1951
3373
|
}
|
|
1952
3374
|
),
|
|
1953
3375
|
code: ({
|
|
@@ -1956,21 +3378,24 @@ var defaultComponents = {
|
|
|
1956
3378
|
node: _node,
|
|
1957
3379
|
...props
|
|
1958
3380
|
}) => {
|
|
1959
|
-
const match = /language-(\w+)/.exec(className || "");
|
|
3381
|
+
const match = /language-([\w-]+)/.exec(className || "");
|
|
1960
3382
|
const code = getTextContent(children);
|
|
1961
3383
|
const isBlockCode = code.includes("\n");
|
|
1962
3384
|
if (match) {
|
|
1963
3385
|
const language = match[1];
|
|
1964
3386
|
const normalizedCode = code.replace(/\n$/, "");
|
|
1965
|
-
|
|
1966
|
-
/* @__PURE__ */ (0,
|
|
3387
|
+
if (language === "mermaid") {
|
|
3388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(MermaidBlock, { code: normalizedCode });
|
|
3389
|
+
}
|
|
3390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
3391
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1967
3392
|
CodeHeader,
|
|
1968
3393
|
{
|
|
1969
3394
|
language,
|
|
1970
3395
|
code: normalizedCode
|
|
1971
3396
|
}
|
|
1972
3397
|
),
|
|
1973
|
-
/* @__PURE__ */ (0,
|
|
3398
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1974
3399
|
SyntaxHighlighter,
|
|
1975
3400
|
{
|
|
1976
3401
|
language,
|
|
@@ -1981,7 +3406,7 @@ var defaultComponents = {
|
|
|
1981
3406
|
] });
|
|
1982
3407
|
}
|
|
1983
3408
|
if (isBlockCode) {
|
|
1984
|
-
return /* @__PURE__ */ (0,
|
|
3409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1985
3410
|
"code",
|
|
1986
3411
|
{
|
|
1987
3412
|
className: cn(
|
|
@@ -1993,7 +3418,7 @@ var defaultComponents = {
|
|
|
1993
3418
|
}
|
|
1994
3419
|
);
|
|
1995
3420
|
}
|
|
1996
|
-
return /* @__PURE__ */ (0,
|
|
3421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1997
3422
|
"code",
|
|
1998
3423
|
{
|
|
1999
3424
|
className: cn(
|
|
@@ -2007,7 +3432,7 @@ var defaultComponents = {
|
|
|
2007
3432
|
}
|
|
2008
3433
|
};
|
|
2009
3434
|
var MarkdownTextImpl = ({ children }) => {
|
|
2010
|
-
return /* @__PURE__ */ (0,
|
|
3435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "markdown-content", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
2011
3436
|
import_react_markdown.default,
|
|
2012
3437
|
{
|
|
2013
3438
|
remarkPlugins: [import_remark_gfm.default, import_remark_math.default],
|
|
@@ -2021,18 +3446,18 @@ var MarkdownText = (0, import_react6.memo)(MarkdownTextImpl);
|
|
|
2021
3446
|
|
|
2022
3447
|
// src/components/thread/messages/widget.tsx
|
|
2023
3448
|
var import_a2ui_react = require("@xpert-ai/a2ui-react");
|
|
2024
|
-
var
|
|
3449
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
2025
3450
|
function WidgetMessage({ messageId, data }) {
|
|
2026
3451
|
const widgets = Array.isArray(data.widgets) ? data.widgets : [];
|
|
2027
3452
|
if (widgets.length === 0) return null;
|
|
2028
3453
|
const baseSurfaceId = `widget-${messageId}`;
|
|
2029
|
-
return /* @__PURE__ */ (0,
|
|
3454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "space-y-3", children: widgets.map((widget, index) => {
|
|
2030
3455
|
const config = widget?.config;
|
|
2031
3456
|
if (!config || typeof config !== "object") {
|
|
2032
3457
|
return null;
|
|
2033
3458
|
}
|
|
2034
3459
|
const surfaceId = widgets.length > 1 ? `${baseSurfaceId}-${index}` : baseSurfaceId;
|
|
2035
|
-
return /* @__PURE__ */ (0,
|
|
3460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
2036
3461
|
import_a2ui_react.SurfaceRenderer,
|
|
2037
3462
|
{
|
|
2038
3463
|
surfaceId,
|
|
@@ -2044,7 +3469,7 @@ function WidgetMessage({ messageId, data }) {
|
|
|
2044
3469
|
}
|
|
2045
3470
|
|
|
2046
3471
|
// src/components/thread/messages/ai.tsx
|
|
2047
|
-
var
|
|
3472
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
2048
3473
|
function isTextContent(content) {
|
|
2049
3474
|
return content.type === "text";
|
|
2050
3475
|
}
|
|
@@ -2060,15 +3485,15 @@ function isComponentContent(content) {
|
|
|
2060
3485
|
var statusConfig = {
|
|
2061
3486
|
success: {
|
|
2062
3487
|
iconClass: "border-green-500 text-green-700",
|
|
2063
|
-
icon:
|
|
3488
|
+
icon: import_lucide_react8.CheckCircle2
|
|
2064
3489
|
},
|
|
2065
3490
|
fail: {
|
|
2066
3491
|
iconClass: "border-red-500 text-red-700",
|
|
2067
|
-
icon:
|
|
3492
|
+
icon: import_lucide_react8.XCircle
|
|
2068
3493
|
},
|
|
2069
3494
|
running: {
|
|
2070
3495
|
iconClass: "border-blue-500 text-blue-700",
|
|
2071
|
-
icon:
|
|
3496
|
+
icon: import_lucide_react8.Loader2
|
|
2072
3497
|
}
|
|
2073
3498
|
};
|
|
2074
3499
|
function isWidgetComponent(content) {
|
|
@@ -2085,14 +3510,17 @@ function safeJson(value) {
|
|
|
2085
3510
|
return String(value);
|
|
2086
3511
|
}
|
|
2087
3512
|
}
|
|
3513
|
+
function formatDisplayValue(value) {
|
|
3514
|
+
return typeof value === "string" ? value : safeJson(value);
|
|
3515
|
+
}
|
|
2088
3516
|
function ReasoningBlock({ reasoning }) {
|
|
2089
3517
|
const blocks = reasoning.filter((item) => item.text?.trim());
|
|
2090
3518
|
if (blocks.length === 0) return null;
|
|
2091
|
-
return /* @__PURE__ */ (0,
|
|
3519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-2", children: blocks.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2092
3520
|
"div",
|
|
2093
3521
|
{
|
|
2094
3522
|
className: "rounded-lg border bg-muted/40 p-3 text-xs text-muted-foreground",
|
|
2095
|
-
children: /* @__PURE__ */ (0,
|
|
3523
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "whitespace-pre-wrap wrap-break-word leading-relaxed", children: item.text })
|
|
2096
3524
|
},
|
|
2097
3525
|
item.id ?? `reasoning-${index}`
|
|
2098
3526
|
)) });
|
|
@@ -2100,27 +3528,27 @@ function ReasoningBlock({ reasoning }) {
|
|
|
2100
3528
|
function ImageBlock({ content }) {
|
|
2101
3529
|
const imageUrl = typeof content.image_url === "string" ? content.image_url : typeof content.image_url?.url === "string" ? content.image_url.url : null;
|
|
2102
3530
|
if (!imageUrl) {
|
|
2103
|
-
return /* @__PURE__ */ (0,
|
|
2104
|
-
/* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
3531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Card, { children: [
|
|
3532
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardHeader, { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTitle, { className: "text-sm", children: "Image" }) }),
|
|
3533
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: safeJson(content) })
|
|
2106
3534
|
] });
|
|
2107
3535
|
}
|
|
2108
|
-
return /* @__PURE__ */ (0,
|
|
3536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("figure", { className: "overflow-hidden rounded-lg border bg-background", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("img", { src: imageUrl, alt: "Assistant output", className: "h-auto w-full object-cover" }) });
|
|
2109
3537
|
}
|
|
2110
3538
|
function MemoryBlock({ content }) {
|
|
2111
|
-
return /* @__PURE__ */ (0,
|
|
2112
|
-
/* @__PURE__ */ (0,
|
|
2113
|
-
/* @__PURE__ */ (0,
|
|
2114
|
-
/* @__PURE__ */ (0,
|
|
3539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Card, { children: [
|
|
3540
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
3541
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTitle, { className: "text-sm", children: "Memory" }),
|
|
3542
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "secondary", children: "Memory" })
|
|
2115
3543
|
] }),
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
3544
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: safeJson(content.data ?? []) }) })
|
|
2117
3545
|
] });
|
|
2118
3546
|
}
|
|
2119
3547
|
function ComponentBlock({ content }) {
|
|
2120
|
-
const [isExpanded, setIsExpanded] =
|
|
2121
|
-
const contentRef =
|
|
2122
|
-
const shouldAutoScrollRef =
|
|
2123
|
-
const previousScrollTopRef =
|
|
3548
|
+
const [isExpanded, setIsExpanded] = React15.useState(false);
|
|
3549
|
+
const contentRef = React15.useRef(null);
|
|
3550
|
+
const shouldAutoScrollRef = React15.useRef(true);
|
|
3551
|
+
const previousScrollTopRef = React15.useRef(0);
|
|
2124
3552
|
const data = content.data ?? {};
|
|
2125
3553
|
const category = data.category ?? "Component";
|
|
2126
3554
|
const title = data.tool && category === "Tool" ? data.tool : data.title ?? data.type ?? "Component";
|
|
@@ -2128,12 +3556,12 @@ function ComponentBlock({ content }) {
|
|
|
2128
3556
|
const message = data.message ?? null;
|
|
2129
3557
|
const output = data.output ?? null;
|
|
2130
3558
|
const error = data.error ?? null;
|
|
2131
|
-
const fallback = message ?? output ??
|
|
3559
|
+
const fallback = message ?? output ?? data.data ?? data;
|
|
2132
3560
|
const hasOutput = message !== null || output !== null;
|
|
2133
|
-
|
|
3561
|
+
React15.useEffect(() => {
|
|
2134
3562
|
if (status === "running" && output !== null) setIsExpanded(true);
|
|
2135
3563
|
}, [status, output]);
|
|
2136
|
-
|
|
3564
|
+
React15.useEffect(() => {
|
|
2137
3565
|
const element = contentRef.current;
|
|
2138
3566
|
if (!element) return;
|
|
2139
3567
|
previousScrollTopRef.current = element.scrollTop;
|
|
@@ -2153,7 +3581,7 @@ function ComponentBlock({ content }) {
|
|
|
2153
3581
|
element.removeEventListener("scroll", updateAutoScrollState);
|
|
2154
3582
|
};
|
|
2155
3583
|
}, [isExpanded]);
|
|
2156
|
-
|
|
3584
|
+
React15.useEffect(() => {
|
|
2157
3585
|
if (status !== "running") {
|
|
2158
3586
|
shouldAutoScrollRef.current = true;
|
|
2159
3587
|
return;
|
|
@@ -2166,21 +3594,21 @@ function ComponentBlock({ content }) {
|
|
|
2166
3594
|
}, [isExpanded, output, status]);
|
|
2167
3595
|
const config = status ? statusConfig[status] : null;
|
|
2168
3596
|
const StatusIcon = config?.icon;
|
|
2169
|
-
return /* @__PURE__ */ (0,
|
|
2170
|
-
/* @__PURE__ */ (0,
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2172
|
-
status && StatusIcon && /* @__PURE__ */ (0,
|
|
2173
|
-
/* @__PURE__ */ (0,
|
|
3597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Card, { children: [
|
|
3598
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2 px-2 py-1 cursor-pointer", onClick: () => setIsExpanded(!isExpanded), children: [
|
|
3599
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center space-x-1 flex-1 min-w-0", children: [
|
|
3600
|
+
status && StatusIcon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(StatusIcon, { className: cn("h-4 w-4", config?.iconClass, status === "running" && "animate-spin") }),
|
|
3601
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTitle, { className: "text-sm truncate", children: title })
|
|
2174
3602
|
] }),
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2176
|
-
/* @__PURE__ */ (0,
|
|
2177
|
-
/* @__PURE__ */ (0,
|
|
3603
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex flex-wrap items-center gap-2 shrink-0", children: [
|
|
3604
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "secondary", className: "rounded-lg px-1.5", children: category }),
|
|
3605
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2178
3606
|
"button",
|
|
2179
3607
|
{
|
|
2180
3608
|
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
2181
3609
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
2182
|
-
children: /* @__PURE__ */ (0,
|
|
2183
|
-
|
|
3610
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3611
|
+
import_lucide_react8.ChevronDown,
|
|
2184
3612
|
{
|
|
2185
3613
|
className: cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")
|
|
2186
3614
|
}
|
|
@@ -2189,89 +3617,128 @@ function ComponentBlock({ content }) {
|
|
|
2189
3617
|
)
|
|
2190
3618
|
] })
|
|
2191
3619
|
] }),
|
|
2192
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
2193
|
-
data.input && /* @__PURE__ */ (0,
|
|
2194
|
-
error ? /* @__PURE__ */ (0,
|
|
3620
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardContent, { ref: contentRef, className: "text-xs text-muted-foreground max-h-60 overflow-auto", children: [
|
|
3621
|
+
data.input && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(data.input) }),
|
|
3622
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word text-destructive", children: formatDisplayValue(error) }) : hasOutput && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "whitespace-pre-wrap wrap-break-word", children: formatDisplayValue(fallback) })
|
|
2195
3623
|
] })
|
|
2196
3624
|
] });
|
|
2197
3625
|
}
|
|
2198
3626
|
function UnknownBlock({ content }) {
|
|
2199
|
-
return /* @__PURE__ */ (0,
|
|
2200
|
-
/* @__PURE__ */ (0,
|
|
2201
|
-
/* @__PURE__ */ (0,
|
|
2202
|
-
/* @__PURE__ */ (0,
|
|
3627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(Card, { children: [
|
|
3628
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CardHeader, { className: "flex flex-row items-center justify-between gap-2", children: [
|
|
3629
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardTitle, { className: "text-sm", children: "Assistant Content" }),
|
|
3630
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Badge, { variant: "outline", children: content.type ?? "unknown" })
|
|
2203
3631
|
] }),
|
|
2204
|
-
/* @__PURE__ */ (0,
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CardContent, { className: "text-xs text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("pre", { className: "whitespace-pre-wrap break-words", children: safeJson(content) }) })
|
|
2205
3633
|
] });
|
|
2206
3634
|
}
|
|
2207
3635
|
function renderContentItem(content, index, messageId) {
|
|
2208
3636
|
if (typeof content === "string") {
|
|
2209
|
-
return /* @__PURE__ */ (0,
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
3637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { children: [
|
|
3638
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MarkdownText, { children: content }),
|
|
2211
3639
|
";"
|
|
2212
3640
|
] }, `text-${index}`);
|
|
2213
3641
|
}
|
|
2214
3642
|
if (isTextContent(content)) {
|
|
2215
|
-
return /* @__PURE__ */ (0,
|
|
3643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MarkdownText, { children: content.text }) }, content.id ?? `text-${index}`);
|
|
2216
3644
|
}
|
|
2217
3645
|
if (isReasoningContent(content)) {
|
|
2218
|
-
return /* @__PURE__ */ (0,
|
|
3646
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ReasoningBlock, { reasoning: [content] }) }, content.id ?? `reasoning-${index}`);
|
|
2219
3647
|
}
|
|
2220
3648
|
if (isImageContent(content)) {
|
|
2221
|
-
return /* @__PURE__ */ (0,
|
|
3649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ImageBlock, { content }) }, content.id ?? `image-${index}`);
|
|
2222
3650
|
}
|
|
2223
3651
|
if (isComponentContent(content)) {
|
|
2224
3652
|
if (isWidgetComponent(content)) {
|
|
2225
|
-
return /* @__PURE__ */ (0,
|
|
3653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(WidgetMessage, { messageId, data: content.data }) }, content.id ?? `widget-${index}`);
|
|
2226
3654
|
}
|
|
2227
|
-
return /* @__PURE__ */ (0,
|
|
3655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ComponentBlock, { content }) }, content.id ?? `component-${index}`);
|
|
2228
3656
|
}
|
|
2229
3657
|
if (isMemoryContent(content)) {
|
|
2230
|
-
return /* @__PURE__ */ (0,
|
|
3658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MemoryBlock, { content }) }, content.id ?? `memory-${index}`);
|
|
2231
3659
|
}
|
|
2232
|
-
return /* @__PURE__ */ (0,
|
|
3660
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(UnknownBlock, { content }) }, content.id ?? `unknown-${index}`);
|
|
2233
3661
|
}
|
|
2234
3662
|
function renderContent(content, messageId) {
|
|
2235
3663
|
if (typeof content === "string") {
|
|
2236
3664
|
if (!content.trim()) return null;
|
|
2237
|
-
return /* @__PURE__ */ (0,
|
|
3665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(MarkdownText, { children: content });
|
|
2238
3666
|
}
|
|
2239
3667
|
if (!Array.isArray(content) || content.length === 0) return null;
|
|
2240
|
-
return /* @__PURE__ */ (0,
|
|
3668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-3", children: content.map((item, index) => renderContentItem(item, index, messageId)) });
|
|
2241
3669
|
}
|
|
2242
|
-
function
|
|
3670
|
+
function AssistantStreamingIndicator({
|
|
3671
|
+
status,
|
|
3672
|
+
className
|
|
3673
|
+
}) {
|
|
2243
3674
|
const { t } = useChatkitTranslation();
|
|
2244
|
-
const
|
|
2245
|
-
|
|
2246
|
-
|
|
3675
|
+
const labelMap = {
|
|
3676
|
+
loading: t("message.loading"),
|
|
3677
|
+
thinking: t("message.thinking"),
|
|
3678
|
+
answering: t("message.answering")
|
|
3679
|
+
};
|
|
3680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cn("flex items-center gap-2 text-xs text-muted-foreground", className), children: [
|
|
3681
|
+
status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react8.Loader2, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
3682
|
+
status === "thinking" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
3683
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.3s]" }),
|
|
3684
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce [animation-delay:-0.15s]" }),
|
|
3685
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-bounce" })
|
|
3686
|
+
] }),
|
|
3687
|
+
status === "answering" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-end gap-1", "aria-hidden": "true", children: [
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-2 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.25s]" }),
|
|
3689
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-3 w-0.5 rounded-full bg-current animate-pulse [animation-delay:-0.1s]" }),
|
|
3690
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "h-2.5 w-0.5 rounded-full bg-current animate-pulse" })
|
|
3691
|
+
] }),
|
|
3692
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: labelMap[status] })
|
|
3693
|
+
] });
|
|
3694
|
+
}
|
|
3695
|
+
function AssistantMessage({
|
|
3696
|
+
message,
|
|
3697
|
+
className,
|
|
3698
|
+
isStreaming = false,
|
|
3699
|
+
streamingStatus
|
|
3700
|
+
}) {
|
|
3701
|
+
const { t } = useChatkitTranslation();
|
|
3702
|
+
const hasContent = hasRenderableMessageContent(message.content);
|
|
3703
|
+
const hasReasoning = hasRenderableReasoning(message.reasoning);
|
|
3704
|
+
const resolvedStreamingStatus = streamingStatus ?? getAssistantStreamingStatus(message, isStreaming);
|
|
2247
3705
|
const answerNode = renderContent(message.content, message.id);
|
|
2248
|
-
const reasoningNode = hasReasoning ? /* @__PURE__ */ (0,
|
|
2249
|
-
if (!
|
|
3706
|
+
const reasoningNode = hasReasoning ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ReasoningBlock, { reasoning: message.reasoning ?? [] }) : null;
|
|
3707
|
+
if (!hasRenderableAssistantMessage(message) && !resolvedStreamingStatus) return null;
|
|
2250
3708
|
const streamingClass = isStreaming ? "streaming-active" : "";
|
|
3709
|
+
if (!hasRenderableAssistantMessage(message) && resolvedStreamingStatus) {
|
|
3710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("space-y-3", streamingClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) });
|
|
3711
|
+
}
|
|
2251
3712
|
if (hasContent && hasReasoning) {
|
|
2252
|
-
return /* @__PURE__ */ (0,
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
/* @__PURE__ */ (0,
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
3713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3714
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
3715
|
+
Tabs,
|
|
3716
|
+
{
|
|
3717
|
+
defaultValue: message.status === "reasoning" ? "reasoning" : "answer",
|
|
3718
|
+
className: "w-full",
|
|
3719
|
+
children: [
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(TabsList, { className: "", children: [
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TabsTrigger, { value: "answer", children: t("message.answer") }),
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TabsTrigger, { value: "reasoning", children: t("message.reasoning") })
|
|
3723
|
+
] }),
|
|
3724
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TabsContent, { value: "answer", className: "space-y-3", children: answerNode }),
|
|
3725
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TabsContent, { value: "reasoning", className: "space-y-3", children: reasoningNode })
|
|
3726
|
+
]
|
|
3727
|
+
}
|
|
3728
|
+
),
|
|
3729
|
+
resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3730
|
+
] });
|
|
2267
3731
|
}
|
|
2268
|
-
return /* @__PURE__ */ (0,
|
|
3732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: cn("space-y-3", streamingClass, className), children: [
|
|
3733
|
+
hasReasoning ? reasoningNode : answerNode,
|
|
3734
|
+
resolvedStreamingStatus ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(AssistantStreamingIndicator, { status: resolvedStreamingStatus }) : null
|
|
3735
|
+
] });
|
|
2269
3736
|
}
|
|
2270
3737
|
|
|
2271
3738
|
// src/components/thread/MessageActions.tsx
|
|
2272
|
-
var
|
|
2273
|
-
var
|
|
2274
|
-
var
|
|
3739
|
+
var React16 = __toESM(require("react"), 1);
|
|
3740
|
+
var import_lucide_react9 = require("lucide-react");
|
|
3741
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
2275
3742
|
function MessageActions({
|
|
2276
3743
|
content,
|
|
2277
3744
|
isAssistant = false,
|
|
@@ -2280,7 +3747,7 @@ function MessageActions({
|
|
|
2280
3747
|
className
|
|
2281
3748
|
}) {
|
|
2282
3749
|
const { t } = useChatkitTranslation();
|
|
2283
|
-
const [copied, setCopied] =
|
|
3750
|
+
const [copied, setCopied] = React16.useState(false);
|
|
2284
3751
|
const handleCopy = async () => {
|
|
2285
3752
|
try {
|
|
2286
3753
|
await navigator.clipboard.writeText(content);
|
|
@@ -2293,7 +3760,7 @@ function MessageActions({
|
|
|
2293
3760
|
if (isStreaming) {
|
|
2294
3761
|
return null;
|
|
2295
3762
|
}
|
|
2296
|
-
return /* @__PURE__ */ (0,
|
|
3763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
2297
3764
|
"div",
|
|
2298
3765
|
{
|
|
2299
3766
|
className: cn(
|
|
@@ -2301,7 +3768,7 @@ function MessageActions({
|
|
|
2301
3768
|
className
|
|
2302
3769
|
),
|
|
2303
3770
|
children: [
|
|
2304
|
-
/* @__PURE__ */ (0,
|
|
3771
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2305
3772
|
"button",
|
|
2306
3773
|
{
|
|
2307
3774
|
type: "button",
|
|
@@ -2311,17 +3778,17 @@ function MessageActions({
|
|
|
2311
3778
|
copied && "text-green-500"
|
|
2312
3779
|
),
|
|
2313
3780
|
title: copied ? t("messageActions.copied") : t("messageActions.copy"),
|
|
2314
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
3781
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Check, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.Copy, { size: 14 })
|
|
2315
3782
|
}
|
|
2316
3783
|
),
|
|
2317
|
-
isAssistant && onRetry && /* @__PURE__ */ (0,
|
|
3784
|
+
isAssistant && onRetry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
2318
3785
|
"button",
|
|
2319
3786
|
{
|
|
2320
3787
|
type: "button",
|
|
2321
3788
|
onClick: onRetry,
|
|
2322
3789
|
className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
|
|
2323
3790
|
title: t("messageActions.regenerate"),
|
|
2324
|
-
children: /* @__PURE__ */ (0,
|
|
3791
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react9.RefreshCw, { size: 14 })
|
|
2325
3792
|
}
|
|
2326
3793
|
)
|
|
2327
3794
|
]
|
|
@@ -2330,20 +3797,20 @@ function MessageActions({
|
|
|
2330
3797
|
}
|
|
2331
3798
|
|
|
2332
3799
|
// src/components/thread/StartScreen.tsx
|
|
2333
|
-
var
|
|
2334
|
-
var
|
|
2335
|
-
var
|
|
3800
|
+
var React17 = require("react");
|
|
3801
|
+
var import_lucide_react10 = require("lucide-react");
|
|
3802
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
2336
3803
|
function getIconComponent2(icon) {
|
|
2337
3804
|
const iconMap = {
|
|
2338
|
-
"circle-question": /* @__PURE__ */ (0,
|
|
2339
|
-
"lightbulb": /* @__PURE__ */ (0,
|
|
2340
|
-
"sparkle": /* @__PURE__ */ (0,
|
|
2341
|
-
"write": /* @__PURE__ */ (0,
|
|
2342
|
-
"search": /* @__PURE__ */ (0,
|
|
2343
|
-
"globe": /* @__PURE__ */ (0,
|
|
2344
|
-
"book-open": /* @__PURE__ */ (0,
|
|
2345
|
-
"compass": /* @__PURE__ */ (0,
|
|
2346
|
-
"bolt": /* @__PURE__ */ (0,
|
|
3805
|
+
"circle-question": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.HelpCircle, { size: 20 }),
|
|
3806
|
+
"lightbulb": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Lightbulb, { size: 20 }),
|
|
3807
|
+
"sparkle": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Sparkles, { size: 20 }),
|
|
3808
|
+
"write": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Pencil, { size: 20 }),
|
|
3809
|
+
"search": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Search, { size: 20 }),
|
|
3810
|
+
"globe": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Globe, { size: 20 }),
|
|
3811
|
+
"book-open": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.BookOpen, { size: 20 }),
|
|
3812
|
+
"compass": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Compass, { size: 20 }),
|
|
3813
|
+
"bolt": /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Zap, { size: 20 })
|
|
2347
3814
|
};
|
|
2348
3815
|
return icon ? iconMap[icon] || iconMap["sparkle"] : iconMap["sparkle"];
|
|
2349
3816
|
}
|
|
@@ -2351,9 +3818,9 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2351
3818
|
const { t } = useChatkitTranslation();
|
|
2352
3819
|
const greeting = startScreen?.greeting ?? t("startScreen.greeting");
|
|
2353
3820
|
const prompts = startScreen?.prompts ?? [];
|
|
2354
|
-
return /* @__PURE__ */ (0,
|
|
2355
|
-
/* @__PURE__ */ (0,
|
|
2356
|
-
prompts.length > 0 && /* @__PURE__ */ (0,
|
|
3821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: cn("flex flex-col items-center justify-center py-12 px-4", className), children: [
|
|
3822
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mb-8 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h2", { className: "text-2xl font-semibold text-foreground mb-2", children: greeting }) }),
|
|
3823
|
+
prompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3", children: prompts.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
2357
3824
|
"button",
|
|
2358
3825
|
{
|
|
2359
3826
|
type: "button",
|
|
@@ -2364,8 +3831,8 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2364
3831
|
"focus:outline-none focus:ring-2 focus:ring-primary/20"
|
|
2365
3832
|
),
|
|
2366
3833
|
children: [
|
|
2367
|
-
/* @__PURE__ */ (0,
|
|
2368
|
-
/* @__PURE__ */ (0,
|
|
3834
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary", children: getIconComponent2(item.icon) }),
|
|
3835
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-sm font-medium text-foreground", children: item.label })
|
|
2369
3836
|
]
|
|
2370
3837
|
},
|
|
2371
3838
|
`prompt-${index}`
|
|
@@ -2374,13 +3841,13 @@ function StartScreen({ startScreen, onPromptClick, className }) {
|
|
|
2374
3841
|
}
|
|
2375
3842
|
|
|
2376
3843
|
// src/components/ui/chatkit-avatar.tsx
|
|
2377
|
-
var
|
|
3844
|
+
var React19 = require("react");
|
|
2378
3845
|
|
|
2379
3846
|
// src/components/ui/avatar.tsx
|
|
2380
|
-
var
|
|
3847
|
+
var React18 = __toESM(require("react"), 1);
|
|
2381
3848
|
var AvatarPrimitive = __toESM(require("@radix-ui/react-avatar"), 1);
|
|
2382
|
-
var
|
|
2383
|
-
var Avatar =
|
|
3849
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3850
|
+
var Avatar = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2384
3851
|
AvatarPrimitive.Root,
|
|
2385
3852
|
{
|
|
2386
3853
|
ref,
|
|
@@ -2392,7 +3859,7 @@ var Avatar = React16.forwardRef(({ className, ...props }, ref) => /* @__PURE__ *
|
|
|
2392
3859
|
}
|
|
2393
3860
|
));
|
|
2394
3861
|
Avatar.displayName = AvatarPrimitive.Root.displayName;
|
|
2395
|
-
var AvatarImage =
|
|
3862
|
+
var AvatarImage = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2396
3863
|
AvatarPrimitive.Image,
|
|
2397
3864
|
{
|
|
2398
3865
|
ref,
|
|
@@ -2401,7 +3868,7 @@ var AvatarImage = React16.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
2401
3868
|
}
|
|
2402
3869
|
));
|
|
2403
3870
|
AvatarImage.displayName = AvatarPrimitive.Image.displayName;
|
|
2404
|
-
var AvatarFallback =
|
|
3871
|
+
var AvatarFallback = React18.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2405
3872
|
AvatarPrimitive.Fallback,
|
|
2406
3873
|
{
|
|
2407
3874
|
ref,
|
|
@@ -2415,7 +3882,7 @@ var AvatarFallback = React16.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
2415
3882
|
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
|
|
2416
3883
|
|
|
2417
3884
|
// src/components/ui/chatkit-avatar.tsx
|
|
2418
|
-
var
|
|
3885
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2419
3886
|
function asRecord(value) {
|
|
2420
3887
|
return value && typeof value === "object" ? value : null;
|
|
2421
3888
|
}
|
|
@@ -2488,21 +3955,21 @@ function ChatkitAvatar({
|
|
|
2488
3955
|
const fallbackStyle = {
|
|
2489
3956
|
...avatar?.background ? { background: avatar.background } : {}
|
|
2490
3957
|
};
|
|
2491
|
-
return /* @__PURE__ */ (0,
|
|
2492
|
-
avatar?.url ? /* @__PURE__ */ (0,
|
|
2493
|
-
/* @__PURE__ */ (0,
|
|
3958
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Avatar, { className: cn(roundedClass, className), style, ...props, children: [
|
|
3959
|
+
avatar?.url ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AvatarImage, { className: imageClassName, src: avatar.url, alt: label }) : null,
|
|
3960
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2494
3961
|
AvatarFallback,
|
|
2495
3962
|
{
|
|
2496
3963
|
className: cn(roundedClass, "text-sm font-medium text-foreground", fallbackClassName),
|
|
2497
3964
|
style: fallbackStyle,
|
|
2498
|
-
children: emojiCharacter ? /* @__PURE__ */ (0,
|
|
3965
|
+
children: emojiCharacter ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-[1.1em] leading-none", style: emojiStyle, children: emojiCharacter }) : fallbackText
|
|
2499
3966
|
}
|
|
2500
3967
|
)
|
|
2501
3968
|
] });
|
|
2502
3969
|
}
|
|
2503
3970
|
|
|
2504
3971
|
// src/hooks/useThreads.ts
|
|
2505
|
-
var
|
|
3972
|
+
var React20 = __toESM(require("react"), 1);
|
|
2506
3973
|
var DEFAULT_LIMIT = 50;
|
|
2507
3974
|
var getThreadTitle = (threadRecord) => {
|
|
2508
3975
|
const title = threadRecord.title?.trim();
|
|
@@ -2540,16 +4007,16 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2540
4007
|
isReady,
|
|
2541
4008
|
isLoading: isStreamLoading
|
|
2542
4009
|
} = useStreamContext();
|
|
2543
|
-
const [threadRecords, setThreadRecords] =
|
|
2544
|
-
const [isLoading, setIsLoading] =
|
|
2545
|
-
const [error, setError] =
|
|
2546
|
-
const upsertThreadRecord =
|
|
4010
|
+
const [threadRecords, setThreadRecords] = React20.useState([]);
|
|
4011
|
+
const [isLoading, setIsLoading] = React20.useState(false);
|
|
4012
|
+
const [error, setError] = React20.useState(null);
|
|
4013
|
+
const upsertThreadRecord = React20.useCallback((threadRecord) => {
|
|
2547
4014
|
setThreadRecords((prev) => {
|
|
2548
4015
|
const next = prev.filter((item) => item.id !== threadRecord.id);
|
|
2549
4016
|
return sortThreadRecords([threadRecord, ...next]);
|
|
2550
4017
|
});
|
|
2551
4018
|
}, []);
|
|
2552
|
-
const refreshThreads =
|
|
4019
|
+
const refreshThreads = React20.useCallback(async () => {
|
|
2553
4020
|
setIsLoading(true);
|
|
2554
4021
|
setError(null);
|
|
2555
4022
|
try {
|
|
@@ -2565,7 +4032,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2565
4032
|
setIsLoading(false);
|
|
2566
4033
|
}
|
|
2567
4034
|
}, [client, limit, assistantId]);
|
|
2568
|
-
const createThread =
|
|
4035
|
+
const createThread = React20.useCallback(
|
|
2569
4036
|
async (input) => {
|
|
2570
4037
|
setError(null);
|
|
2571
4038
|
const payload = {};
|
|
@@ -2579,7 +4046,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2579
4046
|
},
|
|
2580
4047
|
[client, upsertThreadRecord]
|
|
2581
4048
|
);
|
|
2582
|
-
const updateThread =
|
|
4049
|
+
const updateThread = React20.useCallback(
|
|
2583
4050
|
async (recordId, payload) => {
|
|
2584
4051
|
setError(null);
|
|
2585
4052
|
const updated = await client.conversations.update(recordId, payload);
|
|
@@ -2588,7 +4055,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2588
4055
|
},
|
|
2589
4056
|
[client, upsertThreadRecord]
|
|
2590
4057
|
);
|
|
2591
|
-
const deleteThread =
|
|
4058
|
+
const deleteThread = React20.useCallback(
|
|
2592
4059
|
async (recordId) => {
|
|
2593
4060
|
setError(null);
|
|
2594
4061
|
await client.conversations.delete(recordId);
|
|
@@ -2596,23 +4063,24 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2596
4063
|
},
|
|
2597
4064
|
[client]
|
|
2598
4065
|
);
|
|
2599
|
-
|
|
4066
|
+
React20.useEffect(() => {
|
|
2600
4067
|
if (!isReady) return;
|
|
2601
4068
|
void refreshThreads();
|
|
2602
4069
|
}, [refreshThreads, isReady]);
|
|
2603
|
-
|
|
4070
|
+
React20.useEffect(() => {
|
|
2604
4071
|
if (!threadId || !isStreamLoading) return;
|
|
2605
4072
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4073
|
+
const busyStatus = "busy";
|
|
2606
4074
|
setThreadRecords((prev) => {
|
|
2607
4075
|
let changed = false;
|
|
2608
4076
|
const next = prev.map((item) => {
|
|
2609
4077
|
const isCurrentThread = item.threadId === threadId || item.id === threadId;
|
|
2610
4078
|
if (!isCurrentThread) return item;
|
|
2611
|
-
if (item.status ===
|
|
4079
|
+
if (item.status === busyStatus && !item.error) return item;
|
|
2612
4080
|
changed = true;
|
|
2613
4081
|
return {
|
|
2614
4082
|
...item,
|
|
2615
|
-
status:
|
|
4083
|
+
status: busyStatus,
|
|
2616
4084
|
error: void 0,
|
|
2617
4085
|
updatedAt: now
|
|
2618
4086
|
};
|
|
@@ -2620,7 +4088,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2620
4088
|
return changed ? sortThreadRecords(next) : prev;
|
|
2621
4089
|
});
|
|
2622
4090
|
}, [threadId, isStreamLoading]);
|
|
2623
|
-
|
|
4091
|
+
React20.useEffect(() => {
|
|
2624
4092
|
if (!isReady || !threadId || isStreamLoading) return;
|
|
2625
4093
|
let cancelled = false;
|
|
2626
4094
|
void client.conversations.search({ where: { threadId }, limit: 1 }).then((result) => {
|
|
@@ -2634,7 +4102,7 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2634
4102
|
cancelled = true;
|
|
2635
4103
|
};
|
|
2636
4104
|
}, [client, threadId, upsertThreadRecord, isReady, isStreamLoading]);
|
|
2637
|
-
const threads =
|
|
4105
|
+
const threads = React20.useMemo(
|
|
2638
4106
|
() => threadRecords.map((threadRecord) => toThreadItem(threadRecord)),
|
|
2639
4107
|
[threadRecords]
|
|
2640
4108
|
);
|
|
@@ -2651,22 +4119,22 @@ function useThreads(limit = DEFAULT_LIMIT) {
|
|
|
2651
4119
|
}
|
|
2652
4120
|
|
|
2653
4121
|
// src/components/thread/context-usage-indicator.tsx
|
|
2654
|
-
var
|
|
4122
|
+
var React21 = __toESM(require("react"), 1);
|
|
2655
4123
|
|
|
2656
4124
|
// src/components/ui/progress-circle.tsx
|
|
2657
|
-
var
|
|
4125
|
+
var import_jsx_runtime26 = (
|
|
2658
4126
|
// biome-ignore lint/a11y/useFocusableInteractive: false positive (progress + progressbar are not focusable interactives)
|
|
2659
4127
|
// biome-ignore lint/nursery/useAriaPropsSupportedByRole: biome rule at odds with mdn docs (presumed nursary bug with rule)
|
|
2660
4128
|
require("react/jsx-runtime")
|
|
2661
4129
|
);
|
|
2662
|
-
function
|
|
4130
|
+
function clamp2(input, a, b) {
|
|
2663
4131
|
return Math.max(Math.min(input, Math.max(a, b)), Math.min(a, b));
|
|
2664
4132
|
}
|
|
2665
4133
|
var size = 24;
|
|
2666
4134
|
var strokeWidth = 4;
|
|
2667
4135
|
var total = 100;
|
|
2668
4136
|
var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
2669
|
-
const normalizedValue =
|
|
4137
|
+
const normalizedValue = clamp2(value, 0, total);
|
|
2670
4138
|
const radius = (size - strokeWidth) / 2;
|
|
2671
4139
|
const circumference = 2 * Math.PI * radius;
|
|
2672
4140
|
const progress = normalizedValue / total * circumference;
|
|
@@ -2678,7 +4146,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2678
4146
|
fill: "none",
|
|
2679
4147
|
strokeWidth
|
|
2680
4148
|
};
|
|
2681
|
-
return /* @__PURE__ */ (0,
|
|
4149
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
2682
4150
|
"svg",
|
|
2683
4151
|
{
|
|
2684
4152
|
role: "progressbar",
|
|
@@ -2689,8 +4157,8 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2689
4157
|
"aria-valuemax": 100,
|
|
2690
4158
|
...restSvgProps,
|
|
2691
4159
|
children: [
|
|
2692
|
-
/* @__PURE__ */ (0,
|
|
2693
|
-
/* @__PURE__ */ (0,
|
|
4160
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("circle", { ...commonParams, className: "stroke-current/25" }),
|
|
4161
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2694
4162
|
"circle",
|
|
2695
4163
|
{
|
|
2696
4164
|
...commonParams,
|
|
@@ -2708,7 +4176,7 @@ var ProgressCircle = ({ value, className, ...restSvgProps }) => {
|
|
|
2708
4176
|
};
|
|
2709
4177
|
|
|
2710
4178
|
// src/components/thread/context-usage-indicator.tsx
|
|
2711
|
-
var
|
|
4179
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2712
4180
|
var kNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
2713
4181
|
minimumFractionDigits: 0,
|
|
2714
4182
|
maximumFractionDigits: 1
|
|
@@ -2741,20 +4209,20 @@ function ContextUsageIndicator({
|
|
|
2741
4209
|
}) {
|
|
2742
4210
|
const { t } = useChatkitTranslation();
|
|
2743
4211
|
const stream = useStreamContext();
|
|
2744
|
-
const [maxContextSize, setMaxContextSize] =
|
|
2745
|
-
const [usedContextSize, setUsedContextSize] =
|
|
2746
|
-
const [assistantAgentKey, setAssistantAgentKey] =
|
|
2747
|
-
const latestRealtimeUsageRef =
|
|
4212
|
+
const [maxContextSize, setMaxContextSize] = React21.useState(null);
|
|
4213
|
+
const [usedContextSize, setUsedContextSize] = React21.useState(null);
|
|
4214
|
+
const [assistantAgentKey, setAssistantAgentKey] = React21.useState(null);
|
|
4215
|
+
const latestRealtimeUsageRef = React21.useRef({
|
|
2748
4216
|
threadId: null,
|
|
2749
4217
|
agentKey: null,
|
|
2750
4218
|
usedTokens: null
|
|
2751
4219
|
});
|
|
2752
|
-
const realtimeUsage =
|
|
4220
|
+
const realtimeUsage = React21.useMemo(
|
|
2753
4221
|
() => getThreadContextUsage(stream.contextUsageByAgentKey, assistantAgentKey),
|
|
2754
4222
|
[assistantAgentKey, stream.contextUsageByAgentKey]
|
|
2755
4223
|
);
|
|
2756
4224
|
const realtimeUsedContextSize = getThreadContextUsageTotalTokens(realtimeUsage);
|
|
2757
|
-
|
|
4225
|
+
React21.useEffect(() => {
|
|
2758
4226
|
if (!stream.client || !stream.assistantId) {
|
|
2759
4227
|
setMaxContextSize(null);
|
|
2760
4228
|
setAssistantAgentKey(null);
|
|
@@ -2774,18 +4242,18 @@ function ContextUsageIndicator({
|
|
|
2774
4242
|
cancelled = true;
|
|
2775
4243
|
};
|
|
2776
4244
|
}, [stream.client, stream.assistantId]);
|
|
2777
|
-
|
|
4245
|
+
React21.useEffect(() => {
|
|
2778
4246
|
latestRealtimeUsageRef.current = {
|
|
2779
4247
|
threadId: stream.threadId ?? null,
|
|
2780
4248
|
agentKey: assistantAgentKey,
|
|
2781
4249
|
usedTokens: realtimeUsedContextSize
|
|
2782
4250
|
};
|
|
2783
4251
|
}, [assistantAgentKey, realtimeUsedContextSize, stream.threadId]);
|
|
2784
|
-
|
|
4252
|
+
React21.useEffect(() => {
|
|
2785
4253
|
if (realtimeUsedContextSize == null) return;
|
|
2786
4254
|
setUsedContextSize(realtimeUsedContextSize);
|
|
2787
4255
|
}, [realtimeUsedContextSize]);
|
|
2788
|
-
|
|
4256
|
+
React21.useEffect(() => {
|
|
2789
4257
|
if (!stream.client) {
|
|
2790
4258
|
setUsedContextSize(null);
|
|
2791
4259
|
return;
|
|
@@ -2850,8 +4318,8 @@ function ContextUsageIndicator({
|
|
|
2850
4318
|
});
|
|
2851
4319
|
const usageLabelWithSuffix = usageLabel.endsWith(":") ? usageLabel : `${usageLabel}:`;
|
|
2852
4320
|
const progressClassName = percent >= 90 ? "text-destructive" : percent >= 75 ? "text-amber-500" : "text-primary dark:text-zinc-300";
|
|
2853
|
-
return /* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
4321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
|
|
4322
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
2855
4323
|
"button",
|
|
2856
4324
|
{
|
|
2857
4325
|
type: "button",
|
|
@@ -2860,21 +4328,74 @@ function ContextUsageIndicator({
|
|
|
2860
4328
|
className
|
|
2861
4329
|
),
|
|
2862
4330
|
"aria-label": `${usageLabelWithSuffix} ${usageFullLabel}. ${usageTokensLabel}`,
|
|
2863
|
-
children: /* @__PURE__ */ (0,
|
|
4331
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ProgressCircle, { value: percent, className: cn("size-3.5", progressClassName) })
|
|
2864
4332
|
}
|
|
2865
4333
|
) }),
|
|
2866
|
-
/* @__PURE__ */ (0,
|
|
2867
|
-
/* @__PURE__ */ (0,
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
4334
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(TooltipContent, { side: "top", sideOffset: 6, className: "space-y-0.5 px-3 py-2 text-center", children: [
|
|
4335
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-primary-foreground/70", children: usageLabelWithSuffix }),
|
|
4336
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "font-medium text-primary-foreground/80", children: usageFullLabel }),
|
|
4337
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-sm font-semibold", children: usageTokensLabel })
|
|
2870
4338
|
] })
|
|
2871
4339
|
] });
|
|
2872
4340
|
}
|
|
2873
4341
|
|
|
2874
4342
|
// src/components/chat.tsx
|
|
2875
|
-
var
|
|
4343
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2876
4344
|
var import_meta2 = {};
|
|
2877
4345
|
var defaultApiUrl2 = import_meta2.env.VITE_XPERTAI_API_URL;
|
|
4346
|
+
var COMPOSER_INPUT_MAX_HEIGHT = 128;
|
|
4347
|
+
var LONG_TEXT_REFERENCE_THRESHOLD = 5e3;
|
|
4348
|
+
async function readImageDimensions(file) {
|
|
4349
|
+
if (typeof window === "undefined" || typeof URL === "undefined") {
|
|
4350
|
+
return {};
|
|
4351
|
+
}
|
|
4352
|
+
return new Promise((resolve) => {
|
|
4353
|
+
const objectUrl = URL.createObjectURL(file);
|
|
4354
|
+
const image = new window.Image();
|
|
4355
|
+
const cleanup = () => {
|
|
4356
|
+
URL.revokeObjectURL(objectUrl);
|
|
4357
|
+
};
|
|
4358
|
+
image.onload = () => {
|
|
4359
|
+
resolve({
|
|
4360
|
+
width: image.naturalWidth || void 0,
|
|
4361
|
+
height: image.naturalHeight || void 0
|
|
4362
|
+
});
|
|
4363
|
+
cleanup();
|
|
4364
|
+
};
|
|
4365
|
+
image.onerror = () => {
|
|
4366
|
+
resolve({});
|
|
4367
|
+
cleanup();
|
|
4368
|
+
};
|
|
4369
|
+
image.src = objectUrl;
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4372
|
+
function getStorageFileUrl(file) {
|
|
4373
|
+
return file.url ?? file.fileUrl ?? file.thumbUrl;
|
|
4374
|
+
}
|
|
4375
|
+
function buildPastedImageReference(file, storageFile, dimensions) {
|
|
4376
|
+
const name = storageFile.originalName?.trim() || file.name.trim() || "Pasted image";
|
|
4377
|
+
const mimeType = storageFile.mimetype?.trim() || file.type.trim() || "image/*";
|
|
4378
|
+
const size2 = storageFile.size ?? file.size;
|
|
4379
|
+
const width = dimensions?.width;
|
|
4380
|
+
const height = dimensions?.height;
|
|
4381
|
+
const metaParts = [
|
|
4382
|
+
mimeType,
|
|
4383
|
+
width && height ? `${width}x${height}` : null,
|
|
4384
|
+
typeof size2 === "number" ? `${size2} bytes` : null
|
|
4385
|
+
].filter((part) => Boolean(part));
|
|
4386
|
+
return {
|
|
4387
|
+
type: "image",
|
|
4388
|
+
id: storageFile.id,
|
|
4389
|
+
fileId: storageFile.id,
|
|
4390
|
+
url: getStorageFileUrl(storageFile),
|
|
4391
|
+
mimeType,
|
|
4392
|
+
name,
|
|
4393
|
+
...typeof size2 === "number" ? { size: size2 } : {},
|
|
4394
|
+
...width ? { width } : {},
|
|
4395
|
+
...height ? { height } : {},
|
|
4396
|
+
text: `Pasted image${metaParts.length ? ` (${metaParts.join(", ")})` : ""}: ${name}`
|
|
4397
|
+
};
|
|
4398
|
+
}
|
|
2878
4399
|
function formatMessageContent(content) {
|
|
2879
4400
|
if (typeof content === "string") {
|
|
2880
4401
|
return content;
|
|
@@ -2896,6 +4417,81 @@ function formatMessageContent(content) {
|
|
|
2896
4417
|
}
|
|
2897
4418
|
return "";
|
|
2898
4419
|
}
|
|
4420
|
+
function getClosestQuoteContainer(node) {
|
|
4421
|
+
if (!node) {
|
|
4422
|
+
return null;
|
|
4423
|
+
}
|
|
4424
|
+
const element = node instanceof HTMLElement ? node : node instanceof Text ? node.parentElement : null;
|
|
4425
|
+
return element?.closest("[data-quote-message-id]") ?? null;
|
|
4426
|
+
}
|
|
4427
|
+
function ReferenceChip({
|
|
4428
|
+
reference,
|
|
4429
|
+
variant,
|
|
4430
|
+
onRemove,
|
|
4431
|
+
removeLabel
|
|
4432
|
+
}) {
|
|
4433
|
+
const metaLine = getReferenceMetaLine(reference);
|
|
4434
|
+
const isComposer = variant === "composer";
|
|
4435
|
+
const Icon = reference.type === "quote" ? import_lucide_react11.Quote : reference.type === "image" ? import_lucide_react11.ImageIcon : import_lucide_react11.FileText;
|
|
4436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
4437
|
+
"div",
|
|
4438
|
+
{
|
|
4439
|
+
className: cn(
|
|
4440
|
+
"flex items-start gap-2 rounded-md px-2 py-1",
|
|
4441
|
+
isComposer ? "bg-muted text-foreground" : "bg-primary-foreground/20"
|
|
4442
|
+
),
|
|
4443
|
+
title: getReferenceTitle(reference),
|
|
4444
|
+
children: [
|
|
4445
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4446
|
+
Icon,
|
|
4447
|
+
{
|
|
4448
|
+
size: isComposer ? 14 : 12,
|
|
4449
|
+
className: cn(
|
|
4450
|
+
"mt-0.5 shrink-0",
|
|
4451
|
+
isComposer ? "text-muted-foreground" : "text-primary-foreground/80"
|
|
4452
|
+
)
|
|
4453
|
+
}
|
|
4454
|
+
),
|
|
4455
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
4456
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4457
|
+
"div",
|
|
4458
|
+
{
|
|
4459
|
+
className: cn(
|
|
4460
|
+
"truncate whitespace-pre-wrap",
|
|
4461
|
+
isComposer ? "text-sm" : "text-xs font-medium"
|
|
4462
|
+
),
|
|
4463
|
+
children: getReferenceLabel(reference)
|
|
4464
|
+
}
|
|
4465
|
+
),
|
|
4466
|
+
metaLine && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4467
|
+
"div",
|
|
4468
|
+
{
|
|
4469
|
+
className: cn(
|
|
4470
|
+
"truncate whitespace-pre-wrap",
|
|
4471
|
+
isComposer ? "text-xs text-muted-foreground" : "text-[10px] text-primary-foreground/75"
|
|
4472
|
+
),
|
|
4473
|
+
children: metaLine
|
|
4474
|
+
}
|
|
4475
|
+
)
|
|
4476
|
+
] }),
|
|
4477
|
+
onRemove && removeLabel && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
4478
|
+
"button",
|
|
4479
|
+
{
|
|
4480
|
+
type: "button",
|
|
4481
|
+
onClick: onRemove,
|
|
4482
|
+
className: cn(
|
|
4483
|
+
"ml-1 rounded-full p-0.5",
|
|
4484
|
+
isComposer ? "hover:bg-muted-foreground/20" : "hover:bg-primary-foreground/20"
|
|
4485
|
+
),
|
|
4486
|
+
title: removeLabel,
|
|
4487
|
+
"aria-label": removeLabel,
|
|
4488
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.X, { size: 12 })
|
|
4489
|
+
}
|
|
4490
|
+
)
|
|
4491
|
+
]
|
|
4492
|
+
}
|
|
4493
|
+
);
|
|
4494
|
+
}
|
|
2899
4495
|
function Chat({
|
|
2900
4496
|
className,
|
|
2901
4497
|
options,
|
|
@@ -2912,17 +4508,21 @@ function Chat({
|
|
|
2912
4508
|
const apiUrl = options?.api?.apiUrl || defaultApiUrl2;
|
|
2913
4509
|
const { setStream } = useStreamManager();
|
|
2914
4510
|
const stream = useStreamContext();
|
|
2915
|
-
const
|
|
2916
|
-
const [
|
|
2917
|
-
const [
|
|
2918
|
-
const [
|
|
4511
|
+
const { theme } = useTheme();
|
|
4512
|
+
const [isHistoryLoading, setIsHistoryLoading] = React22.useState(false);
|
|
4513
|
+
const [historyError, setHistoryError] = React22.useState(null);
|
|
4514
|
+
const [assistantName, setAssistantName] = React22.useState(null);
|
|
4515
|
+
const [assistantAvatar, setAssistantAvatar] = React22.useState(null);
|
|
2919
4516
|
const LOADING_DOTS_MIN_DURATION = 800;
|
|
2920
|
-
const
|
|
2921
|
-
const
|
|
2922
|
-
|
|
4517
|
+
const STREAMING_STATUS_REFRESH_MS = 250;
|
|
4518
|
+
const [showLoadingDots, setShowLoadingDots] = React22.useState(false);
|
|
4519
|
+
const [streamingNow, setStreamingNow] = React22.useState(() => Date.now());
|
|
4520
|
+
const loadingStartTimeRef = React22.useRef(null);
|
|
4521
|
+
const lastStreamOutputAtRef = React22.useRef(null);
|
|
4522
|
+
React22.useEffect(() => {
|
|
2923
4523
|
setStream(stream);
|
|
2924
4524
|
}, [setStream, stream]);
|
|
2925
|
-
|
|
4525
|
+
React22.useEffect(() => {
|
|
2926
4526
|
if (stream.isLoading) {
|
|
2927
4527
|
if (!loadingStartTimeRef.current) {
|
|
2928
4528
|
loadingStartTimeRef.current = Date.now();
|
|
@@ -2945,67 +4545,181 @@ function Chat({
|
|
|
2945
4545
|
}
|
|
2946
4546
|
}
|
|
2947
4547
|
}, [stream.isLoading]);
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
4548
|
+
React22.useEffect(() => {
|
|
4549
|
+
if (!stream.isLoading) {
|
|
4550
|
+
lastStreamOutputAtRef.current = null;
|
|
4551
|
+
setStreamingNow(Date.now());
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
const now = Date.now();
|
|
4555
|
+
lastStreamOutputAtRef.current = now;
|
|
4556
|
+
setStreamingNow(now);
|
|
4557
|
+
}, [stream.messages, stream.isLoading]);
|
|
4558
|
+
React22.useEffect(() => {
|
|
4559
|
+
if (!stream.isLoading) {
|
|
4560
|
+
return;
|
|
4561
|
+
}
|
|
4562
|
+
const timer = window.setInterval(() => {
|
|
4563
|
+
setStreamingNow(Date.now());
|
|
4564
|
+
}, STREAMING_STATUS_REFRESH_MS);
|
|
4565
|
+
return () => window.clearInterval(timer);
|
|
4566
|
+
}, [stream.isLoading]);
|
|
4567
|
+
const [draft, setDraft] = React22.useState("");
|
|
4568
|
+
const [selectedTool, setSelectedTool] = React22.useState(
|
|
4569
|
+
null
|
|
4570
|
+
);
|
|
4571
|
+
const [attachments, setAttachments] = React22.useState([]);
|
|
4572
|
+
const [references, setReferences] = React22.useState([]);
|
|
4573
|
+
const [isUploadingReferenceImages, setIsUploadingReferenceImages] = React22.useState(false);
|
|
4574
|
+
const [quoteSelection, setQuoteSelection] = React22.useState(null);
|
|
4575
|
+
const [isAtBottom, setIsAtBottom] = React22.useState(true);
|
|
4576
|
+
const [hasUpdatesBelow, setHasUpdatesBelow] = React22.useState(false);
|
|
2953
4577
|
const {
|
|
2954
4578
|
threads,
|
|
2955
4579
|
deleteThread,
|
|
2956
4580
|
refreshThreads,
|
|
2957
4581
|
isLoading: isThreadsLoading
|
|
2958
4582
|
} = useThreads();
|
|
2959
|
-
const viewportRef =
|
|
2960
|
-
const fileInputRef =
|
|
2961
|
-
const
|
|
2962
|
-
const
|
|
2963
|
-
const
|
|
2964
|
-
const
|
|
2965
|
-
const
|
|
2966
|
-
const
|
|
2967
|
-
const
|
|
4583
|
+
const viewportRef = React22.useRef(null);
|
|
4584
|
+
const fileInputRef = React22.useRef(null);
|
|
4585
|
+
const composerInputRef = React22.useRef(null);
|
|
4586
|
+
const shouldAutoScrollRef = React22.useRef(true);
|
|
4587
|
+
const forceFollowRef = React22.useRef(false);
|
|
4588
|
+
const previousMessageCountRef = React22.useRef(0);
|
|
4589
|
+
const previousScrollTopRef = React22.useRef(0);
|
|
4590
|
+
const autoScrollFrameRef = React22.useRef(null);
|
|
4591
|
+
const isPointerDownRef = React22.useRef(false);
|
|
4592
|
+
const lastTouchYRef = React22.useRef(null);
|
|
2968
4593
|
const resolvedTitle = title ?? t("chat.title");
|
|
2969
4594
|
const resolvedPlaceholder = placeholder ?? t("chat.placeholder");
|
|
2970
4595
|
const inputPlaceholder = selectedTool?.placeholderOverride ?? composer?.placeholder ?? resolvedPlaceholder;
|
|
2971
|
-
const messages =
|
|
4596
|
+
const messages = React22.useMemo(
|
|
4597
|
+
() => stream.messages ?? [],
|
|
4598
|
+
[stream.messages]
|
|
4599
|
+
);
|
|
2972
4600
|
const trimmedDraft = draft.trim();
|
|
2973
|
-
const
|
|
4601
|
+
const hasReferences = references.length > 0;
|
|
4602
|
+
const pendingFollowUps = React22.useMemo(
|
|
4603
|
+
() => [...stream.pendingFollowUps ?? []].sort(
|
|
4604
|
+
(a, b) => a.createdAt - b.createdAt
|
|
4605
|
+
),
|
|
4606
|
+
[stream.pendingFollowUps]
|
|
4607
|
+
);
|
|
4608
|
+
const clearQuoteSelection = React22.useCallback(() => {
|
|
4609
|
+
setQuoteSelection(null);
|
|
4610
|
+
}, []);
|
|
4611
|
+
useParentMessenger({
|
|
4612
|
+
onSetComposerValue: React22.useCallback(
|
|
4613
|
+
(payload) => {
|
|
4614
|
+
if (!payload) {
|
|
4615
|
+
return;
|
|
4616
|
+
}
|
|
4617
|
+
if (typeof payload.text === "string") {
|
|
4618
|
+
setDraft(payload.text);
|
|
4619
|
+
}
|
|
4620
|
+
if (Array.isArray(payload.references)) {
|
|
4621
|
+
const nextReferences = normalizeReferences(payload.references);
|
|
4622
|
+
setReferences(
|
|
4623
|
+
(previous) => payload.appendReferences ? mergeReferences(previous, nextReferences) : nextReferences
|
|
4624
|
+
);
|
|
4625
|
+
}
|
|
4626
|
+
if (payload.selectedToolId !== void 0) {
|
|
4627
|
+
const nextTool = payload.selectedToolId === null ? null : (composer?.tools ?? []).find(
|
|
4628
|
+
(tool) => tool.id === payload.selectedToolId
|
|
4629
|
+
) ?? null;
|
|
4630
|
+
setSelectedTool(nextTool);
|
|
4631
|
+
}
|
|
4632
|
+
},
|
|
4633
|
+
[composer?.tools]
|
|
4634
|
+
),
|
|
4635
|
+
onFocusComposer: React22.useCallback(() => {
|
|
4636
|
+
composerInputRef.current?.focus();
|
|
4637
|
+
}, [])
|
|
4638
|
+
});
|
|
4639
|
+
const syncQuoteSelection = React22.useCallback(() => {
|
|
4640
|
+
if (typeof window === "undefined") {
|
|
4641
|
+
clearQuoteSelection();
|
|
4642
|
+
return;
|
|
4643
|
+
}
|
|
4644
|
+
const selection = window.getSelection();
|
|
4645
|
+
if (!selection || selection.isCollapsed || selection.rangeCount === 0) {
|
|
4646
|
+
clearQuoteSelection();
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
const text = selection.toString().trim();
|
|
4650
|
+
if (!text) {
|
|
4651
|
+
clearQuoteSelection();
|
|
4652
|
+
return;
|
|
4653
|
+
}
|
|
4654
|
+
const anchorContainer = getClosestQuoteContainer(selection.anchorNode);
|
|
4655
|
+
const focusContainer = getClosestQuoteContainer(selection.focusNode);
|
|
4656
|
+
if (!anchorContainer || !focusContainer || anchorContainer !== focusContainer || !viewportRef.current?.contains(anchorContainer)) {
|
|
4657
|
+
clearQuoteSelection();
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
const range = selection.getRangeAt(0);
|
|
4661
|
+
const rect = range.getBoundingClientRect();
|
|
4662
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
4663
|
+
clearQuoteSelection();
|
|
4664
|
+
return;
|
|
4665
|
+
}
|
|
4666
|
+
const top = rect.bottom + 8 > window.innerHeight - 48 ? Math.max(12, rect.top - 44) : rect.bottom + 8;
|
|
4667
|
+
const left = Math.min(
|
|
4668
|
+
Math.max(24, rect.left + rect.width / 2),
|
|
4669
|
+
window.innerWidth - 24
|
|
4670
|
+
);
|
|
4671
|
+
const source = anchorContainer.dataset.quoteSource?.trim() || void 0;
|
|
4672
|
+
const messageId = anchorContainer.dataset.quoteMessageId?.trim() || void 0;
|
|
4673
|
+
setQuoteSelection({
|
|
4674
|
+
reference: {
|
|
4675
|
+
type: "quote",
|
|
4676
|
+
text,
|
|
4677
|
+
...messageId ? { messageId } : {},
|
|
4678
|
+
...source ? { source, label: source } : {}
|
|
4679
|
+
},
|
|
4680
|
+
top,
|
|
4681
|
+
left
|
|
4682
|
+
});
|
|
4683
|
+
}, [clearQuoteSelection]);
|
|
4684
|
+
const cancelPendingAutoScroll = React22.useCallback(() => {
|
|
2974
4685
|
if (autoScrollFrameRef.current !== null) {
|
|
2975
4686
|
cancelAnimationFrame(autoScrollFrameRef.current);
|
|
2976
4687
|
autoScrollFrameRef.current = null;
|
|
2977
4688
|
}
|
|
2978
4689
|
}, []);
|
|
2979
|
-
const disableAutoFollow =
|
|
4690
|
+
const disableAutoFollow = React22.useCallback(() => {
|
|
2980
4691
|
forceFollowRef.current = false;
|
|
2981
4692
|
shouldAutoScrollRef.current = false;
|
|
2982
4693
|
cancelPendingAutoScroll();
|
|
2983
4694
|
}, [cancelPendingAutoScroll]);
|
|
2984
|
-
const enableAutoFollow =
|
|
4695
|
+
const enableAutoFollow = React22.useCallback(() => {
|
|
2985
4696
|
forceFollowRef.current = true;
|
|
2986
4697
|
shouldAutoScrollRef.current = true;
|
|
2987
4698
|
setHasUpdatesBelow(false);
|
|
2988
4699
|
}, []);
|
|
2989
|
-
const scrollToBottom =
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
cancelPendingAutoScroll();
|
|
2994
|
-
autoScrollFrameRef.current = requestAnimationFrame(() => {
|
|
2995
|
-
autoScrollFrameRef.current = null;
|
|
2996
|
-
const viewport = viewportRef.current;
|
|
2997
|
-
if (viewport) {
|
|
2998
|
-
if (!force && !shouldAutoScrollRef.current) {
|
|
2999
|
-
return;
|
|
3000
|
-
}
|
|
3001
|
-
viewport.scrollTo({
|
|
3002
|
-
top: viewport.scrollHeight,
|
|
3003
|
-
behavior: smooth ? "smooth" : "instant"
|
|
3004
|
-
});
|
|
4700
|
+
const scrollToBottom = React22.useCallback(
|
|
4701
|
+
(smooth = false, force = false) => {
|
|
4702
|
+
if (force) {
|
|
4703
|
+
enableAutoFollow();
|
|
3005
4704
|
}
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
4705
|
+
cancelPendingAutoScroll();
|
|
4706
|
+
autoScrollFrameRef.current = requestAnimationFrame(() => {
|
|
4707
|
+
autoScrollFrameRef.current = null;
|
|
4708
|
+
const viewport = viewportRef.current;
|
|
4709
|
+
if (viewport) {
|
|
4710
|
+
if (!force && !shouldAutoScrollRef.current) {
|
|
4711
|
+
return;
|
|
4712
|
+
}
|
|
4713
|
+
viewport.scrollTo({
|
|
4714
|
+
top: viewport.scrollHeight,
|
|
4715
|
+
behavior: smooth ? "smooth" : "instant"
|
|
4716
|
+
});
|
|
4717
|
+
}
|
|
4718
|
+
});
|
|
4719
|
+
},
|
|
4720
|
+
[cancelPendingAutoScroll, enableAutoFollow]
|
|
4721
|
+
);
|
|
4722
|
+
React22.useEffect(() => {
|
|
3009
4723
|
const viewport = viewportRef.current;
|
|
3010
4724
|
if (!viewport) return;
|
|
3011
4725
|
previousScrollTopRef.current = viewport.scrollTop;
|
|
@@ -3057,13 +4771,23 @@ function Chat({
|
|
|
3057
4771
|
};
|
|
3058
4772
|
updateAutoScrollState();
|
|
3059
4773
|
viewport.addEventListener("wheel", handleWheel, { passive: true });
|
|
3060
|
-
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
3061
|
-
|
|
3062
|
-
|
|
4774
|
+
viewport.addEventListener("pointerdown", handlePointerDown, {
|
|
4775
|
+
passive: true
|
|
4776
|
+
});
|
|
4777
|
+
viewport.addEventListener("scroll", updateAutoScrollState, {
|
|
4778
|
+
passive: true
|
|
4779
|
+
});
|
|
4780
|
+
viewport.addEventListener("touchstart", handleTouchStart, {
|
|
4781
|
+
passive: true
|
|
4782
|
+
});
|
|
3063
4783
|
viewport.addEventListener("touchmove", handleTouchMove, { passive: true });
|
|
3064
4784
|
viewport.addEventListener("touchend", handleTouchEnd, { passive: true });
|
|
3065
|
-
window.addEventListener("pointerup", stopPointerTracking, {
|
|
3066
|
-
|
|
4785
|
+
window.addEventListener("pointerup", stopPointerTracking, {
|
|
4786
|
+
passive: true
|
|
4787
|
+
});
|
|
4788
|
+
window.addEventListener("pointercancel", stopPointerTracking, {
|
|
4789
|
+
passive: true
|
|
4790
|
+
});
|
|
3067
4791
|
return () => {
|
|
3068
4792
|
cancelPendingAutoScroll();
|
|
3069
4793
|
viewport.removeEventListener("wheel", handleWheel);
|
|
@@ -3076,14 +4800,14 @@ function Chat({
|
|
|
3076
4800
|
window.removeEventListener("pointercancel", stopPointerTracking);
|
|
3077
4801
|
};
|
|
3078
4802
|
}, [cancelPendingAutoScroll, disableAutoFollow]);
|
|
3079
|
-
|
|
4803
|
+
React22.useEffect(() => {
|
|
3080
4804
|
shouldAutoScrollRef.current = true;
|
|
3081
4805
|
forceFollowRef.current = false;
|
|
3082
4806
|
previousScrollTopRef.current = 0;
|
|
3083
4807
|
setIsAtBottom(true);
|
|
3084
4808
|
setHasUpdatesBelow(false);
|
|
3085
4809
|
}, [stream.threadId]);
|
|
3086
|
-
|
|
4810
|
+
React22.useEffect(() => {
|
|
3087
4811
|
const messageCountChanged = messages.length !== previousMessageCountRef.current;
|
|
3088
4812
|
previousMessageCountRef.current = messages.length;
|
|
3089
4813
|
if (!shouldAutoScrollRef.current) {
|
|
@@ -3097,16 +4821,85 @@ function Chat({
|
|
|
3097
4821
|
}
|
|
3098
4822
|
}, [stream.isLoading, messages, scrollToBottom]);
|
|
3099
4823
|
const effectiveClientSecret = stream.apiKey?.trim() ? stream.apiKey : clientSecret;
|
|
3100
|
-
const
|
|
3101
|
-
|
|
4824
|
+
const missingConfigKind = getMissingApiConfigurationKind({
|
|
4825
|
+
apiUrl,
|
|
4826
|
+
clientSecret: effectiveClientSecret
|
|
4827
|
+
});
|
|
4828
|
+
const missingConfig = Boolean(missingConfigKind);
|
|
4829
|
+
const missingConfigShortMessage = React22.useMemo(() => {
|
|
4830
|
+
switch (missingConfigKind) {
|
|
4831
|
+
case "apiUrl":
|
|
4832
|
+
return t("chat.missingApiUrlShort");
|
|
4833
|
+
case "clientSecret":
|
|
4834
|
+
return t("chat.missingClientSecretShort");
|
|
4835
|
+
case "apiUrlAndClientSecret":
|
|
4836
|
+
return t("chat.missingApiUrlAndClientSecretShort");
|
|
4837
|
+
default:
|
|
4838
|
+
return t("chat.missingConfigShort");
|
|
4839
|
+
}
|
|
4840
|
+
}, [missingConfigKind, t]);
|
|
4841
|
+
const missingConfigDetailMessage = React22.useMemo(() => {
|
|
4842
|
+
switch (missingConfigKind) {
|
|
4843
|
+
case "apiUrl":
|
|
4844
|
+
return t("chat.missingApiUrlDetail");
|
|
4845
|
+
case "clientSecret":
|
|
4846
|
+
return t("chat.missingClientSecretDetail");
|
|
4847
|
+
case "apiUrlAndClientSecret":
|
|
4848
|
+
return t("chat.missingApiUrlAndClientSecretDetail");
|
|
4849
|
+
default:
|
|
4850
|
+
return t("chat.missingConfigDetail");
|
|
4851
|
+
}
|
|
4852
|
+
}, [missingConfigKind, t]);
|
|
3102
4853
|
const showMissingConfig = !isClientSecretInitializing && missingConfig;
|
|
3103
4854
|
const hasUploadingFiles = attachments.some((a) => a.status === "uploading");
|
|
3104
|
-
const isSendDisabled = !trimmedDraft
|
|
3105
|
-
|
|
4855
|
+
const isSendDisabled = !trimmedDraft && !hasReferences || missingConfig || isHistoryLoading || hasUploadingFiles || isUploadingReferenceImages;
|
|
4856
|
+
const resizeComposerInput = React22.useCallback(() => {
|
|
4857
|
+
const textarea = composerInputRef.current;
|
|
4858
|
+
if (!textarea) {
|
|
4859
|
+
return;
|
|
4860
|
+
}
|
|
4861
|
+
textarea.style.height = "auto";
|
|
4862
|
+
const nextHeight = Math.min(
|
|
4863
|
+
textarea.scrollHeight,
|
|
4864
|
+
COMPOSER_INPUT_MAX_HEIGHT
|
|
4865
|
+
);
|
|
4866
|
+
textarea.style.height = `${nextHeight}px`;
|
|
4867
|
+
textarea.style.overflowY = textarea.scrollHeight > COMPOSER_INPUT_MAX_HEIGHT ? "auto" : "hidden";
|
|
4868
|
+
}, []);
|
|
4869
|
+
React22.useEffect(() => {
|
|
4870
|
+
resizeComposerInput();
|
|
4871
|
+
}, [draft, resizeComposerInput]);
|
|
4872
|
+
React22.useEffect(() => {
|
|
4873
|
+
document.addEventListener("selectionchange", syncQuoteSelection);
|
|
4874
|
+
return () => {
|
|
4875
|
+
document.removeEventListener("selectionchange", syncQuoteSelection);
|
|
4876
|
+
};
|
|
4877
|
+
}, [syncQuoteSelection]);
|
|
4878
|
+
React22.useEffect(() => {
|
|
4879
|
+
const viewport = viewportRef.current;
|
|
4880
|
+
if (!viewport) {
|
|
4881
|
+
return;
|
|
4882
|
+
}
|
|
4883
|
+
const handleViewportScroll = () => {
|
|
4884
|
+
clearQuoteSelection();
|
|
4885
|
+
};
|
|
4886
|
+
viewport.addEventListener("scroll", handleViewportScroll, {
|
|
4887
|
+
passive: true
|
|
4888
|
+
});
|
|
4889
|
+
window.addEventListener("resize", handleViewportScroll, { passive: true });
|
|
4890
|
+
return () => {
|
|
4891
|
+
viewport.removeEventListener("scroll", handleViewportScroll);
|
|
4892
|
+
window.removeEventListener("resize", handleViewportScroll);
|
|
4893
|
+
};
|
|
4894
|
+
}, [clearQuoteSelection]);
|
|
4895
|
+
React22.useEffect(() => {
|
|
4896
|
+
clearQuoteSelection();
|
|
4897
|
+
}, [messages.length, stream.threadId, clearQuoteSelection]);
|
|
4898
|
+
React22.useEffect(() => {
|
|
3106
4899
|
if (missingConfig) return;
|
|
3107
4900
|
void refreshThreads();
|
|
3108
4901
|
}, [missingConfig, refreshThreads]);
|
|
3109
|
-
|
|
4902
|
+
React22.useEffect(() => {
|
|
3110
4903
|
if (missingConfig || !stream.client || !stream.assistantId) {
|
|
3111
4904
|
setAssistantName(null);
|
|
3112
4905
|
setAssistantAvatar(null);
|
|
@@ -3137,80 +4930,275 @@ function Chat({
|
|
|
3137
4930
|
mimetype: a.storageFile?.mimetype ?? a.file.type,
|
|
3138
4931
|
size: a.storageFile?.size ?? a.file.size
|
|
3139
4932
|
}));
|
|
4933
|
+
const submitDraft = React22.useCallback(
|
|
4934
|
+
(followUpOverride) => {
|
|
4935
|
+
if (isSendDisabled) return;
|
|
4936
|
+
const filesToSend = uploadedFiles.length > 0 ? [...uploadedFiles] : void 0;
|
|
4937
|
+
const referencesToSend = references.length > 0 ? [...references] : void 0;
|
|
4938
|
+
const nextFollowUpMode = stream.isLoading ? followUpOverride ?? stream.followUpBehavior : void 0;
|
|
4939
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
4940
|
+
content: trimmedDraft,
|
|
4941
|
+
references: referencesToSend
|
|
4942
|
+
});
|
|
4943
|
+
if (!humanInput) {
|
|
4944
|
+
return;
|
|
4945
|
+
}
|
|
4946
|
+
const displayContent = trimmedDraft || (referencesToSend ? t("chat.referencedContentOnly") : "");
|
|
4947
|
+
const newMessage = {
|
|
4948
|
+
id: createMessageId(),
|
|
4949
|
+
type: "human",
|
|
4950
|
+
content: displayContent,
|
|
4951
|
+
submittedInput: humanInput.input,
|
|
4952
|
+
...humanInput.referenceComposition ? { referenceComposition: humanInput.referenceComposition } : {},
|
|
4953
|
+
...filesToSend ? { attachments: filesToSend } : {},
|
|
4954
|
+
...referencesToSend ? { references: referencesToSend } : {}
|
|
4955
|
+
};
|
|
4956
|
+
setDraft("");
|
|
4957
|
+
const inputPayload = {
|
|
4958
|
+
...humanInput
|
|
4959
|
+
};
|
|
4960
|
+
if (filesToSend) {
|
|
4961
|
+
inputPayload.files = filesToSend;
|
|
4962
|
+
}
|
|
4963
|
+
const requestOptions = buildInjectedRequestOptions({
|
|
4964
|
+
defaults: options?.request,
|
|
4965
|
+
humanInput: inputPayload
|
|
4966
|
+
});
|
|
4967
|
+
stream.submit(
|
|
4968
|
+
{
|
|
4969
|
+
input: inputPayload,
|
|
4970
|
+
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
4971
|
+
},
|
|
4972
|
+
{
|
|
4973
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
4974
|
+
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
4975
|
+
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
4976
|
+
...!nextFollowUpMode ? {
|
|
4977
|
+
optimisticValues: (prev) => {
|
|
4978
|
+
const prevMessages = prev?.messages ?? [];
|
|
4979
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
4980
|
+
}
|
|
4981
|
+
} : {}
|
|
4982
|
+
}
|
|
4983
|
+
);
|
|
4984
|
+
scrollToBottom(true, true);
|
|
4985
|
+
if (selectedTool && !selectedTool.pinned) {
|
|
4986
|
+
setSelectedTool(null);
|
|
4987
|
+
}
|
|
4988
|
+
setAttachments([]);
|
|
4989
|
+
setReferences([]);
|
|
4990
|
+
},
|
|
4991
|
+
[
|
|
4992
|
+
isSendDisabled,
|
|
4993
|
+
options?.request,
|
|
4994
|
+
references,
|
|
4995
|
+
scrollToBottom,
|
|
4996
|
+
selectedTool,
|
|
4997
|
+
stream,
|
|
4998
|
+
trimmedDraft,
|
|
4999
|
+
uploadedFiles,
|
|
5000
|
+
t
|
|
5001
|
+
]
|
|
5002
|
+
);
|
|
3140
5003
|
const handleSubmit = (event) => {
|
|
3141
5004
|
event.preventDefault();
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
const inputPayload = {
|
|
3152
|
-
input: trimmedDraft
|
|
3153
|
-
};
|
|
3154
|
-
if (filesToSend) {
|
|
3155
|
-
inputPayload.files = filesToSend;
|
|
3156
|
-
}
|
|
3157
|
-
const requestOptions = buildInjectedRequestOptions({
|
|
3158
|
-
defaults: options?.request,
|
|
3159
|
-
humanInput: inputPayload
|
|
3160
|
-
});
|
|
3161
|
-
stream.submit(
|
|
3162
|
-
{
|
|
3163
|
-
input: inputPayload,
|
|
3164
|
-
...requestOptions.state ? { state: requestOptions.state } : {}
|
|
3165
|
-
},
|
|
3166
|
-
{
|
|
3167
|
-
...requestOptions.context ? { context: requestOptions.context } : {},
|
|
3168
|
-
...requestOptions.config ? { config: requestOptions.config } : {},
|
|
3169
|
-
optimisticValues: (prev) => {
|
|
3170
|
-
const prevMessages = prev?.messages ?? [];
|
|
3171
|
-
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
3172
|
-
}
|
|
5005
|
+
submitDraft();
|
|
5006
|
+
};
|
|
5007
|
+
const handleEditPendingFollowUp = React22.useCallback(
|
|
5008
|
+
(id) => {
|
|
5009
|
+
const item = pendingFollowUps.find(
|
|
5010
|
+
(entry) => entry.id === id && entry.mode === "queue"
|
|
5011
|
+
);
|
|
5012
|
+
if (!item) {
|
|
5013
|
+
return;
|
|
3173
5014
|
}
|
|
5015
|
+
const text = item.request?.input?.input?.trim() ?? "";
|
|
5016
|
+
const nextReferences = normalizeReferences(
|
|
5017
|
+
item.request?.input?.references
|
|
5018
|
+
);
|
|
5019
|
+
stream.removePendingFollowUp(id);
|
|
5020
|
+
setDraft(text);
|
|
5021
|
+
setReferences(nextReferences);
|
|
5022
|
+
requestAnimationFrame(() => {
|
|
5023
|
+
const input = composerInputRef.current;
|
|
5024
|
+
if (!input) {
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
input.focus();
|
|
5028
|
+
const position = text.length;
|
|
5029
|
+
input.setSelectionRange(position, position);
|
|
5030
|
+
});
|
|
5031
|
+
},
|
|
5032
|
+
[pendingFollowUps, stream]
|
|
5033
|
+
);
|
|
5034
|
+
const handleQuoteSelection = React22.useCallback(() => {
|
|
5035
|
+
if (!quoteSelection) {
|
|
5036
|
+
return;
|
|
5037
|
+
}
|
|
5038
|
+
setReferences(
|
|
5039
|
+
(previous) => mergeReferences(previous, [quoteSelection.reference])
|
|
3174
5040
|
);
|
|
3175
|
-
|
|
3176
|
-
if (
|
|
3177
|
-
|
|
5041
|
+
clearQuoteSelection();
|
|
5042
|
+
if (typeof window !== "undefined") {
|
|
5043
|
+
window.getSelection()?.removeAllRanges();
|
|
3178
5044
|
}
|
|
3179
|
-
|
|
3180
|
-
};
|
|
5045
|
+
composerInputRef.current?.focus();
|
|
5046
|
+
}, [clearQuoteSelection, quoteSelection]);
|
|
3181
5047
|
const handleAttachmentClick = () => {
|
|
3182
5048
|
fileInputRef.current?.click();
|
|
3183
5049
|
};
|
|
3184
|
-
const
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
5050
|
+
const uploadContextFile = React22.useCallback(
|
|
5051
|
+
(file) => stream.client.contexts.uploadFile(file),
|
|
5052
|
+
[stream.client]
|
|
5053
|
+
);
|
|
5054
|
+
const handleComposerKeyDown = (event) => {
|
|
5055
|
+
if (event.key !== "Enter") {
|
|
5056
|
+
return;
|
|
5057
|
+
}
|
|
5058
|
+
if (event.shiftKey) {
|
|
5059
|
+
return;
|
|
5060
|
+
}
|
|
5061
|
+
if (event.nativeEvent.isComposing) {
|
|
5062
|
+
return;
|
|
5063
|
+
}
|
|
5064
|
+
event.preventDefault();
|
|
5065
|
+
if (isSendDisabled) {
|
|
5066
|
+
return;
|
|
5067
|
+
}
|
|
5068
|
+
if (stream.isLoading) {
|
|
5069
|
+
submitDraft(
|
|
5070
|
+
getBusyComposerShortcutFollowUpMode(event.metaKey || event.ctrlKey)
|
|
5071
|
+
);
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
submitDraft();
|
|
5075
|
+
};
|
|
5076
|
+
const handleComposerPaste = React22.useCallback(
|
|
5077
|
+
(event) => {
|
|
5078
|
+
const clipboardData = event.clipboardData;
|
|
5079
|
+
if (!clipboardData) {
|
|
5080
|
+
return;
|
|
5081
|
+
}
|
|
5082
|
+
const imageFiles = Array.from(clipboardData.items).filter(
|
|
5083
|
+
(item) => item.kind === "file" && item.type.startsWith("image/")
|
|
5084
|
+
).map((item) => item.getAsFile()).filter((item) => Boolean(item));
|
|
5085
|
+
if (imageFiles.length > 0) {
|
|
5086
|
+
event.preventDefault();
|
|
5087
|
+
const maxCount = composer?.attachments?.maxCount ?? 10;
|
|
5088
|
+
const maxSize = composer?.attachments?.maxSize ?? 100 * 1024 * 1024;
|
|
5089
|
+
const currentImageReferenceCount = references.filter(
|
|
5090
|
+
(reference) => reference.type === "image"
|
|
5091
|
+
).length;
|
|
5092
|
+
const availableSlots = Math.max(
|
|
5093
|
+
0,
|
|
5094
|
+
maxCount - currentImageReferenceCount
|
|
5095
|
+
);
|
|
5096
|
+
const nextFiles = imageFiles.filter((file) => file.size <= maxSize).slice(0, availableSlots);
|
|
5097
|
+
if (nextFiles.length === 0) {
|
|
5098
|
+
return;
|
|
5099
|
+
}
|
|
5100
|
+
setIsUploadingReferenceImages(true);
|
|
5101
|
+
void Promise.allSettled(
|
|
5102
|
+
nextFiles.map(async (file) => {
|
|
5103
|
+
const [dimensions, storageFile] = await Promise.all([
|
|
5104
|
+
readImageDimensions(file),
|
|
5105
|
+
uploadContextFile(file)
|
|
5106
|
+
]);
|
|
5107
|
+
return buildPastedImageReference(file, storageFile, dimensions);
|
|
5108
|
+
})
|
|
5109
|
+
).then((results) => {
|
|
5110
|
+
const nextReferences = results.filter(
|
|
5111
|
+
(result) => result.status === "fulfilled"
|
|
5112
|
+
).map((result) => result.value);
|
|
5113
|
+
if (nextReferences.length > 0) {
|
|
5114
|
+
setReferences(
|
|
5115
|
+
(previous) => mergeReferences(previous, nextReferences)
|
|
5116
|
+
);
|
|
5117
|
+
composerInputRef.current?.focus();
|
|
5118
|
+
}
|
|
5119
|
+
results.filter(
|
|
5120
|
+
(result) => result.status === "rejected"
|
|
5121
|
+
).forEach((result) => {
|
|
5122
|
+
console.warn(
|
|
5123
|
+
"[Chat] Failed to upload pasted image reference:",
|
|
5124
|
+
result.reason
|
|
5125
|
+
);
|
|
5126
|
+
});
|
|
5127
|
+
}).finally(() => {
|
|
5128
|
+
setIsUploadingReferenceImages(false);
|
|
5129
|
+
});
|
|
5130
|
+
return;
|
|
5131
|
+
}
|
|
5132
|
+
const pastedText = clipboardData.getData("text/plain");
|
|
5133
|
+
if (pastedText.trim().length <= LONG_TEXT_REFERENCE_THRESHOLD) {
|
|
5134
|
+
return;
|
|
5135
|
+
}
|
|
5136
|
+
event.preventDefault();
|
|
5137
|
+
setReferences(
|
|
5138
|
+
(previous) => mergeReferences(previous, [
|
|
5139
|
+
{
|
|
5140
|
+
type: "quote",
|
|
5141
|
+
source: "Pasted text",
|
|
5142
|
+
text: pastedText
|
|
5143
|
+
}
|
|
5144
|
+
])
|
|
3191
5145
|
);
|
|
3192
|
-
|
|
5146
|
+
composerInputRef.current?.focus();
|
|
5147
|
+
},
|
|
5148
|
+
[
|
|
5149
|
+
composer?.attachments?.maxCount,
|
|
5150
|
+
composer?.attachments?.maxSize,
|
|
5151
|
+
references,
|
|
5152
|
+
uploadContextFile
|
|
5153
|
+
]
|
|
5154
|
+
);
|
|
5155
|
+
const alternateFollowUpShortcutLabel = React22.useMemo(() => {
|
|
5156
|
+
if (typeof navigator === "undefined") {
|
|
5157
|
+
return "\u2318Enter";
|
|
5158
|
+
}
|
|
5159
|
+
const platform = navigator.platform || navigator.userAgent;
|
|
5160
|
+
return /Mac|iPhone|iPad|iPod/i.test(platform) ? "\u2318Enter" : "Ctrl+Enter";
|
|
5161
|
+
}, []);
|
|
5162
|
+
const followUpShortcutLabels = React22.useMemo(
|
|
5163
|
+
() => getComposerFollowUpShortcutLabels(alternateFollowUpShortcutLabel),
|
|
5164
|
+
[alternateFollowUpShortcutLabel]
|
|
5165
|
+
);
|
|
5166
|
+
const uploadFile = React22.useCallback(
|
|
5167
|
+
async (localId, file) => {
|
|
5168
|
+
try {
|
|
5169
|
+
const result = await uploadContextFile(file);
|
|
5170
|
+
setAttachments(
|
|
5171
|
+
(prev) => prev.map(
|
|
5172
|
+
(item) => item.localId === localId ? { ...item, status: "success", storageFile: result } : item
|
|
5173
|
+
)
|
|
5174
|
+
);
|
|
5175
|
+
} catch (error) {
|
|
5176
|
+
setAttachments(
|
|
5177
|
+
(prev) => prev.map(
|
|
5178
|
+
(item) => item.localId === localId ? {
|
|
5179
|
+
...item,
|
|
5180
|
+
status: "error",
|
|
5181
|
+
error: error instanceof Error ? error.message : "Upload failed"
|
|
5182
|
+
} : item
|
|
5183
|
+
)
|
|
5184
|
+
);
|
|
5185
|
+
}
|
|
5186
|
+
},
|
|
5187
|
+
[uploadContextFile]
|
|
5188
|
+
);
|
|
5189
|
+
const handleRetryUpload = React22.useCallback(
|
|
5190
|
+
(localId) => {
|
|
5191
|
+
const attachment = attachments.find((a) => a.localId === localId);
|
|
5192
|
+
if (!attachment || attachment.status !== "error") return;
|
|
3193
5193
|
setAttachments(
|
|
3194
5194
|
(prev) => prev.map(
|
|
3195
|
-
(item) => item.localId === localId ? {
|
|
3196
|
-
...item,
|
|
3197
|
-
status: "error",
|
|
3198
|
-
error: error instanceof Error ? error.message : "Upload failed"
|
|
3199
|
-
} : item
|
|
5195
|
+
(item) => item.localId === localId ? { ...item, status: "uploading", error: void 0 } : item
|
|
3200
5196
|
)
|
|
3201
5197
|
);
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
if (!attachment || attachment.status !== "error") return;
|
|
3207
|
-
setAttachments(
|
|
3208
|
-
(prev) => prev.map(
|
|
3209
|
-
(item) => item.localId === localId ? { ...item, status: "uploading", error: void 0 } : item
|
|
3210
|
-
)
|
|
3211
|
-
);
|
|
3212
|
-
void uploadFile(localId, attachment.file);
|
|
3213
|
-
}, [attachments, uploadFile]);
|
|
5198
|
+
void uploadFile(localId, attachment.file);
|
|
5199
|
+
},
|
|
5200
|
+
[attachments, uploadFile]
|
|
5201
|
+
);
|
|
3214
5202
|
const handleFileChange = (event) => {
|
|
3215
5203
|
const files = event.target.files;
|
|
3216
5204
|
if (!files || files.length === 0) return;
|
|
@@ -3244,12 +5232,15 @@ function Chat({
|
|
|
3244
5232
|
if (!attachment) return;
|
|
3245
5233
|
if (attachment.status === "success" && attachment.storageFile?.id) {
|
|
3246
5234
|
try {
|
|
3247
|
-
await fetch(
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
"
|
|
5235
|
+
await fetch(
|
|
5236
|
+
`${stream.apiUrl}/contexts/file/${attachment.storageFile.id}`,
|
|
5237
|
+
{
|
|
5238
|
+
method: "DELETE",
|
|
5239
|
+
headers: {
|
|
5240
|
+
Authorization: `Bearer ${effectiveClientSecret}`
|
|
5241
|
+
}
|
|
3251
5242
|
}
|
|
3252
|
-
|
|
5243
|
+
);
|
|
3253
5244
|
} catch {
|
|
3254
5245
|
}
|
|
3255
5246
|
}
|
|
@@ -3259,27 +5250,31 @@ function Chat({
|
|
|
3259
5250
|
setSelectedTool((prev) => prev?.id === tool.id ? null : tool);
|
|
3260
5251
|
};
|
|
3261
5252
|
const handlePromptClick = (prompt) => {
|
|
3262
|
-
if (missingConfig ||
|
|
5253
|
+
if (missingConfig || isHistoryLoading) return;
|
|
3263
5254
|
const newMessage = {
|
|
3264
5255
|
id: createMessageId(),
|
|
3265
5256
|
type: "human",
|
|
3266
5257
|
content: prompt
|
|
3267
5258
|
};
|
|
5259
|
+
const nextFollowUpMode = stream.isLoading ? stream.followUpBehavior : void 0;
|
|
3268
5260
|
stream.submit(
|
|
3269
5261
|
{ input: { input: prompt } },
|
|
3270
5262
|
{
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
5263
|
+
...nextFollowUpMode ? { followUpMode: nextFollowUpMode } : {},
|
|
5264
|
+
...!nextFollowUpMode ? {
|
|
5265
|
+
optimisticValues: (prev) => {
|
|
5266
|
+
const prevMessages = prev?.messages ?? [];
|
|
5267
|
+
return { ...prev, messages: [...prevMessages, newMessage] };
|
|
5268
|
+
}
|
|
5269
|
+
} : {}
|
|
3275
5270
|
}
|
|
3276
5271
|
);
|
|
3277
5272
|
scrollToBottom(true, true);
|
|
3278
5273
|
};
|
|
3279
|
-
const loadConversationMessages =
|
|
5274
|
+
const loadConversationMessages = React22.useCallback(
|
|
3280
5275
|
async (recordId) => {
|
|
3281
5276
|
if (missingConfig) {
|
|
3282
|
-
setHistoryError(
|
|
5277
|
+
setHistoryError(missingConfigShortMessage);
|
|
3283
5278
|
return;
|
|
3284
5279
|
}
|
|
3285
5280
|
setHistoryError(null);
|
|
@@ -3295,7 +5290,7 @@ function Chat({
|
|
|
3295
5290
|
setIsHistoryLoading(false);
|
|
3296
5291
|
}
|
|
3297
5292
|
},
|
|
3298
|
-
[missingConfig, stream, t]
|
|
5293
|
+
[missingConfig, missingConfigShortMessage, stream, t]
|
|
3299
5294
|
);
|
|
3300
5295
|
const handleNewThread = async () => {
|
|
3301
5296
|
if (missingConfig || isHistoryLoading) return;
|
|
@@ -3338,12 +5333,16 @@ function Chat({
|
|
|
3338
5333
|
};
|
|
3339
5334
|
const handleRetry = (messageIndex) => {
|
|
3340
5335
|
const messagesUpToIndex = messages.slice(0, messageIndex);
|
|
3341
|
-
const lastHumanMessage = [...messagesUpToIndex].reverse().find(
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
5336
|
+
const lastHumanMessage = [...messagesUpToIndex].reverse().find((m) => String(m.type) === "human");
|
|
5337
|
+
const humanInput = buildHumanMessageInputPayload({
|
|
5338
|
+
content: lastHumanMessage && typeof lastHumanMessage.content === "string" ? lastHumanMessage.content : "",
|
|
5339
|
+
submittedInput: lastHumanMessage?.submittedInput,
|
|
5340
|
+
references: lastHumanMessage?.references,
|
|
5341
|
+
referenceComposition: lastHumanMessage?.referenceComposition
|
|
5342
|
+
});
|
|
5343
|
+
if (humanInput) {
|
|
3345
5344
|
stream.submit(
|
|
3346
|
-
{ input:
|
|
5345
|
+
{ input: humanInput },
|
|
3347
5346
|
{
|
|
3348
5347
|
optimisticValues: (prev) => {
|
|
3349
5348
|
const prevMessages = prev?.messages ?? [];
|
|
@@ -3358,18 +5357,18 @@ function Chat({
|
|
|
3358
5357
|
}
|
|
3359
5358
|
};
|
|
3360
5359
|
const acceptMimes = composer?.attachments?.accept ? Object.entries(composer.attachments.accept).map(([mime, exts]) => [mime, ...exts.map((e) => `.${e}`)].join(",")).join(",") : void 0;
|
|
3361
|
-
const currentThread =
|
|
5360
|
+
const currentThread = React22.useMemo(
|
|
3362
5361
|
() => threads.find((item) => item.id === stream.threadId),
|
|
3363
5362
|
[threads, stream.threadId]
|
|
3364
5363
|
);
|
|
3365
5364
|
const errorMessage = stream.error instanceof Error ? stream.error.message : void 0;
|
|
3366
|
-
const threadErrorMessage =
|
|
5365
|
+
const threadErrorMessage = React22.useMemo(() => {
|
|
3367
5366
|
if (currentThread?.status !== "error") return void 0;
|
|
3368
5367
|
const message = currentThread.error?.trim();
|
|
3369
5368
|
return message || t("thread.errorToast");
|
|
3370
5369
|
}, [currentThread, t]);
|
|
3371
5370
|
const assistantTitle = assistantName || resolvedTitle;
|
|
3372
|
-
return /* @__PURE__ */ (0,
|
|
5371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3373
5372
|
"div",
|
|
3374
5373
|
{
|
|
3375
5374
|
ref: viewportRef,
|
|
@@ -3378,10 +5377,10 @@ function Chat({
|
|
|
3378
5377
|
className
|
|
3379
5378
|
),
|
|
3380
5379
|
children: [
|
|
3381
|
-
/* @__PURE__ */ (0,
|
|
3382
|
-
/* @__PURE__ */ (0,
|
|
3383
|
-
/* @__PURE__ */ (0,
|
|
3384
|
-
/* @__PURE__ */ (0,
|
|
5380
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between border-b p-2 sticky top-0 z-10 bg-background", children: [
|
|
5381
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-3 overflow-hidden", children: [
|
|
5382
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative shrink-0", children: [
|
|
5383
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3385
5384
|
ChatkitAvatar,
|
|
3386
5385
|
{
|
|
3387
5386
|
avatar: assistantAvatar,
|
|
@@ -3389,15 +5388,22 @@ function Chat({
|
|
|
3389
5388
|
label: assistantTitle
|
|
3390
5389
|
}
|
|
3391
5390
|
),
|
|
3392
|
-
/* @__PURE__ */ (0,
|
|
5391
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "absolute bottom-0 right-0 h-2.5 w-2.5 rounded-full border-2 border-background bg-green-500" })
|
|
3393
5392
|
] }),
|
|
3394
|
-
/* @__PURE__ */ (0,
|
|
3395
|
-
/* @__PURE__ */ (0,
|
|
3396
|
-
|
|
5393
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "truncate", children: [
|
|
5394
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5395
|
+
"h2",
|
|
5396
|
+
{
|
|
5397
|
+
className: "text-lg font-semibold truncate",
|
|
5398
|
+
title: assistantTitle,
|
|
5399
|
+
children: assistantTitle
|
|
5400
|
+
}
|
|
5401
|
+
),
|
|
5402
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "text-xs text-muted-foreground", children: t("chat.statusOnline") })
|
|
3397
5403
|
] })
|
|
3398
5404
|
] }),
|
|
3399
|
-
history?.enabled !== false && /* @__PURE__ */ (0,
|
|
3400
|
-
/* @__PURE__ */ (0,
|
|
5405
|
+
history?.enabled !== false && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3401
5407
|
"button",
|
|
3402
5408
|
{
|
|
3403
5409
|
type: "button",
|
|
@@ -3410,10 +5416,10 @@ function Chat({
|
|
|
3410
5416
|
"disabled:opacity-50 disabled:cursor-not-allowed"
|
|
3411
5417
|
),
|
|
3412
5418
|
title: t("history.newThread"),
|
|
3413
|
-
children: /* @__PURE__ */ (0,
|
|
5419
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.Pencil, { size: 16 })
|
|
3414
5420
|
}
|
|
3415
5421
|
),
|
|
3416
|
-
/* @__PURE__ */ (0,
|
|
5422
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3417
5423
|
HistorySidebar,
|
|
3418
5424
|
{
|
|
3419
5425
|
threads,
|
|
@@ -3427,23 +5433,45 @@ function Chat({
|
|
|
3427
5433
|
)
|
|
3428
5434
|
] })
|
|
3429
5435
|
] }),
|
|
3430
|
-
/* @__PURE__ */ (0,
|
|
3431
|
-
errorMessage && /* @__PURE__ */ (0,
|
|
3432
|
-
historyError && /* @__PURE__ */ (0,
|
|
3433
|
-
showMissingConfig && /* @__PURE__ */ (0,
|
|
3434
|
-
isHistoryLoading && /* @__PURE__ */ (0,
|
|
3435
|
-
messages.length === 0 ? /* @__PURE__ */ (0,
|
|
5436
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex-1 p-4", children: [
|
|
5437
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-4 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive", children: errorMessage }),
|
|
5438
|
+
historyError && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: historyError }),
|
|
5439
|
+
showMissingConfig && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-4 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-900", children: missingConfigDetailMessage }),
|
|
5440
|
+
isHistoryLoading && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-4 rounded-lg border border-muted px-3 py-2 text-sm text-muted-foreground", children: t("chat.loadingThread") }),
|
|
5441
|
+
messages.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3436
5442
|
StartScreen,
|
|
3437
5443
|
{
|
|
3438
5444
|
startScreen,
|
|
3439
5445
|
onPromptClick: handlePromptClick
|
|
3440
5446
|
}
|
|
3441
|
-
) : /* @__PURE__ */ (0,
|
|
5447
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "space-y-4", children: [
|
|
3442
5448
|
messages.map((message, index) => {
|
|
3443
5449
|
const messageType = String(message.type);
|
|
3444
5450
|
const isAssistantMessage = messageType === "assistant" || messageType === "ai";
|
|
5451
|
+
const isStreamingMessage = stream.isLoading && index === messages.length - 1;
|
|
5452
|
+
const streamingStatus = isAssistantMessage ? getAssistantStreamingStatus(
|
|
5453
|
+
{
|
|
5454
|
+
...message,
|
|
5455
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5456
|
+
},
|
|
5457
|
+
isStreamingMessage,
|
|
5458
|
+
{ now: streamingNow }
|
|
5459
|
+
) : null;
|
|
5460
|
+
if (isAssistantMessage && !hasRenderableAssistantMessage(message) && !streamingStatus) {
|
|
5461
|
+
return null;
|
|
5462
|
+
}
|
|
3445
5463
|
const messageContent = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.map((part) => formatMessageContent(part)).join("") : formatMessageContent(message.content);
|
|
3446
|
-
|
|
5464
|
+
const hasPlainRenderableContent = messageContent.trim().length > 0;
|
|
5465
|
+
const humanMessage = message;
|
|
5466
|
+
const humanReferences = humanMessage.references ?? [];
|
|
5467
|
+
const humanAttachments = humanMessage.attachments ?? [];
|
|
5468
|
+
const hasHumanAttachments = message.type === "human" && humanAttachments.length > 0;
|
|
5469
|
+
const canQuoteMessage = message.type === "human" || isAssistantMessage;
|
|
5470
|
+
const quoteSource = message.type === "human" ? t("chat.youLabel") : assistantTitle;
|
|
5471
|
+
if (!isAssistantMessage && !hasPlainRenderableContent && !hasHumanAttachments && humanReferences.length === 0) {
|
|
5472
|
+
return null;
|
|
5473
|
+
}
|
|
5474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3447
5475
|
"div",
|
|
3448
5476
|
{
|
|
3449
5477
|
className: cn(
|
|
@@ -3451,53 +5479,66 @@ function Chat({
|
|
|
3451
5479
|
message.type === "human" ? "justify-end" : "justify-start -ml-1"
|
|
3452
5480
|
// AI messages: slightly closer to left
|
|
3453
5481
|
),
|
|
3454
|
-
children: /* @__PURE__ */ (0,
|
|
3455
|
-
/* @__PURE__ */ (0,
|
|
5482
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex flex-col px-3 overflow-hidden", children: [
|
|
5483
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3456
5484
|
"div",
|
|
3457
5485
|
{
|
|
5486
|
+
...canQuoteMessage ? {
|
|
5487
|
+
"data-quote-message-id": message.id,
|
|
5488
|
+
"data-quote-source": quoteSource
|
|
5489
|
+
} : {},
|
|
3458
5490
|
className: cn(
|
|
3459
5491
|
"max-w-full rounded-2xl",
|
|
3460
5492
|
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"
|
|
3461
5493
|
// AI messages: use chat-specific foreground color
|
|
3462
5494
|
),
|
|
3463
|
-
children: isAssistantMessage ? /* @__PURE__ */ (0,
|
|
5495
|
+
children: isAssistantMessage ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3464
5496
|
AssistantMessage,
|
|
3465
5497
|
{
|
|
3466
5498
|
message: {
|
|
3467
5499
|
...message,
|
|
3468
5500
|
type: "assistant"
|
|
3469
5501
|
},
|
|
3470
|
-
isStreaming:
|
|
5502
|
+
isStreaming: isStreamingMessage,
|
|
5503
|
+
streamingStatus
|
|
3471
5504
|
}
|
|
3472
|
-
) : /* @__PURE__ */ (0,
|
|
3473
|
-
message.type === "human" &&
|
|
5505
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
5506
|
+
message.type === "human" && humanReferences.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-2 flex flex-wrap gap-1.5", children: humanReferences.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5507
|
+
ReferenceChip,
|
|
5508
|
+
{
|
|
5509
|
+
reference,
|
|
5510
|
+
variant: "message"
|
|
5511
|
+
},
|
|
5512
|
+
getReferenceKey(reference)
|
|
5513
|
+
)) }),
|
|
5514
|
+
message.type === "human" && humanAttachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex flex-wrap gap-1.5 mb-2", children: humanAttachments.map((file, fileIndex) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3474
5515
|
"div",
|
|
3475
5516
|
{
|
|
3476
5517
|
className: "flex items-center gap-1.5 rounded-md bg-primary-foreground/20 px-2 py-1 text-xs",
|
|
3477
5518
|
children: [
|
|
3478
|
-
/* @__PURE__ */ (0,
|
|
3479
|
-
/* @__PURE__ */ (0,
|
|
5519
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.FileText, { size: 12 }),
|
|
5520
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "max-w-[100px] truncate", children: file.originalName })
|
|
3480
5521
|
]
|
|
3481
5522
|
},
|
|
3482
5523
|
fileIndex
|
|
3483
5524
|
)) }),
|
|
3484
|
-
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0,
|
|
5525
|
+
Array.isArray(message.content) ? message.content.map((part, partIndex) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3485
5526
|
"p",
|
|
3486
5527
|
{
|
|
3487
5528
|
className: "wrap-break-word text-sm leading-relaxed",
|
|
3488
5529
|
children: formatMessageContent(part)
|
|
3489
5530
|
},
|
|
3490
5531
|
`${part.type}-${partIndex}`
|
|
3491
|
-
)) : /* @__PURE__ */ (0,
|
|
5532
|
+
)) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "wrap-break-word text-sm leading-relaxed", children: formatMessageContent(message.content) })
|
|
3492
5533
|
] })
|
|
3493
5534
|
}
|
|
3494
5535
|
),
|
|
3495
|
-
/* @__PURE__ */ (0,
|
|
5536
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3496
5537
|
MessageActions,
|
|
3497
5538
|
{
|
|
3498
5539
|
content: messageContent,
|
|
3499
5540
|
isAssistant: isAssistantMessage,
|
|
3500
|
-
isStreaming:
|
|
5541
|
+
isStreaming: isStreamingMessage,
|
|
3501
5542
|
onRetry: isAssistantMessage && !stream.isLoading && index === messages.length - 1 ? () => handleRetry(index) : void 0
|
|
3502
5543
|
}
|
|
3503
5544
|
)
|
|
@@ -3510,18 +5551,34 @@ function Chat({
|
|
|
3510
5551
|
const lastMessage = messages[messages.length - 1];
|
|
3511
5552
|
const lastMessageType = lastMessage ? String(lastMessage.type) : "";
|
|
3512
5553
|
const isLastMessageFromAI = lastMessageType === "ai" || lastMessageType === "assistant";
|
|
3513
|
-
const
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
5554
|
+
const lastAssistantStatus = isLastMessageFromAI ? getAssistantStreamingStatus(
|
|
5555
|
+
{
|
|
5556
|
+
...lastMessage,
|
|
5557
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5558
|
+
},
|
|
5559
|
+
stream.isLoading,
|
|
5560
|
+
{ now: streamingNow }
|
|
5561
|
+
) : null;
|
|
5562
|
+
if (lastAssistantStatus) return null;
|
|
5563
|
+
const fallbackStreamingStatus = getAssistantStreamingStatus(
|
|
5564
|
+
{
|
|
5565
|
+
status: void 0,
|
|
5566
|
+
reasoning: void 0,
|
|
5567
|
+
lastStreamOutputAt: lastStreamOutputAtRef.current
|
|
5568
|
+
},
|
|
5569
|
+
stream.isLoading,
|
|
5570
|
+
{ now: streamingNow }
|
|
5571
|
+
);
|
|
5572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "flex justify-start gap-3 -ml-2", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "max-w-full rounded-2xl py-2.5", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5573
|
+
AssistantStreamingIndicator,
|
|
5574
|
+
{
|
|
5575
|
+
status: fallbackStreamingStatus ?? "loading"
|
|
5576
|
+
}
|
|
5577
|
+
) }) });
|
|
3521
5578
|
})()
|
|
3522
5579
|
] })
|
|
3523
5580
|
] }),
|
|
3524
|
-
!isAtBottom && messages.length > 0 && /* @__PURE__ */ (0,
|
|
5581
|
+
!isAtBottom && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "sticky bottom-20 z-20 flex justify-center px-4 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3525
5582
|
Button,
|
|
3526
5583
|
{
|
|
3527
5584
|
type: "button",
|
|
@@ -3534,12 +5591,40 @@ function Chat({
|
|
|
3534
5591
|
onClick: () => scrollToBottom(true, true),
|
|
3535
5592
|
"aria-label": t("chat.scrollToBottom"),
|
|
3536
5593
|
title: t("chat.scrollToBottom"),
|
|
3537
|
-
children: /* @__PURE__ */ (0,
|
|
5594
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.ArrowDown, { size: 16 })
|
|
3538
5595
|
}
|
|
3539
5596
|
) }),
|
|
3540
|
-
/* @__PURE__ */ (0,
|
|
3541
|
-
|
|
3542
|
-
|
|
5597
|
+
quoteSelection && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5598
|
+
"div",
|
|
5599
|
+
{
|
|
5600
|
+
className: "pointer-events-none fixed z-50",
|
|
5601
|
+
style: {
|
|
5602
|
+
top: `${quoteSelection.top}px`,
|
|
5603
|
+
left: `${quoteSelection.left}px`,
|
|
5604
|
+
transform: "translateX(-50%)"
|
|
5605
|
+
},
|
|
5606
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
5607
|
+
Button,
|
|
5608
|
+
{
|
|
5609
|
+
type: "button",
|
|
5610
|
+
size: "sm",
|
|
5611
|
+
variant: "secondary",
|
|
5612
|
+
className: "pointer-events-auto shadow-lg",
|
|
5613
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
5614
|
+
onClick: handleQuoteSelection,
|
|
5615
|
+
"aria-label": t("composer.quoteSelection"),
|
|
5616
|
+
title: t("composer.quoteSelection"),
|
|
5617
|
+
children: [
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.Quote, { size: 14 }),
|
|
5619
|
+
t("composer.quoteSelection")
|
|
5620
|
+
]
|
|
5621
|
+
}
|
|
5622
|
+
)
|
|
5623
|
+
}
|
|
5624
|
+
),
|
|
5625
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "p-2 sticky bottom-0 z-10 bg-background", children: [
|
|
5626
|
+
threadErrorMessage && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-3 rounded-lg border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm text-destructive overflow-auto", children: threadErrorMessage }),
|
|
5627
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3543
5628
|
"input",
|
|
3544
5629
|
{
|
|
3545
5630
|
ref: fileInputRef,
|
|
@@ -3550,7 +5635,7 @@ function Chat({
|
|
|
3550
5635
|
className: "hidden"
|
|
3551
5636
|
}
|
|
3552
5637
|
),
|
|
3553
|
-
attachments.length > 0 && /* @__PURE__ */ (0,
|
|
5638
|
+
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: attachments.map((item) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3554
5639
|
"div",
|
|
3555
5640
|
{
|
|
3556
5641
|
className: cn(
|
|
@@ -3558,24 +5643,36 @@ function Chat({
|
|
|
3558
5643
|
item.status === "error" ? "bg-destructive/10 border border-destructive/30" : "bg-muted"
|
|
3559
5644
|
),
|
|
3560
5645
|
children: [
|
|
3561
|
-
item.status === "uploading" && /* @__PURE__ */ (0,
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
),
|
|
3568
|
-
item.status === "
|
|
5646
|
+
item.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5647
|
+
import_lucide_react11.Loader2,
|
|
5648
|
+
{
|
|
5649
|
+
size: 14,
|
|
5650
|
+
className: "animate-spin text-muted-foreground"
|
|
5651
|
+
}
|
|
5652
|
+
),
|
|
5653
|
+
item.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.FileText, { size: 14, className: "text-muted-foreground" }),
|
|
5654
|
+
item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.FileText, { size: 14, className: "text-destructive" }),
|
|
5655
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5656
|
+
"span",
|
|
5657
|
+
{
|
|
5658
|
+
className: cn(
|
|
5659
|
+
"max-w-30 truncate",
|
|
5660
|
+
item.status === "error" && "text-destructive"
|
|
5661
|
+
),
|
|
5662
|
+
children: item.file.name
|
|
5663
|
+
}
|
|
5664
|
+
),
|
|
5665
|
+
item.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3569
5666
|
"button",
|
|
3570
5667
|
{
|
|
3571
5668
|
type: "button",
|
|
3572
5669
|
onClick: () => handleRetryUpload(item.localId),
|
|
3573
5670
|
className: "ml-1 rounded-full p-0.5 text-destructive hover:bg-destructive/20",
|
|
3574
5671
|
title: t("chat.retryUpload"),
|
|
3575
|
-
children: /* @__PURE__ */ (0,
|
|
5672
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.RefreshCw, { size: 12 })
|
|
3576
5673
|
}
|
|
3577
5674
|
),
|
|
3578
|
-
/* @__PURE__ */ (0,
|
|
5675
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3579
5676
|
"button",
|
|
3580
5677
|
{
|
|
3581
5678
|
type: "button",
|
|
@@ -3584,76 +5681,118 @@ function Chat({
|
|
|
3584
5681
|
"ml-1 rounded-full p-0.5",
|
|
3585
5682
|
item.status === "error" ? "text-destructive hover:bg-destructive/20" : "hover:bg-muted-foreground/20"
|
|
3586
5683
|
),
|
|
3587
|
-
children: /* @__PURE__ */ (0,
|
|
5684
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.X, { size: 12 })
|
|
3588
5685
|
}
|
|
3589
5686
|
)
|
|
3590
5687
|
]
|
|
3591
5688
|
},
|
|
3592
5689
|
item.localId
|
|
3593
5690
|
)) }),
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
5691
|
+
references.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mb-3 flex flex-wrap gap-2", children: references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5692
|
+
ReferenceChip,
|
|
5693
|
+
{
|
|
5694
|
+
reference,
|
|
5695
|
+
variant: "composer",
|
|
5696
|
+
onRemove: () => setReferences(
|
|
5697
|
+
(previous) => previous.filter(
|
|
5698
|
+
(item) => getReferenceKey(item) !== getReferenceKey(reference)
|
|
5699
|
+
)
|
|
5700
|
+
),
|
|
5701
|
+
removeLabel: t("composer.removeReference")
|
|
5702
|
+
},
|
|
5703
|
+
getReferenceKey(reference)
|
|
5704
|
+
)) }),
|
|
5705
|
+
selectedTool && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary", children: selectedTool.shortLabel ?? selectedTool.label }),
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3597
5708
|
"button",
|
|
3598
5709
|
{
|
|
3599
5710
|
type: "button",
|
|
3600
5711
|
onClick: () => setSelectedTool(null),
|
|
3601
5712
|
className: "rounded-full p-0.5 text-muted-foreground hover:bg-muted",
|
|
3602
|
-
children: /* @__PURE__ */ (0,
|
|
5713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react11.X, { size: 12 })
|
|
3603
5714
|
}
|
|
3604
5715
|
)
|
|
3605
5716
|
] }),
|
|
3606
|
-
/* @__PURE__ */ (0,
|
|
5717
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5718
|
+
PendingFollowUps,
|
|
5719
|
+
{
|
|
5720
|
+
items: pendingFollowUps,
|
|
5721
|
+
isLoading: stream.isLoading,
|
|
5722
|
+
followUpBehavior: stream.followUpBehavior,
|
|
5723
|
+
onBehaviorChange: stream.setFollowUpBehavior,
|
|
5724
|
+
onPromoteToSteer: (id) => stream.promotePendingFollowUpToSteer(id),
|
|
5725
|
+
canSendNow: stream.canSendPendingFollowUpNow,
|
|
5726
|
+
onSendNow: (id) => stream.sendPendingFollowUpNow(id),
|
|
5727
|
+
onEdit: handleEditPendingFollowUp,
|
|
5728
|
+
onRemove: stream.removePendingFollowUp
|
|
5729
|
+
}
|
|
5730
|
+
),
|
|
5731
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("form", { className: "flex items-end", onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3607
5732
|
"div",
|
|
3608
5733
|
{
|
|
3609
5734
|
className: cn(
|
|
3610
|
-
"flex flex-1 items-
|
|
5735
|
+
"flex flex-1 items-end gap-1 rounded-xl",
|
|
3611
5736
|
"bg-background border border-border shadow-sm",
|
|
3612
5737
|
"pl-1.5 pr-1.5 py-1",
|
|
3613
5738
|
"focus-within:border-muted-foreground/30 focus-within:shadow-md",
|
|
3614
|
-
"transition-shadow duration-200"
|
|
5739
|
+
"transition-shadow duration-200",
|
|
5740
|
+
getRoundedClass(theme.radius)
|
|
3615
5741
|
),
|
|
3616
5742
|
children: [
|
|
3617
|
-
/* @__PURE__ */ (0,
|
|
5743
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3618
5744
|
ComposerMenu,
|
|
3619
5745
|
{
|
|
3620
5746
|
composer,
|
|
3621
5747
|
onAttachmentClick: handleAttachmentClick,
|
|
3622
5748
|
onToolSelect: handleToolSelect,
|
|
3623
5749
|
selectedTool,
|
|
3624
|
-
disabled:
|
|
5750
|
+
disabled: missingConfig || isHistoryLoading
|
|
3625
5751
|
}
|
|
3626
5752
|
),
|
|
3627
|
-
/* @__PURE__ */ (0,
|
|
3628
|
-
"
|
|
5753
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
5754
|
+
"textarea",
|
|
3629
5755
|
{
|
|
3630
|
-
|
|
5756
|
+
ref: composerInputRef,
|
|
3631
5757
|
value: draft,
|
|
3632
5758
|
onChange: (event) => setDraft(event.target.value),
|
|
5759
|
+
onPaste: handleComposerPaste,
|
|
5760
|
+
onKeyDown: handleComposerKeyDown,
|
|
5761
|
+
rows: 1,
|
|
3633
5762
|
placeholder: inputPlaceholder,
|
|
3634
|
-
disabled:
|
|
5763
|
+
disabled: missingConfig || isHistoryLoading,
|
|
3635
5764
|
className: cn(
|
|
3636
|
-
"flex-1 bg-transparent text-sm text-foreground outline-none
|
|
5765
|
+
"min-h-8 max-h-32 flex-1 resize-none bg-transparent py-1 pr-2 text-sm leading-5 text-foreground outline-none",
|
|
3637
5766
|
"placeholder:text-muted-foreground",
|
|
3638
5767
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
|
3639
|
-
)
|
|
3640
|
-
autoComplete: "off"
|
|
5768
|
+
)
|
|
3641
5769
|
}
|
|
3642
5770
|
),
|
|
3643
|
-
/* @__PURE__ */ (0,
|
|
5771
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3644
5772
|
SendButton,
|
|
3645
5773
|
{
|
|
3646
5774
|
disabled: isSendDisabled,
|
|
3647
5775
|
isLoading: stream.isLoading,
|
|
5776
|
+
showStop: stream.isLoading && !trimmedDraft,
|
|
3648
5777
|
onStop: () => stream.stop(),
|
|
3649
5778
|
stopLabel: t("chat.stop"),
|
|
3650
|
-
sendLabel: t("chat.send")
|
|
5779
|
+
sendLabel: t("chat.send"),
|
|
5780
|
+
shortcuts: stream.isLoading && trimmedDraft ? [
|
|
5781
|
+
{
|
|
5782
|
+
label: t("chat.followUps.steer"),
|
|
5783
|
+
keys: followUpShortcutLabels.steer
|
|
5784
|
+
},
|
|
5785
|
+
{
|
|
5786
|
+
label: t("chat.followUps.queue"),
|
|
5787
|
+
keys: followUpShortcutLabels.queue
|
|
5788
|
+
}
|
|
5789
|
+
] : void 0
|
|
3651
5790
|
}
|
|
3652
5791
|
)
|
|
3653
5792
|
]
|
|
3654
5793
|
}
|
|
3655
5794
|
) }),
|
|
3656
|
-
disclaimer?.text && /* @__PURE__ */ (0,
|
|
5795
|
+
disclaimer?.text && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3657
5796
|
"p",
|
|
3658
5797
|
{
|
|
3659
5798
|
className: cn(
|
|
@@ -3663,9 +5802,9 @@ function Chat({
|
|
|
3663
5802
|
children: disclaimer.text
|
|
3664
5803
|
}
|
|
3665
5804
|
),
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
3667
|
-
/* @__PURE__ */ (0,
|
|
3668
|
-
/* @__PURE__ */ (0,
|
|
5805
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mt-2 flex items-center justify-center gap-2 text-xs text-muted-foreground", children: [
|
|
5806
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: t("chat.poweredBy") }),
|
|
5807
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ContextUsageIndicator, { className: "absolute right-4" })
|
|
3669
5808
|
] })
|
|
3670
5809
|
] })
|
|
3671
5810
|
]
|
|
@@ -3674,11 +5813,11 @@ function Chat({
|
|
|
3674
5813
|
}
|
|
3675
5814
|
|
|
3676
5815
|
// src/components/ui/input.tsx
|
|
3677
|
-
var
|
|
3678
|
-
var
|
|
3679
|
-
var Input =
|
|
5816
|
+
var React23 = __toESM(require("react"), 1);
|
|
5817
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
5818
|
+
var Input = React23.forwardRef(
|
|
3680
5819
|
({ className, type, ...props }, ref) => {
|
|
3681
|
-
return /* @__PURE__ */ (0,
|
|
5820
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3682
5821
|
"input",
|
|
3683
5822
|
{
|
|
3684
5823
|
ref,
|
|
@@ -3695,10 +5834,10 @@ var Input = React21.forwardRef(
|
|
|
3695
5834
|
Input.displayName = "Input";
|
|
3696
5835
|
|
|
3697
5836
|
// src/components/ui/separator.tsx
|
|
3698
|
-
var
|
|
3699
|
-
var
|
|
3700
|
-
var Separator =
|
|
3701
|
-
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0,
|
|
5837
|
+
var React24 = __toESM(require("react"), 1);
|
|
5838
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
5839
|
+
var Separator = React24.forwardRef(
|
|
5840
|
+
({ className, orientation = "horizontal", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3702
5841
|
"div",
|
|
3703
5842
|
{
|
|
3704
5843
|
ref,
|