Feature request: declarative cross-model and cross-provider fallback chains #4975
sprintberlin
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Feature request
Add an opt-in, declarative fallback chain to CLIProxyAPI core so one client-facing model can fail over to explicitly configured alternative models and providers when the preferred route is temporarily unavailable or its quota is exhausted.
A practical example is a client requesting
gpt-5.6-sol. If every eligible Codex credential for that model has exhausted its quota, CLIProxyAPI could transparently retry the same request withgrok-4.5, provided the operator explicitly configured that fallback and the request has not started producing downstream output.This is not a request for implicit fallback to arbitrary models. The chain should be explicit, ordered, opt-in, bounded, and compatibility-aware.
Why this is valuable in real deployments
CLIProxyAPI is particularly useful as a unified gateway across subscription-backed OAuth accounts, API-key providers, and OpenAI-compatible backends. In practice, these resources do not fail or reset at the same time:
429,502,503,504, overload, or maintenance error;Credential rotation solves only part of this problem. Retrying ten credentials that all expose the same exhausted model still ends in a hard failure. A model fallback chain solves the next layer: after the eligible credential pool for a route is exhausted, continue with the next explicitly approved model/provider route.
In my opinion, this would be highly useful in production because the gateway already has the information and execution boundary needed to make the decision correctly. Every client implementing its own fallback logic duplicates configuration, error classification, retry limits, streaming safety, and observability. A core implementation would provide one predictable policy for every OpenAI-, Responses-, and Anthropic-compatible client using the gateway.
It would also make subscription-backed pools much more practical. Their limits are often model-specific and time-bucket-specific, so temporary exhaustion should not necessarily make the complete gateway unavailable.
Proposed configuration shape
The exact schema is open for discussion. One possible design:
Alternatively, a logical client-facing alias could own the chain:
The client would always request
resilient-coding, while CLIProxyAPI keeps the configured order and switches only under the configured conditions.Suggested behavior
1. Exhaust credentials before changing the model
For each candidate, CLIProxyAPI should retain its existing credential selection, cooldown, retry, priority, round-robin, fill-first, and session-affinity behavior.
Only after no eligible credential can serve the current candidate, or after a configured terminal fallback condition is received, should execution move to the next candidate.
Conceptually:
2. Explicit error classification
Fallback conditions should be configurable and should support both HTTP status codes and normalized provider reasons. Model-specific subscription errors are not always represented consistently as HTTP
429; examples includeusage_limit_reached, quota exhaustion, account capacity errors, and provider overload responses.The implementation should avoid fragile ad hoc string matching where possible. A normalized internal error classification would also improve logging and future provider support.
Fallback should normally not occur for semantic client errors such as invalid requests, unsupported tools, context overflow, or authentication failures unless an operator explicitly enables those conditions.
3. Safe streaming semantics
For streaming requests, switching is safe only before the first meaningful downstream chunk has been committed. Once tokens, tool calls, or other response items have been emitted, CLIProxyAPI should not splice a second model into the same response.
This behavior should be explicit and covered by tests for SSE and Responses/WebSocket paths where applicable.
4. Compatibility-aware candidates
A candidate should be skipped if it cannot satisfy the request protocol or required capabilities. Examples:
/v1/responsessupport;An explicit per-candidate capability declaration could be supported if automatic detection is not reliable. This avoids falling back from a capable primary model to a backend that accepts basic chat but cannot complete an agent/tool loop.
5. Session behavior
The fallback result should integrate with session affinity. A successful fallback could either:
Both policies are useful, but they should be deterministic and configurable. A sticky fallback is generally preferable for multi-turn agent sessions because switching model families on every turn can affect reasoning style, tool behavior, prompt caching, and provider-specific continuation state.
6. Bounded retries and loop prevention
The chain should have a maximum number of attempts and must prevent recursive aliases or cycles such as
A -> B -> A.Provider retries, credential retries, and model fallback attempts should have a clearly defined combined budget so a single request cannot amplify into an unexpectedly large number of upstream calls.
7. Observability and transparency
Logs and usage events should record at least:
If compatible with the existing API behavior, an optional response header or usage metadata field could expose the final resolved model. This matters for debugging, accounting, and evaluating differences in output quality.
Relationship to existing configuration
The current configuration already provides important building blocks:
request-retryretries selected transient status codes;max-retry-credentialslimits credential rotation;routing.strategycontrols credential selection;oauth-model-aliasand per-authmodel-aliasesrename or remap OAuth models.These features operate primarily at the retry, credential-selection, or alias-mapping layer. They do not provide a generic ordered chain that says: "try this provider/model first, then this different provider/model only if the first route is exhausted or unavailable."
A fallback chain should complement, not replace, the existing behavior.
Related work
This request builds on several previous discussions and implementation attempts:
/v1/responsesrequests.429,502,503, and504.Apparux/cpa-plugin-priority-auto-routerdemonstrates that the plugin APIs can implement prioritized candidates and pre-first-chunk fallback.claude-web-search-routerexample in this repository also demonstrates an executor-managed fallback chain across multiple backends for a specialized use case.Those efforts show both clear demand and technical feasibility. The distinction of this request is a small, generic, declarative, provider-neutral core policy rather than a provider-specific workaround or client-specific plugin.
Why core support in addition to plugins
A plugin remains a valid solution for custom routing. However, fallback is a foundational gateway concern when it combines native credential state, quota cooldowns, provider error normalization, session affinity, protocol translation, streaming commitment, and usage accounting.
Core support could:
host.model.*callbacks.The implementation does not need to replace plugin routing. A minimal core primitive could also give plugins a safer common fallback engine.
Suggested initial scope
A manageable first version could include:
More advanced capability matching and reset-aware recovery policies could follow later.
Acceptance examples
Quota exhaustion
Temporary outage
Streaming safety
Non-fallback client error
I believe this feature would materially improve CLIProxyAPI as a resilient multi-provider gateway while keeping routing behavior explicit and under operator control.
All reactions