onbuzz 3.9.10 → 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 +554 -64
- 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 +9 -0
- 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-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
|
@@ -29,6 +29,7 @@ import ContextInjectionService from '../services/contextInjectionService.js';
|
|
|
29
29
|
import FlowContextService from '../services/flowContextService.js';
|
|
30
30
|
import TokenCountingService from '../services/tokenCountingService.js';
|
|
31
31
|
import ConversationCompactionService from '../services/conversationCompactionService.js';
|
|
32
|
+
import { getToolSchemasForAgent } from '../tools/openaiFunctionSchemas.js';
|
|
32
33
|
import {
|
|
33
34
|
shouldAgentBeActive,
|
|
34
35
|
getActiveAgents,
|
|
@@ -36,6 +37,16 @@ import {
|
|
|
36
37
|
} from '../services/agentActivityService.js';
|
|
37
38
|
|
|
38
39
|
class AgentScheduler {
|
|
40
|
+
/**
|
|
41
|
+
* Register the Discord service so the scheduler can ask whether a given
|
|
42
|
+
* agent is currently bridged — drives conditional `<external>` prompt
|
|
43
|
+
* injection per turn. Optional; unset if Discord isn't available.
|
|
44
|
+
*/
|
|
45
|
+
setDiscordService(discordService) { this.discordService = discordService; }
|
|
46
|
+
|
|
47
|
+
/** Same as {@link setDiscordService} but for Telegram. */
|
|
48
|
+
setTelegramService(telegramService) { this.telegramService = telegramService; }
|
|
49
|
+
|
|
39
50
|
constructor(agentPool, messageProcessor, aiService, logger, webSocketManager = null, modelRouterService = null, modelsService = null) {
|
|
40
51
|
this.agentPool = agentPool;
|
|
41
52
|
this.messageProcessor = messageProcessor;
|
|
@@ -93,11 +104,36 @@ class AgentScheduler {
|
|
|
93
104
|
// Structure: Map<agentId, number> - count of consecutive messages without tools
|
|
94
105
|
this.consecutiveNoToolMessages = new Map();
|
|
95
106
|
|
|
107
|
+
// Visualizer telemetry — see GET /scheduler endpoint.
|
|
108
|
+
// Ring buffer of recent cycle decisions + per-agent lock-acquire timestamps.
|
|
109
|
+
// Not load-bearing; safe to disable by never reading. See _recordCycle().
|
|
110
|
+
this._cycleHistory = []; // newest last
|
|
111
|
+
this._cycleCounter = 0;
|
|
112
|
+
this._lockAcquiredAt = new Map(); // agentId -> Date when lock was acquired
|
|
113
|
+
this._CYCLE_HISTORY_MAX = 200;
|
|
114
|
+
|
|
115
|
+
// Empty-response stall tracker. Populated only when a cycle received an
|
|
116
|
+
// AI response whose content was empty/whitespace AND carried no tool calls.
|
|
117
|
+
// Reset on any productive cycle. Structure: Map<agentId, { count, firstAt }>.
|
|
118
|
+
this._emptyResponseTracker = new Map();
|
|
119
|
+
|
|
96
120
|
// Configuration from constants (no magic numbers)
|
|
97
121
|
this.iterationDelayMs = SCHEDULER_CONFIG.ITERATION_DELAY_MS;
|
|
98
122
|
this.maxIterationsPerCycle = SCHEDULER_CONFIG.MAX_ITERATIONS_PER_CYCLE;
|
|
99
123
|
}
|
|
100
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Append one entry to the cycle-history ring buffer and trim to MAX.
|
|
127
|
+
* Telemetry for the scheduler visualizer.
|
|
128
|
+
* @private
|
|
129
|
+
*/
|
|
130
|
+
_recordCycle(entry) {
|
|
131
|
+
this._cycleHistory.push(entry);
|
|
132
|
+
if (this._cycleHistory.length > this._CYCLE_HISTORY_MAX) {
|
|
133
|
+
this._cycleHistory.splice(0, this._cycleHistory.length - this._CYCLE_HISTORY_MAX);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
101
137
|
/**
|
|
102
138
|
* Start the agent scheduler
|
|
103
139
|
*/
|
|
@@ -158,6 +194,9 @@ class AgentScheduler {
|
|
|
158
194
|
this.stateHashHistory.clear();
|
|
159
195
|
this.agentProcessingLocks.clear();
|
|
160
196
|
this.consecutiveNoToolMessages.clear();
|
|
197
|
+
this._lockAcquiredAt.clear();
|
|
198
|
+
this._cycleHistory.length = 0;
|
|
199
|
+
this._emptyResponseTracker.clear();
|
|
161
200
|
|
|
162
201
|
// Cleanup services
|
|
163
202
|
if (this.tokenCountingService && this.tokenCountingService.cleanup) {
|
|
@@ -167,6 +206,85 @@ class AgentScheduler {
|
|
|
167
206
|
this.logger.info('Agent Scheduler stopped');
|
|
168
207
|
}
|
|
169
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Atomic snapshot of scheduler + agent state, for the /scheduler visualizer.
|
|
211
|
+
*
|
|
212
|
+
* Everything here is read from in-memory state held by the scheduler or by
|
|
213
|
+
* AgentPool — there are no mutations, no network calls, and no awaits other
|
|
214
|
+
* than the single `agentPool.getAllAgents()` call (which is what the scheduler
|
|
215
|
+
* itself invokes every cycle, so calling it on demand is free).
|
|
216
|
+
*
|
|
217
|
+
* @returns {Promise<Object>}
|
|
218
|
+
*/
|
|
219
|
+
async getState() {
|
|
220
|
+
const allAgents = await this.agentPool.getAllAgents();
|
|
221
|
+
const now = Date.now();
|
|
222
|
+
const iter = (allAgents && typeof allAgents[Symbol.iterator] === 'function' && !Array.isArray(allAgents))
|
|
223
|
+
? allAgents.values()
|
|
224
|
+
: allAgents;
|
|
225
|
+
|
|
226
|
+
const agents = [];
|
|
227
|
+
for (const agent of iter) {
|
|
228
|
+
if (!agent) continue;
|
|
229
|
+
const activity = shouldAgentBeActive(agent);
|
|
230
|
+
const lockAcq = this._lockAcquiredAt.get(agent.id);
|
|
231
|
+
const tasks = agent.taskList?.tasks || [];
|
|
232
|
+
const nextActive = tasks.find(t => t.status === 'pending' || t.status === 'in_progress');
|
|
233
|
+
const queues = agent.messageQueues || {};
|
|
234
|
+
const activeAIReq = this.aiService?.getActiveRequest?.(agent.id) || null;
|
|
235
|
+
|
|
236
|
+
agents.push({
|
|
237
|
+
id: agent.id,
|
|
238
|
+
name: agent.name,
|
|
239
|
+
mode: agent.mode,
|
|
240
|
+
status: agent.status,
|
|
241
|
+
currentModel: agent.currentModel,
|
|
242
|
+
activity,
|
|
243
|
+
lockHeld: this.agentProcessingLocks.has(agent.id),
|
|
244
|
+
lockHeldMs: lockAcq ? now - lockAcq.getTime() : null,
|
|
245
|
+
delayEndTime: agent.delayEndTime || null,
|
|
246
|
+
delayedNow: !!(agent.delayEndTime && new Date(agent.delayEndTime).getTime() > now),
|
|
247
|
+
pausedUntil: agent.pausedUntil || null,
|
|
248
|
+
ttl: agent.ttl ?? null,
|
|
249
|
+
awaitingUserInput: agent.awaitingUserInput || null,
|
|
250
|
+
stopRequested: !!agent.stopRequested,
|
|
251
|
+
tasks: {
|
|
252
|
+
total: tasks.length,
|
|
253
|
+
pending: tasks.filter(t => t.status === 'pending').length,
|
|
254
|
+
inProgress: tasks.filter(t => t.status === 'in_progress').length,
|
|
255
|
+
completed: tasks.filter(t => t.status === 'completed').length,
|
|
256
|
+
nextPending: nextActive ? String(nextActive.content || '').slice(0, 120) : null,
|
|
257
|
+
},
|
|
258
|
+
queues: {
|
|
259
|
+
userMessages: Array.isArray(queues.userMessages) ? queues.userMessages.length : 0,
|
|
260
|
+
interAgentMessages: Array.isArray(queues.interAgentMessages) ? queues.interAgentMessages.length : 0,
|
|
261
|
+
toolResults: Array.isArray(queues.toolResults) ? queues.toolResults.length : 0,
|
|
262
|
+
},
|
|
263
|
+
activeAIRequest: activeAIReq,
|
|
264
|
+
stateHashHistory: (this.stateHashHistory.get(agent.id) || []).slice(-10),
|
|
265
|
+
emptyResponse: this._emptyResponseTracker.get(agent.id) || null,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
serverTime: new Date().toISOString(),
|
|
271
|
+
scheduler: {
|
|
272
|
+
running: this.isRunning,
|
|
273
|
+
iterationDelayMs: this.iterationDelayMs,
|
|
274
|
+
maxConcurrent: SCHEDULER_CONFIG.MAX_CONCURRENT_AGENTS || 3,
|
|
275
|
+
currentlyInFlight: this.agentProcessingLocks.size,
|
|
276
|
+
cycleCount: this._cycleCounter,
|
|
277
|
+
cycleHistoryMax: this._CYCLE_HISTORY_MAX,
|
|
278
|
+
},
|
|
279
|
+
locks: Array.from(this.agentProcessingLocks.keys()).map(id => ({
|
|
280
|
+
agentId: id,
|
|
281
|
+
heldMs: this._lockAcquiredAt.get(id) ? now - this._lockAcquiredAt.get(id).getTime() : null,
|
|
282
|
+
})),
|
|
283
|
+
cycles: this._cycleHistory.slice(), // newest last; client reverses
|
|
284
|
+
agents,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
170
288
|
/**
|
|
171
289
|
* Register an agent's session and ensure scheduler is running
|
|
172
290
|
*
|
|
@@ -189,16 +307,26 @@ class AgentScheduler {
|
|
|
189
307
|
});
|
|
190
308
|
}
|
|
191
309
|
|
|
192
|
-
// Clear hash history when user
|
|
193
|
-
//
|
|
194
|
-
|
|
310
|
+
// Clear hash history when the user takes an action that should reset the
|
|
311
|
+
// loop detector: either sending a new message or flipping the agent back
|
|
312
|
+
// into AGENT mode. Without the mode-change reset, a loop intervention
|
|
313
|
+
// that partially failed (e.g. persistAgentState threw before the cleanup
|
|
314
|
+
// could run) could leave stale hashes that re-fire the loop detector on
|
|
315
|
+
// the first cycle after the user resumed autopilot.
|
|
316
|
+
const isFreshStart = context.triggeredBy === 'user-message'
|
|
317
|
+
|| context.triggeredBy === 'mode-change-to-agent';
|
|
318
|
+
|
|
319
|
+
if (isFreshStart) {
|
|
195
320
|
this.clearHashHistory(agentId);
|
|
196
|
-
this.logger.debug(`Hash history cleared for agent ${agentId}
|
|
321
|
+
this.logger.debug(`Hash history cleared for agent ${agentId}`, { triggeredBy: context.triggeredBy });
|
|
197
322
|
|
|
198
|
-
// Also reset consecutive no-tool
|
|
323
|
+
// Also reset consecutive no-tool and empty-response trackers so the
|
|
324
|
+
// agent really does get a clean slate.
|
|
199
325
|
if (this.consecutiveNoToolMessages.has(agentId)) {
|
|
200
326
|
this.consecutiveNoToolMessages.set(agentId, 0);
|
|
201
|
-
|
|
327
|
+
}
|
|
328
|
+
if (this._emptyResponseTracker.has(agentId)) {
|
|
329
|
+
this._emptyResponseTracker.delete(agentId);
|
|
202
330
|
}
|
|
203
331
|
}
|
|
204
332
|
|
|
@@ -244,12 +372,18 @@ class AgentScheduler {
|
|
|
244
372
|
if (this.agentProcessingLocks.has(agentId)) {
|
|
245
373
|
this.agentProcessingLocks.delete(agentId);
|
|
246
374
|
}
|
|
375
|
+
this._lockAcquiredAt.delete(agentId);
|
|
247
376
|
|
|
248
377
|
// Clean up consecutive no-tool counter
|
|
249
378
|
if (this.consecutiveNoToolMessages.has(agentId)) {
|
|
250
379
|
this.consecutiveNoToolMessages.delete(agentId);
|
|
251
380
|
}
|
|
252
381
|
|
|
382
|
+
// Clean up empty-response tracker
|
|
383
|
+
if (this._emptyResponseTracker.has(agentId)) {
|
|
384
|
+
this._emptyResponseTracker.delete(agentId);
|
|
385
|
+
}
|
|
386
|
+
|
|
253
387
|
this.logger.debug(`Agent session cleaned up: ${agentId}`, { reason });
|
|
254
388
|
}
|
|
255
389
|
|
|
@@ -326,6 +460,9 @@ class AgentScheduler {
|
|
|
326
460
|
}
|
|
327
461
|
});
|
|
328
462
|
}
|
|
463
|
+
// Canonical state broadcast — ensures the UI flips the mode toggle
|
|
464
|
+
// even if it isn't listening for the legacy `execution_stopped` event.
|
|
465
|
+
await this.broadcastAgentStateUpdate(agentId, 'user-stopped');
|
|
329
466
|
|
|
330
467
|
this.logger.info(`Agent execution stopped: ${agentId}`, {
|
|
331
468
|
mode: agent.mode
|
|
@@ -365,27 +502,50 @@ class AgentScheduler {
|
|
|
365
502
|
// Get all agents from pool and determine which should be active
|
|
366
503
|
const allAgents = await this.agentPool.getAllAgents();
|
|
367
504
|
const activeAgentResults = getActiveAgents(allAgents);
|
|
505
|
+
const totalAgents = (allAgents && typeof allAgents.size === 'number') ? allAgents.size : (Array.isArray(allAgents) ? allAgents.length : 0);
|
|
506
|
+
const currentlyInFlightAtStart = this.agentProcessingLocks.size;
|
|
507
|
+
const cycleN = ++this._cycleCounter;
|
|
508
|
+
const cycleAt = new Date().toISOString();
|
|
368
509
|
|
|
369
510
|
if (activeAgentResults.length === 0) {
|
|
370
|
-
|
|
511
|
+
// No agents want to run this cycle.
|
|
512
|
+
this._recordCycle({
|
|
513
|
+
n: cycleN, at: cycleAt, totalAgents,
|
|
514
|
+
activeCount: 0, active: [],
|
|
515
|
+
inFlightAtStart: currentlyInFlightAtStart,
|
|
516
|
+
skippedLocked: [], skippedConcurrency: [], launched: [],
|
|
517
|
+
outcome: 'idle',
|
|
518
|
+
});
|
|
519
|
+
return;
|
|
371
520
|
}
|
|
372
521
|
|
|
373
522
|
// Concurrency enforcement: count how many agents are already in-flight
|
|
374
523
|
// from previous cycles, and only launch new ones up to the global cap.
|
|
375
524
|
const maxConcurrent = SCHEDULER_CONFIG.MAX_CONCURRENT_AGENTS || 3;
|
|
376
|
-
const currentlyInFlight =
|
|
525
|
+
const currentlyInFlight = currentlyInFlightAtStart;
|
|
377
526
|
|
|
378
527
|
// Filter out agents already being processed
|
|
528
|
+
const skippedLocked = [];
|
|
379
529
|
const unlockedAgents = activeAgentResults.filter(r => {
|
|
380
530
|
if (this.agentProcessingLocks.get(r.agentId)) {
|
|
381
531
|
this.logger.debug(`Agent ${r.agentId} still processing from previous cycle, skipping`);
|
|
532
|
+
skippedLocked.push(r.agentId);
|
|
382
533
|
return false;
|
|
383
534
|
}
|
|
384
535
|
return true;
|
|
385
536
|
});
|
|
386
537
|
|
|
387
538
|
if (unlockedAgents.length === 0) {
|
|
388
|
-
|
|
539
|
+
// Every active agent is wedged in a previous cycle's lock.
|
|
540
|
+
this._recordCycle({
|
|
541
|
+
n: cycleN, at: cycleAt, totalAgents,
|
|
542
|
+
activeCount: activeAgentResults.length,
|
|
543
|
+
active: activeAgentResults.map(r => ({ agentId: r.agentId, name: r.agent?.name, reason: r.reason, details: r.details })),
|
|
544
|
+
inFlightAtStart: currentlyInFlight,
|
|
545
|
+
skippedLocked, skippedConcurrency: [], launched: [],
|
|
546
|
+
outcome: 'all-locked',
|
|
547
|
+
});
|
|
548
|
+
return;
|
|
389
549
|
}
|
|
390
550
|
|
|
391
551
|
// Round-robin fairness: agents that launched in a recent cycle go to the back
|
|
@@ -399,9 +559,18 @@ class AgentScheduler {
|
|
|
399
559
|
// Cap new launches so total in-flight never exceeds MAX_CONCURRENT_AGENTS
|
|
400
560
|
const slotsAvailable = Math.max(0, maxConcurrent - currentlyInFlight);
|
|
401
561
|
const agentsToLaunch = unlockedAgents.slice(0, slotsAvailable);
|
|
562
|
+
const skippedConcurrency = unlockedAgents.slice(slotsAvailable).map(r => r.agentId);
|
|
402
563
|
|
|
403
564
|
if (agentsToLaunch.length === 0) {
|
|
404
565
|
this.logger.debug(`Concurrency cap reached: ${currentlyInFlight}/${maxConcurrent} agents in-flight, ${unlockedAgents.length} waiting`);
|
|
566
|
+
this._recordCycle({
|
|
567
|
+
n: cycleN, at: cycleAt, totalAgents,
|
|
568
|
+
activeCount: activeAgentResults.length,
|
|
569
|
+
active: activeAgentResults.map(r => ({ agentId: r.agentId, name: r.agent?.name, reason: r.reason, details: r.details })),
|
|
570
|
+
inFlightAtStart: currentlyInFlight,
|
|
571
|
+
skippedLocked, skippedConcurrency, launched: [],
|
|
572
|
+
outcome: 'concurrency-cap',
|
|
573
|
+
});
|
|
405
574
|
return;
|
|
406
575
|
}
|
|
407
576
|
|
|
@@ -413,6 +582,18 @@ class AgentScheduler {
|
|
|
413
582
|
// Track which agents we're launching for round-robin fairness
|
|
414
583
|
this._lastLaunchedAgentIds = new Set(agentsToLaunch.map(r => r.agentId));
|
|
415
584
|
|
|
585
|
+
// Record the launch decision before firing so the visualizer sees it
|
|
586
|
+
// even if the async launch errors.
|
|
587
|
+
this._recordCycle({
|
|
588
|
+
n: cycleN, at: cycleAt, totalAgents,
|
|
589
|
+
activeCount: activeAgentResults.length,
|
|
590
|
+
active: activeAgentResults.map(r => ({ agentId: r.agentId, name: r.agent?.name, reason: r.reason, details: r.details })),
|
|
591
|
+
inFlightAtStart: currentlyInFlight,
|
|
592
|
+
skippedLocked, skippedConcurrency,
|
|
593
|
+
launched: agentsToLaunch.map(r => r.agentId),
|
|
594
|
+
outcome: 'launched',
|
|
595
|
+
});
|
|
596
|
+
|
|
416
597
|
// Fire-and-forget: launch processing without awaiting.
|
|
417
598
|
// Each agent is protected by its own lock in processAgent().
|
|
418
599
|
// Next cycle (1s later) will pick up remaining agents when slots free up.
|
|
@@ -447,6 +628,7 @@ class AgentScheduler {
|
|
|
447
628
|
});
|
|
448
629
|
// Clean up on error - don't leave stale locks
|
|
449
630
|
this.agentProcessingLocks.delete(agentId);
|
|
631
|
+
this._lockAcquiredAt.delete(agentId);
|
|
450
632
|
}
|
|
451
633
|
})
|
|
452
634
|
);
|
|
@@ -475,6 +657,7 @@ class AgentScheduler {
|
|
|
475
657
|
|
|
476
658
|
// Set processing lock (prevents concurrent processing of the same agent)
|
|
477
659
|
this.agentProcessingLocks.set(agentId, true);
|
|
660
|
+
this._lockAcquiredAt.set(agentId, new Date());
|
|
478
661
|
|
|
479
662
|
try {
|
|
480
663
|
// Use centralized service to check if we should skip this iteration
|
|
@@ -531,14 +714,23 @@ class AgentScheduler {
|
|
|
531
714
|
return;
|
|
532
715
|
}
|
|
533
716
|
|
|
534
|
-
// Track
|
|
535
|
-
|
|
717
|
+
// Track what happened this cycle. Two independent signals:
|
|
718
|
+
// gotResponse — the AI service returned *anything* (vs null).
|
|
719
|
+
// advanced — the conversation actually moved forward (message
|
|
720
|
+
// appended or tools extracted). If false despite
|
|
721
|
+
// gotResponse=true, the model returned an empty or
|
|
722
|
+
// whitespace-only message with no tool calls — a
|
|
723
|
+
// "no-op cycle" that must NOT pollute stateHashHistory.
|
|
724
|
+
let gotResponse = false;
|
|
725
|
+
let advanced = false;
|
|
536
726
|
|
|
537
727
|
// Process based on whether there are messages or agent needs autonomous processing
|
|
538
728
|
if (totalMessages === 0 && agent.mode === AGENT_MODES.AGENT) {
|
|
539
729
|
// AGENT mode with no messages - check for task-based work
|
|
540
730
|
await this.autoCreateInitialTaskIfNeeded(agentId);
|
|
541
|
-
|
|
731
|
+
const result = await this.processAgentAutonomously(agentId);
|
|
732
|
+
gotResponse = result.gotResponse;
|
|
733
|
+
advanced = result.advanced;
|
|
542
734
|
} else if (totalMessages > 0) {
|
|
543
735
|
// Has messages to process
|
|
544
736
|
const processedMessages = await this.processAgentQueues(agentId);
|
|
@@ -548,9 +740,8 @@ class AgentScheduler {
|
|
|
548
740
|
const aiResponse = await this.getAgentAIResponse(agentId);
|
|
549
741
|
|
|
550
742
|
if (aiResponse) {
|
|
551
|
-
|
|
552
|
-
await this.processAIResponse(agentId, aiResponse);
|
|
553
|
-
gotNewAIResponse = true;
|
|
743
|
+
gotResponse = true;
|
|
744
|
+
advanced = await this.processAIResponse(agentId, aiResponse);
|
|
554
745
|
|
|
555
746
|
// Clear token limit retry tracker on successful AI response
|
|
556
747
|
this.clearTokenLimitRetryTracker(agentId);
|
|
@@ -561,12 +752,29 @@ class AgentScheduler {
|
|
|
561
752
|
}
|
|
562
753
|
// CHAT mode with no messages: do nothing - activity service will mark as inactive
|
|
563
754
|
|
|
564
|
-
// Only record state hash when
|
|
565
|
-
//
|
|
566
|
-
|
|
755
|
+
// Only record state hash when the conversation actually advanced. If
|
|
756
|
+
// the model returned an empty response (gotResponse=true, advanced=false),
|
|
757
|
+
// we're still in the same conversation state as before and recording
|
|
758
|
+
// would produce phantom duplicates that detectRepetitiveLoop misreads
|
|
759
|
+
// as progress toward a loop.
|
|
760
|
+
if (advanced) {
|
|
567
761
|
this.recordStateHash(agentId, currentStateHash);
|
|
568
762
|
}
|
|
569
763
|
|
|
764
|
+
// Empty-response stall detector. When the model returns an empty /
|
|
765
|
+
// whitespace-only response with no tool calls, we keep retrying — the
|
|
766
|
+
// next cycle may produce a real message. But we ring-buffer the empties
|
|
767
|
+
// so a genuinely stuck model eventually surfaces as a user-facing error
|
|
768
|
+
// instead of silently spinning forever.
|
|
769
|
+
if (gotResponse && !advanced) {
|
|
770
|
+
await this._trackEmptyResponse(agentId);
|
|
771
|
+
} else if (advanced) {
|
|
772
|
+
// Productive cycle — any previous stall has resolved itself.
|
|
773
|
+
if (this._emptyResponseTracker.has(agentId)) {
|
|
774
|
+
this._emptyResponseTracker.delete(agentId);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
570
778
|
// Decrement TTL (Time-to-Live) if set
|
|
571
779
|
// TTL gives agents extra processing cycles after clearing tasks
|
|
572
780
|
const agentForTtl = await this.agentPool.getAgent(agentId);
|
|
@@ -582,6 +790,7 @@ class AgentScheduler {
|
|
|
582
790
|
} finally {
|
|
583
791
|
// Always clear processing lock, even on errors
|
|
584
792
|
this.agentProcessingLocks.delete(agentId);
|
|
793
|
+
this._lockAcquiredAt.delete(agentId);
|
|
585
794
|
}
|
|
586
795
|
}
|
|
587
796
|
|
|
@@ -683,6 +892,20 @@ class AgentScheduler {
|
|
|
683
892
|
const toolIds = [...new Set(toolResults.map(m => m.toolId).filter(Boolean))];
|
|
684
893
|
toolResultContent += `[Tool Results — ${toolCount} result${toolCount > 1 ? 's' : ''} from ${turnCount} tool batch${turnCount > 1 ? 'es' : ''}: ${toolIds.join(', ')}]\n`;
|
|
685
894
|
|
|
895
|
+
// Current-working-directory banner. Reasoning models regularly forget
|
|
896
|
+
// that `change-directory` persists the CWD across turns and then
|
|
897
|
+
// re-prepend the project folder name to relative paths, which nests
|
|
898
|
+
// directories unintentionally (".../foo/foo/..."). Surfacing the CWD
|
|
899
|
+
// at the top of every tool-results injection gives the model a stable
|
|
900
|
+
// anchor: "you are HERE, all relative paths resolve from HERE."
|
|
901
|
+
try {
|
|
902
|
+
const agentForCwd = await this.agentPool.getAgent(agentId);
|
|
903
|
+
const cwd = agentForCwd?.directoryAccess?.workingDirectory;
|
|
904
|
+
if (cwd) {
|
|
905
|
+
toolResultContent += `[CWD: ${cwd} — relative paths resolve from here; do NOT prepend the project folder name]\n`;
|
|
906
|
+
}
|
|
907
|
+
} catch { /* best-effort; never block the tool-results injection */ }
|
|
908
|
+
|
|
686
909
|
if (turnCount === 1) {
|
|
687
910
|
// Single batch — flat list (no sub-headers needed)
|
|
688
911
|
toolResults.forEach(msg => {
|
|
@@ -805,11 +1028,11 @@ class AgentScheduler {
|
|
|
805
1028
|
*/
|
|
806
1029
|
async addMessageToConversation(agentId, message, broadcast = true) {
|
|
807
1030
|
const agent = await this.agentPool.getAgent(agentId);
|
|
808
|
-
if (!agent) return;
|
|
1031
|
+
if (!agent) return false;
|
|
809
1032
|
|
|
810
1033
|
// Format message based on queue type
|
|
811
1034
|
let formattedMessage;
|
|
812
|
-
|
|
1035
|
+
|
|
813
1036
|
switch (message.queueType) {
|
|
814
1037
|
case 'toolResults': // Tool results
|
|
815
1038
|
formattedMessage = {
|
|
@@ -818,7 +1041,7 @@ class AgentScheduler {
|
|
|
818
1041
|
content: this.formatToolResult(message)
|
|
819
1042
|
};
|
|
820
1043
|
break;
|
|
821
|
-
|
|
1044
|
+
|
|
822
1045
|
case 'interAgentMessages': // Inter-agent messages
|
|
823
1046
|
formattedMessage = {
|
|
824
1047
|
...message,
|
|
@@ -826,14 +1049,14 @@ class AgentScheduler {
|
|
|
826
1049
|
content: `Message from ${message.senderName || message.sender}: ${message.content}`
|
|
827
1050
|
};
|
|
828
1051
|
break;
|
|
829
|
-
|
|
1052
|
+
|
|
830
1053
|
case 'userMessages': // User messages
|
|
831
1054
|
formattedMessage = {
|
|
832
1055
|
...message,
|
|
833
1056
|
role: MESSAGE_ROLES.USER
|
|
834
1057
|
};
|
|
835
1058
|
break;
|
|
836
|
-
|
|
1059
|
+
|
|
837
1060
|
default:
|
|
838
1061
|
formattedMessage = message;
|
|
839
1062
|
}
|
|
@@ -843,7 +1066,10 @@ class AgentScheduler {
|
|
|
843
1066
|
formattedMessage.timestamp = new Date().toISOString();
|
|
844
1067
|
}
|
|
845
1068
|
|
|
846
|
-
// GUARD: Skip empty messages - they should never be added to history
|
|
1069
|
+
// GUARD: Skip empty messages - they should never be added to history.
|
|
1070
|
+
// Returning `false` lets the caller (processAIResponse) know the conversation
|
|
1071
|
+
// did NOT advance, so it can avoid polluting stateHashHistory and instead
|
|
1072
|
+
// mark the cycle as an "empty response" for the stall-detector.
|
|
847
1073
|
const messageContent = formattedMessage.content;
|
|
848
1074
|
if (!messageContent || (typeof messageContent === 'string' && !messageContent.trim())) {
|
|
849
1075
|
this.logger.warn(`Skipping empty message for agent ${agentId}`, {
|
|
@@ -851,7 +1077,7 @@ class AgentScheduler {
|
|
|
851
1077
|
queueType: message.queueType,
|
|
852
1078
|
hasContent: !!messageContent
|
|
853
1079
|
});
|
|
854
|
-
return; // Don't add empty messages
|
|
1080
|
+
return false; // Don't add empty messages; caller should treat as "no progress"
|
|
855
1081
|
}
|
|
856
1082
|
|
|
857
1083
|
// Add to conversation history
|
|
@@ -868,6 +1094,8 @@ class AgentScheduler {
|
|
|
868
1094
|
if (broadcast && this.shouldBroadcastMessage(formattedMessage)) {
|
|
869
1095
|
this.broadcastMessageUpdate(agentId, formattedMessage);
|
|
870
1096
|
}
|
|
1097
|
+
|
|
1098
|
+
return true;
|
|
871
1099
|
}
|
|
872
1100
|
|
|
873
1101
|
/**
|
|
@@ -883,16 +1111,22 @@ class AgentScheduler {
|
|
|
883
1111
|
const aiResponse = await this.getAgentAIResponse(agentId);
|
|
884
1112
|
|
|
885
1113
|
if (!aiResponse) {
|
|
886
|
-
|
|
1114
|
+
// No response - activity service will determine if we should continue.
|
|
1115
|
+
// Reported as { gotResponse: false } so the caller doesn't count this
|
|
1116
|
+
// as an "empty-response stall" (which is specifically about empty content).
|
|
1117
|
+
return { gotResponse: false, advanced: false };
|
|
887
1118
|
}
|
|
888
1119
|
|
|
889
|
-
// Process AI response and execute tools
|
|
890
|
-
|
|
1120
|
+
// Process AI response and execute tools. processAIResponse returns `true`
|
|
1121
|
+
// when the conversation actually advanced (assistant message appended or
|
|
1122
|
+
// tool calls extracted), and `false` when the response was empty/whitespace
|
|
1123
|
+
// and carried no tools.
|
|
1124
|
+
const advanced = await this.processAIResponse(agentId, aiResponse);
|
|
891
1125
|
|
|
892
1126
|
// Clear token limit retry tracker on successful AI response
|
|
893
1127
|
this.clearTokenLimitRetryTracker(agentId);
|
|
894
1128
|
|
|
895
|
-
return
|
|
1129
|
+
return { gotResponse: true, advanced };
|
|
896
1130
|
}
|
|
897
1131
|
|
|
898
1132
|
/**
|
|
@@ -1530,6 +1764,30 @@ class AgentScheduler {
|
|
|
1530
1764
|
enhancedSystemPrompt = (enhancedSystemPrompt || '') + systemConstraints;
|
|
1531
1765
|
}
|
|
1532
1766
|
|
|
1767
|
+
// Inject external-channel routing guidance ONLY when the agent has
|
|
1768
|
+
// at least one live bridge. Pulls the per-channel alias list from
|
|
1769
|
+
// each service so the agent can address specific channels/threads
|
|
1770
|
+
// via `<external to="alias">`. When the agent isn't bridged the
|
|
1771
|
+
// paragraph is omitted — no point teaching routing for listeners
|
|
1772
|
+
// that aren't there. Filter + alias matching logic live in
|
|
1773
|
+
// services/channelFilter.js so this block stays declarative.
|
|
1774
|
+
try {
|
|
1775
|
+
const activeChannels = [];
|
|
1776
|
+
if (typeof this.discordService?.getBridgedChannels === 'function') {
|
|
1777
|
+
activeChannels.push(...this.discordService.getBridgedChannels(agentId));
|
|
1778
|
+
}
|
|
1779
|
+
if (typeof this.telegramService?.getBridgedChannels === 'function') {
|
|
1780
|
+
activeChannels.push(...this.telegramService.getBridgedChannels(agentId));
|
|
1781
|
+
}
|
|
1782
|
+
if (activeChannels.length > 0) {
|
|
1783
|
+
const { getExternalChannelPromptGuidance } = await import('../services/channelFilter.js');
|
|
1784
|
+
const guidance = getExternalChannelPromptGuidance(activeChannels);
|
|
1785
|
+
if (guidance) enhancedSystemPrompt = (enhancedSystemPrompt || '') + guidance;
|
|
1786
|
+
}
|
|
1787
|
+
} catch (err) {
|
|
1788
|
+
this.logger.warn('[external-routing] failed to inject <external> guidance', { agentId, error: err.message });
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1533
1791
|
// Inject flow execution context if this is part of a flow
|
|
1534
1792
|
try {
|
|
1535
1793
|
const lastUserMsg = [...conversationHistory].reverse().find(m => m.role === 'user');
|
|
@@ -1564,6 +1822,15 @@ class AgentScheduler {
|
|
|
1564
1822
|
? userStreamingPref !== false
|
|
1565
1823
|
: agent.streamingEnabled !== false; // Default to true
|
|
1566
1824
|
|
|
1825
|
+
// Native function-call tools for the agent's enabled capabilities.
|
|
1826
|
+
// Passed as `options.tools` to the backend. For Responses-API models
|
|
1827
|
+
// (codex/o-series/gpt-5-pro) the backend forwards these to Azure so
|
|
1828
|
+
// the model can emit native function_call events; the backend converts
|
|
1829
|
+
// them back into the CLI's inline JSON-block format on the wire. For
|
|
1830
|
+
// chat-completion models the backend ignores this field and the model
|
|
1831
|
+
// uses the system prompt's inline-JSON instructions as before.
|
|
1832
|
+
const toolSchemas = getToolSchemasForAgent(agent.capabilities || []);
|
|
1833
|
+
|
|
1567
1834
|
if (streamingEnabled && this.aiService.sendMessageStream) {
|
|
1568
1835
|
// Build flow context if this is part of a flow execution
|
|
1569
1836
|
const flowContext = lastUserMsg?.isFlowExecution ? {
|
|
@@ -1579,7 +1846,8 @@ class AgentScheduler {
|
|
|
1579
1846
|
enhancedSystemPrompt,
|
|
1580
1847
|
sessionId,
|
|
1581
1848
|
agent.platformProvided,
|
|
1582
|
-
flowContext
|
|
1849
|
+
flowContext,
|
|
1850
|
+
toolSchemas
|
|
1583
1851
|
);
|
|
1584
1852
|
}
|
|
1585
1853
|
|
|
@@ -1608,7 +1876,8 @@ class AgentScheduler {
|
|
|
1608
1876
|
agentId: agentId,
|
|
1609
1877
|
systemPrompt: enhancedSystemPrompt,
|
|
1610
1878
|
sessionId: sessionId,
|
|
1611
|
-
platformProvided: agent.platformProvided
|
|
1879
|
+
platformProvided: agent.platformProvided,
|
|
1880
|
+
tools: toolSchemas && toolSchemas.length > 0 ? toolSchemas : undefined,
|
|
1612
1881
|
}
|
|
1613
1882
|
);
|
|
1614
1883
|
|
|
@@ -1642,7 +1911,7 @@ class AgentScheduler {
|
|
|
1642
1911
|
* @returns {Promise<Object>} Response object
|
|
1643
1912
|
* @private
|
|
1644
1913
|
*/
|
|
1645
|
-
async _getStreamingResponse(agentId, targetModel, messagesToSend, systemPrompt, sessionId, platformProvided, flowContext = null) {
|
|
1914
|
+
async _getStreamingResponse(agentId, targetModel, messagesToSend, systemPrompt, sessionId, platformProvided, flowContext = null, tools = null) {
|
|
1646
1915
|
// Generate a unique message ID for this streaming response
|
|
1647
1916
|
const streamMessageId = `stream-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1648
1917
|
|
|
@@ -1704,6 +1973,7 @@ class AgentScheduler {
|
|
|
1704
1973
|
systemPrompt: systemPrompt,
|
|
1705
1974
|
sessionId: sessionId,
|
|
1706
1975
|
platformProvided: platformProvided,
|
|
1976
|
+
tools: tools && tools.length > 0 ? tools : undefined,
|
|
1707
1977
|
onChunk: (chunk) => {
|
|
1708
1978
|
// First chunk — clear the prestream watchdog. Active streaming means
|
|
1709
1979
|
// the model is responsive; we don't want to cut a live stream off.
|
|
@@ -1898,6 +2168,7 @@ class AgentScheduler {
|
|
|
1898
2168
|
// Switch agent to CHAT mode - no delay, user can retry when ready
|
|
1899
2169
|
agent.mode = AGENT_MODES.CHAT;
|
|
1900
2170
|
await this.agentPool.persistAgentState(agentId);
|
|
2171
|
+
await this.broadcastAgentStateUpdate(agentId, 'timeout');
|
|
1901
2172
|
|
|
1902
2173
|
// Broadcast timeout notification to UI (toast + console log only, no chat message)
|
|
1903
2174
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
@@ -1924,6 +2195,7 @@ class AgentScheduler {
|
|
|
1924
2195
|
|
|
1925
2196
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.API_KEY_ERROR_DELAY_MS).toISOString();
|
|
1926
2197
|
await this.agentPool.persistAgentState(agentId);
|
|
2198
|
+
await this.broadcastAgentStateUpdate(agentId, 'api-key-error');
|
|
1927
2199
|
|
|
1928
2200
|
// Add error message to agent's queue
|
|
1929
2201
|
await this.agentPool.addToolResult(agentId, {
|
|
@@ -1939,6 +2211,7 @@ class AgentScheduler {
|
|
|
1939
2211
|
|
|
1940
2212
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.RATE_LIMIT_DELAY_MS).toISOString();
|
|
1941
2213
|
await this.agentPool.persistAgentState(agentId);
|
|
2214
|
+
await this.broadcastAgentStateUpdate(agentId, 'rate-limit');
|
|
1942
2215
|
|
|
1943
2216
|
} else if (errorMessage.includes('network') || errorMessage.includes('connection')) {
|
|
1944
2217
|
// Network issues (non-timeout) - shorter delay and retry
|
|
@@ -1946,6 +2219,7 @@ class AgentScheduler {
|
|
|
1946
2219
|
|
|
1947
2220
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.NETWORK_ERROR_DELAY_MS).toISOString();
|
|
1948
2221
|
await this.agentPool.persistAgentState(agentId);
|
|
2222
|
+
await this.broadcastAgentStateUpdate(agentId, 'network-error');
|
|
1949
2223
|
|
|
1950
2224
|
} else if (this.isTokenLimitError(errorMessage)) {
|
|
1951
2225
|
// Token/context limit error - trigger emergency compaction and retry
|
|
@@ -1958,6 +2232,7 @@ class AgentScheduler {
|
|
|
1958
2232
|
|
|
1959
2233
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.UNKNOWN_ERROR_DELAY_MS).toISOString();
|
|
1960
2234
|
await this.agentPool.persistAgentState(agentId);
|
|
2235
|
+
await this.broadcastAgentStateUpdate(agentId, 'server-error');
|
|
1961
2236
|
|
|
1962
2237
|
// Add error message to agent's queue
|
|
1963
2238
|
await this.agentPool.addToolResult(agentId, {
|
|
@@ -2052,6 +2327,7 @@ class AgentScheduler {
|
|
|
2052
2327
|
// Now show the error to the user
|
|
2053
2328
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.UNKNOWN_ERROR_DELAY_MS).toISOString();
|
|
2054
2329
|
await this.agentPool.persistAgentState(agentId);
|
|
2330
|
+
await this.broadcastAgentStateUpdate(agentId, 'context-limit-exhausted');
|
|
2055
2331
|
|
|
2056
2332
|
// Broadcast error to UI
|
|
2057
2333
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
@@ -2324,9 +2600,18 @@ class AgentScheduler {
|
|
|
2324
2600
|
}
|
|
2325
2601
|
|
|
2326
2602
|
/**
|
|
2327
|
-
* Process AI response and execute any tools
|
|
2603
|
+
* Process AI response and execute any tools.
|
|
2604
|
+
*
|
|
2605
|
+
* Returns `true` when the conversation actually advanced (either the assistant
|
|
2606
|
+
* message was appended or tool calls were queued for async execution), and
|
|
2607
|
+
* `false` when the response had empty / whitespace content AND no tool calls.
|
|
2608
|
+
* The caller (processAgent) uses this to decide whether to record the
|
|
2609
|
+
* pre-cycle state hash — preventing the detectRepetitiveLoop pollution that
|
|
2610
|
+
* empty responses would otherwise cause.
|
|
2611
|
+
*
|
|
2328
2612
|
* @param {string} agentId - Agent ID
|
|
2329
2613
|
* @param {Object} aiResponse - AI service response
|
|
2614
|
+
* @returns {Promise<boolean>} true if conversation advanced, false on dropped-empty
|
|
2330
2615
|
* @private
|
|
2331
2616
|
*/
|
|
2332
2617
|
async processAIResponse(agentId, aiResponse) {
|
|
@@ -2337,7 +2622,7 @@ class AgentScheduler {
|
|
|
2337
2622
|
// Safety check: agent must exist
|
|
2338
2623
|
if (!agent) {
|
|
2339
2624
|
this.logger.warn(`Cannot process AI response - agent ${agentId} not found`);
|
|
2340
|
-
return;
|
|
2625
|
+
return false;
|
|
2341
2626
|
}
|
|
2342
2627
|
|
|
2343
2628
|
// Check if response contains tool calls
|
|
@@ -2377,13 +2662,32 @@ class AgentScheduler {
|
|
|
2377
2662
|
|
|
2378
2663
|
// Normalize token usage field names (backend may send input_tokens/output_tokens
|
|
2379
2664
|
// instead of prompt_tokens/completion_tokens depending on provider)
|
|
2665
|
+
// NOTE: use ?? (not ||) so that a genuine 0 doesn't fall through to the next
|
|
2666
|
+
// field — but also guard against the case where `tokenUsage` is entirely
|
|
2667
|
+
// absent or empty. Emits a one-shot debug log so we can see the actual
|
|
2668
|
+
// shape once per unusual response in server logs.
|
|
2380
2669
|
let normalizedTokenUsage = null;
|
|
2381
2670
|
if (aiResponse.tokenUsage) {
|
|
2671
|
+
const u = aiResponse.tokenUsage;
|
|
2382
2672
|
normalizedTokenUsage = {
|
|
2383
|
-
prompt_tokens:
|
|
2384
|
-
completion_tokens:
|
|
2385
|
-
total_tokens:
|
|
2673
|
+
prompt_tokens: u.prompt_tokens ?? u.input_tokens ?? 0,
|
|
2674
|
+
completion_tokens: u.completion_tokens ?? u.output_tokens ?? 0,
|
|
2675
|
+
total_tokens: u.total_tokens ?? ((u.prompt_tokens ?? u.input_tokens ?? 0) + (u.completion_tokens ?? u.output_tokens ?? 0)),
|
|
2386
2676
|
};
|
|
2677
|
+
if (process.env.DEBUG_TOKEN_USAGE === '1' || normalizedTokenUsage.total_tokens === 0) {
|
|
2678
|
+
this.logger.warn('[TOKEN-USAGE] non-zero expected but got zero or debug-requested', {
|
|
2679
|
+
agentId,
|
|
2680
|
+
model: aiResponse.model,
|
|
2681
|
+
rawTokenUsage: u,
|
|
2682
|
+
normalized: normalizedTokenUsage,
|
|
2683
|
+
});
|
|
2684
|
+
}
|
|
2685
|
+
} else if (process.env.DEBUG_TOKEN_USAGE === '1') {
|
|
2686
|
+
this.logger.warn('[TOKEN-USAGE] aiResponse has no tokenUsage field', {
|
|
2687
|
+
agentId,
|
|
2688
|
+
model: aiResponse.model,
|
|
2689
|
+
aiResponseKeys: Object.keys(aiResponse || {}),
|
|
2690
|
+
});
|
|
2387
2691
|
}
|
|
2388
2692
|
|
|
2389
2693
|
// Create response message
|
|
@@ -2400,18 +2704,27 @@ class AgentScheduler {
|
|
|
2400
2704
|
pendingToolExecution: hasTools
|
|
2401
2705
|
};
|
|
2402
2706
|
|
|
2403
|
-
await this.addMessageToConversation(agentId, responseMessage, false);
|
|
2707
|
+
const appended = await this.addMessageToConversation(agentId, responseMessage, false);
|
|
2404
2708
|
|
|
2405
|
-
// IMMEDIATELY broadcast the AI response to UI (don't wait for tool execution)
|
|
2406
|
-
if
|
|
2709
|
+
// IMMEDIATELY broadcast the AI response to UI (don't wait for tool execution).
|
|
2710
|
+
// We only broadcast if the message actually made it into the conversation —
|
|
2711
|
+
// broadcasting an empty message confuses the UI.
|
|
2712
|
+
if (appended && this.shouldBroadcastMessage(responseMessage)) {
|
|
2407
2713
|
const updatedAgent = await this.agentPool.getAgent(agentId);
|
|
2408
2714
|
this.broadcastMessageUpdate(agentId, responseMessage, {
|
|
2409
2715
|
agentCurrentModel: updatedAgent?.currentModel
|
|
2410
2716
|
});
|
|
2411
2717
|
}
|
|
2412
2718
|
|
|
2413
|
-
// Execute tools ASYNCHRONOUSLY - don't block the response
|
|
2719
|
+
// Execute tools ASYNCHRONOUSLY - don't block the response. Tools run even
|
|
2720
|
+
// if the assistant message itself was empty and dropped, so long as the
|
|
2721
|
+
// content string happened to contain tool-call markup.
|
|
2414
2722
|
this._executeToolsAsync(agentId, aiResponse.content, sessionId, responseMessage.id);
|
|
2723
|
+
|
|
2724
|
+
// The cycle "made progress" if EITHER the assistant message was persisted
|
|
2725
|
+
// or a tool call was extracted from the content (tools will surface new
|
|
2726
|
+
// messages through the toolResults queue next cycle).
|
|
2727
|
+
return appended || hasTools;
|
|
2415
2728
|
}
|
|
2416
2729
|
|
|
2417
2730
|
/**
|
|
@@ -2463,6 +2776,7 @@ class AgentScheduler {
|
|
|
2463
2776
|
if (agent) {
|
|
2464
2777
|
agent.delayEndTime = new Date(Date.now() + maxDelay).toISOString();
|
|
2465
2778
|
await this.agentPool.persistAgentState(agentId);
|
|
2779
|
+
await this.broadcastAgentStateUpdate(agentId, 'builtin-delay');
|
|
2466
2780
|
this.logger.debug(`Agent ${agentId} - applying ${maxDelay}ms builtin delay for tool execution`);
|
|
2467
2781
|
}
|
|
2468
2782
|
}
|
|
@@ -2704,6 +3018,45 @@ class AgentScheduler {
|
|
|
2704
3018
|
* @param {Object} agentInfo - Additional agent information for UI sync
|
|
2705
3019
|
* @private
|
|
2706
3020
|
*/
|
|
3021
|
+
/**
|
|
3022
|
+
* Broadcast an agent state snapshot (mode, delayEndTime, awaitingUserInput,
|
|
3023
|
+
* stopRequested) whenever the scheduler mutates one of those fields.
|
|
3024
|
+
*
|
|
3025
|
+
* The UI reducer merges this payload into its agent record, so a single
|
|
3026
|
+
* helper call everywhere-the-state-changes keeps the UI in sync without
|
|
3027
|
+
* adding one-off event types per scenario. `reason` is a short tag
|
|
3028
|
+
* (`timeout`, `rate-limit`, `builtin-delay`, `loop-detected`, etc.) so the
|
|
3029
|
+
* UI can render a human-readable cause if it wants to.
|
|
3030
|
+
*
|
|
3031
|
+
* Best-effort: a missing webSocketManager or a sessionless agent makes this
|
|
3032
|
+
* a no-op. Never throws.
|
|
3033
|
+
*
|
|
3034
|
+
* @param {string} agentId
|
|
3035
|
+
* @param {string} reason Short tag describing WHY the state changed.
|
|
3036
|
+
*/
|
|
3037
|
+
async broadcastAgentStateUpdate(agentId, reason = 'state-change') {
|
|
3038
|
+
try {
|
|
3039
|
+
if (!this.webSocketManager?.broadcastToSession) return;
|
|
3040
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
3041
|
+
if (!agent) return;
|
|
3042
|
+
const sessionId = this.getAgentSession(agentId) || agent.sessionId || 'scheduler-session';
|
|
3043
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3044
|
+
type: 'agent_state_updated',
|
|
3045
|
+
data: {
|
|
3046
|
+
agentId,
|
|
3047
|
+
mode: agent.mode,
|
|
3048
|
+
delayEndTime: agent.delayEndTime || null,
|
|
3049
|
+
awaitingUserInput: agent.awaitingUserInput || null,
|
|
3050
|
+
stopRequested: !!agent.stopRequested,
|
|
3051
|
+
reason,
|
|
3052
|
+
timestamp: new Date().toISOString(),
|
|
3053
|
+
},
|
|
3054
|
+
});
|
|
3055
|
+
} catch (err) {
|
|
3056
|
+
this.logger?.warn?.(`agent_state_updated broadcast failed: ${err.message}`, { agentId, reason });
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
|
|
2707
3060
|
broadcastMessageUpdate(agentId, message, agentInfo = {}) {
|
|
2708
3061
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
2709
3062
|
// Get the session ID from session map, message, or fallback
|
|
@@ -3220,6 +3573,127 @@ class AgentScheduler {
|
|
|
3220
3573
|
};
|
|
3221
3574
|
}
|
|
3222
3575
|
|
|
3576
|
+
/**
|
|
3577
|
+
* Record a cycle where the model returned an empty or whitespace-only
|
|
3578
|
+
* response that carried no tool calls. The scheduler keeps retrying — the
|
|
3579
|
+
* next cycle may produce a real message — but we buffer the empties so
|
|
3580
|
+
* we can surface a clear error to the user if the stall persists.
|
|
3581
|
+
*
|
|
3582
|
+
* @param {string} agentId
|
|
3583
|
+
* @private
|
|
3584
|
+
*/
|
|
3585
|
+
async _trackEmptyResponse(agentId) {
|
|
3586
|
+
const now = Date.now();
|
|
3587
|
+
const existing = this._emptyResponseTracker.get(agentId);
|
|
3588
|
+
const entry = existing
|
|
3589
|
+
? { count: existing.count + 1, firstAt: existing.firstAt, lastAt: now }
|
|
3590
|
+
: { count: 1, firstAt: now, lastAt: now };
|
|
3591
|
+
|
|
3592
|
+
this._emptyResponseTracker.set(agentId, entry);
|
|
3593
|
+
|
|
3594
|
+
this.logger.warn(`[EMPTY-RESPONSE] Agent ${agentId}: cycle produced no content`, {
|
|
3595
|
+
count: entry.count,
|
|
3596
|
+
elapsedMs: now - entry.firstAt,
|
|
3597
|
+
threshold: SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_THRESHOLD,
|
|
3598
|
+
windowMs: SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_WINDOW_MS,
|
|
3599
|
+
});
|
|
3600
|
+
|
|
3601
|
+
const shouldStall =
|
|
3602
|
+
entry.count >= SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_THRESHOLD &&
|
|
3603
|
+
(now - entry.firstAt) >= SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_WINDOW_MS;
|
|
3604
|
+
|
|
3605
|
+
if (shouldStall) {
|
|
3606
|
+
try {
|
|
3607
|
+
await this._handleEmptyResponseStall(agentId, entry);
|
|
3608
|
+
} finally {
|
|
3609
|
+
this._emptyResponseTracker.delete(agentId);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3614
|
+
/**
|
|
3615
|
+
* Circuit breaker fired when an agent has produced N empty responses across
|
|
3616
|
+
* at least the configured time window. Surfaces a user-facing error message,
|
|
3617
|
+
* switches the agent to CHAT mode (scheduler will mark it inactive), and
|
|
3618
|
+
* clears scheduler-side state that could otherwise keep re-firing.
|
|
3619
|
+
*
|
|
3620
|
+
* Mirrors the shape of handleRepetitiveLoop but with a different message
|
|
3621
|
+
* explaining the actual failure mode.
|
|
3622
|
+
*
|
|
3623
|
+
* @param {string} agentId
|
|
3624
|
+
* @param {{count: number, firstAt: number, lastAt: number}} entry
|
|
3625
|
+
* @private
|
|
3626
|
+
*/
|
|
3627
|
+
async _handleEmptyResponseStall(agentId, entry) {
|
|
3628
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
3629
|
+
if (!agent) return;
|
|
3630
|
+
|
|
3631
|
+
// Clear scheduler state FIRST so any throw in persistence / broadcast below
|
|
3632
|
+
// can't leave us re-firing this handler next cycle.
|
|
3633
|
+
this.stateHashHistory.delete(agentId);
|
|
3634
|
+
this.consecutiveNoToolMessages.delete(agentId);
|
|
3635
|
+
|
|
3636
|
+
const elapsedSec = Math.round((entry.lastAt - entry.firstAt) / 1000);
|
|
3637
|
+
const interventionMessage = `The model returned ${entry.count} empty responses in a row over ${elapsedSec}s. ` +
|
|
3638
|
+
`I've switched to chat mode so you can retry or adjust. Common causes: ` +
|
|
3639
|
+
`the selected model is unreachable, rate-limited, or rejecting the current ` +
|
|
3640
|
+
`conversation. You can pick a different model or send a new message to try again.`;
|
|
3641
|
+
|
|
3642
|
+
const messageToAdd = {
|
|
3643
|
+
id: `msg-empty-response-stall-${Date.now()}`,
|
|
3644
|
+
role: 'assistant',
|
|
3645
|
+
content: interventionMessage,
|
|
3646
|
+
timestamp: new Date().toISOString(),
|
|
3647
|
+
isSystemMessage: true,
|
|
3648
|
+
emptyResponseStall: {
|
|
3649
|
+
count: entry.count,
|
|
3650
|
+
elapsedMs: entry.lastAt - entry.firstAt,
|
|
3651
|
+
},
|
|
3652
|
+
};
|
|
3653
|
+
|
|
3654
|
+
if (agent.conversations && agent.conversations.full) {
|
|
3655
|
+
agent.conversations.full.messages.push(messageToAdd);
|
|
3656
|
+
agent.conversations.full.lastUpdated = new Date().toISOString();
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
agent.mode = AGENT_MODES.CHAT;
|
|
3660
|
+
|
|
3661
|
+
// Persist + broadcast are best-effort — a failure here must NOT leave the
|
|
3662
|
+
// agent in a re-firing state. Scheduler state was cleared above.
|
|
3663
|
+
try {
|
|
3664
|
+
await this.agentPool.persistAgentState(agentId);
|
|
3665
|
+
} catch (err) {
|
|
3666
|
+
this.logger.error(`Failed to persist agent after empty-response stall: ${err.message}`, { agentId });
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
const sessionId = this.getAgentSession(agentId) || agent.sessionId;
|
|
3670
|
+
if (sessionId && this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
3671
|
+
try {
|
|
3672
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3673
|
+
type: 'message_added',
|
|
3674
|
+
data: { agentId, message: messageToAdd, type: 'empty_response_stall' },
|
|
3675
|
+
});
|
|
3676
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3677
|
+
type: 'agent_mode_changed',
|
|
3678
|
+
data: {
|
|
3679
|
+
agentId,
|
|
3680
|
+
mode: AGENT_MODES.CHAT,
|
|
3681
|
+
reason: 'empty_response_stall',
|
|
3682
|
+
timestamp: new Date().toISOString(),
|
|
3683
|
+
},
|
|
3684
|
+
});
|
|
3685
|
+
} catch (err) {
|
|
3686
|
+
this.logger.warn(`Failed to broadcast empty-response stall: ${err.message}`, { agentId });
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
await this.broadcastAgentStateUpdate(agentId, 'empty-response-stall');
|
|
3690
|
+
|
|
3691
|
+
this.logger.error(`Agent ${agentId} switched to CHAT mode after ${entry.count} empty responses`, {
|
|
3692
|
+
agentName: agent.name,
|
|
3693
|
+
elapsedMs: entry.lastAt - entry.firstAt,
|
|
3694
|
+
});
|
|
3695
|
+
}
|
|
3696
|
+
|
|
3223
3697
|
/**
|
|
3224
3698
|
* Record a state hash in the sliding window
|
|
3225
3699
|
*
|
|
@@ -3260,6 +3734,14 @@ class AgentScheduler {
|
|
|
3260
3734
|
const agent = await this.agentPool.getAgent(agentId);
|
|
3261
3735
|
if (!agent) return;
|
|
3262
3736
|
|
|
3737
|
+
// Clear scheduler state FIRST. If persistAgentState or a WebSocket broadcast
|
|
3738
|
+
// throws below, we must NOT leave stale loop-detector state that would
|
|
3739
|
+
// re-fire this handler on the next scheduler cycle — that was the exact
|
|
3740
|
+
// "detects a loop repeatedly without adding a new message first" bug.
|
|
3741
|
+
this.stateHashHistory.delete(agentId);
|
|
3742
|
+
this._emptyResponseTracker.delete(agentId);
|
|
3743
|
+
this.consecutiveNoToolMessages.delete(agentId);
|
|
3744
|
+
|
|
3263
3745
|
// Create a user-friendly message
|
|
3264
3746
|
const interventionMessage = `I notice I've been producing similar responses repeatedly (${loopDetection.occurrences} times). This usually means I'm stuck or need your guidance. I've switched to chat mode so you can provide direction.
|
|
3265
3747
|
|
|
@@ -3289,35 +3771,43 @@ What would you like me to do next? You can:
|
|
|
3289
3771
|
|
|
3290
3772
|
// Stop the agent execution - switch to chat mode
|
|
3291
3773
|
agent.mode = AGENT_MODES.CHAT;
|
|
3292
|
-
|
|
3774
|
+
|
|
3775
|
+
// Persist + broadcast are best-effort. Scheduler state was already cleared
|
|
3776
|
+
// above, so a failure here can still leave the intervention un-persisted
|
|
3777
|
+
// but won't cause the loop detector to re-fire.
|
|
3778
|
+
try {
|
|
3779
|
+
await this.agentPool.persistAgentState(agentId);
|
|
3780
|
+
} catch (err) {
|
|
3781
|
+
this.logger.error(`Failed to persist agent after loop detection: ${err.message}`, { agentId });
|
|
3782
|
+
}
|
|
3293
3783
|
|
|
3294
3784
|
// Broadcast the message to UI so it appears in the chat
|
|
3295
3785
|
const sessionId = this.getAgentSession(agentId) || agent.sessionId;
|
|
3296
3786
|
if (sessionId && this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3787
|
+
try {
|
|
3788
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3789
|
+
type: 'message_added',
|
|
3790
|
+
data: {
|
|
3791
|
+
agentId,
|
|
3792
|
+
message: messageToAdd,
|
|
3793
|
+
type: 'loop_intervention'
|
|
3794
|
+
}
|
|
3795
|
+
});
|
|
3306
3796
|
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
}
|
|
3316
|
-
})
|
|
3797
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3798
|
+
type: 'agent_mode_changed',
|
|
3799
|
+
data: {
|
|
3800
|
+
agentId,
|
|
3801
|
+
mode: AGENT_MODES.CHAT,
|
|
3802
|
+
reason: 'loop_detected',
|
|
3803
|
+
timestamp: new Date().toISOString()
|
|
3804
|
+
}
|
|
3805
|
+
});
|
|
3806
|
+
} catch (err) {
|
|
3807
|
+
this.logger.warn(`Failed to broadcast loop intervention: ${err.message}`, { agentId });
|
|
3808
|
+
}
|
|
3317
3809
|
}
|
|
3318
|
-
|
|
3319
|
-
// Clear the hash history for this agent (fresh start when user responds)
|
|
3320
|
-
this.stateHashHistory.delete(agentId);
|
|
3810
|
+
await this.broadcastAgentStateUpdate(agentId, 'loop-detected');
|
|
3321
3811
|
|
|
3322
3812
|
this.logger.warn(`Agent ${agentId} stopped due to repetitive loop - awaiting user intervention`, {
|
|
3323
3813
|
occurrences: loopDetection.occurrences,
|