From 1545145292d0b3161ea56f9c32cde13a2f3b39f6 Mon Sep 17 00:00:00 2001 From: mawkone Date: Sat, 16 May 2026 12:59:16 -0700 Subject: [PATCH] fix(ai): implement two-stage loop detection to warn before hard-stopping (Fix 11) --- vibn-frontend/app/api/chat/route.ts | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/vibn-frontend/app/api/chat/route.ts b/vibn-frontend/app/api/chat/route.ts index 10186d26..ac8080f2 100644 --- a/vibn-frontend/app/api/chat/route.ts +++ b/vibn-frontend/app/api/chat/route.ts @@ -698,13 +698,29 @@ export async function POST(request: Request) { for (const tc of resp.toolCalls) { toolFingerprints.push(fingerprintToolCall(tc)); } - // Sliding window of 10 (was 8); threshold 3 stays the same + // Sliding window of 10 (was 8) const window = toolFingerprints.slice(-10); const counts = new Map(); for (const fp of window) counts.set(fp, (counts.get(fp) ?? 0) + 1); - const repeated = [...counts.entries()].find(([, n]) => n >= 3); - if (repeated) { - loopBreakReason = `Repeated ${repeated[0]} ${repeated[1]}× in last 10 calls`; + + // Find highest repeating tool call + let maxRepeats = 0; + let repeatedCmd = ""; + for (const [fp, n] of counts.entries()) { + if (n > maxRepeats) { + maxRepeats = n; + repeatedCmd = fp.split("|")[0]; + } + } + + // Stage 1: Warning at 3 repeats + if (maxRepeats === 3) { + extraSystem += `\n\n[WARNING] You have called ${repeatedCmd} 3 times recently. Please wrap up this approach or try a completely different tool.`; + } + + // Stage 2: Hard Break at 5 repeats + if (maxRepeats >= 5) { + loopBreakReason = `Repeated ${repeatedCmd} ${maxRepeats}× in last 10 calls`; } // Execute tool calls and add results. OpenAI-compatible APIs