@jungjaehoon/mama-os 0.9.2 → 0.9.3

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 (78) hide show
  1. package/README.md +41 -7
  2. package/dist/api/graph-api.js +1 -1
  3. package/dist/api/graph-api.js.map +1 -1
  4. package/dist/cli/config/config-manager.d.ts.map +1 -1
  5. package/dist/cli/config/config-manager.js +60 -15
  6. package/dist/cli/config/config-manager.js.map +1 -1
  7. package/dist/cli/config/types.d.ts +16 -4
  8. package/dist/cli/config/types.d.ts.map +1 -1
  9. package/dist/cli/config/types.js.map +1 -1
  10. package/dist/gateways/slack.d.ts.map +1 -1
  11. package/dist/gateways/slack.js +0 -10
  12. package/dist/gateways/slack.js.map +1 -1
  13. package/dist/multi-agent/agent-process-manager.d.ts +3 -1
  14. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  15. package/dist/multi-agent/agent-process-manager.js +21 -12
  16. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  17. package/dist/multi-agent/background-task-manager.d.ts +2 -2
  18. package/dist/multi-agent/background-task-manager.js +2 -2
  19. package/dist/multi-agent/council-engine.d.ts +60 -0
  20. package/dist/multi-agent/council-engine.d.ts.map +1 -0
  21. package/dist/multi-agent/council-engine.js +284 -0
  22. package/dist/multi-agent/council-engine.js.map +1 -0
  23. package/dist/multi-agent/multi-agent-base.d.ts +17 -9
  24. package/dist/multi-agent/multi-agent-base.d.ts.map +1 -1
  25. package/dist/multi-agent/multi-agent-base.js +109 -30
  26. package/dist/multi-agent/multi-agent-base.js.map +1 -1
  27. package/dist/multi-agent/multi-agent-discord.d.ts +3 -35
  28. package/dist/multi-agent/multi-agent-discord.d.ts.map +1 -1
  29. package/dist/multi-agent/multi-agent-discord.js +57 -300
  30. package/dist/multi-agent/multi-agent-discord.js.map +1 -1
  31. package/dist/multi-agent/multi-agent-slack.d.ts +0 -25
  32. package/dist/multi-agent/multi-agent-slack.d.ts.map +1 -1
  33. package/dist/multi-agent/multi-agent-slack.js +95 -234
  34. package/dist/multi-agent/multi-agent-slack.js.map +1 -1
  35. package/dist/multi-agent/shared-context.d.ts.map +1 -1
  36. package/dist/multi-agent/shared-context.js +4 -4
  37. package/dist/multi-agent/shared-context.js.map +1 -1
  38. package/dist/multi-agent/system-reminder.d.ts +1 -1
  39. package/dist/multi-agent/system-reminder.js +1 -1
  40. package/dist/multi-agent/types.d.ts +11 -15
  41. package/dist/multi-agent/types.d.ts.map +1 -1
  42. package/dist/multi-agent/types.js +1 -3
  43. package/dist/multi-agent/types.js.map +1 -1
  44. package/dist/multi-agent/ultrawork-state.d.ts +57 -0
  45. package/dist/multi-agent/ultrawork-state.d.ts.map +1 -0
  46. package/dist/multi-agent/ultrawork-state.js +191 -0
  47. package/dist/multi-agent/ultrawork-state.js.map +1 -0
  48. package/dist/multi-agent/ultrawork.d.ts +37 -19
  49. package/dist/multi-agent/ultrawork.d.ts.map +1 -1
  50. package/dist/multi-agent/ultrawork.js +587 -41
  51. package/dist/multi-agent/ultrawork.js.map +1 -1
  52. package/dist/multi-agent/workflow-engine.d.ts.map +1 -1
  53. package/dist/multi-agent/workflow-engine.js +39 -14
  54. package/dist/multi-agent/workflow-engine.js.map +1 -1
  55. package/dist/multi-agent/workflow-types.d.ts +69 -0
  56. package/dist/multi-agent/workflow-types.d.ts.map +1 -1
  57. package/dist/onboarding/complete-autonomous-prompt.d.ts +1 -1
  58. package/dist/onboarding/complete-autonomous-prompt.d.ts.map +1 -1
  59. package/dist/onboarding/complete-autonomous-prompt.js +27 -10
  60. package/dist/onboarding/complete-autonomous-prompt.js.map +1 -1
  61. package/dist/onboarding/phase-7-integrations.d.ts.map +1 -1
  62. package/dist/onboarding/phase-7-integrations.js +23 -3
  63. package/dist/onboarding/phase-7-integrations.js.map +1 -1
  64. package/dist/onboarding/phase-9-finalization.d.ts.map +1 -1
  65. package/dist/onboarding/phase-9-finalization.js +33 -0
  66. package/dist/onboarding/phase-9-finalization.js.map +1 -1
  67. package/package.json +1 -1
  68. package/templates/personas/architect.md +70 -0
  69. package/templates/personas/conductor.md +302 -0
  70. package/templates/personas/developer.md +20 -7
  71. package/templates/personas/pm.md +49 -33
  72. package/templates/personas/reviewer.md +18 -5
  73. package/dist/multi-agent/pr-review-poller.d.ts +0 -197
  74. package/dist/multi-agent/pr-review-poller.d.ts.map +0 -1
  75. package/dist/multi-agent/pr-review-poller.js +0 -972
  76. package/dist/multi-agent/pr-review-poller.js.map +0 -1
  77. package/templates/personas/sisyphus-builtin-en.md +0 -161
  78. package/templates/personas/sisyphus.md +0 -218
