@google/gemini-cli 0.5.0-nightly.20250908.4693137b → 0.5.0-preview

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/package.json +2 -2
  2. package/dist/src/commands/extensions/install.js +5 -12
  3. package/dist/src/commands/extensions/install.js.map +1 -1
  4. package/dist/src/commands/extensions/install.test.js +1 -16
  5. package/dist/src/commands/extensions/install.test.js.map +1 -1
  6. package/dist/src/config/config.js +1 -0
  7. package/dist/src/config/config.js.map +1 -1
  8. package/dist/src/config/extension.d.ts +1 -0
  9. package/dist/src/config/extension.js +70 -46
  10. package/dist/src/config/extension.js.map +1 -1
  11. package/dist/src/config/settings.js +2 -2
  12. package/dist/src/config/settings.js.map +1 -1
  13. package/dist/src/config/settingsSchema.d.ts +31 -6
  14. package/dist/src/config/settingsSchema.js +24 -3
  15. package/dist/src/config/settingsSchema.js.map +1 -1
  16. package/dist/src/config/settingsSchema.test.js +62 -55
  17. package/dist/src/config/settingsSchema.test.js.map +1 -1
  18. package/dist/src/gemini.js +4 -37
  19. package/dist/src/gemini.js.map +1 -1
  20. package/dist/src/generated/git-commit.d.ts +2 -2
  21. package/dist/src/generated/git-commit.js +2 -2
  22. package/dist/src/generated/git-commit.js.map +1 -1
  23. package/dist/src/nonInteractiveCli.js +75 -73
  24. package/dist/src/nonInteractiveCli.js.map +1 -1
  25. package/dist/src/ui/AppContainer.js +40 -136
  26. package/dist/src/ui/AppContainer.js.map +1 -1
  27. package/dist/src/ui/AppContainer.test.js +199 -16
  28. package/dist/src/ui/AppContainer.test.js.map +1 -1
  29. package/dist/src/ui/components/AppHeader.js +5 -2
  30. package/dist/src/ui/components/AppHeader.js.map +1 -1
  31. package/dist/src/ui/components/Composer.js +2 -1
  32. package/dist/src/ui/components/Composer.js.map +1 -1
  33. package/dist/src/ui/components/ConfigInitDisplay.d.ts +6 -0
  34. package/dist/src/ui/components/ConfigInitDisplay.js +37 -0
  35. package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -0
  36. package/dist/src/ui/components/DialogManager.js +2 -3
  37. package/dist/src/ui/components/DialogManager.js.map +1 -1
  38. package/dist/src/ui/components/GeminiRespondingSpinner.d.ts +5 -0
  39. package/dist/src/ui/components/GeminiRespondingSpinner.js +5 -1
  40. package/dist/src/ui/components/GeminiRespondingSpinner.js.map +1 -1
  41. package/dist/src/ui/components/ProQuotaDialog.d.ts +2 -2
  42. package/dist/src/ui/components/ProQuotaDialog.js +2 -2
  43. package/dist/src/ui/components/ProQuotaDialog.js.map +1 -1
  44. package/dist/src/ui/components/ProQuotaDialog.test.js +3 -3
  45. package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
  46. package/dist/src/ui/components/SettingsDialog.js +20 -5
  47. package/dist/src/ui/components/SettingsDialog.js.map +1 -1
  48. package/dist/src/ui/components/SettingsDialog.test.js +144 -79
  49. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  50. package/dist/src/ui/components/ThemeDialog.js +10 -27
  51. package/dist/src/ui/components/ThemeDialog.js.map +1 -1
  52. package/dist/src/ui/components/ThemeDialog.test.d.ts +6 -0
  53. package/dist/src/ui/components/ThemeDialog.test.js +65 -0
  54. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -0
  55. package/dist/src/ui/components/shared/EnumSelector.d.ts +18 -0
  56. package/dist/src/ui/components/shared/EnumSelector.js +44 -0
  57. package/dist/src/ui/components/shared/EnumSelector.js.map +1 -0
  58. package/dist/src/ui/components/shared/EnumSelector.test.d.ts +6 -0
  59. package/dist/src/ui/components/shared/EnumSelector.test.js +70 -0
  60. package/dist/src/ui/components/shared/EnumSelector.test.js.map +1 -0
  61. package/dist/src/ui/components/shared/ScopeSelector.d.ts +19 -0
  62. package/dist/src/ui/components/shared/ScopeSelector.js +11 -0
  63. package/dist/src/ui/components/shared/ScopeSelector.js.map +1 -0
  64. package/dist/src/ui/contexts/UIStateContext.d.ts +8 -2
  65. package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
  66. package/dist/src/ui/hooks/useFolderTrust.d.ts +1 -2
  67. package/dist/src/ui/hooks/useFolderTrust.js +21 -8
  68. package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
  69. package/dist/src/ui/hooks/useGeminiStream.js +36 -34
  70. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  71. package/dist/src/ui/hooks/useMessageQueue.d.ts +2 -1
  72. package/dist/src/ui/hooks/useMessageQueue.js +5 -3
  73. package/dist/src/ui/hooks/useMessageQueue.js.map +1 -1
  74. package/dist/src/ui/hooks/useMessageQueue.test.js +9 -0
  75. package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
  76. package/dist/src/ui/hooks/useQuotaAndFallback.d.ts +21 -0
  77. package/dist/src/ui/hooks/useQuotaAndFallback.js +122 -0
  78. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -0
  79. package/dist/src/ui/hooks/useQuotaAndFallback.test.d.ts +6 -0
  80. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +269 -0
  81. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -0
  82. package/dist/src/utils/settingsUtils.d.ts +16 -6
  83. package/dist/src/utils/settingsUtils.js +35 -25
  84. package/dist/src/utils/settingsUtils.js.map +1 -1
  85. package/dist/src/utils/settingsUtils.test.js +418 -156
  86. package/dist/src/utils/settingsUtils.test.js.map +1 -1
  87. package/dist/src/zed-integration/schema.d.ts +4 -4
  88. package/dist/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +3 -3
  90. package/dist/google-gemini-cli-0.3.4.tgz +0 -0
