summaryrefslogtreecommitdiff
path: root/packages/core/src/services/loopDetectionService.ts
diff options
context:
space:
mode:
authorSandy Tao <[email protected]>2025-07-29 21:05:03 -0700
committerGitHub <[email protected]>2025-07-30 04:05:03 +0000
commit8985e489a5fd5251f3b41fe358797d7a2e90ac6a (patch)
tree85489970648f86806fcde5e389b6b4ea9fd5fb31 /packages/core/src/services/loopDetectionService.ts
parent0ce89392b8d4b6a4af4eef132ac5ae6de86ac25e (diff)
Skip and reset loop checking around code blocks (#5144)
Diffstat (limited to 'packages/core/src/services/loopDetectionService.ts')
-rw-r--r--packages/core/src/services/loopDetectionService.ts20
1 files changed, 20 insertions, 0 deletions
diff --git a/packages/core/src/services/loopDetectionService.ts b/packages/core/src/services/loopDetectionService.ts
index 7b3da20b..f71b8434 100644
--- a/packages/core/src/services/loopDetectionService.ts
+++ b/packages/core/src/services/loopDetectionService.ts
@@ -61,6 +61,7 @@ export class LoopDetectionService {
private contentStats = new Map<string, number[]>();
private lastContentIndex = 0;
private loopDetected = false;
+ private inCodeBlock = false;
// LLM loop track tracking
private turnsInCurrentPrompt = 0;
@@ -156,8 +157,27 @@ export class LoopDetectionService {
* 2. Truncating history if it exceeds the maximum length
* 3. Analyzing content chunks for repetitive patterns using hashing
* 4. Detecting loops when identical chunks appear frequently within a short distance
+ * 5. Disabling loop detection within code blocks to prevent false positives,
+ * as repetitive code structures are common and not necessarily loops.
*/
private checkContentLoop(content: string): boolean {
+ // Code blocks can often contain repetitive syntax that is not indicative of a loop.
+ // To avoid false positives, we detect when we are inside a code block and
+ // temporarily disable loop detection.
+ const numFences = (content.match(/```/g) ?? []).length;
+ if (numFences) {
+ // Reset tracking when a code fence is detected to avoid analyzing content
+ // that spans across code block boundaries.
+ this.resetContentTracking();
+ }
+
+ const wasInCodeBlock = this.inCodeBlock;
+ this.inCodeBlock =
+ numFences % 2 === 0 ? this.inCodeBlock : !this.inCodeBlock;
+ if (wasInCodeBlock) {
+ return false;
+ }
+
this.streamContentHistory += content;
this.truncateAndUpdate();