Releases: Agent-Pattern-Labs/opencode-model-fallback
Release v0.3.2
fix: detect rate-limit and billing errors in text parts for fallback
classifyErrorType only classified missing_api_key and model_not_found, so when opencode didn't populate info.error on message.updated events (which happens for FreeUsageLimitError and Insufficient balance), the text-scanning fallback path missed them.
classifyErrorTypenow checksRETRYABLE_ERROR_PATTERNS→ returns"rate_limit"detectErrorInTextPartsdirectly checksRETRYABLE_ERROR_PATTERNSas a last resort
v0.3.1 — Agent MD frontmatter support
Bug fix: read fallback_models from agent.options (MD frontmatter shape)
When agents are defined in .opencode/agents/<name>.md YAML frontmatter (the pattern used by harness-based opencode projects that ship agents via symlinks), opencode relocates unknown frontmatter keys into a nested `options` sub-object before the plugin sees the merged config. Before this release, the plugin only read `agentConfig.fallback_models` at the top level — so frontmatter-authored chains silently resolved to empty.
After 0.3.1, both shapes work:
```json
// opencode.json — explicit top-level (existing behavior, still works)
{
"agent": {
"coder": {
"fallback_models": ["openai/gpt-5.4"]
}
}
}
```
```yaml
.opencode/agents/coder.md — frontmatter (new in 0.3.1)
model: anthropic/claude-opus-4-6
fallback_models:
- openai/gpt-5.4
- kimi-for-coding/k2p5
```
Top-level entries win over frontmatter when both are set, so consumers can override upstream-shipped chains via their own `opencode.json`.
Source reference
Opencode's config merge happens at `packages/opencode/src/config/config.ts:536-540` — unknown frontmatter keys get folded into `agent.options` via the schema's `.catchall` transform. The plugin's `config` hook receives the fully-merged `cfg` object after this relocation runs.
Tests
- 390/390 pass (3 new: MD frontmatter shape, both-shapes precedence, options-but-no-fallback_models)
v0.3.0 — First public @razroo release
First public release of @razroo/opencode-model-fallback. OpenCode plugin that rotates through a configured fallback_models chain when a model returns rate-limit / 5xx / known provider errors, then replays the in-flight request on the next model.
Features
- Per-agent fallback chains. Each agent in
opencode.jsoncan declare its ownfallback_models: [...]ordered list. - Global fallback chain. A single chain in
.opencode/opencode-model-fallback.json(c)applies to agents that don't declare their own. - Comprehensive error detection. HTTP status codes (429, 500, 502, 503, 504) + pattern-matching on error messages (
rate limit,overloaded,quota exceeded,insufficient credits, etc.) — works around opencode's error-prettifier sometimes stripping status codes. - TTFT timeout. Aborts models that produce no tokens within a configurable window (default 30s). Actively-streaming models are never interrupted.
- Cooldown + auto-recovery. Failed models enter a cooldown period (default 60s); the plugin automatically switches back to the primary once it recovers.
- Custom retryable patterns. Extend built-in error matching with your own regex patterns via
retryable_error_patterns: [...]. Invalid regexes warn once and skip. - Init-time validation. Malformed
fallback_modelsentries (not matchingprovider/modelformat) are flagged in the first log line instead of silently skipping at dispatch. - Structured logging to
~/.config/opencode/opencode-model-fallback.logwith trigger error, original model, fallback model, timestamp, and source event. 10MB rotation with single backup (.log.1). - Toast notifications on fallback events (opt-out via
notify_on_fallback: false). - Subagent result sync. Parent sessions correctly receive the fallback model's response when a child session rotates mid-execution.
Install
```bash
npm install @razroo/opencode-model-fallback
```
Configure
```json
{
"plugin": ["@razroo/opencode-model-fallback"],
"agent": {
"coder": {
"model": "anthropic/claude-opus-4-6",
"fallback_models": ["openai/gpt-5.4", "kimi-for-coding/k2p5"]
}
}
}
```
Optional tuning at .opencode/opencode-model-fallback.json or ~/.config/opencode/opencode-model-fallback.json:
```json
{
"enabled": true,
"cooldown_seconds": 60,
"timeout_seconds": 30,
"max_fallback_attempts": 10,
"notify_on_fallback": true,
"retryable_error_patterns": ["custom-pattern-here"]
}
```
Requirements
@opencode-ai/plugin>= 1.1.19 (peer)@opencode-ai/sdk(optional peer, required only if you use compaction-model fallback)- Node >= 18
Notes
- Built with Bun; ships pre-compiled
dist/— no build step at install time. - 387 tests across 13 test files. See
src/*.test.ts.