onbuzz 4.9.13 → 4.10.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 (451) hide show
  1. package/node_modules/glob/README.md +31 -5
  2. package/node_modules/glob/dist/commonjs/glob.d.ts +8 -0
  3. package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
  4. package/node_modules/glob/dist/commonjs/glob.js +2 -1
  5. package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
  6. package/node_modules/glob/dist/commonjs/index.min.js +3 -3
  7. package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
  8. package/node_modules/glob/dist/commonjs/pattern.d.ts +3 -0
  9. package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
  10. package/node_modules/glob/dist/commonjs/pattern.js +4 -0
  11. package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
  12. package/node_modules/glob/dist/esm/glob.d.ts +8 -0
  13. package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
  14. package/node_modules/glob/dist/esm/glob.js +2 -1
  15. package/node_modules/glob/dist/esm/glob.js.map +1 -1
  16. package/node_modules/glob/dist/esm/index.min.js +3 -3
  17. package/node_modules/glob/dist/esm/index.min.js.map +4 -4
  18. package/node_modules/glob/dist/esm/pattern.d.ts +3 -0
  19. package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
  20. package/node_modules/glob/dist/esm/pattern.js +4 -0
  21. package/node_modules/glob/dist/esm/pattern.js.map +1 -1
  22. package/node_modules/{@isaacs → glob/node_modules}/balanced-match/README.md +7 -10
  23. package/node_modules/{@isaacs → glob/node_modules}/balanced-match/package.json +7 -18
  24. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/README.md +3 -6
  25. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.js +6 -4
  26. package/node_modules/glob/node_modules/brace-expansion/dist/commonjs/index.js.map +1 -0
  27. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.js +6 -4
  28. package/node_modules/glob/node_modules/brace-expansion/dist/esm/index.js.map +1 -0
  29. package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/package.json +11 -7
  30. package/node_modules/glob/node_modules/minimatch/README.md +76 -1
  31. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts +1 -1
  32. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.d.ts.map +1 -1
  33. package/node_modules/glob/node_modules/minimatch/dist/commonjs/assert-valid-pattern.js.map +1 -1
  34. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts +4 -2
  35. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.d.ts.map +1 -1
  36. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js +309 -55
  37. package/node_modules/glob/node_modules/minimatch/dist/commonjs/ast.js.map +1 -1
  38. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +1 -1
  39. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js +2 -4
  40. package/node_modules/glob/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +1 -1
  41. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts +1 -1
  42. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.d.ts.map +1 -1
  43. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js +4 -4
  44. package/node_modules/glob/node_modules/minimatch/dist/commonjs/escape.js.map +1 -1
  45. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts +81 -1
  46. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
  47. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js +232 -134
  48. package/node_modules/glob/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
  49. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts +1 -1
  50. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.d.ts.map +1 -1
  51. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js +8 -8
  52. package/node_modules/glob/node_modules/minimatch/dist/commonjs/unescape.js.map +1 -1
  53. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts +1 -1
  54. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.d.ts.map +1 -1
  55. package/node_modules/glob/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
  56. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts +4 -2
  57. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.d.ts.map +1 -1
  58. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js +309 -55
  59. package/node_modules/glob/node_modules/minimatch/dist/esm/ast.js.map +1 -1
  60. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +1 -1
  61. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js +2 -4
  62. package/node_modules/glob/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
  63. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts +1 -1
  64. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.d.ts.map +1 -1
  65. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js +4 -4
  66. package/node_modules/glob/node_modules/minimatch/dist/esm/escape.js.map +1 -1
  67. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts +81 -1
  68. package/node_modules/glob/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
  69. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js +232 -134
  70. package/node_modules/glob/node_modules/minimatch/dist/esm/index.js.map +1 -1
  71. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts +1 -1
  72. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.d.ts.map +1 -1
  73. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js +8 -8
  74. package/node_modules/glob/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
  75. package/node_modules/glob/node_modules/minimatch/package.json +17 -11
  76. package/node_modules/glob/package.json +10 -13
  77. package/node_modules/minipass/LICENSE.md +55 -0
  78. package/node_modules/minipass/dist/commonjs/index.d.ts +12 -16
  79. package/node_modules/minipass/dist/commonjs/index.d.ts.map +1 -1
  80. package/node_modules/minipass/dist/commonjs/index.js +13 -3
  81. package/node_modules/minipass/dist/commonjs/index.js.map +1 -1
  82. package/node_modules/minipass/dist/esm/index.d.ts +12 -16
  83. package/node_modules/minipass/dist/esm/index.d.ts.map +1 -1
  84. package/node_modules/minipass/dist/esm/index.js +3 -1
  85. package/node_modules/minipass/dist/esm/index.js.map +1 -1
  86. package/node_modules/minipass/package.json +9 -14
  87. package/node_modules/path-scurry/node_modules/lru-cache/README.md +96 -10
  88. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.d.ts.map +1 -0
  89. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel-browser.js.map +1 -0
  90. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.d.ts +5 -0
  91. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/diagnostics-channel.js +7 -0
  92. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts +1400 -0
  93. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.d.ts.map +1 -0
  94. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js +1726 -0
  95. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.js.map +1 -0
  96. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js +2 -0
  97. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/index.min.js.map +7 -0
  98. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts +12 -0
  99. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.d.ts.map +1 -0
  100. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js +10 -0
  101. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/browser/perf.js.map +1 -0
  102. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.cjs.map +1 -0
  103. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel-cjs.d.cts.map +1 -0
  104. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.d.ts +5 -0
  105. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/diagnostics-channel.js +7 -0
  106. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts +109 -32
  107. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.d.ts.map +1 -1
  108. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js +334 -197
  109. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.js.map +1 -1
  110. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js +1 -1
  111. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/index.min.js.map +4 -4
  112. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.d.ts.map +1 -0
  113. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel-node.js.map +1 -0
  114. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.d.ts +5 -0
  115. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/diagnostics-channel.js +9 -0
  116. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts +1400 -0
  117. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.d.ts.map +1 -0
  118. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js +1726 -0
  119. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.js.map +1 -0
  120. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js +2 -0
  121. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/index.min.js.map +7 -0
  122. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts +12 -0
  123. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.d.ts.map +1 -0
  124. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js +10 -0
  125. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/node/perf.js.map +1 -0
  126. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts +12 -0
  127. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.d.ts.map +1 -0
  128. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js +10 -0
  129. package/node_modules/path-scurry/node_modules/lru-cache/dist/commonjs/perf.js.map +1 -0
  130. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.d.ts.map +1 -0
  131. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel-browser.js.map +1 -0
  132. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.d.ts +5 -0
  133. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/diagnostics-channel.js +4 -0
  134. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts +1400 -0
  135. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.d.ts.map +1 -0
  136. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js +1722 -0
  137. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.js.map +1 -0
  138. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js +2 -0
  139. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/index.min.js.map +7 -0
  140. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts +12 -0
  141. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.d.ts.map +1 -0
  142. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js +7 -0
  143. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/browser/perf.js.map +1 -0
  144. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.d.mts.map +1 -0
  145. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel-esm.mjs.map +1 -0
  146. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.d.ts +5 -0
  147. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/diagnostics-channel.js +19 -0
  148. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts +109 -32
  149. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.d.ts.map +1 -1
  150. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js +333 -196
  151. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.js.map +1 -1
  152. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js +1 -1
  153. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/index.min.js.map +4 -4
  154. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.d.ts.map +1 -0
  155. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel-node.js.map +1 -0
  156. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.d.ts +5 -0
  157. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/diagnostics-channel.js +6 -0
  158. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts +1400 -0
  159. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.d.ts.map +1 -0
  160. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js +1722 -0
  161. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.js.map +1 -0
  162. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js +2 -0
  163. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/index.min.js.map +7 -0
  164. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts +12 -0
  165. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.d.ts.map +1 -0
  166. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js +7 -0
  167. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/node/perf.js.map +1 -0
  168. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts +12 -0
  169. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.d.ts.map +1 -0
  170. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js +7 -0
  171. package/node_modules/path-scurry/node_modules/lru-cache/dist/esm/perf.js.map +1 -0
  172. package/node_modules/path-scurry/node_modules/lru-cache/package.json +71 -18
  173. package/node_modules/path-scurry/package.json +8 -24
  174. package/package.json +1 -1
  175. package/scripts/debug-balance-probe.mjs +35 -35
  176. package/scripts/push-image.sh +43 -43
  177. package/scripts/setup-acr.sh +65 -65
  178. package/scripts/verify-optional-deps.js +96 -1
  179. package/src/__tests__/composioCliFlags.test.js +239 -239
  180. package/src/analyzers/CSSAnalyzer.js +298 -297
  181. package/src/analyzers/ConfigValidator.js +691 -690
  182. package/src/analyzers/ESLintAnalyzer.js +320 -320
  183. package/src/analyzers/JavaScriptAnalyzer.js +260 -261
  184. package/src/analyzers/PrettierFormatter.js +246 -247
  185. package/src/analyzers/PythonAnalyzer.js +283 -283
  186. package/src/analyzers/SecurityAnalyzer.js +729 -729
  187. package/src/analyzers/SparrowAnalyzer.js +341 -341
  188. package/src/analyzers/TypeScriptAnalyzer.js +247 -247
  189. package/src/analyzers/__tests__/CSSAnalyzer.test.js +41 -41
  190. package/src/analyzers/__tests__/ConfigValidator.test.js +362 -362
  191. package/src/analyzers/__tests__/JavaScriptAnalyzer.test.js +40 -40
  192. package/src/analyzers/__tests__/PythonAnalyzer.test.js +205 -208
  193. package/src/analyzers/__tests__/SecurityAnalyzer.test.js +303 -303
  194. package/src/analyzers/__tests__/TypeScriptAnalyzer.test.js +187 -187
  195. package/src/analyzers/codeCloneDetector/analyzer.js +344 -344
  196. package/src/analyzers/codeCloneDetector/detector.js +250 -250
  197. package/src/analyzers/codeCloneDetector/index.js +194 -192
  198. package/src/analyzers/codeCloneDetector/parser.js +199 -199
  199. package/src/core/__tests__/agentPool.test.js +866 -866
  200. package/src/core/__tests__/agentPoolAutoResume.test.js +209 -209
  201. package/src/core/__tests__/agentPoolWakeOnMessage.test.js +315 -315
  202. package/src/core/__tests__/agentScheduler.emptyResponseChatStall.test.js +213 -213
  203. package/src/core/__tests__/agentScheduler.errorCategorisation.test.js +246 -246
  204. package/src/core/__tests__/agentScheduler.firstChunkTimeout.test.js +138 -138
  205. package/src/core/__tests__/agentScheduler.modeTransitions.test.js +233 -233
  206. package/src/core/__tests__/agentScheduler.nativePromptPick.test.js +319 -319
  207. package/src/core/__tests__/agentScheduler.taskLifecycleInstruction.test.js +78 -78
  208. package/src/core/__tests__/agentScheduler.visualizer.test.js +258 -258
  209. package/src/core/__tests__/flowCheckpointStore.test.js +140 -140
  210. package/src/core/__tests__/flowEndToEnd.test.js +565 -565
  211. package/src/core/__tests__/flowFieldMapping.test.js +188 -189
  212. package/src/core/__tests__/flowLintClientMirror.test.js +96 -98
  213. package/src/core/__tests__/flowSavePayload.test.js +170 -169
  214. package/src/core/__tests__/flowTemplates.test.js +311 -311
  215. package/src/core/__tests__/flowVersionStore.test.js +123 -123
  216. package/src/core/__tests__/messageProcessor.test.js +669 -669
  217. package/src/core/__tests__/stateManager.test.js +0 -1
  218. package/src/core/agentPool.js +2474 -2475
  219. package/src/core/agentScheduler.js +1 -4
  220. package/src/core/contextManager.js +708 -708
  221. package/src/core/flowExecutor.js +1510 -1510
  222. package/src/core/flowFieldMapping.js +136 -138
  223. package/src/core/messageProcessor.js +953 -954
  224. package/src/core/orchestrator.js +593 -595
  225. package/src/core/stateManager.js +1765 -1752
  226. package/src/index.js +1221 -1221
  227. package/src/interfaces/__tests__/archivedAgentDelete.test.js +207 -207
  228. package/src/interfaces/__tests__/bulkAgentRoute.test.js +361 -361
  229. package/src/interfaces/__tests__/imageServing.test.js +228 -228
  230. package/src/interfaces/__tests__/remoteSessionAuth.test.js +308 -308
  231. package/src/interfaces/__tests__/videoJobsRoutes.test.js +178 -179
  232. package/src/interfaces/__tests__/webServer.marketplace.test.js +629 -629
  233. package/src/interfaces/schedulerRoutes.js +50 -50
  234. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +341 -350
  235. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +156 -156
  236. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +325 -330
  237. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +385 -388
  238. package/src/interfaces/terminal/api/session.js +265 -266
  239. package/src/interfaces/terminal/api/websocket.js +496 -497
  240. package/src/interfaces/terminal/components/AgentCreator.js +691 -705
  241. package/src/interfaces/terminal/components/AgentEditor.js +676 -678
  242. package/src/interfaces/terminal/components/AgentSwitcher.js +331 -330
  243. package/src/interfaces/terminal/components/ErrorPanel.js +263 -264
  244. package/src/interfaces/terminal/components/Header.js +28 -28
  245. package/src/interfaces/terminal/components/Layout.js +598 -603
  246. package/src/interfaces/terminal/components/MessageList.js +280 -281
  247. package/src/interfaces/terminal/components/SettingsPanel.js +410 -415
  248. package/src/interfaces/terminal/components/StatusBar.js +2 -0
  249. package/src/interfaces/terminal/index.js +168 -168
  250. package/src/interfaces/terminal/state/useAgentControl.js +496 -496
  251. package/src/interfaces/terminal/state/useAgents.js +537 -537
  252. package/src/interfaces/terminal/state/useMessages.js +629 -630
  253. package/src/interfaces/terminal/state/useTools.js +554 -554
  254. package/src/interfaces/terminal/utils/debugLogger.js +44 -44
  255. package/src/interfaces/terminal/utils/settingsStorage.js +232 -232
  256. package/src/interfaces/webServer.js +7578 -7579
  257. package/src/interfaces/webServer.js.bak +7046 -7046
  258. package/src/modules/fileExplorer/__tests__/zipDownload.test.js +237 -237
  259. package/src/modules/fileExplorer/controller.js +470 -469
  260. package/src/modules/fileExplorer/routes.js +285 -286
  261. package/src/modules/widget/__tests__/isDisabled.test.js +41 -41
  262. package/src/modules/widget/__tests__/routes.test.js +677 -678
  263. package/src/modules/widget/__tests__/runtime.test.js +401 -401
  264. package/src/modules/widget/__tests__/versioning.test.js +309 -309
  265. package/src/modules/widget/__tests__/webComponentRuntime.test.js +565 -565
  266. package/src/modules/widget/__tests__/widgetTool.test.js +316 -316
  267. package/src/modules/widget/routes.js +435 -435
  268. package/src/modules/widget/runtime/bundle.js +640 -640
  269. package/src/modules/widget/runtime/webComponentBundle.js +470 -470
  270. package/src/modules/widget/schema.js +182 -181
  271. package/src/modules/widget/widgetTool.js +1389 -1389
  272. package/src/services/__tests__/agentActivityService.test.js +401 -402
  273. package/src/services/__tests__/benchmarkService.test.js +184 -184
  274. package/src/services/__tests__/contextInjectionService.test.js +246 -246
  275. package/src/services/__tests__/conversationQuery.test.js +721 -723
  276. package/src/services/__tests__/credentialVault.test.js +469 -469
  277. package/src/services/__tests__/discordService.integration.test.js +638 -639
  278. package/src/services/__tests__/flowContextService.test.js +590 -590
  279. package/src/services/__tests__/memoryService.test.js +1 -1
  280. package/src/services/__tests__/messageSource.test.js +380 -380
  281. package/src/services/__tests__/modelRouterNaming.test.js +111 -111
  282. package/src/services/__tests__/projectDetector.test.js +34 -34
  283. package/src/services/__tests__/promptService.test.js +242 -242
  284. package/src/services/__tests__/telegramService.test.js +941 -941
  285. package/src/services/__tests__/tokenCountingService.test.js +48 -48
  286. package/src/services/agentActivityService.js +419 -420
  287. package/src/services/aiService.js +2997 -3001
  288. package/src/services/apiKeyManager.js +359 -359
  289. package/src/services/benchmarkService.js +196 -196
  290. package/src/services/codebaseKnowledgeService.js +2 -2
  291. package/src/services/composioService.js +738 -738
  292. package/src/services/conversationCompactionService.js +1258 -1257
  293. package/src/services/credentialVault.js +685 -685
  294. package/src/services/discordService.js +792 -793
  295. package/src/services/embeddings/__tests__/azureCustomProvider.test.js +232 -232
  296. package/src/services/embeddings/__tests__/embeddingService.test.js +417 -417
  297. package/src/services/embeddings/__tests__/localProvider.test.js +263 -263
  298. package/src/services/embeddings/autoRecall.js +218 -219
  299. package/src/services/embeddings/indexers/__tests__/agentIndexer.test.js +232 -232
  300. package/src/services/embeddings/indexers/__tests__/memoryIndexer.test.js +418 -418
  301. package/src/services/embeddings/indexers/__tests__/reminisceIndexer.test.js +356 -357
  302. package/src/services/embeddings/indexers/__tests__/skillsIndexer.test.js +145 -145
  303. package/src/services/embeddings/indexers/__tests__/taskIndexer.test.js +146 -146
  304. package/src/services/embeddings/indexers/composioIndexer.js +279 -279
  305. package/src/services/embeddings/providerInterface.js +206 -206
  306. package/src/services/embeddings/providers/localProvider.js +11 -7
  307. package/src/services/embeddings/providers/openaiProvider.js +101 -101
  308. package/src/services/embeddings/vectorStore/inMemoryJsonStore.js +356 -356
  309. package/src/services/errorHandler.js +809 -809
  310. package/src/services/flowContextService.js +586 -586
  311. package/src/services/grounding/MockAdapter.js +125 -125
  312. package/src/services/modelRouterService.js +26 -31
  313. package/src/services/modelsService.js +322 -322
  314. package/src/services/ollamaService.js +452 -452
  315. package/src/services/projectDetector.js +403 -404
  316. package/src/services/promptService.js +418 -418
  317. package/src/services/qualityInspector.js +795 -795
  318. package/src/services/scheduleService.js +726 -726
  319. package/src/services/serviceRegistry.js +386 -386
  320. package/src/services/telegrafBot.js +174 -174
  321. package/src/services/telegramService.js +1972 -1972
  322. package/src/services/visualEditorBridge.js +1033 -1033
  323. package/src/services/visualEditorServer.js +1769 -1774
  324. package/src/services/whatsappService.js +667 -668
  325. package/src/tools/__tests__/agentCommunicationTool.findAgent.test.js +226 -226
  326. package/src/tools/__tests__/agentCommunicationTool.test.js +3 -3
  327. package/src/tools/__tests__/agentDelayTool.test.js +342 -342
  328. package/src/tools/__tests__/baseTool.test.js +3 -3
  329. package/src/tools/__tests__/codeMapTool.test.js +915 -915
  330. package/src/tools/__tests__/fileContentReplaceTool.test.js +309 -309
  331. package/src/tools/__tests__/fileTreeTool.test.js +274 -274
  332. package/src/tools/__tests__/filesystemTool.test.js +815 -815
  333. package/src/tools/__tests__/foundryWebSearchTool.test.js +252 -252
  334. package/src/tools/__tests__/imageTool.validator.test.js +194 -194
  335. package/src/tools/__tests__/jobDoneTool.test.js +580 -581
  336. package/src/tools/__tests__/memoryTool.forgetStale.test.js +272 -272
  337. package/src/tools/__tests__/memoryTool.reminisce.test.js +2 -2
  338. package/src/tools/__tests__/memoryTool.reminisceSemanticSearch.test.js +301 -301
  339. package/src/tools/__tests__/memoryTool.semanticSearch.test.js +405 -405
  340. package/src/tools/__tests__/memoryTool.teamPool.test.js +293 -293
  341. package/src/tools/__tests__/memoryTool.test.js +1 -1
  342. package/src/tools/__tests__/seekTool.test.js +282 -282
  343. package/src/tools/__tests__/skillsTool.search.test.js +164 -164
  344. package/src/tools/__tests__/skillsTool.test.js +226 -226
  345. package/src/tools/__tests__/staticAnalysisTool.test.js +509 -509
  346. package/src/tools/__tests__/taskManagerTool.discipline.test.js +137 -137
  347. package/src/tools/__tests__/taskManagerTool.search.test.js +143 -143
  348. package/src/tools/__tests__/taskManagerTool.test.js +866 -866
  349. package/src/tools/__tests__/terminalTool.test.js +448 -448
  350. package/src/tools/__tests__/toolShapeForgiveness.test.js +259 -260
  351. package/src/tools/__tests__/userPromptTool.test.js +297 -297
  352. package/src/tools/__tests__/videoTool.jobs.test.js +147 -147
  353. package/src/tools/__tests__/webTool.e2e.test.js +609 -603
  354. package/src/tools/__tests__/webTool.unit.test.js +195 -195
  355. package/src/tools/__tests__/webTool.visionModel.test.js +75 -75
  356. package/src/tools/agentCommunicationTool.js +8 -10
  357. package/src/tools/agentDelayTool.js +496 -497
  358. package/src/tools/asyncToolManager.js +602 -603
  359. package/src/tools/baseTool.js +12 -11
  360. package/src/tools/cloneDetectionTool.js +576 -581
  361. package/src/tools/codeMapTool.js +0 -6
  362. package/src/tools/composioTool.js +617 -617
  363. package/src/tools/dependencyResolverTool.js +1211 -1212
  364. package/src/tools/desktop/DesktopTool.js +629 -638
  365. package/src/tools/desktop/__tests__/DesktopTool.e2e.test.js +306 -306
  366. package/src/tools/desktop/__tests__/DesktopTool.test.js +507 -507
  367. package/src/tools/desktop/__tests__/osController.test.js +364 -364
  368. package/src/tools/desktop/osController.js +491 -491
  369. package/src/tools/docxTool.js +623 -623
  370. package/src/tools/excelTool.js +636 -636
  371. package/src/tools/fileContentReplaceTool.js +5 -7
  372. package/src/tools/fileSystemTool.js +12 -19
  373. package/src/tools/fileTreeTool.js +840 -840
  374. package/src/tools/foundryWebSearchTool.js +273 -273
  375. package/src/tools/helpTool.js +198 -198
  376. package/src/tools/imageTool.js +1397 -1397
  377. package/src/tools/importAnalyzerTool.js +1056 -1056
  378. package/src/tools/jobDoneTool.js +495 -495
  379. package/src/tools/memoryTool.js +1 -1
  380. package/src/tools/office/pres/__tests__/presSystem.test.js +365 -365
  381. package/src/tools/office/pres/archetypes/agenda.js +61 -61
  382. package/src/tools/office/pres/archetypes/bentoGrid.js +218 -219
  383. package/src/tools/office/pres/archetypes/bigStat.js +140 -142
  384. package/src/tools/office/pres/archetypes/closing.js +70 -70
  385. package/src/tools/office/pres/archetypes/hero.js +70 -70
  386. package/src/tools/office/pres/archetypes/productHero.js +93 -94
  387. package/src/tools/office/pres/archetypes/table.js +73 -74
  388. package/src/tools/office/pres/backgrounds/orb.js +66 -66
  389. package/src/tools/office/pres/components.js +422 -423
  390. package/src/tools/officeTool.js +441 -441
  391. package/src/tools/pdfTool.js +625 -627
  392. package/src/tools/platformControlTool.js +1081 -1081
  393. package/src/tools/seekTool.js +917 -918
  394. package/src/tools/skillsTool.js +1 -1
  395. package/src/tools/staticAnalysisTool.js +2143 -2146
  396. package/src/tools/taskManagerTool.js +3324 -3324
  397. package/src/tools/terminalTool.js +2615 -2618
  398. package/src/tools/videoTool.js +1303 -1303
  399. package/src/tools/visionTool.js +508 -508
  400. package/src/tools/visualEditorTool.js +1289 -1290
  401. package/src/tools/webTool.js +3368 -3368
  402. package/src/tools/whatsappTool.js +464 -464
  403. package/src/types/__tests__/agent.test.js +499 -499
  404. package/src/types/__tests__/contextReference.test.js +606 -606
  405. package/src/types/__tests__/conversation.test.js +555 -555
  406. package/src/types/__tests__/toolCommand.test.js +584 -584
  407. package/src/types/contextReference.js +974 -971
  408. package/src/types/conversation.js +729 -729
  409. package/src/types/toolCommand.js +746 -746
  410. package/src/utilities/__tests__/attachmentValidator.test.js +80 -80
  411. package/src/utilities/__tests__/auditReport.test.js +328 -328
  412. package/src/utilities/__tests__/directoryAccessManager.test.js +388 -388
  413. package/src/utilities/__tests__/jsonRepair.test.js +103 -104
  414. package/src/utilities/__tests__/modeTransitionReasons.test.js +105 -105
  415. package/src/utilities/__tests__/platformUtils.test.js +80 -87
  416. package/src/utilities/__tests__/structuredFileValidator.test.js +261 -263
  417. package/src/utilities/__tests__/toolConstants.test.js +92 -94
  418. package/src/utilities/__tests__/useIsTouchDevice.detect.test.js +114 -114
  419. package/src/utilities/__tests__/webUiUtilSync.test.js +117 -117
  420. package/src/utilities/attachmentValidator.js +284 -288
  421. package/src/utilities/authCache.js.backup-1779570472481 +121 -121
  422. package/src/utilities/browserStealth.js +631 -630
  423. package/src/utilities/configManager.js +616 -617
  424. package/src/utilities/directoryAccessManager.js +564 -565
  425. package/src/utilities/fileProcessor.js +308 -307
  426. package/src/utilities/humanBehavior.js +454 -453
  427. package/src/utilities/logger.js +479 -479
  428. package/src/utilities/structuredFileValidator.js +696 -699
  429. package/src/utilities/tagParser.js +5 -10
  430. package/src/utilities/userDataDir.js +308 -308
  431. package/node_modules/@isaacs/brace-expansion/dist/commonjs/index.js.map +0 -1
  432. package/node_modules/@isaacs/brace-expansion/dist/esm/index.js.map +0 -1
  433. package/node_modules/minipass/LICENSE +0 -15
  434. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/LICENSE.md +0 -0
  435. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts +0 -0
  436. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.d.ts.map +0 -0
  437. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js +0 -0
  438. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/index.js.map +0 -0
  439. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/commonjs/package.json +0 -0
  440. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts +0 -0
  441. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.d.ts.map +0 -0
  442. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js +0 -0
  443. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/index.js.map +0 -0
  444. /package/node_modules/{@isaacs → glob/node_modules}/balanced-match/dist/esm/package.json +0 -0
  445. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/LICENSE +0 -0
  446. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts +0 -0
  447. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/index.d.ts.map +0 -0
  448. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/commonjs/package.json +0 -0
  449. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts +0 -0
  450. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/index.d.ts.map +0 -0
  451. /package/node_modules/{@isaacs → glob/node_modules}/brace-expansion/dist/esm/package.json +0 -0
