backup current stable ejclaw state

This commit is contained in:
Codex
2026-05-27 10:53:05 +09:00
parent 646bc34372
commit 1509108e04
57 changed files with 7127 additions and 154 deletions

View File

@@ -12,12 +12,14 @@ import { markPairedTaskReviewReady } from './paired-workspace-manager.js';
import {
applyPairedTaskPatch,
hasCodeChangesSinceRef,
isUserInputWaitVerdict,
parseVisibleVerdict,
requestArbiterOrEscalate,
resolveOwnerCompletionSignal,
resolveCanonicalSourceRef,
transitionPairedTaskStatus,
} from './paired-execution-context-shared.js';
import { shouldSkipReviewerForTrivialTurn } from './paired-trivial-turn-detector.js';
import type { PairedTask } from './types.js';
type OwnerFinalizeOutcome = 'stop' | 're_review';
@@ -110,6 +112,29 @@ function handleOwnerFinalizeCompletion(args: {
ownerVerdict === 'step_done' && hasNewChanges === false
? (task.empty_step_done_streak ?? 0) + 1
: 0;
if (isUserInputWaitVerdict(summary)) {
transitionPairedTaskStatus({
taskId,
currentStatus: task.status,
nextStatus: 'completed',
expectedUpdatedAt: task.updated_at,
updatedAt: now,
patch: {
completion_reason: 'escalated',
owner_failure_count: 0,
owner_step_done_streak: 0,
finalize_step_done_count: nextFinalizeStepDoneCount,
empty_step_done_streak: nextEmptyStepDoneStreak,
},
});
logger.info(
{ taskId, ownerVerdict, summary: summary?.slice(0, 100) },
'Owner finalize is waiting for user input — completing paired task to stop follow-up loop',
);
return 'stop';
}
const signal = resolveOwnerCompletionSignal({
phase: 'finalize',
visibleVerdict: ownerVerdict,
@@ -344,6 +369,27 @@ export function handleOwnerCompletion(args: {
const ownerVerdict = parseVisibleVerdict(summary);
const nextOwnerStepDoneStreak =
ownerVerdict === 'step_done' ? (task.owner_step_done_streak ?? 0) + 1 : 0;
if (isUserInputWaitVerdict(summary)) {
transitionPairedTaskStatus({
taskId,
currentStatus: task.status,
nextStatus: 'completed',
expectedUpdatedAt: task.updated_at,
updatedAt: now,
patch: {
completion_reason: 'escalated',
owner_failure_count: 0,
owner_step_done_streak: nextOwnerStepDoneStreak,
},
});
logger.info(
{ taskId, ownerVerdict, summary: summary?.slice(0, 100) },
'Owner is waiting for user input — completing paired task to stop follow-up loop',
);
return;
}
const signal = resolveOwnerCompletionSignal({
phase: 'normal',
visibleVerdict: ownerVerdict,
@@ -381,6 +427,31 @@ export function handleOwnerCompletion(args: {
},
});
}
// Skip reviewer for clearly conversational turns (no code changes,
// short non-technical reply, no code-work keywords from the user).
// The detector is best-effort optimization — if anything goes wrong
// we fall back to running the reviewer (the safe pre-change behavior).
let skip = false;
let skipReason = 'evaluation-error';
try {
const decision = shouldSkipReviewerForTrivialTurn({ task, summary });
skip = decision.skip;
skipReason = decision.reason;
} catch (err) {
logger.warn(
{ err, taskId },
'paired-trivial-turn-detector: unexpected evaluation error — running reviewer',
);
}
if (skip) {
logger.info(
{ taskId, reason: skipReason, summary: summary?.slice(0, 100) },
'Skipping reviewer for trivial conversational turn',
);
return;
}
maybeAutoTriggerReviewerAfterOwnerCompletion({
task,
taskId,