refactor: extract resolveEffectiveAgentType/resolveSessionFolder as SSOT, deduplicate CONTAINER_IMAGE
This commit is contained in:
@@ -40,8 +40,7 @@ import type { RegisteredGroup } from './types.js';
|
|||||||
|
|
||||||
// ── Config ────────────────────────────────────────────────────────
|
// ── Config ────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const CONTAINER_IMAGE =
|
import { REVIEWER_CONTAINER_IMAGE as CONTAINER_IMAGE } from './config.js';
|
||||||
process.env.REVIEWER_CONTAINER_IMAGE || 'ejclaw-reviewer:latest';
|
|
||||||
|
|
||||||
// ── Types ─────────────────────────────────────────────────────────
|
// ── Types ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ import {
|
|||||||
completePairedExecutionContext,
|
completePairedExecutionContext,
|
||||||
preparePairedExecutionContext,
|
preparePairedExecutionContext,
|
||||||
} from './paired-execution-context.js';
|
} from './paired-execution-context.js';
|
||||||
import { resolveActiveRole } from './message-runtime-rules.js';
|
import {
|
||||||
|
resolveActiveRole,
|
||||||
|
resolveEffectiveAgentType,
|
||||||
|
resolveSessionFolder,
|
||||||
|
} from './message-runtime-rules.js';
|
||||||
import { buildRoomRoleContext } from './room-role-context.js';
|
import { buildRoomRoleContext } from './room-role-context.js';
|
||||||
import {
|
import {
|
||||||
classifyRotationTrigger,
|
classifyRotationTrigger,
|
||||||
@@ -35,11 +39,8 @@ import {
|
|||||||
shouldRetryFreshSessionOnAgentFailure,
|
shouldRetryFreshSessionOnAgentFailure,
|
||||||
} from './session-recovery.js';
|
} from './session-recovery.js';
|
||||||
import {
|
import {
|
||||||
ARBITER_AGENT_TYPE,
|
|
||||||
CODEX_MAIN_SERVICE_ID,
|
|
||||||
CODEX_REVIEW_SERVICE_ID,
|
CODEX_REVIEW_SERVICE_ID,
|
||||||
SERVICE_SESSION_SCOPE,
|
SERVICE_SESSION_SCOPE,
|
||||||
REVIEWER_AGENT_TYPE,
|
|
||||||
isClaudeService,
|
isClaudeService,
|
||||||
getRoleModelConfig,
|
getRoleModelConfig,
|
||||||
} from './config.js';
|
} from './config.js';
|
||||||
@@ -107,34 +108,20 @@ export async function runAgentForGroup(
|
|||||||
const reviewerMode = activeRole === 'reviewer';
|
const reviewerMode = activeRole === 'reviewer';
|
||||||
const arbiterMode = activeRole === 'arbiter';
|
const arbiterMode = activeRole === 'arbiter';
|
||||||
|
|
||||||
// Override agent type based on role config (OWNER_AGENT_TYPE / REVIEWER_AGENT_TYPE).
|
const effectiveAgentType = resolveEffectiveAgentType(
|
||||||
// When the reviewer uses a different agent type than the group default,
|
activeRole,
|
||||||
// swap in the configured type for the duration of this execution.
|
group.agentType,
|
||||||
const reviewerAgentTypeOverride =
|
);
|
||||||
reviewerMode && REVIEWER_AGENT_TYPE !== (group.agentType || 'claude-code');
|
const effectiveGroup =
|
||||||
const arbiterAgentTypeOverride =
|
effectiveAgentType !== (group.agentType || 'claude-code')
|
||||||
arbiterMode &&
|
? { ...group, agentType: effectiveAgentType }
|
||||||
ARBITER_AGENT_TYPE != null &&
|
|
||||||
ARBITER_AGENT_TYPE !== (group.agentType || 'claude-code');
|
|
||||||
const effectiveAgentType = arbiterAgentTypeOverride
|
|
||||||
? ARBITER_AGENT_TYPE!
|
|
||||||
: reviewerAgentTypeOverride
|
|
||||||
? REVIEWER_AGENT_TYPE
|
|
||||||
: group.agentType || 'claude-code';
|
|
||||||
const effectiveGroup = arbiterAgentTypeOverride
|
|
||||||
? { ...group, agentType: ARBITER_AGENT_TYPE! }
|
|
||||||
: reviewerAgentTypeOverride
|
|
||||||
? { ...group, agentType: REVIEWER_AGENT_TYPE }
|
|
||||||
: group;
|
: group;
|
||||||
const isClaudeCodeAgent = effectiveAgentType === 'claude-code';
|
const isClaudeCodeAgent = effectiveAgentType === 'claude-code';
|
||||||
|
const sessionFolder = resolveSessionFolder(
|
||||||
// When the reviewer/arbiter uses a different agent type than the group default,
|
group.folder,
|
||||||
// use a separate session key so owner, reviewer, and arbiter sessions don't collide.
|
activeRole,
|
||||||
const sessionFolder = arbiterAgentTypeOverride
|
group.agentType,
|
||||||
? `${group.folder}:arbiter`
|
);
|
||||||
: reviewerAgentTypeOverride
|
|
||||||
? `${group.folder}:reviewer`
|
|
||||||
: group.folder;
|
|
||||||
const sessionId = sessions[sessionFolder];
|
const sessionId = sessions[sessionFolder];
|
||||||
const memoryBriefing = sessionId
|
const memoryBriefing = sessionId
|
||||||
? undefined
|
? undefined
|
||||||
@@ -478,10 +465,7 @@ export async function runAgentForGroup(
|
|||||||
groupFolder: group.folder,
|
groupFolder: group.folder,
|
||||||
runId,
|
runId,
|
||||||
provider: effectiveAgentType,
|
provider: effectiveAgentType,
|
||||||
reviewerMode,
|
role: activeRole,
|
||||||
arbiterMode,
|
|
||||||
reviewerAgentTypeOverride,
|
|
||||||
arbiterAgentTypeOverride,
|
|
||||||
},
|
},
|
||||||
`Using provider: ${effectiveAgentType}`,
|
`Using provider: ${effectiveAgentType}`,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import { normalizeStoredSeqCursor } from './message-cursor.js';
|
|||||||
import { isTriggerAllowed, loadSenderAllowlist } from './sender-allowlist.js';
|
import { isTriggerAllowed, loadSenderAllowlist } from './sender-allowlist.js';
|
||||||
import { isTaskStatusControlMessage } from './task-watch-status.js';
|
import { isTaskStatusControlMessage } from './task-watch-status.js';
|
||||||
import {
|
import {
|
||||||
|
ARBITER_AGENT_TYPE,
|
||||||
|
OWNER_AGENT_TYPE,
|
||||||
|
REVIEWER_AGENT_TYPE,
|
||||||
|
} from './config.js';
|
||||||
|
import {
|
||||||
|
type AgentType,
|
||||||
type Channel,
|
type Channel,
|
||||||
type NewMessage,
|
type NewMessage,
|
||||||
type RegisteredGroup,
|
type RegisteredGroup,
|
||||||
@@ -57,6 +63,38 @@ export function resolveCursorKey(
|
|||||||
return role === 'owner' ? chatJid : `${chatJid}:${role}`;
|
return role === 'owner' ? chatJid : `${chatJid}:${role}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Resolve the effective agent type for a role, considering per-role overrides. */
|
||||||
|
export function resolveEffectiveAgentType(
|
||||||
|
role: 'owner' | 'reviewer' | 'arbiter',
|
||||||
|
groupAgentType: AgentType | undefined,
|
||||||
|
): AgentType {
|
||||||
|
const groupDefault: AgentType = groupAgentType || 'claude-code';
|
||||||
|
switch (role) {
|
||||||
|
case 'reviewer':
|
||||||
|
return REVIEWER_AGENT_TYPE !== groupDefault
|
||||||
|
? REVIEWER_AGENT_TYPE
|
||||||
|
: groupDefault;
|
||||||
|
case 'arbiter':
|
||||||
|
return ARBITER_AGENT_TYPE != null && ARBITER_AGENT_TYPE !== groupDefault
|
||||||
|
? ARBITER_AGENT_TYPE
|
||||||
|
: groupDefault;
|
||||||
|
default:
|
||||||
|
return groupDefault;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Session folder key for a role. Owner uses groupFolder, others use groupFolder:role. */
|
||||||
|
export function resolveSessionFolder(
|
||||||
|
groupFolder: string,
|
||||||
|
role: 'owner' | 'reviewer' | 'arbiter',
|
||||||
|
groupAgentType: AgentType | undefined,
|
||||||
|
): string {
|
||||||
|
const effectiveType = resolveEffectiveAgentType(role, groupAgentType);
|
||||||
|
const groupDefault: AgentType = groupAgentType || 'claude-code';
|
||||||
|
if (effectiveType === groupDefault) return groupFolder;
|
||||||
|
return `${groupFolder}:${role}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function createImplicitContinuationTracker(idleTimeout: number) {
|
export function createImplicitContinuationTracker(idleTimeout: number) {
|
||||||
const implicitContinuationUntil = new Map<string, number>();
|
const implicitContinuationUntil = new Map<string, number>();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user