Skip to content

feat: Add anti-loop / duplicate tool-call guard#82

Open
devin-ai-integration[bot] wants to merge 1 commit into
developfrom
devin/1781115653-anti-loop-guard
Open

feat: Add anti-loop / duplicate tool-call guard#82
devin-ai-integration[bot] wants to merge 1 commit into
developfrom
devin/1781115653-anti-loop-guard

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

Prevents models (Kimi K2, etc.) from burning tokens/API quota by repeating the same tool call in a tight loop. Adds a new ToolCallGuard singleton with 4 layers of protection, wired into the single dispatch chokepoint (SkillDispatcher.dispatch) so it works for all execution paths (chat, sub-agents, background scheduler).

How it works

ToolCallGuard.evaluate(call:) runs before every skill dispatch. On .allow, the call proceeds and its result is recorded via guardedCompletion. On .block, a synthetic error is returned to the model immediately.

Layer 1 — Dedup guard: Tracks the last 5 calls by (name, normalizedArgs) signature. Second call with same signature → blocked with "You already called this tool with these arguments. Stop looping.".

Layer 2 — Repeat counter: Hard-caps identical (name, args) at maxRepeats (default 3). On the 4th attempt → hard abort with "LOOP ABORTED".

Layer 3 — Result diff check: If a tool returned results and the model tries the same call again → blocked with a reminder including a 200-char prefix of the previous result.

Layer 4 — Prompt injection: When any layer trips, sets shouldInjectLoopReminder = true. AgentHarness.buildSystemPrompt reads this flag and appends a strong system-level "⚠️ LOOP DETECTED — STOP REPEATING" reminder, then clears the flag.

Integration points

SkillDispatcher.dispatch()       ← guard.evaluate() + guardedCompletion wrapper
AgentHarness.buildSystemPrompt() ← prompt injection when flag is set
MessagingVC.didSendMessageText() ← resetForNewTurn() on new user message
BackgroundScheduler.runJob()     ← resetForNewTurn() on new scheduled job

Configuration

All thresholds are configurable via ToolCallGuard.Config:

ToolCallGuard.shared.config.maxRepeats = 2        // tighter cap
ToolCallGuard.shared.config.historyWindow = 3      // shorter memory
ToolCallGuard.shared.config.resultDiffEnabled = false  // disable layer 3

Link to Devin session: https://app.devin.ai/sessions/1964159a3f5c4017b31db864e7f176b1

Four-layer protection against models (Kimi K2, etc.) repeating the same
tool call in a tight loop:

1. Dedup guard — tracks last 5 calls (name + normalized args); blocks
   duplicates with a synthetic error.
2. Repeat counter — hard-caps identical calls at 3; aborts the turn on
   the 4th attempt.
3. Result diff check — if a tool returned the same payload and the
   model tries again, short-circuits with previous result summary.
4. Prompt injection — when any layer trips, injects a strong system
   reminder into the next buildSystemPrompt telling the model to stop.

ToolCallGuard is a thread-safe singleton wired into SkillDispatcher.dispatch
(the single chokepoint for MessagingVC, SubAgentRuntime, and
BackgroundScheduler). State resets on each new user message / scheduled job.

All thresholds are configurable via ToolCallGuard.Config (historyWindow,
maxRepeats, per-layer enable flags).

Co-Authored-By: bot_apk <apk@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Original prompt from API User

Implement an anti-loop / duplicate tool-call guard in the LoopHarness tool execution layer to prevent models (especially Kimi K2) from making the same tool call repeatedly in a loop.

Implement these 4 layers of protection:

  1. Deduplication guard: Track the last 3–5 tool calls (name + normalized/serialized args). If a duplicate call is detected, return a synthetic error: "You already called this tool with these arguments. Stop looping."

  2. Repeat counter: Hard-cap identical calls at 2 or 3. On the Nth repeat, abort the turn and surface a warning to the user.

  3. Result diff check: If a tool returns the exact same payload twice in a row, short-circuit the next identical call and append a system prompt reminder: "You are repeating tool calls and getting the same result. Stop. Use what you already have."

  4. Prompt injection: When a loop is detected, inject a strong system reminder into the conversation context telling the model to stop repeating and to use already-retrieved data.

This should work in the tool execution / agent loop layer, regardless of which model backend is running. Make it configurable (e.g., max_repeats threshold) if appropriate. Target the relevant agent/tool-orchestration code in the repo. Add @ashbhat as a reviewer on the PR.

Repository: theashbhat/LoopHarness

@vercel

vercel Bot commented Jun 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
loop-harness Ready Ready Preview, Comment Jun 10, 2026 6:25pm

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot requested a review from ashbhat June 10, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants