Skip to content

Commit 686db11

Browse files
DavidAPiercehotmanxp
authored andcommitted
Respect backend definitions for 3.5 flash and Update auto mode to use 3.5 flash when the flag is enabled. (google-gemini#27645)
1 parent a55ce06 commit 686db11

24 files changed

Lines changed: 463 additions & 42 deletions

docs/reference/configuration.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,13 +1042,15 @@ their corresponding top-level category object in your `settings.json` file.
10421042
"contexts": [
10431043
{
10441044
"condition": {
1045+
"hasAccessToPreview": false,
10451046
"useGemini3_5Flash": true
10461047
},
10471048
"target": "gemini-3.5-flash"
10481049
},
10491050
{
10501051
"condition": {
1051-
"hasAccessToPreview": false
1052+
"hasAccessToPreview": false,
1053+
"useGemini3_5Flash": false
10521054
},
10531055
"target": "gemini-2.5-flash"
10541056
}

packages/cli/src/acp/acpUtils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ export function buildAvailableModels(
265265
const preferredModel = config.getModel() || GEMINI_MODEL_ALIAS_AUTO;
266266
const shouldShowPreviewModels = config.getHasAccessToPreviewModel();
267267
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
268+
const useGemini3_5Flash = config.hasGemini35FlashGAAccess?.() ?? false;
268269
const selectedAuthType = settings.merged.security.auth.selectedType;
269270
const useCustomToolModel =
270271
useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
@@ -276,6 +277,7 @@ export function buildAvailableModels(
276277
) {
277278
const options = config.getModelConfigService().getAvailableModelOptions({
278279
useGemini3_1: useGemini31,
280+
useGemini3_5Flash,
279281
useCustomTools: useCustomToolModel,
280282
hasAccessToPreview: shouldShowPreviewModels,
281283
});
@@ -294,6 +296,7 @@ export function buildAvailableModels(
294296
description: getAutoModelDescription(
295297
shouldShowPreviewModels,
296298
useGemini31,
299+
useGemini3_5Flash,
297300
),
298301
},
299302
];

packages/cli/src/ui/components/ModelDialog.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
6767

6868
const shouldShowPreviewModels = config?.getHasAccessToPreviewModel() ?? false;
6969
const useGemini31 = config?.getGemini31LaunchedSync?.() ?? false;
70+
const useGemini3_5Flash = config?.hasGemini35FlashGAAccess?.() ?? false;
7071
const selectedAuthType = settings.merged.security.auth.selectedType;
7172
const useCustomToolModel =
7273
useGemini31 && selectedAuthType === AuthType.USE_GEMINI;
@@ -129,6 +130,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
129130
.getModelConfigService()
130131
.getAvailableModelOptions({
131132
useGemini3_1: useGemini31,
133+
useGemini3_5Flash,
132134
useCustomTools: useCustomToolModel,
133135
hasAccessToPreview: shouldShowPreviewModels,
134136
hasAccessToProModel,
@@ -162,6 +164,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
162164
description: getAutoModelDescription(
163165
shouldShowPreviewModels,
164166
useGemini31,
167+
useGemini3_5Flash,
165168
),
166169
key: GEMINI_MODEL_ALIAS_AUTO,
167170
},
@@ -181,6 +184,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
181184
shouldShowPreviewModels,
182185
manualModelSelected,
183186
useGemini31,
187+
useGemini3_5Flash,
184188
useCustomToolModel,
185189
hasAccessToProModel,
186190
]);
@@ -195,6 +199,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
195199
.getModelConfigService()
196200
.getAvailableModelOptions({
197201
useGemini3_1: useGemini31,
202+
useGemini3_5Flash,
198203
useCustomTools: useCustomToolModel,
199204
hasAccessToPreview: shouldShowPreviewModels,
200205
hasAccessToProModel,
@@ -287,6 +292,7 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element {
287292
}, [
288293
shouldShowPreviewModels,
289294
useGemini31,
295+
useGemini3_5Flash,
290296
useCustomToolModel,
291297
hasAccessToProModel,
292298
config,

packages/cli/src/ui/components/ModelStatsDisplay.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,49 @@ describe('<ModelStatsDisplay />', () => {
353353
unmount();
354354
});
355355

356+
it('should resolve gemini-3-flash to gemini-3.5-flash via getDisplayString', async () => {
357+
const { lastFrame, unmount } = await renderWithMockedStats({
358+
models: {
359+
'gemini-3-flash': {
360+
api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 100 },
361+
tokens: {
362+
input: 5,
363+
prompt: 10,
364+
candidates: 20,
365+
total: 30,
366+
cached: 5,
367+
thoughts: 2,
368+
tool: 1,
369+
},
370+
roles: {},
371+
},
372+
},
373+
tools: {
374+
totalCalls: 0,
375+
totalSuccess: 0,
376+
totalFail: 0,
377+
totalDurationMs: 0,
378+
totalDecisions: {
379+
accept: 0,
380+
reject: 0,
381+
modify: 0,
382+
[ToolCallDecision.AUTO_ACCEPT]: 0,
383+
},
384+
byName: {},
385+
},
386+
files: {
387+
totalLinesAdded: 0,
388+
totalLinesRemoved: 0,
389+
},
390+
});
391+
392+
const output = lastFrame();
393+
expect(output).toContain('gemini-3.5-flash');
394+
expect(output).not.toContain('gemini-3-flash');
395+
expect(output).toMatchSnapshot();
396+
unmount();
397+
});
398+
356399
it('should handle models with long names (gemini-3-*-preview) without layout breaking', async () => {
357400
const { lastFrame, unmount } = await renderWithMockedStats(
358401
{

packages/cli/src/ui/components/ModelStatsDisplay.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ export const ModelStatsDisplay: React.FC<ModelStatsDisplayProps> = ({
299299
},
300300
...modelNames.map((name) => ({
301301
key: name,
302-
header: name,
302+
header: getDisplayString(name),
303303
flexGrow: 1,
304304
renderCell: (row: StatRowData) => {
305305
// Don't render anything for section headers in model columns

packages/cli/src/ui/components/StatsDisplay.test.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,33 @@ describe('<StatsDisplay />', () => {
131131
expect(output).toMatchSnapshot();
132132
});
133133

134+
it('resolves gemini-3-flash to gemini-3.5-flash in the model usage table', async () => {
135+
const metrics = createTestMetrics({
136+
models: {
137+
'gemini-3-flash': {
138+
api: { totalRequests: 5, totalErrors: 0, totalLatencyMs: 3000 },
139+
tokens: {
140+
input: 1000,
141+
prompt: 2000,
142+
candidates: 3000,
143+
total: 5000,
144+
cached: 500,
145+
thoughts: 100,
146+
tool: 50,
147+
},
148+
roles: {},
149+
},
150+
},
151+
});
152+
153+
const { lastFrame } = await renderWithMockedStats(metrics);
154+
const output = lastFrame();
155+
156+
expect(output).toContain('gemini-3.5-flash');
157+
expect(output).not.toContain('gemini-3-flash\u0020'); // Avoid matching parts of substrings if not intended
158+
expect(output).toMatchSnapshot();
159+
});
160+
134161
it('renders role breakdown correctly under models', async () => {
135162
const metrics = createTestMetrics({
136163
models: {

packages/cli/src/ui/components/StatsDisplay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
import { computeSessionStats } from '../utils/computeStats.js';
2525
import { useSettings } from '../contexts/SettingsContext.js';
2626
import type { QuotaStats } from '../types.js';
27-
import { LlmRole } from '@google/gemini-cli-core';
27+
import { LlmRole, getDisplayString } from '@google/gemini-cli-core';
2828

2929
// A more flexible and powerful StatRow component
3030
interface StatRowProps {
@@ -101,7 +101,7 @@ const ModelUsageTable: React.FC<ModelUsageTableProps> = ({ models }) => {
101101
Object.entries(models).forEach(([name, metrics]) => {
102102
rows.push({
103103
name,
104-
displayName: name,
104+
displayName: getDisplayString(name),
105105
requests: metrics.api.totalRequests,
106106
cachedTokens: metrics.tokens.cached.toLocaleString(),
107107
inputTokens: metrics.tokens.prompt.toLocaleString(),

packages/cli/src/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,26 @@ exports[`<ModelStatsDisplay /> > should render "no API calls" message when there
215215
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
216216
"
217217
`;
218+
219+
exports[`<ModelStatsDisplay /> > should resolve gemini-3-flash to gemini-3.5-flash via getDisplayString 1`] = `
220+
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
221+
│ │
222+
│ Model Stats For Nerds │
223+
│ │
224+
│ │
225+
│ Metric gemini-3.5-flash │
226+
│ ────────────────────────────────────────────────────────────────────────────────────────────── │
227+
│ API │
228+
│ Requests 1 │
229+
│ Errors 0 (0.0%) │
230+
│ Avg Latency 100ms │
231+
│ Tokens │
232+
│ Total 30 │
233+
│ ↳ Input 5 │
234+
│ ↳ Cache Reads 5 (50.0%) │
235+
│ ↳ Thoughts 2 │
236+
│ ↳ Tool 1 │
237+
│ ↳ Output 20 │
238+
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
239+
"
240+
`;

packages/cli/src/ui/components/__snapshots__/StatsDisplay.test.tsx.snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,3 +292,30 @@ exports[`<StatsDisplay /> > renders role breakdown correctly under models 1`] =
292292
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
293293
"
294294
`;
295+
296+
exports[`<StatsDisplay /> > resolves gemini-3-flash to gemini-3.5-flash in the model usage table 1`] = `
297+
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
298+
│ │
299+
│ Session Stats │
300+
│ │
301+
│ Interaction Summary │
302+
│ Session ID: test-session-id │
303+
│ Tool Calls: 0 ( ✓ 0 x 0 ) │
304+
│ Success Rate: 0.0% │
305+
│ │
306+
│ Performance │
307+
│ Wall Time: 1s │
308+
│ Agent Active: 3.0s │
309+
│ » API Time: 3.0s (100.0%) │
310+
│ » Tool Time: 0s (0.0%) │
311+
│ │
312+
│ │
313+
│ Model Usage │
314+
│ Use /model to view model quota information │
315+
│ │
316+
│ Model Reqs Input Tokens Cache Reads Output Tokens │
317+
│ ────────────────────────────────────────────────────────────────────────────────────────────── │
318+
│ gemini-3.5-flash 5 2,000 500 3,000 │
319+
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
320+
"
321+
`;

packages/core/src/config/config.test.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,8 +4357,9 @@ describe('hasGemini35FlashGAAccess model setting', () => {
43574357
cwd: '.',
43584358
};
43594359

4360-
it('should set DEFAULT_GEMINI_FLASH_MODEL and PREVIEW_GEMINI_FLASH_MODEL to gemini-3.5-flash if hasGemini35FlashGAAccess returns true', () => {
4360+
it('should set DEFAULT_GEMINI_FLASH_MODEL to gemini-3.5-flash and PREVIEW_GEMINI_FLASH_MODEL to gemini-3-flash-preview if hasGemini35FlashGAAccess returns true and authType is USE_GEMINI', () => {
43614361
const config = new Config(baseParams);
4362+
config['contentGeneratorConfig'] = { authType: AuthType.USE_GEMINI };
43624363

43634364
// Set experiment to return true for GEMINI_3_5_FLASH_GA_LAUNCHED
43644365
config.setExperiments({
@@ -4375,6 +4376,28 @@ describe('hasGemini35FlashGAAccess model setting', () => {
43754376
expect(result).toBe(true);
43764377

43774378
expect(DEFAULT_GEMINI_FLASH_MODEL).toBe('gemini-3.5-flash');
4378-
expect(PREVIEW_GEMINI_FLASH_MODEL).toBe('gemini-3.5-flash');
4379+
expect(PREVIEW_GEMINI_FLASH_MODEL).toBe('gemini-3-flash-preview');
4380+
});
4381+
4382+
it('should set DEFAULT_GEMINI_FLASH_MODEL and PREVIEW_GEMINI_FLASH_MODEL to gemini-3-flash if hasGemini35FlashGAAccess returns true and authType is not USE_GEMINI', () => {
4383+
const config = new Config(baseParams);
4384+
config['contentGeneratorConfig'] = { authType: AuthType.LOGIN_WITH_GOOGLE };
4385+
4386+
// Set experiment to return true for GEMINI_3_5_FLASH_GA_LAUNCHED
4387+
config.setExperiments({
4388+
experimentIds: [],
4389+
flags: {
4390+
[ExperimentFlags.GEMINI_3_5_FLASH_GA_LAUNCHED]: {
4391+
boolValue: true,
4392+
},
4393+
},
4394+
});
4395+
4396+
// Call the method
4397+
const result = config.hasGemini35FlashGAAccess();
4398+
expect(result).toBe(true);
4399+
4400+
expect(DEFAULT_GEMINI_FLASH_MODEL).toBe('gemini-3-flash');
4401+
expect(PREVIEW_GEMINI_FLASH_MODEL).toBe('gemini-3-flash');
43794402
});
43804403
});

0 commit comments

Comments
 (0)