backup current stable ejclaw state
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user