feat: add customizable fallback chains and improved model matching#1307
feat: add customizable fallback chains and improved model matching#1307wydrox wants to merge 1 commit intocode-yeongyu:devfrom
Conversation
- Add fallback_chain config option to agents and categories schema
- Implement model ID normalization to match prefixed models (e.g., antigravity-*)
- Add getEffectiveFallbackChain and getEffectiveCategoryFallbackChain functions
- Update resolveVariantForModel to use user-defined fallback chains
- Fall back to user config variant when model-based resolution fails
- Add comprehensive tests for new functionality
This allows users to define custom fallback chains in oh-my-opencode.json:
```json
{
"agents": {
"sisyphus": {
"fallback_chain": [
{ "providers": ["google"], "model": "gemini-3-pro", "variant": "max" }
]
}
}
}
```
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA). To sign the CLA, please comment on this PR with: This is a one-time requirement. Once signed, all your future contributions will be automatically accepted. I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
There was a problem hiding this comment.
2 issues found across 4 files
Confidence score: 3/5
- There is a concrete logic risk in
src/shared/agent-variant.ts:findVariantInChaincan choose a provider match even when the model mismatches, which may apply an incompatible variant and skip later fallbacks. - Overall risk is moderate because the main issue could affect variant selection at runtime; the schema duplication in
src/config/schema.tsis low impact and mostly maintenance-related. - Pay close attention to
src/shared/agent-variant.ts- variant selection fallback may ignore model constraints.
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/config/schema.ts">
<violation number="1" location="src/config/schema.ts:133">
P2: `fallback_chain` schema is duplicated in two places; consider extracting a shared schema constant to avoid divergence when the shape changes.</violation>
</file>
<file name="src/shared/agent-variant.ts">
<violation number="1" location="src/shared/agent-variant.ts:120">
P2: findVariantInChain still falls back to the first provider match even when the model does not match. This ignores model constraints and can apply an incompatible variant, preventing later category/agent fallbacks from being tried.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| /** Provider-specific options. Passed directly to OpenCode SDK. */ | ||
| providerOptions: z.record(z.string(), z.unknown()).optional(), | ||
| /** Custom fallback chain for model resolution. Overrides built-in agent fallback chains. */ | ||
| fallback_chain: z.array(z.object({ |
There was a problem hiding this comment.
P2: fallback_chain schema is duplicated in two places; consider extracting a shared schema constant to avoid divergence when the shape changes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/config/schema.ts, line 133:
<comment>`fallback_chain` schema is duplicated in two places; consider extracting a shared schema constant to avoid divergence when the shape changes.</comment>
<file context>
@@ -129,6 +129,12 @@ export const AgentOverrideConfigSchema = z.object({
/** Provider-specific options. Passed directly to OpenCode SDK. */
providerOptions: z.record(z.string(), z.unknown()).optional(),
+ /** Custom fallback chain for model resolution. Overrides built-in agent fallback chains. */
+ fallback_chain: z.array(z.object({
+ providers: z.array(z.string()),
+ model: z.string(),
</file context>
| @@ -1,6 +1,44 @@ | |||
| import type { OhMyOpenCodeConfig } from "../config" | |||
There was a problem hiding this comment.
P2: findVariantInChain still falls back to the first provider match even when the model does not match. This ignores model constraints and can apply an incompatible variant, preventing later category/agent fallbacks from being tried.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/shared/agent-variant.ts, line 120:
<comment>findVariantInChain still falls back to the first provider match even when the model does not match. This ignores model constraints and can apply an incompatible variant, preventing later category/agent fallbacks from being tried.</comment>
<file context>
@@ -35,30 +73,61 @@ export function resolveVariantForModel(
providerID: string,
+ modelID?: string,
): string | undefined {
+ for (const entry of fallbackChain) {
+ if (entry.providers.includes(providerID)) {
+ if (modelID && entry.model) {
</file context>
|
Thank you for this contribution! Unfortunately, I need to close this PR for the following reasons:
That said, this is a valuable feature request! The idea of:
...are all excellent additions that would be useful for users with custom model routing setups. If you'd like to continue:
Feel free to reopen if you'd like to continue working on this! |
|
Sure! Let me work on it. I have read the CLA Document and I hereby sign the CLA |
|
I have addressed all the issues:
Verified with bun test v1.3.5 (1e86cebd). All 25 tests passed. |
Summary
This PR adds support for customizable fallback chains and improves model ID matching to handle prefixed models (like
antigravity-*).Problem
model-requirements.tsantigravity-gemini-3-proSolution
oh-my-opencode.json:{ "agents": { "sisyphus": { "fallback_chain": [ { "providers": ["google"], "model": "gemini-3-pro", "variant": "max" } ] } }, "categories": { "ultrabrain": { "fallback_chain": [ { "providers": ["google"], "model": "gemini-3-pro", "variant": "high" } ] } } }Model ID normalization - Strips common routing prefixes (
antigravity-,proxy-,custom-) when matching models, soantigravity-gemini-3-promatchesgemini-3-proin fallback chains.Improved variant fallback - When model-based resolution fails, falls back to:
Changes
src/config/schema.ts: Addedfallback_chainoption toAgentOverrideConfigSchemaandCategoryConfigSchemasrc/shared/model-requirements.ts: AddedgetEffectiveFallbackChainandgetEffectiveCategoryFallbackChainfunctionssrc/shared/agent-variant.ts:normalizeModelIdandmodelMatchesfunctions for prefix-aware matchingresolveVariantForModelto use user-defined fallback chainssrc/shared/agent-variant.test.ts: Added comprehensive tests for new functionalityTesting
All 19 tests pass including 6 new tests:
antigravity-prefixSummary by cubic
Adds customizable fallback chains for agent/category variant resolution and prefix-aware model matching. Models routed via proxies (e.g., antigravity-gemini-3-pro) now resolve to the intended base model and variant.
New Features
Migration
Written for commit b4ef893. Summary will update on new commits.