@@ -45,7 +45,6 @@ const message_splitter_js_1 = require("../gateways/message-splitter.js");
45
45
  const delegation_format_validator_js_1 = require("./delegation-format-validator.js");
46
46
  const channel_history_js_1 = require("../gateways/channel-history.js");
47
47
  const prompt_enhancer_js_1 = require("../agent/prompt-enhancer.js");
48
- const pr_review_poller_js_1 = require("./pr-review-poller.js");
49
48
  const child_process_1 = require("child_process");
50
49
  const util_1 = require("util");
51
50
  const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
@@ -97,16 +96,8 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
97
96
  historyInjected = new Set();
98
97
  /** Cleanup interval handle for periodic tasks */
99
98
  cleanupInterval = null;
100
- /** PR poller summaries per channel for LEAD wake-up */
101
- prPollerSummaries = new Map();
102
- /** Tracks channels where APPROVE+commit was processed (prevents congratulation loops) */
103
- approveProcessedChannels = new Map();
104
- /** APPROVE cooldown period -- blocks agent-to-agent routing after commit (30 seconds) */
105
- static APPROVE_COOLDOWN_MS = 30 * 1000;
106
99
  /** Cleanup interval period (1 minute) */
107
100
  static CLEANUP_INTERVAL_MS = 60_000;
