Use Preview Flash model if the main model is a preview model for code… (#83)

* Use Preview Flash model if the main model is a preview model for codebase investigator

* fix test

* Generate settings doc
This commit is contained in:
Sehoon Shon
2025-12-12 09:43:46 -05:00
committed by Tommaso Sciortino
parent 48ad6983a3
commit 16e06adb46
8 changed files with 96 additions and 34 deletions

View File

@@ -832,7 +832,7 @@ their corresponding top-level category object in your `settings.json` file.
- **`experimental.codebaseInvestigatorSettings.model`** (string):
- **Description:** The model to use for the Codebase Investigator agent.
- **Default:** `"gemini-2.5-pro"`
- **Default:** `"auto"`
- **Requires restart:** Yes
#### `hooks`

View File

@@ -19,7 +19,7 @@ import {
DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
DEFAULT_MODEL_CONFIGS,
DEFAULT_GEMINI_MODEL,
GEMINI_MODEL_ALIAS_AUTO,
} from '@google/gemini-cli-core';
import type { CustomTheme } from '../ui/themes/theme.js';
import type { SessionRetentionSettings } from './settings.js';
@@ -1394,7 +1394,7 @@ const SETTINGS_SCHEMA = {
label: 'Model',
category: 'Experimental',
requiresRestart: true,
default: DEFAULT_GEMINI_MODEL,
default: GEMINI_MODEL_ALIAS_AUTO,
description:
'The model to use for the Codebase Investigator agent.',
showInDialog: false,

View File

@@ -10,7 +10,13 @@ import { makeFakeConfig } from '../test-utils/config.js';
import type { AgentDefinition } from './types.js';
import type { Config } from '../config/config.js';
import { debugLogger } from '../utils/debugLogger.js';
import { DEFAULT_GEMINI_MODEL } from '../config/models.js';
import {
DEFAULT_GEMINI_FLASH_LITE_MODEL,
GEMINI_MODEL_ALIAS_AUTO,
PREVIEW_GEMINI_FLASH_MODEL,
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL_AUTO,
} from '../config/models.js';
// A test-only subclass to expose the protected `registerAgent` method.
class TestableAgentRegistry extends AgentRegistry {
@@ -74,12 +80,12 @@ describe('AgentRegistry', () => {
);
});
it('should use preview model for codebase investigator if main model is preview', async () => {
it('should use preview flash model for codebase investigator if main model is preview pro', async () => {
const previewConfig = makeFakeConfig({
model: 'gemini-3-pro-preview',
model: PREVIEW_GEMINI_MODEL,
codebaseInvestigatorSettings: {
enabled: true,
model: DEFAULT_GEMINI_MODEL,
model: GEMINI_MODEL_ALIAS_AUTO,
},
});
const previewRegistry = new TestableAgentRegistry(previewConfig);
@@ -90,7 +96,51 @@ describe('AgentRegistry', () => {
'codebase_investigator',
);
expect(investigatorDef).toBeDefined();
expect(investigatorDef?.modelConfig.model).toBe('gemini-3-pro-preview');
expect(investigatorDef?.modelConfig.model).toBe(
PREVIEW_GEMINI_FLASH_MODEL,
);
});
it('should use preview flash model for codebase investigator if main model is preview auto', async () => {
const previewConfig = makeFakeConfig({
model: PREVIEW_GEMINI_MODEL_AUTO,
codebaseInvestigatorSettings: {
enabled: true,
model: GEMINI_MODEL_ALIAS_AUTO,
},
});
const previewRegistry = new TestableAgentRegistry(previewConfig);
await previewRegistry.initialize();
const investigatorDef = previewRegistry.getDefinition(
'codebase_investigator',
);
expect(investigatorDef).toBeDefined();
expect(investigatorDef?.modelConfig.model).toBe(
PREVIEW_GEMINI_FLASH_MODEL,
);
});
it('should use the model from the investigator settings', async () => {
const previewConfig = makeFakeConfig({
model: PREVIEW_GEMINI_MODEL,
codebaseInvestigatorSettings: {
enabled: true,
model: DEFAULT_GEMINI_FLASH_LITE_MODEL,
},
});
const previewRegistry = new TestableAgentRegistry(previewConfig);
await previewRegistry.initialize();
const investigatorDef = previewRegistry.getDefinition(
'codebase_investigator',
);
expect(investigatorDef).toBeDefined();
expect(investigatorDef?.modelConfig.model).toBe(
DEFAULT_GEMINI_FLASH_LITE_MODEL,
);
});
});

View File

@@ -11,11 +11,12 @@ import { type z } from 'zod';
import { debugLogger } from '../utils/debugLogger.js';
import {
DEFAULT_GEMINI_MODEL,
DEFAULT_GEMINI_MODEL_AUTO,
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL_AUTO,
GEMINI_MODEL_ALIAS_AUTO,
PREVIEW_GEMINI_FLASH_MODEL,
isPreviewModel,
} from '../config/models.js';
import type { ModelConfigAlias } from '../services/modelConfigService.js';
import { coreEvents, CoreEvent } from '../utils/events.js';
/**
* Returns the model config alias for a given agent definition.
@@ -42,6 +43,10 @@ export class AgentRegistry {
async initialize(): Promise<void> {
this.loadBuiltInAgents();
coreEvents.on(CoreEvent.ModelChanged, () => {
this.loadBuiltInAgents();
});
if (this.config.getDebugMode()) {
debugLogger.log(
`[AgentRegistry] Initialized with ${this.agents.size} agents.`,
@@ -54,23 +59,17 @@ export class AgentRegistry {
// Only register the agent if it's enabled in the settings.
if (investigatorSettings?.enabled) {
let model =
investigatorSettings.model ??
CodebaseInvestigatorAgent.modelConfig.model;
// If the user is using the preview model for the main agent, force the sub-agent to use it too
// if it's configured to use 'pro' or 'auto'.
if (
this.config.getModel() === PREVIEW_GEMINI_MODEL ||
this.config.getModel() === PREVIEW_GEMINI_MODEL_AUTO
) {
if (
model === PREVIEW_GEMINI_MODEL_AUTO ||
model === DEFAULT_GEMINI_MODEL_AUTO ||
model === DEFAULT_GEMINI_MODEL
) {
model = PREVIEW_GEMINI_MODEL;
}
let model;
const settingsModel = investigatorSettings.model;
// Check if the user explicitly set a model in the settings.
if (settingsModel && settingsModel !== GEMINI_MODEL_ALIAS_AUTO) {
model = settingsModel;
} else {
// Use Preview Flash model if the main model is any of the preview models
// If the main model is not preview model, use default pro model.
model = isPreviewModel(this.config.getModel())
? PREVIEW_GEMINI_FLASH_MODEL
: DEFAULT_GEMINI_MODEL;
}
const agentDef = {

View File

@@ -1704,18 +1704,16 @@ describe('Availability Service Integration', () => {
cwd: '.',
};
it('setActiveModel updates active model and emits event', async () => {
it('setActiveModel updates active model', async () => {
const config = new Config(baseParams);
const model1 = 'model1';
const model2 = 'model2';
config.setActiveModel(model1);
expect(config.getActiveModel()).toBe(model1);
expect(mockCoreEvents.emitModelChanged).toHaveBeenCalledWith(model1);
config.setActiveModel(model2);
expect(config.getActiveModel()).toBe(model2);
expect(mockCoreEvents.emitModelChanged).toHaveBeenCalledWith(model2);
});
it('getActiveModel defaults to configured model if not set', () => {

View File

@@ -843,7 +843,6 @@ export class Config {
setActiveModel(model: string): void {
if (this._activeModel !== model) {
this._activeModel = model;
coreEvents.emitModelChanged(model);
}
}

View File

@@ -12,6 +12,7 @@ export const DEFAULT_GEMINI_FLASH_LITE_MODEL = 'gemini-2.5-flash-lite';
export const VALID_GEMINI_MODELS = new Set([
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_MODEL,
DEFAULT_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_FLASH_LITE_MODEL,
@@ -21,6 +22,7 @@ export const PREVIEW_GEMINI_MODEL_AUTO = 'auto-gemini-3';
export const DEFAULT_GEMINI_MODEL_AUTO = 'auto-gemini-2.5';
// Model aliases for user convenience.
export const GEMINI_MODEL_ALIAS_AUTO = 'auto';
export const GEMINI_MODEL_ALIAS_PRO = 'pro';
export const GEMINI_MODEL_ALIAS_FLASH = 'flash';
export const GEMINI_MODEL_ALIAS_FLASH_LITE = 'flash-lite';
@@ -124,6 +126,20 @@ export function getDisplayString(model: string) {
}
}
/**
* Checks if the model is a preview model.
*
* @param model The model name to check.
* @returns True if the model is a preview model.
*/
export function isPreviewModel(model: string): boolean {
return (
model === PREVIEW_GEMINI_MODEL ||
model === PREVIEW_GEMINI_FLASH_MODEL ||
model === PREVIEW_GEMINI_MODEL_AUTO
);
}
/**
* Checks if the model is a Gemini 2.x model.
*

View File

@@ -1361,8 +1361,8 @@
"model": {
"title": "Model",
"description": "The model to use for the Codebase Investigator agent.",
"markdownDescription": "The model to use for the Codebase Investigator agent.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `gemini-2.5-pro`",
"default": "gemini-2.5-pro",
"markdownDescription": "The model to use for the Codebase Investigator agent.\n\n- Category: `Experimental`\n- Requires restart: `yes`\n- Default: `auto`",
"default": "auto",
"type": "string"
}
},