fix(workbench): keep provider retry diagnostics non-terminal
This commit is contained in:
@@ -2473,6 +2473,7 @@ function mapAgentRunEvent(event, mapping = {}) {
|
||||
|
||||
function agentRunProviderRetryEvent({ base = {}, payload = {}, status = "retrying", label = "agentrun:provider-retry" } = {}) {
|
||||
const failureKind = normalizedFailureKind(payload.failureKind ?? payload.errorCode ?? "provider-stream-disconnected");
|
||||
const retryMessage = providerRetryMessage(textPayload(payload, "Provider stream disconnected; AgentRun will retry."), payload);
|
||||
return {
|
||||
...base,
|
||||
type: "provider_retry",
|
||||
@@ -2491,11 +2492,28 @@ function agentRunProviderRetryEvent({ base = {}, payload = {}, status = "retryin
|
||||
nextRetryAt: firstNonEmpty(payload.nextRetryAt) || null,
|
||||
retryOf: payload.retryOf ?? null,
|
||||
terminalStatus: payload.terminalStatus ?? null,
|
||||
message: textPayload(payload, "Provider stream disconnected; AgentRun will retry."),
|
||||
message: retryMessage,
|
||||
valuesPrinted: false
|
||||
};
|
||||
}
|
||||
|
||||
function providerRetryMessage(message, payload = {}) {
|
||||
const attempt = numberOrNull(payload.retryAttempt);
|
||||
const max = numberOrNull(payload.retryMax);
|
||||
const delayMs = numberOrNull(payload.retryDelayMs);
|
||||
const nextRetryAt = firstNonEmpty(payload.nextRetryAt) || null;
|
||||
const parts = [];
|
||||
if (attempt !== null && max !== null) parts.push(`retry ${attempt}/${max}`);
|
||||
else if (attempt !== null) parts.push(`retry attempt ${attempt}`);
|
||||
else if (max !== null) parts.push(`retry max ${max}`);
|
||||
if (delayMs !== null) parts.push(`after ${delayMs}ms`);
|
||||
if (nextRetryAt) parts.push(`next=${nextRetryAt}`);
|
||||
if (parts.length === 0) return message;
|
||||
const text = String(message || "Provider stream disconnected; AgentRun will retry.").trim();
|
||||
if (attempt !== null && max !== null && text.includes(`${attempt}/${max}`)) return text;
|
||||
return text.replace(/[.。]\s*$/u, "") + `; ${parts.join(" ")}.`;
|
||||
}
|
||||
|
||||
function isRetryableProviderInterruptionPayload(payload = {}, options = {}) {
|
||||
const kind = normalizedFailureKind(payload?.failureKind ?? payload?.errorCode ?? payload?.code);
|
||||
if (kind === "provider-stream-disconnected") return payload?.willRetry === true;
|
||||
|
||||
@@ -117,12 +117,17 @@ export function projectionDiagnostics({ traceId = null, projection = null, resul
|
||||
const turn = projection ?? createWorkbenchTurnProjection({ traceId, result, trace });
|
||||
const sealedCompleted = turn.terminal === true && turn.status === "completed" && Boolean(turn.finalResponse?.text);
|
||||
const source = sealedCompleted ? null : projectionDiagnosticSource(trace);
|
||||
const blocker = sealedCompleted ? null : refreshError ?? source?.blocker ?? trace?.blocker ?? result?.blocker ?? result?.error ?? null;
|
||||
const rawBlocker = sealedCompleted ? null : refreshError ?? source?.blocker ?? trace?.blocker ?? result?.blocker ?? result?.error ?? null;
|
||||
const retryingProviderInterruption = !sealedCompleted && turn.running === true ? retryableProviderInterruptionEvidence(rawBlocker) : null;
|
||||
const blocker = retryingProviderInterruption ? null : rawBlocker;
|
||||
const hasProjectionInput = hasTraceProjection(trace) || Boolean(result || result?.agentRun);
|
||||
const sourceStatus = sealedCompleted ? null : normalizeProjectionStatus(source?.projectionStatus ?? trace?.projectionStatus);
|
||||
const status = sealedCompleted ? "caught-up" : sourceStatus ?? (blocker ? "blocked" : turn.terminal ? "caught-up" : hasProjectionInput ? "projecting" : "unknown");
|
||||
const effectiveSourceStatus = retryingProviderInterruption && sourceStatus === "blocked" ? "projecting" : sourceStatus;
|
||||
const status = sealedCompleted ? "caught-up" : effectiveSourceStatus ?? (blocker ? "blocked" : turn.terminal ? "caught-up" : hasProjectionInput ? "projecting" : "unknown");
|
||||
const diagnostic = blocker ? diagnosticBlocker(blocker) : null;
|
||||
const projectionHealth = sealedCompleted ? "healthy" : normalizeProjectionHealth(source?.projectionHealth ?? trace?.projectionHealth)
|
||||
const sourceHealth = sealedCompleted ? null : normalizeProjectionHealth(source?.projectionHealth ?? trace?.projectionHealth);
|
||||
const effectiveSourceHealth = retryingProviderInterruption && (sourceHealth === "degraded" || sourceHealth === "unavailable" || sourceHealth === "stalled") ? "projecting" : sourceHealth;
|
||||
const projectionHealth = sealedCompleted ? "healthy" : effectiveSourceHealth
|
||||
?? projectionHealthFor({ status, turn, hasProjectionInput, blocker: diagnostic });
|
||||
const staleMs = sealedCompleted ? null : projectionStaleMs(source?.staleMs ?? trace?.staleMs, turn.updatedAt ?? trace?.updatedAt ?? result?.updatedAt);
|
||||
return {
|
||||
@@ -133,6 +138,7 @@ export function projectionDiagnostics({ traceId = null, projection = null, resul
|
||||
sourceCommandId: turn.sourceCommandId ?? null,
|
||||
staleMs,
|
||||
blocker: diagnostic,
|
||||
retryingProviderInterruption,
|
||||
updatedAt: turn.updatedAt ?? null,
|
||||
valuesRedacted: true
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user