mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-17 01:21:10 -07:00
feat(ui): Add confirmation dialog for disabling loop detection for current session (#8231)
This commit is contained in:
@@ -186,6 +186,10 @@ export class GeminiClient {
|
||||
return this.chat?.getChatRecordingService();
|
||||
}
|
||||
|
||||
getLoopDetectionService(): LoopDetectionService {
|
||||
return this.loopDetector;
|
||||
}
|
||||
|
||||
async addDirectoryContext(): Promise<void> {
|
||||
if (!this.chat) {
|
||||
return;
|
||||
|
||||
@@ -130,6 +130,15 @@ describe('LoopDetectionService', () => {
|
||||
expect(service.addAndCheck(toolCallEvent)).toBe(true);
|
||||
expect(loggers.logLoopDetected).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not detect a loop when disabled for session', () => {
|
||||
service.disableForSession();
|
||||
const event = createToolCallRequestEvent('testTool', { param: 'value' });
|
||||
for (let i = 0; i < TOOL_CALL_LOOP_THRESHOLD; i++) {
|
||||
expect(service.addAndCheck(event)).toBe(false);
|
||||
}
|
||||
expect(loggers.logLoopDetected).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Content Loop Detection', () => {
|
||||
@@ -719,4 +728,12 @@ describe('LoopDetectionService LLM Checks', () => {
|
||||
expect(result).toBe(false);
|
||||
expect(loggers.logLoopDetected).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not trigger LLM check when disabled for session', async () => {
|
||||
service.disableForSession();
|
||||
await advanceTurns(30);
|
||||
const result = await service.turnStarted(abortController.signal);
|
||||
expect(result).toBe(false);
|
||||
expect(mockGeminiClient.generateJson).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,10 +74,20 @@ export class LoopDetectionService {
|
||||
private llmCheckInterval = DEFAULT_LLM_CHECK_INTERVAL;
|
||||
private lastCheckTurn = 0;
|
||||
|
||||
// Session-level disable flag
|
||||
private disabledForSession = false;
|
||||
|
||||
constructor(config: Config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables loop detection for the current session.
|
||||
*/
|
||||
disableForSession(): void {
|
||||
this.disabledForSession = true;
|
||||
}
|
||||
|
||||
private getToolCallKey(toolCall: { name: string; args: object }): string {
|
||||
const argsString = JSON.stringify(toolCall.args);
|
||||
const keyString = `${toolCall.name}:${argsString}`;
|
||||
@@ -90,8 +100,8 @@ export class LoopDetectionService {
|
||||
* @returns true if a loop is detected, false otherwise
|
||||
*/
|
||||
addAndCheck(event: ServerGeminiStreamEvent): boolean {
|
||||
if (this.loopDetected) {
|
||||
return true;
|
||||
if (this.loopDetected || this.disabledForSession) {
|
||||
return this.loopDetected;
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
@@ -121,6 +131,9 @@ export class LoopDetectionService {
|
||||
* @returns A promise that resolves to `true` if a loop is detected, and `false` otherwise.
|
||||
*/
|
||||
async turnStarted(signal: AbortSignal) {
|
||||
if (this.disabledForSession) {
|
||||
return false;
|
||||
}
|
||||
this.turnsInCurrentPrompt++;
|
||||
|
||||
if (
|
||||
|
||||
Reference in New Issue
Block a user