Repository navigation
Feat/gemini 3.8 flash 3.5 flash lite - #29443
Conversation
|
📊 PR Size: size/XL
|
Summary of ChangesHello, 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 integrates the latest Gemini Flash models (3.8 Flash and 3.5 Flash Lite) into the system. It updates the core model configuration, routing strategies, and backend mapping logic to support these new tiers while maintaining backward compatibility. The changes include new experiment-gated access flags, updated quota normalization, and comprehensive adjustments to the CLI and core services to ensure seamless model selection and fallback behavior. Highlights
Using Gemini Code AssistThe 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
Customization To customize the 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 Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. 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
|
There was a problem hiding this comment.
Code Review
This pull request refactors the model configuration system to support dynamic resolution of 'Latest' Flash and Flash Lite models, replacing hardcoded versioned references with configurable aliases. It updates multiple files across the codebase to implement this logic and adds test utilities to manage model state. The reviewer identified critical architectural and security concerns regarding the use of global mutable state for model defaults, which could lead to concurrency race conditions and experiment gate bypasses in multi-session environments.
Note: Security Review did not run due to the size of the PR.
|
Size Change: +9.76 kB (+0.03%) Total Size: 35.4 MB
ℹ️ View Unchanged
|
adamfweidman
left a comment
There was a problem hiding this comment.
Code Review Summary: LGTM with minor feedback
PR looks great overall. The promotion of Gemini 3.8 Flash (gemini-3.8-flash) and Gemini 3.5 Flash Lite (gemini-3.5-flash-lite) to the latest GA tiers is clean and well-structured, and permanently moving users off older tiers (3.1 / 2.5) onto 3.5 Flash / 3.8 Flash as the new standard makes complete sense.
Approving to unblock landing quickly. Leaving several minor inline observations, suggestions, and test cleanups for consideration (none are release-blocking):
chatCompressionService.ts: Consider addingcase BASE_GEMINI_FLASH_LITE_MODEL:alongsideLATEST_so any legacy session explicitly referencing 3.1-flash-lite doesn't fall through to default.flagNames.ts: If external packages consumeGEMINI_3_5_FLASH_GA_LAUNCHED, consider keeping its original ID45780819on the deprecated alias.- Tests & Isolation: A few test assertions use the mutable
DEFAULT_GEMINI_FLASH_MODELbinding rather than literal'gemini-3.5-flash'. Consider hoistingresetModelsForTesting()intoafterEachat file level for clean test isolation.
| }, | ||
| }, | ||
| }, | ||
|
|
There was a problem hiding this comment.
Stray blank line inserted between the condition and target properties of the ModelResolution context item. It is unrelated to the flag rename and Prettier preserves single blank lines, so it persists as diff noise in this definition block. Remove it.
| const useLatestFlash = config?.hasLatestFlashGAAccess?.() ?? false; | ||
| const useLatestFlashLite = config?.hasLatestFlashLiteGAAccess?.() ?? false; |
There was a problem hiding this comment.
No UI test coverage for the two new capability flags. packages/cli/src/ui/components/ModelDialog.test.tsx never stubs hasLatestFlashGAAccess/hasLatestFlashLiteGAAccess (its MockConfig interface and mockConfig object only define getGemini31LaunchedSync, getHasAccessToPreviewModel, getProModelNoAccess*), so both optional calls silently resolve to false in every test and neither the dynamic-path getAvailableModelOptions arguments nor the legacy auto description are exercised with the flags on. The gap is compounded by the test's getAutoModelDescription mock, which only interpolates hasAccessToPreview and useGemini3_1 and drops the third (useLatestFlash) argument, so even an enabled flag would produce an identical rendered string. Add mocks for both getters plus assertions that the latest Flash / Flash Lite options and the auto description change when they return true; otherwise this behavior is only validated by the manual /model step in the PR description.
| const useLatestFlash = config?.hasLatestFlashGAAccess?.() ?? false; | ||
| const useLatestFlashLite = config?.hasLatestFlashLiteGAAccess?.() ?? false; |
There was a problem hiding this comment.
hasLatestFlashGAAccess and hasLatestFlashLiteGAAccess are declared as required (non-optional) methods on Config (packages/core/src/config/config.ts:3596, :3628), so the ?.() call guard is dead defensiveness that only masks incomplete test doubles — it is precisely what lets ModelDialog.test.tsx pass without ever defining these methods. Prefer calling them directly so a missing/renamed method fails loudly.
Proposed suggestion:
const useLatestFlash = config?.hasLatestFlashGAAccess() ?? false;
const useLatestFlashLite = config?.hasLatestFlashLiteGAAccess() ?? false;| normalizeModelId(PREVIEW_GEMINI_MODEL), | ||
| normalizeModelId(PREVIEW_GEMINI_FLASH_MODEL), |
There was a problem hiding this comment.
This fallback-target assertion no longer pins a concrete model. PREVIEW_GEMINI_FLASH_MODEL is now an exported mutable let (models.ts:65) that production code rewrites at runtime: resolvePolicyChain calls config.hasLatestFlashGAAccess() (policyHelpers.ts:58), which calls setFlashModels(...) (config.ts:3608-3616) during this very test. Because the expected value is read from the same live binding the code under test mutates, a regression that changes the fallback target (e.g. flash resolving to gemini-3.8-flash) would change both sides and the assertion would still pass. Pin the expected IDs literally (they are deterministic here: no experiments + LOGIN_WITH_GOOGLE => flag off).
Proposed suggestion:
'gemini-3-pro-preview',
'gemini-3-flash-preview',| let client: BaseLlmClient; | ||
|
|
||
| beforeEach(() => { | ||
| resetModelsForTesting(); |
There was a problem hiding this comment.
resetModelsForTesting() was added because the Flash constants are now mutated by hasLatestFlashGAAccess(), but no case in this file exercises the flag-on path. Every test here runs with LATEST_FLASH_GA_LAUNCHED off (no experiments, LOGIN_WITH_GOOGLE), so the new gemini-3.8-flash fallback target introduced by this PR is untested, even though the PR description lists this file as the validation for "fallback chains ... across access conditions". Add a case that stubs Config.prototype.hasLatestFlashGAAccess (or the experiment flag) to true and asserts the Pro -> latest-Flash chain resolves to gemini-3.8-flash.
| const useLatestFlash = config.hasLatestFlashGAAccess?.() ?? false; | ||
| const useLatestFlashLite = config.hasLatestFlashLiteGAAccess?.() ?? false; |
There was a problem hiding this comment.
These two locals duplicate logic that resolveClassifierModel already performs internally: it computes effectiveUseLatestFlash = useLatestFlash || (config?.hasLatestFlashGAAccess?.() ?? false) || ... (and the flash-lite equivalent) in models.ts:388-395, using the very same config instance passed as the 6th argument on line 196. Reading the flags here and forwarding them as arguments 7/8 is a no-op that spreads the access-check across two places, so a future change to the resolution rule in models.ts leaves an independent copy here. Consider dropping these locals and the two trailing arguments and letting resolveClassifierModel derive them from config (same applies to the sibling strategies touched in this PR). Separately, config is typed as Config, where both methods are non-optional, so the ?.() guards only serve to mask incomplete test mocks rather than a real runtime case.
| useCustomTools?: boolean; | ||
| hasAccessToPreview?: boolean; | ||
| /** Matches if the current model is in this list. */ | ||
| hasAccessToProModel?: boolean; |
There was a problem hiding this comment.
Adding hasAccessToProModel here deleted the pre-existing doc comment /** Matches if the current model is in this list. */ that documented requestedModels on the next line. Restore it; unrelated documentation should not be dropped.
Proposed suggestion:
hasAccessToProModel?: boolean;
/** Matches if the current model is in this list. */| const shouldShowPreviewModels = context.hasAccessToPreview ?? false; | ||
| const useGemini31 = context.useGemini3_1 ?? false; | ||
| const useGemini3_5Flash = context.useGemini3_5Flash ?? false; | ||
| const useLatestFlash = context.useLatestFlash ?? false; |
There was a problem hiding this comment.
Inconsistent handling of the deprecated alias. matches() (lines 270-277) explicitly honors context.useGemini3_5Flash as a fallback for context.useLatestFlash, but here the deprecated field is ignored, so a caller that still passes only useGemini3_5Flash gets resolveModelId() routing to the latest Flash model while getAutoModelDescription() is told the latest Flash is off — the dialog description and the resolved model disagree. Apply the same fallback.
Proposed suggestion:
const useLatestFlash =
context.useLatestFlash ?? context.useGemini3_5Flash ?? false;| case 'useLatestFlashLite': | ||
| case 'useGemini3_1FlashLite': { | ||
| const actualValue = | ||
| key === 'useLatestFlashLite' | ||
| ? (context.useLatestFlashLite ?? context.useGemini3_1FlashLite) | ||
| : (context.useGemini3_1FlashLite ?? context.useLatestFlashLite); | ||
| return value === actualValue; | ||
| } | ||
| case 'useLatestFlash': | ||
| case 'useGemini3_5Flash': { | ||
| const actualValue = | ||
| key === 'useLatestFlash' | ||
| ? (context.useLatestFlash ?? context.useGemini3_5Flash) | ||
| : (context.useGemini3_5Flash ?? context.useLatestFlash); | ||
| return value === actualValue; | ||
| } |
There was a problem hiding this comment.
New matching branches are untested. modelConfigService.test.ts only exercises useGemini3_5Flash (lines 1049-1117) against a context that sets the same key; there is no test for useLatestFlash/useLatestFlashLite conditions, nor for the new cross-alias fallback (e.g. condition { useLatestFlash: true } with context { useGemini3_5Flash: true }, and the reverse). These fallbacks are the entire back-compat contract for user-supplied modelIdResolutions, and they also change existing behavior: a condition { useGemini3_1FlashLite: false } now matches a context that only sets useLatestFlashLite: false (previously it compared against undefined and never matched). Please add tests covering both directions and the both-defined case.
| case 'hasAccessToProModel': | ||
| return value === context.hasAccessToProModel; |
There was a problem hiding this comment.
hasAccessToProModel is accepted as a ResolutionCondition key here, but it is not declared in the ModelResolution.contexts[].condition properties in packages/cli/src/config/settingsSchema.ts (lines 3523-3551), which this PR did update for useLatestFlash/useLatestFlashLite/the deprecated aliases. It is also not used by any resolution in defaultModelConfigs.ts and has no test. Either add it to the settings schema (and regenerate schemas/settings.schema.json + docs/reference/configuration.md) with a test, or drop this branch until a config needs it.
|
/patch |
|
🚀 [Step 1/4] Patch workflow(s) waiting for approval! 📋 Details:
⏳ Status: The patch creation workflow has been triggered and is waiting for deployment approval. Please visit the specific workflow links below and approve the runs. 🔗 Track Progress: |
|
🚀 [Step 2/4] Patch PR Created! 📋 Patch Details:
📝 Next Steps:
🔗 Track Progress: |
|
🚀 [Step 2/4] Patch PR Created! 📋 Patch Details:
📝 Next Steps:
🔗 Track Progress: |
|
🚀 [Step 3/4] Patch Release Waiting for Approval! 📋 Release Details:
⏳ Status: The patch release has been triggered and is waiting for deployment approval. Please visit the specific workflow run link below and approve the deployment. You'll receive another update when it completes. 🔗 Track Progress: |
|
❌ [Step 4/4] Patch Release Failed! 📋 Details:
🔍 Next Steps:
🔗 Troubleshooting: |
|
❌ [Step 4/4] Patch Release Failed! 📋 Details:
🔍 Next Steps:
🔗 Troubleshooting: |
|
✅ [Step 4/4] Patch Release Complete! 📦 Release Details:
🎉 Status: Your patch has been successfully released and published to npm! 📝 What's Available:
🔗 Links: |
Summary
This PR adds support for Gemini 3.8 Flash (
gemini-3.8-flash) and Gemini 3.5 Flash Lite (gemini-3.5-flash-lite) as the latest GA models in the Flash and Flash Lite tiers, promotinggemini-3.5-flashandgemini-3.1-flash-liteto the base tiers.Key updates include:
LATEST_FLASH_GA_LAUNCHED(Flag ID:45842815) andLATEST_FLASH_LITE_GA_LAUNCHED(Flag ID:45827489).USE_GEMINI,USE_VERTEX_AI, andGATEWAY).Details
Model Hierarchy & Constants (
packages/core/src/config/models.ts):BASE_GEMINI_FLASH_MODEL(gemini-3.5-flash) andLATEST_GEMINI_FLASH_MODEL(gemini-3.8-flash).BASE_GEMINI_FLASH_LITE_MODEL(gemini-3.1-flash-lite) andLATEST_GEMINI_FLASH_LITE_MODEL(gemini-3.5-flash-lite).LEGACY_CCPA_FLASH_MODEL(gemini-3-flash) and backwards-compatible aliases (DEFAULT_GEMINI_3_5_FLASH_MODEL,SECONDARY_GEMINI_3_5_FLASH_MODEL,DEFAULT_GEMINI_FLASH_LITE_MODEL).resetModelsForTesting()to cleanly reset mutable module constants between test runs and eliminate state leakage.Experiment Flag Evaluation & Non-Flag Auth Types (
packages/core/src/config/config.ts):hasLatestFlashGAAccess()andhasLatestFlashLiteGAAccess().USE_GEMINI,USE_VERTEX_AI,GATEWAY) bypass experiment flag checks and automatically receive access togemini-3.8-flashandgemini-3.5-flash-lite.LOGIN_WITH_GOOGLE/ Code Assist) checkLATEST_FLASH_GA_LAUNCHEDandLATEST_FLASH_LITE_GA_LAUNCHED.hasGemini35FlashGAAccess()andGEMINI_3_5_FLASH_GA_LAUNCHEDmappings for backward compatibility.Dynamic Outbound Backend Request Mapping (
packages/core/src/core/contentGenerator.ts,modelMappingContentGenerator.ts):ModelMappingContentGeneratorto support dynamic getter functions (() => Record<string, string>) to evaluate mappings per request.gemini-3.5-flash/gemini-3-flashtogemini-3.8-flashwhen the latest flash flag is enabled, and mapsgemini-3.5-flashtogemini-3-flashfor Code Assist when disabled.gemini-3.1-flash-litetogemini-3.5-flash-litewhen the latest flash lite flag is enabled.Quota Tracking & Bucket Normalization (
packages/core/src/config/config.ts):gemini-3-flash,gemini-3.5-flash, andgemini-3.8-flashto either latest or base Flash depending on access, and similarly normalizes Flash Lite buckets.Routing, Context Compression, UI, and Schema:
packages/core/src/config/defaultModelConfigs.tsandschemas/settings.schema.jsonwith conditional contexts foruseLatestFlashanduseLatestFlashLiteacross aliases (flash,flash-lite,auto, etc.).ApprovalModeStrategy,ClassifierStrategy,GemmaClassifierStrategy,NumericalClassifierStrategy,DefaultStrategy,FallbackStrategy, andOverrideStrategyto propagate latest model capabilities.chatCompressionService.tsto route compression forgemini-3.8-flashandgemini-3.5-flash-lite.ModelDialog.tsxto surface correct model availability options and descriptions.docs/reference/configuration.mdwith new model configurations and condition schemas.Related Issues
Related to #29164, #28802
How to Validate
Run Core Model & Configuration Tests:
npm test -w @google/gemini-cli-core -- src/config/config.test.ts src/config/models.test.tsExpected: All tests pass, validating model resolution, quota normalization, and experiment flag logic.
Verify Non-Flag Auth Type Access:
Expected: Confirms that
USE_GEMINI,USE_VERTEX_AI, andGATEWAYreturntrueand configuregemini-3.8-flashandgemini-3.5-flash-liteeven when experiment flags are false.Verify Routing & Fallback Integration Tests:
npm test -w @google/gemini-cli-core -- src/availability/autoRoutingFallback.integration.test.ts src/availability/policyHelpers.test.ts src/context/chatCompressionService.test.tsExpected: Fallback chains, policy resolution, and compression models resolve correctly across access conditions.
Verify Outbound Model Mappings:
npm test -w @google/gemini-cli-core -- src/core/contentGenerator.test.tsExpected: Model mapping generator rewrites models appropriately for Code Assist and Gemini API pipelines.
Manual Verification via CLI Model Picker:
Open the model selection dialog (
/model) and confirmGemini 3.8 FlashandGemini 3.5 Flash Liteoptions display correctly and auto-selection routes to the expected tiers.Pre-Merge Checklist