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[];
};
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: {
cfg: OpenClawConfig | undefined;
defaultProvider: string;
@@ -376,22 +396,15 @@ export async function runWithModelFallback<T>(params: {
}
}
if (attempts.length <= 1 && lastError) {
throw lastError;
}
const summary =
attempts.length > 0
? attempts
.map(
(attempt) =>
`${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,
throwFallbackFailureSummary({
attempts,
candidates,
lastError,
label: "models",
formatAttempt: (attempt) =>
`${attempt.provider}/${attempt.model}: ${attempt.error}${
attempt.reason ? ` (${attempt.reason})` : ""
}`,
});
}
@@ -445,16 +458,11 @@ export async function runWithImageModelFallback<T>(params: {
}
}
if (attempts.length <= 1 && lastError) {
throw lastError;
}
const summary =
attempts.length > 0
? attempts
.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,
throwFallbackFailureSummary({
attempts,
candidates,
lastError,
label: "image models",
formatAttempt: (attempt) => `${attempt.provider}/${attempt.model}: ${attempt.error}`,
});
}