refactor: use resolveActiveRole() as SSOT for all status→role mapping

Eliminated duplicate task status checks in message-agent-executor.ts
and message-runtime.ts. All status→role decisions now flow through
the single resolveActiveRole() function.
This commit is contained in:
Eyejoker
2026-03-30 23:03:00 +09:00
parent d3df67e08c
commit 5562e30ce1
2 changed files with 14 additions and 21 deletions

View File

@@ -23,6 +23,7 @@ import {
completePairedExecutionContext, completePairedExecutionContext,
preparePairedExecutionContext, preparePairedExecutionContext,
} from './paired-execution-context.js'; } from './paired-execution-context.js';
import { resolveActiveRole } from './message-runtime-rules.js';
import { buildRoomRoleContext } from './room-role-context.js'; import { buildRoomRoleContext } from './room-role-context.js';
import { import {
classifyRotationTrigger, classifyRotationTrigger,
@@ -95,16 +96,15 @@ export async function runAgentForGroup(
const pairedTask = currentLease.reviewer_service_id const pairedTask = currentLease.reviewer_service_id
? getLatestOpenPairedTaskForChat(chatJid) ? getLatestOpenPairedTaskForChat(chatJid)
: null; : null;
const activeRole = resolveActiveRole(pairedTask?.status);
const effectiveServiceId = const effectiveServiceId =
pairedTask && activeRole === 'arbiter'
(pairedTask.status === 'arbiter_requested' || pairedTask.status === 'in_arbitration')
? currentLease.arbiter_service_id! ? currentLease.arbiter_service_id!
: pairedTask && : activeRole === 'reviewer'
(pairedTask.status === 'review_ready' || pairedTask.status === 'in_review')
? currentLease.reviewer_service_id! ? currentLease.reviewer_service_id!
: currentLease.owner_service_id; : currentLease.owner_service_id;
const reviewerMode = effectiveServiceId === currentLease.reviewer_service_id; const reviewerMode = activeRole === 'reviewer';
const arbiterMode = effectiveServiceId === currentLease.arbiter_service_id; const arbiterMode = activeRole === 'arbiter';
// Override agent type based on role config (OWNER_AGENT_TYPE / REVIEWER_AGENT_TYPE). // 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, // When the reviewer uses a different agent type than the group default,
@@ -112,7 +112,9 @@ export async function runAgentForGroup(
const reviewerAgentTypeOverride = const reviewerAgentTypeOverride =
reviewerMode && REVIEWER_AGENT_TYPE !== (group.agentType || 'claude-code'); reviewerMode && REVIEWER_AGENT_TYPE !== (group.agentType || 'claude-code');
const arbiterAgentTypeOverride = 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 const effectiveAgentType = arbiterAgentTypeOverride
? ARBITER_AGENT_TYPE! ? ARBITER_AGENT_TYPE!
: reviewerAgentTypeOverride : reviewerAgentTypeOverride

View File

@@ -602,11 +602,8 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
const pendingReviewTask = isPairedRoomJid(chatJid) const pendingReviewTask = isPairedRoomJid(chatJid)
? getLatestOpenPairedTaskForChat(chatJid) ? getLatestOpenPairedTaskForChat(chatJid)
: null; : null;
if ( const pendingRole = resolveActiveRole(pendingReviewTask?.status);
pendingReviewTask && if (pendingReviewTask && pendingRole === 'reviewer') {
(pendingReviewTask.status === 'review_ready' ||
pendingReviewTask.status === 'in_review')
) {
// No processable messages remain. Review workspace state using the // No processable messages remain. Review workspace state using the
// user's request as context, but don't re-inject filtered raw bot // user's request as context, but don't re-inject filtered raw bot
// output from older turns into the next review prompt. // output from older turns into the next review prompt.
@@ -646,12 +643,7 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
return deliverySucceeded; return deliverySucceeded;
} }
// arbiter_requested / in_arbitration: run arbiter turn if (pendingReviewTask && pendingRole === 'arbiter') {
if (
pendingReviewTask &&
(pendingReviewTask.status === 'arbiter_requested' ||
pendingReviewTask.status === 'in_arbitration')
) {
const lastRaw = rawMissedMessages[rawMissedMessages.length - 1]; const lastRaw = rawMissedMessages[rawMissedMessages.length - 1];
const cursor = lastRaw?.seq ?? lastRaw?.timestamp; const cursor = lastRaw?.seq ?? lastRaw?.timestamp;
if (cursor != null) { if (cursor != null) {
@@ -826,10 +818,9 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
const cursorKey = resolveCursorKey(chatJid, taskStatus); const cursorKey = resolveCursorKey(chatJid, taskStatus);
// Arbiter turns use a dedicated context prompt; regular turns use formatted messages. // Arbiter turns use a dedicated context prompt; regular turns use formatted messages.
const isArbiterTurn = const turnRole = resolveActiveRole(taskStatus);
taskStatus === 'arbiter_requested' || taskStatus === 'in_arbitration';
let prompt: string; let prompt: string;
if (isArbiterTurn && pendingTaskForChannel) { if (turnRole === 'arbiter' && pendingTaskForChannel) {
const arbiterMsgs = labelPairedSenders( const arbiterMsgs = labelPairedSenders(
chatJid, chatJid,
getRecentChatMessages(chatJid, 20), getRecentChatMessages(chatJid, 20),