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
This commit is contained in:
parent
782686bcf3
commit
a588d5cd10
|
@ -25,7 +25,8 @@ export const ToolMessage: React.FC<IndividualToolCallDisplay> = ({
|
||||||
<Box minHeight={1}>
|
<Box minHeight={1}>
|
||||||
{/* Status Indicator */}
|
{/* Status Indicator */}
|
||||||
<Box minWidth={statusIndicatorWidth}>
|
<Box minWidth={statusIndicatorWidth}>
|
||||||
{status === ToolCallStatus.Pending && <Spinner type="dots" />}
|
{(status === ToolCallStatus.Pending ||
|
||||||
|
status === ToolCallStatus.Executing) && <Spinner type="dots" />}
|
||||||
{status === ToolCallStatus.Success && (
|
{status === ToolCallStatus.Success && (
|
||||||
<Text color={Colors.AccentGreen}>✔</Text>
|
<Text color={Colors.AccentGreen}>✔</Text>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -396,6 +396,32 @@ export const useGeminiStream = (
|
||||||
// Call the original server-side handler first
|
// Call the original server-side handler first
|
||||||
originalConfirmationDetails.onConfirm(outcome);
|
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) {
|
if (outcome === ToolConfirmationOutcome.Cancel) {
|
||||||
let resultDisplay: ToolResultDisplay | undefined;
|
let resultDisplay: ToolResultDisplay | undefined;
|
||||||
if ('fileDiff' in originalConfirmationDetails) {
|
if ('fileDiff' in originalConfirmationDetails) {
|
||||||
|
@ -470,6 +496,7 @@ export const useGeminiStream = (
|
||||||
setShowHelp,
|
setShowHelp,
|
||||||
toolRegistry,
|
toolRegistry,
|
||||||
setInitError,
|
setInitError,
|
||||||
|
refreshStatic,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ export enum ToolCallStatus {
|
||||||
Pending = 'Pending',
|
Pending = 'Pending',
|
||||||
Canceled = 'Canceled',
|
Canceled = 'Canceled',
|
||||||
Confirming = 'Confirming',
|
Confirming = 'Confirming',
|
||||||
|
Executing = 'Executing',
|
||||||
Success = 'Success',
|
Success = 'Success',
|
||||||
Error = 'Error',
|
Error = 'Error',
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue