Skip to content

fix(opencode): add runtime model fallback - #2342

Merged
shunkakinoki merged 3 commits into
mainfrom
codex/add-opencode-main-alias
Aug 10, 2026
Merged

fix(opencode): add runtime model fallback#2342
shunkakinoki merged 3 commits into
mainfrom
codex/add-opencode-main-alias

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Aug 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • install opencode-runtime-fallback@0.2.3, pinned to the npm release whose gitHead matches the audited public source commit
  • keep shunkakinoki/deepseek-v4-flash as the explicit OpenCode default; there is no main model alias
  • add an OpenCode-only fallback chain: DeepSeek Pro, Gemma, GLM, MiniMax, then the OpenRouter free route
  • retry 401, 404, 429, and 5xx failures with a 60-second model cooldown and 30-second time-to-first-token timeout
  • leave CLIProxy routing, Hermes configuration, Fish defaults, and models.json unchanged

Validation

  • upstream plugin: 387 tests, 0 failures; typecheck and build pass
  • OpenCode 1.18.15 isolated config load: plugin installed and initialized with all 5 fallback models
  • make format: 0 files changed
  • focused ShellSpec: 79 examples, 0 failures
  • Fish: 454 checks, 0 failures
  • full ShellSpec: 2,047 examples; the only failure is pre-existing on current main because Hermes PR fix(hermes): set provider to openrouter to enable prompt caching #2341 changed model.provider to openrouter while spec/hermes_hydrate_spec.sh still forbids that string (tracked as shunkakinokisoftware-tjrr)

Plugin source: https://github.com/youngbinkim0/opencode-fallback

@indent-zero

indent-zero Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Warning

Indent Zero is shutting down on August 7th. Please migrate over to Indent 2.0 to continue getting PR reviews.

PR Summary

The PR pivoted: the earlier main cliproxy alias approach was reverted, and the failover story is now handled by the opencode-runtime-fallback@0.2.3 opencode plugin plus a generated opencode-fallback.jsonc chain. All main-alias touches (cliproxy config, fish wrappers, opencode default/small_model, related spec updates) are rolled back to pre-PR state, and the PR now delivers a plugin-driven fallback ladder plus some tangential hermes tuning.

  • Reverts alias: "main" from openrouter/aliyun/opencode blocks in config/cliproxyapi/config.{tpl,template}.yaml.
  • Reverts _ocxe_function / _ocxeh_function (.fish + .tpl.fish) back to cliproxyapi/deepseek-v4-flash / cliproxyapi/__DEEPSEEK_FLASH__.
  • Reverts opencode default model to shunkakinoki/deepseek-v4-flash and small_model to shunkakinoki/z-ai/glm-4.7.
  • Adds opencode-runtime-fallback@0.2.3 to the plugin array in opencode.jsonc(.tpl) and registers four new remote provider models (deepseek-v4-pro, gemma-4-31b-it, minimax-m3, free) plus a second glm-4.7 entry.
  • Adds config/opencode/opencode-fallback.tpl.jsonc + generated sibling + default.nix home.file mapping — chain [deepseek-v4-pro, gemma-4-31b-it, glm-4.7, minimax-m3, free] (under shunkakinoki), retry on [401,404,429,500,502,503,504], max_fallback_attempts: 5, cooldown_seconds: 60, timeout_seconds: 30.
  • Teaches scripts/llm-update.sh about the new template mapping.
  • Spec block renamed to OpenCode runtime fallback; pins the plugin version, jq-verifies the fallback chain structure, asserts the main alias is fully gone; whitelist restored to only allow free; fish specs reverted to the DeepSeek Flash assertions.
  • Unrelated hermes tweaks bundled in the same commit: model.provider cliproxy → openrouter, prompt_caching.cache_ttl 5m → 30m, context.engine summary → compressor.

Issues

4 potential issues found:

  • spec/llm_update_spec.sh:116-120 only jq-asserts three of the seven fields in opencode-fallback.jsonc (retry_on_errors, max_fallback_attempts, fallback_models) — a template regression that flips enabled: false, zeroes timeout_seconds, or drops notify_on_fallback will not fail CI. Consider extending the predicate to pin all documented fields. → Autofix
  • Two unrelated hermes tuning changes rode along in the "add runtime model fallback" commit: prompt_caching.cache_ttl 5m → 30m and context.engine summary → compressor in config/hermes/config.{tpl,template}.yaml — no spec coverage and not mentioned in the commit title. Worth confirming they were intentional (or splitting them into a separate commit). → Autofix
  • small_model was reverted to shunkakinoki/z-ai/glm-4.7, which is not a registered alias on cliproxy (the z-ai provider only exposes alias: "glm-4.7") — every background call (session titles, summaries, tool decisions) will 404. Coverage depends on whether opencode-runtime-fallback intercepts small_model requests; its README only documents per-agent + global chat completions, not small_model, so verify before merging. → Autofix
  • Hermes model.provider was flipped to openrouter but the providers: block only declares cliproxy — no openrouter entry exists in the hermes config; any code path that resolves an unqualified model name will hit an undefined provider (all current references use explicit cliproxy/… prefixes so it appears inert today, but this is a latent config error). → Autofix
