feat: launch Gemini 3 in Gemini CLI 🚀🚀🚀 (in main) (#13287)

Co-authored-by: Adam Weidman <65992621+adamfweidman@users.noreply.github.com>
Co-authored-by: Sehoon Shon <sshon@google.com>
Co-authored-by: Adib234 <30782825+Adib234@users.noreply.github.com>
Co-authored-by: Sandy Tao <sandytao520@icloud.com>
Co-authored-by: Abhi <43648792+abhipatel12@users.noreply.github.com>
Co-authored-by: Aishanee Shah <aishaneeshah@gmail.com>
Co-authored-by: gemini-cli-robot <gemini-cli-robot@google.com>
Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
Co-authored-by: Jacob Richman <jacob314@gmail.com>
Co-authored-by: joshualitt <joshualitt@google.com>
Co-authored-by: Jenna Inouye <jinouye@google.com>
This commit is contained in:
Shreya Keshive
2025-11-18 12:01:16 -05:00
committed by GitHub
parent 78075c8a37
commit 86828bb561
79 changed files with 3148 additions and 605 deletions

View File

@@ -6,9 +6,19 @@
import type { Config } from '../config/config.js';
import { AuthType } from '../core/contentGenerator.js';
import { DEFAULT_GEMINI_FLASH_MODEL } from '../config/models.js';
import {
DEFAULT_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL,
} from '../config/models.js';
import { logFlashFallback, FlashFallbackEvent } from '../telemetry/index.js';
import { coreEvents } from '../utils/events.js';
import { openBrowserSecurely } from '../utils/secure-browser-launcher.js';
import { debugLogger } from '../utils/debugLogger.js';
import { getErrorMessage } from '../utils/errors.js';
import { ModelNotFoundError } from '../utils/httpErrors.js';
const UPGRADE_URL_PAGE = 'https://goo.gle/set-up-gemini-code-assist';
export async function handleFallback(
config: Config,
@@ -19,7 +29,31 @@ export async function handleFallback(
// Applicability Checks
if (authType !== AuthType.LOGIN_WITH_GOOGLE) return null;
const fallbackModel = DEFAULT_GEMINI_FLASH_MODEL;
// Guardrail: If it's a ModelNotFoundError but NOT the preview model, do not handle it.
if (
error instanceof ModelNotFoundError &&
failedModel !== PREVIEW_GEMINI_MODEL
) {
return null;
}
// Preview Model Specific Logic
if (failedModel === PREVIEW_GEMINI_MODEL) {
// Always set bypass mode for the immediate retry.
// This ensures the next attempt uses 2.5 Pro.
config.setPreviewModelBypassMode(true);
// If we are already in Preview Model fallback mode (user previously said "Always"),
// we silently retry (which will use 2.5 Pro due to bypass mode).
if (config.isPreviewModelFallbackMode()) {
return true;
}
}
const fallbackModel =
failedModel === PREVIEW_GEMINI_MODEL
? DEFAULT_GEMINI_MODEL
: DEFAULT_GEMINI_FLASH_MODEL;
// Consult UI Handler for Intent
const fallbackModelHandler = config.fallbackModelHandler;
@@ -35,11 +69,18 @@ export async function handleFallback(
// Process Intent and Update State
switch (intent) {
case 'retry':
// Activate fallback mode. The NEXT retry attempt will pick this up.
activateFallbackMode(config, authType);
case 'retry_always':
if (failedModel === PREVIEW_GEMINI_MODEL) {
activatePreviewModelFallbackMode(config);
} else {
activateFallbackMode(config, authType);
}
return true; // Signal retryWithBackoff to continue.
case 'retry_once':
// Just retry this time, do NOT set sticky fallback mode.
return true;
case 'stop':
activateFallbackMode(config, authType);
return false;
@@ -47,6 +88,10 @@ export async function handleFallback(
case 'retry_later':
return false;
case 'upgrade':
await handleUpgrade();
return false;
default:
throw new Error(
`Unexpected fallback intent received from fallbackModelHandler: "${intent}"`,
@@ -58,6 +103,17 @@ export async function handleFallback(
}
}
async function handleUpgrade() {
try {
await openBrowserSecurely(UPGRADE_URL_PAGE);
} catch (error) {
debugLogger.warn(
'Failed to open browser automatically:',
getErrorMessage(error),
);
}
}
function activateFallbackMode(config: Config, authType: string | undefined) {
if (!config.isInFallbackMode()) {
config.setFallbackMode(true);
@@ -67,3 +123,10 @@ function activateFallbackMode(config: Config, authType: string | undefined) {
}
}
}
function activatePreviewModelFallbackMode(config: Config) {
if (!config.isPreviewModelFallbackMode()) {
config.setPreviewModelFallbackMode(true);
// We might want a specific event for Preview Model fallback, but for now we just set the mode.
}
}