kulono / doom-loop
blob · README.md · md
README.mdmd
1# doom-loop23> Agents get stuck in loops. This detects it and makes them recover — autonomously.45## The problem67Every agent framework sets a `max_iterations` cap. That's not loop detection,8that's giving up. A real agent can:910- Retry the **exact same tool call** that just failed (repeat loop)11- Flip between two actions forever (ping-pong loop)12- Poll a resource that never changes (poll-without-progress)13- Trigger loops **across** cooperating agents (cross-agent loop)1415`doom-loop` detects all four patterns at runtime and fires **graded recovery16actions** — retry with different args, switch tool, rollback, downgrade model,17or force a summary — before any turn budget is burned.1819## Install2021```bash22pip install doom-loop23```2425## Usage2627```python28import asyncio29from doom_loop import DoomLoopDetector, DoomLoopConfig, RecoveryAction3031detector = DoomLoopDetector(DoomLoopConfig(32 warn_threshold_base=2,33 critical_threshold_base=3,34 adaptive_enabled=False, # True in prod raises the bar under rapid calls35))3637async def on_recover(result):38 print(f"RECOVERING: {result.message}")39 return True4041# callbacks are keyed by RecoveryAction and awaited after execute_recovery()42detector.register_recovery_callback(RecoveryAction.FORCE_SUMMARIZE, on_recover)4344# feed every tool call + its outcome45detector.record_tool_call("read_file", {"path": "/etc/hosts"})46detector.record_tool_outcome("read_file", {"path": "/etc/hosts"}, "ok")4748result = detector.detect()49if result.stuck:50 asyncio.run(detector.execute_recovery(result))51```5253### Determinism gotcha5455`DoomLoopConfig` defaults to `adaptive_enabled=True`. Under high-frequency calls56the adaptive threshold *raises*, so tight tests need `adaptive_enabled=False`57to get deterministic triggers.5859## Design6061- 4 detector engines share one call/outcome history62- `_fuzzy_args_hash` treats near-identical args as the same retry63- Recovery callbacks are keyed by `RecoveryAction` (async, awaited via `execute_recovery`)64- `result.stuck` + graded `LoopLevel` (NONE / WARNING / CRITICAL)6566Runs 24×7 in the tical-code / EITE agent mesh.6768## License6970AGPL-3.0.71
100%