python main.py SCENARIO from the repository root.
Run the visual examples through the SDK
UseLoopGuard.stream() to inspect the same events, signals, and decisions shown
in the UI. get_scenario() supplies a demo agent, detectors, and initial input.
In your application, pass your own agent and input or use the
callback integration.
Run these snippets from the source checkout after
installing the demo dependencies.
They load the root .env just like the demo entry points. The exact example needs
no credentials; check the requirements below before running the other three.
What each run needs
exact runs offline after dependency installation. Every other scenario can make
provider calls. calc and trap include semantic detection, so model credentials
alone are not enough when chat and embedding providers differ.Exact loop
no results.
Why it matters: repeated calls become suspicious when the results never change.
Expected behavior: exact repetition accumulates, followed by stagnant-result
evidence. The policy reaches STOP, and the graph turns red in the UI.
This scenario uses LoopDetector and StallDetector, so its stop timing differs
from the default callback example, which also includes ProgressDetector.
Python SDK: run the same agent and detector mix, then inspect the evidence and
policy decisions that the UI displays.
stop decision; the final done message has
interrupted: True.

A LoopGuard demo run showing identical searches and empty results ending in interruption.
Semantic loop
signal messages expose the similarity evidence behind the screenshot’s alert.

Semantic evidence catches repeated intent across different search phrases.
Controlled progress
pending, processing, then completed with useful status details.
Why it matters: the same status tool is useful when its output advances.
Expected behavior: let the run finish. This scenario uses a looser exact-repeat
threshold of four so three changing status calls don’t create an unnecessary warning.
Controlled 503 recovery
503 temporarily unavailable twice and then
returns a success message.
Why it matters: repetition alone is not a reason to stop. Allowing short
retries lets the agent recover from a temporary failure.
Expected behavior: retryable-failure evidence can warn, but should allow this
short recovery sequence. The model still decides whether to issue the next call.
Controlled 401 failure
401 unauthorized: token expired.
Why it matters: repeating this request cannot repair the credential.
Expected behavior: stop for the permanent failure. This demo deliberately sets
the repeated-failure threshold to one, so the first observed auth failure can stop
the run. The default live detector uses a threshold of two.
Controlled empty results
no results.
Why it matters: the agent can change its wording without finding useful information.
Expected behavior: repeated or similar actions combined with no progress
should reach STOP. This scenario includes an embedding-backed detector, even
though the tool responses are controlled.
Healthy calculation
4801 * 379 + 1234 and
returns an answer.
Why it matters: a normal successful tool call should finish without interruption.
Expected behavior: useful output lets the run finish without a fatal loop alert.
This is the healthy comparison for the stuck search runs.
Python SDK: the real agent gets a useful result and finishes. Inspect the
decision stream and expect interrupted: False in the final done message when
the task succeeds. Check for error messages separately.

A calculation finishes with a useful tool result and no fatal loop alert.
Impossible goal
action: "stop" followed by a done
message with interrupted: True and a reason.

A LoopGuard demo run showing repeated intent while searching for an impossible confirmation.