summaryrefslogtreecommitdiff
path: root/packages/cli/src
diff options
context:
space:
mode:
authorTaylor Mullen <[email protected]>2025-05-06 22:26:38 -0700
committerN. Taylor Mullen <[email protected]>2025-05-06 22:38:30 -0700
commita588d5cd10e71bbb99912fb4d7f43c162a2a68ba (patch)
tree3f5beee5f3981ea88312bf49f5fa2f67a5c68169 /packages/cli/src
parent782686bcf33052309db530ef5fe61c35622f7ba5 (diff)
Prevent UI hang on long tool confirmations.
Problem: When a tool confirmation dialog appeared for a potentially long-running operation (e.g., `npm install`), accepting the confirmation would cause the UI to appear to hang. The confirmation dialog would remain visible, and no further UI updates would occur until the long-running task completed. This provided a poor user experience as the application seemed unresponsive. Fix: This change addresses the issue by ensuring the UI is updated to remove the confirmation dialog *before* the long-running operation begins. It also marks the tool as executing so a spinner can be shown. Fixes https://b.corp.google.com/issues/415844994 Signed, sealed, delivered, it's yours! - Gemini, your friendly neighborhood code-slinger
Diffstat (limited to 'packages/cli/src')
-rw-r--r--packages/cli/src/ui/components/messages/ToolMessage.tsx3
-rw-r--r--packages/cli/src/ui/hooks/useGeminiStream.ts27
-rw-r--r--packages/cli/src/ui/types.ts1
3 files changed, 30 insertions, 1 deletions
diff --git a/packages/cli/src/ui/components/messages/ToolMessage.tsx b/packages/cli/src/ui/components/messages/ToolMessage.tsx
index 4d5fca37..1d8c478c 100644
--- a/packages/cli/src/ui/components/messages/ToolMessage.tsx
+++ b/packages/cli/src/ui/components/messages/ToolMessage.tsx
@@ -25,7 +25,8 @@ export const ToolMessage: React.FC<IndividualToolCallDisplay> = ({
<Box minHeight={1}>
{/* Status Indicator */}
<Box minWidth={statusIndicatorWidth}>
- {status === ToolCallStatus.Pending && <Spinner type="dots" />}
+ {(status === ToolCallStatus.Pending ||
+ status === ToolCallStatus.Executing) && <Spinner type="dots" />}
{status === ToolCallStatus.Success && (
<Text color={Colors.AccentGreen}>✔</Text>
)}
diff --git a/packages/cli/src/ui/hooks/useGeminiStream.ts b/packages/cli/src/ui/hooks/useGeminiStream.ts
index 611ea3e7..40c688a3 100644
--- a/packages/cli/src/ui/hooks/useGeminiStream.ts
+++ b/packages/cli/src/ui/hooks/useGeminiStream.ts
@@ -396,6 +396,32 @@ export const useGeminiStream = (
// Call the original server-side handler first
originalConfirmationDetails.onConfirm(outcome);
+ // Ensure UI updates before potentially long-running operations
+ if (currentToolGroupMessageId !== null) {
+ updateItem(
+ currentToolGroupMessageId,
+ (currentItem: HistoryItem) => {
+ if (currentItem?.type !== 'tool_group')
+ return currentItem as Partial<Omit<HistoryItem, 'id'>>;
+ return {
+ ...currentItem,
+ tools: (currentItem.tools || []).map((tool) =>
+ tool.callId === request.callId
+ ? {
+ ...tool,
+ confirmationDetails: undefined,
+ status: ToolCallStatus.Executing,
+ }
+ : tool,
+ ),
+ } as Partial<Omit<HistoryItem, 'id'>>;
+ },
+ );
+ refreshStatic();
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 0)); // Allow UI to re-render
+
if (outcome === ToolConfirmationOutcome.Cancel) {
let resultDisplay: ToolResultDisplay | undefined;
if ('fileDiff' in originalConfirmationDetails) {
@@ -470,6 +496,7 @@ export const useGeminiStream = (
setShowHelp,
toolRegistry,
setInitError,
+ refreshStatic,
],
);
diff --git a/packages/cli/src/ui/types.ts b/packages/cli/src/ui/types.ts
index 4e1ab9cc..d6279598 100644
--- a/packages/cli/src/ui/types.ts
+++ b/packages/cli/src/ui/types.ts
@@ -27,6 +27,7 @@ export enum ToolCallStatus {
Pending = 'Pending',
Canceled = 'Canceled',
Confirming = 'Confirming',
+ Executing = 'Executing',
Success = 'Success',
Error = 'Error',
}