Tune run limits and detection sensitivity for the way your agent works.
A polling agent and a research agent can repeat for different reasons. Change
settings when healthy runs trigger too much evidence, stuck runs take too long to
flag, or you need a hard work limit.
Maximum recorded live events; exported steps in check mode.
Cap total work independently of loop detection.
max_tool_calls
Maximum recorded tool calls.
Limit repeated tool work.
exact_threshold / exact_window
Matching calls required inside a recent event window.
Allow longer healthy polling or catch exact loops sooner.
stall_patience
Identical consecutive observations required by StallDetector.
Your tools often return the same status while working.
handoff_repeats / handoff_window
Repeated closed handoff cycles inside an event window.
Your workflow legitimately revisits agents.
semantic
Enables the embedding-backed detector.
The agent repeats an approach using different words.
stall_patience changes StallDetector only. ProgressDetector has its own
three-observation default, which this config loader does not expose. Likewise,
cycle and repeated-failure thresholds require a custom detector list in Python.
Settings ending in _fatal are detector evidence hints. They do not override the
policy or disable every route to STOP. For example, exact_fatal: false still
allows repetition plus no progress to stop a run. Use observe-only mode when you
need to guarantee that the callback will not raise an interrupt.
Set semantic: true in the live section. Choose the embedding provider in your
process environment:OpenAI embeddings work with the published 0.2.1 package. Gemini support is in
the source checkout; its tab below includes the source installation step.
GEMINI_API_KEY is also accepted. The implementation uses
gemini-embedding-2-preview by default. Confirm access to that model in your account.
In PowerShell, set values with $env:NAME = "value" instead of export.
The library reads environment variables; it does not load .env files for you.
The demo entry points load .env explicitly.Embedding calls require network access and may incur provider charges. Embeddings
are cached by text within each embedder instance. The config loader does not expose
an embedding-model setting; custom models are selected through Python embedder objects.
The loader accepts JSON or a small YAML subset: scalar values, a section mapping,
and simple lists. It does not implement full YAML features such as anchors,
multiline strings, or arbitrary nesting. Use true and false for booleans.If a named live or check section is absent, that consumer falls back to top-level
keys. Check flags override config values. Repeated --fail-on flags replace the
configured failure set rather than extending it.All detector settings loaded from config must be positive; budgets must be positive
integers. Omit a budget to leave it unset. Tune thresholds against labeled examples
from your own application.Look up every supported config field or
inspect saved traces while tuning.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"LoopGuard","description":"Detect stuck AI agents without treating every retry as a loop.","colors":{"primary":"#0369A1","light":"#38BDF8","dark":"#0284C7"},"navbar":{"links":[{"href":"https://github.com/mahimathacker/loopguard","label":"GitHub"},{"href":"https://pypi.org/project/loopguard-runtime/","label":"PyPI"}],"primary":{"type":"button","label":"Watch the demo","href":"https://youtu.be/i5XRrvFoPA0"}},"footer":{"socials":{"github":"https://github.com/mahimathacker/loopguard"}},"seo":{"metatags":{"robots":"index, follow","canonical":"https://loopguard.mintlify.site"}},"contextual":{"options":["chatgpt","claude","aistudio","perplexity","grok","copy","view"],"display":"header"},"markdown":{"instructions":["LoopGuard is a Python runtime guardrail SDK. Install loopguard-runtime and import loopguard. Use /getting-started and /guides/integration for application code.","Use the Concepts section for agent loops, tests versus traces versus evals, and trajectory/convergence. The convergence helper compares counts without checking success; LoopGuard events are not OpenTelemetry spans. Distinguish these general concepts from implemented SDK features.","The exact, semantic, calc, and trap UI examples illustrate Python SDK detection behavior. Read /demo/scenarios for runnable SDK examples and /guides/integration to attach callbacks or inspect streamed updates.","These docs follow the checkout. PyPI 0.2.1 lacks Gemini support, controlled demo scenarios, and additional decision display fields; check /development/status before describing release capabilities.","Repetition alone does not force STOP. REPLAN and PAUSE are recorded recommendations. Observe-only mode records decisions without raising. Follow /guides/integration for interrupt propagation.","Use the Python API, CLI, and configuration references for supported names and flags. Screenshots illustrate observed runs, not guaranteed stop counts or benchmark results."]},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"loopguard","hasAudioNarration":false,"actualSubdomain":"loopguard","customDomains":[],"gitSource":{"type":"github","owner":"mahimathacker","repo":"loopguard","deployBranch":"master","contentDirectory":"docs","isPrivate":false,"mountPath":"","label":"","_id":"6ae482d5516c780aa3740aba"},"chroma":{"latestBuiltDeploymentHistoryId":"6ae498d735628143bec433c7","collectionId":"0ce76fff-8a24-4de9-94d8-94e3386098a1","liveDeploymentHistoryId":"6ae498d735628143bec433c7","schemaVersion":"v3"},"entitlements":{},"buildId":"6ae4baf8d51aac6e910af2e5","clientVersion":"0.0.4021","searchFilterCounts":[{"language":"default","tag":"Use LoopGuard","count":5},{"language":"default","tag":"Test and troubleshoot","count":4},{"language":"default","tag":"Concepts","count":3},{"language":"default","tag":"Start here","count":3},{"language":"default","tag":"Reference","count":3},{"language":"default","tag":"Explore the demo","count":2}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"guides/configuration","slug":"/guides/configuration","pageMetadata":{"title":"Configure LoopGuard","description":"Tune run limits and detection sensitivity for the way your agent works.","href":"/guides/configuration"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Tune run limits and detection sensitivity for the way your agent works.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,p:`p`,pre:`pre`,span:`span`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,..._provideComponents(),...props.components},{CodeBlock,Heading,Tab,Table,Tabs,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tab)_missingMdxReference(`Tab`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tabs)_missingMdxReference(`Tabs`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`A polling agent and a research agent can repeat for different reasons. Change\nsettings when healthy runs trigger too much evidence, stuck runs take too long to\nflag, or you need a hard work limit.`}),`\n`,_jsx(Heading,{level:`2`,id:`start-with-one-application-config`,children:`Start with one application config`}),`\n`,_jsxs(_components.p,{children:[`Save this as `,_jsx(_components.code,{children:`loopguard.yml`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`19`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`19`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`live`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_steps`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`40`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_tool_calls`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`15`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` exact_threshold`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`3`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` exact_window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`12`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` stall_patience`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`4`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` stall_fatal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` handoff_repeats`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`2`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` handoff_window`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`16`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` handoff_max_cycle_length`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`5`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` handoff_fatal`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` semantic`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`check`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` fail_on`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`looping`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`stalled`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_steps`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`40`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_tool_calls`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`15`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Load the `,_jsx(_components.code,{children:`live`}),` section in your application:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` loopguard `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` LoopGuardCallbackHandler`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`handler `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` LoopGuardCallbackHandler.from_config(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"loopguard.yml\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`handler.raise_error `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` True`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Or use the `,_jsx(_components.code,{children:`check`}),` section with an exported trace:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`python`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -m`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` loopguard.check`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` examples/sample_trace.json`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --config`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` loopguard.yml`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The trace command assumes a repository checkout. The sample deliberately includes\na loop, so this check exits with code `,_jsx(_components.code,{children:`1`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`choose-limits-and-sensitivity`,children:`Choose limits and sensitivity`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Setting`}),_jsx(_components.th,{children:`What it controls`}),_jsx(_components.th,{children:`When to change it`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`max_steps`})}),_jsx(_components.td,{children:`Maximum recorded live events; exported steps in check mode.`}),_jsx(_components.td,{children:`Cap total work independently of loop detection.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`max_tool_calls`})}),_jsx(_components.td,{children:`Maximum recorded tool calls.`}),_jsx(_components.td,{children:`Limit repeated tool work.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`exact_threshold`}),` / `,_jsx(_components.code,{children:`exact_window`})]}),_jsx(_components.td,{children:`Matching calls required inside a recent event window.`}),_jsx(_components.td,{children:`Allow longer healthy polling or catch exact loops sooner.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`stall_patience`})}),_jsxs(_components.td,{children:[`Identical consecutive observations required by `,_jsx(_components.code,{children:`StallDetector`}),`.`]}),_jsx(_components.td,{children:`Your tools often return the same status while working.`})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`handoff_repeats`}),` / `,_jsx(_components.code,{children:`handoff_window`})]}),_jsx(_components.td,{children:`Repeated closed handoff cycles inside an event window.`}),_jsx(_components.td,{children:`Your workflow legitimately revisits agents.`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`semantic`})}),_jsx(_components.td,{children:`Enables the embedding-backed detector.`}),_jsx(_components.td,{children:`The agent repeats an approach using different words.`})]})]})]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`stall_patience`}),` changes `,_jsx(_components.code,{children:`StallDetector`}),` only. `,_jsx(_components.code,{children:`ProgressDetector`}),` has its own\nthree-observation default, which this config loader does not expose. Likewise,\ncycle and repeated-failure thresholds require a custom detector list in Python.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Settings ending in `,_jsx(_components.code,{children:`_fatal`}),` are detector evidence hints. They do not override the\npolicy or disable every route to `,_jsx(_components.code,{children:`STOP`}),`. For example, `,_jsx(_components.code,{children:`exact_fatal: false`}),` still\nallows repetition plus no progress to stop a run. Use observe-only mode when you\nneed to guarantee that the callback will not raise an interrupt.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`enable-semantic-detection`,children:`Enable semantic detection`}),`\n`,_jsx(_components.p,{children:`Install the optional SDKs:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pip`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` install`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"loopguard-runtime[semantic]\"`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Set `,_jsx(_components.code,{children:`semantic: true`}),` in the `,_jsx(_components.code,{children:`live`}),` section. Choose the embedding provider in your\nprocess environment:`]}),`\n`,_jsxs(_components.p,{children:[`OpenAI embeddings work with the published `,_jsx(_components.code,{children:`0.2.1`}),` package. Gemini support is in\nthe source checkout; its tab below includes the source installation step.`]}),`\n`,_jsxs(Tabs,{children:[_jsxs(Tab,{title:`OpenAI`,id:`openai`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` LOOPGUARD_EMBEDDING_PROVIDER`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`openai`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` OPENAI_API_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`your-key`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`The implementation uses `,_jsx(_components.code,{children:`text-embedding-3-small`}),` by default.`]})]}),_jsxs(Tab,{title:`Gemini`,id:`gemini`,children:[_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`git`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` clone`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` https://github.com/mahimathacker/loopguard.git`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`cd`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` loopguard`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pip`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` install`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -e`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \".[semantic]\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` LOOPGUARD_EMBEDDING_PROVIDER`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`gemini`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`export`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` GOOGLE_API_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`your-key`})]}),`\n`]})})}),_jsxs(_components.p,{children:[_jsx(_components.code,{children:`GEMINI_API_KEY`}),` is also accepted. The implementation uses\n`,_jsx(_components.code,{children:`gemini-embedding-2-preview`}),` by default. Confirm access to that model in your account.`]})]})]}),`\n`,_jsxs(_components.p,{children:[`In PowerShell, set values with `,_jsx(_components.code,{children:`$env:NAME = \"value\"`}),` instead of `,_jsx(_components.code,{children:`export`}),`.\nThe library reads environment variables; it does not load `,_jsx(_components.code,{children:`.env`}),` files for you.\nThe demo entry points load `,_jsx(_components.code,{children:`.env`}),` explicitly.`]}),`\n`,_jsx(_components.p,{children:`Embedding calls require network access and may incur provider charges. Embeddings\nare cached by text within each embedder instance. The config loader does not expose\nan embedding-model setting; custom models are selected through Python embedder objects.`}),`\n`,_jsx(Heading,{level:`2`,id:`keep-config-simple`,children:`Keep config simple`}),`\n`,_jsxs(_components.p,{children:[`The loader accepts JSON or a small YAML subset: scalar values, a section mapping,\nand simple lists. It does not implement full YAML features such as anchors,\nmultiline strings, or arbitrary nesting. Use `,_jsx(_components.code,{children:`true`}),` and `,_jsx(_components.code,{children:`false`}),` for booleans.`]}),`\n`,_jsxs(_components.p,{children:[`If a named `,_jsx(_components.code,{children:`live`}),` or `,_jsx(_components.code,{children:`check`}),` section is absent, that consumer falls back to top-level\nkeys. Check flags override config values. Repeated `,_jsx(_components.code,{children:`--fail-on`}),` flags replace the\nconfigured failure set rather than extending it.`]}),`\n`,_jsx(_components.p,{children:`All detector settings loaded from config must be positive; budgets must be positive\nintegers. Omit a budget to leave it unset. Tune thresholds against labeled examples\nfrom your own application.`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`/reference/configuration`,children:`Look up every supported config field`}),` or\n`,_jsx(_components.a,{href:`/guides/saved-traces`,children:`inspect saved traces`}),` while tuning.`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Configure LoopGuard","description":"Tune run limits and detection sensitivity for the way your agent works.","href":"/guides/configuration"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Start with one application config","slug":"start-with-one-application-config","depth":2,"children":[]},{"title":"Choose limits and sensitivity","slug":"choose-limits-and-sensitivity","depth":2,"children":[]},{"title":"Enable semantic detection","slug":"enable-semantic-detection","depth":2,"children":[]},{"title":"Keep config simple","slug":"keep-config-simple","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"loopguard","siteName":"LoopGuard","title":"Configure LoopGuard - LoopGuard","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-30T11:44:49.004Z","originalFileLocation":"guides/configuration.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Tune run limits and detection sensitivity for the way your agent works.\">\u003cmeta data-mint-head name=\"application-name\" content=\"LoopGuard\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/apple-touch-icon.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon-32x32.png?v=3\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon-16x16.png?v=3\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/favicon.ico?v=3\">\u003cmeta data-mint-head property=\"og:title\" content=\"Configure LoopGuard - LoopGuard\">\u003cmeta data-mint-head property=\"og:description\" content=\"Tune run limits and detection sensitivity for the way your agent works.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"LoopGuard\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://loopguard.mintlify.site/guides/configuration\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://loopguard.mintlify.app/_mintlify/api/og/v2?division=Use+LoopGuard\u0026amp;title=Configure+LoopGuard\u0026amp;description=Tune+run+limits+and+detection+sensitivity+for+the+way+your+agent+works.\u0026amp;theme=2c27cc35ccb7ce9812604402\u0026amp;signature=e873ac7ec4ac7d15770d721854b5c66945e6579904595b33e442f6993d6c7ae6\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Configure LoopGuard - LoopGuard\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Tune run limits and detection sensitivity for the way your agent works.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://loopguard.mintlify.app/_mintlify/api/og/v2?division=Use+LoopGuard\u0026amp;title=Configure+LoopGuard\u0026amp;description=Tune+run+limits+and+detection+sensitivity+for+the+way+your+agent+works.\u0026amp;theme=2c27cc35ccb7ce9812604402\u0026amp;signature=e873ac7ec4ac7d15770d721854b5c66945e6579904595b33e442f6993d6c7ae6\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"https://mintlify.s3.us-west-1.amazonaws.com/loopguard/_generated/favicon/browserconfig.xml?v=3\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"LoopGuard\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0369A1\">\u003clink data-mint-head rel=\"canonical\" href=\"https://loopguard.mintlify.site/guides/configuration\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/guides/configuration.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://loopguard.mintlify.site/#organization\",\"name\":\"LoopGuard\",\"url\":\"https://loopguard.mintlify.site\"},{\"@type\":\"WebSite\",\"@id\":\"https://loopguard.mintlify.site#website\",\"name\":\"LoopGuard\",\"url\":\"https://loopguard.mintlify.site\",\"publisher\":{\"@id\":\"https://loopguard.mintlify.site/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://loopguard.mintlify.site/guides/configuration#webpage\",\"url\":\"https://loopguard.mintlify.site/guides/configuration\",\"name\":\"Configure LoopGuard\",\"description\":\"Tune run limits and detection sensitivity for the way your agent works.\",\"dateModified\":\"2026-10-30T11:44:49.004Z\",\"isPartOf\":{\"@id\":\"https://loopguard.mintlify.site#website\"},\"breadcrumb\":{\"@id\":\"https://loopguard.mintlify.site/guides/configuration#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://loopguard.mintlify.site/guides/configuration#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Use LoopGuard\",\"item\":\"https://loopguard.mintlify.site/detection\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Configure LoopGuard\",\"item\":\"https://loopguard.mintlify.site/guides/configuration\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://loopguard.mintlify.site/guides/configuration#article\",\"headline\":\"Configure LoopGuard\",\"name\":\"Configure LoopGuard\",\"description\":\"Tune run limits and detection sensitivity for the way your agent works.\",\"url\":\"https://loopguard.mintlify.site/guides/configuration\",\"mainEntityOfPage\":{\"@id\":\"https://loopguard.mintlify.site/guides/configuration#webpage\"},\"dateModified\":\"2026-10-30T11:44:49.004Z\",\"publisher\":{\"@id\":\"https://loopguard.mintlify.site/#organization\"},\"isPartOf\":{\"@id\":\"https://loopguard.mintlify.site#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"LoopGuard\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"LoopGuard","nav":{"global":null,"groups":[{"group":"Start here","pages":[{"title":"LoopGuard","sidebarTitle":"Introduction","href":"/index"},{"title":"Getting started","href":"/getting-started"},{"title":"How LoopGuard works","href":"/how-it-works"}]},{"group":"Concepts","pages":[{"title":"AI agents and loops","href":"/concepts/agents-and-loops"},{"title":"Tests, traces, and evals","href":"/concepts/tests-traces-and-evals"},{"title":"Agent trajectories and convergence","href":"/concepts/trajectory-and-convergence"}]},{"group":"Use LoopGuard","pages":[{"title":"Detecting stuck agents","href":"/detection"},{"title":"LangGraph and LangChain","description":"Add tool callbacks to an existing agent and control how stop decisions reach your application.","href":"/guides/integration"},{"title":"Configure LoopGuard","href":"/guides/configuration"},{"title":"Analyze saved traces","description":"Replay an exported run locally and use check mode for script or CI pass/fail behavior.","href":"/guides/saved-traces"},{"title":"Add a trace regression check","href":"/guides/regression-checks"}]},{"group":"Explore the demo","pages":[{"title":"Demo scenarios","href":"/demo/scenarios"},{"title":"Run the demo UI","href":"/demo/running-locally"}]},{"group":"Test and troubleshoot","pages":[{"title":"Evaluation and tests","href":"/development/evaluation"},{"title":"Troubleshooting","href":"/troubleshooting"},{"title":"Project status","href":"/development/status"},{"title":"Contributing and docs maintenance","href":"/development/contributing"}]},{"group":"Reference","pages":[{"title":"Python API","href":"/reference/python"},{"title":"CLI reference","href":"/reference/cli"},{"title":"Configuration reference","href":"/reference/configuration"}]}]},"title":"Configure LoopGuard - LoopGuard","buildId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","deploymentId":"dpl_EnxDqhjaNc9a8MVa833TGULPd9uJ","dynamics":[],"chunks":[]}