2 issues already resolved
  • config/omp/config.yml:67 still hardcodes default: "cliproxyapi/deepseek-v4-flash" instead of cliproxyapi/main, so OMP won't gain the OpenCode → Aliyun → OpenRouter fallback the PR introduces elsewhere — if this was intentional scope, ignore; otherwise switch it to main for parity with the ocxe wrappers. (fixed by commit bd05464)
  • Remote shunkakinoki cliproxy must publish the main alias before this merges — opencode.jsonc now defaults to shunkakinoki/main, which routes to https://cliproxy.shunkakinoki.com/v1; until that server is redeployed with the updated config.template.yaml, fresh opencode sessions using the default config will error with unknown-model on the remote path (local cliproxyapi/main used by _ocxe* is unaffected). (fixed by commit bd05464)

CI Checks

Waiting for CI checks...


⚡ Autofix All Issues

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added automatic model fallback with retries, cooldowns, timeouts, and notifications.
    • Added five fallback models, including DeepSeek, Gemma, GLM, MiniMax, and a free router option.
    • Added additional model provider options and runtime fallback support.
  • Bug Fixes

    • Improved fallback behavior for retryable service errors.
  • Tests

    • Added coverage for fallback defaults, model chains, plugin versions, and alias handling.

Walkthrough

OpenCode now includes runtime fallback settings, additional provider models, and the opencode-runtime-fallback@0.2.3 plugin. Home Manager installation, template generation, and shell tests support the new configuration.

Changes

OpenCode fallback support

Layer / File(s) Summary
Fallback configuration and installation
config/opencode/opencode-fallback*.jsonc, config/opencode/default.nix, scripts/llm-update.sh
Adds retry rules, timing limits, notifications, and ordered fallback models. Home Manager installs the fallback file, and the update script maps its template to the generated output.
Provider models and runtime plugin
config/opencode/opencode.jsonc, config/opencode/opencode.tpl.jsonc
Adds five models to the remote provider and enables opencode-runtime-fallback@0.2.3.
Fallback validation
spec/llm_update_spec.sh
Tests fallback defaults, retry settings, model order, plugin version, and the absence of a main alias.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

A rabbit hops through fallback lanes,
With model names in tidy trains.
Retry, cooldown, timeout too,
The plugin knows just what to do.
No main alias blocks the way—
OpenCode config blooms today!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description accurately covers the OpenCode runtime fallback configuration, plugin, fallback chain, retry behavior, and validation.
Title check ✅ Passed The title clearly summarizes the primary changes: adding runtime model fallback support for OpenCode.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/add-opencode-main-alias

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 13 files

Re-trigger cubic

@shunkakinoki
shunkakinoki force-pushed the codex/add-opencode-main-alias branch from eaae25c to bd05464 Compare August 10, 2026 12:43
@shunkakinoki shunkakinoki changed the title fix(opencode): add main fallback route fix(opencode): add runtime model fallback Aug 10, 2026
@shunkakinoki
shunkakinoki merged commit cd54471 into main Aug 10, 2026
9 of 12 checks passed
@shunkakinoki
shunkakinoki deleted the codex/add-opencode-main-alias branch August 10, 2026 12:44

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
spec/llm_update_spec.sh (1)

121-123: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert every fallback setting.

The jq expression checks retry codes, maximum attempts, and model order, but it does not check enabled, cooldown_seconds, timeout_seconds, or notify_on_fallback. A generated file can disable fallback or change timing while this test still passes.

Proposed predicate extension
- .retry_on_errors == [401,404,429,500,502,503,504] and .max_fallback_attempts == 5 and .fallback_models == ["shunkakinoki/deepseek-v4-pro","shunkakinoki/gemma-4-31b-it","shunkakinoki/glm-4.7","shunkakinoki/minimax-m3","shunkakinoki/free"]
+ .enabled == true and
+ .retry_on_errors == [401,404,429,500,502,503,504] and
+ .max_fallback_attempts == 5 and
+ .cooldown_seconds == 60 and
+ .timeout_seconds == 30 and
+ .notify_on_fallback == true and
+ .fallback_models == ["shunkakinoki/deepseek-v4-pro","shunkakinoki/gemma-4-31b-it","shunkakinoki/glm-4.7","shunkakinoki/minimax-m3","shunkakinoki/free"]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spec/llm_update_spec.sh` around lines 121 - 123, Extend the jq predicate in
“generates a separate OpenCode fallback chain” to also assert the expected
enabled state, cooldown_seconds, timeout_seconds, and notify_on_fallback values,
while preserving the existing retry codes, maximum attempts, and fallback_models
order checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@spec/llm_update_spec.sh`:
- Around line 121-123: Extend the jq predicate in “generates a separate OpenCode
fallback chain” to also assert the expected enabled state, cooldown_seconds,
timeout_seconds, and notify_on_fallback values, while preserving the existing
retry codes, maximum attempts, and fallback_models order checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ce03c0cf-f102-49e8-a5e2-e740b25bc878

📥 Commits

Reviewing files that changed from the base of the PR and between 265c432 and bd05464.

📒 Files selected for processing (7)
  • config/opencode/default.nix
  • config/opencode/opencode-fallback.jsonc
  • config/opencode/opencode-fallback.tpl.jsonc
  • config/opencode/opencode.jsonc
  • config/opencode/opencode.tpl.jsonc
  • scripts/llm-update.sh
  • spec/llm_update_spec.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant