






















@@ -229,24 +229,10 @@ export async function handleAssistantFailover(params: {
229229return sameModelIdleTimeoutRetry();
230230}
231231params.logAssistantFailoverDecision("surface_error");
232-// Two surface_error shapes already have downstream synthesis and
233-// must keep falling through to `continue_normal`:
234-// 1. External abort (user pressed stop) — partial assistant
235-// output carries the turn; no provider error to synthesize.
236-// 2. Timeout without an idle-retry — run.ts emits a dedicated
237-// timeout payload when buildEmbeddedRunPayloads produces no
238-// assistant content (see the `timedOut &&
239-// !timedOutDuringCompaction && !payloadsWithToolMedia.length`
240-// block in run.ts). Throwing here would short-circuit that
241-// synthesis and break timeout-compaction retry coverage.
242-// Every other surface_error is a concrete provider failure that
243-// continue_normal would silently drop before the payload builder
244-// sees it (openclaw#70124: billing errors reached the gateway
245-// but never the webchat because stopReason was not "error" and
246-// no other synthesis path caught them). Throw a FailoverError so
247-// the client surface can render it the same way it already
248-// renders fallback_model failures.
249-if (!params.externalAbort && !params.timedOut) {
232+// Only current provider failures throw here. External aborts, timeout
233+// payload synthesis, and stale classified text without failoverFailure
234+// keep the normal payload path.
235+if (!params.externalAbort && !params.timedOut && params.failoverFailure) {
250236const message = resolveAssistantFailoverErrorMessage(params);
251237const reason = resolveSurfaceErrorReason(decision.reason, params);
252238const status =
@@ -313,12 +299,6 @@ function resolveAssistantFailoverErrorMessage(params: {
313299);
314300}
315301316-// surface_error decisions can arrive with `reason: null` when
317-// shouldRotateAssistant fired on `failoverFailure` without a classified
318-// upstream reason. FailoverError requires a concrete reason, so map
319-// null onto the most specific failure the run observed, falling back
320-// to "unknown" when no signal is set. Callers only hit this helper on
321-// the non-timeout throw branch, so timeouts don't need a case here.
322302function resolveSurfaceErrorReason(
323303declared: FailoverReason | null,
324304params: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。