fix: normalize stuck code queue retries

This commit is contained in:
Codex
2026-05-17 10:10:21 +00:00
parent 3d2af9ff86
commit 171ad7f8b4
@@ -591,6 +591,12 @@ function hasClaimMarkers(task: QueueTask): boolean {
|| task.attempts.length > 0;
}
function retryableClaimedQueueState(task: QueueTask): boolean {
return (task.status === "queued" || task.status === "retry_wait")
&& task.activeTurnId === null
&& hasClaimMarkers(task);
}
function terminalTaskUnread(task: QueueTask): boolean {
return terminalTask(task) && task.readAt === null;
}
@@ -1922,25 +1928,30 @@ async function retryTask(taskId: string, req: Request): Promise<Response> {
`;
if (rows[0] === undefined) return { task: null, changed: false };
const nextTask = rowToTask(rows[0]);
if (!terminalTask(nextTask)) return { task: nextTask, changed: false };
const isTerminal = terminalTask(nextTask);
const isClaimedQueueRetry = retryableClaimedQueueState(nextTask);
if (!isTerminal && !isClaimedQueueRetry) return { task: nextTask, changed: false };
nextTask.status = hasClaimMarkers(nextTask) ? "retry_wait" : "queued";
nextTask.finishedAt = null;
nextTask.readAt = null;
nextTask.cancelRequested = false;
nextTask.lastError = null;
nextTask.maxAttempts = Math.max(nextTask.maxAttempts, nextTask.attempts.length + 1);
nextTask.maxAttempts = Math.max(nextTask.maxAttempts, nextTask.currentAttempt + 1, nextTask.attempts.length + 1);
nextTask.nextMode = "retry";
nextTask.nextPrompt = explicitPrompt.length > 0 ? explicitPrompt : "Manual retry requested from master code-queue-mgr. Continue the original task and produce a visible final response.";
nextTask.updatedAt = queuedAt;
nextTask.queueEnteredAt = queuedAt;
nextTask.output.push({ seq: outputMaxSeq(nextTask) + 1, at: queuedAt, channel: "system", text: "manual retry queued by master code-queue-mgr\n", method: "manual-retry" });
const retryText = isClaimedQueueRetry
? "claimed queued task normalized to retry_wait by master code-queue-mgr\n"
: "manual retry queued by master code-queue-mgr\n";
nextTask.output.push({ seq: outputMaxSeq(nextTask) + 1, at: queuedAt, channel: "system", text: retryText, method: "manual-retry" });
nextTask.outputMaxSeq = outputMaxSeq(nextTask);
await upsertTask(client, nextTask);
return { task: nextTask, changed: true };
});
const task = result.task;
if (task === null) return jsonResponse({ ok: false, error: "task not found" }, 404);
if (!result.changed) return jsonResponse({ ok: false, error: `task is not terminal: ${task.status}`, task: taskListResponse(task) }, 409);
if (!result.changed) return jsonResponse({ ok: false, error: `task cannot be retried from status=${task.status}`, task: taskListResponse(task) }, 409);
return jsonResponse({ ok: true, task: taskListResponse(task, false), queue: await queueSummary() }, 202);
}