fix: respect explicit model selection after Flash quota exhaustion (#26759) (#26872)

This commit is contained in:
Coco Sheng
2026-05-12 10:26:50 -04:00
committed by GitHub
parent 11a9edc808
commit 7a9ed4c20a
10 changed files with 197 additions and 44 deletions
@@ -27,6 +27,7 @@ import type { Content } from '@google/genai';
import type { ResolvedModelConfig } from '../../services/modelConfigService.js';
import { debugLogger } from '../../utils/debugLogger.js';
import { AuthType } from '../../core/contentGenerator.js';
import { ModelAvailabilityService } from '../../availability/modelAvailabilityService.js';
vi.mock('../../core/baseLlmClient.js');
@@ -68,6 +69,9 @@ describe('ClassifierStrategy', () => {
getContentGeneratorConfig: vi.fn().mockReturnValue({
authType: AuthType.LOGIN_WITH_GOOGLE,
}),
getModelAvailabilityService: vi
.fn()
.mockReturnValue(new ModelAvailabilityService()),
} as unknown as Config;
mockBaseLlmClient = {
generateJson: vi.fn(),
@@ -20,6 +20,7 @@ import {
isFunctionResponse,
} from '../../utils/messageInspectors.js';
import { debugLogger } from '../../utils/debugLogger.js';
import { normalizeModelId } from '../../utils/modelUtils.js';
import type { LocalLiteRtLmClient } from '../../core/localLiteRtLmClient.js';
import { LlmRole } from '../../telemetry/types.js';
@@ -177,16 +178,28 @@ export class ClassifierStrategy implements RoutingStrategy {
config.getGemini31FlashLiteLaunched(),
config.getUseCustomToolModel(),
]);
const selectedModel = resolveClassifierModel(
model,
routerResponse.model_choice,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
const selectedModel = normalizeModelId(
resolveClassifierModel(
normalizeModelId(model),
routerResponse.model_choice,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
),
);
const service = config.getModelAvailabilityService();
const snapshot = service.snapshot(selectedModel);
if (!snapshot.available) {
debugLogger.warn(
`[Routing] Classifier selected unavailable model ${selectedModel} (${snapshot.reason}). Bypassing.`,
);
return null;
}
return {
model: selectedModel,
metadata: {
@@ -27,6 +27,7 @@ import type { ResolvedModelConfig } from '../../services/modelConfigService.js';
import { debugLogger } from '../../utils/debugLogger.js';
import type { LocalLiteRtLmClient } from '../../core/localLiteRtLmClient.js';
import { AuthType } from '../../core/contentGenerator.js';
import { ModelAvailabilityService } from '../../availability/modelAvailabilityService.js';
vi.mock('../../core/baseLlmClient.js');
@@ -71,6 +72,9 @@ describe('NumericalClassifierStrategy', () => {
getContentGeneratorConfig: vi.fn().mockReturnValue({
authType: AuthType.LOGIN_WITH_GOOGLE,
}),
getModelAvailabilityService: vi
.fn()
.mockReturnValue(new ModelAvailabilityService()),
} as unknown as Config;
mockBaseLlmClient = {
generateJson: vi.fn(),
@@ -20,6 +20,7 @@ import {
isFunctionResponse,
} from '../../utils/messageInspectors.js';
import { debugLogger } from '../../utils/debugLogger.js';
import { normalizeModelId } from '../../utils/modelUtils.js';
import type { LocalLiteRtLmClient } from '../../core/localLiteRtLmClient.js';
import { LlmRole } from '../../telemetry/types.js';
@@ -172,16 +173,28 @@ export class NumericalClassifierStrategy implements RoutingStrategy {
config.getGemini31FlashLiteLaunched(),
config.getUseCustomToolModel(),
]);
const selectedModel = resolveClassifierModel(
model,
modelAlias,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
const selectedModel = normalizeModelId(
resolveClassifierModel(
normalizeModelId(model),
modelAlias,
useGemini3_1,
useGemini3_1FlashLite,
useCustomToolModel,
config.getHasAccessToPreviewModel?.() ?? true,
config,
),
);
const service = config.getModelAvailabilityService();
const snapshot = service.snapshot(selectedModel);
if (!snapshot.available) {
debugLogger.warn(
`[Routing] Numerical classifier selected unavailable model ${selectedModel} (${snapshot.reason}). Bypassing.`,
);
return null;
}
const latencyMs = Date.now() - startTime;
return {