@jungjaehoon/mama-os 0.28.6 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (452) hide show
  1. package/dist/agent/agent-loop.d.ts +0 -4
  2. package/dist/agent/agent-loop.d.ts.map +1 -1
  3. package/dist/agent/agent-loop.js +33 -10
  4. package/dist/agent/agent-loop.js.map +1 -1
  5. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  6. package/dist/agent/code-act/host-bridge.js +53 -3
  7. package/dist/agent/code-act/host-bridge.js.map +1 -1
  8. package/dist/agent/code-act/tool-policy.d.ts.map +1 -1
  9. package/dist/agent/code-act/tool-policy.js +5 -0
  10. package/dist/agent/code-act/tool-policy.js.map +1 -1
  11. package/dist/agent/codex-auth.d.ts +0 -1
  12. package/dist/agent/codex-auth.d.ts.map +1 -1
  13. package/dist/agent/codex-auth.js +0 -4
  14. package/dist/agent/codex-auth.js.map +1 -1
  15. package/dist/agent/codex-home.d.ts +0 -2
  16. package/dist/agent/codex-home.d.ts.map +1 -1
  17. package/dist/agent/codex-home.js +0 -66
  18. package/dist/agent/codex-home.js.map +1 -1
  19. package/dist/agent/context-compile-service.d.ts +9 -0
  20. package/dist/agent/context-compile-service.d.ts.map +1 -1
  21. package/dist/agent/context-compile-service.js +6 -0
  22. package/dist/agent/context-compile-service.js.map +1 -1
  23. package/dist/agent/context-prompt-builder.d.ts +0 -6
  24. package/dist/agent/context-prompt-builder.d.ts.map +1 -1
  25. package/dist/agent/context-prompt-builder.js +0 -131
  26. package/dist/agent/context-prompt-builder.js.map +1 -1
  27. package/dist/agent/contract-extractor.d.ts +0 -4
  28. package/dist/agent/contract-extractor.d.ts.map +1 -1
  29. package/dist/agent/contract-extractor.js +0 -68
  30. package/dist/agent/contract-extractor.js.map +1 -1
  31. package/dist/agent/gateway-tool-executor.d.ts +20 -15
  32. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  33. package/dist/agent/gateway-tool-executor.js +236 -90
  34. package/dist/agent/gateway-tool-executor.js.map +1 -1
  35. package/dist/agent/gateway-tools.md +7 -4
  36. package/dist/agent/skill-loader.d.ts +0 -7
  37. package/dist/agent/skill-loader.d.ts.map +1 -1
  38. package/dist/agent/skill-loader.js +0 -86
  39. package/dist/agent/skill-loader.js.map +1 -1
  40. package/dist/agent/token-estimator.d.ts +0 -8
  41. package/dist/agent/token-estimator.d.ts.map +1 -1
  42. package/dist/agent/token-estimator.js +0 -14
  43. package/dist/agent/token-estimator.js.map +1 -1
  44. package/dist/agent/tool-registry.d.ts.map +1 -1
  45. package/dist/agent/tool-registry.js +23 -5
  46. package/dist/agent/tool-registry.js.map +1 -1
  47. package/dist/agent/types.d.ts +27 -1
  48. package/dist/agent/types.d.ts.map +1 -1
  49. package/dist/agent/types.js.map +1 -1
  50. package/dist/api/agent-graph-handler.d.ts +9 -0
  51. package/dist/api/agent-graph-handler.d.ts.map +1 -1
  52. package/dist/api/agent-graph-handler.js +27 -1
  53. package/dist/api/agent-graph-handler.js.map +1 -1
  54. package/dist/api/entity-audit-handler.d.ts +1 -2
  55. package/dist/api/entity-audit-handler.d.ts.map +1 -1
  56. package/dist/api/entity-audit-handler.js +0 -5
  57. package/dist/api/entity-audit-handler.js.map +1 -1
  58. package/dist/api/index.d.ts +1 -9
  59. package/dist/api/index.d.ts.map +1 -1
  60. package/dist/api/index.js +4 -17
  61. package/dist/api/index.js.map +1 -1
  62. package/dist/api/intelligence-handler.d.ts +0 -5
  63. package/dist/api/intelligence-handler.d.ts.map +1 -1
  64. package/dist/api/intelligence-handler.js +0 -15
  65. package/dist/api/intelligence-handler.js.map +1 -1
  66. package/dist/api/types.d.ts +1 -5
  67. package/dist/api/types.d.ts.map +1 -1
  68. package/dist/api/types.js +0 -14
  69. package/dist/api/types.js.map +1 -1
  70. package/dist/cli/commands/start.d.ts +117 -3
  71. package/dist/cli/commands/start.d.ts.map +1 -1
  72. package/dist/cli/commands/start.js +223 -62
  73. package/dist/cli/commands/start.js.map +1 -1
  74. package/dist/cli/config/config-manager.d.ts +0 -5
  75. package/dist/cli/config/config-manager.d.ts.map +1 -1
  76. package/dist/cli/config/config-manager.js +0 -29
  77. package/dist/cli/config/config-manager.js.map +1 -1
  78. package/dist/cli/config/types.d.ts.map +1 -1
  79. package/dist/cli/config/types.js +3 -0
  80. package/dist/cli/config/types.js.map +1 -1
  81. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  82. package/dist/cli/runtime/api-routes-init.js +32 -5
  83. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  84. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  85. package/dist/cli/runtime/api-server-init.js +2 -0
  86. package/dist/cli/runtime/api-server-init.js.map +1 -1
  87. package/dist/cli/runtime/gateway-init.d.ts +1 -1
  88. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  89. package/dist/cli/runtime/gateway-init.js +11 -38
  90. package/dist/cli/runtime/gateway-init.js.map +1 -1
  91. package/dist/cli/runtime/gateway-wiring.d.ts.map +1 -1
  92. package/dist/cli/runtime/gateway-wiring.js +6 -120
  93. package/dist/cli/runtime/gateway-wiring.js.map +1 -1
  94. package/dist/cli/utils/pid-manager.d.ts +0 -10
  95. package/dist/cli/utils/pid-manager.d.ts.map +1 -1
  96. package/dist/cli/utils/pid-manager.js +0 -26
  97. package/dist/cli/utils/pid-manager.js.map +1 -1
  98. package/dist/connectors/framework/polling-scheduler.d.ts +33 -1
  99. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  100. package/dist/connectors/framework/polling-scheduler.js +46 -40
  101. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  102. package/dist/connectors/trello/query-tools.d.ts +32 -5
  103. package/dist/connectors/trello/query-tools.d.ts.map +1 -1
  104. package/dist/connectors/trello/query-tools.js +56 -17
  105. package/dist/connectors/trello/query-tools.js.map +1 -1
  106. package/dist/db/agent-store.d.ts +0 -4
  107. package/dist/db/agent-store.d.ts.map +1 -1
  108. package/dist/db/agent-store.js +0 -65
  109. package/dist/db/agent-store.js.map +1 -1
  110. package/dist/envelope/enforcer.d.ts.map +1 -1
  111. package/dist/envelope/enforcer.js +10 -1
  112. package/dist/envelope/enforcer.js.map +1 -1
  113. package/dist/envelope/index.d.ts +0 -1
  114. package/dist/envelope/index.d.ts.map +1 -1
  115. package/dist/envelope/index.js +0 -1
  116. package/dist/envelope/index.js.map +1 -1
  117. package/dist/envelope/signature.d.ts +0 -1
  118. package/dist/envelope/signature.d.ts.map +1 -1
  119. package/dist/envelope/signature.js +0 -7
  120. package/dist/envelope/signature.js.map +1 -1
  121. package/dist/envelope/tool-connector-scope.d.ts +35 -0
  122. package/dist/envelope/tool-connector-scope.d.ts.map +1 -0
  123. package/dist/envelope/tool-connector-scope.js +57 -0
  124. package/dist/envelope/tool-connector-scope.js.map +1 -0
  125. package/dist/evidence/effects.d.ts +107 -0
  126. package/dist/evidence/effects.d.ts.map +1 -0
  127. package/dist/evidence/effects.js +281 -0
  128. package/dist/evidence/effects.js.map +1 -0
  129. package/dist/evidence/read.d.ts +75 -0
  130. package/dist/evidence/read.d.ts.map +1 -0
  131. package/dist/evidence/read.js +105 -0
  132. package/dist/evidence/read.js.map +1 -0
  133. package/dist/gateways/base-gateway.d.ts +23 -3
  134. package/dist/gateways/base-gateway.d.ts.map +1 -1
  135. package/dist/gateways/base-gateway.js +15 -2
  136. package/dist/gateways/base-gateway.js.map +1 -1
  137. package/dist/gateways/discord.d.ts +4 -16
  138. package/dist/gateways/discord.d.ts.map +1 -1
  139. package/dist/gateways/discord.js +22 -189
  140. package/dist/gateways/discord.js.map +1 -1
  141. package/dist/gateways/index.d.ts +2 -1
  142. package/dist/gateways/index.d.ts.map +1 -1
  143. package/dist/gateways/message-router.d.ts +13 -20
  144. package/dist/gateways/message-router.d.ts.map +1 -1
  145. package/dist/gateways/message-router.js +32 -3
  146. package/dist/gateways/message-router.js.map +1 -1
  147. package/dist/gateways/slack.d.ts +2 -12
  148. package/dist/gateways/slack.d.ts.map +1 -1
  149. package/dist/gateways/slack.js +6 -220
  150. package/dist/gateways/slack.js.map +1 -1
  151. package/dist/gateways/telegram.d.ts +2 -2
  152. package/dist/gateways/telegram.d.ts.map +1 -1
  153. package/dist/gateways/telegram.js +3 -2
  154. package/dist/gateways/telegram.js.map +1 -1
  155. package/dist/gateways/turn-contract.d.ts +104 -0
  156. package/dist/gateways/turn-contract.d.ts.map +1 -0
  157. package/dist/{memory/consult-contract.js → gateways/turn-contract.js} +1 -1
  158. package/dist/gateways/turn-contract.js.map +1 -0
  159. package/dist/memory/provenance-live.d.ts +111 -0
  160. package/dist/memory/provenance-live.d.ts.map +1 -0
  161. package/dist/memory/provenance-live.js +381 -0
  162. package/dist/memory/provenance-live.js.map +1 -0
  163. package/dist/memory/provenance-resolver.d.ts +184 -0
  164. package/dist/memory/provenance-resolver.d.ts.map +1 -0
  165. package/dist/memory/provenance-resolver.js +152 -0
  166. package/dist/memory/provenance-resolver.js.map +1 -0
  167. package/dist/multi-agent/agent-event-bus.d.ts +1 -0
  168. package/dist/multi-agent/agent-event-bus.d.ts.map +1 -1
  169. package/dist/multi-agent/bmad-templates.d.ts +0 -18
  170. package/dist/multi-agent/bmad-templates.d.ts.map +1 -1
  171. package/dist/multi-agent/bmad-templates.js +0 -127
  172. package/dist/multi-agent/bmad-templates.js.map +1 -1
  173. package/dist/multi-agent/dashboard-agent-persona.js +3 -3
  174. package/dist/operator/board-reconcile.d.ts +2 -3
  175. package/dist/operator/board-reconcile.d.ts.map +1 -1
  176. package/dist/operator/board-reconcile.js +18 -32
  177. package/dist/operator/board-reconcile.js.map +1 -1
  178. package/dist/operator/changes-projection.d.ts +70 -0
  179. package/dist/operator/changes-projection.d.ts.map +1 -0
  180. package/dist/operator/changes-projection.js +109 -0
  181. package/dist/operator/changes-projection.js.map +1 -0
  182. package/dist/operator/external-correlation.d.ts +94 -0
  183. package/dist/operator/external-correlation.d.ts.map +1 -0
  184. package/dist/operator/external-correlation.js +177 -0
  185. package/dist/operator/external-correlation.js.map +1 -0
  186. package/dist/operator/operator-trigger-loop.d.ts +9 -1
  187. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  188. package/dist/operator/operator-trigger-loop.js +8 -4
  189. package/dist/operator/operator-trigger-loop.js.map +1 -1
  190. package/dist/operator/provenance-lookup.d.ts +18 -0
  191. package/dist/operator/provenance-lookup.d.ts.map +1 -0
  192. package/dist/operator/provenance-lookup.js +54 -0
  193. package/dist/operator/provenance-lookup.js.map +1 -0
  194. package/dist/operator/report-carry.d.ts +18 -1
  195. package/dist/operator/report-carry.d.ts.map +1 -1
  196. package/dist/operator/report-carry.js +22 -3
  197. package/dist/operator/report-carry.js.map +1 -1
  198. package/dist/operator/report-run.d.ts +31 -0
  199. package/dist/operator/report-run.d.ts.map +1 -1
  200. package/dist/operator/report-run.js +140 -22
  201. package/dist/operator/report-run.js.map +1 -1
  202. package/dist/operator/task-ledger.d.ts +84 -2
  203. package/dist/operator/task-ledger.d.ts.map +1 -1
  204. package/dist/operator/task-ledger.js +274 -31
  205. package/dist/operator/task-ledger.js.map +1 -1
  206. package/dist/operator/trigger-author.d.ts +7 -0
  207. package/dist/operator/trigger-author.d.ts.map +1 -1
  208. package/dist/operator/trigger-author.js +78 -7
  209. package/dist/operator/trigger-author.js.map +1 -1
  210. package/dist/operator/worker-run.js +1 -1
  211. package/dist/operator/worker-run.js.map +1 -1
  212. package/dist/operator/workorder-hooks.d.ts +79 -4
  213. package/dist/operator/workorder-hooks.d.ts.map +1 -1
  214. package/dist/operator/workorder-hooks.js +152 -20
  215. package/dist/operator/workorder-hooks.js.map +1 -1
  216. package/dist/operator/workorder-publishers.d.ts +2 -0
  217. package/dist/operator/workorder-publishers.d.ts.map +1 -1
  218. package/dist/operator/workorder-publishers.js +8 -1
  219. package/dist/operator/workorder-publishers.js.map +1 -1
  220. package/dist/utils/untrusted-content.d.ts +11 -0
  221. package/dist/utils/untrusted-content.d.ts.map +1 -1
  222. package/dist/utils/untrusted-content.js +20 -0
  223. package/dist/utils/untrusted-content.js.map +1 -1
  224. package/package.json +4 -3
  225. package/scripts/backfill-channel-keys.ts +451 -0
  226. package/dist/agent/auto-recall.d.ts +0 -48
  227. package/dist/agent/auto-recall.d.ts.map +0 -1
  228. package/dist/agent/auto-recall.js +0 -192
  229. package/dist/agent/auto-recall.js.map +0 -1
  230. package/dist/agent/claude-client.d.ts +0 -50
  231. package/dist/agent/claude-client.d.ts.map +0 -1
  232. package/dist/agent/claude-client.js +0 -219
  233. package/dist/agent/claude-client.js.map +0 -1
  234. package/dist/agent/delegation-executor.d.ts +0 -49
  235. package/dist/agent/delegation-executor.d.ts.map +0 -1
  236. package/dist/agent/delegation-executor.js +0 -692
  237. package/dist/agent/delegation-executor.js.map +0 -1
  238. package/dist/agent/mcp-executor.d.ts +0 -60
  239. package/dist/agent/mcp-executor.d.ts.map +0 -1
  240. package/dist/agent/mcp-executor.js +0 -190
  241. package/dist/agent/mcp-executor.js.map +0 -1
  242. package/dist/agent/process-tree.d.ts +0 -6
  243. package/dist/agent/process-tree.d.ts.map +0 -1
  244. package/dist/agent/process-tree.js +0 -21
  245. package/dist/agent/process-tree.js.map +0 -1
  246. package/dist/agent/streaming-callback-manager.d.ts +0 -85
  247. package/dist/agent/streaming-callback-manager.d.ts.map +0 -1
  248. package/dist/agent/streaming-callback-manager.js +0 -103
  249. package/dist/agent/streaming-callback-manager.js.map +0 -1
  250. package/dist/agent/token-budget.d.ts +0 -49
  251. package/dist/agent/token-budget.d.ts.map +0 -1
  252. package/dist/agent/token-budget.js +0 -92
  253. package/dist/agent/token-budget.js.map +0 -1
  254. package/dist/connectors/kagemusha/history-compiler.d.ts +0 -18
  255. package/dist/connectors/kagemusha/history-compiler.d.ts.map +0 -1
  256. package/dist/connectors/kagemusha/history-compiler.js +0 -35
  257. package/dist/connectors/kagemusha/history-compiler.js.map +0 -1
  258. package/dist/db/migrations/wiki-artifacts.d.ts +0 -3
  259. package/dist/db/migrations/wiki-artifacts.d.ts.map +0 -1
  260. package/dist/db/migrations/wiki-artifacts.js +0 -24
  261. package/dist/db/migrations/wiki-artifacts.js.map +0 -1
  262. package/dist/envelope/subset.d.ts +0 -9
  263. package/dist/envelope/subset.d.ts.map +0 -1
  264. package/dist/envelope/subset.js +0 -67
  265. package/dist/envelope/subset.js.map +0 -1
  266. package/dist/memory/consult-contract.d.ts +0 -8
  267. package/dist/memory/consult-contract.d.ts.map +0 -1
  268. package/dist/memory/consult-contract.js.map +0 -1
  269. package/dist/multi-agent/agent-message-queue.d.ts +0 -104
  270. package/dist/multi-agent/agent-message-queue.d.ts.map +0 -1
  271. package/dist/multi-agent/agent-message-queue.js +0 -227
  272. package/dist/multi-agent/agent-message-queue.js.map +0 -1
  273. package/dist/multi-agent/background-task-manager.d.ts +0 -248
  274. package/dist/multi-agent/background-task-manager.d.ts.map +0 -1
  275. package/dist/multi-agent/background-task-manager.js +0 -415
  276. package/dist/multi-agent/background-task-manager.js.map +0 -1
  277. package/dist/multi-agent/category-router.d.ts +0 -56
  278. package/dist/multi-agent/category-router.d.ts.map +0 -1
  279. package/dist/multi-agent/category-router.js +0 -99
  280. package/dist/multi-agent/category-router.js.map +0 -1
  281. package/dist/multi-agent/council-engine.d.ts +0 -60
  282. package/dist/multi-agent/council-engine.d.ts.map +0 -1
  283. package/dist/multi-agent/council-engine.js +0 -284
  284. package/dist/multi-agent/council-engine.js.map +0 -1
  285. package/dist/multi-agent/delegation-format-validator.d.ts +0 -22
  286. package/dist/multi-agent/delegation-format-validator.d.ts.map +0 -1
  287. package/dist/multi-agent/delegation-format-validator.js +0 -31
  288. package/dist/multi-agent/delegation-format-validator.js.map +0 -1
  289. package/dist/multi-agent/delegation-manager.d.ts +0 -128
  290. package/dist/multi-agent/delegation-manager.d.ts.map +0 -1
  291. package/dist/multi-agent/delegation-manager.js +0 -276
  292. package/dist/multi-agent/delegation-manager.js.map +0 -1
  293. package/dist/multi-agent/i18n-messages.d.ts +0 -35
  294. package/dist/multi-agent/i18n-messages.d.ts.map +0 -1
  295. package/dist/multi-agent/i18n-messages.js +0 -54
  296. package/dist/multi-agent/i18n-messages.js.map +0 -1
  297. package/dist/multi-agent/index.d.ts +0 -31
  298. package/dist/multi-agent/index.d.ts.map +0 -1
  299. package/dist/multi-agent/index.js +0 -46
  300. package/dist/multi-agent/index.js.map +0 -1
  301. package/dist/multi-agent/multi-agent-base.d.ts +0 -223
  302. package/dist/multi-agent/multi-agent-base.d.ts.map +0 -1
  303. package/dist/multi-agent/multi-agent-base.js +0 -592
  304. package/dist/multi-agent/multi-agent-base.js.map +0 -1
  305. package/dist/multi-agent/multi-agent-discord.d.ts +0 -142
  306. package/dist/multi-agent/multi-agent-discord.d.ts.map +0 -1
  307. package/dist/multi-agent/multi-agent-discord.js +0 -1235
  308. package/dist/multi-agent/multi-agent-discord.js.map +0 -1
  309. package/dist/multi-agent/multi-agent-slack.d.ts +0 -146
  310. package/dist/multi-agent/multi-agent-slack.d.ts.map +0 -1
  311. package/dist/multi-agent/multi-agent-slack.js +0 -953
  312. package/dist/multi-agent/multi-agent-slack.js.map +0 -1
  313. package/dist/multi-agent/multi-bot-manager.d.ts +0 -119
  314. package/dist/multi-agent/multi-bot-manager.d.ts.map +0 -1
  315. package/dist/multi-agent/multi-bot-manager.js +0 -449
  316. package/dist/multi-agent/multi-bot-manager.js.map +0 -1
  317. package/dist/multi-agent/orchestrator.d.ts +0 -110
  318. package/dist/multi-agent/orchestrator.d.ts.map +0 -1
  319. package/dist/multi-agent/orchestrator.js +0 -436
  320. package/dist/multi-agent/orchestrator.js.map +0 -1
  321. package/dist/multi-agent/rate-limiter.d.ts +0 -76
  322. package/dist/multi-agent/rate-limiter.d.ts.map +0 -1
  323. package/dist/multi-agent/rate-limiter.js +0 -128
  324. package/dist/multi-agent/rate-limiter.js.map +0 -1
  325. package/dist/multi-agent/shared-context.d.ts +0 -127
  326. package/dist/multi-agent/shared-context.d.ts.map +0 -1
  327. package/dist/multi-agent/shared-context.js +0 -239
  328. package/dist/multi-agent/shared-context.js.map +0 -1
  329. package/dist/multi-agent/slack-config-validator.d.ts +0 -42
  330. package/dist/multi-agent/slack-config-validator.d.ts.map +0 -1
  331. package/dist/multi-agent/slack-config-validator.js +0 -194
  332. package/dist/multi-agent/slack-config-validator.js.map +0 -1
  333. package/dist/multi-agent/slack-multi-bot-manager.d.ts +0 -143
  334. package/dist/multi-agent/slack-multi-bot-manager.d.ts.map +0 -1
  335. package/dist/multi-agent/slack-multi-bot-manager.js +0 -413
  336. package/dist/multi-agent/slack-multi-bot-manager.js.map +0 -1
  337. package/dist/multi-agent/swarm/swarm-anti-pattern-detector.d.ts +0 -98
  338. package/dist/multi-agent/swarm/swarm-anti-pattern-detector.d.ts.map +0 -1
  339. package/dist/multi-agent/swarm/swarm-anti-pattern-detector.js +0 -225
  340. package/dist/multi-agent/swarm/swarm-anti-pattern-detector.js.map +0 -1
  341. package/dist/multi-agent/swarm/swarm-db.d.ts +0 -175
  342. package/dist/multi-agent/swarm/swarm-db.d.ts.map +0 -1
  343. package/dist/multi-agent/swarm/swarm-db.js +0 -313
  344. package/dist/multi-agent/swarm/swarm-db.js.map +0 -1
  345. package/dist/multi-agent/swarm/swarm-event-reporter.d.ts +0 -116
  346. package/dist/multi-agent/swarm/swarm-event-reporter.d.ts.map +0 -1
  347. package/dist/multi-agent/swarm/swarm-event-reporter.js +0 -243
  348. package/dist/multi-agent/swarm/swarm-event-reporter.js.map +0 -1
  349. package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts +0 -57
  350. package/dist/multi-agent/swarm/swarm-mama-adapter.d.ts.map +0 -1
  351. package/dist/multi-agent/swarm/swarm-mama-adapter.js +0 -87
  352. package/dist/multi-agent/swarm/swarm-mama-adapter.js.map +0 -1
  353. package/dist/multi-agent/swarm/swarm-manager.d.ts +0 -122
  354. package/dist/multi-agent/swarm/swarm-manager.d.ts.map +0 -1
  355. package/dist/multi-agent/swarm/swarm-manager.js +0 -199
  356. package/dist/multi-agent/swarm/swarm-manager.js.map +0 -1
  357. package/dist/multi-agent/swarm/swarm-task-learner.d.ts +0 -104
  358. package/dist/multi-agent/swarm/swarm-task-learner.d.ts.map +0 -1
  359. package/dist/multi-agent/swarm/swarm-task-learner.js +0 -211
  360. package/dist/multi-agent/swarm/swarm-task-learner.js.map +0 -1
  361. package/dist/multi-agent/swarm/swarm-task-runner.d.ts +0 -155
  362. package/dist/multi-agent/swarm/swarm-task-runner.d.ts.map +0 -1
  363. package/dist/multi-agent/swarm/swarm-task-runner.js +0 -615
  364. package/dist/multi-agent/swarm/swarm-task-runner.js.map +0 -1
  365. package/dist/multi-agent/swarm/wave-engine.d.ts +0 -96
  366. package/dist/multi-agent/swarm/wave-engine.d.ts.map +0 -1
  367. package/dist/multi-agent/swarm/wave-engine.js +0 -123
  368. package/dist/multi-agent/swarm/wave-engine.js.map +0 -1
  369. package/dist/multi-agent/system-reminder.d.ts +0 -206
  370. package/dist/multi-agent/system-reminder.d.ts.map +0 -1
  371. package/dist/multi-agent/system-reminder.js +0 -455
  372. package/dist/multi-agent/system-reminder.js.map +0 -1
  373. package/dist/multi-agent/task-continuation.d.ts +0 -74
  374. package/dist/multi-agent/task-continuation.d.ts.map +0 -1
  375. package/dist/multi-agent/task-continuation.js +0 -172
  376. package/dist/multi-agent/task-continuation.js.map +0 -1
  377. package/dist/multi-agent/ultrawork-state.d.ts +0 -57
  378. package/dist/multi-agent/ultrawork-state.d.ts.map +0 -1
  379. package/dist/multi-agent/ultrawork-state.js +0 -191
  380. package/dist/multi-agent/ultrawork-state.js.map +0 -1
  381. package/dist/multi-agent/ultrawork.d.ts +0 -152
  382. package/dist/multi-agent/ultrawork.d.ts.map +0 -1
  383. package/dist/multi-agent/ultrawork.js +0 -879
  384. package/dist/multi-agent/ultrawork.js.map +0 -1
  385. package/dist/multi-agent/work-tracker.d.ts +0 -22
  386. package/dist/multi-agent/work-tracker.d.ts.map +0 -1
  387. package/dist/multi-agent/work-tracker.js +0 -45
  388. package/dist/multi-agent/work-tracker.js.map +0 -1
  389. package/dist/multi-agent/workflow-engine.d.ts +0 -87
  390. package/dist/multi-agent/workflow-engine.d.ts.map +0 -1
  391. package/dist/multi-agent/workflow-engine.js +0 -604
  392. package/dist/multi-agent/workflow-engine.js.map +0 -1
  393. package/dist/onboarding/all-tools.d.ts +0 -18
  394. package/dist/onboarding/all-tools.d.ts.map +0 -1
  395. package/dist/onboarding/all-tools.js +0 -149
  396. package/dist/onboarding/all-tools.js.map +0 -1
  397. package/dist/onboarding/autonomous-discovery-tools.d.ts +0 -23
  398. package/dist/onboarding/autonomous-discovery-tools.d.ts.map +0 -1
  399. package/dist/onboarding/autonomous-discovery-tools.js +0 -268
  400. package/dist/onboarding/autonomous-discovery-tools.js.map +0 -1
  401. package/dist/onboarding/onboarding-state.d.ts +0 -70
  402. package/dist/onboarding/onboarding-state.d.ts.map +0 -1
  403. package/dist/onboarding/onboarding-state.js +0 -183
  404. package/dist/onboarding/onboarding-state.js.map +0 -1
  405. package/dist/onboarding/personality-quiz.d.ts +0 -35
  406. package/dist/onboarding/personality-quiz.d.ts.map +0 -1
  407. package/dist/onboarding/personality-quiz.js +0 -219
  408. package/dist/onboarding/personality-quiz.js.map +0 -1
  409. package/dist/onboarding/phase-5-summary.d.ts +0 -26
  410. package/dist/onboarding/phase-5-summary.d.ts.map +0 -1
  411. package/dist/onboarding/phase-5-summary.js +0 -153
  412. package/dist/onboarding/phase-5-summary.js.map +0 -1
  413. package/dist/onboarding/phase-6-security.d.ts +0 -33
  414. package/dist/onboarding/phase-6-security.d.ts.map +0 -1
  415. package/dist/onboarding/phase-6-security.js +0 -473
  416. package/dist/onboarding/phase-6-security.js.map +0 -1
  417. package/dist/onboarding/phase-7-integrations.d.ts +0 -91
  418. package/dist/onboarding/phase-7-integrations.d.ts.map +0 -1
  419. package/dist/onboarding/phase-7-integrations.js +0 -725
  420. package/dist/onboarding/phase-7-integrations.js.map +0 -1
  421. package/dist/onboarding/phase-8-demo.d.ts +0 -43
  422. package/dist/onboarding/phase-8-demo.d.ts.map +0 -1
  423. package/dist/onboarding/phase-8-demo.js +0 -346
  424. package/dist/onboarding/phase-8-demo.js.map +0 -1
  425. package/dist/onboarding/phase-9-finalization.d.ts +0 -27
  426. package/dist/onboarding/phase-9-finalization.d.ts.map +0 -1
  427. package/dist/onboarding/phase-9-finalization.js +0 -417
  428. package/dist/onboarding/phase-9-finalization.js.map +0 -1
  429. package/dist/onboarding/ritual-prompt.d.ts +0 -2
  430. package/dist/onboarding/ritual-prompt.d.ts.map +0 -1
  431. package/dist/onboarding/ritual-prompt.js +0 -285
  432. package/dist/onboarding/ritual-prompt.js.map +0 -1
  433. package/dist/onboarding/ritual-tools.d.ts +0 -17
  434. package/dist/onboarding/ritual-tools.d.ts.map +0 -1
  435. package/dist/onboarding/ritual-tools.js +0 -93
  436. package/dist/onboarding/ritual-tools.js.map +0 -1
  437. package/dist/setup/setup-tools.d.ts +0 -13
  438. package/dist/setup/setup-tools.d.ts.map +0 -1
  439. package/dist/setup/setup-tools.js +0 -106
  440. package/dist/setup/setup-tools.js.map +0 -1
  441. package/dist/utils/slack-input-validator.d.ts +0 -74
  442. package/dist/utils/slack-input-validator.d.ts.map +0 -1
  443. package/dist/utils/slack-input-validator.js +0 -275
  444. package/dist/utils/slack-input-validator.js.map +0 -1
  445. package/dist/utils/slack-rate-limiter.d.ts +0 -139
  446. package/dist/utils/slack-rate-limiter.d.ts.map +0 -1
  447. package/dist/utils/slack-rate-limiter.js +0 -324
  448. package/dist/utils/slack-rate-limiter.js.map +0 -1
  449. package/dist/wiki/wiki-compiler.d.ts +0 -13
  450. package/dist/wiki/wiki-compiler.d.ts.map +0 -1
  451. package/dist/wiki/wiki-compiler.js +0 -82
  452. package/dist/wiki/wiki-compiler.js.map +0 -1
