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,730 +1,730 @@
1
- /**
2
- * Conversation Data Model - Type definitions and validation for conversations
3
- *
4
- * Purpose:
5
- * - Define the structure and properties of conversations
6
- * - Provide validation functions for conversation data
7
- * - Handle conversation lifecycle and state management
8
- */
9
-
10
- import { CONVERSATION_STATUS, MESSAGE_ROLES } from '../utilities/constants.js';
11
-
12
- /**
13
- * Conversation data model
14
- * @typedef {Object} Conversation
15
- * @property {string} id - Unique conversation identifier
16
- * @property {string} title - Human-readable conversation title
17
- * @property {string} agentId - ID of the associated agent
18
- * @property {string} status - Conversation status (active, archived, suspended)
19
- * @property {Message[]} messages - Array of conversation messages
20
- * @property {ConversationMetadata} metadata - Conversation metadata
21
- * @property {ConversationSettings} settings - Conversation-specific settings
22
- * @property {ConversationContext} context - Current conversation context
23
- * @property {string} createdAt - ISO timestamp of creation
24
- * @property {string} updatedAt - ISO timestamp of last update
25
- * @property {string} lastMessageAt - ISO timestamp of last message
26
- * @property {number} messageCount - Total number of messages
27
- * @property {number} tokenCount - Total tokens used in conversation
28
- * @property {number} cost - Total cost of conversation (USD)
29
- * @property {string[]} participants - List of participant IDs
30
- * @property {Object} summary - Conversation summary data
31
- */
32
-
33
- /**
34
- * Message data model
35
- * @typedef {Object} Message
36
- * @property {string} id - Unique message identifier
37
- * @property {string} conversationId - ID of parent conversation
38
- * @property {string} role - Message role (user, assistant, system)
39
- * @property {string} content - Message content
40
- * @property {string} agentId - ID of agent (for assistant messages)
41
- * @property {string} userId - ID of user (for user messages)
42
- * @property {MessageMetadata} metadata - Message metadata
43
- * @property {ContextReference[]} contextReferences - Referenced context items
44
- * @property {ToolExecution[]} toolExecutions - Tool executions in this message
45
- * @property {TokenUsage} tokenUsage - Token usage for this message
46
- * @property {string} createdAt - ISO timestamp of creation
47
- * @property {string} [editedAt] - ISO timestamp of last edit
48
- * @property {string} [parentMessageId] - ID of parent message (for edits/branches)
49
- * @property {boolean} isEdited - Whether message has been edited
50
- * @property {Object} flags - Message flags and annotations
51
- */
52
-
53
- /**
54
- * Conversation metadata
55
- * @typedef {Object} ConversationMetadata
56
- * @property {string[]} tags - Conversation tags
57
- * @property {string} category - Conversation category
58
- * @property {string} description - Conversation description
59
- * @property {boolean} isBookmarked - Whether conversation is bookmarked
60
- * @property {number} priority - Conversation priority (1-5)
61
- * @property {string} language - Primary language of conversation
62
- * @property {Object} customFields - Custom metadata fields
63
- * @property {string[]} relatedConversations - IDs of related conversations
64
- */
65
-
66
- /**
67
- * Conversation settings
68
- * @typedef {Object} ConversationSettings
69
- * @property {boolean} persistHistory - Whether to persist conversation history
70
- * @property {number} maxMessages - Maximum number of messages to keep
71
- * @property {boolean} autoSummarize - Whether to auto-generate summaries
72
- * @property {number} summarizeThreshold - Message count threshold for summarization
73
- * @property {boolean} enableContextReferences - Whether context references are enabled
74
- * @property {number} maxContextReferences - Maximum context references per message
75
- * @property {Object} notificationSettings - Notification preferences
76
- * @property {Object} privacySettings - Privacy and sharing settings
77
- */
78
-
79
- /**
80
- * Conversation context
81
- * @typedef {Object} ConversationContext
82
- * @property {string} currentTopic - Current conversation topic
83
- * @property {string[]} mentionedEntities - Entities mentioned in conversation
84
- * @property {Object} variables - Context variables and their values
85
- * @property {string[]} activeTools - Currently active/relevant tools
86
- * @property {Object} workingMemory - Short-term memory for conversation
87
- * @property {Object} preferences - User preferences relevant to conversation
88
- * @property {string} phase - Current conversation phase
89
- * @property {Object} goals - Conversation goals and objectives
90
- */
91
-
92
- /**
93
- * Message metadata
94
- * @typedef {Object} MessageMetadata
95
- * @property {string} model - AI model used (for assistant messages)
96
- * @property {number} temperature - Generation temperature used
97
- * @property {number} responseTime - Time taken to generate response (ms)
98
- * @property {string} ipAddress - IP address of sender (if applicable)
99
- * @property {string} userAgent - User agent string (if applicable)
100
- * @property {Object} modelParameters - Model-specific parameters used
101
- * @property {string} generationId - Unique generation identifier
102
- * @property {Object} annotations - Message annotations and labels
103
- */
104
-
105
- /**
106
- * Token usage information
107
- * @typedef {Object} TokenUsage
108
- * @property {number} promptTokens - Tokens used in prompt
109
- * @property {number} completionTokens - Tokens used in completion
110
- * @property {number} totalTokens - Total tokens used
111
- * @property {number} cost - Cost of token usage (USD)
112
- * @property {string} model - Model used for generation
113
- * @property {Object} breakdown - Detailed token usage breakdown
114
- */
115
-
116
- /**
117
- * Context reference in messages
118
- * @typedef {Object} ContextReference
119
- * @property {string} id - Unique reference identifier
120
- * @property {string} type - Reference type (file, component, selection, directory)
121
- * @property {string} path - Path or identifier of referenced item
122
- * @property {string} name - Human-readable name
123
- * @property {string} [content] - Referenced content (if applicable)
124
- * @property {number} [startLine] - Start line (for selections)
125
- * @property {number} [endLine] - End line (for selections)
126
- * @property {Object} metadata - Reference metadata
127
- */
128
-
129
- /**
130
- * Tool execution information
131
- * @typedef {Object} ToolExecution
132
- * @property {string} id - Unique execution identifier
133
- * @property {string} toolId - Tool identifier
134
- * @property {string} status - Execution status (pending, executing, completed, failed)
135
- * @property {Object} input - Tool input parameters
136
- * @property {Object} [output] - Tool output (if completed)
137
- * @property {string} [error] - Error message (if failed)
138
- * @property {number} executionTime - Execution time in milliseconds
139
- * @property {string} startedAt - ISO timestamp when execution started
140
- * @property {string} [completedAt] - ISO timestamp when execution completed
141
- */
142
-
143
- /**
144
- * Conversation validation functions
145
- */
146
- export class ConversationValidator {
147
- /**
148
- * Validate conversation data structure
149
- * @param {Object} conversation - Conversation data to validate
150
- * @returns {Object} Validation result
151
- */
152
- static validate(conversation) {
153
- const errors = [];
154
- const warnings = [];
155
-
156
- // Required fields
157
- if (!conversation.id || typeof conversation.id !== 'string') {
158
- errors.push('Conversation ID is required and must be a string');
159
- }
160
-
161
- if (!conversation.agentId || typeof conversation.agentId !== 'string') {
162
- errors.push('Agent ID is required and must be a string');
163
- }
164
-
165
- if (!conversation.title || typeof conversation.title !== 'string') {
166
- errors.push('Conversation title is required and must be a string');
167
- }
168
-
169
- if (conversation.title && conversation.title.length > 200) {
170
- warnings.push('Conversation title is very long (>200 characters)');
171
- }
172
-
173
- // Status validation
174
- if (conversation.status && !Object.values(CONVERSATION_STATUS).includes(conversation.status)) {
175
- errors.push(`Invalid conversation status: ${conversation.status}`);
176
- }
177
-
178
- // Messages validation
179
- if (conversation.messages && !Array.isArray(conversation.messages)) {
180
- errors.push('Messages must be an array');
181
- }
182
-
183
- if (conversation.messages) {
184
- conversation.messages.forEach((message, index) => {
185
- const messageValidation = this.validateMessage(message);
186
- messageValidation.errors.forEach(error => {
187
- errors.push(`Message ${index}: ${error}`);
188
- });
189
- messageValidation.warnings.forEach(warning => {
190
- warnings.push(`Message ${index}: ${warning}`);
191
- });
192
- });
193
- }
194
-
195
- // Numeric validations
196
- if (conversation.messageCount !== undefined && typeof conversation.messageCount !== 'number') {
197
- errors.push('Message count must be a number');
198
- }
199
-
200
- if (conversation.tokenCount !== undefined && typeof conversation.tokenCount !== 'number') {
201
- errors.push('Token count must be a number');
202
- }
203
-
204
- if (conversation.cost !== undefined && typeof conversation.cost !== 'number') {
205
- errors.push('Cost must be a number');
206
- }
207
-
208
- // Participants validation
209
- if (conversation.participants && !Array.isArray(conversation.participants)) {
210
- errors.push('Participants must be an array');
211
- }
212
-
213
- // Timestamp validation
214
- const timestampFields = ['createdAt', 'updatedAt', 'lastMessageAt'];
215
- timestampFields.forEach(field => {
216
- if (conversation[field] && !this.isValidTimestamp(conversation[field])) {
217
- errors.push(`Invalid timestamp for ${field}: ${conversation[field]}`);
218
- }
219
- });
220
-
221
- return {
222
- isValid: errors.length === 0,
223
- errors,
224
- warnings
225
- };
226
- }
227
-
228
- /**
229
- * Validate message data structure
230
- * @param {Object} message - Message data to validate
231
- * @returns {Object} Validation result
232
- */
233
- static validateMessage(message) {
234
- const errors = [];
235
- const warnings = [];
236
-
237
- // Required fields
238
- if (!message.id || typeof message.id !== 'string') {
239
- errors.push('Message ID is required and must be a string');
240
- }
241
-
242
- if (!message.conversationId || typeof message.conversationId !== 'string') {
243
- errors.push('Conversation ID is required and must be a string');
244
- }
245
-
246
- if (!message.role || typeof message.role !== 'string') {
247
- errors.push('Message role is required and must be a string');
248
- }
249
-
250
- if (message.role && !Object.values(MESSAGE_ROLES).includes(message.role)) {
251
- errors.push(`Invalid message role: ${message.role}`);
252
- }
253
-
254
- if (!message.content || typeof message.content !== 'string') {
255
- errors.push('Message content is required and must be a string');
256
- }
257
-
258
- if (message.content && message.content.length > 100000) {
259
- warnings.push('Message content is very long (>100000 characters)');
260
- }
261
-
262
- // Role-specific validations
263
- if (message.role === MESSAGE_ROLES.ASSISTANT && !message.agentId) {
264
- errors.push('Assistant messages must have an agentId');
265
- }
266
-
267
- if (message.role === MESSAGE_ROLES.USER && !message.userId) {
268
- warnings.push('User messages should have a userId');
269
- }
270
-
271
- // Context references validation
272
- if (message.contextReferences && !Array.isArray(message.contextReferences)) {
273
- errors.push('Context references must be an array');
274
- }
275
-
276
- // Tool executions validation
277
- if (message.toolExecutions && !Array.isArray(message.toolExecutions)) {
278
- errors.push('Tool executions must be an array');
279
- }
280
-
281
- // Token usage validation
282
- if (message.tokenUsage) {
283
- const tokenValidation = this.validateTokenUsage(message.tokenUsage);
284
- errors.push(...tokenValidation.errors);
285
- warnings.push(...tokenValidation.warnings);
286
- }
287
-
288
- // Timestamp validation
289
- if (message.createdAt && !this.isValidTimestamp(message.createdAt)) {
290
- errors.push(`Invalid createdAt timestamp: ${message.createdAt}`);
291
- }
292
-
293
- if (message.editedAt && !this.isValidTimestamp(message.editedAt)) {
294
- errors.push(`Invalid editedAt timestamp: ${message.editedAt}`);
295
- }
296
-
297
- return { errors, warnings };
298
- }
299
-
300
- /**
301
- * Validate token usage data
302
- * @param {Object} tokenUsage - Token usage to validate
303
- * @returns {Object} Validation result
304
- */
305
- static validateTokenUsage(tokenUsage) {
306
- const errors = [];
307
- const warnings = [];
308
-
309
- if (typeof tokenUsage.totalTokens !== 'number' || tokenUsage.totalTokens < 0) {
310
- errors.push('Total tokens must be a non-negative number');
311
- }
312
-
313
- if (tokenUsage.promptTokens !== undefined && (typeof tokenUsage.promptTokens !== 'number' || tokenUsage.promptTokens < 0)) {
314
- errors.push('Prompt tokens must be a non-negative number');
315
- }
316
-
317
- if (tokenUsage.completionTokens !== undefined && (typeof tokenUsage.completionTokens !== 'number' || tokenUsage.completionTokens < 0)) {
318
- errors.push('Completion tokens must be a non-negative number');
319
- }
320
-
321
- if (tokenUsage.cost !== undefined && (typeof tokenUsage.cost !== 'number' || tokenUsage.cost < 0)) {
322
- errors.push('Cost must be a non-negative number');
323
- }
324
-
325
- if (tokenUsage.promptTokens && tokenUsage.completionTokens) {
326
- const calculatedTotal = tokenUsage.promptTokens + tokenUsage.completionTokens;
327
- if (Math.abs(calculatedTotal - tokenUsage.totalTokens) > 1) {
328
- warnings.push('Total tokens does not match sum of prompt and completion tokens');
329
- }
330
- }
331
-
332
- return { errors, warnings };
333
- }
334
-
335
- /**
336
- * Check if a timestamp is valid ISO string
337
- * @param {string} timestamp - Timestamp to validate
338
- * @returns {boolean} True if valid
339
- */
340
- static isValidTimestamp(timestamp) {
341
- if (typeof timestamp !== 'string') return false;
342
- const date = new Date(timestamp);
343
- return date instanceof Date && !isNaN(date.getTime());
344
- }
345
- }
346
-
347
- /**
348
- * Conversation factory functions
349
- */
350
- export class ConversationFactory {
351
- /**
352
- * Create a new conversation
353
- * @param {string} agentId - Agent ID
354
- * @param {string} title - Conversation title
355
- * @param {Object} options - Additional options
356
- * @returns {Conversation} New conversation object
357
- */
358
- static create(agentId, title, options = {}) {
359
- const now = new Date().toISOString();
360
- const conversationId = this.generateConversationId();
361
-
362
- return {
363
- id: conversationId,
364
- title: title || 'New Conversation',
365
- agentId,
366
- status: CONVERSATION_STATUS.ACTIVE,
367
- messages: [],
368
- metadata: this.createDefaultMetadata(options.metadata),
369
- settings: this.createDefaultSettings(options.settings),
370
- context: this.createDefaultContext(),
371
- createdAt: now,
372
- updatedAt: now,
373
- lastMessageAt: now,
374
- messageCount: 0,
375
- tokenCount: 0,
376
- cost: 0,
377
- participants: [agentId, ...(options.participants || [])],
378
- summary: {}
379
- };
380
- }
381
-
382
- /**
383
- * Create a new message
384
- * @param {string} conversationId - Conversation ID
385
- * @param {string} role - Message role
386
- * @param {string} content - Message content
387
- * @param {Object} options - Additional options
388
- * @returns {Message} New message object
389
- */
390
- static createMessage(conversationId, role, content, options = {}) {
391
- const now = new Date().toISOString();
392
- const messageId = this.generateMessageId();
393
-
394
- return {
395
- id: messageId,
396
- conversationId,
397
- role,
398
- content,
399
- agentId: options.agentId || null,
400
- userId: options.userId || null,
401
- metadata: options.metadata || {},
402
- contextReferences: options.contextReferences || [],
403
- toolExecutions: options.toolExecutions || [],
404
- tokenUsage: options.tokenUsage || null,
405
- createdAt: now,
406
- editedAt: null,
407
- parentMessageId: options.parentMessageId || null,
408
- isEdited: false,
409
- flags: options.flags || {}
410
- };
411
- }
412
-
413
- /**
414
- * Create default conversation metadata
415
- * @param {Object} overrides - Metadata overrides
416
- * @returns {ConversationMetadata} Default metadata
417
- */
418
- static createDefaultMetadata(overrides = {}) {
419
- return {
420
- tags: [],
421
- category: 'general',
422
- description: '',
423
- isBookmarked: false,
424
- priority: 3,
425
- language: 'en',
426
- customFields: {},
427
- relatedConversations: [],
428
- ...overrides
429
- };
430
- }
431
-
432
- /**
433
- * Create default conversation settings
434
- * @param {Object} overrides - Settings overrides
435
- * @returns {ConversationSettings} Default settings
436
- */
437
- static createDefaultSettings(overrides = {}) {
438
- return {
439
- persistHistory: true,
440
- maxMessages: 1000,
441
- autoSummarize: true,
442
- summarizeThreshold: 50,
443
- enableContextReferences: true,
444
- maxContextReferences: 10,
445
- notificationSettings: {
446
- newMessage: true,
447
- agentResponse: true,
448
- toolExecution: false
449
- },
450
- privacySettings: {
451
- shareHistory: false,
452
- allowAnalytics: true
453
- },
454
- ...overrides
455
- };
456
- }
457
-
458
- /**
459
- * Create default conversation context
460
- * @returns {ConversationContext} Default context
461
- */
462
- static createDefaultContext() {
463
- return {
464
- currentTopic: null,
465
- mentionedEntities: [],
466
- variables: {},
467
- activeTools: [],
468
- workingMemory: {},
469
- preferences: {},
470
- phase: 'initial',
471
- goals: {}
472
- };
473
- }
474
-
475
- /**
476
- * Generate unique conversation ID
477
- * @returns {string} Unique conversation ID
478
- */
479
- static generateConversationId() {
480
- const timestamp = Date.now().toString(36);
481
- const random = Math.random().toString(36).substr(2, 9);
482
- return `conv_${timestamp}_${random}`;
483
- }
484
-
485
- /**
486
- * Generate unique message ID
487
- * @returns {string} Unique message ID
488
- */
489
- static generateMessageId() {
490
- const timestamp = Date.now().toString(36);
491
- const random = Math.random().toString(36).substr(2, 9);
492
- return `msg_${timestamp}_${random}`;
493
- }
494
- }
495
-
496
- /**
497
- * Conversation utility functions
498
- */
499
- export class ConversationUtils {
500
- /**
501
- * Calculate conversation statistics
502
- * @param {Conversation} conversation - Conversation to analyze
503
- * @returns {Object} Conversation statistics
504
- */
505
- static getStatistics(conversation) {
506
- const messages = conversation.messages || [];
507
- const userMessages = messages.filter(m => m.role === MESSAGE_ROLES.USER);
508
- const assistantMessages = messages.filter(m => m.role === MESSAGE_ROLES.ASSISTANT);
509
- const systemMessages = messages.filter(m => m.role === MESSAGE_ROLES.SYSTEM);
510
-
511
- const totalTokens = messages.reduce((sum, m) => sum + (m.tokenUsage?.totalTokens || 0), 0);
512
- const totalCost = messages.reduce((sum, m) => sum + (m.tokenUsage?.cost || 0), 0);
513
-
514
- const toolExecutions = messages.reduce((sum, m) => sum + (m.toolExecutions?.length || 0), 0);
515
- const contextReferences = messages.reduce((sum, m) => sum + (m.contextReferences?.length || 0), 0);
516
-
517
- return {
518
- totalMessages: messages.length,
519
- userMessages: userMessages.length,
520
- assistantMessages: assistantMessages.length,
521
- systemMessages: systemMessages.length,
522
- totalTokens,
523
- totalCost,
524
- toolExecutions,
525
- contextReferences,
526
- averageMessageLength: messages.length > 0
527
- ? messages.reduce((sum, m) => sum + m.content.length, 0) / messages.length
528
- : 0,
529
- conversationDuration: this.getConversationDuration(conversation)
530
- };
531
- }
532
-
533
- /**
534
- * Get conversation duration in milliseconds
535
- * @param {Conversation} conversation - Conversation to analyze
536
- * @returns {number} Duration in milliseconds
537
- */
538
- static getConversationDuration(conversation) {
539
- if (!conversation.messages || conversation.messages.length === 0) {
540
- return 0;
541
- }
542
-
543
- const firstMessage = conversation.messages[0];
544
- const lastMessage = conversation.messages[conversation.messages.length - 1];
545
-
546
- const startTime = new Date(firstMessage.createdAt);
547
- const endTime = new Date(lastMessage.createdAt);
548
-
549
- return endTime.getTime() - startTime.getTime();
550
- }
551
-
552
- /**
553
- * Generate conversation summary
554
- * @param {Conversation} conversation - Conversation to summarize
555
- * @returns {Object} Conversation summary
556
- */
557
- static generateSummary(conversation) {
558
- const stats = this.getStatistics(conversation);
559
- const messages = conversation.messages || [];
560
-
561
- // Extract key topics and entities
562
- const topics = this.extractTopics(messages);
563
- const entities = this.extractEntities(messages);
564
-
565
- // Get recent activity
566
- const recentMessages = messages.slice(-10);
567
- const lastActivity = conversation.lastMessageAt || conversation.updatedAt;
568
-
569
- return {
570
- title: conversation.title,
571
- messageCount: stats.totalMessages,
572
- duration: stats.conversationDuration,
573
- participants: conversation.participants.length,
574
- topics: topics.slice(0, 5), // Top 5 topics
575
- entities: entities.slice(0, 10), // Top 10 entities
576
- lastActivity,
577
- recentActivity: recentMessages.map(m => ({
578
- role: m.role,
579
- timestamp: m.createdAt,
580
- preview: m.content.substring(0, 100) + (m.content.length > 100 ? '...' : '')
581
- })),
582
- stats
583
- };
584
- }
585
-
586
- /**
587
- * Extract topics from conversation messages
588
- * @param {Message[]} messages - Messages to analyze
589
- * @returns {string[]} Extracted topics
590
- */
591
- static extractTopics(messages) {
592
- // Simple topic extraction based on keywords
593
- // In a real implementation, this would use more sophisticated NLP
594
- const topicKeywords = new Map();
595
-
596
- messages.forEach(message => {
597
- const words = message.content.toLowerCase()
598
- .split(/\s+/)
599
- .filter(word => word.length > 3 && !this.isStopWord(word));
600
-
601
- words.forEach(word => {
602
- topicKeywords.set(word, (topicKeywords.get(word) || 0) + 1);
603
- });
604
- });
605
-
606
- return Array.from(topicKeywords.entries())
607
- .sort((a, b) => b[1] - a[1])
608
- .map(([word]) => word);
609
- }
610
-
611
- /**
612
- * Extract entities from conversation messages
613
- * @param {Message[]} messages - Messages to analyze
614
- * @returns {string[]} Extracted entities
615
- */
616
- static extractEntities(messages) {
617
- // Simple entity extraction
618
- // In a real implementation, this would use NER
619
- const entities = new Set();
620
-
621
- messages.forEach(message => {
622
- // Extract capitalized words (potential proper nouns)
623
- const capitalizedWords = message.content.match(/\b[A-Z][a-z]+\b/g) || [];
624
- capitalizedWords.forEach(word => entities.add(word));
625
-
626
- // Extract file paths
627
- const filePaths = message.content.match(/\b[\w\/\-\.]+\.\w+\b/g) || [];
628
- filePaths.forEach(path => entities.add(path));
629
- });
630
-
631
- return Array.from(entities);
632
- }
633
-
634
- /**
635
- * Check if word is a stop word
636
- * @param {string} word - Word to check
637
- * @returns {boolean} True if stop word
638
- */
639
- static isStopWord(word) {
640
- const stopWords = new Set([
641
- 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
642
- 'by', 'from', 'up', 'about', 'into', 'through', 'during', 'before',
643
- 'after', 'above', 'below', 'over', 'under', 'again', 'further',
644
- 'then', 'once', 'here', 'there', 'when', 'where', 'why', 'how',
645
- 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other',
646
- 'some', 'such', 'only', 'own', 'same', 'so', 'than', 'too',
647
- 'very', 'can', 'will', 'just', 'should', 'now'
648
- ]);
649
-
650
- return stopWords.has(word.toLowerCase());
651
- }
652
-
653
- /**
654
- * Format conversation for export
655
- * @param {Conversation} conversation - Conversation to format
656
- * @param {string} format - Export format ('json', 'markdown', 'plain')
657
- * @returns {string} Formatted conversation
658
- */
659
- static formatForExport(conversation, format = 'json') {
660
- switch (format) {
661
- case 'markdown':
662
- return this.formatAsMarkdown(conversation);
663
- case 'plain':
664
- return this.formatAsPlainText(conversation);
665
- case 'json':
666
- default:
667
- return JSON.stringify(conversation, null, 2);
668
- }
669
- }
670
-
671
- /**
672
- * Format conversation as markdown
673
- * @param {Conversation} conversation - Conversation to format
674
- * @returns {string} Markdown formatted conversation
675
- */
676
- static formatAsMarkdown(conversation) {
677
- let markdown = `# ${conversation.title}\n\n`;
678
- markdown += `**Created:** ${new Date(conversation.createdAt).toLocaleString()}\n`;
679
- markdown += `**Agent:** ${conversation.agentId}\n`;
680
- markdown += `**Messages:** ${conversation.messageCount}\n\n`;
681
-
682
- conversation.messages.forEach(message => {
683
- const timestamp = new Date(message.createdAt).toLocaleTimeString();
684
- const role = message.role.charAt(0).toUpperCase() + message.role.slice(1);
685
-
686
- markdown += `## ${role} (${timestamp})\n\n`;
687
- markdown += `${message.content}\n\n`;
688
-
689
- if (message.contextReferences && message.contextReferences.length > 0) {
690
- markdown += `**Context References:**\n`;
691
- message.contextReferences.forEach(ref => {
692
- markdown += `- ${ref.name} (${ref.type})\n`;
693
- });
694
- markdown += '\n';
695
- }
696
- });
697
-
698
- return markdown;
699
- }
700
-
701
- /**
702
- * Format conversation as plain text
703
- * @param {Conversation} conversation - Conversation to format
704
- * @returns {string} Plain text formatted conversation
705
- */
706
- static formatAsPlainText(conversation) {
707
- let text = `Conversation: ${conversation.title}\n`;
708
- text += `Created: ${new Date(conversation.createdAt).toLocaleString()}\n`;
709
- text += `Agent: ${conversation.agentId}\n`;
710
- text += `Messages: ${conversation.messageCount}\n\n`;
711
-
712
- text += '-'.repeat(50) + '\n\n';
713
-
714
- conversation.messages.forEach(message => {
715
- const timestamp = new Date(message.createdAt).toLocaleTimeString();
716
- const role = message.role.toUpperCase();
717
-
718
- text += `[${timestamp}] ${role}:\n`;
719
- text += `${message.content}\n\n`;
720
- });
721
-
722
- return text;
723
- }
724
- }
725
-
726
- export default {
727
- ConversationValidator,
728
- ConversationFactory,
729
- ConversationUtils
1
+ /**
2
+ * Conversation Data Model - Type definitions and validation for conversations
3
+ *
4
+ * Purpose:
5
+ * - Define the structure and properties of conversations
6
+ * - Provide validation functions for conversation data
7
+ * - Handle conversation lifecycle and state management
8
+ */
9
+
10
+ import { CONVERSATION_STATUS, MESSAGE_ROLES } from '../utilities/constants.js';
11
+
12
+ /**
13
+ * Conversation data model
14
+ * @typedef {Object} Conversation
15
+ * @property {string} id - Unique conversation identifier
16
+ * @property {string} title - Human-readable conversation title
17
+ * @property {string} agentId - ID of the associated agent
18
+ * @property {string} status - Conversation status (active, archived, suspended)
19
+ * @property {Message[]} messages - Array of conversation messages
20
+ * @property {ConversationMetadata} metadata - Conversation metadata
21
+ * @property {ConversationSettings} settings - Conversation-specific settings
22
+ * @property {ConversationContext} context - Current conversation context
23
+ * @property {string} createdAt - ISO timestamp of creation
24
+ * @property {string} updatedAt - ISO timestamp of last update
25
+ * @property {string} lastMessageAt - ISO timestamp of last message
26
+ * @property {number} messageCount - Total number of messages
27
+ * @property {number} tokenCount - Total tokens used in conversation
28
+ * @property {number} cost - Total cost of conversation (USD)
29
+ * @property {string[]} participants - List of participant IDs
30
+ * @property {Object} summary - Conversation summary data
31
+ */
32
+
33
+ /**
34
+ * Message data model
35
+ * @typedef {Object} Message
36
+ * @property {string} id - Unique message identifier
37
+ * @property {string} conversationId - ID of parent conversation
38
+ * @property {string} role - Message role (user, assistant, system)
39
+ * @property {string} content - Message content
40
+ * @property {string} agentId - ID of agent (for assistant messages)
41
+ * @property {string} userId - ID of user (for user messages)
42
+ * @property {MessageMetadata} metadata - Message metadata
43
+ * @property {ContextReference[]} contextReferences - Referenced context items
44
+ * @property {ToolExecution[]} toolExecutions - Tool executions in this message
45
+ * @property {TokenUsage} tokenUsage - Token usage for this message
46
+ * @property {string} createdAt - ISO timestamp of creation
47
+ * @property {string} [editedAt] - ISO timestamp of last edit
48
+ * @property {string} [parentMessageId] - ID of parent message (for edits/branches)
49
+ * @property {boolean} isEdited - Whether message has been edited
50
+ * @property {Object} flags - Message flags and annotations
51
+ */
52
+
53
+ /**
54
+ * Conversation metadata
55
+ * @typedef {Object} ConversationMetadata
56
+ * @property {string[]} tags - Conversation tags
57
+ * @property {string} category - Conversation category
58
+ * @property {string} description - Conversation description
59
+ * @property {boolean} isBookmarked - Whether conversation is bookmarked
60
+ * @property {number} priority - Conversation priority (1-5)
61
+ * @property {string} language - Primary language of conversation
62
+ * @property {Object} customFields - Custom metadata fields
63
+ * @property {string[]} relatedConversations - IDs of related conversations
64
+ */
65
+
66
+ /**
67
+ * Conversation settings
68
+ * @typedef {Object} ConversationSettings
69
+ * @property {boolean} persistHistory - Whether to persist conversation history
70
+ * @property {number} maxMessages - Maximum number of messages to keep
71
+ * @property {boolean} autoSummarize - Whether to auto-generate summaries
72
+ * @property {number} summarizeThreshold - Message count threshold for summarization
73
+ * @property {boolean} enableContextReferences - Whether context references are enabled
74
+ * @property {number} maxContextReferences - Maximum context references per message
75
+ * @property {Object} notificationSettings - Notification preferences
76
+ * @property {Object} privacySettings - Privacy and sharing settings
77
+ */
78
+
79
+ /**
80
+ * Conversation context
81
+ * @typedef {Object} ConversationContext
82
+ * @property {string} currentTopic - Current conversation topic
83
+ * @property {string[]} mentionedEntities - Entities mentioned in conversation
84
+ * @property {Object} variables - Context variables and their values
85
+ * @property {string[]} activeTools - Currently active/relevant tools
86
+ * @property {Object} workingMemory - Short-term memory for conversation
87
+ * @property {Object} preferences - User preferences relevant to conversation
88
+ * @property {string} phase - Current conversation phase
89
+ * @property {Object} goals - Conversation goals and objectives
90
+ */
91
+
92
+ /**
93
+ * Message metadata
94
+ * @typedef {Object} MessageMetadata
95
+ * @property {string} model - AI model used (for assistant messages)
96
+ * @property {number} temperature - Generation temperature used
97
+ * @property {number} responseTime - Time taken to generate response (ms)
98
+ * @property {string} ipAddress - IP address of sender (if applicable)
99
+ * @property {string} userAgent - User agent string (if applicable)
100
+ * @property {Object} modelParameters - Model-specific parameters used
101
+ * @property {string} generationId - Unique generation identifier
102
+ * @property {Object} annotations - Message annotations and labels
103
+ */
104
+
105
+ /**
106
+ * Token usage information
107
+ * @typedef {Object} TokenUsage
108
+ * @property {number} promptTokens - Tokens used in prompt
109
+ * @property {number} completionTokens - Tokens used in completion
110
+ * @property {number} totalTokens - Total tokens used
111
+ * @property {number} cost - Cost of token usage (USD)
112
+ * @property {string} model - Model used for generation
113
+ * @property {Object} breakdown - Detailed token usage breakdown
114
+ */
115
+
116
+ /**
117
+ * Context reference in messages
118
+ * @typedef {Object} ContextReference
119
+ * @property {string} id - Unique reference identifier
120
+ * @property {string} type - Reference type (file, component, selection, directory)
121
+ * @property {string} path - Path or identifier of referenced item
122
+ * @property {string} name - Human-readable name
123
+ * @property {string} [content] - Referenced content (if applicable)
124
+ * @property {number} [startLine] - Start line (for selections)
125
+ * @property {number} [endLine] - End line (for selections)
126
+ * @property {Object} metadata - Reference metadata
127
+ */
128
+
129
+ /**
130
+ * Tool execution information
131
+ * @typedef {Object} ToolExecution
132
+ * @property {string} id - Unique execution identifier
133
+ * @property {string} toolId - Tool identifier
134
+ * @property {string} status - Execution status (pending, executing, completed, failed)
135
+ * @property {Object} input - Tool input parameters
136
+ * @property {Object} [output] - Tool output (if completed)
137
+ * @property {string} [error] - Error message (if failed)
138
+ * @property {number} executionTime - Execution time in milliseconds
139
+ * @property {string} startedAt - ISO timestamp when execution started
140
+ * @property {string} [completedAt] - ISO timestamp when execution completed
141
+ */
142
+
143
+ /**
144
+ * Conversation validation functions
145
+ */
146
+ export class ConversationValidator {
147
+ /**
148
+ * Validate conversation data structure
149
+ * @param {Object} conversation - Conversation data to validate
150
+ * @returns {Object} Validation result
151
+ */
152
+ static validate(conversation) {
153
+ const errors = [];
154
+ const warnings = [];
155
+
156
+ // Required fields
157
+ if (!conversation.id || typeof conversation.id !== 'string') {
158
+ errors.push('Conversation ID is required and must be a string');
159
+ }
160
+
161
+ if (!conversation.agentId || typeof conversation.agentId !== 'string') {
162
+ errors.push('Agent ID is required and must be a string');
163
+ }
164
+
165
+ if (!conversation.title || typeof conversation.title !== 'string') {
166
+ errors.push('Conversation title is required and must be a string');
167
+ }
168
+
169
+ if (conversation.title && conversation.title.length > 200) {
170
+ warnings.push('Conversation title is very long (>200 characters)');
171
+ }
172
+
173
+ // Status validation
174
+ if (conversation.status && !Object.values(CONVERSATION_STATUS).includes(conversation.status)) {
175
+ errors.push(`Invalid conversation status: ${conversation.status}`);
176
+ }
177
+
178
+ // Messages validation
179
+ if (conversation.messages && !Array.isArray(conversation.messages)) {
180
+ errors.push('Messages must be an array');
181
+ }
182
+
183
+ if (conversation.messages) {
184
+ conversation.messages.forEach((message, index) => {
185
+ const messageValidation = this.validateMessage(message);
186
+ messageValidation.errors.forEach(error => {
187
+ errors.push(`Message ${index}: ${error}`);
188
+ });
189
+ messageValidation.warnings.forEach(warning => {
190
+ warnings.push(`Message ${index}: ${warning}`);
191
+ });
192
+ });
193
+ }
194
+
195
+ // Numeric validations
196
+ if (conversation.messageCount !== undefined && typeof conversation.messageCount !== 'number') {
197
+ errors.push('Message count must be a number');
198
+ }
199
+
200
+ if (conversation.tokenCount !== undefined && typeof conversation.tokenCount !== 'number') {
201
+ errors.push('Token count must be a number');
202
+ }
203
+
204
+ if (conversation.cost !== undefined && typeof conversation.cost !== 'number') {
205
+ errors.push('Cost must be a number');
206
+ }
207
+
208
+ // Participants validation
209
+ if (conversation.participants && !Array.isArray(conversation.participants)) {
210
+ errors.push('Participants must be an array');
211
+ }
212
+
213
+ // Timestamp validation
214
+ const timestampFields = ['createdAt', 'updatedAt', 'lastMessageAt'];
215
+ timestampFields.forEach(field => {
216
+ if (conversation[field] && !this.isValidTimestamp(conversation[field])) {
217
+ errors.push(`Invalid timestamp for ${field}: ${conversation[field]}`);
218
+ }
219
+ });
220
+
221
+ return {
222
+ isValid: errors.length === 0,
223
+ errors,
224
+ warnings
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Validate message data structure
230
+ * @param {Object} message - Message data to validate
231
+ * @returns {Object} Validation result
232
+ */
233
+ static validateMessage(message) {
234
+ const errors = [];
235
+ const warnings = [];
236
+
237
+ // Required fields
238
+ if (!message.id || typeof message.id !== 'string') {
239
+ errors.push('Message ID is required and must be a string');
240
+ }
241
+
242
+ if (!message.conversationId || typeof message.conversationId !== 'string') {
243
+ errors.push('Conversation ID is required and must be a string');
244
+ }
245
+
246
+ if (!message.role || typeof message.role !== 'string') {
247
+ errors.push('Message role is required and must be a string');
248
+ }
249
+
250
+ if (message.role && !Object.values(MESSAGE_ROLES).includes(message.role)) {
251
+ errors.push(`Invalid message role: ${message.role}`);
252
+ }
253
+
254
+ if (!message.content || typeof message.content !== 'string') {
255
+ errors.push('Message content is required and must be a string');
256
+ }
257
+
258
+ if (message.content && message.content.length > 100000) {
259
+ warnings.push('Message content is very long (>100000 characters)');
260
+ }
261
+
262
+ // Role-specific validations
263
+ if (message.role === MESSAGE_ROLES.ASSISTANT && !message.agentId) {
264
+ errors.push('Assistant messages must have an agentId');
265
+ }
266
+
267
+ if (message.role === MESSAGE_ROLES.USER && !message.userId) {
268
+ warnings.push('User messages should have a userId');
269
+ }
270
+
271
+ // Context references validation
272
+ if (message.contextReferences && !Array.isArray(message.contextReferences)) {
273
+ errors.push('Context references must be an array');
274
+ }
275
+
276
+ // Tool executions validation
277
+ if (message.toolExecutions && !Array.isArray(message.toolExecutions)) {
278
+ errors.push('Tool executions must be an array');
279
+ }
280
+
281
+ // Token usage validation
282
+ if (message.tokenUsage) {
283
+ const tokenValidation = this.validateTokenUsage(message.tokenUsage);
284
+ errors.push(...tokenValidation.errors);
285
+ warnings.push(...tokenValidation.warnings);
286
+ }
287
+
288
+ // Timestamp validation
289
+ if (message.createdAt && !this.isValidTimestamp(message.createdAt)) {
290
+ errors.push(`Invalid createdAt timestamp: ${message.createdAt}`);
291
+ }
292
+
293
+ if (message.editedAt && !this.isValidTimestamp(message.editedAt)) {
294
+ errors.push(`Invalid editedAt timestamp: ${message.editedAt}`);
295
+ }
296
+
297
+ return { errors, warnings };
298
+ }
299
+
300
+ /**
301
+ * Validate token usage data
302
+ * @param {Object} tokenUsage - Token usage to validate
303
+ * @returns {Object} Validation result
304
+ */
305
+ static validateTokenUsage(tokenUsage) {
306
+ const errors = [];
307
+ const warnings = [];
308
+
309
+ if (typeof tokenUsage.totalTokens !== 'number' || tokenUsage.totalTokens < 0) {
310
+ errors.push('Total tokens must be a non-negative number');
311
+ }
312
+
313
+ if (tokenUsage.promptTokens !== undefined && (typeof tokenUsage.promptTokens !== 'number' || tokenUsage.promptTokens < 0)) {
314
+ errors.push('Prompt tokens must be a non-negative number');
315
+ }
316
+
317
+ if (tokenUsage.completionTokens !== undefined && (typeof tokenUsage.completionTokens !== 'number' || tokenUsage.completionTokens < 0)) {
318
+ errors.push('Completion tokens must be a non-negative number');
319
+ }
320
+
321
+ if (tokenUsage.cost !== undefined && (typeof tokenUsage.cost !== 'number' || tokenUsage.cost < 0)) {
322
+ errors.push('Cost must be a non-negative number');
323
+ }
324
+
325
+ if (tokenUsage.promptTokens && tokenUsage.completionTokens) {
326
+ const calculatedTotal = tokenUsage.promptTokens + tokenUsage.completionTokens;
327
+ if (Math.abs(calculatedTotal - tokenUsage.totalTokens) > 1) {
328
+ warnings.push('Total tokens does not match sum of prompt and completion tokens');
329
+ }
330
+ }
331
+
332
+ return { errors, warnings };
333
+ }
334
+
335
+ /**
336
+ * Check if a timestamp is valid ISO string
337
+ * @param {string} timestamp - Timestamp to validate
338
+ * @returns {boolean} True if valid
339
+ */
340
+ static isValidTimestamp(timestamp) {
341
+ if (typeof timestamp !== 'string') return false;
342
+ const date = new Date(timestamp);
343
+ return date instanceof Date && !isNaN(date.getTime());
344
+ }
345
+ }
346
+
347
+ /**
348
+ * Conversation factory functions
349
+ */
350
+ export class ConversationFactory {
351
+ /**
352
+ * Create a new conversation
353
+ * @param {string} agentId - Agent ID
354
+ * @param {string} title - Conversation title
355
+ * @param {Object} options - Additional options
356
+ * @returns {Conversation} New conversation object
357
+ */
358
+ static create(agentId, title, options = {}) {
359
+ const now = new Date().toISOString();
360
+ const conversationId = this.generateConversationId();
361
+
362
+ return {
363
+ id: conversationId,
364
+ title: title || 'New Conversation',
365
+ agentId,
366
+ status: CONVERSATION_STATUS.ACTIVE,
367
+ messages: [],
368
+ metadata: this.createDefaultMetadata(options.metadata),
369
+ settings: this.createDefaultSettings(options.settings),
370
+ context: this.createDefaultContext(),
371
+ createdAt: now,
372
+ updatedAt: now,
373
+ lastMessageAt: now,
374
+ messageCount: 0,
375
+ tokenCount: 0,
376
+ cost: 0,
377
+ participants: [agentId, ...(options.participants || [])],
378
+ summary: {}
379
+ };
380
+ }
381
+
382
+ /**
383
+ * Create a new message
384
+ * @param {string} conversationId - Conversation ID
385
+ * @param {string} role - Message role
386
+ * @param {string} content - Message content
387
+ * @param {Object} options - Additional options
388
+ * @returns {Message} New message object
389
+ */
390
+ static createMessage(conversationId, role, content, options = {}) {
391
+ const now = new Date().toISOString();
392
+ const messageId = this.generateMessageId();
393
+
394
+ return {
395
+ id: messageId,
396
+ conversationId,
397
+ role,
398
+ content,
399
+ agentId: options.agentId || null,
400
+ userId: options.userId || null,
401
+ metadata: options.metadata || {},
402
+ contextReferences: options.contextReferences || [],
403
+ toolExecutions: options.toolExecutions || [],
404
+ tokenUsage: options.tokenUsage || null,
405
+ createdAt: now,
406
+ editedAt: null,
407
+ parentMessageId: options.parentMessageId || null,
408
+ isEdited: false,
409
+ flags: options.flags || {}
410
+ };
411
+ }
412
+
413
+ /**
414
+ * Create default conversation metadata
415
+ * @param {Object} overrides - Metadata overrides
416
+ * @returns {ConversationMetadata} Default metadata
417
+ */
418
+ static createDefaultMetadata(overrides = {}) {
419
+ return {
420
+ tags: [],
421
+ category: 'general',
422
+ description: '',
423
+ isBookmarked: false,
424
+ priority: 3,
425
+ language: 'en',
426
+ customFields: {},
427
+ relatedConversations: [],
428
+ ...overrides
429
+ };
430
+ }
431
+
432
+ /**
433
+ * Create default conversation settings
434
+ * @param {Object} overrides - Settings overrides
435
+ * @returns {ConversationSettings} Default settings
436
+ */
437
+ static createDefaultSettings(overrides = {}) {
438
+ return {
439
+ persistHistory: true,
440
+ maxMessages: 1000,
441
+ autoSummarize: true,
442
+ summarizeThreshold: 50,
443
+ enableContextReferences: true,
444
+ maxContextReferences: 10,
445
+ notificationSettings: {
446
+ newMessage: true,
447
+ agentResponse: true,
448
+ toolExecution: false
449
+ },
450
+ privacySettings: {
451
+ shareHistory: false,
452
+ allowAnalytics: true
453
+ },
454
+ ...overrides
455
+ };
456
+ }
457
+
458
+ /**
459
+ * Create default conversation context
460
+ * @returns {ConversationContext} Default context
461
+ */
462
+ static createDefaultContext() {
463
+ return {
464
+ currentTopic: null,
465
+ mentionedEntities: [],
466
+ variables: {},
467
+ activeTools: [],
468
+ workingMemory: {},
469
+ preferences: {},
470
+ phase: 'initial',
471
+ goals: {}
472
+ };
473
+ }
474
+
475
+ /**
476
+ * Generate unique conversation ID
477
+ * @returns {string} Unique conversation ID
478
+ */
479
+ static generateConversationId() {
480
+ const timestamp = Date.now().toString(36);
481
+ const random = Math.random().toString(36).substr(2, 9);
482
+ return `conv_${timestamp}_${random}`;
483
+ }
484
+
485
+ /**
486
+ * Generate unique message ID
487
+ * @returns {string} Unique message ID
488
+ */
489
+ static generateMessageId() {
490
+ const timestamp = Date.now().toString(36);
491
+ const random = Math.random().toString(36).substr(2, 9);
492
+ return `msg_${timestamp}_${random}`;
493
+ }
494
+ }
495
+
496
+ /**
497
+ * Conversation utility functions
498
+ */
499
+ export class ConversationUtils {
500
+ /**
501
+ * Calculate conversation statistics
502
+ * @param {Conversation} conversation - Conversation to analyze
503
+ * @returns {Object} Conversation statistics
504
+ */
505
+ static getStatistics(conversation) {
506
+ const messages = conversation.messages || [];
507
+ const userMessages = messages.filter(m => m.role === MESSAGE_ROLES.USER);
508
+ const assistantMessages = messages.filter(m => m.role === MESSAGE_ROLES.ASSISTANT);
509
+ const systemMessages = messages.filter(m => m.role === MESSAGE_ROLES.SYSTEM);
510
+
511
+ const totalTokens = messages.reduce((sum, m) => sum + (m.tokenUsage?.totalTokens || 0), 0);
512
+ const totalCost = messages.reduce((sum, m) => sum + (m.tokenUsage?.cost || 0), 0);
513
+
514
+ const toolExecutions = messages.reduce((sum, m) => sum + (m.toolExecutions?.length || 0), 0);
515
+ const contextReferences = messages.reduce((sum, m) => sum + (m.contextReferences?.length || 0), 0);
516
+
517
+ return {
518
+ totalMessages: messages.length,
519
+ userMessages: userMessages.length,
520
+ assistantMessages: assistantMessages.length,
521
+ systemMessages: systemMessages.length,
522
+ totalTokens,
523
+ totalCost,
524
+ toolExecutions,
525
+ contextReferences,
526
+ averageMessageLength: messages.length > 0
527
+ ? messages.reduce((sum, m) => sum + m.content.length, 0) / messages.length
528
+ : 0,
529
+ conversationDuration: this.getConversationDuration(conversation)
530
+ };
531
+ }
532
+
533
+ /**
534
+ * Get conversation duration in milliseconds
535
+ * @param {Conversation} conversation - Conversation to analyze
536
+ * @returns {number} Duration in milliseconds
537
+ */
538
+ static getConversationDuration(conversation) {
539
+ if (!conversation.messages || conversation.messages.length === 0) {
540
+ return 0;
541
+ }
542
+
543
+ const firstMessage = conversation.messages[0];
544
+ const lastMessage = conversation.messages[conversation.messages.length - 1];
545
+
546
+ const startTime = new Date(firstMessage.createdAt);
547
+ const endTime = new Date(lastMessage.createdAt);
548
+
549
+ return endTime.getTime() - startTime.getTime();
550
+ }
551
+
552
+ /**
553
+ * Generate conversation summary
554
+ * @param {Conversation} conversation - Conversation to summarize
555
+ * @returns {Object} Conversation summary
556
+ */
557
+ static generateSummary(conversation) {
558
+ const stats = this.getStatistics(conversation);
559
+ const messages = conversation.messages || [];
560
+
561
+ // Extract key topics and entities
562
+ const topics = this.extractTopics(messages);
563
+ const entities = this.extractEntities(messages);
564
+
565
+ // Get recent activity
566
+ const recentMessages = messages.slice(-10);
567
+ const lastActivity = conversation.lastMessageAt || conversation.updatedAt;
568
+
569
+ return {
570
+ title: conversation.title,
571
+ messageCount: stats.totalMessages,
572
+ duration: stats.conversationDuration,
573
+ participants: conversation.participants.length,
574
+ topics: topics.slice(0, 5), // Top 5 topics
575
+ entities: entities.slice(0, 10), // Top 10 entities
576
+ lastActivity,
577
+ recentActivity: recentMessages.map(m => ({
578
+ role: m.role,
579
+ timestamp: m.createdAt,
580
+ preview: m.content.substring(0, 100) + (m.content.length > 100 ? '...' : '')
581
+ })),
582
+ stats
583
+ };
584
+ }
585
+
586
+ /**
587
+ * Extract topics from conversation messages
588
+ * @param {Message[]} messages - Messages to analyze
589
+ * @returns {string[]} Extracted topics
590
+ */
591
+ static extractTopics(messages) {
592
+ // Simple topic extraction based on keywords
593
+ // In a real implementation, this would use more sophisticated NLP
594
+ const topicKeywords = new Map();
595
+
596
+ messages.forEach(message => {
597
+ const words = message.content.toLowerCase()
598
+ .split(/\s+/)
599
+ .filter(word => word.length > 3 && !this.isStopWord(word));
600
+
601
+ words.forEach(word => {
602
+ topicKeywords.set(word, (topicKeywords.get(word) || 0) + 1);
603
+ });
604
+ });
605
+
606
+ return Array.from(topicKeywords.entries())
607
+ .sort((a, b) => b[1] - a[1])
608
+ .map(([word]) => word);
609
+ }
610
+
611
+ /**
612
+ * Extract entities from conversation messages
613
+ * @param {Message[]} messages - Messages to analyze
614
+ * @returns {string[]} Extracted entities
615
+ */
616
+ static extractEntities(messages) {
617
+ // Simple entity extraction
618
+ // In a real implementation, this would use NER
619
+ const entities = new Set();
620
+
621
+ messages.forEach(message => {
622
+ // Extract capitalized words (potential proper nouns)
623
+ const capitalizedWords = message.content.match(/\b[A-Z][a-z]+\b/g) || [];
624
+ capitalizedWords.forEach(word => entities.add(word));
625
+
626
+ // Extract file paths
627
+ const filePaths = message.content.match(/\b[\w/\-.]+\.\w+\b/g) || [];
628
+ filePaths.forEach(path => entities.add(path));
629
+ });
630
+
631
+ return Array.from(entities);
632
+ }
633
+
634
+ /**
635
+ * Check if word is a stop word
636
+ * @param {string} word - Word to check
637
+ * @returns {boolean} True if stop word
638
+ */
639
+ static isStopWord(word) {
640
+ const stopWords = new Set([
641
+ 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with',
642
+ 'by', 'from', 'up', 'about', 'into', 'through', 'during', 'before',
643
+ 'after', 'above', 'below', 'over', 'under', 'again', 'further',
644
+ 'then', 'once', 'here', 'there', 'when', 'where', 'why', 'how',
645
+ 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other',
646
+ 'some', 'such', 'only', 'own', 'same', 'so', 'than', 'too',
647
+ 'very', 'can', 'will', 'just', 'should', 'now'
648
+ ]);
649
+
650
+ return stopWords.has(word.toLowerCase());
651
+ }
652
+
653
+ /**
654
+ * Format conversation for export
655
+ * @param {Conversation} conversation - Conversation to format
656
+ * @param {string} format - Export format ('json', 'markdown', 'plain')
657
+ * @returns {string} Formatted conversation
658
+ */
659
+ static formatForExport(conversation, format = 'json') {
660
+ switch (format) {
661
+ case 'markdown':
662
+ return this.formatAsMarkdown(conversation);
663
+ case 'plain':
664
+ return this.formatAsPlainText(conversation);
665
+ case 'json':
666
+ default:
667
+ return JSON.stringify(conversation, null, 2);
668
+ }
669
+ }
670
+
671
+ /**
672
+ * Format conversation as markdown
673
+ * @param {Conversation} conversation - Conversation to format
674
+ * @returns {string} Markdown formatted conversation
675
+ */
676
+ static formatAsMarkdown(conversation) {
677
+ let markdown = `# ${conversation.title}\n\n`;
678
+ markdown += `**Created:** ${new Date(conversation.createdAt).toLocaleString()}\n`;
679
+ markdown += `**Agent:** ${conversation.agentId}\n`;
680
+ markdown += `**Messages:** ${conversation.messageCount}\n\n`;
681
+
682
+ conversation.messages.forEach(message => {
683
+ const timestamp = new Date(message.createdAt).toLocaleTimeString();
684
+ const role = message.role.charAt(0).toUpperCase() + message.role.slice(1);
685
+
686
+ markdown += `## ${role} (${timestamp})\n\n`;
687
+ markdown += `${message.content}\n\n`;
688
+
689
+ if (message.contextReferences && message.contextReferences.length > 0) {
690
+ markdown += `**Context References:**\n`;
691
+ message.contextReferences.forEach(ref => {
692
+ markdown += `- ${ref.name} (${ref.type})\n`;
693
+ });
694
+ markdown += '\n';
695
+ }
696
+ });
697
+
698
+ return markdown;
699
+ }
700
+
701
+ /**
702
+ * Format conversation as plain text
703
+ * @param {Conversation} conversation - Conversation to format
704
+ * @returns {string} Plain text formatted conversation
705
+ */
706
+ static formatAsPlainText(conversation) {
707
+ let text = `Conversation: ${conversation.title}\n`;
708
+ text += `Created: ${new Date(conversation.createdAt).toLocaleString()}\n`;
709
+ text += `Agent: ${conversation.agentId}\n`;
710
+ text += `Messages: ${conversation.messageCount}\n\n`;
711
+
712
+ text += '-'.repeat(50) + '\n\n';
713
+
714
+ conversation.messages.forEach(message => {
715
+ const timestamp = new Date(message.createdAt).toLocaleTimeString();
716
+ const role = message.role.toUpperCase();
717
+
718
+ text += `[${timestamp}] ${role}:\n`;
719
+ text += `${message.content}\n\n`;
720
+ });
721
+
722
+ return text;
723
+ }
724
+ }
725
+
726
+ export default {
727
+ ConversationValidator,
728
+ ConversationFactory,
729
+ ConversationUtils
730
730
  };