diff options
Diffstat (limited to 'modules/core/module-aiassist.js')
| -rw-r--r-- | modules/core/module-aiassist.js | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index 9c9b1ca..caf6d99 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -765,6 +765,7 @@ buildSystemPrompt() { async agenticLoop(messages) { let toolTurns = 0; const _seenCalls = new Map(); // v4.5.66: loop detection — track repeated tool calls + const _loopWindow = 30000; // 30s window for loop detection while (toolTurns < this.MAX_TOOL_TURNS) { if (this._cancelled) { this.terminal.print('AI loop cancelled', 'warning'); return { finalAnswer: null, toolTurns }; } toolTurns++; @@ -791,16 +792,22 @@ buildSystemPrompt() { return { finalAnswer: text, toolTurns }; } if (res.tool_calls && res.tool_calls.length > 0) { - // v4.5.66: Loop detection — break if AI repeats same tool+args 3+ times - // Reset per-turn so legitimate retries across turns don't false-positive - _seenCalls.clear(); + // v4.5.66: Loop detection — break if AI repeats same tool+args 6+ times in 30s + // Accumulates across turns (no clear) so real loops are caught, + // but time-windowed so legitimate retries across separate queries don't false-positive + const now = Date.now(); let looping = false; for (const tc of res.tool_calls) { const sig = tc.function.name + ':' + (tc.function.arguments || ''); - const count = (_seenCalls.get(sig) || 0) + 1; - _seenCalls.set(sig, count); - if (count >= 3) { - this.terminal.print(`🔄 Loop detected: ${tc.function.name} called ${count}x with same args — breaking loop`, 'warning'); + let entry = _seenCalls.get(sig); + if (!entry || (now - entry.ts) > _loopWindow) { + entry = { count: 0, ts: now }; + } + entry.count++; + entry.ts = now; + _seenCalls.set(sig, entry); + if (entry.count >= 6) { + this.terminal.print(`🔄 Loop detected: ${tc.function.name} called ${entry.count}x with same args in 30s — breaking loop`, 'warning'); looping = true; break; } |