diff --git a/src/message-agent-executor.ts b/src/message-agent-executor.ts index 4604a19..856a9a5 100644 --- a/src/message-agent-executor.ts +++ b/src/message-agent-executor.ts @@ -23,6 +23,7 @@ import { completePairedExecutionContext, preparePairedExecutionContext, } from './paired-execution-context.js'; +import { resolveActiveRole } from './message-runtime-rules.js'; import { buildRoomRoleContext } from './room-role-context.js'; import { classifyRotationTrigger, @@ -95,16 +96,15 @@ export async function runAgentForGroup( const pairedTask = currentLease.reviewer_service_id ? getLatestOpenPairedTaskForChat(chatJid) : null; + const activeRole = resolveActiveRole(pairedTask?.status); const effectiveServiceId = - pairedTask && - (pairedTask.status === 'arbiter_requested' || pairedTask.status === 'in_arbitration') + activeRole === 'arbiter' ? currentLease.arbiter_service_id! - : pairedTask && - (pairedTask.status === 'review_ready' || pairedTask.status === 'in_review') + : activeRole === 'reviewer' ? currentLease.reviewer_service_id! : currentLease.owner_service_id; - const reviewerMode = effectiveServiceId === currentLease.reviewer_service_id; - const arbiterMode = effectiveServiceId === currentLease.arbiter_service_id; + const reviewerMode = activeRole === 'reviewer'; + const arbiterMode = activeRole === 'arbiter'; // Override agent type based on role config (OWNER_AGENT_TYPE / REVIEWER_AGENT_TYPE). // When the reviewer uses a different agent type than the group default, @@ -112,7 +112,9 @@ export async function runAgentForGroup( const reviewerAgentTypeOverride = reviewerMode && REVIEWER_AGENT_TYPE !== (group.agentType || 'claude-code'); const arbiterAgentTypeOverride = - arbiterMode && ARBITER_AGENT_TYPE != null && ARBITER_AGENT_TYPE !== (group.agentType || 'claude-code'); + arbiterMode && + ARBITER_AGENT_TYPE != null && + ARBITER_AGENT_TYPE !== (group.agentType || 'claude-code'); const effectiveAgentType = arbiterAgentTypeOverride ? ARBITER_AGENT_TYPE! : reviewerAgentTypeOverride diff --git a/src/message-runtime.ts b/src/message-runtime.ts index 8764689..8ee1a16 100644 --- a/src/message-runtime.ts +++ b/src/message-runtime.ts @@ -602,11 +602,8 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): { const pendingReviewTask = isPairedRoomJid(chatJid) ? getLatestOpenPairedTaskForChat(chatJid) : null; - if ( - pendingReviewTask && - (pendingReviewTask.status === 'review_ready' || - pendingReviewTask.status === 'in_review') - ) { + const pendingRole = resolveActiveRole(pendingReviewTask?.status); + if (pendingReviewTask && pendingRole === 'reviewer') { // No processable messages remain. Review workspace state using the // user's request as context, but don't re-inject filtered raw bot // output from older turns into the next review prompt. @@ -646,12 +643,7 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): { return deliverySucceeded; } - // arbiter_requested / in_arbitration: run arbiter turn - if ( - pendingReviewTask && - (pendingReviewTask.status === 'arbiter_requested' || - pendingReviewTask.status === 'in_arbitration') - ) { + if (pendingReviewTask && pendingRole === 'arbiter') { const lastRaw = rawMissedMessages[rawMissedMessages.length - 1]; const cursor = lastRaw?.seq ?? lastRaw?.timestamp; if (cursor != null) { @@ -826,10 +818,9 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): { const cursorKey = resolveCursorKey(chatJid, taskStatus); // Arbiter turns use a dedicated context prompt; regular turns use formatted messages. - const isArbiterTurn = - taskStatus === 'arbiter_requested' || taskStatus === 'in_arbitration'; + const turnRole = resolveActiveRole(taskStatus); let prompt: string; - if (isArbiterTurn && pendingTaskForChannel) { + if (turnRole === 'arbiter' && pendingTaskForChannel) { const arbiterMsgs = labelPairedSenders( chatJid, getRecentChatMessages(chatJid, 20),