Skip to content

Commit b052b57

Browse files
vNeeL-codeclaude
andcommitted
Add stuck loop detection — auto-flush KV when model repeats itself
If the model returns the same response twice in a row (hash match), force a KV cache flush. Catches short-response loops like "I am good" that slip past the 40-char truncateRepetition() check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 253a9d3 commit b052b57

1 file changed

Lines changed: 22 additions & 0 deletions

File tree

app/src/main/kotlin/com/gemma/api/agent/KoogAgent.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ class KoogAgent(
179179

180180
// Inference timestamp for thermal rate limiting
181181
@Volatile private var lastInferenceTime: Long = 0L
182+
183+
// Stuck loop detection — if model returns same response N times, force KV flush
184+
@Volatile private var lastResponseHash: Int = 0
185+
@Volatile private var sameResponseCount: Int = 0
182186

183187
private val checkpointFile: File
184188
get() = File(checkpointDir, "koog_agent_checkpoint.json")
@@ -549,6 +553,24 @@ class KoogAgent(
549553
// Mark inference complete for thermal rate limiting
550554
lastInferenceTime = System.currentTimeMillis()
551555

556+
// Stuck loop detection: if model returns same response twice in a row, flush KV
557+
val responseHash = response.trim().lowercase().hashCode()
558+
if (responseHash == lastResponseHash) {
559+
sameResponseCount++
560+
if (sameResponseCount >= 2) {
561+
Timber.w("🔄 STUCK LOOP detected ('${response.take(30)}' repeated $sameResponseCount times). Flushing KV cache.")
562+
try {
563+
llmEngine.softReset(buildSystemPrompt())
564+
} catch (e: Exception) {
565+
Timber.e(e, "Emergency KV flush failed")
566+
}
567+
sameResponseCount = 0
568+
}
569+
} else {
570+
sameResponseCount = 0
571+
}
572+
lastResponseHash = responseHash
573+
552574
// 4. ACT: Parse response for tool calls and execute them
553575
Timber.i("⚡ Acting on response...")
554576
val (cleanResponse, toolResults) = act(response)

0 commit comments

Comments
 (0)