diff --git a/packages/cli/src/ui/hooks/useQuotaAndFallback.ts b/packages/cli/src/ui/hooks/useQuotaAndFallback.ts index ff4bc6c4b8c..eb53513fdc6 100644 --- a/packages/cli/src/ui/hooks/useQuotaAndFallback.ts +++ b/packages/cli/src/ui/hooks/useQuotaAndFallback.ts @@ -130,10 +130,10 @@ export function useQuotaAndFallback({ isDialogPending.current = false; // Reset the flag here if (choice === 'retry_always') { - // Explicitly set the model to the fallback model to persist the user's choice. + // Set the model to the fallback model for the current session. // This ensures the Footer updates and future turns use this model. - config.setModel(proQuotaRequest.fallbackModel); - + // The change is not persisted, so the original model is restored on restart. + config.activateFallbackMode(proQuotaRequest.fallbackModel); historyManager.addItem( { type: MessageType.INFO, diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index dc78a789660..fd98520b33b 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -60,8 +60,11 @@ import { ideContextStore } from '../ide/ideContext.js'; import { WriteTodosTool } from '../tools/write-todos.js'; import type { FileSystemService } from '../services/fileSystemService.js'; import { StandardFileSystemService } from '../services/fileSystemService.js'; -import { logRipgrepFallback } from '../telemetry/loggers.js'; -import { RipgrepFallbackEvent } from '../telemetry/types.js'; +import { logRipgrepFallback, logFlashFallback } from '../telemetry/loggers.js'; +import { + RipgrepFallbackEvent, + FlashFallbackEvent, +} from '../telemetry/types.js'; import type { FallbackModelHandler } from '../fallback/types.js'; import { ModelAvailabilityService } from '../availability/modelAvailabilityService.js'; import { ModelRouterService } from '../routing/modelRouterService.js'; @@ -869,6 +872,14 @@ export class Config { this.modelAvailabilityService.reset(); } + activateFallbackMode(model: string): void { + this.setModel(model); + const authType = this.getContentGeneratorConfig()?.authType; + if (authType) { + logFlashFallback(this, new FlashFallbackEvent(authType)); + } + } + getActiveModel(): string { return this._activeModel ?? this.model; } diff --git a/packages/core/src/config/flashFallback.test.ts b/packages/core/src/config/flashFallback.test.ts index b86ae68d3ce..320d69c5657 100644 --- a/packages/core/src/config/flashFallback.test.ts +++ b/packages/core/src/config/flashFallback.test.ts @@ -7,10 +7,16 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { Config } from './config.js'; import { DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_FLASH_MODEL } from './models.js'; +import { logFlashFallback } from '../telemetry/loggers.js'; +import { FlashFallbackEvent } from '../telemetry/types.js'; import fs from 'node:fs'; vi.mock('node:fs'); +vi.mock('../telemetry/loggers.js', () => ({ + logFlashFallback: vi.fn(), + logRipgrepFallback: vi.fn(), +})); describe('Flash Model Fallback Configuration', () => { let config: Config; @@ -57,4 +63,15 @@ describe('Flash Model Fallback Configuration', () => { expect(newConfig.getModel()).toBe('custom-model'); }); }); + + describe('activateFallbackMode', () => { + it('should set model to fallback and log event', () => { + config.activateFallbackMode(DEFAULT_GEMINI_FLASH_MODEL); + expect(config.getModel()).toBe(DEFAULT_GEMINI_FLASH_MODEL); + expect(logFlashFallback).toHaveBeenCalledWith( + config, + expect.any(FlashFallbackEvent), + ); + }); + }); });