diff --git a/packages/core/src/services/loopDetectionService.test.ts b/packages/core/src/services/loopDetectionService.test.ts index f579ba3273..27a9d4e936 100644 --- a/packages/core/src/services/loopDetectionService.test.ts +++ b/packages/core/src/services/loopDetectionService.test.ts @@ -558,6 +558,30 @@ describe('LoopDetectionService', () => { }); }); + describe('Divider Content Detection', () => { + it('should not detect a loop for repeating divider-like content', () => { + service.reset(''); + const dividerContent = '-'.repeat(CONTENT_CHUNK_SIZE); + let isLoop = false; + for (let i = 0; i < CONTENT_LOOP_THRESHOLD + 5; i++) { + isLoop = service.addAndCheck(createContentEvent(dividerContent)); + expect(isLoop).toBe(false); + } + expect(loggers.logLoopDetected).not.toHaveBeenCalled(); + }); + + it('should not detect a loop for repeating complex box-drawing dividers', () => { + service.reset(''); + const dividerContent = '╭─'.repeat(CONTENT_CHUNK_SIZE / 2); + let isLoop = false; + for (let i = 0; i < CONTENT_LOOP_THRESHOLD + 5; i++) { + isLoop = service.addAndCheck(createContentEvent(dividerContent)); + expect(isLoop).toBe(false); + } + expect(loggers.logLoopDetected).not.toHaveBeenCalled(); + }); + }); + describe('Reset Functionality', () => { it('tool call should reset content count', () => { const contentEvent = createContentEvent('Some content.'); diff --git a/packages/core/src/services/loopDetectionService.ts b/packages/core/src/services/loopDetectionService.ts index 8e94ac69fc..967e9a4c64 100644 --- a/packages/core/src/services/loopDetectionService.ts +++ b/packages/core/src/services/loopDetectionService.ts @@ -169,8 +169,16 @@ export class LoopDetectionService { /(^|\n)\s*[*-+]\s/.test(content) || /(^|\n)\s*\d+\.\s/.test(content); const hasHeading = /(^|\n)#+\s/.test(content); const hasBlockquote = /(^|\n)>\s/.test(content); + const isDivider = /^[+-_=*\u2500-\u257F]+$/.test(content); - if (numFences || hasTable || hasListItem || hasHeading || hasBlockquote) { + if ( + numFences || + hasTable || + hasListItem || + hasHeading || + hasBlockquote || + isDivider + ) { // Reset tracking when different content elements are detected to avoid analyzing content // that spans across different element boundaries. this.resetContentTracking(); @@ -179,7 +187,7 @@ export class LoopDetectionService { const wasInCodeBlock = this.inCodeBlock; this.inCodeBlock = numFences % 2 === 0 ? this.inCodeBlock : !this.inCodeBlock; - if (wasInCodeBlock || this.inCodeBlock) { + if (wasInCodeBlock || this.inCodeBlock || isDivider) { return false; }