跳到主要内容
    ↑↓ 选择↵ 打开esc 关闭
    中文English
    SkS-Other

    Model Fallback

    v1.1.1代码智能
    @shutovks/opencode-model-fallback

    OpenCode plugin that retries failed sessions with fallback models.

    GitHub 星标

    1

    月装机量

    266

    近 7 天 31

    综合评分SCORE

    36.0

    生态多维模型

    最近提交

    1 个月前

    2026-07-20

    快速安装与配置

    opencode.json

    写入当前项目的 opencode.json,只对这个仓库生效。

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["@shutovks/opencode-model-fallback@1.1.1"]
    }

    opencode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。

    Keep your OpenCode session alive when the model fails — automatic fallback to the next configured model on rate limits, quota exhaustion, overloads, and transient provider errors.

    CI npm License: MIT Bun

    When the active model errors out with a transient failure, this plugin retries the last user message in the same session using the next model from your fallback list — then recovers back to the original once it's healthy again. No lost context, no manual restart.

    Install

    bun add -g @shutovks/opencode-model-fallback
    

    Or use any package manager OpenCode can resolve from your plugin config.

    Configure

    Add the plugin to opencode.json or .opencode/opencode.json:

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": [
        [
          "@shutovks/opencode-model-fallback",
          {
            "enabled": true,
            "fallback_models": [
              "anthropic/claude-sonnet-4-5",
              "openai/gpt-5.1-codex",
              "google/gemini-2.5-pro"
            ],
            "unavailable_models": [],
            "max_attempts": 3,
            "attempts_window_ms": 600000,
            "cooldown_ms": 60000,
            "backoff_ms": 0,
            "recover_original_model": true,
            "notify": true,
            "debug": false
          }
        ]
      ]
    }
    

    Restart OpenCode after changing config.

    Options

    Option Default Meaning
    enabled true Default behavior for new sessions.
    fallback_models [] Ordered fallback model list, each as provider/model.
    unavailable_models [] Exact model IDs to skip in the config hook before the first provider call. Useful when OpenCode fails before emitting session.error.
    retry_on_errors [429, 500, 502, 503, 504] HTTP status codes that trigger fallback.
    retry_on_patterns [] Extra case-insensitive regex sources matched against the error text, appended to the built-in patterns. Invalid regexes are skipped.
    max_attempts 3 Max fallback retries within attempts_window_ms.
    attempts_window_ms 600000 Sliding window (ms) for max_attempts. Older attempts stop counting once outside it. Set 0 for a lifetime cap.
    cooldown_ms 60000 How long to avoid a failed model.
    backoff_ms 0 Base delay for exponential backoff with equal jitter before a retry. 0 = instant.
    backoff_max_ms 30000 Cap for the computed backoff delay.
    recover_original_model true Return to the original model once its cooldown expires instead of staying on the fallback.
    notify true Show a toast when switching or recovering models.
    debug false Write a [model-fallback] … trace to stderr explaining every fallback decision.

    Session Control

    The plugin registers one tool:

    model_fallback_control(action: "enable" | "disable" | "status" | "reset")
    

    Use it from inside OpenCode to control fallback for the current session:

    Use model_fallback_control to disable fallback in this session.
    
    Action Effect
    enable Enable fallback for the current session.
    disable Disable fallback for the current session.
    status Return effective state, current model, attempts, windowed attempt count, per-model failure counts, active cooldowns, recent switches, and configured fallbacks.
    reset Clear session state and return to the config default.

    Session overrides live in memory only — they disappear when the session is deleted or OpenCode restarts.

    unavailable_models vs fallback_models

    They look similar but act at different times:

    fallback_models unavailable_models
    Purpose Retry on these when the current model fails with a transient error. Skip these up front because they are known-bad (deprecated, no credentials, etc.).
    When After a session.error or on recovery. Before any provider call.
    Trigger A retryable error at runtime. Static configuration — no error needed.
    Example "If claude-opus is rate-limited, try gpt-5.1-codex." "Never select claude-3-opus; OpenCode errors before session.error."

    A model can be in both lists, but that's redundant — anything in unavailable_models is already filtered out when the plugin picks the next fallback.

    What Counts As Retryable

    Fallback triggers on configured status codes and common transient error text:

    • rate limit / too many requests
    • quota exceeded
    • all credentials for model exhausted
    • model unsupported
    • service unavailable / overloaded / temporarily unavailable
    • "try again" with a transient qualifier (later / soon / shortly / in Ns) — a bare "try again" does not match
    • 429, 503, 529 in plain text errors

    Status codes and text are also detected through the wrapped error.cause chain, so a 429/503 buried in a fetch error still triggers fallback. Add your own phrases with retry_on_patterns.

    Troubleshooting

    Fallback never triggers

    Turn on debug: true and reproduce. The [model-fallback] … lines in the OpenCode log explain each skip: disabled, no fallback_models, "not retryable" (status/text unmatched), max_attempts reached, or no available model.

    Fallback triggers too aggressively

    A provider's non-transient message may be matching a pattern. Check debug output, then either narrow retry_on_errors or set retry_on_patterns to only the phrases you want. Note that a bare "try again" no longer matches by default.

    Session stuck on a fallback model

    Expected only while the original model's cooldown (cooldown_ms) is active. Once it expires the next message recovers to the original model — unless recover_original_model: false or the original is in unavailable_models.

    Fallback stops retrying partway through a long session

    max_attempts counts within attempts_window_ms (default 10 min). Raise max_attempts, lengthen attempts_window_ms, or set attempts_window_ms: 0 for an absolute lifetime cap.

    A known-broken model still gets selected

    List it in unavailable_models so the plugin skips it before any provider call, not only after it fails.

    Limitations

    OpenCode does not let a plugin swap the model inside a failed stream. This plugin starts a new prompt in the same session with the last user message and the fallback model.

    It does not restore a half-finished tool-call turn. If the model failed after starting tool calls, the retry is a new model turn from the last user request.

    Development

    bun install
    bun test
    bun run typecheck
    bun run build
    

    See CHANGELOG.md for release history.

    License

    MIT


    This project is independent and is not built by, endorsed by, or affiliated with the OpenCode team.