@xpert-ai/plugin-loop-guard
v0.0.2
Published
`@xpert-ai/plugin-loop-guard` implements a pure-plugin tool-call loop detector for Xpert agents. It does not rely on `xpert-pro` consuming `jumpTo: "model"`.
Downloads
226
Readme
Xpert Plugin: Loop Guard Middleware
@xpert-ai/plugin-loop-guard implements a pure-plugin tool-call loop detector for Xpert agents. It does not rely on xpert-pro consuming jumpTo: "model".
What It Does
- hashes the last
AIMessage.tool_callsas one normalized batch - keeps a sliding window in middleware state
- schedules a warning for the next
beforeModelturn after repeated batches crosswarnThreshold - hard-stops the current turn after repeated batches cross
hardLimitwhenonLoopisend - throws
LoopGuardTriggeredErrorafter repeated batches crosshardLimitwhenonLoopiserror
This middleware stores its detection window in agent state, so the signal survives across invocations on the same thread.
Lifecycle Strategy
beforeAgent: initializes or prunes loop-detection state without resetting the thread windowbeforeModel: injects aHumanMessageif a warning was scheduled on the previous turnafterModel: hashes the latest tool-call batch, updates the sliding window, and decides whether to warn, stop, or throw
Quick Start
- Register the plugin:
PLUGINS=@xpert-ai/plugin-loop-guard - Add a middleware entry using strategy
LoopGuardMiddleware. - Start with the default configuration:
{ "type": "LoopGuardMiddleware", "options": { "warnThreshold": 3, "hardLimit": 5, "windowSize": 20, "onLoop": "end" } }
Configuration
| Field | Type | Description | Default |
| ----- | ---- | ----------- | ------- |
| warnThreshold | number | Repeated-batch count that schedules a warning for the next model turn. | 3 |
| hardLimit | number | Repeated-batch count that triggers hard-stop or error handling. | 5 |
| windowSize | number | Number of recent tracked batches kept in state. Must be at least hardLimit. | 20 |
| onLoop | "continue" | "end" | "error" | Hard-limit behavior. | "end" |
| warningMessage | string | Optional override for the next-turn warning. | built-in |
| hardStopMessage | string | Optional override for the final stop message. | built-in |
Built-in ignored arg keys are always applied:
idrequestIdtraceIdtimestamptimenonce
Behaviors
continue- keeps warning-only semantics even after the hard limit is reached
- never depends on
jumpTo: "model"
end- warns on the next turn at
warnThreshold - clears the current
tool_callsand appends a finalAIMessageathardLimit
- warns on the next turn at
error- warns on the next turn at
warnThreshold - throws
LoopGuardTriggeredErrorathardLimit
- warns on the next turn at
Notes
- Detection is based on normalized tool batches, not individual
tool_call_idvalues. - Multi-tool batches are sorted before hashing, so reordered but otherwise identical batches are treated as the same pattern.
- This middleware no longer uses result-based loop heuristics such as "same result window".
Development
NX_DAEMON=false pnpm -C /path/to/xpert-plugins/xpertai exec jest middlewares/loop-guard/src/lib/loopGuard.spec.ts --config middlewares/loop-guard/jest.config.cjs --runInBand
NX_DAEMON=false pnpm -C /path/to/xpert-plugins/xpertai exec tsc -b middlewares/loop-guard/tsconfig.lib.json