From e356949d3fb600abd1a993949300a6c3e0008621 Mon Sep 17 00:00:00 2001 From: Bryan Morgan Date: Tue, 24 Jun 2025 18:48:55 -0400 Subject: [JUNE 25] Permanent failover to Flash model for OAuth users after persistent 429 errors (#1376) Co-authored-by: Scott Densmore --- packages/core/src/config/config.ts | 59 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'packages/core/src/config/config.ts') diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index a92dd7ba..b266512c 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -35,7 +35,10 @@ import { TelemetryTarget, StartSessionEvent, } from '../telemetry/index.js'; -import { DEFAULT_GEMINI_EMBEDDING_MODEL } from './models.js'; +import { + DEFAULT_GEMINI_EMBEDDING_MODEL, + DEFAULT_GEMINI_FLASH_MODEL, +} from './models.js'; import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js'; export enum ApprovalMode { @@ -85,6 +88,11 @@ export interface SandboxConfig { image: string; } +export type FlashFallbackHandler = ( + currentModel: string, + fallbackModel: string, +) => Promise; + export interface ConfigParameters { sessionId: string; embeddingModel?: string; @@ -156,6 +164,8 @@ export class Config { private readonly bugCommand: BugCommandSettings | undefined; private readonly model: string; private readonly extensionContextFilePaths: string[]; + private modelSwitchedDuringSession: boolean = false; + flashFallbackHandler?: FlashFallbackHandler; constructor(params: ConfigParameters) { this.sessionId = params.sessionId; @@ -216,9 +226,24 @@ export class Config { } async refreshAuth(authMethod: AuthType) { + // Check if this is actually a switch to a different auth method + const previousAuthType = this.contentGeneratorConfig?.authType; + const _isAuthMethodSwitch = + previousAuthType && previousAuthType !== authMethod; + + // Always use the original default model when switching auth methods + // This ensures users don't stay on Flash after switching between auth types + // and allows API key users to get proper fallback behavior from getEffectiveModel + const modelToUse = this.model; // Use the original default model + + // Temporarily clear contentGeneratorConfig to prevent getModel() from returning + // the previous session's model (which might be Flash) + this.contentGeneratorConfig = undefined!; + const contentConfig = await createContentGeneratorConfig( - this.getModel(), + modelToUse, authMethod, + this, ); const gc = new GeminiClient(this); @@ -226,6 +251,11 @@ export class Config { this.toolRegistry = await createToolRegistry(this); await gc.initialize(contentConfig); this.contentGeneratorConfig = contentConfig; + + // Reset the session flag since we're explicitly changing auth and using default model + this.modelSwitchedDuringSession = false; + + // Note: In the future, we may want to reset any cached state when switching auth methods } getSessionId(): string { @@ -240,6 +270,28 @@ export class Config { return this.contentGeneratorConfig?.model || this.model; } + setModel(newModel: string): void { + if (this.contentGeneratorConfig) { + this.contentGeneratorConfig.model = newModel; + this.modelSwitchedDuringSession = true; + } + } + + isModelSwitchedDuringSession(): boolean { + return this.modelSwitchedDuringSession; + } + + resetModelToDefault(): void { + if (this.contentGeneratorConfig) { + this.contentGeneratorConfig.model = this.model; // Reset to the original default model + this.modelSwitchedDuringSession = false; + } + } + + setFlashFallbackHandler(handler: FlashFallbackHandler): void { + this.flashFallbackHandler = handler; + } + getEmbeddingModel(): string { return this.embeddingModel; } @@ -445,3 +497,6 @@ export function createToolRegistry(config: Config): Promise { return registry; })(); } + +// Export model constants for use in CLI +export { DEFAULT_GEMINI_FLASH_MODEL }; -- cgit v1.2.3