diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts index 37ddf87642..c358cd65aa 100644 --- a/packages/cli/src/config/settingsSchema.test.ts +++ b/packages/cli/src/config/settingsSchema.test.ts @@ -538,8 +538,32 @@ describe('SettingsSchema', () => { } }; + const visitJsonSchema = (jsonSchema: Record) => { + const ref = jsonSchema['ref']; + if (typeof ref === 'string') { + referenced.add(ref); + } + const properties = jsonSchema['properties']; + if ( + properties && + typeof properties === 'object' && + !Array.isArray(properties) + ) { + Object.values(properties as Record).forEach((prop) => + visitJsonSchema(prop as Record), + ); + } + const items = jsonSchema['items']; + if (items && typeof items === 'object' && !Array.isArray(items)) { + visitJsonSchema(items as Record); + } + }; + Object.values(schema).forEach(visitDefinition); + // Also visit all definitions to find nested references + Object.values(SETTINGS_SCHEMA_DEFINITIONS).forEach(visitJsonSchema); + // Ensure definitions map doesn't accumulate stale entries. Object.keys(SETTINGS_SCHEMA_DEFINITIONS).forEach((key) => { if (!referenced.has(key)) { diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 3724253e97..3a622460aa 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -1094,7 +1094,7 @@ const SETTINGS_SCHEMA = { showInDialog: false, additionalProperties: { type: 'array', - ref: 'ModelPolicy', + ref: 'ModelPolicyChain', }, }, }, @@ -2998,6 +2998,14 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record< }, }, }, + ModelPolicyChain: { + type: 'array', + description: 'A chain of model policies for fallback behavior.', + items: { + type: 'object', + ref: 'ModelPolicy', + }, + }, ModelPolicy: { type: 'object', description: diff --git a/packages/cli/src/ui/components/ModelDialog.tsx b/packages/cli/src/ui/components/ModelDialog.tsx index 85cf16de3b..c42838c070 100644 --- a/packages/cli/src/ui/components/ModelDialog.tsx +++ b/packages/cli/src/ui/components/ModelDialog.tsx @@ -233,7 +233,8 @@ export function ModelDialog({ onClose }: ModelDialogProps): React.JSX.Element { }); // Deduplicate: only show one entry per unique resolved model value. - // This is needed because 3 pro and 3.1 pro models can resolve to the same value. + // This is needed because 3 pro and 3.1 pro models can resolve to the same + // value, depending on the useGemini31 flag. const seen = new Set(); return list.filter((option) => { if (seen.has(option.value)) return false; diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 85a907e57e..a231558bf7 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -2061,7 +2061,7 @@ }, "type": "object", "additionalProperties": { - "$ref": "#/$defs/ModelPolicy" + "$ref": "#/$defs/ModelPolicyChain" } } }, @@ -3686,6 +3686,14 @@ } } }, + "ModelPolicyChain": { + "type": "array", + "description": "A chain of model policies for fallback behavior.", + "items": { + "type": "object", + "ref": "ModelPolicy" + } + }, "ModelPolicy": { "type": "object", "description": "Defines the policy for a single model in the availability chain.",