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.
Files changed (959) hide show
  1. package/package.json +1 -1
  2. package/src/core/__tests__/agentPool.test.js +60 -0
  3. package/src/core/__tests__/agentScheduler.test.js +129 -0
  4. package/src/core/agentPool.js +24 -0
  5. package/src/core/agentScheduler.js +574 -73
  6. package/src/index.js +8 -0
  7. package/src/interfaces/webServer.js +288 -0
  8. package/src/services/__tests__/channelFilter.test.js +264 -0
  9. package/src/services/__tests__/channelRelay.integration.test.js +496 -0
  10. package/src/services/__tests__/discordService.integration.test.js +10 -10
  11. package/src/services/__tests__/discordService.test.js +14 -7
  12. package/src/services/aiService.js +10 -3
  13. package/src/services/channelFilter.js +137 -0
  14. package/src/services/discordService.js +103 -19
  15. package/src/services/telegramService.js +58 -1
  16. package/src/tools/__tests__/visualEditorTool.context.test.js +141 -0
  17. package/src/tools/fileSystemTool.js +27 -3
  18. package/src/tools/openaiFunctionSchemas.js +270 -0
  19. package/src/tools/taskManagerTool.js +45 -2
  20. package/src/tools/terminalTool.js +23 -2
  21. package/src/tools/visualEditorTool.js +28 -4
  22. package/src/utilities/constants.js +9 -0
  23. package/web-ui/build/index.html +2 -2
  24. package/web-ui/build/static/1c-BbqxH6FC.js +1 -0
  25. package/web-ui/build/static/abap-UmHCZ0i1.js +1 -0
  26. package/web-ui/build/static/abnf-KQJciEU1.js +1 -0
  27. package/web-ui/build/static/abnf-wz9mo6UY.js +1 -0
  28. package/web-ui/build/static/accesslog-a-KjP-hj.js +1 -0
  29. package/web-ui/build/static/actionscript-C0kkFktE.js +1 -0
  30. package/web-ui/build/static/actionscript-CVfzNF7V.js +1 -0
  31. package/web-ui/build/static/ada-BtDccpCo.js +1 -0
  32. package/web-ui/build/static/ada-CsP-T950.js +1 -0
  33. package/web-ui/build/static/agda-DZ0Wv_k_.js +1 -0
  34. package/web-ui/build/static/al-Dieo4A36.js +1 -0
  35. package/web-ui/build/static/angelscript-Dxqs-qHl.js +1 -0
  36. package/web-ui/build/static/antlr4-2iwVxagJ.js +1 -0
  37. package/web-ui/build/static/apache-nHxOzinq.js +1 -0
  38. package/web-ui/build/static/apacheconf-DxkrSh6l.js +1 -0
  39. package/web-ui/build/static/apex-Broi_TKn.js +1 -0
  40. package/web-ui/build/static/apl-iAZYRZnE.js +1 -0
  41. package/web-ui/build/static/applescript-C-EKPlRf.js +1 -0
  42. package/web-ui/build/static/applescript-CVipha9P.js +1 -0
  43. package/web-ui/build/static/aql-Dn0E4LhK.js +1 -0
  44. package/web-ui/build/static/arcade-D5kIj1ez.js +1 -0
  45. package/web-ui/build/static/arduino-CydV4LN9.js +1 -0
  46. package/web-ui/build/static/arduino-DXaSwrry.js +1 -0
  47. package/web-ui/build/static/arff-yeDNnxkY.js +1 -0
  48. package/web-ui/build/static/armasm-DTu74JIo.js +1 -0
  49. package/web-ui/build/static/asciidoc-CLaqB1Gg.js +1 -0
  50. package/web-ui/build/static/asciidoc-DguUDHf5.js +1 -0
  51. package/web-ui/build/static/asm6502-C2c-H0Jh.js +1 -0
  52. package/web-ui/build/static/asmatmel-5xAyVq56.js +1 -0
  53. package/web-ui/build/static/aspectj-D5JvBRBv.js +1 -0
  54. package/web-ui/build/static/aspnet-DZfW9iG1.js +1 -0
  55. package/web-ui/build/static/autohotkey-3yT8W87y.js +1 -0
  56. package/web-ui/build/static/autohotkey-CxEWa3D5.js +1 -0
  57. package/web-ui/build/static/autoit-COt7rtxE.js +1 -0
  58. package/web-ui/build/static/autoit-DSva7SrP.js +1 -0
  59. package/web-ui/build/static/avisynth-DdpQ810f.js +1 -0
  60. package/web-ui/build/static/avrasm-BR0ncM-L.js +1 -0
  61. package/web-ui/build/static/avro-idl-DCISsbhh.js +1 -0
  62. package/web-ui/build/static/awk-Dd5HJDa0.js +1 -0
  63. package/web-ui/build/static/axapta-DWn0qUrW.js +1 -0
  64. package/web-ui/build/static/bash-B024Y1MV.js +1 -0
  65. package/web-ui/build/static/bash-qq4eTfOM.js +1 -0
  66. package/web-ui/build/static/basic-BWjvt39D.js +1 -0
  67. package/web-ui/build/static/basic-DVlMYdnX.js +1 -0
  68. package/web-ui/build/static/batch-Bb3dgg5p.js +1 -0
  69. package/web-ui/build/static/bbcode-DIclgs6t.js +1 -0
  70. package/web-ui/build/static/bicep-CXafPJf-.js +1 -0
  71. package/web-ui/build/static/birb-Btu8LQQE.js +1 -0
  72. package/web-ui/build/static/bison-CDXROKZw.js +1 -0
  73. package/web-ui/build/static/bnf-BB43qRSC.js +1 -0
  74. package/web-ui/build/static/bnf-ClpHUN6K.js +1 -0
  75. package/web-ui/build/static/brainfuck-BIgmc-EZ.js +1 -0
  76. package/web-ui/build/static/brainfuck-BJtPWa6l.js +1 -0
  77. package/web-ui/build/static/brightscript-9fU7OT4Y.js +1 -0
  78. package/web-ui/build/static/bro-DLftyzoO.js +1 -0
  79. package/web-ui/build/static/bsl-BWPnBSvd.js +1 -0
  80. package/web-ui/build/static/c-CD-936sv.js +1 -0
  81. package/web-ui/build/static/c-Do5sfWh2.js +1 -0
  82. package/web-ui/build/static/c-like-Cerk48hs.js +1 -0
  83. package/web-ui/build/static/cal-BfMsPDa0.js +1 -0
  84. package/web-ui/build/static/capnproto-mR83jTKG.js +1 -0
  85. package/web-ui/build/static/ceylon-Dt2cl-Ez.js +1 -0
  86. package/web-ui/build/static/cfscript-CFB-YYf8.js +1 -0
  87. package/web-ui/build/static/chaiscript-D3skeymm.js +1 -0
  88. package/web-ui/build/static/cil-DeczQ_ut.js +1 -0
  89. package/web-ui/build/static/clean-BXJPwGNL.js +1 -0
  90. package/web-ui/build/static/clojure-HHG1U7gj.js +1 -0
  91. package/web-ui/build/static/clojure-rEWdWYo_.js +1 -0
  92. package/web-ui/build/static/clojure-repl-CE4jr3K0.js +1 -0
  93. package/web-ui/build/static/cmake-DAzvKH16.js +1 -0
  94. package/web-ui/build/static/cmake-tD6uZl-y.js +1 -0
  95. package/web-ui/build/static/cobol-C2X6-bRz.js +1 -0
  96. package/web-ui/build/static/coffeescript-C9qjSh74.js +1 -0
  97. package/web-ui/build/static/coffeescript-DeHnRseX.js +1 -0
  98. package/web-ui/build/static/concurnas-DNuInYde.js +1 -0
  99. package/web-ui/build/static/coq-BQFo5XwN.js +1 -0
  100. package/web-ui/build/static/coq-Bmnum53S.js +1 -0
  101. package/web-ui/build/static/cos-D_0u-U2Y.js +1 -0
  102. package/web-ui/build/static/cpp-CoD9F6ol.js +1 -0
  103. package/web-ui/build/static/cpp-DB8R2f_c.js +1 -0
  104. package/web-ui/build/static/crmsh-DghD3B1u.js +1 -0
  105. package/web-ui/build/static/crystal-C63_SlFe.js +1 -0
  106. package/web-ui/build/static/crystal-GkhJSVpE.js +1 -0
  107. package/web-ui/build/static/csharp-Upa_qqR3.js +1 -0
  108. package/web-ui/build/static/csharp-kB8isYBD.js +1 -0
  109. package/web-ui/build/static/cshtml-BjeIyJW7.js +1 -0
  110. package/web-ui/build/static/csp-B9zvIPTA.js +1 -0
  111. package/web-ui/build/static/csp-hqOQW_KO.js +1 -0
  112. package/web-ui/build/static/css-BOqi7Sb8.js +1 -0
  113. package/web-ui/build/static/css-extras-NaDRDQYb.js +1 -0
  114. package/web-ui/build/static/csv-C7zNP0bV.js +1 -0
  115. package/web-ui/build/static/cypher-DzSGt09R.js +1 -0
  116. package/web-ui/build/static/d-DU9v7A7o.js +1 -0
  117. package/web-ui/build/static/d-YLgAiEhY.js +1 -0
  118. package/web-ui/build/static/dart-CLSlIEjd.js +1 -0
  119. package/web-ui/build/static/dart-Cv0y84fm.js +1 -0
  120. package/web-ui/build/static/dataweave-5zYOQCxv.js +1 -0
  121. package/web-ui/build/static/dax-C6xLX5GM.js +1 -0
  122. package/web-ui/build/static/delphi-D5HcUuVw.js +1 -0
  123. package/web-ui/build/static/dhall-C8OzwmzV.js +1 -0
  124. package/web-ui/build/static/diff-B030ZRbb.js +1 -0
  125. package/web-ui/build/static/diff-NCsBJCa7.js +1 -0
  126. package/web-ui/build/static/django-BeQDLTjX.js +1 -0
  127. package/web-ui/build/static/django-cC0WFEf1.js +1 -0
  128. package/web-ui/build/static/dns-CGMMfnr4.js +1 -0
  129. package/web-ui/build/static/dns-zone-file-908DrcaX.js +1 -0
  130. package/web-ui/build/static/docker-CE6F0WPR.js +1 -0
  131. package/web-ui/build/static/dockerfile-CUNa_EmN.js +1 -0
  132. package/web-ui/build/static/dos-CiM5tkPu.js +1 -0
  133. package/web-ui/build/static/dot-CZ0WLAzq.js +1 -0
  134. package/web-ui/build/static/dsconfig-Wo1ktU-F.js +1 -0
  135. package/web-ui/build/static/dts-BQJ7eIaM.js +1 -0
  136. package/web-ui/build/static/dust-DWnG4XQf.js +1 -0
  137. package/web-ui/build/static/ebnf-BqQRECjk.js +1 -0
  138. package/web-ui/build/static/ebnf-Cn_QHOpW.js +1 -0
  139. package/web-ui/build/static/editorconfig-CRE_lK21.js +1 -0
  140. package/web-ui/build/static/eiffel-h-dSP-Mu.js +1 -0
  141. package/web-ui/build/static/ejs-PVoVLwHk.js +1 -0
  142. package/web-ui/build/static/elixir-DVoAEVq_.js +1 -0
  143. package/web-ui/build/static/elixir-ZA65-L5t.js +1 -0
  144. package/web-ui/build/static/elm-ClRnxcFJ.js +1 -0
  145. package/web-ui/build/static/elm-Ttg_Dv8v.js +1 -0
  146. package/web-ui/build/static/erb-DCMJz1va.js +1 -0
  147. package/web-ui/build/static/erb-DDL7TB76.js +1 -0
  148. package/web-ui/build/static/erlang-01AtuMB8.js +1 -0
  149. package/web-ui/build/static/erlang-CLb6foRm.js +1 -0
  150. package/web-ui/build/static/erlang-repl-BwUG_X-H.js +1 -0
  151. package/web-ui/build/static/etlua-7jIebQwZ.js +1 -0
  152. package/web-ui/build/static/excel-BkKnPFBB.js +1 -0
  153. package/web-ui/build/static/excel-formula-dDd7nIUV.js +1 -0
  154. package/web-ui/build/static/factor-BLn5sqxN.js +1 -0
  155. package/web-ui/build/static/false-CNuRH4WA.js +1 -0
  156. package/web-ui/build/static/firestore-security-rules-Cr5e6oSH.js +1 -0
  157. package/web-ui/build/static/fix-NJ8G_1Tt.js +1 -0
  158. package/web-ui/build/static/flix-CBhTDcl9.js +1 -0
  159. package/web-ui/build/static/flow-DvgK1btf.js +1 -0
  160. package/web-ui/build/static/fortran-Bo-O9xtT.js +1 -0
  161. package/web-ui/build/static/fortran-Dj3v5L_m.js +1 -0
  162. package/web-ui/build/static/fsharp-5c6P8ZUH.js +1 -0
  163. package/web-ui/build/static/fsharp-C8bhnjfe.js +1 -0
  164. package/web-ui/build/static/ftl-8qE-2FJL.js +1 -0
  165. package/web-ui/build/static/gams-pbQRvKgr.js +1 -0
  166. package/web-ui/build/static/gap-CSFizYYs.js +1 -0
  167. package/web-ui/build/static/gauss-C0BsqEdj.js +1 -0
  168. package/web-ui/build/static/gcode-DMuLrnJF.js +1 -0
  169. package/web-ui/build/static/gcode-as5uEQOe.js +1 -0
  170. package/web-ui/build/static/gdscript-CSaSlSna.js +1 -0
  171. package/web-ui/build/static/gedcom-Cm86Ngut.js +1 -0
  172. package/web-ui/build/static/gherkin-C7FSJ6d3.js +1 -0
  173. package/web-ui/build/static/gherkin-C8wqlUqv.js +1 -0
  174. package/web-ui/build/static/git-DzPBmHlg.js +1 -0
  175. package/web-ui/build/static/glsl-D0_rPD58.js +1 -0
  176. package/web-ui/build/static/glsl-oUwWN2Xp.js +1 -0
  177. package/web-ui/build/static/gml-DNrWm4kb.js +1 -0
  178. package/web-ui/build/static/gml-JDXVyhBU.js +1 -0
  179. package/web-ui/build/static/gn-Bw-OsDH_.js +1 -0
  180. package/web-ui/build/static/go-B7Traa8J.js +1 -0
  181. package/web-ui/build/static/go-CaXFvYLQ.js +1 -0
  182. package/web-ui/build/static/go-module-BzKKnNxf.js +1 -0
  183. package/web-ui/build/static/golo-BokfRozl.js +1 -0
  184. package/web-ui/build/static/gradle-BBE_z74S.js +1 -0
  185. package/web-ui/build/static/graphql-DyqQ249q.js +1 -0
  186. package/web-ui/build/static/groovy-C9bdtULM.js +1 -0
  187. package/web-ui/build/static/groovy-CTYHYVKe.js +1 -0
  188. package/web-ui/build/static/haml--wzGI8rV.js +1 -0
  189. package/web-ui/build/static/haml-CP_fk9Du.js +1 -0
  190. package/web-ui/build/static/handlebars-BCN8I_fU.js +1 -0
  191. package/web-ui/build/static/handlebars-ClNs_EWN.js +1 -0
  192. package/web-ui/build/static/haskell-9-8FOmKL.js +1 -0
  193. package/web-ui/build/static/haskell-CeDcPoLF.js +1 -0
  194. package/web-ui/build/static/haxe-50b4_Uxu.js +1 -0
  195. package/web-ui/build/static/haxe-DV1jCpSQ.js +1 -0
  196. package/web-ui/build/static/hcl-BYAKEmjA.js +1 -0
  197. package/web-ui/build/static/hlsl-_V666kTg.js +1 -0
  198. package/web-ui/build/static/hoon-Xx5CPs_2.js +1 -0
  199. package/web-ui/build/static/hpkp-Dgu8ZS6s.js +1 -0
  200. package/web-ui/build/static/hsp-B0EcUcwP.js +1 -0
  201. package/web-ui/build/static/hsts-B1FQvgxb.js +1 -0
  202. package/web-ui/build/static/htmlbars-BGs3CWC2.js +1 -0
  203. package/web-ui/build/static/http-BvrKmZx0.js +1 -0
  204. package/web-ui/build/static/http-DUnWgTgI.js +1 -0
  205. package/web-ui/build/static/hy-StjWDayT.js +1 -0
  206. package/web-ui/build/static/ichigojam-Dla3EUZJ.js +1 -0
  207. package/web-ui/build/static/icon-CEA3F2cM.js +1 -0
  208. package/web-ui/build/static/icu-message-format-CIRX0H1E.js +1 -0
  209. package/web-ui/build/static/idris-z8g0EYLs.js +1 -0
  210. package/web-ui/build/static/iecst-D99vO-YV.js +1 -0
  211. package/web-ui/build/static/ignore-Bd9HTGo7.js +1 -0
  212. package/web-ui/build/static/index-9mcWHG2c.js +13 -0
  213. package/web-ui/build/static/index-BUtXAjd5.css +1 -0
  214. package/web-ui/build/static/index-CaMlGjdh.js +834 -0
  215. package/web-ui/build/static/index-D35injhb.js +1 -0
  216. package/web-ui/build/static/inform7-CKq2EPhg.js +1 -0
  217. package/web-ui/build/static/inform7-D-KIfWlv.js +1 -0
  218. package/web-ui/build/static/ini-CoFKaEFp.js +1 -0
  219. package/web-ui/build/static/ini-Cqh2VeO8.js +1 -0
  220. package/web-ui/build/static/io-A1ozJngc.js +1 -0
  221. package/web-ui/build/static/irpf90-DLGfrn4I.js +1 -0
  222. package/web-ui/build/static/isbl-dbyF-dLf.js +1 -0
  223. package/web-ui/build/static/j-ByhCpf6J.js +1 -0
  224. package/web-ui/build/static/java-DCbnRaHw.js +1 -0
  225. package/web-ui/build/static/java-LzFZofIb.js +1 -0
  226. package/web-ui/build/static/javadoc-CaKRZCNM.js +1 -0
  227. package/web-ui/build/static/javadoclike-CmvAiCvn.js +1 -0
  228. package/web-ui/build/static/javascript-Cpvfsh-z.js +1 -0
  229. package/web-ui/build/static/javastacktrace-CSUMoXqu.js +1 -0
  230. package/web-ui/build/static/jboss-cli-Cv0HXjqO.js +1 -0
  231. package/web-ui/build/static/jexl-CtUU8Pyc.js +1 -0
  232. package/web-ui/build/static/jolie-Ccbea_Ca.js +1 -0
  233. package/web-ui/build/static/jq-DQJKGqGL.js +1 -0
  234. package/web-ui/build/static/js-extras-BST2fo5a.js +1 -0
  235. package/web-ui/build/static/js-templates-T4aqrsni.js +1 -0
  236. package/web-ui/build/static/jsdoc-DZuHBRHT.js +1 -0
  237. package/web-ui/build/static/json-ByIlxtOm.js +1 -0
  238. package/web-ui/build/static/json-Dd-I2QR8.js +1 -0
  239. package/web-ui/build/static/json5-CIBARWXJ.js +1 -0
  240. package/web-ui/build/static/jsonp-Cs7yuq7_.js +1 -0
  241. package/web-ui/build/static/jsstacktrace-DrmYorp8.js +1 -0
  242. package/web-ui/build/static/jsx-Clb0obdm.js +1 -0
  243. package/web-ui/build/static/julia-BreTVWTb.js +1 -0
  244. package/web-ui/build/static/julia-qQfG7KSh.js +1 -0
  245. package/web-ui/build/static/julia-repl-wN09lKm6.js +1 -0
  246. package/web-ui/build/static/keepalived-DCyf_6ml.js +1 -0
  247. package/web-ui/build/static/keyman-B22SYHoa.js +1 -0
  248. package/web-ui/build/static/kotlin-DeVs-dNz.js +1 -0
  249. package/web-ui/build/static/kotlin-OMSaUY06.js +1 -0
  250. package/web-ui/build/static/kumir-Y-M6VOUG.js +1 -0
  251. package/web-ui/build/static/kusto-BnDldn0z.js +1 -0
  252. package/web-ui/build/static/lasso-BlUPIy-8.js +1 -0
  253. package/web-ui/build/static/latex-BGueNdTW.js +1 -0
  254. package/web-ui/build/static/latex-EZ8QNCjf.js +1 -0
  255. package/web-ui/build/static/latte-BkyPxQ_A.js +1 -0
  256. package/web-ui/build/static/ldif-BCIcpQI_.js +1 -0
  257. package/web-ui/build/static/leaf-BAG78wZj.js +1 -0
  258. package/web-ui/build/static/less-CFghh9Qx.js +1 -0
  259. package/web-ui/build/static/less-CbqfFGMD.js +1 -0
  260. package/web-ui/build/static/lilypond-BSpYx-1e.js +1 -0
  261. package/web-ui/build/static/liquid-CHhOmyTU.js +1 -0
  262. package/web-ui/build/static/lisp-QMm5BThy.js +1 -0
  263. package/web-ui/build/static/lisp-rizdk7e8.js +1 -0
  264. package/web-ui/build/static/livecodeserver-Bbh0nB2d.js +1 -0
  265. package/web-ui/build/static/livescript--QIhQOIm.js +1 -0
  266. package/web-ui/build/static/livescript-wYJ9C7MN.js +1 -0
  267. package/web-ui/build/static/llvm-qWkZ6M3-.js +1 -0
  268. package/web-ui/build/static/llvm-x8W93e2q.js +1 -0
  269. package/web-ui/build/static/log-D4PGnDHU.js +1 -0
  270. package/web-ui/build/static/lolcode-CHKS4ygP.js +1 -0
  271. package/web-ui/build/static/lsl-BEuQrHG7.js +1 -0
  272. package/web-ui/build/static/lua-Czrw1nZw.js +1 -0
  273. package/web-ui/build/static/lua-DUasTiYT.js +1 -0
  274. package/web-ui/build/static/magma-B16nUtxA.js +1 -0
  275. package/web-ui/build/static/makefile-BkqsEpVd.js +1 -0
  276. package/web-ui/build/static/makefile-DmoEDBJj.js +1 -0
  277. package/web-ui/build/static/markdown-FL-EZYmc.js +1 -0
  278. package/web-ui/build/static/markdown-N4YibSvf.js +1 -0
  279. package/web-ui/build/static/markup-templating-C1Q3BuB3.js +1 -0
  280. package/web-ui/build/static/mathematica-BZ50Ibwb.js +1 -0
  281. package/web-ui/build/static/matlab-CJFiUipn.js +1 -0
  282. package/web-ui/build/static/matlab-D-LwnpYW.js +1 -0
  283. package/web-ui/build/static/maxima-D1nKJHio.js +1 -0
  284. package/web-ui/build/static/maxscript-3ukqkynT.js +1 -0
  285. package/web-ui/build/static/mel-BpGPnIg7.js +1 -0
  286. package/web-ui/build/static/mel-DAIpK4k4.js +1 -0
  287. package/web-ui/build/static/mercury-BO6AXAJw.js +1 -0
  288. package/web-ui/build/static/mermaid-Cvu66kFB.js +1 -0
  289. package/web-ui/build/static/mipsasm-CP7z3_gg.js +1 -0
  290. package/web-ui/build/static/mizar-1tBmTbFY.js +1 -0
  291. package/web-ui/build/static/mizar-vPQKaBOY.js +1 -0
  292. package/web-ui/build/static/mojolicious-3wXNqu2Z.js +1 -0
  293. package/web-ui/build/static/mongodb-DkJ5x1x3.js +1 -0
  294. package/web-ui/build/static/monkey-DwU43sRn.js +1 -0
  295. package/web-ui/build/static/monkey-DzoqN4GB.js +1 -0
  296. package/web-ui/build/static/moonscript-CgTduPCr.js +1 -0
  297. package/web-ui/build/static/moonscript-Dzbt70Ke.js +1 -0
  298. package/web-ui/build/static/n1ql-BaVhxD8V.js +1 -0
  299. package/web-ui/build/static/n1ql-DUHSzjt3.js +1 -0
  300. package/web-ui/build/static/n4js-DZ7dW-NZ.js +1 -0
  301. package/web-ui/build/static/nand2tetris-hdl-C-ecDW8U.js +1 -0
  302. package/web-ui/build/static/naniscript-dzw8pH4q.js +1 -0
  303. package/web-ui/build/static/nasm-B0fCm10I.js +1 -0
  304. package/web-ui/build/static/neon-DRlFTieL.js +1 -0
  305. package/web-ui/build/static/nevod-BEzTxq7x.js +1 -0
  306. package/web-ui/build/static/nginx-BI0b7qBW.js +1 -0
  307. package/web-ui/build/static/nginx-BTbIqU-1.js +1 -0
  308. package/web-ui/build/static/nim-C1lYEnIA.js +1 -0
  309. package/web-ui/build/static/nim-mfWcJfe-.js +1 -0
  310. package/web-ui/build/static/nix-PO76YCUx.js +1 -0
  311. package/web-ui/build/static/nix-a-29l1yK.js +1 -0
  312. package/web-ui/build/static/node-repl-DDA8xtxU.js +1 -0
  313. package/web-ui/build/static/nsis-CLyYop70.js +1 -0
  314. package/web-ui/build/static/nsis-GiqT6oer.js +1 -0
  315. package/web-ui/build/static/objectivec-DF-fhcs7.js +1 -0
  316. package/web-ui/build/static/objectivec-DtXa6iKB.js +1 -0
  317. package/web-ui/build/static/ocaml-D4ptVFU5.js +1 -0
  318. package/web-ui/build/static/ocaml-DBtZVh9H.js +1 -0
  319. package/web-ui/build/static/opencl-0Z_Gtfzx.js +1 -0
  320. package/web-ui/build/static/openqasm-BafUOtKF.js +1 -0
  321. package/web-ui/build/static/openscad-DwQ7I7ze.js +1 -0
  322. package/web-ui/build/static/oxygene-Bt7r8sbX.js +1 -0
  323. package/web-ui/build/static/oz-Da-qnXiT.js +1 -0
  324. package/web-ui/build/static/parigp-D6mMgLkz.js +1 -0
  325. package/web-ui/build/static/parser-DUfGrzvv.js +1 -0
  326. package/web-ui/build/static/parser3-C4GwCqRM.js +1 -0
  327. package/web-ui/build/static/pascal-CKsIwy8z.js +1 -0
  328. package/web-ui/build/static/pascaligo-0Y00fNzu.js +1 -0
  329. package/web-ui/build/static/pcaxis-BFwUDXM-.js +1 -0
  330. package/web-ui/build/static/peoplecode-D8-HVebY.js +1 -0
  331. package/web-ui/build/static/perl-CoNeuMP2.js +1 -0
  332. package/web-ui/build/static/perl-Dk_kCckE.js +1 -0
  333. package/web-ui/build/static/pf-DWKdp2Z5.js +1 -0
  334. package/web-ui/build/static/pgsql-DQM_KLIL.js +1 -0
  335. package/web-ui/build/static/php-BLJ1RddK.js +1 -0
  336. package/web-ui/build/static/php-C4Q-EoBs.js +1 -0
  337. package/web-ui/build/static/php-extras-DH16mdyb.js +1 -0
  338. package/web-ui/build/static/php-template-Bgyau4h4.js +1 -0
  339. package/web-ui/build/static/phpdoc-CrGYZCs3.js +1 -0
  340. package/web-ui/build/static/plaintext--cxrnnIY.js +1 -0
  341. package/web-ui/build/static/plsql-DXxJ1j1M.js +1 -0
  342. package/web-ui/build/static/pony-Bk4QKmb5.js +1 -0
  343. package/web-ui/build/static/powerquery-BNY7Y_eg.js +1 -0
  344. package/web-ui/build/static/powershell-CjTGWZrY.js +1 -0
  345. package/web-ui/build/static/powershell-DKKBTrGN.js +1 -0
  346. package/web-ui/build/static/processing-CoCmNEON.js +1 -0
  347. package/web-ui/build/static/processing-dWxOKKau.js +1 -0
  348. package/web-ui/build/static/profile-DinHOW6q.js +1 -0
  349. package/web-ui/build/static/prolog-D8s2MxCR.js +1 -0
  350. package/web-ui/build/static/prolog-tfF0hJ7N.js +1 -0
  351. package/web-ui/build/static/promql-BbpNnYtf.js +1 -0
  352. package/web-ui/build/static/properties-BH5IGhCw.js +1 -0
  353. package/web-ui/build/static/properties-BtBGEFji.js +1 -0
  354. package/web-ui/build/static/protobuf-Bq57MNXu.js +1 -0
  355. package/web-ui/build/static/protobuf-FQ5v_34f.js +1 -0
  356. package/web-ui/build/static/psl-DH3KK34y.js +1 -0
  357. package/web-ui/build/static/pug-BH0-FqNN.js +1 -0
  358. package/web-ui/build/static/puppet-D6IQ0-e_.js +1 -0
  359. package/web-ui/build/static/puppet-DhDhkrHQ.js +1 -0
  360. package/web-ui/build/static/pure-D-zzqNXt.js +1 -0
  361. package/web-ui/build/static/purebasic-C3ZHqBxR.js +1 -0
  362. package/web-ui/build/static/purebasic-DTWXM0iu.js +1 -0
  363. package/web-ui/build/static/purescript-C9dMZi0f.js +1 -0
  364. package/web-ui/build/static/python-kp4UxaFP.js +1 -0
  365. package/web-ui/build/static/python-repl-Bugvu_dB.js +1 -0
  366. package/web-ui/build/static/python-vnX1mWhI.js +1 -0
  367. package/web-ui/build/static/q-BRREgX-f.js +1 -0
  368. package/web-ui/build/static/q-V3GLDm_n.js +1 -0
  369. package/web-ui/build/static/qml-DfQdRLrG.js +1 -0
  370. package/web-ui/build/static/qml-i0MLAsR_.js +1 -0
  371. package/web-ui/build/static/qore-CFRmreiI.js +1 -0
  372. package/web-ui/build/static/qsharp-BpxCSpMu.js +1 -0
  373. package/web-ui/build/static/r-BFhn56zx.js +1 -0
  374. package/web-ui/build/static/r-D19R1VlL.js +1 -0
  375. package/web-ui/build/static/racket-D6Do3XQN.js +1 -0
  376. package/web-ui/build/static/reason-BLxB_uYS.js +1 -0
  377. package/web-ui/build/static/reasonml-CR2O5QXc.js +1 -0
  378. package/web-ui/build/static/regex-ExQT3DD-.js +1 -0
  379. package/web-ui/build/static/rego-BG1H2Grq.js +1 -0
  380. package/web-ui/build/static/renpy-DPYPiSEa.js +1 -0
  381. package/web-ui/build/static/rest-BXeudWmA.js +1 -0
  382. package/web-ui/build/static/rib-B50qbZUa.js +1 -0
  383. package/web-ui/build/static/rip-Oy08VNTd.js +1 -0
  384. package/web-ui/build/static/roboconf-BJlNdB3f.js +1 -0
  385. package/web-ui/build/static/roboconf-BWCGa42W.js +1 -0
  386. package/web-ui/build/static/robotframework-CrL-sTEo.js +1 -0
  387. package/web-ui/build/static/routeros-BV_7BLfU.js +1 -0
  388. package/web-ui/build/static/rsl-3QUMrc7D.js +1 -0
  389. package/web-ui/build/static/ruby-CocpOjC3.js +1 -0
  390. package/web-ui/build/static/ruby-xGmQ173X.js +1 -0
  391. package/web-ui/build/static/ruleslanguage-Dvh9iMSY.js +1 -0
  392. package/web-ui/build/static/rust-BZNigb_r.js +1 -0
  393. package/web-ui/build/static/rust-DwNjoaBZ.js +1 -0
  394. package/web-ui/build/static/sas-BJAlmleu.js +1 -0
  395. package/web-ui/build/static/sas-DMbLpxbs.js +1 -0
  396. package/web-ui/build/static/sass-DqYzzuDm.js +1 -0
  397. package/web-ui/build/static/scala-Bh2FkhWY.js +1 -0
  398. package/web-ui/build/static/scala-CBjzCnx6.js +1 -0
  399. package/web-ui/build/static/scheme-D2RTBnn4.js +1 -0
  400. package/web-ui/build/static/scheme-YLsRQlUd.js +1 -0
  401. package/web-ui/build/static/scilab-CXvKl1CZ.js +1 -0
  402. package/web-ui/build/static/scss-BE2dzDGl.js +1 -0
  403. package/web-ui/build/static/scss-J1E3J7lz.js +1 -0
  404. package/web-ui/build/static/shell-AzmPYKrI.js +1 -0
  405. package/web-ui/build/static/shell-session-C5dCMLWG.js +1 -0
  406. package/web-ui/build/static/smali-C88i6nEO.js +1 -0
  407. package/web-ui/build/static/smali-Ddnoiqfy.js +1 -0
  408. package/web-ui/build/static/smalltalk-C72n_dxy.js +1 -0
  409. package/web-ui/build/static/smalltalk-CPfRSVZs.js +1 -0
  410. package/web-ui/build/static/smarty-Dypt4i8b.js +1 -0
  411. package/web-ui/build/static/sml-BGGb-k8a.js +1 -0
  412. package/web-ui/build/static/sml-BODNZSm_.js +1 -0
  413. package/web-ui/build/static/solidity-D6wtTexR.js +1 -0
  414. package/web-ui/build/static/solution-file-5lZW0oOE.js +1 -0
  415. package/web-ui/build/static/soy-y16jnIDo.js +1 -0
  416. package/web-ui/build/static/sparql-DrdB7SPu.js +1 -0
  417. package/web-ui/build/static/splunk-spl-Doyv_CQR.js +1 -0
  418. package/web-ui/build/static/sqf-BSSKLJcS.js +1 -0
  419. package/web-ui/build/static/sqf-C27vJSdk.js +1 -0
  420. package/web-ui/build/static/sql-BGAlidwo.js +1 -0
  421. package/web-ui/build/static/sql-D632T_PJ.js +1 -0
  422. package/web-ui/build/static/sql_more-DxYQWBWa.js +1 -0
  423. package/web-ui/build/static/squirrel-BtynEITS.js +1 -0
  424. package/web-ui/build/static/stan-_WgX5GWP.js +1 -0
  425. package/web-ui/build/static/stan-oF5qmMKy.js +1 -0
  426. package/web-ui/build/static/stata-wLOz3xoi.js +1 -0
  427. package/web-ui/build/static/step21-BbsA7W89.js +1 -0
  428. package/web-ui/build/static/stylus-DtfRtkyR.js +1 -0
  429. package/web-ui/build/static/stylus-vEf2q3jH.js +1 -0
  430. package/web-ui/build/static/subunit-BRaQkxqR.js +1 -0
  431. package/web-ui/build/static/swift-DT015mq6.js +1 -0
  432. package/web-ui/build/static/swift-Drl9Vhia.js +1 -0
  433. package/web-ui/build/static/systemd-DWH7nh0Q.js +1 -0
  434. package/web-ui/build/static/t4-cs-BqiTmoCX.js +1 -0
  435. package/web-ui/build/static/t4-templating-Bof0eAYR.js +1 -0
  436. package/web-ui/build/static/t4-vb-8nW7Q4TI.js +1 -0
  437. package/web-ui/build/static/taggerscript-Dmu4nEaQ.js +1 -0
  438. package/web-ui/build/static/tap-B19AuLWq.js +1 -0
  439. package/web-ui/build/static/tap-DOdxz1Vj.js +1 -0
  440. package/web-ui/build/static/tcl-BAqD74MG.js +1 -0
  441. package/web-ui/build/static/tcl-DOM7n3Vd.js +1 -0
  442. package/web-ui/build/static/textile-DFXg54i4.js +1 -0
  443. package/web-ui/build/static/thrift-BGDpLcp_.js +1 -0
  444. package/web-ui/build/static/toml-J8m0tgag.js +1 -0
  445. package/web-ui/build/static/tp-BQkDcUXJ.js +1 -0
  446. package/web-ui/build/static/tremor-hOnek1Vr.js +1 -0
  447. package/web-ui/build/static/tsx-dhyw01LJ.js +1 -0
  448. package/web-ui/build/static/tt2-BZlvT5MG.js +1 -0
  449. package/web-ui/build/static/turtle-CEGacgOB.js +1 -0
  450. package/web-ui/build/static/twig-C7j-eyaz.js +1 -0
  451. package/web-ui/build/static/twig-MQre7lvF.js +1 -0
  452. package/web-ui/build/static/typescript-Dq5ZmyEV.js +1 -0
  453. package/web-ui/build/static/typescript-qPtHjmzW.js +1 -0
  454. package/web-ui/build/static/typoscript-B0sirAiC.js +1 -0
  455. package/web-ui/build/static/unrealscript-D_kXyIkW.js +1 -0
  456. package/web-ui/build/static/uorazor-8wB8nSC0.js +1 -0
  457. package/web-ui/build/static/uri-CaeHYk3y.js +1 -0
  458. package/web-ui/build/static/v-CYZwlqI2.js +1 -0
  459. package/web-ui/build/static/vala-DDkZds8N.js +1 -0
  460. package/web-ui/build/static/vala-zKk5gtUp.js +1 -0
  461. package/web-ui/build/static/vbnet-DY8Bh7zr.js +1 -0
  462. package/web-ui/build/static/vbnet-Z7zud-Nk.js +1 -0
  463. package/web-ui/build/static/vbscript-0xsGTIri.js +1 -0
  464. package/web-ui/build/static/vbscript-html-CQJqQ_tQ.js +1 -0
  465. package/web-ui/build/static/velocity-Dqe4ZgAo.js +1 -0
  466. package/web-ui/build/static/verilog-B0uVsHQr.js +1 -0
  467. package/web-ui/build/static/verilog-DLybxDJj.js +1 -0
  468. package/web-ui/build/static/vhdl-CP0JnbrM.js +1 -0
  469. package/web-ui/build/static/vhdl-CRV0TYO8.js +1 -0
  470. package/web-ui/build/static/vim-06LYR_Gs.js +1 -0
  471. package/web-ui/build/static/vim-DGgQcHr4.js +1 -0
  472. package/web-ui/build/static/visual-basic-BUWV1u5S.js +1 -0
  473. package/web-ui/build/static/warpscript-DKb8tXBH.js +1 -0
  474. package/web-ui/build/static/wasm-8E-n1sJQ.js +1 -0
  475. package/web-ui/build/static/web-idl-Bynfh0Gg.js +1 -0
  476. package/web-ui/build/static/wiki-Ck0ehuwt.js +1 -0
  477. package/web-ui/build/static/wolfram-BE1k6uuJ.js +1 -0
  478. package/web-ui/build/static/wren-Ce_CEEnI.js +1 -0
  479. package/web-ui/build/static/x86asm-DZUKtGAe.js +1 -0
  480. package/web-ui/build/static/xeora-DvXhnkv6.js +1 -0
  481. package/web-ui/build/static/xl-B1lBPZU_.js +1 -0
  482. package/web-ui/build/static/xml-D3p5hl_7.js +1 -0
  483. package/web-ui/build/static/xml-doc-CF8VvGyG.js +1 -0
  484. package/web-ui/build/static/xojo-D-WnMFdK.js +1 -0
  485. package/web-ui/build/static/xquery-BNNLxmJw.js +1 -0
  486. package/web-ui/build/static/xquery-D-mYtMjU.js +1 -0
  487. package/web-ui/build/static/yaml-a5-6TRUw.js +1 -0
  488. package/web-ui/build/static/yaml-aH3GAAQN.js +1 -0
  489. package/web-ui/build/static/yang-B2qT8oVg.js +1 -0
  490. package/web-ui/build/static/zephir-yxlgFmpA.js +1 -0
  491. package/web-ui/build/static/zig-B_AoM5P0.js +1 -0
  492. package/web-ui/build/static/1c-DUhJWQrP.js +0 -1
  493. package/web-ui/build/static/abap-D5pCv45A.js +0 -1
  494. package/web-ui/build/static/abnf-BqIdp1gH.js +0 -1
  495. package/web-ui/build/static/abnf-CBjlJif0.js +0 -1
  496. package/web-ui/build/static/accesslog-C5KlxDoB.js +0 -1
  497. package/web-ui/build/static/actionscript-CEdNWXaD.js +0 -1
  498. package/web-ui/build/static/actionscript-CgxJfO4L.js +0 -1
  499. package/web-ui/build/static/ada-Bdm6rSt3.js +0 -1
  500. package/web-ui/build/static/ada-Cqq140Rj.js +0 -1
  501. package/web-ui/build/static/agda-glonKdcN.js +0 -1
  502. package/web-ui/build/static/al-C_FHJHny.js +0 -1
  503. package/web-ui/build/static/angelscript-Rz4JX2Rq.js +0 -1
  504. package/web-ui/build/static/antlr4-D4LSk0Ay.js +0 -1
  505. package/web-ui/build/static/apache-BaMp4ZSC.js +0 -1
  506. package/web-ui/build/static/apacheconf-BVq0Zx-9.js +0 -1
  507. package/web-ui/build/static/apex-DdKma-_U.js +0 -1
  508. package/web-ui/build/static/apl-CXIfpQjm.js +0 -1
  509. package/web-ui/build/static/applescript-D92-mz1s.js +0 -1
  510. package/web-ui/build/static/applescript-eHzEb7oT.js +0 -1
  511. package/web-ui/build/static/aql-D_F7mVkg.js +0 -1
  512. package/web-ui/build/static/arcade-DgXn3lOp.js +0 -1
  513. package/web-ui/build/static/arduino-10f7W_Wz.js +0 -1
  514. package/web-ui/build/static/arduino-Bi8wBo3Q.js +0 -1
  515. package/web-ui/build/static/arff-DAZwwp1m.js +0 -1
  516. package/web-ui/build/static/armasm-4k-fm-WI.js +0 -1
  517. package/web-ui/build/static/asciidoc-9iyohD53.js +0 -1
  518. package/web-ui/build/static/asciidoc-BPxaG9gt.js +0 -1
  519. package/web-ui/build/static/asm6502-DlE-NUYG.js +0 -1
  520. package/web-ui/build/static/asmatmel-ykXUz67l.js +0 -1
  521. package/web-ui/build/static/aspectj-BkcGzoIw.js +0 -1
  522. package/web-ui/build/static/aspnet-B8bHvD3e.js +0 -1
  523. package/web-ui/build/static/autohotkey-BXgybckQ.js +0 -1
  524. package/web-ui/build/static/autohotkey-rJX88r3D.js +0 -1
  525. package/web-ui/build/static/autoit-BV42RCy-.js +0 -1
  526. package/web-ui/build/static/autoit-DtcYxn7t.js +0 -1
  527. package/web-ui/build/static/avisynth-B4vyExrv.js +0 -1
  528. package/web-ui/build/static/avrasm-hptGkmwL.js +0 -1
  529. package/web-ui/build/static/avro-idl-D6Eh5Tip.js +0 -1
  530. package/web-ui/build/static/awk-VZHEebeo.js +0 -1
  531. package/web-ui/build/static/axapta-MDY4Ol3-.js +0 -1
  532. package/web-ui/build/static/bash-CEVIQPNU.js +0 -1
  533. package/web-ui/build/static/bash-CQheSBd0.js +0 -1
  534. package/web-ui/build/static/basic-BNAC47vx.js +0 -1
  535. package/web-ui/build/static/basic-o0l9wI82.js +0 -1
  536. package/web-ui/build/static/batch-05P80ryo.js +0 -1
  537. package/web-ui/build/static/bbcode-CvQ1b2hw.js +0 -1
  538. package/web-ui/build/static/bicep-CfAYoZNS.js +0 -1
  539. package/web-ui/build/static/birb-JD-jZNqk.js +0 -1
  540. package/web-ui/build/static/bison-i3sQbLUm.js +0 -1
  541. package/web-ui/build/static/bnf-B5bYoRbA.js +0 -1
  542. package/web-ui/build/static/bnf-D98r2gkN.js +0 -1
  543. package/web-ui/build/static/brainfuck-BU_egZbB.js +0 -1
  544. package/web-ui/build/static/brainfuck-Df0tVgjY.js +0 -1
  545. package/web-ui/build/static/brightscript-DSvCPg0z.js +0 -1
  546. package/web-ui/build/static/bro-BBxgPL7i.js +0 -1
  547. package/web-ui/build/static/bsl-JrkU-4lx.js +0 -1
  548. package/web-ui/build/static/c-BWSIorgH.js +0 -1
  549. package/web-ui/build/static/c-BXBwfPOR.js +0 -1
  550. package/web-ui/build/static/c-like-4jLL6ZeZ.js +0 -1
  551. package/web-ui/build/static/cal-BUukjt45.js +0 -1
  552. package/web-ui/build/static/capnproto-DzfXkblk.js +0 -1
  553. package/web-ui/build/static/ceylon-C6eNUw7A.js +0 -1
  554. package/web-ui/build/static/cfscript-DtzcDoB6.js +0 -1
  555. package/web-ui/build/static/chaiscript-q5NSJZ6c.js +0 -1
  556. package/web-ui/build/static/cil-DXg6HnTF.js +0 -1
  557. package/web-ui/build/static/clean-DhrJyfi0.js +0 -1
  558. package/web-ui/build/static/clojure-DCN-fEKt.js +0 -1
  559. package/web-ui/build/static/clojure-aNTgtXL1.js +0 -1
  560. package/web-ui/build/static/clojure-repl-B_eFHp5m.js +0 -1
  561. package/web-ui/build/static/cmake-BDtm7sss.js +0 -1
  562. package/web-ui/build/static/cmake-Bj_M_zqn.js +0 -1
  563. package/web-ui/build/static/cobol-qo3jUBf5.js +0 -1
  564. package/web-ui/build/static/coffeescript-CIyOUYJ3.js +0 -1
  565. package/web-ui/build/static/coffeescript-CduS6q85.js +0 -1
  566. package/web-ui/build/static/concurnas-DtdAZDrQ.js +0 -1
  567. package/web-ui/build/static/coq-CN6lKK7F.js +0 -1
  568. package/web-ui/build/static/coq-DzGUbX5U.js +0 -1
  569. package/web-ui/build/static/cos-DFcou98i.js +0 -1
  570. package/web-ui/build/static/cpp-Dgg9pFUu.js +0 -1
  571. package/web-ui/build/static/cpp-PRuqGY7D.js +0 -1
  572. package/web-ui/build/static/crmsh-DLLfnotO.js +0 -1
  573. package/web-ui/build/static/crystal-BPylX4xG.js +0 -1
  574. package/web-ui/build/static/crystal-R1dH-Ebf.js +0 -1
  575. package/web-ui/build/static/csharp-CzwY39sl.js +0 -1
  576. package/web-ui/build/static/csharp-DJyymJhf.js +0 -1
  577. package/web-ui/build/static/cshtml-CwtJYmS1.js +0 -1
  578. package/web-ui/build/static/csp-Bj2DpAcY.js +0 -1
  579. package/web-ui/build/static/csp-xY5_PNPj.js +0 -1
  580. package/web-ui/build/static/css-DBGSwd91.js +0 -1
  581. package/web-ui/build/static/css-extras-BvlTqCpv.js +0 -1
  582. package/web-ui/build/static/csv-UTBn-Q9j.js +0 -1
  583. package/web-ui/build/static/cypher-BfzzS1h2.js +0 -1
  584. package/web-ui/build/static/d-BvamtLdb.js +0 -1
  585. package/web-ui/build/static/d-XpxNI5JF.js +0 -1
  586. package/web-ui/build/static/dart-BEM6fjpM.js +0 -1
  587. package/web-ui/build/static/dart-CsMrP4Ax.js +0 -1
  588. package/web-ui/build/static/dataweave-B-vfR-Jf.js +0 -1
  589. package/web-ui/build/static/dax-2WUcEUPn.js +0 -1
  590. package/web-ui/build/static/delphi-7XWS5oTs.js +0 -1
  591. package/web-ui/build/static/dhall-NWRUZH7l.js +0 -1
  592. package/web-ui/build/static/diff-AEgTdaYv.js +0 -1
  593. package/web-ui/build/static/diff-BRgtzr2U.js +0 -1
  594. package/web-ui/build/static/django-4bH3I4pv.js +0 -1
  595. package/web-ui/build/static/django-CrlKM5br.js +0 -1
  596. package/web-ui/build/static/dns-BSqNAZE3.js +0 -1
  597. package/web-ui/build/static/dns-zone-file-Di5cZlps.js +0 -1
  598. package/web-ui/build/static/docker-C9BRbp6h.js +0 -1
  599. package/web-ui/build/static/dockerfile-DbkS5WIL.js +0 -1
  600. package/web-ui/build/static/dos-per3p9hI.js +0 -1
  601. package/web-ui/build/static/dot-DjnTpyv1.js +0 -1
  602. package/web-ui/build/static/dsconfig-BjcpCNTB.js +0 -1
  603. package/web-ui/build/static/dts-DSWuKx2J.js +0 -1
  604. package/web-ui/build/static/dust-BCqihcI2.js +0 -1
  605. package/web-ui/build/static/ebnf-7ErhUPMF.js +0 -1
  606. package/web-ui/build/static/ebnf-CHADdlPD.js +0 -1
  607. package/web-ui/build/static/editorconfig--daZb_D-.js +0 -1
  608. package/web-ui/build/static/eiffel-C5zhT7HO.js +0 -1
  609. package/web-ui/build/static/ejs-ncnPF5oJ.js +0 -1
  610. package/web-ui/build/static/elixir-kFl2IHfo.js +0 -1
  611. package/web-ui/build/static/elixir-m8Rwrydm.js +0 -1
  612. package/web-ui/build/static/elm-CvywOdPd.js +0 -1
  613. package/web-ui/build/static/elm-Dsie_raS.js +0 -1
  614. package/web-ui/build/static/erb-BvkeA6hu.js +0 -1
  615. package/web-ui/build/static/erb-CtAdMBZY.js +0 -1
  616. package/web-ui/build/static/erlang-B1PynliZ.js +0 -1
  617. package/web-ui/build/static/erlang-DO2EN0IW.js +0 -1
  618. package/web-ui/build/static/erlang-repl-DWSpk7kU.js +0 -1
  619. package/web-ui/build/static/etlua-yEBP6vtw.js +0 -1
  620. package/web-ui/build/static/excel-Bhh_OwNT.js +0 -1
  621. package/web-ui/build/static/excel-formula-D8YNVKGY.js +0 -1
  622. package/web-ui/build/static/factor-U8_v_-Qx.js +0 -1
  623. package/web-ui/build/static/false-CbflHcQ4.js +0 -1
  624. package/web-ui/build/static/firestore-security-rules-C9yS7u9K.js +0 -1
  625. package/web-ui/build/static/fix-9oju1yrf.js +0 -1
  626. package/web-ui/build/static/flix-DlGExg75.js +0 -1
  627. package/web-ui/build/static/flow-DKikR-YL.js +0 -1
  628. package/web-ui/build/static/fortran-BTYpE8K2.js +0 -1
  629. package/web-ui/build/static/fortran-BxxaCEOU.js +0 -1
  630. package/web-ui/build/static/fsharp-BSNG-jCK.js +0 -1
  631. package/web-ui/build/static/fsharp-CCg0Y4HA.js +0 -1
  632. package/web-ui/build/static/ftl-DjWJ0y-0.js +0 -1
  633. package/web-ui/build/static/gams-C5fvQ3Od.js +0 -1
  634. package/web-ui/build/static/gap-BvL-biL4.js +0 -1
  635. package/web-ui/build/static/gauss-BzZO8GCS.js +0 -1
  636. package/web-ui/build/static/gcode-Cz8GsjzL.js +0 -1
  637. package/web-ui/build/static/gcode-Dg2JcAQS.js +0 -1
  638. package/web-ui/build/static/gdscript-BOCutEVV.js +0 -1
  639. package/web-ui/build/static/gedcom-Bdq0EwEN.js +0 -1
  640. package/web-ui/build/static/gherkin-Bn1mABAH.js +0 -1
  641. package/web-ui/build/static/gherkin-DpDnmvFb.js +0 -1
  642. package/web-ui/build/static/git-Cd4zgk7f.js +0 -1
  643. package/web-ui/build/static/glsl-BGXyo7Gw.js +0 -1
  644. package/web-ui/build/static/glsl-COPc8ZeZ.js +0 -1
  645. package/web-ui/build/static/gml-BCkIu1Er.js +0 -1
  646. package/web-ui/build/static/gml-COtYpJl2.js +0 -1
  647. package/web-ui/build/static/gn-Bjg1CRig.js +0 -1
  648. package/web-ui/build/static/go-BB6lvTry.js +0 -1
  649. package/web-ui/build/static/go-adzEcqWq.js +0 -1
  650. package/web-ui/build/static/go-module-CfC8Vt2L.js +0 -1
  651. package/web-ui/build/static/golo-C2rGlTHX.js +0 -1
  652. package/web-ui/build/static/gradle-Dh3gdCGU.js +0 -1
  653. package/web-ui/build/static/graphql-w9z3CiM9.js +0 -1
  654. package/web-ui/build/static/groovy-BU2m7Ekt.js +0 -1
  655. package/web-ui/build/static/groovy-Bi8INA80.js +0 -1
  656. package/web-ui/build/static/haml-t0Z0NMdQ.js +0 -1
  657. package/web-ui/build/static/haml-yTEKBHVm.js +0 -1
  658. package/web-ui/build/static/handlebars-BmRED509.js +0 -1
  659. package/web-ui/build/static/handlebars-DmmahO5D.js +0 -1
  660. package/web-ui/build/static/haskell-B4TTwJ5u.js +0 -1
  661. package/web-ui/build/static/haskell-BX4vB3_v.js +0 -1
  662. package/web-ui/build/static/haxe-B81ItqL6.js +0 -1
  663. package/web-ui/build/static/haxe-Z6MewpJj.js +0 -1
  664. package/web-ui/build/static/hcl-CT8vHUwN.js +0 -1
  665. package/web-ui/build/static/hlsl-BNvVW3bY.js +0 -1
  666. package/web-ui/build/static/hoon-07zLMFzn.js +0 -1
  667. package/web-ui/build/static/hpkp-DxK9DKwE.js +0 -1
  668. package/web-ui/build/static/hsp-BFSV4VGN.js +0 -1
  669. package/web-ui/build/static/hsts-Dfi1_v6k.js +0 -1
  670. package/web-ui/build/static/htmlbars-CBGS41Tx.js +0 -1
  671. package/web-ui/build/static/http-Ck2d_NdZ.js +0 -1
  672. package/web-ui/build/static/http-CljalO0f.js +0 -1
  673. package/web-ui/build/static/hy-CWwWerqr.js +0 -1
  674. package/web-ui/build/static/ichigojam-BUq638e8.js +0 -1
  675. package/web-ui/build/static/icon-CkGyT1bh.js +0 -1
  676. package/web-ui/build/static/icu-message-format-BQoqTHNl.js +0 -1
  677. package/web-ui/build/static/idris-nI6aQ55s.js +0 -1
  678. package/web-ui/build/static/iecst-BVwN13uc.js +0 -1
  679. package/web-ui/build/static/ignore-BLfLC9PA.js +0 -1
  680. package/web-ui/build/static/index-BwLo9qDf.js +0 -1
  681. package/web-ui/build/static/index-BwNJoEC1.css +0 -1
  682. package/web-ui/build/static/index-CrzpLgj1.js +0 -13
  683. package/web-ui/build/static/index-DqzIkFBw.js +0 -834
  684. package/web-ui/build/static/inform7-BML_idR2.js +0 -1
  685. package/web-ui/build/static/inform7-xoROt4DC.js +0 -1
  686. package/web-ui/build/static/ini-CCSkzm0H.js +0 -1
  687. package/web-ui/build/static/ini-CYmzo02a.js +0 -1
  688. package/web-ui/build/static/io-DXnvLdgN.js +0 -1
  689. package/web-ui/build/static/irpf90-DxKOk6dw.js +0 -1
  690. package/web-ui/build/static/isbl-0B0tD40P.js +0 -1
  691. package/web-ui/build/static/j-DXpPF6fV.js +0 -1
  692. package/web-ui/build/static/java-D2GSVfv5.js +0 -1
  693. package/web-ui/build/static/java-KuHaGPGv.js +0 -1
  694. package/web-ui/build/static/javadoc-BCT2sPL1.js +0 -1
  695. package/web-ui/build/static/javadoclike-BvnqsHVU.js +0 -1
  696. package/web-ui/build/static/javascript-CiWbQcs7.js +0 -1
  697. package/web-ui/build/static/javastacktrace-eBMVSx2Z.js +0 -1
  698. package/web-ui/build/static/jboss-cli-C01AEskS.js +0 -1
  699. package/web-ui/build/static/jexl-Dn5KxGiK.js +0 -1
  700. package/web-ui/build/static/jolie-D3Zt6_TW.js +0 -1
  701. package/web-ui/build/static/jq-DxOmFCSQ.js +0 -1
  702. package/web-ui/build/static/js-extras-CMUXnpUe.js +0 -1
  703. package/web-ui/build/static/js-templates-BzQwIldl.js +0 -1
  704. package/web-ui/build/static/jsdoc-CkAdh1ug.js +0 -1
  705. package/web-ui/build/static/json-C-B6MwWV.js +0 -1
  706. package/web-ui/build/static/json-C75IrF6s.js +0 -1
  707. package/web-ui/build/static/json5-DvXR6PNV.js +0 -1
  708. package/web-ui/build/static/jsonp-B92u1PFA.js +0 -1
  709. package/web-ui/build/static/jsstacktrace-DJjcSHfr.js +0 -1
  710. package/web-ui/build/static/jsx-C9-rq-CT.js +0 -1
  711. package/web-ui/build/static/julia-DS04VXIz.js +0 -1
  712. package/web-ui/build/static/julia-DrUeWVfq.js +0 -1
  713. package/web-ui/build/static/julia-repl-i80v_zZH.js +0 -1
  714. package/web-ui/build/static/keepalived-BHGEAKGU.js +0 -1
  715. package/web-ui/build/static/keyman-Bdzqqi9H.js +0 -1
  716. package/web-ui/build/static/kotlin-BzHWfKYa.js +0 -1
  717. package/web-ui/build/static/kotlin-C_V1S_FQ.js +0 -1
  718. package/web-ui/build/static/kumir-CotiKPE1.js +0 -1
  719. package/web-ui/build/static/kusto-DRtZ_YAs.js +0 -1
  720. package/web-ui/build/static/lasso-CWuEv8wJ.js +0 -1
  721. package/web-ui/build/static/latex-BQyvVAOm.js +0 -1
  722. package/web-ui/build/static/latex-DMFvqai-.js +0 -1
  723. package/web-ui/build/static/latte-DBzhXpVk.js +0 -1
  724. package/web-ui/build/static/ldif-CHIDpBfE.js +0 -1
  725. package/web-ui/build/static/leaf-BUM990MU.js +0 -1
  726. package/web-ui/build/static/less-Ct98Xd8m.js +0 -1
  727. package/web-ui/build/static/less-cA1L-hw1.js +0 -1
  728. package/web-ui/build/static/lilypond-BxQcVtKe.js +0 -1
  729. package/web-ui/build/static/liquid-BsdpMPYc.js +0 -1
  730. package/web-ui/build/static/lisp-BNcefi1U.js +0 -1
  731. package/web-ui/build/static/lisp-CBeHrUJR.js +0 -1
  732. package/web-ui/build/static/livecodeserver-BRZ6ns7E.js +0 -1
  733. package/web-ui/build/static/livescript-C9VXNDh2.js +0 -1
  734. package/web-ui/build/static/livescript-CPM4TEaS.js +0 -1
  735. package/web-ui/build/static/llvm-D-ktoQ6Z.js +0 -1
  736. package/web-ui/build/static/llvm-aGR2Ei-6.js +0 -1
  737. package/web-ui/build/static/log-BDQPp9ei.js +0 -1
  738. package/web-ui/build/static/lolcode-H3tk4sVp.js +0 -1
  739. package/web-ui/build/static/lsl-E_sO-uEk.js +0 -1
  740. package/web-ui/build/static/lua-CII1BReE.js +0 -1
  741. package/web-ui/build/static/lua-c32KCD1t.js +0 -1
  742. package/web-ui/build/static/magma-BhWArSfW.js +0 -1
  743. package/web-ui/build/static/makefile-BL9Ig9xO.js +0 -1
  744. package/web-ui/build/static/makefile-C_xncXma.js +0 -1
  745. package/web-ui/build/static/markdown-Bjx0QXUF.js +0 -1
  746. package/web-ui/build/static/markdown-DKcNzXLC.js +0 -1
  747. package/web-ui/build/static/markup-templating-DAQlKGf9.js +0 -1
  748. package/web-ui/build/static/mathematica-CvqfUKaF.js +0 -1
  749. package/web-ui/build/static/matlab-BErKso28.js +0 -1
  750. package/web-ui/build/static/matlab-ClFikeke.js +0 -1
  751. package/web-ui/build/static/maxima-Ft3syDPO.js +0 -1
  752. package/web-ui/build/static/maxscript-DT0tXOez.js +0 -1
  753. package/web-ui/build/static/mel-B9RYm_nG.js +0 -1
  754. package/web-ui/build/static/mel-DGpfnKg9.js +0 -1
  755. package/web-ui/build/static/mercury-CXmUlA2y.js +0 -1
  756. package/web-ui/build/static/mermaid-BDmkIkXi.js +0 -1
  757. package/web-ui/build/static/mipsasm-B2G5mL-v.js +0 -1
  758. package/web-ui/build/static/mizar-9hVFfba0.js +0 -1
  759. package/web-ui/build/static/mizar-FYnr9CDP.js +0 -1
  760. package/web-ui/build/static/mojolicious-D3hJYxqh.js +0 -1
  761. package/web-ui/build/static/mongodb-HP0s-riS.js +0 -1
  762. package/web-ui/build/static/monkey-CBt12SEM.js +0 -1
  763. package/web-ui/build/static/monkey-DIqWIXYW.js +0 -1
  764. package/web-ui/build/static/moonscript-B8Z_r4dn.js +0 -1
  765. package/web-ui/build/static/moonscript-CE7UuyXU.js +0 -1
  766. package/web-ui/build/static/n1ql-B16jfOjw.js +0 -1
  767. package/web-ui/build/static/n1ql-BgMWCckC.js +0 -1
  768. package/web-ui/build/static/n4js-CAXy3_Jy.js +0 -1
  769. package/web-ui/build/static/nand2tetris-hdl-C3vzslgj.js +0 -1
  770. package/web-ui/build/static/naniscript-DAFwQQVi.js +0 -1
  771. package/web-ui/build/static/nasm-BOFKVnaS.js +0 -1
  772. package/web-ui/build/static/neon-D0ISL7qJ.js +0 -1
  773. package/web-ui/build/static/nevod-KoDi24v0.js +0 -1
  774. package/web-ui/build/static/nginx-Cr5DfqWR.js +0 -1
  775. package/web-ui/build/static/nginx-DCCnctTG.js +0 -1
  776. package/web-ui/build/static/nim-DPJN-_EC.js +0 -1
  777. package/web-ui/build/static/nim-De05kw0n.js +0 -1
  778. package/web-ui/build/static/nix-CELEwiHo.js +0 -1
  779. package/web-ui/build/static/nix-CSaBChxR.js +0 -1
  780. package/web-ui/build/static/node-repl-C32a7yiw.js +0 -1
  781. package/web-ui/build/static/nsis-CZuaKioB.js +0 -1
  782. package/web-ui/build/static/nsis-VwfBkj3d.js +0 -1
  783. package/web-ui/build/static/objectivec-DJKZtPL2.js +0 -1
  784. package/web-ui/build/static/objectivec-DK2yoaBg.js +0 -1
  785. package/web-ui/build/static/ocaml-Dxx1cjem.js +0 -1
  786. package/web-ui/build/static/ocaml-kjKWdGCz.js +0 -1
  787. package/web-ui/build/static/opencl-BNtKnv1J.js +0 -1
  788. package/web-ui/build/static/openqasm-CdvNeYug.js +0 -1
  789. package/web-ui/build/static/openscad-B_qvsjfe.js +0 -1
  790. package/web-ui/build/static/oxygene-DG1hddn5.js +0 -1
  791. package/web-ui/build/static/oz-CRY87qeP.js +0 -1
  792. package/web-ui/build/static/parigp-BkAr6-G8.js +0 -1
  793. package/web-ui/build/static/parser-CP5clEop.js +0 -1
  794. package/web-ui/build/static/parser3-crTb7A0X.js +0 -1
  795. package/web-ui/build/static/pascal-DPfyfoDh.js +0 -1
  796. package/web-ui/build/static/pascaligo-DURFNQ_j.js +0 -1
  797. package/web-ui/build/static/pcaxis-DD7RAxRP.js +0 -1
  798. package/web-ui/build/static/peoplecode-So_X5jSp.js +0 -1
  799. package/web-ui/build/static/perl-B1DBrLmJ.js +0 -1
  800. package/web-ui/build/static/perl-BFaVXeG7.js +0 -1
  801. package/web-ui/build/static/pf-CEB1L5qm.js +0 -1
  802. package/web-ui/build/static/pgsql-A0nsUgDI.js +0 -1
  803. package/web-ui/build/static/php-8ihB7EPM.js +0 -1
  804. package/web-ui/build/static/php-Sh6D6NIJ.js +0 -1
  805. package/web-ui/build/static/php-extras-Cy_aBZK6.js +0 -1
  806. package/web-ui/build/static/php-template-Cit-PHnf.js +0 -1
  807. package/web-ui/build/static/phpdoc-DNU6hjDm.js +0 -1
  808. package/web-ui/build/static/plaintext-FLJCTahD.js +0 -1
  809. package/web-ui/build/static/plsql-1giFa6G7.js +0 -1
  810. package/web-ui/build/static/pony-BEp1IqY4.js +0 -1
  811. package/web-ui/build/static/powerquery-B43RvEYw.js +0 -1
  812. package/web-ui/build/static/powershell-B0QtH4nv.js +0 -1
  813. package/web-ui/build/static/powershell-BdHnDhS8.js +0 -1
  814. package/web-ui/build/static/processing-Be1Oglu_.js +0 -1
  815. package/web-ui/build/static/processing-CARItQwm.js +0 -1
  816. package/web-ui/build/static/profile-BwlQtk0y.js +0 -1
  817. package/web-ui/build/static/prolog-DKK6jUnc.js +0 -1
  818. package/web-ui/build/static/prolog-b_8huu7c.js +0 -1
  819. package/web-ui/build/static/promql-BZZ7XfbI.js +0 -1
  820. package/web-ui/build/static/properties-BFb1Pf6n.js +0 -1
  821. package/web-ui/build/static/properties-CmsBqXVJ.js +0 -1
  822. package/web-ui/build/static/protobuf-DeLotQpJ.js +0 -1
  823. package/web-ui/build/static/protobuf-WK1D_sJI.js +0 -1
  824. package/web-ui/build/static/psl-MNZR2qmI.js +0 -1
  825. package/web-ui/build/static/pug-CF9nceJD.js +0 -1
  826. package/web-ui/build/static/puppet-CZbKHt9x.js +0 -1
  827. package/web-ui/build/static/puppet-DUMENOgH.js +0 -1
  828. package/web-ui/build/static/pure-37fhgfVL.js +0 -1
  829. package/web-ui/build/static/purebasic-BdORV50m.js +0 -1
  830. package/web-ui/build/static/purebasic-D8axvRJF.js +0 -1
  831. package/web-ui/build/static/purescript-BmZhg2WR.js +0 -1
  832. package/web-ui/build/static/python-CnE0eaJH.js +0 -1
  833. package/web-ui/build/static/python-rT3smsTM.js +0 -1
  834. package/web-ui/build/static/python-repl-oAPThvRZ.js +0 -1
  835. package/web-ui/build/static/q-C9PeNAsV.js +0 -1
  836. package/web-ui/build/static/q-DEhOeRm8.js +0 -1
  837. package/web-ui/build/static/qml-CzmXy0mm.js +0 -1
  838. package/web-ui/build/static/qml-ZLrRDW5F.js +0 -1
  839. package/web-ui/build/static/qore-C4BmNqiC.js +0 -1
  840. package/web-ui/build/static/qsharp-CUspIxRd.js +0 -1
  841. package/web-ui/build/static/r-CmTJdjSW.js +0 -1
  842. package/web-ui/build/static/r-Dul2vX00.js +0 -1
  843. package/web-ui/build/static/racket-DuTLmSg0.js +0 -1
  844. package/web-ui/build/static/reason-CPbzN4QK.js +0 -1
  845. package/web-ui/build/static/reasonml-BX6GGy_7.js +0 -1
  846. package/web-ui/build/static/regex-C-S4lu9H.js +0 -1
  847. package/web-ui/build/static/rego-C552rbmD.js +0 -1
  848. package/web-ui/build/static/renpy-CAXD5ZIz.js +0 -1
  849. package/web-ui/build/static/rest-C0ztj_j5.js +0 -1
  850. package/web-ui/build/static/rib-qZJul5T1.js +0 -1
  851. package/web-ui/build/static/rip-Bi2BsowV.js +0 -1
  852. package/web-ui/build/static/roboconf-BcDqw_pY.js +0 -1
  853. package/web-ui/build/static/roboconf-CEx3VVi1.js +0 -1
  854. package/web-ui/build/static/robotframework-CJVompq9.js +0 -1
  855. package/web-ui/build/static/routeros-BhoPpLPN.js +0 -1
  856. package/web-ui/build/static/rsl-BnetYcE2.js +0 -1
  857. package/web-ui/build/static/ruby-D-6W0bRE.js +0 -1
  858. package/web-ui/build/static/ruby-Dy6NjAXK.js +0 -1
  859. package/web-ui/build/static/ruleslanguage-Bl49mJdL.js +0 -1
  860. package/web-ui/build/static/rust-DxOQY_0w.js +0 -1
  861. package/web-ui/build/static/rust-Dxv6L6Ol.js +0 -1
  862. package/web-ui/build/static/sas-B2aGiUg2.js +0 -1
  863. package/web-ui/build/static/sas-Cbzi-GmN.js +0 -1
  864. package/web-ui/build/static/sass-DwAAr7qH.js +0 -1
  865. package/web-ui/build/static/scala-CNOqwEfe.js +0 -1
  866. package/web-ui/build/static/scala-DxlUiOFp.js +0 -1
  867. package/web-ui/build/static/scheme-B1ALEy7P.js +0 -1
  868. package/web-ui/build/static/scheme-DUNdLa4B.js +0 -1
  869. package/web-ui/build/static/scilab-C6Y0UImx.js +0 -1
  870. package/web-ui/build/static/scss-8m-w5Uh_.js +0 -1
  871. package/web-ui/build/static/scss-C_igD-9N.js +0 -1
  872. package/web-ui/build/static/shell-CTp1MeZM.js +0 -1
  873. package/web-ui/build/static/shell-session-CN3B6Mtp.js +0 -1
  874. package/web-ui/build/static/smali-DMehnCvR.js +0 -1
  875. package/web-ui/build/static/smali-DUPqcHaD.js +0 -1
  876. package/web-ui/build/static/smalltalk-BZWXwh4-.js +0 -1
  877. package/web-ui/build/static/smalltalk-Jd4VA-e4.js +0 -1
  878. package/web-ui/build/static/smarty-2BmLPFNh.js +0 -1
  879. package/web-ui/build/static/sml-BC5HDEBf.js +0 -1
  880. package/web-ui/build/static/sml-BrJo7y64.js +0 -1
  881. package/web-ui/build/static/solidity-muZ3xQn0.js +0 -1
  882. package/web-ui/build/static/solution-file-CF9Xt6f6.js +0 -1
  883. package/web-ui/build/static/soy-DZg8DGEU.js +0 -1
  884. package/web-ui/build/static/sparql-kmkyqBAK.js +0 -1
  885. package/web-ui/build/static/splunk-spl-CmBLwT62.js +0 -1
  886. package/web-ui/build/static/sqf-Ct-q_HqH.js +0 -1
  887. package/web-ui/build/static/sqf-DSuUvyV6.js +0 -1
  888. package/web-ui/build/static/sql-BKhJK7dD.js +0 -1
  889. package/web-ui/build/static/sql-MRpfxEIR.js +0 -1
  890. package/web-ui/build/static/sql_more-By_l7rJw.js +0 -1
  891. package/web-ui/build/static/squirrel-Oyf4apfe.js +0 -1
  892. package/web-ui/build/static/stan-CYPvm7ay.js +0 -1
  893. package/web-ui/build/static/stan-OSfpjfxd.js +0 -1
  894. package/web-ui/build/static/stata-BN_7-HVj.js +0 -1
  895. package/web-ui/build/static/step21-B0MUaGQd.js +0 -1
  896. package/web-ui/build/static/stylus-B2zpewvs.js +0 -1
  897. package/web-ui/build/static/stylus-CiP04Uso.js +0 -1
  898. package/web-ui/build/static/subunit-Ccz6OcJn.js +0 -1
  899. package/web-ui/build/static/swift-DWAzs8_N.js +0 -1
  900. package/web-ui/build/static/swift-ssBR_Hx9.js +0 -1
  901. package/web-ui/build/static/systemd-CT9j1seU.js +0 -1
  902. package/web-ui/build/static/t4-cs-B81S0qkn.js +0 -1
  903. package/web-ui/build/static/t4-templating-CR8sHwkP.js +0 -1
  904. package/web-ui/build/static/t4-vb-AK-9z7xL.js +0 -1
  905. package/web-ui/build/static/taggerscript-BWTFecfl.js +0 -1
  906. package/web-ui/build/static/tap-BuWdU6cR.js +0 -1
  907. package/web-ui/build/static/tap-CvD65fMN.js +0 -1
  908. package/web-ui/build/static/tcl-CWTwAImW.js +0 -1
  909. package/web-ui/build/static/tcl-DxPPqU89.js +0 -1
  910. package/web-ui/build/static/textile-Bb8aIOgT.js +0 -1
  911. package/web-ui/build/static/thrift-BSdmFMYv.js +0 -1
  912. package/web-ui/build/static/toml-CYmQZs0L.js +0 -1
  913. package/web-ui/build/static/tp-Bt1wA2RW.js +0 -1
  914. package/web-ui/build/static/tremor-EDFsRn35.js +0 -1
  915. package/web-ui/build/static/tsx-CRpZ39XI.js +0 -1
  916. package/web-ui/build/static/tt2-C0lRkX9G.js +0 -1
  917. package/web-ui/build/static/turtle-i57e7COQ.js +0 -1
  918. package/web-ui/build/static/twig-DLmpdej0.js +0 -1
  919. package/web-ui/build/static/twig-DwotmZ4d.js +0 -1
  920. package/web-ui/build/static/typescript-C02UFCEu.js +0 -1
  921. package/web-ui/build/static/typescript-Dv4852yn.js +0 -1
  922. package/web-ui/build/static/typoscript-DsiStA8T.js +0 -1
  923. package/web-ui/build/static/unrealscript-DREvLy9b.js +0 -1
  924. package/web-ui/build/static/uorazor-DjjRGSlO.js +0 -1
  925. package/web-ui/build/static/uri-DNx0Ltr1.js +0 -1
  926. package/web-ui/build/static/v-BtcT9t45.js +0 -1
  927. package/web-ui/build/static/vala-CtrGtWLL.js +0 -1
  928. package/web-ui/build/static/vala-DGVJkbdQ.js +0 -1
  929. package/web-ui/build/static/vbnet-9N5EIy45.js +0 -1
  930. package/web-ui/build/static/vbnet-C8V-5wZc.js +0 -1
  931. package/web-ui/build/static/vbscript-C5ZX035F.js +0 -1
  932. package/web-ui/build/static/vbscript-html-Dk-JOSq9.js +0 -1
  933. package/web-ui/build/static/velocity-CMJONQlV.js +0 -1
  934. package/web-ui/build/static/verilog-B448hVUF.js +0 -1
  935. package/web-ui/build/static/verilog-D9rg9wGb.js +0 -1
  936. package/web-ui/build/static/vhdl-B0K99MAb.js +0 -1
  937. package/web-ui/build/static/vhdl-BLJZCy5e.js +0 -1
  938. package/web-ui/build/static/vim-CYLY4wFr.js +0 -1
  939. package/web-ui/build/static/vim-DE6BqLa5.js +0 -1
  940. package/web-ui/build/static/visual-basic-BwcdH-Kn.js +0 -1
  941. package/web-ui/build/static/warpscript-BbfcoHYW.js +0 -1
  942. package/web-ui/build/static/wasm-DHUeRG-u.js +0 -1
  943. package/web-ui/build/static/web-idl-BE2wsaTW.js +0 -1
  944. package/web-ui/build/static/wiki-D-OoB7Gs.js +0 -1
  945. package/web-ui/build/static/wolfram-D-AbA_lC.js +0 -1
  946. package/web-ui/build/static/wren-M0B5FCO6.js +0 -1
  947. package/web-ui/build/static/x86asm-Gg-JtiBh.js +0 -1
  948. package/web-ui/build/static/xeora-BeNNN_-l.js +0 -1
  949. package/web-ui/build/static/xl-C1jOa_4Q.js +0 -1
  950. package/web-ui/build/static/xml-doc-BwW35pek.js +0 -1
  951. package/web-ui/build/static/xml-zQuyG7Gq.js +0 -1
  952. package/web-ui/build/static/xojo-Bf6Y1tsn.js +0 -1
  953. package/web-ui/build/static/xquery-5ZEPqG2y.js +0 -1
  954. package/web-ui/build/static/xquery-OpQT69RV.js +0 -1
  955. package/web-ui/build/static/yaml-CWnr1ERL.js +0 -1
  956. package/web-ui/build/static/yaml-D9QDmLde.js +0 -1
  957. package/web-ui/build/static/yang-DSZmLri0.js +0 -1
  958. package/web-ui/build/static/zephir-C5UVIt-7.js +0 -1
  959. 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 sends a new message
