mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-18 10:01:29 -07:00
feat(core): add setting to disable loop detection (#18008)
This commit is contained in:
@@ -393,6 +393,7 @@ export interface ConfigParameters {
|
||||
includeDirectories?: string[];
|
||||
bugCommand?: BugCommandSettings;
|
||||
model: string;
|
||||
disableLoopDetection?: boolean;
|
||||
maxSessionTurns?: number;
|
||||
experimentalZedIntegration?: boolean;
|
||||
listSessions?: boolean;
|
||||
@@ -531,6 +532,7 @@ export class Config {
|
||||
private readonly cwd: string;
|
||||
private readonly bugCommand: BugCommandSettings | undefined;
|
||||
private model: string;
|
||||
private readonly disableLoopDetection: boolean;
|
||||
private previewFeatures: boolean | undefined;
|
||||
private hasAccessToPreviewModel: boolean = false;
|
||||
private readonly noBrowser: boolean;
|
||||
@@ -697,6 +699,7 @@ export class Config {
|
||||
this.fileDiscoveryService = params.fileDiscoveryService ?? null;
|
||||
this.bugCommand = params.bugCommand;
|
||||
this.model = params.model;
|
||||
this.disableLoopDetection = params.disableLoopDetection ?? false;
|
||||
this._activeModel = params.model;
|
||||
this.enableAgents = params.enableAgents ?? false;
|
||||
this.agents = params.agents ?? {};
|
||||
@@ -1118,6 +1121,10 @@ export class Config {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
getDisableLoopDetection(): boolean {
|
||||
return this.disableLoopDetection ?? false;
|
||||
}
|
||||
|
||||
setModel(newModel: string, isTemporary: boolean = true): void {
|
||||
if (this.model !== newModel || this._activeModel !== newModel) {
|
||||
this.model = newModel;
|
||||
|
||||
@@ -213,6 +213,7 @@ describe('Gemini Client (client.ts)', () => {
|
||||
getGlobalMemory: vi.fn().mockReturnValue(''),
|
||||
getEnvironmentMemory: vi.fn().mockReturnValue(''),
|
||||
isJitContextEnabled: vi.fn().mockReturnValue(false),
|
||||
getDisableLoopDetection: vi.fn().mockReturnValue(false),
|
||||
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getProxy: vi.fn().mockReturnValue(undefined),
|
||||
|
||||
@@ -38,6 +38,7 @@ describe('LoopDetectionService', () => {
|
||||
mockConfig = {
|
||||
getTelemetryEnabled: () => true,
|
||||
isInteractive: () => false,
|
||||
getDisableLoopDetection: () => false,
|
||||
getModelAvailabilityService: vi
|
||||
.fn()
|
||||
.mockReturnValue(createAvailabilityServiceMock()),
|
||||
@@ -162,6 +163,15 @@ describe('LoopDetectionService', () => {
|
||||
// Should now return false even though a loop was previously detected
|
||||
expect(service.addAndCheck(event)).toBe(false);
|
||||
});
|
||||
|
||||
it('should skip loop detection if disabled in config', () => {
|
||||
vi.spyOn(mockConfig, 'getDisableLoopDetection').mockReturnValue(true);
|
||||
const event = createToolCallRequestEvent('testTool', { param: 'value' });
|
||||
for (let i = 0; i < TOOL_CALL_LOOP_THRESHOLD + 2; i++) {
|
||||
expect(service.addAndCheck(event)).toBe(false);
|
||||
}
|
||||
expect(loggers.logLoopDetected).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Content Loop Detection', () => {
|
||||
@@ -742,6 +752,7 @@ describe('LoopDetectionService LLM Checks', () => {
|
||||
mockConfig = {
|
||||
getGeminiClient: () => mockGeminiClient,
|
||||
getBaseLlmClient: () => mockBaseLlmClient,
|
||||
getDisableLoopDetection: () => false,
|
||||
getDebugMode: () => false,
|
||||
getTelemetryEnabled: () => true,
|
||||
getModel: vi.fn().mockReturnValue('cognitive-loop-v1'),
|
||||
|
||||
@@ -147,7 +147,7 @@ export class LoopDetectionService {
|
||||
* @returns true if a loop is detected, false otherwise
|
||||
*/
|
||||
addAndCheck(event: ServerGeminiStreamEvent): boolean {
|
||||
if (this.disabledForSession) {
|
||||
if (this.disabledForSession || this.config.getDisableLoopDetection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ 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) {
|
||||
if (this.disabledForSession || this.config.getDisableLoopDetection()) {
|
||||
return false;
|
||||
}
|
||||
this.turnsInCurrentPrompt++;
|
||||
|
||||
Reference in New Issue
Block a user