mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-23 00:01:24 -07:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e6bdb8c11 | |||
| f534f3f17a | |||
| f146618b6b |
@@ -974,6 +974,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"gemini-3.1-pro-preview": {
|
||||
"default": "gemini-3.1-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -991,6 +997,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"gemini-3.1-pro-preview-customtools": {
|
||||
"default": "gemini-3.1-pro-preview-customtools",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1002,6 +1014,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"gemini-3-flash-preview": {
|
||||
"default": "gemini-3-flash-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-flash"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1013,6 +1031,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"gemini-3-pro-preview": {
|
||||
"default": "gemini-3-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1037,6 +1061,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"auto": {
|
||||
"default": "gemini-3-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"releaseChannel": "stable"
|
||||
@@ -1067,6 +1097,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"pro": {
|
||||
"default": "gemini-3-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1091,6 +1127,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"gemini-3.1-flash-lite-preview": {
|
||||
"default": "gemini-3.1-flash-lite-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-flash-lite"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"useGemini3_1FlashLite": false
|
||||
@@ -1102,6 +1144,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"flash": {
|
||||
"default": "gemini-3-flash-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-flash"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1115,7 +1163,15 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"useGemini3_1FlashLite": true
|
||||
"useGemini3_1FlashLite": true,
|
||||
"authType": "gemini-api-key"
|
||||
},
|
||||
"target": "gemini-3.1-flash-lite-preview"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"useGemini3_1FlashLite": true,
|
||||
"authType": "vertex-ai"
|
||||
},
|
||||
"target": "gemini-3.1-flash-lite-preview"
|
||||
}
|
||||
@@ -1124,6 +1180,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"auto-gemini-3": {
|
||||
"default": "gemini-3-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1163,6 +1225,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"flash": {
|
||||
"default": "gemini-3-flash-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-flash"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
@@ -1180,6 +1248,12 @@ their corresponding top-level category object in your `settings.json` file.
|
||||
"pro": {
|
||||
"default": "gemini-3-pro-preview",
|
||||
"contexts": [
|
||||
{
|
||||
"condition": {
|
||||
"authType": "oauth-personal"
|
||||
},
|
||||
"target": "gemini-2.5-pro"
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"hasAccessToPreview": false
|
||||
|
||||
@@ -56,6 +56,9 @@ let errorSpy: vi.SpyInstance;
|
||||
let debugSpy: vi.SpyInstance;
|
||||
|
||||
beforeEach(() => {
|
||||
// Ensure a clean home directory state for all tests
|
||||
vi.stubEnv('GEMINI_CLI_HOME', '');
|
||||
|
||||
// Reset themeManager state to ensure test isolation
|
||||
themeManager.resetForTesting();
|
||||
|
||||
|
||||
@@ -2801,6 +2801,10 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
return getChannelFromVersion(this._clientVersion);
|
||||
}
|
||||
|
||||
getAuthType(): string | undefined {
|
||||
return this.contentGeneratorConfig?.authType;
|
||||
}
|
||||
|
||||
getPendingIncludeDirectories(): string[] {
|
||||
return this.pendingIncludeDirectories;
|
||||
}
|
||||
|
||||
@@ -428,6 +428,10 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
'gemini-3.1-pro-preview': {
|
||||
default: 'gemini-3.1-pro-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-pro',
|
||||
},
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
condition: { useCustomTools: true },
|
||||
@@ -438,12 +442,20 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
'gemini-3.1-pro-preview-customtools': {
|
||||
default: 'gemini-3.1-pro-preview-customtools',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-pro',
|
||||
},
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
],
|
||||
},
|
||||
'gemini-3-flash-preview': {
|
||||
default: 'gemini-3-flash-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-flash',
|
||||
},
|
||||
{
|
||||
condition: { hasAccessToPreview: false },
|
||||
target: 'gemini-2.5-flash',
|
||||
@@ -453,6 +465,10 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
'gemini-3-pro-preview': {
|
||||
default: 'gemini-3-pro-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-pro',
|
||||
},
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
condition: { useGemini3_1: true, useCustomTools: true },
|
||||
@@ -467,6 +483,7 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
auto: {
|
||||
default: 'gemini-3-pro-preview',
|
||||
contexts: [
|
||||
{ condition: { authType: 'oauth-personal' }, target: 'gemini-2.5-pro' },
|
||||
{ condition: { releaseChannel: 'stable' }, target: 'gemini-2.5-pro' },
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
@@ -482,6 +499,7 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
pro: {
|
||||
default: 'gemini-3-pro-preview',
|
||||
contexts: [
|
||||
{ condition: { authType: 'oauth-personal' }, target: 'gemini-2.5-pro' },
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
condition: { useGemini3_1: true, useCustomTools: true },
|
||||
@@ -496,6 +514,10 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
'gemini-3.1-flash-lite-preview': {
|
||||
default: 'gemini-3.1-flash-lite-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-flash-lite',
|
||||
},
|
||||
{
|
||||
condition: { useGemini3_1FlashLite: false },
|
||||
target: 'gemini-2.5-flash-lite',
|
||||
@@ -505,6 +527,10 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
flash: {
|
||||
default: 'gemini-3-flash-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-flash',
|
||||
},
|
||||
{
|
||||
condition: { hasAccessToPreview: false },
|
||||
target: 'gemini-2.5-flash',
|
||||
@@ -515,7 +541,14 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
default: 'gemini-2.5-flash-lite',
|
||||
contexts: [
|
||||
{
|
||||
condition: { useGemini3_1FlashLite: true },
|
||||
condition: {
|
||||
useGemini3_1FlashLite: true,
|
||||
authType: 'gemini-api-key',
|
||||
},
|
||||
target: 'gemini-3.1-flash-lite-preview',
|
||||
},
|
||||
{
|
||||
condition: { useGemini3_1FlashLite: true, authType: 'vertex-ai' },
|
||||
target: 'gemini-3.1-flash-lite-preview',
|
||||
},
|
||||
],
|
||||
@@ -523,6 +556,7 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
'auto-gemini-3': {
|
||||
default: 'gemini-3-pro-preview',
|
||||
contexts: [
|
||||
{ condition: { authType: 'oauth-personal' }, target: 'gemini-2.5-pro' },
|
||||
{ condition: { hasAccessToPreview: false }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
condition: { useGemini3_1: true, useCustomTools: true },
|
||||
@@ -542,6 +576,10 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
flash: {
|
||||
default: 'gemini-3-flash-preview',
|
||||
contexts: [
|
||||
{
|
||||
condition: { authType: 'oauth-personal' },
|
||||
target: 'gemini-2.5-flash',
|
||||
},
|
||||
{
|
||||
condition: { hasAccessToPreview: false },
|
||||
target: 'gemini-2.5-flash',
|
||||
@@ -555,6 +593,7 @@ export const DEFAULT_MODEL_CONFIGS: ModelConfigServiceConfig = {
|
||||
pro: {
|
||||
default: 'gemini-3-pro-preview',
|
||||
contexts: [
|
||||
{ condition: { authType: 'oauth-personal' }, target: 'gemini-2.5-pro' },
|
||||
{
|
||||
condition: { hasAccessToPreview: false },
|
||||
target: 'gemini-2.5-pro',
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface ModelResolutionContext {
|
||||
hasAccessToPreview?: boolean;
|
||||
requestedModel?: string;
|
||||
releaseChannel?: string;
|
||||
authType?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +51,7 @@ export interface ModelCapabilityContext {
|
||||
readonly modelConfigService: IModelConfigService;
|
||||
getExperimentalDynamicModelConfiguration(): boolean;
|
||||
getReleaseChannel?(): string;
|
||||
getAuthType?(): string | undefined;
|
||||
}
|
||||
|
||||
export const PREVIEW_GEMINI_MODEL = 'gemini-3-pro-preview';
|
||||
@@ -127,6 +129,7 @@ export function resolveModel(
|
||||
hasAccessToPreview: boolean = true,
|
||||
config?: ModelCapabilityContext,
|
||||
releaseChannel?: string,
|
||||
authType?: string,
|
||||
): string {
|
||||
// Defensive check against non-string inputs at runtime
|
||||
const normalizedModel = Array.isArray(requestedModel)
|
||||
@@ -136,6 +139,7 @@ export function resolveModel(
|
||||
: requestedModel.trim() || '';
|
||||
|
||||
const currentReleaseChannel = releaseChannel ?? config?.getReleaseChannel?.();
|
||||
const currentAuthType = authType ?? config?.getAuthType?.();
|
||||
|
||||
if (config?.getExperimentalDynamicModelConfiguration?.() === true) {
|
||||
const resolved = config.modelConfigService.resolveModelId(normalizedModel, {
|
||||
@@ -144,6 +148,7 @@ export function resolveModel(
|
||||
useCustomTools: useCustomToolModel,
|
||||
hasAccessToPreview,
|
||||
releaseChannel: currentReleaseChannel,
|
||||
authType: currentAuthType,
|
||||
});
|
||||
|
||||
if (!hasAccessToPreview && isPreviewModel(resolved, config)) {
|
||||
@@ -245,6 +250,7 @@ export function resolveClassifierModel(
|
||||
useCustomToolModel: boolean = false,
|
||||
hasAccessToPreview: boolean = true,
|
||||
config?: ModelCapabilityContext,
|
||||
authType?: string,
|
||||
): string {
|
||||
if (config?.getExperimentalDynamicModelConfiguration?.() === true) {
|
||||
return config.modelConfigService.resolveClassifierModelId(
|
||||
@@ -255,6 +261,7 @@ export function resolveClassifierModel(
|
||||
useGemini3_1FlashLite,
|
||||
useCustomTools: useCustomToolModel,
|
||||
hasAccessToPreview,
|
||||
authType: authType ?? config?.getAuthType?.(),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -281,6 +288,9 @@ export function resolveClassifierModel(
|
||||
false,
|
||||
false,
|
||||
hasAccessToPreview,
|
||||
config,
|
||||
undefined,
|
||||
authType,
|
||||
);
|
||||
}
|
||||
return resolveModel(
|
||||
@@ -289,6 +299,9 @@ export function resolveClassifierModel(
|
||||
useGemini3_1FlashLite,
|
||||
useCustomToolModel,
|
||||
hasAccessToPreview,
|
||||
config,
|
||||
undefined,
|
||||
authType,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
resolveModel,
|
||||
PREVIEW_GEMINI_MODEL_AUTO,
|
||||
PREVIEW_GEMINI_MODEL,
|
||||
DEFAULT_GEMINI_MODEL,
|
||||
type ModelCapabilityContext,
|
||||
} from './models.js';
|
||||
import { ModelConfigService } from '../services/modelConfigService.js';
|
||||
import { DEFAULT_MODEL_CONFIGS } from './defaultModelConfigs.js';
|
||||
|
||||
const modelConfigService = new ModelConfigService(DEFAULT_MODEL_CONFIGS);
|
||||
|
||||
const dynamicConfig = {
|
||||
getExperimentalDynamicModelConfiguration: () => true,
|
||||
modelConfigService,
|
||||
} as unknown as ModelCapabilityContext;
|
||||
|
||||
describe('resolveModel with authType', () => {
|
||||
it('should resolve auto-gemini-3 to gemini-3-pro-preview for non-personal auth', () => {
|
||||
const model = resolveModel(
|
||||
PREVIEW_GEMINI_MODEL_AUTO,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
dynamicConfig,
|
||||
'stable',
|
||||
'gemini-api-key',
|
||||
);
|
||||
expect(model).toBe(PREVIEW_GEMINI_MODEL);
|
||||
});
|
||||
|
||||
it('should resolve auto-gemini-3 to gemini-2.5-pro for oauth-personal auth', () => {
|
||||
const model = resolveModel(
|
||||
PREVIEW_GEMINI_MODEL_AUTO,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
dynamicConfig,
|
||||
'stable',
|
||||
'oauth-personal',
|
||||
);
|
||||
expect(model).toBe(DEFAULT_GEMINI_MODEL);
|
||||
});
|
||||
|
||||
it('should use authType from config if not passed explicitly', () => {
|
||||
const configWithAuth = {
|
||||
...dynamicConfig,
|
||||
getAuthType: () => 'oauth-personal',
|
||||
} as unknown as ModelCapabilityContext;
|
||||
|
||||
const model = resolveModel(
|
||||
PREVIEW_GEMINI_MODEL_AUTO,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
configWithAuth,
|
||||
);
|
||||
expect(model).toBe(DEFAULT_GEMINI_MODEL);
|
||||
});
|
||||
});
|
||||
@@ -217,6 +217,8 @@ export async function createContentGenerator(
|
||||
false,
|
||||
gcConfig.getHasAccessToPreviewModel?.() ?? true,
|
||||
gcConfig,
|
||||
undefined,
|
||||
config.authType,
|
||||
);
|
||||
const customHeadersEnv =
|
||||
process.env['GEMINI_CLI_CUSTOM_HEADERS'] || undefined;
|
||||
|
||||
@@ -103,6 +103,7 @@ export interface ResolutionContext {
|
||||
hasAccessToProModel?: boolean;
|
||||
requestedModel?: string;
|
||||
releaseChannel?: string;
|
||||
authType?: string;
|
||||
}
|
||||
|
||||
/** The requirements defined in the registry. */
|
||||
@@ -114,6 +115,7 @@ export interface ResolutionCondition {
|
||||
/** Matches if the current model is in this list. */
|
||||
requestedModels?: string[];
|
||||
releaseChannel?: string;
|
||||
authType?: string;
|
||||
}
|
||||
|
||||
export interface ModelConfigServiceConfig {
|
||||
@@ -267,6 +269,8 @@ export class ModelConfigService {
|
||||
);
|
||||
case 'releaseChannel':
|
||||
return value === context.releaseChannel;
|
||||
case 'authType':
|
||||
return value === context.authType;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ if (process.env.NO_COLOR !== undefined) {
|
||||
}
|
||||
|
||||
import { setSimulate429 } from './src/utils/testUtils.js';
|
||||
import { vi, afterEach } from 'vitest';
|
||||
import { vi, afterEach, beforeEach } from 'vitest';
|
||||
import { coreEvents } from './src/utils/events.js';
|
||||
|
||||
// Increase max listeners to avoid warnings in large test suites
|
||||
@@ -19,6 +19,11 @@ coreEvents.setMaxListeners(100);
|
||||
// Disable 429 simulation globally for all tests
|
||||
setSimulate429(false);
|
||||
|
||||
beforeEach(() => {
|
||||
// Ensure a clean home directory state for all tests
|
||||
vi.stubEnv('GEMINI_CLI_HOME', '');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user