onbuzz 4.7.2 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (990) hide show
  1. package/package.json +1 -1
  2. package/scripts/grounding-bench/bench.mjs +300 -0
  3. package/scripts/grounding-bench/cases.js +173 -0
  4. package/scripts/grounding-bench/imageBuilder.js +119 -0
  5. package/src/core/__tests__/agentScheduler.test.js +74 -0
  6. package/src/core/agentScheduler.js +59 -5
  7. package/src/index.js +36 -0
  8. package/src/interfaces/webServer.js +42 -0
  9. package/src/services/__tests__/memoryService.test.js +521 -450
  10. package/src/services/__tests__/modelRouterNaming.test.js +93 -0
  11. package/src/services/__tests__/modelRouterService.test.js +477 -388
  12. package/src/services/aiService.js +136 -1
  13. package/src/services/grounding/GroundingModel.js +116 -0
  14. package/src/services/grounding/KimiAdapter.js +427 -0
  15. package/src/services/grounding/MockAdapter.js +125 -0
  16. package/src/services/grounding/__tests__/KimiAdapter.test.js +475 -0
  17. package/src/services/grounding/__tests__/MockAdapter.test.js +66 -0
  18. package/src/services/grounding/__tests__/groundingMetrics.test.js +156 -0
  19. package/src/services/grounding/__tests__/registry.test.js +122 -0
  20. package/src/services/grounding/constants.js +121 -0
  21. package/src/services/grounding/groundingMetrics.js +121 -0
  22. package/src/services/grounding/index.js +53 -0
  23. package/src/services/grounding/registry.js +125 -0
  24. package/src/services/grounding/types.js +108 -0
  25. package/src/services/memoryService.js +559 -521
  26. package/src/services/modelRouterService.js +433 -364
  27. package/src/services/tokenCountingService.js +2 -2
  28. package/src/tools/__tests__/agentCommunicationTool.test.js +752 -717
  29. package/src/tools/__tests__/baseTool.test.js +22 -0
  30. package/src/tools/__tests__/codeMapTool.test.js +388 -0
  31. package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -0
  32. package/src/tools/__tests__/memoryTool.reminisce.test.js +364 -363
  33. package/src/tools/__tests__/memoryTool.test.js +391 -297
  34. package/src/tools/__tests__/parserHelpers.test.js +233 -0
  35. package/src/tools/__tests__/webTool.e2e.test.js +13 -1
  36. package/src/tools/agentCommunicationTool.js +1399 -1385
  37. package/src/tools/baseTool.js +19 -4
  38. package/src/tools/codeMapTool.js +794 -130
  39. package/src/tools/desktop/DesktopTool.js +638 -0
  40. package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -0
  41. package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -0
  42. package/src/tools/desktop/__tests__/osCapabilities.test.js +106 -0
  43. package/src/tools/desktop/__tests__/osController.test.js +364 -0
  44. package/src/tools/desktop/osCapabilities.js +248 -0
  45. package/src/tools/desktop/osController.js +491 -0
  46. package/src/tools/foundryWebSearchTool.js +273 -0
  47. package/src/tools/memoryTool.js +892 -820
  48. package/src/tools/parserHelpers.js +296 -0
  49. package/src/utilities/__tests__/planInjection.test.js +125 -0
  50. package/src/utilities/__tests__/tagParser.test.js +943 -887
  51. package/src/utilities/constants.js +1 -1
  52. package/src/utilities/planInjection.js +103 -0
  53. package/src/utilities/tagParser.js +918 -896
  54. package/web-ui/build/index.html +2 -2
  55. package/web-ui/build/static/1c-DGpIT7i5.js +1 -0
  56. package/web-ui/build/static/abap-5wFDdWLh.js +1 -0
  57. package/web-ui/build/static/abnf-BP1dpNSE.js +1 -0
  58. package/web-ui/build/static/abnf-DBEIAl8g.js +1 -0
  59. package/web-ui/build/static/accesslog-CWSM_T5E.js +1 -0
  60. package/web-ui/build/static/actionscript-DONkco1J.js +1 -0
  61. package/web-ui/build/static/actionscript-FqBYk5er.js +1 -0
  62. package/web-ui/build/static/ada-C2JLRIaM.js +1 -0
  63. package/web-ui/build/static/ada-gKiygTRK.js +1 -0
  64. package/web-ui/build/static/agda-CkSODqK2.js +1 -0
  65. package/web-ui/build/static/al-BJ_YR6p7.js +1 -0
  66. package/web-ui/build/static/angelscript-Dg2byMGg.js +1 -0
  67. package/web-ui/build/static/antlr4-BnpyaFNr.js +1 -0
  68. package/web-ui/build/static/apache-Dffxsd7O.js +1 -0
  69. package/web-ui/build/static/apacheconf-DLitjtWj.js +1 -0
  70. package/web-ui/build/static/apex-Drr_IvU2.js +1 -0
  71. package/web-ui/build/static/apl-CF6qxmXG.js +1 -0
  72. package/web-ui/build/static/applescript-CjOlw3b_.js +1 -0
  73. package/web-ui/build/static/applescript-DjkSl1Ry.js +1 -0
  74. package/web-ui/build/static/aql-KwVmK1gP.js +1 -0
  75. package/web-ui/build/static/arcade-CENSXx0R.js +1 -0
  76. package/web-ui/build/static/arduino-B3Ta9Fll.js +1 -0
  77. package/web-ui/build/static/arduino-CzcsaB9_.js +1 -0
  78. package/web-ui/build/static/arff-CMJSVt_O.js +1 -0
  79. package/web-ui/build/static/armasm-0zSgSPB4.js +1 -0
  80. package/web-ui/build/static/asciidoc-B8K5ctWq.js +1 -0
  81. package/web-ui/build/static/asciidoc-bk2Sg6b6.js +1 -0
  82. package/web-ui/build/static/asm6502-ji6zm4FQ.js +1 -0
  83. package/web-ui/build/static/asmatmel-DJqObM4Y.js +1 -0
  84. package/web-ui/build/static/aspectj-DqQKI7J5.js +1 -0
  85. package/web-ui/build/static/aspnet-9cenTxW7.js +1 -0
  86. package/web-ui/build/static/autohotkey-C6EhiZvl.js +1 -0
  87. package/web-ui/build/static/autohotkey-sTGJOvMM.js +1 -0
  88. package/web-ui/build/static/autoit-B0Im8iQ1.js +1 -0
  89. package/web-ui/build/static/autoit-CO6pUD0H.js +1 -0
  90. package/web-ui/build/static/avisynth-OvOHTfj5.js +1 -0
  91. package/web-ui/build/static/avrasm-BLWZ5Mye.js +1 -0
  92. package/web-ui/build/static/avro-idl-BB2ODvnw.js +1 -0
  93. package/web-ui/build/static/awk-_jhMabQ0.js +1 -0
  94. package/web-ui/build/static/axapta-DdBRgoYy.js +1 -0
  95. package/web-ui/build/static/bash-CsaRGXBQ.js +1 -0
  96. package/web-ui/build/static/bash-CxLFkwAC.js +1 -0
  97. package/web-ui/build/static/basic-BJyy7JJE.js +1 -0
  98. package/web-ui/build/static/basic-CrMb-gv0.js +1 -0
  99. package/web-ui/build/static/batch-BvcykMe5.js +1 -0
  100. package/web-ui/build/static/bbcode-EOBuY5Y6.js +1 -0
  101. package/web-ui/build/static/bicep-QkDJBA34.js +1 -0
  102. package/web-ui/build/static/birb-TAOxKurn.js +1 -0
  103. package/web-ui/build/static/bison-BEK6cnad.js +1 -0
  104. package/web-ui/build/static/bnf-DfEODxsr.js +1 -0
  105. package/web-ui/build/static/bnf-DhbMjsuA.js +1 -0
  106. package/web-ui/build/static/brainfuck-BoVocOa7.js +1 -0
  107. package/web-ui/build/static/brainfuck-DDC5QXPK.js +1 -0
  108. package/web-ui/build/static/brightscript-DNN598w2.js +1 -0
  109. package/web-ui/build/static/bro-Cn_jjZ8P.js +1 -0
  110. package/web-ui/build/static/bsl-CMCN75Gu.js +1 -0
  111. package/web-ui/build/static/c-DbOGQnEJ.js +1 -0
  112. package/web-ui/build/static/c-kggwYFsy.js +1 -0
  113. package/web-ui/build/static/c-like-BIsuUvof.js +1 -0
  114. package/web-ui/build/static/cal-DpgMsBZE.js +1 -0
  115. package/web-ui/build/static/capnproto-C1AHYI-M.js +1 -0
  116. package/web-ui/build/static/ceylon-pvJffDe1.js +1 -0
  117. package/web-ui/build/static/cfscript-C1qylu52.js +1 -0
  118. package/web-ui/build/static/chaiscript-D417WKRI.js +1 -0
  119. package/web-ui/build/static/cil-CjbZHbcY.js +1 -0
  120. package/web-ui/build/static/clean-Dvc6R-F2.js +1 -0
  121. package/web-ui/build/static/clojure-CSVRQPMQ.js +1 -0
  122. package/web-ui/build/static/clojure-ig1Vkg7X.js +1 -0
  123. package/web-ui/build/static/clojure-repl-C1uyEabk.js +1 -0
  124. package/web-ui/build/static/cmake-DSbVcAB3.js +1 -0
  125. package/web-ui/build/static/cmake-Zp8kPwnH.js +1 -0
  126. package/web-ui/build/static/cobol-OsZSiK_P.js +1 -0
  127. package/web-ui/build/static/coffeescript-D8r0416S.js +1 -0
  128. package/web-ui/build/static/coffeescript-DCpgClxh.js +1 -0
  129. package/web-ui/build/static/concurnas-DKnsxUOc.js +1 -0
  130. package/web-ui/build/static/coq-BQFlywVI.js +1 -0
  131. package/web-ui/build/static/coq-BvS9mQB2.js +1 -0
  132. package/web-ui/build/static/cos-D3ze2791.js +1 -0
  133. package/web-ui/build/static/cpp-Bw-cV3P1.js +1 -0
  134. package/web-ui/build/static/cpp-vi1p7XpB.js +1 -0
  135. package/web-ui/build/static/crmsh-BClnJTeQ.js +1 -0
  136. package/web-ui/build/static/crystal-DGzOUYZq.js +1 -0
  137. package/web-ui/build/static/crystal-DMzk6EvA.js +1 -0
  138. package/web-ui/build/static/csharp-BTom8s2X.js +1 -0
  139. package/web-ui/build/static/csharp-Cp2V3jfR.js +1 -0
  140. package/web-ui/build/static/cshtml-Dmtt9Kto.js +1 -0
  141. package/web-ui/build/static/csp-WPVsLe9_.js +1 -0
  142. package/web-ui/build/static/csp-qddj5fu_.js +1 -0
  143. package/web-ui/build/static/css-B0FAm7kj.js +1 -0
  144. package/web-ui/build/static/css-extras-Bx3pvjiG.js +1 -0
  145. package/web-ui/build/static/csv-CH-edgS5.js +1 -0
  146. package/web-ui/build/static/cypher-c3G8Leew.js +1 -0
  147. package/web-ui/build/static/d-BMDSy22_.js +1 -0
  148. package/web-ui/build/static/d-BdH4oW8-.js +1 -0
  149. package/web-ui/build/static/dart-C-r72q-O.js +1 -0
  150. package/web-ui/build/static/dart-CwpBMrKa.js +1 -0
  151. package/web-ui/build/static/dataweave-BPvqdt4k.js +1 -0
  152. package/web-ui/build/static/dax-Eyy6ixcN.js +1 -0
  153. package/web-ui/build/static/delphi-DhEbPj_5.js +1 -0
  154. package/web-ui/build/static/dhall-Ct1L8sN1.js +1 -0
  155. package/web-ui/build/static/diff-CSTqCgwn.js +1 -0
  156. package/web-ui/build/static/diff-Da97B5vW.js +1 -0
  157. package/web-ui/build/static/django-DGit_lCg.js +1 -0
  158. package/web-ui/build/static/django-DPgqFB8k.js +1 -0
  159. package/web-ui/build/static/dns-DUyXuZ-a.js +1 -0
  160. package/web-ui/build/static/dns-zone-file-D79MDxVG.js +1 -0
  161. package/web-ui/build/static/docker-DTiy4o38.js +1 -0
  162. package/web-ui/build/static/dockerfile-CvwPP8wE.js +1 -0
  163. package/web-ui/build/static/dos-CaIUWxvb.js +1 -0
  164. package/web-ui/build/static/dot-D3504w6Y.js +1 -0
  165. package/web-ui/build/static/dsconfig-Smy1eeX_.js +1 -0
  166. package/web-ui/build/static/dts-DyTYSXZj.js +1 -0
  167. package/web-ui/build/static/dust-CrJyi6qA.js +1 -0
  168. package/web-ui/build/static/ebnf-C8nqfkBH.js +1 -0
  169. package/web-ui/build/static/ebnf-Cuh5Vh2-.js +1 -0
  170. package/web-ui/build/static/editorconfig-C7pTGl6n.js +1 -0
  171. package/web-ui/build/static/eiffel-C75MSJCA.js +1 -0
  172. package/web-ui/build/static/ejs-Dyo7DF5w.js +1 -0
  173. package/web-ui/build/static/elixir-D4yJefOc.js +1 -0
  174. package/web-ui/build/static/elixir-DKRow2SJ.js +1 -0
  175. package/web-ui/build/static/elm-CgbdDlkT.js +1 -0
  176. package/web-ui/build/static/elm-D3N-UgU0.js +1 -0
  177. package/web-ui/build/static/erb-BsITh8qW.js +1 -0
  178. package/web-ui/build/static/erb-lY_LyKyS.js +1 -0
  179. package/web-ui/build/static/erlang-BCnPiYmB.js +1 -0
  180. package/web-ui/build/static/erlang-JEghiPXc.js +1 -0
  181. package/web-ui/build/static/erlang-repl-DzU97ugC.js +1 -0
  182. package/web-ui/build/static/etlua-CsBo8cJa.js +1 -0
  183. package/web-ui/build/static/excel-formula-C2piiCYa.js +1 -0
  184. package/web-ui/build/static/excel-kqNypwQD.js +1 -0
  185. package/web-ui/build/static/factor-DZTOhkyU.js +1 -0
  186. package/web-ui/build/static/false-yLjhfaSw.js +1 -0
  187. package/web-ui/build/static/firestore-security-rules-oaQNoH8l.js +1 -0
  188. package/web-ui/build/static/fix-C9IfnTuS.js +1 -0
  189. package/web-ui/build/static/flix-EmJ_JhPo.js +1 -0
  190. package/web-ui/build/static/flow-DCUl7IAQ.js +1 -0
  191. package/web-ui/build/static/fortran-DvyxJmFN.js +1 -0
  192. package/web-ui/build/static/fortran-EEP9R3S5.js +1 -0
  193. package/web-ui/build/static/fsharp-D_98s3RX.js +1 -0
  194. package/web-ui/build/static/fsharp-Dt9jOO5G.js +1 -0
  195. package/web-ui/build/static/ftl-C8gMHWLo.js +1 -0
  196. package/web-ui/build/static/gams-BHxVPb4z.js +1 -0
  197. package/web-ui/build/static/gap-DFtyHk-q.js +1 -0
  198. package/web-ui/build/static/gauss-BwhJWUcg.js +1 -0
  199. package/web-ui/build/static/gcode-BvmXwp09.js +1 -0
  200. package/web-ui/build/static/gcode-gWcD6Vc7.js +1 -0
  201. package/web-ui/build/static/gdscript-btHoX8RE.js +1 -0
  202. package/web-ui/build/static/gedcom-MgPs9iqh.js +1 -0
  203. package/web-ui/build/static/gherkin-B9c_Q16A.js +1 -0
  204. package/web-ui/build/static/gherkin-BvOgkK6h.js +1 -0
  205. package/web-ui/build/static/git-D9XWOVcQ.js +1 -0
  206. package/web-ui/build/static/glsl-CshBHxHY.js +1 -0
  207. package/web-ui/build/static/glsl-fNRUMTDr.js +1 -0
  208. package/web-ui/build/static/gml-B78deHK8.js +1 -0
  209. package/web-ui/build/static/gml-Cj7d2u8O.js +1 -0
  210. package/web-ui/build/static/gn-CJLD-mF1.js +1 -0
  211. package/web-ui/build/static/go-CT93BEkL.js +1 -0
  212. package/web-ui/build/static/go-CTTlNuQO.js +1 -0
  213. package/web-ui/build/static/go-module-BgnXboUE.js +1 -0
  214. package/web-ui/build/static/golo-2S5tXS-l.js +1 -0
  215. package/web-ui/build/static/gradle-8W8DCcWJ.js +1 -0
  216. package/web-ui/build/static/graphql-DZfp6FNU.js +1 -0
  217. package/web-ui/build/static/groovy-BfsyMb3X.js +1 -0
  218. package/web-ui/build/static/groovy-Dxov7ENz.js +1 -0
  219. package/web-ui/build/static/haml-BlUFsdVV.js +1 -0
  220. package/web-ui/build/static/haml-CjVj6vvW.js +1 -0
  221. package/web-ui/build/static/handlebars-DxrQFkyA.js +1 -0
  222. package/web-ui/build/static/handlebars-FE6fotYl.js +1 -0
  223. package/web-ui/build/static/haskell-B6z0RCD_.js +1 -0
  224. package/web-ui/build/static/haskell-JBFmJTRy.js +1 -0
  225. package/web-ui/build/static/haxe-BtMZMi-_.js +1 -0
  226. package/web-ui/build/static/haxe-C1J8n-fH.js +1 -0
  227. package/web-ui/build/static/hcl-DJP-bFWE.js +1 -0
  228. package/web-ui/build/static/hlsl-DrGjhs1b.js +1 -0
  229. package/web-ui/build/static/hoon-Cg-ZhqIT.js +1 -0
  230. package/web-ui/build/static/hpkp-D07vgmoZ.js +1 -0
  231. package/web-ui/build/static/hsp-CsypPWoA.js +1 -0
  232. package/web-ui/build/static/hsts-B6DMRxvP.js +1 -0
  233. package/web-ui/build/static/htmlbars-BI7_Hw4e.js +1 -0
  234. package/web-ui/build/static/http-90ihEi4s.js +1 -0
  235. package/web-ui/build/static/http-Dp4QXj9E.js +1 -0
  236. package/web-ui/build/static/hy-BMgKvP4K.js +1 -0
  237. package/web-ui/build/static/ichigojam-D6wKvJDb.js +1 -0
  238. package/web-ui/build/static/icon-CrgkmCwl.js +1 -0
  239. package/web-ui/build/static/icu-message-format-Bi2JxCXs.js +1 -0
  240. package/web-ui/build/static/idris-DbUsyZt5.js +1 -0
  241. package/web-ui/build/static/iecst-CQZ9t8fW.js +1 -0
  242. package/web-ui/build/static/ignore-BaFgtNMs.js +1 -0
  243. package/web-ui/build/static/index-DEWSWosh.css +1 -0
  244. package/web-ui/build/static/index-Di1bjCFA.js +13 -0
  245. package/web-ui/build/static/index-otR_WSsL.js +1 -0
  246. package/web-ui/build/static/index-whZPU4as.js +1183 -0
  247. package/web-ui/build/static/inform7-ClyX1Gro.js +1 -0
  248. package/web-ui/build/static/inform7-tZHBS5XP.js +1 -0
  249. package/web-ui/build/static/ini-BrP5JNYL.js +1 -0
  250. package/web-ui/build/static/ini-CVkrAhwV.js +1 -0
  251. package/web-ui/build/static/io-BJ1Y6Bdc.js +1 -0
  252. package/web-ui/build/static/irpf90-fjjcKS_8.js +1 -0
  253. package/web-ui/build/static/isbl-ClpvfUIz.js +1 -0
  254. package/web-ui/build/static/j-CICW77xS.js +1 -0
  255. package/web-ui/build/static/java-B9DFK-0E.js +1 -0
  256. package/web-ui/build/static/java-BL_6rYko.js +1 -0
  257. package/web-ui/build/static/javadoc-Cc4HKpKK.js +1 -0
  258. package/web-ui/build/static/javadoclike-CgNkUDOm.js +1 -0
  259. package/web-ui/build/static/javascript-CM40ZECq.js +1 -0
  260. package/web-ui/build/static/javastacktrace-BHSqXfG5.js +1 -0
  261. package/web-ui/build/static/jboss-cli-Bv5NhVSZ.js +1 -0
  262. package/web-ui/build/static/jexl--Ohk_keA.js +1 -0
  263. package/web-ui/build/static/jolie-DMTN5Vdf.js +1 -0
  264. package/web-ui/build/static/jq-nXRLldXX.js +1 -0
  265. package/web-ui/build/static/js-extras-eLwv3frs.js +1 -0
  266. package/web-ui/build/static/js-templates-Ca0owlrg.js +1 -0
  267. package/web-ui/build/static/jsdoc-KERXp0da.js +1 -0
  268. package/web-ui/build/static/json-BTjLaRsy.js +1 -0
  269. package/web-ui/build/static/json-p7pU0qdW.js +1 -0
  270. package/web-ui/build/static/json5-Cxjy1udc.js +1 -0
  271. package/web-ui/build/static/jsonp-CO52H7Gy.js +1 -0
  272. package/web-ui/build/static/jsstacktrace-8YKfoyJP.js +1 -0
  273. package/web-ui/build/static/jsx-Ct_05KbM.js +1 -0
  274. package/web-ui/build/static/julia-23I1ubCE.js +1 -0
  275. package/web-ui/build/static/julia-d8rVGed_.js +1 -0
  276. package/web-ui/build/static/julia-repl-mwnHedW_.js +1 -0
  277. package/web-ui/build/static/keepalived-E85Rx_fF.js +1 -0
  278. package/web-ui/build/static/keyman-aWd3QUDq.js +1 -0
  279. package/web-ui/build/static/kotlin-Cu370hQq.js +1 -0
  280. package/web-ui/build/static/kotlin-DoJ2WnmZ.js +1 -0
  281. package/web-ui/build/static/kumir-oiOgqcQO.js +1 -0
  282. package/web-ui/build/static/kusto-Bp-B02K5.js +1 -0
  283. package/web-ui/build/static/lasso-BxoQVwOO.js +1 -0
  284. package/web-ui/build/static/latex-CANm5vsX.js +1 -0
  285. package/web-ui/build/static/latex-PMroeNch.js +1 -0
  286. package/web-ui/build/static/latte-2ErU_2XF.js +1 -0
  287. package/web-ui/build/static/ldif-ChPn_F7o.js +1 -0
  288. package/web-ui/build/static/leaf-UkCugDgG.js +1 -0
  289. package/web-ui/build/static/less-CCH5RA89.js +1 -0
  290. package/web-ui/build/static/less-CGZbVU1g.js +1 -0
  291. package/web-ui/build/static/lilypond-BoyM37sv.js +1 -0
  292. package/web-ui/build/static/liquid-DGJVpRBi.js +1 -0
  293. package/web-ui/build/static/lisp-93nne61u.js +1 -0
  294. package/web-ui/build/static/lisp-DYjIRsXz.js +1 -0
  295. package/web-ui/build/static/livecodeserver-CfNaxIE4.js +1 -0
  296. package/web-ui/build/static/livescript-C8kDlQkz.js +1 -0
  297. package/web-ui/build/static/livescript-CoarnRHq.js +1 -0
  298. package/web-ui/build/static/llvm-CBVyNmAh.js +1 -0
  299. package/web-ui/build/static/llvm-DGxq8a7u.js +1 -0
  300. package/web-ui/build/static/log-BivgwFql.js +1 -0
  301. package/web-ui/build/static/lolcode-l5sK2cZz.js +1 -0
  302. package/web-ui/build/static/lsl-Xm44xLRQ.js +1 -0
  303. package/web-ui/build/static/lua-CGvrzfKp.js +1 -0
  304. package/web-ui/build/static/lua-nHwXeY4c.js +1 -0
  305. package/web-ui/build/static/magma-DmNItmna.js +1 -0
  306. package/web-ui/build/static/makefile-CKJNNHGb.js +1 -0
  307. package/web-ui/build/static/makefile-DI6y5Qml.js +1 -0
  308. package/web-ui/build/static/markdown-BgpbxKd-.js +1 -0
  309. package/web-ui/build/static/markdown-CvcxA4yk.js +1 -0
  310. package/web-ui/build/static/markup-templating-DijqesiA.js +1 -0
  311. package/web-ui/build/static/mathematica-Cxll1Q10.js +1 -0
  312. package/web-ui/build/static/matlab-BJo2T1A-.js +1 -0
  313. package/web-ui/build/static/matlab-C6DlZX4l.js +1 -0
  314. package/web-ui/build/static/maxima-DJXO4sbL.js +1 -0
  315. package/web-ui/build/static/maxscript-DdLpUYBs.js +1 -0
  316. package/web-ui/build/static/mel-BIpfnSyZ.js +1 -0
  317. package/web-ui/build/static/mel-BYcTUZJW.js +1 -0
  318. package/web-ui/build/static/mercury-C_LSpbD8.js +1 -0
  319. package/web-ui/build/static/mermaid-D9yBWnrT.js +1 -0
  320. package/web-ui/build/static/mipsasm-nR_K2Ue-.js +1 -0
  321. package/web-ui/build/static/mizar-BeLUPncD.js +1 -0
  322. package/web-ui/build/static/mizar-BesIbZd9.js +1 -0
  323. package/web-ui/build/static/mojolicious-cBx3OWa-.js +1 -0
  324. package/web-ui/build/static/mongodb-DTWKy9ac.js +1 -0
  325. package/web-ui/build/static/monkey-B72bZC3c.js +1 -0
  326. package/web-ui/build/static/monkey-G9XELYPQ.js +1 -0
  327. package/web-ui/build/static/moonscript-BXYVQiqj.js +1 -0
  328. package/web-ui/build/static/moonscript-sDd-5knz.js +1 -0
  329. package/web-ui/build/static/n1ql-0vKSfFAO.js +1 -0
  330. package/web-ui/build/static/n1ql-C9_BSZfz.js +1 -0
  331. package/web-ui/build/static/n4js-B7Ct8dds.js +1 -0
  332. package/web-ui/build/static/nand2tetris-hdl-p9gpphTM.js +1 -0
  333. package/web-ui/build/static/naniscript-6ZVr8Aug.js +1 -0
  334. package/web-ui/build/static/nasm-Ca73yTUt.js +1 -0
  335. package/web-ui/build/static/neon-DNP49oyX.js +1 -0
  336. package/web-ui/build/static/nevod-Qhgt7Bce.js +1 -0
  337. package/web-ui/build/static/nginx-D5e7lu62.js +1 -0
  338. package/web-ui/build/static/nginx-DobnyESB.js +1 -0
  339. package/web-ui/build/static/nim-BPBivUOV.js +1 -0
  340. package/web-ui/build/static/nim-Baoug1Wa.js +1 -0
  341. package/web-ui/build/static/nix-CSPTQs5y.js +1 -0
  342. package/web-ui/build/static/nix-Dk4eNw49.js +1 -0
  343. package/web-ui/build/static/node-repl-NJNL8VFR.js +1 -0
  344. package/web-ui/build/static/nsis-BZ0oMzEw.js +1 -0
  345. package/web-ui/build/static/nsis-CKPCjtCU.js +1 -0
  346. package/web-ui/build/static/objectivec-BkfIRhhV.js +1 -0
  347. package/web-ui/build/static/objectivec-CnQgqhbJ.js +1 -0
  348. package/web-ui/build/static/ocaml-9rGNzRrK.js +1 -0
  349. package/web-ui/build/static/ocaml-CTolCqxL.js +1 -0
  350. package/web-ui/build/static/opencl-9Q3vRDxv.js +1 -0
  351. package/web-ui/build/static/openqasm-D2QiuFBp.js +1 -0
  352. package/web-ui/build/static/openscad-C3HyuzpB.js +1 -0
  353. package/web-ui/build/static/oxygene-4gi-VYy_.js +1 -0
  354. package/web-ui/build/static/oz-BGDEB-1A.js +1 -0
  355. package/web-ui/build/static/parigp-CfZzp1uE.js +1 -0
  356. package/web-ui/build/static/parser-UbGteTcy.js +1 -0
  357. package/web-ui/build/static/parser3-C-Jx-fy7.js +1 -0
  358. package/web-ui/build/static/pascal-D1_R0gW-.js +1 -0
  359. package/web-ui/build/static/pascaligo-B8C-98Np.js +1 -0
  360. package/web-ui/build/static/pcaxis-TGnlUKNs.js +1 -0
  361. package/web-ui/build/static/peoplecode-C5Vf1AH0.js +1 -0
  362. package/web-ui/build/static/perl-CBp1N62T.js +1 -0
  363. package/web-ui/build/static/perl-Z59j904t.js +1 -0
  364. package/web-ui/build/static/pf-Cq8B_xwQ.js +1 -0
  365. package/web-ui/build/static/pgsql-ofJbUHkL.js +1 -0
  366. package/web-ui/build/static/php-OlH7HLQJ.js +1 -0
  367. package/web-ui/build/static/php-extras-GqtrxLuk.js +1 -0
  368. package/web-ui/build/static/php-r09kMDOB.js +1 -0
  369. package/web-ui/build/static/php-template-18uT97Qo.js +1 -0
  370. package/web-ui/build/static/phpdoc-9tRFvup9.js +1 -0
  371. package/web-ui/build/static/plaintext-DsYT6Mu-.js +1 -0
  372. package/web-ui/build/static/plsql-RhWQNJVb.js +1 -0
  373. package/web-ui/build/static/pony-DD6JMLYI.js +1 -0
  374. package/web-ui/build/static/powerquery-CALow-bt.js +1 -0
  375. package/web-ui/build/static/powershell-C2QvIuKF.js +1 -0
  376. package/web-ui/build/static/powershell-yrbJEhCh.js +1 -0
  377. package/web-ui/build/static/processing-1T5w_Q03.js +1 -0
  378. package/web-ui/build/static/processing-DBim_dO-.js +1 -0
  379. package/web-ui/build/static/profile-Cdloh8mZ.js +1 -0
  380. package/web-ui/build/static/prolog-DRSsNnns.js +1 -0
  381. package/web-ui/build/static/prolog-D_ajweDr.js +1 -0
  382. package/web-ui/build/static/promql-BRuwn6Bn.js +1 -0
  383. package/web-ui/build/static/properties-D5Wyl4X4.js +1 -0
  384. package/web-ui/build/static/properties-kn4fl1bl.js +1 -0
  385. package/web-ui/build/static/protobuf-BMO76zWi.js +1 -0
  386. package/web-ui/build/static/protobuf-CTUCF-U-.js +1 -0
  387. package/web-ui/build/static/psl-CiqYdQbY.js +1 -0
  388. package/web-ui/build/static/pug-BLE2Qayj.js +1 -0
  389. package/web-ui/build/static/puppet-CFKLWXft.js +1 -0
  390. package/web-ui/build/static/puppet-DQci0Dl5.js +1 -0
  391. package/web-ui/build/static/pure-D2h_GynV.js +1 -0
  392. package/web-ui/build/static/purebasic-BF8MVw8V.js +1 -0
  393. package/web-ui/build/static/purebasic-BTtHiCkh.js +1 -0
  394. package/web-ui/build/static/purescript-D1ZSh-sH.js +1 -0
  395. package/web-ui/build/static/python-Cp9_Vdhb.js +1 -0
  396. package/web-ui/build/static/python-DdgNw8IW.js +1 -0
  397. package/web-ui/build/static/python-repl-DvK89VMC.js +1 -0
  398. package/web-ui/build/static/q-COaIgwhT.js +1 -0
  399. package/web-ui/build/static/q-Cm0dQkW8.js +1 -0
  400. package/web-ui/build/static/qml-BpsOqqJM.js +1 -0
  401. package/web-ui/build/static/qml-BziQXlU4.js +1 -0
  402. package/web-ui/build/static/qore-Cutz6g-2.js +1 -0
  403. package/web-ui/build/static/qsharp-B16619X1.js +1 -0
  404. package/web-ui/build/static/r-CFUIj5Hd.js +1 -0
  405. package/web-ui/build/static/r-CPrwCi5w.js +1 -0
  406. package/web-ui/build/static/racket-Bh08DFXF.js +1 -0
  407. package/web-ui/build/static/reason-BxjDq4e-.js +1 -0
  408. package/web-ui/build/static/reasonml-Ds5SsGP8.js +1 -0
  409. package/web-ui/build/static/regex-DhBIDIMI.js +1 -0
  410. package/web-ui/build/static/rego-DCwxZXcB.js +1 -0
  411. package/web-ui/build/static/renpy-C2fuQfqb.js +1 -0
  412. package/web-ui/build/static/rest-C52ZpxWQ.js +1 -0
  413. package/web-ui/build/static/rib-Cbl2Mzyj.js +1 -0
  414. package/web-ui/build/static/rip-BTOu5ZIE.js +1 -0
  415. package/web-ui/build/static/roboconf-3Oi2wuVk.js +1 -0
  416. package/web-ui/build/static/roboconf-ndLZLE39.js +1 -0
  417. package/web-ui/build/static/robotframework-BzHXiIj1.js +1 -0
  418. package/web-ui/build/static/routeros-CkpPoqx-.js +1 -0
  419. package/web-ui/build/static/rsl-C0bwOQ38.js +1 -0
  420. package/web-ui/build/static/ruby-C_hIhtuQ.js +1 -0
  421. package/web-ui/build/static/ruby-DvKfZPzj.js +1 -0
  422. package/web-ui/build/static/ruleslanguage-CbZJlddz.js +1 -0
  423. package/web-ui/build/static/rust-BFPIhB-X.js +1 -0
  424. package/web-ui/build/static/rust-sBpUq-qE.js +1 -0
  425. package/web-ui/build/static/sas-BCXvYN9x.js +1 -0
  426. package/web-ui/build/static/sas-D7GAsTY3.js +1 -0
  427. package/web-ui/build/static/sass-BdaErGMN.js +1 -0
  428. package/web-ui/build/static/scala-Cj81oCl9.js +1 -0
  429. package/web-ui/build/static/scala-CvbksfY6.js +1 -0
  430. package/web-ui/build/static/scheme-BM5ZqKnl.js +1 -0
  431. package/web-ui/build/static/scheme-BPvlu9Tk.js +1 -0
  432. package/web-ui/build/static/scilab-CJanLKQN.js +1 -0
  433. package/web-ui/build/static/scss-C53YF_7f.js +1 -0
  434. package/web-ui/build/static/scss-DPp8UZbr.js +1 -0
  435. package/web-ui/build/static/shell-CC9bQXMe.js +1 -0
  436. package/web-ui/build/static/shell-session-CuR3fbf-.js +1 -0
  437. package/web-ui/build/static/smali-CUgLls3D.js +1 -0
  438. package/web-ui/build/static/smali-YODSX8qt.js +1 -0
  439. package/web-ui/build/static/smalltalk-BMJQ4bbs.js +1 -0
  440. package/web-ui/build/static/smalltalk-BVGY3CTl.js +1 -0
  441. package/web-ui/build/static/smarty-C9aNt4-p.js +1 -0
  442. package/web-ui/build/static/sml-C3BIHhfq.js +1 -0
  443. package/web-ui/build/static/sml-DTipyRmY.js +1 -0
  444. package/web-ui/build/static/solidity-1yuPUqoC.js +1 -0
  445. package/web-ui/build/static/solution-file-BgzK4GOU.js +1 -0
  446. package/web-ui/build/static/soy-CFJXRvqc.js +1 -0
  447. package/web-ui/build/static/sparql-CAosYMpl.js +1 -0
  448. package/web-ui/build/static/splunk-spl-DkINtWr8.js +1 -0
  449. package/web-ui/build/static/sqf-DbrWIS2M.js +1 -0
  450. package/web-ui/build/static/sqf-nq8Q9J2W.js +1 -0
  451. package/web-ui/build/static/sql-9bwClhZQ.js +1 -0
  452. package/web-ui/build/static/sql-CqPkY-lX.js +1 -0
  453. package/web-ui/build/static/sql_more-CsY5ts77.js +1 -0
  454. package/web-ui/build/static/squirrel-BuqtzRBD.js +1 -0
  455. package/web-ui/build/static/stan-BNxBSglc.js +1 -0
  456. package/web-ui/build/static/stan-CZVMc34l.js +1 -0
  457. package/web-ui/build/static/stata-DKnVdHCd.js +1 -0
  458. package/web-ui/build/static/step21-Cu_TaBGF.js +1 -0
  459. package/web-ui/build/static/stylus-BS7-OJew.js +1 -0
  460. package/web-ui/build/static/stylus-DtFrp1Nk.js +1 -0
  461. package/web-ui/build/static/subunit-DDCoWkkc.js +1 -0
  462. package/web-ui/build/static/swift-BaguUZbl.js +1 -0
  463. package/web-ui/build/static/swift-mwBsb8Bx.js +1 -0
  464. package/web-ui/build/static/systemd-D6PpyDKk.js +1 -0
  465. package/web-ui/build/static/t4-cs-Cem8g4Ck.js +1 -0
  466. package/web-ui/build/static/t4-templating-BZo-HjmD.js +1 -0
  467. package/web-ui/build/static/t4-vb-B4oVnKa4.js +1 -0
  468. package/web-ui/build/static/taggerscript-DweAZ5pw.js +1 -0
  469. package/web-ui/build/static/tap-DpuvKHHF.js +1 -0
  470. package/web-ui/build/static/tap-hUKmJObZ.js +1 -0
  471. package/web-ui/build/static/tcl-BUvhAi7u.js +1 -0
  472. package/web-ui/build/static/tcl-Dsck63d8.js +1 -0
  473. package/web-ui/build/static/textile-CgKbqJ-j.js +1 -0
  474. package/web-ui/build/static/thrift-B5H6rApp.js +1 -0
  475. package/web-ui/build/static/toml-DggTpfOo.js +1 -0
  476. package/web-ui/build/static/tp-CazB2P2X.js +1 -0
  477. package/web-ui/build/static/tremor-B1jy7S5p.js +1 -0
  478. package/web-ui/build/static/tsx-BqF2lVDi.js +1 -0
  479. package/web-ui/build/static/tt2-BNoNXpEe.js +1 -0
  480. package/web-ui/build/static/turtle-B0evd5mn.js +1 -0
  481. package/web-ui/build/static/twig-B5A7nMdv.js +1 -0
  482. package/web-ui/build/static/twig-DZnLWvh8.js +1 -0
  483. package/web-ui/build/static/typescript-Bbe_P093.js +1 -0
  484. package/web-ui/build/static/typescript-BfhvmSSG.js +1 -0
  485. package/web-ui/build/static/typoscript-BjuZEIgw.js +1 -0
  486. package/web-ui/build/static/unrealscript-C3iUCFRi.js +1 -0
  487. package/web-ui/build/static/uorazor-CbZXwzIj.js +1 -0
  488. package/web-ui/build/static/uri-xMPSnp6m.js +1 -0
  489. package/web-ui/build/static/v-BKcGo5I6.js +1 -0
  490. package/web-ui/build/static/vala-BRoBE4am.js +1 -0
  491. package/web-ui/build/static/vala-B__Iyrma.js +1 -0
  492. package/web-ui/build/static/vbnet-DBxlMRvN.js +1 -0
  493. package/web-ui/build/static/vbnet-DjAXt5BE.js +1 -0
  494. package/web-ui/build/static/vbscript-BNA4oANi.js +1 -0
  495. package/web-ui/build/static/vbscript-html-o8ckLPKG.js +1 -0
  496. package/web-ui/build/static/velocity-D7sc5ggA.js +1 -0
  497. package/web-ui/build/static/verilog-BWJfMIng.js +1 -0
  498. package/web-ui/build/static/verilog-jW2GPC--.js +1 -0
  499. package/web-ui/build/static/vhdl-BIVlXRPa.js +1 -0
  500. package/web-ui/build/static/vhdl-BeqdhhxD.js +1 -0
  501. package/web-ui/build/static/vim-712lI4-g.js +1 -0
  502. package/web-ui/build/static/vim-DMROTzr0.js +1 -0
  503. package/web-ui/build/static/visual-basic-CQfbM-ta.js +1 -0
  504. package/web-ui/build/static/warpscript-DFAvCXFQ.js +1 -0
  505. package/web-ui/build/static/wasm-CiYoxBl0.js +1 -0
  506. package/web-ui/build/static/web-idl-DoCkPK8y.js +1 -0
  507. package/web-ui/build/static/wiki-bvz0AGzB.js +1 -0
  508. package/web-ui/build/static/wolfram-fBuyFEgU.js +1 -0
  509. package/web-ui/build/static/wren-DvATFxjF.js +1 -0
  510. package/web-ui/build/static/x86asm-r4bPbUR_.js +1 -0
  511. package/web-ui/build/static/xeora-B6iOnDJY.js +1 -0
  512. package/web-ui/build/static/xl-Ce6B5slc.js +1 -0
  513. package/web-ui/build/static/xml-DNjyPmhQ.js +1 -0
  514. package/web-ui/build/static/xml-doc-DydogmZD.js +1 -0
  515. package/web-ui/build/static/xojo-DCQLltvr.js +1 -0
  516. package/web-ui/build/static/xquery-C-fAnA0H.js +1 -0
  517. package/web-ui/build/static/xquery-CNeqzhLO.js +1 -0
  518. package/web-ui/build/static/yaml-BsVaGsk5.js +1 -0
  519. package/web-ui/build/static/yaml-kVZvwv_C.js +1 -0
  520. package/web-ui/build/static/yang-B_gq9JEq.js +1 -0
  521. package/web-ui/build/static/zephir-ECIXgXhX.js +1 -0
  522. package/web-ui/build/static/zig-DY325EKG.js +1 -0
  523. package/web-ui/build/static/1c-BLo2-5GS.js +0 -1
  524. package/web-ui/build/static/abap-BjUneMMr.js +0 -1
  525. package/web-ui/build/static/abnf-CZTz-l7P.js +0 -1
  526. package/web-ui/build/static/abnf-ITJ5mkBo.js +0 -1
  527. package/web-ui/build/static/accesslog-Dj78lZOU.js +0 -1
  528. package/web-ui/build/static/actionscript-Chivtu59.js +0 -1
  529. package/web-ui/build/static/actionscript-CrvMFXnx.js +0 -1
  530. package/web-ui/build/static/ada-DdJtyoYe.js +0 -1
  531. package/web-ui/build/static/ada-GIvogaLi.js +0 -1
  532. package/web-ui/build/static/agda-DbPp4fQi.js +0 -1
  533. package/web-ui/build/static/al-BZ24KwRS.js +0 -1
  534. package/web-ui/build/static/angelscript-DzsFypYt.js +0 -1
  535. package/web-ui/build/static/antlr4-3qb4rD3S.js +0 -1
  536. package/web-ui/build/static/apache-DF0P5ZRm.js +0 -1
  537. package/web-ui/build/static/apacheconf-C8KuNf9c.js +0 -1
  538. package/web-ui/build/static/apex-CPV-DeVE.js +0 -1
  539. package/web-ui/build/static/apl-C60bVxxW.js +0 -1
  540. package/web-ui/build/static/applescript-uz0i0tu1.js +0 -1
  541. package/web-ui/build/static/applescript-xcPRUBia.js +0 -1
  542. package/web-ui/build/static/aql-CRh4IGkA.js +0 -1
  543. package/web-ui/build/static/arcade-CmLedeqc.js +0 -1
  544. package/web-ui/build/static/arduino-3pr1BvXB.js +0 -1
  545. package/web-ui/build/static/arduino-C2BejAip.js +0 -1
  546. package/web-ui/build/static/arff-DE6Wr9MU.js +0 -1
  547. package/web-ui/build/static/armasm-DXodTfP4.js +0 -1
  548. package/web-ui/build/static/asciidoc-BU2BDFme.js +0 -1
  549. package/web-ui/build/static/asciidoc-CgvtvdeC.js +0 -1
  550. package/web-ui/build/static/asm6502-BMuYCKmP.js +0 -1
  551. package/web-ui/build/static/asmatmel-Dwxzg4kq.js +0 -1
  552. package/web-ui/build/static/aspectj-XZIldIRI.js +0 -1
  553. package/web-ui/build/static/aspnet-UxY2bZ9O.js +0 -1
  554. package/web-ui/build/static/autohotkey-BdZoQT7s.js +0 -1
  555. package/web-ui/build/static/autohotkey-DLWs6p8o.js +0 -1
  556. package/web-ui/build/static/autoit-CxcZx_kh.js +0 -1
  557. package/web-ui/build/static/autoit-HY_BHh1p.js +0 -1
  558. package/web-ui/build/static/avisynth-4Q4be9zq.js +0 -1
  559. package/web-ui/build/static/avrasm-CFqVJML2.js +0 -1
  560. package/web-ui/build/static/avro-idl-DVTV2YZm.js +0 -1
  561. package/web-ui/build/static/awk-C1Udi4As.js +0 -1
  562. package/web-ui/build/static/axapta-B9lexIDC.js +0 -1
  563. package/web-ui/build/static/bash-DDZrx0R1.js +0 -1
  564. package/web-ui/build/static/bash-Uuijyc_K.js +0 -1
  565. package/web-ui/build/static/basic-B29QFWwp.js +0 -1
  566. package/web-ui/build/static/basic-DKDOc42O.js +0 -1
  567. package/web-ui/build/static/batch-CA3q9wRr.js +0 -1
  568. package/web-ui/build/static/bbcode-DkUDcqrp.js +0 -1
  569. package/web-ui/build/static/bicep-AHSQiVgQ.js +0 -1
  570. package/web-ui/build/static/birb-BsAnN1j3.js +0 -1
  571. package/web-ui/build/static/bison-BIq5-ZXo.js +0 -1
  572. package/web-ui/build/static/bnf-BexLm6hz.js +0 -1
  573. package/web-ui/build/static/bnf-Dm46EM5S.js +0 -1
  574. package/web-ui/build/static/brainfuck-CBG8MHhD.js +0 -1
  575. package/web-ui/build/static/brainfuck-DrHuUFVv.js +0 -1
  576. package/web-ui/build/static/brightscript-CoQ7s_l3.js +0 -1
  577. package/web-ui/build/static/bro-Cz5RmvoK.js +0 -1
  578. package/web-ui/build/static/bsl-C9wXomkX.js +0 -1
  579. package/web-ui/build/static/c-BZFEFWwC.js +0 -1
  580. package/web-ui/build/static/c-CfFWLEL7.js +0 -1
  581. package/web-ui/build/static/c-like-CvIii1QP.js +0 -1
  582. package/web-ui/build/static/cal-be-Dz3GC.js +0 -1
  583. package/web-ui/build/static/capnproto-Bcaxak1e.js +0 -1
  584. package/web-ui/build/static/ceylon-QH_iQXnW.js +0 -1
  585. package/web-ui/build/static/cfscript-BRgBlxCO.js +0 -1
  586. package/web-ui/build/static/chaiscript-DSBx5kyN.js +0 -1
  587. package/web-ui/build/static/cil-C90LIbge.js +0 -1
  588. package/web-ui/build/static/clean-D2X3fSKw.js +0 -1
  589. package/web-ui/build/static/clojure-CvKE0e-3.js +0 -1
  590. package/web-ui/build/static/clojure-Cy3Zg4vZ.js +0 -1
  591. package/web-ui/build/static/clojure-repl-D0kONHv2.js +0 -1
  592. package/web-ui/build/static/cmake-DIDVe3n_.js +0 -1
  593. package/web-ui/build/static/cmake-DPijEs9c.js +0 -1
  594. package/web-ui/build/static/cobol-BPEjLjGY.js +0 -1
  595. package/web-ui/build/static/coffeescript-CoSx9MQU.js +0 -1
  596. package/web-ui/build/static/coffeescript-L5CBXrnP.js +0 -1
  597. package/web-ui/build/static/concurnas-q5sXhVU4.js +0 -1
  598. package/web-ui/build/static/coq-BAEq82zI.js +0 -1
  599. package/web-ui/build/static/coq-BBgtQZwi.js +0 -1
  600. package/web-ui/build/static/cos-9FdwfBC5.js +0 -1
  601. package/web-ui/build/static/cpp-CYt8UYn2.js +0 -1
  602. package/web-ui/build/static/cpp-CZ2lOXlm.js +0 -1
  603. package/web-ui/build/static/crmsh-C_TZWkES.js +0 -1
  604. package/web-ui/build/static/crystal-BDf_0NDz.js +0 -1
  605. package/web-ui/build/static/crystal-BrTR9dGT.js +0 -1
  606. package/web-ui/build/static/csharp-BSBrba50.js +0 -1
  607. package/web-ui/build/static/csharp-Cerqyqbn.js +0 -1
  608. package/web-ui/build/static/cshtml-heNA_ya5.js +0 -1
  609. package/web-ui/build/static/csp-CJprtNTl.js +0 -1
  610. package/web-ui/build/static/csp-CyYfNNga.js +0 -1
  611. package/web-ui/build/static/css-ClMfqSLF.js +0 -1
  612. package/web-ui/build/static/css-extras-BRU-Fmfk.js +0 -1
  613. package/web-ui/build/static/csv-VxPQSCnT.js +0 -1
  614. package/web-ui/build/static/cypher-COR7lVoB.js +0 -1
  615. package/web-ui/build/static/d-CjJIoaqU.js +0 -1
  616. package/web-ui/build/static/d-DrTea74c.js +0 -1
  617. package/web-ui/build/static/dart-Dx1CtbrO.js +0 -1
  618. package/web-ui/build/static/dart-Kqlt_5Iy.js +0 -1
  619. package/web-ui/build/static/dataweave-DpoRPYaa.js +0 -1
  620. package/web-ui/build/static/dax-BdRNDjXh.js +0 -1
  621. package/web-ui/build/static/delphi-C6ZfxFVF.js +0 -1
  622. package/web-ui/build/static/dhall-DZrga6Gc.js +0 -1
  623. package/web-ui/build/static/diff-BuMvzPYe.js +0 -1
  624. package/web-ui/build/static/diff-DZYXzKCb.js +0 -1
  625. package/web-ui/build/static/django-D_vRowuc.js +0 -1
  626. package/web-ui/build/static/django-NYcglI2i.js +0 -1
  627. package/web-ui/build/static/dns-Cd7tDS1i.js +0 -1
  628. package/web-ui/build/static/dns-zone-file-C3-2vwxy.js +0 -1
  629. package/web-ui/build/static/docker-DQ7ZFefk.js +0 -1
  630. package/web-ui/build/static/dockerfile-BpU0w0F-.js +0 -1
  631. package/web-ui/build/static/dos-B1_ZGbVG.js +0 -1
  632. package/web-ui/build/static/dot-BGB_tXU7.js +0 -1
  633. package/web-ui/build/static/dsconfig-BbDxyV_e.js +0 -1
  634. package/web-ui/build/static/dts-BfjOjY8l.js +0 -1
  635. package/web-ui/build/static/dust-BdwQ-7T_.js +0 -1
  636. package/web-ui/build/static/ebnf-BQTMmaYU.js +0 -1
  637. package/web-ui/build/static/ebnf-BwwBWilG.js +0 -1
  638. package/web-ui/build/static/editorconfig-DWS4VSOM.js +0 -1
  639. package/web-ui/build/static/eiffel-DVvlc0AI.js +0 -1
  640. package/web-ui/build/static/ejs-DsD496m-.js +0 -1
  641. package/web-ui/build/static/elixir-CLxuo9eh.js +0 -1
  642. package/web-ui/build/static/elixir-Cnyg3Ezx.js +0 -1
  643. package/web-ui/build/static/elm-CMAIkLMI.js +0 -1
  644. package/web-ui/build/static/elm-DZBnlwPV.js +0 -1
  645. package/web-ui/build/static/erb-B5xezjly.js +0 -1
  646. package/web-ui/build/static/erb-CJr8Ab4S.js +0 -1
  647. package/web-ui/build/static/erlang-BKy_rMFs.js +0 -1
  648. package/web-ui/build/static/erlang-DtaEL15_.js +0 -1
  649. package/web-ui/build/static/erlang-repl-CC5OZ0oZ.js +0 -1
  650. package/web-ui/build/static/etlua-1AfbSbi_.js +0 -1
  651. package/web-ui/build/static/excel-AEWYaJMN.js +0 -1
  652. package/web-ui/build/static/excel-formula-DXCH31eV.js +0 -1
  653. package/web-ui/build/static/factor-BvZsNxRC.js +0 -1
  654. package/web-ui/build/static/false-Y69sPjTa.js +0 -1
  655. package/web-ui/build/static/firestore-security-rules-BAYXaIU_.js +0 -1
  656. package/web-ui/build/static/fix-D7wVox5L.js +0 -1
  657. package/web-ui/build/static/flix-xYG3kZl-.js +0 -1
  658. package/web-ui/build/static/flow-zBPh0c8a.js +0 -1
  659. package/web-ui/build/static/fortran-C7OgAOwk.js +0 -1
  660. package/web-ui/build/static/fortran-D7HqnRra.js +0 -1
  661. package/web-ui/build/static/fsharp-Dz8jq_YD.js +0 -1
  662. package/web-ui/build/static/fsharp-wem8e879.js +0 -1
  663. package/web-ui/build/static/ftl-BNZhFjQT.js +0 -1
  664. package/web-ui/build/static/gams-C0WL3JTk.js +0 -1
  665. package/web-ui/build/static/gap-C3QTJPj2.js +0 -1
  666. package/web-ui/build/static/gauss-HDeDt6Js.js +0 -1
  667. package/web-ui/build/static/gcode-B6xVa-Q4.js +0 -1
  668. package/web-ui/build/static/gcode-KfjFk59Y.js +0 -1
  669. package/web-ui/build/static/gdscript-CZWTW6OT.js +0 -1
  670. package/web-ui/build/static/gedcom-DGTBZtDe.js +0 -1
  671. package/web-ui/build/static/gherkin-BM2fti5q.js +0 -1
  672. package/web-ui/build/static/gherkin-BsD-keLP.js +0 -1
  673. package/web-ui/build/static/git-CwXnrvg5.js +0 -1
  674. package/web-ui/build/static/glsl-CEL-DKdu.js +0 -1
  675. package/web-ui/build/static/glsl-DClg1hhL.js +0 -1
  676. package/web-ui/build/static/gml-BuyC2nUx.js +0 -1
  677. package/web-ui/build/static/gml-CaV0fexF.js +0 -1
  678. package/web-ui/build/static/gn-RZ4XHU09.js +0 -1
  679. package/web-ui/build/static/go-2fZP5dFL.js +0 -1
  680. package/web-ui/build/static/go-B-2r4QAR.js +0 -1
  681. package/web-ui/build/static/go-module-DSWZUUGo.js +0 -1
  682. package/web-ui/build/static/golo-BLZaLyU5.js +0 -1
  683. package/web-ui/build/static/gradle--RLe7WtU.js +0 -1
  684. package/web-ui/build/static/graphql-Dersm5rs.js +0 -1
  685. package/web-ui/build/static/groovy-BhCtzyFe.js +0 -1
  686. package/web-ui/build/static/groovy-CvbHavu3.js +0 -1
  687. package/web-ui/build/static/haml-CQhB89Xl.js +0 -1
  688. package/web-ui/build/static/haml-CemWzAX2.js +0 -1
  689. package/web-ui/build/static/handlebars-B39jLKjQ.js +0 -1
  690. package/web-ui/build/static/handlebars-Cl4dI91M.js +0 -1
  691. package/web-ui/build/static/haskell-CO9Ug-Kw.js +0 -1
  692. package/web-ui/build/static/haskell-EXme4CFR.js +0 -1
  693. package/web-ui/build/static/haxe-BDkCyqBy.js +0 -1
  694. package/web-ui/build/static/haxe-ahczQlFA.js +0 -1
  695. package/web-ui/build/static/hcl-liOTbdHr.js +0 -1
  696. package/web-ui/build/static/hlsl-Bnkb1zrP.js +0 -1
  697. package/web-ui/build/static/hoon-DCXHuTNp.js +0 -1
  698. package/web-ui/build/static/hpkp-CPJOGDF_.js +0 -1
  699. package/web-ui/build/static/hsp-BdeT0enM.js +0 -1
  700. package/web-ui/build/static/hsts-BoIN2VGK.js +0 -1
  701. package/web-ui/build/static/htmlbars-B5Ruf2zT.js +0 -1
  702. package/web-ui/build/static/http-BacVzmeC.js +0 -1
  703. package/web-ui/build/static/http-DifjpER4.js +0 -1
  704. package/web-ui/build/static/hy-DQ-M6mjk.js +0 -1
  705. package/web-ui/build/static/ichigojam-CcVrpthd.js +0 -1
  706. package/web-ui/build/static/icon-B4N1Fnx2.js +0 -1
  707. package/web-ui/build/static/icu-message-format-aDIl6Oaf.js +0 -1
  708. package/web-ui/build/static/idris-DKvV6i27.js +0 -1
  709. package/web-ui/build/static/iecst-zqZH79Dw.js +0 -1
  710. package/web-ui/build/static/ignore-BBbP-u2O.js +0 -1
  711. package/web-ui/build/static/index-CkhVK4lF.js +0 -1164
  712. package/web-ui/build/static/index-Cm1gK3R7.css +0 -1
  713. package/web-ui/build/static/index-D9JNKR2k.js +0 -13
  714. package/web-ui/build/static/index-DqZhvIWG.js +0 -1
  715. package/web-ui/build/static/inform7-BwvEArfL.js +0 -1
  716. package/web-ui/build/static/inform7-YkPDg57k.js +0 -1
  717. package/web-ui/build/static/ini-DU4drXRb.js +0 -1
  718. package/web-ui/build/static/ini-OhDTn0L5.js +0 -1
  719. package/web-ui/build/static/io-4thQGR-r.js +0 -1
  720. package/web-ui/build/static/irpf90-BnhmotbX.js +0 -1
  721. package/web-ui/build/static/isbl-BKcWS-M5.js +0 -1
  722. package/web-ui/build/static/j-Bw6CUCl9.js +0 -1
  723. package/web-ui/build/static/java-8IzvJ-mZ.js +0 -1
  724. package/web-ui/build/static/java-_jaQp1m2.js +0 -1
  725. package/web-ui/build/static/javadoc-D6KaHkhq.js +0 -1
  726. package/web-ui/build/static/javadoclike-B-DnR3Tl.js +0 -1
  727. package/web-ui/build/static/javascript-CfOOSye9.js +0 -1
  728. package/web-ui/build/static/javastacktrace-DHyDfhlB.js +0 -1
  729. package/web-ui/build/static/jboss-cli-zEH5UaRS.js +0 -1
  730. package/web-ui/build/static/jexl-CRpgdJ2f.js +0 -1
  731. package/web-ui/build/static/jolie-C5S16-nE.js +0 -1
  732. package/web-ui/build/static/jq-Dy-2LJZM.js +0 -1
  733. package/web-ui/build/static/js-extras-CNfXr3kE.js +0 -1
  734. package/web-ui/build/static/js-templates-DCJ1syUw.js +0 -1
  735. package/web-ui/build/static/jsdoc-BamyoRCh.js +0 -1
  736. package/web-ui/build/static/json-Buz-eeND.js +0 -1
  737. package/web-ui/build/static/json-D4xr_AK1.js +0 -1
  738. package/web-ui/build/static/json5-CS3uAaJP.js +0 -1
  739. package/web-ui/build/static/jsonp-CmEAdOcH.js +0 -1
  740. package/web-ui/build/static/jsstacktrace-D35jXpCN.js +0 -1
  741. package/web-ui/build/static/jsx-DRMEK-Qn.js +0 -1
  742. package/web-ui/build/static/julia-BgYJV7ho.js +0 -1
  743. package/web-ui/build/static/julia-CRsGDmxp.js +0 -1
  744. package/web-ui/build/static/julia-repl-D0vTZKUn.js +0 -1
  745. package/web-ui/build/static/keepalived-BlhBatvM.js +0 -1
  746. package/web-ui/build/static/keyman-B_-J66sg.js +0 -1
  747. package/web-ui/build/static/kotlin-B7HqYBGK.js +0 -1
  748. package/web-ui/build/static/kotlin-CszxhoS4.js +0 -1
  749. package/web-ui/build/static/kumir-B_wpMfXS.js +0 -1
  750. package/web-ui/build/static/kusto-BrHkOiE1.js +0 -1
  751. package/web-ui/build/static/lasso-xizuiq1s.js +0 -1
  752. package/web-ui/build/static/latex-62pryLTa.js +0 -1
  753. package/web-ui/build/static/latex-D7Tnbs2l.js +0 -1
  754. package/web-ui/build/static/latte-B_8xJj-y.js +0 -1
  755. package/web-ui/build/static/ldif-B69eIciC.js +0 -1
  756. package/web-ui/build/static/leaf-DPnh4k7N.js +0 -1
  757. package/web-ui/build/static/less-Bg3xuki-.js +0 -1
  758. package/web-ui/build/static/less-Cm-zhk4i.js +0 -1
  759. package/web-ui/build/static/lilypond-BFSXmrKQ.js +0 -1
  760. package/web-ui/build/static/liquid-D_jMXN_8.js +0 -1
  761. package/web-ui/build/static/lisp-CDWjXhWU.js +0 -1
  762. package/web-ui/build/static/lisp-DAu9fWrQ.js +0 -1
  763. package/web-ui/build/static/livecodeserver-BNgd6rBu.js +0 -1
  764. package/web-ui/build/static/livescript-C6sYNsdz.js +0 -1
  765. package/web-ui/build/static/livescript-CMOawYYt.js +0 -1
  766. package/web-ui/build/static/llvm-Yx2vcmJw.js +0 -1
  767. package/web-ui/build/static/llvm-w4vVb6qs.js +0 -1
  768. package/web-ui/build/static/log-CqhluDSP.js +0 -1
  769. package/web-ui/build/static/lolcode-Ck0rxP3x.js +0 -1
  770. package/web-ui/build/static/lsl-BwPX-Qjm.js +0 -1
  771. package/web-ui/build/static/lua-4H_Ijh4D.js +0 -1
  772. package/web-ui/build/static/lua-dDdlvQ6u.js +0 -1
  773. package/web-ui/build/static/magma-2nRRraug.js +0 -1
  774. package/web-ui/build/static/makefile-C887R9mV.js +0 -1
  775. package/web-ui/build/static/makefile-hlNtZePL.js +0 -1
  776. package/web-ui/build/static/markdown-DCALPnuW.js +0 -1
  777. package/web-ui/build/static/markdown-DGM_Z5tW.js +0 -1
  778. package/web-ui/build/static/markup-templating-PAvYDmBZ.js +0 -1
  779. package/web-ui/build/static/mathematica-CGL-Gomp.js +0 -1
  780. package/web-ui/build/static/matlab-C46ZZzlH.js +0 -1
  781. package/web-ui/build/static/matlab-WUgx8roJ.js +0 -1
  782. package/web-ui/build/static/maxima-Dd_TIy4H.js +0 -1
  783. package/web-ui/build/static/maxscript-f8SP9Ybn.js +0 -1
  784. package/web-ui/build/static/mel-6l2ZAh7F.js +0 -1
  785. package/web-ui/build/static/mel-BYdNMJzZ.js +0 -1
  786. package/web-ui/build/static/mercury-CdHf1buq.js +0 -1
  787. package/web-ui/build/static/mermaid-IRgUMtb1.js +0 -1
  788. package/web-ui/build/static/mipsasm-CRPpDKP4.js +0 -1
  789. package/web-ui/build/static/mizar-B4DBCLSi.js +0 -1
  790. package/web-ui/build/static/mizar-DiuZyDh7.js +0 -1
  791. package/web-ui/build/static/mojolicious-ChuQv8wb.js +0 -1
  792. package/web-ui/build/static/mongodb-CE5Epj0T.js +0 -1
  793. package/web-ui/build/static/monkey-BAz4pIwb.js +0 -1
  794. package/web-ui/build/static/monkey-i_g3gMkJ.js +0 -1
  795. package/web-ui/build/static/moonscript-BNaNpboV.js +0 -1
  796. package/web-ui/build/static/moonscript-uHlQVjxf.js +0 -1
  797. package/web-ui/build/static/n1ql-CBDLma2D.js +0 -1
  798. package/web-ui/build/static/n1ql-u4YLlLfk.js +0 -1
  799. package/web-ui/build/static/n4js-IVFjZEMP.js +0 -1
  800. package/web-ui/build/static/nand2tetris-hdl-Ba72aD32.js +0 -1
  801. package/web-ui/build/static/naniscript-CjMhybrb.js +0 -1
  802. package/web-ui/build/static/nasm-DjKhk70h.js +0 -1
  803. package/web-ui/build/static/neon-JEhMoh8P.js +0 -1
  804. package/web-ui/build/static/nevod-6tgpQVCA.js +0 -1
  805. package/web-ui/build/static/nginx-C6NwXcw_.js +0 -1
  806. package/web-ui/build/static/nginx-CquSTZbP.js +0 -1
  807. package/web-ui/build/static/nim-0bOOYxfL.js +0 -1
  808. package/web-ui/build/static/nim-aCQGMs_4.js +0 -1
  809. package/web-ui/build/static/nix-BV4kRCY_.js +0 -1
  810. package/web-ui/build/static/nix-FvSL2V8j.js +0 -1
  811. package/web-ui/build/static/node-repl-GtjTvb93.js +0 -1
  812. package/web-ui/build/static/nsis-DsftItKH.js +0 -1
  813. package/web-ui/build/static/nsis-pu7O80Pq.js +0 -1
  814. package/web-ui/build/static/objectivec-Bx7Bj0U_.js +0 -1
  815. package/web-ui/build/static/objectivec-GtO6Znp9.js +0 -1
  816. package/web-ui/build/static/ocaml-B71sR3qa.js +0 -1
  817. package/web-ui/build/static/ocaml-BlhoK75p.js +0 -1
  818. package/web-ui/build/static/opencl-40JZ6XXw.js +0 -1
  819. package/web-ui/build/static/openqasm-cDL6l7w3.js +0 -1
  820. package/web-ui/build/static/openscad-BQ0gNGv9.js +0 -1
  821. package/web-ui/build/static/oxygene-1fX2ftBa.js +0 -1
  822. package/web-ui/build/static/oz-Cgq2yQZq.js +0 -1
  823. package/web-ui/build/static/parigp-DfRO3DxU.js +0 -1
  824. package/web-ui/build/static/parser-hZcHrq-n.js +0 -1
  825. package/web-ui/build/static/parser3-Cf2p4Ryg.js +0 -1
  826. package/web-ui/build/static/pascal-C6tg_yvS.js +0 -1
  827. package/web-ui/build/static/pascaligo-9U9PdOS6.js +0 -1
  828. package/web-ui/build/static/pcaxis-B5EnEKrt.js +0 -1
  829. package/web-ui/build/static/peoplecode-Cf2sGzFJ.js +0 -1
  830. package/web-ui/build/static/perl-C9FNSHZx.js +0 -1
  831. package/web-ui/build/static/perl-uzSwl6wJ.js +0 -1
  832. package/web-ui/build/static/pf-C7Bjci1q.js +0 -1
  833. package/web-ui/build/static/pgsql-IBD1Cka7.js +0 -1
  834. package/web-ui/build/static/php-19XvqtTQ.js +0 -1
  835. package/web-ui/build/static/php-CUjVuQ1J.js +0 -1
  836. package/web-ui/build/static/php-extras-GWBU2Qbm.js +0 -1
  837. package/web-ui/build/static/php-template-Chtii014.js +0 -1
  838. package/web-ui/build/static/phpdoc-BLcJXgrV.js +0 -1
  839. package/web-ui/build/static/plaintext-BX3hHjdj.js +0 -1
  840. package/web-ui/build/static/plsql-tCcTmmsx.js +0 -1
  841. package/web-ui/build/static/pony-CKD16QkU.js +0 -1
  842. package/web-ui/build/static/powerquery-DXj7kqMe.js +0 -1
  843. package/web-ui/build/static/powershell-0jB2gvRR.js +0 -1
  844. package/web-ui/build/static/powershell-Ca6UjZV2.js +0 -1
  845. package/web-ui/build/static/processing-CPjwH4wc.js +0 -1
  846. package/web-ui/build/static/processing-ItKy7l8u.js +0 -1
  847. package/web-ui/build/static/profile-6N_Rzycx.js +0 -1
  848. package/web-ui/build/static/prolog-BV3TgLfG.js +0 -1
  849. package/web-ui/build/static/prolog-C5UoVyBz.js +0 -1
  850. package/web-ui/build/static/promql-CZot8Bw3.js +0 -1
  851. package/web-ui/build/static/properties-C_r_5f7N.js +0 -1
  852. package/web-ui/build/static/properties-qycKL1T0.js +0 -1
  853. package/web-ui/build/static/protobuf-BmdKEOw6.js +0 -1
  854. package/web-ui/build/static/protobuf-CxWC8PvT.js +0 -1
  855. package/web-ui/build/static/psl-CFSNRM7z.js +0 -1
  856. package/web-ui/build/static/pug-8dv12FtI.js +0 -1
  857. package/web-ui/build/static/puppet-CNjskGXn.js +0 -1
  858. package/web-ui/build/static/puppet-Cf6xZODN.js +0 -1
  859. package/web-ui/build/static/pure-exFir566.js +0 -1
  860. package/web-ui/build/static/purebasic-Bm6QaKku.js +0 -1
  861. package/web-ui/build/static/purebasic-lfzND9Qp.js +0 -1
  862. package/web-ui/build/static/purescript-D1xRYVQG.js +0 -1
  863. package/web-ui/build/static/python-DgkOjU0T.js +0 -1
  864. package/web-ui/build/static/python-o7BJVaX6.js +0 -1
  865. package/web-ui/build/static/python-repl-6SyonvH1.js +0 -1
  866. package/web-ui/build/static/q-CiQ2AFzU.js +0 -1
  867. package/web-ui/build/static/q-g7rEIWgm.js +0 -1
  868. package/web-ui/build/static/qml-ARc9Akfg.js +0 -1
  869. package/web-ui/build/static/qml-rVumxss_.js +0 -1
  870. package/web-ui/build/static/qore-CUXpqOSx.js +0 -1
  871. package/web-ui/build/static/qsharp-DMPNcgaz.js +0 -1
  872. package/web-ui/build/static/r-DCIo6joW.js +0 -1
  873. package/web-ui/build/static/r-nUBzz4LB.js +0 -1
  874. package/web-ui/build/static/racket--fPY_Q4o.js +0 -1
  875. package/web-ui/build/static/reason-CeVN9vJx.js +0 -1
  876. package/web-ui/build/static/reasonml-49SEasi3.js +0 -1
  877. package/web-ui/build/static/regex-BS97XMMk.js +0 -1
  878. package/web-ui/build/static/rego-Brc7DU11.js +0 -1
  879. package/web-ui/build/static/renpy-C2sPWAHv.js +0 -1
  880. package/web-ui/build/static/rest-DlZ7ycRe.js +0 -1
  881. package/web-ui/build/static/rib-C8WsA4on.js +0 -1
  882. package/web-ui/build/static/rip-dd9bS3Ar.js +0 -1
  883. package/web-ui/build/static/roboconf-CAEw-rS3.js +0 -1
  884. package/web-ui/build/static/roboconf-D0TfrLeu.js +0 -1
  885. package/web-ui/build/static/robotframework-CkgVY4bX.js +0 -1
  886. package/web-ui/build/static/routeros-DIek1v-Z.js +0 -1
  887. package/web-ui/build/static/rsl-DExhHtA1.js +0 -1
  888. package/web-ui/build/static/ruby-BjvzODgO.js +0 -1
  889. package/web-ui/build/static/ruby-Dflr1gcA.js +0 -1
  890. package/web-ui/build/static/ruleslanguage-BgzP6UBl.js +0 -1
  891. package/web-ui/build/static/rust-DxIro-GW.js +0 -1
  892. package/web-ui/build/static/rust-qWzP5Jcw.js +0 -1
  893. package/web-ui/build/static/sas-BrCJWU_w.js +0 -1
  894. package/web-ui/build/static/sas-itaOGZ-D.js +0 -1
  895. package/web-ui/build/static/sass-BTk1_hyU.js +0 -1
  896. package/web-ui/build/static/scala-DEtImhEo.js +0 -1
  897. package/web-ui/build/static/scala-DdZCH_nS.js +0 -1
  898. package/web-ui/build/static/scheme-CiOCQffl.js +0 -1
  899. package/web-ui/build/static/scheme-WaU-JPJX.js +0 -1
  900. package/web-ui/build/static/scilab-03tyg0ft.js +0 -1
  901. package/web-ui/build/static/scss-DXl2WSdH.js +0 -1
  902. package/web-ui/build/static/scss-movJ3vcX.js +0 -1
  903. package/web-ui/build/static/shell-DWmlNcrf.js +0 -1
  904. package/web-ui/build/static/shell-session-lHcfQbT0.js +0 -1
  905. package/web-ui/build/static/smali-7RKwn9RZ.js +0 -1
  906. package/web-ui/build/static/smali-TEMQ7bRM.js +0 -1
  907. package/web-ui/build/static/smalltalk-B_nVEfab.js +0 -1
  908. package/web-ui/build/static/smalltalk-BsA9wucb.js +0 -1
  909. package/web-ui/build/static/smarty-DSf4s_8v.js +0 -1
  910. package/web-ui/build/static/sml-BDO_Hmie.js +0 -1
  911. package/web-ui/build/static/sml-DKuy82zG.js +0 -1
  912. package/web-ui/build/static/solidity-jtWv6laA.js +0 -1
  913. package/web-ui/build/static/solution-file-DcfiquuJ.js +0 -1
  914. package/web-ui/build/static/soy-DmBVrDYd.js +0 -1
  915. package/web-ui/build/static/sparql-_JOxZ7fM.js +0 -1
  916. package/web-ui/build/static/splunk-spl-CHeBtp33.js +0 -1
  917. package/web-ui/build/static/sqf-9wI8rp5o.js +0 -1
  918. package/web-ui/build/static/sqf-BuKh30bG.js +0 -1
  919. package/web-ui/build/static/sql-ClFFHGMY.js +0 -1
  920. package/web-ui/build/static/sql-DVXtimpW.js +0 -1
  921. package/web-ui/build/static/sql_more-CNw-JJON.js +0 -1
  922. package/web-ui/build/static/squirrel-Bdi8LbT5.js +0 -1
  923. package/web-ui/build/static/stan-Brcz64A8.js +0 -1
  924. package/web-ui/build/static/stan-C9Q08Juk.js +0 -1
  925. package/web-ui/build/static/stata-ES8hryw_.js +0 -1
  926. package/web-ui/build/static/step21-Cfmoq4Lb.js +0 -1
  927. package/web-ui/build/static/stylus-DMKHLSvm.js +0 -1
  928. package/web-ui/build/static/stylus-Dcs8vyW2.js +0 -1
  929. package/web-ui/build/static/subunit-DRjv565H.js +0 -1
  930. package/web-ui/build/static/swift-0x_T9zx8.js +0 -1
  931. package/web-ui/build/static/swift-CUvpRg4a.js +0 -1
  932. package/web-ui/build/static/systemd-Dl8xGVv9.js +0 -1
  933. package/web-ui/build/static/t4-cs-DqvXuZwc.js +0 -1
  934. package/web-ui/build/static/t4-templating-DjN2N1uM.js +0 -1
  935. package/web-ui/build/static/t4-vb-CZQn9IVK.js +0 -1
  936. package/web-ui/build/static/taggerscript-CPCJkC2t.js +0 -1
  937. package/web-ui/build/static/tap-BPfuLhe7.js +0 -1
  938. package/web-ui/build/static/tap-CSdsd38Q.js +0 -1
  939. package/web-ui/build/static/tcl-4BqhAKLC.js +0 -1
  940. package/web-ui/build/static/tcl-Bh0Jg8jj.js +0 -1
  941. package/web-ui/build/static/textile-BiD4awlU.js +0 -1
  942. package/web-ui/build/static/thrift-Br1-10xh.js +0 -1
  943. package/web-ui/build/static/toml-QlLCqVpQ.js +0 -1
  944. package/web-ui/build/static/tp-B2Ef9EBz.js +0 -1
  945. package/web-ui/build/static/tremor-DuZdAfVr.js +0 -1
  946. package/web-ui/build/static/tsx-W3KEjccO.js +0 -1
  947. package/web-ui/build/static/tt2-D_tdF-56.js +0 -1
  948. package/web-ui/build/static/turtle-DxrQkFoq.js +0 -1
  949. package/web-ui/build/static/twig-DD44ApyU.js +0 -1
  950. package/web-ui/build/static/twig-vA3ZwAxn.js +0 -1
  951. package/web-ui/build/static/typescript-BfbcKNOu.js +0 -1
  952. package/web-ui/build/static/typescript-CvKtq1ix.js +0 -1
  953. package/web-ui/build/static/typoscript-BEu84JpE.js +0 -1
  954. package/web-ui/build/static/unrealscript-ohUNsJGM.js +0 -1
  955. package/web-ui/build/static/uorazor-BWer-chm.js +0 -1
  956. package/web-ui/build/static/uri-CPLTr_NY.js +0 -1
  957. package/web-ui/build/static/v-gAkMRmmI.js +0 -1
  958. package/web-ui/build/static/vala-Bktj5SNB.js +0 -1
  959. package/web-ui/build/static/vala-D1fDPFxI.js +0 -1
  960. package/web-ui/build/static/vbnet-Cn0g0ohh.js +0 -1
  961. package/web-ui/build/static/vbnet-TiYHF2WM.js +0 -1
  962. package/web-ui/build/static/vbscript-BUV-Kjvs.js +0 -1
  963. package/web-ui/build/static/vbscript-html-s1RgByjf.js +0 -1
  964. package/web-ui/build/static/velocity-DTy-TOwB.js +0 -1
  965. package/web-ui/build/static/verilog-4jk4MMXN.js +0 -1
  966. package/web-ui/build/static/verilog-aR4U-DJX.js +0 -1
  967. package/web-ui/build/static/vhdl-D72XnBZR.js +0 -1
  968. package/web-ui/build/static/vhdl-DFdtG28B.js +0 -1
  969. package/web-ui/build/static/vim-BMqsbQ-a.js +0 -1
  970. package/web-ui/build/static/vim-Cc3UuKOs.js +0 -1
  971. package/web-ui/build/static/visual-basic-CyC2kNGV.js +0 -1
  972. package/web-ui/build/static/warpscript-DpKFeISB.js +0 -1
  973. package/web-ui/build/static/wasm-SPljCkFH.js +0 -1
  974. package/web-ui/build/static/web-idl-Cie2yHU9.js +0 -1
  975. package/web-ui/build/static/wiki-BfYfwsBk.js +0 -1
  976. package/web-ui/build/static/wolfram-Dgi1K2gQ.js +0 -1
  977. package/web-ui/build/static/wren-CFQxgLld.js +0 -1
  978. package/web-ui/build/static/x86asm-CBIt2r64.js +0 -1
  979. package/web-ui/build/static/xeora-e5JHDF1T.js +0 -1
  980. package/web-ui/build/static/xl-CPZe-czl.js +0 -1
  981. package/web-ui/build/static/xml-BEuPuoS1.js +0 -1
  982. package/web-ui/build/static/xml-doc-DTOJGYE2.js +0 -1
  983. package/web-ui/build/static/xojo-ByMSKdYJ.js +0 -1
  984. package/web-ui/build/static/xquery--5iaD5oE.js +0 -1
  985. package/web-ui/build/static/xquery-DJp5PXZo.js +0 -1
  986. package/web-ui/build/static/yaml-CH8EnM9M.js +0 -1
  987. package/web-ui/build/static/yaml-mKr8oN1v.js +0 -1
  988. package/web-ui/build/static/yang-Nqdvm2mQ.js +0 -1
  989. package/web-ui/build/static/zephir-BJZaDzrW.js +0 -1
  990. package/web-ui/build/static/zig-DRkhvZLn.js +0 -1
