mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-15 16:41:11 -07:00
feat(ui): Add confirmation dialog for disabling loop detection for current session (#8231)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
import { Box, Text } from 'ink';
|
||||
import { IdeIntegrationNudge } from '../IdeIntegrationNudge.js';
|
||||
import { LoopDetectionConfirmation } from './LoopDetectionConfirmation.js';
|
||||
import { FolderTrustDialog } from './FolderTrustDialog.js';
|
||||
import { ShellConfirmationDialog } from './ShellConfirmationDialog.js';
|
||||
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
|
||||
@@ -83,6 +84,13 @@ export const DialogManager = () => {
|
||||
<ShellConfirmationDialog request={uiState.shellConfirmationRequest} />
|
||||
);
|
||||
}
|
||||
if (uiState.loopDetectionConfirmationRequest) {
|
||||
return (
|
||||
<LoopDetectionConfirmation
|
||||
onComplete={uiState.loopDetectionConfirmationRequest.onComplete}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (uiState.confirmationRequest) {
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { renderWithProviders } from '../../test-utils/render.js';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { LoopDetectionConfirmation } from './LoopDetectionConfirmation.js';
|
||||
|
||||
describe('LoopDetectionConfirmation', () => {
|
||||
const onComplete = vi.fn();
|
||||
|
||||
it('renders correctly', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<LoopDetectionConfirmation onComplete={onComplete} />,
|
||||
);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('contains the expected options', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<LoopDetectionConfirmation onComplete={onComplete} />,
|
||||
);
|
||||
const output = lastFrame()!.toString();
|
||||
|
||||
expect(output).toContain('A potential loop was detected');
|
||||
expect(output).toContain('Keep loop detection enabled (esc)');
|
||||
expect(output).toContain('Disable loop detection for this session');
|
||||
expect(output).toContain(
|
||||
'This can happen due to repetitive tool calls or other model behavior',
|
||||
);
|
||||
});
|
||||
});
|
||||
88
packages/cli/src/ui/components/LoopDetectionConfirmation.tsx
Normal file
88
packages/cli/src/ui/components/LoopDetectionConfirmation.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { Box, Text } from 'ink';
|
||||
import type { RadioSelectItem } from './shared/RadioButtonSelect.js';
|
||||
import { RadioButtonSelect } from './shared/RadioButtonSelect.js';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
|
||||
export type LoopDetectionConfirmationResult = {
|
||||
userSelection: 'disable' | 'keep';
|
||||
};
|
||||
|
||||
interface LoopDetectionConfirmationProps {
|
||||
onComplete: (result: LoopDetectionConfirmationResult) => void;
|
||||
}
|
||||
|
||||
export function LoopDetectionConfirmation({
|
||||
onComplete,
|
||||
}: LoopDetectionConfirmationProps) {
|
||||
useKeypress(
|
||||
(key) => {
|
||||
if (key.name === 'escape') {
|
||||
onComplete({
|
||||
userSelection: 'keep',
|
||||
});
|
||||
}
|
||||
},
|
||||
{ isActive: true },
|
||||
);
|
||||
|
||||
const OPTIONS: Array<RadioSelectItem<LoopDetectionConfirmationResult>> = [
|
||||
{
|
||||
label: 'Keep loop detection enabled (esc)',
|
||||
value: {
|
||||
userSelection: 'keep',
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Disable loop detection for this session',
|
||||
value: {
|
||||
userSelection: 'disable',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Box
|
||||
flexDirection="column"
|
||||
borderStyle="round"
|
||||
borderColor={theme.status.warning}
|
||||
width="100%"
|
||||
marginLeft={1}
|
||||
>
|
||||
<Box paddingX={1} paddingY={0} flexDirection="column">
|
||||
<Box minHeight={1}>
|
||||
<Box minWidth={3}>
|
||||
<Text color={theme.status.warning} aria-label="Loop detected:">
|
||||
?
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text wrap="truncate-end">
|
||||
<Text color={theme.text.primary} bold>
|
||||
A potential loop was detected
|
||||
</Text>{' '}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box width="100%" marginTop={1}>
|
||||
<Box flexDirection="column">
|
||||
<Text color={theme.text.secondary}>
|
||||
This can happen due to repetitive tool calls or other model
|
||||
behavior. Do you want to keep loop detection enabled or disable it
|
||||
for this session?
|
||||
</Text>
|
||||
<Box marginTop={1}>
|
||||
<RadioButtonSelect items={OPTIONS} onSelect={onComplete} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`LoopDetectionConfirmation > renders correctly 1`] = `
|
||||
" ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? A potential loop was detected │
|
||||
│ │
|
||||
│ This can happen due to repetitive tool calls or other model behavior. Do you want to keep loop │
|
||||
│ detection enabled or disable it for this session? │
|
||||
│ │
|
||||
│ ● 1. Keep loop detection enabled (esc) │
|
||||
│ 2. Disable loop detection for this session │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
Reference in New Issue
Block a user