diff --git a/CHANGELOG.md b/CHANGELOG.md index e3b8fd6e3f1..3fc07ffb059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,9 @@ Docs: https://docs.openclaw.ai ### Fixes +- Docs/tool-loop detection config keys: align `docs/tools/loop-detection.md` examples and field names with the current `tools.loopDetection` schema to prevent copy-paste validation failures from outdated keys. (#33182) Thanks @Mylszd. - Telegram/DM draft finalization reliability: require verified final-text draft emission before treating preview finalization as delivered, and fall back to normal payload send when final draft delivery is not confirmed (preventing missing final responses and preserving media/button delivery). (#32118) Thanks @OpenCils. -- Discord/audit wildcard warnings: ignore "*" wildcard keys when counting unresolved guild channels so doctor/status no longer warns on allow-all configs. (#33125) Thanks @thewilloftheshadow. +- Discord/audit wildcard warnings: ignore "\*" wildcard keys when counting unresolved guild channels so doctor/status no longer warns on allow-all configs. (#33125) Thanks @thewilloftheshadow. - Discord/channel resolution: default bare numeric recipients to channels, harden allowlist numeric ID handling with safe fallbacks, and avoid inbound WS heartbeat stalls. (#33142) Thanks @thewilloftheshadow. - Exec heartbeat routing: scope exec-triggered heartbeat wakes to agent session keys so unrelated agents are no longer awakened by exec events, while preserving legacy unscoped behavior for non-canonical session keys. (#32724) thanks @altaywtf - macOS/Tailscale remote gateway discovery: add a Tailscale Serve fallback peer probe path (`wss://.ts.net`) when Bonjour and wide-area DNS-SD discovery return no gateways, and refresh both discovery paths from macOS onboarding. (#32860) Thanks @ngutman. diff --git a/docs/tools/loop-detection.md b/docs/tools/loop-detection.md index f41eeb0851b..56d843f1276 100644 --- a/docs/tools/loop-detection.md +++ b/docs/tools/loop-detection.md @@ -30,14 +30,14 @@ Global defaults: tools: { loopDetection: { enabled: false, - historySize: 20, - detectorCooldownMs: 12000, - repeatThreshold: 3, - criticalThreshold: 6, + historySize: 30, + warningThreshold: 10, + criticalThreshold: 20, + globalCircuitBreakerThreshold: 30, detectors: { - repeatedFailure: true, - knownPollLoop: true, - repeatingNoProgress: true, + genericRepeat: true, + knownPollNoProgress: true, + pingPong: true, }, }, }, @@ -55,8 +55,8 @@ Per-agent override (optional): tools: { loopDetection: { enabled: true, - repeatThreshold: 2, - criticalThreshold: 5, + warningThreshold: 8, + criticalThreshold: 16, }, }, }, @@ -69,18 +69,20 @@ Per-agent override (optional): - `enabled`: Master switch. `false` means no loop detection is performed. - `historySize`: number of recent tool calls kept for analysis. -- `detectorCooldownMs`: time window used by the no-progress detector. -- `repeatThreshold`: minimum repeats before warning/blocking starts. -- `criticalThreshold`: stronger threshold that can trigger stricter handling. -- `detectors.repeatedFailure`: detects repeated failed attempts on the same call path. -- `detectors.knownPollLoop`: detects known polling-like loops. -- `detectors.repeatingNoProgress`: detects high-frequency repeated calls without state change. +- `warningThreshold`: threshold before classifying a pattern as warning-only. +- `criticalThreshold`: threshold for blocking repetitive loop patterns. +- `globalCircuitBreakerThreshold`: global no-progress breaker threshold. +- `detectors.genericRepeat`: detects repeated same-tool + same-params patterns. +- `detectors.knownPollNoProgress`: detects known polling-like patterns with no state change. +- `detectors.pingPong`: detects alternating ping-pong patterns. ## Recommended setup - Start with `enabled: true`, defaults unchanged. +- Keep thresholds ordered as `warningThreshold < criticalThreshold < globalCircuitBreakerThreshold`. - If false positives occur: - - raise `repeatThreshold` and/or `criticalThreshold` + - raise `warningThreshold` and/or `criticalThreshold` + - (optionally) raise `globalCircuitBreakerThreshold` - disable only the detector causing issues - reduce `historySize` for less strict historical context diff --git a/src/discord/monitor/message-handler.preflight.test.ts b/src/discord/monitor/message-handler.preflight.test.ts index ec67c208a7e..69e6ca2e898 100644 --- a/src/discord/monitor/message-handler.preflight.test.ts +++ b/src/discord/monitor/message-handler.preflight.test.ts @@ -85,7 +85,6 @@ describe("preflightDiscordMessage", () => { it("drops bound-thread bot system messages to prevent ACP self-loop", async () => { const threadBinding = createThreadBinding({ - targetKind: "acp", targetSessionKey: "agent:main:acp:discord-thread-1", }); const threadId = "thread-system-1"; @@ -172,7 +171,6 @@ describe("preflightDiscordMessage", () => { it("keeps bound-thread regular bot messages flowing when allowBots=true", async () => { const threadBinding = createThreadBinding({ - targetKind: "acp", targetSessionKey: "agent:main:acp:discord-thread-1", }); const threadId = "thread-bot-regular-1";