Stop an agent that repeats itself
Your task
A coding agent sometimes gets stuck: it reads the same file over and over, or keeps running a test that keeps failing, burning tokens until someone notices. A loop guard watches its tool calls and stops the run.
Write loop_guard(calls, max_steps, max_repeats, max_failures). calls is the run's tool calls in order, each [tool, args, ok]: the tool name, the call's arguments as a string (compared exactly), and whether the call succeeded. Tool names and args can contain any character, | and : included. The three limits are at least 1.
For the call at index i (the run's step i + 1), apply these checks in order:
"step_limit": ifi >= max_steps, the run has used all its steps; stop before this call."repeat": if this exact call, the same tool with the same args, has already runmax_repeatstimes earlier in the run (in a row or not), stop before it.- Otherwise the call runs. If it failed and it is the
max_failures-th failed call in a row, stop after it with"failing". A successful call resets that count.
Return [i, reason] for the call at which the guard stopped the run, or [-1, "ok"] if the run ended without being stopped.
Examples:
loop_guard([["read", "a.py", True], ["read", "a.py", True], ["read", "a.py", True]], 10, 2, 3)returns[2, "repeat"]: the third identical read.loop_guard([["test", "", False], ["edit", "a.py", True], ["test", "", False], ["test", "", False]], 10, 5, 2)returns[3, "failing"]: the edit reset the count, then two failures in a row.loop_guard([["ls", ".", True], ["read", "b.py", True], ["grep", "foo", True]], 2, 5, 5)returns[2, "step_limit"].
Examples
loop_guard(calls: list[list], max_steps: int, max_repeats: int, max_failures: int) -> listExample 1
Input
loop_guard([["read", "a.py", True], ["read", "a.py", True], ["read", "a.py", True]], 10, 2, 3)Output
[2, "repeat"]Example 2
Input
loop_guard([["test", "", False], ["edit", "a.py", True], ["test", "", False], ["test", "", False]], 10, 5, 2)Output
[3, "failing"]Example 3
Input
loop_guard([["ls", ".", True], ["read", "b.py", True], ["grep", "foo", True]], 2, 5, 5)Output
[2, "step_limit"]