fix(workbench): back off non-terminal projection resumes (#1803)
This commit is contained in:
@@ -1273,6 +1273,7 @@ async function runAgentRunProjectionResumePass({ options = {}, traceStore = defa
|
||||
const candidates = stateCandidates.length > 0 ? stateCandidates : sessions.flatMap((session) => agentRunProjectionResumeCandidates(session, { minAgeMs }));
|
||||
let resumed = 0;
|
||||
let terminal = 0;
|
||||
let nonTerminal = 0;
|
||||
let failed = 0;
|
||||
let skippedCooldown = 0;
|
||||
let skippedExhausted = 0;
|
||||
@@ -1291,8 +1292,25 @@ async function runAgentRunProjectionResumePass({ options = {}, traceStore = defa
|
||||
try {
|
||||
const result = await resumeAgentRunProjectionCandidate({ candidate, options, traceStore });
|
||||
resumed += 1;
|
||||
candidateRetryState.delete(retryKey);
|
||||
if (isTraceCommandTerminalStatus(result?.status)) terminal += 1;
|
||||
if (isTraceCommandTerminalStatus(result?.status)) {
|
||||
terminal += 1;
|
||||
candidateRetryState.delete(retryKey);
|
||||
} else {
|
||||
nonTerminal += 1;
|
||||
const previousAttempts = Number.isFinite(retryState?.attempts) ? retryState.attempts : 0;
|
||||
const retryAttempt = previousAttempts + 1;
|
||||
const retryExhausted = retryAttempt >= candidateRetryMaxAttempts;
|
||||
const retryDelayMs = retryExhausted ? 0 : projectionResumeCandidateRetryDelayMs(retryAttempt, candidateRetryInitialDelayMs, candidateRetryMaxDelayMs);
|
||||
const nextRetryAtMs = retryExhausted ? null : Date.now() + retryDelayMs;
|
||||
const nextRetryAt = Number.isFinite(nextRetryAtMs) ? new Date(nextRetryAtMs).toISOString() : null;
|
||||
candidateRetryState.set(retryKey, {
|
||||
attempts: retryAttempt,
|
||||
nextRetryAtMs,
|
||||
exhausted: retryExhausted,
|
||||
lastErrorCode: "projection_resume_non_terminal"
|
||||
});
|
||||
appendProjectionResumeRetry(traceStore, candidate, { retryAttempt, retryMaxAttempts: candidateRetryMaxAttempts, retryLabel: retryAttempt + "/" + candidateRetryMaxAttempts, retryDelayMs, nextRetryAt, retryExhausted, status: result?.status ?? null });
|
||||
}
|
||||
} catch (error) {
|
||||
failed += 1;
|
||||
const previousAttempts = Number.isFinite(retryState?.attempts) ? retryState.attempts : 0;
|
||||
@@ -1321,6 +1339,7 @@ async function runAgentRunProjectionResumePass({ options = {}, traceStore = defa
|
||||
candidates: candidates.length,
|
||||
resumed,
|
||||
terminal,
|
||||
nonTerminal,
|
||||
failed,
|
||||
skippedCooldown,
|
||||
skippedExhausted,
|
||||
@@ -1328,7 +1347,7 @@ async function runAgentRunProjectionResumePass({ options = {}, traceStore = defa
|
||||
candidateRetryMaxAttempts,
|
||||
valuesRedacted: true
|
||||
});
|
||||
return { offset, scannedSessions: sessions.length, candidates: candidates.length, resumed, terminal, failed, skippedCooldown, skippedExhausted };
|
||||
return { offset, scannedSessions: sessions.length, candidates: candidates.length, resumed, terminal, nonTerminal, failed, skippedCooldown, skippedExhausted };
|
||||
}
|
||||
|
||||
async function listAgentRunProjectionResumeStateCandidates(options = {}, batchSize = DEFAULT_AGENTRUN_PROJECTION_RESUME_BATCH_SIZE, offset = 0, { minAgeMs = DEFAULT_AGENTRUN_PROJECTION_RESUME_MIN_AGE_MS } = {}) {
|
||||
@@ -1570,6 +1589,30 @@ function appendProjectionResumeError(traceStore, candidate, error, retry = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
function appendProjectionResumeRetry(traceStore, candidate, retry = {}) {
|
||||
const traceId = safeTraceId(candidate?.traceId);
|
||||
if (!traceId) return;
|
||||
traceStore.append(traceId, {
|
||||
type: "turn-status",
|
||||
status: "degraded",
|
||||
label: "projection-resume:non-terminal-backoff",
|
||||
errorCode: "projection_resume_non_terminal",
|
||||
message: "AgentRun projection resume did not reach a terminal status; next resume is delayed.",
|
||||
runId: candidate?.result?.agentRun?.runId ?? null,
|
||||
commandId: candidate?.result?.agentRun?.commandId ?? null,
|
||||
waitingFor: "agentrun-result-resume",
|
||||
observedStatus: retry.status ?? null,
|
||||
retryAttempt: retry.retryAttempt ?? null,
|
||||
retryMaxAttempts: retry.retryMaxAttempts ?? null,
|
||||
retryLabel: retry.retryLabel ?? null,
|
||||
retryDelayMs: retry.retryDelayMs ?? null,
|
||||
nextRetryAt: retry.nextRetryAt ?? null,
|
||||
retryExhausted: retry.retryExhausted === true,
|
||||
terminal: false,
|
||||
valuesPrinted: false
|
||||
});
|
||||
}
|
||||
|
||||
function logAgentRunProjectionResume(logger, payload) {
|
||||
try {
|
||||
const line = JSON.stringify(payload);
|
||||
|
||||
Reference in New Issue
Block a user