> ## Documentation Index
> Fetch the complete documentation index at: https://docs.praison.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Loop Detection

> Detect and break stuck tool-call loops automatically

Loop detection prevents agents from getting stuck calling the same tool repeatedly with no progress.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "3 Detectors"
        A["🔄 Generic Repeat<br/>Same tool + same args"] --> Check{Threshold?}
        B["📊 Poll No Progress<br/>Same result each time"] --> Check
        C["🏓 Ping Pong<br/>A → B → A → B"] --> Check
        Check -->|Warning| W["⚠️ Warn Agent"]
        Check -->|Critical| S["🛑 Block Execution"]
    end

    classDef detector fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef check fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    classDef critical fill:#8B0000,stroke:#7C90A0,color:#fff

    class A,B,C detector
    class Check check
    class W result
    class S critical
```

## Quick Start

<Steps>
  <Step title="Enable with True">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents import Agent

    agent = Agent(
        instructions="You are a helpful assistant.",
        loop_detection=True  # Uses safe defaults
    )
    ```
  </Step>

  <Step title="Custom Thresholds">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonaiagents.agent.loop_detection import LoopDetectionConfig

    agent = Agent(
        instructions="You are a helpful assistant.",
        loop_detection=LoopDetectionConfig(
            enabled=True,
            warn_threshold=5,       # Warn after 5 identical calls
            critical_threshold=10,  # Block after 10
        )
    )
    ```
  </Step>
</Steps>

***

## How It Works

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Agent
    participant Tool
    participant Detector

    loop Each tool call
        Agent->>Detector: record_tool_call(name, args)
        Agent->>Tool: Execute
        Tool-->>Agent: Result
        Agent->>Detector: record_tool_outcome(result)
        Detector->>Detector: Check 3 detectors
        alt No loop
            Detector-->>Agent: stuck=False ✅
        else Warning
            Detector-->>Agent: ⚠️ "Try a different approach"
        else Critical
            Detector-->>Agent: 🛑 "Execution blocked"
        end
    end
```

***

## Detectors

| Detector           | What It Detects                         | Example                                                      |
| ------------------ | --------------------------------------- | ------------------------------------------------------------ |
| `generic_repeat`   | Same tool + identical args N times      | `read_file("config.py")` called 10 times                     |
| `poll_no_progress` | Same args AND same result (no progress) | `check_status("job-1")` returns identical "pending" 10 times |
| `ping_pong`        | Alternating A → B → A → B pattern       | Two tools oscillating back and forth                         |

<Note>
  `poll_no_progress` uses heuristic tool name matching — tools with "status", "poll", "check", "wait", "ping", "health" in their name are automatically classified as polling tools.
</Note>

***

## Configuration Options

| Option               | Type   | Default                                                                 | Description                                                |
| -------------------- | ------ | ----------------------------------------------------------------------- | ---------------------------------------------------------- |
| `enabled`            | `bool` | `False`                                                                 | Opt-in. Zero overhead when disabled                        |
| `history_size`       | `int`  | `30`                                                                    | Sliding window of recent tool calls                        |
| `warn_threshold`     | `int`  | `10`                                                                    | Identical calls before warning                             |
| `critical_threshold` | `int`  | `20`                                                                    | Identical calls before blocking (auto-corrected to > warn) |
| `detectors`          | `dict` | `{"generic_repeat": True, "poll_no_progress": True, "ping_pong": True}` | Enable/disable individual detectors                        |

***

## Common Patterns

### Disable a Specific Detector

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents.agent.loop_detection import LoopDetectionConfig

agent = Agent(
    instructions="Monitor server health",
    loop_detection=LoopDetectionConfig(
        enabled=True,
        detectors={"generic_repeat": True, "poll_no_progress": False, "ping_pong": True}
    )
)
```

### Aggressive Detection

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
agent = Agent(
    instructions="Quick task agent",
    loop_detection=LoopDetectionConfig(
        enabled=True,
        warn_threshold=3,
        critical_threshold=5,
    )
)
```

***

## Best Practices

<AccordionGroup>
  <Accordion title="Enable for Autonomous Agents">
    Agents running in `autonomy=True` mode should always have loop detection. Long-running autonomous agents are most susceptible to getting stuck.
  </Accordion>

  <Accordion title="Adjust Thresholds for Polling Tools">
    If your agent legitimately polls a status endpoint, increase thresholds or disable `poll_no_progress` for that workflow.
  </Accordion>

  <Accordion title="Zero Overhead When Disabled">
    Loop detection uses stdlib only (`hashlib`, `json`). When `enabled=False` (default), zero CPU cost — the detector returns immediately.
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Autonomy" icon="robot" href="/docs/features/escalation-pipeline">
    Autonomous agent execution with escalation
  </Card>

  <Card title="Background Tasks" icon="clock" href="/docs/features/background-tasks">
    Long-running agents with scheduling
  </Card>
</CardGroup>
