feat: add global fallback provider support (#689)

When all combo models are exhausted (502/503), OmniRoute now checks for
a globalFallbackModel setting and attempts one last request through it
before returning the error. Settings stored in key_value table, no
migration needed.
This commit is contained in:
diegosouzapw
2026-03-28 21:08:03 -03:00
parent a0acdfdcb9
commit f1cddba938

View File

@@ -284,6 +284,45 @@ export async function handleChat(request: any, clientRawRequest: any = null) {
allCombos,
});
// ── Global Fallback Provider (#689) ────────────────────────────────────
// If combo exhausted all models, try the global fallback before giving up.
if (
!response.ok &&
[502, 503].includes(response.status) &&
typeof (settings as any)?.globalFallbackModel === "string" &&
(settings as any).globalFallbackModel.trim()
) {
const fallbackModel = (settings as any).globalFallbackModel.trim();
log.info(
"GLOBAL_FALLBACK",
`Combo "${combo.name}" exhausted — attempting global fallback: ${fallbackModel}`
);
try {
const fallbackResponse = await handleSingleModelChat(
body,
fallbackModel,
clientRawRequest,
request,
combo.name,
apiKeyInfo,
telemetry,
{ sessionId, emergencyFallbackTried: true }
);
if (fallbackResponse.ok) {
log.info("GLOBAL_FALLBACK", `Global fallback ${fallbackModel} succeeded`);
recordTelemetry(telemetry);
return withSessionHeader(fallbackResponse, sessionId);
}
log.warn(
"GLOBAL_FALLBACK",
`Global fallback ${fallbackModel} also failed (${fallbackResponse.status})`
);
} catch (err: any) {
log.warn("GLOBAL_FALLBACK", `Global fallback error: ${err?.message || "unknown"}`);
}
}
// ─────────────────────────────────────────────────────────────────────────
// Record telemetry
recordTelemetry(telemetry);
return withSessionHeader(response, sessionId);