refactor(agents): share fallback failure summary builder

This commit is contained in:
Peter Steinberger
2026-02-19 00:10:08 +00:00
parent 8e1f25631b
commit ef5d7cee22

View File

@@ -96,6 +96,26 @@ type ModelFallbackRunResult<T> = {
attempts: FallbackAttempt[]; attempts: FallbackAttempt[];
}; };
function throwFallbackFailureSummary(params: {
attempts: FallbackAttempt[];
candidates: ModelCandidate[];
lastError: unknown;
label: string;
formatAttempt: (attempt: FallbackAttempt) => string;
}): never {
if (params.attempts.length <= 1 && params.lastError) {
throw params.lastError;
}
const summary =
params.attempts.length > 0 ? params.attempts.map(params.formatAttempt).join(" | ") : "unknown";
throw new Error(
`All ${params.label} failed (${params.attempts.length || params.candidates.length}): ${summary}`,
{
cause: params.lastError instanceof Error ? params.lastError : undefined,
},
);
}
function resolveImageFallbackCandidates(params: { function resolveImageFallbackCandidates(params: {
cfg: OpenClawConfig | undefined; cfg: OpenClawConfig | undefined;
defaultProvider: string; defaultProvider: string;
@@ -376,22 +396,15 @@ export async function runWithModelFallback<T>(params: {
} }
} }
if (attempts.length <= 1 && lastError) { throwFallbackFailureSummary({
throw lastError; attempts,
} candidates,
const summary = lastError,
attempts.length > 0 label: "models",
? attempts formatAttempt: (attempt) =>
.map( `${attempt.provider}/${attempt.model}: ${attempt.error}${
(attempt) => attempt.reason ? ` (${attempt.reason})` : ""
`${attempt.provider}/${attempt.model}: ${attempt.error}${ }`,
attempt.reason ? ` (${attempt.reason})` : ""
}`,
)
.join(" | ")
: "unknown";
throw new Error(`All models failed (${attempts.length || candidates.length}): ${summary}`, {
cause: lastError instanceof Error ? lastError : undefined,
}); });
} }
@@ -445,16 +458,11 @@ export async function runWithImageModelFallback<T>(params: {
} }
} }
if (attempts.length <= 1 && lastError) { throwFallbackFailureSummary({
throw lastError; attempts,
} candidates,
const summary = lastError,
attempts.length > 0 label: "image models",
? attempts formatAttempt: (attempt) => `${attempt.provider}/${attempt.model}: ${attempt.error}`,
.map((attempt) => `${attempt.provider}/${attempt.model}: ${attempt.error}`)
.join(" | ")
: "unknown";
throw new Error(`All image models failed (${attempts.length || candidates.length}): ${summary}`, {
cause: lastError instanceof Error ? lastError : undefined,
}); });
} }