onbuzz 3.9.8 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/__tests__/agentScheduler.test.js +129 -0
- package/src/core/agentScheduler.js +3850 -3301
- 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/fileSystemTool.js +27 -3
- package/src/tools/openaiFunctionSchemas.js +270 -0
- package/src/tools/taskManagerTool.js +35 -2
- package/src/tools/terminalTool.js +23 -2
- package/src/utilities/constants.js +886 -871
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-D0gS3Hso.js +1 -0
- package/web-ui/build/static/abap-CyCKEEhS.js +1 -0
- package/web-ui/build/static/abnf-BZBn0pag.js +1 -0
- package/web-ui/build/static/abnf-BpCrg_Bf.js +1 -0
- package/web-ui/build/static/accesslog-DuTggsRZ.js +1 -0
- package/web-ui/build/static/actionscript-Ba9yLObR.js +1 -0
- package/web-ui/build/static/actionscript-C_BTnWxb.js +1 -0
- package/web-ui/build/static/ada-B69_itVh.js +1 -0
- package/web-ui/build/static/ada-DoeTM_BQ.js +1 -0
- package/web-ui/build/static/agda-jCpnVEpX.js +1 -0
- package/web-ui/build/static/al-CakFGn97.js +1 -0
- package/web-ui/build/static/angelscript-CnSUNIGj.js +1 -0
- package/web-ui/build/static/antlr4-Cn-R7SWD.js +1 -0
- package/web-ui/build/static/apache-jWzYeO33.js +1 -0
- package/web-ui/build/static/apacheconf-Qf6ccteC.js +1 -0
- package/web-ui/build/static/apex-BBFeLnmZ.js +1 -0
- package/web-ui/build/static/apl-Id4G-9pR.js +1 -0
- package/web-ui/build/static/applescript-Cndkqqg_.js +1 -0
- package/web-ui/build/static/applescript-De2uOrG8.js +1 -0
- package/web-ui/build/static/aql-Bx0hBEFP.js +1 -0
- package/web-ui/build/static/arcade-kv3B2d64.js +1 -0
- package/web-ui/build/static/arduino-Di5etN7-.js +1 -0
- package/web-ui/build/static/arduino-dzzVGXPJ.js +1 -0
- package/web-ui/build/static/arff-vVmlJyxT.js +1 -0
- package/web-ui/build/static/armasm-CLLemW4j.js +1 -0
- package/web-ui/build/static/asciidoc-5N0GIB1H.js +1 -0
- package/web-ui/build/static/asciidoc-BUQcC9k5.js +1 -0
- package/web-ui/build/static/asm6502-DrvbjZqg.js +1 -0
- package/web-ui/build/static/asmatmel-DXaAmo9p.js +1 -0
- package/web-ui/build/static/aspectj-QEbU6lqv.js +1 -0
- package/web-ui/build/static/aspnet-D1DOd55H.js +1 -0
- package/web-ui/build/static/autohotkey-CeN6Nxl7.js +1 -0
- package/web-ui/build/static/autohotkey-DK33Y-ag.js +1 -0
- package/web-ui/build/static/autoit-Ce15EHmT.js +1 -0
- package/web-ui/build/static/autoit-Du48dS3x.js +1 -0
- package/web-ui/build/static/avisynth-CTNNDQJu.js +1 -0
- package/web-ui/build/static/avrasm-U3bAmy_8.js +1 -0
- package/web-ui/build/static/avro-idl-hdYq5Y_G.js +1 -0
- package/web-ui/build/static/awk-D_y_Ybkz.js +1 -0
- package/web-ui/build/static/axapta-BtorzWAb.js +1 -0
- package/web-ui/build/static/bash-C7jHPzRr.js +1 -0
- package/web-ui/build/static/bash-C8rx4ZX7.js +1 -0
- package/web-ui/build/static/basic-BnB1QbT9.js +1 -0
- package/web-ui/build/static/basic-C3lmrCJn.js +1 -0
- package/web-ui/build/static/batch-D3zfZMkE.js +1 -0
- package/web-ui/build/static/bbcode-CcaWY4r6.js +1 -0
- package/web-ui/build/static/bicep-BTSNjNeE.js +1 -0
- package/web-ui/build/static/birb-FlitQ-CB.js +1 -0
- package/web-ui/build/static/bison-BwUeAPik.js +1 -0
- package/web-ui/build/static/bnf-BO0epnqT.js +1 -0
- package/web-ui/build/static/bnf-Dr7Yhkhf.js +1 -0
- package/web-ui/build/static/brainfuck-CQXtVvdr.js +1 -0
- package/web-ui/build/static/brainfuck-DBI8WFED.js +1 -0
- package/web-ui/build/static/brightscript-DMCw9cpk.js +1 -0
- package/web-ui/build/static/bro-DLuuGrl1.js +1 -0
- package/web-ui/build/static/bsl-YJucc4YV.js +1 -0
- package/web-ui/build/static/c-DhDv7jSS.js +1 -0
- package/web-ui/build/static/c-DxhyzKko.js +1 -0
- package/web-ui/build/static/c-like-DlgSkBV0.js +1 -0
- package/web-ui/build/static/cal-l1d2rfZn.js +1 -0
- package/web-ui/build/static/capnproto-dj8ChcGe.js +1 -0
- package/web-ui/build/static/ceylon-D54yMfbT.js +1 -0
- package/web-ui/build/static/cfscript-D6rZc4oz.js +1 -0
- package/web-ui/build/static/chaiscript-C5TnPhY1.js +1 -0
- package/web-ui/build/static/cil-OfdzNvKT.js +1 -0
- package/web-ui/build/static/clean-CIKWd5m_.js +1 -0
- package/web-ui/build/static/clojure-DPPjCSD9.js +1 -0
- package/web-ui/build/static/clojure-E4hINJlB.js +1 -0
- package/web-ui/build/static/clojure-repl-ByPwVP0v.js +1 -0
- package/web-ui/build/static/cmake-EmgODR4I.js +1 -0
- package/web-ui/build/static/cmake-FzVdKoPQ.js +1 -0
- package/web-ui/build/static/cobol-BCywZ9YX.js +1 -0
- package/web-ui/build/static/coffeescript-B3PJfOGT.js +1 -0
- package/web-ui/build/static/coffeescript-Cn6ayg_l.js +1 -0
- package/web-ui/build/static/concurnas-CDZuVXuU.js +1 -0
- package/web-ui/build/static/coq-CmxamUdH.js +1 -0
- package/web-ui/build/static/coq-OIzJsY4F.js +1 -0
- package/web-ui/build/static/cos-DGL5rP0B.js +1 -0
- package/web-ui/build/static/cpp-6bJ9ZCLp.js +1 -0
- package/web-ui/build/static/cpp-CnpCPPE0.js +1 -0
- package/web-ui/build/static/crmsh-UqfNCx22.js +1 -0
- package/web-ui/build/static/crystal-BZPfo8wh.js +1 -0
- package/web-ui/build/static/crystal-BmnmtxvU.js +1 -0
- package/web-ui/build/static/csharp-Ddd4cQJM.js +1 -0
- package/web-ui/build/static/csharp-Ozmwd4H7.js +1 -0
- package/web-ui/build/static/cshtml-CKUifIKv.js +1 -0
- package/web-ui/build/static/csp-DIKKHabm.js +1 -0
- package/web-ui/build/static/csp-DVNj8KoC.js +1 -0
- package/web-ui/build/static/css-C5xXuaIa.js +1 -0
- package/web-ui/build/static/css-extras-BcO-SjvT.js +1 -0
- package/web-ui/build/static/csv-Ckfvef5r.js +1 -0
- package/web-ui/build/static/cypher-nFX3ujhC.js +1 -0
- package/web-ui/build/static/d-C51vBcAN.js +1 -0
- package/web-ui/build/static/d-C5Zzmfpj.js +1 -0
- package/web-ui/build/static/dart-DTgXq_zq.js +1 -0
- package/web-ui/build/static/dart-nEf62Xtl.js +1 -0
- package/web-ui/build/static/dataweave-BBu_SXNo.js +1 -0
- package/web-ui/build/static/dax-BgSY6VXv.js +1 -0
- package/web-ui/build/static/delphi-BsEFn1Dg.js +1 -0
- package/web-ui/build/static/dhall-DZLoRbRq.js +1 -0
- package/web-ui/build/static/diff-BigjWm8-.js +1 -0
- package/web-ui/build/static/diff-GaoenF5U.js +1 -0
- package/web-ui/build/static/django-BHquQxg_.js +1 -0
- package/web-ui/build/static/django-BklTsfN1.js +1 -0
- package/web-ui/build/static/dns-Fye2v3C_.js +1 -0
- package/web-ui/build/static/dns-zone-file-Cl9DxAn6.js +1 -0
- package/web-ui/build/static/docker-ByXHv0Ly.js +1 -0
- package/web-ui/build/static/dockerfile-C3JvS7wx.js +1 -0
- package/web-ui/build/static/dos-DZjvZtlb.js +1 -0
- package/web-ui/build/static/dot-Ce9RBw-P.js +1 -0
- package/web-ui/build/static/dsconfig-CqzyFCWR.js +1 -0
- package/web-ui/build/static/dts-CzmHan27.js +1 -0
- package/web-ui/build/static/dust-ooMZaltT.js +1 -0
- package/web-ui/build/static/ebnf-BQTW3VN9.js +1 -0
- package/web-ui/build/static/ebnf-BWQPIMhj.js +1 -0
- package/web-ui/build/static/editorconfig-ChULEndb.js +1 -0
- package/web-ui/build/static/eiffel-DNf4Lf6d.js +1 -0
- package/web-ui/build/static/ejs-BN91k0H9.js +1 -0
- package/web-ui/build/static/elixir-BsUN2TJ3.js +1 -0
- package/web-ui/build/static/elixir-DowOmwjw.js +1 -0
- package/web-ui/build/static/elm-BR0-AOlB.js +1 -0
- package/web-ui/build/static/elm-CyQ-Tu1y.js +1 -0
- package/web-ui/build/static/erb-C3-ICRZC.js +1 -0
- package/web-ui/build/static/erb-CDwwnVfP.js +1 -0
- package/web-ui/build/static/erlang-CkKAvBqC.js +1 -0
- package/web-ui/build/static/erlang-b8hjzYg_.js +1 -0
- package/web-ui/build/static/erlang-repl-gGfh3Gx4.js +1 -0
- package/web-ui/build/static/etlua-DD1BETje.js +1 -0
- package/web-ui/build/static/excel-BHUhNjbb.js +1 -0
- package/web-ui/build/static/excel-formula-pygAkTSb.js +1 -0
- package/web-ui/build/static/factor-DGtAXbeO.js +1 -0
- package/web-ui/build/static/false-CmwPZZMx.js +1 -0
- package/web-ui/build/static/firestore-security-rules-BPVh7g3V.js +1 -0
- package/web-ui/build/static/fix-D0X2IrLW.js +1 -0
- package/web-ui/build/static/flix-B_K9PtSC.js +1 -0
- package/web-ui/build/static/flow-Bj8UDWFS.js +1 -0
- package/web-ui/build/static/fortran-CVjlvxYP.js +1 -0
- package/web-ui/build/static/fortran-CeuwkeSi.js +1 -0
- package/web-ui/build/static/fsharp-7ZnhHRI2.js +1 -0
- package/web-ui/build/static/fsharp-Dg0zkEUM.js +1 -0
- package/web-ui/build/static/ftl-DTiv91OH.js +1 -0
- package/web-ui/build/static/gams-mzIliqa9.js +1 -0
- package/web-ui/build/static/gap-CZy17Yrg.js +1 -0
- package/web-ui/build/static/gauss-eN8ZSPsu.js +1 -0
- package/web-ui/build/static/gcode-BilRDZ1d.js +1 -0
- package/web-ui/build/static/gcode-DgLXH4R9.js +1 -0
- package/web-ui/build/static/gdscript-ZYuV2APS.js +1 -0
- package/web-ui/build/static/gedcom-0kGxJiZ9.js +1 -0
- package/web-ui/build/static/gherkin-CCSGpV3s.js +1 -0
- package/web-ui/build/static/gherkin-DGxXFCBT.js +1 -0
- package/web-ui/build/static/git-CdLGzlwT.js +1 -0
- package/web-ui/build/static/glsl-BtFVLAdf.js +1 -0
- package/web-ui/build/static/glsl-pOLV_i61.js +1 -0
- package/web-ui/build/static/gml-BvRYdpYB.js +1 -0
- package/web-ui/build/static/gml-kixDldbq.js +1 -0
- package/web-ui/build/static/gn-B0j6r1ZR.js +1 -0
- package/web-ui/build/static/go-0gVqv26H.js +1 -0
- package/web-ui/build/static/go-hMMVdAxn.js +1 -0
- package/web-ui/build/static/go-module-nQEPOPuc.js +1 -0
- package/web-ui/build/static/golo-Dm43VBu7.js +1 -0
- package/web-ui/build/static/gradle-CHC1_Cae.js +1 -0
- package/web-ui/build/static/graphql-0VBsLded.js +1 -0
- package/web-ui/build/static/groovy-D8pgT7Gh.js +1 -0
- package/web-ui/build/static/groovy-LYh6lufY.js +1 -0
- package/web-ui/build/static/haml-D7TlUCYV.js +1 -0
- package/web-ui/build/static/haml-DM_YbLsX.js +1 -0
- package/web-ui/build/static/handlebars-C6s9z8yY.js +1 -0
- package/web-ui/build/static/handlebars-MmYUBbhF.js +1 -0
- package/web-ui/build/static/haskell-WDNKcSr-.js +1 -0
- package/web-ui/build/static/haskell-uN4RNceQ.js +1 -0
- package/web-ui/build/static/haxe-BfngEDpC.js +1 -0
- package/web-ui/build/static/haxe-Di7jSobz.js +1 -0
- package/web-ui/build/static/hcl-CCY9WaU5.js +1 -0
- package/web-ui/build/static/hlsl-BZeRODlS.js +1 -0
- package/web-ui/build/static/hoon-CYgEwHo6.js +1 -0
- package/web-ui/build/static/hpkp-CDGRQT6H.js +1 -0
- package/web-ui/build/static/hsp-Bd3e6SwQ.js +1 -0
- package/web-ui/build/static/hsts-BOUlTJ6c.js +1 -0
- package/web-ui/build/static/htmlbars-BPiYH0_n.js +1 -0
- package/web-ui/build/static/http-BX5oUCxR.js +1 -0
- package/web-ui/build/static/http-DVroDmj6.js +1 -0
- package/web-ui/build/static/hy-BCcF_QHP.js +1 -0
- package/web-ui/build/static/ichigojam-BiISBr0y.js +1 -0
- package/web-ui/build/static/icon-ClvK1B41.js +1 -0
- package/web-ui/build/static/icu-message-format-DbYDqmui.js +1 -0
- package/web-ui/build/static/idris-DUkwgVYa.js +1 -0
- package/web-ui/build/static/iecst-Dsthm7u9.js +1 -0
- package/web-ui/build/static/ignore-C6sD6BBI.js +1 -0
- package/web-ui/build/static/index-BJi0QI4y.js +13 -0
- package/web-ui/build/static/index-BUtXAjd5.css +1 -0
- package/web-ui/build/static/index-C0yagaf_.js +1 -0
- package/web-ui/build/static/index-rmQCMu11.js +834 -0
- package/web-ui/build/static/inform7-BhpCpaCI.js +1 -0
- package/web-ui/build/static/inform7-CypdUZ2H.js +1 -0
- package/web-ui/build/static/ini-D3bMjLFy.js +1 -0
- package/web-ui/build/static/ini-mZ4DmMFa.js +1 -0
- package/web-ui/build/static/io-CAPenDjW.js +1 -0
- package/web-ui/build/static/irpf90-DMLZfHOl.js +1 -0
- package/web-ui/build/static/isbl-C-heO4bo.js +1 -0
- package/web-ui/build/static/j-CYnuDyva.js +1 -0
- package/web-ui/build/static/java-BwxvO1xU.js +1 -0
- package/web-ui/build/static/java-DrS-TIOG.js +1 -0
- package/web-ui/build/static/javadoc-C7g1nvf0.js +1 -0
- package/web-ui/build/static/javadoclike-BccMcxyJ.js +1 -0
- package/web-ui/build/static/javascript-BTLBzg4X.js +1 -0
- package/web-ui/build/static/javastacktrace-DMfJDkdg.js +1 -0
- package/web-ui/build/static/jboss-cli-Bod2dA9a.js +1 -0
- package/web-ui/build/static/jexl-N6nsHGWj.js +1 -0
- package/web-ui/build/static/jolie-CsrX6xYs.js +1 -0
- package/web-ui/build/static/jq-UVBu2R02.js +1 -0
- package/web-ui/build/static/js-extras-CuwwBN5k.js +1 -0
- package/web-ui/build/static/js-templates-DIBe0p7a.js +1 -0
- package/web-ui/build/static/jsdoc-DtDbuWdy.js +1 -0
- package/web-ui/build/static/json-BI3FHwe1.js +1 -0
- package/web-ui/build/static/json-P6SuA8aJ.js +1 -0
- package/web-ui/build/static/json5-CRP2homn.js +1 -0
- package/web-ui/build/static/jsonp-9ElDctKO.js +1 -0
- package/web-ui/build/static/jsstacktrace-D2Fl9d_V.js +1 -0
- package/web-ui/build/static/jsx-CQTwBhTH.js +1 -0
- package/web-ui/build/static/julia-DuUl4PLy.js +1 -0
- package/web-ui/build/static/julia-nGiK_b-G.js +1 -0
- package/web-ui/build/static/julia-repl-CZXv3gUI.js +1 -0
- package/web-ui/build/static/keepalived-BXuewLUw.js +1 -0
- package/web-ui/build/static/keyman-qJzqzYn7.js +1 -0
- package/web-ui/build/static/kotlin-B9n_utKk.js +1 -0
- package/web-ui/build/static/kotlin-haL4BAuN.js +1 -0
- package/web-ui/build/static/kumir-B3qOyQmg.js +1 -0
- package/web-ui/build/static/kusto-DBaBX58G.js +1 -0
- package/web-ui/build/static/lasso-BKSAUuYM.js +1 -0
- package/web-ui/build/static/latex-BRrZyaQT.js +1 -0
- package/web-ui/build/static/latex-m1lQaqf1.js +1 -0
- package/web-ui/build/static/latte-eiBbKf65.js +1 -0
- package/web-ui/build/static/ldif-y2LZUUyZ.js +1 -0
- package/web-ui/build/static/leaf-hIUS2wti.js +1 -0
- package/web-ui/build/static/less-Bo6R8taI.js +1 -0
- package/web-ui/build/static/less-DuKmENyN.js +1 -0
- package/web-ui/build/static/lilypond-BBpJhRQ9.js +1 -0
- package/web-ui/build/static/liquid-CAprdcX2.js +1 -0
- package/web-ui/build/static/lisp-Bf1XYdUw.js +1 -0
- package/web-ui/build/static/lisp-CK4NShQS.js +1 -0
- package/web-ui/build/static/livecodeserver-D-7DT8n5.js +1 -0
- package/web-ui/build/static/livescript-C53jjB4u.js +1 -0
- package/web-ui/build/static/livescript-C6BLAugR.js +1 -0
- package/web-ui/build/static/llvm-DwsfQGGS.js +1 -0
- package/web-ui/build/static/llvm-x2WOwJip.js +1 -0
- package/web-ui/build/static/log-ycx4d2kp.js +1 -0
- package/web-ui/build/static/lolcode-kQPJj9kJ.js +1 -0
- package/web-ui/build/static/lsl-DYPjhHe3.js +1 -0
- package/web-ui/build/static/lua-DbyfdtuA.js +1 -0
- package/web-ui/build/static/lua-k-RdWswg.js +1 -0
- package/web-ui/build/static/magma-C0BRcgX4.js +1 -0
- package/web-ui/build/static/makefile-CZQdxsni.js +1 -0
- package/web-ui/build/static/makefile-D-G1cICu.js +1 -0
- package/web-ui/build/static/markdown-BXgB-fA-.js +1 -0
- package/web-ui/build/static/markdown-Ce-22f29.js +1 -0
- package/web-ui/build/static/markup-templating-BpdQJTBM.js +1 -0
- package/web-ui/build/static/mathematica-IkAnPpu4.js +1 -0
- package/web-ui/build/static/matlab-D00TnflQ.js +1 -0
- package/web-ui/build/static/matlab-D9nj0uha.js +1 -0
- package/web-ui/build/static/maxima-C7a7zrie.js +1 -0
- package/web-ui/build/static/maxscript-BV3koaAu.js +1 -0
- package/web-ui/build/static/mel-C7fC2vR0.js +1 -0
- package/web-ui/build/static/mel-DUFmm8LA.js +1 -0
- package/web-ui/build/static/mercury-D0zWajPt.js +1 -0
- package/web-ui/build/static/mermaid-BcIFh8lC.js +1 -0
- package/web-ui/build/static/mipsasm-Ch8zsfD7.js +1 -0
- package/web-ui/build/static/mizar-D72L8LdH.js +1 -0
- package/web-ui/build/static/mizar-H2a4eeQU.js +1 -0
- package/web-ui/build/static/mojolicious-CXGZY6wR.js +1 -0
- package/web-ui/build/static/mongodb-ycbZ-Gtu.js +1 -0
- package/web-ui/build/static/monkey-B1PWgo4u.js +1 -0
- package/web-ui/build/static/monkey-BTLKqHiE.js +1 -0
- package/web-ui/build/static/moonscript-CGujt4hQ.js +1 -0
- package/web-ui/build/static/moonscript-Cd65ANue.js +1 -0
- package/web-ui/build/static/n1ql-5SoXRWF5.js +1 -0
- package/web-ui/build/static/n1ql-SrTc8dgR.js +1 -0
- package/web-ui/build/static/n4js-DcydNbvU.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-DgTjIFTD.js +1 -0
- package/web-ui/build/static/naniscript-Cgu0Uhgv.js +1 -0
- package/web-ui/build/static/nasm-C6Jwlhb3.js +1 -0
- package/web-ui/build/static/neon-BlmLz-44.js +1 -0
- package/web-ui/build/static/nevod-QYVtYYuZ.js +1 -0
- package/web-ui/build/static/nginx-BuLLVaOi.js +1 -0
- package/web-ui/build/static/nginx-D32yC6aV.js +1 -0
- package/web-ui/build/static/nim-lYMS-Zao.js +1 -0
- package/web-ui/build/static/nim-mOq8l1DZ.js +1 -0
- package/web-ui/build/static/nix-BF2uUjB0.js +1 -0
- package/web-ui/build/static/nix-CvXMc2Qe.js +1 -0
- package/web-ui/build/static/node-repl-b6WSKwpJ.js +1 -0
- package/web-ui/build/static/nsis-By4cMroz.js +1 -0
- package/web-ui/build/static/nsis-CdtEDB4h.js +1 -0
- package/web-ui/build/static/objectivec-1qRjQ45C.js +1 -0
- package/web-ui/build/static/objectivec-B_fabLIN.js +1 -0
- package/web-ui/build/static/ocaml-CgNFmQRO.js +1 -0
- package/web-ui/build/static/ocaml-RYK_k0qm.js +1 -0
- package/web-ui/build/static/opencl-DS8fpnDf.js +1 -0
- package/web-ui/build/static/openqasm-DJaB3Rq-.js +1 -0
- package/web-ui/build/static/openscad-CG2Cr9_f.js +1 -0
- package/web-ui/build/static/oxygene-C5StnXkF.js +1 -0
- package/web-ui/build/static/oz-Chp4Q4tx.js +1 -0
- package/web-ui/build/static/parigp-CHrkrXXH.js +1 -0
- package/web-ui/build/static/parser-oClS8RsF.js +1 -0
- package/web-ui/build/static/parser3-DAnZ8BBa.js +1 -0
- package/web-ui/build/static/pascal-C3UXKTAg.js +1 -0
- package/web-ui/build/static/pascaligo-bQ2eEItJ.js +1 -0
- package/web-ui/build/static/pcaxis-Cb18v5lb.js +1 -0
- package/web-ui/build/static/peoplecode-DSinbacy.js +1 -0
- package/web-ui/build/static/perl-CJyKzdWx.js +1 -0
- package/web-ui/build/static/perl-DPC7B2HS.js +1 -0
- package/web-ui/build/static/pf-CufleM0I.js +1 -0
- package/web-ui/build/static/pgsql-C_0MdqVp.js +1 -0
- package/web-ui/build/static/php-BO1Ap_Os.js +1 -0
- package/web-ui/build/static/php-CJgcNJVe.js +1 -0
- package/web-ui/build/static/php-extras-BXgszKUS.js +1 -0
- package/web-ui/build/static/php-template-Cb_xvIiQ.js +1 -0
- package/web-ui/build/static/phpdoc-BfOts4aJ.js +1 -0
- package/web-ui/build/static/plaintext-DN7uh6jc.js +1 -0
- package/web-ui/build/static/plsql-v3WUpEeY.js +1 -0
- package/web-ui/build/static/pony-DJxNA-H0.js +1 -0
- package/web-ui/build/static/powerquery-BtsNylnn.js +1 -0
- package/web-ui/build/static/powershell-C6cTgKNj.js +1 -0
- package/web-ui/build/static/powershell-w7qa2Po0.js +1 -0
- package/web-ui/build/static/processing-B4LQG2qT.js +1 -0
- package/web-ui/build/static/processing-sqZsG0Ty.js +1 -0
- package/web-ui/build/static/profile-BmJYpErx.js +1 -0
- package/web-ui/build/static/prolog-BesbmNtC.js +1 -0
- package/web-ui/build/static/prolog-Bhfih4kN.js +1 -0
- package/web-ui/build/static/promql-C0f632z2.js +1 -0
- package/web-ui/build/static/properties-D4QlRz8E.js +1 -0
- package/web-ui/build/static/properties-jKkliMyl.js +1 -0
- package/web-ui/build/static/protobuf-1DEpY6d3.js +1 -0
- package/web-ui/build/static/protobuf-BGXS-kPK.js +1 -0
- package/web-ui/build/static/psl-C0CZXE-V.js +1 -0
- package/web-ui/build/static/pug-BF9VjA3d.js +1 -0
- package/web-ui/build/static/puppet-DbCz1V2e.js +1 -0
- package/web-ui/build/static/puppet-sw6E5TP0.js +1 -0
- package/web-ui/build/static/pure-C7mJA0tr.js +1 -0
- package/web-ui/build/static/purebasic-BSMar56G.js +1 -0
- package/web-ui/build/static/purebasic-lZ85aQ75.js +1 -0
- package/web-ui/build/static/purescript-7W6hcoJU.js +1 -0
- package/web-ui/build/static/python-Cf1rHsAv.js +1 -0
- package/web-ui/build/static/python-D6YthG1T.js +1 -0
- package/web-ui/build/static/python-repl-L_ce-JlI.js +1 -0
- package/web-ui/build/static/q-C4jLiln2.js +1 -0
- package/web-ui/build/static/q-DbbElowk.js +1 -0
- package/web-ui/build/static/qml-BpzqRYBe.js +1 -0
- package/web-ui/build/static/qml-DhqooLOn.js +1 -0
- package/web-ui/build/static/qore-CDdWlH4L.js +1 -0
- package/web-ui/build/static/qsharp-CYjzWQn8.js +1 -0
- package/web-ui/build/static/r-C0m7OAlP.js +1 -0
- package/web-ui/build/static/r-nRzPzIPC.js +1 -0
- package/web-ui/build/static/racket-BMk7mOQz.js +1 -0
- package/web-ui/build/static/reason-BXQPEhQe.js +1 -0
- package/web-ui/build/static/reasonml-BX4tkmG7.js +1 -0
- package/web-ui/build/static/regex-I514pFOx.js +1 -0
- package/web-ui/build/static/rego-nryy7Qo5.js +1 -0
- package/web-ui/build/static/renpy-73dSR30u.js +1 -0
- package/web-ui/build/static/rest-BVkqAn_D.js +1 -0
- package/web-ui/build/static/rib-CkA1SeIw.js +1 -0
- package/web-ui/build/static/rip-DdqP7xQ_.js +1 -0
- package/web-ui/build/static/roboconf-B1xFEP2z.js +1 -0
- package/web-ui/build/static/roboconf-MHZ9iUN8.js +1 -0
- package/web-ui/build/static/robotframework-Be6JB4Sm.js +1 -0
- package/web-ui/build/static/routeros-BDbHsrl3.js +1 -0
- package/web-ui/build/static/rsl-vBbR8fM2.js +1 -0
- package/web-ui/build/static/ruby-Bl6coIpX.js +1 -0
- package/web-ui/build/static/ruby-CYoX7aZ3.js +1 -0
- package/web-ui/build/static/ruleslanguage-CNda0rO_.js +1 -0
- package/web-ui/build/static/rust-Cn7CeLWb.js +1 -0
- package/web-ui/build/static/rust-DqfPHA-4.js +1 -0
- package/web-ui/build/static/sas-DX4nVHMx.js +1 -0
- package/web-ui/build/static/sas-TP86Lr_H.js +1 -0
- package/web-ui/build/static/sass-DLbsRbZq.js +1 -0
- package/web-ui/build/static/scala-BnuBUE7N.js +1 -0
- package/web-ui/build/static/scala-e0xCO3PH.js +1 -0
- package/web-ui/build/static/scheme-CgksT1_b.js +1 -0
- package/web-ui/build/static/scheme-wKIEujhs.js +1 -0
- package/web-ui/build/static/scilab-BK5XtNGf.js +1 -0
- package/web-ui/build/static/scss-CgF0LqaR.js +1 -0
- package/web-ui/build/static/scss-DtfwOUSt.js +1 -0
- package/web-ui/build/static/shell-mV_H_B9k.js +1 -0
- package/web-ui/build/static/shell-session-CcycyI-F.js +1 -0
- package/web-ui/build/static/smali-DUHlxZcA.js +1 -0
- package/web-ui/build/static/smali-vgrIyB1v.js +1 -0
- package/web-ui/build/static/smalltalk-C0Ge9l_D.js +1 -0
- package/web-ui/build/static/smalltalk-CXwx9xen.js +1 -0
- package/web-ui/build/static/smarty-ATfkwbr-.js +1 -0
- package/web-ui/build/static/sml-CPHHv48a.js +1 -0
- package/web-ui/build/static/sml-D8zKZZ0g.js +1 -0
- package/web-ui/build/static/solidity-DU2sGoWA.js +1 -0
- package/web-ui/build/static/solution-file-D20yiaNa.js +1 -0
- package/web-ui/build/static/soy-NkZd2NuM.js +1 -0
- package/web-ui/build/static/sparql-CURkC9N5.js +1 -0
- package/web-ui/build/static/splunk-spl-DACtCZRc.js +1 -0
- package/web-ui/build/static/sqf-BEdMNLDm.js +1 -0
- package/web-ui/build/static/sqf-RqYJHX2k.js +1 -0
- package/web-ui/build/static/sql-Bgepr53d.js +1 -0
- package/web-ui/build/static/sql-CW0TRs77.js +1 -0
- package/web-ui/build/static/sql_more-C2HWexYA.js +1 -0
- package/web-ui/build/static/squirrel-B6wcVYWs.js +1 -0
- package/web-ui/build/static/stan-Dl3AavYY.js +1 -0
- package/web-ui/build/static/stan-RZ2M2r7-.js +1 -0
- package/web-ui/build/static/stata-PGzYv80j.js +1 -0
- package/web-ui/build/static/step21-yyjO2ozE.js +1 -0
- package/web-ui/build/static/stylus-CA7oCY6H.js +1 -0
- package/web-ui/build/static/stylus-CMppe6Nc.js +1 -0
- package/web-ui/build/static/subunit-CgXzRGNV.js +1 -0
- package/web-ui/build/static/swift-BEZPFJIt.js +1 -0
- package/web-ui/build/static/swift-N42216FZ.js +1 -0
- package/web-ui/build/static/systemd-DFn17zHD.js +1 -0
- package/web-ui/build/static/t4-cs-D2og3B0M.js +1 -0
- package/web-ui/build/static/t4-templating-D9rCAn0c.js +1 -0
- package/web-ui/build/static/t4-vb-DG0xTVDc.js +1 -0
- package/web-ui/build/static/taggerscript-C89CvllW.js +1 -0
- package/web-ui/build/static/tap-D19DYT30.js +1 -0
- package/web-ui/build/static/tap-ERFF4Ark.js +1 -0
- package/web-ui/build/static/tcl-BCrLy0kY.js +1 -0
- package/web-ui/build/static/tcl-Db3hH49l.js +1 -0
- package/web-ui/build/static/textile-C45CZf2E.js +1 -0
- package/web-ui/build/static/thrift-DPSiQbdQ.js +1 -0
- package/web-ui/build/static/toml-OY_aaWwT.js +1 -0
- package/web-ui/build/static/tp-B3eRQVO4.js +1 -0
- package/web-ui/build/static/tremor-BqAT46SE.js +1 -0
- package/web-ui/build/static/tsx-BCfhl9AT.js +1 -0
- package/web-ui/build/static/tt2-C0sqlstv.js +1 -0
- package/web-ui/build/static/turtle-ClBSXu8f.js +1 -0
- package/web-ui/build/static/twig-BxxoTcyR.js +1 -0
- package/web-ui/build/static/twig-D1iWWft8.js +1 -0
- package/web-ui/build/static/typescript-D92P7Q_T.js +1 -0
- package/web-ui/build/static/typescript-IMBE9asI.js +1 -0
- package/web-ui/build/static/typoscript-Ct5LqTJd.js +1 -0
- package/web-ui/build/static/unrealscript-DzhFlMW5.js +1 -0
- package/web-ui/build/static/uorazor-DR4IM7ll.js +1 -0
- package/web-ui/build/static/uri-D10KlPiP.js +1 -0
- package/web-ui/build/static/v-CHHzCtfa.js +1 -0
- package/web-ui/build/static/vala-ChoAAQZv.js +1 -0
- package/web-ui/build/static/vala-CsGoPWkE.js +1 -0
- package/web-ui/build/static/vbnet-BSMzhrci.js +1 -0
- package/web-ui/build/static/vbnet-tWgXxlpd.js +1 -0
- package/web-ui/build/static/vbscript-C5MSBjcM.js +1 -0
- package/web-ui/build/static/vbscript-html-DgC8phmk.js +1 -0
- package/web-ui/build/static/velocity-ChLZNkgf.js +1 -0
- package/web-ui/build/static/verilog-RKDyj9CP.js +1 -0
- package/web-ui/build/static/verilog-qAYw6v_5.js +1 -0
- package/web-ui/build/static/vhdl-CRSvweFg.js +1 -0
- package/web-ui/build/static/vhdl-DnTmxitY.js +1 -0
- package/web-ui/build/static/vim-CnOJH9xw.js +1 -0
- package/web-ui/build/static/vim-LKJY3Sb8.js +1 -0
- package/web-ui/build/static/visual-basic-DZTN8GNq.js +1 -0
- package/web-ui/build/static/warpscript-Bz5PHWGb.js +1 -0
- package/web-ui/build/static/wasm-DjXA7rVQ.js +1 -0
- package/web-ui/build/static/web-idl-qpPnV3-c.js +1 -0
- package/web-ui/build/static/wiki-h1S7Uj0l.js +1 -0
- package/web-ui/build/static/wolfram-BsqW0Evw.js +1 -0
- package/web-ui/build/static/wren-2NkHwSLr.js +1 -0
- package/web-ui/build/static/x86asm-D8Cg9MTd.js +1 -0
- package/web-ui/build/static/xeora-CIwPPgRx.js +1 -0
- package/web-ui/build/static/xl-DIsgBj_c.js +1 -0
- package/web-ui/build/static/xml-D19j4_jb.js +1 -0
- package/web-ui/build/static/xml-doc-DMtIXpse.js +1 -0
- package/web-ui/build/static/xojo-Yr0egAH7.js +1 -0
- package/web-ui/build/static/xquery-3A0gaIyY.js +1 -0
- package/web-ui/build/static/xquery-ondigVMj.js +1 -0
- package/web-ui/build/static/yaml-BC7GbQPc.js +1 -0
- package/web-ui/build/static/yaml-DvN1W_m1.js +1 -0
- package/web-ui/build/static/yang-BJH3-Oqi.js +1 -0
- package/web-ui/build/static/zephir-DsXXe3UC.js +1 -0
- package/web-ui/build/static/zig-9jAF8TxG.js +1 -0
- package/web-ui/build/static/1c-CbzecjHi.js +0 -1
- package/web-ui/build/static/abap-B64Rmd3x.js +0 -1
- package/web-ui/build/static/abnf-0eZ1ofqG.js +0 -1
- package/web-ui/build/static/abnf-BhANbO1L.js +0 -1
- package/web-ui/build/static/accesslog-clFlGMX1.js +0 -1
- package/web-ui/build/static/actionscript-DXab4IMG.js +0 -1
- package/web-ui/build/static/actionscript-RFf8wL8w.js +0 -1
- package/web-ui/build/static/ada-Bm94vJQR.js +0 -1
- package/web-ui/build/static/ada-zNbObSyu.js +0 -1
- package/web-ui/build/static/agda-K3kQv8iy.js +0 -1
- package/web-ui/build/static/al-B3t1K-du.js +0 -1
- package/web-ui/build/static/angelscript-CnHodqV_.js +0 -1
- package/web-ui/build/static/antlr4-BZgY7Twd.js +0 -1
- package/web-ui/build/static/apache-C12AF3ev.js +0 -1
- package/web-ui/build/static/apacheconf-DkOEqFh0.js +0 -1
- package/web-ui/build/static/apex-BDpgbClJ.js +0 -1
- package/web-ui/build/static/apl-Dh1dt5kw.js +0 -1
- package/web-ui/build/static/applescript-Bg_fqdWd.js +0 -1
- package/web-ui/build/static/applescript-ByhrvNiG.js +0 -1
- package/web-ui/build/static/aql-QIblVVYJ.js +0 -1
- package/web-ui/build/static/arcade-Cm4e2zMb.js +0 -1
- package/web-ui/build/static/arduino-CGkuSXzN.js +0 -1
- package/web-ui/build/static/arduino-OsL_Nhym.js +0 -1
- package/web-ui/build/static/arff-B4JSuA76.js +0 -1
- package/web-ui/build/static/armasm-DdbgiOrV.js +0 -1
- package/web-ui/build/static/asciidoc-0lb-Ko8S.js +0 -1
- package/web-ui/build/static/asciidoc-BYRGLnED.js +0 -1
- package/web-ui/build/static/asm6502-DG0RlvQN.js +0 -1
- package/web-ui/build/static/asmatmel-DWT2_REW.js +0 -1
- package/web-ui/build/static/aspectj-MEt9NeRB.js +0 -1
- package/web-ui/build/static/aspnet-DR3hLqcA.js +0 -1
- package/web-ui/build/static/autohotkey-B6JJ6A0n.js +0 -1
- package/web-ui/build/static/autohotkey-BCqVAmnV.js +0 -1
- package/web-ui/build/static/autoit-BqyLjnUK.js +0 -1
- package/web-ui/build/static/autoit-D3OL2ya6.js +0 -1
- package/web-ui/build/static/avisynth-CFYPlhWF.js +0 -1
- package/web-ui/build/static/avrasm-BvoWo5z1.js +0 -1
- package/web-ui/build/static/avro-idl-Dmt54kEx.js +0 -1
- package/web-ui/build/static/awk-DKHI_UvD.js +0 -1
- package/web-ui/build/static/axapta-jgtqYlu1.js +0 -1
- package/web-ui/build/static/bash-CM-bsVnP.js +0 -1
- package/web-ui/build/static/bash-rbX0rKbK.js +0 -1
- package/web-ui/build/static/basic-B31B3k7x.js +0 -1
- package/web-ui/build/static/basic-Gu99ccWS.js +0 -1
- package/web-ui/build/static/batch-Dxt_s5aG.js +0 -1
- package/web-ui/build/static/bbcode-C0kmzu6X.js +0 -1
- package/web-ui/build/static/bicep-BsOEq_j9.js +0 -1
- package/web-ui/build/static/birb-CtTYWirD.js +0 -1
- package/web-ui/build/static/bison-D50hClIy.js +0 -1
- package/web-ui/build/static/bnf-CZQ0tN86.js +0 -1
- package/web-ui/build/static/bnf-keJM21-h.js +0 -1
- package/web-ui/build/static/brainfuck-BYsdquiy.js +0 -1
- package/web-ui/build/static/brainfuck-ChqXjCJ9.js +0 -1
- package/web-ui/build/static/brightscript-C2Wd5Kft.js +0 -1
- package/web-ui/build/static/bro-Cg2wy26n.js +0 -1
- package/web-ui/build/static/bsl-KPpKnfiJ.js +0 -1
- package/web-ui/build/static/c-DngIvZ7L.js +0 -1
- package/web-ui/build/static/c-Iq8EIPIe.js +0 -1
- package/web-ui/build/static/c-like-Bec9Rkda.js +0 -1
- package/web-ui/build/static/cal-BS26ucSy.js +0 -1
- package/web-ui/build/static/capnproto-W0IWf2FW.js +0 -1
- package/web-ui/build/static/ceylon-ujPry_yR.js +0 -1
- package/web-ui/build/static/cfscript-806779CY.js +0 -1
- package/web-ui/build/static/chaiscript-D9HG2WFc.js +0 -1
- package/web-ui/build/static/cil-BDNzOY3h.js +0 -1
- package/web-ui/build/static/clean-DoE0KPLU.js +0 -1
- package/web-ui/build/static/clojure-B-nWTi09.js +0 -1
- package/web-ui/build/static/clojure-BIPQIlEM.js +0 -1
- package/web-ui/build/static/clojure-repl-C6Xgw1BL.js +0 -1
- package/web-ui/build/static/cmake-BCUVXGkd.js +0 -1
- package/web-ui/build/static/cmake-DoEfzWcx.js +0 -1
- package/web-ui/build/static/cobol-DyuJRPLj.js +0 -1
- package/web-ui/build/static/coffeescript-CzPUmFhd.js +0 -1
- package/web-ui/build/static/coffeescript-cxIqfyb2.js +0 -1
- package/web-ui/build/static/concurnas-YafoHwhS.js +0 -1
- package/web-ui/build/static/coq-DtAS2_j-.js +0 -1
- package/web-ui/build/static/coq-sa9vsIqd.js +0 -1
- package/web-ui/build/static/cos-nEV8XIfx.js +0 -1
- package/web-ui/build/static/cpp-CcKjDXtx.js +0 -1
- package/web-ui/build/static/cpp-CcxmwIS8.js +0 -1
- package/web-ui/build/static/crmsh-BCZKA2g2.js +0 -1
- package/web-ui/build/static/crystal-CI7ryNid.js +0 -1
- package/web-ui/build/static/crystal-DpjmCsWq.js +0 -1
- package/web-ui/build/static/csharp-BJEFr34Q.js +0 -1
- package/web-ui/build/static/csharp-Di8gXUl6.js +0 -1
- package/web-ui/build/static/cshtml-CM5kdsbL.js +0 -1
- package/web-ui/build/static/csp-CCUatC8F.js +0 -1
- package/web-ui/build/static/csp-CQMJNBVX.js +0 -1
- package/web-ui/build/static/css-Ca1P3y8D.js +0 -1
- package/web-ui/build/static/css-extras-B-WsWoLG.js +0 -1
- package/web-ui/build/static/csv-Dp2D1vNQ.js +0 -1
- package/web-ui/build/static/cypher-C2lTf63v.js +0 -1
- package/web-ui/build/static/d-BpN31fsJ.js +0 -1
- package/web-ui/build/static/d-DF2Z_5Y5.js +0 -1
- package/web-ui/build/static/dart-D2xFtNlR.js +0 -1
- package/web-ui/build/static/dart-D_CllGe8.js +0 -1
- package/web-ui/build/static/dataweave-D0S0J-fB.js +0 -1
- package/web-ui/build/static/dax-LFApbZ_c.js +0 -1
- package/web-ui/build/static/delphi-BwOo_vb0.js +0 -1
- package/web-ui/build/static/dhall-Bdnii7zv.js +0 -1
- package/web-ui/build/static/diff-BkC59Drj.js +0 -1
- package/web-ui/build/static/diff-Ft7pVJ9X.js +0 -1
- package/web-ui/build/static/django-CBZk8JcH.js +0 -1
- package/web-ui/build/static/django-WTsadJGk.js +0 -1
- package/web-ui/build/static/dns-DiL3BhcP.js +0 -1
- package/web-ui/build/static/dns-zone-file-pi6xeovf.js +0 -1
- package/web-ui/build/static/docker-DyQR3JA7.js +0 -1
- package/web-ui/build/static/dockerfile-BE207Z5W.js +0 -1
- package/web-ui/build/static/dos-BhnpGRsK.js +0 -1
- package/web-ui/build/static/dot-Dhy7kpoM.js +0 -1
- package/web-ui/build/static/dsconfig-DzkFGUpr.js +0 -1
- package/web-ui/build/static/dts-BhMOwHm3.js +0 -1
- package/web-ui/build/static/dust-DkbHh2Pg.js +0 -1
- package/web-ui/build/static/ebnf-C3wm6ooH.js +0 -1
- package/web-ui/build/static/ebnf-DqOIsQzW.js +0 -1
- package/web-ui/build/static/editorconfig-D2EbTZsp.js +0 -1
- package/web-ui/build/static/eiffel-C_xptgK8.js +0 -1
- package/web-ui/build/static/ejs-CcONaJS0.js +0 -1
- package/web-ui/build/static/elixir-CagtfrW4.js +0 -1
- package/web-ui/build/static/elixir-CyP-nJp8.js +0 -1
- package/web-ui/build/static/elm-BkimtfCC.js +0 -1
- package/web-ui/build/static/elm-Cy0zy-Wk.js +0 -1
- package/web-ui/build/static/erb-CKfVidCX.js +0 -1
- package/web-ui/build/static/erb-Di0rdfuA.js +0 -1
- package/web-ui/build/static/erlang-C9YmoUs7.js +0 -1
- package/web-ui/build/static/erlang-DRED-UWJ.js +0 -1
- package/web-ui/build/static/erlang-repl-DeR_2uii.js +0 -1
- package/web-ui/build/static/etlua-B6Z-QQtE.js +0 -1
- package/web-ui/build/static/excel-DYqxHaXE.js +0 -1
- package/web-ui/build/static/excel-formula-BreCIdiF.js +0 -1
- package/web-ui/build/static/factor-jyOxALZ3.js +0 -1
- package/web-ui/build/static/false-BNO0FXoK.js +0 -1
- package/web-ui/build/static/firestore-security-rules-8OJaVJPI.js +0 -1
- package/web-ui/build/static/fix-DxdEj5oc.js +0 -1
- package/web-ui/build/static/flix-Dz2xZZH5.js +0 -1
- package/web-ui/build/static/flow-DpzKZb4e.js +0 -1
- package/web-ui/build/static/fortran-CtfIFIgp.js +0 -1
- package/web-ui/build/static/fortran-Cv6ED2BG.js +0 -1
- package/web-ui/build/static/fsharp-BC6e3hD1.js +0 -1
- package/web-ui/build/static/fsharp-CMyk8GxQ.js +0 -1
- package/web-ui/build/static/ftl-DZnBCzfq.js +0 -1
- package/web-ui/build/static/gams-ClY69INi.js +0 -1
- package/web-ui/build/static/gap-DYeEWwoE.js +0 -1
- package/web-ui/build/static/gauss-CCHXytat.js +0 -1
- package/web-ui/build/static/gcode-DoWDPjLg.js +0 -1
- package/web-ui/build/static/gcode-N6PPDTDT.js +0 -1
- package/web-ui/build/static/gdscript-agxR9uG0.js +0 -1
- package/web-ui/build/static/gedcom-BvBAgJXG.js +0 -1
- package/web-ui/build/static/gherkin-BW8CWXxJ.js +0 -1
- package/web-ui/build/static/gherkin-CqawSkQY.js +0 -1
- package/web-ui/build/static/git-99C9UE-e.js +0 -1
- package/web-ui/build/static/glsl-CQEuDShu.js +0 -1
- package/web-ui/build/static/glsl-DuhoPpCv.js +0 -1
- package/web-ui/build/static/gml-Bsn22WsK.js +0 -1
- package/web-ui/build/static/gml-BvXK6GGq.js +0 -1
- package/web-ui/build/static/gn-BUoYUPzm.js +0 -1
- package/web-ui/build/static/go-CvTv9DUi.js +0 -1
- package/web-ui/build/static/go-module-Dwpq3Jsg.js +0 -1
- package/web-ui/build/static/go-sGZzTvuq.js +0 -1
- package/web-ui/build/static/golo-C6DHxID0.js +0 -1
- package/web-ui/build/static/gradle-D7XVSr1y.js +0 -1
- package/web-ui/build/static/graphql-DIIA3EdJ.js +0 -1
- package/web-ui/build/static/groovy-B5TJuGtQ.js +0 -1
- package/web-ui/build/static/groovy-BVf2VudZ.js +0 -1
- package/web-ui/build/static/haml-B0dZKFFV.js +0 -1
- package/web-ui/build/static/haml-B5rD_eqj.js +0 -1
- package/web-ui/build/static/handlebars-Db8etm3q.js +0 -1
- package/web-ui/build/static/handlebars-Qm9HXVGH.js +0 -1
- package/web-ui/build/static/haskell-BbTqR78v.js +0 -1
- package/web-ui/build/static/haskell-cf6URQ36.js +0 -1
- package/web-ui/build/static/haxe-4ugxCu3z.js +0 -1
- package/web-ui/build/static/haxe-BscBu1yx.js +0 -1
- package/web-ui/build/static/hcl-QK-f8vU5.js +0 -1
- package/web-ui/build/static/hlsl-BnQDpabJ.js +0 -1
- package/web-ui/build/static/hoon-VPMuvItP.js +0 -1
- package/web-ui/build/static/hpkp-VpqLQgGP.js +0 -1
- package/web-ui/build/static/hsp-DTlBvyyT.js +0 -1
- package/web-ui/build/static/hsts-B6Dishdu.js +0 -1
- package/web-ui/build/static/htmlbars-Byn3Paw0.js +0 -1
- package/web-ui/build/static/http-CM7a2429.js +0 -1
- package/web-ui/build/static/http-QOmRJ4Jd.js +0 -1
- package/web-ui/build/static/hy-D3_6scbm.js +0 -1
- package/web-ui/build/static/ichigojam-Os0-Gxpc.js +0 -1
- package/web-ui/build/static/icon-DAjjoH9X.js +0 -1
- package/web-ui/build/static/icu-message-format-CCtlXoOl.js +0 -1
- package/web-ui/build/static/idris-BLmLcq2C.js +0 -1
- package/web-ui/build/static/iecst-CL0FD1hF.js +0 -1
- package/web-ui/build/static/ignore-Bcd-tuGH.js +0 -1
- package/web-ui/build/static/index-BPqTB5k7.js +0 -1
- package/web-ui/build/static/index-BwNJoEC1.css +0 -1
- package/web-ui/build/static/index-ClWUfRkv.js +0 -13
- package/web-ui/build/static/index-DY0DLa8y.js +0 -831
- package/web-ui/build/static/inform7-ChnghUc9.js +0 -1
- package/web-ui/build/static/inform7-DFioFNVH.js +0 -1
- package/web-ui/build/static/ini-B7Qqa2Hv.js +0 -1
- package/web-ui/build/static/ini-CFmmlUla.js +0 -1
- package/web-ui/build/static/io-C5MldizL.js +0 -1
- package/web-ui/build/static/irpf90-Co951JRw.js +0 -1
- package/web-ui/build/static/isbl-BlVCsoVY.js +0 -1
- package/web-ui/build/static/j-BfpCTQLT.js +0 -1
- package/web-ui/build/static/java-B8eLTuI_.js +0 -1
- package/web-ui/build/static/java-Cp73UB-4.js +0 -1
- package/web-ui/build/static/javadoc-sKuB5y9S.js +0 -1
- package/web-ui/build/static/javadoclike-0oCrjeqP.js +0 -1
- package/web-ui/build/static/javascript-DhJRIVbT.js +0 -1
- package/web-ui/build/static/javastacktrace-34av_07D.js +0 -1
- package/web-ui/build/static/jboss-cli-B3LjD57q.js +0 -1
- package/web-ui/build/static/jexl-DjeCXh3R.js +0 -1
- package/web-ui/build/static/jolie-DSguA0co.js +0 -1
- package/web-ui/build/static/jq-CrNdtEVM.js +0 -1
- package/web-ui/build/static/js-extras-DRiGHN_t.js +0 -1
- package/web-ui/build/static/js-templates-BOAGBe4G.js +0 -1
- package/web-ui/build/static/jsdoc-BD9HPtj-.js +0 -1
- package/web-ui/build/static/json-DWyPfZ7N.js +0 -1
- package/web-ui/build/static/json-ZOqNWxv3.js +0 -1
- package/web-ui/build/static/json5-CtFHocU-.js +0 -1
- package/web-ui/build/static/jsonp-D6qQgfvt.js +0 -1
- package/web-ui/build/static/jsstacktrace-4V_XcjuT.js +0 -1
- package/web-ui/build/static/jsx-BEPywbwa.js +0 -1
- package/web-ui/build/static/julia-BMbPnK5h.js +0 -1
- package/web-ui/build/static/julia-DdAob-5L.js +0 -1
- package/web-ui/build/static/julia-repl-D8h3n5ls.js +0 -1
- package/web-ui/build/static/keepalived-DMtuOIPi.js +0 -1
- package/web-ui/build/static/keyman-BYoKRL3H.js +0 -1
- package/web-ui/build/static/kotlin-DKSAAlR0.js +0 -1
- package/web-ui/build/static/kotlin-av8HkILL.js +0 -1
- package/web-ui/build/static/kumir-DKW-dbIw.js +0 -1
- package/web-ui/build/static/kusto-CmM_Dgdi.js +0 -1
- package/web-ui/build/static/lasso-UpwhKAGW.js +0 -1
- package/web-ui/build/static/latex--o0dGgqN.js +0 -1
- package/web-ui/build/static/latex-BDYUhb2n.js +0 -1
- package/web-ui/build/static/latte-BIQdMLZM.js +0 -1
- package/web-ui/build/static/ldif-BHZbj1Gt.js +0 -1
- package/web-ui/build/static/leaf-tKJVpCFa.js +0 -1
- package/web-ui/build/static/less-BWc29iML.js +0 -1
- package/web-ui/build/static/less-Cbs0Yz51.js +0 -1
- package/web-ui/build/static/lilypond-B5_XQXAT.js +0 -1
- package/web-ui/build/static/liquid-BUBwhbDU.js +0 -1
- package/web-ui/build/static/lisp-ConZsrCa.js +0 -1
- package/web-ui/build/static/lisp-CyghfRqh.js +0 -1
- package/web-ui/build/static/livecodeserver-BdtmjzpM.js +0 -1
- package/web-ui/build/static/livescript-CbEttWiK.js +0 -1
- package/web-ui/build/static/livescript-DlaJUNpa.js +0 -1
- package/web-ui/build/static/llvm-CljEFNfy.js +0 -1
- package/web-ui/build/static/llvm-OEx8ipzf.js +0 -1
- package/web-ui/build/static/log-CtjresKJ.js +0 -1
- package/web-ui/build/static/lolcode-CbZB03Q-.js +0 -1
- package/web-ui/build/static/lsl-TsKq2mca.js +0 -1
- package/web-ui/build/static/lua-1Rx_tY_z.js +0 -1
- package/web-ui/build/static/lua-CrgLvyqs.js +0 -1
- package/web-ui/build/static/magma-BK5awswf.js +0 -1
- package/web-ui/build/static/makefile-6SJJhsz5.js +0 -1
- package/web-ui/build/static/makefile-DXokzicL.js +0 -1
- package/web-ui/build/static/markdown-Bzf4rNiL.js +0 -1
- package/web-ui/build/static/markdown-D2e-R2p5.js +0 -1
- package/web-ui/build/static/markup-templating-Brr7NCtI.js +0 -1
- package/web-ui/build/static/mathematica-BHdsgRlV.js +0 -1
- package/web-ui/build/static/matlab-D_t3IZfZ.js +0 -1
- package/web-ui/build/static/matlab-cKsG1reI.js +0 -1
- package/web-ui/build/static/maxima-cBBBfxwc.js +0 -1
- package/web-ui/build/static/maxscript-C1ulETQI.js +0 -1
- package/web-ui/build/static/mel-Bi5R0sfT.js +0 -1
- package/web-ui/build/static/mel-CExeAiGY.js +0 -1
- package/web-ui/build/static/mercury-BQmKWkZv.js +0 -1
- package/web-ui/build/static/mermaid-n5nH0--1.js +0 -1
- package/web-ui/build/static/mipsasm-B5MOlnt9.js +0 -1
- package/web-ui/build/static/mizar-BOKt_6pu.js +0 -1
- package/web-ui/build/static/mizar-BQn40NA6.js +0 -1
- package/web-ui/build/static/mojolicious-B9lAb6C9.js +0 -1
- package/web-ui/build/static/mongodb-DBaQzUEE.js +0 -1
- package/web-ui/build/static/monkey-FadeXREo.js +0 -1
- package/web-ui/build/static/monkey-HfvbiXjN.js +0 -1
- package/web-ui/build/static/moonscript-CNC9qFDz.js +0 -1
- package/web-ui/build/static/moonscript-Cin88noO.js +0 -1
- package/web-ui/build/static/n1ql-Dr9Yo8b-.js +0 -1
- package/web-ui/build/static/n1ql-DzlVOUYJ.js +0 -1
- package/web-ui/build/static/n4js-DTmfxRT4.js +0 -1
- package/web-ui/build/static/nand2tetris-hdl-Bod-DCUu.js +0 -1
- package/web-ui/build/static/naniscript-CfiXCI4Z.js +0 -1
- package/web-ui/build/static/nasm-BXYRoY2W.js +0 -1
- package/web-ui/build/static/neon-D2krcpRE.js +0 -1
- package/web-ui/build/static/nevod-BQHDBMPo.js +0 -1
- package/web-ui/build/static/nginx-C_9KHeCP.js +0 -1
- package/web-ui/build/static/nginx-KL5tR7Jx.js +0 -1
- package/web-ui/build/static/nim-37p-xSET.js +0 -1
- package/web-ui/build/static/nim-D6PBji9h.js +0 -1
- package/web-ui/build/static/nix-CKra7X1P.js +0 -1
- package/web-ui/build/static/nix-CvbOGPFE.js +0 -1
- package/web-ui/build/static/node-repl-Cgo-gZ2g.js +0 -1
- package/web-ui/build/static/nsis-CtJDG2rE.js +0 -1
- package/web-ui/build/static/nsis-Cyt_6huf.js +0 -1
- package/web-ui/build/static/objectivec-Dy3dfqtz.js +0 -1
- package/web-ui/build/static/objectivec-QkHVj_us.js +0 -1
- package/web-ui/build/static/ocaml-C6TUnerY.js +0 -1
- package/web-ui/build/static/ocaml-c_egR_d6.js +0 -1
- package/web-ui/build/static/opencl-B9yN9nWN.js +0 -1
- package/web-ui/build/static/openqasm-BklslFAf.js +0 -1
- package/web-ui/build/static/openscad-C0AzYzEM.js +0 -1
- package/web-ui/build/static/oxygene-D2P6nG-V.js +0 -1
- package/web-ui/build/static/oz-CITL0kRx.js +0 -1
- package/web-ui/build/static/parigp-B9QyF2Nn.js +0 -1
- package/web-ui/build/static/parser-bpYn2eF8.js +0 -1
- package/web-ui/build/static/parser3-COZ5BGpE.js +0 -1
- package/web-ui/build/static/pascal-CjnX24jl.js +0 -1
- package/web-ui/build/static/pascaligo-BACCpo1a.js +0 -1
- package/web-ui/build/static/pcaxis-BoQE7JGE.js +0 -1
- package/web-ui/build/static/peoplecode-CgLXg57_.js +0 -1
- package/web-ui/build/static/perl-CJpIvn7i.js +0 -1
- package/web-ui/build/static/perl-DfM-sqCy.js +0 -1
- package/web-ui/build/static/pf-BF6Acu_U.js +0 -1
- package/web-ui/build/static/pgsql-08w-3mdC.js +0 -1
- package/web-ui/build/static/php-CSic_Yu4.js +0 -1
- package/web-ui/build/static/php-DFxYbY5N.js +0 -1
- package/web-ui/build/static/php-extras-DnRPSllm.js +0 -1
- package/web-ui/build/static/php-template-1kNXCBCk.js +0 -1
- package/web-ui/build/static/phpdoc-CLUTjtz4.js +0 -1
- package/web-ui/build/static/plaintext-dz7_1xmX.js +0 -1
- package/web-ui/build/static/plsql-BGMyKYzB.js +0 -1
- package/web-ui/build/static/pony-B1lWEmkm.js +0 -1
- package/web-ui/build/static/powerquery-iafim1FR.js +0 -1
- package/web-ui/build/static/powershell-Bum4b4hl.js +0 -1
- package/web-ui/build/static/powershell-CuB2b8w1.js +0 -1
- package/web-ui/build/static/processing-BpLaX01w.js +0 -1
- package/web-ui/build/static/processing-dUSz33TD.js +0 -1
- package/web-ui/build/static/profile-C7sg9dHs.js +0 -1
- package/web-ui/build/static/prolog-BBCiPfqc.js +0 -1
- package/web-ui/build/static/prolog-nGaUTvbS.js +0 -1
- package/web-ui/build/static/promql-BBDfFLGg.js +0 -1
- package/web-ui/build/static/properties-BlRMM1Ox.js +0 -1
- package/web-ui/build/static/properties-BxuonvJH.js +0 -1
- package/web-ui/build/static/protobuf-COJo2eGP.js +0 -1
- package/web-ui/build/static/protobuf-Jz8_e3Gc.js +0 -1
- package/web-ui/build/static/psl-aKlFbB2o.js +0 -1
- package/web-ui/build/static/pug-B3kgkOaV.js +0 -1
- package/web-ui/build/static/puppet-Bn-ilWOt.js +0 -1
- package/web-ui/build/static/puppet-CAYrNHnV.js +0 -1
- package/web-ui/build/static/pure-Dae3dENv.js +0 -1
- package/web-ui/build/static/purebasic-BUc1d9bO.js +0 -1
- package/web-ui/build/static/purebasic-Ts3KCWkR.js +0 -1
- package/web-ui/build/static/purescript-DpsJiDL7.js +0 -1
- package/web-ui/build/static/python-C1ydkjn5.js +0 -1
- package/web-ui/build/static/python-CGJhIYP9.js +0 -1
- package/web-ui/build/static/python-repl-B_OutDuW.js +0 -1
- package/web-ui/build/static/q-DhLYm0oH.js +0 -1
- package/web-ui/build/static/q-Dj9Ezde0.js +0 -1
- package/web-ui/build/static/qml-BdSL3VMg.js +0 -1
- package/web-ui/build/static/qml-CjHJFscZ.js +0 -1
- package/web-ui/build/static/qore-CI3GTUtJ.js +0 -1
- package/web-ui/build/static/qsharp-CIibh84F.js +0 -1
- package/web-ui/build/static/r-BwwEbG-u.js +0 -1
- package/web-ui/build/static/r-C3s_ZZZQ.js +0 -1
- package/web-ui/build/static/racket-BcskASd8.js +0 -1
- package/web-ui/build/static/reason-DPziNH3U.js +0 -1
- package/web-ui/build/static/reasonml-D8R2Q19F.js +0 -1
- package/web-ui/build/static/regex-GzOZXBr2.js +0 -1
- package/web-ui/build/static/rego-l3gotT8l.js +0 -1
- package/web-ui/build/static/renpy-A19Zs8lh.js +0 -1
- package/web-ui/build/static/rest-wpzEKBJX.js +0 -1
- package/web-ui/build/static/rib-D_1KUGxh.js +0 -1
- package/web-ui/build/static/rip-8I3EGZnx.js +0 -1
- package/web-ui/build/static/roboconf-BSDIosSS.js +0 -1
- package/web-ui/build/static/roboconf-kHnsbEMa.js +0 -1
- package/web-ui/build/static/robotframework-De413her.js +0 -1
- package/web-ui/build/static/routeros-CF8DUMUu.js +0 -1
- package/web-ui/build/static/rsl-BSdv82fF.js +0 -1
- package/web-ui/build/static/ruby-7_GfbcxC.js +0 -1
- package/web-ui/build/static/ruby-BBYtzWvG.js +0 -1
- package/web-ui/build/static/ruleslanguage-CXhlU3tA.js +0 -1
- package/web-ui/build/static/rust-C2zLvQSk.js +0 -1
- package/web-ui/build/static/rust-CA-fq6LB.js +0 -1
- package/web-ui/build/static/sas-B-Yl0xMb.js +0 -1
- package/web-ui/build/static/sas-fjwRLuAQ.js +0 -1
- package/web-ui/build/static/sass-BUQ0WSOP.js +0 -1
- package/web-ui/build/static/scala-CJGiisP_.js +0 -1
- package/web-ui/build/static/scala-D15Fs72E.js +0 -1
- package/web-ui/build/static/scheme-CUk9mzNj.js +0 -1
- package/web-ui/build/static/scheme-CpvRWrML.js +0 -1
- package/web-ui/build/static/scilab-CdjikQAK.js +0 -1
- package/web-ui/build/static/scss-Bei63J7g.js +0 -1
- package/web-ui/build/static/scss-DbyTXjpl.js +0 -1
- package/web-ui/build/static/shell-CnHgXkIR.js +0 -1
- package/web-ui/build/static/shell-session-6lXCFDCO.js +0 -1
- package/web-ui/build/static/smali-BWdSwwzU.js +0 -1
- package/web-ui/build/static/smali-Bbc5YAcf.js +0 -1
- package/web-ui/build/static/smalltalk-BJDkU3rO.js +0 -1
- package/web-ui/build/static/smalltalk-Dm14AAUR.js +0 -1
- package/web-ui/build/static/smarty-CjCz5oQD.js +0 -1
- package/web-ui/build/static/sml-4QhxjTg1.js +0 -1
- package/web-ui/build/static/sml-BzhtSqHU.js +0 -1
- package/web-ui/build/static/solidity-BkXRM40v.js +0 -1
- package/web-ui/build/static/solution-file-BFJbqEWI.js +0 -1
- package/web-ui/build/static/soy-BWsRHx_l.js +0 -1
- package/web-ui/build/static/sparql-BmnAgU1w.js +0 -1
- package/web-ui/build/static/splunk-spl-BHQ0Zdjq.js +0 -1
- package/web-ui/build/static/sqf-BgRLbdp_.js +0 -1
- package/web-ui/build/static/sqf-DLLI0el0.js +0 -1
- package/web-ui/build/static/sql-2q54nPNH.js +0 -1
- package/web-ui/build/static/sql-DlC3YX66.js +0 -1
- package/web-ui/build/static/sql_more-BQKcXmJ0.js +0 -1
- package/web-ui/build/static/squirrel-DmebN_EL.js +0 -1
- package/web-ui/build/static/stan-BDGrHwEo.js +0 -1
- package/web-ui/build/static/stan-BasdJxfJ.js +0 -1
- package/web-ui/build/static/stata-DAcZR0XQ.js +0 -1
- package/web-ui/build/static/step21-RptXxSDX.js +0 -1
- package/web-ui/build/static/stylus-BtiAI269.js +0 -1
- package/web-ui/build/static/stylus-CbjAOV1A.js +0 -1
- package/web-ui/build/static/subunit-CNB_tt3p.js +0 -1
- package/web-ui/build/static/swift-BV3DOlYX.js +0 -1
- package/web-ui/build/static/swift-Bi-kz7aa.js +0 -1
- package/web-ui/build/static/systemd-CG-NuWtk.js +0 -1
- package/web-ui/build/static/t4-cs-DUThZgjr.js +0 -1
- package/web-ui/build/static/t4-templating-C7ED6iGj.js +0 -1
- package/web-ui/build/static/t4-vb-CT2spCQD.js +0 -1
- package/web-ui/build/static/taggerscript-CIWvWwRH.js +0 -1
- package/web-ui/build/static/tap-B-OZQ_98.js +0 -1
- package/web-ui/build/static/tap-ULV7YBw-.js +0 -1
- package/web-ui/build/static/tcl-DarZx3V_.js +0 -1
- package/web-ui/build/static/tcl-FAfHZOuK.js +0 -1
- package/web-ui/build/static/textile-YIaZ55lg.js +0 -1
- package/web-ui/build/static/thrift-Cw-lC7xb.js +0 -1
- package/web-ui/build/static/toml-CrMkp-dJ.js +0 -1
- package/web-ui/build/static/tp-DCzAu7jW.js +0 -1
- package/web-ui/build/static/tremor-CFDwS8vd.js +0 -1
- package/web-ui/build/static/tsx-DEeAlDW6.js +0 -1
- package/web-ui/build/static/tt2-BzFfu8wk.js +0 -1
- package/web-ui/build/static/turtle-84Pa71hh.js +0 -1
- package/web-ui/build/static/twig-BayQvHS_.js +0 -1
- package/web-ui/build/static/twig-BsjBtlDh.js +0 -1
- package/web-ui/build/static/typescript-Cnjvfmxu.js +0 -1
- package/web-ui/build/static/typescript-DtikLyM7.js +0 -1
- package/web-ui/build/static/typoscript-zFoMPUtV.js +0 -1
- package/web-ui/build/static/unrealscript-BD0AGGE4.js +0 -1
- package/web-ui/build/static/uorazor-DEt_IzcG.js +0 -1
- package/web-ui/build/static/uri-CIvm0_Br.js +0 -1
- package/web-ui/build/static/v-BQoK7-a7.js +0 -1
- package/web-ui/build/static/vala-BDiY-0iU.js +0 -1
- package/web-ui/build/static/vala-CoUXbdfw.js +0 -1
- package/web-ui/build/static/vbnet-BahQpBvh.js +0 -1
- package/web-ui/build/static/vbnet-CTFmJ_tD.js +0 -1
- package/web-ui/build/static/vbscript-RIjZOgm7.js +0 -1
- package/web-ui/build/static/vbscript-html-etVtdRUU.js +0 -1
- package/web-ui/build/static/velocity-k8t18OIQ.js +0 -1
- package/web-ui/build/static/verilog-BkuqYQQS.js +0 -1
- package/web-ui/build/static/verilog-CO7q-Nx8.js +0 -1
- package/web-ui/build/static/vhdl-F9maVm1z.js +0 -1
- package/web-ui/build/static/vhdl-jHowTwXP.js +0 -1
- package/web-ui/build/static/vim-5tQiPYrt.js +0 -1
- package/web-ui/build/static/vim-B6g6AlZK.js +0 -1
- package/web-ui/build/static/visual-basic-BVe6araH.js +0 -1
- package/web-ui/build/static/warpscript-DpWoozOM.js +0 -1
- package/web-ui/build/static/wasm-BVySa5nz.js +0 -1
- package/web-ui/build/static/web-idl-Cx8PIp9r.js +0 -1
- package/web-ui/build/static/wiki-CnAy151p.js +0 -1
- package/web-ui/build/static/wolfram-CJHJcKVC.js +0 -1
- package/web-ui/build/static/wren-C2PAcX7s.js +0 -1
- package/web-ui/build/static/x86asm-C1SuPV6P.js +0 -1
- package/web-ui/build/static/xeora-l6fZzLIy.js +0 -1
- package/web-ui/build/static/xl-CkVwYUVn.js +0 -1
- package/web-ui/build/static/xml-DLjQp4KT.js +0 -1
- package/web-ui/build/static/xml-doc-Dawa4cLr.js +0 -1
- package/web-ui/build/static/xojo-Da05ByLG.js +0 -1
- package/web-ui/build/static/xquery-CS7xhikd.js +0 -1
- package/web-ui/build/static/xquery-DFbsJTQt.js +0 -1
- package/web-ui/build/static/yaml-BGwGJYFK.js +0 -1
- package/web-ui/build/static/yaml-OtITZEUe.js +0 -1
- package/web-ui/build/static/yang-o4P5TRpK.js +0 -1
- package/web-ui/build/static/zephir-B7zGXFYj.js +0 -1
- package/web-ui/build/static/zig-DtRlHrbt.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
|