Files
gemini-cli/packages/cli/src/ui/components/ProQuotaDialog.tsx
T

137 lines
3.4 KiB
TypeScript
Raw Normal View History

2025-08-29 04:19:43 +05:30
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type React from 'react';
import { Box, Text } from 'ink';
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
2025-09-10 10:57:07 -07:00
import { theme } from '../semantic-colors.js';
2025-08-29 04:19:43 +05:30
2025-11-18 12:01:16 -05:00
import {
DEFAULT_GEMINI_FLASH_LITE_MODEL,
DEFAULT_GEMINI_FLASH_MODEL,
DEFAULT_GEMINI_MODEL,
2025-11-18 12:01:16 -05:00
UserTierId,
} from '@google/gemini-cli-core';
2025-08-29 04:19:43 +05:30
interface ProQuotaDialogProps {
2025-11-18 12:01:16 -05:00
failedModel: string;
2025-08-29 04:19:43 +05:30
fallbackModel: string;
2025-11-18 12:01:16 -05:00
message: string;
isTerminalQuotaError: boolean;
isModelNotFoundError?: boolean;
onChoice: (
choice: 'retry_later' | 'retry_once' | 'retry_always' | 'upgrade',
) => void;
userTier: UserTierId | undefined;
2025-08-29 04:19:43 +05:30
}
export function ProQuotaDialog({
2025-11-18 12:01:16 -05:00
failedModel,
2025-08-29 04:19:43 +05:30
fallbackModel,
2025-11-18 12:01:16 -05:00
message,
isTerminalQuotaError,
isModelNotFoundError,
2025-08-29 04:19:43 +05:30
onChoice,
2025-11-18 12:01:16 -05:00
userTier,
2025-08-29 04:19:43 +05:30
}: ProQuotaDialogProps): React.JSX.Element {
2025-11-18 12:01:16 -05:00
// Use actual user tier if available; otherwise, default to FREE tier behavior (safe default)
const isPaidTier =
userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD;
let items;
// flash and flash lite don't have options to switch or upgrade.
if (
failedModel === DEFAULT_GEMINI_FLASH_MODEL ||
failedModel === DEFAULT_GEMINI_FLASH_LITE_MODEL
) {
items = [
{
label: 'Keep trying',
value: 'retry_once' as const,
key: 'retry_once',
},
{
label: 'Stop',
value: 'retry_later' as const,
key: 'retry_later',
},
];
} else if (isModelNotFoundError || (isTerminalQuotaError && isPaidTier)) {
// out of quota
items = [
{
label: `Switch to ${fallbackModel}`,
value: 'retry_always' as const,
key: 'retry_always',
},
{
label: `Stop`,
value: 'retry_later' as const,
key: 'retry_later',
},
];
} else if (isTerminalQuotaError && !isPaidTier) {
// free user gets an option to upgrade
items = [
{
label: `Switch to ${fallbackModel}`,
value: 'retry_always' as const,
key: 'retry_always',
},
{
label: 'Upgrade for higher limits',
value: 'upgrade' as const,
key: 'upgrade',
},
{
label: `Stop`,
value: 'retry_later' as const,
key: 'retry_later',
},
];
} else {
// capacity error
items = [
{
label: 'Keep trying',
value: 'retry_once' as const,
key: 'retry_once',
},
{
label: `Switch to ${fallbackModel}`,
value: 'retry_always' as const,
key: 'retry_always',
},
{
label: 'Stop',
value: 'retry_later' as const,
key: 'retry_later',
},
];
}
2025-08-29 04:19:43 +05:30
2025-11-18 12:01:16 -05:00
const handleSelect = (
choice: 'retry_later' | 'retry_once' | 'retry_always' | 'upgrade',
) => {
2025-08-29 04:19:43 +05:30
onChoice(choice);
};
return (
2025-11-18 12:01:16 -05:00
<Box borderStyle="round" flexDirection="column" padding={1}>
<Box marginBottom={1}>
<Text>{message}</Text>
</Box>
<Box marginTop={1} marginBottom={1}>
2025-11-18 12:01:16 -05:00
<RadioButtonSelect items={items} onSelect={handleSelect} />
2025-08-29 04:19:43 +05:30
</Box>
<Text color={theme.text.primary}>
{fallbackModel === DEFAULT_GEMINI_MODEL && !isModelNotFoundError
2025-11-18 12:01:16 -05:00
? 'Note: We will periodically retry Preview Model to see if congestion has cleared.'
: 'Note: You can always use /model to select a different option.'}
</Text>
2025-08-29 04:19:43 +05:30
</Box>
);
}