loopguard-runtime and imported as loopguard.
Start with the callback handler for tool events or the wrapper for supported
LangGraph stream updates.
This reference tracks the source checkout. The published 0.2.1 wheel has the
core entry points, but lacks the checkout’s additional serialized decision display
fields and Gemini provider support. See release scope.
LoopGuardCallbackHandler
Constructor budget values should be positive integers. Config-file loading validates
that constraint; direct constructors do not apply the same validation.
Use
handler.raise_error = True to let LangChain propagate callback exceptions.
This is inherited framework behavior, not a LoopGuard constructor parameter.
See integration for surrounding tool-error handling.
Configuration and lifecycle
from_config(path, interrupt_on_fatal=True) reads the live settings.
reset() clears detector state, messages, events, signals, decisions, and alerts
before a new run. Prefer a fresh handler per run when running agents concurrently.
Read the result
report()["interrupted"] is the policy’s stop flag. It can be true even when
observe-only mode or framework exception handling allowed execution to continue.
LoopGuardInterrupt
RuntimeError subclass carries decision and alert attributes, which can
be None. A policy stop normally provides a GuardDecision; its stop_reason
supplies the message. Catch it outside the run and retain the handler’s report.
LoopGuard stream wrapper
LoopGuard.from_config(path, detectors=None, recursion_limit=50) loads live
settings. Passing a detector list replaces the configured/default list.
guard.stream(agent, initial=None, recursion_limit=None) yields dictionaries.
An explicit recursion limit for stream() overrides the instance value.
The wrapper stops consuming updates after
STOP. It catches runtime exceptions,
emits error, and still emits final metrics and done. Inspect errors separately
from the interruption flag. initial=None uses the scripted weather-demo input;
pass your own initial state for other agents.
The lower-level exported stream_run(agent, detectors, initial=None, recursion_limit=50) uses the same message contract.
Report data
Decision actions serialize as lowercase strings:
continue, warn, replan,
pause, and stop. stop_reason is None for other actions. repeat_rate is
the fraction of tool calls beyond the first instance of each distinct signature,
not a measure of model quality or wasted tokens.
Saved-trace functions
These functions live inloopguard.ingest rather than the package root:
analyze_trace(trace, detectors=None) returns a TraceReport.
analyze_file(path, detectors=None) returns a list of reports. Supply a custom
detector list to change offline behavior or add a semantic detector. The functions
replay the whole trace and do not execute its tools.
TraceReport exposes run_id, steps, events, tool_calls, decisions,
alerts, status, looped, and final_decision. looped means any STOP,
including failures and budgets, not only a literal loop.
Lower-level public surfaces
Use these when writing an adapter or experimenting with policy. They are not required for normal callback integration.
The default callback/wrapper constructors do not expose a custom policy parameter.
Use a lower-level
Monitor when you need to inject a PolicyEngine.
Detector classes are imported from loopguard.detectors; embedders from
loopguard.embeddings. See detection and the
configuration reference for behavior and defaults.
Evaluation helper
loopguard.evals.convergence_score(step_counts) returns the average ratio of the
shortest positive supplied count to each positive count. It ignores nonpositive
counts and returns 0.0 when no positive counts remain.
This function accepts step counts, not traces or success labels. It does not
verify outcomes or measure cost. See agent trajectories and convergence
for a runnable example and how to select comparable runs.