FEAT: Add availabilityService (#81)

* auto and fallback work

* test fixes

* fixes

* Show model dialog even if there's no more fallback option

* fix tests

* fix failing test

* disable showInDialog for model in settings

* revert package-lock.json

* remove dup line

---------

Co-authored-by: Sehoon Shon <sshon@google.com>
This commit is contained in:
Adam Weidman
2025-12-11 21:51:16 -05:00
committed by Tommaso Sciortino
parent 4b3d858f31
commit af94beea11
36 changed files with 875 additions and 1510 deletions
@@ -14,6 +14,7 @@ import {
type UserTierId,
PREVIEW_GEMINI_MODEL,
DEFAULT_GEMINI_MODEL,
VALID_GEMINI_MODELS,
} from '@google/gemini-cli-core';
import { useCallback, useEffect, useRef, useState } from 'react';
import { type UseHistoryManagerReturn } from './useHistoryManager.js';
@@ -71,12 +72,15 @@ export function useQuotaAndFallback({
`/auth to switch to API key.`,
].filter(Boolean);
message = messageLines.join('\n');
} else if (error instanceof ModelNotFoundError) {
} else if (
error instanceof ModelNotFoundError &&
VALID_GEMINI_MODELS.has(failedModel)
) {
isModelNotFoundError = true;
const messageLines = [
`It seems like you don't have access to Gemini 3.`,
`It seems like you don't have access to ${failedModel}.`,
`Learn more at https://goo.gle/enable-preview-features`,
`To disable Gemini 3, disable "Preview features" in /settings.`,
`To disable ${failedModel}, disable "Preview features" in /settings.`,
];
message = messageLines.join('\n');
} else {
@@ -120,30 +124,20 @@ export function useQuotaAndFallback({
isDialogPending.current = false; // Reset the flag here
if (choice === 'retry_always') {
// If we were recovering from a Preview Model failure, show a specific message.
if (proQuotaRequest.failedModel === PREVIEW_GEMINI_MODEL) {
const showPeriodicalCheckMessage =
!proQuotaRequest.isModelNotFoundError &&
proQuotaRequest.fallbackModel === DEFAULT_GEMINI_MODEL;
historyManager.addItem(
{
type: MessageType.INFO,
text: `Switched to fallback model ${proQuotaRequest.fallbackModel}. ${showPeriodicalCheckMessage ? `We will periodically check if ${PREVIEW_GEMINI_MODEL} is available again.` : ''}`,
},
Date.now(),
);
} else {
historyManager.addItem(
{
type: MessageType.INFO,
text: 'Switched to fallback model.',
},
Date.now(),
);
}
// Explicitly set the model to the fallback model to persist the user's choice.
// This ensures the Footer updates and future turns use this model.
config.setModel(proQuotaRequest.fallbackModel);
historyManager.addItem(
{
type: MessageType.INFO,
text: `Switched to fallback model ${proQuotaRequest.fallbackModel}`,
},
Date.now(),
);
}
},
[proQuotaRequest, historyManager],
[proQuotaRequest, historyManager, config],
);
return {