Skip to content

fix(core): distinguish fallback chains and fix maxAttempts for auto vs explicit model selection#26163

Merged
adamfweidman merged 9 commits intomainfrom
fix/dynamic-routing-fallback-attempts
Apr 29, 2026
Merged

fix(core): distinguish fallback chains and fix maxAttempts for auto vs explicit model selection#26163
adamfweidman merged 9 commits intomainfrom
fix/dynamic-routing-fallback-attempts

Conversation

@adamfweidman
Copy link
Copy Markdown
Contributor

Summary

This PR addresses discrepancies between explicit model selections and auto-routing, specifically targeting the maxAttempts fall-through bug and ensuring consistent behavior for fallback chains.

Details

Previously, the routing logic forced any explicit selection of a Gemini 3 model into the auto-routing chains, limiting it to 3 attempts and silently downgrading to Flash on failure. Furthermore, a bug existed in geminiChat.ts where maxAttempts was resolved statically at the start of a turn, causing a model like Flash (which should have 10 attempts) to inherit Pro's 3-attempt limit if it fell back mid-turn.

This PR introduces the following changes:

  • Refactors policyCatalog.ts and defaultModelConfigs.ts to cleanly separate auto-routing logic from explicit selections using an isAutoSelection flag.
  • Introduces auto-preview and auto-default chains for dynamic model routing.
  • Auto-routing continues to use 3 attempts and silent sticky retries, while explicit selections now correctly default to 10 attempts and prompt before fallback.
  • Extracted duplicated auto-routing configuration to a shared AUTO_ROUTING_OVERRIDES constant in policyCatalog.ts.
  • Uses defensive short-circuiting (preferredModel && isAutoModel(preferredModel, config)) in policyHelpers.ts to evaluate the auto selection logic cleanly.
  • Updates geminiChat.ts to dynamically resolve currentMaxAttempts on each iteration of retryWithBackoff using the existing getAvailabilityContext callback, fixing the fallback limit inheritance bug.

Related Issues

How to Validate

  1. Run Vitest across gemini-cli-core (npm test -w @google/gemini-cli-core -- src/core/geminiChat.test.ts src/availability/policyHelpers.test.ts src/availability/policyCatalog.test.ts src/utils/retry.test.ts) to ensure strict parity between dynamic and legacy chains holds, and that retries evaluate dynamically.
  2. Select a model explicitly (e.g. --model gemini-3-pro-preview) and mock a persistent 429 error to verify it retries 10 times and prompts the user.
  3. Select --model auto and mock a persistent 429 error to verify it silently falls back to Flash after 3 attempts.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@adamfweidman adamfweidman requested a review from a team as a code owner April 29, 2026 03:55
@gemini-cli
Copy link
Copy Markdown
Contributor

gemini-cli Bot commented Apr 29, 2026

Hi @adamfweidman, thank you so much for your contribution to Gemini CLI! We really appreciate the time and effort you've put into this.

We're making some updates to our contribution process to improve how we track and review changes. Please take a moment to review our recent discussion post: Improving Our Contribution Process & Introducing New Guidelines.

Key Update: Starting January 26, 2026, the Gemini CLI project will require all pull requests to be associated with an existing issue. Any pull requests not linked to an issue by that date will be automatically closed.

Thank you for your understanding and for being a part of our community!

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses critical discrepancies in model routing and retry behavior. By decoupling auto-routing logic from explicit model selections and enabling dynamic resolution of retry limits, the changes ensure that models maintain their intended attempt thresholds even when falling back mid-turn. This improves the reliability of both automated and user-specified model interactions.

Highlights

  • Model Selection Logic: Refactored policy catalog to clearly distinguish between auto-routing and explicit model selections using an isAutoSelection flag.
  • Dynamic Retry Limits: Updated retry logic to dynamically resolve maxAttempts on each iteration, preventing models from inheriting incorrect attempt limits during fallback.
  • Fallback Behavior: Standardized auto-routing to use 3 attempts with silent retries, while explicit selections now correctly default to 10 attempts with user prompts.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 29, 2026

Size Change: +2.99 kB (+0.01%)

Total Size: 33.9 MB

