aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-aiassist.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-23 18:00:58 +0200
committerAgando <roduccomm@gmail.com>2026-06-23 18:00:58 +0200
commit168a7bc6d50023215f75fa8a0d95362473cfe033 (patch)
tree7351abfcaff59a6fcebf19ea322a77eda9b6ed6b /modules/core/module-aiassist.js
parente9b75cd3a801689f57bc8a013f14c058e57e3b46 (diff)
auto: 2026-06-23_18:00 changes
Diffstat (limited to 'modules/core/module-aiassist.js')
-rw-r--r--modules/core/module-aiassist.js21
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;
}