diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index a3b4788026..7df1de61f1 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -688,7 +688,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -698,6 +698,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "pro", "family": "gemini-3", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": true @@ -707,7 +708,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -717,7 +718,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "flash", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": true @@ -727,7 +728,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "pro", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -737,7 +738,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "flash", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -747,7 +748,7 @@ their corresponding top-level category object in your `settings.json` file. "tier": "flash-lite", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -756,6 +757,7 @@ their corresponding top-level category object in your `settings.json` file. "auto": { "tier": "auto", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -764,6 +766,7 @@ their corresponding top-level category object in your `settings.json` file. "pro": { "tier": "pro", "isPreview": false, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -772,6 +775,7 @@ their corresponding top-level category object in your `settings.json` file. "flash": { "tier": "flash", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -780,6 +784,7 @@ their corresponding top-level category object in your `settings.json` file. "flash-lite": { "tier": "flash-lite", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -789,7 +794,7 @@ their corresponding top-level category object in your `settings.json` file. "displayName": "Auto (Gemini 3)", "tier": "auto", "isPreview": true, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash", "features": { "thinking": true, @@ -800,7 +805,7 @@ their corresponding top-level category object in your `settings.json` file. "displayName": "Auto (Gemini 2.5)", "tier": "auto", "isPreview": false, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash", "features": { "thinking": false, @@ -812,6 +817,184 @@ their corresponding top-level category object in your `settings.json` file. - **Requires restart:** Yes +- **`modelConfigs.modelIdResolutions`** (object): + - **Description:** Rules for resolving requested model names to concrete model + IDs based on context. + - **Default:** + + ```json + { + "gemini-3-pro-preview": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-3": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-2.5": { + "default": "gemini-2.5-pro" + }, + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-flash" + } + ] + }, + "flash-lite": { + "default": "gemini-2.5-flash-lite" + } + } + ``` + + - **Requires restart:** Yes + +- **`modelConfigs.classifierIdResolutions`** (object): + - **Description:** Rules for resolving classifier tiers (flash, pro) to + concrete model IDs. + - **Default:** + + ```json + { + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-flash" + }, + { + "condition": { + "requestedModels": ["auto-gemini-3", "gemini-3-pro-preview"] + }, + "target": "gemini-3-flash-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + } + } + ``` + + - **Requires restart:** Yes + #### `agents` - **`agents.overrides`** (object): diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index b06df48bc3..8a107c4d47 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -1053,6 +1053,34 @@ const SETTINGS_SCHEMA = { ref: 'ModelDefinition', }, }, + modelIdResolutions: { + type: 'object', + label: 'Model ID Resolutions', + category: 'Model', + requiresRestart: true, + default: DEFAULT_MODEL_CONFIGS.modelIdResolutions, + description: + 'Rules for resolving requested model names to concrete model IDs based on context.', + showInDialog: false, + additionalProperties: { + type: 'object', + ref: 'ModelResolution', + }, + }, + classifierIdResolutions: { + type: 'object', + label: 'Classifier ID Resolutions', + category: 'Model', + requiresRestart: true, + default: DEFAULT_MODEL_CONFIGS.classifierIdResolutions, + description: + 'Rules for resolving classifier tiers (flash, pro) to concrete model IDs.', + showInDialog: false, + additionalProperties: { + type: 'object', + ref: 'ModelResolution', + }, + }, }, }, @@ -2800,7 +2828,7 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record< tier: { enum: ['pro', 'flash', 'flash-lite', 'custom', 'auto'] }, family: { type: 'string' }, isPreview: { type: 'boolean' }, - dialogLocation: { enum: ['main', 'manual'] }, + isVisible: { type: 'boolean' }, dialogDescription: { type: 'string' }, features: { type: 'object', @@ -2811,6 +2839,34 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record< }, }, }, + ModelResolution: { + type: 'object', + description: 'Model resolution rule.', + properties: { + default: { type: 'string' }, + contexts: { + type: 'array', + items: { + type: 'object', + properties: { + condition: { + type: 'object', + properties: { + useGemini3_1: { type: 'boolean' }, + useCustomTools: { type: 'boolean' }, + hasAccessToPreview: { type: 'boolean' }, + requestedModels: { + type: 'array', + items: { type: 'string' }, + }, + }, + }, + target: { type: 'string' }, + }, + }, + }, + }, + }, }; export function getSettingsSchema(): SettingsSchemaType { diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 4e860e838a..fb445254ca 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -981,6 +981,14 @@ export class Config implements McpContext, AgentLoopContext { ...DEFAULT_MODEL_CONFIGS.modelDefinitions, ...modelConfigServiceConfig.modelDefinitions, }; + const mergedModelIdResolutions = { + ...DEFAULT_MODEL_CONFIGS.modelIdResolutions, + ...modelConfigServiceConfig.modelIdResolutions, + }; + const mergedClassifierIdResolutions = { + ...DEFAULT_MODEL_CONFIGS.classifierIdResolutions, + ...modelConfigServiceConfig.classifierIdResolutions, + }; modelConfigServiceConfig = { // Preserve other user settings like customAliases @@ -992,6 +1000,8 @@ export class Config implements McpContext, AgentLoopContext { modelConfigServiceConfig.overrides ?? DEFAULT_MODEL_CONFIGS.overrides, // Use the merged model definitions modelDefinitions: mergedModelDefinitions, + modelIdResolutions: mergedModelIdResolutions, + classifierIdResolutions: mergedClassifierIdResolutions, }; } diff --git a/packages/core/src/config/defaultModelConfigs.ts b/packages/core/src/config/defaultModelConfigs.ts index c0e8b6c6ba..4a9315359b 100644 --- a/packages/core/src/config/defaultModelConfigs.ts +++ b/packages/core/src/config/defaultModelConfigs.ts @@ -255,76 +255,81 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = { tier: 'pro', family: 'gemini-3', isPreview: true, - dialogLocation: 'manual', + isVisible: true, features: { thinking: true, multimodalToolUse: true }, }, 'gemini-3.1-pro-preview-customtools': { tier: 'pro', family: 'gemini-3', isPreview: true, + isVisible: false, features: { thinking: true, multimodalToolUse: true }, }, 'gemini-3-pro-preview': { tier: 'pro', family: 'gemini-3', isPreview: true, - dialogLocation: 'manual', + isVisible: true, features: { thinking: true, multimodalToolUse: true }, }, 'gemini-3-flash-preview': { tier: 'flash', family: 'gemini-3', isPreview: true, - dialogLocation: 'manual', + isVisible: true, features: { thinking: false, multimodalToolUse: true }, }, 'gemini-2.5-pro': { tier: 'pro', family: 'gemini-2.5', isPreview: false, - dialogLocation: 'manual', + isVisible: true, features: { thinking: false, multimodalToolUse: false }, }, 'gemini-2.5-flash': { tier: 'flash', family: 'gemini-2.5', isPreview: false, - dialogLocation: 'manual', + isVisible: true, features: { thinking: false, multimodalToolUse: false }, }, 'gemini-2.5-flash-lite': { tier: 'flash-lite', family: 'gemini-2.5', isPreview: false, - dialogLocation: 'manual', + isVisible: true, features: { thinking: false, multimodalToolUse: false }, }, // Aliases auto: { tier: 'auto', isPreview: true, + isVisible: false, features: { thinking: true, multimodalToolUse: false }, }, pro: { tier: 'pro', isPreview: false, + isVisible: false, features: { thinking: true, multimodalToolUse: false }, }, flash: { tier: 'flash', isPreview: false, + isVisible: false, features: { thinking: false, multimodalToolUse: false }, }, 'flash-lite': { tier: 'flash-lite', isPreview: false, + isVisible: false, features: { thinking: false, multimodalToolUse: false }, }, 'auto-gemini-3': { displayName: 'Auto (Gemini 3)', tier: 'auto', isPreview: true, - dialogLocation: 'main', + isVisible: true, dialogDescription: 'Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash', features: { thinking: true, multimodalToolUse: false }, @@ -333,10 +338,117 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = { displayName: 'Auto (Gemini 2.5)', tier: 'auto', isPreview: false, - dialogLocation: 'main', + isVisible: true, dialogDescription: 'Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash', features: { thinking: false, multimodalToolUse: false }, }, }, + modelIdResolutions: { + 'gemini-3-pro-preview': { + default: 'gemini-3-pro-preview', + contexts: [ + { condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' }, + { + condition: { useGemini3_1: true, useCustomTools: true }, + target: 'gemini-3.1-pro-preview-customtools', + }, + { + condition: { useGemini3_1: true }, + target: 'gemini-3.1-pro-preview', + }, + ], + }, + 'auto-gemini-3': { + default: 'gemini-3-pro-preview', + contexts: [ + { condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' }, + { + condition: { useGemini3_1: true, useCustomTools: true }, + target: 'gemini-3.1-pro-preview-customtools', + }, + { + condition: { useGemini3_1: true }, + target: 'gemini-3.1-pro-preview', + }, + ], + }, + auto: { + default: 'gemini-3-pro-preview', + contexts: [ + { condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' }, + { + condition: { useGemini3_1: true, useCustomTools: true }, + target: 'gemini-3.1-pro-preview-customtools', + }, + { + condition: { useGemini3_1: true }, + target: 'gemini-3.1-pro-preview', + }, + ], + }, + pro: { + default: 'gemini-3-pro-preview', + contexts: [ + { condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' }, + { + condition: { useGemini3_1: true, useCustomTools: true }, + target: 'gemini-3.1-pro-preview-customtools', + }, + { + condition: { useGemini3_1: true }, + target: 'gemini-3.1-pro-preview', + }, + ], + }, + 'auto-gemini-2.5': { + default: 'gemini-2.5-pro', + }, + flash: { + default: 'gemini-3-flash-preview', + contexts: [ + { + condition: { hasAccessToPreview: false }, + target: 'gemini-2.5-flash', + }, + ], + }, + 'flash-lite': { + default: 'gemini-2.5-flash-lite', + }, + }, + classifierIdResolutions: { + flash: { + default: 'gemini-3-flash-preview', + contexts: [ + { + condition: { requestedModels: ['auto-gemini-2.5', 'gemini-2.5-pro'] }, + target: 'gemini-2.5-flash', + }, + { + condition: { + requestedModels: ['auto-gemini-3', 'gemini-3-pro-preview'], + }, + target: 'gemini-3-flash-preview', + }, + ], + }, + pro: { + default: 'gemini-3-pro-preview', + contexts: [ + { + condition: { requestedModels: ['auto-gemini-2.5', 'gemini-2.5-pro'] }, + target: 'gemini-2.5-pro', + }, + { + condition: { useGemini3_1: true, useCustomTools: true }, + target: 'gemini-3.1-pro-preview-customtools', + }, + { + condition: { useGemini3_1: true }, + target: 'gemini-3.1-pro-preview', + }, + ], + }, + }, }; diff --git a/packages/core/src/config/models.test.ts b/packages/core/src/config/models.test.ts index 21c738ce12..9aa1e00058 100644 --- a/packages/core/src/config/models.test.ts +++ b/packages/core/src/config/models.test.ts @@ -60,6 +60,90 @@ describe('Dynamic Configuration Parity', () => { 'custom-model', ]; + const flagCombos = [ + { useGemini3_1: false, useCustomToolModel: false }, + { useGemini3_1: true, useCustomToolModel: false }, + { useGemini3_1: true, useCustomToolModel: true }, + ]; + + it('resolveModel should match legacy behavior when dynamicModelConfiguration flag enabled.', () => { + for (const model of modelsToTest) { + for (const flags of flagCombos) { + for (const hasAccess of [true, false]) { + const mockLegacyConfig = { + ...legacyConfig, + getHasAccessToPreviewModel: () => hasAccess, + } as unknown as Config; + const mockDynamicConfig = { + ...dynamicConfig, + getHasAccessToPreviewModel: () => hasAccess, + } as unknown as Config; + + const legacy = resolveModel( + model, + flags.useGemini3_1, + flags.useCustomToolModel, + hasAccess, + mockLegacyConfig, + ); + const dynamic = resolveModel( + model, + flags.useGemini3_1, + flags.useCustomToolModel, + hasAccess, + mockDynamicConfig, + ); + expect(dynamic).toBe(legacy); + } + } + } + }); + + it('resolveClassifierModel should match legacy behavior.', () => { + const classifierTiers = [GEMINI_MODEL_ALIAS_PRO, GEMINI_MODEL_ALIAS_FLASH]; + const anchorModels = [ + PREVIEW_GEMINI_MODEL_AUTO, + DEFAULT_GEMINI_MODEL_AUTO, + PREVIEW_GEMINI_MODEL, + DEFAULT_GEMINI_MODEL, + ]; + + for (const hasAccess of [true, false]) { + const mockLegacyConfig = { + ...legacyConfig, + getHasAccessToPreviewModel: () => hasAccess, + } as unknown as Config; + const mockDynamicConfig = { + ...dynamicConfig, + getHasAccessToPreviewModel: () => hasAccess, + } as unknown as Config; + + for (const tier of classifierTiers) { + for (const anchor of anchorModels) { + for (const flags of flagCombos) { + const legacy = resolveClassifierModel( + anchor, + tier, + flags.useGemini3_1, + flags.useCustomToolModel, + hasAccess, + mockLegacyConfig, + ); + const dynamic = resolveClassifierModel( + anchor, + tier, + flags.useGemini3_1, + flags.useCustomToolModel, + hasAccess, + mockDynamicConfig, + ); + expect(dynamic).toBe(legacy); + } + } + } + } + }); + it('getDisplayString should match legacy behavior', () => { for (const model of modelsToTest) { const legacy = getDisplayString(model, legacyConfig); diff --git a/packages/core/src/config/models.ts b/packages/core/src/config/models.ts index 21b11d077a..7e1a57c5c3 100644 --- a/packages/core/src/config/models.ts +++ b/packages/core/src/config/models.ts @@ -4,6 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +export interface ModelResolutionContext { + useGemini3_1?: boolean; + useCustomTools?: boolean; + hasAccessToPreview?: boolean; + requestedModel?: string; +} + /** * Interface for the ModelConfigService to break circular dependencies. */ @@ -20,6 +27,17 @@ export interface IModelConfigService { }; } | undefined; + + resolveModelId( + requestedModel: string, + context?: ModelResolutionContext, + ): string; + + resolveClassifierModelId( + tier: string, + requestedModel: string, + context?: ModelResolutionContext, + ): string; } /** @@ -81,7 +99,16 @@ export function resolveModel( useGemini3_1: boolean = false, useCustomToolModel: boolean = false, hasAccessToPreview: boolean = true, + config?: ModelCapabilityContext, ): string { + if (config?.getExperimentalDynamicModelConfiguration?.() === true) { + return config.modelConfigService.resolveModelId(requestedModel, { + useGemini3_1, + useCustomTools: useCustomToolModel, + hasAccessToPreview, + }); + } + let resolved: string; switch (requestedModel) { case PREVIEW_GEMINI_MODEL: @@ -144,6 +171,9 @@ 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 useGemini3_1 Whether to use Gemini 3.1 Pro Preview. + * @param useCustomToolModel Whether to use the custom tool model. + * @param config Optional config object for dynamic model configuration. * @returns The resolved concrete model name. */ export function resolveClassifierModel( @@ -151,7 +181,21 @@ export function resolveClassifierModel( modelAlias: string, useGemini3_1: boolean = false, useCustomToolModel: boolean = false, + hasAccessToPreview: boolean = true, + config?: ModelCapabilityContext, ): string { + if (config?.getExperimentalDynamicModelConfiguration?.() === true) { + return config.modelConfigService.resolveClassifierModelId( + modelAlias, + requestedModel, + { + useGemini3_1, + useCustomTools: useCustomToolModel, + hasAccessToPreview, + }, + ); + } + if (modelAlias === GEMINI_MODEL_ALIAS_FLASH) { if ( requestedModel === DEFAULT_GEMINI_MODEL_AUTO || @@ -169,6 +213,7 @@ export function resolveClassifierModel( } return resolveModel(requestedModel, useGemini3_1, useCustomToolModel); } + export function getDisplayString( model: string, config?: ModelCapabilityContext, @@ -289,7 +334,7 @@ export function isCustomModel( config?: ModelCapabilityContext, ): boolean { if (config?.getExperimentalDynamicModelConfiguration?.() === true) { - const resolved = resolveModel(model); + const resolved = resolveModel(model, false, false, true, config); return ( config.modelConfigService.getModelDefinition(resolved)?.tier === 'custom' || !resolved.startsWith('gemini-') diff --git a/packages/core/src/core/client.ts b/packages/core/src/core/client.ts index c398a356ff..01577452f4 100644 --- a/packages/core/src/core/client.ts +++ b/packages/core/src/core/client.ts @@ -569,6 +569,9 @@ export class GeminiClient { return resolveModel( this.config.getActiveModel(), this.config.getGemini31LaunchedSync?.() ?? false, + false, + this.config.getHasAccessToPreviewModel?.() ?? true, + this.config, ); } diff --git a/packages/core/src/core/contentGenerator.ts b/packages/core/src/core/contentGenerator.ts index f61fa950eb..60641abdeb 100644 --- a/packages/core/src/core/contentGenerator.ts +++ b/packages/core/src/core/contentGenerator.ts @@ -171,6 +171,9 @@ export async function createContentGenerator( config.authType === AuthType.USE_GEMINI || config.authType === AuthType.USE_VERTEX_AI || ((await gcConfig.getGemini31Launched?.()) ?? false), + false, + gcConfig.getHasAccessToPreviewModel?.() ?? true, + gcConfig, ); const customHeadersEnv = process.env['GEMINI_CLI_CUSTOM_HEADERS'] || undefined; diff --git a/packages/core/src/core/geminiChat.ts b/packages/core/src/core/geminiChat.ts index dff16d4df6..ff6c3a3806 100644 --- a/packages/core/src/core/geminiChat.ts +++ b/packages/core/src/core/geminiChat.ts @@ -525,7 +525,13 @@ export class GeminiChat { const useGemini3_1 = (await this.context.config.getGemini31Launched?.()) ?? false; // Default to the last used model (which respects arguments/availability selection) - let modelToUse = resolveModel(lastModelToUse, useGemini3_1); + let modelToUse = resolveModel( + lastModelToUse, + useGemini3_1, + false, + this.context.config.getHasAccessToPreviewModel?.() ?? true, + this.context.config, + ); // If the active model has changed (e.g. due to a fallback updating the config), // we switch to the new active model. @@ -533,6 +539,9 @@ export class GeminiChat { modelToUse = resolveModel( this.context.config.getActiveModel(), useGemini3_1, + false, + this.context.config.getHasAccessToPreviewModel?.() ?? true, + this.context.config, ); } diff --git a/packages/core/src/prompts/promptProvider.ts b/packages/core/src/prompts/promptProvider.ts index ed71b035dc..7c01105f7f 100644 --- a/packages/core/src/prompts/promptProvider.ts +++ b/packages/core/src/prompts/promptProvider.ts @@ -62,6 +62,9 @@ export class PromptProvider { const desiredModel = resolveModel( context.config.getActiveModel(), context.config.getGemini31LaunchedSync?.() ?? false, + false, + context.config.getHasAccessToPreviewModel?.() ?? true, + context.config, ); const isModernModel = supportsModernFeatures(desiredModel); const activeSnippets = isModernModel ? snippets : legacySnippets; @@ -239,6 +242,9 @@ export class PromptProvider { const desiredModel = resolveModel( context.config.getActiveModel(), context.config.getGemini31LaunchedSync?.() ?? false, + false, + context.config.getHasAccessToPreviewModel?.() ?? true, + context.config, ); const isModernModel = supportsModernFeatures(desiredModel); const activeSnippets = isModernModel ? snippets : legacySnippets; diff --git a/packages/core/src/routing/strategies/classifierStrategy.ts b/packages/core/src/routing/strategies/classifierStrategy.ts index 3532e34c63..e27b69ed0f 100644 --- a/packages/core/src/routing/strategies/classifierStrategy.ts +++ b/packages/core/src/routing/strategies/classifierStrategy.ts @@ -180,6 +180,8 @@ export class ClassifierStrategy implements RoutingStrategy { routerResponse.model_choice, useGemini3_1, useCustomToolModel, + config.getHasAccessToPreviewModel?.() ?? true, + config, ); return { diff --git a/packages/core/src/routing/strategies/defaultStrategy.ts b/packages/core/src/routing/strategies/defaultStrategy.ts index d380ba7ad2..a2c02e83b7 100644 --- a/packages/core/src/routing/strategies/defaultStrategy.ts +++ b/packages/core/src/routing/strategies/defaultStrategy.ts @@ -26,6 +26,9 @@ export class DefaultStrategy implements TerminalStrategy { const defaultModel = resolveModel( config.getModel(), config.getGemini31LaunchedSync?.() ?? false, + false, + config.getHasAccessToPreviewModel?.() ?? true, + config, ); return { model: defaultModel, diff --git a/packages/core/src/routing/strategies/fallbackStrategy.ts b/packages/core/src/routing/strategies/fallbackStrategy.ts index 21a080e9da..653f712c14 100644 --- a/packages/core/src/routing/strategies/fallbackStrategy.ts +++ b/packages/core/src/routing/strategies/fallbackStrategy.ts @@ -28,6 +28,9 @@ export class FallbackStrategy implements RoutingStrategy { const resolvedModel = resolveModel( requestedModel, config.getGemini31LaunchedSync?.() ?? false, + false, + config.getHasAccessToPreviewModel?.() ?? true, + config, ); const service = config.getModelAvailabilityService(); const snapshot = service.snapshot(resolvedModel); diff --git a/packages/core/src/routing/strategies/numericalClassifierStrategy.ts b/packages/core/src/routing/strategies/numericalClassifierStrategy.ts index a97180c8eb..cda761e9ff 100644 --- a/packages/core/src/routing/strategies/numericalClassifierStrategy.ts +++ b/packages/core/src/routing/strategies/numericalClassifierStrategy.ts @@ -156,6 +156,8 @@ export class NumericalClassifierStrategy implements RoutingStrategy { modelAlias, useGemini3_1, useCustomToolModel, + config.getHasAccessToPreviewModel?.() ?? true, + config, ); const latencyMs = Date.now() - startTime; diff --git a/packages/core/src/routing/strategies/overrideStrategy.ts b/packages/core/src/routing/strategies/overrideStrategy.ts index 37e23e188b..e424e533be 100644 --- a/packages/core/src/routing/strategies/overrideStrategy.ts +++ b/packages/core/src/routing/strategies/overrideStrategy.ts @@ -38,6 +38,9 @@ export class OverrideStrategy implements RoutingStrategy { model: resolveModel( overrideModel, config.getGemini31LaunchedSync?.() ?? false, + false, + config.getHasAccessToPreviewModel?.() ?? true, + config, ), metadata: { source: this.name, diff --git a/packages/core/src/services/modelConfigService.ts b/packages/core/src/services/modelConfigService.ts index 2999129116..581dbfecb9 100644 --- a/packages/core/src/services/modelConfigService.ts +++ b/packages/core/src/services/modelConfigService.ts @@ -59,9 +59,8 @@ export interface ModelDefinition { tier?: string; // 'pro' | 'flash' | 'flash-lite' | 'custom' | 'auto' family?: string; // The gemini family, e.g. 'gemini-3' | 'gemini-2' isPreview?: boolean; - // Specifies which view the model should appear in. If unset, the model will - // not appear in the dialog. - dialogLocation?: 'main' | 'manual'; + // Specifies whether the model should be visible in the dialog. + isVisible?: boolean; /** A short description of the model for the dialog. */ dialogDescription?: string; features?: { @@ -73,12 +72,45 @@ export interface ModelDefinition { }; } +// A model resolution is a mapping from a model name to a list of conditions +// that can be used to resolve the model to a model ID. +export interface ModelResolution { + // The default model ID to use when no conditions are met. + default: string; + // A list of conditions that can be used to resolve the model. + contexts?: Array<{ + // The condition to check for. + condition: ResolutionCondition; + // The model ID to use when the condition is met. + target: string; + }>; +} + +/** The actual state of the current session. */ +export interface ResolutionContext { + useGemini3_1?: boolean; + useCustomTools?: boolean; + hasAccessToPreview?: boolean; + requestedModel?: string; +} + +/** The requirements defined in the registry. */ +export interface ResolutionCondition { + useGemini3_1?: boolean; + useCustomTools?: boolean; + hasAccessToPreview?: boolean; + /** Matches if the current model is in this list. */ + requestedModels?: string[]; +} + export interface ModelConfigServiceConfig { aliases?: Record; customAliases?: Record; overrides?: ModelConfigOverride[]; customOverrides?: ModelConfigOverride[]; modelDefinitions?: Record; + modelIdResolutions?: Record; + classifierIdResolutions?: Record; } const MAX_ALIAS_CHAIN_DEPTH = 100; @@ -121,6 +153,74 @@ export class ModelConfigService { return this.config.modelDefinitions ?? {}; } + private matches( + condition: ResolutionCondition, + context: ResolutionContext, + ): boolean { + return Object.entries(condition).every(([key, value]) => { + if (value === undefined) return true; + + switch (key) { + case 'useGemini3_1': + return value === context.useGemini3_1; + case 'useCustomTools': + return value === context.useCustomTools; + case 'hasAccessToPreview': + return value === context.hasAccessToPreview; + case 'requestedModels': + return ( + Array.isArray(value) && + !!context.requestedModel && + value.includes(context.requestedModel) + ); + default: + return false; + } + }); + } + + // Resolves a model ID to a concrete model ID based on the provided context. + resolveModelId( + requestedName: string, + context: ResolutionContext = {}, + ): string { + const resolution = this.config.modelIdResolutions?.[requestedName]; + if (!resolution) { + return requestedName; + } + + for (const ctx of resolution.contexts ?? []) { + if (this.matches(ctx.condition, context)) { + return ctx.target; + } + } + + return resolution.default; + } + + // Resolves a classifier model ID to a concrete model ID based on the provided context. + resolveClassifierModelId( + tier: string, + requestedModel: string, + context: ResolutionContext = {}, + ): string { + const resolution = this.config.classifierIdResolutions?.[tier]; + const fullContext: ResolutionContext = { ...context, requestedModel }; + + if (!resolution) { + // Fallback to regular model resolution if no classifier-specific rule exists + return this.resolveModelId(tier, fullContext); + } + + for (const ctx of resolution.contexts ?? []) { + if (this.matches(ctx.condition, fullContext)) { + return ctx.target; + } + } + + return resolution.default; + } + registerRuntimeModelConfig(aliasName: string, alias: ModelConfigAlias): void { this.runtimeAliases[aliasName] = alias; } diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 1f180ac6dd..f85a39bb35 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -629,7 +629,7 @@ "modelConfigs": { "title": "Model Configs", "description": "Model configurations.", - "markdownDescription": "Model configurations.\n\n- Category: `Model`\n- Requires restart: `no`\n- Default: `{\n \"aliases\": {\n \"base\": {\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"temperature\": 0,\n \"topP\": 1\n }\n }\n },\n \"chat-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"includeThoughts\": true\n },\n \"temperature\": 1,\n \"topP\": 0.95,\n \"topK\": 64\n }\n }\n },\n \"chat-base-2.5\": {\n \"extends\": \"chat-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingBudget\": 8192\n }\n }\n }\n },\n \"chat-base-3\": {\n \"extends\": \"chat-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingLevel\": \"HIGH\"\n }\n }\n }\n },\n \"gemini-3-pro-preview\": {\n \"extends\": \"chat-base-3\",\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"gemini-3-flash-preview\": {\n \"extends\": \"chat-base-3\",\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"gemini-2.5-pro\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-pro\"\n }\n },\n \"gemini-2.5-flash\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\"\n }\n },\n \"gemini-2.5-flash-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"gemini-3-flash-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"classifier\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 1024,\n \"thinkingConfig\": {\n \"thinkingBudget\": 512\n }\n }\n }\n },\n \"prompt-completion\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"temperature\": 0.3,\n \"maxOutputTokens\": 16000,\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"fast-ack-helper\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"temperature\": 0.2,\n \"maxOutputTokens\": 120,\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"edit-corrector\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"summarizer-default\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 2000\n }\n }\n },\n \"summarizer-shell\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 2000\n }\n }\n },\n \"web-search\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"tools\": [\n {\n \"googleSearch\": {}\n }\n ]\n }\n }\n },\n \"web-fetch\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"tools\": [\n {\n \"urlContext\": {}\n }\n ]\n }\n }\n },\n \"web-fetch-fallback\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"loop-detection\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"loop-detection-double-check\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"llm-edit-fixer\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"next-speaker-checker\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"chat-compression-3-pro\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"chat-compression-3-flash\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"chat-compression-2.5-pro\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-pro\"\n }\n },\n \"chat-compression-2.5-flash\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"chat-compression-2.5-flash-lite\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\"\n }\n },\n \"chat-compression-default\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n }\n },\n \"overrides\": [\n {\n \"match\": {\n \"model\": \"chat-base\",\n \"isRetry\": true\n },\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"temperature\": 1\n }\n }\n }\n ],\n \"modelDefinitions\": {\n \"gemini-3.1-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-flash-preview\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-2.5-pro\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"tier\": \"flash-lite\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto\": {\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"pro\": {\n \"tier\": \"pro\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"flash\": {\n \"tier\": \"flash\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"flash-lite\": {\n \"tier\": \"flash-lite\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-3\": {\n \"displayName\": \"Auto (Gemini 3)\",\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"dialogLocation\": \"main\",\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-2.5\": {\n \"displayName\": \"Auto (Gemini 2.5)\",\n \"tier\": \"auto\",\n \"isPreview\": false,\n \"dialogLocation\": \"main\",\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n }\n }\n}`", + "markdownDescription": "Model configurations.\n\n- Category: `Model`\n- Requires restart: `no`\n- Default: `{\n \"aliases\": {\n \"base\": {\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"temperature\": 0,\n \"topP\": 1\n }\n }\n },\n \"chat-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"includeThoughts\": true\n },\n \"temperature\": 1,\n \"topP\": 0.95,\n \"topK\": 64\n }\n }\n },\n \"chat-base-2.5\": {\n \"extends\": \"chat-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingBudget\": 8192\n }\n }\n }\n },\n \"chat-base-3\": {\n \"extends\": \"chat-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingLevel\": \"HIGH\"\n }\n }\n }\n },\n \"gemini-3-pro-preview\": {\n \"extends\": \"chat-base-3\",\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"gemini-3-flash-preview\": {\n \"extends\": \"chat-base-3\",\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"gemini-2.5-pro\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-pro\"\n }\n },\n \"gemini-2.5-flash\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"extends\": \"chat-base-2.5\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\"\n }\n },\n \"gemini-2.5-flash-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"gemini-3-flash-base\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"classifier\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 1024,\n \"thinkingConfig\": {\n \"thinkingBudget\": 512\n }\n }\n }\n },\n \"prompt-completion\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"temperature\": 0.3,\n \"maxOutputTokens\": 16000,\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"fast-ack-helper\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"temperature\": 0.2,\n \"maxOutputTokens\": 120,\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"edit-corrector\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"thinkingConfig\": {\n \"thinkingBudget\": 0\n }\n }\n }\n },\n \"summarizer-default\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 2000\n }\n }\n },\n \"summarizer-shell\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\",\n \"generateContentConfig\": {\n \"maxOutputTokens\": 2000\n }\n }\n },\n \"web-search\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"tools\": [\n {\n \"googleSearch\": {}\n }\n ]\n }\n }\n },\n \"web-fetch\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"tools\": [\n {\n \"urlContext\": {}\n }\n ]\n }\n }\n },\n \"web-fetch-fallback\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"loop-detection\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"loop-detection-double-check\": {\n \"extends\": \"base\",\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"llm-edit-fixer\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"next-speaker-checker\": {\n \"extends\": \"gemini-3-flash-base\",\n \"modelConfig\": {}\n },\n \"chat-compression-3-pro\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n },\n \"chat-compression-3-flash\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-flash-preview\"\n }\n },\n \"chat-compression-2.5-pro\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-pro\"\n }\n },\n \"chat-compression-2.5-flash\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash\"\n }\n },\n \"chat-compression-2.5-flash-lite\": {\n \"modelConfig\": {\n \"model\": \"gemini-2.5-flash-lite\"\n }\n },\n \"chat-compression-default\": {\n \"modelConfig\": {\n \"model\": \"gemini-3-pro-preview\"\n }\n }\n },\n \"overrides\": [\n {\n \"match\": {\n \"model\": \"chat-base\",\n \"isRetry\": true\n },\n \"modelConfig\": {\n \"generateContentConfig\": {\n \"temperature\": 1\n }\n }\n }\n ],\n \"modelDefinitions\": {\n \"gemini-3.1-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-flash-preview\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-2.5-pro\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"tier\": \"flash-lite\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto\": {\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"pro\": {\n \"tier\": \"pro\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"flash\": {\n \"tier\": \"flash\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"flash-lite\": {\n \"tier\": \"flash-lite\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-3\": {\n \"displayName\": \"Auto (Gemini 3)\",\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-2.5\": {\n \"displayName\": \"Auto (Gemini 2.5)\",\n \"tier\": \"auto\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n }\n },\n \"modelIdResolutions\": {\n \"gemini-3-pro-preview\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto-gemini-3\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"pro\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto-gemini-2.5\": {\n \"default\": \"gemini-2.5-pro\"\n },\n \"flash\": {\n \"default\": \"gemini-3-flash-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-flash\"\n }\n ]\n },\n \"flash-lite\": {\n \"default\": \"gemini-2.5-flash-lite\"\n }\n },\n \"classifierIdResolutions\": {\n \"flash\": {\n \"default\": \"gemini-3-flash-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-2.5\",\n \"gemini-2.5-pro\"\n ]\n },\n \"target\": \"gemini-2.5-flash\"\n },\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-3\",\n \"gemini-3-pro-preview\"\n ]\n },\n \"target\": \"gemini-3-flash-preview\"\n }\n ]\n },\n \"pro\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-2.5\",\n \"gemini-2.5-pro\"\n ]\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n }\n }\n}`", "default": { "aliases": { "base": { @@ -877,7 +877,7 @@ "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -887,6 +887,7 @@ "tier": "pro", "family": "gemini-3", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": true @@ -896,7 +897,7 @@ "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -906,7 +907,7 @@ "tier": "flash", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": true @@ -916,7 +917,7 @@ "tier": "pro", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -926,7 +927,7 @@ "tier": "flash", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -936,7 +937,7 @@ "tier": "flash-lite", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -945,6 +946,7 @@ "auto": { "tier": "auto", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -953,6 +955,7 @@ "pro": { "tier": "pro", "isPreview": false, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -961,6 +964,7 @@ "flash": { "tier": "flash", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -969,6 +973,7 @@ "flash-lite": { "tier": "flash-lite", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -978,7 +983,7 @@ "displayName": "Auto (Gemini 3)", "tier": "auto", "isPreview": true, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash", "features": { "thinking": true, @@ -989,13 +994,171 @@ "displayName": "Auto (Gemini 2.5)", "tier": "auto", "isPreview": false, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash", "features": { "thinking": false, "multimodalToolUse": false } } + }, + "modelIdResolutions": { + "gemini-3-pro-preview": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-3": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-2.5": { + "default": "gemini-2.5-pro" + }, + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-flash" + } + ] + }, + "flash-lite": { + "default": "gemini-2.5-flash-lite" + } + }, + "classifierIdResolutions": { + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-flash" + }, + { + "condition": { + "requestedModels": ["auto-gemini-3", "gemini-3-pro-preview"] + }, + "target": "gemini-3-flash-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + } } }, "type": "object", @@ -1262,13 +1425,13 @@ "modelDefinitions": { "title": "Model Definitions", "description": "Registry of model metadata, including tier, family, and features.", - "markdownDescription": "Registry of model metadata, including tier, family, and features.\n\n- Category: `Model`\n- Requires restart: `yes`\n- Default: `{\n \"gemini-3.1-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-flash-preview\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-2.5-pro\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"tier\": \"flash-lite\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"dialogLocation\": \"manual\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto\": {\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"pro\": {\n \"tier\": \"pro\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"flash\": {\n \"tier\": \"flash\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"flash-lite\": {\n \"tier\": \"flash-lite\",\n \"isPreview\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-3\": {\n \"displayName\": \"Auto (Gemini 3)\",\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"dialogLocation\": \"main\",\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-2.5\": {\n \"displayName\": \"Auto (Gemini 2.5)\",\n \"tier\": \"auto\",\n \"isPreview\": false,\n \"dialogLocation\": \"main\",\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n }\n}`", + "markdownDescription": "Registry of model metadata, including tier, family, and features.\n\n- Category: `Model`\n- Requires restart: `yes`\n- Default: `{\n \"gemini-3.1-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3.1-pro-preview-customtools\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-pro-preview\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-3-flash-preview\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-3\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": true\n }\n },\n \"gemini-2.5-pro\": {\n \"tier\": \"pro\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash\": {\n \"tier\": \"flash\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"gemini-2.5-flash-lite\": {\n \"tier\": \"flash-lite\",\n \"family\": \"gemini-2.5\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto\": {\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"pro\": {\n \"tier\": \"pro\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"flash\": {\n \"tier\": \"flash\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"flash-lite\": {\n \"tier\": \"flash-lite\",\n \"isPreview\": false,\n \"isVisible\": false,\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-3\": {\n \"displayName\": \"Auto (Gemini 3)\",\n \"tier\": \"auto\",\n \"isPreview\": true,\n \"isVisible\": true,\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash\",\n \"features\": {\n \"thinking\": true,\n \"multimodalToolUse\": false\n }\n },\n \"auto-gemini-2.5\": {\n \"displayName\": \"Auto (Gemini 2.5)\",\n \"tier\": \"auto\",\n \"isPreview\": false,\n \"isVisible\": true,\n \"dialogDescription\": \"Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash\",\n \"features\": {\n \"thinking\": false,\n \"multimodalToolUse\": false\n }\n }\n}`", "default": { "gemini-3.1-pro-preview": { "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -1278,6 +1441,7 @@ "tier": "pro", "family": "gemini-3", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": true @@ -1287,7 +1451,7 @@ "tier": "pro", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": true, "multimodalToolUse": true @@ -1297,7 +1461,7 @@ "tier": "flash", "family": "gemini-3", "isPreview": true, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": true @@ -1307,7 +1471,7 @@ "tier": "pro", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -1317,7 +1481,7 @@ "tier": "flash", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -1327,7 +1491,7 @@ "tier": "flash-lite", "family": "gemini-2.5", "isPreview": false, - "dialogLocation": "manual", + "isVisible": true, "features": { "thinking": false, "multimodalToolUse": false @@ -1336,6 +1500,7 @@ "auto": { "tier": "auto", "isPreview": true, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -1344,6 +1509,7 @@ "pro": { "tier": "pro", "isPreview": false, + "isVisible": false, "features": { "thinking": true, "multimodalToolUse": false @@ -1352,6 +1518,7 @@ "flash": { "tier": "flash", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -1360,6 +1527,7 @@ "flash-lite": { "tier": "flash-lite", "isPreview": false, + "isVisible": false, "features": { "thinking": false, "multimodalToolUse": false @@ -1369,7 +1537,7 @@ "displayName": "Auto (Gemini 3)", "tier": "auto", "isPreview": true, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-3.1-pro, gemini-3-flash", "features": { "thinking": true, @@ -1380,7 +1548,7 @@ "displayName": "Auto (Gemini 2.5)", "tier": "auto", "isPreview": false, - "dialogLocation": "main", + "isVisible": true, "dialogDescription": "Let Gemini CLI decide the best model for the task: gemini-2.5-pro, gemini-2.5-flash", "features": { "thinking": false, @@ -1392,6 +1560,182 @@ "additionalProperties": { "$ref": "#/$defs/ModelDefinition" } + }, + "modelIdResolutions": { + "title": "Model ID Resolutions", + "description": "Rules for resolving requested model names to concrete model IDs based on context.", + "markdownDescription": "Rules for resolving requested model names to concrete model IDs based on context.\n\n- Category: `Model`\n- Requires restart: `yes`\n- Default: `{\n \"gemini-3-pro-preview\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto-gemini-3\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"pro\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n },\n \"auto-gemini-2.5\": {\n \"default\": \"gemini-2.5-pro\"\n },\n \"flash\": {\n \"default\": \"gemini-3-flash-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"hasAccessToPreview\": false\n },\n \"target\": \"gemini-2.5-flash\"\n }\n ]\n },\n \"flash-lite\": {\n \"default\": \"gemini-2.5-flash-lite\"\n }\n}`", + "default": { + "gemini-3-pro-preview": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-3": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + }, + "auto-gemini-2.5": { + "default": "gemini-2.5-pro" + }, + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "hasAccessToPreview": false + }, + "target": "gemini-2.5-flash" + } + ] + }, + "flash-lite": { + "default": "gemini-2.5-flash-lite" + } + }, + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/ModelResolution" + } + }, + "classifierIdResolutions": { + "title": "Classifier ID Resolutions", + "description": "Rules for resolving classifier tiers (flash, pro) to concrete model IDs.", + "markdownDescription": "Rules for resolving classifier tiers (flash, pro) to concrete model IDs.\n\n- Category: `Model`\n- Requires restart: `yes`\n- Default: `{\n \"flash\": {\n \"default\": \"gemini-3-flash-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-2.5\",\n \"gemini-2.5-pro\"\n ]\n },\n \"target\": \"gemini-2.5-flash\"\n },\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-3\",\n \"gemini-3-pro-preview\"\n ]\n },\n \"target\": \"gemini-3-flash-preview\"\n }\n ]\n },\n \"pro\": {\n \"default\": \"gemini-3-pro-preview\",\n \"contexts\": [\n {\n \"condition\": {\n \"requestedModels\": [\n \"auto-gemini-2.5\",\n \"gemini-2.5-pro\"\n ]\n },\n \"target\": \"gemini-2.5-pro\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true,\n \"useCustomTools\": true\n },\n \"target\": \"gemini-3.1-pro-preview-customtools\"\n },\n {\n \"condition\": {\n \"useGemini3_1\": true\n },\n \"target\": \"gemini-3.1-pro-preview\"\n }\n ]\n }\n}`", + "default": { + "flash": { + "default": "gemini-3-flash-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-flash" + }, + { + "condition": { + "requestedModels": ["auto-gemini-3", "gemini-3-pro-preview"] + }, + "target": "gemini-3-flash-preview" + } + ] + }, + "pro": { + "default": "gemini-3-pro-preview", + "contexts": [ + { + "condition": { + "requestedModels": ["auto-gemini-2.5", "gemini-2.5-pro"] + }, + "target": "gemini-2.5-pro" + }, + { + "condition": { + "useGemini3_1": true, + "useCustomTools": true + }, + "target": "gemini-3.1-pro-preview-customtools" + }, + { + "condition": { + "useGemini3_1": true + }, + "target": "gemini-3.1-pro-preview" + } + ] + } + }, + "type": "object", + "additionalProperties": { + "$ref": "#/$defs/ModelResolution" + } } }, "additionalProperties": false @@ -2844,8 +3188,8 @@ "isPreview": { "type": "boolean" }, - "dialogLocation": { - "enum": ["main", "manual"] + "isVisible": { + "type": "boolean" }, "dialogDescription": { "type": "string" @@ -2862,6 +3206,46 @@ } } } + }, + "ModelResolution": { + "type": "object", + "description": "Model resolution rule.", + "properties": { + "default": { + "type": "string" + }, + "contexts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "condition": { + "type": "object", + "properties": { + "useGemini3_1": { + "type": "boolean" + }, + "useCustomTools": { + "type": "boolean" + }, + "hasAccessToPreview": { + "type": "boolean" + }, + "requestedModels": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "target": { + "type": "string" + } + } + } + } + } } } }