Skip to content

Commit 6f19d7b

Browse files
sehoon38gemini-cli-robot
authored andcommitted
feat(core): add policy chain support for Gemini 3.1 (#19991)
# Conflicts: # packages/core/src/availability/policyHelpers.test.ts # packages/core/src/availability/policyHelpers.ts
1 parent aee560c commit 6f19d7b

4 files changed

Lines changed: 114 additions & 7 deletions

File tree

packages/core/src/availability/policyCatalog.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
} from './policyCatalog.js';
1313
import {
1414
DEFAULT_GEMINI_MODEL,
15+
PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
16+
PREVIEW_GEMINI_3_1_MODEL,
1517
PREVIEW_GEMINI_MODEL,
1618
} from '../config/models.js';
1719

@@ -22,6 +24,27 @@ describe('policyCatalog', () => {
2224
expect(chain).toHaveLength(2);
2325
});
2426

27+
it('returns Gemini 3.1 chain when useGemini31 is true', () => {
28+
const chain = getModelPolicyChain({
29+
previewEnabled: true,
30+
useGemini31: true,
31+
});
32+
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_MODEL);
33+
expect(chain).toHaveLength(2);
34+
expect(chain[1]?.model).toBe('gemini-3-flash-preview');
35+
});
36+
37+
it('returns Gemini 3.1 Custom Tools chain when useGemini31 and useCustomToolModel are true', () => {
38+
const chain = getModelPolicyChain({
39+
previewEnabled: true,
40+
useGemini31: true,
41+
useCustomToolModel: true,
42+
});
43+
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL);
44+
expect(chain).toHaveLength(2);
45+
expect(chain[1]?.model).toBe('gemini-3-flash-preview');
46+
});
47+
2548
it('returns default chain when preview disabled', () => {
2649
const chain = getModelPolicyChain({ previewEnabled: false });
2750
expect(chain[0]?.model).toBe(DEFAULT_GEMINI_MODEL);

packages/core/src/availability/policyCatalog.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
DEFAULT_GEMINI_MODEL,
1717
PREVIEW_GEMINI_FLASH_MODEL,
1818
PREVIEW_GEMINI_MODEL,
19+
resolveModel,
1920
} from '../config/models.js';
2021
import type { UserTierId } from '../code_assist/types.js';
2122

@@ -28,6 +29,8 @@ type PolicyConfig = Omit<ModelPolicy, 'actions' | 'stateTransitions'> & {
2829
export interface ModelPolicyOptions {
2930
previewEnabled: boolean;
3031
userTier?: UserTierId;
32+
useGemini31?: boolean;
33+
useCustomToolModel?: boolean;
3134
}
3235

3336
const DEFAULT_ACTIONS: ModelPolicyActionMap = {
@@ -56,11 +59,6 @@ const DEFAULT_CHAIN: ModelPolicyChain = [
5659
definePolicy({ model: DEFAULT_GEMINI_FLASH_MODEL, isLastResort: true }),
5760
];
5861

59-
const PREVIEW_CHAIN: ModelPolicyChain = [
60-
definePolicy({ model: PREVIEW_GEMINI_MODEL }),
61-
definePolicy({ model: PREVIEW_GEMINI_FLASH_MODEL, isLastResort: true }),
62-
];
63-
6462
const FLASH_LITE_CHAIN: ModelPolicyChain = [
6563
definePolicy({
6664
model: DEFAULT_GEMINI_FLASH_LITE_MODEL,
@@ -84,7 +82,15 @@ export function getModelPolicyChain(
8482
options: ModelPolicyOptions,
8583
): ModelPolicyChain {
8684
if (options.previewEnabled) {
87-
return cloneChain(PREVIEW_CHAIN);
85+
const previewModel = resolveModel(
86+
PREVIEW_GEMINI_MODEL,
87+
options.useGemini31,
88+
options.useCustomToolModel,
89+
);
90+
return [
91+
definePolicy({ model: previewModel }),
92+
definePolicy({ model: PREVIEW_GEMINI_FLASH_MODEL, isLastResort: true }),
93+
];
8894
}
8995

9096
return cloneChain(DEFAULT_CHAIN);

packages/core/src/availability/policyHelpers.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ import type { Config } from '../config/config.js';
1515
import {
1616
DEFAULT_GEMINI_FLASH_LITE_MODEL,
1717
DEFAULT_GEMINI_MODEL_AUTO,
18+
PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL,
19+
PREVIEW_GEMINI_3_1_MODEL,
1820
} from '../config/models.js';
21+
import { AuthType } from '../core/contentGenerator.js';
1922

2023
const createMockConfig = (overrides: Partial<Config> = {}): Config =>
2124
({
2225
getUserTier: () => undefined,
2326
getModel: () => 'gemini-2.5-pro',
27+
getGemini31LaunchedSync: () => false,
28+
getContentGeneratorConfig: () => ({ authType: undefined }),
2429
...overrides,
2530
}) as unknown as Config;
2631

@@ -115,6 +120,43 @@ describe('policyHelpers', () => {
115120
expect(chain[0]?.model).toBe('gemini-2.5-flash');
116121
expect(chain[1]?.model).toBe('gemini-2.5-pro');
117122
});
123+
<<<<<<< HEAD
124+
=======
125+
126+
it('proactively returns Gemini 2.5 chain if Gemini 3 requested but user lacks access', () => {
127+
const config = createMockConfig({
128+
getModel: () => 'auto-gemini-3',
129+
getHasAccessToPreviewModel: () => false,
130+
});
131+
const chain = resolvePolicyChain(config);
132+
133+
// Should downgrade to [Pro 2.5, Flash 2.5]
134+
expect(chain).toHaveLength(2);
135+
expect(chain[0]?.model).toBe('gemini-2.5-pro');
136+
expect(chain[1]?.model).toBe('gemini-2.5-flash');
137+
});
138+
139+
it('returns Gemini 3.1 Pro chain when launched and auto-gemini-3 requested', () => {
140+
const config = createMockConfig({
141+
getModel: () => 'auto-gemini-3',
142+
getGemini31LaunchedSync: () => true,
143+
});
144+
const chain = resolvePolicyChain(config);
145+
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_MODEL);
146+
expect(chain[1]?.model).toBe('gemini-3-flash-preview');
147+
});
148+
149+
it('returns Gemini 3.1 Pro Custom Tools chain when launched, auth is Gemini, and auto-gemini-3 requested', () => {
150+
const config = createMockConfig({
151+
getModel: () => 'auto-gemini-3',
152+
getGemini31LaunchedSync: () => true,
153+
getContentGeneratorConfig: () => ({ authType: AuthType.USE_GEMINI }),
154+
});
155+
const chain = resolvePolicyChain(config);
156+
expect(chain[0]?.model).toBe(PREVIEW_GEMINI_3_1_CUSTOM_TOOLS_MODEL);
157+
expect(chain[1]?.model).toBe('gemini-3-flash-preview');
158+
});
159+
>>>>>>> aa9163da6 (feat(core): add policy chain support for Gemini 3.1 (#19991))
118160
});
119161

120162
describe('buildFallbackPolicyContext', () => {

packages/core/src/availability/policyHelpers.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import type { GenerateContentConfig } from '@google/genai';
88
import type { Config } from '../config/config.js';
9+
import { AuthType } from '../core/contentGenerator.js';
910
import type {
1011
FailureKind,
1112
FallbackAction,
@@ -43,15 +44,22 @@ export function resolvePolicyChain(
4344
const configuredModel = config.getModel();
4445

4546
let chain;
47+
const useGemini31 = config.getGemini31LaunchedSync?.() ?? false;
48+
const useCustomToolModel =
49+
useGemini31 &&
50+
config.getContentGeneratorConfig?.()?.authType === AuthType.USE_GEMINI;
51+
4652
const resolvedModel = resolveModel(
4753
modelFromConfig,
48-
config.getGemini31LaunchedSync?.() ?? false,
54+
useGemini31,
55+
useCustomToolModel,
4956
);
5057
const isAutoPreferred = preferredModel ? isAutoModel(preferredModel) : false;
5158
const isAutoConfigured = isAutoModel(configuredModel);
5259

5360
if (resolvedModel === DEFAULT_GEMINI_FLASH_LITE_MODEL) {
5461
chain = getFlashLitePolicyChain();
62+
<<<<<<< HEAD
5563
} else if (isAutoPreferred || isAutoConfigured) {
5664
const previewEnabled =
5765
preferredModel === PREVIEW_GEMINI_MODEL_AUTO ||
@@ -60,6 +68,34 @@ export function resolvePolicyChain(
6068
previewEnabled,
6169
userTier: config.getUserTier(),
6270
});
71+
=======
72+
} else if (
73+
isGemini3Model(resolvedModel) ||
74+
isAutoPreferred ||
75+
isAutoConfigured
76+
) {
77+
if (hasAccessToPreview) {
78+
const previewEnabled =
79+
isGemini3Model(resolvedModel) ||
80+
preferredModel === PREVIEW_GEMINI_MODEL_AUTO ||
81+
configuredModel === PREVIEW_GEMINI_MODEL_AUTO;
82+
chain = getModelPolicyChain({
83+
previewEnabled,
84+
userTier: config.getUserTier(),
85+
useGemini31,
86+
useCustomToolModel,
87+
});
88+
} else {
89+
// User requested Gemini 3 but has no access. Proactively downgrade
90+
// to the stable Gemini 2.5 chain.
91+
return getModelPolicyChain({
92+
previewEnabled: false,
93+
userTier: config.getUserTier(),
94+
useGemini31,
95+
useCustomToolModel,
96+
});
97+
}
98+
>>>>>>> aa9163da6 (feat(core): add policy chain support for Gemini 3.1 (#19991))
6399
} else {
64100
chain = createSingleModelChain(modelFromConfig);
65101
}

0 commit comments

Comments
 (0)