onbuzz 3.9.10 → 4.0.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/package.json +1 -1
- package/src/core/__tests__/agentPool.test.js +60 -0
- package/src/core/__tests__/agentScheduler.test.js +129 -0
- package/src/core/agentPool.js +24 -0
- package/src/core/agentScheduler.js +574 -73
- package/src/index.js +8 -0
- package/src/interfaces/webServer.js +288 -0
- package/src/services/__tests__/channelFilter.test.js +264 -0
- package/src/services/__tests__/channelRelay.integration.test.js +496 -0
- package/src/services/__tests__/discordService.integration.test.js +10 -10
- package/src/services/__tests__/discordService.test.js +14 -7
- package/src/services/aiService.js +10 -3
- package/src/services/channelFilter.js +137 -0
- package/src/services/discordService.js +103 -19
- package/src/services/telegramService.js +58 -1
- package/src/tools/__tests__/visualEditorTool.context.test.js +141 -0
- package/src/tools/fileSystemTool.js +27 -3
- package/src/tools/openaiFunctionSchemas.js +270 -0
- package/src/tools/taskManagerTool.js +45 -2
- package/src/tools/terminalTool.js +23 -2
- package/src/tools/visualEditorTool.js +28 -4
- package/src/utilities/constants.js +9 -0
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-BbqxH6FC.js +1 -0
- package/web-ui/build/static/abap-UmHCZ0i1.js +1 -0
- package/web-ui/build/static/abnf-KQJciEU1.js +1 -0
- package/web-ui/build/static/abnf-wz9mo6UY.js +1 -0
- package/web-ui/build/static/accesslog-a-KjP-hj.js +1 -0
- package/web-ui/build/static/actionscript-C0kkFktE.js +1 -0
- package/web-ui/build/static/actionscript-CVfzNF7V.js +1 -0
- package/web-ui/build/static/ada-BtDccpCo.js +1 -0
- package/web-ui/build/static/ada-CsP-T950.js +1 -0
- package/web-ui/build/static/agda-DZ0Wv_k_.js +1 -0
- package/web-ui/build/static/al-Dieo4A36.js +1 -0
- package/web-ui/build/static/angelscript-Dxqs-qHl.js +1 -0
- package/web-ui/build/static/antlr4-2iwVxagJ.js +1 -0
- package/web-ui/build/static/apache-nHxOzinq.js +1 -0
- package/web-ui/build/static/apacheconf-DxkrSh6l.js +1 -0
- package/web-ui/build/static/apex-Broi_TKn.js +1 -0
- package/web-ui/build/static/apl-iAZYRZnE.js +1 -0
- package/web-ui/build/static/applescript-C-EKPlRf.js +1 -0
- package/web-ui/build/static/applescript-CVipha9P.js +1 -0
- package/web-ui/build/static/aql-Dn0E4LhK.js +1 -0
- package/web-ui/build/static/arcade-D5kIj1ez.js +1 -0
- package/web-ui/build/static/arduino-CydV4LN9.js +1 -0
- package/web-ui/build/static/arduino-DXaSwrry.js +1 -0
- package/web-ui/build/static/arff-yeDNnxkY.js +1 -0
- package/web-ui/build/static/armasm-DTu74JIo.js +1 -0
- package/web-ui/build/static/asciidoc-CLaqB1Gg.js +1 -0
- package/web-ui/build/static/asciidoc-DguUDHf5.js +1 -0
- package/web-ui/build/static/asm6502-C2c-H0Jh.js +1 -0
- package/web-ui/build/static/asmatmel-5xAyVq56.js +1 -0
- package/web-ui/build/static/aspectj-D5JvBRBv.js +1 -0
- package/web-ui/build/static/aspnet-DZfW9iG1.js +1 -0
- package/web-ui/build/static/autohotkey-3yT8W87y.js +1 -0
- package/web-ui/build/static/autohotkey-CxEWa3D5.js +1 -0
- package/web-ui/build/static/autoit-COt7rtxE.js +1 -0
- package/web-ui/build/static/autoit-DSva7SrP.js +1 -0
- package/web-ui/build/static/avisynth-DdpQ810f.js +1 -0
- package/web-ui/build/static/avrasm-BR0ncM-L.js +1 -0
- package/web-ui/build/static/avro-idl-DCISsbhh.js +1 -0
- package/web-ui/build/static/awk-Dd5HJDa0.js +1 -0
- package/web-ui/build/static/axapta-DWn0qUrW.js +1 -0
- package/web-ui/build/static/bash-B024Y1MV.js +1 -0
- package/web-ui/build/static/bash-qq4eTfOM.js +1 -0
- package/web-ui/build/static/basic-BWjvt39D.js +1 -0
- package/web-ui/build/static/basic-DVlMYdnX.js +1 -0
- package/web-ui/build/static/batch-Bb3dgg5p.js +1 -0
- package/web-ui/build/static/bbcode-DIclgs6t.js +1 -0
- package/web-ui/build/static/bicep-CXafPJf-.js +1 -0
- package/web-ui/build/static/birb-Btu8LQQE.js +1 -0
- package/web-ui/build/static/bison-CDXROKZw.js +1 -0
- package/web-ui/build/static/bnf-BB43qRSC.js +1 -0
- package/web-ui/build/static/bnf-ClpHUN6K.js +1 -0
- package/web-ui/build/static/brainfuck-BIgmc-EZ.js +1 -0
- package/web-ui/build/static/brainfuck-BJtPWa6l.js +1 -0
- package/web-ui/build/static/brightscript-9fU7OT4Y.js +1 -0
- package/web-ui/build/static/bro-DLftyzoO.js +1 -0
- package/web-ui/build/static/bsl-BWPnBSvd.js +1 -0
- package/web-ui/build/static/c-CD-936sv.js +1 -0
- package/web-ui/build/static/c-Do5sfWh2.js +1 -0
- package/web-ui/build/static/c-like-Cerk48hs.js +1 -0
- package/web-ui/build/static/cal-BfMsPDa0.js +1 -0
- package/web-ui/build/static/capnproto-mR83jTKG.js +1 -0
- package/web-ui/build/static/ceylon-Dt2cl-Ez.js +1 -0
- package/web-ui/build/static/cfscript-CFB-YYf8.js +1 -0
- package/web-ui/build/static/chaiscript-D3skeymm.js +1 -0
- package/web-ui/build/static/cil-DeczQ_ut.js +1 -0
- package/web-ui/build/static/clean-BXJPwGNL.js +1 -0
- package/web-ui/build/static/clojure-HHG1U7gj.js +1 -0
- package/web-ui/build/static/clojure-rEWdWYo_.js +1 -0
- package/web-ui/build/static/clojure-repl-CE4jr3K0.js +1 -0
- package/web-ui/build/static/cmake-DAzvKH16.js +1 -0
- package/web-ui/build/static/cmake-tD6uZl-y.js +1 -0
- package/web-ui/build/static/cobol-C2X6-bRz.js +1 -0
- package/web-ui/build/static/coffeescript-C9qjSh74.js +1 -0
- package/web-ui/build/static/coffeescript-DeHnRseX.js +1 -0
- package/web-ui/build/static/concurnas-DNuInYde.js +1 -0
- package/web-ui/build/static/coq-BQFo5XwN.js +1 -0
- package/web-ui/build/static/coq-Bmnum53S.js +1 -0
- package/web-ui/build/static/cos-D_0u-U2Y.js +1 -0
- package/web-ui/build/static/cpp-CoD9F6ol.js +1 -0
- package/web-ui/build/static/cpp-DB8R2f_c.js +1 -0
- package/web-ui/build/static/crmsh-DghD3B1u.js +1 -0
- package/web-ui/build/static/crystal-C63_SlFe.js +1 -0
- package/web-ui/build/static/crystal-GkhJSVpE.js +1 -0
- package/web-ui/build/static/csharp-Upa_qqR3.js +1 -0
- package/web-ui/build/static/csharp-kB8isYBD.js +1 -0
- package/web-ui/build/static/cshtml-BjeIyJW7.js +1 -0
- package/web-ui/build/static/csp-B9zvIPTA.js +1 -0
- package/web-ui/build/static/csp-hqOQW_KO.js +1 -0
- package/web-ui/build/static/css-BOqi7Sb8.js +1 -0
- package/web-ui/build/static/css-extras-NaDRDQYb.js +1 -0
- package/web-ui/build/static/csv-C7zNP0bV.js +1 -0
- package/web-ui/build/static/cypher-DzSGt09R.js +1 -0
- package/web-ui/build/static/d-DU9v7A7o.js +1 -0
- package/web-ui/build/static/d-YLgAiEhY.js +1 -0
- package/web-ui/build/static/dart-CLSlIEjd.js +1 -0
- package/web-ui/build/static/dart-Cv0y84fm.js +1 -0
- package/web-ui/build/static/dataweave-5zYOQCxv.js +1 -0
- package/web-ui/build/static/dax-C6xLX5GM.js +1 -0
- package/web-ui/build/static/delphi-D5HcUuVw.js +1 -0
- package/web-ui/build/static/dhall-C8OzwmzV.js +1 -0
- package/web-ui/build/static/diff-B030ZRbb.js +1 -0
- package/web-ui/build/static/diff-NCsBJCa7.js +1 -0
- package/web-ui/build/static/django-BeQDLTjX.js +1 -0
- package/web-ui/build/static/django-cC0WFEf1.js +1 -0
- package/web-ui/build/static/dns-CGMMfnr4.js +1 -0
- package/web-ui/build/static/dns-zone-file-908DrcaX.js +1 -0
- package/web-ui/build/static/docker-CE6F0WPR.js +1 -0
- package/web-ui/build/static/dockerfile-CUNa_EmN.js +1 -0
- package/web-ui/build/static/dos-CiM5tkPu.js +1 -0
- package/web-ui/build/static/dot-CZ0WLAzq.js +1 -0
- package/web-ui/build/static/dsconfig-Wo1ktU-F.js +1 -0
- package/web-ui/build/static/dts-BQJ7eIaM.js +1 -0
- package/web-ui/build/static/dust-DWnG4XQf.js +1 -0
- package/web-ui/build/static/ebnf-BqQRECjk.js +1 -0
- package/web-ui/build/static/ebnf-Cn_QHOpW.js +1 -0
- package/web-ui/build/static/editorconfig-CRE_lK21.js +1 -0
- package/web-ui/build/static/eiffel-h-dSP-Mu.js +1 -0
- package/web-ui/build/static/ejs-PVoVLwHk.js +1 -0
- package/web-ui/build/static/elixir-DVoAEVq_.js +1 -0
- package/web-ui/build/static/elixir-ZA65-L5t.js +1 -0
- package/web-ui/build/static/elm-ClRnxcFJ.js +1 -0
- package/web-ui/build/static/elm-Ttg_Dv8v.js +1 -0
- package/web-ui/build/static/erb-DCMJz1va.js +1 -0
- package/web-ui/build/static/erb-DDL7TB76.js +1 -0
- package/web-ui/build/static/erlang-01AtuMB8.js +1 -0
- package/web-ui/build/static/erlang-CLb6foRm.js +1 -0
- package/web-ui/build/static/erlang-repl-BwUG_X-H.js +1 -0
- package/web-ui/build/static/etlua-7jIebQwZ.js +1 -0
- package/web-ui/build/static/excel-BkKnPFBB.js +1 -0
- package/web-ui/build/static/excel-formula-dDd7nIUV.js +1 -0
- package/web-ui/build/static/factor-BLn5sqxN.js +1 -0
- package/web-ui/build/static/false-CNuRH4WA.js +1 -0
- package/web-ui/build/static/firestore-security-rules-Cr5e6oSH.js +1 -0
- package/web-ui/build/static/fix-NJ8G_1Tt.js +1 -0
- package/web-ui/build/static/flix-CBhTDcl9.js +1 -0
- package/web-ui/build/static/flow-DvgK1btf.js +1 -0
- package/web-ui/build/static/fortran-Bo-O9xtT.js +1 -0
- package/web-ui/build/static/fortran-Dj3v5L_m.js +1 -0
- package/web-ui/build/static/fsharp-5c6P8ZUH.js +1 -0
- package/web-ui/build/static/fsharp-C8bhnjfe.js +1 -0
- package/web-ui/build/static/ftl-8qE-2FJL.js +1 -0
- package/web-ui/build/static/gams-pbQRvKgr.js +1 -0
- package/web-ui/build/static/gap-CSFizYYs.js +1 -0
- package/web-ui/build/static/gauss-C0BsqEdj.js +1 -0
- package/web-ui/build/static/gcode-DMuLrnJF.js +1 -0
- package/web-ui/build/static/gcode-as5uEQOe.js +1 -0
- package/web-ui/build/static/gdscript-CSaSlSna.js +1 -0
- package/web-ui/build/static/gedcom-Cm86Ngut.js +1 -0
- package/web-ui/build/static/gherkin-C7FSJ6d3.js +1 -0
- package/web-ui/build/static/gherkin-C8wqlUqv.js +1 -0
- package/web-ui/build/static/git-DzPBmHlg.js +1 -0
- package/web-ui/build/static/glsl-D0_rPD58.js +1 -0
- package/web-ui/build/static/glsl-oUwWN2Xp.js +1 -0
- package/web-ui/build/static/gml-DNrWm4kb.js +1 -0
- package/web-ui/build/static/gml-JDXVyhBU.js +1 -0
- package/web-ui/build/static/gn-Bw-OsDH_.js +1 -0
- package/web-ui/build/static/go-B7Traa8J.js +1 -0
- package/web-ui/build/static/go-CaXFvYLQ.js +1 -0
- package/web-ui/build/static/go-module-BzKKnNxf.js +1 -0
- package/web-ui/build/static/golo-BokfRozl.js +1 -0
- package/web-ui/build/static/gradle-BBE_z74S.js +1 -0
- package/web-ui/build/static/graphql-DyqQ249q.js +1 -0
- package/web-ui/build/static/groovy-C9bdtULM.js +1 -0
- package/web-ui/build/static/groovy-CTYHYVKe.js +1 -0
- package/web-ui/build/static/haml--wzGI8rV.js +1 -0
- package/web-ui/build/static/haml-CP_fk9Du.js +1 -0
- package/web-ui/build/static/handlebars-BCN8I_fU.js +1 -0
- package/web-ui/build/static/handlebars-ClNs_EWN.js +1 -0
- package/web-ui/build/static/haskell-9-8FOmKL.js +1 -0
- package/web-ui/build/static/haskell-CeDcPoLF.js +1 -0
- package/web-ui/build/static/haxe-50b4_Uxu.js +1 -0
- package/web-ui/build/static/haxe-DV1jCpSQ.js +1 -0
- package/web-ui/build/static/hcl-BYAKEmjA.js +1 -0
- package/web-ui/build/static/hlsl-_V666kTg.js +1 -0
- package/web-ui/build/static/hoon-Xx5CPs_2.js +1 -0
- package/web-ui/build/static/hpkp-Dgu8ZS6s.js +1 -0
- package/web-ui/build/static/hsp-B0EcUcwP.js +1 -0
- package/web-ui/build/static/hsts-B1FQvgxb.js +1 -0
- package/web-ui/build/static/htmlbars-BGs3CWC2.js +1 -0
- package/web-ui/build/static/http-BvrKmZx0.js +1 -0
- package/web-ui/build/static/http-DUnWgTgI.js +1 -0
- package/web-ui/build/static/hy-StjWDayT.js +1 -0
- package/web-ui/build/static/ichigojam-Dla3EUZJ.js +1 -0
- package/web-ui/build/static/icon-CEA3F2cM.js +1 -0
- package/web-ui/build/static/icu-message-format-CIRX0H1E.js +1 -0
- package/web-ui/build/static/idris-z8g0EYLs.js +1 -0
- package/web-ui/build/static/iecst-D99vO-YV.js +1 -0
- package/web-ui/build/static/ignore-Bd9HTGo7.js +1 -0
- package/web-ui/build/static/index-9mcWHG2c.js +13 -0
- package/web-ui/build/static/index-BUtXAjd5.css +1 -0
- package/web-ui/build/static/index-CaMlGjdh.js +834 -0
- package/web-ui/build/static/index-D35injhb.js +1 -0
- package/web-ui/build/static/inform7-CKq2EPhg.js +1 -0
- package/web-ui/build/static/inform7-D-KIfWlv.js +1 -0
- package/web-ui/build/static/ini-CoFKaEFp.js +1 -0
- package/web-ui/build/static/ini-Cqh2VeO8.js +1 -0
- package/web-ui/build/static/io-A1ozJngc.js +1 -0
- package/web-ui/build/static/irpf90-DLGfrn4I.js +1 -0
- package/web-ui/build/static/isbl-dbyF-dLf.js +1 -0
- package/web-ui/build/static/j-ByhCpf6J.js +1 -0
- package/web-ui/build/static/java-DCbnRaHw.js +1 -0
- package/web-ui/build/static/java-LzFZofIb.js +1 -0
- package/web-ui/build/static/javadoc-CaKRZCNM.js +1 -0
- package/web-ui/build/static/javadoclike-CmvAiCvn.js +1 -0
- package/web-ui/build/static/javascript-Cpvfsh-z.js +1 -0
- package/web-ui/build/static/javastacktrace-CSUMoXqu.js +1 -0
- package/web-ui/build/static/jboss-cli-Cv0HXjqO.js +1 -0
- package/web-ui/build/static/jexl-CtUU8Pyc.js +1 -0
- package/web-ui/build/static/jolie-Ccbea_Ca.js +1 -0
- package/web-ui/build/static/jq-DQJKGqGL.js +1 -0
- package/web-ui/build/static/js-extras-BST2fo5a.js +1 -0
- package/web-ui/build/static/js-templates-T4aqrsni.js +1 -0
- package/web-ui/build/static/jsdoc-DZuHBRHT.js +1 -0
- package/web-ui/build/static/json-ByIlxtOm.js +1 -0
- package/web-ui/build/static/json-Dd-I2QR8.js +1 -0
- package/web-ui/build/static/json5-CIBARWXJ.js +1 -0
- package/web-ui/build/static/jsonp-Cs7yuq7_.js +1 -0
- package/web-ui/build/static/jsstacktrace-DrmYorp8.js +1 -0
- package/web-ui/build/static/jsx-Clb0obdm.js +1 -0
- package/web-ui/build/static/julia-BreTVWTb.js +1 -0
- package/web-ui/build/static/julia-qQfG7KSh.js +1 -0
- package/web-ui/build/static/julia-repl-wN09lKm6.js +1 -0
- package/web-ui/build/static/keepalived-DCyf_6ml.js +1 -0
- package/web-ui/build/static/keyman-B22SYHoa.js +1 -0
- package/web-ui/build/static/kotlin-DeVs-dNz.js +1 -0
- package/web-ui/build/static/kotlin-OMSaUY06.js +1 -0
- package/web-ui/build/static/kumir-Y-M6VOUG.js +1 -0
- package/web-ui/build/static/kusto-BnDldn0z.js +1 -0
- package/web-ui/build/static/lasso-BlUPIy-8.js +1 -0
- package/web-ui/build/static/latex-BGueNdTW.js +1 -0
- package/web-ui/build/static/latex-EZ8QNCjf.js +1 -0
- package/web-ui/build/static/latte-BkyPxQ_A.js +1 -0
- package/web-ui/build/static/ldif-BCIcpQI_.js +1 -0
- package/web-ui/build/static/leaf-BAG78wZj.js +1 -0
- package/web-ui/build/static/less-CFghh9Qx.js +1 -0
- package/web-ui/build/static/less-CbqfFGMD.js +1 -0
- package/web-ui/build/static/lilypond-BSpYx-1e.js +1 -0
- package/web-ui/build/static/liquid-CHhOmyTU.js +1 -0
- package/web-ui/build/static/lisp-QMm5BThy.js +1 -0
- package/web-ui/build/static/lisp-rizdk7e8.js +1 -0
- package/web-ui/build/static/livecodeserver-Bbh0nB2d.js +1 -0
- package/web-ui/build/static/livescript--QIhQOIm.js +1 -0
- package/web-ui/build/static/livescript-wYJ9C7MN.js +1 -0
- package/web-ui/build/static/llvm-qWkZ6M3-.js +1 -0
- package/web-ui/build/static/llvm-x8W93e2q.js +1 -0
- package/web-ui/build/static/log-D4PGnDHU.js +1 -0
- package/web-ui/build/static/lolcode-CHKS4ygP.js +1 -0
- package/web-ui/build/static/lsl-BEuQrHG7.js +1 -0
- package/web-ui/build/static/lua-Czrw1nZw.js +1 -0
- package/web-ui/build/static/lua-DUasTiYT.js +1 -0
- package/web-ui/build/static/magma-B16nUtxA.js +1 -0
- package/web-ui/build/static/makefile-BkqsEpVd.js +1 -0
- package/web-ui/build/static/makefile-DmoEDBJj.js +1 -0
- package/web-ui/build/static/markdown-FL-EZYmc.js +1 -0
- package/web-ui/build/static/markdown-N4YibSvf.js +1 -0
- package/web-ui/build/static/markup-templating-C1Q3BuB3.js +1 -0
- package/web-ui/build/static/mathematica-BZ50Ibwb.js +1 -0
- package/web-ui/build/static/matlab-CJFiUipn.js +1 -0
- package/web-ui/build/static/matlab-D-LwnpYW.js +1 -0
- package/web-ui/build/static/maxima-D1nKJHio.js +1 -0
- package/web-ui/build/static/maxscript-3ukqkynT.js +1 -0
- package/web-ui/build/static/mel-BpGPnIg7.js +1 -0
- package/web-ui/build/static/mel-DAIpK4k4.js +1 -0
- package/web-ui/build/static/mercury-BO6AXAJw.js +1 -0
- package/web-ui/build/static/mermaid-Cvu66kFB.js +1 -0
- package/web-ui/build/static/mipsasm-CP7z3_gg.js +1 -0
- package/web-ui/build/static/mizar-1tBmTbFY.js +1 -0
- package/web-ui/build/static/mizar-vPQKaBOY.js +1 -0
- package/web-ui/build/static/mojolicious-3wXNqu2Z.js +1 -0
- package/web-ui/build/static/mongodb-DkJ5x1x3.js +1 -0
- package/web-ui/build/static/monkey-DwU43sRn.js +1 -0
- package/web-ui/build/static/monkey-DzoqN4GB.js +1 -0
- package/web-ui/build/static/moonscript-CgTduPCr.js +1 -0
- package/web-ui/build/static/moonscript-Dzbt70Ke.js +1 -0
- package/web-ui/build/static/n1ql-BaVhxD8V.js +1 -0
- package/web-ui/build/static/n1ql-DUHSzjt3.js +1 -0
- package/web-ui/build/static/n4js-DZ7dW-NZ.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-C-ecDW8U.js +1 -0
- package/web-ui/build/static/naniscript-dzw8pH4q.js +1 -0
- package/web-ui/build/static/nasm-B0fCm10I.js +1 -0
- package/web-ui/build/static/neon-DRlFTieL.js +1 -0
- package/web-ui/build/static/nevod-BEzTxq7x.js +1 -0
- package/web-ui/build/static/nginx-BI0b7qBW.js +1 -0
- package/web-ui/build/static/nginx-BTbIqU-1.js +1 -0
- package/web-ui/build/static/nim-C1lYEnIA.js +1 -0
- package/web-ui/build/static/nim-mfWcJfe-.js +1 -0
- package/web-ui/build/static/nix-PO76YCUx.js +1 -0
- package/web-ui/build/static/nix-a-29l1yK.js +1 -0
- package/web-ui/build/static/node-repl-DDA8xtxU.js +1 -0
- package/web-ui/build/static/nsis-CLyYop70.js +1 -0
- package/web-ui/build/static/nsis-GiqT6oer.js +1 -0
- package/web-ui/build/static/objectivec-DF-fhcs7.js +1 -0
- package/web-ui/build/static/objectivec-DtXa6iKB.js +1 -0
- package/web-ui/build/static/ocaml-D4ptVFU5.js +1 -0
- package/web-ui/build/static/ocaml-DBtZVh9H.js +1 -0
- package/web-ui/build/static/opencl-0Z_Gtfzx.js +1 -0
- package/web-ui/build/static/openqasm-BafUOtKF.js +1 -0
- package/web-ui/build/static/openscad-DwQ7I7ze.js +1 -0
- package/web-ui/build/static/oxygene-Bt7r8sbX.js +1 -0
- package/web-ui/build/static/oz-Da-qnXiT.js +1 -0
- package/web-ui/build/static/parigp-D6mMgLkz.js +1 -0
- package/web-ui/build/static/parser-DUfGrzvv.js +1 -0
- package/web-ui/build/static/parser3-C4GwCqRM.js +1 -0
- package/web-ui/build/static/pascal-CKsIwy8z.js +1 -0
- package/web-ui/build/static/pascaligo-0Y00fNzu.js +1 -0
- package/web-ui/build/static/pcaxis-BFwUDXM-.js +1 -0
- package/web-ui/build/static/peoplecode-D8-HVebY.js +1 -0
- package/web-ui/build/static/perl-CoNeuMP2.js +1 -0
- package/web-ui/build/static/perl-Dk_kCckE.js +1 -0
- package/web-ui/build/static/pf-DWKdp2Z5.js +1 -0
- package/web-ui/build/static/pgsql-DQM_KLIL.js +1 -0
- package/web-ui/build/static/php-BLJ1RddK.js +1 -0
- package/web-ui/build/static/php-C4Q-EoBs.js +1 -0
- package/web-ui/build/static/php-extras-DH16mdyb.js +1 -0
- package/web-ui/build/static/php-template-Bgyau4h4.js +1 -0
- package/web-ui/build/static/phpdoc-CrGYZCs3.js +1 -0
- package/web-ui/build/static/plaintext--cxrnnIY.js +1 -0
- package/web-ui/build/static/plsql-DXxJ1j1M.js +1 -0
- package/web-ui/build/static/pony-Bk4QKmb5.js +1 -0
- package/web-ui/build/static/powerquery-BNY7Y_eg.js +1 -0
- package/web-ui/build/static/powershell-CjTGWZrY.js +1 -0
- package/web-ui/build/static/powershell-DKKBTrGN.js +1 -0
- package/web-ui/build/static/processing-CoCmNEON.js +1 -0
- package/web-ui/build/static/processing-dWxOKKau.js +1 -0
- package/web-ui/build/static/profile-DinHOW6q.js +1 -0
- package/web-ui/build/static/prolog-D8s2MxCR.js +1 -0
- package/web-ui/build/static/prolog-tfF0hJ7N.js +1 -0
- package/web-ui/build/static/promql-BbpNnYtf.js +1 -0
- package/web-ui/build/static/properties-BH5IGhCw.js +1 -0
- package/web-ui/build/static/properties-BtBGEFji.js +1 -0
- package/web-ui/build/static/protobuf-Bq57MNXu.js +1 -0
- package/web-ui/build/static/protobuf-FQ5v_34f.js +1 -0
- package/web-ui/build/static/psl-DH3KK34y.js +1 -0
- package/web-ui/build/static/pug-BH0-FqNN.js +1 -0
- package/web-ui/build/static/puppet-D6IQ0-e_.js +1 -0
- package/web-ui/build/static/puppet-DhDhkrHQ.js +1 -0
- package/web-ui/build/static/pure-D-zzqNXt.js +1 -0
- package/web-ui/build/static/purebasic-C3ZHqBxR.js +1 -0
- package/web-ui/build/static/purebasic-DTWXM0iu.js +1 -0
- package/web-ui/build/static/purescript-C9dMZi0f.js +1 -0
- package/web-ui/build/static/python-kp4UxaFP.js +1 -0
- package/web-ui/build/static/python-repl-Bugvu_dB.js +1 -0
- package/web-ui/build/static/python-vnX1mWhI.js +1 -0
- package/web-ui/build/static/q-BRREgX-f.js +1 -0
- package/web-ui/build/static/q-V3GLDm_n.js +1 -0
- package/web-ui/build/static/qml-DfQdRLrG.js +1 -0
- package/web-ui/build/static/qml-i0MLAsR_.js +1 -0
- package/web-ui/build/static/qore-CFRmreiI.js +1 -0
- package/web-ui/build/static/qsharp-BpxCSpMu.js +1 -0
- package/web-ui/build/static/r-BFhn56zx.js +1 -0
- package/web-ui/build/static/r-D19R1VlL.js +1 -0
- package/web-ui/build/static/racket-D6Do3XQN.js +1 -0
- package/web-ui/build/static/reason-BLxB_uYS.js +1 -0
- package/web-ui/build/static/reasonml-CR2O5QXc.js +1 -0
- package/web-ui/build/static/regex-ExQT3DD-.js +1 -0
- package/web-ui/build/static/rego-BG1H2Grq.js +1 -0
- package/web-ui/build/static/renpy-DPYPiSEa.js +1 -0
- package/web-ui/build/static/rest-BXeudWmA.js +1 -0
- package/web-ui/build/static/rib-B50qbZUa.js +1 -0
- package/web-ui/build/static/rip-Oy08VNTd.js +1 -0
- package/web-ui/build/static/roboconf-BJlNdB3f.js +1 -0
- package/web-ui/build/static/roboconf-BWCGa42W.js +1 -0
- package/web-ui/build/static/robotframework-CrL-sTEo.js +1 -0
- package/web-ui/build/static/routeros-BV_7BLfU.js +1 -0
- package/web-ui/build/static/rsl-3QUMrc7D.js +1 -0
- package/web-ui/build/static/ruby-CocpOjC3.js +1 -0
- package/web-ui/build/static/ruby-xGmQ173X.js +1 -0
- package/web-ui/build/static/ruleslanguage-Dvh9iMSY.js +1 -0
- package/web-ui/build/static/rust-BZNigb_r.js +1 -0
- package/web-ui/build/static/rust-DwNjoaBZ.js +1 -0
- package/web-ui/build/static/sas-BJAlmleu.js +1 -0
- package/web-ui/build/static/sas-DMbLpxbs.js +1 -0
- package/web-ui/build/static/sass-DqYzzuDm.js +1 -0
- package/web-ui/build/static/scala-Bh2FkhWY.js +1 -0
- package/web-ui/build/static/scala-CBjzCnx6.js +1 -0
- package/web-ui/build/static/scheme-D2RTBnn4.js +1 -0
- package/web-ui/build/static/scheme-YLsRQlUd.js +1 -0
- package/web-ui/build/static/scilab-CXvKl1CZ.js +1 -0
- package/web-ui/build/static/scss-BE2dzDGl.js +1 -0
- package/web-ui/build/static/scss-J1E3J7lz.js +1 -0
- package/web-ui/build/static/shell-AzmPYKrI.js +1 -0
- package/web-ui/build/static/shell-session-C5dCMLWG.js +1 -0
- package/web-ui/build/static/smali-C88i6nEO.js +1 -0
- package/web-ui/build/static/smali-Ddnoiqfy.js +1 -0
- package/web-ui/build/static/smalltalk-C72n_dxy.js +1 -0
- package/web-ui/build/static/smalltalk-CPfRSVZs.js +1 -0
- package/web-ui/build/static/smarty-Dypt4i8b.js +1 -0
- package/web-ui/build/static/sml-BGGb-k8a.js +1 -0
- package/web-ui/build/static/sml-BODNZSm_.js +1 -0
- package/web-ui/build/static/solidity-D6wtTexR.js +1 -0
- package/web-ui/build/static/solution-file-5lZW0oOE.js +1 -0
- package/web-ui/build/static/soy-y16jnIDo.js +1 -0
- package/web-ui/build/static/sparql-DrdB7SPu.js +1 -0
- package/web-ui/build/static/splunk-spl-Doyv_CQR.js +1 -0
- package/web-ui/build/static/sqf-BSSKLJcS.js +1 -0
- package/web-ui/build/static/sqf-C27vJSdk.js +1 -0
- package/web-ui/build/static/sql-BGAlidwo.js +1 -0
- package/web-ui/build/static/sql-D632T_PJ.js +1 -0
- package/web-ui/build/static/sql_more-DxYQWBWa.js +1 -0
- package/web-ui/build/static/squirrel-BtynEITS.js +1 -0
- package/web-ui/build/static/stan-_WgX5GWP.js +1 -0
- package/web-ui/build/static/stan-oF5qmMKy.js +1 -0
- package/web-ui/build/static/stata-wLOz3xoi.js +1 -0
- package/web-ui/build/static/step21-BbsA7W89.js +1 -0
- package/web-ui/build/static/stylus-DtfRtkyR.js +1 -0
- package/web-ui/build/static/stylus-vEf2q3jH.js +1 -0
- package/web-ui/build/static/subunit-BRaQkxqR.js +1 -0
- package/web-ui/build/static/swift-DT015mq6.js +1 -0
- package/web-ui/build/static/swift-Drl9Vhia.js +1 -0
- package/web-ui/build/static/systemd-DWH7nh0Q.js +1 -0
- package/web-ui/build/static/t4-cs-BqiTmoCX.js +1 -0
- package/web-ui/build/static/t4-templating-Bof0eAYR.js +1 -0
- package/web-ui/build/static/t4-vb-8nW7Q4TI.js +1 -0
- package/web-ui/build/static/taggerscript-Dmu4nEaQ.js +1 -0
- package/web-ui/build/static/tap-B19AuLWq.js +1 -0
- package/web-ui/build/static/tap-DOdxz1Vj.js +1 -0
- package/web-ui/build/static/tcl-BAqD74MG.js +1 -0
- package/web-ui/build/static/tcl-DOM7n3Vd.js +1 -0
- package/web-ui/build/static/textile-DFXg54i4.js +1 -0
- package/web-ui/build/static/thrift-BGDpLcp_.js +1 -0
- package/web-ui/build/static/toml-J8m0tgag.js +1 -0
- package/web-ui/build/static/tp-BQkDcUXJ.js +1 -0
- package/web-ui/build/static/tremor-hOnek1Vr.js +1 -0
- package/web-ui/build/static/tsx-dhyw01LJ.js +1 -0
- package/web-ui/build/static/tt2-BZlvT5MG.js +1 -0
- package/web-ui/build/static/turtle-CEGacgOB.js +1 -0
- package/web-ui/build/static/twig-C7j-eyaz.js +1 -0
- package/web-ui/build/static/twig-MQre7lvF.js +1 -0
- package/web-ui/build/static/typescript-Dq5ZmyEV.js +1 -0
- package/web-ui/build/static/typescript-qPtHjmzW.js +1 -0
- package/web-ui/build/static/typoscript-B0sirAiC.js +1 -0
- package/web-ui/build/static/unrealscript-D_kXyIkW.js +1 -0
- package/web-ui/build/static/uorazor-8wB8nSC0.js +1 -0
- package/web-ui/build/static/uri-CaeHYk3y.js +1 -0
- package/web-ui/build/static/v-CYZwlqI2.js +1 -0
- package/web-ui/build/static/vala-DDkZds8N.js +1 -0
- package/web-ui/build/static/vala-zKk5gtUp.js +1 -0
- package/web-ui/build/static/vbnet-DY8Bh7zr.js +1 -0
- package/web-ui/build/static/vbnet-Z7zud-Nk.js +1 -0
- package/web-ui/build/static/vbscript-0xsGTIri.js +1 -0
- package/web-ui/build/static/vbscript-html-CQJqQ_tQ.js +1 -0
- package/web-ui/build/static/velocity-Dqe4ZgAo.js +1 -0
- package/web-ui/build/static/verilog-B0uVsHQr.js +1 -0
- package/web-ui/build/static/verilog-DLybxDJj.js +1 -0
- package/web-ui/build/static/vhdl-CP0JnbrM.js +1 -0
- package/web-ui/build/static/vhdl-CRV0TYO8.js +1 -0
- package/web-ui/build/static/vim-06LYR_Gs.js +1 -0
- package/web-ui/build/static/vim-DGgQcHr4.js +1 -0
- package/web-ui/build/static/visual-basic-BUWV1u5S.js +1 -0
- package/web-ui/build/static/warpscript-DKb8tXBH.js +1 -0
- package/web-ui/build/static/wasm-8E-n1sJQ.js +1 -0
- package/web-ui/build/static/web-idl-Bynfh0Gg.js +1 -0
- package/web-ui/build/static/wiki-Ck0ehuwt.js +1 -0
- package/web-ui/build/static/wolfram-BE1k6uuJ.js +1 -0
- package/web-ui/build/static/wren-Ce_CEEnI.js +1 -0
- package/web-ui/build/static/x86asm-DZUKtGAe.js +1 -0
- package/web-ui/build/static/xeora-DvXhnkv6.js +1 -0
- package/web-ui/build/static/xl-B1lBPZU_.js +1 -0
- package/web-ui/build/static/xml-D3p5hl_7.js +1 -0
- package/web-ui/build/static/xml-doc-CF8VvGyG.js +1 -0
- package/web-ui/build/static/xojo-D-WnMFdK.js +1 -0
- package/web-ui/build/static/xquery-BNNLxmJw.js +1 -0
- package/web-ui/build/static/xquery-D-mYtMjU.js +1 -0
- package/web-ui/build/static/yaml-a5-6TRUw.js +1 -0
- package/web-ui/build/static/yaml-aH3GAAQN.js +1 -0
- package/web-ui/build/static/yang-B2qT8oVg.js +1 -0
- package/web-ui/build/static/zephir-yxlgFmpA.js +1 -0
- package/web-ui/build/static/zig-B_AoM5P0.js +1 -0
- package/web-ui/build/static/1c-DUhJWQrP.js +0 -1
- package/web-ui/build/static/abap-D5pCv45A.js +0 -1
- package/web-ui/build/static/abnf-BqIdp1gH.js +0 -1
- package/web-ui/build/static/abnf-CBjlJif0.js +0 -1
- package/web-ui/build/static/accesslog-C5KlxDoB.js +0 -1
- package/web-ui/build/static/actionscript-CEdNWXaD.js +0 -1
- package/web-ui/build/static/actionscript-CgxJfO4L.js +0 -1
- package/web-ui/build/static/ada-Bdm6rSt3.js +0 -1
- package/web-ui/build/static/ada-Cqq140Rj.js +0 -1
- package/web-ui/build/static/agda-glonKdcN.js +0 -1
- package/web-ui/build/static/al-C_FHJHny.js +0 -1
- package/web-ui/build/static/angelscript-Rz4JX2Rq.js +0 -1
- package/web-ui/build/static/antlr4-D4LSk0Ay.js +0 -1
- package/web-ui/build/static/apache-BaMp4ZSC.js +0 -1
- package/web-ui/build/static/apacheconf-BVq0Zx-9.js +0 -1
- package/web-ui/build/static/apex-DdKma-_U.js +0 -1
- package/web-ui/build/static/apl-CXIfpQjm.js +0 -1
- package/web-ui/build/static/applescript-D92-mz1s.js +0 -1
- package/web-ui/build/static/applescript-eHzEb7oT.js +0 -1
- package/web-ui/build/static/aql-D_F7mVkg.js +0 -1
- package/web-ui/build/static/arcade-DgXn3lOp.js +0 -1
- package/web-ui/build/static/arduino-10f7W_Wz.js +0 -1
- package/web-ui/build/static/arduino-Bi8wBo3Q.js +0 -1
- package/web-ui/build/static/arff-DAZwwp1m.js +0 -1
- package/web-ui/build/static/armasm-4k-fm-WI.js +0 -1
- package/web-ui/build/static/asciidoc-9iyohD53.js +0 -1
- package/web-ui/build/static/asciidoc-BPxaG9gt.js +0 -1
- package/web-ui/build/static/asm6502-DlE-NUYG.js +0 -1
- package/web-ui/build/static/asmatmel-ykXUz67l.js +0 -1
- package/web-ui/build/static/aspectj-BkcGzoIw.js +0 -1
- package/web-ui/build/static/aspnet-B8bHvD3e.js +0 -1
- package/web-ui/build/static/autohotkey-BXgybckQ.js +0 -1
- package/web-ui/build/static/autohotkey-rJX88r3D.js +0 -1
- package/web-ui/build/static/autoit-BV42RCy-.js +0 -1
- package/web-ui/build/static/autoit-DtcYxn7t.js +0 -1
- package/web-ui/build/static/avisynth-B4vyExrv.js +0 -1
- package/web-ui/build/static/avrasm-hptGkmwL.js +0 -1
- package/web-ui/build/static/avro-idl-D6Eh5Tip.js +0 -1
- package/web-ui/build/static/awk-VZHEebeo.js +0 -1
- package/web-ui/build/static/axapta-MDY4Ol3-.js +0 -1
- package/web-ui/build/static/bash-CEVIQPNU.js +0 -1
- package/web-ui/build/static/bash-CQheSBd0.js +0 -1
- package/web-ui/build/static/basic-BNAC47vx.js +0 -1
- package/web-ui/build/static/basic-o0l9wI82.js +0 -1
- package/web-ui/build/static/batch-05P80ryo.js +0 -1
- package/web-ui/build/static/bbcode-CvQ1b2hw.js +0 -1
- package/web-ui/build/static/bicep-CfAYoZNS.js +0 -1
- package/web-ui/build/static/birb-JD-jZNqk.js +0 -1
- package/web-ui/build/static/bison-i3sQbLUm.js +0 -1
- package/web-ui/build/static/bnf-B5bYoRbA.js +0 -1
- package/web-ui/build/static/bnf-D98r2gkN.js +0 -1
- package/web-ui/build/static/brainfuck-BU_egZbB.js +0 -1
- package/web-ui/build/static/brainfuck-Df0tVgjY.js +0 -1
- package/web-ui/build/static/brightscript-DSvCPg0z.js +0 -1
- package/web-ui/build/static/bro-BBxgPL7i.js +0 -1
- package/web-ui/build/static/bsl-JrkU-4lx.js +0 -1
- package/web-ui/build/static/c-BWSIorgH.js +0 -1
- package/web-ui/build/static/c-BXBwfPOR.js +0 -1
- package/web-ui/build/static/c-like-4jLL6ZeZ.js +0 -1
- package/web-ui/build/static/cal-BUukjt45.js +0 -1
- package/web-ui/build/static/capnproto-DzfXkblk.js +0 -1
- package/web-ui/build/static/ceylon-C6eNUw7A.js +0 -1
- package/web-ui/build/static/cfscript-DtzcDoB6.js +0 -1
- package/web-ui/build/static/chaiscript-q5NSJZ6c.js +0 -1
- package/web-ui/build/static/cil-DXg6HnTF.js +0 -1
- package/web-ui/build/static/clean-DhrJyfi0.js +0 -1
- package/web-ui/build/static/clojure-DCN-fEKt.js +0 -1
- package/web-ui/build/static/clojure-aNTgtXL1.js +0 -1
- package/web-ui/build/static/clojure-repl-B_eFHp5m.js +0 -1
- package/web-ui/build/static/cmake-BDtm7sss.js +0 -1
- package/web-ui/build/static/cmake-Bj_M_zqn.js +0 -1
- package/web-ui/build/static/cobol-qo3jUBf5.js +0 -1
- package/web-ui/build/static/coffeescript-CIyOUYJ3.js +0 -1
- package/web-ui/build/static/coffeescript-CduS6q85.js +0 -1
- package/web-ui/build/static/concurnas-DtdAZDrQ.js +0 -1
- package/web-ui/build/static/coq-CN6lKK7F.js +0 -1
- package/web-ui/build/static/coq-DzGUbX5U.js +0 -1
- package/web-ui/build/static/cos-DFcou98i.js +0 -1
- package/web-ui/build/static/cpp-Dgg9pFUu.js +0 -1
- package/web-ui/build/static/cpp-PRuqGY7D.js +0 -1
- package/web-ui/build/static/crmsh-DLLfnotO.js +0 -1
- package/web-ui/build/static/crystal-BPylX4xG.js +0 -1
- package/web-ui/build/static/crystal-R1dH-Ebf.js +0 -1
- package/web-ui/build/static/csharp-CzwY39sl.js +0 -1
- package/web-ui/build/static/csharp-DJyymJhf.js +0 -1
- package/web-ui/build/static/cshtml-CwtJYmS1.js +0 -1
- package/web-ui/build/static/csp-Bj2DpAcY.js +0 -1
- package/web-ui/build/static/csp-xY5_PNPj.js +0 -1
- package/web-ui/build/static/css-DBGSwd91.js +0 -1
- package/web-ui/build/static/css-extras-BvlTqCpv.js +0 -1
- package/web-ui/build/static/csv-UTBn-Q9j.js +0 -1
- package/web-ui/build/static/cypher-BfzzS1h2.js +0 -1
- package/web-ui/build/static/d-BvamtLdb.js +0 -1
- package/web-ui/build/static/d-XpxNI5JF.js +0 -1
- package/web-ui/build/static/dart-BEM6fjpM.js +0 -1
- package/web-ui/build/static/dart-CsMrP4Ax.js +0 -1
- package/web-ui/build/static/dataweave-B-vfR-Jf.js +0 -1
- package/web-ui/build/static/dax-2WUcEUPn.js +0 -1
- package/web-ui/build/static/delphi-7XWS5oTs.js +0 -1
- package/web-ui/build/static/dhall-NWRUZH7l.js +0 -1
- package/web-ui/build/static/diff-AEgTdaYv.js +0 -1
- package/web-ui/build/static/diff-BRgtzr2U.js +0 -1
- package/web-ui/build/static/django-4bH3I4pv.js +0 -1
- package/web-ui/build/static/django-CrlKM5br.js +0 -1
- package/web-ui/build/static/dns-BSqNAZE3.js +0 -1
- package/web-ui/build/static/dns-zone-file-Di5cZlps.js +0 -1
- package/web-ui/build/static/docker-C9BRbp6h.js +0 -1
- package/web-ui/build/static/dockerfile-DbkS5WIL.js +0 -1
- package/web-ui/build/static/dos-per3p9hI.js +0 -1
- package/web-ui/build/static/dot-DjnTpyv1.js +0 -1
- package/web-ui/build/static/dsconfig-BjcpCNTB.js +0 -1
- package/web-ui/build/static/dts-DSWuKx2J.js +0 -1
- package/web-ui/build/static/dust-BCqihcI2.js +0 -1
- package/web-ui/build/static/ebnf-7ErhUPMF.js +0 -1
- package/web-ui/build/static/ebnf-CHADdlPD.js +0 -1
- package/web-ui/build/static/editorconfig--daZb_D-.js +0 -1
- package/web-ui/build/static/eiffel-C5zhT7HO.js +0 -1
- package/web-ui/build/static/ejs-ncnPF5oJ.js +0 -1
- package/web-ui/build/static/elixir-kFl2IHfo.js +0 -1
- package/web-ui/build/static/elixir-m8Rwrydm.js +0 -1
- package/web-ui/build/static/elm-CvywOdPd.js +0 -1
- package/web-ui/build/static/elm-Dsie_raS.js +0 -1
- package/web-ui/build/static/erb-BvkeA6hu.js +0 -1
- package/web-ui/build/static/erb-CtAdMBZY.js +0 -1
- package/web-ui/build/static/erlang-B1PynliZ.js +0 -1
- package/web-ui/build/static/erlang-DO2EN0IW.js +0 -1
- package/web-ui/build/static/erlang-repl-DWSpk7kU.js +0 -1
- package/web-ui/build/static/etlua-yEBP6vtw.js +0 -1
- package/web-ui/build/static/excel-Bhh_OwNT.js +0 -1
- package/web-ui/build/static/excel-formula-D8YNVKGY.js +0 -1
- package/web-ui/build/static/factor-U8_v_-Qx.js +0 -1
- package/web-ui/build/static/false-CbflHcQ4.js +0 -1
- package/web-ui/build/static/firestore-security-rules-C9yS7u9K.js +0 -1
- package/web-ui/build/static/fix-9oju1yrf.js +0 -1
- package/web-ui/build/static/flix-DlGExg75.js +0 -1
- package/web-ui/build/static/flow-DKikR-YL.js +0 -1
- package/web-ui/build/static/fortran-BTYpE8K2.js +0 -1
- package/web-ui/build/static/fortran-BxxaCEOU.js +0 -1
- package/web-ui/build/static/fsharp-BSNG-jCK.js +0 -1
- package/web-ui/build/static/fsharp-CCg0Y4HA.js +0 -1
- package/web-ui/build/static/ftl-DjWJ0y-0.js +0 -1
- package/web-ui/build/static/gams-C5fvQ3Od.js +0 -1
- package/web-ui/build/static/gap-BvL-biL4.js +0 -1
- package/web-ui/build/static/gauss-BzZO8GCS.js +0 -1
- package/web-ui/build/static/gcode-Cz8GsjzL.js +0 -1
- package/web-ui/build/static/gcode-Dg2JcAQS.js +0 -1
- package/web-ui/build/static/gdscript-BOCutEVV.js +0 -1
- package/web-ui/build/static/gedcom-Bdq0EwEN.js +0 -1
- package/web-ui/build/static/gherkin-Bn1mABAH.js +0 -1
- package/web-ui/build/static/gherkin-DpDnmvFb.js +0 -1
- package/web-ui/build/static/git-Cd4zgk7f.js +0 -1
- package/web-ui/build/static/glsl-BGXyo7Gw.js +0 -1
- package/web-ui/build/static/glsl-COPc8ZeZ.js +0 -1
- package/web-ui/build/static/gml-BCkIu1Er.js +0 -1
- package/web-ui/build/static/gml-COtYpJl2.js +0 -1
- package/web-ui/build/static/gn-Bjg1CRig.js +0 -1
- package/web-ui/build/static/go-BB6lvTry.js +0 -1
- package/web-ui/build/static/go-adzEcqWq.js +0 -1
- package/web-ui/build/static/go-module-CfC8Vt2L.js +0 -1
- package/web-ui/build/static/golo-C2rGlTHX.js +0 -1
- package/web-ui/build/static/gradle-Dh3gdCGU.js +0 -1
- package/web-ui/build/static/graphql-w9z3CiM9.js +0 -1
- package/web-ui/build/static/groovy-BU2m7Ekt.js +0 -1
- package/web-ui/build/static/groovy-Bi8INA80.js +0 -1
- package/web-ui/build/static/haml-t0Z0NMdQ.js +0 -1
- package/web-ui/build/static/haml-yTEKBHVm.js +0 -1
- package/web-ui/build/static/handlebars-BmRED509.js +0 -1
- package/web-ui/build/static/handlebars-DmmahO5D.js +0 -1
- package/web-ui/build/static/haskell-B4TTwJ5u.js +0 -1
- package/web-ui/build/static/haskell-BX4vB3_v.js +0 -1
- package/web-ui/build/static/haxe-B81ItqL6.js +0 -1
- package/web-ui/build/static/haxe-Z6MewpJj.js +0 -1
- package/web-ui/build/static/hcl-CT8vHUwN.js +0 -1
- package/web-ui/build/static/hlsl-BNvVW3bY.js +0 -1
- package/web-ui/build/static/hoon-07zLMFzn.js +0 -1
- package/web-ui/build/static/hpkp-DxK9DKwE.js +0 -1
- package/web-ui/build/static/hsp-BFSV4VGN.js +0 -1
- package/web-ui/build/static/hsts-Dfi1_v6k.js +0 -1
- package/web-ui/build/static/htmlbars-CBGS41Tx.js +0 -1
- package/web-ui/build/static/http-Ck2d_NdZ.js +0 -1
- package/web-ui/build/static/http-CljalO0f.js +0 -1
- package/web-ui/build/static/hy-CWwWerqr.js +0 -1
- package/web-ui/build/static/ichigojam-BUq638e8.js +0 -1
- package/web-ui/build/static/icon-CkGyT1bh.js +0 -1
- package/web-ui/build/static/icu-message-format-BQoqTHNl.js +0 -1
- package/web-ui/build/static/idris-nI6aQ55s.js +0 -1
- package/web-ui/build/static/iecst-BVwN13uc.js +0 -1
- package/web-ui/build/static/ignore-BLfLC9PA.js +0 -1
- package/web-ui/build/static/index-BwLo9qDf.js +0 -1
- package/web-ui/build/static/index-BwNJoEC1.css +0 -1
- package/web-ui/build/static/index-CrzpLgj1.js +0 -13
- package/web-ui/build/static/index-DqzIkFBw.js +0 -834
- package/web-ui/build/static/inform7-BML_idR2.js +0 -1
- package/web-ui/build/static/inform7-xoROt4DC.js +0 -1
- package/web-ui/build/static/ini-CCSkzm0H.js +0 -1
- package/web-ui/build/static/ini-CYmzo02a.js +0 -1
- package/web-ui/build/static/io-DXnvLdgN.js +0 -1
- package/web-ui/build/static/irpf90-DxKOk6dw.js +0 -1
- package/web-ui/build/static/isbl-0B0tD40P.js +0 -1
- package/web-ui/build/static/j-DXpPF6fV.js +0 -1
- package/web-ui/build/static/java-D2GSVfv5.js +0 -1
- package/web-ui/build/static/java-KuHaGPGv.js +0 -1
- package/web-ui/build/static/javadoc-BCT2sPL1.js +0 -1
- package/web-ui/build/static/javadoclike-BvnqsHVU.js +0 -1
- package/web-ui/build/static/javascript-CiWbQcs7.js +0 -1
- package/web-ui/build/static/javastacktrace-eBMVSx2Z.js +0 -1
- package/web-ui/build/static/jboss-cli-C01AEskS.js +0 -1
- package/web-ui/build/static/jexl-Dn5KxGiK.js +0 -1
- package/web-ui/build/static/jolie-D3Zt6_TW.js +0 -1
- package/web-ui/build/static/jq-DxOmFCSQ.js +0 -1
- package/web-ui/build/static/js-extras-CMUXnpUe.js +0 -1
- package/web-ui/build/static/js-templates-BzQwIldl.js +0 -1
- package/web-ui/build/static/jsdoc-CkAdh1ug.js +0 -1
- package/web-ui/build/static/json-C-B6MwWV.js +0 -1
- package/web-ui/build/static/json-C75IrF6s.js +0 -1
- package/web-ui/build/static/json5-DvXR6PNV.js +0 -1
- package/web-ui/build/static/jsonp-B92u1PFA.js +0 -1
- package/web-ui/build/static/jsstacktrace-DJjcSHfr.js +0 -1
- package/web-ui/build/static/jsx-C9-rq-CT.js +0 -1
- package/web-ui/build/static/julia-DS04VXIz.js +0 -1
- package/web-ui/build/static/julia-DrUeWVfq.js +0 -1
- package/web-ui/build/static/julia-repl-i80v_zZH.js +0 -1
- package/web-ui/build/static/keepalived-BHGEAKGU.js +0 -1
- package/web-ui/build/static/keyman-Bdzqqi9H.js +0 -1
- package/web-ui/build/static/kotlin-BzHWfKYa.js +0 -1
- package/web-ui/build/static/kotlin-C_V1S_FQ.js +0 -1
- package/web-ui/build/static/kumir-CotiKPE1.js +0 -1
- package/web-ui/build/static/kusto-DRtZ_YAs.js +0 -1
- package/web-ui/build/static/lasso-CWuEv8wJ.js +0 -1
- package/web-ui/build/static/latex-BQyvVAOm.js +0 -1
- package/web-ui/build/static/latex-DMFvqai-.js +0 -1
- package/web-ui/build/static/latte-DBzhXpVk.js +0 -1
- package/web-ui/build/static/ldif-CHIDpBfE.js +0 -1
- package/web-ui/build/static/leaf-BUM990MU.js +0 -1
- package/web-ui/build/static/less-Ct98Xd8m.js +0 -1
- package/web-ui/build/static/less-cA1L-hw1.js +0 -1
- package/web-ui/build/static/lilypond-BxQcVtKe.js +0 -1
- package/web-ui/build/static/liquid-BsdpMPYc.js +0 -1
- package/web-ui/build/static/lisp-BNcefi1U.js +0 -1
- package/web-ui/build/static/lisp-CBeHrUJR.js +0 -1
- package/web-ui/build/static/livecodeserver-BRZ6ns7E.js +0 -1
- package/web-ui/build/static/livescript-C9VXNDh2.js +0 -1
- package/web-ui/build/static/livescript-CPM4TEaS.js +0 -1
- package/web-ui/build/static/llvm-D-ktoQ6Z.js +0 -1
- package/web-ui/build/static/llvm-aGR2Ei-6.js +0 -1
- package/web-ui/build/static/log-BDQPp9ei.js +0 -1
- package/web-ui/build/static/lolcode-H3tk4sVp.js +0 -1
- package/web-ui/build/static/lsl-E_sO-uEk.js +0 -1
- package/web-ui/build/static/lua-CII1BReE.js +0 -1
- package/web-ui/build/static/lua-c32KCD1t.js +0 -1
- package/web-ui/build/static/magma-BhWArSfW.js +0 -1
- package/web-ui/build/static/makefile-BL9Ig9xO.js +0 -1
- package/web-ui/build/static/makefile-C_xncXma.js +0 -1
- package/web-ui/build/static/markdown-Bjx0QXUF.js +0 -1
- package/web-ui/build/static/markdown-DKcNzXLC.js +0 -1
- package/web-ui/build/static/markup-templating-DAQlKGf9.js +0 -1
- package/web-ui/build/static/mathematica-CvqfUKaF.js +0 -1
- package/web-ui/build/static/matlab-BErKso28.js +0 -1
- package/web-ui/build/static/matlab-ClFikeke.js +0 -1
- package/web-ui/build/static/maxima-Ft3syDPO.js +0 -1
- package/web-ui/build/static/maxscript-DT0tXOez.js +0 -1
- package/web-ui/build/static/mel-B9RYm_nG.js +0 -1
- package/web-ui/build/static/mel-DGpfnKg9.js +0 -1
- package/web-ui/build/static/mercury-CXmUlA2y.js +0 -1
- package/web-ui/build/static/mermaid-BDmkIkXi.js +0 -1
- package/web-ui/build/static/mipsasm-B2G5mL-v.js +0 -1
- package/web-ui/build/static/mizar-9hVFfba0.js +0 -1
- package/web-ui/build/static/mizar-FYnr9CDP.js +0 -1
- package/web-ui/build/static/mojolicious-D3hJYxqh.js +0 -1
- package/web-ui/build/static/mongodb-HP0s-riS.js +0 -1
- package/web-ui/build/static/monkey-CBt12SEM.js +0 -1
- package/web-ui/build/static/monkey-DIqWIXYW.js +0 -1
- package/web-ui/build/static/moonscript-B8Z_r4dn.js +0 -1
- package/web-ui/build/static/moonscript-CE7UuyXU.js +0 -1
- package/web-ui/build/static/n1ql-B16jfOjw.js +0 -1
- package/web-ui/build/static/n1ql-BgMWCckC.js +0 -1
- package/web-ui/build/static/n4js-CAXy3_Jy.js +0 -1
- package/web-ui/build/static/nand2tetris-hdl-C3vzslgj.js +0 -1
- package/web-ui/build/static/naniscript-DAFwQQVi.js +0 -1
- package/web-ui/build/static/nasm-BOFKVnaS.js +0 -1
- package/web-ui/build/static/neon-D0ISL7qJ.js +0 -1
- package/web-ui/build/static/nevod-KoDi24v0.js +0 -1
- package/web-ui/build/static/nginx-Cr5DfqWR.js +0 -1
- package/web-ui/build/static/nginx-DCCnctTG.js +0 -1
- package/web-ui/build/static/nim-DPJN-_EC.js +0 -1
- package/web-ui/build/static/nim-De05kw0n.js +0 -1
- package/web-ui/build/static/nix-CELEwiHo.js +0 -1
- package/web-ui/build/static/nix-CSaBChxR.js +0 -1
- package/web-ui/build/static/node-repl-C32a7yiw.js +0 -1
- package/web-ui/build/static/nsis-CZuaKioB.js +0 -1
- package/web-ui/build/static/nsis-VwfBkj3d.js +0 -1
- package/web-ui/build/static/objectivec-DJKZtPL2.js +0 -1
- package/web-ui/build/static/objectivec-DK2yoaBg.js +0 -1
- package/web-ui/build/static/ocaml-Dxx1cjem.js +0 -1
- package/web-ui/build/static/ocaml-kjKWdGCz.js +0 -1
- package/web-ui/build/static/opencl-BNtKnv1J.js +0 -1
- package/web-ui/build/static/openqasm-CdvNeYug.js +0 -1
- package/web-ui/build/static/openscad-B_qvsjfe.js +0 -1
- package/web-ui/build/static/oxygene-DG1hddn5.js +0 -1
- package/web-ui/build/static/oz-CRY87qeP.js +0 -1
- package/web-ui/build/static/parigp-BkAr6-G8.js +0 -1
- package/web-ui/build/static/parser-CP5clEop.js +0 -1
- package/web-ui/build/static/parser3-crTb7A0X.js +0 -1
- package/web-ui/build/static/pascal-DPfyfoDh.js +0 -1
- package/web-ui/build/static/pascaligo-DURFNQ_j.js +0 -1
- package/web-ui/build/static/pcaxis-DD7RAxRP.js +0 -1
- package/web-ui/build/static/peoplecode-So_X5jSp.js +0 -1
- package/web-ui/build/static/perl-B1DBrLmJ.js +0 -1
- package/web-ui/build/static/perl-BFaVXeG7.js +0 -1
- package/web-ui/build/static/pf-CEB1L5qm.js +0 -1
- package/web-ui/build/static/pgsql-A0nsUgDI.js +0 -1
- package/web-ui/build/static/php-8ihB7EPM.js +0 -1
- package/web-ui/build/static/php-Sh6D6NIJ.js +0 -1
- package/web-ui/build/static/php-extras-Cy_aBZK6.js +0 -1
- package/web-ui/build/static/php-template-Cit-PHnf.js +0 -1
- package/web-ui/build/static/phpdoc-DNU6hjDm.js +0 -1
- package/web-ui/build/static/plaintext-FLJCTahD.js +0 -1
- package/web-ui/build/static/plsql-1giFa6G7.js +0 -1
- package/web-ui/build/static/pony-BEp1IqY4.js +0 -1
- package/web-ui/build/static/powerquery-B43RvEYw.js +0 -1
- package/web-ui/build/static/powershell-B0QtH4nv.js +0 -1
- package/web-ui/build/static/powershell-BdHnDhS8.js +0 -1
- package/web-ui/build/static/processing-Be1Oglu_.js +0 -1
- package/web-ui/build/static/processing-CARItQwm.js +0 -1
- package/web-ui/build/static/profile-BwlQtk0y.js +0 -1
- package/web-ui/build/static/prolog-DKK6jUnc.js +0 -1
- package/web-ui/build/static/prolog-b_8huu7c.js +0 -1
- package/web-ui/build/static/promql-BZZ7XfbI.js +0 -1
- package/web-ui/build/static/properties-BFb1Pf6n.js +0 -1
- package/web-ui/build/static/properties-CmsBqXVJ.js +0 -1
- package/web-ui/build/static/protobuf-DeLotQpJ.js +0 -1
- package/web-ui/build/static/protobuf-WK1D_sJI.js +0 -1
- package/web-ui/build/static/psl-MNZR2qmI.js +0 -1
- package/web-ui/build/static/pug-CF9nceJD.js +0 -1
- package/web-ui/build/static/puppet-CZbKHt9x.js +0 -1
- package/web-ui/build/static/puppet-DUMENOgH.js +0 -1
- package/web-ui/build/static/pure-37fhgfVL.js +0 -1
- package/web-ui/build/static/purebasic-BdORV50m.js +0 -1
- package/web-ui/build/static/purebasic-D8axvRJF.js +0 -1
- package/web-ui/build/static/purescript-BmZhg2WR.js +0 -1
- package/web-ui/build/static/python-CnE0eaJH.js +0 -1
- package/web-ui/build/static/python-rT3smsTM.js +0 -1
- package/web-ui/build/static/python-repl-oAPThvRZ.js +0 -1
- package/web-ui/build/static/q-C9PeNAsV.js +0 -1
- package/web-ui/build/static/q-DEhOeRm8.js +0 -1
- package/web-ui/build/static/qml-CzmXy0mm.js +0 -1
- package/web-ui/build/static/qml-ZLrRDW5F.js +0 -1
- package/web-ui/build/static/qore-C4BmNqiC.js +0 -1
- package/web-ui/build/static/qsharp-CUspIxRd.js +0 -1
- package/web-ui/build/static/r-CmTJdjSW.js +0 -1
- package/web-ui/build/static/r-Dul2vX00.js +0 -1
- package/web-ui/build/static/racket-DuTLmSg0.js +0 -1
- package/web-ui/build/static/reason-CPbzN4QK.js +0 -1
- package/web-ui/build/static/reasonml-BX6GGy_7.js +0 -1
- package/web-ui/build/static/regex-C-S4lu9H.js +0 -1
- package/web-ui/build/static/rego-C552rbmD.js +0 -1
- package/web-ui/build/static/renpy-CAXD5ZIz.js +0 -1
- package/web-ui/build/static/rest-C0ztj_j5.js +0 -1
- package/web-ui/build/static/rib-qZJul5T1.js +0 -1
- package/web-ui/build/static/rip-Bi2BsowV.js +0 -1
- package/web-ui/build/static/roboconf-BcDqw_pY.js +0 -1
- package/web-ui/build/static/roboconf-CEx3VVi1.js +0 -1
- package/web-ui/build/static/robotframework-CJVompq9.js +0 -1
- package/web-ui/build/static/routeros-BhoPpLPN.js +0 -1
- package/web-ui/build/static/rsl-BnetYcE2.js +0 -1
- package/web-ui/build/static/ruby-D-6W0bRE.js +0 -1
- package/web-ui/build/static/ruby-Dy6NjAXK.js +0 -1
- package/web-ui/build/static/ruleslanguage-Bl49mJdL.js +0 -1
- package/web-ui/build/static/rust-DxOQY_0w.js +0 -1
- package/web-ui/build/static/rust-Dxv6L6Ol.js +0 -1
- package/web-ui/build/static/sas-B2aGiUg2.js +0 -1
- package/web-ui/build/static/sas-Cbzi-GmN.js +0 -1
- package/web-ui/build/static/sass-DwAAr7qH.js +0 -1
- package/web-ui/build/static/scala-CNOqwEfe.js +0 -1
- package/web-ui/build/static/scala-DxlUiOFp.js +0 -1
- package/web-ui/build/static/scheme-B1ALEy7P.js +0 -1
- package/web-ui/build/static/scheme-DUNdLa4B.js +0 -1
- package/web-ui/build/static/scilab-C6Y0UImx.js +0 -1
- package/web-ui/build/static/scss-8m-w5Uh_.js +0 -1
- package/web-ui/build/static/scss-C_igD-9N.js +0 -1
- package/web-ui/build/static/shell-CTp1MeZM.js +0 -1
- package/web-ui/build/static/shell-session-CN3B6Mtp.js +0 -1
- package/web-ui/build/static/smali-DMehnCvR.js +0 -1
- package/web-ui/build/static/smali-DUPqcHaD.js +0 -1
- package/web-ui/build/static/smalltalk-BZWXwh4-.js +0 -1
- package/web-ui/build/static/smalltalk-Jd4VA-e4.js +0 -1
- package/web-ui/build/static/smarty-2BmLPFNh.js +0 -1
- package/web-ui/build/static/sml-BC5HDEBf.js +0 -1
- package/web-ui/build/static/sml-BrJo7y64.js +0 -1
- package/web-ui/build/static/solidity-muZ3xQn0.js +0 -1
- package/web-ui/build/static/solution-file-CF9Xt6f6.js +0 -1
- package/web-ui/build/static/soy-DZg8DGEU.js +0 -1
- package/web-ui/build/static/sparql-kmkyqBAK.js +0 -1
- package/web-ui/build/static/splunk-spl-CmBLwT62.js +0 -1
- package/web-ui/build/static/sqf-Ct-q_HqH.js +0 -1
- package/web-ui/build/static/sqf-DSuUvyV6.js +0 -1
- package/web-ui/build/static/sql-BKhJK7dD.js +0 -1
- package/web-ui/build/static/sql-MRpfxEIR.js +0 -1
- package/web-ui/build/static/sql_more-By_l7rJw.js +0 -1
- package/web-ui/build/static/squirrel-Oyf4apfe.js +0 -1
- package/web-ui/build/static/stan-CYPvm7ay.js +0 -1
- package/web-ui/build/static/stan-OSfpjfxd.js +0 -1
- package/web-ui/build/static/stata-BN_7-HVj.js +0 -1
- package/web-ui/build/static/step21-B0MUaGQd.js +0 -1
- package/web-ui/build/static/stylus-B2zpewvs.js +0 -1
- package/web-ui/build/static/stylus-CiP04Uso.js +0 -1
- package/web-ui/build/static/subunit-Ccz6OcJn.js +0 -1
- package/web-ui/build/static/swift-DWAzs8_N.js +0 -1
- package/web-ui/build/static/swift-ssBR_Hx9.js +0 -1
- package/web-ui/build/static/systemd-CT9j1seU.js +0 -1
- package/web-ui/build/static/t4-cs-B81S0qkn.js +0 -1
- package/web-ui/build/static/t4-templating-CR8sHwkP.js +0 -1
- package/web-ui/build/static/t4-vb-AK-9z7xL.js +0 -1
- package/web-ui/build/static/taggerscript-BWTFecfl.js +0 -1
- package/web-ui/build/static/tap-BuWdU6cR.js +0 -1
- package/web-ui/build/static/tap-CvD65fMN.js +0 -1
- package/web-ui/build/static/tcl-CWTwAImW.js +0 -1
- package/web-ui/build/static/tcl-DxPPqU89.js +0 -1
- package/web-ui/build/static/textile-Bb8aIOgT.js +0 -1
- package/web-ui/build/static/thrift-BSdmFMYv.js +0 -1
- package/web-ui/build/static/toml-CYmQZs0L.js +0 -1
- package/web-ui/build/static/tp-Bt1wA2RW.js +0 -1
- package/web-ui/build/static/tremor-EDFsRn35.js +0 -1
- package/web-ui/build/static/tsx-CRpZ39XI.js +0 -1
- package/web-ui/build/static/tt2-C0lRkX9G.js +0 -1
- package/web-ui/build/static/turtle-i57e7COQ.js +0 -1
- package/web-ui/build/static/twig-DLmpdej0.js +0 -1
- package/web-ui/build/static/twig-DwotmZ4d.js +0 -1
- package/web-ui/build/static/typescript-C02UFCEu.js +0 -1
- package/web-ui/build/static/typescript-Dv4852yn.js +0 -1
- package/web-ui/build/static/typoscript-DsiStA8T.js +0 -1
- package/web-ui/build/static/unrealscript-DREvLy9b.js +0 -1
- package/web-ui/build/static/uorazor-DjjRGSlO.js +0 -1
- package/web-ui/build/static/uri-DNx0Ltr1.js +0 -1
- package/web-ui/build/static/v-BtcT9t45.js +0 -1
- package/web-ui/build/static/vala-CtrGtWLL.js +0 -1
- package/web-ui/build/static/vala-DGVJkbdQ.js +0 -1
- package/web-ui/build/static/vbnet-9N5EIy45.js +0 -1
- package/web-ui/build/static/vbnet-C8V-5wZc.js +0 -1
- package/web-ui/build/static/vbscript-C5ZX035F.js +0 -1
- package/web-ui/build/static/vbscript-html-Dk-JOSq9.js +0 -1
- package/web-ui/build/static/velocity-CMJONQlV.js +0 -1
- package/web-ui/build/static/verilog-B448hVUF.js +0 -1
- package/web-ui/build/static/verilog-D9rg9wGb.js +0 -1
- package/web-ui/build/static/vhdl-B0K99MAb.js +0 -1
- package/web-ui/build/static/vhdl-BLJZCy5e.js +0 -1
- package/web-ui/build/static/vim-CYLY4wFr.js +0 -1
- package/web-ui/build/static/vim-DE6BqLa5.js +0 -1
- package/web-ui/build/static/visual-basic-BwcdH-Kn.js +0 -1
- package/web-ui/build/static/warpscript-BbfcoHYW.js +0 -1
- package/web-ui/build/static/wasm-DHUeRG-u.js +0 -1
- package/web-ui/build/static/web-idl-BE2wsaTW.js +0 -1
- package/web-ui/build/static/wiki-D-OoB7Gs.js +0 -1
- package/web-ui/build/static/wolfram-D-AbA_lC.js +0 -1
- package/web-ui/build/static/wren-M0B5FCO6.js +0 -1
- package/web-ui/build/static/x86asm-Gg-JtiBh.js +0 -1
- package/web-ui/build/static/xeora-BeNNN_-l.js +0 -1
- package/web-ui/build/static/xl-C1jOa_4Q.js +0 -1
- package/web-ui/build/static/xml-doc-BwW35pek.js +0 -1
- package/web-ui/build/static/xml-zQuyG7Gq.js +0 -1
- package/web-ui/build/static/xojo-Bf6Y1tsn.js +0 -1
- package/web-ui/build/static/xquery-5ZEPqG2y.js +0 -1
- package/web-ui/build/static/xquery-OpQT69RV.js +0 -1
- package/web-ui/build/static/yaml-CWnr1ERL.js +0 -1
- package/web-ui/build/static/yaml-D9QDmLde.js +0 -1
- package/web-ui/build/static/yang-DSZmLri0.js +0 -1
- package/web-ui/build/static/zephir-C5UVIt-7.js +0 -1
- package/web-ui/build/static/zig-B1yDYj97.js +0 -1
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end integration tests for the external-channel relay path.
|
|
3
|
+
*
|
|
4
|
+
* Simulates a full `stream_complete` WebSocket broadcast hitting both
|
|
5
|
+
* DiscordService and TelegramService, with a mock send surface attached
|
|
6
|
+
* to each, and verifies:
|
|
7
|
+
* - Only content inside <external>…</external> reaches the mock send.
|
|
8
|
+
* - Blocks route to the correct channels via alias matching.
|
|
9
|
+
* - Substring/case-insensitive alias resolution works end-to-end.
|
|
10
|
+
* - Default (no-to) blocks broadcast to every bridge owned by the service.
|
|
11
|
+
* - Content outside <external> never leaves the process.
|
|
12
|
+
* - Cross-service isolation: a block addressed to `telegram` is NOT
|
|
13
|
+
* forwarded by Discord, and vice-versa.
|
|
14
|
+
*
|
|
15
|
+
* We mock:
|
|
16
|
+
* - `fs` (both services write config; mocks short-circuit it)
|
|
17
|
+
* - `utilities/userDataDir.js` (avoids touching real disk paths)
|
|
18
|
+
* - The discord.js `channels.fetch` / `channel.send` surface on the
|
|
19
|
+
* Discord client used for outbound message relay.
|
|
20
|
+
*
|
|
21
|
+
* What's intentionally real:
|
|
22
|
+
* - The channel filter and alias resolver (the unit under test).
|
|
23
|
+
* - The relay functions themselves, including message splitting,
|
|
24
|
+
* interaction lookup, and session targeting.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
|
|
28
|
+
import { createMockLogger } from '../../__test-utils__/mockFactories.js';
|
|
29
|
+
|
|
30
|
+
jest.unstable_mockModule('fs', () => ({
|
|
31
|
+
promises: {
|
|
32
|
+
mkdir: jest.fn().mockResolvedValue(undefined),
|
|
33
|
+
readFile: jest.fn().mockRejectedValue(new Error('ENOENT')),
|
|
34
|
+
writeFile: jest.fn().mockResolvedValue(undefined),
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
jest.unstable_mockModule('../../utilities/userDataDir.js', () => ({
|
|
39
|
+
getUserDataPaths: () => ({ base: '/mock/data' }),
|
|
40
|
+
ensureUserDataDirs: jest.fn().mockResolvedValue(undefined),
|
|
41
|
+
}));
|
|
42
|
+
|
|
43
|
+
const { DiscordService, DISCORD_STATUS } = await import('../discordService.js');
|
|
44
|
+
const { TelegramService, TELEGRAM_STATUS } = await import('../telegramService.js');
|
|
45
|
+
|
|
46
|
+
// ───────────────────────── Discord relay harness ─────────────────────────
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Stand up a DiscordService wired with mock channel/send surfaces so the
|
|
50
|
+
* real relay code path can run end-to-end. Seeds `recentInteractions`
|
|
51
|
+
* with two bridged channels for the given agent (#ops and #general).
|
|
52
|
+
*/
|
|
53
|
+
function makeDiscordHarness({ agentId = 'agent-x', extraChannels = [] } = {}) {
|
|
54
|
+
const logger = createMockLogger();
|
|
55
|
+
const service = new DiscordService(logger);
|
|
56
|
+
service.status = DISCORD_STATUS.CONNECTED;
|
|
57
|
+
|
|
58
|
+
// Mock an agent pool so relay can resolve agent name.
|
|
59
|
+
service.setAgentPool({
|
|
60
|
+
getAgent: jest.fn().mockResolvedValue({ id: agentId, name: 'Agent X' }),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Mock Discord client surface: `channels.fetch(id) → { send(text) }`.
|
|
64
|
+
const sends = []; // flat log of every channel.send call, in order
|
|
65
|
+
const makeChannel = (channelId) => ({
|
|
66
|
+
send: jest.fn(async (text) => {
|
|
67
|
+
sends.push({ channelId, text });
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
service.client = {
|
|
71
|
+
channels: {
|
|
72
|
+
fetch: jest.fn(async (channelId) => makeChannel(channelId)),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Seed two bridged channels in the same guild.
|
|
77
|
+
const channels = [
|
|
78
|
+
{
|
|
79
|
+
key: 'guild-1:chan-ops',
|
|
80
|
+
interaction: {
|
|
81
|
+
channelKey: 'guild-1:chan-ops',
|
|
82
|
+
channelId: 'chan-ops',
|
|
83
|
+
channelName: 'ops',
|
|
84
|
+
guildId: 'guild-1',
|
|
85
|
+
guildName: 'Acme',
|
|
86
|
+
timestamp: Date.now(),
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
key: 'guild-1:chan-general',
|
|
91
|
+
interaction: {
|
|
92
|
+
channelKey: 'guild-1:chan-general',
|
|
93
|
+
channelId: 'chan-general',
|
|
94
|
+
channelName: 'general',
|
|
95
|
+
guildId: 'guild-1',
|
|
96
|
+
guildName: 'Acme',
|
|
97
|
+
timestamp: Date.now(),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
...extraChannels,
|
|
101
|
+
];
|
|
102
|
+
for (const { key, interaction } of channels) {
|
|
103
|
+
service.recentInteractions.set(`${agentId}:${key}`, interaction);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return { service, sends, agentId };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
describe('Discord relay — end-to-end via _handleBroadcastEvent', () => {
|
|
110
|
+
let harness;
|
|
111
|
+
|
|
112
|
+
beforeEach(() => {
|
|
113
|
+
harness = makeDiscordHarness();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('stream_complete with no <external> → nothing sent', async () => {
|
|
117
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
118
|
+
type: 'stream_complete',
|
|
119
|
+
data: { agentId: harness.agentId, content: 'private planning\nno tags at all' },
|
|
120
|
+
});
|
|
121
|
+
expect(harness.sends).toEqual([]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('role=user is skipped (safety for non-assistant relays)', async () => {
|
|
125
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
126
|
+
type: 'stream_complete',
|
|
127
|
+
data: {
|
|
128
|
+
agentId: harness.agentId,
|
|
129
|
+
role: 'user',
|
|
130
|
+
content: '<external>this should never leak</external>',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
expect(harness.sends).toEqual([]);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('default <external> block broadcasts to every bridged Discord channel', async () => {
|
|
137
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
138
|
+
type: 'stream_complete',
|
|
139
|
+
data: {
|
|
140
|
+
agentId: harness.agentId,
|
|
141
|
+
content: '<external>broadcast line</external>',
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
const channelIds = harness.sends.map(s => s.channelId).sort();
|
|
145
|
+
expect(channelIds).toEqual(['chan-general', 'chan-ops'].sort());
|
|
146
|
+
// Every send includes the agent header prefix plus the content.
|
|
147
|
+
for (const s of harness.sends) {
|
|
148
|
+
expect(s.text).toContain('Agent X');
|
|
149
|
+
expect(s.text).toContain('broadcast line');
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('targeted block with substring alias → only matching channel', async () => {
|
|
154
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
155
|
+
type: 'stream_complete',
|
|
156
|
+
data: {
|
|
157
|
+
agentId: harness.agentId,
|
|
158
|
+
content: '<external to="#ops">ops only</external>',
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
expect(harness.sends).toHaveLength(1);
|
|
162
|
+
expect(harness.sends[0].channelId).toBe('chan-ops');
|
|
163
|
+
expect(harness.sends[0].text).toContain('ops only');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
test('multi-alias to= sends to each matching channel once', async () => {
|
|
167
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
168
|
+
type: 'stream_complete',
|
|
169
|
+
data: {
|
|
170
|
+
agentId: harness.agentId,
|
|
171
|
+
content: '<external to="#ops,#general">both</external>',
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
const ids = harness.sends.map(s => s.channelId).sort();
|
|
175
|
+
expect(ids).toEqual(['chan-general', 'chan-ops'].sort());
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test('content OUTSIDE <external> never leaves the service', async () => {
|
|
179
|
+
const content =
|
|
180
|
+
'internal planning that must stay local\n' +
|
|
181
|
+
'```json\n{"toolId":"terminal","parameters":{}}\n```\n' +
|
|
182
|
+
'<external to="#ops">only this</external>';
|
|
183
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
184
|
+
type: 'stream_complete',
|
|
185
|
+
data: { agentId: harness.agentId, content },
|
|
186
|
+
});
|
|
187
|
+
expect(harness.sends).toHaveLength(1);
|
|
188
|
+
expect(harness.sends[0].text).toContain('only this');
|
|
189
|
+
expect(harness.sends[0].text).not.toContain('internal planning');
|
|
190
|
+
expect(harness.sends[0].text).not.toContain('terminal');
|
|
191
|
+
expect(harness.sends[0].text).not.toContain('toolId');
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test('content INSIDE <external> is verbatim — code blocks preserved', async () => {
|
|
195
|
+
const codeBlock = '```js\nconst x = 1;\n```';
|
|
196
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
197
|
+
type: 'stream_complete',
|
|
198
|
+
data: {
|
|
199
|
+
agentId: harness.agentId,
|
|
200
|
+
content: `<external to="#ops">Here:\n${codeBlock}</external>`,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
expect(harness.sends).toHaveLength(1);
|
|
204
|
+
expect(harness.sends[0].text).toContain(codeBlock);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('content INSIDE <external> is verbatim — tool JSON preserved if the agent chose to include it', async () => {
|
|
208
|
+
// Key correctness claim: the filter does NOT second-guess content
|
|
209
|
+
// shape. If the agent wraps a task summary (including raw tool JSON)
|
|
210
|
+
// in <external>, that's the agent's call, and Discord sees it.
|
|
211
|
+
const tool = '```json\n{"toolId":"taskmanager","parameters":{}}\n```';
|
|
212
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
213
|
+
type: 'stream_complete',
|
|
214
|
+
data: {
|
|
215
|
+
agentId: harness.agentId,
|
|
216
|
+
content: `<external to="#ops">Status:\n${tool}</external>`,
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
expect(harness.sends).toHaveLength(1);
|
|
220
|
+
expect(harness.sends[0].text).toContain('toolId');
|
|
221
|
+
expect(harness.sends[0].text).toContain('taskmanager');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('to="*" behaves the same as default (broadcast)', async () => {
|
|
225
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
226
|
+
type: 'stream_complete',
|
|
227
|
+
data: {
|
|
228
|
+
agentId: harness.agentId,
|
|
229
|
+
content: '<external to="*">star</external>',
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
expect(harness.sends.map(s => s.channelId).sort())
|
|
233
|
+
.toEqual(['chan-general', 'chan-ops'].sort());
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('no bridged channels for this agent → nothing sent', async () => {
|
|
237
|
+
// Clear interactions so the agent has no bridges.
|
|
238
|
+
harness.service.recentInteractions.clear();
|
|
239
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
240
|
+
type: 'stream_complete',
|
|
241
|
+
data: {
|
|
242
|
+
agentId: harness.agentId,
|
|
243
|
+
content: '<external>anywhere?</external>',
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
expect(harness.sends).toEqual([]);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
test('cross-service isolation: block addressed to telegram → Discord ignores it', async () => {
|
|
250
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
251
|
+
type: 'stream_complete',
|
|
252
|
+
data: {
|
|
253
|
+
agentId: harness.agentId,
|
|
254
|
+
content: '<external to="telegram">not for discord</external>',
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
expect(harness.sends).toEqual([]);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
test('multiple <external> blocks each routed independently', async () => {
|
|
261
|
+
const content =
|
|
262
|
+
'<external to="#ops">for ops</external>\n' +
|
|
263
|
+
'<external to="#general">for general</external>\n' +
|
|
264
|
+
'<external>for everyone</external>';
|
|
265
|
+
await harness.service._handleBroadcastEvent('session-1', {
|
|
266
|
+
type: 'stream_complete',
|
|
267
|
+
data: { agentId: harness.agentId, content },
|
|
268
|
+
});
|
|
269
|
+
// ops: 1 targeted + 1 broadcast = 2 sends
|
|
270
|
+
// general: 1 targeted + 1 broadcast = 2 sends
|
|
271
|
+
const perChannel = harness.sends.reduce((acc, s) => {
|
|
272
|
+
acc[s.channelId] = (acc[s.channelId] || []);
|
|
273
|
+
acc[s.channelId].push(s.text);
|
|
274
|
+
return acc;
|
|
275
|
+
}, {});
|
|
276
|
+
expect(perChannel['chan-ops']).toHaveLength(2);
|
|
277
|
+
expect(perChannel['chan-general']).toHaveLength(2);
|
|
278
|
+
expect(perChannel['chan-ops'].some(t => t.includes('for ops'))).toBe(true);
|
|
279
|
+
expect(perChannel['chan-ops'].some(t => t.includes('for everyone'))).toBe(true);
|
|
280
|
+
expect(perChannel['chan-general'].some(t => t.includes('for general'))).toBe(true);
|
|
281
|
+
expect(perChannel['chan-general'].some(t => t.includes('for everyone'))).toBe(true);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test('getBridgedChannels exposes the alias list with labels', () => {
|
|
285
|
+
const bridged = harness.service.getBridgedChannels(harness.agentId);
|
|
286
|
+
expect(bridged).toEqual(expect.arrayContaining([
|
|
287
|
+
expect.objectContaining({ alias: 'discord:#ops', label: expect.stringContaining('ops') }),
|
|
288
|
+
expect.objectContaining({ alias: 'discord:#general' }),
|
|
289
|
+
]));
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
test('isAgentBridged returns false for unknown agent, true for seeded agent', () => {
|
|
293
|
+
expect(harness.service.isAgentBridged(harness.agentId)).toBe(true);
|
|
294
|
+
expect(harness.service.isAgentBridged('other-agent')).toBe(false);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
test('isAgentBridged returns false when service disconnected', () => {
|
|
298
|
+
harness.service.status = DISCORD_STATUS.DISCONNECTED;
|
|
299
|
+
expect(harness.service.isAgentBridged(harness.agentId)).toBe(false);
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// ───────────────────────── Telegram relay harness ─────────────────────────
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* TelegramService only sends when `bot.sendMessage` resolves; we stub the
|
|
307
|
+
* minimal surface (sendMessage) and mark the agent as active. The filter
|
|
308
|
+
* + alias wiring we exercise is the same code path Discord uses, via
|
|
309
|
+
* a separate service implementation.
|
|
310
|
+
*/
|
|
311
|
+
function makeTelegramHarness({ agentId = 'agent-y', chatId = 42 } = {}) {
|
|
312
|
+
const logger = createMockLogger();
|
|
313
|
+
const service = new TelegramService(logger);
|
|
314
|
+
service.status = TELEGRAM_STATUS.CONNECTED;
|
|
315
|
+
service.chatId = chatId;
|
|
316
|
+
service.activeAgentIds.add(agentId);
|
|
317
|
+
// The event handler short-circuits on `!this.bot`; populate a stub so the
|
|
318
|
+
// relay pipeline runs. Our `_send` override is the real interception point.
|
|
319
|
+
service.bot = { sendMessage: jest.fn() };
|
|
320
|
+
service.setAgentPool({
|
|
321
|
+
getAgent: jest.fn().mockResolvedValue({ id: agentId, name: 'Agent Y' }),
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// Intercept the real underlying `_send` to avoid hitting node-telegram-bot-api.
|
|
325
|
+
const sends = [];
|
|
326
|
+
service._send = jest.fn(async (chatIdArg, text) => {
|
|
327
|
+
sends.push({ chatId: chatIdArg, text });
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
return { service, sends, agentId, chatId };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
describe('Telegram relay — end-to-end via _handleBroadcastEvent', () => {
|
|
334
|
+
let harness;
|
|
335
|
+
|
|
336
|
+
beforeEach(() => {
|
|
337
|
+
harness = makeTelegramHarness();
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
test('no <external> block → nothing sent', async () => {
|
|
341
|
+
await harness.service._handleBroadcastEvent({
|
|
342
|
+
type: 'stream_complete',
|
|
343
|
+
data: { agentId: harness.agentId, content: 'plain reasoning only' },
|
|
344
|
+
});
|
|
345
|
+
expect(harness.sends).toEqual([]);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
test('default <external> relays to the chat', async () => {
|
|
349
|
+
await harness.service._handleBroadcastEvent({
|
|
350
|
+
type: 'stream_complete',
|
|
351
|
+
data: {
|
|
352
|
+
agentId: harness.agentId,
|
|
353
|
+
content: '<external>hi from agent</external>',
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
expect(harness.sends).toHaveLength(1);
|
|
357
|
+
expect(harness.sends[0].chatId).toBe(harness.chatId);
|
|
358
|
+
expect(harness.sends[0].text).toContain('hi from agent');
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
test('to="telegram" routes correctly', async () => {
|
|
362
|
+
await harness.service._handleBroadcastEvent({
|
|
363
|
+
type: 'stream_complete',
|
|
364
|
+
data: {
|
|
365
|
+
agentId: harness.agentId,
|
|
366
|
+
content: '<external to="telegram">direct</external>',
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
expect(harness.sends).toHaveLength(1);
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
test('to="discord:#ops" is NOT relayed by Telegram (cross-service isolation)', async () => {
|
|
373
|
+
await harness.service._handleBroadcastEvent({
|
|
374
|
+
type: 'stream_complete',
|
|
375
|
+
data: {
|
|
376
|
+
agentId: harness.agentId,
|
|
377
|
+
content: '<external to="discord:#ops">wrong channel</external>',
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
expect(harness.sends).toEqual([]);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
test('broadcast (default) reaches Telegram exactly once per block', async () => {
|
|
384
|
+
const content =
|
|
385
|
+
'<external>A</external>\n' +
|
|
386
|
+
'<external>B</external>\n' +
|
|
387
|
+
'<external to="telegram">C</external>';
|
|
388
|
+
await harness.service._handleBroadcastEvent({
|
|
389
|
+
type: 'stream_complete',
|
|
390
|
+
data: { agentId: harness.agentId, content },
|
|
391
|
+
});
|
|
392
|
+
expect(harness.sends).toHaveLength(3);
|
|
393
|
+
expect(harness.sends.map(s => s.text).join('|')).toMatch(/A.*B.*C/s);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
test('agent not in activeAgentIds → nothing sent', async () => {
|
|
397
|
+
harness.service.activeAgentIds.clear();
|
|
398
|
+
await harness.service._handleBroadcastEvent({
|
|
399
|
+
type: 'stream_complete',
|
|
400
|
+
data: {
|
|
401
|
+
agentId: harness.agentId,
|
|
402
|
+
content: '<external>quiet please</external>',
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
expect(harness.sends).toEqual([]);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
test('service disconnected → nothing sent even with <external>', async () => {
|
|
409
|
+
harness.service.status = TELEGRAM_STATUS.DISCONNECTED;
|
|
410
|
+
await harness.service._handleBroadcastEvent({
|
|
411
|
+
type: 'stream_complete',
|
|
412
|
+
data: {
|
|
413
|
+
agentId: harness.agentId,
|
|
414
|
+
content: '<external>anyone?</external>',
|
|
415
|
+
},
|
|
416
|
+
});
|
|
417
|
+
expect(harness.sends).toEqual([]);
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
test('content outside <external> never leaves the service', async () => {
|
|
421
|
+
await harness.service._handleBroadcastEvent({
|
|
422
|
+
type: 'stream_complete',
|
|
423
|
+
data: {
|
|
424
|
+
agentId: harness.agentId,
|
|
425
|
+
content:
|
|
426
|
+
'private thought chain\n' +
|
|
427
|
+
'```json\n{"toolId":"memory","parameters":{}}\n```\n' +
|
|
428
|
+
'<external>only this part</external>',
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
expect(harness.sends).toHaveLength(1);
|
|
432
|
+
expect(harness.sends[0].text).toContain('only this part');
|
|
433
|
+
expect(harness.sends[0].text).not.toContain('private thought');
|
|
434
|
+
expect(harness.sends[0].text).not.toContain('memory');
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
test('getBridgedChannels returns the telegram alias when bridged, empty otherwise', () => {
|
|
438
|
+
expect(harness.service.getBridgedChannels(harness.agentId))
|
|
439
|
+
.toEqual([{ alias: 'telegram', label: 'Telegram chat' }]);
|
|
440
|
+
expect(harness.service.getBridgedChannels('other-agent')).toEqual([]);
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// ─────────────────── Cross-service: one broadcast, two services ───────────────────
|
|
445
|
+
|
|
446
|
+
describe('Cross-service isolation: a single agent response splits across platforms', () => {
|
|
447
|
+
test('Discord takes its blocks, Telegram takes its own, neither overreaches', async () => {
|
|
448
|
+
const agentId = 'agent-split';
|
|
449
|
+
|
|
450
|
+
const discord = makeDiscordHarness({ agentId });
|
|
451
|
+
const telegram = makeTelegramHarness({ agentId, chatId: 77 });
|
|
452
|
+
|
|
453
|
+
// Representative content shape matching what stream_complete carries
|
|
454
|
+
// for either Responses API or Chat Completions after the bridge.
|
|
455
|
+
const content =
|
|
456
|
+
'Private reasoning the operator sees.\n' +
|
|
457
|
+
'**Calling taskmanager** — type: complete…\n' +
|
|
458
|
+
'```json\n{"toolId":"taskmanager","parameters":{"actions":[{"type":"complete","taskId":"t-1"}]}}\n```\n\n' +
|
|
459
|
+
'<external to="discord:#ops">\n' +
|
|
460
|
+
'**Deploy finished.** 42 tests passed.\n' +
|
|
461
|
+
'```bash\nnpm test\n```\n' +
|
|
462
|
+
'</external>\n\n' +
|
|
463
|
+
'<external to="telegram">✅ deploy ok</external>\n\n' +
|
|
464
|
+
'<external>general broadcast for every bridge</external>';
|
|
465
|
+
|
|
466
|
+
const broadcast = { type: 'stream_complete', data: { agentId, content } };
|
|
467
|
+
await Promise.all([
|
|
468
|
+
discord.service._handleBroadcastEvent('session-1', broadcast),
|
|
469
|
+
telegram.service._handleBroadcastEvent(broadcast),
|
|
470
|
+
]);
|
|
471
|
+
|
|
472
|
+
// Discord should receive:
|
|
473
|
+
// - the #ops block once (to discord:#ops only)
|
|
474
|
+
// - the general broadcast twice (once per bridged Discord channel)
|
|
475
|
+
// ... and NEVER the telegram-only block.
|
|
476
|
+
const opsSends = discord.sends.filter(s => s.channelId === 'chan-ops');
|
|
477
|
+
const genSends = discord.sends.filter(s => s.channelId === 'chan-general');
|
|
478
|
+
expect(opsSends.some(s => s.text.includes('Deploy finished'))).toBe(true);
|
|
479
|
+
expect(opsSends.some(s => s.text.includes('general broadcast'))).toBe(true);
|
|
480
|
+
expect(genSends.some(s => s.text.includes('general broadcast'))).toBe(true);
|
|
481
|
+
// Crucial isolation checks:
|
|
482
|
+
expect(discord.sends.some(s => /deploy ok/i.test(s.text))).toBe(false);
|
|
483
|
+
expect(discord.sends.some(s => /Private reasoning/i.test(s.text))).toBe(false);
|
|
484
|
+
expect(discord.sends.some(s => /Calling taskmanager/i.test(s.text))).toBe(false);
|
|
485
|
+
|
|
486
|
+
// Telegram should receive:
|
|
487
|
+
// - its own block
|
|
488
|
+
// - the general broadcast (once)
|
|
489
|
+
// ... and NEVER the discord-specific block or internal content.
|
|
490
|
+
expect(telegram.sends.some(s => /deploy ok/i.test(s.text))).toBe(true);
|
|
491
|
+
expect(telegram.sends.some(s => /general broadcast/i.test(s.text))).toBe(true);
|
|
492
|
+
expect(telegram.sends.some(s => /Deploy finished/i.test(s.text))).toBe(false);
|
|
493
|
+
expect(telegram.sends.some(s => /Private reasoning/i.test(s.text))).toBe(false);
|
|
494
|
+
expect(telegram.sends.some(s => /taskmanager/i.test(s.text))).toBe(false);
|
|
495
|
+
});
|
|
496
|
+
});
|
|
@@ -121,7 +121,7 @@ describe('Flow: Full message round-trip', () => {
|
|
|
121
121
|
await service._handleBroadcastEvent('discord-guild-1-ch-1', {
|
|
122
122
|
type: 'stream_complete',
|
|
123
123
|
agentId: 'agent-alpha',
|
|
124
|
-
content: 'Recursion is when a function calls itself
|
|
124
|
+
content: '<external>Recursion is when a function calls itself.</external>'
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
// Step 4: Verify response was sent to the correct channel
|
|
@@ -136,12 +136,12 @@ describe('Flow: Full message round-trip', () => {
|
|
|
136
136
|
const msg = createDiscordMessage('write a long essay');
|
|
137
137
|
await service._handleMessage(msg);
|
|
138
138
|
|
|
139
|
-
// Simulate a response longer than Discord's limit
|
|
139
|
+
// Simulate a response longer than Discord's limit, wrapped for relay
|
|
140
140
|
const longContent = 'A'.repeat(3500);
|
|
141
141
|
await service._handleBroadcastEvent('discord-guild-1-ch-1', {
|
|
142
142
|
type: 'stream_complete',
|
|
143
143
|
agentId: 'agent-alpha',
|
|
144
|
-
content: longContent
|
|
144
|
+
content: `<external>${longContent}</external>`
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
// Should have split into multiple messages
|
|
@@ -259,11 +259,11 @@ describe('Flow: Multi-channel response isolation', () => {
|
|
|
259
259
|
const msg = createDiscordMessage('hello', { guildId: 'g1', channelId: 'chA' });
|
|
260
260
|
await service._handleMessage(msg);
|
|
261
261
|
|
|
262
|
-
// Agent responds via broadcast
|
|
262
|
+
// Agent responds via broadcast (wrapped for external relay)
|
|
263
263
|
await service._handleBroadcastEvent('discord-g1-chA', {
|
|
264
264
|
type: 'stream_complete',
|
|
265
265
|
agentId: 'agent-1',
|
|
266
|
-
content: 'Hi there
|
|
266
|
+
content: '<external>Hi there!</external>'
|
|
267
267
|
});
|
|
268
268
|
|
|
269
269
|
// Channel A should get the response
|
|
@@ -281,10 +281,10 @@ describe('Flow: Multi-channel response isolation', () => {
|
|
|
281
281
|
const msgB = createDiscordMessage('question B', { guildId: 'g1', channelId: 'chB' });
|
|
282
282
|
await service._handleMessage(msgB);
|
|
283
283
|
|
|
284
|
-
// Agent responds (to question A)
|
|
284
|
+
// Agent responds (to question A) — wrapped for external relay
|
|
285
285
|
await service._relayAgentResponse({
|
|
286
286
|
agentId: 'agent-1',
|
|
287
|
-
content: 'Answer A'
|
|
287
|
+
content: '<external>Answer A</external>'
|
|
288
288
|
});
|
|
289
289
|
|
|
290
290
|
// Both channels should get the response (both have recent interaction)
|
|
@@ -300,7 +300,7 @@ describe('Flow: Multi-channel response isolation', () => {
|
|
|
300
300
|
|
|
301
301
|
await service._relayAgentResponse({
|
|
302
302
|
agentId: 'agent-1',
|
|
303
|
-
content: 'Answer B'
|
|
303
|
+
content: '<external>Answer B</external>'
|
|
304
304
|
});
|
|
305
305
|
|
|
306
306
|
// Only channel B should get it now
|
|
@@ -598,11 +598,11 @@ describe('Flow: Thread-level routing', () => {
|
|
|
598
598
|
});
|
|
599
599
|
await service._handleMessage(msg);
|
|
600
600
|
|
|
601
|
-
// Agent responds
|
|
601
|
+
// Agent responds — wrapped for external relay
|
|
602
602
|
await service._handleBroadcastEvent('session', {
|
|
603
603
|
type: 'stream_complete',
|
|
604
604
|
agentId: 'a1',
|
|
605
|
-
content: 'answer'
|
|
605
|
+
content: '<external>answer</external>'
|
|
606
606
|
});
|
|
607
607
|
|
|
608
608
|
// Response should go to the thread, not the parent
|
|
@@ -382,17 +382,22 @@ describe('DiscordService', () => {
|
|
|
382
382
|
mockChannel.send.mockClear();
|
|
383
383
|
});
|
|
384
384
|
|
|
385
|
-
test('relays
|
|
385
|
+
test('relays ONLY the <external> portion to a channel with recent interaction', async () => {
|
|
386
|
+
// The relay is opt-in: content without <external> tags stays local.
|
|
387
|
+
// A full response typically mixes private reasoning with a wrapped
|
|
388
|
+
// reply — the wrapped block is all Discord ever sees.
|
|
386
389
|
service.recentInteractions.set('a1:g1:c1', {
|
|
387
390
|
channelKey: 'g1:c1',
|
|
388
391
|
channelId: 'c1',
|
|
392
|
+
channelName: 'ops',
|
|
389
393
|
guildId: 'g1',
|
|
394
|
+
guildName: 'Acme',
|
|
390
395
|
timestamp: Date.now()
|
|
391
396
|
});
|
|
392
397
|
|
|
393
398
|
await service._relayAgentResponse({
|
|
394
399
|
agentId: 'a1',
|
|
395
|
-
content: 'Here is my answer',
|
|
400
|
+
content: 'private planning\n<external>Here is my answer</external>\nstill local',
|
|
396
401
|
type: 'stream_complete'
|
|
397
402
|
});
|
|
398
403
|
|
|
@@ -401,6 +406,8 @@ describe('DiscordService', () => {
|
|
|
401
406
|
const sentText = mockChannel.send.mock.calls[0][0];
|
|
402
407
|
expect(sentText).toContain('TestAgent');
|
|
403
408
|
expect(sentText).toContain('Here is my answer');
|
|
409
|
+
expect(sentText).not.toContain('private planning');
|
|
410
|
+
expect(sentText).not.toContain('still local');
|
|
404
411
|
});
|
|
405
412
|
|
|
406
413
|
test('does NOT relay when no recent interaction for agent', async () => {
|
|
@@ -413,7 +420,7 @@ describe('DiscordService', () => {
|
|
|
413
420
|
expect(mockChannel.send).not.toHaveBeenCalled();
|
|
414
421
|
});
|
|
415
422
|
|
|
416
|
-
test('does NOT relay expired interactions (TTL)', async () => {
|
|
423
|
+
test('does NOT relay expired interactions (TTL) — even with an <external> block', async () => {
|
|
417
424
|
service.recentInteractions.set('a1:g1:c1', {
|
|
418
425
|
channelKey: 'g1:c1',
|
|
419
426
|
channelId: 'c1',
|
|
@@ -423,7 +430,7 @@ describe('DiscordService', () => {
|
|
|
423
430
|
|
|
424
431
|
await service._relayAgentResponse({
|
|
425
432
|
agentId: 'a1',
|
|
426
|
-
content: 'Hello'
|
|
433
|
+
content: '<external>Hello</external>'
|
|
427
434
|
});
|
|
428
435
|
|
|
429
436
|
expect(mockChannel.send).not.toHaveBeenCalled();
|
|
@@ -434,13 +441,13 @@ describe('DiscordService', () => {
|
|
|
434
441
|
test('relays only to the correct agent channels', async () => {
|
|
435
442
|
// agent-1 has interaction on c1, agent-2 has interaction on c2
|
|
436
443
|
service.recentInteractions.set('a1:g1:c1', {
|
|
437
|
-
channelKey: 'g1:c1', channelId: 'c1', guildId: 'g1', timestamp: Date.now()
|
|
444
|
+
channelKey: 'g1:c1', channelId: 'c1', channelName: 'ops', guildId: 'g1', timestamp: Date.now()
|
|
438
445
|
});
|
|
439
446
|
service.recentInteractions.set('a2:g1:c2', {
|
|
440
|
-
channelKey: 'g1:c2', channelId: 'c2', guildId: 'g1', timestamp: Date.now()
|
|
447
|
+
channelKey: 'g1:c2', channelId: 'c2', channelName: 'other', guildId: 'g1', timestamp: Date.now()
|
|
441
448
|
});
|
|
442
449
|
|
|
443
|
-
await service._relayAgentResponse({ agentId: 'a1', content: 'Reply from a1' });
|
|
450
|
+
await service._relayAgentResponse({ agentId: 'a1', content: '<external>Reply from a1</external>' });
|
|
444
451
|
|
|
445
452
|
// Should only fetch c1, not c2
|
|
446
453
|
expect(service.client.channels.fetch).toHaveBeenCalledWith('c1');
|
|
@@ -297,7 +297,9 @@ class AIService {
|
|
|
297
297
|
// Respect options.maxTokens if provided (e.g., from compaction service)
|
|
298
298
|
max_tokens: Math.min(options.maxTokens || this.modelSpecs[model]?.maxTokens || COMPACTION_CONFIG.MAX_OUTPUT_TOKENS, COMPACTION_CONFIG.MAX_OUTPUT_TOKENS),
|
|
299
299
|
temperature: options.temperature || 0.7,
|
|
300
|
-
stream: options.stream || false
|
|
300
|
+
stream: options.stream || false,
|
|
301
|
+
// Native function-call tools — same convention as the streaming path.
|
|
302
|
+
...(Array.isArray(options.tools) && options.tools.length > 0 && { tools: options.tools }),
|
|
301
303
|
},
|
|
302
304
|
metadata: {
|
|
303
305
|
requestId,
|
|
@@ -409,7 +411,11 @@ class AIService {
|
|
|
409
411
|
options: {
|
|
410
412
|
max_tokens: Math.min(options.maxTokens || this.modelSpecs[model]?.maxTokens || COMPACTION_CONFIG.MAX_OUTPUT_TOKENS, COMPACTION_CONFIG.MAX_OUTPUT_TOKENS),
|
|
411
413
|
temperature: options.temperature || 0.7,
|
|
412
|
-
stream: true // Force streaming
|
|
414
|
+
stream: true, // Force streaming
|
|
415
|
+
// Native function-call tools. CLI owns the tool catalog; backend
|
|
416
|
+
// forwards these verbatim to the Responses API (and ignores for
|
|
417
|
+
// chat-completion models). See src/tools/openaiFunctionSchemas.js.
|
|
418
|
+
...(Array.isArray(options.tools) && options.tools.length > 0 && { tools: options.tools }),
|
|
413
419
|
},
|
|
414
420
|
metadata: {
|
|
415
421
|
requestId,
|
|
@@ -426,7 +432,8 @@ class AIService {
|
|
|
426
432
|
this.logger.info(`Sending streaming message to model: ${model}`, {
|
|
427
433
|
requestId,
|
|
428
434
|
agentId: options.agentId,
|
|
429
|
-
messageCount: Array.isArray(messages) ? messages.length : 1
|
|
435
|
+
messageCount: Array.isArray(messages) ? messages.length : 1,
|
|
436
|
+
toolCount: options.tools?.length || 0,
|
|
430
437
|
});
|
|
431
438
|
|
|
432
439
|
// Make streaming API request
|