@@ -84,7 +84,6 @@ export function createToolLoopGuard(
8484 const successFingerprint = `${ toolCall . function . name } |values:${ valueSignature } |success` ;
8585 const repeatCount = ( counts . get ( successFingerprint ) ?? 0 ) + 1 ;
8686 counts . set ( successFingerprint , repeatCount ) ;
87- const strictTriggered = repeatCount > maxRepeat ;
8887
8988 // Some tools (notably edit/write) can get stuck in "successful" loops where
9089 // the model keeps re-issuing the same operation with slightly different
@@ -101,19 +100,15 @@ export function createToolLoopGuard(
101100 if ( coarseSuccessFingerprint ) {
102101 coarseCounts . set ( coarseSuccessFingerprint , coarseRepeatCount ) ;
103102 }
104- // Coarse fingerprints are intentionally less specific; give them a slightly
105- // higher threshold to reduce false positives.
106- const coarseMaxRepeat = maxRepeat + 1 ;
107103 const coarseTriggered = coarseSuccessFingerprint
108- ? coarseRepeatCount > coarseMaxRepeat
104+ ? coarseRepeatCount > maxRepeat
109105 : false ;
110- const preferCoarseFingerprint = coarseTriggered && ! strictTriggered ;
111106 return {
112- fingerprint : preferCoarseFingerprint ? coarseSuccessFingerprint ! : successFingerprint ,
113- repeatCount : preferCoarseFingerprint ? coarseRepeatCount : repeatCount ,
114- maxRepeat : preferCoarseFingerprint ? coarseMaxRepeat : maxRepeat ,
107+ fingerprint : coarseTriggered ? coarseSuccessFingerprint ! : successFingerprint ,
108+ repeatCount : coarseTriggered ? coarseRepeatCount : repeatCount ,
109+ maxRepeat,
115110 errorClass,
116- triggered : strictTriggered || coarseTriggered ,
111+ triggered : repeatCount > maxRepeat || coarseTriggered ,
117112 tracked : true ,
118113 } ;
119114 }
0 commit comments