@@ -3,5 +3,5 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- export declare const GIT_COMMIT_INFO = "4693137b";
7
- export declare const CLI_VERSION = "0.5.0-nightly.20250908.4693137b";
6
+ export declare const GIT_COMMIT_INFO = "a31830a3";
7
+ export declare const CLI_VERSION = "0.5.0-preview";
@@ -5,6 +5,6 @@
5
5
  */
6
6
  // This file is auto-generated by the build script (scripts/generate-git-commit-info.js)
7
7
  // Do not edit this file manually.
8
- export const GIT_COMMIT_INFO = '4693137b';
9
- export const CLI_VERSION = '0.5.0-nightly.20250908.4693137b';
8
+ export const GIT_COMMIT_INFO = 'a31830a3';
9
+ export const CLI_VERSION = '0.5.0-preview';
10
10
  //# sourceMappingURL=git-commit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-commit.js","sourceRoot":"","sources":["../../../src/generated/git-commit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wFAAwF;AACxF,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,iCAAiC,CAAC"}
1
+ {"version":3,"file":"git-commit.js","sourceRoot":"","sources":["../../../src/generated/git-commit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,wFAAwF;AACxF,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC;AAC1C,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC"}
@@ -3,90 +3,92 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { executeToolCall, shutdownTelemetry, isTelemetrySdkInitialized, GeminiEventType, parseAndFormatApiError, FatalInputError, FatalTurnLimitedError, } from '@google/gemini-cli-core';
6
+ import { executeToolCall, shutdownTelemetry, isTelemetrySdkInitialized, GeminiEventType, parseAndFormatApiError, FatalInputError, FatalTurnLimitedError, promptIdContext, } from '@google/gemini-cli-core';
7
7
  import { ConsolePatcher } from './ui/utils/ConsolePatcher.js';
8
8
  import { handleAtCommand } from './ui/hooks/atCommandProcessor.js';
9
9
  export async function runNonInteractive(config, input, prompt_id) {
10
- const consolePatcher = new ConsolePatcher({
11
- stderr: true,
12
- debugMode: config.getDebugMode(),
13
- });
14
- try {
15
- consolePatcher.patch();
16
- // Handle EPIPE errors when the output is piped to a command that closes early.
17
- process.stdout.on('error', (err) => {
18
- if (err.code === 'EPIPE') {
19
- // Exit gracefully if the pipe is closed.
20
- process.exit(0);
21
- }
22
- });
23
- const geminiClient = config.getGeminiClient();
24
- const abortController = new AbortController();
25
- const { processedQuery, shouldProceed } = await handleAtCommand({
26
- query: input,
27
- config,
28
- addItem: (_item, _timestamp) => 0,
29
- onDebugMessage: () => { },
30
- messageId: Date.now(),
31
- signal: abortController.signal,
10
+ return promptIdContext.run(prompt_id, async () => {
11
+ const consolePatcher = new ConsolePatcher({
12
+ stderr: true,
13
+ debugMode: config.getDebugMode(),
32
14
  });
33
- if (!shouldProceed || !processedQuery) {
34
- // An error occurred during @include processing (e.g., file not found).
35
- // The error message is already logged by handleAtCommand.
36
- throw new FatalInputError('Exiting due to an error processing the @ command.');
37
- }
38
- let currentMessages = [
39
- { role: 'user', parts: processedQuery },
40
- ];
41
- let turnCount = 0;
42
- while (true) {
43
- turnCount++;
44
- if (config.getMaxSessionTurns() >= 0 &&
45
- turnCount > config.getMaxSessionTurns()) {
46
- throw new FatalTurnLimitedError('Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json.');
47
- }
48
- const toolCallRequests = [];
49
- const responseStream = geminiClient.sendMessageStream(currentMessages[0]?.parts || [], abortController.signal, prompt_id);
50
- for await (const event of responseStream) {
51
- if (abortController.signal.aborted) {
52
- console.error('Operation cancelled.');
53
- return;
54
- }
55
- if (event.type === GeminiEventType.Content) {
56
- process.stdout.write(event.value);
57
- }
58
- else if (event.type === GeminiEventType.ToolCallRequest) {
59
- toolCallRequests.push(event.value);
15
+ try {
16
+ consolePatcher.patch();
17
+ // Handle EPIPE errors when the output is piped to a command that closes early.
18
+ process.stdout.on('error', (err) => {
19
+ if (err.code === 'EPIPE') {
20
+ // Exit gracefully if the pipe is closed.
21
+ process.exit(0);
60
22
  }
23
+ });
24
+ const geminiClient = config.getGeminiClient();
25
+ const abortController = new AbortController();
26
+ const { processedQuery, shouldProceed } = await handleAtCommand({
27
+ query: input,
28
+ config,
29
+ addItem: (_item, _timestamp) => 0,
30
+ onDebugMessage: () => { },
31
+ messageId: Date.now(),
32
+ signal: abortController.signal,
33
+ });
34
+ if (!shouldProceed || !processedQuery) {
35
+ // An error occurred during @include processing (e.g., file not found).
36
+ // The error message is already logged by handleAtCommand.
37
+ throw new FatalInputError('Exiting due to an error processing the @ command.');
61
38
  }
62
- if (toolCallRequests.length > 0) {
63
- const toolResponseParts = [];
64
- for (const requestInfo of toolCallRequests) {
65
- const toolResponse = await executeToolCall(config, requestInfo, abortController.signal);
66
- if (toolResponse.error) {
67
- console.error(`Error executing tool ${requestInfo.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`);
39
+ let currentMessages = [
40
+ { role: 'user', parts: processedQuery },
41
+ ];
42
+ let turnCount = 0;
43
+ while (true) {
44
+ turnCount++;
45
+ if (config.getMaxSessionTurns() >= 0 &&
46
+ turnCount > config.getMaxSessionTurns()) {
47
+ throw new FatalTurnLimitedError('Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json.');
48
+ }
49
+ const toolCallRequests = [];
50
+ const responseStream = geminiClient.sendMessageStream(currentMessages[0]?.parts || [], abortController.signal, prompt_id);
51
+ for await (const event of responseStream) {
52
+ if (abortController.signal.aborted) {
53
+ console.error('Operation cancelled.');
54
+ return;
68
55
  }
69
- if (toolResponse.responseParts) {
70
- toolResponseParts.push(...toolResponse.responseParts);
56
+ if (event.type === GeminiEventType.Content) {
57
+ process.stdout.write(event.value);
58
+ }
59
+ else if (event.type === GeminiEventType.ToolCallRequest) {
60
+ toolCallRequests.push(event.value);
71
61
  }
72
62
  }
73
- currentMessages = [{ role: 'user', parts: toolResponseParts }];
74
- }
75
- else {
76
- process.stdout.write('\n'); // Ensure a final newline
77
- return;
63
+ if (toolCallRequests.length > 0) {
64
+ const toolResponseParts = [];
65
+ for (const requestInfo of toolCallRequests) {
66
+ const toolResponse = await executeToolCall(config, requestInfo, abortController.signal);
67
+ if (toolResponse.error) {
68
+ console.error(`Error executing tool ${requestInfo.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`);
69
+ }
70
+ if (toolResponse.responseParts) {
71
+ toolResponseParts.push(...toolResponse.responseParts);
72
+ }
73
+ }
74
+ currentMessages = [{ role: 'user', parts: toolResponseParts }];
75
+ }
76
+ else {
77
+ process.stdout.write('\n'); // Ensure a final newline
78
+ return;
79
+ }
78
80
  }
79
81
  }
80
- }
81
- catch (error) {
82
- console.error(parseAndFormatApiError(error, config.getContentGeneratorConfig()?.authType));
83
- throw error;
84
- }
85
- finally {
86
- consolePatcher.cleanup();
87
- if (isTelemetrySdkInitialized()) {
88
- await shutdownTelemetry(config);
82
+ catch (error) {
83
+ console.error(parseAndFormatApiError(error, config.getContentGeneratorConfig()?.authType));
84
+ throw error;
85
+ }
86
+ finally {
87
+ consolePatcher.cleanup();
88
+ if (isTelemetrySdkInitialized()) {
89
+ await shutdownTelemetry(config);
90
+ }
89
91
  }
90
- }
92
+ });
91
93
  }
92
94
  //# sourceMappingURL=nonInteractiveCli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nonInteractiveCli.js","sourceRoot":"","sources":["../../src/nonInteractiveCli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nonInteractiveCli.js","sourceRoot":"","sources":["../../src/nonInteractiveCli.ts"],"names":[],"mappings":"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"}
@@ -13,13 +13,14 @@ import { UIActionsContext, } from './contexts/UIActionsContext.js';
13
13
  import { ConfigContext } from './contexts/ConfigContext.js';
14
14
  import { ToolCallStatus, AuthState, } from './types.js';
15
15
  import { MessageType, StreamingState } from './types.js';
16
- import { IdeClient, ideContext, getErrorMessage, getAllGeminiMdFilenames, UserTierId, AuthType, isProQuotaExceededError, isGenericQuotaExceededError, logFlashFallback, FlashFallbackEvent, clearCachedCredentialFile, } from '@google/gemini-cli-core';
16
+ import { DEFAULT_GEMINI_FLASH_MODEL, IdeClient, ideContext, getErrorMessage, getAllGeminiMdFilenames, AuthType, clearCachedCredentialFile, } from '@google/gemini-cli-core';
17
17
  import { validateAuthMethod } from '../config/auth.js';
18
18
  import { loadHierarchicalGeminiMemory } from '../config/config.js';
19
19
  import process from 'node:process';
20
20
  import { useHistory } from './hooks/useHistoryManager.js';
21
21
  import { useThemeCommand } from './hooks/useThemeCommand.js';
22
22
  import { useAuthCommand } from './auth/useAuth.js';
23
+ import { useQuotaAndFallback } from './hooks/useQuotaAndFallback.js';
23
24
  import { useEditorSettings } from './hooks/useEditorSettings.js';
24
25
  import { useSettingsCommand } from './hooks/useSettingsCommand.js';
25
26
  import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
@@ -77,10 +78,16 @@ export const AppContainer = (props) => {
77
78
  const [historyRemountKey, setHistoryRemountKey] = useState(0);
78
79
  const [updateInfo, setUpdateInfo] = useState(null);
79
80
  const [isTrustedFolder, setIsTrustedFolder] = useState(config.isTrustedFolder());
80
- const [currentModel, setCurrentModel] = useState(config.getModel());
81
+ // Helper to determine the effective model, considering the fallback state.
82
+ const getEffectiveModel = useCallback(() => {
83
+ if (config.isInFallbackMode()) {
84
+ return DEFAULT_GEMINI_FLASH_MODEL;
85
+ }
86
+ return config.getModel();
87
+ }, [config]);
88
+ const [currentModel, setCurrentModel] = useState(getEffectiveModel());
81
89
  const [userTier, setUserTier] = useState(undefined);
82
- const [isProQuotaDialogOpen, setIsProQuotaDialogOpen] = useState(false);
83
- const [proQuotaDialogResolver, setProQuotaDialogResolver] = useState(null);
90
+ const [isConfigInitialized, setConfigInitialized] = useState(false);
84
91
  // Auto-accept indicator
85
92
  const showAutoAcceptIndicator = useAutoAcceptIndicator({
86
93
  config,
@@ -99,28 +106,30 @@ export const AppContainer = (props) => {
99
106
  const mainControlsRef = useRef(null);
100
107
  const staticExtraHeight = 3;
101
108
  useEffect(() => {
109
+ (async () => {
110
+ // Note: the program will not work if this fails so let errors be
111
+ // handled by the global catch.
112
+ await config.initialize();
113
+ setConfigInitialized(true);
114
+ })();
102
115
  registerCleanup(async () => {
103
116
  const ideClient = await IdeClient.getInstance();
104
117
  await ideClient.disconnect();
105
118
  });
106
119
  }, [config]);
107
- useEffect(() => {
108
- const cleanup = setUpdateHandler(historyManager.addItem, setUpdateInfo);
109
- return cleanup;
110
- }, [historyManager.addItem]);
120
+ useEffect(() => setUpdateHandler(historyManager.addItem, setUpdateInfo), [historyManager.addItem]);
111
121
  // Watch for model changes (e.g., from Flash fallback)
112
122
  useEffect(() => {
113
123
  const checkModelChange = () => {
114
- const configModel = config.getModel();
115
- if (configModel !== currentModel) {
116
- setCurrentModel(configModel);
124
+ const effectiveModel = getEffectiveModel();
125
+ if (effectiveModel !== currentModel) {
126
+ setCurrentModel(effectiveModel);
117
127
  }
118
128
  };
119
- // Check immediately and then periodically
120
129
  checkModelChange();
121
130
  const interval = setInterval(checkModelChange, 1000); // Check every second
122
131
  return () => clearInterval(interval);
123
- }, [config, currentModel]);
132
+ }, [config, currentModel, getEffectiveModel]);
124
133
  const { consoleMessages, handleNewMessage, clearConsoleMessages: clearConsoleMessagesState, } = useConsoleMessages();
125
134
  useEffect(() => {
126
135
  const consolePatcher = new ConsolePatcher({
@@ -183,6 +192,13 @@ export const AppContainer = (props) => {
183
192
  }, [setHistoryRemountKey, stdout]);
184
193
  const { isThemeDialogOpen, openThemeDialog, handleThemeSelect, handleThemeHighlight, } = useThemeCommand(settings, setThemeError, historyManager.addItem, initializationResult.themeError);
185
194
  const { authState, setAuthState, authError, onAuthError } = useAuthCommand(settings, config);
195
+ const { proQuotaRequest, handleProQuotaChoice } = useQuotaAndFallback({
196
+ config,
197
+ historyManager,
198
+ userTier,
199
+ setAuthState,
200
+ setModelSwitchedFromQuotaError,
201
+ });
186
202
  // Derive auth state variables for backward compatibility with UIStateContext
187
203
  const isAuthDialogOpen = authState === AuthState.Updating;
188
204
  const isAuthenticating = authState === AuthState.Unauthenticated;
@@ -303,108 +319,10 @@ Logging in with Google... Please restart Gemini CLI to continue.
303
319
  console.error('Error refreshing memory:', error);
304
320
  }
305
321
  }, [config, historyManager, settings.merged]);
306
- // Set up Flash fallback handler
307
- useEffect(() => {
308
- const flashFallbackHandler = async (currentModel, fallbackModel, error) => {
309
- // Check if we've already switched to the fallback model
310
- if (config.isInFallbackMode()) {
311
- // If we're already in fallback mode, don't show the dialog again
312
- return false;
313
- }
314
- let message;
315
- if (config.getContentGeneratorConfig().authType ===
316
- AuthType.LOGIN_WITH_GOOGLE) {
317
- // Use actual user tier if available; otherwise, default to FREE tier behavior (safe default)
318
- const isPaidTier = userTier === UserTierId.LEGACY || userTier === UserTierId.STANDARD;
319
- // Check if this is a Pro quota exceeded error
320
- if (error && isProQuotaExceededError(error)) {
321
- if (isPaidTier) {
322
- message = `⚡ You have reached your daily ${currentModel} quota limit.
323
- ⚡ You can choose to authenticate with a paid API key or continue with the fallback model.
324
- ⚡ 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`;
325
- }
326
- else {
327
- message = `⚡ You have reached your daily ${currentModel} quota limit.
328
- ⚡ You can choose to authenticate with a paid API key or continue with the fallback model.
329
- ⚡ 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
330
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
331
- ⚡ You can switch authentication methods by typing /auth`;
332
- }
333
- }
334
- else if (error && isGenericQuotaExceededError(error)) {
335
- if (isPaidTier) {
336
- message = `⚡ You have reached your daily quota limit.
337
- ⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
338
- ⚡ 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`;
339
- }
340
- else {
341
- message = `⚡ You have reached your daily quota limit.
342
- ⚡ Automatically switching from ${currentModel} to ${fallbackModel} for the remainder of this session.
343
- ⚡ 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
344
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
345
- ⚡ You can switch authentication methods by typing /auth`;
346
- }
347
- }
348
- else {
349
- if (isPaidTier) {
350
- // Default fallback message for other cases (like consecutive 429s)
351
- message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
352
- ⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
353
- ⚡ 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`;
354
- }
355
- else {
356
- // Default fallback message for other cases (like consecutive 429s)
357
- message = `⚡ Automatically switching from ${currentModel} to ${fallbackModel} for faster responses for the remainder of this session.
358
- ⚡ Possible reasons for this are that you have received multiple consecutive capacity errors or you have reached your daily ${currentModel} quota limit
359
- ⚡ 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
360
- ⚡ Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
361
- ⚡ You can switch authentication methods by typing /auth`;
362
- }
363
- }
364
- // Add message to UI history
365
- historyManager.addItem({
366
- type: MessageType.INFO,
367
- text: message,
368
- }, Date.now());
369
- // For Pro quota errors, show the dialog and wait for user's choice
370
- if (error && isProQuotaExceededError(error)) {
371
- // Set the flag to prevent tool continuation
372
- setModelSwitchedFromQuotaError(true);
373
- // Set global quota error flag to prevent Flash model calls
374
- config.setQuotaErrorOccurred(true);
375
- // Show the ProQuotaDialog and wait for user's choice
376
- const shouldContinueWithFallback = await new Promise((resolve) => {
377
- setIsProQuotaDialogOpen(true);
378
- setProQuotaDialogResolver(() => resolve);
379
- });
380
- // If user chose to continue with fallback, we don't need to stop the current prompt
381
- if (shouldContinueWithFallback) {
382
- // Switch to fallback model for future use
383
- config.setModel(fallbackModel);
384
- config.setFallbackMode(true);
385
- logFlashFallback(config, new FlashFallbackEvent(config.getContentGeneratorConfig().authType));
386
- return true; // Continue with current prompt using fallback model
387
- }
388
- // If user chose to authenticate, stop current prompt
389
- return false;
390
- }
391
- // For other quota errors, automatically switch to fallback model
392
- // Set the flag to prevent tool continuation
393
- setModelSwitchedFromQuotaError(true);
394
- // Set global quota error flag to prevent Flash model calls
395
- config.setQuotaErrorOccurred(true);
396
- }
397
- // Switch model for future use but return false to stop current retry
398
- config.setModel(fallbackModel);
399
- config.setFallbackMode(true);
400
- logFlashFallback(config, new FlashFallbackEvent(config.getContentGeneratorConfig().authType));
401
- return false; // Don't continue with current prompt
402
- };
403
- config.setFlashFallbackHandler(flashFallbackHandler);
404
- }, [config, historyManager, userTier]);
405
322
  const cancelHandlerRef = useRef(() => { });
406
323
  const { streamingState, submitQuery, initError, pendingHistoryItems: pendingGeminiHistoryItems, thought, cancelOngoingRequest, } = useGeminiStream(config.getGeminiClient(), historyManager.history, historyManager.addItem, config, settings, setDebugMessage, handleSlashCommand, shellModeActive, () => settings.merged.general?.preferredEditor, onAuthError, performMemoryRefresh, modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError, refreshStatic, () => cancelHandlerRef.current());
407
324
  const { messageQueue, addMessage, clearQueue, getQueuedMessagesText } = useMessageQueue({
325
+ isConfigInitialized,
408
326
  streamingState,
409
327
  submitQuery,
410
328
  });
@@ -444,19 +362,6 @@ Logging in with Google... Please restart Gemini CLI to continue.
444
362
  console.clear();
445
363
  refreshStatic();
446
364
  }, [historyManager, clearConsoleMessagesState, refreshStatic]);
447
- const handleProQuotaChoice = useCallback((choice) => {
448
- setIsProQuotaDialogOpen(false);
449
- if (proQuotaDialogResolver) {
450
- if (choice === 'auth') {
451
- proQuotaDialogResolver(false); // Don't continue with fallback, show auth dialog
452
- setAuthState(AuthState.Updating);
453
- }
454
- else {
455
- proQuotaDialogResolver(true); // Continue with fallback model
456
- }
457
- setProQuotaDialogResolver(null);
458
- }
459
- }, [proQuotaDialogResolver, setAuthState]);
460
365
  const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
461
366
  /**
462
367
  * Determines if the input prompt should be active and accept user input.
@@ -470,7 +375,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
470
375
  !isProcessing &&
471
376
  (streamingState === StreamingState.Idle ||
472
377
  streamingState === StreamingState.Responding) &&
473
- !isProQuotaDialogOpen;
378
+ !proQuotaRequest;
474
379
  // Compute available terminal height based on controls measurement
475
380
  const availableTerminalHeight = useMemo(() => {
476
381
  if (mainControlsRef.current) {
@@ -496,6 +401,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
496
401
  const geminiClient = config.getGeminiClient();
497
402
  useEffect(() => {
498
403
  if (initialPrompt &&
404
+ isConfigInitialized &&
499
405
  !initialPromptSubmitted.current &&
500
406
  !isAuthenticating &&
501
407
  !isAuthDialogOpen &&
@@ -508,6 +414,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
508
414
  }
509
415
  }, [
510
416
  initialPrompt,
417
+ isConfigInitialized,
511
418
  handleFinalSubmit,
512
419
  isAuthenticating,
513
420
  isAuthDialogOpen,
@@ -540,7 +447,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
540
447
  const [ideContextState, setIdeContextState] = useState();
541
448
  const [showEscapePrompt, setShowEscapePrompt] = useState(false);
542
449
  const [showIdeRestartPrompt, setShowIdeRestartPrompt] = useState(false);
543
- const { isFolderTrustDialogOpen, handleFolderTrustSelect, isRestarting } = useFolderTrust(settings, config, setIsTrustedFolder);
450
+ const { isFolderTrustDialogOpen, handleFolderTrustSelect, isRestarting } = useFolderTrust(settings, setIsTrustedFolder, refreshStatic);
544
451
  const { needsRestart: ideNeedsRestart } = useIdeTrustListener();
545
452
  const isInitialMount = useRef(true);
546
453
  useEffect(() => {
@@ -719,7 +626,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
719
626
  isAuthDialogOpen ||
720
627
  isEditorDialogOpen ||
721
628
  showPrivacyNotice ||
722
- isProQuotaDialogOpen, [
629
+ !!proQuotaRequest, [
723
630
  showWorkspaceMigrationDialog,
724
631
  shouldShowIdePrompt,
725
632
  isFolderTrustDialogOpen,
@@ -731,7 +638,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
731
638
  isAuthDialogOpen,
732
639
  isEditorDialogOpen,
733
640
  showPrivacyNotice,
734
- isProQuotaDialogOpen,
641
+ proQuotaRequest,
735
642
  ]);
736
643
  const pendingHistoryItems = useMemo(() => [...pendingSlashCommandHistoryItems, ...pendingGeminiHistoryItems], [pendingSlashCommandHistoryItems, pendingGeminiHistoryItems]);
737
644
  const uiState = useMemo(() => ({
@@ -739,6 +646,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
739
646
  isThemeDialogOpen,
740
647
  themeError,
741
648
  isAuthenticating,
649
+ isConfigInitialized,
742
650
  authError,
743
651
  isAuthDialogOpen,
744
652
  editorError,
@@ -783,11 +691,9 @@ Logging in with Google... Please restart Gemini CLI to continue.
783
691
  showAutoAcceptIndicator,
784
692
  showWorkspaceMigrationDialog,
785
693
  workspaceExtensions,
786
- // Use current state values instead of config.getModel()
787
694
  currentModel,
788
695
  userTier,
789
- isProQuotaDialogOpen,
790
- // New fields
696
+ proQuotaRequest,
791
697
  contextFileNames,
792
698
  errorCount,
793
699
  availableTerminalHeight,
@@ -811,6 +717,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
811
717
  isThemeDialogOpen,
812
718
  themeError,
813
719
  isAuthenticating,
720
+ isConfigInitialized,
814
721
  authError,
815
722
  isAuthDialogOpen,
816
723
  editorError,
@@ -855,10 +762,8 @@ Logging in with Google... Please restart Gemini CLI to continue.
855
762
  showAutoAcceptIndicator,
856
763
  showWorkspaceMigrationDialog,
857
764
  workspaceExtensions,
858
- // Quota-related state dependencies
859
765
  userTier,
860
- isProQuotaDialogOpen,
861
- // New fields dependencies
766
+ proQuotaRequest,
862
767
  contextFileNames,
863
768
  errorCount,
864
769
  availableTerminalHeight,
@@ -877,7 +782,6 @@ Logging in with Google... Please restart Gemini CLI to continue.
877
782
  updateInfo,
878
783
  showIdeRestartPrompt,
879
784
  isRestarting,
880
- // Quota-related dependencies
881
785
  currentModel,
882
786
  ]);
883
787
  const uiActions = useMemo(() => ({