@@ -1,717 +1,752 @@
1
- import { jest, describe, test, expect, beforeEach } from '@jest/globals';
2
- import { createMockLogger, createMockConfig } from '../../__test-utils__/mockFactories.js';
3
-
4
- // Mock fs (promises) and crypto BEFORE importing the tool
5
- const fsMock = {
6
- mkdir: jest.fn().mockResolvedValue(undefined),
7
- readFile: jest.fn().mockResolvedValue('{}'),
8
- writeFile: jest.fn().mockResolvedValue(undefined),
9
- stat: jest.fn().mockResolvedValue({ size: 100 }),
10
- copyFile: jest.fn().mockResolvedValue(undefined),
11
- access: jest.fn().mockResolvedValue(undefined)
12
- };
13
-
14
- jest.unstable_mockModule('fs', () => ({
15
- default: { promises: fsMock },
16
- promises: fsMock
17
- }));
18
-
19
- jest.unstable_mockModule('crypto', () => ({
20
- default: {
21
- randomUUID: jest.fn(() => 'mock-crypto-uuid'),
22
- randomBytes: jest.fn(() => ({ toString: () => 'mockrandom' }))
23
- }
24
- }));
25
-
26
- const { default: AgentCommunicationTool } = await import('../agentCommunicationTool.js');
27
-
28
- /**
29
- * Helper: builds a tool, agent pool, and context for tests.
30
- */
31
- function createTestSetup() {
32
- const logger = createMockLogger();
33
- const tool = new AgentCommunicationTool({ storageDir: '/tmp/msg-test' });
34
- tool.logger = logger;
35
-
36
- const senderAgent = {
37
- id: 'agent-sender',
38
- name: 'Sender Agent',
39
- type: 'developer',
40
- capabilities: ['code'],
41
- status: 'active',
42
- isPaused: false,
43
- conversations: { full: { messages: [], lastUpdated: '' } },
44
- currentModel: null
45
- };
46
-
47
- const recipientAgent = {
48
- id: 'agent-recipient',
49
- name: 'Recipient Agent',
50
- type: 'reviewer',
51
- capabilities: ['review'],
52
- status: 'active',
53
- isPaused: false,
54
- conversations: { full: { messages: [], lastUpdated: '' } },
55
- currentModel: null
56
- };
57
-
58
- const agents = new Map();
59
- agents.set('agent-sender', senderAgent);
60
- agents.set('agent-recipient', recipientAgent);
61
-
62
- const agentPool = {
63
- getAgent: jest.fn((id) => Promise.resolve(agents.get(id) || null)),
64
- listActiveAgents: jest.fn().mockResolvedValue([senderAgent, recipientAgent]),
65
- notifyAgent: jest.fn().mockResolvedValue(undefined),
66
- persistAgentState: jest.fn().mockResolvedValue(undefined),
67
- updateAgent: jest.fn().mockResolvedValue(undefined),
68
- addInterAgentMessage: jest.fn().mockResolvedValue(undefined)
69
- };
70
-
71
- const context = {
72
- agentId: 'agent-sender',
73
- agentPool,
74
- projectDir: '/tmp/test'
75
- };
76
-
77
- return { tool, senderAgent, recipientAgent, agentPool, context, logger };
78
- }
79
-
80
- describe('AgentCommunicationTool', () => {
81
- // ── constructor ─────────────────────────────────────────────────
82
- describe('constructor', () => {
83
- test('initializes with default config values', () => {
84
- const tool = new AgentCommunicationTool();
85
- expect(tool.config.maxConversationDepth).toBe(10);
86
- expect(tool.config.maxRecipientsPerMessage).toBe(3);
87
- expect(tool.messages).toBeInstanceOf(Map);
88
- expect(tool.conversations).toBeInstanceOf(Map);
89
- });
90
-
91
- test('accepts custom config overrides', () => {
92
- const tool = new AgentCommunicationTool({ maxConversationDepth: 5 });
93
- expect(tool.config.maxConversationDepth).toBe(5);
94
- });
95
- });
96
-
97
- // ── getDescription ──────────────────────────────────────────────
98
- describe('getDescription', () => {
99
- test('returns description with action list', () => {
100
- const tool = new AgentCommunicationTool();
101
- const desc = tool.getDescription();
102
- expect(desc).toContain('get-available-agents');
103
- expect(desc).toContain('send-message');
104
- expect(desc).toContain('reply-to-message');
105
- });
106
- });
107
-
108
- // ── parseParameters ─────────────────────────────────────────────
109
- describe('parseParameters', () => {
110
- test('parses object with actions array', () => {
111
- const tool = new AgentCommunicationTool();
112
- const result = tool.parseParameters({
113
- actions: [{ type: 'get-available-agents' }]
114
- });
115
- expect(result.action).toBe('get-available-agents');
116
- });
117
-
118
- test('parses object with action field', () => {
119
- const tool = new AgentCommunicationTool();
120
- const result = tool.parseParameters({ action: 'send-message', subject: 'Hi' });
121
- expect(result.action).toBe('send-message');
122
- });
123
-
124
- test('parses JSON string', () => {
125
- const tool = new AgentCommunicationTool();
126
- const result = tool.parseParameters('{"action": "get-available-agents"}');
127
- expect(result.action).toBe('get-available-agents');
128
- });
129
-
130
- test('parses XML-style content', () => {
131
- const tool = new AgentCommunicationTool();
132
- const result = tool.parseParameters('<action>send-message</action><subject>Hello</subject>');
133
- expect(result.action).toBe('send-message');
134
- expect(result.subject).toBe('Hello');
135
- });
136
-
137
- test('returns empty object for null input', () => {
138
- const tool = new AgentCommunicationTool();
139
- const result = tool.parseParameters(null);
140
- expect(result).toEqual({});
141
- });
142
- });
143
-
144
- // ── execute - missing action ────────────────────────────────────
145
- describe('execute - missing params', () => {
146
- test('throws when action is missing', async () => {
147
- const { tool, context } = createTestSetup();
148
- await expect(tool.execute({}, context)).rejects.toThrow('Action parameter is required');
149
- });
150
-
151
- test('throws when agentId is missing from context', async () => {
152
- const { tool } = createTestSetup();
153
- await expect(tool.execute({ action: 'get-available-agents' }, {}))
154
- .rejects.toThrow('Agent ID is required');
155
- });
156
-
157
- test('throws for unknown action', async () => {
158
- const { tool, context } = createTestSetup();
159
- await expect(tool.execute({ action: 'teleport' }, context))
160
- .rejects.toThrow('Unknown action');
161
- });
162
- });
163
-
164
- // ── get-available-agents ────────────────────────────────────────
165
- describe('execute - get-available-agents', () => {
166
- test('returns list excluding requesting agent', async () => {
167
- const { tool, context } = createTestSetup();
168
- const result = await tool.execute({ action: 'get-available-agents' }, context);
169
- expect(result.success).toBe(true);
170
- expect(result.agents).toHaveLength(1);
171
- expect(result.agents[0].id).toBe('agent-recipient');
172
- });
173
-
174
- test('includes message stats for each agent', async () => {
175
- const { tool, context } = createTestSetup();
176
- const result = await tool.execute({ action: 'get-available-agents' }, context);
177
- expect(result.agents[0].messageStats).toBeDefined();
178
- });
179
-
180
- test('returns error when agentPool missing', async () => {
181
- const { tool } = createTestSetup();
182
- const result = await tool.execute(
183
- { action: 'get-available-agents' },
184
- { agentId: 'agent-sender', agentPool: null }
185
- );
186
- // Should catch internally and return success: false
187
- expect(result.success).toBe(false);
188
- expect(result.error).toBeDefined();
189
- });
190
- });
191
-
192
- // ── send-message ────────────────────────────────────────────────
193
- describe('execute - send-message', () => {
194
- test('sends message to recipient successfully', async () => {
195
- const { tool, context } = createTestSetup();
196
- const result = await tool.execute({
197
- action: 'send-message',
198
- recipient: 'agent-recipient',
199
- subject: 'Review code',
200
- message: 'Please review the auth module'
201
- }, context);
202
- expect(result.success).toBe(true);
203
- expect(result.messageId).toBeDefined();
204
- expect(result.conversationId).toBeDefined();
205
- expect(result.recipients).toContain('agent-recipient');
206
- });
207
-
208
- test('errors when subject is missing', async () => {
209
- const { tool, context } = createTestSetup();
210
- const result = await tool.execute({
211
- action: 'send-message',
212
- recipient: 'agent-recipient',
213
- message: 'No subject'
214
- }, context);
215
- expect(result.success).toBe(false);
216
- expect(result.error).toContain('Subject and message are required');
217
- });
218
-
219
- test('errors when message is missing', async () => {
220
- const { tool, context } = createTestSetup();
221
- const result = await tool.execute({
222
- action: 'send-message',
223
- recipient: 'agent-recipient',
224
- subject: 'No body'
225
- }, context);
226
- expect(result.success).toBe(false);
227
- });
228
-
229
- test('errors when no recipient provided', async () => {
230
- const { tool, context } = createTestSetup();
231
- const result = await tool.execute({
232
- action: 'send-message',
233
- subject: 'Test',
234
- message: 'Hello'
235
- }, context);
236
- expect(result.success).toBe(false);
237
- expect(result.error).toContain('At least one recipient');
238
- });
239
-
240
- test('returns suggestions when recipient not found', async () => {
241
- const { tool, context, agentPool } = createTestSetup();
242
- // Mock _canSendMessage to allow (bypass delay check)
243
- tool._canSendMessage = jest.fn().mockResolvedValue({ allowed: true });
244
- const result = await tool.execute({
245
- action: 'send-message',
246
- recipient: 'agent-nonexistent',
247
- subject: 'Test',
248
- message: 'Hello'
249
- }, context);
250
- expect(result.success).toBe(false);
251
- expect(result.suggestion).toBeDefined();
252
- });
253
-
254
- test('updates message counts after sending', async () => {
255
- const { tool, context } = createTestSetup();
256
- await tool.execute({
257
- action: 'send-message',
258
- recipient: 'agent-recipient',
259
- subject: 'Test',
260
- message: 'Content'
261
- }, context);
262
- const senderStats = tool.agentMessageCounts.get('agent-sender');
263
- expect(senderStats.sent).toBe(1);
264
- });
265
- });
266
-
267
- // ── reply-to-message ────────────────────────────────────────────
268
- describe('execute - reply-to-message', () => {
269
- test('replies to an existing message', async () => {
270
- const { tool, context } = createTestSetup();
271
- // Send initial message
272
- const sendResult = await tool.execute({
273
- action: 'send-message',
274
- recipient: 'agent-recipient',
275
- subject: 'Question',
276
- message: 'What is the status?'
277
- }, context);
278
- const msgId = sendResult.messageId;
279
-
280
- // Reply as recipient
281
- const replyResult = await tool.execute({
282
- action: 'reply-to-message',
283
- 'message-id': msgId,
284
- message: 'All good!'
285
- }, { agentId: 'agent-recipient', agentPool: context.agentPool });
286
- expect(replyResult.success).toBe(true);
287
- expect(replyResult.depth).toBe(1);
288
- });
289
-
290
- test('errors when original message ID missing', async () => {
291
- const { tool, context } = createTestSetup();
292
- const result = await tool.execute({
293
- action: 'reply-to-message',
294
- message: 'Reply without ID'
295
- }, context);
296
- expect(result.success).toBe(false);
297
- expect(result.error).toContain('Original message ID and reply content are required');
298
- });
299
-
300
- test('errors when original message not found', async () => {
301
- const { tool, context } = createTestSetup();
302
- const result = await tool.execute({
303
- action: 'reply-to-message',
304
- 'message-id': 'msg-nonexistent',
305
- message: 'Reply'
306
- }, context);
307
- expect(result.success).toBe(false);
308
- expect(result.error).toContain('Original message not found');
309
- });
310
-
311
- test('errors when sender is not a participant', async () => {
312
- const { tool, context, agentPool } = createTestSetup();
313
- // Send message between sender and recipient
314
- const sendResult = await tool.execute({
315
- action: 'send-message',
316
- recipient: 'agent-recipient',
317
- subject: 'Private',
318
- message: 'Secret'
319
- }, context);
320
-
321
- // Try to reply as an outsider
322
- const outsider = {
323
- id: 'agent-outsider', name: 'Outsider', conversations: { full: { messages: [] } }
324
- };
325
- agentPool.getAgent.mockImplementation((id) => {
326
- if (id === 'agent-outsider') return Promise.resolve(outsider);
327
- if (id === 'agent-sender') return Promise.resolve(context.agentPool);
328
- return Promise.resolve(null);
329
- });
330
-
331
- const result = await tool.execute({
332
- action: 'reply-to-message',
333
- 'message-id': sendResult.messageId,
334
- message: 'Eavesdrop'
335
- }, { agentId: 'agent-outsider', agentPool });
336
- expect(result.success).toBe(false);
337
- expect(result.error).toContain('not a participant');
338
- });
339
-
340
- test('rejects reply when conversation depth limit reached', async () => {
341
- const { tool, context } = createTestSetup();
342
- tool.config.maxConversationDepth = 1;
343
-
344
- const sendResult = await tool.execute({
345
- action: 'send-message',
346
- recipient: 'agent-recipient',
347
- subject: 'Deep',
348
- message: 'Start'
349
- }, context);
350
-
351
- // First reply (depth 1) - should succeed
352
- const reply1 = await tool.execute({
353
- action: 'reply-to-message',
354
- 'message-id': sendResult.messageId,
355
- message: 'Reply 1'
356
- }, { agentId: 'agent-recipient', agentPool: context.agentPool });
357
- expect(reply1.success).toBe(true);
358
-
359
- // Second reply (depth 2) should fail at depth limit 1
360
- const reply2 = await tool.execute({
361
- action: 'reply-to-message',
362
- 'message-id': reply1.messageId,
363
- message: 'Reply 2'
364
- }, context);
365
- expect(reply2.success).toBe(false);
366
- expect(reply2.error).toContain('depth limit');
367
- });
368
- });
369
-
370
- // ── get-unreplied-messages ──────────────────────────────────────
371
- describe('execute - get-unreplied-messages', () => {
372
- test('returns unreplied messages for agent', async () => {
373
- const { tool, context } = createTestSetup();
374
- // Send message requiring reply
375
- await tool.execute({
376
- action: 'send-message',
377
- recipient: 'agent-recipient',
378
- subject: 'Need reply',
379
- message: 'Please respond',
380
- 'requires-reply': true
381
- }, context);
382
-
383
- const result = await tool.execute(
384
- { action: 'get-unreplied-messages' },
385
- { agentId: 'agent-recipient', agentPool: context.agentPool }
386
- );
387
- expect(result.success).toBe(true);
388
- expect(result.messages.length).toBeGreaterThan(0);
389
- expect(result.messages[0].subject).toBe('Need reply');
390
- });
391
-
392
- test('returns empty list when no messages', async () => {
393
- const { tool, context } = createTestSetup();
394
- const result = await tool.execute(
395
- { action: 'get-unreplied-messages' },
396
- { agentId: 'agent-recipient', agentPool: context.agentPool }
397
- );
398
- expect(result.success).toBe(true);
399
- expect(result.messages).toHaveLength(0);
400
- });
401
- });
402
-
403
- // ── mark-conversation-ended ─────────────────────────────────────
404
- describe('execute - mark-conversation-ended', () => {
405
- test('ends a conversation successfully', async () => {
406
- const { tool, context } = createTestSetup();
407
- const sendResult = await tool.execute({
408
- action: 'send-message',
409
- recipient: 'agent-recipient',
410
- subject: 'End me',
411
- message: 'Done'
412
- }, context);
413
-
414
- const result = await tool.execute({
415
- action: 'mark-conversation-ended',
416
- 'conversation-id': sendResult.conversationId,
417
- reason: 'Work complete'
418
- }, context);
419
- expect(result.success).toBe(true);
420
- expect(result.status).toBe('ended');
421
- });
422
-
423
- test('errors when conversation-id is missing', async () => {
424
- const { tool, context } = createTestSetup();
425
- const result = await tool.execute(
426
- { action: 'mark-conversation-ended' }, context
427
- );
428
- expect(result.success).toBe(false);
429
- expect(result.error).toContain('Conversation ID is required');
430
- });
431
-
432
- test('errors for non-existent conversation', async () => {
433
- const { tool, context } = createTestSetup();
434
- const result = await tool.execute({
435
- action: 'mark-conversation-ended',
436
- 'conversation-id': 'conv-nope'
437
- }, context);
438
- expect(result.success).toBe(false);
439
- expect(result.error).toContain('Conversation not found');
440
- });
441
-
442
- test('errors when agent is not a participant', async () => {
443
- const { tool, context, agentPool } = createTestSetup();
444
- const sendResult = await tool.execute({
445
- action: 'send-message',
446
- recipient: 'agent-recipient',
447
- subject: 'Private',
448
- message: 'Content'
449
- }, context);
450
-
451
- const result = await tool.execute({
452
- action: 'mark-conversation-ended',
453
- 'conversation-id': sendResult.conversationId
454
- }, { agentId: 'agent-outsider', agentPool });
455
- expect(result.success).toBe(false);
456
- expect(result.error).toContain('not a participant');
457
- });
458
- });
459
-
460
- // ── helper methods ──────────────────────────────────────────────
461
- describe('_parseRecipients', () => {
462
- test('parses single recipient string', () => {
463
- const tool = new AgentCommunicationTool();
464
- const result = tool._parseRecipients('agent-1', null);
465
- expect(result).toEqual(['agent-1']);
466
- });
467
-
468
- test('parses JSON array of recipients', () => {
469
- const tool = new AgentCommunicationTool();
470
- const result = tool._parseRecipients(null, '["agent-1", "agent-2"]');
471
- expect(result).toEqual(['agent-1', 'agent-2']);
472
- });
473
-
474
- test('handles array recipients directly', () => {
475
- const tool = new AgentCommunicationTool();
476
- const result = tool._parseRecipients(null, ['agent-1', 'agent-2']);
477
- expect(result).toEqual(['agent-1', 'agent-2']);
478
- });
479
-
480
- test('deduplicates recipients', () => {
481
- const tool = new AgentCommunicationTool();
482
- const result = tool._parseRecipients('agent-1', ['agent-1', 'agent-2']);
483
- expect(result).toEqual(['agent-1', 'agent-2']);
484
- });
485
-
486
- test('handles non-JSON string as single recipient', () => {
487
- const tool = new AgentCommunicationTool();
488
- const result = tool._parseRecipients(null, 'plain-id');
489
- expect(result).toEqual(['plain-id']);
490
- });
491
- });
492
-
493
- describe('_processAttachments', () => {
494
- test('returns empty array for null/undefined', async () => {
495
- const tool = new AgentCommunicationTool();
496
- expect(await tool._processAttachments(null, 'agent-1')).toEqual([]);
497
- expect(await tool._processAttachments(undefined, 'agent-1')).toEqual([]);
498
- });
499
- });
500
-
501
- // ─── Team affiliation in get-available-agents ─────────────────────────
502
-
503
- describe('team affiliation', () => {
504
- function createTeamSetup(senderMeta, agentsMeta) {
505
- const tool = new AgentCommunicationTool({ storageDir: '/tmp/msg-test' });
506
- tool.logger = createMockLogger();
507
-
508
- const sender = {
509
- id: 'agent-mgr', name: 'Manager', type: 'manager', capabilities: [],
510
- status: 'active', isPaused: false, metadata: senderMeta
511
- };
512
- const allAgents = [sender, ...agentsMeta.map((meta, i) => ({
513
- id: `agent-${i}`, name: `Agent ${i}`, type: 'worker', capabilities: ['code'],
514
- status: 'active', isPaused: false, metadata: meta
515
- }))];
516
- const agentPool = {
517
- listActiveAgents: jest.fn().mockResolvedValue(allAgents),
518
- getAgent: jest.fn(id => Promise.resolve(allAgents.find(a => a.id === id)))
519
- };
520
- return { tool, agentPool, context: { agentPool, agentId: 'agent-mgr' } };
521
- }
522
-
523
- test('sameTeam is true when agents share a team (new format)', async () => {
524
- const { tool, context } = createTeamSetup(
525
- { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
526
- [{ teams: [{ id: 'team-a', name: 'Alpha', role: 'member' }] }]
527
- );
528
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
529
- expect(result.success).toBe(true);
530
- expect(result.agents[0].sameTeam).toBe(true);
531
- expect(result.agents[0].sharedTeams).toContain('team-a');
532
- });
533
-
534
- test('sameTeam is false when agents are on different teams', async () => {
535
- const { tool, context } = createTeamSetup(
536
- { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
537
- [{ teams: [{ id: 'team-b', name: 'Beta', role: 'member' }] }]
538
- );
539
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
540
- expect(result.agents[0].sameTeam).toBe(false);
541
- expect(result.agents[0].sharedTeams).toEqual([]);
542
- });
543
-
544
- test('sameTeam works with legacy single teamId format', async () => {
545
- const { tool, context } = createTeamSetup(
546
- { teamId: 'team-x', teamName: 'X Team', teamRole: 'manager' },
547
- [{ teamId: 'team-x', teamName: 'X Team', teamRole: 'member' }]
548
- );
549
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
550
- expect(result.agents[0].sameTeam).toBe(true);
551
- expect(result.agents[0].sharedTeams).toContain('team-x');
552
- });
553
-
554
- test('agent with no team metadata has sameTeam=false and empty teams', async () => {
555
- const { tool, context } = createTeamSetup(
556
- { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
557
- [{}] // no team metadata
558
- );
559
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
560
- expect(result.agents[0].sameTeam).toBe(false);
561
- expect(result.agents[0].teams).toEqual([]);
562
- expect(result.agents[0].sharedTeams).toEqual([]);
563
- });
564
-
565
- test('multi-team agent shares subset of teams', async () => {
566
- const { tool, context } = createTeamSetup(
567
- { teams: [{ id: 'team-a', role: 'manager' }, { id: 'team-b', role: 'manager' }] },
568
- [{ teams: [{ id: 'team-b', role: 'member' }, { id: 'team-c', role: 'member' }] }]
569
- );
570
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
571
- expect(result.agents[0].sameTeam).toBe(true);
572
- expect(result.agents[0].sharedTeams).toEqual(['team-b']);
573
- expect(result.agents[0].teams).toHaveLength(2);
574
- });
575
-
576
- test('yourTeams reflects the requesting agent teams', async () => {
577
- const { tool, context } = createTeamSetup(
578
- { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }, { id: 'team-b', name: 'Beta', role: 'member' }] },
579
- [{}]
580
- );
581
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
582
- expect(result.yourTeams).toHaveLength(2);
583
- expect(result.yourTeams[0].id).toBe('team-a');
584
- expect(result.yourTeams[1].id).toBe('team-b');
585
- });
586
-
587
- test('yourTeams is null when requesting agent has no teams', async () => {
588
- const { tool, context } = createTeamSetup({}, [{}]);
589
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
590
- expect(result.yourTeams).toBeNull();
591
- });
592
-
593
- test('teamRole is exposed in teams array', async () => {
594
- const { tool, context } = createTeamSetup(
595
- { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
596
- [{ teams: [{ id: 'team-a', name: 'Alpha', role: 'member' }] }]
597
- );
598
- const result = await tool.getAvailableAgents('agent-mgr', {}, context);
599
- expect(result.agents[0].teams[0].role).toBe('member');
600
- expect(result.yourTeams[0].role).toBe('manager');
601
- });
602
- });
603
-
604
- // Per-agent toolConfig overrides (agent.toolConfig.agentcommunication).
605
- // Effective limits resolve via BaseTool#getEffectiveConfig at each
606
- // check-point in the tool.
607
- describe('per-agent toolConfig overrides', () => {
608
- test('per-agent maxRecipientsPerMessage overrides global default', async () => {
609
- const { tool, context } = createTestSetup();
610
- // Global default = 3; per-agent override = 1 → sending to 2 must fail.
611
- const result = await tool.sendMessage('agent-sender', {
612
- recipients: ['agent-recipient', 'agent-other'],
613
- subject: 's',
614
- message: 'm',
615
- }, { ...context, toolConfig: { maxRecipientsPerMessage: 1 } });
616
- expect(result.success).toBe(false);
617
- expect(result.error).toMatch(/Maximum 1 recipients allowed/);
618
- });
619
-
620
- test('global default still applies when no per-agent override', async () => {
621
- const { tool, context } = createTestSetup();
622
- // Global default = 3; 4 recipients fails without any override.
623
- const result = await tool.sendMessage('agent-sender', {
624
- recipients: ['a', 'b', 'c', 'd'],
625
- subject: 's',
626
- message: 'm',
627
- }, context);
628
- expect(result.success).toBe(false);
629
- expect(result.error).toMatch(/Maximum 3 recipients allowed/);
630
- });
631
-
632
- test('per-agent maxAttachmentsPerMessage overrides global default', async () => {
633
- const { tool, context } = createTestSetup();
634
- const atts = [
635
- { path: '/a.txt' },
636
- { path: '/b.txt' },
637
- { path: '/c.txt' },
638
- ];
639
- await expect(
640
- tool._processAttachments(atts, 'agent-sender', { ...context, toolConfig: { maxAttachmentsPerMessage: 2 } })
641
- ).rejects.toThrow(/Maximum 2 attachments allowed/);
642
- });
643
-
644
- test('per-agent maxAttachmentSize overrides global default', async () => {
645
- const { tool, context } = createTestSetup();
646
- // Stat returns size 100; override to 10 → too large. The tool's
647
- // per-attachment try/catch swallows the error and just skips the
648
- // attachment, so the emitted array is empty. We also assert the
649
- // error was logged as proof the size gate actually fired.
650
- fsMock.stat.mockResolvedValue({ size: 100 });
651
- const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
652
- const out = await tool._processAttachments([{ path: '/big.txt' }], 'agent-sender', {
653
- ...context,
654
- toolConfig: { maxAttachmentSize: 10 },
655
- });
656
- expect(out).toEqual([]);
657
- expect(errorSpy).toHaveBeenCalledWith(
658
- expect.stringMatching(/Failed to process attachment/),
659
- expect.objectContaining({ message: expect.stringMatching(/exceeds size limit/) })
660
- );
661
- errorSpy.mockRestore();
662
- });
663
-
664
- test('per-agent maxAttachmentSize ALLOWS attachments within limit', async () => {
665
- const { tool, context } = createTestSetup();
666
- fsMock.stat.mockResolvedValue({ size: 50 });
667
- const out = await tool._processAttachments([{ path: '/small.txt' }], 'agent-sender', {
668
- ...context,
669
- toolConfig: { maxAttachmentSize: 1024 },
670
- });
671
- expect(out).toHaveLength(1);
672
- });
673
-
674
- test('per-agent maxConversationDepth caps reply chain', async () => {
675
- // Start a fresh conversation with a per-agent cap of 1: the first
676
- // reply goes through, the second hits the limit. Mirrors the
677
- // existing "rejects reply when conversation depth limit reached"
678
- // test but drives the cap from context.toolConfig instead of
679
- // mutating tool.config.
680
- const { tool, context } = createTestSetup();
681
-
682
- const sendResult = await tool.execute({
683
- action: 'send-message',
684
- recipient: 'agent-recipient',
685
- subject: 'Deep',
686
- message: 'Start',
687
- }, { ...context, toolConfig: { maxConversationDepth: 1 } });
688
- expect(sendResult.success).toBe(true);
689
-
690
- // First reply (depth 1) — should succeed even under the cap.
691
- const reply1 = await tool.execute({
692
- action: 'reply-to-message',
693
- 'message-id': sendResult.messageId,
694
- message: 'Reply 1',
695
- }, { agentId: 'agent-recipient', agentPool: context.agentPool, toolConfig: { maxConversationDepth: 1 } });
696
- expect(reply1.success).toBe(true);
697
-
698
- // Second reply — depth now 1, cap is 1, must fail.
699
- const reply2 = await tool.execute({
700
- action: 'reply-to-message',
701
- 'message-id': reply1.messageId,
702
- message: 'Reply 2',
703
- }, { ...context, toolConfig: { maxConversationDepth: 1 } });
704
- expect(reply2.success).toBe(false);
705
- expect(reply2.error).toMatch(/depth limit reached \(1\)/);
706
- });
707
-
708
- test('_processAttachments with no context uses global config (backward compat)', async () => {
709
- const { tool } = createTestSetup();
710
- // Global = 5; 4 atts ok (stat mocked to size 100, global max = 10MB).
711
- fsMock.stat.mockResolvedValue({ size: 100 });
712
- const atts = [{ path: '/a.txt' }, { path: '/b.txt' }];
713
- const out = await tool._processAttachments(atts, 'agent-sender');
714
- expect(Array.isArray(out)).toBe(true);
715
- });
716
- });
717
- });
1
+ import { jest, describe, test, expect, beforeEach } from '@jest/globals';
2
+ import { createMockLogger, createMockConfig } from '../../__test-utils__/mockFactories.js';
3
+
4
+ // Mock fs (promises) and crypto BEFORE importing the tool
5
+ const fsMock = {
6
+ mkdir: jest.fn().mockResolvedValue(undefined),
7
+ readFile: jest.fn().mockResolvedValue('{}'),
8
+ writeFile: jest.fn().mockResolvedValue(undefined),
9
+ stat: jest.fn().mockResolvedValue({ size: 100 }),
10
+ copyFile: jest.fn().mockResolvedValue(undefined),
11
+ access: jest.fn().mockResolvedValue(undefined)
12
+ };
13
+
14
+ jest.unstable_mockModule('fs', () => ({
15
+ default: { promises: fsMock },
16
+ promises: fsMock
17
+ }));
18
+
19
+ jest.unstable_mockModule('crypto', () => ({
20
+ default: {
21
+ randomUUID: jest.fn(() => 'mock-crypto-uuid'),
22
+ randomBytes: jest.fn(() => ({ toString: () => 'mockrandom' }))
23
+ }
24
+ }));
25
+
26
+ const { default: AgentCommunicationTool } = await import('../agentCommunicationTool.js');
27
+
28
+ /**
29
+ * Helper: builds a tool, agent pool, and context for tests.
30
+ */
31
+ function createTestSetup() {
32
+ const logger = createMockLogger();
33
+ const tool = new AgentCommunicationTool({ storageDir: '/tmp/msg-test' });
34
+ tool.logger = logger;
35
+
36
+ const senderAgent = {
37
+ id: 'agent-sender',
38
+ name: 'Sender Agent',
39
+ type: 'developer',
40
+ capabilities: ['code'],
41
+ status: 'active',
42
+ isPaused: false,
43
+ conversations: { full: { messages: [], lastUpdated: '' } },
44
+ currentModel: null
45
+ };
46
+
47
+ const recipientAgent = {
48
+ id: 'agent-recipient',
49
+ name: 'Recipient Agent',
50
+ type: 'reviewer',
51
+ capabilities: ['review'],
52
+ status: 'active',
53
+ isPaused: false,
54
+ conversations: { full: { messages: [], lastUpdated: '' } },
55
+ currentModel: null
56
+ };
57
+
58
+ const agents = new Map();
59
+ agents.set('agent-sender', senderAgent);
60
+ agents.set('agent-recipient', recipientAgent);
61
+
62
+ const agentPool = {
63
+ getAgent: jest.fn((id) => Promise.resolve(agents.get(id) || null)),
64
+ listActiveAgents: jest.fn().mockResolvedValue([senderAgent, recipientAgent]),
65
+ notifyAgent: jest.fn().mockResolvedValue(undefined),
66
+ persistAgentState: jest.fn().mockResolvedValue(undefined),
67
+ updateAgent: jest.fn().mockResolvedValue(undefined),
68
+ addInterAgentMessage: jest.fn().mockResolvedValue(undefined)
69
+ };
70
+
71
+ const context = {
72
+ agentId: 'agent-sender',
73
+ agentPool,
74
+ projectDir: '/tmp/test'
75
+ };
76
+
77
+ return { tool, senderAgent, recipientAgent, agentPool, context, logger };
78
+ }
79
+
80
+ describe('AgentCommunicationTool', () => {
81
+ // ── constructor ─────────────────────────────────────────────────
82
+ describe('constructor', () => {
83
+ test('initializes with default config values', () => {
84
+ const tool = new AgentCommunicationTool();
85
+ expect(tool.config.maxConversationDepth).toBe(10);
86
+ expect(tool.config.maxRecipientsPerMessage).toBe(3);
87
+ expect(tool.messages).toBeInstanceOf(Map);
88
+ expect(tool.conversations).toBeInstanceOf(Map);
89
+ });
90
+
91
+ test('accepts custom config overrides', () => {
92
+ const tool = new AgentCommunicationTool({ maxConversationDepth: 5 });
93
+ expect(tool.config.maxConversationDepth).toBe(5);
94
+ });
95
+ });
96
+
97
+ // ── getDescription ──────────────────────────────────────────────
98
+ describe('getDescription', () => {
99
+ test('returns description with action list', () => {
100
+ const tool = new AgentCommunicationTool();
101
+ const desc = tool.getDescription();
102
+ expect(desc).toContain('get-available-agents');
103
+ expect(desc).toContain('send-message');
104
+ expect(desc).toContain('reply-to-message');
105
+ });
106
+ });
107
+
108
+ // ── parseParameters ─────────────────────────────────────────────
109
+ describe('parseParameters', () => {
110
+ test('parses object with actions array', () => {
111
+ const tool = new AgentCommunicationTool();
112
+ const result = tool.parseParameters({
113
+ actions: [{ type: 'get-available-agents' }]
114
+ });
115
+ expect(result.action).toBe('get-available-agents');
116
+ });
117
+
118
+ test('parses object with action field', () => {
119
+ const tool = new AgentCommunicationTool();
120
+ const result = tool.parseParameters({ action: 'send-message', subject: 'Hi' });
121
+ expect(result.action).toBe('send-message');
122
+ });
123
+
124
+ test('parses JSON string', () => {
125
+ const tool = new AgentCommunicationTool();
126
+ const result = tool.parseParameters('{"action": "get-available-agents"}');
127
+ expect(result.action).toBe('get-available-agents');
128
+ });
129
+
130
+ test('parses XML-style content', () => {
131
+ const tool = new AgentCommunicationTool();
132
+ const result = tool.parseParameters('<action>send-message</action><subject>Hello</subject>');
133
+ expect(result.action).toBe('send-message');
134
+ expect(result.subject).toBe('Hello');
135
+ });
136
+
137
+ test('returns empty object for null input', () => {
138
+ const tool = new AgentCommunicationTool();
139
+ const result = tool.parseParameters(null);
140
+ expect(result).toEqual({});
141
+ });
142
+ });
143
+
144
+ // ── execute - missing action ────────────────────────────────────
145
+ describe('execute - missing params', () => {
146
+ test('throws when action is missing', async () => {
147
+ const { tool, context } = createTestSetup();
148
+ await expect(tool.execute({}, context)).rejects.toThrow('Action parameter is required');
149
+ });
150
+
151
+ test('throws when agentId is missing from context', async () => {
152
+ const { tool } = createTestSetup();
153
+ await expect(tool.execute({ action: 'get-available-agents' }, {}))
154
+ .rejects.toThrow('Agent ID is required');
155
+ });
156
+
157
+ test('throws for unknown action', async () => {
158
+ const { tool, context } = createTestSetup();
159
+ await expect(tool.execute({ action: 'teleport' }, context))
160
+ .rejects.toThrow('Unknown action');
161
+ });
162
+
163
+ test('REGRESSION: {actions:[{type}]} (no top-level action) is recovered, not rejected', async () => {
164
+ // Users hit "first call rejected for missing parameter, second
165
+ // works with same syntax". Root cause: when the LLM nested the
166
+ // actions array inside a `parameters` wrapper, tagParser passed
167
+ // through `{actions: [{type: "get-available-agents"}]}` without
168
+ // hoisting the action up. This pinned the recovery path.
169
+ const { tool, context } = createTestSetup();
170
+ const result = await tool.execute(
171
+ { actions: [{ type: 'get-available-agents' }] },
172
+ context,
173
+ );
174
+ expect(result.success).toBe(true);
175
+ expect(result.agents).toHaveLength(1);
176
+ });
177
+
178
+ test('REGRESSION: {actions:[{type,recipient,...}]} hoists fields too', async () => {
179
+ // Make sure the recovery path also surfaces send-message params
180
+ // (recipient, subject, message) when nested inside actions[0].
181
+ const { tool, context } = createTestSetup();
182
+ const result = await tool.execute(
183
+ {
184
+ actions: [{
185
+ type: 'send-message',
186
+ recipient: 'agent-recipient',
187
+ subject: 'Hi',
188
+ message: 'Hello world',
189
+ }],
190
+ },
191
+ context,
192
+ );
193
+ expect(result.success).toBe(true);
194
+ expect(result.messageId).toBeDefined();
195
+ expect(result.recipients).toEqual(['agent-recipient']);
196
+ });
197
+ });
198
+
199
+ // ── get-available-agents ────────────────────────────────────────
200
+ describe('execute - get-available-agents', () => {
201
+ test('returns list excluding requesting agent', async () => {
202
+ const { tool, context } = createTestSetup();
203
+ const result = await tool.execute({ action: 'get-available-agents' }, context);
204
+ expect(result.success).toBe(true);
205
+ expect(result.agents).toHaveLength(1);
206
+ expect(result.agents[0].id).toBe('agent-recipient');
207
+ });
208
+
209
+ test('includes message stats for each agent', async () => {
210
+ const { tool, context } = createTestSetup();
211
+ const result = await tool.execute({ action: 'get-available-agents' }, context);
212
+ expect(result.agents[0].messageStats).toBeDefined();
213
+ });
214
+
215
+ test('returns error when agentPool missing', async () => {
216
+ const { tool } = createTestSetup();
217
+ const result = await tool.execute(
218
+ { action: 'get-available-agents' },
219
+ { agentId: 'agent-sender', agentPool: null }
220
+ );
221
+ // Should catch internally and return success: false
222
+ expect(result.success).toBe(false);
223
+ expect(result.error).toBeDefined();
224
+ });
225
+ });
226
+
227
+ // ── send-message ────────────────────────────────────────────────
228
+ describe('execute - send-message', () => {
229
+ test('sends message to recipient successfully', async () => {
230
+ const { tool, context } = createTestSetup();
231
+ const result = await tool.execute({
232
+ action: 'send-message',
233
+ recipient: 'agent-recipient',
234
+ subject: 'Review code',
235
+ message: 'Please review the auth module'
236
+ }, context);
237
+ expect(result.success).toBe(true);
238
+ expect(result.messageId).toBeDefined();
239
+ expect(result.conversationId).toBeDefined();
240
+ expect(result.recipients).toContain('agent-recipient');
241
+ });
242
+
243
+ test('errors when subject is missing', async () => {
244
+ const { tool, context } = createTestSetup();
245
+ const result = await tool.execute({
246
+ action: 'send-message',
247
+ recipient: 'agent-recipient',
248
+ message: 'No subject'
249
+ }, context);
250
+ expect(result.success).toBe(false);
251
+ expect(result.error).toContain('Subject and message are required');
252
+ });
253
+
254
+ test('errors when message is missing', async () => {
255
+ const { tool, context } = createTestSetup();
256
+ const result = await tool.execute({
257
+ action: 'send-message',
258
+ recipient: 'agent-recipient',
259
+ subject: 'No body'
260
+ }, context);
261
+ expect(result.success).toBe(false);
262
+ });
263
+
264
+ test('errors when no recipient provided', async () => {
265
+ const { tool, context } = createTestSetup();
266
+ const result = await tool.execute({
267
+ action: 'send-message',
268
+ subject: 'Test',
269
+ message: 'Hello'
270
+ }, context);
271
+ expect(result.success).toBe(false);
272
+ expect(result.error).toContain('At least one recipient');
273
+ });
274
+
275
+ test('returns suggestions when recipient not found', async () => {
276
+ const { tool, context, agentPool } = createTestSetup();
277
+ // Mock _canSendMessage to allow (bypass delay check)
278
+ tool._canSendMessage = jest.fn().mockResolvedValue({ allowed: true });
279
+ const result = await tool.execute({
280
+ action: 'send-message',
281
+ recipient: 'agent-nonexistent',
282
+ subject: 'Test',
283
+ message: 'Hello'
284
+ }, context);
285
+ expect(result.success).toBe(false);
286
+ expect(result.suggestion).toBeDefined();
287
+ });
288
+
289
+ test('updates message counts after sending', async () => {
290
+ const { tool, context } = createTestSetup();
291
+ await tool.execute({
292
+ action: 'send-message',
293
+ recipient: 'agent-recipient',
294
+ subject: 'Test',
295
+ message: 'Content'
296
+ }, context);
297
+ const senderStats = tool.agentMessageCounts.get('agent-sender');
298
+ expect(senderStats.sent).toBe(1);
299
+ });
300
+ });
301
+
302
+ // ── reply-to-message ────────────────────────────────────────────
303
+ describe('execute - reply-to-message', () => {
304
+ test('replies to an existing message', async () => {
305
+ const { tool, context } = createTestSetup();
306
+ // Send initial message
307
+ const sendResult = await tool.execute({
308
+ action: 'send-message',
309
+ recipient: 'agent-recipient',
310
+ subject: 'Question',
311
+ message: 'What is the status?'
312
+ }, context);
313
+ const msgId = sendResult.messageId;
314
+
315
+ // Reply as recipient
316
+ const replyResult = await tool.execute({
317
+ action: 'reply-to-message',
318
+ 'message-id': msgId,
319
+ message: 'All good!'
320
+ }, { agentId: 'agent-recipient', agentPool: context.agentPool });
321
+ expect(replyResult.success).toBe(true);
322
+ expect(replyResult.depth).toBe(1);
323
+ });
324
+
325
+ test('errors when original message ID missing', async () => {
326
+ const { tool, context } = createTestSetup();
327
+ const result = await tool.execute({
328
+ action: 'reply-to-message',
329
+ message: 'Reply without ID'
330
+ }, context);
331
+ expect(result.success).toBe(false);
332
+ expect(result.error).toContain('Original message ID and reply content are required');
333
+ });
334
+
335
+ test('errors when original message not found', async () => {
336
+ const { tool, context } = createTestSetup();
337
+ const result = await tool.execute({
338
+ action: 'reply-to-message',
339
+ 'message-id': 'msg-nonexistent',
340
+ message: 'Reply'
341
+ }, context);
342
+ expect(result.success).toBe(false);
343
+ expect(result.error).toContain('Original message not found');
344
+ });
345
+
346
+ test('errors when sender is not a participant', async () => {
347
+ const { tool, context, agentPool } = createTestSetup();
348
+ // Send message between sender and recipient
349
+ const sendResult = await tool.execute({
350
+ action: 'send-message',
351
+ recipient: 'agent-recipient',
352
+ subject: 'Private',
353
+ message: 'Secret'
354
+ }, context);
355
+
356
+ // Try to reply as an outsider
357
+ const outsider = {
358
+ id: 'agent-outsider', name: 'Outsider', conversations: { full: { messages: [] } }
359
+ };
360
+ agentPool.getAgent.mockImplementation((id) => {
361
+ if (id === 'agent-outsider') return Promise.resolve(outsider);
362
+ if (id === 'agent-sender') return Promise.resolve(context.agentPool);
363
+ return Promise.resolve(null);
364
+ });
365
+
366
+ const result = await tool.execute({
367
+ action: 'reply-to-message',
368
+ 'message-id': sendResult.messageId,
369
+ message: 'Eavesdrop'
370
+ }, { agentId: 'agent-outsider', agentPool });
371
+ expect(result.success).toBe(false);
372
+ expect(result.error).toContain('not a participant');
373
+ });
374
+
375
+ test('rejects reply when conversation depth limit reached', async () => {
376
+ const { tool, context } = createTestSetup();
377
+ tool.config.maxConversationDepth = 1;
378
+
379
+ const sendResult = await tool.execute({
380
+ action: 'send-message',
381
+ recipient: 'agent-recipient',
382
+ subject: 'Deep',
383
+ message: 'Start'
384
+ }, context);
385
+
386
+ // First reply (depth 1) - should succeed
387
+ const reply1 = await tool.execute({
388
+ action: 'reply-to-message',
389
+ 'message-id': sendResult.messageId,
390
+ message: 'Reply 1'
391
+ }, { agentId: 'agent-recipient', agentPool: context.agentPool });
392
+ expect(reply1.success).toBe(true);
393
+
394
+ // Second reply (depth 2) should fail at depth limit 1
395
+ const reply2 = await tool.execute({
396
+ action: 'reply-to-message',
397
+ 'message-id': reply1.messageId,
398
+ message: 'Reply 2'
399
+ }, context);
400
+ expect(reply2.success).toBe(false);
401
+ expect(reply2.error).toContain('depth limit');
402
+ });
403
+ });
404
+
405
+ // ── get-unreplied-messages ──────────────────────────────────────
406
+ describe('execute - get-unreplied-messages', () => {
407
+ test('returns unreplied messages for agent', async () => {
408
+ const { tool, context } = createTestSetup();
409
+ // Send message requiring reply
410
+ await tool.execute({
411
+ action: 'send-message',
412
+ recipient: 'agent-recipient',
413
+ subject: 'Need reply',
414
+ message: 'Please respond',
415
+ 'requires-reply': true
416
+ }, context);
417
+
418
+ const result = await tool.execute(
419
+ { action: 'get-unreplied-messages' },
420
+ { agentId: 'agent-recipient', agentPool: context.agentPool }
421
+ );
422
+ expect(result.success).toBe(true);
423
+ expect(result.messages.length).toBeGreaterThan(0);
424
+ expect(result.messages[0].subject).toBe('Need reply');
425
+ });
426
+
427
+ test('returns empty list when no messages', async () => {
428
+ const { tool, context } = createTestSetup();
429
+ const result = await tool.execute(
430
+ { action: 'get-unreplied-messages' },
431
+ { agentId: 'agent-recipient', agentPool: context.agentPool }
432
+ );
433
+ expect(result.success).toBe(true);
434
+ expect(result.messages).toHaveLength(0);
435
+ });
436
+ });
437
+
438
+ // ── mark-conversation-ended ─────────────────────────────────────
439
+ describe('execute - mark-conversation-ended', () => {
440
+ test('ends a conversation successfully', async () => {
441
+ const { tool, context } = createTestSetup();
442
+ const sendResult = await tool.execute({
443
+ action: 'send-message',
444
+ recipient: 'agent-recipient',
445
+ subject: 'End me',
446
+ message: 'Done'
447
+ }, context);
448
+
449
+ const result = await tool.execute({
450
+ action: 'mark-conversation-ended',
451
+ 'conversation-id': sendResult.conversationId,
452
+ reason: 'Work complete'
453
+ }, context);
454
+ expect(result.success).toBe(true);
455
+ expect(result.status).toBe('ended');
456
+ });
457
+
458
+ test('errors when conversation-id is missing', async () => {
459
+ const { tool, context } = createTestSetup();
460
+ const result = await tool.execute(
461
+ { action: 'mark-conversation-ended' }, context
462
+ );
463
+ expect(result.success).toBe(false);
464
+ expect(result.error).toContain('Conversation ID is required');
465
+ });
466
+
467
+ test('errors for non-existent conversation', async () => {
468
+ const { tool, context } = createTestSetup();
469
+ const result = await tool.execute({
470
+ action: 'mark-conversation-ended',
471
+ 'conversation-id': 'conv-nope'
472
+ }, context);
473
+ expect(result.success).toBe(false);
474
+ expect(result.error).toContain('Conversation not found');
475
+ });
476
+
477
+ test('errors when agent is not a participant', async () => {
478
+ const { tool, context, agentPool } = createTestSetup();
479
+ const sendResult = await tool.execute({
480
+ action: 'send-message',
481
+ recipient: 'agent-recipient',
482
+ subject: 'Private',
483
+ message: 'Content'
484
+ }, context);
485
+
486
+ const result = await tool.execute({
487
+ action: 'mark-conversation-ended',
488
+ 'conversation-id': sendResult.conversationId
489
+ }, { agentId: 'agent-outsider', agentPool });
490
+ expect(result.success).toBe(false);
491
+ expect(result.error).toContain('not a participant');
492
+ });
493
+ });
494
+
495
+ // ── helper methods ──────────────────────────────────────────────
496
+ describe('_parseRecipients', () => {
497
+ test('parses single recipient string', () => {
498
+ const tool = new AgentCommunicationTool();
499
+ const result = tool._parseRecipients('agent-1', null);
500
+ expect(result).toEqual(['agent-1']);
501
+ });
502
+
503
+ test('parses JSON array of recipients', () => {
504
+ const tool = new AgentCommunicationTool();
505
+ const result = tool._parseRecipients(null, '["agent-1", "agent-2"]');
506
+ expect(result).toEqual(['agent-1', 'agent-2']);
507
+ });
508
+
509
+ test('handles array recipients directly', () => {
510
+ const tool = new AgentCommunicationTool();
511
+ const result = tool._parseRecipients(null, ['agent-1', 'agent-2']);
512
+ expect(result).toEqual(['agent-1', 'agent-2']);
513
+ });
514
+
515
+ test('deduplicates recipients', () => {
516
+ const tool = new AgentCommunicationTool();
517
+ const result = tool._parseRecipients('agent-1', ['agent-1', 'agent-2']);
518
+ expect(result).toEqual(['agent-1', 'agent-2']);
519
+ });
520
+
521
+ test('handles non-JSON string as single recipient', () => {
522
+ const tool = new AgentCommunicationTool();
523
+ const result = tool._parseRecipients(null, 'plain-id');
524
+ expect(result).toEqual(['plain-id']);
525
+ });
526
+ });
527
+
528
+ describe('_processAttachments', () => {
529
+ test('returns empty array for null/undefined', async () => {
530
+ const tool = new AgentCommunicationTool();
531
+ expect(await tool._processAttachments(null, 'agent-1')).toEqual([]);
532
+ expect(await tool._processAttachments(undefined, 'agent-1')).toEqual([]);
533
+ });
534
+ });
535
+
536
+ // ─── Team affiliation in get-available-agents ─────────────────────────
537
+
538
+ describe('team affiliation', () => {
539
+ function createTeamSetup(senderMeta, agentsMeta) {
540
+ const tool = new AgentCommunicationTool({ storageDir: '/tmp/msg-test' });
541
+ tool.logger = createMockLogger();
542
+
543
+ const sender = {
544
+ id: 'agent-mgr', name: 'Manager', type: 'manager', capabilities: [],
545
+ status: 'active', isPaused: false, metadata: senderMeta
546
+ };
547
+ const allAgents = [sender, ...agentsMeta.map((meta, i) => ({
548
+ id: `agent-${i}`, name: `Agent ${i}`, type: 'worker', capabilities: ['code'],
549
+ status: 'active', isPaused: false, metadata: meta
550
+ }))];
551
+ const agentPool = {
552
+ listActiveAgents: jest.fn().mockResolvedValue(allAgents),
553
+ getAgent: jest.fn(id => Promise.resolve(allAgents.find(a => a.id === id)))
554
+ };
555
+ return { tool, agentPool, context: { agentPool, agentId: 'agent-mgr' } };
556
+ }
557
+
558
+ test('sameTeam is true when agents share a team (new format)', async () => {
559
+ const { tool, context } = createTeamSetup(
560
+ { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
561
+ [{ teams: [{ id: 'team-a', name: 'Alpha', role: 'member' }] }]
562
+ );
563
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
564
+ expect(result.success).toBe(true);
565
+ expect(result.agents[0].sameTeam).toBe(true);
566
+ expect(result.agents[0].sharedTeams).toContain('team-a');
567
+ });
568
+
569
+ test('sameTeam is false when agents are on different teams', async () => {
570
+ const { tool, context } = createTeamSetup(
571
+ { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
572
+ [{ teams: [{ id: 'team-b', name: 'Beta', role: 'member' }] }]
573
+ );
574
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
575
+ expect(result.agents[0].sameTeam).toBe(false);
576
+ expect(result.agents[0].sharedTeams).toEqual([]);
577
+ });
578
+
579
+ test('sameTeam works with legacy single teamId format', async () => {
580
+ const { tool, context } = createTeamSetup(
581
+ { teamId: 'team-x', teamName: 'X Team', teamRole: 'manager' },
582
+ [{ teamId: 'team-x', teamName: 'X Team', teamRole: 'member' }]
583
+ );
584
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
585
+ expect(result.agents[0].sameTeam).toBe(true);
586
+ expect(result.agents[0].sharedTeams).toContain('team-x');
587
+ });
588
+
589
+ test('agent with no team metadata has sameTeam=false and empty teams', async () => {
590
+ const { tool, context } = createTeamSetup(
591
+ { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
592
+ [{}] // no team metadata
593
+ );
594
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
595
+ expect(result.agents[0].sameTeam).toBe(false);
596
+ expect(result.agents[0].teams).toEqual([]);
597
+ expect(result.agents[0].sharedTeams).toEqual([]);
598
+ });
599
+
600
+ test('multi-team agent shares subset of teams', async () => {
601
+ const { tool, context } = createTeamSetup(
602
+ { teams: [{ id: 'team-a', role: 'manager' }, { id: 'team-b', role: 'manager' }] },
603
+ [{ teams: [{ id: 'team-b', role: 'member' }, { id: 'team-c', role: 'member' }] }]
604
+ );
605
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
606
+ expect(result.agents[0].sameTeam).toBe(true);
607
+ expect(result.agents[0].sharedTeams).toEqual(['team-b']);
608
+ expect(result.agents[0].teams).toHaveLength(2);
609
+ });
610
+
611
+ test('yourTeams reflects the requesting agent teams', async () => {
612
+ const { tool, context } = createTeamSetup(
613
+ { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }, { id: 'team-b', name: 'Beta', role: 'member' }] },
614
+ [{}]
615
+ );
616
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
617
+ expect(result.yourTeams).toHaveLength(2);
618
+ expect(result.yourTeams[0].id).toBe('team-a');
619
+ expect(result.yourTeams[1].id).toBe('team-b');
620
+ });
621
+
622
+ test('yourTeams is null when requesting agent has no teams', async () => {
623
+ const { tool, context } = createTeamSetup({}, [{}]);
624
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
625
+ expect(result.yourTeams).toBeNull();
626
+ });
627
+
628
+ test('teamRole is exposed in teams array', async () => {
629
+ const { tool, context } = createTeamSetup(
630
+ { teams: [{ id: 'team-a', name: 'Alpha', role: 'manager' }] },
631
+ [{ teams: [{ id: 'team-a', name: 'Alpha', role: 'member' }] }]
632
+ );
633
+ const result = await tool.getAvailableAgents('agent-mgr', {}, context);
634
+ expect(result.agents[0].teams[0].role).toBe('member');
635
+ expect(result.yourTeams[0].role).toBe('manager');
636
+ });
637
+ });
638
+
639
+ // Per-agent toolConfig overrides (agent.toolConfig.agentcommunication).
640
+ // Effective limits resolve via BaseTool#getEffectiveConfig at each
641
+ // check-point in the tool.
642
+ describe('per-agent toolConfig overrides', () => {
643
+ test('per-agent maxRecipientsPerMessage overrides global default', async () => {
644
+ const { tool, context } = createTestSetup();
645
+ // Global default = 3; per-agent override = 1 → sending to 2 must fail.
646
+ const result = await tool.sendMessage('agent-sender', {
647
+ recipients: ['agent-recipient', 'agent-other'],
648
+ subject: 's',
649
+ message: 'm',
650
+ }, { ...context, toolConfig: { maxRecipientsPerMessage: 1 } });
651
+ expect(result.success).toBe(false);
652
+ expect(result.error).toMatch(/Maximum 1 recipients allowed/);
653
+ });
654
+
655
+ test('global default still applies when no per-agent override', async () => {
656
+ const { tool, context } = createTestSetup();
657
+ // Global default = 3; 4 recipients fails without any override.
658
+ const result = await tool.sendMessage('agent-sender', {
659
+ recipients: ['a', 'b', 'c', 'd'],
660
+ subject: 's',
661
+ message: 'm',
662
+ }, context);
663
+ expect(result.success).toBe(false);
664
+ expect(result.error).toMatch(/Maximum 3 recipients allowed/);
665
+ });
666
+
667
+ test('per-agent maxAttachmentsPerMessage overrides global default', async () => {
668
+ const { tool, context } = createTestSetup();
669
+ const atts = [
670
+ { path: '/a.txt' },
671
+ { path: '/b.txt' },
672
+ { path: '/c.txt' },
673
+ ];
674
+ await expect(
675
+ tool._processAttachments(atts, 'agent-sender', { ...context, toolConfig: { maxAttachmentsPerMessage: 2 } })
676
+ ).rejects.toThrow(/Maximum 2 attachments allowed/);
677
+ });
678
+
679
+ test('per-agent maxAttachmentSize overrides global default', async () => {
680
+ const { tool, context } = createTestSetup();
681
+ // Stat returns size 100; override to 10 → too large. The tool's
682
+ // per-attachment try/catch swallows the error and just skips the
683
+ // attachment, so the emitted array is empty. We also assert the
684
+ // error was logged as proof the size gate actually fired.
685
+ fsMock.stat.mockResolvedValue({ size: 100 });
686
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
687
+ const out = await tool._processAttachments([{ path: '/big.txt' }], 'agent-sender', {
688
+ ...context,
689
+ toolConfig: { maxAttachmentSize: 10 },
690
+ });
691
+ expect(out).toEqual([]);
692
+ expect(errorSpy).toHaveBeenCalledWith(
693
+ expect.stringMatching(/Failed to process attachment/),
694
+ expect.objectContaining({ message: expect.stringMatching(/exceeds size limit/) })
695
+ );
696
+ errorSpy.mockRestore();
697
+ });
698
+
699
+ test('per-agent maxAttachmentSize ALLOWS attachments within limit', async () => {
700
+ const { tool, context } = createTestSetup();
701
+ fsMock.stat.mockResolvedValue({ size: 50 });
702
+ const out = await tool._processAttachments([{ path: '/small.txt' }], 'agent-sender', {
703
+ ...context,
704
+ toolConfig: { maxAttachmentSize: 1024 },
705
+ });
706
+ expect(out).toHaveLength(1);
707
+ });
708
+
709
+ test('per-agent maxConversationDepth caps reply chain', async () => {
710
+ // Start a fresh conversation with a per-agent cap of 1: the first
711
+ // reply goes through, the second hits the limit. Mirrors the
712
+ // existing "rejects reply when conversation depth limit reached"
713
+ // test but drives the cap from context.toolConfig instead of
714
+ // mutating tool.config.
715
+ const { tool, context } = createTestSetup();
716
+
717
+ const sendResult = await tool.execute({
718
+ action: 'send-message',
719
+ recipient: 'agent-recipient',
720
+ subject: 'Deep',
721
+ message: 'Start',
722
+ }, { ...context, toolConfig: { maxConversationDepth: 1 } });
723
+ expect(sendResult.success).toBe(true);
724
+
725
+ // First reply (depth 1) — should succeed even under the cap.
726
+ const reply1 = await tool.execute({
727
+ action: 'reply-to-message',
728
+ 'message-id': sendResult.messageId,
729
+ message: 'Reply 1',
730
+ }, { agentId: 'agent-recipient', agentPool: context.agentPool, toolConfig: { maxConversationDepth: 1 } });
731
+ expect(reply1.success).toBe(true);
732
+
733
+ // Second reply — depth now 1, cap is 1, must fail.
734
+ const reply2 = await tool.execute({
735
+ action: 'reply-to-message',
736
+ 'message-id': reply1.messageId,
737
+ message: 'Reply 2',
738
+ }, { ...context, toolConfig: { maxConversationDepth: 1 } });
739
+ expect(reply2.success).toBe(false);
740
+ expect(reply2.error).toMatch(/depth limit reached \(1\)/);
741
+ });
742
+
743
+ test('_processAttachments with no context uses global config (backward compat)', async () => {
744
+ const { tool } = createTestSetup();
745
+ // Global = 5; 4 atts → ok (stat mocked to size 100, global max = 10MB).
746
+ fsMock.stat.mockResolvedValue({ size: 100 });
747
+ const atts = [{ path: '/a.txt' }, { path: '/b.txt' }];
748
+ const out = await tool._processAttachments(atts, 'agent-sender');
749
+ expect(Array.isArray(out)).toBe(true);
750
+ });
751
+ });
752
+ });