@theajmalrazaq/agentsloopguard
v0.1.0
Published
Framework-agnostic safety helpers for tool-calling LLM agent loops.
Downloads
19
Maintainers
Readme
agentsloopguard
agentsloopguard helps tool-calling LLM agents avoid repeated, expensive, or
non-productive loops.
It gives you reusable runtime safety helpers for:
- pruning stale tool results before the next step
- stripping orphaned assistant tool calls
- building stable tool-call signatures
- detecting repeated tool-call cycles
- detecting "tool-calls but no progress" loops
- extracting the latest successful tool summary for graceful fallbacks
Install
npm i @theajmalrazaq/agentsloopguardpnpm add @theajmalrazaq/agentsloopguardHow People Use It
You use this package inside your existing agent loop. It does not replace your LLM framework. Instead, it helps you decide when to keep going, when to stop, and how to recover a useful summary from the last successful tool step.
Typical use cases:
- AI SDK or custom agent loops with tool calling
- MCP or function-calling runtimes
- multi-step agents where repeated tool calls can waste tokens
- apps that need safer fallback behavior when a step budget is exhausted
Quick Start
import {
createLoopGuard,
getLatestToolSuccessSummary,
pruneToolResultMessages,
} from "@theajmalrazaq/agentsloopguard";
const guard = createLoopGuard({
maxNoProgressSteps: 3,
signatureHistory: 9,
});
const preparedMessages = pruneToolResultMessages(messages);
const decision = guard.observeStep({
finishReason: event.finishReason,
responseMessages: event.response.messages,
});
if (!decision.shouldContinue) {
const latest = getLatestToolSuccessSummary(history);
console.log({
reason: decision.reason,
fallbackSummary: latest?.summary ?? null,
});
}API
createLoopGuard(options?)
Creates a small stateful guard that tracks repeated signatures and no-progress steps.
const guard = createLoopGuard({
maxNoProgressSteps: 3,
signatureHistory: 9,
});guard.observeStep({ finishReason, responseMessages })
Inspects one agent step and tells you whether continuing is safe.
const result = guard.observeStep({
finishReason: "tool-calls",
responseMessages,
});
if (!result.shouldContinue) {
console.log(result.reason); // "loop-detected" | "no-progress"
}pruneToolResultMessages(messages, options?)
Shrinks older tool results so the latest step keeps useful context without carrying large stale payloads forever.
const compactMessages = pruneToolResultMessages(messages, {
latestLimit: 2500,
staleLimit: 180,
});stripOrphanedAssistantToolCalls(messages)
Removes assistant-side tool invocations that never received a matching tool result.
const sanitizedMessages = stripOrphanedAssistantToolCalls(uiMessages);inspectStepMessages(messages)
Builds normalized tool-call signatures and success/failure state for one step.
detectToolCallCycle(history)
Detects simple repeated loop patterns from a list of recent signatures.
getLatestToolSuccessSummary(messages)
Extracts the latest human-friendly summary from prior successful tool results so you can show a graceful fallback message if the loop stops early.
Status
This package is intentionally framework-agnostic in v0.1.0.
It does not yet include:
- a Vercel AI SDK adapter
- MCP-specific recovery plugins
- framework-specific integrations
Those can be layered on top later while keeping the core helpers stable.
