onbuzz 3.9.10 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/__tests__/agentPool.test.js +60 -0
- package/src/core/__tests__/agentScheduler.test.js +129 -0
- package/src/core/agentPool.js +24 -0
- package/src/core/agentScheduler.js +574 -73
- package/src/index.js +8 -0
- package/src/interfaces/webServer.js +288 -0
- package/src/services/__tests__/channelFilter.test.js +264 -0
- package/src/services/__tests__/channelRelay.integration.test.js +496 -0
- package/src/services/__tests__/discordService.integration.test.js +10 -10
- package/src/services/__tests__/discordService.test.js +14 -7
- package/src/services/aiService.js +10 -3
- package/src/services/channelFilter.js +137 -0
- package/src/services/discordService.js +103 -19
- package/src/services/telegramService.js +58 -1
- package/src/tools/__tests__/visualEditorTool.context.test.js +141 -0
- package/src/tools/fileSystemTool.js +27 -3
- package/src/tools/openaiFunctionSchemas.js +270 -0
- package/src/tools/taskManagerTool.js +45 -2
- package/src/tools/terminalTool.js +23 -2
- package/src/tools/visualEditorTool.js +28 -4
- package/src/utilities/constants.js +9 -0
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/1c-BbqxH6FC.js +1 -0
- package/web-ui/build/static/abap-UmHCZ0i1.js +1 -0
- package/web-ui/build/static/abnf-KQJciEU1.js +1 -0
- package/web-ui/build/static/abnf-wz9mo6UY.js +1 -0
- package/web-ui/build/static/accesslog-a-KjP-hj.js +1 -0
- package/web-ui/build/static/actionscript-C0kkFktE.js +1 -0
- package/web-ui/build/static/actionscript-CVfzNF7V.js +1 -0
- package/web-ui/build/static/ada-BtDccpCo.js +1 -0
- package/web-ui/build/static/ada-CsP-T950.js +1 -0
- package/web-ui/build/static/agda-DZ0Wv_k_.js +1 -0
- package/web-ui/build/static/al-Dieo4A36.js +1 -0
- package/web-ui/build/static/angelscript-Dxqs-qHl.js +1 -0
- package/web-ui/build/static/antlr4-2iwVxagJ.js +1 -0
- package/web-ui/build/static/apache-nHxOzinq.js +1 -0
- package/web-ui/build/static/apacheconf-DxkrSh6l.js +1 -0
- package/web-ui/build/static/apex-Broi_TKn.js +1 -0
- package/web-ui/build/static/apl-iAZYRZnE.js +1 -0
- package/web-ui/build/static/applescript-C-EKPlRf.js +1 -0
- package/web-ui/build/static/applescript-CVipha9P.js +1 -0
- package/web-ui/build/static/aql-Dn0E4LhK.js +1 -0
- package/web-ui/build/static/arcade-D5kIj1ez.js +1 -0
- package/web-ui/build/static/arduino-CydV4LN9.js +1 -0
- package/web-ui/build/static/arduino-DXaSwrry.js +1 -0
- package/web-ui/build/static/arff-yeDNnxkY.js +1 -0
- package/web-ui/build/static/armasm-DTu74JIo.js +1 -0
- package/web-ui/build/static/asciidoc-CLaqB1Gg.js +1 -0
- package/web-ui/build/static/asciidoc-DguUDHf5.js +1 -0
- package/web-ui/build/static/asm6502-C2c-H0Jh.js +1 -0
- package/web-ui/build/static/asmatmel-5xAyVq56.js +1 -0
- package/web-ui/build/static/aspectj-D5JvBRBv.js +1 -0
- package/web-ui/build/static/aspnet-DZfW9iG1.js +1 -0
- package/web-ui/build/static/autohotkey-3yT8W87y.js +1 -0
- package/web-ui/build/static/autohotkey-CxEWa3D5.js +1 -0
- package/web-ui/build/static/autoit-COt7rtxE.js +1 -0
- package/web-ui/build/static/autoit-DSva7SrP.js +1 -0
- package/web-ui/build/static/avisynth-DdpQ810f.js +1 -0
- package/web-ui/build/static/avrasm-BR0ncM-L.js +1 -0
- package/web-ui/build/static/avro-idl-DCISsbhh.js +1 -0
- package/web-ui/build/static/awk-Dd5HJDa0.js +1 -0
- package/web-ui/build/static/axapta-DWn0qUrW.js +1 -0
- package/web-ui/build/static/bash-B024Y1MV.js +1 -0
- package/web-ui/build/static/bash-qq4eTfOM.js +1 -0
- package/web-ui/build/static/basic-BWjvt39D.js +1 -0
- package/web-ui/build/static/basic-DVlMYdnX.js +1 -0
- package/web-ui/build/static/batch-Bb3dgg5p.js +1 -0
- package/web-ui/build/static/bbcode-DIclgs6t.js +1 -0
- package/web-ui/build/static/bicep-CXafPJf-.js +1 -0
- package/web-ui/build/static/birb-Btu8LQQE.js +1 -0
- package/web-ui/build/static/bison-CDXROKZw.js +1 -0
- package/web-ui/build/static/bnf-BB43qRSC.js +1 -0
- package/web-ui/build/static/bnf-ClpHUN6K.js +1 -0
- package/web-ui/build/static/brainfuck-BIgmc-EZ.js +1 -0
- package/web-ui/build/static/brainfuck-BJtPWa6l.js +1 -0
- package/web-ui/build/static/brightscript-9fU7OT4Y.js +1 -0
- package/web-ui/build/static/bro-DLftyzoO.js +1 -0
- package/web-ui/build/static/bsl-BWPnBSvd.js +1 -0
- package/web-ui/build/static/c-CD-936sv.js +1 -0
- package/web-ui/build/static/c-Do5sfWh2.js +1 -0
- package/web-ui/build/static/c-like-Cerk48hs.js +1 -0
- package/web-ui/build/static/cal-BfMsPDa0.js +1 -0
- package/web-ui/build/static/capnproto-mR83jTKG.js +1 -0
- package/web-ui/build/static/ceylon-Dt2cl-Ez.js +1 -0
- package/web-ui/build/static/cfscript-CFB-YYf8.js +1 -0
- package/web-ui/build/static/chaiscript-D3skeymm.js +1 -0
- package/web-ui/build/static/cil-DeczQ_ut.js +1 -0
- package/web-ui/build/static/clean-BXJPwGNL.js +1 -0
- package/web-ui/build/static/clojure-HHG1U7gj.js +1 -0
- package/web-ui/build/static/clojure-rEWdWYo_.js +1 -0
- package/web-ui/build/static/clojure-repl-CE4jr3K0.js +1 -0
- package/web-ui/build/static/cmake-DAzvKH16.js +1 -0
- package/web-ui/build/static/cmake-tD6uZl-y.js +1 -0
- package/web-ui/build/static/cobol-C2X6-bRz.js +1 -0
- package/web-ui/build/static/coffeescript-C9qjSh74.js +1 -0
- package/web-ui/build/static/coffeescript-DeHnRseX.js +1 -0
- package/web-ui/build/static/concurnas-DNuInYde.js +1 -0
- package/web-ui/build/static/coq-BQFo5XwN.js +1 -0
- package/web-ui/build/static/coq-Bmnum53S.js +1 -0
- package/web-ui/build/static/cos-D_0u-U2Y.js +1 -0
- package/web-ui/build/static/cpp-CoD9F6ol.js +1 -0
- package/web-ui/build/static/cpp-DB8R2f_c.js +1 -0
- package/web-ui/build/static/crmsh-DghD3B1u.js +1 -0
- package/web-ui/build/static/crystal-C63_SlFe.js +1 -0
- package/web-ui/build/static/crystal-GkhJSVpE.js +1 -0
- package/web-ui/build/static/csharp-Upa_qqR3.js +1 -0
- package/web-ui/build/static/csharp-kB8isYBD.js +1 -0
- package/web-ui/build/static/cshtml-BjeIyJW7.js +1 -0
- package/web-ui/build/static/csp-B9zvIPTA.js +1 -0
- package/web-ui/build/static/csp-hqOQW_KO.js +1 -0
- package/web-ui/build/static/css-BOqi7Sb8.js +1 -0
- package/web-ui/build/static/css-extras-NaDRDQYb.js +1 -0
- package/web-ui/build/static/csv-C7zNP0bV.js +1 -0
- package/web-ui/build/static/cypher-DzSGt09R.js +1 -0
- package/web-ui/build/static/d-DU9v7A7o.js +1 -0
- package/web-ui/build/static/d-YLgAiEhY.js +1 -0
- package/web-ui/build/static/dart-CLSlIEjd.js +1 -0
- package/web-ui/build/static/dart-Cv0y84fm.js +1 -0
- package/web-ui/build/static/dataweave-5zYOQCxv.js +1 -0
- package/web-ui/build/static/dax-C6xLX5GM.js +1 -0
- package/web-ui/build/static/delphi-D5HcUuVw.js +1 -0
- package/web-ui/build/static/dhall-C8OzwmzV.js +1 -0
- package/web-ui/build/static/diff-B030ZRbb.js +1 -0
- package/web-ui/build/static/diff-NCsBJCa7.js +1 -0
- package/web-ui/build/static/django-BeQDLTjX.js +1 -0
- package/web-ui/build/static/django-cC0WFEf1.js +1 -0
- package/web-ui/build/static/dns-CGMMfnr4.js +1 -0
- package/web-ui/build/static/dns-zone-file-908DrcaX.js +1 -0
- package/web-ui/build/static/docker-CE6F0WPR.js +1 -0
- package/web-ui/build/static/dockerfile-CUNa_EmN.js +1 -0
- package/web-ui/build/static/dos-CiM5tkPu.js +1 -0
- package/web-ui/build/static/dot-CZ0WLAzq.js +1 -0
- package/web-ui/build/static/dsconfig-Wo1ktU-F.js +1 -0
- package/web-ui/build/static/dts-BQJ7eIaM.js +1 -0
- package/web-ui/build/static/dust-DWnG4XQf.js +1 -0
- package/web-ui/build/static/ebnf-BqQRECjk.js +1 -0
- package/web-ui/build/static/ebnf-Cn_QHOpW.js +1 -0
- package/web-ui/build/static/editorconfig-CRE_lK21.js +1 -0
- package/web-ui/build/static/eiffel-h-dSP-Mu.js +1 -0
- package/web-ui/build/static/ejs-PVoVLwHk.js +1 -0
- package/web-ui/build/static/elixir-DVoAEVq_.js +1 -0
- package/web-ui/build/static/elixir-ZA65-L5t.js +1 -0
- package/web-ui/build/static/elm-ClRnxcFJ.js +1 -0
- package/web-ui/build/static/elm-Ttg_Dv8v.js +1 -0
- package/web-ui/build/static/erb-DCMJz1va.js +1 -0
- package/web-ui/build/static/erb-DDL7TB76.js +1 -0
- package/web-ui/build/static/erlang-01AtuMB8.js +1 -0
- package/web-ui/build/static/erlang-CLb6foRm.js +1 -0
- package/web-ui/build/static/erlang-repl-BwUG_X-H.js +1 -0
- package/web-ui/build/static/etlua-7jIebQwZ.js +1 -0
- package/web-ui/build/static/excel-BkKnPFBB.js +1 -0
- package/web-ui/build/static/excel-formula-dDd7nIUV.js +1 -0
- package/web-ui/build/static/factor-BLn5sqxN.js +1 -0
- package/web-ui/build/static/false-CNuRH4WA.js +1 -0
- package/web-ui/build/static/firestore-security-rules-Cr5e6oSH.js +1 -0
- package/web-ui/build/static/fix-NJ8G_1Tt.js +1 -0
- package/web-ui/build/static/flix-CBhTDcl9.js +1 -0
- package/web-ui/build/static/flow-DvgK1btf.js +1 -0
- package/web-ui/build/static/fortran-Bo-O9xtT.js +1 -0
- package/web-ui/build/static/fortran-Dj3v5L_m.js +1 -0
- package/web-ui/build/static/fsharp-5c6P8ZUH.js +1 -0
- package/web-ui/build/static/fsharp-C8bhnjfe.js +1 -0
- package/web-ui/build/static/ftl-8qE-2FJL.js +1 -0
- package/web-ui/build/static/gams-pbQRvKgr.js +1 -0
- package/web-ui/build/static/gap-CSFizYYs.js +1 -0
- package/web-ui/build/static/gauss-C0BsqEdj.js +1 -0
- package/web-ui/build/static/gcode-DMuLrnJF.js +1 -0
- package/web-ui/build/static/gcode-as5uEQOe.js +1 -0
- package/web-ui/build/static/gdscript-CSaSlSna.js +1 -0
- package/web-ui/build/static/gedcom-Cm86Ngut.js +1 -0
- package/web-ui/build/static/gherkin-C7FSJ6d3.js +1 -0
- package/web-ui/build/static/gherkin-C8wqlUqv.js +1 -0
- package/web-ui/build/static/git-DzPBmHlg.js +1 -0
- package/web-ui/build/static/glsl-D0_rPD58.js +1 -0
- package/web-ui/build/static/glsl-oUwWN2Xp.js +1 -0
- package/web-ui/build/static/gml-DNrWm4kb.js +1 -0
- package/web-ui/build/static/gml-JDXVyhBU.js +1 -0
- package/web-ui/build/static/gn-Bw-OsDH_.js +1 -0
- package/web-ui/build/static/go-B7Traa8J.js +1 -0
- package/web-ui/build/static/go-CaXFvYLQ.js +1 -0
- package/web-ui/build/static/go-module-BzKKnNxf.js +1 -0
- package/web-ui/build/static/golo-BokfRozl.js +1 -0
- package/web-ui/build/static/gradle-BBE_z74S.js +1 -0
- package/web-ui/build/static/graphql-DyqQ249q.js +1 -0
- package/web-ui/build/static/groovy-C9bdtULM.js +1 -0
- package/web-ui/build/static/groovy-CTYHYVKe.js +1 -0
- package/web-ui/build/static/haml--wzGI8rV.js +1 -0
- package/web-ui/build/static/haml-CP_fk9Du.js +1 -0
- package/web-ui/build/static/handlebars-BCN8I_fU.js +1 -0
- package/web-ui/build/static/handlebars-ClNs_EWN.js +1 -0
- package/web-ui/build/static/haskell-9-8FOmKL.js +1 -0
- package/web-ui/build/static/haskell-CeDcPoLF.js +1 -0
- package/web-ui/build/static/haxe-50b4_Uxu.js +1 -0
- package/web-ui/build/static/haxe-DV1jCpSQ.js +1 -0
- package/web-ui/build/static/hcl-BYAKEmjA.js +1 -0
- package/web-ui/build/static/hlsl-_V666kTg.js +1 -0
- package/web-ui/build/static/hoon-Xx5CPs_2.js +1 -0
- package/web-ui/build/static/hpkp-Dgu8ZS6s.js +1 -0
- package/web-ui/build/static/hsp-B0EcUcwP.js +1 -0
- package/web-ui/build/static/hsts-B1FQvgxb.js +1 -0
- package/web-ui/build/static/htmlbars-BGs3CWC2.js +1 -0
- package/web-ui/build/static/http-BvrKmZx0.js +1 -0
- package/web-ui/build/static/http-DUnWgTgI.js +1 -0
- package/web-ui/build/static/hy-StjWDayT.js +1 -0
- package/web-ui/build/static/ichigojam-Dla3EUZJ.js +1 -0
- package/web-ui/build/static/icon-CEA3F2cM.js +1 -0
- package/web-ui/build/static/icu-message-format-CIRX0H1E.js +1 -0
- package/web-ui/build/static/idris-z8g0EYLs.js +1 -0
- package/web-ui/build/static/iecst-D99vO-YV.js +1 -0
- package/web-ui/build/static/ignore-Bd9HTGo7.js +1 -0
- package/web-ui/build/static/index-9mcWHG2c.js +13 -0
- package/web-ui/build/static/index-BUtXAjd5.css +1 -0
- package/web-ui/build/static/index-CaMlGjdh.js +834 -0
- package/web-ui/build/static/index-D35injhb.js +1 -0
- package/web-ui/build/static/inform7-CKq2EPhg.js +1 -0
- package/web-ui/build/static/inform7-D-KIfWlv.js +1 -0
- package/web-ui/build/static/ini-CoFKaEFp.js +1 -0
- package/web-ui/build/static/ini-Cqh2VeO8.js +1 -0
- package/web-ui/build/static/io-A1ozJngc.js +1 -0
- package/web-ui/build/static/irpf90-DLGfrn4I.js +1 -0
- package/web-ui/build/static/isbl-dbyF-dLf.js +1 -0
- package/web-ui/build/static/j-ByhCpf6J.js +1 -0
- package/web-ui/build/static/java-DCbnRaHw.js +1 -0
- package/web-ui/build/static/java-LzFZofIb.js +1 -0
- package/web-ui/build/static/javadoc-CaKRZCNM.js +1 -0
- package/web-ui/build/static/javadoclike-CmvAiCvn.js +1 -0
- package/web-ui/build/static/javascript-Cpvfsh-z.js +1 -0
- package/web-ui/build/static/javastacktrace-CSUMoXqu.js +1 -0
- package/web-ui/build/static/jboss-cli-Cv0HXjqO.js +1 -0
- package/web-ui/build/static/jexl-CtUU8Pyc.js +1 -0
- package/web-ui/build/static/jolie-Ccbea_Ca.js +1 -0
- package/web-ui/build/static/jq-DQJKGqGL.js +1 -0
- package/web-ui/build/static/js-extras-BST2fo5a.js +1 -0
- package/web-ui/build/static/js-templates-T4aqrsni.js +1 -0
- package/web-ui/build/static/jsdoc-DZuHBRHT.js +1 -0
- package/web-ui/build/static/json-ByIlxtOm.js +1 -0
- package/web-ui/build/static/json-Dd-I2QR8.js +1 -0
- package/web-ui/build/static/json5-CIBARWXJ.js +1 -0
- package/web-ui/build/static/jsonp-Cs7yuq7_.js +1 -0
- package/web-ui/build/static/jsstacktrace-DrmYorp8.js +1 -0
- package/web-ui/build/static/jsx-Clb0obdm.js +1 -0
- package/web-ui/build/static/julia-BreTVWTb.js +1 -0
- package/web-ui/build/static/julia-qQfG7KSh.js +1 -0
- package/web-ui/build/static/julia-repl-wN09lKm6.js +1 -0
- package/web-ui/build/static/keepalived-DCyf_6ml.js +1 -0
- package/web-ui/build/static/keyman-B22SYHoa.js +1 -0
- package/web-ui/build/static/kotlin-DeVs-dNz.js +1 -0
- package/web-ui/build/static/kotlin-OMSaUY06.js +1 -0
- package/web-ui/build/static/kumir-Y-M6VOUG.js +1 -0
- package/web-ui/build/static/kusto-BnDldn0z.js +1 -0
- package/web-ui/build/static/lasso-BlUPIy-8.js +1 -0
- package/web-ui/build/static/latex-BGueNdTW.js +1 -0
- package/web-ui/build/static/latex-EZ8QNCjf.js +1 -0
- package/web-ui/build/static/latte-BkyPxQ_A.js +1 -0
- package/web-ui/build/static/ldif-BCIcpQI_.js +1 -0
- package/web-ui/build/static/leaf-BAG78wZj.js +1 -0
- package/web-ui/build/static/less-CFghh9Qx.js +1 -0
- package/web-ui/build/static/less-CbqfFGMD.js +1 -0
- package/web-ui/build/static/lilypond-BSpYx-1e.js +1 -0
- package/web-ui/build/static/liquid-CHhOmyTU.js +1 -0
- package/web-ui/build/static/lisp-QMm5BThy.js +1 -0
- package/web-ui/build/static/lisp-rizdk7e8.js +1 -0
- package/web-ui/build/static/livecodeserver-Bbh0nB2d.js +1 -0
- package/web-ui/build/static/livescript--QIhQOIm.js +1 -0
- package/web-ui/build/static/livescript-wYJ9C7MN.js +1 -0
- package/web-ui/build/static/llvm-qWkZ6M3-.js +1 -0
- package/web-ui/build/static/llvm-x8W93e2q.js +1 -0
- package/web-ui/build/static/log-D4PGnDHU.js +1 -0
- package/web-ui/build/static/lolcode-CHKS4ygP.js +1 -0
- package/web-ui/build/static/lsl-BEuQrHG7.js +1 -0
- package/web-ui/build/static/lua-Czrw1nZw.js +1 -0
- package/web-ui/build/static/lua-DUasTiYT.js +1 -0
- package/web-ui/build/static/magma-B16nUtxA.js +1 -0
- package/web-ui/build/static/makefile-BkqsEpVd.js +1 -0
- package/web-ui/build/static/makefile-DmoEDBJj.js +1 -0
- package/web-ui/build/static/markdown-FL-EZYmc.js +1 -0
- package/web-ui/build/static/markdown-N4YibSvf.js +1 -0
- package/web-ui/build/static/markup-templating-C1Q3BuB3.js +1 -0
- package/web-ui/build/static/mathematica-BZ50Ibwb.js +1 -0
- package/web-ui/build/static/matlab-CJFiUipn.js +1 -0
- package/web-ui/build/static/matlab-D-LwnpYW.js +1 -0
- package/web-ui/build/static/maxima-D1nKJHio.js +1 -0
- package/web-ui/build/static/maxscript-3ukqkynT.js +1 -0
- package/web-ui/build/static/mel-BpGPnIg7.js +1 -0
- package/web-ui/build/static/mel-DAIpK4k4.js +1 -0
- package/web-ui/build/static/mercury-BO6AXAJw.js +1 -0
- package/web-ui/build/static/mermaid-Cvu66kFB.js +1 -0
- package/web-ui/build/static/mipsasm-CP7z3_gg.js +1 -0
- package/web-ui/build/static/mizar-1tBmTbFY.js +1 -0
- package/web-ui/build/static/mizar-vPQKaBOY.js +1 -0
- package/web-ui/build/static/mojolicious-3wXNqu2Z.js +1 -0
- package/web-ui/build/static/mongodb-DkJ5x1x3.js +1 -0
- package/web-ui/build/static/monkey-DwU43sRn.js +1 -0
- package/web-ui/build/static/monkey-DzoqN4GB.js +1 -0
- package/web-ui/build/static/moonscript-CgTduPCr.js +1 -0
- package/web-ui/build/static/moonscript-Dzbt70Ke.js +1 -0
- package/web-ui/build/static/n1ql-BaVhxD8V.js +1 -0
- package/web-ui/build/static/n1ql-DUHSzjt3.js +1 -0
- package/web-ui/build/static/n4js-DZ7dW-NZ.js +1 -0
- package/web-ui/build/static/nand2tetris-hdl-C-ecDW8U.js +1 -0
- package/web-ui/build/static/naniscript-dzw8pH4q.js +1 -0
- package/web-ui/build/static/nasm-B0fCm10I.js +1 -0
- package/web-ui/build/static/neon-DRlFTieL.js +1 -0
- package/web-ui/build/static/nevod-BEzTxq7x.js +1 -0
- package/web-ui/build/static/nginx-BI0b7qBW.js +1 -0
- package/web-ui/build/static/nginx-BTbIqU-1.js +1 -0
- package/web-ui/build/static/nim-C1lYEnIA.js +1 -0
- package/web-ui/build/static/nim-mfWcJfe-.js +1 -0
- package/web-ui/build/static/nix-PO76YCUx.js +1 -0
- package/web-ui/build/static/nix-a-29l1yK.js +1 -0
- package/web-ui/build/static/node-repl-DDA8xtxU.js +1 -0
- package/web-ui/build/static/nsis-CLyYop70.js +1 -0
- package/web-ui/build/static/nsis-GiqT6oer.js +1 -0
- package/web-ui/build/static/objectivec-DF-fhcs7.js +1 -0
- package/web-ui/build/static/objectivec-DtXa6iKB.js +1 -0
- package/web-ui/build/static/ocaml-D4ptVFU5.js +1 -0
- package/web-ui/build/static/ocaml-DBtZVh9H.js +1 -0
- package/web-ui/build/static/opencl-0Z_Gtfzx.js +1 -0
- package/web-ui/build/static/openqasm-BafUOtKF.js +1 -0
- package/web-ui/build/static/openscad-DwQ7I7ze.js +1 -0
- package/web-ui/build/static/oxygene-Bt7r8sbX.js +1 -0
- package/web-ui/build/static/oz-Da-qnXiT.js +1 -0
- package/web-ui/build/static/parigp-D6mMgLkz.js +1 -0
- package/web-ui/build/static/parser-DUfGrzvv.js +1 -0
- package/web-ui/build/static/parser3-C4GwCqRM.js +1 -0
- package/web-ui/build/static/pascal-CKsIwy8z.js +1 -0
- package/web-ui/build/static/pascaligo-0Y00fNzu.js +1 -0
- package/web-ui/build/static/pcaxis-BFwUDXM-.js +1 -0
- package/web-ui/build/static/peoplecode-D8-HVebY.js +1 -0
- package/web-ui/build/static/perl-CoNeuMP2.js +1 -0
- package/web-ui/build/static/perl-Dk_kCckE.js +1 -0
- package/web-ui/build/static/pf-DWKdp2Z5.js +1 -0
- package/web-ui/build/static/pgsql-DQM_KLIL.js +1 -0
- package/web-ui/build/static/php-BLJ1RddK.js +1 -0
- package/web-ui/build/static/php-C4Q-EoBs.js +1 -0
- package/web-ui/build/static/php-extras-DH16mdyb.js +1 -0
- package/web-ui/build/static/php-template-Bgyau4h4.js +1 -0
- package/web-ui/build/static/phpdoc-CrGYZCs3.js +1 -0
- package/web-ui/build/static/plaintext--cxrnnIY.js +1 -0
- package/web-ui/build/static/plsql-DXxJ1j1M.js +1 -0
- package/web-ui/build/static/pony-Bk4QKmb5.js +1 -0
- package/web-ui/build/static/powerquery-BNY7Y_eg.js +1 -0
- package/web-ui/build/static/powershell-CjTGWZrY.js +1 -0
- package/web-ui/build/static/powershell-DKKBTrGN.js +1 -0
- package/web-ui/build/static/processing-CoCmNEON.js +1 -0
- package/web-ui/build/static/processing-dWxOKKau.js +1 -0
- package/web-ui/build/static/profile-DinHOW6q.js +1 -0
- package/web-ui/build/static/prolog-D8s2MxCR.js +1 -0
- package/web-ui/build/static/prolog-tfF0hJ7N.js +1 -0
- package/web-ui/build/static/promql-BbpNnYtf.js +1 -0
- package/web-ui/build/static/properties-BH5IGhCw.js +1 -0
- package/web-ui/build/static/properties-BtBGEFji.js +1 -0
- package/web-ui/build/static/protobuf-Bq57MNXu.js +1 -0
- package/web-ui/build/static/protobuf-FQ5v_34f.js +1 -0
- package/web-ui/build/static/psl-DH3KK34y.js +1 -0
- package/web-ui/build/static/pug-BH0-FqNN.js +1 -0
- package/web-ui/build/static/puppet-D6IQ0-e_.js +1 -0
- package/web-ui/build/static/puppet-DhDhkrHQ.js +1 -0
- package/web-ui/build/static/pure-D-zzqNXt.js +1 -0
- package/web-ui/build/static/purebasic-C3ZHqBxR.js +1 -0
- package/web-ui/build/static/purebasic-DTWXM0iu.js +1 -0
- package/web-ui/build/static/purescript-C9dMZi0f.js +1 -0
- package/web-ui/build/static/python-kp4UxaFP.js +1 -0
- package/web-ui/build/static/python-repl-Bugvu_dB.js +1 -0
- package/web-ui/build/static/python-vnX1mWhI.js +1 -0
- package/web-ui/build/static/q-BRREgX-f.js +1 -0
- package/web-ui/build/static/q-V3GLDm_n.js +1 -0
- package/web-ui/build/static/qml-DfQdRLrG.js +1 -0
- package/web-ui/build/static/qml-i0MLAsR_.js +1 -0
- package/web-ui/build/static/qore-CFRmreiI.js +1 -0
- package/web-ui/build/static/qsharp-BpxCSpMu.js +1 -0
- package/web-ui/build/static/r-BFhn56zx.js +1 -0
- package/web-ui/build/static/r-D19R1VlL.js +1 -0
- package/web-ui/build/static/racket-D6Do3XQN.js +1 -0
- package/web-ui/build/static/reason-BLxB_uYS.js +1 -0
- package/web-ui/build/static/reasonml-CR2O5QXc.js +1 -0
- package/web-ui/build/static/regex-ExQT3DD-.js +1 -0
- package/web-ui/build/static/rego-BG1H2Grq.js +1 -0
- package/web-ui/build/static/renpy-DPYPiSEa.js +1 -0
- package/web-ui/build/static/rest-BXeudWmA.js +1 -0
- package/web-ui/build/static/rib-B50qbZUa.js +1 -0
- package/web-ui/build/static/rip-Oy08VNTd.js +1 -0
- package/web-ui/build/static/roboconf-BJlNdB3f.js +1 -0
- package/web-ui/build/static/roboconf-BWCGa42W.js +1 -0
- package/web-ui/build/static/robotframework-CrL-sTEo.js +1 -0
- package/web-ui/build/static/routeros-BV_7BLfU.js +1 -0
- package/web-ui/build/static/rsl-3QUMrc7D.js +1 -0
- package/web-ui/build/static/ruby-CocpOjC3.js +1 -0
- package/web-ui/build/static/ruby-xGmQ173X.js +1 -0
- package/web-ui/build/static/ruleslanguage-Dvh9iMSY.js +1 -0
- package/web-ui/build/static/rust-BZNigb_r.js +1 -0
- package/web-ui/build/static/rust-DwNjoaBZ.js +1 -0
- package/web-ui/build/static/sas-BJAlmleu.js +1 -0
- package/web-ui/build/static/sas-DMbLpxbs.js +1 -0
- package/web-ui/build/static/sass-DqYzzuDm.js +1 -0
- package/web-ui/build/static/scala-Bh2FkhWY.js +1 -0
- package/web-ui/build/static/scala-CBjzCnx6.js +1 -0
- package/web-ui/build/static/scheme-D2RTBnn4.js +1 -0
- package/web-ui/build/static/scheme-YLsRQlUd.js +1 -0
- package/web-ui/build/static/scilab-CXvKl1CZ.js +1 -0
- package/web-ui/build/static/scss-BE2dzDGl.js +1 -0
- package/web-ui/build/static/scss-J1E3J7lz.js +1 -0
- package/web-ui/build/static/shell-AzmPYKrI.js +1 -0
- package/web-ui/build/static/shell-session-C5dCMLWG.js +1 -0
- package/web-ui/build/static/smali-C88i6nEO.js +1 -0
- package/web-ui/build/static/smali-Ddnoiqfy.js +1 -0
- package/web-ui/build/static/smalltalk-C72n_dxy.js +1 -0
- package/web-ui/build/static/smalltalk-CPfRSVZs.js +1 -0
- package/web-ui/build/static/smarty-Dypt4i8b.js +1 -0
- package/web-ui/build/static/sml-BGGb-k8a.js +1 -0
- package/web-ui/build/static/sml-BODNZSm_.js +1 -0
- package/web-ui/build/static/solidity-D6wtTexR.js +1 -0
- package/web-ui/build/static/solution-file-5lZW0oOE.js +1 -0
- package/web-ui/build/static/soy-y16jnIDo.js +1 -0
- package/web-ui/build/static/sparql-DrdB7SPu.js +1 -0
- package/web-ui/build/static/splunk-spl-Doyv_CQR.js +1 -0
- package/web-ui/build/static/sqf-BSSKLJcS.js +1 -0
- package/web-ui/build/static/sqf-C27vJSdk.js +1 -0
- package/web-ui/build/static/sql-BGAlidwo.js +1 -0
- package/web-ui/build/static/sql-D632T_PJ.js +1 -0
- package/web-ui/build/static/sql_more-DxYQWBWa.js +1 -0
- package/web-ui/build/static/squirrel-BtynEITS.js +1 -0
- package/web-ui/build/static/stan-_WgX5GWP.js +1 -0
- package/web-ui/build/static/stan-oF5qmMKy.js +1 -0
- package/web-ui/build/static/stata-wLOz3xoi.js +1 -0
- package/web-ui/build/static/step21-BbsA7W89.js +1 -0
- package/web-ui/build/static/stylus-DtfRtkyR.js +1 -0
- package/web-ui/build/static/stylus-vEf2q3jH.js +1 -0
- package/web-ui/build/static/subunit-BRaQkxqR.js +1 -0
- package/web-ui/build/static/swift-DT015mq6.js +1 -0
- package/web-ui/build/static/swift-Drl9Vhia.js +1 -0
- package/web-ui/build/static/systemd-DWH7nh0Q.js +1 -0
- package/web-ui/build/static/t4-cs-BqiTmoCX.js +1 -0
- package/web-ui/build/static/t4-templating-Bof0eAYR.js +1 -0
- package/web-ui/build/static/t4-vb-8nW7Q4TI.js +1 -0
- package/web-ui/build/static/taggerscript-Dmu4nEaQ.js +1 -0
- package/web-ui/build/static/tap-B19AuLWq.js +1 -0
- package/web-ui/build/static/tap-DOdxz1Vj.js +1 -0
- package/web-ui/build/static/tcl-BAqD74MG.js +1 -0
- package/web-ui/build/static/tcl-DOM7n3Vd.js +1 -0
- package/web-ui/build/static/textile-DFXg54i4.js +1 -0
- package/web-ui/build/static/thrift-BGDpLcp_.js +1 -0
- package/web-ui/build/static/toml-J8m0tgag.js +1 -0
- package/web-ui/build/static/tp-BQkDcUXJ.js +1 -0
- package/web-ui/build/static/tremor-hOnek1Vr.js +1 -0
- package/web-ui/build/static/tsx-dhyw01LJ.js +1 -0
- package/web-ui/build/static/tt2-BZlvT5MG.js +1 -0
- package/web-ui/build/static/turtle-CEGacgOB.js +1 -0
- package/web-ui/build/static/twig-C7j-eyaz.js +1 -0
- package/web-ui/build/static/twig-MQre7lvF.js +1 -0
- package/web-ui/build/static/typescript-Dq5ZmyEV.js +1 -0
- package/web-ui/build/static/typescript-qPtHjmzW.js +1 -0
- package/web-ui/build/static/typoscript-B0sirAiC.js +1 -0
- package/web-ui/build/static/unrealscript-D_kXyIkW.js +1 -0
- package/web-ui/build/static/uorazor-8wB8nSC0.js +1 -0
- package/web-ui/build/static/uri-CaeHYk3y.js +1 -0
- package/web-ui/build/static/v-CYZwlqI2.js +1 -0
- package/web-ui/build/static/vala-DDkZds8N.js +1 -0
- package/web-ui/build/static/vala-zKk5gtUp.js +1 -0
- package/web-ui/build/static/vbnet-DY8Bh7zr.js +1 -0
- package/web-ui/build/static/vbnet-Z7zud-Nk.js +1 -0
- package/web-ui/build/static/vbscript-0xsGTIri.js +1 -0
- package/web-ui/build/static/vbscript-html-CQJqQ_tQ.js +1 -0
- package/web-ui/build/static/velocity-Dqe4ZgAo.js +1 -0
- package/web-ui/build/static/verilog-B0uVsHQr.js +1 -0
- package/web-ui/build/static/verilog-DLybxDJj.js +1 -0
- package/web-ui/build/static/vhdl-CP0JnbrM.js +1 -0
- package/web-ui/build/static/vhdl-CRV0TYO8.js +1 -0
- package/web-ui/build/static/vim-06LYR_Gs.js +1 -0
- package/web-ui/build/static/vim-DGgQcHr4.js +1 -0
- package/web-ui/build/static/visual-basic-BUWV1u5S.js +1 -0
- package/web-ui/build/static/warpscript-DKb8tXBH.js +1 -0
- package/web-ui/build/static/wasm-8E-n1sJQ.js +1 -0
- package/web-ui/build/static/web-idl-Bynfh0Gg.js +1 -0
- package/web-ui/build/static/wiki-Ck0ehuwt.js +1 -0
- package/web-ui/build/static/wolfram-BE1k6uuJ.js +1 -0
- package/web-ui/build/static/wren-Ce_CEEnI.js +1 -0
- package/web-ui/build/static/x86asm-DZUKtGAe.js +1 -0
- package/web-ui/build/static/xeora-DvXhnkv6.js +1 -0
- package/web-ui/build/static/xl-B1lBPZU_.js +1 -0
- package/web-ui/build/static/xml-D3p5hl_7.js +1 -0
- package/web-ui/build/static/xml-doc-CF8VvGyG.js +1 -0
- package/web-ui/build/static/xojo-D-WnMFdK.js +1 -0
- package/web-ui/build/static/xquery-BNNLxmJw.js +1 -0
- package/web-ui/build/static/xquery-D-mYtMjU.js +1 -0
- package/web-ui/build/static/yaml-a5-6TRUw.js +1 -0
- package/web-ui/build/static/yaml-aH3GAAQN.js +1 -0
- package/web-ui/build/static/yang-B2qT8oVg.js +1 -0
- package/web-ui/build/static/zephir-yxlgFmpA.js +1 -0
- package/web-ui/build/static/zig-B_AoM5P0.js +1 -0
- package/web-ui/build/static/1c-DUhJWQrP.js +0 -1
- package/web-ui/build/static/abap-D5pCv45A.js +0 -1
- package/web-ui/build/static/abnf-BqIdp1gH.js +0 -1
- package/web-ui/build/static/abnf-CBjlJif0.js +0 -1
- package/web-ui/build/static/accesslog-C5KlxDoB.js +0 -1
- package/web-ui/build/static/actionscript-CEdNWXaD.js +0 -1
- package/web-ui/build/static/actionscript-CgxJfO4L.js +0 -1
- package/web-ui/build/static/ada-Bdm6rSt3.js +0 -1
- package/web-ui/build/static/ada-Cqq140Rj.js +0 -1
- package/web-ui/build/static/agda-glonKdcN.js +0 -1
- package/web-ui/build/static/al-C_FHJHny.js +0 -1
- package/web-ui/build/static/angelscript-Rz4JX2Rq.js +0 -1
- package/web-ui/build/static/antlr4-D4LSk0Ay.js +0 -1
- package/web-ui/build/static/apache-BaMp4ZSC.js +0 -1
- package/web-ui/build/static/apacheconf-BVq0Zx-9.js +0 -1
- package/web-ui/build/static/apex-DdKma-_U.js +0 -1
- package/web-ui/build/static/apl-CXIfpQjm.js +0 -1
- package/web-ui/build/static/applescript-D92-mz1s.js +0 -1
- package/web-ui/build/static/applescript-eHzEb7oT.js +0 -1
- package/web-ui/build/static/aql-D_F7mVkg.js +0 -1
- package/web-ui/build/static/arcade-DgXn3lOp.js +0 -1
- package/web-ui/build/static/arduino-10f7W_Wz.js +0 -1
- package/web-ui/build/static/arduino-Bi8wBo3Q.js +0 -1
- package/web-ui/build/static/arff-DAZwwp1m.js +0 -1
- package/web-ui/build/static/armasm-4k-fm-WI.js +0 -1
- package/web-ui/build/static/asciidoc-9iyohD53.js +0 -1
- package/web-ui/build/static/asciidoc-BPxaG9gt.js +0 -1
- package/web-ui/build/static/asm6502-DlE-NUYG.js +0 -1
- package/web-ui/build/static/asmatmel-ykXUz67l.js +0 -1
- package/web-ui/build/static/aspectj-BkcGzoIw.js +0 -1
- package/web-ui/build/static/aspnet-B8bHvD3e.js +0 -1
- package/web-ui/build/static/autohotkey-BXgybckQ.js +0 -1
- package/web-ui/build/static/autohotkey-rJX88r3D.js +0 -1
- package/web-ui/build/static/autoit-BV42RCy-.js +0 -1
- package/web-ui/build/static/autoit-DtcYxn7t.js +0 -1
- package/web-ui/build/static/avisynth-B4vyExrv.js +0 -1
- package/web-ui/build/static/avrasm-hptGkmwL.js +0 -1
- package/web-ui/build/static/avro-idl-D6Eh5Tip.js +0 -1
- package/web-ui/build/static/awk-VZHEebeo.js +0 -1
- package/web-ui/build/static/axapta-MDY4Ol3-.js +0 -1
- package/web-ui/build/static/bash-CEVIQPNU.js +0 -1
- package/web-ui/build/static/bash-CQheSBd0.js +0 -1
- package/web-ui/build/static/basic-BNAC47vx.js +0 -1
- package/web-ui/build/static/basic-o0l9wI82.js +0 -1
- package/web-ui/build/static/batch-05P80ryo.js +0 -1
- package/web-ui/build/static/bbcode-CvQ1b2hw.js +0 -1
- package/web-ui/build/static/bicep-CfAYoZNS.js +0 -1
- package/web-ui/build/static/birb-JD-jZNqk.js +0 -1
- package/web-ui/build/static/bison-i3sQbLUm.js +0 -1
- package/web-ui/build/static/bnf-B5bYoRbA.js +0 -1
- package/web-ui/build/static/bnf-D98r2gkN.js +0 -1
- package/web-ui/build/static/brainfuck-BU_egZbB.js +0 -1
- package/web-ui/build/static/brainfuck-Df0tVgjY.js +0 -1
- package/web-ui/build/static/brightscript-DSvCPg0z.js +0 -1
- package/web-ui/build/static/bro-BBxgPL7i.js +0 -1
- package/web-ui/build/static/bsl-JrkU-4lx.js +0 -1
- package/web-ui/build/static/c-BWSIorgH.js +0 -1
- package/web-ui/build/static/c-BXBwfPOR.js +0 -1
- package/web-ui/build/static/c-like-4jLL6ZeZ.js +0 -1
- package/web-ui/build/static/cal-BUukjt45.js +0 -1
- package/web-ui/build/static/capnproto-DzfXkblk.js +0 -1
- package/web-ui/build/static/ceylon-C6eNUw7A.js +0 -1
- package/web-ui/build/static/cfscript-DtzcDoB6.js +0 -1
- package/web-ui/build/static/chaiscript-q5NSJZ6c.js +0 -1
- package/web-ui/build/static/cil-DXg6HnTF.js +0 -1
- package/web-ui/build/static/clean-DhrJyfi0.js +0 -1
- package/web-ui/build/static/clojure-DCN-fEKt.js +0 -1
- package/web-ui/build/static/clojure-aNTgtXL1.js +0 -1
- package/web-ui/build/static/clojure-repl-B_eFHp5m.js +0 -1
- package/web-ui/build/static/cmake-BDtm7sss.js +0 -1
- package/web-ui/build/static/cmake-Bj_M_zqn.js +0 -1
- package/web-ui/build/static/cobol-qo3jUBf5.js +0 -1
- package/web-ui/build/static/coffeescript-CIyOUYJ3.js +0 -1
- package/web-ui/build/static/coffeescript-CduS6q85.js +0 -1
- package/web-ui/build/static/concurnas-DtdAZDrQ.js +0 -1
- package/web-ui/build/static/coq-CN6lKK7F.js +0 -1
- package/web-ui/build/static/coq-DzGUbX5U.js +0 -1
- package/web-ui/build/static/cos-DFcou98i.js +0 -1
- package/web-ui/build/static/cpp-Dgg9pFUu.js +0 -1
- package/web-ui/build/static/cpp-PRuqGY7D.js +0 -1
- package/web-ui/build/static/crmsh-DLLfnotO.js +0 -1
- package/web-ui/build/static/crystal-BPylX4xG.js +0 -1
- package/web-ui/build/static/crystal-R1dH-Ebf.js +0 -1
- package/web-ui/build/static/csharp-CzwY39sl.js +0 -1
- package/web-ui/build/static/csharp-DJyymJhf.js +0 -1
- package/web-ui/build/static/cshtml-CwtJYmS1.js +0 -1
- package/web-ui/build/static/csp-Bj2DpAcY.js +0 -1
- package/web-ui/build/static/csp-xY5_PNPj.js +0 -1
- package/web-ui/build/static/css-DBGSwd91.js +0 -1
- package/web-ui/build/static/css-extras-BvlTqCpv.js +0 -1
- package/web-ui/build/static/csv-UTBn-Q9j.js +0 -1
- package/web-ui/build/static/cypher-BfzzS1h2.js +0 -1
- package/web-ui/build/static/d-BvamtLdb.js +0 -1
- package/web-ui/build/static/d-XpxNI5JF.js +0 -1
- package/web-ui/build/static/dart-BEM6fjpM.js +0 -1
- package/web-ui/build/static/dart-CsMrP4Ax.js +0 -1
- package/web-ui/build/static/dataweave-B-vfR-Jf.js +0 -1
- package/web-ui/build/static/dax-2WUcEUPn.js +0 -1
- package/web-ui/build/static/delphi-7XWS5oTs.js +0 -1
- package/web-ui/build/static/dhall-NWRUZH7l.js +0 -1
- package/web-ui/build/static/diff-AEgTdaYv.js +0 -1
- package/web-ui/build/static/diff-BRgtzr2U.js +0 -1
- package/web-ui/build/static/django-4bH3I4pv.js +0 -1
- package/web-ui/build/static/django-CrlKM5br.js +0 -1
- package/web-ui/build/static/dns-BSqNAZE3.js +0 -1
- package/web-ui/build/static/dns-zone-file-Di5cZlps.js +0 -1
- package/web-ui/build/static/docker-C9BRbp6h.js +0 -1
- package/web-ui/build/static/dockerfile-DbkS5WIL.js +0 -1
- package/web-ui/build/static/dos-per3p9hI.js +0 -1
- package/web-ui/build/static/dot-DjnTpyv1.js +0 -1
- package/web-ui/build/static/dsconfig-BjcpCNTB.js +0 -1
- package/web-ui/build/static/dts-DSWuKx2J.js +0 -1
- package/web-ui/build/static/dust-BCqihcI2.js +0 -1
- package/web-ui/build/static/ebnf-7ErhUPMF.js +0 -1
- package/web-ui/build/static/ebnf-CHADdlPD.js +0 -1
- package/web-ui/build/static/editorconfig--daZb_D-.js +0 -1
- package/web-ui/build/static/eiffel-C5zhT7HO.js +0 -1
- package/web-ui/build/static/ejs-ncnPF5oJ.js +0 -1
- package/web-ui/build/static/elixir-kFl2IHfo.js +0 -1
- package/web-ui/build/static/elixir-m8Rwrydm.js +0 -1
- package/web-ui/build/static/elm-CvywOdPd.js +0 -1
- package/web-ui/build/static/elm-Dsie_raS.js +0 -1
- package/web-ui/build/static/erb-BvkeA6hu.js +0 -1
- package/web-ui/build/static/erb-CtAdMBZY.js +0 -1
- package/web-ui/build/static/erlang-B1PynliZ.js +0 -1
- package/web-ui/build/static/erlang-DO2EN0IW.js +0 -1
- package/web-ui/build/static/erlang-repl-DWSpk7kU.js +0 -1
- package/web-ui/build/static/etlua-yEBP6vtw.js +0 -1
- package/web-ui/build/static/excel-Bhh_OwNT.js +0 -1
- package/web-ui/build/static/excel-formula-D8YNVKGY.js +0 -1
- package/web-ui/build/static/factor-U8_v_-Qx.js +0 -1
- package/web-ui/build/static/false-CbflHcQ4.js +0 -1
- package/web-ui/build/static/firestore-security-rules-C9yS7u9K.js +0 -1
- package/web-ui/build/static/fix-9oju1yrf.js +0 -1
- package/web-ui/build/static/flix-DlGExg75.js +0 -1
- package/web-ui/build/static/flow-DKikR-YL.js +0 -1
- package/web-ui/build/static/fortran-BTYpE8K2.js +0 -1
- package/web-ui/build/static/fortran-BxxaCEOU.js +0 -1
- package/web-ui/build/static/fsharp-BSNG-jCK.js +0 -1
- package/web-ui/build/static/fsharp-CCg0Y4HA.js +0 -1
- package/web-ui/build/static/ftl-DjWJ0y-0.js +0 -1
- package/web-ui/build/static/gams-C5fvQ3Od.js +0 -1
- package/web-ui/build/static/gap-BvL-biL4.js +0 -1
- package/web-ui/build/static/gauss-BzZO8GCS.js +0 -1
- package/web-ui/build/static/gcode-Cz8GsjzL.js +0 -1
- package/web-ui/build/static/gcode-Dg2JcAQS.js +0 -1
- package/web-ui/build/static/gdscript-BOCutEVV.js +0 -1
- package/web-ui/build/static/gedcom-Bdq0EwEN.js +0 -1
- package/web-ui/build/static/gherkin-Bn1mABAH.js +0 -1
- package/web-ui/build/static/gherkin-DpDnmvFb.js +0 -1
- package/web-ui/build/static/git-Cd4zgk7f.js +0 -1
- package/web-ui/build/static/glsl-BGXyo7Gw.js +0 -1
- package/web-ui/build/static/glsl-COPc8ZeZ.js +0 -1
- package/web-ui/build/static/gml-BCkIu1Er.js +0 -1
- package/web-ui/build/static/gml-COtYpJl2.js +0 -1
- package/web-ui/build/static/gn-Bjg1CRig.js +0 -1
- package/web-ui/build/static/go-BB6lvTry.js +0 -1
- package/web-ui/build/static/go-adzEcqWq.js +0 -1
- package/web-ui/build/static/go-module-CfC8Vt2L.js +0 -1
- package/web-ui/build/static/golo-C2rGlTHX.js +0 -1
- package/web-ui/build/static/gradle-Dh3gdCGU.js +0 -1
- package/web-ui/build/static/graphql-w9z3CiM9.js +0 -1
- package/web-ui/build/static/groovy-BU2m7Ekt.js +0 -1
- package/web-ui/build/static/groovy-Bi8INA80.js +0 -1
- package/web-ui/build/static/haml-t0Z0NMdQ.js +0 -1
- package/web-ui/build/static/haml-yTEKBHVm.js +0 -1
- package/web-ui/build/static/handlebars-BmRED509.js +0 -1
- package/web-ui/build/static/handlebars-DmmahO5D.js +0 -1
- package/web-ui/build/static/haskell-B4TTwJ5u.js +0 -1
- package/web-ui/build/static/haskell-BX4vB3_v.js +0 -1
- package/web-ui/build/static/haxe-B81ItqL6.js +0 -1
- package/web-ui/build/static/haxe-Z6MewpJj.js +0 -1
- package/web-ui/build/static/hcl-CT8vHUwN.js +0 -1
- package/web-ui/build/static/hlsl-BNvVW3bY.js +0 -1
- package/web-ui/build/static/hoon-07zLMFzn.js +0 -1
- package/web-ui/build/static/hpkp-DxK9DKwE.js +0 -1
- package/web-ui/build/static/hsp-BFSV4VGN.js +0 -1
- package/web-ui/build/static/hsts-Dfi1_v6k.js +0 -1
- package/web-ui/build/static/htmlbars-CBGS41Tx.js +0 -1
- package/web-ui/build/static/http-Ck2d_NdZ.js +0 -1
- package/web-ui/build/static/http-CljalO0f.js +0 -1
- package/web-ui/build/static/hy-CWwWerqr.js +0 -1
- package/web-ui/build/static/ichigojam-BUq638e8.js +0 -1
- package/web-ui/build/static/icon-CkGyT1bh.js +0 -1
- package/web-ui/build/static/icu-message-format-BQoqTHNl.js +0 -1
- package/web-ui/build/static/idris-nI6aQ55s.js +0 -1
- package/web-ui/build/static/iecst-BVwN13uc.js +0 -1
- package/web-ui/build/static/ignore-BLfLC9PA.js +0 -1
- package/web-ui/build/static/index-BwLo9qDf.js +0 -1
- package/web-ui/build/static/index-BwNJoEC1.css +0 -1
- package/web-ui/build/static/index-CrzpLgj1.js +0 -13
- package/web-ui/build/static/index-DqzIkFBw.js +0 -834
- package/web-ui/build/static/inform7-BML_idR2.js +0 -1
- package/web-ui/build/static/inform7-xoROt4DC.js +0 -1
- package/web-ui/build/static/ini-CCSkzm0H.js +0 -1
- package/web-ui/build/static/ini-CYmzo02a.js +0 -1
- package/web-ui/build/static/io-DXnvLdgN.js +0 -1
- package/web-ui/build/static/irpf90-DxKOk6dw.js +0 -1
- package/web-ui/build/static/isbl-0B0tD40P.js +0 -1
- package/web-ui/build/static/j-DXpPF6fV.js +0 -1
- package/web-ui/build/static/java-D2GSVfv5.js +0 -1
- package/web-ui/build/static/java-KuHaGPGv.js +0 -1
- package/web-ui/build/static/javadoc-BCT2sPL1.js +0 -1
- package/web-ui/build/static/javadoclike-BvnqsHVU.js +0 -1
- package/web-ui/build/static/javascript-CiWbQcs7.js +0 -1
- package/web-ui/build/static/javastacktrace-eBMVSx2Z.js +0 -1
- package/web-ui/build/static/jboss-cli-C01AEskS.js +0 -1
- package/web-ui/build/static/jexl-Dn5KxGiK.js +0 -1
- package/web-ui/build/static/jolie-D3Zt6_TW.js +0 -1
- package/web-ui/build/static/jq-DxOmFCSQ.js +0 -1
- package/web-ui/build/static/js-extras-CMUXnpUe.js +0 -1
- package/web-ui/build/static/js-templates-BzQwIldl.js +0 -1
- package/web-ui/build/static/jsdoc-CkAdh1ug.js +0 -1
- package/web-ui/build/static/json-C-B6MwWV.js +0 -1
- package/web-ui/build/static/json-C75IrF6s.js +0 -1
- package/web-ui/build/static/json5-DvXR6PNV.js +0 -1
- package/web-ui/build/static/jsonp-B92u1PFA.js +0 -1
- package/web-ui/build/static/jsstacktrace-DJjcSHfr.js +0 -1
- package/web-ui/build/static/jsx-C9-rq-CT.js +0 -1
- package/web-ui/build/static/julia-DS04VXIz.js +0 -1
- package/web-ui/build/static/julia-DrUeWVfq.js +0 -1
- package/web-ui/build/static/julia-repl-i80v_zZH.js +0 -1
- package/web-ui/build/static/keepalived-BHGEAKGU.js +0 -1
- package/web-ui/build/static/keyman-Bdzqqi9H.js +0 -1
- package/web-ui/build/static/kotlin-BzHWfKYa.js +0 -1
- package/web-ui/build/static/kotlin-C_V1S_FQ.js +0 -1
- package/web-ui/build/static/kumir-CotiKPE1.js +0 -1
- package/web-ui/build/static/kusto-DRtZ_YAs.js +0 -1
- package/web-ui/build/static/lasso-CWuEv8wJ.js +0 -1
- package/web-ui/build/static/latex-BQyvVAOm.js +0 -1
- package/web-ui/build/static/latex-DMFvqai-.js +0 -1
- package/web-ui/build/static/latte-DBzhXpVk.js +0 -1
- package/web-ui/build/static/ldif-CHIDpBfE.js +0 -1
- package/web-ui/build/static/leaf-BUM990MU.js +0 -1
- package/web-ui/build/static/less-Ct98Xd8m.js +0 -1
- package/web-ui/build/static/less-cA1L-hw1.js +0 -1
- package/web-ui/build/static/lilypond-BxQcVtKe.js +0 -1
- package/web-ui/build/static/liquid-BsdpMPYc.js +0 -1
- package/web-ui/build/static/lisp-BNcefi1U.js +0 -1
- package/web-ui/build/static/lisp-CBeHrUJR.js +0 -1
- package/web-ui/build/static/livecodeserver-BRZ6ns7E.js +0 -1
- package/web-ui/build/static/livescript-C9VXNDh2.js +0 -1
- package/web-ui/build/static/livescript-CPM4TEaS.js +0 -1
- package/web-ui/build/static/llvm-D-ktoQ6Z.js +0 -1
- package/web-ui/build/static/llvm-aGR2Ei-6.js +0 -1
- package/web-ui/build/static/log-BDQPp9ei.js +0 -1
- package/web-ui/build/static/lolcode-H3tk4sVp.js +0 -1
- package/web-ui/build/static/lsl-E_sO-uEk.js +0 -1
- package/web-ui/build/static/lua-CII1BReE.js +0 -1
- package/web-ui/build/static/lua-c32KCD1t.js +0 -1
- package/web-ui/build/static/magma-BhWArSfW.js +0 -1
- package/web-ui/build/static/makefile-BL9Ig9xO.js +0 -1
- package/web-ui/build/static/makefile-C_xncXma.js +0 -1
- package/web-ui/build/static/markdown-Bjx0QXUF.js +0 -1
- package/web-ui/build/static/markdown-DKcNzXLC.js +0 -1
- package/web-ui/build/static/markup-templating-DAQlKGf9.js +0 -1
- package/web-ui/build/static/mathematica-CvqfUKaF.js +0 -1
- package/web-ui/build/static/matlab-BErKso28.js +0 -1
- package/web-ui/build/static/matlab-ClFikeke.js +0 -1
- package/web-ui/build/static/maxima-Ft3syDPO.js +0 -1
- package/web-ui/build/static/maxscript-DT0tXOez.js +0 -1
- package/web-ui/build/static/mel-B9RYm_nG.js +0 -1
- package/web-ui/build/static/mel-DGpfnKg9.js +0 -1
- package/web-ui/build/static/mercury-CXmUlA2y.js +0 -1
- package/web-ui/build/static/mermaid-BDmkIkXi.js +0 -1
- package/web-ui/build/static/mipsasm-B2G5mL-v.js +0 -1
- package/web-ui/build/static/mizar-9hVFfba0.js +0 -1
- package/web-ui/build/static/mizar-FYnr9CDP.js +0 -1
- package/web-ui/build/static/mojolicious-D3hJYxqh.js +0 -1
- package/web-ui/build/static/mongodb-HP0s-riS.js +0 -1
- package/web-ui/build/static/monkey-CBt12SEM.js +0 -1
- package/web-ui/build/static/monkey-DIqWIXYW.js +0 -1
- package/web-ui/build/static/moonscript-B8Z_r4dn.js +0 -1
- package/web-ui/build/static/moonscript-CE7UuyXU.js +0 -1
- package/web-ui/build/static/n1ql-B16jfOjw.js +0 -1
- package/web-ui/build/static/n1ql-BgMWCckC.js +0 -1
- package/web-ui/build/static/n4js-CAXy3_Jy.js +0 -1
- package/web-ui/build/static/nand2tetris-hdl-C3vzslgj.js +0 -1
- package/web-ui/build/static/naniscript-DAFwQQVi.js +0 -1
- package/web-ui/build/static/nasm-BOFKVnaS.js +0 -1
- package/web-ui/build/static/neon-D0ISL7qJ.js +0 -1
- package/web-ui/build/static/nevod-KoDi24v0.js +0 -1
- package/web-ui/build/static/nginx-Cr5DfqWR.js +0 -1
- package/web-ui/build/static/nginx-DCCnctTG.js +0 -1
- package/web-ui/build/static/nim-DPJN-_EC.js +0 -1
- package/web-ui/build/static/nim-De05kw0n.js +0 -1
- package/web-ui/build/static/nix-CELEwiHo.js +0 -1
- package/web-ui/build/static/nix-CSaBChxR.js +0 -1
- package/web-ui/build/static/node-repl-C32a7yiw.js +0 -1
- package/web-ui/build/static/nsis-CZuaKioB.js +0 -1
- package/web-ui/build/static/nsis-VwfBkj3d.js +0 -1
- package/web-ui/build/static/objectivec-DJKZtPL2.js +0 -1
- package/web-ui/build/static/objectivec-DK2yoaBg.js +0 -1
- package/web-ui/build/static/ocaml-Dxx1cjem.js +0 -1
- package/web-ui/build/static/ocaml-kjKWdGCz.js +0 -1
- package/web-ui/build/static/opencl-BNtKnv1J.js +0 -1
- package/web-ui/build/static/openqasm-CdvNeYug.js +0 -1
- package/web-ui/build/static/openscad-B_qvsjfe.js +0 -1
- package/web-ui/build/static/oxygene-DG1hddn5.js +0 -1
- package/web-ui/build/static/oz-CRY87qeP.js +0 -1
- package/web-ui/build/static/parigp-BkAr6-G8.js +0 -1
- package/web-ui/build/static/parser-CP5clEop.js +0 -1
- package/web-ui/build/static/parser3-crTb7A0X.js +0 -1
- package/web-ui/build/static/pascal-DPfyfoDh.js +0 -1
- package/web-ui/build/static/pascaligo-DURFNQ_j.js +0 -1
- package/web-ui/build/static/pcaxis-DD7RAxRP.js +0 -1
- package/web-ui/build/static/peoplecode-So_X5jSp.js +0 -1
- package/web-ui/build/static/perl-B1DBrLmJ.js +0 -1
- package/web-ui/build/static/perl-BFaVXeG7.js +0 -1
- package/web-ui/build/static/pf-CEB1L5qm.js +0 -1
- package/web-ui/build/static/pgsql-A0nsUgDI.js +0 -1
- package/web-ui/build/static/php-8ihB7EPM.js +0 -1
- package/web-ui/build/static/php-Sh6D6NIJ.js +0 -1
- package/web-ui/build/static/php-extras-Cy_aBZK6.js +0 -1
- package/web-ui/build/static/php-template-Cit-PHnf.js +0 -1
- package/web-ui/build/static/phpdoc-DNU6hjDm.js +0 -1
- package/web-ui/build/static/plaintext-FLJCTahD.js +0 -1
- package/web-ui/build/static/plsql-1giFa6G7.js +0 -1
- package/web-ui/build/static/pony-BEp1IqY4.js +0 -1
- package/web-ui/build/static/powerquery-B43RvEYw.js +0 -1
- package/web-ui/build/static/powershell-B0QtH4nv.js +0 -1
- package/web-ui/build/static/powershell-BdHnDhS8.js +0 -1
- package/web-ui/build/static/processing-Be1Oglu_.js +0 -1
- package/web-ui/build/static/processing-CARItQwm.js +0 -1
- package/web-ui/build/static/profile-BwlQtk0y.js +0 -1
- package/web-ui/build/static/prolog-DKK6jUnc.js +0 -1
- package/web-ui/build/static/prolog-b_8huu7c.js +0 -1
- package/web-ui/build/static/promql-BZZ7XfbI.js +0 -1
- package/web-ui/build/static/properties-BFb1Pf6n.js +0 -1
- package/web-ui/build/static/properties-CmsBqXVJ.js +0 -1
- package/web-ui/build/static/protobuf-DeLotQpJ.js +0 -1
- package/web-ui/build/static/protobuf-WK1D_sJI.js +0 -1
- package/web-ui/build/static/psl-MNZR2qmI.js +0 -1
- package/web-ui/build/static/pug-CF9nceJD.js +0 -1
- package/web-ui/build/static/puppet-CZbKHt9x.js +0 -1
- package/web-ui/build/static/puppet-DUMENOgH.js +0 -1
- package/web-ui/build/static/pure-37fhgfVL.js +0 -1
- package/web-ui/build/static/purebasic-BdORV50m.js +0 -1
- package/web-ui/build/static/purebasic-D8axvRJF.js +0 -1
- package/web-ui/build/static/purescript-BmZhg2WR.js +0 -1
- package/web-ui/build/static/python-CnE0eaJH.js +0 -1
- package/web-ui/build/static/python-rT3smsTM.js +0 -1
- package/web-ui/build/static/python-repl-oAPThvRZ.js +0 -1
- package/web-ui/build/static/q-C9PeNAsV.js +0 -1
- package/web-ui/build/static/q-DEhOeRm8.js +0 -1
- package/web-ui/build/static/qml-CzmXy0mm.js +0 -1
- package/web-ui/build/static/qml-ZLrRDW5F.js +0 -1
- package/web-ui/build/static/qore-C4BmNqiC.js +0 -1
- package/web-ui/build/static/qsharp-CUspIxRd.js +0 -1
- package/web-ui/build/static/r-CmTJdjSW.js +0 -1
- package/web-ui/build/static/r-Dul2vX00.js +0 -1
- package/web-ui/build/static/racket-DuTLmSg0.js +0 -1
- package/web-ui/build/static/reason-CPbzN4QK.js +0 -1
- package/web-ui/build/static/reasonml-BX6GGy_7.js +0 -1
- package/web-ui/build/static/regex-C-S4lu9H.js +0 -1
- package/web-ui/build/static/rego-C552rbmD.js +0 -1
- package/web-ui/build/static/renpy-CAXD5ZIz.js +0 -1
- package/web-ui/build/static/rest-C0ztj_j5.js +0 -1
- package/web-ui/build/static/rib-qZJul5T1.js +0 -1
- package/web-ui/build/static/rip-Bi2BsowV.js +0 -1
- package/web-ui/build/static/roboconf-BcDqw_pY.js +0 -1
- package/web-ui/build/static/roboconf-CEx3VVi1.js +0 -1
- package/web-ui/build/static/robotframework-CJVompq9.js +0 -1
- package/web-ui/build/static/routeros-BhoPpLPN.js +0 -1
- package/web-ui/build/static/rsl-BnetYcE2.js +0 -1
- package/web-ui/build/static/ruby-D-6W0bRE.js +0 -1
- package/web-ui/build/static/ruby-Dy6NjAXK.js +0 -1
- package/web-ui/build/static/ruleslanguage-Bl49mJdL.js +0 -1
- package/web-ui/build/static/rust-DxOQY_0w.js +0 -1
- package/web-ui/build/static/rust-Dxv6L6Ol.js +0 -1
- package/web-ui/build/static/sas-B2aGiUg2.js +0 -1
- package/web-ui/build/static/sas-Cbzi-GmN.js +0 -1
- package/web-ui/build/static/sass-DwAAr7qH.js +0 -1
- package/web-ui/build/static/scala-CNOqwEfe.js +0 -1
- package/web-ui/build/static/scala-DxlUiOFp.js +0 -1
- package/web-ui/build/static/scheme-B1ALEy7P.js +0 -1
- package/web-ui/build/static/scheme-DUNdLa4B.js +0 -1
- package/web-ui/build/static/scilab-C6Y0UImx.js +0 -1
- package/web-ui/build/static/scss-8m-w5Uh_.js +0 -1
- package/web-ui/build/static/scss-C_igD-9N.js +0 -1
- package/web-ui/build/static/shell-CTp1MeZM.js +0 -1
- package/web-ui/build/static/shell-session-CN3B6Mtp.js +0 -1
- package/web-ui/build/static/smali-DMehnCvR.js +0 -1
- package/web-ui/build/static/smali-DUPqcHaD.js +0 -1
- package/web-ui/build/static/smalltalk-BZWXwh4-.js +0 -1
- package/web-ui/build/static/smalltalk-Jd4VA-e4.js +0 -1
- package/web-ui/build/static/smarty-2BmLPFNh.js +0 -1
- package/web-ui/build/static/sml-BC5HDEBf.js +0 -1
- package/web-ui/build/static/sml-BrJo7y64.js +0 -1
- package/web-ui/build/static/solidity-muZ3xQn0.js +0 -1
- package/web-ui/build/static/solution-file-CF9Xt6f6.js +0 -1
- package/web-ui/build/static/soy-DZg8DGEU.js +0 -1
- package/web-ui/build/static/sparql-kmkyqBAK.js +0 -1
- package/web-ui/build/static/splunk-spl-CmBLwT62.js +0 -1
- package/web-ui/build/static/sqf-Ct-q_HqH.js +0 -1
- package/web-ui/build/static/sqf-DSuUvyV6.js +0 -1
- package/web-ui/build/static/sql-BKhJK7dD.js +0 -1
- package/web-ui/build/static/sql-MRpfxEIR.js +0 -1
- package/web-ui/build/static/sql_more-By_l7rJw.js +0 -1
- package/web-ui/build/static/squirrel-Oyf4apfe.js +0 -1
- package/web-ui/build/static/stan-CYPvm7ay.js +0 -1
- package/web-ui/build/static/stan-OSfpjfxd.js +0 -1
- package/web-ui/build/static/stata-BN_7-HVj.js +0 -1
- package/web-ui/build/static/step21-B0MUaGQd.js +0 -1
- package/web-ui/build/static/stylus-B2zpewvs.js +0 -1
- package/web-ui/build/static/stylus-CiP04Uso.js +0 -1
- package/web-ui/build/static/subunit-Ccz6OcJn.js +0 -1
- package/web-ui/build/static/swift-DWAzs8_N.js +0 -1
- package/web-ui/build/static/swift-ssBR_Hx9.js +0 -1
- package/web-ui/build/static/systemd-CT9j1seU.js +0 -1
- package/web-ui/build/static/t4-cs-B81S0qkn.js +0 -1
- package/web-ui/build/static/t4-templating-CR8sHwkP.js +0 -1
- package/web-ui/build/static/t4-vb-AK-9z7xL.js +0 -1
- package/web-ui/build/static/taggerscript-BWTFecfl.js +0 -1
- package/web-ui/build/static/tap-BuWdU6cR.js +0 -1
- package/web-ui/build/static/tap-CvD65fMN.js +0 -1
- package/web-ui/build/static/tcl-CWTwAImW.js +0 -1
- package/web-ui/build/static/tcl-DxPPqU89.js +0 -1
- package/web-ui/build/static/textile-Bb8aIOgT.js +0 -1
- package/web-ui/build/static/thrift-BSdmFMYv.js +0 -1
- package/web-ui/build/static/toml-CYmQZs0L.js +0 -1
- package/web-ui/build/static/tp-Bt1wA2RW.js +0 -1
- package/web-ui/build/static/tremor-EDFsRn35.js +0 -1
- package/web-ui/build/static/tsx-CRpZ39XI.js +0 -1
- package/web-ui/build/static/tt2-C0lRkX9G.js +0 -1
- package/web-ui/build/static/turtle-i57e7COQ.js +0 -1
- package/web-ui/build/static/twig-DLmpdej0.js +0 -1
- package/web-ui/build/static/twig-DwotmZ4d.js +0 -1
- package/web-ui/build/static/typescript-C02UFCEu.js +0 -1
- package/web-ui/build/static/typescript-Dv4852yn.js +0 -1
- package/web-ui/build/static/typoscript-DsiStA8T.js +0 -1
- package/web-ui/build/static/unrealscript-DREvLy9b.js +0 -1
- package/web-ui/build/static/uorazor-DjjRGSlO.js +0 -1
- package/web-ui/build/static/uri-DNx0Ltr1.js +0 -1
- package/web-ui/build/static/v-BtcT9t45.js +0 -1
- package/web-ui/build/static/vala-CtrGtWLL.js +0 -1
- package/web-ui/build/static/vala-DGVJkbdQ.js +0 -1
- package/web-ui/build/static/vbnet-9N5EIy45.js +0 -1
- package/web-ui/build/static/vbnet-C8V-5wZc.js +0 -1
- package/web-ui/build/static/vbscript-C5ZX035F.js +0 -1
- package/web-ui/build/static/vbscript-html-Dk-JOSq9.js +0 -1
- package/web-ui/build/static/velocity-CMJONQlV.js +0 -1
- package/web-ui/build/static/verilog-B448hVUF.js +0 -1
- package/web-ui/build/static/verilog-D9rg9wGb.js +0 -1
- package/web-ui/build/static/vhdl-B0K99MAb.js +0 -1
- package/web-ui/build/static/vhdl-BLJZCy5e.js +0 -1
- package/web-ui/build/static/vim-CYLY4wFr.js +0 -1
- package/web-ui/build/static/vim-DE6BqLa5.js +0 -1
- package/web-ui/build/static/visual-basic-BwcdH-Kn.js +0 -1
- package/web-ui/build/static/warpscript-BbfcoHYW.js +0 -1
- package/web-ui/build/static/wasm-DHUeRG-u.js +0 -1
- package/web-ui/build/static/web-idl-BE2wsaTW.js +0 -1
- package/web-ui/build/static/wiki-D-OoB7Gs.js +0 -1
- package/web-ui/build/static/wolfram-D-AbA_lC.js +0 -1
- package/web-ui/build/static/wren-M0B5FCO6.js +0 -1
- package/web-ui/build/static/x86asm-Gg-JtiBh.js +0 -1
- package/web-ui/build/static/xeora-BeNNN_-l.js +0 -1
- package/web-ui/build/static/xl-C1jOa_4Q.js +0 -1
- package/web-ui/build/static/xml-doc-BwW35pek.js +0 -1
- package/web-ui/build/static/xml-zQuyG7Gq.js +0 -1
- package/web-ui/build/static/xojo-Bf6Y1tsn.js +0 -1
- package/web-ui/build/static/xquery-5ZEPqG2y.js +0 -1
- package/web-ui/build/static/xquery-OpQT69RV.js +0 -1
- package/web-ui/build/static/yaml-CWnr1ERL.js +0 -1
- package/web-ui/build/static/yaml-D9QDmLde.js +0 -1
- package/web-ui/build/static/yang-DSZmLri0.js +0 -1
- package/web-ui/build/static/zephir-C5UVIt-7.js +0 -1
- package/web-ui/build/static/zig-B1yDYj97.js +0 -1
|
@@ -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
|
|
@@ -502,21 +685,32 @@ class AgentScheduler {
|
|
|
502
685
|
return;
|
|
503
686
|
}
|
|
504
687
|
|
|
505
|
-
// Check if this exact state was just processed (immediate duplicate)
|
|
506
|
-
if (loopDetection.isImmediateDuplicate) {
|
|
507
|
-
this.logger.debug(`Agent ${agentId} state unchanged from last iteration, skipping`, {
|
|
508
|
-
stateHash: currentStateHash,
|
|
509
|
-
agentMode: agent.mode
|
|
510
|
-
});
|
|
511
|
-
return; // Skip - nothing new to process
|
|
512
|
-
}
|
|
513
|
-
|
|
514
688
|
// Get message queue status
|
|
515
689
|
const queues = agent.messageQueues || {};
|
|
516
690
|
const totalMessages = (queues.toolResults?.length || 0) +
|
|
517
691
|
(queues.interAgentMessages?.length || 0) +
|
|
518
692
|
(queues.userMessages?.length || 0);
|
|
519
693
|
|
|
694
|
+
// Check if this exact state was just processed (immediate duplicate).
|
|
695
|
+
// The hash is computed from the agent's OUTPUT (last assistant
|
|
696
|
+
// messages) so when nothing new has been emitted since the previous
|
|
697
|
+
// cycle the hash repeats. But we must NOT skip when there is pending
|
|
698
|
+
// input queued — tool results, user messages, or inter-agent
|
|
699
|
+
// messages all change the effective "state" even though the output
|
|
700
|
+
// history looks the same. Without this guard, an agent that
|
|
701
|
+
// finishes a turn, gets tool results back, and then matches the
|
|
702
|
+
// prior hash stalls forever: processAgent returns early every
|
|
703
|
+
// cycle, the queued tool results never get consumed, no new
|
|
704
|
+
// assistant message is produced, hash never changes — perpetual
|
|
705
|
+
// skip. Starvation, not a loop.
|
|
706
|
+
if (loopDetection.isImmediateDuplicate && totalMessages === 0) {
|
|
707
|
+
this.logger.debug(`Agent ${agentId} state unchanged and no pending input, skipping`, {
|
|
708
|
+
stateHash: currentStateHash,
|
|
709
|
+
agentMode: agent.mode
|
|
710
|
+
});
|
|
711
|
+
return; // Skip - nothing new to process
|
|
712
|
+
}
|
|
713
|
+
|
|
520
714
|
// Log if user messages are present (highest priority)
|
|
521
715
|
if (queues.userMessages?.length > 0) {
|
|
522
716
|
this.logger.info(`User message detected for agent ${agentId} - will be prioritized`, {
|
|
@@ -531,14 +725,23 @@ class AgentScheduler {
|
|
|
531
725
|
return;
|
|
532
726
|
}
|
|
533
727
|
|
|
534
|
-
// Track
|
|
535
|
-
|
|
728
|
+
// Track what happened this cycle. Two independent signals:
|
|
729
|
+
// gotResponse — the AI service returned *anything* (vs null).
|
|
730
|
+
// advanced — the conversation actually moved forward (message
|
|
731
|
+
// appended or tools extracted). If false despite
|
|
732
|
+
// gotResponse=true, the model returned an empty or
|
|
733
|
+
// whitespace-only message with no tool calls — a
|
|
734
|
+
// "no-op cycle" that must NOT pollute stateHashHistory.
|
|
735
|
+
let gotResponse = false;
|
|
736
|
+
let advanced = false;
|
|
536
737
|
|
|
537
738
|
// Process based on whether there are messages or agent needs autonomous processing
|
|
538
739
|
if (totalMessages === 0 && agent.mode === AGENT_MODES.AGENT) {
|
|
539
740
|
// AGENT mode with no messages - check for task-based work
|
|
540
741
|
await this.autoCreateInitialTaskIfNeeded(agentId);
|
|
541
|
-
|
|
742
|
+
const result = await this.processAgentAutonomously(agentId);
|
|
743
|
+
gotResponse = result.gotResponse;
|
|
744
|
+
advanced = result.advanced;
|
|
542
745
|
} else if (totalMessages > 0) {
|
|
543
746
|
// Has messages to process
|
|
544
747
|
const processedMessages = await this.processAgentQueues(agentId);
|
|
@@ -548,9 +751,8 @@ class AgentScheduler {
|
|
|
548
751
|
const aiResponse = await this.getAgentAIResponse(agentId);
|
|
549
752
|
|
|
550
753
|
if (aiResponse) {
|
|
551
|
-
|
|
552
|
-
await this.processAIResponse(agentId, aiResponse);
|
|
553
|
-
gotNewAIResponse = true;
|
|
754
|
+
gotResponse = true;
|
|
755
|
+
advanced = await this.processAIResponse(agentId, aiResponse);
|
|
554
756
|
|
|
555
757
|
// Clear token limit retry tracker on successful AI response
|
|
556
758
|
this.clearTokenLimitRetryTracker(agentId);
|
|
@@ -561,12 +763,29 @@ class AgentScheduler {
|
|
|
561
763
|
}
|
|
562
764
|
// CHAT mode with no messages: do nothing - activity service will mark as inactive
|
|
563
765
|
|
|
564
|
-
// Only record state hash when
|
|
565
|
-
//
|
|
566
|
-
|
|
766
|
+
// Only record state hash when the conversation actually advanced. If
|
|
767
|
+
// the model returned an empty response (gotResponse=true, advanced=false),
|
|
768
|
+
// we're still in the same conversation state as before and recording
|
|
769
|
+
// would produce phantom duplicates that detectRepetitiveLoop misreads
|
|
770
|
+
// as progress toward a loop.
|
|
771
|
+
if (advanced) {
|
|
567
772
|
this.recordStateHash(agentId, currentStateHash);
|
|
568
773
|
}
|
|
569
774
|
|
|
775
|
+
// Empty-response stall detector. When the model returns an empty /
|
|
776
|
+
// whitespace-only response with no tool calls, we keep retrying — the
|
|
777
|
+
// next cycle may produce a real message. But we ring-buffer the empties
|
|
778
|
+
// so a genuinely stuck model eventually surfaces as a user-facing error
|
|
779
|
+
// instead of silently spinning forever.
|
|
780
|
+
if (gotResponse && !advanced) {
|
|
781
|
+
await this._trackEmptyResponse(agentId);
|
|
782
|
+
} else if (advanced) {
|
|
783
|
+
// Productive cycle — any previous stall has resolved itself.
|
|
784
|
+
if (this._emptyResponseTracker.has(agentId)) {
|
|
785
|
+
this._emptyResponseTracker.delete(agentId);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
570
789
|
// Decrement TTL (Time-to-Live) if set
|
|
571
790
|
// TTL gives agents extra processing cycles after clearing tasks
|
|
572
791
|
const agentForTtl = await this.agentPool.getAgent(agentId);
|
|
@@ -582,6 +801,7 @@ class AgentScheduler {
|
|
|
582
801
|
} finally {
|
|
583
802
|
// Always clear processing lock, even on errors
|
|
584
803
|
this.agentProcessingLocks.delete(agentId);
|
|
804
|
+
this._lockAcquiredAt.delete(agentId);
|
|
585
805
|
}
|
|
586
806
|
}
|
|
587
807
|
|
|
@@ -683,6 +903,20 @@ class AgentScheduler {
|
|
|
683
903
|
const toolIds = [...new Set(toolResults.map(m => m.toolId).filter(Boolean))];
|
|
684
904
|
toolResultContent += `[Tool Results — ${toolCount} result${toolCount > 1 ? 's' : ''} from ${turnCount} tool batch${turnCount > 1 ? 'es' : ''}: ${toolIds.join(', ')}]\n`;
|
|
685
905
|
|
|
906
|
+
// Current-working-directory banner. Reasoning models regularly forget
|
|
907
|
+
// that `change-directory` persists the CWD across turns and then
|
|
908
|
+
// re-prepend the project folder name to relative paths, which nests
|
|
909
|
+
// directories unintentionally (".../foo/foo/..."). Surfacing the CWD
|
|
910
|
+
// at the top of every tool-results injection gives the model a stable
|
|
911
|
+
// anchor: "you are HERE, all relative paths resolve from HERE."
|
|
912
|
+
try {
|
|
913
|
+
const agentForCwd = await this.agentPool.getAgent(agentId);
|
|
914
|
+
const cwd = agentForCwd?.directoryAccess?.workingDirectory;
|
|
915
|
+
if (cwd) {
|
|
916
|
+
toolResultContent += `[CWD: ${cwd} — relative paths resolve from here; do NOT prepend the project folder name]\n`;
|
|
917
|
+
}
|
|
918
|
+
} catch { /* best-effort; never block the tool-results injection */ }
|
|
919
|
+
|
|
686
920
|
if (turnCount === 1) {
|
|
687
921
|
// Single batch — flat list (no sub-headers needed)
|
|
688
922
|
toolResults.forEach(msg => {
|
|
@@ -805,11 +1039,11 @@ class AgentScheduler {
|
|
|
805
1039
|
*/
|
|
806
1040
|
async addMessageToConversation(agentId, message, broadcast = true) {
|
|
807
1041
|
const agent = await this.agentPool.getAgent(agentId);
|
|
808
|
-
if (!agent) return;
|
|
1042
|
+
if (!agent) return false;
|
|
809
1043
|
|
|
810
1044
|
// Format message based on queue type
|
|
811
1045
|
let formattedMessage;
|
|
812
|
-
|
|
1046
|
+
|
|
813
1047
|
switch (message.queueType) {
|
|
814
1048
|
case 'toolResults': // Tool results
|
|
815
1049
|
formattedMessage = {
|
|
@@ -818,7 +1052,7 @@ class AgentScheduler {
|
|
|
818
1052
|
content: this.formatToolResult(message)
|
|
819
1053
|
};
|
|
820
1054
|
break;
|
|
821
|
-
|
|
1055
|
+
|
|
822
1056
|
case 'interAgentMessages': // Inter-agent messages
|
|
823
1057
|
formattedMessage = {
|
|
824
1058
|
...message,
|
|
@@ -826,14 +1060,14 @@ class AgentScheduler {
|
|
|
826
1060
|
content: `Message from ${message.senderName || message.sender}: ${message.content}`
|
|
827
1061
|
};
|
|
828
1062
|
break;
|
|
829
|
-
|
|
1063
|
+
|
|
830
1064
|
case 'userMessages': // User messages
|
|
831
1065
|
formattedMessage = {
|
|
832
1066
|
...message,
|
|
833
1067
|
role: MESSAGE_ROLES.USER
|
|
834
1068
|
};
|
|
835
1069
|
break;
|
|
836
|
-
|
|
1070
|
+
|
|
837
1071
|
default:
|
|
838
1072
|
formattedMessage = message;
|
|
839
1073
|
}
|
|
@@ -843,7 +1077,10 @@ class AgentScheduler {
|
|
|
843
1077
|
formattedMessage.timestamp = new Date().toISOString();
|
|
844
1078
|
}
|
|
845
1079
|
|
|
846
|
-
// GUARD: Skip empty messages - they should never be added to history
|
|
1080
|
+
// GUARD: Skip empty messages - they should never be added to history.
|
|
1081
|
+
// Returning `false` lets the caller (processAIResponse) know the conversation
|
|
1082
|
+
// did NOT advance, so it can avoid polluting stateHashHistory and instead
|
|
1083
|
+
// mark the cycle as an "empty response" for the stall-detector.
|
|
847
1084
|
const messageContent = formattedMessage.content;
|
|
848
1085
|
if (!messageContent || (typeof messageContent === 'string' && !messageContent.trim())) {
|
|
849
1086
|
this.logger.warn(`Skipping empty message for agent ${agentId}`, {
|
|
@@ -851,7 +1088,7 @@ class AgentScheduler {
|
|
|
851
1088
|
queueType: message.queueType,
|
|
852
1089
|
hasContent: !!messageContent
|
|
853
1090
|
});
|
|
854
|
-
return; // Don't add empty messages
|
|
1091
|
+
return false; // Don't add empty messages; caller should treat as "no progress"
|
|
855
1092
|
}
|
|
856
1093
|
|
|
857
1094
|
// Add to conversation history
|
|
@@ -868,6 +1105,8 @@ class AgentScheduler {
|
|
|
868
1105
|
if (broadcast && this.shouldBroadcastMessage(formattedMessage)) {
|
|
869
1106
|
this.broadcastMessageUpdate(agentId, formattedMessage);
|
|
870
1107
|
}
|
|
1108
|
+
|
|
1109
|
+
return true;
|
|
871
1110
|
}
|
|
872
1111
|
|
|
873
1112
|
/**
|
|
@@ -883,16 +1122,22 @@ class AgentScheduler {
|
|
|
883
1122
|
const aiResponse = await this.getAgentAIResponse(agentId);
|
|
884
1123
|
|
|
885
1124
|
if (!aiResponse) {
|
|
886
|
-
|
|
1125
|
+
// No response - activity service will determine if we should continue.
|
|
1126
|
+
// Reported as { gotResponse: false } so the caller doesn't count this
|
|
1127
|
+
// as an "empty-response stall" (which is specifically about empty content).
|
|
1128
|
+
return { gotResponse: false, advanced: false };
|
|
887
1129
|
}
|
|
888
1130
|
|
|
889
|
-
// Process AI response and execute tools
|
|
890
|
-
|
|
1131
|
+
// Process AI response and execute tools. processAIResponse returns `true`
|
|
1132
|
+
// when the conversation actually advanced (assistant message appended or
|
|
1133
|
+
// tool calls extracted), and `false` when the response was empty/whitespace
|
|
1134
|
+
// and carried no tools.
|
|
1135
|
+
const advanced = await this.processAIResponse(agentId, aiResponse);
|
|
891
1136
|
|
|
892
1137
|
// Clear token limit retry tracker on successful AI response
|
|
893
1138
|
this.clearTokenLimitRetryTracker(agentId);
|
|
894
1139
|
|
|
895
|
-
return
|
|
1140
|
+
return { gotResponse: true, advanced };
|
|
896
1141
|
}
|
|
897
1142
|
|
|
898
1143
|
/**
|
|
@@ -1530,6 +1775,30 @@ class AgentScheduler {
|
|
|
1530
1775
|
enhancedSystemPrompt = (enhancedSystemPrompt || '') + systemConstraints;
|
|
1531
1776
|
}
|
|
1532
1777
|
|
|
1778
|
+
// Inject external-channel routing guidance ONLY when the agent has
|
|
1779
|
+
// at least one live bridge. Pulls the per-channel alias list from
|
|
1780
|
+
// each service so the agent can address specific channels/threads
|
|
1781
|
+
// via `<external to="alias">`. When the agent isn't bridged the
|
|
1782
|
+
// paragraph is omitted — no point teaching routing for listeners
|
|
1783
|
+
// that aren't there. Filter + alias matching logic live in
|
|
1784
|
+
// services/channelFilter.js so this block stays declarative.
|
|
1785
|
+
try {
|
|
1786
|
+
const activeChannels = [];
|
|
1787
|
+
if (typeof this.discordService?.getBridgedChannels === 'function') {
|
|
1788
|
+
activeChannels.push(...this.discordService.getBridgedChannels(agentId));
|
|
1789
|
+
}
|
|
1790
|
+
if (typeof this.telegramService?.getBridgedChannels === 'function') {
|
|
1791
|
+
activeChannels.push(...this.telegramService.getBridgedChannels(agentId));
|
|
1792
|
+
}
|
|
1793
|
+
if (activeChannels.length > 0) {
|
|
1794
|
+
const { getExternalChannelPromptGuidance } = await import('../services/channelFilter.js');
|
|
1795
|
+
const guidance = getExternalChannelPromptGuidance(activeChannels);
|
|
1796
|
+
if (guidance) enhancedSystemPrompt = (enhancedSystemPrompt || '') + guidance;
|
|
1797
|
+
}
|
|
1798
|
+
} catch (err) {
|
|
1799
|
+
this.logger.warn('[external-routing] failed to inject <external> guidance', { agentId, error: err.message });
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1533
1802
|
// Inject flow execution context if this is part of a flow
|
|
1534
1803
|
try {
|
|
1535
1804
|
const lastUserMsg = [...conversationHistory].reverse().find(m => m.role === 'user');
|
|
@@ -1564,6 +1833,15 @@ class AgentScheduler {
|
|
|
1564
1833
|
? userStreamingPref !== false
|
|
1565
1834
|
: agent.streamingEnabled !== false; // Default to true
|
|
1566
1835
|
|
|
1836
|
+
// Native function-call tools for the agent's enabled capabilities.
|
|
1837
|
+
// Passed as `options.tools` to the backend. For Responses-API models
|
|
1838
|
+
// (codex/o-series/gpt-5-pro) the backend forwards these to Azure so
|
|
1839
|
+
// the model can emit native function_call events; the backend converts
|
|
1840
|
+
// them back into the CLI's inline JSON-block format on the wire. For
|
|
1841
|
+
// chat-completion models the backend ignores this field and the model
|
|
1842
|
+
// uses the system prompt's inline-JSON instructions as before.
|
|
1843
|
+
const toolSchemas = getToolSchemasForAgent(agent.capabilities || []);
|
|
1844
|
+
|
|
1567
1845
|
if (streamingEnabled && this.aiService.sendMessageStream) {
|
|
1568
1846
|
// Build flow context if this is part of a flow execution
|
|
1569
1847
|
const flowContext = lastUserMsg?.isFlowExecution ? {
|
|
@@ -1579,7 +1857,8 @@ class AgentScheduler {
|
|
|
1579
1857
|
enhancedSystemPrompt,
|
|
1580
1858
|
sessionId,
|
|
1581
1859
|
agent.platformProvided,
|
|
1582
|
-
flowContext
|
|
1860
|
+
flowContext,
|
|
1861
|
+
toolSchemas
|
|
1583
1862
|
);
|
|
1584
1863
|
}
|
|
1585
1864
|
|
|
@@ -1608,7 +1887,8 @@ class AgentScheduler {
|
|
|
1608
1887
|
agentId: agentId,
|
|
1609
1888
|
systemPrompt: enhancedSystemPrompt,
|
|
1610
1889
|
sessionId: sessionId,
|
|
1611
|
-
platformProvided: agent.platformProvided
|
|
1890
|
+
platformProvided: agent.platformProvided,
|
|
1891
|
+
tools: toolSchemas && toolSchemas.length > 0 ? toolSchemas : undefined,
|
|
1612
1892
|
}
|
|
1613
1893
|
);
|
|
1614
1894
|
|
|
@@ -1642,7 +1922,7 @@ class AgentScheduler {
|
|
|
1642
1922
|
* @returns {Promise<Object>} Response object
|
|
1643
1923
|
* @private
|
|
1644
1924
|
*/
|
|
1645
|
-
async _getStreamingResponse(agentId, targetModel, messagesToSend, systemPrompt, sessionId, platformProvided, flowContext = null) {
|
|
1925
|
+
async _getStreamingResponse(agentId, targetModel, messagesToSend, systemPrompt, sessionId, platformProvided, flowContext = null, tools = null) {
|
|
1646
1926
|
// Generate a unique message ID for this streaming response
|
|
1647
1927
|
const streamMessageId = `stream-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1648
1928
|
|
|
@@ -1704,6 +1984,7 @@ class AgentScheduler {
|
|
|
1704
1984
|
systemPrompt: systemPrompt,
|
|
1705
1985
|
sessionId: sessionId,
|
|
1706
1986
|
platformProvided: platformProvided,
|
|
1987
|
+
tools: tools && tools.length > 0 ? tools : undefined,
|
|
1707
1988
|
onChunk: (chunk) => {
|
|
1708
1989
|
// First chunk — clear the prestream watchdog. Active streaming means
|
|
1709
1990
|
// the model is responsive; we don't want to cut a live stream off.
|
|
@@ -1898,6 +2179,7 @@ class AgentScheduler {
|
|
|
1898
2179
|
// Switch agent to CHAT mode - no delay, user can retry when ready
|
|
1899
2180
|
agent.mode = AGENT_MODES.CHAT;
|
|
1900
2181
|
await this.agentPool.persistAgentState(agentId);
|
|
2182
|
+
await this.broadcastAgentStateUpdate(agentId, 'timeout');
|
|
1901
2183
|
|
|
1902
2184
|
// Broadcast timeout notification to UI (toast + console log only, no chat message)
|
|
1903
2185
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
@@ -1924,6 +2206,7 @@ class AgentScheduler {
|
|
|
1924
2206
|
|
|
1925
2207
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.API_KEY_ERROR_DELAY_MS).toISOString();
|
|
1926
2208
|
await this.agentPool.persistAgentState(agentId);
|
|
2209
|
+
await this.broadcastAgentStateUpdate(agentId, 'api-key-error');
|
|
1927
2210
|
|
|
1928
2211
|
// Add error message to agent's queue
|
|
1929
2212
|
await this.agentPool.addToolResult(agentId, {
|
|
@@ -1939,6 +2222,7 @@ class AgentScheduler {
|
|
|
1939
2222
|
|
|
1940
2223
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.RATE_LIMIT_DELAY_MS).toISOString();
|
|
1941
2224
|
await this.agentPool.persistAgentState(agentId);
|
|
2225
|
+
await this.broadcastAgentStateUpdate(agentId, 'rate-limit');
|
|
1942
2226
|
|
|
1943
2227
|
} else if (errorMessage.includes('network') || errorMessage.includes('connection')) {
|
|
1944
2228
|
// Network issues (non-timeout) - shorter delay and retry
|
|
@@ -1946,6 +2230,7 @@ class AgentScheduler {
|
|
|
1946
2230
|
|
|
1947
2231
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.NETWORK_ERROR_DELAY_MS).toISOString();
|
|
1948
2232
|
await this.agentPool.persistAgentState(agentId);
|
|
2233
|
+
await this.broadcastAgentStateUpdate(agentId, 'network-error');
|
|
1949
2234
|
|
|
1950
2235
|
} else if (this.isTokenLimitError(errorMessage)) {
|
|
1951
2236
|
// Token/context limit error - trigger emergency compaction and retry
|
|
@@ -1958,6 +2243,7 @@ class AgentScheduler {
|
|
|
1958
2243
|
|
|
1959
2244
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.UNKNOWN_ERROR_DELAY_MS).toISOString();
|
|
1960
2245
|
await this.agentPool.persistAgentState(agentId);
|
|
2246
|
+
await this.broadcastAgentStateUpdate(agentId, 'server-error');
|
|
1961
2247
|
|
|
1962
2248
|
// Add error message to agent's queue
|
|
1963
2249
|
await this.agentPool.addToolResult(agentId, {
|
|
@@ -2052,6 +2338,7 @@ class AgentScheduler {
|
|
|
2052
2338
|
// Now show the error to the user
|
|
2053
2339
|
agent.delayEndTime = new Date(Date.now() + SCHEDULER_CONFIG.UNKNOWN_ERROR_DELAY_MS).toISOString();
|
|
2054
2340
|
await this.agentPool.persistAgentState(agentId);
|
|
2341
|
+
await this.broadcastAgentStateUpdate(agentId, 'context-limit-exhausted');
|
|
2055
2342
|
|
|
2056
2343
|
// Broadcast error to UI
|
|
2057
2344
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
@@ -2324,9 +2611,18 @@ class AgentScheduler {
|
|
|
2324
2611
|
}
|
|
2325
2612
|
|
|
2326
2613
|
/**
|
|
2327
|
-
* Process AI response and execute any tools
|
|
2614
|
+
* Process AI response and execute any tools.
|
|
2615
|
+
*
|
|
2616
|
+
* Returns `true` when the conversation actually advanced (either the assistant
|
|
2617
|
+
* message was appended or tool calls were queued for async execution), and
|
|
2618
|
+
* `false` when the response had empty / whitespace content AND no tool calls.
|
|
2619
|
+
* The caller (processAgent) uses this to decide whether to record the
|
|
2620
|
+
* pre-cycle state hash — preventing the detectRepetitiveLoop pollution that
|
|
2621
|
+
* empty responses would otherwise cause.
|
|
2622
|
+
*
|
|
2328
2623
|
* @param {string} agentId - Agent ID
|
|
2329
2624
|
* @param {Object} aiResponse - AI service response
|
|
2625
|
+
* @returns {Promise<boolean>} true if conversation advanced, false on dropped-empty
|
|
2330
2626
|
* @private
|
|
2331
2627
|
*/
|
|
2332
2628
|
async processAIResponse(agentId, aiResponse) {
|
|
@@ -2337,7 +2633,7 @@ class AgentScheduler {
|
|
|
2337
2633
|
// Safety check: agent must exist
|
|
2338
2634
|
if (!agent) {
|
|
2339
2635
|
this.logger.warn(`Cannot process AI response - agent ${agentId} not found`);
|
|
2340
|
-
return;
|
|
2636
|
+
return false;
|
|
2341
2637
|
}
|
|
2342
2638
|
|
|
2343
2639
|
// Check if response contains tool calls
|
|
@@ -2377,13 +2673,32 @@ class AgentScheduler {
|
|
|
2377
2673
|
|
|
2378
2674
|
// Normalize token usage field names (backend may send input_tokens/output_tokens
|
|
2379
2675
|
// instead of prompt_tokens/completion_tokens depending on provider)
|
|
2676
|
+
// NOTE: use ?? (not ||) so that a genuine 0 doesn't fall through to the next
|
|
2677
|
+
// field — but also guard against the case where `tokenUsage` is entirely
|
|
2678
|
+
// absent or empty. Emits a one-shot debug log so we can see the actual
|
|
2679
|
+
// shape once per unusual response in server logs.
|
|
2380
2680
|
let normalizedTokenUsage = null;
|
|
2381
2681
|
if (aiResponse.tokenUsage) {
|
|
2682
|
+
const u = aiResponse.tokenUsage;
|
|
2382
2683
|
normalizedTokenUsage = {
|
|
2383
|
-
prompt_tokens:
|
|
2384
|
-
completion_tokens:
|
|
2385
|
-
total_tokens:
|
|
2684
|
+
prompt_tokens: u.prompt_tokens ?? u.input_tokens ?? 0,
|
|
2685
|
+
completion_tokens: u.completion_tokens ?? u.output_tokens ?? 0,
|
|
2686
|
+
total_tokens: u.total_tokens ?? ((u.prompt_tokens ?? u.input_tokens ?? 0) + (u.completion_tokens ?? u.output_tokens ?? 0)),
|
|
2386
2687
|
};
|
|
2688
|
+
if (process.env.DEBUG_TOKEN_USAGE === '1' || normalizedTokenUsage.total_tokens === 0) {
|
|
2689
|
+
this.logger.warn('[TOKEN-USAGE] non-zero expected but got zero or debug-requested', {
|
|
2690
|
+
agentId,
|
|
2691
|
+
model: aiResponse.model,
|
|
2692
|
+
rawTokenUsage: u,
|
|
2693
|
+
normalized: normalizedTokenUsage,
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
} else if (process.env.DEBUG_TOKEN_USAGE === '1') {
|
|
2697
|
+
this.logger.warn('[TOKEN-USAGE] aiResponse has no tokenUsage field', {
|
|
2698
|
+
agentId,
|
|
2699
|
+
model: aiResponse.model,
|
|
2700
|
+
aiResponseKeys: Object.keys(aiResponse || {}),
|
|
2701
|
+
});
|
|
2387
2702
|
}
|
|
2388
2703
|
|
|
2389
2704
|
// Create response message
|
|
@@ -2400,18 +2715,27 @@ class AgentScheduler {
|
|
|
2400
2715
|
pendingToolExecution: hasTools
|
|
2401
2716
|
};
|
|
2402
2717
|
|
|
2403
|
-
await this.addMessageToConversation(agentId, responseMessage, false);
|
|
2718
|
+
const appended = await this.addMessageToConversation(agentId, responseMessage, false);
|
|
2404
2719
|
|
|
2405
|
-
// IMMEDIATELY broadcast the AI response to UI (don't wait for tool execution)
|
|
2406
|
-
if
|
|
2720
|
+
// IMMEDIATELY broadcast the AI response to UI (don't wait for tool execution).
|
|
2721
|
+
// We only broadcast if the message actually made it into the conversation —
|
|
2722
|
+
// broadcasting an empty message confuses the UI.
|
|
2723
|
+
if (appended && this.shouldBroadcastMessage(responseMessage)) {
|
|
2407
2724
|
const updatedAgent = await this.agentPool.getAgent(agentId);
|
|
2408
2725
|
this.broadcastMessageUpdate(agentId, responseMessage, {
|
|
2409
2726
|
agentCurrentModel: updatedAgent?.currentModel
|
|
2410
2727
|
});
|
|
2411
2728
|
}
|
|
2412
2729
|
|
|
2413
|
-
// Execute tools ASYNCHRONOUSLY - don't block the response
|
|
2730
|
+
// Execute tools ASYNCHRONOUSLY - don't block the response. Tools run even
|
|
2731
|
+
// if the assistant message itself was empty and dropped, so long as the
|
|
2732
|
+
// content string happened to contain tool-call markup.
|
|
2414
2733
|
this._executeToolsAsync(agentId, aiResponse.content, sessionId, responseMessage.id);
|
|
2734
|
+
|
|
2735
|
+
// The cycle "made progress" if EITHER the assistant message was persisted
|
|
2736
|
+
// or a tool call was extracted from the content (tools will surface new
|
|
2737
|
+
// messages through the toolResults queue next cycle).
|
|
2738
|
+
return appended || hasTools;
|
|
2415
2739
|
}
|
|
2416
2740
|
|
|
2417
2741
|
/**
|
|
@@ -2463,6 +2787,7 @@ class AgentScheduler {
|
|
|
2463
2787
|
if (agent) {
|
|
2464
2788
|
agent.delayEndTime = new Date(Date.now() + maxDelay).toISOString();
|
|
2465
2789
|
await this.agentPool.persistAgentState(agentId);
|
|
2790
|
+
await this.broadcastAgentStateUpdate(agentId, 'builtin-delay');
|
|
2466
2791
|
this.logger.debug(`Agent ${agentId} - applying ${maxDelay}ms builtin delay for tool execution`);
|
|
2467
2792
|
}
|
|
2468
2793
|
}
|
|
@@ -2704,6 +3029,45 @@ class AgentScheduler {
|
|
|
2704
3029
|
* @param {Object} agentInfo - Additional agent information for UI sync
|
|
2705
3030
|
* @private
|
|
2706
3031
|
*/
|
|
3032
|
+
/**
|
|
3033
|
+
* Broadcast an agent state snapshot (mode, delayEndTime, awaitingUserInput,
|
|
3034
|
+
* stopRequested) whenever the scheduler mutates one of those fields.
|
|
3035
|
+
*
|
|
3036
|
+
* The UI reducer merges this payload into its agent record, so a single
|
|
3037
|
+
* helper call everywhere-the-state-changes keeps the UI in sync without
|
|
3038
|
+
* adding one-off event types per scenario. `reason` is a short tag
|
|
3039
|
+
* (`timeout`, `rate-limit`, `builtin-delay`, `loop-detected`, etc.) so the
|
|
3040
|
+
* UI can render a human-readable cause if it wants to.
|
|
3041
|
+
*
|
|
3042
|
+
* Best-effort: a missing webSocketManager or a sessionless agent makes this
|
|
3043
|
+
* a no-op. Never throws.
|
|
3044
|
+
*
|
|
3045
|
+
* @param {string} agentId
|
|
3046
|
+
* @param {string} reason Short tag describing WHY the state changed.
|
|
3047
|
+
*/
|
|
3048
|
+
async broadcastAgentStateUpdate(agentId, reason = 'state-change') {
|
|
3049
|
+
try {
|
|
3050
|
+
if (!this.webSocketManager?.broadcastToSession) return;
|
|
3051
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
3052
|
+
if (!agent) return;
|
|
3053
|
+
const sessionId = this.getAgentSession(agentId) || agent.sessionId || 'scheduler-session';
|
|
3054
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3055
|
+
type: 'agent_state_updated',
|
|
3056
|
+
data: {
|
|
3057
|
+
agentId,
|
|
3058
|
+
mode: agent.mode,
|
|
3059
|
+
delayEndTime: agent.delayEndTime || null,
|
|
3060
|
+
awaitingUserInput: agent.awaitingUserInput || null,
|
|
3061
|
+
stopRequested: !!agent.stopRequested,
|
|
3062
|
+
reason,
|
|
3063
|
+
timestamp: new Date().toISOString(),
|
|
3064
|
+
},
|
|
3065
|
+
});
|
|
3066
|
+
} catch (err) {
|
|
3067
|
+
this.logger?.warn?.(`agent_state_updated broadcast failed: ${err.message}`, { agentId, reason });
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
|
|
2707
3071
|
broadcastMessageUpdate(agentId, message, agentInfo = {}) {
|
|
2708
3072
|
if (this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
2709
3073
|
// Get the session ID from session map, message, or fallback
|
|
@@ -3220,6 +3584,127 @@ class AgentScheduler {
|
|
|
3220
3584
|
};
|
|
3221
3585
|
}
|
|
3222
3586
|
|
|
3587
|
+
/**
|
|
3588
|
+
* Record a cycle where the model returned an empty or whitespace-only
|
|
3589
|
+
* response that carried no tool calls. The scheduler keeps retrying — the
|
|
3590
|
+
* next cycle may produce a real message — but we buffer the empties so
|
|
3591
|
+
* we can surface a clear error to the user if the stall persists.
|
|
3592
|
+
*
|
|
3593
|
+
* @param {string} agentId
|
|
3594
|
+
* @private
|
|
3595
|
+
*/
|
|
3596
|
+
async _trackEmptyResponse(agentId) {
|
|
3597
|
+
const now = Date.now();
|
|
3598
|
+
const existing = this._emptyResponseTracker.get(agentId);
|
|
3599
|
+
const entry = existing
|
|
3600
|
+
? { count: existing.count + 1, firstAt: existing.firstAt, lastAt: now }
|
|
3601
|
+
: { count: 1, firstAt: now, lastAt: now };
|
|
3602
|
+
|
|
3603
|
+
this._emptyResponseTracker.set(agentId, entry);
|
|
3604
|
+
|
|
3605
|
+
this.logger.warn(`[EMPTY-RESPONSE] Agent ${agentId}: cycle produced no content`, {
|
|
3606
|
+
count: entry.count,
|
|
3607
|
+
elapsedMs: now - entry.firstAt,
|
|
3608
|
+
threshold: SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_THRESHOLD,
|
|
3609
|
+
windowMs: SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_WINDOW_MS,
|
|
3610
|
+
});
|
|
3611
|
+
|
|
3612
|
+
const shouldStall =
|
|
3613
|
+
entry.count >= SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_THRESHOLD &&
|
|
3614
|
+
(now - entry.firstAt) >= SCHEDULER_CONFIG.EMPTY_RESPONSE_STALL_WINDOW_MS;
|
|
3615
|
+
|
|
3616
|
+
if (shouldStall) {
|
|
3617
|
+
try {
|
|
3618
|
+
await this._handleEmptyResponseStall(agentId, entry);
|
|
3619
|
+
} finally {
|
|
3620
|
+
this._emptyResponseTracker.delete(agentId);
|
|
3621
|
+
}
|
|
3622
|
+
}
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
/**
|
|
3626
|
+
* Circuit breaker fired when an agent has produced N empty responses across
|
|
3627
|
+
* at least the configured time window. Surfaces a user-facing error message,
|
|
3628
|
+
* switches the agent to CHAT mode (scheduler will mark it inactive), and
|
|
3629
|
+
* clears scheduler-side state that could otherwise keep re-firing.
|
|
3630
|
+
*
|
|
3631
|
+
* Mirrors the shape of handleRepetitiveLoop but with a different message
|
|
3632
|
+
* explaining the actual failure mode.
|
|
3633
|
+
*
|
|
3634
|
+
* @param {string} agentId
|
|
3635
|
+
* @param {{count: number, firstAt: number, lastAt: number}} entry
|
|
3636
|
+
* @private
|
|
3637
|
+
*/
|
|
3638
|
+
async _handleEmptyResponseStall(agentId, entry) {
|
|
3639
|
+
const agent = await this.agentPool.getAgent(agentId);
|
|
3640
|
+
if (!agent) return;
|
|
3641
|
+
|
|
3642
|
+
// Clear scheduler state FIRST so any throw in persistence / broadcast below
|
|
3643
|
+
// can't leave us re-firing this handler next cycle.
|
|
3644
|
+
this.stateHashHistory.delete(agentId);
|
|
3645
|
+
this.consecutiveNoToolMessages.delete(agentId);
|
|
3646
|
+
|
|
3647
|
+
const elapsedSec = Math.round((entry.lastAt - entry.firstAt) / 1000);
|
|
3648
|
+
const interventionMessage = `The model returned ${entry.count} empty responses in a row over ${elapsedSec}s. ` +
|
|
3649
|
+
`I've switched to chat mode so you can retry or adjust. Common causes: ` +
|
|
3650
|
+
`the selected model is unreachable, rate-limited, or rejecting the current ` +
|
|
3651
|
+
`conversation. You can pick a different model or send a new message to try again.`;
|
|
3652
|
+
|
|
3653
|
+
const messageToAdd = {
|
|
3654
|
+
id: `msg-empty-response-stall-${Date.now()}`,
|
|
3655
|
+
role: 'assistant',
|
|
3656
|
+
content: interventionMessage,
|
|
3657
|
+
timestamp: new Date().toISOString(),
|
|
3658
|
+
isSystemMessage: true,
|
|
3659
|
+
emptyResponseStall: {
|
|
3660
|
+
count: entry.count,
|
|
3661
|
+
elapsedMs: entry.lastAt - entry.firstAt,
|
|
3662
|
+
},
|
|
3663
|
+
};
|
|
3664
|
+
|
|
3665
|
+
if (agent.conversations && agent.conversations.full) {
|
|
3666
|
+
agent.conversations.full.messages.push(messageToAdd);
|
|
3667
|
+
agent.conversations.full.lastUpdated = new Date().toISOString();
|
|
3668
|
+
}
|
|
3669
|
+
|
|
3670
|
+
agent.mode = AGENT_MODES.CHAT;
|
|
3671
|
+
|
|
3672
|
+
// Persist + broadcast are best-effort — a failure here must NOT leave the
|
|
3673
|
+
// agent in a re-firing state. Scheduler state was cleared above.
|
|
3674
|
+
try {
|
|
3675
|
+
await this.agentPool.persistAgentState(agentId);
|
|
3676
|
+
} catch (err) {
|
|
3677
|
+
this.logger.error(`Failed to persist agent after empty-response stall: ${err.message}`, { agentId });
|
|
3678
|
+
}
|
|
3679
|
+
|
|
3680
|
+
const sessionId = this.getAgentSession(agentId) || agent.sessionId;
|
|
3681
|
+
if (sessionId && this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
3682
|
+
try {
|
|
3683
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3684
|
+
type: 'message_added',
|
|
3685
|
+
data: { agentId, message: messageToAdd, type: 'empty_response_stall' },
|
|
3686
|
+
});
|
|
3687
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3688
|
+
type: 'agent_mode_changed',
|
|
3689
|
+
data: {
|
|
3690
|
+
agentId,
|
|
3691
|
+
mode: AGENT_MODES.CHAT,
|
|
3692
|
+
reason: 'empty_response_stall',
|
|
3693
|
+
timestamp: new Date().toISOString(),
|
|
3694
|
+
},
|
|
3695
|
+
});
|
|
3696
|
+
} catch (err) {
|
|
3697
|
+
this.logger.warn(`Failed to broadcast empty-response stall: ${err.message}`, { agentId });
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
await this.broadcastAgentStateUpdate(agentId, 'empty-response-stall');
|
|
3701
|
+
|
|
3702
|
+
this.logger.error(`Agent ${agentId} switched to CHAT mode after ${entry.count} empty responses`, {
|
|
3703
|
+
agentName: agent.name,
|
|
3704
|
+
elapsedMs: entry.lastAt - entry.firstAt,
|
|
3705
|
+
});
|
|
3706
|
+
}
|
|
3707
|
+
|
|
3223
3708
|
/**
|
|
3224
3709
|
* Record a state hash in the sliding window
|
|
3225
3710
|
*
|
|
@@ -3260,6 +3745,14 @@ class AgentScheduler {
|
|
|
3260
3745
|
const agent = await this.agentPool.getAgent(agentId);
|
|
3261
3746
|
if (!agent) return;
|
|
3262
3747
|
|
|
3748
|
+
// Clear scheduler state FIRST. If persistAgentState or a WebSocket broadcast
|
|
3749
|
+
// throws below, we must NOT leave stale loop-detector state that would
|
|
3750
|
+
// re-fire this handler on the next scheduler cycle — that was the exact
|
|
3751
|
+
// "detects a loop repeatedly without adding a new message first" bug.
|
|
3752
|
+
this.stateHashHistory.delete(agentId);
|
|
3753
|
+
this._emptyResponseTracker.delete(agentId);
|
|
3754
|
+
this.consecutiveNoToolMessages.delete(agentId);
|
|
3755
|
+
|
|
3263
3756
|
// Create a user-friendly message
|
|
3264
3757
|
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
3758
|
|
|
@@ -3289,35 +3782,43 @@ What would you like me to do next? You can:
|
|
|
3289
3782
|
|
|
3290
3783
|
// Stop the agent execution - switch to chat mode
|
|
3291
3784
|
agent.mode = AGENT_MODES.CHAT;
|
|
3292
|
-
|
|
3785
|
+
|
|
3786
|
+
// Persist + broadcast are best-effort. Scheduler state was already cleared
|
|
3787
|
+
// above, so a failure here can still leave the intervention un-persisted
|
|
3788
|
+
// but won't cause the loop detector to re-fire.
|
|
3789
|
+
try {
|
|
3790
|
+
await this.agentPool.persistAgentState(agentId);
|
|
3791
|
+
} catch (err) {
|
|
3792
|
+
this.logger.error(`Failed to persist agent after loop detection: ${err.message}`, { agentId });
|
|
3793
|
+
}
|
|
3293
3794
|
|
|
3294
3795
|
// Broadcast the message to UI so it appears in the chat
|
|
3295
3796
|
const sessionId = this.getAgentSession(agentId) || agent.sessionId;
|
|
3296
3797
|
if (sessionId && this.webSocketManager && this.webSocketManager.broadcastToSession) {
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3798
|
+
try {
|
|
3799
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3800
|
+
type: 'message_added',
|
|
3801
|
+
data: {
|
|
3802
|
+
agentId,
|
|
3803
|
+
message: messageToAdd,
|
|
3804
|
+
type: 'loop_intervention'
|
|
3805
|
+
}
|
|
3806
|
+
});
|
|
3306
3807
|
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
}
|
|
3316
|
-
})
|
|
3808
|
+
this.webSocketManager.broadcastToSession(sessionId, {
|
|
3809
|
+
type: 'agent_mode_changed',
|
|
3810
|
+
data: {
|
|
3811
|
+
agentId,
|
|
3812
|
+
mode: AGENT_MODES.CHAT,
|
|
3813
|
+
reason: 'loop_detected',
|
|
3814
|
+
timestamp: new Date().toISOString()
|
|
3815
|
+
}
|
|
3816
|
+
});
|
|
3817
|
+
} catch (err) {
|
|
3818
|
+
this.logger.warn(`Failed to broadcast loop intervention: ${err.message}`, { agentId });
|
|
3819
|
+
}
|
|
3317
3820
|
}
|
|
3318
|
-
|
|
3319
|
-
// Clear the hash history for this agent (fresh start when user responds)
|
|
3320
|
-
this.stateHashHistory.delete(agentId);
|
|
3821
|
+
await this.broadcastAgentStateUpdate(agentId, 'loop-detected');
|
|
3321
3822
|
|
|
3322
3823
|
this.logger.warn(`Agent ${agentId} stopped due to repetitive loop - awaiting user intervention`, {
|
|
3323
3824
|
occurrences: loopDetection.occurrences,
|