Skip to content

fix: add google provider model transform across all resolution paths#1917

Open
feelsodev wants to merge 3 commits intocode-yeongyu:devfrom
feelsodev:fix/google-provider-model-transform
Open

fix: add google provider model transform across all resolution paths#1917
feelsodev wants to merge 3 commits intocode-yeongyu:devfrom
feelsodev:fix/google-provider-model-transform

Conversation

@feelsodev
Copy link

@feelsodev feelsodev commented Feb 17, 2026

Summary

transformModelForProvider() only handled the github-copilot provider, leaving google provider models untransformed. This caused ProviderModelNotFoundError when google/gemini-3-flash was sent to Google's API — the correct model ID is gemini-3-flash-preview.

Problem

When the model resolution pipeline resolves gemini-3-flash for the google provider, it passes through transformModelForProvider() without transformation. Multiple code paths allow the raw model ID to reach the API:

  1. Config generation (model-fallback.ts): resolveModelFromChaintransformModelForProvider("google", "gemini-3-flash") → returns unchanged → writes google/gemini-3-flash to config
  2. Runtime category-default (model-resolution-pipeline.ts): When availableModels is empty but connected provider exists, normalizedCategoryDefault is returned as-is without transformation
  3. First-run fallback (model-resolution.ts): getFirstFallbackModel() constructs ${provider}/${entry.model} without calling transformModelForProvider
  4. GitHub Copilot gemini models: The existing .replace() calls for gemini transforms were vulnerable to double-transformation (gemini-3-pro-previewgemini-3-pro-preview-preview)

Fix

1. Centralized transform function (shared/provider-model-id-transform.ts)

  • Added google provider handling with idempotent regex negative lookahead (?!-) to prevent double -preview suffix
  • Fixed github-copilot provider gemini transforms to also use idempotent regex (was using plain .replace())
  • Single source of truth — imported by both CLI and shared layers (no code duplication)

2. Runtime category-default path (shared/model-resolution-pipeline.ts)

  • When availableModels.size === 0 and connected provider exists, now applies transformModelForProvider before returning the category default model

3. First-run fallback path (agents/builtin-agents/model-resolution.ts)

  • getFirstFallbackModel() now applies transformModelForProvider when constructing the model ID on first run with no cache

Tests

20 new test cases across 2 files:

Unit tests (src/cli/provider-model-id-transform.test.ts) — 15 total

  • Google provider: flash/pro transforms, passthrough for other models, double-transform prevention
  • GitHub Copilot provider: claude transforms, gemini transforms, double-transform prevention (new)
  • Unknown provider: passthrough behavior

Runtime integration tests (src/shared/model-resolver.test.ts) — 5 new

  • Google category-default transform (gemini-3-progemini-3-pro-preview)
  • Google category-default transform for flash variant
  • Double-transform prevention through full resolution pipeline
  • Google fallback-chain transform through runtime pipeline
  • Non-gemini-3 model passthrough (no false positives)

Existing tests

  • Updated snapshot expectations (22 snapshots reflect correct google transforms)
  • Updated existing category-default test to expect transformed model ID
  • All 104 tests passing (20 new + 84 existing)

Files Changed

File Change
src/shared/provider-model-id-transform.ts Add google provider, idempotent regex for both providers
src/shared/model-resolution-pipeline.ts Apply transform in category-default connected-provider path
src/agents/builtin-agents/model-resolution.ts Apply transform in getFirstFallbackModel() first-run path
src/cli/provider-model-id-transform.ts Re-export from shared (entry point for CLI)
src/cli/provider-model-id-transform.test.ts 15 unit tests including double-transform prevention
src/shared/model-resolver.test.ts 5 runtime integration tests
src/cli/__snapshots__/model-fallback.test.ts.snap Updated 22 snapshots

@github-actions
Copy link
Contributor

github-actions bot commented Feb 17, 2026

All contributors have signed the CLA. Thank you! ✅
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.

No issues found across 3 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Requires human review: Large changes and new tests added, but 100% regression safety isn't guaranteed yet.