Filename Size Change
./bundle/chunk-B5EYDN26.js 0 B -19.5 kB (removed) 🏆
./bundle/chunk-C6X7MEUZ.js 0 B -49.2 kB (removed) 🏆
./bundle/chunk-FHRSRKTR.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-KYZEOF3Z.js 0 B -3.8 kB (removed) 🏆
./bundle/chunk-KZ6AC35Y.js 0 B -3.43 kB (removed) 🏆
./bundle/chunk-OCFMZT2V.js 0 B -2.72 MB (removed) 🏆
./bundle/chunk-OGUBFKDI.js 0 B -655 kB (removed) 🏆
./bundle/chunk-VYW4BWTG.js 0 B -12.6 kB (removed) 🏆
./bundle/core-AGS6H7YH.js 0 B -48.2 kB (removed) 🏆
./bundle/devtoolsService-WZWBBVEM.js 0 B -28 kB (removed) 🏆
./bundle/gemini-3NLNOTQG.js 0 B -576 kB (removed) 🏆
./bundle/interactiveCli-EJPOBPZP.js 0 B -1.31 MB (removed) 🏆
./bundle/liteRtServerManager-KDIBDWV4.js 0 B -2.11 kB (removed) 🏆
./bundle/oauth2-provider-J7FYUO63.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-EP3TRFKH.js 655 kB +655 kB (new file) 🆕
./bundle/chunk-EZIH5TT6.js 12.6 kB +12.6 kB (new file) 🆕
./bundle/chunk-K5GBHEZX.js 19.5 kB +19.5 kB (new file) 🆕
./bundle/chunk-OMEH5QMC.js 3.8 kB +3.8 kB (new file) 🆕
./bundle/chunk-QGEM5WH6.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/chunk-VSM5VM64.js 3.43 kB +3.43 kB (new file) 🆕
./bundle/chunk-VWU22TJN.js 49.2 kB +49.2 kB (new file) 🆕
./bundle/chunk-ZWXWFBXT.js 2.72 MB +2.72 MB (new file) 🆕
./bundle/core-FTYHBWBA.js 48.2 kB +48.2 kB (new file) 🆕
./bundle/devtoolsService-D5LKATHJ.js 28 kB +28 kB (new file) 🆕
./bundle/gemini-MKXPINZ7.js 576 kB +576 kB (new file) 🆕
./bundle/interactiveCli-PFZROBIO.js 1.31 MB +1.31 MB (new file) 🆕
./bundle/liteRtServerManager-2FFGPMQW.js 2.11 kB +2.11 kB (new file) 🆕
./bundle/oauth2-provider-GZPASS4G.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size Change
./bundle/bundled/third_party/index.js 8 MB 0 B
./bundle/chunk-34MYV7JD.js 2.45 kB 0 B
./bundle/chunk-5AUYMPVF.js 858 B 0 B
./bundle/chunk-5PS3AYFU.js 1.18 kB 0 B
./bundle/chunk-664ZODQF.js 124 kB 0 B
./bundle/chunk-DAHVX5MI.js 206 kB 0 B
./bundle/chunk-IUUIT4SU.js 56.5 kB 0 B
./bundle/chunk-RJTRUG2J.js 39.8 kB 0 B
./bundle/chunk-XRLFHCHC.js 1.97 MB 0 B
./bundle/cleanup-QWAIIFVM.js 0 B -932 B (removed) 🏆
./bundle/devtools-36NN55EP.js 696 kB 0 B
./bundle/dist-T73EYRDX.js 356 B 0 B
./bundle/events-XB7DADIJ.js 418 B 0 B
./bundle/examples/hooks/scripts/on-start.js 188 B 0 B
./bundle/examples/mcp-server/example.js 1.43 kB 0 B
./bundle/gemini.js 5.1 kB 0 B
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB 0 B
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB 0 B
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB 0 B
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB 0 B
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB 0 B
./bundle/memoryDiscovery-FN3IAPBT.js 980 B 0 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 kB 0 B
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B 0 B
./bundle/sandbox-macos-permissive-open.sb 890 B 0 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB 0 B
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB 0 B
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB 0 B
./bundle/sandbox-macos-strict-open.sb 4.82 kB 0 B
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB 0 B
./bundle/src-QVCVGIUX.js 47 kB 0 B
./bundle/start-GAGTZPUS.js 0 B -652 B (removed) 🏆
./bundle/tree-sitter-7U6MW5PS.js 274 kB 0 B
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB 0 B
./bundle/cleanup-I2OHBANF.js 932 B +932 B (new file) 🆕
./bundle/start-5TMNRGCN.js 652 B +652 B (new file) 🆕

compressed-size-action

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements enhanced retry logic for auto-selected models, introducing a configurable maximum attempt count (defaulting to 3) and 'sticky' retry behavior for transient failures. The changes span the model availability service, policy configurations, and the core retry utility, which now dynamically retrieves the maximum allowed attempts from the active policy context. Additionally, error classification is updated to support name-based matching for cross-realm errors, and environment stubbing is added to tests for consistency. Review feedback highlights an opportunity to reduce redundant logic in policyHelpers.ts and suggests a performance optimization in the retry loop to avoid repeated expensive policy resolutions.

Comment thread packages/core/src/availability/policyHelpers.ts Outdated
Comment thread packages/core/src/utils/retry.ts
@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label Apr 29, 2026
@adamfweidman adamfweidman force-pushed the fix/dynamic-routing-fallback-attempts branch from f5ede9d to 55a14fd Compare April 29, 2026 13:03
@adamfweidman adamfweidman requested a review from a team as a code owner April 29, 2026 13:48
@adamfweidman adamfweidman added this pull request to the merge queue Apr 29, 2026
Merged via the queue into main with commit 3aedbbc Apr 29, 2026
26 of 27 checks passed
@adamfweidman adamfweidman deleted the fix/dynamic-routing-fallback-attempts branch April 29, 2026 20:37
TirthNaik-99 pushed a commit to TirthNaik-99/gemini-cli that referenced this pull request May 4, 2026
kimjune01 pushed a commit to kimjune01/gemini-cli-claude that referenced this pull request May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants