diff --git a/packages/cli/src/acp/acpSessionManager.test.ts b/packages/cli/src/acp/acpSessionManager.test.ts
index 8629e3642b..562b8dd70c 100644
--- a/packages/cli/src/acp/acpSessionManager.test.ts
+++ b/packages/cli/src/acp/acpSessionManager.test.ts
@@ -243,6 +243,27 @@ describe('AcpSessionManager', () => {
);
});
+ it('should NOT include retired preview models (none) in available models', async () => {
+ mockConfig.getContentGeneratorConfig = vi.fn().mockReturnValue({
+ apiKey: 'test-key',
+ });
+ mockConfig.getHasAccessToPreviewModel = vi.fn().mockReturnValue(true);
+ mockConfig.getGemini31LaunchedSync = vi.fn().mockReturnValue(true);
+ mockConfig.getGemini31FlashLiteLaunchedSync = vi.fn().mockReturnValue(true);
+
+ const response = await manager.newSession(
+ {
+ cwd: '/tmp',
+ mcpServers: [],
+ },
+ {},
+ );
+
+ const modelIds =
+ response.models?.availableModels?.map((m) => m.modelId) ?? [];
+ expect(modelIds).not.toContain('none');
+ });
+
it('should return modes with plan mode when plan is enabled', async () => {
mockConfig.getContentGeneratorConfig = vi.fn().mockReturnValue({
apiKey: 'test-key',
diff --git a/packages/cli/src/acp/acpUtils.ts b/packages/cli/src/acp/acpUtils.ts
index d0c7f26074..c9735fa7c7 100644
--- a/packages/cli/src/acp/acpUtils.ts
+++ b/packages/cli/src/acp/acpUtils.ts
@@ -336,7 +336,7 @@ export function buildAvailableModels(
},
];
- if (useGemini31FlashLite) {
+ if (useGemini31FlashLite && PREVIEW_GEMINI_FLASH_LITE_MODEL !== 'none') {
previewOptions.push({
value: PREVIEW_GEMINI_FLASH_LITE_MODEL,
title: getDisplayString(PREVIEW_GEMINI_FLASH_LITE_MODEL),
diff --git a/packages/cli/src/ui/components/ModelDialog.test.tsx b/packages/cli/src/ui/components/ModelDialog.test.tsx
index 2136fdb49b..0c30dc07cf 100644
--- a/packages/cli/src/ui/components/ModelDialog.test.tsx
+++ b/packages/cli/src/ui/components/ModelDialog.test.tsx
@@ -47,7 +47,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
mockModelSlashCommandEvent(model);
}
},
- PREVIEW_GEMINI_FLASH_LITE_MODEL: 'gemini-3.1-flash-lite',
+ PREVIEW_GEMINI_FLASH_LITE_MODEL: 'none',
};
});
@@ -159,7 +159,7 @@ describe('', () => {
// Verify order: Flash Preview -> Flash Lite (Preview/Default) -> Flash
const flashPreviewIdx = output.indexOf(PREVIEW_GEMINI_FLASH_MODEL);
- const flashLiteIdx = output.indexOf(PREVIEW_GEMINI_FLASH_LITE_MODEL);
+ const flashLiteIdx = output.indexOf(DEFAULT_GEMINI_FLASH_LITE_MODEL);
const flashIdx = output.indexOf(DEFAULT_GEMINI_FLASH_MODEL);
expect(flashPreviewIdx).toBeLessThan(flashLiteIdx);
@@ -449,7 +449,7 @@ describe('', () => {
unmount();
});
- it('shows Flash Lite Preview model regardless of tier when flag is enabled', async () => {
+ it('does not show Flash Lite Preview model when it is retired (none) even if flag is enabled', async () => {
mockGetProModelNoAccessSync.mockReturnValue(false);
mockGetProModelNoAccess.mockResolvedValue(false);
mockGetHasAccessToPreviewModel.mockReturnValue(true);
@@ -468,7 +468,8 @@ describe('', () => {
await waitUntilReady();
const output = lastFrame();
- expect(output).toContain(PREVIEW_GEMINI_FLASH_LITE_MODEL);
+ expect(output).not.toContain(PREVIEW_GEMINI_FLASH_LITE_MODEL);
+ expect(output).toContain(DEFAULT_GEMINI_FLASH_LITE_MODEL);
unmount();
});
});
diff --git a/packages/cli/src/ui/components/ModelDialog.tsx b/packages/cli/src/ui/components/ModelDialog.tsx
index 750150a15f..489f75f736 100644
--- a/packages/cli/src/ui/components/ModelDialog.tsx
+++ b/packages/cli/src/ui/components/ModelDialog.tsx
@@ -96,7 +96,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
PREVIEW_GEMINI_FLASH_LITE_MODEL,
PREVIEW_GEMINI_FLASH_MODEL,
- ];
+ ].filter((m) => m !== 'none');
if (manualModels.includes(preferredModel)) {
return preferredModel;
}
@@ -223,16 +223,16 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
title: getDisplayString(DEFAULT_GEMINI_MODEL),
key: DEFAULT_GEMINI_MODEL,
},
- {
- value: DEFAULT_GEMINI_FLASH_MODEL,
- title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL),
- key: DEFAULT_GEMINI_FLASH_MODEL,
- },
{
value: DEFAULT_GEMINI_FLASH_LITE_MODEL,
title: getDisplayString(DEFAULT_GEMINI_FLASH_LITE_MODEL),
key: DEFAULT_GEMINI_FLASH_LITE_MODEL,
},
+ {
+ value: DEFAULT_GEMINI_FLASH_MODEL,
+ title: getDisplayString(DEFAULT_GEMINI_FLASH_MODEL),
+ key: DEFAULT_GEMINI_FLASH_MODEL,
+ },
];
if (showGemmaModels) {
@@ -272,7 +272,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
},
];
- if (useGemini31FlashLite) {
+ if (useGemini31FlashLite && PREVIEW_GEMINI_FLASH_LITE_MODEL !== 'none') {
previewOptions.push({
value: PREVIEW_GEMINI_FLASH_LITE_MODEL,
title: getDisplayString(PREVIEW_GEMINI_FLASH_LITE_MODEL),
diff --git a/packages/core/src/config/models.test.ts b/packages/core/src/config/models.test.ts
index f02d4d898b..1d4f994d08 100644
--- a/packages/core/src/config/models.test.ts
+++ b/packages/core/src/config/models.test.ts
@@ -229,13 +229,29 @@ describe('Dynamic Configuration Parity', () => {
});
describe('isPreviewModel', () => {
- it('should return true for preview models', () => {
- expect(isPreviewModel(PREVIEW_GEMINI_MODEL)).toBe(true);
- expect(isPreviewModel(PREVIEW_GEMINI_3_1_MODEL)).toBe(true);
- expect(isPreviewModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL)).toBe(true);
- expect(isPreviewModel(PREVIEW_GEMINI_FLASH_MODEL)).toBe(true);
+ const PREVIEW_MODELS = [
+ PREVIEW_GEMINI_MODEL,
+ PREVIEW_GEMINI_3_1_MODEL,
+ PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
+ PREVIEW_GEMINI_FLASH_MODEL,
+ PREVIEW_GEMINI_FLASH_LITE_MODEL,
+ ];
+
+ it('should return true for active preview models', () => {
+ for (const model of PREVIEW_MODELS) {
+ if (model !== 'none') {
+ expect(isPreviewModel(model)).toBe(true);
+ }
+ }
expect(isPreviewModel(PREVIEW_GEMINI_MODEL_AUTO)).toBe(true);
- expect(isPreviewModel(PREVIEW_GEMINI_FLASH_LITE_MODEL)).toBe(true);
+ expect(isPreviewModel(GEMINI_MODEL_ALIAS_AUTO)).toBe(true);
+ });
+
+ it('should return false if a preview model is retired (set to none)', () => {
+ const retiredModels = PREVIEW_MODELS.filter((m) => m === 'none');
+ for (const model of retiredModels) {
+ expect(isPreviewModel(model)).toBe(false);
+ }
});
it('should return false for non-preview models', () => {
@@ -625,22 +641,28 @@ describe('isActiveModel', () => {
expect(isActiveModel(DEFAULT_GEMINI_MODEL, true)).toBe(true);
});
- it('should return true for PREVIEW_GEMINI_FLASH_LITE_MODEL only when useGemini3_1FlashLite is true, and always true for DEFAULT_GEMINI_FLASH_LITE_MODEL', () => {
- expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, false, true)).toBe(
- true,
- );
+ it('should handle PREVIEW_GEMINI_FLASH_LITE_MODEL activity correctly based on retirement status', () => {
+ if (PREVIEW_GEMINI_FLASH_LITE_MODEL === 'none') {
+ expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, false, true)).toBe(
+ false,
+ );
+ expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, true, true)).toBe(
+ false,
+ );
+ } else {
+ expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, false, true)).toBe(
+ true,
+ );
+ expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, true, true)).toBe(
+ true,
+ );
+ }
expect(isActiveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, false, false)).toBe(
true,
);
- expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, true, true)).toBe(
- true,
- );
expect(isActiveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, true, true)).toBe(
true,
);
- expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, true, false)).toBe(
- false,
- );
expect(isActiveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, true, false)).toBe(
true,
);
@@ -677,9 +699,11 @@ describe('isActiveModel', () => {
expect(
isActiveModel(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL, false, false, false),
).toBe(false);
- expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, false, false)).toBe(
- false,
- );
+ if (PREVIEW_GEMINI_FLASH_LITE_MODEL !== 'none') {
+ expect(isActiveModel(PREVIEW_GEMINI_FLASH_LITE_MODEL, false, false)).toBe(
+ false,
+ );
+ }
expect(isActiveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, false, false)).toBe(
true,
);
@@ -707,14 +731,23 @@ describe('Gemini 3.1 Config Resolution', () => {
).toBeDefined();
});
- it('PREVIEW_GEMINI_FLASH_LITE_MODEL should resolve to chat-base-3 config (including thinkingLevel)', () => {
- const resolved = modelConfigService.getResolvedConfig({
- model: PREVIEW_GEMINI_FLASH_LITE_MODEL,
- isChatModel: true,
- });
- expect(
- resolved.generateContentConfig?.thinkingConfig?.thinkingLevel,
- ).toBeDefined();
+ it('PREVIEW_GEMINI_FLASH_LITE_MODEL should resolve to appropriate config based on retirement status', () => {
+ if (PREVIEW_GEMINI_FLASH_LITE_MODEL === 'none') {
+ // If none, it falls back to chat-base which may not have thinkingLevel
+ const resolved = modelConfigService.getResolvedConfig({
+ model: PREVIEW_GEMINI_FLASH_LITE_MODEL,
+ isChatModel: true,
+ });
+ expect(resolved.model).toBe(PREVIEW_GEMINI_FLASH_LITE_MODEL);
+ } else {
+ const resolved = modelConfigService.getResolvedConfig({
+ model: PREVIEW_GEMINI_FLASH_LITE_MODEL,
+ isChatModel: true,
+ });
+ expect(
+ resolved.generateContentConfig?.thinkingConfig?.thinkingLevel,
+ ).toBeDefined();
+ }
});
});
@@ -727,13 +760,13 @@ describe('getAutoModelDescription', () => {
it('should return Gemini 3.0 description when hasAccessToPreview is true', () => {
const desc = getAutoModelDescription(true, false);
- expect(desc).toContain('gemini-3-pro');
- expect(desc).toContain('gemini-3-flash');
+ expect(desc).toContain('gemini-3-pro-preview');
+ expect(desc).toContain('gemini-3-flash-preview');
});
it('should return Gemini 3.1 description when hasAccessToPreview and useGemini3_1 are true', () => {
const desc = getAutoModelDescription(true, true);
- expect(desc).toContain('gemini-3.1-pro');
- expect(desc).toContain('gemini-3-flash');
+ expect(desc).toContain('gemini-3.1-pro-preview');
+ expect(desc).toContain('gemini-3-flash-preview');
});
});
diff --git a/packages/core/src/config/models.ts b/packages/core/src/config/models.ts
index e645b40f3d..700c8e2222 100644
--- a/packages/core/src/config/models.ts
+++ b/packages/core/src/config/models.ts
@@ -101,10 +101,12 @@ export function getAutoModelDescription(
) {
const proModel = hasAccessToPreview
? useGemini3_1
- ? 'gemini-3.1-pro'
- : 'gemini-3-pro'
- : 'gemini-2.5-pro';
- const flashModel = hasAccessToPreview ? 'gemini-3-flash' : 'gemini-2.5-flash';
+ ? PREVIEW_GEMINI_3_1_MODEL
+ : PREVIEW_GEMINI_MODEL
+ : DEFAULT_GEMINI_MODEL;
+ const flashModel = hasAccessToPreview
+ ? PREVIEW_GEMINI_FLASH_MODEL
+ : DEFAULT_GEMINI_FLASH_MODEL;
return `Let Gemini CLI decide the best model for the task: ${proModel}, ${flashModel}`;
}
@@ -332,6 +334,9 @@ export function isPreviewModel(
model: string,
config?: ModelCapabilityContext,
): boolean {
+ if (model === 'none') {
+ return false;
+ }
if (config?.getExperimentalDynamicModelConfiguration?.() === true) {
return (
config.modelConfigService.getModelDefinition(model)?.isPreview === true
@@ -345,7 +350,7 @@ export function isPreviewModel(
model === PREVIEW_GEMINI_FLASH_MODEL ||
model === PREVIEW_GEMINI_MODEL_AUTO ||
model === GEMINI_MODEL_ALIAS_AUTO ||
- (model === PREVIEW_GEMINI_FLASH_LITE_MODEL && model !== 'none')
+ model === PREVIEW_GEMINI_FLASH_LITE_MODEL
);
}
diff --git a/packages/core/src/context/chatCompressionService.ts b/packages/core/src/context/chatCompressionService.ts
index d9b92abfe6..7eaa4df52a 100644
--- a/packages/core/src/context/chatCompressionService.ts
+++ b/packages/core/src/context/chatCompressionService.ts
@@ -107,6 +107,7 @@ export function modelStringToModelConfigAlias(model: string): string {
case PREVIEW_GEMINI_FLASH_MODEL:
return 'chat-compression-3-flash';
case PREVIEW_GEMINI_FLASH_LITE_MODEL:
+ // fallthrough
case DEFAULT_GEMINI_FLASH_LITE_MODEL:
return 'chat-compression-3.1-flash-lite';
case 'gemini-2.5-flash-lite':