Unify paired status transitions and retry handling

This commit is contained in:
ejclaw
2026-04-07 02:49:02 +09:00
parent 4511ca5692
commit b8e8c9dabf
13 changed files with 574 additions and 280 deletions

View File

@@ -1,7 +1,9 @@
import { ARBITER_DEADLOCK_THRESHOLD } from './config.js';
import { updatePairedTask } from './db.js';
import { logger } from './logger.js';
import { classifyArbiterVerdict } from './paired-execution-context-shared.js';
import {
classifyArbiterVerdict,
transitionPairedTaskStatus,
} from './paired-execution-context-shared.js';
import type { PairedTask } from './types.js';
export function handleFailedArbiterExecution(args: {
@@ -15,7 +17,12 @@ export function handleFailedArbiterExecution(args: {
? 'arbiter_requested'
: task.status;
if (fallbackStatus !== task.status) {
updatePairedTask(taskId, { status: fallbackStatus, updated_at: now });
transitionPairedTaskStatus({
taskId,
currentStatus: task.status,
nextStatus: fallbackStatus,
updatedAt: now,
});
logger.warn(
{
taskId,
@@ -45,11 +52,15 @@ export function handleArbiterCompletion(args: {
case 'proceed':
case 'revise':
case 'reset':
updatePairedTask(taskId, {
status: 'active',
round_trip_count: Math.max(0, ARBITER_DEADLOCK_THRESHOLD - 1),
arbiter_verdict: arbiterVerdict,
updated_at: now,
transitionPairedTaskStatus({
taskId,
currentStatus: 'in_arbitration',
nextStatus: 'active',
updatedAt: now,
patch: {
round_trip_count: Math.max(0, ARBITER_DEADLOCK_THRESHOLD - 1),
arbiter_verdict: arbiterVerdict,
},
});
logger.info(
{ taskId, arbiterVerdict },
@@ -57,20 +68,28 @@ export function handleArbiterCompletion(args: {
);
return;
case 'escalate':
updatePairedTask(taskId, {
status: 'completed',
arbiter_verdict: 'escalate',
completion_reason: 'arbiter_escalated',
updated_at: now,
transitionPairedTaskStatus({
taskId,
currentStatus: 'in_arbitration',
nextStatus: 'completed',
updatedAt: now,
patch: {
arbiter_verdict: 'escalate',
completion_reason: 'arbiter_escalated',
},
});
logger.info({ taskId }, 'Arbiter escalated to user — task completed');
return;
default:
updatePairedTask(taskId, {
status: 'active',
round_trip_count: Math.max(0, ARBITER_DEADLOCK_THRESHOLD - 1),
arbiter_verdict: 'unknown',
updated_at: now,
transitionPairedTaskStatus({
taskId,
currentStatus: 'in_arbitration',
nextStatus: 'active',
updatedAt: now,
patch: {
round_trip_count: Math.max(0, ARBITER_DEADLOCK_THRESHOLD - 1),
arbiter_verdict: 'unknown',
},
});
logger.warn(
{ taskId, summary: summary?.slice(0, 200) },