fix: correct channelId extraction and dormant check in hooks

message-received.ts:
- message_received ctx has channelId/accountId/conversationId (not
  sessionKey). Add extraction from ctx.channelId and metadata.to
  ("channel:ID" format) before the conversation_info fallback.

agent-end.ts:
- When tail-match is interrupted, only call wakeFromDormant() if the
  channel is actually dormant. For non-dormant interrupts (e.g. the
  moderator bot's own trigger messages firing message_received on
  other agents), fall through to normal advanceSpeaker() so the turn
  cycle continues correctly instead of re-triggering the same speaker.
- Import isDormant from turn-manager.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
h z
2026-04-09 06:24:05 +01:00
parent b9cbb7e895
commit 74e6d61d4d
2 changed files with 28 additions and 7 deletions

View File

@@ -7,6 +7,7 @@ import {
getAnchor,
advanceSpeaker,
wakeFromDormant,
isDormant,
hasSpeakers,
getDebugInfo,
isTurnPending,
@@ -175,10 +176,16 @@ export function registerAgentEndHook(deps: AgentEndDeps): InterruptFn {
});
if (interrupted) {
api.logger.info(`dirigent: tail-match interrupted channel=${channelId} — wake-from-dormant`);
const first = wakeFromDormant(channelId);
if (first) await triggerNextSpeaker(channelId, first);
return;
if (isDormant(channelId)) {
// Channel is dormant: a new external message woke it — restart from first speaker
api.logger.info(`dirigent: tail-match interrupted (dormant) channel=${channelId} — waking`);
const first = wakeFromDormant(channelId);
if (first) await triggerNextSpeaker(channelId, first);
return;
}
// Not dormant: interrupt was a spurious trigger (e.g. moderator bot message).
// Fall through to normal advance so the turn cycle continues correctly.
api.logger.info(`dirigent: tail-match interrupted (non-dormant) channel=${channelId} — advancing normally`);
}
if (!matched) {
api.logger.warn(`dirigent: tail-match timeout channel=${channelId} agentId=${agentId} — advancing anyway`);