193
- // This provides a "fresh start" after user intervention, preventing false loop detection
194
- if (context.triggeredBy === 'user-message') {
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} due to user message`);
321
+ this.logger.debug(`Hash history cleared for agent ${agentId}`, { triggeredBy: context.triggeredBy });
197
322
 
198
- // Also reset consecutive no-tool counter on user message (fresh interaction)
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
- this.logger.debug(`Consecutive no-tool counter reset for agent ${agentId} due to user message`);
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
- return; // No agents to process
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 = this.agentProcessingLocks.size;
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
- return; // All active agents already being processed
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 whether we actually got a new AI response this cycle
535
- let gotNewAIResponse = false;
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
- gotNewAIResponse = await this.processAgentAutonomously(agentId);
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
- // Process AI response and execute any tools
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 we actually got a new AI response
565
- // This prevents false loop detection when agent is idle
566
- if (gotNewAIResponse) {
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
- return false; // No response - activity service will determine if we should continue
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
- await this.processAIResponse(agentId, aiResponse);
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 true; // We got a new AI response
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: aiResponse.tokenUsage.prompt_tokens || aiResponse.tokenUsage.input_tokens || 0,
2384
- completion_tokens: aiResponse.tokenUsage.completion_tokens || aiResponse.tokenUsage.output_tokens || 0,
2385
- total_tokens: aiResponse.tokenUsage.total_tokens || 0
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 (this.shouldBroadcastMessage(responseMessage)) {
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
- await this.agentPool.persistAgentState(agentId);
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
- // Broadcast the intervention message
3298
- this.webSocketManager.broadcastToSession(sessionId, {
3299
- type: 'message_added',
3300
- data: {
3301
- agentId,
3302
- message: messageToAdd,
3303
- type: 'loop_intervention'
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
- // Also broadcast mode change
3308
- this.webSocketManager.broadcastToSession(sessionId, {
3309
- type: 'agent_mode_changed',
3310
- data: {
3311
- agentId,
3312
- mode: AGENT_MODES.CHAT,
3313
- reason: 'loop_detected',
3314
- timestamp: new Date().toISOString()
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,