@@ -1,596 +1,594 @@
1
- /**
2
- * Orchestrator - Central coordination hub for Loxia AI Agents System
3
- *
4
- * Purpose:
5
- * - Unified request/response handling for all interfaces (CLI, Web, VSCode)
6
- * - Agent lifecycle management
7
- * - Session management
8
- * - Error handling and response formatting
9
- * - Interface-agnostic communication protocol
10
- */
11
-
12
- import {
13
- INTERFACE_TYPES,
14
- AGENT_TYPES,
15
- AGENT_STATUS,
16
- MESSAGE_MODES,
17
- ORCHESTRATOR_ACTIONS,
18
- SYSTEM_DEFAULTS
19
- } from '../utilities/constants.js';
20
-
21
- class Orchestrator {
22
- constructor(config, logger, agentPool, messageProcessor, aiService, stateManager) {
23
- this.config = config;
24
- this.logger = logger;
25
- this.agentPool = agentPool;
26
- this.messageProcessor = messageProcessor;
27
- this.aiService = aiService;
28
- this.stateManager = stateManager;
29
-
30
- this.activeSessions = new Map();
31
- this.requestHandlers = new Map();
32
-
33
- this._initializeRequestHandlers();
34
- }
35
-
36
- /**
37
- * Main entry point for all requests from client interfaces
38
- * @param {Object} request - Request object with interface, sessionId, action, payload, projectDir, user
39
- * @returns {Promise<Object>} Response object with success, data, error, metadata
40
- */
41
- async processRequest(request) {
42
- const startTime = Date.now();
43
-
44
- try {
45
- this._validateRequest(request);
46
-
47
- const handler = this.requestHandlers.get(request.action);
48
- if (!handler) {
49
- this.logger.error(`Unknown action received: ${request.action}`, {
50
- availableActions: Array.from(this.requestHandlers.keys()),
51
- requestAction: request.action,
52
- actionType: typeof request.action
53
- });
54
- throw new Error(`Unknown action: ${request.action}`);
55
- }
56
-
57
- // Ensure session exists
58
- await this._ensureSession(request.sessionId, request.projectDir);
59
-
60
- // Execute request handler
61
- const result = await handler.call(this, request);
62
-
63
- // Generate response metadata
64
- const metadata = {
65
- timestamp: new Date().toISOString(),
66
- executionTime: Date.now() - startTime,
67
- sessionId: request.sessionId,
68
- interface: request.interface
69
- };
70
-
71
- return {
72
- success: true,
73
- data: result,
74
- error: null,
75
- metadata
76
- };
77
-
78
- } catch (error) {
79
- this.logger.error(`Request processing failed: ${error.message}`, {
80
- request: this._sanitizeRequestForLogging(request),
81
- error: error.stack
82
- });
83
-
84
- return {
85
- success: false,
86
- data: null,
87
- error: error.message,
88
- metadata: {
89
- timestamp: new Date().toISOString(),
90
- executionTime: Date.now() - startTime,
91
- sessionId: request.sessionId,
92
- interface: request.interface
93
- }
94
- };
95
- }
96
- }
97
-
98
- /**
99
- * Create a new agent with specified configuration
100
- * @param {string} systemPrompt - Agent's system prompt
101
- * @param {string} model - Preferred LLM model
102
- * @param {Object} options - Additional agent configuration
103
- * @returns {Promise<Object>} Created agent object
104
- */
105
- async createAgent(systemPrompt, model, options = {}) {
106
- const agentConfig = {
107
- name: options.name || `Agent-${Date.now()}`,
108
- type: options.type || AGENT_TYPES.USER_CREATED,
109
- systemPrompt,
110
- preferredModel: model,
111
- capabilities: options.capabilities || [],
112
- ...options
113
- };
114
-
115
- const agent = await this.agentPool.createAgent(agentConfig);
116
-
117
- this.logger.info(`Agent created: ${agent.id}`, {
118
- agentId: agent.id,
119
- name: agent.name,
120
- model: agent.preferredModel
121
- });
122
-
123
- return agent;
124
- }
125
-
126
- /**
127
- * Route message to specified agent
128
- * @param {string} agentId - Target agent ID
129
- * @param {string} message - Message content
130
- * @param {Object} context - Message context (projectDir, contextReferences, etc.)
131
- * @returns {Promise<Object>} Agent response
132
- */
133
- async routeToAgent(agentId, message, context = {}) {
134
- const agent = await this.agentPool.getAgent(agentId);
135
- if (!agent) {
136
- throw new Error(`Agent not found: ${agentId}`);
137
- }
138
-
139
- // NOTE: We deliberately do NOT short-circuit on agent.status === PAUSED
140
- // here. A user message is an explicit "act now" signal and must
141
- // override any pause/delay state. agentPool.addUserMessage() calls
142
- // _wakeAgentForMessage() which resumes paused agents, clears
143
- // scheduler-enforced delayEndTime, and clears pausedUntil so by
144
- // the time the message lands in the queue the agent is back to
145
- // active status. Rejecting here would silently drop user intent
146
- // (the symptom was: "agent is paused" toast, no processing, the
147
- // agent happily napping while the user waits). See
148
- // src/core/__tests__/orchestratorUserMessageOverridesPause.test.js
149
- // for the regression guard.
150
-
151
- // Process message through message processor (NEW ARCHITECTURE: just queues message)
152
- const result = await this.messageProcessor.processMessage(agentId, message, context);
153
-
154
- // NEW ARCHITECTURE: MessageProcessor just queues messages, actual processing happens in AgentScheduler
155
- // Return immediate queuing confirmation to UI
156
- if (result.success) {
157
- const response = {
158
- success: true,
159
- data: {
160
- message: `Message queued for agent processing`,
161
- agentId: result.agentId,
162
- queuedAt: result.queuedAt,
163
- status: 'queued',
164
- // Legacy fields for backward compatibility
165
- toolResults: [],
166
- agentRedirects: [],
167
- currentModel: agent.currentModel
168
- },
169
- processingId: `queued-${Date.now()}`
170
- };
171
-
172
- this.logger.info(`Message queued for agent: ${agentId}`, {
173
- agentName: agent.name,
174
- messageLength: message.length,
175
- sessionId: context.sessionId
176
- });
177
-
178
- return response;
179
- } else {
180
- return result; // Return error response as-is
181
- }
182
- }
183
-
184
- /**
185
- * Get current session state
186
- * @param {string} sessionId - Session identifier
187
- * @returns {Promise<Object>} Session state object
188
- */
189
- async getSessionState(sessionId) {
190
- const session = this.activeSessions.get(sessionId);
191
- if (!session) {
192
- throw new Error(`Session not found: ${sessionId}`);
193
- }
194
-
195
- const agents = await this.agentPool.listActiveAgents();
196
- const projectState = await this.stateManager.getProjectState(session.projectDir);
197
-
198
- return {
199
- sessionId,
200
- projectDir: session.projectDir,
201
- createdAt: session.createdAt,
202
- lastActivity: session.lastActivity,
203
- agents: agents, // Return full agent objects since listActiveAgents already filters appropriately
204
- projectState
205
- };
206
- }
207
-
208
- /**
209
- * Shutdown orchestrator and cleanup resources
210
- * @returns {Promise<void>}
211
- */
212
- async shutdown() {
213
- this.logger.info('Shutting down orchestrator...');
214
-
215
- // Save all agent states
216
- const agents = await this.agentPool.listActiveAgents();
217
- for (const agent of agents) {
218
- await this.stateManager.persistAgentState(agent.id);
219
- }
220
-
221
- // Clear active sessions
222
- this.activeSessions.clear();
223
-
224
- this.logger.info('Orchestrator shutdown complete');
225
- }
226
-
227
- /**
228
- * Initialize request handlers for different actions
229
- * @private
230
- */
231
- _initializeRequestHandlers() {
232
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.CREATE_AGENT, this._handleCreateAgent.bind(this));
233
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.UPDATE_AGENT, this._handleUpdateAgent.bind(this));
234
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.DELETE_AGENT, this._handleDeleteAgent.bind(this));
235
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.UNLOAD_AGENT, this._handleUnloadAgent.bind(this));
236
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.SEND_MESSAGE, this._handleSendMessage.bind(this));
237
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.LIST_AGENTS, this._handleListAgents.bind(this));
238
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.RESUME_SESSION, this._handleResumeSession.bind(this));
239
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_SESSION_STATE, this._handleGetSessionState.bind(this));
240
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.PAUSE_AGENT, this._handlePauseAgent.bind(this));
241
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.RESUME_AGENT, this._handleResumeAgent.bind(this));
242
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.SWITCH_MODEL, this._handleSwitchModel.bind(this));
243
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_AGENT_STATUS, this._handleGetAgentStatus.bind(this));
244
- this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_AGENT_CONVERSATIONS, this._handleGetAgentConversations.bind(this));
245
- }
246
-
247
- /**
248
- * Handle create agent requests
249
- * @private
250
- */
251
- async _handleCreateAgent(request) {
252
- const { name, systemPrompt, model, capabilities, dynamicModelRouting, platformProvided, directoryAccess } = request.payload;
253
-
254
- this.logger.info('Creating agent with payload', {
255
- name,
256
- model,
257
- dynamicModelRouting,
258
- platformProvided,
259
- capabilities,
260
- directoryAccess: directoryAccess ? {
261
- workingDirectory: directoryAccess.workingDirectory,
262
- readOnlyDirectories: directoryAccess.readOnlyDirectories?.length || 0,
263
- writeEnabledDirectories: directoryAccess.writeEnabledDirectories?.length || 0,
264
- restrictToProject: directoryAccess.restrictToProject
265
- } : null
266
- });
267
-
268
- return await this.createAgent(systemPrompt, model, {
269
- name,
270
- capabilities,
271
- dynamicModelRouting,
272
- platformProvided,
273
- directoryAccess,
274
- sessionId: request.sessionId,
275
- projectDir: request.projectDir
276
- });
277
- }
278
-
279
- /**
280
- * Handle update agent requests
281
- * @private
282
- */
283
- async _handleUpdateAgent(request) {
284
- const { agentId, updates } = request.payload;
285
-
286
- if (!agentId) {
287
- throw new Error('Agent ID is required for update');
288
- }
289
-
290
- if (!updates || typeof updates !== 'object') {
291
- throw new Error('Updates object is required');
292
- }
293
-
294
- // Get agent before update to ensure it exists
295
- const agent = await this.agentPool.getAgent(agentId);
296
- if (!agent) {
297
- throw new Error(`Agent not found: ${agentId}`);
298
- }
299
-
300
- this.logger.info('Updating agent with payload', {
301
- agentId,
302
- updates,
303
- agentName: agent.name
304
- });
305
-
306
- // Update the agent through the agent pool
307
- // Include sessionId in updates to maintain API key context
308
- const updatesWithSession = {
309
- ...updates,
310
- sessionId: request.sessionId // Ensure current session context is preserved
311
- };
312
- const updatedAgent = await this.agentPool.updateAgent(agentId, updatesWithSession);
313
-
314
- this.logger.info(`Agent updated: ${agentId}`, {
315
- agentName: updatedAgent.name,
316
- newMode: updatedAgent.mode,
317
- sessionId: request.sessionId
318
- });
319
-
320
- return updatedAgent;
321
- }
322
-
323
- /**
324
- * Handle delete agent requests
325
- * @private
326
- */
327
- async _handleDeleteAgent(request) {
328
- const { agentId } = request.payload;
329
-
330
- if (!agentId) {
331
- throw new Error('Agent ID is required for deletion');
332
- }
333
-
334
- // Best-effort lookup for logging + response shape. We do NOT throw
335
- // when the agent isn't loaded that breaks bulk-delete against
336
- // agents that were unloaded earlier in the session (the original
337
- // implementation made the entire group operation fail with
338
- // "Failed to delete N agents"). agentPool.deleteAgent now handles
339
- // the unloaded case by cleaning up persistent state only.
340
- const agent = await this.agentPool.getAgent(agentId);
341
-
342
- const result = await this.agentPool.deleteAgent(agentId);
343
-
344
- this.logger.info(`Agent deleted: ${agentId}`, {
345
- agentName: agent?.name || '(not loaded)',
346
- sessionId: request.sessionId
347
- });
348
-
349
- return {
350
- success: true,
351
- deletedAgent: {
352
- id: agentId,
353
- name: agent?.name || null,
354
- },
355
- ...result
356
- };
357
- }
358
-
359
- /**
360
- * Handle unload agent requests (remove from memory, keep files)
361
- * @private
362
- */
363
- async _handleUnloadAgent(request) {
364
- const { agentId } = request.payload;
365
-
366
- if (!agentId) {
367
- throw new Error('Agent ID is required for unloading');
368
- }
369
-
370
- // Get agent before unloading to return info
371
- const agent = await this.agentPool.getAgent(agentId);
372
- if (!agent) {
373
- throw new Error(`Agent not found: ${agentId}`);
374
- }
375
-
376
- // Unload the agent (preserves files)
377
- const result = await this.agentPool.unloadAgent(agentId);
378
-
379
- this.logger.info(`Agent unloaded: ${agentId}`, {
380
- agentName: agent.name,
381
- sessionId: request.sessionId
382
- });
383
-
384
- return {
385
- success: true,
386
- unloadedAgent: {
387
- id: agent.id,
388
- name: agent.name
389
- },
390
- ...result
391
- };
392
- }
393
-
394
- /**
395
- * Handle send message requests
396
- * @private
397
- */
398
- async _handleSendMessage(request) {
399
- const { agentId, message, mode, contextReferences, apiKey, customApiKeys, streamingEnabled, source } = request.payload;
400
-
401
- const context = {
402
- projectDir: request.projectDir,
403
- sessionId: request.sessionId,
404
- interface: request.interface,
405
- mode: mode || MESSAGE_MODES.CHAT,
406
- contextReferences: contextReferences || [],
407
- apiKey: apiKey, // Pass Loxia API key through context
408
- customApiKeys: customApiKeys || {}, // Pass custom API keys through context
409
- streamingEnabled: streamingEnabled !== false, // Default to true if not specified
410
- // Provenance metadata from the inbound adapter (Discord/Telegram/…).
411
- // Preserved verbatim by messageProcessor and agentPool so the agent
412
- // can see where the message came from. See services/messageSource.js.
413
- source: source || null,
414
- };
415
-
416
- return await this.routeToAgent(agentId, message, context);
417
- }
418
-
419
- /**
420
- * Handle list agents requests
421
- * @private
422
- */
423
- async _handleListAgents(request) {
424
- return await this.agentPool.listActiveAgents();
425
- }
426
-
427
- /**
428
- * Handle resume session requests
429
- * @private
430
- */
431
- async _handleResumeSession(request) {
432
- const { projectDir } = request.payload;
433
-
434
- const resumedState = await this.stateManager.resumeProject(projectDir);
435
-
436
- // Restore agents to agent pool
437
- for (const agent of resumedState.agents) {
438
- await this.agentPool.restoreAgent(agent);
439
- }
440
-
441
- return resumedState;
442
- }
443
-
444
- /**
445
- * Handle get session state requests
446
- * @private
447
- */
448
- async _handleGetSessionState(request) {
449
- return await this.getSessionState(request.sessionId);
450
- }
451
-
452
- /**
453
- * Handle pause agent requests
454
- * @private
455
- */
456
- async _handlePauseAgent(request) {
457
- const { agentId, duration, reason } = request.payload;
458
-
459
- return await this.agentPool.pauseAgent(agentId, duration, reason);
460
- }
461
-
462
- /**
463
- * Handle resume agent requests
464
- * @private
465
- */
466
- async _handleResumeAgent(request) {
467
- const { agentId } = request.payload;
468
-
469
- return await this.agentPool.resumeAgent(agentId);
470
- }
471
-
472
- /**
473
- * Handle switch model requests
474
- * @private
475
- */
476
- async _handleSwitchModel(request) {
477
- const { agentId, newModel } = request.payload;
478
-
479
- const agent = await this.agentPool.getAgent(agentId);
480
- if (!agent) {
481
- throw new Error(`Agent not found: ${agentId}`);
482
- }
483
-
484
- // Switch model via AI service conversation manager
485
- return await this.aiService.switchAgentModel(agentId, newModel);
486
- }
487
-
488
- /**
489
- * Handle get agent status requests
490
- * @private
491
- */
492
- async _handleGetAgentStatus(request) {
493
- const { agentId } = request.payload;
494
-
495
- const agent = await this.agentPool.getAgent(agentId);
496
- if (!agent) {
497
- throw new Error(`Agent not found: ${agentId}`);
498
- }
499
-
500
- return {
501
- id: agent.id,
502
- name: agent.name,
503
- status: agent.status,
504
- mode: agent.mode,
505
- currentModel: agent.currentModel,
506
- lastActivity: agent.lastActivity,
507
- isPaused: agent.status === 'paused',
508
- pausedUntil: agent.pausedUntil
509
- };
510
- }
511
-
512
- /**
513
- * Handle get agent conversations requests
514
- * @private
515
- */
516
- async _handleGetAgentConversations(request) {
517
- const { agentId } = request.payload;
518
-
519
- const agent = await this.agentPool.getAgent(agentId);
520
- if (!agent) {
521
- throw new Error(`Agent not found: ${agentId}`);
522
- }
523
-
524
- return {
525
- agentId: agent.id,
526
- conversations: agent.conversations,
527
- messageCount: agent.conversations?.full?.messages?.length || 0
528
- };
529
- }
530
-
531
- /**
532
- * Validate request format
533
- * @private
534
- */
535
- _validateRequest(request) {
536
- if (!request || typeof request !== 'object') {
537
- throw new Error('Invalid request format');
538
- }
539
-
540
- const requiredFields = ['interface', 'sessionId', 'action', 'payload'];
541
- for (const field of requiredFields) {
542
- if (!(field in request)) {
543
- throw new Error(`Missing required field: ${field}`);
544
- }
545
- }
546
-
547
- const validInterfaces = Object.values(INTERFACE_TYPES);
548
- if (!validInterfaces.includes(request.interface)) {
549
- throw new Error(`Invalid interface: ${request.interface}`);
550
- }
551
- }
552
-
553
- /**
554
- * Ensure session exists, create if needed
555
- * @private
556
- */
557
- async _ensureSession(sessionId, projectDir) {
558
- if (!this.activeSessions.has(sessionId)) {
559
- const session = {
560
- id: sessionId,
561
- projectDir: projectDir || process.cwd(),
562
- createdAt: new Date().toISOString(),
563
- lastActivity: new Date().toISOString()
564
- };
565
-
566
- this.activeSessions.set(sessionId, session);
567
- this.logger.info(`Session created: ${sessionId}`, { projectDir: session.projectDir });
568
- } else {
569
- // Update last activity
570
- const session = this.activeSessions.get(sessionId);
571
- session.lastActivity = new Date().toISOString();
572
- }
573
- }
574
-
575
- /**
576
- * Sanitize request for logging (remove sensitive data)
577
- * @private
578
- */
579
- _sanitizeRequestForLogging(request) {
580
- const sanitized = { ...request };
581
-
582
- // Remove potentially sensitive user data
583
- if (sanitized.user) {
584
- sanitized.user = { id: sanitized.user.id };
585
- }
586
-
587
- // Truncate large message content
588
- if (sanitized.payload && sanitized.payload.message && sanitized.payload.message.length > 500) {
589
- sanitized.payload.message = sanitized.payload.message.substring(0, 500) + '... [truncated]';
590
- }
591
-
592
- return sanitized;
593
- }
594
- }
595
-
1
+ /**
2
+ * Orchestrator - Central coordination hub for Loxia AI Agents System
3
+ *
4
+ * Purpose:
5
+ * - Unified request/response handling for all interfaces (CLI, Web, VSCode)
6
+ * - Agent lifecycle management
7
+ * - Session management
8
+ * - Error handling and response formatting
9
+ * - Interface-agnostic communication protocol
10
+ */
11
+
12
+ import {
13
+ INTERFACE_TYPES,
14
+ AGENT_TYPES,
15
+ MESSAGE_MODES,
16
+ ORCHESTRATOR_ACTIONS
17
+ } from '../utilities/constants.js';
18
+
19
+ class Orchestrator {
20
+ constructor(config, logger, agentPool, messageProcessor, aiService, stateManager) {
21
+ this.config = config;
22
+ this.logger = logger;
23
+ this.agentPool = agentPool;
24
+ this.messageProcessor = messageProcessor;
25
+ this.aiService = aiService;
26
+ this.stateManager = stateManager;
27
+
28
+ this.activeSessions = new Map();
29
+ this.requestHandlers = new Map();
30
+
31
+ this._initializeRequestHandlers();
32
+ }
33
+
34
+ /**
35
+ * Main entry point for all requests from client interfaces
36
+ * @param {Object} request - Request object with interface, sessionId, action, payload, projectDir, user
37
+ * @returns {Promise<Object>} Response object with success, data, error, metadata
38
+ */
39
+ async processRequest(request) {
40
+ const startTime = Date.now();
41
+
42
+ try {
43
+ this._validateRequest(request);
44
+
45
+ const handler = this.requestHandlers.get(request.action);
46
+ if (!handler) {
47
+ this.logger.error(`Unknown action received: ${request.action}`, {
48
+ availableActions: Array.from(this.requestHandlers.keys()),
49
+ requestAction: request.action,
50
+ actionType: typeof request.action
51
+ });
52
+ throw new Error(`Unknown action: ${request.action}`);
53
+ }
54
+
55
+ // Ensure session exists
56
+ await this._ensureSession(request.sessionId, request.projectDir);
57
+
58
+ // Execute request handler
59
+ const result = await handler.call(this, request);
60
+
61
+ // Generate response metadata
62
+ const metadata = {
63
+ timestamp: new Date().toISOString(),
64
+ executionTime: Date.now() - startTime,
65
+ sessionId: request.sessionId,
66
+ interface: request.interface
67
+ };
68
+
69
+ return {
70
+ success: true,
71
+ data: result,
72
+ error: null,
73
+ metadata
74
+ };
75
+
76
+ } catch (error) {
77
+ this.logger.error(`Request processing failed: ${error.message}`, {
78
+ request: this._sanitizeRequestForLogging(request),
79
+ error: error.stack
80
+ });
81
+
82
+ return {
83
+ success: false,
84
+ data: null,
85
+ error: error.message,
86
+ metadata: {
87
+ timestamp: new Date().toISOString(),
88
+ executionTime: Date.now() - startTime,
89
+ sessionId: request.sessionId,
90
+ interface: request.interface
91
+ }
92
+ };
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Create a new agent with specified configuration
98
+ * @param {string} systemPrompt - Agent's system prompt
99
+ * @param {string} model - Preferred LLM model
100
+ * @param {Object} options - Additional agent configuration
101
+ * @returns {Promise<Object>} Created agent object
102
+ */
103
+ async createAgent(systemPrompt, model, options = {}) {
104
+ const agentConfig = {
105
+ name: options.name || `Agent-${Date.now()}`,
106
+ type: options.type || AGENT_TYPES.USER_CREATED,
107
+ systemPrompt,
108
+ preferredModel: model,
109
+ capabilities: options.capabilities || [],
110
+ ...options
111
+ };
112
+
113
+ const agent = await this.agentPool.createAgent(agentConfig);
114
+
115
+ this.logger.info(`Agent created: ${agent.id}`, {
116
+ agentId: agent.id,
117
+ name: agent.name,
118
+ model: agent.preferredModel
119
+ });
120
+
121
+ return agent;
122
+ }
123
+
124
+ /**
125
+ * Route message to specified agent
126
+ * @param {string} agentId - Target agent ID
127
+ * @param {string} message - Message content
128
+ * @param {Object} context - Message context (projectDir, contextReferences, etc.)
129
+ * @returns {Promise<Object>} Agent response
130
+ */
131
+ async routeToAgent(agentId, message, context = {}) {
132
+ const agent = await this.agentPool.getAgent(agentId);
133
+ if (!agent) {
134
+ throw new Error(`Agent not found: ${agentId}`);
135
+ }
136
+
137
+ // NOTE: We deliberately do NOT short-circuit on agent.status === PAUSED
138
+ // here. A user message is an explicit "act now" signal and must
139
+ // override any pause/delay state. agentPool.addUserMessage() calls
140
+ // _wakeAgentForMessage() which resumes paused agents, clears
141
+ // scheduler-enforced delayEndTime, and clears pausedUntil — so by
142
+ // the time the message lands in the queue the agent is back to
143
+ // active status. Rejecting here would silently drop user intent
144
+ // (the symptom was: "agent is paused" toast, no processing, the
145
+ // agent happily napping while the user waits). See
146
+ // src/core/__tests__/orchestratorUserMessageOverridesPause.test.js
147
+ // for the regression guard.
148
+
149
+ // Process message through message processor (NEW ARCHITECTURE: just queues message)
150
+ const result = await this.messageProcessor.processMessage(agentId, message, context);
151
+
152
+ // NEW ARCHITECTURE: MessageProcessor just queues messages, actual processing happens in AgentScheduler
153
+ // Return immediate queuing confirmation to UI
154
+ if (result.success) {
155
+ const response = {
156
+ success: true,
157
+ data: {
158
+ message: `Message queued for agent processing`,
159
+ agentId: result.agentId,
160
+ queuedAt: result.queuedAt,
161
+ status: 'queued',
162
+ // Legacy fields for backward compatibility
163
+ toolResults: [],
164
+ agentRedirects: [],
165
+ currentModel: agent.currentModel
166
+ },
167
+ processingId: `queued-${Date.now()}`
168
+ };
169
+
170
+ this.logger.info(`Message queued for agent: ${agentId}`, {
171
+ agentName: agent.name,
172
+ messageLength: message.length,
173
+ sessionId: context.sessionId
174
+ });
175
+
176
+ return response;
177
+ } else {
178
+ return result; // Return error response as-is
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Get current session state
184
+ * @param {string} sessionId - Session identifier
185
+ * @returns {Promise<Object>} Session state object
186
+ */
187
+ async getSessionState(sessionId) {
188
+ const session = this.activeSessions.get(sessionId);
189
+ if (!session) {
190
+ throw new Error(`Session not found: ${sessionId}`);
191
+ }
192
+
193
+ const agents = await this.agentPool.listActiveAgents();
194
+ const projectState = await this.stateManager.getProjectState(session.projectDir);
195
+
196
+ return {
197
+ sessionId,
198
+ projectDir: session.projectDir,
199
+ createdAt: session.createdAt,
200
+ lastActivity: session.lastActivity,
201
+ agents: agents, // Return full agent objects since listActiveAgents already filters appropriately
202
+ projectState
203
+ };
204
+ }
205
+
206
+ /**
207
+ * Shutdown orchestrator and cleanup resources
208
+ * @returns {Promise<void>}
209
+ */
210
+ async shutdown() {
211
+ this.logger.info('Shutting down orchestrator...');
212
+
213
+ // Save all agent states
214
+ const agents = await this.agentPool.listActiveAgents();
215
+ for (const agent of agents) {
216
+ await this.stateManager.persistAgentState(agent.id);
217
+ }
218
+
219
+ // Clear active sessions
220
+ this.activeSessions.clear();
221
+
222
+ this.logger.info('Orchestrator shutdown complete');
223
+ }
224
+
225
+ /**
226
+ * Initialize request handlers for different actions
227
+ * @private
228
+ */
229
+ _initializeRequestHandlers() {
230
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.CREATE_AGENT, this._handleCreateAgent.bind(this));
231
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.UPDATE_AGENT, this._handleUpdateAgent.bind(this));
232
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.DELETE_AGENT, this._handleDeleteAgent.bind(this));
233
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.UNLOAD_AGENT, this._handleUnloadAgent.bind(this));
234
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.SEND_MESSAGE, this._handleSendMessage.bind(this));
235
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.LIST_AGENTS, this._handleListAgents.bind(this));
236
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.RESUME_SESSION, this._handleResumeSession.bind(this));
237
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_SESSION_STATE, this._handleGetSessionState.bind(this));
238
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.PAUSE_AGENT, this._handlePauseAgent.bind(this));
239
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.RESUME_AGENT, this._handleResumeAgent.bind(this));
240
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.SWITCH_MODEL, this._handleSwitchModel.bind(this));
241
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_AGENT_STATUS, this._handleGetAgentStatus.bind(this));
242
+ this.requestHandlers.set(ORCHESTRATOR_ACTIONS.GET_AGENT_CONVERSATIONS, this._handleGetAgentConversations.bind(this));
243
+ }
244
+
245
+ /**
246
+ * Handle create agent requests
247
+ * @private
248
+ */
249
+ async _handleCreateAgent(request) {
250
+ const { name, systemPrompt, model, capabilities, dynamicModelRouting, platformProvided, directoryAccess } = request.payload;
251
+
252
+ this.logger.info('Creating agent with payload', {
253
+ name,
254
+ model,
255
+ dynamicModelRouting,
256
+ platformProvided,
257
+ capabilities,
258
+ directoryAccess: directoryAccess ? {
259
+ workingDirectory: directoryAccess.workingDirectory,
260
+ readOnlyDirectories: directoryAccess.readOnlyDirectories?.length || 0,
261
+ writeEnabledDirectories: directoryAccess.writeEnabledDirectories?.length || 0,
262
+ restrictToProject: directoryAccess.restrictToProject
263
+ } : null
264
+ });
265
+
266
+ return await this.createAgent(systemPrompt, model, {
267
+ name,
268
+ capabilities,
269
+ dynamicModelRouting,
270
+ platformProvided,
271
+ directoryAccess,
272
+ sessionId: request.sessionId,
273
+ projectDir: request.projectDir
274
+ });
275
+ }
276
+
277
+ /**
278
+ * Handle update agent requests
279
+ * @private
280
+ */
281
+ async _handleUpdateAgent(request) {
282
+ const { agentId, updates } = request.payload;
283
+
284
+ if (!agentId) {
285
+ throw new Error('Agent ID is required for update');
286
+ }
287
+
288
+ if (!updates || typeof updates !== 'object') {
289
+ throw new Error('Updates object is required');
290
+ }
291
+
292
+ // Get agent before update to ensure it exists
293
+ const agent = await this.agentPool.getAgent(agentId);
294
+ if (!agent) {
295
+ throw new Error(`Agent not found: ${agentId}`);
296
+ }
297
+
298
+ this.logger.info('Updating agent with payload', {
299
+ agentId,
300
+ updates,
301
+ agentName: agent.name
302
+ });
303
+
304
+ // Update the agent through the agent pool
305
+ // Include sessionId in updates to maintain API key context
306
+ const updatesWithSession = {
307
+ ...updates,
308
+ sessionId: request.sessionId // Ensure current session context is preserved
309
+ };
310
+ const updatedAgent = await this.agentPool.updateAgent(agentId, updatesWithSession);
311
+
312
+ this.logger.info(`Agent updated: ${agentId}`, {
313
+ agentName: updatedAgent.name,
314
+ newMode: updatedAgent.mode,
315
+ sessionId: request.sessionId
316
+ });
317
+
318
+ return updatedAgent;
319
+ }
320
+
321
+ /**
322
+ * Handle delete agent requests
323
+ * @private
324
+ */
325
+ async _handleDeleteAgent(request) {
326
+ const { agentId } = request.payload;
327
+
328
+ if (!agentId) {
329
+ throw new Error('Agent ID is required for deletion');
330
+ }
331
+
332
+ // Best-effort lookup for logging + response shape. We do NOT throw
333
+ // when the agent isn't loaded — that breaks bulk-delete against
334
+ // agents that were unloaded earlier in the session (the original
335
+ // implementation made the entire group operation fail with
336
+ // "Failed to delete N agents"). agentPool.deleteAgent now handles
337
+ // the unloaded case by cleaning up persistent state only.
338
+ const agent = await this.agentPool.getAgent(agentId);
339
+
340
+ const result = await this.agentPool.deleteAgent(agentId);
341
+
342
+ this.logger.info(`Agent deleted: ${agentId}`, {
343
+ agentName: agent?.name || '(not loaded)',
344
+ sessionId: request.sessionId
345
+ });
346
+
347
+ return {
348
+ success: true,
349
+ deletedAgent: {
350
+ id: agentId,
351
+ name: agent?.name || null,
352
+ },
353
+ ...result
354
+ };
355
+ }
356
+
357
+ /**
358
+ * Handle unload agent requests (remove from memory, keep files)
359
+ * @private
360
+ */
361
+ async _handleUnloadAgent(request) {
362
+ const { agentId } = request.payload;
363
+
364
+ if (!agentId) {
365
+ throw new Error('Agent ID is required for unloading');
366
+ }
367
+
368
+ // Get agent before unloading to return info
369
+ const agent = await this.agentPool.getAgent(agentId);
370
+ if (!agent) {
371
+ throw new Error(`Agent not found: ${agentId}`);
372
+ }
373
+
374
+ // Unload the agent (preserves files)
375
+ const result = await this.agentPool.unloadAgent(agentId);
376
+
377
+ this.logger.info(`Agent unloaded: ${agentId}`, {
378
+ agentName: agent.name,
379
+ sessionId: request.sessionId
380
+ });
381
+
382
+ return {
383
+ success: true,
384
+ unloadedAgent: {
385
+ id: agent.id,
386
+ name: agent.name
387
+ },
388
+ ...result
389
+ };
390
+ }
391
+
392
+ /**
393
+ * Handle send message requests
394
+ * @private
395
+ */
396
+ async _handleSendMessage(request) {
397
+ const { agentId, message, mode, contextReferences, apiKey, customApiKeys, streamingEnabled, source } = request.payload;
398
+
399
+ const context = {
400
+ projectDir: request.projectDir,
401
+ sessionId: request.sessionId,
402
+ interface: request.interface,
403
+ mode: mode || MESSAGE_MODES.CHAT,
404
+ contextReferences: contextReferences || [],
405
+ apiKey: apiKey, // Pass Loxia API key through context
406
+ customApiKeys: customApiKeys || {}, // Pass custom API keys through context
407
+ streamingEnabled: streamingEnabled !== false, // Default to true if not specified
408
+ // Provenance metadata from the inbound adapter (Discord/Telegram/…).
409
+ // Preserved verbatim by messageProcessor and agentPool so the agent
410
+ // can see where the message came from. See services/messageSource.js.
411
+ source: source || null,
412
+ };
413
+
414
+ return await this.routeToAgent(agentId, message, context);
415
+ }
416
+
417
+ /**
418
+ * Handle list agents requests
419
+ * @private
420
+ */
421
+ async _handleListAgents() {
422
+ return await this.agentPool.listActiveAgents();
423
+ }
424
+
425
+ /**
426
+ * Handle resume session requests
427
+ * @private
428
+ */
429
+ async _handleResumeSession(request) {
430
+ const { projectDir } = request.payload;
431
+
432
+ const resumedState = await this.stateManager.resumeProject(projectDir);
433
+
434
+ // Restore agents to agent pool
435
+ for (const agent of resumedState.agents) {
436
+ await this.agentPool.restoreAgent(agent);
437
+ }
438
+
439
+ return resumedState;
440
+ }
441
+
442
+ /**
443
+ * Handle get session state requests
444
+ * @private
445
+ */
446
+ async _handleGetSessionState(request) {
447
+ return await this.getSessionState(request.sessionId);
448
+ }
449
+
450
+ /**
451
+ * Handle pause agent requests
452
+ * @private
453
+ */
454
+ async _handlePauseAgent(request) {
455
+ const { agentId, duration, reason } = request.payload;
456
+
457
+ return await this.agentPool.pauseAgent(agentId, duration, reason);
458
+ }
459
+
460
+ /**
461
+ * Handle resume agent requests
462
+ * @private
463
+ */
464
+ async _handleResumeAgent(request) {
465
+ const { agentId } = request.payload;
466
+
467
+ return await this.agentPool.resumeAgent(agentId);
468
+ }
469
+
470
+ /**
471
+ * Handle switch model requests
472
+ * @private
473
+ */
474
+ async _handleSwitchModel(request) {
475
+ const { agentId, newModel } = request.payload;
476
+
477
+ const agent = await this.agentPool.getAgent(agentId);
478
+ if (!agent) {
479
+ throw new Error(`Agent not found: ${agentId}`);
480
+ }
481
+
482
+ // Switch model via AI service conversation manager
483
+ return await this.aiService.switchAgentModel(agentId, newModel);
484
+ }
485
+
486
+ /**
487
+ * Handle get agent status requests
488
+ * @private
489
+ */
490
+ async _handleGetAgentStatus(request) {
491
+ const { agentId } = request.payload;
492
+
493
+ const agent = await this.agentPool.getAgent(agentId);
494
+ if (!agent) {
495
+ throw new Error(`Agent not found: ${agentId}`);
496
+ }
497
+
498
+ return {
499
+ id: agent.id,
500
+ name: agent.name,
501
+ status: agent.status,
502
+ mode: agent.mode,
503
+ currentModel: agent.currentModel,
504
+ lastActivity: agent.lastActivity,
505
+ isPaused: agent.status === 'paused',
506
+ pausedUntil: agent.pausedUntil
507
+ };
508
+ }
509
+
510
+ /**
511
+ * Handle get agent conversations requests
512
+ * @private
513
+ */
514
+ async _handleGetAgentConversations(request) {
515
+ const { agentId } = request.payload;
516
+
517
+ const agent = await this.agentPool.getAgent(agentId);
518
+ if (!agent) {
519
+ throw new Error(`Agent not found: ${agentId}`);
520
+ }
521
+
522
+ return {
523
+ agentId: agent.id,
524
+ conversations: agent.conversations,
525
+ messageCount: agent.conversations?.full?.messages?.length || 0
526
+ };
527
+ }
528
+
529
+ /**
530
+ * Validate request format
531
+ * @private
532
+ */
533
+ _validateRequest(request) {
534
+ if (!request || typeof request !== 'object') {
535
+ throw new Error('Invalid request format');
536
+ }
537
+
538
+ const requiredFields = ['interface', 'sessionId', 'action', 'payload'];
539
+ for (const field of requiredFields) {
540
+ if (!(field in request)) {
541
+ throw new Error(`Missing required field: ${field}`);
542
+ }
543
+ }
544
+
545
+ const validInterfaces = Object.values(INTERFACE_TYPES);
546
+ if (!validInterfaces.includes(request.interface)) {
547
+ throw new Error(`Invalid interface: ${request.interface}`);
548
+ }
549
+ }
550
+
551
+ /**
552
+ * Ensure session exists, create if needed
553
+ * @private
554
+ */
555
+ async _ensureSession(sessionId, projectDir) {
556
+ if (!this.activeSessions.has(sessionId)) {
557
+ const session = {
558
+ id: sessionId,
559
+ projectDir: projectDir || process.cwd(),
560
+ createdAt: new Date().toISOString(),
561
+ lastActivity: new Date().toISOString()
562
+ };
563
+
564
+ this.activeSessions.set(sessionId, session);
565
+ this.logger.info(`Session created: ${sessionId}`, { projectDir: session.projectDir });
566
+ } else {
567
+ // Update last activity
568
+ const session = this.activeSessions.get(sessionId);
569
+ session.lastActivity = new Date().toISOString();
570
+ }
571
+ }
572
+
573
+ /**
574
+ * Sanitize request for logging (remove sensitive data)
575
+ * @private
576
+ */
577
+ _sanitizeRequestForLogging(request) {
578
+ const sanitized = { ...request };
579
+
580
+ // Remove potentially sensitive user data
581
+ if (sanitized.user) {
582
+ sanitized.user = { id: sanitized.user.id };
583
+ }
584
+
585
+ // Truncate large message content
586
+ if (sanitized.payload && sanitized.payload.message && sanitized.payload.message.length > 500) {
587
+ sanitized.payload.message = sanitized.payload.message.substring(0, 500) + '... [truncated]';
588
+ }
589
+
590
+ return sanitized;
591
+ }
592
+ }
593
+
596
594
  export default Orchestrator;