|
| 1 | +Stuck-Loop Guard (Agent Loop Progress Detection) |
| 2 | +================================================ |
| 3 | + |
| 4 | +The dominant computer-use failure mode is an agent burning its budget repeating |
| 5 | +an action that has no effect — and the model usually can't see its own loop, so |
| 6 | +it must be caught **mechanically** from outside, by watching the stream of |
| 7 | +``(tool, args, result)`` triples. ``LoopGuard`` flags three patterns: |
| 8 | + |
| 9 | +- ``repeat`` — the same ``(tool, args)`` fired many times in a row; |
| 10 | +- ``ping_pong`` — two actions alternating A-B-A-B with no progress; |
| 11 | +- ``no_op`` — the observation (a screenshot/state digest) never changes. |
| 12 | + |
| 13 | +It complements a step/time budget (which can't tell a productive loop from a |
| 14 | +stuck one) and the offline trajectory evaluator. Pure standard library |
| 15 | +(``collections`` + ``hashlib``), deterministic; imports no ``PySide6``. |
| 16 | + |
| 17 | +Headless API |
| 18 | +------------ |
| 19 | + |
| 20 | +.. code-block:: python |
| 21 | +
|
| 22 | + from je_auto_control import LoopGuard, digest_result |
| 23 | +
|
| 24 | + guard = LoopGuard(warn=8, critical=15) |
| 25 | + for step in agent_steps: |
| 26 | + verdict = guard.observe(step.tool, step.args, |
| 27 | + digest_result(step.screenshot)) |
| 28 | + if verdict.level == "critical": |
| 29 | + break # abort: stuck loop |
| 30 | + if verdict.level == "warn": |
| 31 | + nudge_the_model(verdict.pattern) |
| 32 | +
|
| 33 | +``observe`` returns ``{pattern, level, count}`` where ``level`` is ``ok`` / |
| 34 | +``warn`` / ``critical`` once the run length crosses the thresholds. ``count`` is |
| 35 | +the length of the detected run. ``digest_result`` makes a stable short hash of a |
| 36 | +screenshot/observation (bytes or any JSON-able value). ``reset`` clears history. |
| 37 | + |
| 38 | +Executor commands |
| 39 | +----------------- |
| 40 | + |
| 41 | +A module-level default guard backs the executor/MCP surfaces so a flow can track |
| 42 | +progress across steps: |
| 43 | + |
| 44 | +================================ =================================================== |
| 45 | +Command Effect |
| 46 | +================================ =================================================== |
| 47 | +``AC_loop_guard_observe`` Feed a step; returns ``{pattern, level, count}``. |
| 48 | +``AC_loop_guard_reset`` Clear the default guard's history. |
| 49 | +================================ =================================================== |
| 50 | + |
| 51 | +The same operations are exposed as MCP tools (``ac_loop_guard_observe`` / |
| 52 | +``ac_loop_guard_reset``) and as Script Builder commands under **Agent**. |
0 commit comments