Skip to content

feat: add customizable fallback chains and improved model matching#1307

Closed
wydrox wants to merge 1 commit intocode-yeongyu:devfrom
wydrox:feature/customizable-fallback-chains
Closed

feat: add customizable fallback chains and improved model matching#1307
wydrox wants to merge 1 commit intocode-yeongyu:devfrom
wydrox:feature/customizable-fallback-chains

Conversation

@wydrox
Copy link

@wydrox wydrox commented Jan 31, 2026

Summary

This PR adds support for customizable fallback chains and improves model ID matching to handle prefixed models (like antigravity-*).

Problem

  • Fallback chains are hardcoded in model-requirements.ts
  • Variant resolution only works with exact provider/model matches
  • No support for custom model names like antigravity-gemini-3-pro
  • When using models through routing proxies (e.g., Antigravity), variant resolution fails because the model ID doesn't match exactly

Solution

  1. Customizable fallback chains - Users can now define their own fallback chains in 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" }
      ]
    }
  }
}
  1. Model ID normalization - Strips common routing prefixes (antigravity-, proxy-, custom-) when matching models, so antigravity-gemini-3-pro matches gemini-3-pro in fallback chains.

  2. Improved variant fallback - When model-based resolution fails, falls back to:

    • Category config variant (if agent has category)
    • Agent config variant (if set directly)

Changes

  • src/config/schema.ts: Added fallback_chain option to AgentOverrideConfigSchema and CategoryConfigSchema
  • src/shared/model-requirements.ts: Added getEffectiveFallbackChain and getEffectiveCategoryFallbackChain functions
  • src/shared/agent-variant.ts:
    • Added normalizeModelId and modelMatches functions for prefix-aware matching
    • Updated resolveVariantForModel to use user-defined fallback chains
  • src/shared/agent-variant.test.ts: Added comprehensive tests for new functionality

Testing

All 19 tests pass including 6 new tests:

  • Model matching with antigravity- prefix
  • User-defined agent fallback chains
  • User-defined category fallback chains
  • Fallback to agent variant
  • Fallback to category variant

Summary 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

    • Added fallback_chain to agents and categories in oh-my-opencode.json to override built-in chains.
    • Model matching strips antigravity-, proxy-, and custom- prefixes for provider/model matching.
    • Resolution order: agent user chain → category user chain → built-ins → category variant → agent variant.
  • Migration

    • Optional: define agents..fallback_chain or categories..fallback_chain with providers, model, and optional variant.

Written for commit b4ef893. Summary will update on new commits.

- 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" }
      ]
    }
  }
}
```
@github-actions
Copy link
Contributor

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:

I have read the CLA Document and I hereby sign the CLA

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.

Copy link

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

Choose a reason for hiding this comment

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

2 issues found across 4 files

Confidence score: 3/5

  • There is a concrete logic risk in src/shared/agent-variant.ts: findVariantInChain can 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.ts is 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({
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 31, 2026

Choose a reason for hiding this comment

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

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>
Fix with Cubic

@@ -1,6 +1,44 @@
import type { OhMyOpenCodeConfig } from "../config"
Copy link

@cubic-dev-ai cubic-dev-ai bot Jan 31, 2026

Choose a reason for hiding this comment

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

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>
Fix with Cubic

@code-yeongyu
Copy link
Owner

Thank you for this contribution!

Unfortunately, I need to close this PR for the following reasons:

  1. Merge Conflicts: This PR is in CONFLICTING state with the dev branch and has merge conflicts that need resolution.

  2. CLA Not Signed: The Contributor License Agreement has not been signed yet. Please comment I have read the CLA Document and I hereby sign the CLA to proceed.

  3. Code Review Issues: There are 2 issues identified by cubic-dev-ai review that need addressing:

    • Schema duplication in src/config/schema.ts
    • Logic issue in findVariantInChain where variant selection may ignore model constraints

That said, this is a valuable feature request! The idea of:

  • Customizable fallback chains via config
  • Model ID normalization for prefixed models (antigravity-, proxy-, custom-*)
  • Improved variant resolution logic

...are all excellent additions that would be useful for users with custom model routing setups.

If you'd like to continue:

  1. Sign the CLA
  2. Rebase your branch to resolve conflicts with the latest dev
  3. Address the review comments
  4. Reopen the PR

Feel free to reopen if you'd like to continue working on this!

@wydrox
Copy link
Author

wydrox commented Feb 1, 2026

Sure! Let me work on it. I have read the CLA Document and I hereby sign the CLA

@wydrox
Copy link
Author

wydrox commented Feb 3, 2026

I have addressed all the issues:

  1. Resolved merge conflicts with branch.
  2. Signed the CLA.
  3. Extracted shared in to deduplicate definitions.
  4. Fixed the logic bug in (now requires strict model matching when is defined).
  5. Added comprehensive edge case tests to covering model mismatches, chain ordering, and multi-provider entries.

Verified with bun test v1.3.5 (1e86cebd). All 25 tests passed.

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.

2 participants