Files
EJClaw/src/paired-turn-identity.ts

104 lines
2.5 KiB
TypeScript

import type {
PairedRoomRole,
PairedTaskStatus,
PairedTurnReservationIntentKind,
} from './types.js';
export interface PairedTurnIdentity {
turnId: string;
taskId: string;
taskUpdatedAt: string;
intentKind: PairedTurnReservationIntentKind;
role: PairedRoomRole;
}
export function resolvePairedTurnRole(
intentKind: PairedTurnReservationIntentKind,
): PairedRoomRole {
switch (intentKind) {
case 'reviewer-turn':
return 'reviewer';
case 'arbiter-turn':
return 'arbiter';
case 'owner-turn':
case 'owner-follow-up':
case 'finalize-owner-turn':
default:
return 'owner';
}
}
export function buildPairedTurnId(args: {
taskId: string;
taskUpdatedAt: string;
intentKind: PairedTurnReservationIntentKind;
}): string {
return [args.taskId, args.taskUpdatedAt, args.intentKind].join(':');
}
export function buildPairedTurnIdentity(args: {
taskId: string;
taskUpdatedAt: string;
intentKind: PairedTurnReservationIntentKind;
role?: PairedRoomRole;
turnId?: string | null;
}): PairedTurnIdentity {
const role = args.role ?? resolvePairedTurnRole(args.intentKind);
if (role !== resolvePairedTurnRole(args.intentKind)) {
throw new Error(
`paired turn identity role mismatch: ${role} does not match ${args.intentKind}`,
);
}
return {
turnId:
args.turnId ??
buildPairedTurnId({
taskId: args.taskId,
taskUpdatedAt: args.taskUpdatedAt,
intentKind: args.intentKind,
}),
taskId: args.taskId,
taskUpdatedAt: args.taskUpdatedAt,
intentKind: args.intentKind,
role,
};
}
export function resolveOwnerTurnIntentKind(args: {
taskStatus?: PairedTaskStatus | null;
hasHumanMessage?: boolean;
}): 'owner-turn' | 'owner-follow-up' | 'finalize-owner-turn' {
if (args.hasHumanMessage) {
return 'owner-turn';
}
if (args.taskStatus === 'merge_ready') {
return 'finalize-owner-turn';
}
return 'owner-follow-up';
}
export function resolveRuntimePairedTurnIdentity(args: {
taskId: string;
taskUpdatedAt: string;
role: PairedRoomRole;
taskStatus?: PairedTaskStatus | null;
hasHumanMessage?: boolean;
}): PairedTurnIdentity {
const intentKind =
args.role === 'reviewer'
? 'reviewer-turn'
: args.role === 'arbiter'
? 'arbiter-turn'
: resolveOwnerTurnIntentKind({
taskStatus: args.taskStatus,
hasHumanMessage: args.hasHumanMessage,
});
return buildPairedTurnIdentity({
taskId: args.taskId,
taskUpdatedAt: args.taskUpdatedAt,
intentKind,
role: args.role,
});
}