@feelsodev feelsodev force-pushed the fix/google-provider-model-transform branch 2 times, most recently from 7eaa45d to dcfb82b Compare February 17, 2026 12:22
@feelsodev
Copy link
Author

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

github-actions bot added a commit that referenced this pull request Feb 17, 2026
…ew suffix

transformModelForProvider only handled github-copilot provider, leaving
google provider models untransformed. This caused ProviderModelNotFoundError
when google/gemini-3-flash was sent to the API (correct ID is
gemini-3-flash-preview).

Add google provider block with -preview suffix guard to prevent double
transformation.
@feelsodev feelsodev force-pushed the fix/google-provider-model-transform branch from dcfb82b to 57188fa Compare February 17, 2026 12:57
feelsodev and others added 2 commits February 17, 2026 22:18
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
transformModelForProvider only handled github-copilot provider, leaving
google provider models untransformed. This caused ProviderModelNotFoundError
when google/gemini-3-flash was sent to the API (correct ID is
gemini-3-flash-preview).

Changes:
- Add google provider to transformModelForProvider with idempotent regex
  negative lookahead to prevent double -preview suffix
- Fix category-default path in model-resolution-pipeline when
  availableModels is empty but connected provider exists
- Fix getFirstFallbackModel first-run path that constructed raw model IDs
  without transformation
- Fix github-copilot provider gemini transforms to also use idempotent
  regex (was vulnerable to double-transform)
- Extract transformModelForProvider to shared module (single source of
  truth, imported by cli and shared layers)
- Add 20 new test cases: unit tests for both providers, runtime
  integration tests for category-default and fallback-chain paths,
  double-transform prevention for both providers
@feelsodev feelsodev force-pushed the fix/google-provider-model-transform branch from db1b74d to 63d994f Compare February 17, 2026 13:23
@feelsodev feelsodev changed the title fix: add google provider model transform for gemini-3-flash/pro preview suffix fix: add google provider model transform across all resolution paths Feb 17, 2026
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.

1 issue found across 5 files (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/cli/provider-model-id-transform.ts">

<violation number="1" location="src/cli/provider-model-id-transform.ts:1">
P1: GitHub Copilot provider missing suffix guard causing double-preview suffix bug</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

}
return model
}
export { transformModelForProvider } from "../shared/provider-model-id-transform"
Copy link

@cubic-dev-ai cubic-dev-ai bot Feb 17, 2026

Choose a reason for hiding this comment

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

P1: GitHub Copilot provider missing suffix guard causing double-preview suffix bug

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/cli/provider-model-id-transform.ts, line 1:

<comment>GitHub Copilot provider missing suffix guard causing double-preview suffix bug</comment>

<file context>
@@ -1,20 +1 @@
-	}
-	return model
-}
+export { transformModelForProvider } from "../shared/provider-model-id-transform"
</file context>
Fix with Cubic

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for flagging this! This is actually a false positive though 😄

The old code in src/cli/provider-model-id-transform.ts used plain .replace() which was indeed vulnerable to double-transform (gemini-3-pro-previewgemini-3-pro-preview-preview). But that's exactly what this PR fixes!

The implementation was moved to src/shared/provider-model-id-transform.ts, and it now uses idempotent regex with negative lookahead (?!-):

.replace(/gemini-3-pro(?!-)/g, "gemini-3-pro-preview")
.replace(/gemini-3-flash(?!-)/g, "gemini-3-flash-preview")

This ensures:

  • gemini-3-pro → matches (no - follows) → gemini-3-pro-preview
  • gemini-3-pro-preview → does NOT match (- follows pro) → stays unchanged ✅

Both github-copilot and google providers use the same idempotent regex, and there are explicit test cases covering double-transform prevention for both providers (see provider-model-id-transform.test.ts lines 67-89, 129-151).

The CLI file is now just a re-export — the actual guard lives in the shared module. No issue here!

Copy link
Author

Choose a reason for hiding this comment

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

@cubic-dev-ai review

Copy link

Choose a reason for hiding this comment

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

@feelsodev I have started the AI code review. It will take a few minutes to complete.

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.

No issues found across 8 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Auto-approved: Comprehensive tests ensure correct model transformations with no regressions detected by AI review.

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

Comments