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: { case DEFAULT_GEMINI_MODEL_AUTO: {
return DEFAULT_GEMINI_MODEL; return DEFAULT_GEMINI_MODEL;
} }
case GEMINI_MODEL_ALIAS_AUTO:
case GEMINI_MODEL_ALIAS_PRO: { case GEMINI_MODEL_ALIAS_PRO: {
return previewFeaturesEnabled return previewFeaturesEnabled
? PREVIEW_GEMINI_MODEL ? PREVIEW_GEMINI_MODEL

View File

@@ -4,18 +4,28 @@
* SPDX-License-Identifier: Apache-2.0 * 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 { DefaultStrategy } from './defaultStrategy.js';
import type { RoutingContext } from '../routingStrategy.js'; import type { RoutingContext } from '../routingStrategy.js';
import type { BaseLlmClient } from '../../core/baseLlmClient.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'; import type { Config } from '../../config/config.js';
describe('DefaultStrategy', () => { 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 strategy = new DefaultStrategy();
const mockContext = {} as RoutingContext; 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 mockClient = {} as BaseLlmClient;
const decision = await strategy.route(mockContext, mockConfig, mockClient); 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, RoutingDecision,
TerminalStrategy, TerminalStrategy,
} from '../routingStrategy.js'; } from '../routingStrategy.js';
import { DEFAULT_GEMINI_MODEL } from '../../config/models.js'; import { resolveModel } from '../../config/models.js';
export class DefaultStrategy implements TerminalStrategy { export class DefaultStrategy implements TerminalStrategy {
readonly name = 'default'; readonly name = 'default';
async route( async route(
_context: RoutingContext, _context: RoutingContext,
_config: Config, config: Config,
_baseLlmClient: BaseLlmClient, _baseLlmClient: BaseLlmClient,
): Promise<RoutingDecision> { ): Promise<RoutingDecision> {
const defaultModel = resolveModel(
config.getModel(),
config.getPreviewFeatures(),
);
return { return {
model: DEFAULT_GEMINI_MODEL, model: defaultModel,
metadata: { metadata: {
source: this.name, source: this.name,
latencyMs: 0, 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...'); console.log('\nRunning sensitive keyword linter...');
const SENSITIVE_PATTERN = /gemini-\d+(\.\d+)?/g; const SENSITIVE_PATTERN = /gemini-\d+(\.\d+)?/g;
const ALLOWED_KEYWORDS = new Set([ const ALLOWED_KEYWORDS = new Set([
'gemini-3',
'gemini-3.0', 'gemini-3.0',
'gemini-2.5', 'gemini-2.5',
'gemini-2.0', 'gemini-2.0',