Remove previewFeatures and default to Gemini 3 (#18414)

This commit is contained in:
Sehoon Shon
2026-02-06 13:02:57 -05:00
committed by GitHub
parent 1495294cc0
commit 61d92c4a21
57 changed files with 91 additions and 797 deletions
+5 -35
View File
@@ -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');
});
+2 -16
View File
@@ -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');
@@ -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
@@ -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 {