Extract message runtime role channel resolution

This commit is contained in:
ejclaw
2026-04-29 11:03:16 +09:00
parent fab7e2b9d2
commit e4d30f527d
3 changed files with 100 additions and 21 deletions

View File

@@ -0,0 +1,56 @@
import { describe, expect, it, vi } from 'vitest';
import { resolvePairedRoleChannels } from './message-runtime-role-channels.js';
import type { Channel } from './types.js';
function makeChannel(name: string): Channel {
return {
name,
connect: vi.fn(),
sendMessage: vi.fn(),
isConnected: vi.fn(() => true),
ownsJid: vi.fn(() => false),
disconnect: vi.fn(),
} as unknown as Channel;
}
describe('message-runtime-role-channels', () => {
it('maps owner, reviewer, and arbiter roles to their runtime channels', () => {
const ownerChannel = makeChannel('discord-owner');
const reviewerChannel = makeChannel('discord-review');
const arbiterChannel = makeChannel('discord-arbiter');
const result = resolvePairedRoleChannels(
[ownerChannel, reviewerChannel, arbiterChannel],
ownerChannel,
);
expect(result).toEqual({
roleToChannel: {
owner: ownerChannel,
reviewer: reviewerChannel,
arbiter: arbiterChannel,
},
reviewerChannelName: 'discord-review',
foundReviewerChannel: reviewerChannel,
arbiterChannelName: 'discord-arbiter',
foundArbiterChannel: arbiterChannel,
});
});
it('keeps missing reviewer and arbiter channels explicit as null', () => {
const ownerChannel = makeChannel('discord-owner');
expect(resolvePairedRoleChannels([ownerChannel], ownerChannel)).toEqual({
roleToChannel: {
owner: ownerChannel,
reviewer: null,
arbiter: null,
},
reviewerChannelName: 'discord-review',
foundReviewerChannel: null,
arbiterChannelName: 'discord-arbiter',
foundArbiterChannel: null,
});
});
});

View File

@@ -0,0 +1,37 @@
import { findChannelByName } from './router.js';
import type { Channel, PairedRoomRole } from './types.js';
export type PairedRoleChannels = Record<PairedRoomRole, Channel | null>;
export interface PairedRoleChannelResolution {
roleToChannel: PairedRoleChannels;
reviewerChannelName: string;
foundReviewerChannel: Channel | null;
arbiterChannelName: string;
foundArbiterChannel: Channel | null;
}
export function resolvePairedRoleChannels(
channels: Channel[],
ownerChannel: Channel,
): PairedRoleChannelResolution {
const reviewerChannelName = 'discord-review';
const foundReviewerChannel =
findChannelByName(channels, reviewerChannelName) ?? null;
const arbiterChannelName = 'discord-arbiter';
const foundArbiterChannel =
findChannelByName(channels, arbiterChannelName) ?? null;
return {
roleToChannel: {
owner: ownerChannel,
reviewer: foundReviewerChannel,
arbiter: foundArbiterChannel,
},
reviewerChannelName,
foundReviewerChannel,
arbiterChannelName,
foundArbiterChannel,
};
}

View File

@@ -13,7 +13,7 @@ import {
SERVICE_SESSION_SCOPE,
} from './config.js';
import { GroupQueue, GroupRunContext } from './group-queue.js';
import { findChannel, findChannelByName, formatMessages } from './router.js';
import { findChannel, formatMessages } from './router.js';
import { isTriggerAllowed, loadSenderAllowlist } from './sender-allowlist.js';
import { enqueueGenericFollowUpAfterDeliveryRetry as enqueueDeliveryRetryFollowUp } from './message-runtime-dispatch.js';
import {
@@ -73,6 +73,7 @@ import {
isDuplicateOfLastBotFinal,
labelPairedSenders,
} from './message-runtime-turns.js';
import { resolvePairedRoleChannels } from './message-runtime-role-channels.js';
export { isDuplicateOfLastBotFinal };
@@ -381,28 +382,13 @@ export function createMessageRuntime(deps: MessageRuntimeDeps): {
return true;
}
// For paired rooms, reviewer/arbiter outputs use their fixed role bots.
const reviewerChannelName = 'discord-review';
const foundReviewerChannel = findChannelByName(
deps.channels,
const {
roleToChannel,
reviewerChannelName,
);
const arbiterChannelName = 'discord-arbiter';
const foundArbiterChannel = findChannelByName(
deps.channels,
foundReviewerChannel,
arbiterChannelName,
);
// Resolve the correct Discord channel for a given task status.
const roleToChannel: Record<
'owner' | 'reviewer' | 'arbiter',
Channel | null
> = {
owner: channel,
reviewer: foundReviewerChannel || null,
arbiter: foundArbiterChannel || null,
};
foundArbiterChannel,
} = resolvePairedRoleChannels(deps.channels, channel);
if (hasReviewerLease(chatJid)) {
log.info(
{