fix(auth): bidirectional mode/type compat + sync OAuth to all agents (#12692)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 2dee8e1174
Co-authored-by: mudrii <220262+mudrii@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
This commit is contained in:
mudrii
2026-02-20 18:31:09 +08:00
committed by GitHub
parent 083298ab9d
commit 7ecfc1d93c
14 changed files with 568 additions and 46 deletions

View File

@@ -765,6 +765,37 @@ export function isAuthAssistantError(msg: AssistantMessage | undefined): boolean
return isAuthErrorMessage(msg.errorMessage ?? "");
}
export function isModelNotFoundErrorMessage(raw: string): boolean {
if (!raw) {
return false;
}
const lower = raw.toLowerCase();
// Direct pattern matches from OpenClaw internals and common providers.
if (
lower.includes("unknown model") ||
lower.includes("model not found") ||
lower.includes("model_not_found") ||
lower.includes("not_found_error") ||
(lower.includes("does not exist") && lower.includes("model")) ||
(lower.includes("invalid model") && !lower.includes("invalid model reference"))
) {
return true;
}
// Google Gemini: "models/X is not found for api version"
if (/models\/[^\s]+ is not found/i.test(raw)) {
return true;
}
// JSON error payloads: {"status": "NOT_FOUND"} or {"code": 404} combined with not-found text.
if (/\b404\b/.test(raw) && /not[-_ ]?found/i.test(raw)) {
return true;
}
return false;
}
export function classifyFailoverReason(raw: string): FailoverReason | null {
if (isImageDimensionErrorMessage(raw)) {
return null;
@@ -772,6 +803,9 @@ export function classifyFailoverReason(raw: string): FailoverReason | null {
if (isImageSizeError(raw)) {
return null;
}
if (isModelNotFoundErrorMessage(raw)) {
return "model_not_found";
}
if (isTransientHttpError(raw)) {
// Treat transient 5xx provider failures as retryable transport issues.
return "timeout";

View File

@@ -1,3 +1,10 @@
export type EmbeddedContextFile = { path: string; content: string };
export type FailoverReason = "auth" | "format" | "rate_limit" | "billing" | "timeout" | "unknown";
export type FailoverReason =
| "auth"
| "format"
| "rate_limit"
| "billing"
| "timeout"
| "model_not_found"
| "unknown";