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,630 +1,629 @@
1
- /**
2
- * Message State Management Hook
3
- * React hook for managing chat messages - sending, receiving, history, and pagination
4
- */
5
-
6
- import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
7
- import { debugLog } from '../utils/debugLogger.js';
8
- import {
9
- MESSAGE_CONFIG,
10
- PAGINATION,
11
- MESSAGE_ROLE,
12
- WS_MESSAGE_TYPE,
13
- } from '../config/constants.js';
14
-
15
- // Funny thinking phrases for loading animation
16
- const THINKING_PHRASES = [
17
- 'Pondering deeply...',
18
- 'Consulting the oracle...',
19
- 'Summoning wisdom...',
20
- 'Brewing thoughts...',
21
- 'Channeling brilliance...',
22
- 'Contemplating existence...',
23
- 'Computing the answer to life...',
24
- 'Thinking really hard...',
25
- 'Engaging neural networks...',
26
- 'Processing cosmic data...',
27
- 'Calibrating response generators...',
28
- 'Warming up the brain cells...',
29
- ];
30
-
31
- /**
32
- * Message state management hook
33
- * Manages message list, sending, receiving, history, and pagination
34
- */
35
- export function useMessages(sessionManager, messageRouter, currentAgentId) {
36
- // Message state
37
- const [messages, setMessages] = useState([]);
38
- const [loading, setLoading] = useState(false);
39
- const [sending, setSending] = useState(false);
40
- const [error, setError] = useState(null);
41
-
42
- // Pagination state
43
- const [hasMore, setHasMore] = useState(false);
44
- const [currentPage, setCurrentPage] = useState(0);
45
- const [totalMessages, setTotalMessages] = useState(0);
46
-
47
- // Message cache (per agent)
48
- const messageCache = useRef(new Map());
49
-
50
- // Current input text
51
- const [inputText, setInputText] = useState('');
52
-
53
- // Thinking animation state
54
- const [thinkingPhraseIndex, setThinkingPhraseIndex] = useState(0);
55
- const thinkingIntervalRef = useRef(null);
56
-
57
- /**
58
- * Start thinking animation
59
- */
60
- const startThinkingAnimation = useCallback(() => {
61
- // Pick a random starting phrase
62
- const randomIndex = Math.floor(Math.random() * THINKING_PHRASES.length);
63
- setThinkingPhraseIndex(randomIndex);
64
-
65
- // Clear any existing interval
66
- if (thinkingIntervalRef.current) {
67
- clearInterval(thinkingIntervalRef.current);
68
- }
69
-
70
- // Cycle through phrases every 2 seconds
71
- thinkingIntervalRef.current = setInterval(() => {
72
- setThinkingPhraseIndex(prev => (prev + 1) % THINKING_PHRASES.length);
73
- }, 2000);
74
- }, []);
75
-
76
- /**
77
- * Stop thinking animation
78
- */
79
- const stopThinkingAnimation = useCallback(() => {
80
- if (thinkingIntervalRef.current) {
81
- clearInterval(thinkingIntervalRef.current);
82
- thinkingIntervalRef.current = null;
83
- }
84
- }, []);
85
-
86
- /**
87
- * Get messages for current agent from cache
88
- */
89
- const getCachedMessages = useCallback(() => {
90
- if (!currentAgentId) return [];
91
- return messageCache.current.get(currentAgentId) || [];
92
- }, [currentAgentId]);
93
-
94
- /**
95
- * Update cache for current agent
96
- */
97
- const updateCache = useCallback((newMessages) => {
98
- if (!currentAgentId) return;
99
- messageCache.current.set(currentAgentId, newMessages);
100
- }, [currentAgentId]);
101
-
102
- /**
103
- * Fetch message history for current agent
104
- */
105
- const fetchMessages = useCallback(async (options = {}) => {
106
- debugLog('useMessages fetchMessages', 'Called with options:', options);
107
-
108
- if (!sessionManager?.isValid() || !currentAgentId) {
109
- debugLog('useMessages fetchMessages', 'FAILED: Invalid session or no agent');
110
- return { success: false, error: 'Invalid session or no agent selected' };
111
- }
112
-
113
- const {
114
- page = 0,
115
- limit = PAGINATION.PAGE_SIZE,
116
- append = false,
117
- } = options;
118
-
119
- debugLog('useMessages fetchMessages', `Starting fetch - page: ${page}, limit: ${limit}, append: ${append}`);
120
- setLoading(true);
121
- setError(null);
122
-
123
- try {
124
- debugLog('useMessages fetchMessages', 'Making API request to orchestrator...');
125
-
126
- // Request messages via orchestrator
127
- const response = await sessionManager.makeRequest('POST', '/api/orchestrator', {
128
- action: 'get_agent_conversations',
129
- payload: {
130
- agentId: currentAgentId,
131
- offset: page * limit,
132
- limit,
133
- },
134
- sessionId: sessionManager.getSessionId(),
135
- });
136
-
137
- debugLog('useMessages fetchMessages', 'API response received:', {
138
- success: response.success,
139
- hasData: !!response.data,
140
- hasConversations: !!(response.data?.conversations || response.conversations),
141
- error: response.error
142
- });
143
-
144
- if (response.success) {
145
- // Extract messages from conversations structure (can be in response.data or response directly)
146
- const responseData = response.data || response;
147
- const conversations = responseData.conversations || {};
148
- const fullConversation = conversations.full || {};
149
- const allMessages = fullConversation.messages || [];
150
-
151
- debugLog('useMessages fetchMessages', `Extracted ${allMessages.length} messages from response`);
152
-
153
- // Apply pagination manually since orchestrator returns full conversation
154
- const startIndex = page * limit;
155
- const endIndex = startIndex + limit;
156
- const newMessages = allMessages.slice(startIndex, endIndex);
157
-
158
- debugLog('useMessages fetchMessages', `After pagination: showing ${newMessages.length} messages (${startIndex} to ${endIndex})`);
159
-
160
- if (append) {
161
- // Append to existing messages (pagination) - use functional setState
162
- setMessages(prev => {
163
- const combined = [...prev, ...newMessages];
164
- updateCache(combined);
165
- debugLog('useMessages fetchMessages', `Appended messages, total: ${combined.length}`);
166
- return combined;
167
- });
168
- } else {
169
- // Replace messages (initial load)
170
- setMessages(newMessages);
171
- updateCache(newMessages);
172
- debugLog('useMessages fetchMessages', `Replaced messages, total: ${newMessages.length}`);
173
- }
174
-
175
- setTotalMessages(allMessages.length);
176
- setHasMore(endIndex < allMessages.length);
177
- setCurrentPage(page);
178
-
179
- debugLog('useMessages fetchMessages', 'Fetch complete - SUCCESS');
180
- return { success: true, messages: newMessages };
181
- }
182
-
183
- const errorMsg = response.error || 'Failed to fetch messages';
184
- debugLog('useMessages fetchMessages', 'Fetch FAILED:', errorMsg);
185
- throw new Error(errorMsg);
186
- } catch (err) {
187
- debugLog('useMessages fetchMessages', 'Exception caught:', err.message);
188
- debugLog('useMessages fetchMessages', 'Full error:', err.stack);
189
- setError(err.message);
190
- return { success: false, error: err.message };
191
- } finally {
192
- setLoading(false);
193
- debugLog('useMessages fetchMessages', 'Fetch complete (finally block)');
194
- }
195
- }, [sessionManager, currentAgentId, updateCache]);
196
-
197
- /**
198
- * Send a message to the current agent
199
- */
200
- const sendMessage = useCallback(async (content, options = {}) => {
201
- // DEBUG: Log received parameters
202
- debugLog('useMessages sendMessage', ' Called with content:', JSON.stringify(content));
203
- debugLog('useMessages sendMessage', ' content type:', typeof content);
204
- debugLog('useMessages sendMessage', ' options:', JSON.stringify(options));
205
-
206
- if (!sessionManager?.isValid() || !currentAgentId) {
207
- debugLog('useMessages sendMessage', ' VALIDATION FAILED: Invalid session or no agent');
208
- throw new Error('Invalid session or no agent selected');
209
- }
210
-
211
- if (!content || content.trim().length === 0) {
212
- debugLog('useMessages sendMessage', ' VALIDATION FAILED: Empty content');
213
- debugLog('useMessages sendMessage', ' !content:', !content);
214
- debugLog('useMessages sendMessage', ' trim length:', typeof content === 'string' ? content.trim().length : 'N/A');
215
- throw new Error('Message content cannot be empty');
216
- }
217
-
218
- if (content.length > MESSAGE_CONFIG.MAX_MESSAGE_LENGTH) {
219
- debugLog('useMessages sendMessage', ' VALIDATION FAILED: Content too long');
220
- throw new Error(`Message too long (max ${MESSAGE_CONFIG.MAX_MESSAGE_LENGTH} characters)`);
221
- }
222
-
223
- debugLog('useMessages sendMessage', ' All validations PASSED');
224
-
225
- setSending(true);
226
- setError(null);
227
-
228
- try {
229
- const {
230
- role = MESSAGE_ROLE.USER,
231
- attachments = [],
232
- } = options;
233
-
234
- debugLog('useMessages sendMessage', ' Prepared payload - agentId:', currentAgentId, 'content:', JSON.stringify(content), 'role:', role);
235
-
236
- // Send message via orchestrator
237
- const response = await sessionManager.makeRequest('POST', '/api/orchestrator', {
238
- action: 'send_message',
239
- payload: {
240
- agentId: currentAgentId,
241
- message: content, // Backend expects 'message' not 'content'
242
- role,
243
- attachments,
244
- },
245
- sessionId: sessionManager.getSessionId(),
246
- });
247
-
248
- debugLog('useMessages sendMessage', ' API response:', response.success ? 'SUCCESS' : 'FAILED');
249
-
250
- if (response.success) {
251
- // Clear input
252
- setInputText('');
253
-
254
- // OPTIMISTIC UPDATE: Add user message to UI immediately
255
- // Backend doesn't broadcast user messages via WebSocket, only assistant responses
256
- const userMessage = {
257
- id: `user-message-${Date.now()}`,
258
- agentId: currentAgentId,
259
- role,
260
- content,
261
- timestamp: new Date().toISOString(),
262
- };
263
-
264
- debugLog('useMessages sendMessage', ' Adding user message optimistically:', JSON.stringify(userMessage));
265
- addMessage(userMessage);
266
-
267
- // Add thinking message
268
- const thinkingMessage = {
269
- id: 'thinking-placeholder',
270
- agentId: currentAgentId,
271
- role: MESSAGE_ROLE.ASSISTANT,
272
- content: THINKING_PHRASES[thinkingPhraseIndex],
273
- timestamp: new Date().toISOString(),
274
- isThinking: true, // Special flag to identify this as a thinking message
275
- };
276
-
277
- addMessage(thinkingMessage);
278
- startThinkingAnimation();
279
-
280
- return { success: true };
281
- }
282
-
283
- throw new Error(response.error || 'Failed to send message');
284
- } catch (err) {
285
- setError(err.message);
286
- throw err;
287
- } finally {
288
- setSending(false);
289
- }
290
- }, [sessionManager, currentAgentId]);
291
-
292
- /**
293
- * Add a message to the list (from WebSocket)
294
- */
295
- const addMessage = useCallback((message) => {
296
- debugLog('useMessages addMessage', 'Called with message:', JSON.stringify(message));
297
- debugLog('useMessages addMessage', 'currentAgentId:', currentAgentId);
298
- debugLog('useMessages addMessage', 'message.agentId:', message.agentId);
299
-
300
- // Only add if for current agent
301
- if (message.agentId !== currentAgentId) {
302
- debugLog('useMessages addMessage', 'BLOCKED: agentId mismatch');
303
- return;
304
- }
305
-
306
- debugLog('useMessages addMessage', 'Adding message to state');
307
-
308
- setMessages(prev => {
309
- // If this is a real assistant message, remove the thinking placeholder
310
- if (message.role === MESSAGE_ROLE.ASSISTANT && !message.isThinking) {
311
- stopThinkingAnimation();
312
- // Remove thinking placeholder
313
- const withoutThinking = prev.filter(m => m.id !== 'thinking-placeholder');
314
-
315
- // Check for duplicates in the filtered array
316
- if (withoutThinking.find(m => m.id === message.id)) {
317
- debugLog('useMessages addMessage', 'BLOCKED: Duplicate message ID');
318
- return prev;
319
- }
320
-
321
- const updated = [...withoutThinking, message];
322
- const trimmed = updated.slice(-MESSAGE_CONFIG.MAX_MESSAGES_DISPLAY);
323
-
324
- debugLog('useMessages addMessage', 'Real AI response added, thinking removed, new count:', trimmed.length);
325
- updateCache(trimmed);
326
- return trimmed;
327
- }
328
-
329
- // Check for duplicates
330
- if (prev.find(m => m.id === message.id)) {
331
- debugLog('useMessages addMessage', 'BLOCKED: Duplicate message ID');
332
- return prev;
333
- }
334
-
335
- const updated = [...prev, message];
336
-
337
- // Enforce max messages limit
338
- const trimmed = updated.slice(-MESSAGE_CONFIG.MAX_MESSAGES_DISPLAY);
339
-
340
- debugLog('useMessages addMessage', 'Message added, new count:', trimmed.length);
341
- updateCache(trimmed);
342
- return trimmed;
343
- });
344
-
345
- setTotalMessages(prev => prev + 1);
346
- }, [currentAgentId, updateCache, stopThinkingAnimation]);
347
-
348
- /**
349
- * Update a message in the list
350
- */
351
- const updateMessage = useCallback((messageId, updates) => {
352
- setMessages(prev => prev.map(msg =>
353
- msg.id === messageId ? { ...msg, ...updates } : msg
354
- ));
355
- }, []);
356
-
357
- /**
358
- * Remove a message from the list
359
- */
360
- const removeMessage = useCallback((messageId) => {
361
- setMessages(prev => prev.filter(msg => msg.id !== messageId));
362
- setTotalMessages(prev => Math.max(0, prev - 1));
363
- }, []);
364
-
365
- /**
366
- * Clear all messages
367
- */
368
- const clearMessages = useCallback(() => {
369
- setMessages([]);
370
- setTotalMessages(0);
371
- setHasMore(false);
372
- setCurrentPage(0);
373
- if (currentAgentId) {
374
- updateCache([]);
375
- }
376
- }, [currentAgentId, updateCache]);
377
-
378
- /**
379
- * Load more messages (pagination)
380
- */
381
- const loadMore = useCallback(async () => {
382
- if (!hasMore || loading) {
383
- return;
384
- }
385
-
386
- return fetchMessages({
387
- page: currentPage + 1,
388
- append: true,
389
- });
390
- }, [hasMore, loading, currentPage, fetchMessages]);
391
-
392
- /**
393
- * Refresh message list
394
- */
395
- const refresh = useCallback(async () => {
396
- return fetchMessages({ page: 0, append: false });
397
- }, [fetchMessages]);
398
-
399
- /**
400
- * Get messages by role
401
- */
402
- const getMessagesByRole = useCallback((role) => {
403
- return messages.filter(msg => msg.role === role);
404
- }, [messages]);
405
-
406
- /**
407
- * Get user messages
408
- */
409
- const getUserMessages = useCallback(() => {
410
- return getMessagesByRole(MESSAGE_ROLE.USER);
411
- }, [getMessagesByRole]);
412
-
413
- /**
414
- * Get assistant messages
415
- */
416
- const getAssistantMessages = useCallback(() => {
417
- return getMessagesByRole(MESSAGE_ROLE.ASSISTANT);
418
- }, [getMessagesByRole]);
419
-
420
- /**
421
- * Get latest message
422
- */
423
- const getLatestMessage = useCallback(() => {
424
- return messages[messages.length - 1] || null;
425
- }, [messages]);
426
-
427
- /**
428
- * Search messages by content
429
- */
430
- const searchMessages = useCallback((query) => {
431
- if (!query || query.trim().length === 0) {
432
- return messages;
433
- }
434
-
435
- const lowerQuery = query.toLowerCase();
436
- return messages.filter(msg =>
437
- msg.content?.toLowerCase().includes(lowerQuery)
438
- );
439
- }, [messages]);
440
-
441
- /**
442
- * Clear error
443
- */
444
- const clearError = useCallback(() => {
445
- setError(null);
446
- }, []);
447
-
448
- // Set up WebSocket message listeners
449
- useEffect(() => {
450
- if (!messageRouter) return;
451
-
452
- debugLog('useMessages WebSocket', 'Setting up listeners for agent:', currentAgentId);
453
-
454
- // New message added
455
- const handleMessageAdded = (data) => {
456
- debugLog('useMessages WebSocket', 'Received agent:message_added event:', JSON.stringify(data));
457
- debugLog('useMessages WebSocket', 'data.agentId:', data.agentId, 'currentAgentId:', currentAgentId);
458
-
459
- if (data.agentId === currentAgentId) {
460
- debugLog('useMessages WebSocket', 'Agent ID matches, calling addMessage');
461
- addMessage(data.message);
462
- } else {
463
- debugLog('useMessages WebSocket', 'Agent ID mismatch, ignoring message');
464
- }
465
- };
466
-
467
- // Message updated
468
- const handleMessageUpdated = (data) => {
469
- debugLog('useMessages WebSocket', 'Received message:updated event:', JSON.stringify(data));
470
-
471
- if (data.agentId === currentAgentId) {
472
- updateMessage(data.messageId, data.updates);
473
- }
474
- };
475
-
476
- messageRouter.on('agent:message_added', handleMessageAdded);
477
- messageRouter.on('message:updated', handleMessageUpdated);
478
-
479
- debugLog('useMessages WebSocket', 'Listeners registered');
480
-
481
- return () => {
482
- debugLog('useMessages WebSocket', 'Cleaning up listeners');
483
- messageRouter.off('agent:message_added', handleMessageAdded);
484
- messageRouter.off('message:updated', handleMessageUpdated);
485
- };
486
- }, [messageRouter, currentAgentId, addMessage, updateMessage]);
487
-
488
- // Update thinking message content when phrase changes
489
- useEffect(() => {
490
- setMessages(prev => {
491
- const thinkingMsg = prev.find(m => m.id === 'thinking-placeholder');
492
- if (!thinkingMsg) return prev;
493
-
494
- return prev.map(m =>
495
- m.id === 'thinking-placeholder'
496
- ? { ...m, content: THINKING_PHRASES[thinkingPhraseIndex] }
497
- : m
498
- );
499
- });
500
- }, [thinkingPhraseIndex]);
501
-
502
- // Cleanup thinking animation on unmount
503
- useEffect(() => {
504
- return () => {
505
- stopThinkingAnimation();
506
- };
507
- }, [stopThinkingAnimation]);
508
-
509
- // Load messages when agent changes
510
- useEffect(() => {
511
- debugLog('useMessages', `Agent changed: currentAgentId=${currentAgentId}`);
512
-
513
- if (!currentAgentId) {
514
- debugLog('useMessages', 'No agent selected, clearing messages');
515
- setMessages([]);
516
- return;
517
- }
518
-
519
- // Check cache first
520
- const cached = getCachedMessages();
521
- debugLog('useMessages', `Cache check: found ${cached.length} cached messages`);
522
-
523
- if (cached.length > 0) {
524
- debugLog('useMessages', `Loading ${cached.length} messages from cache`);
525
- setMessages(cached);
526
- setTotalMessages(cached.length);
527
- } else {
528
- // Load conversation history from server
529
- debugLog('useMessages', 'No cache, fetching messages from server...');
530
- fetchMessages({ page: 0 });
531
- }
532
- }, [currentAgentId, getCachedMessages, fetchMessages]);
533
-
534
- // Return hook interface
535
- return useMemo(() => ({
536
- // State
537
- messages,
538
- loading,
539
- sending,
540
- error,
541
-
542
- // Pagination
543
- hasMore,
544
- currentPage,
545
- totalMessages,
546
-
547
- // Input
548
- inputText,
549
- setInputText,
550
-
551
- // Operations
552
- sendMessage,
553
- fetchMessages,
554
- loadMore,
555
- refresh,
556
-
557
- // Message management
558
- addMessage,
559
- updateMessage,
560
- removeMessage,
561
- clearMessages,
562
-
563
- // Queries
564
- getMessagesByRole,
565
- getUserMessages,
566
- getAssistantMessages,
567
- getLatestMessage,
568
- searchMessages,
569
-
570
- // Utilities
571
- clearError,
572
- }), [
573
- messages,
574
- loading,
575
- sending,
576
- error,
577
- hasMore,
578
- currentPage,
579
- totalMessages,
580
- inputText,
581
- setInputText,
582
- sendMessage,
583
- fetchMessages,
584
- loadMore,
585
- refresh,
586
- addMessage,
587
- updateMessage,
588
- removeMessage,
589
- clearMessages,
590
- getMessagesByRole,
591
- getUserMessages,
592
- getAssistantMessages,
593
- getLatestMessage,
594
- searchMessages,
595
- clearError,
596
- ]);
597
- }
598
-
599
- /**
600
- * Lightweight hook for message count only
601
- */
602
- export function useMessageCount(messages) {
603
- const [userCount, setUserCount] = useState(0);
604
- const [assistantCount, setAssistantCount] = useState(0);
605
- const [totalCount, setTotalCount] = useState(0);
606
-
607
- useEffect(() => {
608
- if (!messages) {
609
- setUserCount(0);
610
- setAssistantCount(0);
611
- setTotalCount(0);
612
- return;
613
- }
614
-
615
- const user = messages.filter(m => m.role === MESSAGE_ROLE.USER).length;
616
- const assistant = messages.filter(m => m.role === MESSAGE_ROLE.ASSISTANT).length;
617
-
618
- setUserCount(user);
619
- setAssistantCount(assistant);
620
- setTotalCount(messages.length);
621
- }, [messages]);
622
-
623
- return useMemo(() => ({
624
- userCount,
625
- assistantCount,
626
- totalCount,
627
- }), [userCount, assistantCount, totalCount]);
628
- }
629
-
630
- export default useMessages;
1
+ /**
2
+ * Message State Management Hook
3
+ * React hook for managing chat messages - sending, receiving, history, and pagination
4
+ */
5
+
6
+ import { useState, useEffect, useCallback, useRef, useMemo } from 'react';
7
+ import { debugLog } from '../utils/debugLogger.js';
8
+ import {
9
+ MESSAGE_CONFIG,
10
+ PAGINATION,
11
+ MESSAGE_ROLE,
12
+ } from '../config/constants.js';
13
+
14
+ // Funny thinking phrases for loading animation
15
+ const THINKING_PHRASES = [
16
+ 'Pondering deeply...',
17
+ 'Consulting the oracle...',
18
+ 'Summoning wisdom...',
19
+ 'Brewing thoughts...',
20
+ 'Channeling brilliance...',
21
+ 'Contemplating existence...',
22
+ 'Computing the answer to life...',
23
+ 'Thinking really hard...',
24
+ 'Engaging neural networks...',
25
+ 'Processing cosmic data...',
26
+ 'Calibrating response generators...',
27
+ 'Warming up the brain cells...',
28
+ ];
29
+
30
+ /**
31
+ * Message state management hook
32
+ * Manages message list, sending, receiving, history, and pagination
33
+ */
34
+ export function useMessages(sessionManager, messageRouter, currentAgentId) {
35
+ // Message state
36
+ const [messages, setMessages] = useState([]);
37
+ const [loading, setLoading] = useState(false);
38
+ const [sending, setSending] = useState(false);
39
+ const [error, setError] = useState(null);
40
+
41
+ // Pagination state
42
+ const [hasMore, setHasMore] = useState(false);
43
+ const [currentPage, setCurrentPage] = useState(0);
44
+ const [totalMessages, setTotalMessages] = useState(0);
45
+
46
+ // Message cache (per agent)
47
+ const messageCache = useRef(new Map());
48
+
49
+ // Current input text
50
+ const [inputText, setInputText] = useState('');
51
+
52
+ // Thinking animation state
53
+ const [thinkingPhraseIndex, setThinkingPhraseIndex] = useState(0);
54
+ const thinkingIntervalRef = useRef(null);
55
+
56
+ /**
57
+ * Start thinking animation
58
+ */
59
+ const startThinkingAnimation = useCallback(() => {
60
+ // Pick a random starting phrase
61
+ const randomIndex = Math.floor(Math.random() * THINKING_PHRASES.length);
62
+ setThinkingPhraseIndex(randomIndex);
63
+
64
+ // Clear any existing interval
65
+ if (thinkingIntervalRef.current) {
66
+ clearInterval(thinkingIntervalRef.current);
67
+ }
68
+
69
+ // Cycle through phrases every 2 seconds
70
+ thinkingIntervalRef.current = setInterval(() => {
71
+ setThinkingPhraseIndex(prev => (prev + 1) % THINKING_PHRASES.length);
72
+ }, 2000);
73
+ }, []);
74
+
75
+ /**
76
+ * Stop thinking animation
77
+ */
78
+ const stopThinkingAnimation = useCallback(() => {
79
+ if (thinkingIntervalRef.current) {
80
+ clearInterval(thinkingIntervalRef.current);
81
+ thinkingIntervalRef.current = null;
82
+ }
83
+ }, []);
84
+
85
+ /**
86
+ * Get messages for current agent from cache
87
+ */
88
+ const getCachedMessages = useCallback(() => {
89
+ if (!currentAgentId) return [];
90
+ return messageCache.current.get(currentAgentId) || [];
91
+ }, [currentAgentId]);
92
+
93
+ /**
94
+ * Update cache for current agent
95
+ */
96
+ const updateCache = useCallback((newMessages) => {
97
+ if (!currentAgentId) return;
98
+ messageCache.current.set(currentAgentId, newMessages);
99
+ }, [currentAgentId]);
100
+
101
+ /**
102
+ * Fetch message history for current agent
103
+ */
104
+ const fetchMessages = useCallback(async (options = {}) => {
105
+ debugLog('useMessages fetchMessages', 'Called with options:', options);
106
+
107
+ if (!sessionManager?.isValid() || !currentAgentId) {
108
+ debugLog('useMessages fetchMessages', 'FAILED: Invalid session or no agent');
109
+ return { success: false, error: 'Invalid session or no agent selected' };
110
+ }
111
+
112
+ const {
113
+ page = 0,
114
+ limit = PAGINATION.PAGE_SIZE,
115
+ append = false,
116
+ } = options;
117
+
118
+ debugLog('useMessages fetchMessages', `Starting fetch - page: ${page}, limit: ${limit}, append: ${append}`);
119
+ setLoading(true);
120
+ setError(null);
121
+
122
+ try {
123
+ debugLog('useMessages fetchMessages', 'Making API request to orchestrator...');
124
+
125
+ // Request messages via orchestrator
126
+ const response = await sessionManager.makeRequest('POST', '/api/orchestrator', {
127
+ action: 'get_agent_conversations',
128
+ payload: {
129
+ agentId: currentAgentId,
130
+ offset: page * limit,
131
+ limit,
132
+ },
133
+ sessionId: sessionManager.getSessionId(),
134
+ });
135
+
136
+ debugLog('useMessages fetchMessages', 'API response received:', {
137
+ success: response.success,
138
+ hasData: !!response.data,
139
+ hasConversations: !!(response.data?.conversations || response.conversations),
140
+ error: response.error
141
+ });
142
+
143
+ if (response.success) {
144
+ // Extract messages from conversations structure (can be in response.data or response directly)
145
+ const responseData = response.data || response;
146
+ const conversations = responseData.conversations || {};
147
+ const fullConversation = conversations.full || {};
148
+ const allMessages = fullConversation.messages || [];
149
+
150
+ debugLog('useMessages fetchMessages', `Extracted ${allMessages.length} messages from response`);
151
+
152
+ // Apply pagination manually since orchestrator returns full conversation
153
+ const startIndex = page * limit;
154
+ const endIndex = startIndex + limit;
155
+ const newMessages = allMessages.slice(startIndex, endIndex);
156
+
157
+ debugLog('useMessages fetchMessages', `After pagination: showing ${newMessages.length} messages (${startIndex} to ${endIndex})`);
158
+
159
+ if (append) {
160
+ // Append to existing messages (pagination) - use functional setState
161
+ setMessages(prev => {
162
+ const combined = [...prev, ...newMessages];
163
+ updateCache(combined);
164
+ debugLog('useMessages fetchMessages', `Appended messages, total: ${combined.length}`);
165
+ return combined;
166
+ });
167
+ } else {
168
+ // Replace messages (initial load)
169
+ setMessages(newMessages);
170
+ updateCache(newMessages);
171
+ debugLog('useMessages fetchMessages', `Replaced messages, total: ${newMessages.length}`);
172
+ }
173
+
174
+ setTotalMessages(allMessages.length);
175
+ setHasMore(endIndex < allMessages.length);
176
+ setCurrentPage(page);
177
+
178
+ debugLog('useMessages fetchMessages', 'Fetch complete - SUCCESS');
179
+ return { success: true, messages: newMessages };
180
+ }
181
+
182
+ const errorMsg = response.error || 'Failed to fetch messages';
183
+ debugLog('useMessages fetchMessages', 'Fetch FAILED:', errorMsg);
184
+ throw new Error(errorMsg);
185
+ } catch (err) {
186
+ debugLog('useMessages fetchMessages', 'Exception caught:', err.message);
187
+ debugLog('useMessages fetchMessages', 'Full error:', err.stack);
188
+ setError(err.message);
189
+ return { success: false, error: err.message };
190
+ } finally {
191
+ setLoading(false);
192
+ debugLog('useMessages fetchMessages', 'Fetch complete (finally block)');
193
+ }
194
+ }, [sessionManager, currentAgentId, updateCache]);
195
+
196
+ /**
197
+ * Send a message to the current agent
198
+ */
199
+ const sendMessage = useCallback(async (content, options = {}) => {
200
+ // DEBUG: Log received parameters
201
+ debugLog('useMessages sendMessage', ' Called with content:', JSON.stringify(content));
202
+ debugLog('useMessages sendMessage', ' content type:', typeof content);
203
+ debugLog('useMessages sendMessage', ' options:', JSON.stringify(options));
204
+
205
+ if (!sessionManager?.isValid() || !currentAgentId) {
206
+ debugLog('useMessages sendMessage', ' VALIDATION FAILED: Invalid session or no agent');
207
+ throw new Error('Invalid session or no agent selected');
208
+ }
209
+
210
+ if (!content || content.trim().length === 0) {
211
+ debugLog('useMessages sendMessage', ' VALIDATION FAILED: Empty content');
212
+ debugLog('useMessages sendMessage', ' !content:', !content);
213
+ debugLog('useMessages sendMessage', ' trim length:', typeof content === 'string' ? content.trim().length : 'N/A');
214
+ throw new Error('Message content cannot be empty');
215
+ }
216
+
217
+ if (content.length > MESSAGE_CONFIG.MAX_MESSAGE_LENGTH) {
218
+ debugLog('useMessages sendMessage', ' VALIDATION FAILED: Content too long');
219
+ throw new Error(`Message too long (max ${MESSAGE_CONFIG.MAX_MESSAGE_LENGTH} characters)`);
220
+ }
221
+
222
+ debugLog('useMessages sendMessage', ' All validations PASSED');
223
+
224
+ setSending(true);
225
+ setError(null);
226
+
227
+ try {
228
+ const {
229
+ role = MESSAGE_ROLE.USER,
230
+ attachments = [],
231
+ } = options;
232
+
233
+ debugLog('useMessages sendMessage', ' Prepared payload - agentId:', currentAgentId, 'content:', JSON.stringify(content), 'role:', role);
234
+
235
+ // Send message via orchestrator
236
+ const response = await sessionManager.makeRequest('POST', '/api/orchestrator', {
237
+ action: 'send_message',
238
+ payload: {
239
+ agentId: currentAgentId,
240
+ message: content, // Backend expects 'message' not 'content'
241
+ role,
242
+ attachments,
243
+ },
244
+ sessionId: sessionManager.getSessionId(),
245
+ });
246
+
247
+ debugLog('useMessages sendMessage', ' API response:', response.success ? 'SUCCESS' : 'FAILED');
248
+
249
+ if (response.success) {
250
+ // Clear input
251
+ setInputText('');
252
+
253
+ // OPTIMISTIC UPDATE: Add user message to UI immediately
254
+ // Backend doesn't broadcast user messages via WebSocket, only assistant responses
255
+ const userMessage = {
256
+ id: `user-message-${Date.now()}`,
257
+ agentId: currentAgentId,
258
+ role,
259
+ content,
260
+ timestamp: new Date().toISOString(),
261
+ };
262
+
263
+ debugLog('useMessages sendMessage', ' Adding user message optimistically:', JSON.stringify(userMessage));
264
+ addMessage(userMessage);
265
+
266
+ // Add thinking message
267
+ const thinkingMessage = {
268
+ id: 'thinking-placeholder',
269
+ agentId: currentAgentId,
270
+ role: MESSAGE_ROLE.ASSISTANT,
271
+ content: THINKING_PHRASES[thinkingPhraseIndex],
272
+ timestamp: new Date().toISOString(),
273
+ isThinking: true, // Special flag to identify this as a thinking message
274
+ };
275
+
276
+ addMessage(thinkingMessage);
277
+ startThinkingAnimation();
278
+
279
+ return { success: true };
280
+ }
281
+
282
+ throw new Error(response.error || 'Failed to send message');
283
+ } catch (err) {
284
+ setError(err.message);
285
+ throw err;
286
+ } finally {
287
+ setSending(false);
288
+ }
289
+ }, [sessionManager, currentAgentId]);
290
+
291
+ /**
292
+ * Add a message to the list (from WebSocket)
293
+ */
294
+ const addMessage = useCallback((message) => {
295
+ debugLog('useMessages addMessage', 'Called with message:', JSON.stringify(message));
296
+ debugLog('useMessages addMessage', 'currentAgentId:', currentAgentId);
297
+ debugLog('useMessages addMessage', 'message.agentId:', message.agentId);
298
+
299
+ // Only add if for current agent
300
+ if (message.agentId !== currentAgentId) {
301
+ debugLog('useMessages addMessage', 'BLOCKED: agentId mismatch');
302
+ return;
303
+ }
304
+
305
+ debugLog('useMessages addMessage', 'Adding message to state');
306
+
307
+ setMessages(prev => {
308
+ // If this is a real assistant message, remove the thinking placeholder
309
+ if (message.role === MESSAGE_ROLE.ASSISTANT && !message.isThinking) {
310
+ stopThinkingAnimation();
311
+ // Remove thinking placeholder
312
+ const withoutThinking = prev.filter(m => m.id !== 'thinking-placeholder');
313
+
314
+ // Check for duplicates in the filtered array
315
+ if (withoutThinking.find(m => m.id === message.id)) {
316
+ debugLog('useMessages addMessage', 'BLOCKED: Duplicate message ID');
317
+ return prev;
318
+ }
319
+
320
+ const updated = [...withoutThinking, message];
321
+ const trimmed = updated.slice(-MESSAGE_CONFIG.MAX_MESSAGES_DISPLAY);
322
+
323
+ debugLog('useMessages addMessage', 'Real AI response added, thinking removed, new count:', trimmed.length);
324
+ updateCache(trimmed);
325
+ return trimmed;
326
+ }
327
+
328
+ // Check for duplicates
329
+ if (prev.find(m => m.id === message.id)) {
330
+ debugLog('useMessages addMessage', 'BLOCKED: Duplicate message ID');
331
+ return prev;
332
+ }
333
+
334
+ const updated = [...prev, message];
335
+
336
+ // Enforce max messages limit
337
+ const trimmed = updated.slice(-MESSAGE_CONFIG.MAX_MESSAGES_DISPLAY);
338
+
339
+ debugLog('useMessages addMessage', 'Message added, new count:', trimmed.length);
340
+ updateCache(trimmed);
341
+ return trimmed;
342
+ });
343
+
344
+ setTotalMessages(prev => prev + 1);
345
+ }, [currentAgentId, updateCache, stopThinkingAnimation]);
346
+
347
+ /**
348
+ * Update a message in the list
349
+ */
350
+ const updateMessage = useCallback((messageId, updates) => {
351
+ setMessages(prev => prev.map(msg =>
352
+ msg.id === messageId ? { ...msg, ...updates } : msg
353
+ ));
354
+ }, []);
355
+
356
+ /**
357
+ * Remove a message from the list
358
+ */
359
+ const removeMessage = useCallback((messageId) => {
360
+ setMessages(prev => prev.filter(msg => msg.id !== messageId));
361
+ setTotalMessages(prev => Math.max(0, prev - 1));
362
+ }, []);
363
+
364
+ /**
365
+ * Clear all messages
366
+ */
367
+ const clearMessages = useCallback(() => {
368
+ setMessages([]);
369
+ setTotalMessages(0);
370
+ setHasMore(false);
371
+ setCurrentPage(0);
372
+ if (currentAgentId) {
373
+ updateCache([]);
374
+ }
375
+ }, [currentAgentId, updateCache]);
376
+
377
+ /**
378
+ * Load more messages (pagination)
379
+ */
380
+ const loadMore = useCallback(async () => {
381
+ if (!hasMore || loading) {
382
+ return;
383
+ }
384
+
385
+ return fetchMessages({
386
+ page: currentPage + 1,
387
+ append: true,
388
+ });
389
+ }, [hasMore, loading, currentPage, fetchMessages]);
390
+
391
+ /**
392
+ * Refresh message list
393
+ */
394
+ const refresh = useCallback(async () => {
395
+ return fetchMessages({ page: 0, append: false });
396
+ }, [fetchMessages]);
397
+
398
+ /**
399
+ * Get messages by role
400
+ */
401
+ const getMessagesByRole = useCallback((role) => {
402
+ return messages.filter(msg => msg.role === role);
403
+ }, [messages]);
404
+
405
+ /**
406
+ * Get user messages
407
+ */
408
+ const getUserMessages = useCallback(() => {
409
+ return getMessagesByRole(MESSAGE_ROLE.USER);
410
+ }, [getMessagesByRole]);
411
+
412
+ /**
413
+ * Get assistant messages
414
+ */
415
+ const getAssistantMessages = useCallback(() => {
416
+ return getMessagesByRole(MESSAGE_ROLE.ASSISTANT);
417
+ }, [getMessagesByRole]);
418
+
419
+ /**
420
+ * Get latest message
421
+ */
422
+ const getLatestMessage = useCallback(() => {
423
+ return messages[messages.length - 1] || null;
424
+ }, [messages]);
425
+
426
+ /**
427
+ * Search messages by content
428
+ */
429
+ const searchMessages = useCallback((query) => {
430
+ if (!query || query.trim().length === 0) {
431
+ return messages;
432
+ }
433
+
434
+ const lowerQuery = query.toLowerCase();
435
+ return messages.filter(msg =>
436
+ msg.content?.toLowerCase().includes(lowerQuery)
437
+ );
438
+ }, [messages]);
439
+
440
+ /**
441
+ * Clear error
442
+ */
443
+ const clearError = useCallback(() => {
444
+ setError(null);
445
+ }, []);
446
+
447
+ // Set up WebSocket message listeners
448
+ useEffect(() => {
449
+ if (!messageRouter) return;
450
+
451
+ debugLog('useMessages WebSocket', 'Setting up listeners for agent:', currentAgentId);
452
+
453
+ // New message added
454
+ const handleMessageAdded = (data) => {
455
+ debugLog('useMessages WebSocket', 'Received agent:message_added event:', JSON.stringify(data));
456
+ debugLog('useMessages WebSocket', 'data.agentId:', data.agentId, 'currentAgentId:', currentAgentId);
457
+
458
+ if (data.agentId === currentAgentId) {
459
+ debugLog('useMessages WebSocket', 'Agent ID matches, calling addMessage');
460
+ addMessage(data.message);
461
+ } else {
462
+ debugLog('useMessages WebSocket', 'Agent ID mismatch, ignoring message');
463
+ }
464
+ };
465
+
466
+ // Message updated
467
+ const handleMessageUpdated = (data) => {
468
+ debugLog('useMessages WebSocket', 'Received message:updated event:', JSON.stringify(data));
469
+
470
+ if (data.agentId === currentAgentId) {
471
+ updateMessage(data.messageId, data.updates);
472
+ }
473
+ };
474
+
475
+ messageRouter.on('agent:message_added', handleMessageAdded);
476
+ messageRouter.on('message:updated', handleMessageUpdated);
477
+
478
+ debugLog('useMessages WebSocket', 'Listeners registered');
479
+
480
+ return () => {
481
+ debugLog('useMessages WebSocket', 'Cleaning up listeners');
482
+ messageRouter.off('agent:message_added', handleMessageAdded);
483
+ messageRouter.off('message:updated', handleMessageUpdated);
484
+ };
485
+ }, [messageRouter, currentAgentId, addMessage, updateMessage]);
486
+
487
+ // Update thinking message content when phrase changes
488
+ useEffect(() => {
489
+ setMessages(prev => {
490
+ const thinkingMsg = prev.find(m => m.id === 'thinking-placeholder');
491
+ if (!thinkingMsg) return prev;
492
+
493
+ return prev.map(m =>
494
+ m.id === 'thinking-placeholder'
495
+ ? { ...m, content: THINKING_PHRASES[thinkingPhraseIndex] }
496
+ : m
497
+ );
498
+ });
499
+ }, [thinkingPhraseIndex]);
500
+
501
+ // Cleanup thinking animation on unmount
502
+ useEffect(() => {
503
+ return () => {
504
+ stopThinkingAnimation();
505
+ };
506
+ }, [stopThinkingAnimation]);
507
+
508
+ // Load messages when agent changes
509
+ useEffect(() => {
510
+ debugLog('useMessages', `Agent changed: currentAgentId=${currentAgentId}`);
511
+
512
+ if (!currentAgentId) {
513
+ debugLog('useMessages', 'No agent selected, clearing messages');
514
+ setMessages([]);
515
+ return;
516
+ }
517
+
518
+ // Check cache first
519
+ const cached = getCachedMessages();
520
+ debugLog('useMessages', `Cache check: found ${cached.length} cached messages`);
521
+
522
+ if (cached.length > 0) {
523
+ debugLog('useMessages', `Loading ${cached.length} messages from cache`);
524
+ setMessages(cached);
525
+ setTotalMessages(cached.length);
526
+ } else {
527
+ // Load conversation history from server
528
+ debugLog('useMessages', 'No cache, fetching messages from server...');
529
+ fetchMessages({ page: 0 });
530
+ }
531
+ }, [currentAgentId, getCachedMessages, fetchMessages]);
532
+
533
+ // Return hook interface
534
+ return useMemo(() => ({
535
+ // State
536
+ messages,
537
+ loading,
538
+ sending,
539
+ error,
540
+
541
+ // Pagination
542
+ hasMore,
543
+ currentPage,
544
+ totalMessages,
545
+
546
+ // Input
547
+ inputText,
548
+ setInputText,
549
+
550
+ // Operations
551
+ sendMessage,
552
+ fetchMessages,
553
+ loadMore,
554
+ refresh,
555
+
556
+ // Message management
557
+ addMessage,
558
+ updateMessage,
559
+ removeMessage,
560
+ clearMessages,
561
+
562
+ // Queries
563
+ getMessagesByRole,
564
+ getUserMessages,
565
+ getAssistantMessages,
566
+ getLatestMessage,
567
+ searchMessages,
568
+
569
+ // Utilities
570
+ clearError,
571
+ }), [
572
+ messages,
573
+ loading,
574
+ sending,
575
+ error,
576
+ hasMore,
577
+ currentPage,
578
+ totalMessages,
579
+ inputText,
580
+ setInputText,
581
+ sendMessage,
582
+ fetchMessages,
583
+ loadMore,
584
+ refresh,
585
+ addMessage,
586
+ updateMessage,
587
+ removeMessage,
588
+ clearMessages,
589
+ getMessagesByRole,
590
+ getUserMessages,
591
+ getAssistantMessages,
592
+ getLatestMessage,
593
+ searchMessages,
594
+ clearError,
595
+ ]);
596
+ }
597
+
598
+ /**
599
+ * Lightweight hook for message count only
600
+ */
601
+ export function useMessageCount(messages) {
602
+ const [userCount, setUserCount] = useState(0);
603
+ const [assistantCount, setAssistantCount] = useState(0);
604
+ const [totalCount, setTotalCount] = useState(0);
605
+
606
+ useEffect(() => {
607
+ if (!messages) {
608
+ setUserCount(0);
609
+ setAssistantCount(0);
610
+ setTotalCount(0);
611
+ return;
612
+ }
613
+
614
+ const user = messages.filter(m => m.role === MESSAGE_ROLE.USER).length;
615
+ const assistant = messages.filter(m => m.role === MESSAGE_ROLE.ASSISTANT).length;
616
+
617
+ setUserCount(user);
618
+ setAssistantCount(assistant);
619
+ setTotalCount(messages.length);
620
+ }, [messages]);
621
+
622
+ return useMemo(() => ({
623
+ userCount,
624
+ assistantCount,
625
+ totalCount,
626
+ }), [userCount, assistantCount, totalCount]);
627
+ }
628
+
629
+ export default useMessages;