diff options
Diffstat (limited to 'packages/cli/src/ui/utils/errorParsing.ts')
| -rw-r--r-- | packages/cli/src/ui/utils/errorParsing.ts | 136 |
1 files changed, 97 insertions, 39 deletions
diff --git a/packages/cli/src/ui/utils/errorParsing.ts b/packages/cli/src/ui/utils/errorParsing.ts index 33014812..555d5e4e 100644 --- a/packages/cli/src/ui/utils/errorParsing.ts +++ b/packages/cli/src/ui/utils/errorParsing.ts @@ -4,66 +4,118 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { AuthType, StructuredError } from '@google/gemini-cli-core'; +import { + AuthType, + UserTierId, + DEFAULT_GEMINI_FLASH_MODEL, + DEFAULT_GEMINI_MODEL, + isProQuotaExceededError, + isGenericQuotaExceededError, + isApiError, + isStructuredError, +} from '@google/gemini-cli-core'; -const RATE_LIMIT_ERROR_MESSAGE_GOOGLE = - '\nPlease wait and try again later. To increase your limits, upgrade to a plan with higher limits, or use /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey'; +// Free Tier message functions +const getRateLimitErrorMessageGoogleFree = ( + fallbackModel: string = DEFAULT_GEMINI_FLASH_MODEL, +) => + `\nSlow response times detected. Switching to the ${fallbackModel} model for the rest of this session.`; + +const getRateLimitErrorMessageGoogleProQuotaFree = ( + currentModel: string = DEFAULT_GEMINI_MODEL, + fallbackModel: string = DEFAULT_GEMINI_FLASH_MODEL, +) => + `\nYou have reached your daily ${currentModel} quota limit. You will be switched to the ${fallbackModel} model for the rest of this session. To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist, or use /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`; + +const getRateLimitErrorMessageGoogleGenericQuotaFree = () => + `\nYou have reached your daily quota limit. To increase your limits, upgrade to a Gemini Code Assist Standard or Enterprise plan with higher limits at https://goo.gle/set-up-gemini-code-assist, or use /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`; + +// Legacy/Standard Tier message functions +const getRateLimitErrorMessageGooglePaid = ( + fallbackModel: string = DEFAULT_GEMINI_FLASH_MODEL, +) => + `\nSlow response times detected. Switching to the ${fallbackModel} model for the rest of this session. We appreciate you for choosing Gemini Code Assist and the Gemini CLI.`; + +const getRateLimitErrorMessageGoogleProQuotaPaid = ( + currentModel: string = DEFAULT_GEMINI_MODEL, + fallbackModel: string = DEFAULT_GEMINI_FLASH_MODEL, +) => + `\nYou have reached your daily ${currentModel} quota limit. You will be switched to the ${fallbackModel} model for the rest of this session. We appreciate you for choosing Gemini Code Assist and the Gemini CLI. To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`; + +const getRateLimitErrorMessageGoogleGenericQuotaPaid = ( + currentModel: string = DEFAULT_GEMINI_MODEL, +) => + `\nYou have reached your daily quota limit. We appreciate you for choosing Gemini Code Assist and the Gemini CLI. To continue accessing the ${currentModel} model today, consider using /auth to switch to using a paid API key from AI Studio at https://aistudio.google.com/apikey`; const RATE_LIMIT_ERROR_MESSAGE_USE_GEMINI = '\nPlease wait and try again later. To increase your limits, request a quota increase through AI Studio, or switch to another /auth method'; const RATE_LIMIT_ERROR_MESSAGE_VERTEX = '\nPlease wait and try again later. To increase your limits, request a quota increase through Vertex, or switch to another /auth method'; -const RATE_LIMIT_ERROR_MESSAGE_DEFAULT = - 'Your request has been rate limited. Please wait and try again later.'; - -export interface ApiError { - error: { - code: number; - message: string; - status: string; - details: unknown[]; - }; -} - -function isApiError(error: unknown): error is ApiError { - return ( - typeof error === 'object' && - error !== null && - 'error' in error && - typeof (error as ApiError).error === 'object' && - 'message' in (error as ApiError).error - ); -} - -function isStructuredError(error: unknown): error is StructuredError { - return ( - typeof error === 'object' && - error !== null && - 'message' in error && - typeof (error as StructuredError).message === 'string' - ); -} +const getRateLimitErrorMessageDefault = ( + fallbackModel: string = DEFAULT_GEMINI_FLASH_MODEL, +) => + `\nSlow response times detected. Switching to the ${fallbackModel} model for the rest of this session.`; -function getRateLimitMessage(authType?: AuthType): string { +function getRateLimitMessage( + authType?: AuthType, + error?: unknown, + userTier?: UserTierId, + currentModel?: string, + fallbackModel?: string, +): string { switch (authType) { - case AuthType.LOGIN_WITH_GOOGLE: - return RATE_LIMIT_ERROR_MESSAGE_GOOGLE; + case AuthType.LOGIN_WITH_GOOGLE: { + // Determine if user is on a paid tier (Legacy or Standard) - default to FREE if not specified + const isPaidTier = + userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD; + + if (isProQuotaExceededError(error)) { + return isPaidTier + ? getRateLimitErrorMessageGoogleProQuotaPaid( + currentModel || DEFAULT_GEMINI_MODEL, + fallbackModel, + ) + : getRateLimitErrorMessageGoogleProQuotaFree( + currentModel || DEFAULT_GEMINI_MODEL, + fallbackModel, + ); + } else if (isGenericQuotaExceededError(error)) { + return isPaidTier + ? getRateLimitErrorMessageGoogleGenericQuotaPaid( + currentModel || DEFAULT_GEMINI_MODEL, + ) + : getRateLimitErrorMessageGoogleGenericQuotaFree(); + } else { + return isPaidTier + ? getRateLimitErrorMessageGooglePaid(fallbackModel) + : getRateLimitErrorMessageGoogleFree(fallbackModel); + } + } case AuthType.USE_GEMINI: return RATE_LIMIT_ERROR_MESSAGE_USE_GEMINI; case AuthType.USE_VERTEX_AI: return RATE_LIMIT_ERROR_MESSAGE_VERTEX; default: - return RATE_LIMIT_ERROR_MESSAGE_DEFAULT; + return getRateLimitErrorMessageDefault(fallbackModel); } } export function parseAndFormatApiError( error: unknown, authType?: AuthType, + userTier?: UserTierId, + currentModel?: string, + fallbackModel?: string, ): string { if (isStructuredError(error)) { let text = `[API Error: ${error.message}]`; if (error.status === 429) { - text += getRateLimitMessage(authType); + text += getRateLimitMessage( + authType, + error, + userTier, + currentModel, + fallbackModel, + ); } return text; } @@ -92,7 +144,13 @@ export function parseAndFormatApiError( } let text = `[API Error: ${finalMessage} (Status: ${parsedError.error.status})]`; if (parsedError.error.code === 429) { - text += getRateLimitMessage(authType); + text += getRateLimitMessage( + authType, + parsedError, + userTier, + currentModel, + fallbackModel, + ); } return text; } |
