Skip to main content
Loop detection prevents agents from calling the same tool repeatedly with no progress.
from praisonaiagents import Agent

agent = Agent(
    name="assistant",
    instructions="Stop repeating the same failing tool pattern",
)

agent.start("Fix the deployment issue")
The user watches the agent work; doom-loop detection escalates when cycles repeat.

Quick Start

1

Enable the plugin

Import the plugin once — it registers a global BEFORE_TOOL hook.
import praisonaiagents.plugins.loop_detection_plugin  # noqa: F401
from praisonaiagents import Agent

agent = Agent(instructions="You are a helpful assistant.")
agent.start("Read config.yaml and summarise it.")
2

Custom thresholds before import

from praisonaiagents.agent.loop_detection import LoopDetectionConfig
import praisonaiagents.plugins.loop_detection_plugin as ldp

ldp.DEFAULT_CONFIG = LoopDetectionConfig(
    enabled=True,
    warn_threshold=5,
    critical_threshold=10,
)

from praisonaiagents import Agent

agent = Agent(instructions="Poll a job status endpoint.")
agent.start("Check whether job-42 finished.")

How It Works


Detectors

DetectorWhat It DetectsExample
generic_repeatSame tool + identical args N timesread_file("config.py") called 10 times
poll_no_progressSame args AND same result (no progress)check_status("job-1") returns identical “pending” 10 times
ping_pongAlternating A → B → A → B patternTwo tools oscillating back and forth
poll_no_progress uses heuristic tool name matching — tools with “status”, “poll”, “check”, “wait”, “ping”, or “health” in their name are classified as polling tools.

Configuration Options

OptionTypeDefaultDescription
enabledboolFalseOpt-in on LoopDetectionConfig; plugin sets True when imported
history_sizeint30Sliding window of recent tool calls
warn_thresholdint10Identical calls before warning
critical_thresholdint20Identical calls before blocking (auto-corrected to > warn)
detectorsdictall three TrueEnable or disable individual detectors

Common Patterns

Disable a Specific Detector

from praisonaiagents.agent.loop_detection import LoopDetectionConfig
import praisonaiagents.plugins.loop_detection_plugin as ldp

ldp.DEFAULT_CONFIG = LoopDetectionConfig(
    enabled=True,
    detectors={"generic_repeat": True, "poll_no_progress": False, "ping_pong": True},
)

from praisonaiagents import Agent

agent = Agent(instructions="Monitor server health")
agent.start("Is the API healthy?")

Aggressive Detection

from praisonaiagents.agent.loop_detection import LoopDetectionConfig
import praisonaiagents.plugins.loop_detection_plugin as ldp

ldp.DEFAULT_CONFIG = LoopDetectionConfig(
    enabled=True,
    warn_threshold=3,
    critical_threshold=5,
)

from praisonaiagents import Agent

agent = Agent(instructions="Quick task agent")
agent.start("Fetch the homepage title.")

Loop Detection is opt-in (import the plugin) and catches identical-argument / no-progress patterns. Loop Guard (docs) is always-on and counts per-turn tool calls with idempotent-vs-mutating thresholds. Use both for autonomous agents — Loop Guard as the safety net, Loop Detection for deeper pattern matching.

Best Practices

Long-running agents with many tool calls benefit most from loop detection — add the import at process startup.
If your agent legitimately polls a status endpoint, increase thresholds or disable poll_no_progress.
The detector uses stdlib only (hashlib, json). Without importing the plugin, no hook is registered.
Autonomy mode has separate doom loop detection for repeated actions during self-directed runs.

Loop Guard

Always-on per-turn tool-call guardrails

Autonomy Loop

Self-directed execution and doom loop thresholds