108
- /** PR review chain override (allows LEAD → DEV → REVIEWER → LEAD) */
109
- static PR_REVIEW_MAX_CHAIN = 6;
110
101
  constructor(config, processOptions = {}, runtimeOptions = {}) {
111
102
  super(config, processOptions, runtimeOptions);
112
103
  this.multiBotManager = new multi_bot_manager_js_1.MultiBotManager(config);
@@ -115,7 +106,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
115
106
  this.cleanupInterval = setInterval(() => {
116
107
  this.messageQueue.clearExpired();
117
108
  this.cleanupProcessedMentions();
118
- this.cleanupApproveChannels();
119
109
  }, MultiAgentDiscordHandler.CLEANUP_INTERVAL_MS);
120
110
  // Setup idle event listeners for all agents (F7)
121
111
  this.setupIdleListeners();
@@ -193,15 +183,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
193
183
  if (this.processedMentions.has(dedupKey))
194
184
  return;
195
185
  this.processedMentions.set(dedupKey, Date.now());
196
- // Block agent-to-LEAD mentions during post-APPROVE cooldown
197
- // Only blocks mentions targeting the default (LEAD) agent -- not other agents like DEV
198
- const approveCooldown = this.approveProcessedChannels.get(message.channel.id);
199
- if (message.author.bot &&
200
- approveCooldown &&
201
- Date.now() - approveCooldown < MultiAgentDiscordHandler.APPROVE_COOLDOWN_MS &&
202
- agentId === this.config.default_agent) {
203
- return;
204
- }
205
186
  const cleanContent = message.content.replace(/<@!?\d+>/g, '').trim();
206
187
  if (!cleanContent)
207
188
  return;
@@ -213,7 +194,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
213
194
  // Chain depth check for mention_delegation
214
195
  if (isFromAgent && senderAgentId && senderAgentId !== 'main') {
215
196
  const chainState = this.orchestrator.getChainState(message.channel.id);
216
- const maxDepth = this.getEffectiveMaxMentionDepth(message.channel.id);
197
+ const maxDepth = this.getEffectiveMaxMentionDepth();
217
198
  if (chainState.blocked) {
218
199
  logger.info(`[MultiAgent] Mention chain blocked in channel ${message.channel.id}, ignoring`);
219
200
  return;
@@ -300,7 +281,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
300
281
  if (this.config.mention_delegation) {
301
282
  const botUserIdMap = this.multiBotManager.getBotUserIdMap();
302
283
  // Include LEAD (default agent) which uses the main bot token
303
- // Without this, @Sisyphus in other agents' personas won't resolve to <@userId>
284
+ // Without this, @Conductor in other agents' personas won't resolve to <@userId>
304
285
  const defaultAgentId = this.config.default_agent;
305
286
  if (defaultAgentId && !botUserIdMap.has(defaultAgentId)) {
306
287
  const mainBotUserId = this.multiBotManager.getMainBotUserId();
@@ -311,16 +292,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
311
292
  this.processManager.setBotUserIdMap(botUserIdMap);
312
293
  this.processManager.setMentionDelegation(true);
313
294
  logger.info(`[MultiAgent] Mention delegation enabled with ${botUserIdMap.size} bot IDs`);
314
- if (this.isPrReviewPollingEnabled()) {
315
- // PR Review Poller: target LEAD directly.
316
- // LEAD analyzes → delegates to DevBot → DevBot fixes → Reviewer reviews after.
317
- const orchestratorId = defaultAgentId || 'sisyphus';
318
- const orchestratorUserId = botUserIdMap.get(orchestratorId);
319
- if (orchestratorUserId) {
320
- this.prReviewPoller.setTargetAgentUserId(orchestratorUserId);
321
- logger.info(`[MultiAgent] PR Poller target: ${orchestratorId} (LEAD)`);
322
- }
323
- }
324
295
  }
325
296
  }
326
297
  /**
@@ -354,109 +325,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
354
325
  }
355
326
  }
356
327
  }, 'discord');
357
- if (this.isPrReviewPollingEnabled()) {
358
- // Capture compact batch summaries so LEAD receives actionable context.
359
- this.prReviewPoller.setMessageSender(async () => { });
360
- this.prReviewPoller.setOnBatchItem(async (channelId, summary, item) => {
361
- const bucket = this.prPollerSummaries.get(channelId) ?? [];
362
- const compact = this.compactPrReviewBatchSummary(summary);
363
- if (!compact || bucket.some((candidate) => candidate.id === item.id)) {
364
- return;
365
- }
366
- const merged = {
367
- ...item,
368
- summary: compact,
369
- };
370
- // Keep bounded for prompt size and avoid repeats within one poll batch.
371
- this.prPollerSummaries.set(channelId, [...bucket, merged].slice(-12));
372
- });
373
- // After poll cycle: post count to channel and wake up PR workflow agents.
374
- this.prReviewPoller.setOnBatchComplete(async (channelId, digest) => {
375
- const items = (digest?.items && digest.items.length > 0
376
- ? digest.items
377
- : this.prPollerSummaries.get(channelId)) ?? [];
378
- if (items.length === 0) {
379
- return;
380
- }
381
- const actionItems = digest?.newItems ?? items.filter((item) => !item.isReminder);
382
- const reminderItems = digest?.reminderItems ?? items.filter((item) => item.isReminder);
383
- const allActionable = actionItems.length > 0;
384
- const count = items.length;
385
- if (!allActionable) {
386
- this.prPollerSummaries.delete(channelId);
387
- return;
388
- }
389
- const compactItems = items.map((item, idx) => `- ${idx + 1}. [${item.severity}] ${item.summary}`);
390
- const summaryLines = compactItems.join('\n');
391
- const sessions = this.prReviewPoller.getSessionDetails();
392
- const session = sessions.find((s) => s.channelId === channelId);
393
- if (!session) {
394
- // Clean up stale summary to prevent memory leak
395
- this.prPollerSummaries.delete(channelId);
396
- return;
397
- }
398
- const prLabel = `${session.owner}/${session.repo}#${session.prNumber}`;
399
- const promptSummary = `\n${summaryLines}`;
400
- const reminderSummary = reminderItems.length > 0 ? `\nšŸ”” Reminders only: ${reminderItems.length} item(s).` : '';
401
- this.prPollerSummaries.delete(channelId);
402
- // Post summary to channel (visible to humans)
403
- const channel = await client.channels.fetch(channelId);
404
- if (channel && 'send' in channel) {
405
- const content = `šŸ“Š PR ${prLabel} — ${count} new review item(s)\n\n${promptSummary}${reminderSummary}`;
406
- const chunks = (0, message_splitter_js_1.splitForDiscord)(content);
407
- for (const chunk of chunks) {
408
- await channel.send({
409
- content: chunk,
410
- });
411
- }
412
- }
413
- // Wake up LEAD with compact PR summary + workspace path.
414
- this.orchestrator.resetChain(channelId);
415
- const defaultAgentId = this.config.default_agent || 'sisyphus';
416
- const workspace = `\`${session.workspaceDir}\``;
417
- const workflowPrompt = `šŸ“Š PR Review follow-up (${count} new item(s))`;
418
- const taskContext = `Target: ${prLabel}\nWorkspace: ${workspace}\n`;
419
- const itemsContext = `Items:\n${summaryLines}`;
420
- const basePrompt = `${workflowPrompt}\n${taskContext}${itemsContext}${reminderSummary}`;
421
- this.messageQueue.enqueue(defaultAgentId, {
422
- prompt: `${basePrompt}\n\nClassify severity, implement fixable items, and coordinate with Dev/Reviewer.`,
423
- channelId,
424
- source: 'discord',
425
- enqueuedAt: Date.now(),
426
- context: { channelId, userId: 'pr-poller' },
427
- });
428
- logger.info(`[MultiAgent] PR Poller -> LEAD wake-up (${count} items)`);
429
- this.tryDrainNow(defaultAgentId, 'discord', channelId).catch(() => { });
430
- // Wake implementation/review agents in parallel so review loop can proceed autonomously.
431
- const helperAgents = this.resolvePrReviewAssistants(defaultAgentId);
432
- for (const helperAgentId of helperAgents) {
433
- const helperPrompt = helperAgentId === 'developer'
434
- ? `${basePrompt}\n\nImplement available fixes in the workspace and request Reviewer verification when changes are made.`
435
- : `${basePrompt}\n\nInspect the comments for correctness issues and provide reviewer guidance.`;
436
- this.messageQueue.enqueue(helperAgentId, {
437
- prompt: helperPrompt,
438
- channelId,
439
- source: 'discord',
440
- enqueuedAt: Date.now(),
441
- context: { channelId, userId: 'pr-poller' },
442
- });
443
- logger.info(`[MultiAgent] PR Poller -> ${helperAgentId} wake-up (${count} items)`);
444
- this.tryDrainNow(helperAgentId, 'discord', channelId).catch(() => { });
445
- }
446
- });
447
- logger.info('[MultiAgent] PR Review Poller message sender configured for Discord');
448
- }
449
- }
450
- /**
451
- * Keep PR poller summaries short and remove duplicates.
452
- */
453
- compactPrReviewBatchSummary(summary) {
454
- const compact = summary.replace(/[\r\n]+/g, ' ').trim();
455
- const max = 230;
456
- if (!compact) {
457
- return '';
458
- }
459
- return compact.length > max ? `${compact.slice(0, max)}…` : compact;
460
328
  }
461
329
  /**
462
330
  * Set main bot token (to avoid duplicate logins in MultiBotManager)
@@ -472,10 +340,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
472
340
  this.orchestrator.updateConfig(config);
473
341
  this.processManager.updateConfig(config);
474
342
  this.multiBotManager.updateConfig(config);
475
- if (!this.isPrReviewPollingEnabled()) {
476
- this.prReviewPoller.stopAll();
477
- this.prPollerSummaries.clear();
478
- }
479
343
  }
480
344
  /**
481
345
  * Handle a Discord message with multi-agent logic
@@ -490,14 +354,9 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
490
354
  }
491
355
  // Build message context
492
356
  const context = this.buildMessageContext(message, cleanContent);
493
- this.updateChainOverrideForChannel(context.channelId);
494
357
  // Record human message to shared context
495
358
  if (!context.isBot) {
496
359
  this.sharedContext.recordHumanMessage(context.channelId, message.author.username, cleanContent, message.id);
497
- if (this.isPrReviewPollingEnabled()) {
498
- // Auto-detect PR URLs in user messages and start polling
499
- this.detectAndPollPRUrls(cleanContent, context.channelId, message);
500
- }
501
360
  }
502
361
  // Select responding agents
503
362
  const selection = this.orchestrator.selectRespondingAgents(context);
@@ -532,10 +391,6 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
532
391
  if (responses.length === 0) {
533
392
  return null;
534
393
  }
535
- // Auto-detect PR URLs in agent responses and start polling
536
- for (const resp of responses) {
537
- this.detectAndPollPRUrls(resp.rawContent, context.channelId, message);
538
- }
539
394
  return {
540
395
  selectedAgents: selection.selectedAgents,
541
396
  reason: selection.reason,
@@ -808,15 +663,21 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
808
663
  }
809
664
  let msg = '';
810
665
  const modelTag = event.agentModel ? ` [${event.agentModel}]` : '';
666
+ const progress = event.totalSteps && event.completedSteps !== undefined
667
+ ? ` [${event.completedSteps}/${event.totalSteps}]`
668
+ : '';
811
669
  if (event.type === 'step-started') {
812
- msg = ` ${event.agentDisplayName}${modelTag} ģ‹œģž‘...`;
670
+ msg = ` ${event.agentDisplayName}${modelTag}${progress} ģ‹œģž‘...`;
813
671
  }
814
672
  else if (event.type === 'step-completed') {
815
673
  const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
816
- msg = `${event.agentDisplayName}${modelTag} (${sec}s) ģ™„ė£Œ`;
674
+ const pct = event.totalSteps && event.completedSteps !== undefined
675
+ ? ` (${Math.round((event.completedSteps / event.totalSteps) * 100)}%)`
676
+ : '';
677
+ msg = `${event.agentDisplayName}${modelTag} (${sec}s)${pct} ģ™„ė£Œ`;
817
678
  }
818
679
  else if (event.type === 'step-failed') {
819
- msg = `${event.agentDisplayName}${modelTag} āŒ ģ‹¤ķŒØ: ${event.error?.substring(0, 100)}`;
680
+ msg = `${event.agentDisplayName}${modelTag}${progress} āŒ ģ‹¤ķŒØ: ${event.error?.substring(0, 100)}`;
820
681
  }
821
682
  if (msg) {
822
683
  this.sendChannelNotification(context.channelId, msg).catch(() => { });
@@ -836,6 +697,38 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
836
697
  duration: totalDuration,
837
698
  };
838
699
  }
700
+ // Check for council plan (after workflow, before tool calls)
701
+ const councilResult = await this.tryExecuteCouncil(result.response, context.channelId, 'discord', (event) => {
702
+ if (!this.discordClient)
703
+ return;
704
+ let msg = '';
705
+ if (event.type === 'council-round-started') {
706
+ msg = `šŸ—£ļø ${event.agentDisplayName} Round ${event.round} ģ‹œģž‘...`;
707
+ }
708
+ else if (event.type === 'council-round-completed') {
709
+ const sec = event.duration_ms ? Math.round(event.duration_ms / 1000) : 0;
710
+ msg = `šŸ—£ļø ${event.agentDisplayName} Round ${event.round} (${sec}s) ģ™„ė£Œ`;
711
+ }
712
+ else if (event.type === 'council-round-failed') {
713
+ msg = `šŸ—£ļø ${event.agentDisplayName} Round ${event.round} āŒ ģ‹¤ķŒØ: ${event.error?.substring(0, 100)}`;
714
+ }
715
+ if (msg) {
716
+ this.sendChannelNotification(context.channelId, msg).catch(() => { });
717
+ }
718
+ });
719
+ if (councilResult) {
720
+ const display = councilResult.directMessage
721
+ ? `${councilResult.directMessage}\n\n${councilResult.result}`
722
+ : councilResult.result;
723
+ const formattedResponse = this.formatAgentResponse(agent, display);
724
+ return {
725
+ agentId,
726
+ agent,
727
+ content: formattedResponse,
728
+ rawContent: display,
729
+ duration: Date.now() - workflowStart + (result.duration_ms ?? 0),
730
+ };
731
+ }
839
732
  const cleanedResponse = await this.executeAgentToolCalls(agentId, result.response);
840
733
  // Detect API error responses — skip mention resolution and delegation to prevent error loops
841
734
  const isErrorResponse = /API Error:\s*\d{3}\b/.test(cleanedResponse);
@@ -849,8 +742,9 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
849
742
  let submittedCount = 0;
850
743
  const submittedAgents = [];
851
744
  for (const delegation of bgDelegations) {
852
- if (!delegation.background)
745
+ if (!delegation.background) {
853
746
  continue;
747
+ }
854
748
  const check = this.delegationManager.isDelegationAllowed(delegation.fromAgentId, delegation.toAgentId);
855
749
  if (check.allowed) {
856
750
  this.backgroundTaskManager.submit({
@@ -975,8 +869,9 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
975
869
  if (delegations.length > 0 && hasBackground) {
976
870
  let submittedCount = 0;
977
871
  for (const delegation of delegations) {
978
- if (!delegation.background)
872
+ if (!delegation.background) {
979
873
  continue;
874
+ }
980
875
  const check = this.delegationManager.isDelegationAllowed(delegation.fromAgentId, delegation.toAgentId);
981
876
  if (check.allowed) {
982
877
  this.backgroundTaskManager.submit({
@@ -1119,7 +1014,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1119
1014
  console.error(`[MultiAgent] Failed to send response for agent ${response.agentId}:`, err);
1120
1015
  }
1121
1016
  }
1122
- // Post-send: Auto-review trigger for default agent (Armed Sisyphus) self-implementations
1017
+ // Post-send: Auto-review trigger for default agent (Armed Conductor) self-implementations
1123
1018
  const defaultAgentId = this.config.default_agent;
1124
1019
  if (defaultAgentId) {
1125
1020
  const selfImplemented = responses.find((r) => r.agentId === defaultAgentId && this.detectSelfImplementation(r.rawContent));
@@ -1130,7 +1025,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1130
1025
  return sentMessages;
1131
1026
  }
1132
1027
  /**
1133
- * Detect if the default agent (Sisyphus) performed direct code edits.
1028
+ * Detect if the default agent (Conductor) performed direct code edits.
1134
1029
  * Checks for Claude CLI tool-use markers that indicate Edit/Write operations.
1135
1030
  */
1136
1031
  detectSelfImplementation(rawContent) {
@@ -1149,7 +1044,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1149
1044
  return editIndicators.some((pattern) => pattern.test(rawContent));
1150
1045
  }
1151
1046
  /**
1152
- * Check git diff size after Sisyphus self-implementation.
1047
+ * Check git diff size after Conductor self-implementation.
1153
1048
  * If diff exceeds thresholds, auto-trigger Reviewer for quality gate.
1154
1049
  *
1155
1050
  * Thresholds (PAIR mode auto-escalation):
@@ -1189,7 +1084,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1189
1084
  }
1190
1085
  }
1191
1086
  if (filesChanged > MAX_FILES || totalLines > MAX_LINES) {
1192
- logger.info(`[AutoReview] Sisyphus self-implementation exceeded thresholds: ${filesChanged} files, ${totalLines} lines -> auto-triggering Reviewer`);
1087
+ logger.info(`[AutoReview] Conductor self-implementation exceeded thresholds: ${filesChanged} files, ${totalLines} lines -> auto-triggering Reviewer`);
1193
1088
  // Find reviewer agent using shared helper
1194
1089
  const reviewerEntry = this.findReviewerAgent();
1195
1090
  const reviewerAgentId = reviewerEntry?.[0];
@@ -1199,7 +1094,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1199
1094
  }
1200
1095
  }
1201
1096
  else {
1202
- logger.info(`[AutoReview] Sisyphus self-implementation within thresholds: ${filesChanged} files, ${totalLines} lines -- no auto-review needed`);
1097
+ logger.info(`[AutoReview] Conductor self-implementation within thresholds: ${filesChanged} files, ${totalLines} lines -- no auto-review needed`);
1203
1098
  }
1204
1099
  }
1205
1100
  catch {
@@ -1256,33 +1151,14 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1256
1151
  }
1257
1152
  }
1258
1153
  logger.info(`[MultiAgent] Auto-routing mentions from ${response.agentId}: -> ${mentionedAgentIds.join(', ')}`);
1259
- const defaultAgentId = this.config.default_agent;
1260
- const hasApproveSignal = /\b(APPROVE[DS]?|LGTM)\b/i.test(response.rawContent) &&
1261
- !/\b(not?\s+approve|don'?t\s+approve|cannot\s+approve|rejected)\b/i.test(response.rawContent);
1262
- const isReviewerApproveToLead = this.isReviewerAgent(response.agentId) &&
1263
- mentionedAgentIds.includes(defaultAgentId || '') &&
1264
- hasApproveSignal;
1265
- if (isReviewerApproveToLead) {
1266
- // Dedup: skip if APPROVE already processed for this channel
1267
- const lastApprove = this.approveProcessedChannels.get(originalMessage.channel.id);
1268
- if (lastApprove &&
1269
- Date.now() - lastApprove < MultiAgentDiscordHandler.APPROVE_COOLDOWN_MS) {
1270
- logger.info(`[MultiAgent] APPROVE already processed for ${originalMessage.channel.id}, skipping`);
1271
- continue;
1272
- }
1273
- }
1274
1154
  // Route to all mentioned agents in parallel
1275
- await Promise.all(mentionedAgentIds.map((targetAgentId) => this.handleDelegatedMention(targetAgentId, originalMessage, response, isReviewerApproveToLead ? 'REVIEWER_APPROVED' : null)));
1276
- // Set APPROVE cooldown AFTER routing to LEAD (so LEAD gets the first one)
1277
- if (isReviewerApproveToLead) {
1278
- this.approveProcessedChannels.set(originalMessage.channel.id, Date.now());
1279
- }
1155
+ await Promise.all(mentionedAgentIds.map((targetAgentId) => this.handleDelegatedMention(targetAgentId, originalMessage, response)));
1280
1156
  }
1281
1157
  }
1282
1158
  /**
1283
1159
  * Handle a delegated mention: process target agent response and recursively route.
1284
1160
  */
1285
- async handleDelegatedMention(targetAgentId, originalMessage, sourceResponse, reviewerSignal) {
1161
+ async handleDelegatedMention(targetAgentId, originalMessage, sourceResponse) {
1286
1162
  // Dedup: prevent double processing
1287
1163
  const dedupKey = `${targetAgentId}:${sourceResponse.messageId || originalMessage.id}`;
1288
1164
  if (this.processedMentions.has(dedupKey))
@@ -1333,16 +1209,10 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1333
1209
  channelId,
1334
1210
  timestamp: Date.now(),
1335
1211
  });
1336
- let delegationContent = sourceResponse.rawContent
1212
+ const delegationContent = sourceResponse.rawContent
1337
1213
  .replace(/<@!?\d+>/g, '')
1338
1214
  .replace(/DELEGATE(?:_BG)?::[\w-]+::/g, '')
1339
1215
  .trim();
1340
- if (reviewerSignal === 'REVIEWER_APPROVED' && targetAgentId === this.config.default_agent) {
1341
- delegationContent +=
1342
- '\n\nšŸ”” [SYSTEM] Reviewer has APPROVED the changes.\n' +
1343
- 'Review the changes yourself, then commit and push when you are satisfied.\n' +
1344
- 'Use your judgement on the commit message and which files to include.';
1345
- }
1346
1216
  try {
1347
1217
  const response = await this.processAgentResponse(targetAgentId, {
1348
1218
  channelId,
@@ -1455,7 +1325,7 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1455
1325
  }
1456
1326
  /**
1457
1327
  * Resolve @Name mentions in LLM response text to <@userId> Discord format.
1458
- * LLMs generate plain text like "@LEAD", "@Sisyphus", "@DevBot" which won't
1328
+ * LLMs generate plain text like "@LEAD", "@Conductor", "@DevBot" which won't
1459
1329
  * trigger Discord mentions or routeResponseMentions detection.
1460
1330
  */
1461
1331
  resolveResponseMentions(text) {
@@ -1503,122 +1373,9 @@ class MultiAgentDiscordHandler extends multi_agent_base_js_1.MultiAgentHandlerBa
1503
1373
  }
1504
1374
  return resolved;
1505
1375
  }
1506
- cleanupApproveChannels() {
1507
- const now = Date.now();
1508
- for (const [channelId, ts] of this.approveProcessedChannels) {
1509
- if (now - ts > MultiAgentDiscordHandler.APPROVE_COOLDOWN_MS) {
1510
- this.approveProcessedChannels.delete(channelId);
1511
- }
1512
- }
1513
- }
1514
- /**
1515
- * Detect PR URLs in text and auto-start polling.
1516
- * Sends a notification to the channel when polling starts.
1517
- */
1518
- detectAndPollPRUrls(text, channelId, message) {
1519
- if (!this.isPrReviewPollingEnabled())
1520
- return;
1521
- const prUrls = pr_review_poller_js_1.PRReviewPoller.extractPRUrls(text);
1522
- if (prUrls.length === 0)
1523
- return;
1524
- for (const prUrl of prUrls) {
1525
- this.prReviewPoller
1526
- .startPolling(prUrl, channelId)
1527
- .then((started) => {
1528
- const parsed = this.prReviewPoller.parsePRUrl(prUrl);
1529
- const key = parsed ? `${parsed.owner}/${parsed.repo}#${parsed.prNumber}` : prUrl;
1530
- if (started) {
1531
- this.updateChainOverrideForChannel(channelId);
1532
- if ('send' in message.channel) {
1533
- message.channel
1534
- .send({
1535
- content: `šŸ‘€ **PR Review Poller Started** -- ${key}\nDetecting new review comments every 60 seconds.`,
1536
- })
1537
- .catch((err) => {
1538
- console.warn(`[MultiAgent] Failed to send PR polling start message to Discord channel ${channelId}:`, err?.message || err);
1539
- });
1540
- }
1541
- logger.info(`[MultiAgent] PR Poller started for ${key} in Discord channel ${channelId}`);
1542
- }
1543
- else {
1544
- if ('send' in message.channel) {
1545
- message.channel
1546
- .send({
1547
- content: `ā„¹ļø PR Review Poller is already active for ${key}.`,
1548
- })
1549
- .catch((err) => {
1550
- console.warn(`[MultiAgent] Failed to send PR polling already-running message to Discord channel ${channelId}:`, err?.message || err);
1551
- });
1552
- }
1553
- }
1554
- })
1555
- .catch((err) => {
1556
- console.error(`[MultiAgent] Failed to start PR polling:`, err);
1557
- if ('send' in message.channel) {
1558
- message.channel
1559
- .send({
1560
- content: `āš ļø Failed to start PR Review Poller for ${prUrl}: ${String(err)}`,
1561
- })
1562
- .catch((sendErr) => {
1563
- console.warn(`[MultiAgent] Failed to send PR polling error message to Discord channel ${channelId}:`, sendErr?.message || sendErr);
1564
- });
1565
- }
1566
- });
1567
- }
1568
- }
1569
- /**
1570
- * Resolve helper agents for PR review workflow in addition to default lead.
1571
- */
1572
- resolvePrReviewAssistants(defaultAgentId) {
1573
- const candidateIds = ['developer', 'reviewer', 'dev', 'lead'];
1574
- const helperAgents = [];
1575
- for (const id of candidateIds) {
1576
- const cfg = this.config.agents[id];
1577
- if (!cfg || id === defaultAgentId) {
1578
- continue;
1579
- }
1580
- if (cfg.enabled === false) {
1581
- continue;
1582
- }
1583
- helperAgents.push(id);
1584
- }
1585
- return [...new Set(helperAgents)];
1586
- }
1587
- /**
1588
- * Update chain/mention depth overrides when PR review polling is active.
1589
- */
1590
- updateChainOverrideForChannel(channelId) {
1591
- if (this.isPrReviewActive(channelId)) {
1592
- this.orchestrator.setChannelChainLimit(channelId, MultiAgentDiscordHandler.PR_REVIEW_MAX_CHAIN);
1593
- }
1594
- else {
1595
- this.orchestrator.clearChannelChainLimit(channelId);
1596
- }
1597
- }
1598
- getEffectiveMaxMentionDepth(channelId) {
1599
- if (this.isPrReviewActive(channelId)) {
1600
- return MultiAgentDiscordHandler.PR_REVIEW_MAX_CHAIN;
1601
- }
1376
+ getEffectiveMaxMentionDepth() {
1602
1377
  return this.config.max_mention_depth ?? 3;
1603
1378
  }
1604
- isPrReviewActive(channelId) {
1605
- if (!this.isPrReviewPollingEnabled()) {
1606
- return false;
1607
- }
1608
- return this.prReviewPoller
1609
- .getSessionDetails()
1610
- .some((session) => session.channelId === channelId);
1611
- }
1612
- isPrReviewPollingEnabled() {
1613
- return this.config.pr_review_poller?.enabled === true;
1614
- }
1615
- /**
1616
- * Check if an agent ID is the reviewer agent
1617
- */
1618
- isReviewerAgent(agentId) {
1619
- return (agentId.toLowerCase().includes('review') ||
1620
- this.config.agents[agentId]?.name?.toLowerCase().includes('review') === true);
1621
- }
1622
1379
  /**
1623
1380
  * Find the reviewer agent entry from config
1624
1381
  */