Safety & enforcement
Loop detection
Zelyx watches for repeating call patterns and can warn or block when an agent appears to be looping. The single biggest cause of unexpected AI spend is an agent that retries in a tight loop — loop detection catches this before the bill does.
How it works
For each call, Zelyx creates a fingerprint based on the session ID, model, and whether the call uses tools. It then counts how many calls with the same fingerprint have occurred within a rolling time window.
If the count reaches the configured threshold, loop detection triggers and takes the configured action (warn or block).
X-Zelyx-Session-Id are grouped under a default per-company fingerprint, which has a much higher effective threshold. Set a session ID on agent calls to get accurate per-session detection.Configuration
Configure loop detection in Settings → Loop detection.
| Setting | Default | Description |
|---|---|---|
| Enabled | On | Toggle loop detection on or off for the workspace. |
| Threshold | 10 calls | Number of matching calls within the window before detection triggers. |
| Window | 60 seconds | The rolling window over which calls are counted. |
| Action | warn | What to do when a loop is detected. warn fires an alert but the call proceeds. block rejects the call (HTTP 429) and fires an alert. |
Actions
| Action | HTTP | Effect |
|---|---|---|
| warn | 200 (call proceeds) | Loop alert fires to all configured channels. The call is still forwarded to the provider. Useful to observe looping patterns before enforcing. |
| block | 429 | Call rejected. Budget for that call is released. Loop alert fires. The agent must handle the 429 and back off. |
Handling a 429 in your agent
import time, httpx
for attempt in range(max_attempts):
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
extra_headers={"X-Zelyx-Session-Id": session_id},
)
break
except httpx.HTTPStatusError as e:
if e.response.status_code == 429:
# Loop detected — back off and re-evaluate
time.sleep(10)
messages = trim_messages(messages) # reduce context, try again
else:
raiseResetting a session counter
Loop counters are in-memory and reset automatically on server restart. If a legitimate burst of calls (e.g. parallel document processing) triggers loop detection, the counter resets by itself within the window — no manual action required. If you need an immediate reset, use a different session ID for the new job.
batch-{date}-{uuid}). This keeps batch traffic isolated from interactive session traffic and avoids false positives.