fix(core): resolve auto model in default strategy (#17116)

This commit is contained in:
Sehoon Shon
2026-01-20 16:03:34 -05:00
committed by GitHub
parent f0f705d3ca
commit ed0b0fae49
4 changed files with 109 additions and 8 deletions

View File

@@ -51,6 +51,7 @@ export function resolveModel(
case DEFAULT_GEMINI_MODEL_AUTO: {
return DEFAULT_GEMINI_MODEL;
}
case GEMINI_MODEL_ALIAS_AUTO:
case GEMINI_MODEL_ALIAS_PRO: {
return previewFeaturesEnabled
? PREVIEW_GEMINI_MODEL

View File

@@ -4,18 +4,28 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import { DefaultStrategy } from './defaultStrategy.js';
import type { RoutingContext } from '../routingStrategy.js';
import type { BaseLlmClient } from '../../core/baseLlmClient.js';
import { DEFAULT_GEMINI_MODEL } from '../../config/models.js';
import {
DEFAULT_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL,
PREVIEW_GEMINI_MODEL_AUTO,
DEFAULT_GEMINI_MODEL_AUTO,
GEMINI_MODEL_ALIAS_AUTO,
PREVIEW_GEMINI_FLASH_MODEL,
} from '../../config/models.js';
import type { Config } from '../../config/config.js';
describe('DefaultStrategy', () => {
it('should always route to the default Gemini model', async () => {
it('should route to the default model when requested model is default auto', async () => {
const strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext;
const mockConfig = {} as Config;
const mockConfig = {
getModel: vi.fn().mockReturnValue(DEFAULT_GEMINI_MODEL_AUTO),
getPreviewFeatures: vi.fn().mockReturnValue(false),
} as unknown as Config;
const mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient);
@@ -29,4 +39,89 @@ describe('DefaultStrategy', () => {
},
});
});
it('should route to the preview model when requested model is preview auto', async () => {
const strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext;
const mockConfig = {
getModel: vi.fn().mockReturnValue(PREVIEW_GEMINI_MODEL_AUTO),
getPreviewFeatures: vi.fn().mockReturnValue(false),
} as unknown as Config;
const mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient);
expect(decision).toEqual({
model: PREVIEW_GEMINI_MODEL,
metadata: {
source: 'default',
latencyMs: 0,
reasoning: `Routing to default model: ${PREVIEW_GEMINI_MODEL}`,
},
});
});
it('should route to the preview model when requested model is auto and previewfeature is on', async () => {
const strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext;
const mockConfig = {
getModel: vi.fn().mockReturnValue(GEMINI_MODEL_ALIAS_AUTO),
getPreviewFeatures: vi.fn().mockReturnValue(true),
} as unknown as Config;
const mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient);
expect(decision).toEqual({
model: PREVIEW_GEMINI_MODEL,
metadata: {
source: 'default',
latencyMs: 0,
reasoning: `Routing to default model: ${PREVIEW_GEMINI_MODEL}`,
},
});
});
it('should route to the default model when requested model is auto and previewfeature is off', async () => {
const strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext;
const mockConfig = {
getModel: vi.fn().mockReturnValue(GEMINI_MODEL_ALIAS_AUTO),
getPreviewFeatures: vi.fn().mockReturnValue(false),
} as unknown as Config;
const mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient);
expect(decision).toEqual({
model: DEFAULT_GEMINI_MODEL,
metadata: {
source: 'default',
latencyMs: 0,
reasoning: `Routing to default model: ${DEFAULT_GEMINI_MODEL}`,
},
});
});
// this should not happen, adding the test just in case it happens.
it('should route to the same model if it is not an auto mode', async () => {
const strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext;
const mockConfig = {
getModel: vi.fn().mockReturnValue(PREVIEW_GEMINI_FLASH_MODEL),
getPreviewFeatures: vi.fn().mockReturnValue(false),
} as unknown as Config;
const mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient);
expect(decision).toEqual({
model: PREVIEW_GEMINI_FLASH_MODEL,
metadata: {
source: 'default',
latencyMs: 0,
reasoning: `Routing to default model: ${PREVIEW_GEMINI_FLASH_MODEL}`,
},
});
});
});

View File

@@ -11,22 +11,26 @@ import type {
RoutingDecision,
TerminalStrategy,
} from '../routingStrategy.js';
import { DEFAULT_GEMINI_MODEL } from '../../config/models.js';
import { resolveModel } from '../../config/models.js';
export class DefaultStrategy implements TerminalStrategy {
readonly name = 'default';
async route(
_context: RoutingContext,
_config: Config,
config: Config,
_baseLlmClient: BaseLlmClient,
): Promise<RoutingDecision> {
const defaultModel = resolveModel(
config.getModel(),
config.getPreviewFeatures(),
);
return {
model: DEFAULT_GEMINI_MODEL,
model: defaultModel,
metadata: {
source: this.name,
latencyMs: 0,
reasoning: `Routing to default model: ${DEFAULT_GEMINI_MODEL}`,
reasoning: `Routing to default model: ${defaultModel}`,
},
};
}

View File

@@ -197,6 +197,7 @@ export function runSensitiveKeywordLinter() {
console.log('\nRunning sensitive keyword linter...');
const SENSITIVE_PATTERN = /gemini-\d+(\.\d+)?/g;
const ALLOWED_KEYWORDS = new Set([
'gemini-3',
'gemini-3.0',
'gemini-2.5',
'gemini-2.0',