@@ -1,1235 +0,0 @@
1
- "use strict";
2
- /**
3
- * Multi-Agent Discord Integration
4
- *
5
- * Extends the Discord gateway with multi-agent support.
6
- * Enables multiple AI personas to interact in Discord channels.
7
- */
8
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
- if (k2 === undefined) k2 = k;
10
- var desc = Object.getOwnPropertyDescriptor(m, k);
11
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
- desc = { enumerable: true, get: function() { return m[k]; } };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- }) : (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- }));
19
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
- Object.defineProperty(o, "default", { enumerable: true, value: v });
21
- }) : function(o, v) {
22
- o["default"] = v;
23
- });
24
- var __importStar = (this && this.__importStar) || (function () {
25
- var ownKeys = function(o) {
26
- ownKeys = Object.getOwnPropertyNames || function (o) {
27
- var ar = [];
28
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
- return ar;
30
- };
31
- return ownKeys(o);
32
- };
33
- return function (mod) {
34
- if (mod && mod.__esModule) return mod;
35
- var result = {};
36
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
- __setModuleDefault(result, mod);
38
- return result;
39
- };
40
- })();
41
- Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.MultiAgentDiscordHandler = void 0;
43
- const multi_bot_manager_js_1 = require("./multi-bot-manager.js");
44
- const message_splitter_js_1 = require("../gateways/message-splitter.js");
45
- const channel_history_js_1 = require("../gateways/channel-history.js");
46
- const prompt_enhancer_js_1 = require("../agent/prompt-enhancer.js");
47
- const tool_status_tracker_js_1 = require("../gateways/tool-status-tracker.js");
48
- const child_process_1 = require("child_process");
49
- const util_1 = require("util");
50
- const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
51
- const config_manager_js_1 = require("../cli/config/config-manager.js");
52
- const multi_agent_base_js_1 = require("./multi-agent-base.js");
53
- const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
54
- const { DebugLogger } = debugLogger;
55
- const logger = new DebugLogger('MultiAgentDiscord');
56
- /** Delay before showing progress message (ms) -- fast requests never show it */
57
- const PROGRESS_DELAY_MS = 5_000;
58
- /** Minimum interval between progress message edits (ms) -- Discord rate limit safety */
59
- const PROGRESS_EDIT_INTERVAL_MS = 3_000;
60
- /** Phase emoji progression */
61
- const _PHASE_EMOJIS = ['👀', '🔍', '💻', '🔧', '📝', '✅'];
62
- /** Max characters allowed for dynamic context blocks to avoid prompt bloat */
63
- const MAX_DYNAMIC_CONTEXT_CHARS = () => (0, config_manager_js_1.getConfig)().io?.max_dynamic_context_chars ?? 4_000;
64
- /** Map tool names to phase emojis */
65
- function toolToPhaseEmoji(toolName) {
66
- switch (toolName) {
67
- case 'Task':
68
- case 'Read':
69
- case 'Grep':
70
- case 'Glob':
71
- case 'WebFetch':
72
- case 'WebSearch':
73
- return '🔍'; // analysis
74
- case 'Bash':
75
- return '💻'; // terminal commands
76
- case 'Edit':
77
- case 'Write':
78
- case 'NotebookEdit':
79
- return '🔧'; // implementation (file mutations only)
80
- default:
81
- return null; // no change
82
- }
83
- }
84
- /**
85
- * Multi-Agent Discord Handler
86
- *
87
- * Integrates with the Discord gateway to provide multi-agent support.
88
- * Should be instantiated and called from the Discord gateway when
89
- * multi-agent mode is enabled.
90
- */
91
- class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBase {
92
- multiBotManager;
93
- promptEnhancer;
94
- /** Discord client reference for main bot channel sends */
95
- discordClient = null;
96
- /** Tracks which agent:channel combos have received history injection (new session only) */
97
- historyInjected = new Set();
98
- constructor(config, processOptions = {}, runtimeOptions = {}) {
99
- super(config, processOptions, runtimeOptions);
100
- this.multiBotManager = new multi_bot_manager_js_1.MultiBotManager(config);
101
- this.promptEnhancer = new prompt_enhancer_js_1.PromptEnhancer();
102
- // Setup idle event listeners for all agents (F7)
103
- this.setupIdleListeners();
104
- }
105
- getPlatformName() {
106
- return 'discord';
107
- }
108
- formatBold(text) {
109
- return `**${text}**`;
110
- }
111
- async sendChannelNotification(channelId, message) {
112
- try {
113
- if (this.discordClient) {
114
- const channel = await this.discordClient.channels.fetch(channelId);
115
- if (channel && 'send' in channel) {
116
- await channel.send({
117
- content: message,
118
- });
119
- }
120
- }
121
- }
122
- catch (err) {
123
- console.error(`[MultiAgent] Failed to send channel notification:`, err);
124
- }
125
- }
126
- /**
127
- * Extract agent IDs from <@USER_ID> mentions in message content.
128
- */
129
- extractMentionedAgentIds(content) {
130
- const agentIds = [];
131
- // Discord native mentions: <@USER_ID> or <@!USER_ID>
132
- const mentionPattern = /<@!?(\d+)>/g;
133
- let match;
134
- while ((match = mentionPattern.exec(content)) !== null) {
135
- const userId = match[1];
136
- const agentId = this.multiBotManager.resolveAgentIdFromUserId(userId);
137
- if (agentId && agentId !== 'main') {
138
- agentIds.push(agentId);
139
- }
140
- else if (agentId === 'main' && this.config.default_agent) {
141
- // Main bot userId maps to the default agent (LEAD)
142
- agentIds.push(this.config.default_agent);
143
- }
144
- }
145
- return agentIds;
146
- }
147
- async platformCleanup() {
148
- await this.multiBotManager.stopAll();
149
- }
150
- /**
151
- * Initialize multi-bot support (call after Discord connects)
152
- */
153
- async initializeMultiBots() {
154
- if (this.multiBotInitialized)
155
- return;
156
- // Register mention callback so agent bots forward mentions to handler
157
- this.multiBotManager.onMention(async (agentId, message) => {
158
- // Dedup: skip if already processed via routeResponseMentions
159
- const dedupKey = `${agentId}:${message.id}`;
160
- if (this.processedMentions.has(dedupKey))
161
- return;
162
- this.processedMentions.set(dedupKey, Date.now());
163
- const cleanContent = message.content.replace(/<@!?\d+>/g, '').trim();
164
- if (!cleanContent)
165
- return;
166
- // Determine if sender is an agent bot (for mention_delegation chains)
167
- const isFromAgent = message.author.bot;
168
- const senderAgentId = isFromAgent
169
- ? (this.multiBotManager.isFromAgentBot(message) ?? undefined)
170
- : undefined;
171
- // Chain depth check for mention_delegation
172
- if (isFromAgent && senderAgentId && senderAgentId !== 'main') {
173
- const chainState = this.orchestrator.getChainState(message.channel.id);
174
- const maxDepth = this.getEffectiveMaxMentionDepth();
175
- if (chainState.blocked) {
176
- logger.info(`[MultiAgent] Mention chain blocked in channel ${message.channel.id}, ignoring`);
177
- return;
178
- }
179
- if (chainState.length >= maxDepth) {
180
- logger.info(`[MultiAgent] Mention chain depth ${chainState.length} >= max ${maxDepth}, ignoring`);
181
- return;
182
- }
183
- }
184
- logger.info(`[MultiAgent] Mention-triggered: agent=${agentId}, from=${senderAgentId ?? message.author.tag}, content="${cleanContent.substring(0, 50)}"`);
185
- // Extract mentioned agent IDs from the original content
186
- const mentionedAgentIds = this.extractMentionedAgentIds(message.content);
187
- // Add eyes emoji to indicate processing
188
- try {
189
- await message.react('👀');
190
- }
191
- catch {
192
- /* ignore */
193
- }
194
- // Force this specific agent to respond
195
- const mentionDescription = cleanContent.substring(0, 200);
196
- let mentionResponse = null;
197
- try {
198
- this.systemReminder.notify({
199
- type: 'delegation-started',
200
- taskId: '',
201
- description: mentionDescription,
202
- agentId,
203
- requestedBy: senderAgentId ?? message.author.tag,
204
- channelId: message.channel.id,
205
- source: 'discord',
206
- timestamp: Date.now(),
207
- });
208
- mentionResponse = await this.processAgentResponse(agentId, {
209
- channelId: message.channel.id,
210
- userId: message.author.id,
211
- content: cleanContent,
212
- isBot: isFromAgent,
213
- senderAgentId: senderAgentId && senderAgentId !== 'main' ? senderAgentId : undefined,
214
- mentionedAgentIds,
215
- messageId: message.id,
216
- timestamp: message.createdTimestamp,
217
- }, cleanContent, message);
218
- if (mentionResponse) {
219
- this.systemReminder.notify({
220
- type: 'delegation-completed',
221
- taskId: '',
222
- description: mentionDescription,
223
- agentId,
224
- requestedBy: senderAgentId ?? message.author.tag,
225
- channelId: message.channel.id,
226
- source: 'discord',
227
- duration: mentionResponse.duration,
228
- timestamp: Date.now(),
229
- });
230
- await this.sendAgentResponses(message, [mentionResponse]);
231
- this.orchestrator.recordAgentResponse(agentId, message.channel.id, mentionResponse.messageId);
232
- // Route delegation mentions from this agent's response
233
- if (this.isMentionDelegationEnabled()) {
234
- await this.routeResponseMentions(message, [mentionResponse]);
235
- }
236
- }
237
- }
238
- catch (err) {
239
- console.error(`[MultiAgent] Mention handler error:`, err);
240
- }
241
- finally {
242
- // Only add checkmark if agent responded (null = busy/queued)
243
- if (mentionResponse) {
244
- try {
245
- await message.react('✅');
246
- }
247
- catch {
248
- /* ignore */
249
- }
250
- }
251
- }
252
- });
253
- await this.multiBotManager.initialize();
254
- this.multiBotInitialized = true;
255
- const connectedAgents = this.multiBotManager.getConnectedAgents();
256
- if (connectedAgents.length > 0) {
257
- logger.info(`[MultiAgent] Multi-bot mode active for: ${connectedAgents.join(', ')}`);
258
- }
259
- // Pass bot ID map to process manager for mention-based delegation prompts
260
- if (this.config.mention_delegation) {
261
- const botUserIdMap = this.multiBotManager.getBotUserIdMap();
262
- // Include LEAD (default agent) which uses the main bot token
263
- // Without this, @Conductor in other agents' personas won't resolve to <@userId>
264
- const defaultAgentId = this.config.default_agent;
265
- if (defaultAgentId && !botUserIdMap.has(defaultAgentId)) {
266
- const mainBotUserId = this.multiBotManager.getMainBotUserId();
267
- if (mainBotUserId) {
268
- botUserIdMap.set(defaultAgentId, mainBotUserId);
269
- }
270
- }
271
- this.processManager.setBotUserIdMap(botUserIdMap);
272
- this.processManager.setMentionDelegation(true);
273
- logger.info(`[MultiAgent] Mention delegation enabled with ${botUserIdMap.size} bot IDs`);
274
- }
275
- }
276
- /**
277
- * Set bot's own user ID (call when Discord connects)
278
- * Also wires the PR Review Poller message sender via Discord client.
279
- */
280
- setBotUserId(userId) {
281
- this.multiBotManager.setMainBotUserId(userId);
282
- }
283
- /**
284
- * Set Discord client for PR Review Poller message delivery.
285
- * Call after Discord client is ready.
286
- * The sender posts the message to the channel AND injects it into the
287
- * multi-agent flow so LEAD processes the review comments.
288
- */
289
- setDiscordClient(client) {
290
- // Guard against setting different client when already configured
291
- if (this.discordClient && this.discordClient !== client) {
292
- console.warn('[MultiAgent] Attempted to set different Discord client - ignoring');
293
- return;
294
- }
295
- this.discordClient = client;
296
- this.systemReminder.registerCallback(async (channelId, message) => {
297
- const ch = await client.channels.fetch(channelId);
298
- if (ch && 'send' in ch) {
299
- const chunks = (0, message_splitter_js_1.splitForDiscord)(message);
300
- for (const chunk of chunks) {
301
- await ch.send({
302
- content: chunk,
303
- });
304
- }
305
- }
306
- }, 'discord');
307
- }
308
- /**
309
- * Set main bot token (to avoid duplicate logins in MultiBotManager)
310
- */
311
- setMainBotToken(token) {
312
- this.multiBotManager.setMainBotToken(token);
313
- }
314
- /**
315
- * Update configuration (for hot reload)
316
- */
317
- updateConfig(config) {
318
- this.config = config;
319
- this.orchestrator.updateConfig(config);
320
- this.processManager.updateConfig(config);
321
- this.multiBotManager.updateConfig(config);
322
- }
323
- /**
324
- * Handle a Discord message with multi-agent logic
325
- *
326
- * @returns Object with selected agents and their responses, or null if no agents respond
327
- */
328
- async handleMessage(message, cleanContent) {
329
- // Intercept !stop command before any agent routing
330
- if (cleanContent.startsWith('!stop')) {
331
- await this.handleStopCommand(message, cleanContent);
332
- return null;
333
- }
334
- // Build message context
335
- const context = this.buildMessageContext(message, cleanContent);
336
- // Record human message to shared context
337
- if (!context.isBot) {
338
- this.sharedContext.recordHumanMessage(context.channelId, message.author.username, cleanContent, message.id);
339
- }
340
- // Select responding agents
341
- const selection = this.orchestrator.selectRespondingAgents(context);
342
- logger.info(`[MultiAgent] Selection result: agents=${selection.selectedAgents.join(',')}, reason=${selection.reason}, blocked=${selection.blocked}`);
343
- if (selection.blocked) {
344
- logger.info(`[MultiAgent] Blocked: ${selection.blockReason}`);
345
- return null;
346
- }
347
- if (selection.selectedAgents.length === 0) {
348
- return null;
349
- }
350
- // Process all selected agents in parallel
351
- const results = await Promise.allSettled(selection.selectedAgents.map((agentId) => this.processAgentResponse(agentId, context, cleanContent, message)));
352
- const responses = [];
353
- for (let i = 0; i < results.length; i++) {
354
- const result = results[i];
355
- const agentId = selection.selectedAgents[i];
356
- if (result.status === 'fulfilled' && result.value) {
357
- const response = result.value;
358
- responses.push(response);
359
- // Record agent response to orchestrator and shared context
360
- this.orchestrator.recordAgentResponse(agentId, context.channelId, response.messageId);
361
- const agent = this.orchestrator.getAgent(agentId);
362
- if (agent) {
363
- this.sharedContext.recordAgentMessage(context.channelId, agent, response.content, response.messageId);
364
- }
365
- }
366
- else if (result.status === 'rejected') {
367
- console.error(`[MultiAgent] Error processing agent ${agentId}:`, result.reason);
368
- }
369
- }
370
- if (responses.length === 0) {
371
- return null;
372
- }
373
- return {
374
- selectedAgents: selection.selectedAgents,
375
- reason: selection.reason,
376
- responses,
377
- };
378
- }
379
- async handleStopCommand(message, cleanContent) {
380
- const channelId = message.channel.id;
381
- const args = cleanContent.slice('!stop'.length).trim();
382
- if (args) {
383
- const agentId = args;
384
- const agent = this.orchestrator.getAgent(agentId);
385
- if (!agent) {
386
- await message.reply({ content: `⏹️ Unknown agent: \`${agentId}\`` });
387
- return;
388
- }
389
- const hasActive = this.processManager.hasActiveProcess('discord', channelId, agentId);
390
- if (hasActive) {
391
- this.processManager.stopProcess('discord', channelId, agentId);
392
- this.orchestrator.resetChain(channelId);
393
- const displayName = agent.display_name || agentId;
394
- await message.reply({ content: `⏹️ Stopped ${displayName}` });
395
- }
396
- else {
397
- await message.reply({ content: `⏹️ No running agents to stop` });
398
- }
399
- }
400
- else {
401
- const activeAgents = this.processManager.getActiveAgentsInChannel('discord', channelId);
402
- if (activeAgents.length > 0) {
403
- this.processManager.stopChannelProcesses('discord', channelId);
404
- this.orchestrator.resetChain(channelId);
405
- await message.reply({ content: `⏹️ Stopped all agents in this channel` });
406
- }
407
- else {
408
- await message.reply({ content: `⏹️ No running agents to stop` });
409
- }
410
- }
411
- logger.info(`[MultiAgent] !stop command: channel=${channelId}, target=${args || 'all'}`);
412
- }
413
- /**
414
- * Process a single agent's response
415
- * @param discordMessage - Optional Discord message for emoji progression
416
- */
417
- async processAgentResponse(agentId, context, userMessage, discordMessage) {
418
- const agent = this.orchestrator.getAgent(agentId);
419
- if (!agent) {
420
- console.error(`[MultiAgent] Unknown agent: ${agentId}`);
421
- return null;
422
- }
423
- // Strip trigger prefix from message if present
424
- const cleanMessage = this.orchestrator.stripTriggerPrefix(userMessage, agentId);
425
- // Build context for this agent.
426
- // In delegation chains (senderAgentId set), include own messages so the agent
427
- // can see what it already said and reason about whether to repeat.
428
- // In normal triggers, exclude own messages to avoid self-reference confusion.
429
- let agentContext;
430
- if (context.senderAgentId) {
431
- const messages = this.sharedContext.getRecentMessages(context.channelId, 10);
432
- if (messages.length > 0) {
433
- const lines = messages.map((msg) => {
434
- const isSelf = msg.agentId === agentId;
435
- const prefix = msg.isHuman ? '👤' : isSelf ? '📌 (you)' : '🤖';
436
- const content = msg.content.length > 600 ? msg.content.slice(0, 600) + '...' : msg.content;
437
- return `${prefix} **${msg.displayName}**: ${content}`;
438
- });
439
- agentContext = `## Delegation Chain Context\n${lines.join('\n')}`;
440
- }
441
- else {
442
- agentContext = '';
443
- }
444
- }
445
- else {
446
- agentContext = this.sharedContext.buildContextForAgent(context.channelId, agentId, 5);
447
- }
448
- // Build full prompt with context.
449
- // - agentContext: other agents' recent messages (inter-agent awareness)
450
- // - historyContext: human-only channel history (LEAD agent only)
451
- // DevBot/Reviewer are sub-agent-like -- they get tasks via delegation, not channel history.
452
- // Only LEAD needs channel context to understand the conversation flow.
453
- let fullPrompt = cleanMessage;
454
- // Inject channel history for all agents on new sessions only.
455
- // - Keeps human messages + this agent's own messages, excludes other bots.
456
- // - Only on first message per session (subsequent messages are in session memory).
457
- const sessionKey = `${agentId}:${context.channelId}`;
458
- if (!this.historyInjected.has(sessionKey)) {
459
- const channelHistory = (0, channel_history_js_1.getChannelHistory)();
460
- const displayName = agent.display_name || agentId;
461
- const historyContext = channelHistory.formatForContext(context.channelId, context.messageId, displayName // keep human + this agent's own messages, exclude other bots
462
- );
463
- if (historyContext) {
464
- fullPrompt = `${historyContext}\n\n${fullPrompt}`;
465
- }
466
- this.historyInjected.add(sessionKey);
467
- }
468
- if (agentContext) {
469
- fullPrompt = `${agentContext}\n\n${fullPrompt}`;
470
- }
471
- // Inject agent availability status, active work, and channel context (Phase 2 + 3)
472
- const agentStatus = this.buildAgentStatusSection(agentId);
473
- const workSection = this.workTracker.buildWorkSection(agentId);
474
- const channelInfo = `## Current Channel\nPlatform: Discord\nchannel_id: ${context.channelId}\nUse **discord_send** to send messages/files to this channel.`;
475
- const dynamicContextRaw = [agentStatus, workSection, channelInfo].filter(Boolean).join('\n');
476
- const dynamicContext = dynamicContextRaw.length > MAX_DYNAMIC_CONTEXT_CHARS()
477
- ? `${dynamicContextRaw.slice(0, MAX_DYNAMIC_CONTEXT_CHARS())}\n...`
478
- : dynamicContextRaw;
479
- if (dynamicContext) {
480
- fullPrompt = `${dynamicContext}\n\n${fullPrompt}`;
481
- }
482
- // Enhance prompt with keyword detection (ultrawork/search/analyze modes)
483
- const workspacePath = globalThis.process.env.MAMA_WORKSPACE || '';
484
- const ruleContext = {
485
- agentId,
486
- tier: agent.tier,
487
- channelId: context.channelId,
488
- };
489
- const enhanced = await this.promptEnhancer.enhance(cleanMessage, workspacePath, ruleContext);
490
- if (enhanced.skillContent) {
491
- const safeSkillContent = enhanced.skillContent.replace(/<\/system-reminder>/gi, '</system\u2011reminder>');
492
- fullPrompt = `<system-reminder>\n${safeSkillContent}\n</system-reminder>\n\n${fullPrompt}`;
493
- logger.info(`[SkillMatch] Injecting skill into Discord agent ${agentId}: ${enhanced.skillContent.length} chars`);
494
- }
495
- if (enhanced.keywordInstructions) {
496
- fullPrompt = `${enhanced.keywordInstructions}\n\n${fullPrompt}`;
497
- logger.info(`[PromptEnhancer] Keyword detected for agent ${agentId}: ${enhanced.keywordInstructions.length} chars injected`);
498
- }
499
- if (enhanced.rulesContent) {
500
- fullPrompt = `## Project Rules\n${enhanced.rulesContent}\n\n${fullPrompt}`;
501
- logger.info(`[PromptEnhancer] Rules injected for agent ${agentId}: ${enhanced.rulesContent.length} chars`);
502
- }
503
- logger.info(`[MultiAgent] Processing agent ${agentId}, prompt length: ${fullPrompt.length}`);
504
- // Track work start (completed in finally block)
505
- this.workTracker.startWork(agentId, context.channelId, cleanMessage);
506
- let agentProcess = null;
507
- try {
508
- // Get or create process for this agent in this channel
509
- agentProcess = await this.processManager.getProcess('discord', context.channelId, agentId);
510
- // Build onToolUse callback for emoji progression (accumulate, don't replace)
511
- const addedEmojis = new Set();
512
- const hasOwnBot = this.multiBotManager.hasAgentBot(agentId);
513
- // Create tool status tracker for progress messages
514
- let tracker = null;
515
- if (discordMessage) {
516
- const channelId = discordMessage.channel.id;
517
- let placeholderMsg = null;
518
- const discordAdapter = {
519
- postPlaceholder: async (content) => {
520
- if (hasOwnBot) {
521
- placeholderMsg = await this.multiBotManager.sendAsAgent(agentId, channelId, content);
522
- }
523
- else if ('send' in discordMessage.channel) {
524
- placeholderMsg = await discordMessage.channel.send(content);
525
- }
526
- return placeholderMsg?.id ?? null;
527
- },
528
- editPlaceholder: async (_handle, content) => {
529
- if (placeholderMsg) {
530
- await placeholderMsg.edit(content);
531
- }
532
- },
533
- deletePlaceholder: async (_handle) => {
534
- if (placeholderMsg) {
535
- await placeholderMsg.delete();
536
- placeholderMsg = null;
537
- }
538
- },
539
- };
540
- tracker = new tool_status_tracker_js_1.ToolStatusTracker(discordAdapter, {
541
- throttleMs: PROGRESS_EDIT_INTERVAL_MS,
542
- initialDelayMs: PROGRESS_DELAY_MS,
543
- });
544
- }
545
- const onToolUse = discordMessage
546
- ? (name, input) => {
547
- // Emoji reaction behavior
548
- const emoji = toolToPhaseEmoji(name);
549
- if (emoji && !addedEmojis.has(emoji)) {
550
- addedEmojis.add(emoji);
551
- if (hasOwnBot) {
552
- this.multiBotManager
553
- .reactAsAgent(agentId, discordMessage.channel.id, discordMessage.id, emoji)
554
- .catch(() => {
555
- /* ignore */
556
- });
557
- }
558
- else {
559
- discordMessage.react(emoji).catch(() => {
560
- /* ignore */
561
- });
562
- }
563
- }
564
- // Tool status tracker
565
- tracker?.onToolUse(name, input);
566
- }
567
- : undefined;
568
- // Send message and get response (with timeout, properly cleaned up)
569
- // agent_ms=0 means unlimited (no timeout race)
570
- let timeoutHandle;
571
- let result;
572
- try {
573
- const agentTimeout = (0, multi_agent_base_js_1.AGENT_TIMEOUT_MS)();
574
- const sendPromise = agentProcess.sendMessage(fullPrompt, onToolUse ? { onToolUse } : undefined);
575
- if (agentTimeout > 0) {
576
- result = await Promise.race([
577
- sendPromise,
578
- new Promise((_, reject) => {
579
- timeoutHandle = setTimeout(() => reject(new Error(`Agent ${agentId} timed out after ${agentTimeout / 1000}s`)), agentTimeout);
580
- }),
581
- ]);
582
- }
583
- else {
584
- result = await sendPromise;
585
- }
586
- }
587
- finally {
588
- if (timeoutHandle)
589
- clearTimeout(timeoutHandle);
590
- await tracker?.cleanup();
591
- }
592
- // Execute text-based gateway tool calls (```tool_call blocks in response)
593
- // Claude CLI handles built-in tools (Read, Bash, Glob) internally via native tool_use.
594
- // Gateway tools (discord_send, mama_*) are requested via text-based tool_call blocks.
595
- // discord_send is routed through the agent's own bot (not the main LEAD bot).
596
- // Check for workflow plan BEFORE executing tool calls (priority)
597
- const workflowStart = Date.now();
598
- const workflowResult = await this.tryExecuteWorkflow(result.response, context.channelId, 'discord', (event) => {
599
- if (!this.discordClient) {
600
- return;
601
- }
602
- let msg = '';
603
- const modelTag = event.agentModel ? ` [${event.agentModel}]` : '';
604
- const progress = event.totalSteps && event.completedSteps !== undefined
605
- ? ` [${event.completedSteps}/${event.totalSteps}]`
606
- : '';
607
- if (event.type === 'step-started') {
608
- msg = ` ${event.agentDisplayName}${modelTag}${progress} starting...`;
609
- }
610
- else if (event.type === 'step-completed') {
611
- const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
612
- const pct = event.totalSteps && event.completedSteps !== undefined
613
- ? ` (${Math.round((event.completedSteps / event.totalSteps) * 100)}%)`
614
- : '';
615
- msg = `${event.agentDisplayName}${modelTag} (${sec}s)${pct} completed`;
616
- }
617
- else if (event.type === 'step-failed') {
618
- msg = `${event.agentDisplayName}${modelTag}${progress} ❌ failed: ${event.error?.substring(0, 100)}`;
619
- }
620
- if (msg) {
621
- this.sendChannelNotification(context.channelId, msg).catch(() => { });
622
- }
623
- });
624
- if (workflowResult) {
625
- if (workflowResult.failed) {
626
- this.logger.warn(`[MultiAgentDiscord] Workflow failed: ${workflowResult.failed}, sending feedback to conductor`);
627
- const feedback = `[SYSTEM] Your workflow_plan failed to execute.\nReason: ${workflowResult.failed}\nPlease adjust and retry, or respond without a workflow_plan.`;
628
- const retryResult = await agentProcess.sendMessage(feedback);
629
- const cleanedRetry = await this.executeAgentToolCalls(agentId, retryResult.response);
630
- const formattedResponse = this.formatAgentResponse(agent, cleanedRetry);
631
- return {
632
- agentId,
633
- agent,
634
- content: formattedResponse,
635
- rawContent: cleanedRetry,
636
- duration: Date.now() - workflowStart + (result.duration_ms ?? 0),
637
- };
638
- }
639
- const display = workflowResult.directMessage
640
- ? `${workflowResult.directMessage}\n\n${workflowResult.result}`
641
- : workflowResult.result;
642
- const formattedResponse = this.formatAgentResponse(agent, display);
643
- const totalDuration = Date.now() - workflowStart + (result.duration_ms ?? 0);
644
- return {
645
- agentId,
646
- agent,
647
- content: formattedResponse,
648
- rawContent: display,
649
- duration: totalDuration,
650
- };
651
- }
652
- // Check for council plan (after workflow, before tool calls)
653
- const councilResult = await this.tryExecuteCouncil(result.response, context.channelId, 'discord', (event) => {
654
- if (!this.discordClient)
655
- return;
656
- let msg = '';
657
- if (event.type === 'council-round-started') {
658
- msg = `🗣️ ${event.agentDisplayName} Round ${event.round} starting...`;
659
- }
660
- else if (event.type === 'council-round-completed') {
661
- const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
662
- msg = `🗣️ ${event.agentDisplayName} Round ${event.round} (${sec}s) completed`;
663
- }
664
- else if (event.type === 'council-round-failed') {
665
- msg = `🗣️ ${event.agentDisplayName} Round ${event.round} ❌ failed: ${event.error?.substring(0, 100)}`;
666
- }
667
- if (msg) {
668
- this.sendChannelNotification(context.channelId, msg).catch(() => { });
669
- }
670
- });
671
- if (councilResult) {
672
- const display = councilResult.directMessage
673
- ? `${councilResult.directMessage}\n\n${councilResult.result}`
674
- : councilResult.result;
675
- const formattedResponse = this.formatAgentResponse(agent, display);
676
- return {
677
- agentId,
678
- agent,
679
- content: formattedResponse,
680
- rawContent: display,
681
- duration: Date.now() - workflowStart + (result.duration_ms ?? 0),
682
- };
683
- }
684
- // Strip any workflow/council plan JSON that wasn't executed
685
- let responseForProcessing = result.response;
686
- if (this.workflowEngine?.isEnabled()) {
687
- responseForProcessing = this.workflowEngine.extractNonPlanContent(responseForProcessing);
688
- }
689
- if (this.councilEngine) {
690
- responseForProcessing = this.councilEngine.extractNonPlanContent(responseForProcessing);
691
- }
692
- const cleanedResponse = await this.executeAgentToolCalls(agentId, responseForProcessing);
693
- // Detect API error responses — skip mention resolution to prevent error loops
694
- const isErrorResponse = /API Error:\s*\d{3}\b/.test(cleanedResponse);
695
- const resolvedResponse = isErrorResponse
696
- ? cleanedResponse
697
- : this.resolveResponseMentions(cleanedResponse);
698
- const formattedResponse = this.formatAgentResponse(agent, resolvedResponse);
699
- return {
700
- agentId,
701
- agent,
702
- content: formattedResponse,
703
- rawContent: resolvedResponse,
704
- duration: result.duration_ms,
705
- };
706
- }
707
- catch (error) {
708
- const errMsg = error instanceof Error ? error.message : String(error);
709
- console.error(`[MultiAgent] Failed to get response from ${agentId}:`, error);
710
- if (errMsg.includes('busy')) {
711
- logger.info(`[MultiAgent] Agent ${agentId} busy, enqueuing message`);
712
- const queuedMessage = {
713
- prompt: fullPrompt,
714
- channelId: context.channelId,
715
- threadTs: context.messageId,
716
- source: 'discord',
717
- enqueuedAt: Date.now(),
718
- context,
719
- discordMessageId: discordMessage?.id,
720
- };
721
- this.messageQueue.enqueue(agentId, queuedMessage);
722
- // Trigger immediate drain if process is idle or reaped
723
- this.tryDrainNow(agentId, 'discord', context.channelId).catch(() => { });
724
- if (discordMessage) {
725
- try {
726
- await discordMessage.react('⏳');
727
- }
728
- catch {
729
- /* ignore */
730
- }
731
- }
732
- }
733
- return null;
734
- }
735
- finally {
736
- this.workTracker.completeWork(agentId, context.channelId);
737
- }
738
- }
739
- /**
740
- * Build message context from Discord message
741
- */
742
- buildMessageContext(message, cleanContent) {
743
- const isBot = message.author.bot;
744
- let senderAgentId;
745
- if (isBot) {
746
- // Check if message is from one of our agent bots
747
- const agentBotId = this.multiBotManager.isFromAgentBot(message);
748
- if (agentBotId && agentBotId !== 'main') {
749
- senderAgentId = agentBotId;
750
- }
751
- else {
752
- // Try to extract agent ID from message display name (main bot)
753
- const extracted = this.orchestrator.extractAgentIdFromMessage(message.content);
754
- senderAgentId = extracted ?? undefined;
755
- }
756
- }
757
- // Extract mentioned agent IDs from Discord mentions
758
- const mentionedAgentIds = isBot ? undefined : this.extractMentionedAgentIds(message.content);
759
- return {
760
- channelId: message.channel.id,
761
- userId: message.author.id,
762
- content: cleanContent,
763
- isBot,
764
- senderAgentId,
765
- mentionedAgentIds: mentionedAgentIds?.length ? mentionedAgentIds : undefined,
766
- messageId: message.id,
767
- timestamp: message.createdTimestamp,
768
- };
769
- }
770
- /**
771
- * Send queued response to Discord (F7: message queue drain callback)
772
- */
773
- async sendQueuedResponse(agentId, message, response) {
774
- const agent = this.orchestrator.getAgent(agentId);
775
- if (!agent) {
776
- console.error(`[MultiAgent] Unknown agent in queue: ${agentId}`);
777
- return;
778
- }
779
- // Try executing workflow if this is a conductor response with a workflow_plan
780
- let cleanedResponse;
781
- const workflowResult = await this.tryExecuteWorkflow(response, message.channelId, 'discord');
782
- if (workflowResult && !workflowResult.failed) {
783
- cleanedResponse = workflowResult.directMessage
784
- ? `${workflowResult.directMessage}\n\n${workflowResult.result}`
785
- : workflowResult.result;
786
- }
787
- else {
788
- // Strip workflow/council plan JSON that wasn't executed
789
- let strippedResponse = response;
790
- if (this.workflowEngine?.isEnabled()) {
791
- strippedResponse = this.workflowEngine.extractNonPlanContent(strippedResponse);
792
- }
793
- if (this.councilEngine) {
794
- strippedResponse = this.councilEngine.extractNonPlanContent(strippedResponse);
795
- }
796
- // Execute gateway tool calls from response
797
- cleanedResponse = await this.executeAgentToolCalls(agentId, strippedResponse);
798
- }
799
- const displayResponse = cleanedResponse;
800
- // Format response with agent prefix
801
- const formattedResponse = this.formatAgentResponse(agent, displayResponse);
802
- const chunks = (0, message_splitter_js_1.splitForDiscord)(formattedResponse);
803
- const hasOwnBot = this.multiBotManager.hasAgentBot(agentId);
804
- for (const chunk of chunks) {
805
- try {
806
- if (hasOwnBot) {
807
- // Use agent's dedicated bot - send to channel
808
- await this.multiBotManager.sendAsAgent(agentId, message.channelId, chunk);
809
- }
810
- else if (this.discordClient) {
811
- // Use main bot via stored Discord client
812
- const channel = await this.discordClient.channels.fetch(message.channelId);
813
- if (channel && 'send' in channel) {
814
- await channel.send(chunk);
815
- }
816
- }
817
- else {
818
- console.warn(`[MultiAgent] Cannot send queued message for ${agentId}: no agent bot or Discord client`);
819
- }
820
- }
821
- catch (err) {
822
- console.error(`[MultiAgent] Failed to send queued response for ${agentId}:`, err);
823
- }
824
- }
825
- // Record to shared context
826
- this.sharedContext.recordAgentMessage(message.channelId, agent, response, '');
827
- // Mark original Discord message as completed
828
- if (message.discordMessageId && this.discordClient) {
829
- try {
830
- const channel = await this.discordClient.channels.fetch(message.channelId);
831
- if (channel && 'messages' in channel) {
832
- const originalMsg = await channel.messages.fetch(message.discordMessageId);
833
- if (originalMsg) {
834
- await originalMsg.react('✅');
835
- }
836
- }
837
- }
838
- catch {
839
- /* ignore -- message may have been deleted */
840
- }
841
- }
842
- logger.info(`[MultiAgent] Queued message delivered for ${agentId} in ${message.channelId}`);
843
- }
844
- /**
845
- * Send formatted response to Discord (handles message splitting)
846
- * Uses agent's dedicated bot if available, otherwise main bot
847
- */
848
- async sendAgentResponses(originalMessage, responses) {
849
- const sentMessages = [];
850
- for (const response of responses) {
851
- try {
852
- const chunks = (0, message_splitter_js_1.splitForDiscord)(response.content);
853
- const hasOwnBot = this.multiBotManager.hasAgentBot(response.agentId);
854
- for (let i = 0; i < chunks.length; i++) {
855
- let sentMessage = null;
856
- try {
857
- if (hasOwnBot) {
858
- // Use agent's dedicated bot
859
- if (i === 0) {
860
- // First chunk: reply to original message
861
- sentMessage = await this.multiBotManager.replyAsAgent(response.agentId, originalMessage, chunks[i]);
862
- }
863
- else {
864
- // Subsequent chunks: send as new message
865
- sentMessage = await this.multiBotManager.sendAsAgent(response.agentId, originalMessage.channel.id, chunks[i]);
866
- }
867
- }
868
- else {
869
- // Use main bot
870
- if (sentMessages.length === 0 && i === 0) {
871
- // First message: reply to original
872
- sentMessage = await originalMessage.reply({ content: chunks[i] });
873
- }
874
- else {
875
- // Subsequent messages: send as new message
876
- if ('send' in originalMessage.channel) {
877
- sentMessage = await originalMessage.channel.send({ content: chunks[i] });
878
- }
879
- }
880
- }
881
- if (sentMessage) {
882
- sentMessages.push(sentMessage);
883
- // Update response with message ID (for chain tracking)
884
- if (i === 0) {
885
- response.messageId = sentMessage.id;
886
- }
887
- }
888
- }
889
- catch (chunkErr) {
890
- // Per-chunk error handling: don't let one chunk failure drop remaining chunks
891
- console.error(`[MultiAgent] Failed to send chunk ${i + 1}/${chunks.length} for agent ${response.agentId}:`, chunkErr);
892
- // Continue with next chunk
893
- }
894
- }
895
- }
896
- catch (err) {
897
- // Per-response error handling: don't let one agent's failure drop other agents' responses
898
- console.error(`[MultiAgent] Failed to send response for agent ${response.agentId}:`, err);
899
- }
900
- }
901
- // Post-send: Auto-review trigger for default agent (Armed Conductor) self-implementations
902
- const defaultAgentId = this.config.default_agent;
903
- if (defaultAgentId) {
904
- const selfImplemented = responses.find((r) => r.agentId === defaultAgentId && this.detectSelfImplementation(r.rawContent));
905
- if (selfImplemented && sentMessages.length > 0) {
906
- this.triggerAutoReviewIfNeeded(originalMessage.channel.id, defaultAgentId).catch((err) => console.error('[AutoReview] Failed to check diff size:', err));
907
- }
908
- }
909
- return sentMessages;
910
- }
911
- /**
912
- * Detect if the default agent (Conductor) performed direct code edits.
913
- * Checks for Claude CLI tool-use markers that indicate Edit/Write operations.
914
- */
915
- detectSelfImplementation(rawContent) {
916
- // Claude CLI responses contain tool use results -- look for Edit/Write indicators
917
- const editIndicators = [
918
- /\bedit\b.*\bapplied\b/i,
919
- /\bwrote\b.*\bfile\b/i,
920
- /\bmodified\b.*\bfile/i,
921
- /\bEdit\b.*\bsuccess/i,
922
- /\bWrite\b.*\bsuccess/i,
923
- /파일.*수정/, // Korean: "file...modified" — detects Korean user input
924
- /수정.*완료/, // Korean: "modification...completed" — detects Korean user input
925
- /\[SOLO\]/i,
926
- /\[PAIR\]/i,
927
- ];
928
- return editIndicators.some((pattern) => pattern.test(rawContent));
929
- }
930
- /**
931
- * Check git diff size after Conductor self-implementation.
932
- * If diff exceeds thresholds, auto-trigger Reviewer for quality gate.
933
- *
934
- * Thresholds (PAIR mode auto-escalation):
935
- * - >3 files changed -> auto-mention Reviewer
936
- * - >200 lines changed -> auto-mention Reviewer
937
- */
938
- async triggerAutoReviewIfNeeded(channelId, defaultAgentId) {
939
- const MAX_FILES = 3;
940
- const MAX_LINES = 200;
941
- try {
942
- // Get diff stats from git
943
- const { stdout: diffStat } = await execFileAsync('git', ['diff', '--stat', '--cached'], {
944
- cwd: process.cwd(),
945
- timeout: 5000,
946
- });
947
- // Also check unstaged changes (increased timeout for large repos)
948
- const { stdout: diffUnstaged } = await execFileAsync('git', ['diff', '--stat'], {
949
- cwd: process.cwd(),
950
- timeout: 10000,
951
- });
952
- const combinedDiff = diffStat + '\n' + diffUnstaged;
953
- const fileLines = combinedDiff
954
- .split('\n')
955
- .filter((l) => l.includes('|'))
956
- .map((l) => l.trim())
957
- .filter((l) => l.length > 0);
958
- const filesChanged = fileLines.length;
959
- // Parse total insertions/deletions from summary line
960
- const summaryMatch = combinedDiff.match(/(\d+)\s+insertion|(\d+)\s+deletion/g);
961
- let totalLines = 0;
962
- if (summaryMatch) {
963
- for (const m of summaryMatch) {
964
- const num = m.match(/(\d+)/);
965
- if (num) {
966
- totalLines += parseInt(num[1], 10);
967
- }
968
- }
969
- }
970
- if (filesChanged > MAX_FILES || totalLines > MAX_LINES) {
971
- logger.info(`[AutoReview] Conductor self-implementation exceeded thresholds: ${filesChanged} files, ${totalLines} lines -> auto-triggering Reviewer`);
972
- // Find reviewer agent using shared helper
973
- const reviewerEntry = this.findReviewerAgent();
974
- const reviewerAgentId = reviewerEntry?.[0];
975
- if (reviewerAgentId && this.multiBotManager.hasAgentBot(reviewerAgentId)) {
976
- const reviewMsg = `⬆️ **Auto-Review Triggered** -- ${defaultAgentId} self-implemented but diff exceeded thresholds (${filesChanged} files, ${totalLines} lines). Requesting @Reviewer auto-review.`;
977
- await this.multiBotManager.sendAsAgent(reviewerAgentId, channelId, reviewMsg);
978
- }
979
- }
980
- else {
981
- logger.info(`[AutoReview] Conductor self-implementation within thresholds: ${filesChanged} files, ${totalLines} lines -- no auto-review needed`);
982
- }
983
- }
984
- catch {
985
- // Git not available or not in a repo -- skip silently
986
- }
987
- }
988
- /**
989
- * Get multi-bot manager
990
- */
991
- getMultiBotManager() {
992
- return this.multiBotManager;
993
- }
994
- /**
995
- * Get status of all agent bots
996
- */
997
- getBotStatus() {
998
- return this.multiBotManager.getStatus();
999
- }
1000
- /**
1001
- * After sending agent responses, check for mentions to other agents and route them.
1002
- * Discord equivalent of Slack's routeResponseMentions -- necessary because Discord
1003
- * bots don't receive their own messages as events.
1004
- */
1005
- async routeResponseMentions(originalMessage, responses) {
1006
- for (const response of responses) {
1007
- // Filter out self-mentions only. All agents can route to any other agent
1008
- // including LEAD -- the receiving LLM agent can reason about whether to
1009
- // respond with new information or acknowledge without repeating.
1010
- const mentionedAgentIds = this.extractMentionedAgentIds(response.rawContent).filter((id) => id !== response.agentId // no self-mention
1011
- );
1012
- if (mentionedAgentIds.length === 0)
1013
- continue;
1014
- logger.info(`[MultiAgent] Auto-routing mentions from ${response.agentId}: -> ${mentionedAgentIds.join(', ')}`);
1015
- // Route to all mentioned agents in parallel
1016
- await Promise.all(mentionedAgentIds.map((targetAgentId) => this.handleDelegatedMention(targetAgentId, originalMessage, response)));
1017
- }
1018
- }
1019
- /**
1020
- * Handle a delegated mention: process target agent response and recursively route.
1021
- */
1022
- async handleDelegatedMention(targetAgentId, originalMessage, sourceResponse) {
1023
- // Dedup: prevent double processing
1024
- const dedupKey = `${targetAgentId}:${sourceResponse.messageId || originalMessage.id}`;
1025
- if (this.processedMentions.has(dedupKey))
1026
- return;
1027
- this.processedMentions.set(dedupKey, Date.now());
1028
- // Chain depth check
1029
- const chainState = this.orchestrator.getChainState(originalMessage.channel.id);
1030
- const maxDepth = this.config.max_mention_depth ?? 3;
1031
- if (chainState.blocked || chainState.length >= maxDepth) {
1032
- logger.info(`[MultiAgent] Delegation chain blocked/maxed in ${originalMessage.channel.id}`);
1033
- return;
1034
- }
1035
- // Delegation rule validation (Phase 4)
1036
- if (this.config.delegation_rules) {
1037
- const rule = this.config.delegation_rules.find((r) => r.from === sourceResponse.agentId && r.to.includes(targetAgentId));
1038
- if (!rule) {
1039
- logger.info(`[MultiAgent] Delegation blocked by rule: ${sourceResponse.agentId} → ${targetAgentId}`);
1040
- return;
1041
- }
1042
- }
1043
- logger.info(`[MultiAgent] Delegated mention: ${sourceResponse.agentId} -> ${targetAgentId}`);
1044
- // React on the delegation message (source agent's response), not the user's original message
1045
- const hasOwnBot = this.multiBotManager.hasAgentBot(targetAgentId);
1046
- const delegationMsgId = sourceResponse.messageId || originalMessage.id;
1047
- const channelId = originalMessage.channel.id;
1048
- try {
1049
- if (hasOwnBot) {
1050
- await this.multiBotManager.reactAsAgent(targetAgentId, channelId, delegationMsgId, '👀');
1051
- }
1052
- else {
1053
- await originalMessage.react('👀');
1054
- }
1055
- }
1056
- catch {
1057
- /* ignore */
1058
- }
1059
- const truncatedDescription = sourceResponse.rawContent
1060
- .replace(/<@!?\d+>/g, '')
1061
- .trim()
1062
- .substring(0, 200);
1063
- this.systemReminder.notify({
1064
- type: 'delegation-started',
1065
- taskId: '',
1066
- description: truncatedDescription,
1067
- agentId: targetAgentId,
1068
- requestedBy: sourceResponse.agentId,
1069
- channelId,
1070
- source: 'discord',
1071
- timestamp: Date.now(),
1072
- });
1073
- const delegationContent = sourceResponse.rawContent.replace(/<@!?\d+>/g, '').trim();
1074
- try {
1075
- const response = await this.processAgentResponse(targetAgentId, {
1076
- channelId,
1077
- userId: originalMessage.author.id,
1078
- content: delegationContent,
1079
- isBot: true,
1080
- senderAgentId: sourceResponse.agentId,
1081
- mentionedAgentIds: [targetAgentId],
1082
- messageId: originalMessage.id,
1083
- timestamp: originalMessage.createdTimestamp,
1084
- }, delegationContent, undefined // Don't pass discordMessage -- emojis handled here via delegation messageId
1085
- );
1086
- if (response) {
1087
- this.systemReminder.notify({
1088
- type: 'delegation-completed',
1089
- taskId: '',
1090
- description: truncatedDescription,
1091
- agentId: targetAgentId,
1092
- requestedBy: sourceResponse.agentId,
1093
- channelId,
1094
- source: 'discord',
1095
- duration: response.duration,
1096
- timestamp: Date.now(),
1097
- });
1098
- await this.sendAgentResponses(originalMessage, [response]);
1099
- this.orchestrator.recordAgentResponse(targetAgentId, originalMessage.channel.id, response.messageId);
1100
- // Recursively route mentions in this agent's response
1101
- await this.routeResponseMentions(originalMessage, [response]);
1102
- }
1103
- }
1104
- catch (err) {
1105
- const isBusy = err instanceof Error && err.message.includes('Process is busy');
1106
- if (isBusy) {
1107
- logger.info(`[MultiAgent] ${targetAgentId} busy, enqueuing delegation from ${sourceResponse.agentId}`);
1108
- this.messageQueue.enqueue(targetAgentId, {
1109
- prompt: delegationContent,
1110
- channelId,
1111
- source: 'discord',
1112
- enqueuedAt: Date.now(),
1113
- context: { channelId, userId: originalMessage.author.id },
1114
- });
1115
- this.tryDrainNow(targetAgentId, 'discord', channelId).catch(() => { });
1116
- }
1117
- else {
1118
- console.error(`[MultiAgent] Delegated mention error (${targetAgentId}):`, err);
1119
- }
1120
- }
1121
- finally {
1122
- // Add checkmark on the delegation message (source agent's response)
1123
- try {
1124
- if (hasOwnBot) {
1125
- await this.multiBotManager.reactAsAgent(targetAgentId, channelId, delegationMsgId, '✅');
1126
- }
1127
- else {
1128
- // Fix: React to the delegation message, not the original user message
1129
- const delegationMsg = await originalMessage.channel.messages.fetch(delegationMsgId);
1130
- await delegationMsg.react('✅');
1131
- }
1132
- }
1133
- catch {
1134
- /* ignore */
1135
- }
1136
- }
1137
- }
1138
- /**
1139
- * Execute text-based tool calls, routing discord_send through the agent's own bot.
1140
- * Non-discord tools fall through to the base executeTextToolCalls.
1141
- */
1142
- async executeAgentToolCalls(agentId, responseText) {
1143
- const toolCalls = this.parseToolCallsFromText(responseText);
1144
- if (toolCalls.length === 0)
1145
- return responseText;
1146
- const hasOwnBot = this.multiBotManager.hasAgentBot(agentId);
1147
- for (const toolCall of toolCalls) {
1148
- try {
1149
- if (toolCall.name === 'discord_send' && hasOwnBot) {
1150
- if (typeof toolCall.input !== 'object' || toolCall.input === null) {
1151
- console.warn(`[MultiAgent] Tool ${toolCall.name}: invalid input (not an object)`);
1152
- continue;
1153
- }
1154
- const input = toolCall.input;
1155
- const channelId = typeof input.channel_id === 'string' ? input.channel_id : undefined;
1156
- const filePath = typeof input.file_path === 'string'
1157
- ? input.file_path
1158
- : typeof input.image_path === 'string'
1159
- ? input.image_path
1160
- : undefined;
1161
- const message = typeof input.message === 'string' ? input.message : undefined;
1162
- if (!channelId || (!filePath && !message)) {
1163
- console.warn(`[MultiAgent] Tool ${toolCall.name}: missing channel_id or payload`);
1164
- continue;
1165
- }
1166
- if (channelId && filePath) {
1167
- await this.multiBotManager.sendFileAsAgent(agentId, channelId, filePath, message);
1168
- }
1169
- else if (channelId && message) {
1170
- await this.multiBotManager.sendAsAgent(agentId, channelId, message);
1171
- }
1172
- logger.info(`[MultiAgent] discord_send routed through agent bot: ${agentId}`);
1173
- }
1174
- else if (this.gatewayToolExecutor) {
1175
- const result = await this.gatewayToolExecutor.execute(toolCall.name, toolCall.input);
1176
- logger.info(`[MultiAgent] Tool ${toolCall.name} succeeded:`, JSON.stringify(result).substring(0, 200));
1177
- }
1178
- }
1179
- catch (error) {
1180
- console.error(`[MultiAgent] Tool ${toolCall.name} failed:`, error instanceof Error ? error.message : error);
1181
- }
1182
- }
1183
- return this.removeToolCallBlocks(responseText);
1184
- }
1185
- /**
1186
- * Resolve @Name mentions in LLM response text to <@userId> Discord format.
1187
- * LLMs generate plain text like "@LEAD", "@Conductor", "@DevBot" which won't
1188
- * trigger Discord mentions or routeResponseMentions detection.
1189
- */
1190
- resolveResponseMentions(text) {
1191
- if (!this.config.mention_delegation)
1192
- return text;
1193
- const botUserIdMap = this.multiBotManager.getBotUserIdMap();
1194
- const mainBotUserId = this.multiBotManager.getMainBotUserId();
1195
- const defaultAgentId = this.config.default_agent;
1196
- // Build pattern -> <@userId> lookup
1197
- const patterns = new Map();
1198
- for (const [agentId, agentConfig] of Object.entries(this.config.agents)) {
1199
- let userId = botUserIdMap.get(agentId);
1200
- if (!userId && agentId === defaultAgentId && mainBotUserId) {
1201
- userId = mainBotUserId;
1202
- }
1203
- if (!userId)
1204
- continue;
1205
- const mention = `<@${userId}>`;
1206
- if (agentConfig.name)
1207
- patterns.set(agentConfig.name.toLowerCase(), { mention, agentId });
1208
- if (agentConfig.display_name)
1209
- patterns.set(agentConfig.display_name.toLowerCase(), { mention, agentId });
1210
- patterns.set(agentId.toLowerCase(), { mention, agentId });
1211
- }
1212
- // Also match "LEAD" for the default agent
1213
- if (defaultAgentId && mainBotUserId) {
1214
- patterns.set('lead', { mention: `<@${mainBotUserId}>`, agentId: defaultAgentId });
1215
- }
1216
- let resolved = text;
1217
- for (const [pattern, { mention }] of patterns) {
1218
- // Match @pattern but NOT already-resolved <@pattern
1219
- const regex = new RegExp(`(?<!<)@${pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'gi');
1220
- resolved = resolved.replace(regex, mention);
1221
- }
1222
- return resolved;
1223
- }
1224
- getEffectiveMaxMentionDepth() {
1225
- return this.config.max_mention_depth ?? 3;
1226
- }
1227
- /**
1228
- * Find the reviewer agent entry from config
1229
- */
1230
- findReviewerAgent() {
1231
- return Object.entries(this.config.agents).find(([aid, cfg]) => aid.toLowerCase().includes('review') || cfg.name?.toLowerCase().includes('review'));
1232
- }
1233
- }
1234
- exports.MultiAgentDiscordHandler = MultiAgentDiscordHandler;
1235
- //# sourceMappingURL=multi-agent-discord.js.map