From 61d92c4a21fda8de66e02431c6b7b4c0fc81ca46 Mon Sep 17 00:00:00 2001 From: Sehoon Shon Date: Fri, 6 Feb 2026 13:02:57 -0500 Subject: [PATCH] Remove previewFeatures and default to Gemini 3 (#18414) --- docs/cli/settings.md | 15 ++- docs/get-started/configuration.md | 4 - packages/a2a-server/src/config/config.ts | 6 +- .../a2a-server/src/config/settings.test.ts | 61 --------- packages/a2a-server/src/config/settings.ts | 3 - packages/cli/src/config/config.test.ts | 4 +- packages/cli/src/config/config.ts | 6 +- .../cli/src/config/settingsSchema.test.ts | 24 ---- packages/cli/src/config/settingsSchema.ts | 9 -- .../cli/src/config/settings_repro.test.ts | 1 - packages/cli/src/test-utils/mockConfig.ts | 1 - packages/cli/src/ui/AppContainer.tsx | 14 +-- .../cli/src/ui/components/AppHeader.test.tsx | 47 ------- packages/cli/src/ui/components/AppHeader.tsx | 2 +- packages/cli/src/ui/components/Footer.tsx | 2 +- .../src/ui/components/ModelDialog.test.tsx | 79 ------------ .../cli/src/ui/components/ModelDialog.tsx | 32 +---- .../src/ui/components/SettingsDialog.test.tsx | 12 +- .../cli/src/ui/components/SettingsDialog.tsx | 19 +-- .../__snapshots__/AppHeader.test.tsx.snap | 39 ------ .../SettingsDialog.test.tsx.snap | 70 +++++------ .../messages/ToolGroupMessage.test.tsx | 1 - packages/cli/src/ui/hooks/useBanner.test.ts | 40 +----- packages/cli/src/ui/hooks/useBanner.ts | 18 +-- .../src/ui/hooks/useQuotaAndFallback.test.ts | 3 +- .../cli/src/ui/hooks/useQuotaAndFallback.ts | 3 +- .../zed-integration/zedIntegration.test.ts | 2 - .../cli/src/zed-integration/zedIntegration.ts | 5 +- .../availability/fallbackIntegration.test.ts | 1 - .../src/availability/policyHelpers.test.ts | 1 - packages/core/src/config/config.test.ts | 118 +----------------- packages/core/src/config/config.ts | 36 ------ packages/core/src/config/models.test.ts | 78 ++---------- packages/core/src/config/models.ts | 35 ++---- packages/core/src/core/baseLlmClient.test.ts | 1 - packages/core/src/core/client.test.ts | 1 - .../core/src/core/contentGenerator.test.ts | 10 -- packages/core/src/core/contentGenerator.ts | 5 +- packages/core/src/core/geminiChat.test.ts | 1 - packages/core/src/core/geminiChat.ts | 10 +- .../src/core/geminiChat_network_retry.test.ts | 1 - .../src/core/prompts-substitution.test.ts | 1 - packages/core/src/core/prompts.test.ts | 2 - packages/core/src/fallback/handler.test.ts | 4 - packages/core/src/prompts/promptProvider.ts | 5 +- .../strategies/classifierStrategy.test.ts | 1 - .../routing/strategies/classifierStrategy.ts | 1 - .../strategies/defaultStrategy.test.ts | 27 +--- .../src/routing/strategies/defaultStrategy.ts | 5 +- .../strategies/fallbackStrategy.test.ts | 1 - .../routing/strategies/fallbackStrategy.ts | 5 +- .../numericalClassifierStrategy.test.ts | 1 - .../strategies/numericalClassifierStrategy.ts | 1 - .../strategies/overrideStrategy.test.ts | 4 - .../routing/strategies/overrideStrategy.ts | 2 +- packages/test-utils/src/test-rig.ts | 1 - schemas/settings.schema.json | 7 -- 57 files changed, 91 insertions(+), 797 deletions(-) diff --git a/docs/cli/settings.md b/docs/cli/settings.md index e925c49482..e7741249f7 100644 --- a/docs/cli/settings.md +++ b/docs/cli/settings.md @@ -22,14 +22,13 @@ they appear in the UI. ### General -| UI Label | Setting | Description | Default | -| ------------------------------- | ---------------------------------- | ------------------------------------------------------------- | ------- | -| Preview Features (e.g., models) | `general.previewFeatures` | Enable preview features (e.g., preview models). | `false` | -| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | -| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | -| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` | -| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | -| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` | +| UI Label | Setting | Description | Default | +| ------------------------ | ---------------------------------- | ------------------------------------------------------------- | ------- | +| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | +| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | +| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` | +| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | +| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` | ### Output diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md index 99d119abf9..066d866986 100644 --- a/docs/get-started/configuration.md +++ b/docs/get-started/configuration.md @@ -98,10 +98,6 @@ their corresponding top-level category object in your `settings.json` file. #### `general` -- **`general.previewFeatures`** (boolean): - - **Description:** Enable preview features (e.g., preview models). - - **Default:** `false` - - **`general.preferredEditor`** (string): - **Description:** The preferred editor to open files in. - **Default:** `undefined` diff --git a/packages/a2a-server/src/config/config.ts b/packages/a2a-server/src/config/config.ts index 5b8793d15e..91c23d7910 100644 --- a/packages/a2a-server/src/config/config.ts +++ b/packages/a2a-server/src/config/config.ts @@ -18,7 +18,6 @@ import { loadServerHierarchicalMemory, GEMINI_DIR, DEFAULT_GEMINI_EMBEDDING_MODEL, - DEFAULT_GEMINI_MODEL, type ExtensionLoader, startupProfiler, PREVIEW_GEMINI_MODEL, @@ -60,9 +59,7 @@ export async function loadConfig( const configParams: ConfigParameters = { sessionId: taskId, - model: settings.general?.previewFeatures - ? PREVIEW_GEMINI_MODEL - : DEFAULT_GEMINI_MODEL, + model: PREVIEW_GEMINI_MODEL, embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL, sandbox: undefined, // Sandbox might not be relevant for a server-side agent targetDir: workspaceDir, // Or a specific directory the agent operates on @@ -104,7 +101,6 @@ export async function loadConfig( trustedFolder: true, extensionLoader, checkpointing, - previewFeatures: settings.general?.previewFeatures, interactive: true, enableInteractiveShell: true, ptyInfo: 'auto', diff --git a/packages/a2a-server/src/config/settings.test.ts b/packages/a2a-server/src/config/settings.test.ts index b5788b0fb6..7c51950535 100644 --- a/packages/a2a-server/src/config/settings.test.ts +++ b/packages/a2a-server/src/config/settings.test.ts @@ -89,67 +89,6 @@ describe('loadSettings', () => { vi.restoreAllMocks(); }); - it('should load nested previewFeatures from user settings', () => { - const settings = { - general: { - previewFeatures: true, - }, - }; - fs.writeFileSync(USER_SETTINGS_PATH, JSON.stringify(settings)); - - const result = loadSettings(mockWorkspaceDir); - expect(result.general?.previewFeatures).toBe(true); - }); - - it('should load nested previewFeatures from workspace settings', () => { - const settings = { - general: { - previewFeatures: true, - }, - }; - const workspaceSettingsPath = path.join( - mockGeminiWorkspaceDir, - 'settings.json', - ); - fs.writeFileSync(workspaceSettingsPath, JSON.stringify(settings)); - - const result = loadSettings(mockWorkspaceDir); - expect(result.general?.previewFeatures).toBe(true); - }); - - it('should prioritize workspace settings over user settings', () => { - const userSettings = { - general: { - previewFeatures: false, - }, - }; - fs.writeFileSync(USER_SETTINGS_PATH, JSON.stringify(userSettings)); - - const workspaceSettings = { - general: { - previewFeatures: true, - }, - }; - const workspaceSettingsPath = path.join( - mockGeminiWorkspaceDir, - 'settings.json', - ); - fs.writeFileSync(workspaceSettingsPath, JSON.stringify(workspaceSettings)); - - const result = loadSettings(mockWorkspaceDir); - expect(result.general?.previewFeatures).toBe(true); - }); - - it('should handle missing previewFeatures', () => { - const settings = { - general: {}, - }; - fs.writeFileSync(USER_SETTINGS_PATH, JSON.stringify(settings)); - - const result = loadSettings(mockWorkspaceDir); - expect(result.general?.previewFeatures).toBeUndefined(); - }); - it('should load other top-level settings correctly', () => { const settings = { showMemoryUsage: true, diff --git a/packages/a2a-server/src/config/settings.ts b/packages/a2a-server/src/config/settings.ts index f57e177681..5538576dc7 100644 --- a/packages/a2a-server/src/config/settings.ts +++ b/packages/a2a-server/src/config/settings.ts @@ -31,9 +31,6 @@ export interface Settings { showMemoryUsage?: boolean; checkpointing?: CheckpointingSettings; folderTrust?: boolean; - general?: { - previewFeatures?: boolean; - }; // Git-aware file filtering settings fileFiltering?: { diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 74d5fe273a..bc1c582a23 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -1683,7 +1683,7 @@ describe('loadCliConfig model selection', () => { argv, ); - expect(config.getModel()).toBe('auto-gemini-2.5'); + expect(config.getModel()).toBe('auto-gemini-3'); }); it('always prefers model from argv', async () => { @@ -1727,7 +1727,7 @@ describe('loadCliConfig model selection', () => { argv, ); - expect(config.getModel()).toBe('auto-gemini-2.5'); + expect(config.getModel()).toBe('auto-gemini-3'); }); }); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 9669dcfb4a..f904922ba9 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -15,7 +15,6 @@ import { setGeminiMdFilename as setServerGeminiMdFilename, getCurrentGeminiMdFilename, ApprovalMode, - DEFAULT_GEMINI_MODEL_AUTO, DEFAULT_GEMINI_EMBEDDING_MODEL, DEFAULT_FILE_FILTERING_OPTIONS, DEFAULT_MEMORY_FILE_FILTERING_OPTIONS, @@ -662,9 +661,7 @@ export async function loadCliConfig( ); policyEngineConfig.nonInteractive = !interactive; - const defaultModel = settings.general?.previewFeatures - ? PREVIEW_GEMINI_MODEL_AUTO - : DEFAULT_GEMINI_MODEL_AUTO; + const defaultModel = PREVIEW_GEMINI_MODEL_AUTO; const specifiedModel = argv.model || process.env['GEMINI_MODEL'] || settings.model?.name; @@ -740,7 +737,6 @@ export async function loadCliConfig( settings.context?.loadMemoryFromIncludeDirectories || false, debugMode, question, - previewFeatures: settings.general?.previewFeatures, coreTools: settings.tools?.core || undefined, allowedTools: allowedTools.length > 0 ? allowedTools : undefined, diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts index 3081ce9a10..ed66409e6c 100644 --- a/packages/cli/src/config/settingsSchema.test.ts +++ b/packages/cli/src/config/settingsSchema.test.ts @@ -328,30 +328,6 @@ describe('SettingsSchema', () => { ).toBe('Enable debug logging of keystrokes to the console.'); }); - it('should have previewFeatures setting in schema', () => { - expect( - getSettingsSchema().general.properties.previewFeatures, - ).toBeDefined(); - expect(getSettingsSchema().general.properties.previewFeatures.type).toBe( - 'boolean', - ); - expect( - getSettingsSchema().general.properties.previewFeatures.category, - ).toBe('General'); - expect( - getSettingsSchema().general.properties.previewFeatures.default, - ).toBe(false); - expect( - getSettingsSchema().general.properties.previewFeatures.requiresRestart, - ).toBe(false); - expect( - getSettingsSchema().general.properties.previewFeatures.showInDialog, - ).toBe(true); - expect( - getSettingsSchema().general.properties.previewFeatures.description, - ).toBe('Enable preview features (e.g., preview models).'); - }); - it('should have enableAgents setting in schema', () => { const setting = getSettingsSchema().experimental.properties.enableAgents; expect(setting).toBeDefined(); diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 9a858ec8bb..c4224f2846 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -162,15 +162,6 @@ const SETTINGS_SCHEMA = { description: 'General application settings.', showInDialog: false, properties: { - previewFeatures: { - type: 'boolean', - label: 'Preview Features (e.g., models)', - category: 'General', - requiresRestart: false, - default: false, - description: 'Enable preview features (e.g., preview models).', - showInDialog: true, - }, preferredEditor: { type: 'string', label: 'Preferred Editor', diff --git a/packages/cli/src/config/settings_repro.test.ts b/packages/cli/src/config/settings_repro.test.ts index de4cc9ad8e..846aea374c 100644 --- a/packages/cli/src/config/settings_repro.test.ts +++ b/packages/cli/src/config/settings_repro.test.ts @@ -134,7 +134,6 @@ describe('Settings Repro', () => { enablePromptCompletion: false, preferredEditor: 'vim', vimMode: false, - previewFeatures: false, }, security: { auth: { diff --git a/packages/cli/src/test-utils/mockConfig.ts b/packages/cli/src/test-utils/mockConfig.ts index 537f2097f6..012ad09312 100644 --- a/packages/cli/src/test-utils/mockConfig.ts +++ b/packages/cli/src/test-utils/mockConfig.ts @@ -151,7 +151,6 @@ export const createMockConfig = (overrides: Partial = {}): Config => getAllowedMcpServers: vi.fn().mockReturnValue([]), getBlockedMcpServers: vi.fn().mockReturnValue([]), getExperiments: vi.fn().mockReturnValue(undefined), - getPreviewFeatures: vi.fn().mockReturnValue(false), getHasAccessToPreviewModel: vi.fn().mockReturnValue(false), ...overrides, }) as unknown as Config; diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx index efae760cc1..57afef24d6 100644 --- a/packages/cli/src/ui/AppContainer.tsx +++ b/packages/cli/src/ui/AppContainer.tsx @@ -246,7 +246,7 @@ export const AppContainer = (props: AppContainerProps) => { [defaultBannerText, warningBannerText], ); - const { bannerText } = useBanner(bannerData, config); + const { bannerText } = useBanner(bannerData); const extensionManager = config.getExtensionLoader() as ExtensionManager; // We are in the interactive CLI, update how we request consent and settings. @@ -1772,7 +1772,8 @@ Logging in with Google... Restarting Gemini CLI to continue. const fetchBannerTexts = async () => { const [defaultBanner, warningBanner] = await Promise.all([ - config.getBannerTextNoCapacityIssues(), + // TODO: temporarily disabling the banner, it will be re-added. + '', config.getBannerTextCapacityIssues(), ]); @@ -1780,15 +1781,6 @@ Logging in with Google... Restarting Gemini CLI to continue. setDefaultBannerText(defaultBanner); setWarningBannerText(warningBanner); setBannerVisible(true); - const authType = config.getContentGeneratorConfig()?.authType; - if ( - authType === AuthType.USE_GEMINI || - authType === AuthType.USE_VERTEX_AI - ) { - setDefaultBannerText( - 'Gemini 3 Flash and Pro are now available. \nEnable "Preview features" in /settings. \nLearn more at https://goo.gle/enable-preview-features', - ); - } } }; // eslint-disable-next-line @typescript-eslint/no-floating-promises diff --git a/packages/cli/src/ui/components/AppHeader.test.tsx b/packages/cli/src/ui/components/AppHeader.test.tsx index ba276533ca..13f7b13e77 100644 --- a/packages/cli/src/ui/components/AppHeader.test.tsx +++ b/packages/cli/src/ui/components/AppHeader.test.tsx @@ -89,53 +89,6 @@ describe('', () => { unmount(); }); - it('should render the banner when previewFeatures is disabled', () => { - const mockConfig = makeFakeConfig({ previewFeatures: false }); - const uiState = { - history: [], - bannerData: { - defaultText: 'This is the default banner', - warningText: '', - }, - bannerVisible: true, - }; - - const { lastFrame, unmount } = renderWithProviders( - , - { - config: mockConfig, - uiState, - }, - ); - - expect(lastFrame()).toContain('This is the default banner'); - expect(lastFrame()).toMatchSnapshot(); - unmount(); - }); - - it('should not render the banner when previewFeatures is enabled', () => { - const mockConfig = makeFakeConfig({ previewFeatures: true }); - const uiState = { - history: [], - bannerData: { - defaultText: 'This is the default banner', - warningText: '', - }, - }; - - const { lastFrame, unmount } = renderWithProviders( - , - { - config: mockConfig, - uiState, - }, - ); - - expect(lastFrame()).not.toContain('This is the default banner'); - expect(lastFrame()).toMatchSnapshot(); - unmount(); - }); - it('should not render the default banner if shown count is 5 or more', () => { const mockConfig = makeFakeConfig(); const uiState = { diff --git a/packages/cli/src/ui/components/AppHeader.tsx b/packages/cli/src/ui/components/AppHeader.tsx index 01eac44496..38b0f9b468 100644 --- a/packages/cli/src/ui/components/AppHeader.tsx +++ b/packages/cli/src/ui/components/AppHeader.tsx @@ -24,7 +24,7 @@ export const AppHeader = ({ version }: AppHeaderProps) => { const config = useConfig(); const { nightly, terminalWidth, bannerData, bannerVisible } = useUIState(); - const { bannerText } = useBanner(bannerData, config); + const { bannerText } = useBanner(bannerData); const { showTips } = useTips(); return ( diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index c488568e7d..64ee355f56 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -147,7 +147,7 @@ export const Footer: React.FC = () => { - {getDisplayString(model, config.getPreviewFeatures())} + {getDisplayString(model)} /model {!hideContextPercentage && ( <> diff --git a/packages/cli/src/ui/components/ModelDialog.test.tsx b/packages/cli/src/ui/components/ModelDialog.test.tsx index fbfddbfad1..e936ad3bae 100644 --- a/packages/cli/src/ui/components/ModelDialog.test.tsx +++ b/packages/cli/src/ui/components/ModelDialog.test.tsx @@ -14,8 +14,6 @@ import { DEFAULT_GEMINI_MODEL_AUTO, DEFAULT_GEMINI_FLASH_MODEL, DEFAULT_GEMINI_FLASH_LITE_MODEL, - PREVIEW_GEMINI_MODEL, - PREVIEW_GEMINI_MODEL_AUTO, } from '@google/gemini-cli-core'; import type { Config, ModelSlashCommandEvent } from '@google/gemini-cli-core'; @@ -42,28 +40,24 @@ vi.mock('@google/gemini-cli-core', async () => { describe('', () => { const mockSetModel = vi.fn(); const mockGetModel = vi.fn(); - const mockGetPreviewFeatures = vi.fn(); const mockOnClose = vi.fn(); const mockGetHasAccessToPreviewModel = vi.fn(); interface MockConfig extends Partial { setModel: (model: string, isTemporary?: boolean) => void; getModel: () => string; - getPreviewFeatures: () => boolean; getHasAccessToPreviewModel: () => boolean; } const mockConfig: MockConfig = { setModel: mockSetModel, getModel: mockGetModel, - getPreviewFeatures: mockGetPreviewFeatures, getHasAccessToPreviewModel: mockGetHasAccessToPreviewModel, }; beforeEach(() => { vi.resetAllMocks(); mockGetModel.mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO); - mockGetPreviewFeatures.mockReturnValue(false); mockGetHasAccessToPreviewModel.mockReturnValue(false); // Default implementation for getDisplayString @@ -94,13 +88,6 @@ describe('', () => { expect(lastFrame()).toContain('Manual'); }); - it('renders "main" view with preview options when preview features are enabled', () => { - mockGetPreviewFeatures.mockReturnValue(true); - mockGetHasAccessToPreviewModel.mockReturnValue(true); // Must have access - const { lastFrame } = renderComponent(); - expect(lastFrame()).toContain('Auto (Preview)'); - }); - it('switches to "manual" view when "Manual" is selected', async () => { const { lastFrame, stdin } = renderComponent(); @@ -119,26 +106,6 @@ describe('', () => { expect(lastFrame()).toContain(DEFAULT_GEMINI_FLASH_LITE_MODEL); }); - it('renders "manual" view with preview options when preview features are enabled', async () => { - mockGetPreviewFeatures.mockReturnValue(true); - mockGetHasAccessToPreviewModel.mockReturnValue(true); // Must have access - mockGetModel.mockReturnValue(PREVIEW_GEMINI_MODEL_AUTO); - const { lastFrame, stdin } = renderComponent(); - - // Select "Manual" (index 2 because Preview Auto is first, then Auto (Gemini 2.5)) - // Press down enough times to ensure we reach the bottom (Manual) - stdin.write('\u001B[B'); // Arrow Down - await waitForUpdate(); - stdin.write('\u001B[B'); // Arrow Down - await waitForUpdate(); - - // Press enter to select Manual - stdin.write('\r'); - await waitForUpdate(); - - expect(lastFrame()).toContain(PREVIEW_GEMINI_MODEL); - }); - it('sets model and closes when a model is selected in "main" view', async () => { const { stdin } = renderComponent(); @@ -220,50 +187,4 @@ describe('', () => { // Should be back to main view (Manual option visible) expect(lastFrame()).toContain('Manual'); }); - - describe('Preview Logic', () => { - it('should NOT show preview options if user has no access', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(false); - mockGetPreviewFeatures.mockReturnValue(true); // Even if enabled - const { lastFrame } = renderComponent(); - expect(lastFrame()).not.toContain('Auto (Preview)'); - }); - - it('should NOT show preview options if user has access but preview features are disabled', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(true); - mockGetPreviewFeatures.mockReturnValue(false); - const { lastFrame } = renderComponent(); - expect(lastFrame()).not.toContain('Auto (Preview)'); - }); - - it('should show preview options if user has access AND preview features are enabled', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(true); - mockGetPreviewFeatures.mockReturnValue(true); - const { lastFrame } = renderComponent(); - expect(lastFrame()).toContain('Auto (Preview)'); - }); - - it('should show "Gemini 3 is now available" header if user has access but preview features disabled', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(true); - mockGetPreviewFeatures.mockReturnValue(false); - const { lastFrame } = renderComponent(); - expect(lastFrame()).toContain('Gemini 3 is now available.'); - expect(lastFrame()).toContain('Enable "Preview features" in /settings'); - }); - - it('should show "Gemini 3 is coming soon" header if user has no access', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(false); - mockGetPreviewFeatures.mockReturnValue(false); - const { lastFrame } = renderComponent(); - expect(lastFrame()).toContain('Gemini 3 is coming soon.'); - }); - - it('should NOT show header/subheader if preview options are shown', () => { - mockGetHasAccessToPreviewModel.mockReturnValue(true); - mockGetPreviewFeatures.mockReturnValue(true); - const { lastFrame } = renderComponent(); - expect(lastFrame()).not.toContain('Gemini 3 is now available.'); - expect(lastFrame()).not.toContain('Gemini 3 is coming soon.'); - }); - }); }); diff --git a/packages/cli/src/ui/components/ModelDialog.tsx b/packages/cli/src/ui/components/ModelDialog.tsx index ed299f4f13..88be57b841 100644 --- a/packages/cli/src/ui/components/ModelDialog.tsx +++ b/packages/cli/src/ui/components/ModelDialog.tsx @@ -23,7 +23,6 @@ import { useKeypress } from '../hooks/useKeypress.js'; import { theme } from '../semantic-colors.js'; import { DescriptiveRadioButtonSelect } from './shared/DescriptiveRadioButtonSelect.js'; import { ConfigContext } from '../contexts/ConfigContext.js'; -import { ThemedGradient } from './ThemedGradient.js'; interface ModelDialogProps { onClose: () => void; @@ -37,8 +36,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element { // Determine the Preferred Model (read once when the dialog opens). const preferredModel = config?.getModel() || DEFAULT_GEMINI_MODEL_AUTO; - const shouldShowPreviewModels = - config?.getPreviewFeatures() && config.getHasAccessToPreviewModel(); + const shouldShowPreviewModels = config?.getHasAccessToPreviewModel(); const manualModelSelected = useMemo(() => { const manualModels = [ @@ -173,24 +171,6 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element { [config, onClose, persistMode], ); - let header; - let subheader; - - // Do not show any header or subheader since it's already showing preview model - // options - if (shouldShowPreviewModels) { - header = undefined; - subheader = undefined; - // When a user has the access but has not enabled the preview features. - } else if (config?.getHasAccessToPreviewModel()) { - header = 'Gemini 3 is now available.'; - subheader = - 'Enable "Preview features" in /settings.\nLearn more at https://goo.gle/enable-preview-features'; - } else { - header = 'Gemini 3 is coming soon.'; - subheader = undefined; - } - return ( Select Model - - {header && ( - - - {header} - - - )} - {subheader && {subheader}} - { const { stdin, unmount, lastFrame } = renderDialog(settings, onSelect); - // Wait for initial render and verify we're on Preview Features (first setting) - await waitFor(() => { - expect(lastFrame()).toContain('Preview Features (e.g., models)'); - }); - - // Navigate to Vim Mode setting and verify we're there - act(() => { - stdin.write(TerminalKeys.DOWN_ARROW as string); - }); + // Wait for initial render and verify we're on Vim Mode (first setting) await waitFor(() => { expect(lastFrame()).toContain('Vim Mode'); }); - // Toggle the setting + // Toggle the setting (Vim Mode is the first setting now) act(() => { stdin.write(TerminalKeys.ENTER as string); }); diff --git a/packages/cli/src/ui/components/SettingsDialog.tsx b/packages/cli/src/ui/components/SettingsDialog.tsx index 76c6a27e6e..3f606ae22f 100644 --- a/packages/cli/src/ui/components/SettingsDialog.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.tsx @@ -355,10 +355,6 @@ export function SettingsDialog({ next.delete(key); return next; }); - - if (key === 'general.previewFeatures') { - config?.setPreviewFeatures(newValue as boolean); - } } else { // For restart-required settings, track as modified setModifiedSettings((prev) => { @@ -387,14 +383,7 @@ export function SettingsDialog({ }); } }, - [ - pendingSettings, - settings, - selectedScope, - vimEnabled, - toggleVimEnabled, - config, - ], + [pendingSettings, settings, selectedScope, vimEnabled, toggleVimEnabled], ); // Edit commit handler @@ -522,12 +511,6 @@ export function SettingsDialog({ }); } } - - if (key === 'general.previewFeatures') { - const booleanDefaultValue = - typeof defaultValue === 'boolean' ? defaultValue : false; - config?.setPreviewFeatures(booleanDefaultValue); - } } // Remove from modified sets diff --git a/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap index bb28344103..d47f6546f7 100644 --- a/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/AppHeader.test.tsx.snap @@ -18,24 +18,6 @@ Tips for getting started: 4. /help for more information." `; -exports[` > should not render the banner when previewFeatures is enabled 1`] = ` -" - ███ █████████ -░░░███ ███░░░░░███ - ░░░███ ███ ░░░ - ░░░███░███ - ███░ ░███ █████ - ███░ ░░███ ░░███ - ███░ ░░█████████ -░░░ ░░░░░░░░░ - -Tips for getting started: -1. Ask questions, edit files, or run commands. -2. Be specific for the best results. -3. Create GEMINI.md files to customize your interactions with Gemini. -4. /help for more information." -`; - exports[` > should not render the default banner if shown count is 5 or more 1`] = ` " ███ █████████ @@ -54,27 +36,6 @@ Tips for getting started: 4. /help for more information." `; -exports[` > should render the banner when previewFeatures is disabled 1`] = ` -" - ███ █████████ -░░░███ ███░░░░░███ - ░░░███ ███ ░░░ - ░░░███░███ - ███░ ░███ █████ - ███░ ░░███ ░░███ - ███░ ░░█████████ -░░░ ░░░░░░░░░ - -╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ -│ This is the default banner │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ -Tips for getting started: -1. Ask questions, edit files, or run commands. -2. Be specific for the best results. -3. Create GEMINI.md files to customize your interactions with Gemini. -4. /help for more information." -`; - exports[` > should render the banner with default text 1`] = ` " ███ █████████ diff --git a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap index 233c14abdb..786867ccc0 100644 --- a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap @@ -10,10 +10,7 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false │ +│ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true │ @@ -34,6 +31,9 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -56,10 +56,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode true* │ +│ ● Vim Mode true* │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true │ @@ -80,6 +77,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -102,10 +102,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false* │ +│ ● Vim Mode false* │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true* │ @@ -126,6 +123,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -148,10 +148,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false │ +│ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true │ @@ -172,6 +169,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -194,10 +194,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false │ +│ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true │ @@ -218,6 +215,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -240,9 +240,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ │ Vim Mode false │ │ Enable Vim keybindings │ │ │ @@ -264,6 +261,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ > Apply To │ @@ -286,10 +286,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false* │ +│ ● Vim Mode false* │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update false* │ @@ -310,6 +307,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -332,10 +332,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode false │ +│ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update true │ @@ -356,6 +353,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ @@ -378,10 +378,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ ▲ │ -│ ● Preview Features (e.g., models) false │ -│ Enable preview features (e.g., preview models). │ -│ │ -│ Vim Mode true* │ +│ ● Vim Mode true* │ │ Enable Vim keybindings │ │ │ │ Enable Auto Update false* │ @@ -402,6 +399,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ +│ Terminal Background Polling Interval 60 │ +│ Interval in seconds to poll the terminal background color. │ +│ │ │ ▼ │ │ │ │ Apply To │ diff --git a/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx b/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx index 28475b52c6..5368684ea2 100644 --- a/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx +++ b/packages/cli/src/ui/components/messages/ToolGroupMessage.test.tsx @@ -45,7 +45,6 @@ describe('', () => { folderTrust: false, ideMode: false, enableInteractiveShell: true, - previewFeatures: false, enableEventDrivenScheduler: true, }); diff --git a/packages/cli/src/ui/hooks/useBanner.test.ts b/packages/cli/src/ui/hooks/useBanner.test.ts index 27909fae27..1d876c078c 100644 --- a/packages/cli/src/ui/hooks/useBanner.test.ts +++ b/packages/cli/src/ui/hooks/useBanner.test.ts @@ -15,7 +15,6 @@ import { import { renderHook } from '../../test-utils/render.js'; import { useBanner } from './useBanner.js'; import { persistentState } from '../../utils/persistentState.js'; -import type { Config } from '@google/gemini-cli-core'; import crypto from 'node:crypto'; vi.mock('../../utils/persistentState.js', () => ({ @@ -39,13 +38,7 @@ vi.mock('../colors.js', () => ({ }, })); -// Define the shape of the config methods used by this hook -interface MockConfigShape { - getPreviewFeatures: MockedFunction<() => boolean>; -} - describe('useBanner', () => { - let mockConfig: MockConfigShape; const mockedPersistentStateGet = persistentState.get as MockedFunction< typeof persistentState.get >; @@ -61,11 +54,6 @@ describe('useBanner', () => { beforeEach(() => { vi.resetAllMocks(); - // Initialize the mock config with default behavior - mockConfig = { - getPreviewFeatures: vi.fn().mockReturnValue(false), - }; - // Default persistentState behavior: return empty object (no counts) mockedPersistentStateGet.mockReturnValue({}); }); @@ -73,25 +61,11 @@ describe('useBanner', () => { it('should return warning text and warning color if warningText is present', () => { const data = { defaultText: 'Standard', warningText: 'Critical Error' }; - const { result } = renderHook(() => - useBanner(data, mockConfig as unknown as Config), - ); + const { result } = renderHook(() => useBanner(data)); expect(result.current.bannerText).toBe('Critical Error'); }); - it('should NOT show default banner if preview features are enabled in config', () => { - // Simulate Preview Features Enabled - mockConfig.getPreviewFeatures.mockReturnValue(true); - - const { result } = renderHook(() => - useBanner(defaultBannerData, mockConfig as unknown as Config), - ); - - // Should fall back to warningText (which is empty) - expect(result.current.bannerText).toBe(''); - }); - it('should hide banner if show count exceeds max limit (Legacy format)', () => { mockedPersistentStateGet.mockReturnValue({ [crypto @@ -100,9 +74,7 @@ describe('useBanner', () => { .digest('hex')]: 5, }); - const { result } = renderHook(() => - useBanner(defaultBannerData, mockConfig as unknown as Config), - ); + const { result } = renderHook(() => useBanner(defaultBannerData)); expect(result.current.bannerText).toBe(''); }); @@ -115,7 +87,7 @@ describe('useBanner', () => { [crypto.createHash('sha256').update(data.defaultText).digest('hex')]: 1, }); - renderHook(() => useBanner(data, mockConfig as unknown as Config)); + renderHook(() => useBanner(data)); // Expect set to be called with incremented count expect(mockedPersistentStateSet).toHaveBeenCalledWith( @@ -129,7 +101,7 @@ describe('useBanner', () => { it('should NOT increment count if warning text is shown instead', () => { const data = { defaultText: 'Standard', warningText: 'Warning' }; - renderHook(() => useBanner(data, mockConfig as unknown as Config)); + renderHook(() => useBanner(data)); // Since warning text takes precedence, default banner logic (and increment) is skipped expect(mockedPersistentStateSet).not.toHaveBeenCalled(); @@ -138,9 +110,7 @@ describe('useBanner', () => { it('should handle newline replacements', () => { const data = { defaultText: 'Line1\\nLine2', warningText: '' }; - const { result } = renderHook(() => - useBanner(data, mockConfig as unknown as Config), - ); + const { result } = renderHook(() => useBanner(data)); expect(result.current.bannerText).toBe('Line1\nLine2'); }); diff --git a/packages/cli/src/ui/hooks/useBanner.ts b/packages/cli/src/ui/hooks/useBanner.ts index faca37ca02..ab6d0b6a51 100644 --- a/packages/cli/src/ui/hooks/useBanner.ts +++ b/packages/cli/src/ui/hooks/useBanner.ts @@ -6,7 +6,6 @@ import { useState, useEffect, useRef } from 'react'; import { persistentState } from '../../utils/persistentState.js'; -import type { Config } from '@google/gemini-cli-core'; import crypto from 'node:crypto'; const DEFAULT_MAX_BANNER_SHOWN_COUNT = 5; @@ -16,20 +15,9 @@ interface BannerData { warningText: string; } -export function useBanner(bannerData: BannerData, config: Config) { +export function useBanner(bannerData: BannerData) { const { defaultText, warningText } = bannerData; - const [previewEnabled, setPreviewEnabled] = useState( - config.getPreviewFeatures(), - ); - - useEffect(() => { - const isEnabled = config.getPreviewFeatures(); - if (isEnabled !== previewEnabled) { - setPreviewEnabled(isEnabled); - } - }, [config, previewEnabled]); - const [bannerCounts] = useState( () => persistentState.get('defaultBannerShownCount') || {}, ); @@ -42,9 +30,7 @@ export function useBanner(bannerData: BannerData, config: Config) { const currentBannerCount = bannerCounts[hashedText] || 0; const showDefaultBanner = - warningText === '' && - !previewEnabled && - currentBannerCount < DEFAULT_MAX_BANNER_SHOWN_COUNT; + warningText === '' && currentBannerCount < DEFAULT_MAX_BANNER_SHOWN_COUNT; const rawBannerText = showDefaultBanner ? defaultText : warningText; const bannerText = rawBannerText.replace(/\\n/g, '\n'); diff --git a/packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts b/packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts index 2a9106329e..94a126d5f7 100644 --- a/packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts +++ b/packages/cli/src/ui/hooks/useQuotaAndFallback.test.ts @@ -328,8 +328,7 @@ describe('useQuotaAndFallback', () => { const message = request!.message; expect(message).toBe( `It seems like you don't have access to gemini-3-pro-preview. -Learn more at https://goo.gle/enable-preview-features -To disable gemini-3-pro-preview, disable "Preview features" in /settings.`, +Your admin might have disabled the access. Contact them to enable the Preview Release Channel.`, ); // Simulate the user choosing to switch diff --git a/packages/cli/src/ui/hooks/useQuotaAndFallback.ts b/packages/cli/src/ui/hooks/useQuotaAndFallback.ts index bc12c60907..175f17f21d 100644 --- a/packages/cli/src/ui/hooks/useQuotaAndFallback.ts +++ b/packages/cli/src/ui/hooks/useQuotaAndFallback.ts @@ -90,8 +90,7 @@ export function useQuotaAndFallback({ isModelNotFoundError = true; const messageLines = [ `It seems like you don't have access to ${failedModel}.`, - `Learn more at https://goo.gle/enable-preview-features`, - `To disable ${failedModel}, disable "Preview features" in /settings.`, + `Your admin might have disabled the access. Contact them to enable the Preview Release Channel.`, ]; message = messageLines.join('\n'); } else { diff --git a/packages/cli/src/zed-integration/zedIntegration.test.ts b/packages/cli/src/zed-integration/zedIntegration.test.ts index 41a0958f56..ec6f046374 100644 --- a/packages/cli/src/zed-integration/zedIntegration.test.ts +++ b/packages/cli/src/zed-integration/zedIntegration.test.ts @@ -110,7 +110,6 @@ describe('GeminiAgent', () => { getContentGeneratorConfig: vi.fn(), getActiveModel: vi.fn().mockReturnValue('gemini-pro'), getModel: vi.fn().mockReturnValue('gemini-pro'), - getPreviewFeatures: vi.fn().mockReturnValue({}), getGeminiClient: vi.fn().mockReturnValue({ startChat: vi.fn().mockResolvedValue({}), }), @@ -343,7 +342,6 @@ describe('Session', () => { mockConfig = { getModel: vi.fn().mockReturnValue('gemini-pro'), getActiveModel: vi.fn().mockReturnValue('gemini-pro'), - getPreviewFeatures: vi.fn().mockReturnValue({}), getToolRegistry: vi.fn().mockReturnValue(mockToolRegistry), getFileService: vi.fn().mockReturnValue({ shouldIgnoreFile: vi.fn().mockReturnValue(false), diff --git a/packages/cli/src/zed-integration/zedIntegration.ts b/packages/cli/src/zed-integration/zedIntegration.ts index 634c20a1a0..ea5a9dc039 100644 --- a/packages/cli/src/zed-integration/zedIntegration.ts +++ b/packages/cli/src/zed-integration/zedIntegration.ts @@ -482,10 +482,7 @@ export class Session { const functionCalls: FunctionCall[] = []; try { - const model = resolveModel( - this.config.getModel(), - this.config.getPreviewFeatures(), - ); + const model = resolveModel(this.config.getModel()); const responseStream = await chat.sendMessageStream( { model }, nextMessage?.parts ?? [], diff --git a/packages/core/src/availability/fallbackIntegration.test.ts b/packages/core/src/availability/fallbackIntegration.test.ts index 39cbe2e0b4..55f9ac800f 100644 --- a/packages/core/src/availability/fallbackIntegration.test.ts +++ b/packages/core/src/availability/fallbackIntegration.test.ts @@ -27,7 +27,6 @@ describe('Fallback Integration', () => { getModel: () => PREVIEW_GEMINI_MODEL_AUTO, getActiveModel: () => PREVIEW_GEMINI_MODEL_AUTO, setActiveModel: vi.fn(), - getPreviewFeatures: () => true, // Preview enabled for Gemini 3 getUserTier: () => undefined, getModelAvailabilityService: () => availabilityService, modelConfigService: undefined as unknown as ModelConfigService, diff --git a/packages/core/src/availability/policyHelpers.test.ts b/packages/core/src/availability/policyHelpers.test.ts index bc64ba419b..4e923f638e 100644 --- a/packages/core/src/availability/policyHelpers.test.ts +++ b/packages/core/src/availability/policyHelpers.test.ts @@ -19,7 +19,6 @@ import { const createMockConfig = (overrides: Partial = {}): Config => ({ - getPreviewFeatures: () => false, getUserTier: () => undefined, getModel: () => 'gemini-2.5-pro', ...overrides, diff --git a/packages/core/src/config/config.test.ts b/packages/core/src/config/config.test.ts index 6ca6ad238d..ce67c53e74 100644 --- a/packages/core/src/config/config.test.ts +++ b/packages/core/src/config/config.test.ts @@ -39,12 +39,7 @@ import { ToolRegistry } from '../tools/tool-registry.js'; import { ACTIVATE_SKILL_TOOL_NAME } from '../tools/tool-names.js'; import type { SkillDefinition } from '../skills/skillLoader.js'; import { DEFAULT_MODEL_CONFIGS } from './defaultModelConfigs.js'; -import { - DEFAULT_GEMINI_MODEL, - DEFAULT_GEMINI_MODEL_AUTO, - PREVIEW_GEMINI_MODEL, - PREVIEW_GEMINI_MODEL_AUTO, -} from './models.js'; +import { DEFAULT_GEMINI_MODEL, PREVIEW_GEMINI_MODEL } from './models.js'; vi.mock('fs', async (importOriginal) => { const actual = await importOriginal(); @@ -511,78 +506,6 @@ describe('Server Config (config.ts)', () => { }); }); - describe('Preview Features Logic in refreshAuth', () => { - beforeEach(() => { - // Set up default mock behavior for these functions before each test - vi.mocked(getCodeAssistServer).mockReturnValue(undefined); - vi.mocked(getExperiments).mockResolvedValue({ - flags: {}, - experimentIds: [], - }); - }); - - it('should enable preview features for Google auth when remote flag is true', async () => { - // Override the default mock for this specific test - vi.mocked(getCodeAssistServer).mockReturnValue({} as CodeAssistServer); // Simulate Google auth by returning a truthy value - vi.mocked(getExperiments).mockResolvedValue({ - flags: { - [ExperimentFlags.ENABLE_PREVIEW]: { boolValue: true }, - }, - experimentIds: [], - }); - const config = new Config({ ...baseParams, previewFeatures: undefined }); - await config.refreshAuth(AuthType.LOGIN_WITH_GOOGLE); - expect(config.getPreviewFeatures()).toBe(true); - }); - - it('should disable preview features for Google auth when remote flag is false', async () => { - // Override the default mock - vi.mocked(getCodeAssistServer).mockReturnValue({} as CodeAssistServer); - vi.mocked(getExperiments).mockResolvedValue({ - flags: { - [ExperimentFlags.ENABLE_PREVIEW]: { boolValue: false }, - }, - experimentIds: [], - }); - const config = new Config({ ...baseParams, previewFeatures: undefined }); - await config.refreshAuth(AuthType.LOGIN_WITH_GOOGLE); - expect(config.getPreviewFeatures()).toBe(undefined); - }); - - it('should disable preview features for Google auth when remote flag is missing', async () => { - // Override the default mock for getCodeAssistServer, the getExperiments mock is already correct - vi.mocked(getCodeAssistServer).mockReturnValue({} as CodeAssistServer); - const config = new Config({ ...baseParams, previewFeatures: undefined }); - await config.refreshAuth(AuthType.LOGIN_WITH_GOOGLE); - expect(config.getPreviewFeatures()).toBe(undefined); - }); - - it('should not change preview features or model if it is already set to true', async () => { - const initialModel = 'some-other-model'; - const config = new Config({ - ...baseParams, - previewFeatures: true, - model: initialModel, - }); - // It doesn't matter which auth method we use here, the logic should exit early - await config.refreshAuth(AuthType.USE_GEMINI); - expect(config.getPreviewFeatures()).toBe(true); - expect(config.getModel()).toBe(initialModel); - }); - - it('should not change preview features or model if it is already set to false', async () => { - const initialModel = 'some-other-model'; - const config = new Config({ - ...baseParams, - previewFeatures: false, - model: initialModel, - }); - await config.refreshAuth(AuthType.USE_GEMINI); - expect(config.getPreviewFeatures()).toBe(false); - expect(config.getModel()).toBe(initialModel); - }); - }); - it('Config constructor should store userMemory correctly', () => { const config = new Config(baseParams); @@ -2105,45 +2028,6 @@ describe('Config Quota & Preview Model Access', () => { }); }); - describe('setPreviewFeatures', () => { - it('should reset model to default auto if disabling preview features while using a preview model', () => { - config.setPreviewFeatures(true); - config.setModel(PREVIEW_GEMINI_MODEL); - - config.setPreviewFeatures(false); - - expect(config.getModel()).toBe(DEFAULT_GEMINI_MODEL_AUTO); - }); - - it('should NOT reset model if disabling preview features while NOT using a preview model', () => { - config.setPreviewFeatures(true); - const nonPreviewModel = 'gemini-1.5-pro'; - config.setModel(nonPreviewModel); - - config.setPreviewFeatures(false); - - expect(config.getModel()).toBe(nonPreviewModel); - }); - - it('should switch to preview auto model if enabling preview features while using default auto model', () => { - config.setPreviewFeatures(false); - config.setModel(DEFAULT_GEMINI_MODEL_AUTO); - - config.setPreviewFeatures(true); - - expect(config.getModel()).toBe(PREVIEW_GEMINI_MODEL_AUTO); - }); - - it('should NOT reset model if enabling preview features', () => { - config.setPreviewFeatures(false); - config.setModel(PREVIEW_GEMINI_MODEL); // Just pretending it was set somehow - - config.setPreviewFeatures(true); - - expect(config.getModel()).toBe(PREVIEW_GEMINI_MODEL); - }); - }); - describe('isPlanEnabled', () => { it('should return false by default', () => { const config = new Config(baseParams); diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 2d8aa2470a..17997e587d 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -56,7 +56,6 @@ import { DEFAULT_GEMINI_MODEL_AUTO, isPreviewModel, PREVIEW_GEMINI_MODEL, - PREVIEW_GEMINI_MODEL_AUTO, } from './models.js'; import { shouldAttemptBrowserLaunch } from '../utils/browser.js'; import type { MCPOAuthConfig } from '../mcp/oauth-provider.js'; @@ -467,7 +466,6 @@ export interface ConfigParameters { hooks?: { [K in HookEventName]?: HookDefinition[] }; disabledHooks?: string[]; projectHooks?: { [K in HookEventName]?: HookDefinition[] }; - previewFeatures?: boolean; enableAgents?: boolean; enableEventDrivenScheduler?: boolean; skillsSupport?: boolean; @@ -552,7 +550,6 @@ export class Config { private readonly bugCommand: BugCommandSettings | undefined; private model: string; private readonly disableLoopDetection: boolean; - private previewFeatures: boolean | undefined; private hasAccessToPreviewModel: boolean = false; private readonly noBrowser: boolean; private readonly folderTrust: boolean; @@ -733,7 +730,6 @@ export class Config { this.disabledSkills = params.disabledSkills ?? []; this.adminSkillsEnabled = params.adminSkillsEnabled ?? true; this.modelAvailabilityService = new ModelAvailabilityService(); - this.previewFeatures = params.previewFeatures ?? undefined; this.experimentalJitContext = params.experimentalJitContext ?? false; this.toolOutputMasking = { enabled: params.toolOutputMasking?.enabled ?? false, @@ -1027,15 +1023,6 @@ export class Config { this.experimentsPromise = getExperiments(codeAssistServer) .then((experiments) => { this.setExperiments(experiments); - - // If preview features have not been set and the user authenticated through Google, we enable preview based on remote config only if it's true - if (this.getPreviewFeatures() === undefined) { - const remotePreviewFeatures = - experiments.flags[ExperimentFlags.ENABLE_PREVIEW]?.boolValue; - if (remotePreviewFeatures === true) { - this.setPreviewFeatures(remotePreviewFeatures); - } - } }) .catch((e) => { debugLogger.error('Failed to fetch experiments', e); @@ -1288,29 +1275,6 @@ export class Config { return this.question; } - getPreviewFeatures(): boolean | undefined { - return this.previewFeatures; - } - - setPreviewFeatures(previewFeatures: boolean) { - // No change in state, no action needed - if (this.previewFeatures === previewFeatures) { - return; - } - this.previewFeatures = previewFeatures; - const currentModel = this.getModel(); - - // Case 1: Disabling preview features while on a preview model - if (!previewFeatures && isPreviewModel(currentModel)) { - this.setModel(DEFAULT_GEMINI_MODEL_AUTO); - } - - // Case 2: Enabling preview features while on the default auto model - else if (previewFeatures && currentModel === DEFAULT_GEMINI_MODEL_AUTO) { - this.setModel(PREVIEW_GEMINI_MODEL_AUTO); - } - } - getHasAccessToPreviewModel(): boolean { return this.hasAccessToPreviewModel; } diff --git a/packages/core/src/config/models.test.ts b/packages/core/src/config/models.test.ts index 8e6c3ea895..bd8fa9919a 100644 --- a/packages/core/src/config/models.test.ts +++ b/packages/core/src/config/models.test.ts @@ -18,7 +18,6 @@ import { supportsMultimodalFunctionResponse, GEMINI_MODEL_ALIAS_PRO, GEMINI_MODEL_ALIAS_FLASH, - GEMINI_MODEL_ALIAS_FLASH_LITE, GEMINI_MODEL_ALIAS_AUTO, PREVIEW_GEMINI_FLASH_MODEL, PREVIEW_GEMINI_MODEL_AUTO, @@ -37,19 +36,11 @@ describe('getDisplayString', () => { }); it('should return concrete model name for pro alias', () => { - expect(getDisplayString(GEMINI_MODEL_ALIAS_PRO, false)).toBe( - DEFAULT_GEMINI_MODEL, - ); - expect(getDisplayString(GEMINI_MODEL_ALIAS_PRO, true)).toBe( - PREVIEW_GEMINI_MODEL, - ); + expect(getDisplayString(GEMINI_MODEL_ALIAS_PRO)).toBe(PREVIEW_GEMINI_MODEL); }); it('should return concrete model name for flash alias', () => { - expect(getDisplayString(GEMINI_MODEL_ALIAS_FLASH, false)).toBe( - DEFAULT_GEMINI_FLASH_MODEL, - ); - expect(getDisplayString(GEMINI_MODEL_ALIAS_FLASH, true)).toBe( + expect(getDisplayString(GEMINI_MODEL_ALIAS_FLASH)).toBe( PREVIEW_GEMINI_FLASH_MODEL, ); }); @@ -81,69 +72,30 @@ describe('supportsMultimodalFunctionResponse', () => { describe('resolveModel', () => { describe('delegation logic', () => { it('should return the Preview Pro model when auto-gemini-3 is requested', () => { - const model = resolveModel(PREVIEW_GEMINI_MODEL_AUTO, false); + const model = resolveModel(PREVIEW_GEMINI_MODEL_AUTO); expect(model).toBe(PREVIEW_GEMINI_MODEL); }); it('should return the Default Pro model when auto-gemini-2.5 is requested', () => { - const model = resolveModel(DEFAULT_GEMINI_MODEL_AUTO, false); + const model = resolveModel(DEFAULT_GEMINI_MODEL_AUTO); expect(model).toBe(DEFAULT_GEMINI_MODEL); }); it('should return the requested model as-is for explicit specific models', () => { - expect(resolveModel(DEFAULT_GEMINI_MODEL, false)).toBe( - DEFAULT_GEMINI_MODEL, - ); - expect(resolveModel(DEFAULT_GEMINI_FLASH_MODEL, false)).toBe( + expect(resolveModel(DEFAULT_GEMINI_MODEL)).toBe(DEFAULT_GEMINI_MODEL); + expect(resolveModel(DEFAULT_GEMINI_FLASH_MODEL)).toBe( DEFAULT_GEMINI_FLASH_MODEL, ); - expect(resolveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, false)).toBe( + expect(resolveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL)).toBe( DEFAULT_GEMINI_FLASH_LITE_MODEL, ); }); it('should return a custom model name when requested', () => { const customModel = 'custom-model-v1'; - const model = resolveModel(customModel, false); + const model = resolveModel(customModel); expect(model).toBe(customModel); }); - - describe('with preview features', () => { - it('should return the preview model when pro alias is requested', () => { - const model = resolveModel(GEMINI_MODEL_ALIAS_PRO, true); - expect(model).toBe(PREVIEW_GEMINI_MODEL); - }); - - it('should return the default pro model when pro alias is requested and preview is off', () => { - const model = resolveModel(GEMINI_MODEL_ALIAS_PRO, false); - expect(model).toBe(DEFAULT_GEMINI_MODEL); - }); - - it('should return the flash model when flash is requested and preview is on', () => { - const model = resolveModel(GEMINI_MODEL_ALIAS_FLASH, true); - expect(model).toBe(PREVIEW_GEMINI_FLASH_MODEL); - }); - - it('should return the flash model when lite is requested and preview is on', () => { - const model = resolveModel(GEMINI_MODEL_ALIAS_FLASH_LITE, true); - expect(model).toBe(DEFAULT_GEMINI_FLASH_LITE_MODEL); - }); - - it('should return the flash model when the flash model name is explicitly requested and preview is on', () => { - const model = resolveModel(DEFAULT_GEMINI_FLASH_MODEL, true); - expect(model).toBe(DEFAULT_GEMINI_FLASH_MODEL); - }); - - it('should return the lite model when the lite model name is requested and preview is on', () => { - const model = resolveModel(DEFAULT_GEMINI_FLASH_LITE_MODEL, true); - expect(model).toBe(DEFAULT_GEMINI_FLASH_LITE_MODEL); - }); - - it('should return the default gemini model when the model is explicitly set and preview is on', () => { - const model = resolveModel(DEFAULT_GEMINI_MODEL, true); - expect(model).toBe(DEFAULT_GEMINI_MODEL); - }); - }); }); }); @@ -217,18 +169,4 @@ describe('resolveClassifierModel', () => { resolveClassifierModel(PREVIEW_GEMINI_MODEL_AUTO, GEMINI_MODEL_ALIAS_PRO), ).toBe(PREVIEW_GEMINI_MODEL); }); - - it('should handle preview features being enabled', () => { - // If preview is enabled, resolving 'flash' without context (fallback) might switch to preview flash, - // but here we test explicit auto models which should stick to their families if possible? - // Actually our logic forces DEFAULT_GEMINI_FLASH_MODEL for DEFAULT_GEMINI_MODEL_AUTO even if preview is on, - // because the USER requested 2.5 explicitly via "auto-gemini-2.5". - expect( - resolveClassifierModel( - DEFAULT_GEMINI_MODEL_AUTO, - GEMINI_MODEL_ALIAS_FLASH, - true, - ), - ).toBe(DEFAULT_GEMINI_FLASH_MODEL); - }); }); diff --git a/packages/core/src/config/models.ts b/packages/core/src/config/models.ts index 519f49c98e..b23fe35dcc 100644 --- a/packages/core/src/config/models.ts +++ b/packages/core/src/config/models.ts @@ -34,16 +34,12 @@ export const DEFAULT_THINKING_MODE = 8192; /** * Resolves the requested model alias (e.g., 'auto-gemini-3', 'pro', 'flash', 'flash-lite') - * to a concrete model name, considering preview features. + * to a concrete model name. * * @param requestedModel The model alias or concrete model name requested by the user. - * @param previewFeaturesEnabled A boolean indicating if preview features are enabled. * @returns The resolved concrete model name. */ -export function resolveModel( - requestedModel: string, - previewFeaturesEnabled: boolean = false, -): string { +export function resolveModel(requestedModel: string): string { switch (requestedModel) { case PREVIEW_GEMINI_MODEL_AUTO: { return PREVIEW_GEMINI_MODEL; @@ -53,14 +49,10 @@ export function resolveModel( } case GEMINI_MODEL_ALIAS_AUTO: case GEMINI_MODEL_ALIAS_PRO: { - return previewFeaturesEnabled - ? PREVIEW_GEMINI_MODEL - : DEFAULT_GEMINI_MODEL; + return PREVIEW_GEMINI_MODEL; } case GEMINI_MODEL_ALIAS_FLASH: { - return previewFeaturesEnabled - ? PREVIEW_GEMINI_FLASH_MODEL - : DEFAULT_GEMINI_FLASH_MODEL; + return PREVIEW_GEMINI_FLASH_MODEL; } case GEMINI_MODEL_ALIAS_FLASH_LITE: { return DEFAULT_GEMINI_FLASH_LITE_MODEL; @@ -76,13 +68,11 @@ export function resolveModel( * * @param requestedModel The current requested model (e.g. auto-gemini-2.5). * @param modelAlias The alias selected by the classifier ('flash' or 'pro'). - * @param previewFeaturesEnabled Whether preview features are enabled. * @returns The resolved concrete model name. */ export function resolveClassifierModel( requestedModel: string, modelAlias: string, - previewFeaturesEnabled: boolean = false, ): string { if (modelAlias === GEMINI_MODEL_ALIAS_FLASH) { if ( @@ -97,27 +87,20 @@ export function resolveClassifierModel( ) { return PREVIEW_GEMINI_FLASH_MODEL; } - return resolveModel(GEMINI_MODEL_ALIAS_FLASH, previewFeaturesEnabled); + return resolveModel(GEMINI_MODEL_ALIAS_FLASH); } - return resolveModel(requestedModel, previewFeaturesEnabled); + return resolveModel(requestedModel); } -export function getDisplayString( - model: string, - previewFeaturesEnabled: boolean = false, -) { +export function getDisplayString(model: string) { switch (model) { case PREVIEW_GEMINI_MODEL_AUTO: return 'Auto (Gemini 3)'; case DEFAULT_GEMINI_MODEL_AUTO: return 'Auto (Gemini 2.5)'; case GEMINI_MODEL_ALIAS_PRO: - return previewFeaturesEnabled - ? PREVIEW_GEMINI_MODEL - : DEFAULT_GEMINI_MODEL; + return PREVIEW_GEMINI_MODEL; case GEMINI_MODEL_ALIAS_FLASH: - return previewFeaturesEnabled - ? PREVIEW_GEMINI_FLASH_MODEL - : DEFAULT_GEMINI_FLASH_MODEL; + return PREVIEW_GEMINI_FLASH_MODEL; default: return model; } diff --git a/packages/core/src/core/baseLlmClient.test.ts b/packages/core/src/core/baseLlmClient.test.ts index bcb701e739..c1f796389e 100644 --- a/packages/core/src/core/baseLlmClient.test.ts +++ b/packages/core/src/core/baseLlmClient.test.ts @@ -115,7 +115,6 @@ describe('BaseLlmClient', () => { .fn() .mockReturnValue(createAvailabilityServiceMock()), setActiveModel: vi.fn(), - getPreviewFeatures: vi.fn().mockReturnValue(false), getUserTier: vi.fn().mockReturnValue(undefined), getModel: vi.fn().mockReturnValue('test-model'), getActiveModel: vi.fn().mockReturnValue('test-model'), diff --git a/packages/core/src/core/client.test.ts b/packages/core/src/core/client.test.ts index 98c7dd0b30..ac8d9f1bd6 100644 --- a/packages/core/src/core/client.test.ts +++ b/packages/core/src/core/client.test.ts @@ -228,7 +228,6 @@ describe('Gemini Client (client.ts)', () => { getIdeModeFeature: vi.fn().mockReturnValue(false), getIdeMode: vi.fn().mockReturnValue(true), getDebugMode: vi.fn().mockReturnValue(false), - getPreviewFeatures: vi.fn().mockReturnValue(false), getWorkspaceContext: vi.fn().mockReturnValue({ getDirectories: vi.fn().mockReturnValue(['/test/dir']), }), diff --git a/packages/core/src/core/contentGenerator.test.ts b/packages/core/src/core/contentGenerator.test.ts index f7c5a6d8d8..536085711c 100644 --- a/packages/core/src/core/contentGenerator.test.ts +++ b/packages/core/src/core/contentGenerator.test.ts @@ -31,7 +31,6 @@ const mockConfig = { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: vi.fn().mockReturnValue(true), - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; describe('createContentGenerator', () => { @@ -121,7 +120,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => true, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; // Set a fixed version for testing @@ -189,7 +187,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -236,7 +233,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -270,7 +266,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -312,7 +307,6 @@ describe('createContentGenerator', () => { const mockConfig = { getModel: vi.fn().mockReturnValue('gemini-pro'), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { models: {}, @@ -344,7 +338,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -378,7 +371,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -416,7 +408,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { @@ -455,7 +446,6 @@ describe('createContentGenerator', () => { getModel: vi.fn().mockReturnValue('gemini-pro'), getProxy: vi.fn().mockReturnValue(undefined), getUsageStatisticsEnabled: () => false, - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockGenerator = { diff --git a/packages/core/src/core/contentGenerator.ts b/packages/core/src/core/contentGenerator.ts index 77d0413349..c0bb4909a1 100644 --- a/packages/core/src/core/contentGenerator.ts +++ b/packages/core/src/core/contentGenerator.ts @@ -122,10 +122,7 @@ export async function createContentGenerator( return new LoggingContentGenerator(fakeGenerator, gcConfig); } const version = await getVersion(); - const model = resolveModel( - gcConfig.getModel(), - gcConfig.getPreviewFeatures(), - ); + const model = resolveModel(gcConfig.getModel()); const customHeadersEnv = process.env['GEMINI_CLI_CUSTOM_HEADERS'] || undefined; const userAgent = `GeminiCLI/${version}/${model} (${process.platform}; ${process.arch})`; diff --git a/packages/core/src/core/geminiChat.test.ts b/packages/core/src/core/geminiChat.test.ts index 741e369f58..c75cc4967d 100644 --- a/packages/core/src/core/geminiChat.test.ts +++ b/packages/core/src/core/geminiChat.test.ts @@ -130,7 +130,6 @@ describe('GeminiChat', () => { getTelemetryLogPromptsEnabled: () => true, getUsageStatisticsEnabled: () => true, getDebugMode: () => false, - getPreviewFeatures: () => false, getContentGeneratorConfig: vi.fn().mockImplementation(() => ({ authType: 'oauth-personal', model: currentModel, diff --git a/packages/core/src/core/geminiChat.ts b/packages/core/src/core/geminiChat.ts index 69c494a4e0..c45642c7be 100644 --- a/packages/core/src/core/geminiChat.ts +++ b/packages/core/src/core/geminiChat.ts @@ -492,18 +492,12 @@ export class GeminiChat { const apiCall = async () => { // Default to the last used model (which respects arguments/availability selection) - let modelToUse = resolveModel( - lastModelToUse, - this.config.getPreviewFeatures(), - ); + let modelToUse = resolveModel(lastModelToUse); // If the active model has changed (e.g. due to a fallback updating the config), // we switch to the new active model. if (this.config.getActiveModel() !== initialActiveModel) { - modelToUse = resolveModel( - this.config.getActiveModel(), - this.config.getPreviewFeatures(), - ); + modelToUse = resolveModel(this.config.getActiveModel()); } if (modelToUse !== lastModelToUse) { diff --git a/packages/core/src/core/geminiChat_network_retry.test.ts b/packages/core/src/core/geminiChat_network_retry.test.ts index 3dafc081d3..07561fed36 100644 --- a/packages/core/src/core/geminiChat_network_retry.test.ts +++ b/packages/core/src/core/geminiChat_network_retry.test.ts @@ -78,7 +78,6 @@ describe('GeminiChat Network Retries', () => { getTelemetryLogPromptsEnabled: () => true, getUsageStatisticsEnabled: () => true, getDebugMode: () => false, - getPreviewFeatures: () => false, getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth-personal', model: 'test-model', diff --git a/packages/core/src/core/prompts-substitution.test.ts b/packages/core/src/core/prompts-substitution.test.ts index dd35b639a6..b85acce6cb 100644 --- a/packages/core/src/core/prompts-substitution.test.ts +++ b/packages/core/src/core/prompts-substitution.test.ts @@ -38,7 +38,6 @@ describe('Core System Prompt Substitution', () => { isAgentsEnabled: vi.fn().mockReturnValue(false), getModel: vi.fn().mockReturnValue('auto'), getActiveModel: vi.fn().mockReturnValue('gemini-1.5-pro'), - getPreviewFeatures: vi.fn().mockReturnValue(false), getAgentRegistry: vi.fn().mockReturnValue({ getDirectoryContext: vi.fn().mockReturnValue('Mock Agent Directory'), }), diff --git a/packages/core/src/core/prompts.test.ts b/packages/core/src/core/prompts.test.ts index 931cfd6613..f92bdc8735 100644 --- a/packages/core/src/core/prompts.test.ts +++ b/packages/core/src/core/prompts.test.ts @@ -96,7 +96,6 @@ describe('Core System Prompt (prompts.ts)', () => { isAgentsEnabled: vi.fn().mockReturnValue(false), getModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO), getActiveModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL), - getPreviewFeatures: vi.fn().mockReturnValue(false), getMessageBus: vi.fn(), getAgentRegistry: vi.fn().mockReturnValue({ getDirectoryContext: vi.fn().mockReturnValue('Mock Agent Directory'), @@ -259,7 +258,6 @@ describe('Core System Prompt (prompts.ts)', () => { isAgentsEnabled: vi.fn().mockReturnValue(false), getModel: vi.fn().mockReturnValue('auto'), getActiveModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL), - getPreviewFeatures: vi.fn().mockReturnValue(false), getAgentRegistry: vi.fn().mockReturnValue({ getDirectoryContext: vi.fn().mockReturnValue('Mock Agent Directory'), }), diff --git a/packages/core/src/fallback/handler.test.ts b/packages/core/src/fallback/handler.test.ts index c6b0997737..fbb925130c 100644 --- a/packages/core/src/fallback/handler.test.ts +++ b/packages/core/src/fallback/handler.test.ts @@ -75,7 +75,6 @@ const createMockConfig = (overrides: Partial = {}): Config => ), getActiveModel: vi.fn(() => MOCK_PRO_MODEL), getModel: vi.fn(() => MOCK_PRO_MODEL), - getPreviewFeatures: vi.fn(() => false), getUserTier: vi.fn(() => undefined), isInteractive: vi.fn(() => false), ...overrides, @@ -141,7 +140,6 @@ describe('handleFallback', () => { it('uses availability selection with correct candidates when enabled', async () => { // Direct mock manipulation since it's already a vi.fn() - vi.mocked(policyConfig.getPreviewFeatures).mockReturnValue(true); vi.mocked(policyConfig.getModel).mockReturnValue( DEFAULT_GEMINI_MODEL_AUTO, ); @@ -210,7 +208,6 @@ describe('handleFallback', () => { it('does not wrap around to upgrade candidates if the current model was selected at the end (e.g. by router)', async () => { // Last-resort failure (Flash) in [Preview, Pro, Flash] checks Preview then Pro (all upstream). - vi.mocked(policyConfig.getPreviewFeatures).mockReturnValue(true); vi.mocked(policyConfig.getModel).mockReturnValue( DEFAULT_GEMINI_MODEL_AUTO, ); @@ -241,7 +238,6 @@ describe('handleFallback', () => { skipped: [], }); policyHandler.mockResolvedValue('retry_once'); - vi.mocked(policyConfig.getPreviewFeatures).mockReturnValue(true); vi.mocked(policyConfig.getActiveModel).mockReturnValue( PREVIEW_GEMINI_MODEL, ); diff --git a/packages/core/src/prompts/promptProvider.ts b/packages/core/src/prompts/promptProvider.ts index 274235d73e..46359b1e66 100644 --- a/packages/core/src/prompts/promptProvider.ts +++ b/packages/core/src/prompts/promptProvider.ts @@ -52,10 +52,7 @@ export class PromptProvider { const enabledToolNames = new Set(toolNames); const approvedPlanPath = config.getApprovedPlanPath(); - const desiredModel = resolveModel( - config.getActiveModel(), - config.getPreviewFeatures(), - ); + const desiredModel = resolveModel(config.getActiveModel()); const isGemini3 = isPreviewModel(desiredModel); // --- Context Gathering --- diff --git a/packages/core/src/routing/strategies/classifierStrategy.test.ts b/packages/core/src/routing/strategies/classifierStrategy.test.ts index ef0f784ee2..a516439557 100644 --- a/packages/core/src/routing/strategies/classifierStrategy.test.ts +++ b/packages/core/src/routing/strategies/classifierStrategy.test.ts @@ -51,7 +51,6 @@ describe('ClassifierStrategy', () => { getResolvedConfig: vi.fn().mockReturnValue(mockResolvedConfig), }, getModel: () => DEFAULT_GEMINI_MODEL_AUTO, - getPreviewFeatures: () => false, getNumericalRoutingEnabled: vi.fn().mockResolvedValue(false), } as unknown as Config; mockBaseLlmClient = { diff --git a/packages/core/src/routing/strategies/classifierStrategy.ts b/packages/core/src/routing/strategies/classifierStrategy.ts index 4edf85a351..387151046b 100644 --- a/packages/core/src/routing/strategies/classifierStrategy.ts +++ b/packages/core/src/routing/strategies/classifierStrategy.ts @@ -166,7 +166,6 @@ export class ClassifierStrategy implements RoutingStrategy { const selectedModel = resolveClassifierModel( context.requestedModel ?? config.getModel(), routerResponse.model_choice, - config.getPreviewFeatures(), ); return { diff --git a/packages/core/src/routing/strategies/defaultStrategy.test.ts b/packages/core/src/routing/strategies/defaultStrategy.test.ts index 2f1ce539e2..ceec72d171 100644 --- a/packages/core/src/routing/strategies/defaultStrategy.test.ts +++ b/packages/core/src/routing/strategies/defaultStrategy.test.ts @@ -24,7 +24,6 @@ describe('DefaultStrategy', () => { const mockContext = {} as RoutingContext; const mockConfig = { getModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO), - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockClient = {} as BaseLlmClient; @@ -45,7 +44,6 @@ describe('DefaultStrategy', () => { const mockContext = {} as RoutingContext; const mockConfig = { getModel: vi.fn().mockReturnValue(PREVIEW_GEMINI_MODEL_AUTO), - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockClient = {} as BaseLlmClient; @@ -61,12 +59,11 @@ describe('DefaultStrategy', () => { }); }); - it('should route to the preview model when requested model is auto and previewfeature is on', async () => { + it('should route to the default model when requested model is auto', async () => { const strategy = new DefaultStrategy(); const mockContext = {} as RoutingContext; const mockConfig = { getModel: vi.fn().mockReturnValue(GEMINI_MODEL_ALIAS_AUTO), - getPreviewFeatures: vi.fn().mockReturnValue(true), } as unknown as Config; const mockClient = {} as BaseLlmClient; @@ -82,34 +79,12 @@ describe('DefaultStrategy', () => { }); }); - it('should route to the default model when requested model is auto and previewfeature is off', async () => { - const strategy = new DefaultStrategy(); - const mockContext = {} as RoutingContext; - const mockConfig = { - getModel: vi.fn().mockReturnValue(GEMINI_MODEL_ALIAS_AUTO), - getPreviewFeatures: vi.fn().mockReturnValue(false), - } as unknown as Config; - const mockClient = {} as BaseLlmClient; - - const decision = await strategy.route(mockContext, mockConfig, mockClient); - - expect(decision).toEqual({ - model: DEFAULT_GEMINI_MODEL, - metadata: { - source: 'default', - latencyMs: 0, - reasoning: `Routing to default model: ${DEFAULT_GEMINI_MODEL}`, - }, - }); - }); - // this should not happen, adding the test just in case it happens. it('should route to the same model if it is not an auto mode', async () => { const strategy = new DefaultStrategy(); const mockContext = {} as RoutingContext; const mockConfig = { getModel: vi.fn().mockReturnValue(PREVIEW_GEMINI_FLASH_MODEL), - getPreviewFeatures: vi.fn().mockReturnValue(false), } as unknown as Config; const mockClient = {} as BaseLlmClient; diff --git a/packages/core/src/routing/strategies/defaultStrategy.ts b/packages/core/src/routing/strategies/defaultStrategy.ts index 5552ad1057..e5b89eb1b3 100644 --- a/packages/core/src/routing/strategies/defaultStrategy.ts +++ b/packages/core/src/routing/strategies/defaultStrategy.ts @@ -21,10 +21,7 @@ export class DefaultStrategy implements TerminalStrategy { config: Config, _baseLlmClient: BaseLlmClient, ): Promise { - const defaultModel = resolveModel( - config.getModel(), - config.getPreviewFeatures(), - ); + const defaultModel = resolveModel(config.getModel()); return { model: defaultModel, metadata: { diff --git a/packages/core/src/routing/strategies/fallbackStrategy.test.ts b/packages/core/src/routing/strategies/fallbackStrategy.test.ts index 2d30b153e5..d0be7938c4 100644 --- a/packages/core/src/routing/strategies/fallbackStrategy.test.ts +++ b/packages/core/src/routing/strategies/fallbackStrategy.test.ts @@ -25,7 +25,6 @@ const createMockConfig = (overrides: Partial = {}): Config => ({ getModelAvailabilityService: vi.fn(), getModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL), - getPreviewFeatures: vi.fn().mockReturnValue(false), ...overrides, }) as unknown as Config; diff --git a/packages/core/src/routing/strategies/fallbackStrategy.ts b/packages/core/src/routing/strategies/fallbackStrategy.ts index 383f441713..d568039cbc 100644 --- a/packages/core/src/routing/strategies/fallbackStrategy.ts +++ b/packages/core/src/routing/strategies/fallbackStrategy.ts @@ -23,10 +23,7 @@ export class FallbackStrategy implements RoutingStrategy { _baseLlmClient: BaseLlmClient, ): Promise { const requestedModel = context.requestedModel ?? config.getModel(); - const resolvedModel = resolveModel( - requestedModel, - config.getPreviewFeatures(), - ); + const resolvedModel = resolveModel(requestedModel); const service = config.getModelAvailabilityService(); const snapshot = service.snapshot(resolvedModel); diff --git a/packages/core/src/routing/strategies/numericalClassifierStrategy.test.ts b/packages/core/src/routing/strategies/numericalClassifierStrategy.test.ts index 93e75fcdb5..73c1d91efc 100644 --- a/packages/core/src/routing/strategies/numericalClassifierStrategy.test.ts +++ b/packages/core/src/routing/strategies/numericalClassifierStrategy.test.ts @@ -47,7 +47,6 @@ describe('NumericalClassifierStrategy', () => { getResolvedConfig: vi.fn().mockReturnValue(mockResolvedConfig), }, getModel: () => DEFAULT_GEMINI_MODEL_AUTO, - getPreviewFeatures: () => false, getSessionId: vi.fn().mockReturnValue('control-group-id'), // Default to Control Group (Hash 71 >= 50) getNumericalRoutingEnabled: vi.fn().mockResolvedValue(true), getClassifierThreshold: vi.fn().mockResolvedValue(undefined), diff --git a/packages/core/src/routing/strategies/numericalClassifierStrategy.ts b/packages/core/src/routing/strategies/numericalClassifierStrategy.ts index 9bcaebf432..10ccb6dc4f 100644 --- a/packages/core/src/routing/strategies/numericalClassifierStrategy.ts +++ b/packages/core/src/routing/strategies/numericalClassifierStrategy.ts @@ -179,7 +179,6 @@ export class NumericalClassifierStrategy implements RoutingStrategy { const selectedModel = resolveClassifierModel( config.getModel(), modelAlias, - config.getPreviewFeatures(), ); const latencyMs = Date.now() - startTime; diff --git a/packages/core/src/routing/strategies/overrideStrategy.test.ts b/packages/core/src/routing/strategies/overrideStrategy.test.ts index 97e9f4915f..73c1aeec62 100644 --- a/packages/core/src/routing/strategies/overrideStrategy.test.ts +++ b/packages/core/src/routing/strategies/overrideStrategy.test.ts @@ -19,7 +19,6 @@ describe('OverrideStrategy', () => { it('should return null when the override model is auto', async () => { const mockConfig = { getModel: () => DEFAULT_GEMINI_MODEL_AUTO, - getPreviewFeatures: () => false, } as Config; const decision = await strategy.route(mockContext, mockConfig, mockClient); @@ -30,7 +29,6 @@ describe('OverrideStrategy', () => { const overrideModel = 'gemini-2.5-pro-custom'; const mockConfig = { getModel: () => overrideModel, - getPreviewFeatures: () => false, } as Config; const decision = await strategy.route(mockContext, mockConfig, mockClient); @@ -48,7 +46,6 @@ describe('OverrideStrategy', () => { const overrideModel = 'gemini-2.5-flash-experimental'; const mockConfig = { getModel: () => overrideModel, - getPreviewFeatures: () => false, } as Config; const decision = await strategy.route(mockContext, mockConfig, mockClient); @@ -62,7 +59,6 @@ describe('OverrideStrategy', () => { const configModel = 'config-model'; const mockConfig = { getModel: () => configModel, - getPreviewFeatures: () => false, } as Config; const contextWithRequestedModel = { requestedModel, diff --git a/packages/core/src/routing/strategies/overrideStrategy.ts b/packages/core/src/routing/strategies/overrideStrategy.ts index c5f632ca3d..b8382407bd 100644 --- a/packages/core/src/routing/strategies/overrideStrategy.ts +++ b/packages/core/src/routing/strategies/overrideStrategy.ts @@ -33,7 +33,7 @@ export class OverrideStrategy implements RoutingStrategy { // Return the overridden model name. return { - model: resolveModel(overrideModel, config.getPreviewFeatures()), + model: resolveModel(overrideModel), metadata: { source: this.name, latencyMs: 0, diff --git a/packages/test-utils/src/test-rig.ts b/packages/test-utils/src/test-rig.ts index de58b43daa..9648751339 100644 --- a/packages/test-utils/src/test-rig.ts +++ b/packages/test-utils/src/test-rig.ts @@ -390,7 +390,6 @@ export class TestRig { // Nightly releases sometimes becomes out of sync with local code and // triggers auto-update, which causes tests to fail. disableAutoUpdate: true, - previewFeatures: false, }, telemetry: { enabled: true, diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 1fd5f62ffd..2cac0ed760 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -29,13 +29,6 @@ "default": {}, "type": "object", "properties": { - "previewFeatures": { - "title": "Preview Features (e.g., models)", - "description": "Enable preview features (e.g., preview models).", - "markdownDescription": "Enable preview features (e.g., preview models).\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `false`", - "default": false, - "type": "boolean" - }, "preferredEditor": { "title": "Preferred Editor", "description": "The preferred editor to open files in.",