Skip to content

fix(loop-detection): escalate generic_repeat to critical at criticalThreshold#60248

Closed
jwchmodx wants to merge 2 commits into
openclaw:mainfrom
jwchmodx:fix/generic-repeat-critical-threshold
Closed

fix(loop-detection): escalate generic_repeat to critical at criticalThreshold#60248
jwchmodx wants to merge 2 commits into
openclaw:mainfrom
jwchmodx:fix/generic-repeat-critical-threshold

Conversation

@jwchmodx

@jwchmodx jwchmodx commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #60111.

The generic_repeat detector only checked warningThreshold and always returned level: "warning", making criticalThreshold a no-op for the most common runaway loop pattern (same tool, same arguments, repeated calls).

  • Added a criticalThreshold check in the generic_repeat code path, before the existing warningThreshold check
  • Updated the test that was asserting the broken warn-only behavior to assert the correct critical escalation

This makes generic_repeat consistent with known_poll_no_progress and ping_pong, which both escalate to "critical" at criticalThreshold.

Detector warningThreshold criticalThreshold
known_poll_no_progress ⚠️ Warns ✅ Blocks
ping_pong ⚠️ Warns ✅ Blocks (with noProgressEvidence)
generic_repeat (before) ⚠️ Warns ❌ Not checked
generic_repeat (after) ⚠️ Warns ✅ Blocks

Test plan

  • Existing 29 tests pass
  • Updated test now asserts level: "critical" and detector: "generic_repeat" at criticalThreshold

🤖 Generated with Claude Code

@greptile-apps

greptile-apps Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR correctly fixes the generic_repeat loop detector so it escalates to "critical" at criticalThreshold (previously it only ever returned "warning"), making it consistent with the known_poll_no_progress and ping_pong detectors. It also bundles an unrelated fix in extensions/mattermost that prevents DM replies from being threaded by adding a required kind: ChatType guard to resolveMattermostReplyRootId; all three call sites are updated and new tests cover the DM-gating behavior.

Confidence Score: 5/5

Safe to merge — logic is correct, all call sites are updated, and only P2 suggestions remain.

No P0 or P1 issues found. The critical-threshold check for generic_repeat is correctly ordered before the warning check, matching the established pattern. The mattermost DM threading guard is complete and tested. Remaining comments are style suggestions only.

No files require special attention.

Comments Outside Diff (1)

  1. extensions/mattermost/src/mattermost/monitor.ts, line 160-173 (link)

    P2 Unrelated fix bundled without PR description coverage

    The kind: ChatType parameter addition to resolveMattermostReplyRootId — preventing DM threading — is a separate behaviour fix not mentioned in the PR description or summary. Since the function is exported, reviewers need to know it was intentionally included and that all three call sites (lines 536, 744, 1456) were updated. The change itself is correct, but it would be worth adding a note in the PR description so it can be tracked against the issue it resolves.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/mattermost/src/mattermost/monitor.ts
    Line: 160-173
    
    Comment:
    **Unrelated fix bundled without PR description coverage**
    
    The `kind: ChatType` parameter addition to `resolveMattermostReplyRootId` — preventing DM threading — is a separate behaviour fix not mentioned in the PR description or summary. Since the function is `export`ed, reviewers need to know it was intentionally included and that all three call sites (lines 536, 744, 1456) were updated. The change itself is correct, but it would be worth adding a note in the PR description so it can be tracked against the issue it resolves.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/tool-loop-detection.test.ts
Line: 302-316

Comment:
**Missing count assertion in updated test**

The renamed test now asserts `level: "critical"` and `detector: "generic_repeat"`, but the previous test also checked `result.count`. Adding `expect(loopResult.count).toBe(CRITICAL_THRESHOLD)` would keep coverage parity with the existing warning-level test (line 296) and pin the count value returned by the new critical path.

```suggestion
      expect(loopResult.stuck).toBe(true);
      if (loopResult.stuck) {
        expect(loopResult.level).toBe("critical");
        expect(loopResult.detector).toBe("generic_repeat");
        expect(loopResult.count).toBe(CRITICAL_THRESHOLD);
        expect(loopResult.message).toContain("CRITICAL");
      }
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/mattermost/src/mattermost/monitor.ts
Line: 160-173

Comment:
**Unrelated fix bundled without PR description coverage**

The `kind: ChatType` parameter addition to `resolveMattermostReplyRootId` — preventing DM threading — is a separate behaviour fix not mentioned in the PR description or summary. Since the function is `export`ed, reviewers need to know it was intentionally included and that all three call sites (lines 536, 744, 1456) were updated. The change itself is correct, but it would be worth adding a note in the PR description so it can be tracked against the issue it resolves.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(loop-detection): escalate generic_re..." | Re-trigger Greptile

Comment thread src/agents/tool-loop-detection.test.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e02478669a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/tool-loop-detection.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a02183ce7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/infra/provider-usage.fetch.minimax.ts
jwchmodx and others added 2 commits April 28, 2026 07:37
…hreshold

The generic_repeat detector only checked warningThreshold and always
returned level "warning", making criticalThreshold effectively a no-op
for the most common runaway loop pattern (same tool + same args).

Add a critical-threshold check before the warning check, consistent
with how known_poll_no_progress and ping_pong already behave.

Fixes openclaw#60111

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@vincentkoc
vincentkoc force-pushed the fix/generic-repeat-critical-threshold branch from 9a02183 to 9fd4b85 Compare April 28, 2026 07:37
@vincentkoc

Copy link
Copy Markdown
Member

ProjectClownfish pushed a narrow repair to this branch so the original contributor path can stay canonical.

Source PR: #60248
Validation: pnpm test src/agents/tool-loop-detection.test.ts -- --reporter=dot; pnpm check:changed
Contributor credit is preserved in the branch history and PR context.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation agents Agent runtime and tooling size: S labels Apr 28, 2026
@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I did a careful shell check against current main, and this is already implemented.

Current main already contains the complete no-progress-gated generic_repeat critical escalation, with unit, before-tool-call e2e, diagnostic, docs, changelog, and release-note coverage from the merged replacement PR.

So I’m closing this as already implemented rather than keeping a duplicate issue open.

Review details

Best possible solution:

Keep the merged current-main implementation from #80668 and close this superseded contributor branch instead of merging a narrower stale diff.

Do we have a high-confidence way to reproduce the issue?

Yes for the original bug: the detector/test path around repeated same-tool calls showed the warning-only gap before the fix. On current main, that failure no longer reproduces because the source and e2e tests now cover generic_repeat critical blocking for identical outcomes.

Is this the best way to solve the issue?

Yes. The current-main implementation is the narrow maintainable solution because it blocks only repeated no-progress outcomes and includes the before-tool-call e2e/diagnostic coverage this PR was missing.

Security review:

Security review cleared: The reviewed PR and merged replacement only affect loop-detection behavior, tests, docs, and changelog, with no dependency, CI, secret, install, or package execution changes.

What I checked:

Likely related people:

  • frankekn: Merged PR fix: abort generic no-progress tool loops #80668 implemented the no-progress-gated generic repeat block and touched the central detector, tests, e2e, docs, and changelog paths. (role: current fix author and merger; confidence: high; commits: cffba00372f3, 7fa287cd0f88, 678b2510b22c; files: src/agents/tool-loop-detection.ts, src/agents/tool-loop-detection.test.ts, src/agents/pi-tools.before-tool-call.e2e.test.ts)
  • steipete: Repository history for commit 076df94 identifies the original configurable tool loop detection work that created this detector/config surface. (role: introduced behavior; confidence: medium; commits: 076df941a326; files: src/agents/tool-loop-detection.ts, docs/tools/loop-detection.md)
  • vincentkoc: The PR discussion records a narrow repair pushed to this branch to keep the contributor path canonical, changing the generic repeat behavior to require no-progress evidence. (role: branch repair contributor; confidence: medium; commits: 9fd4b85d9a4b; files: src/agents/tool-loop-detection.ts, src/agents/tool-loop-detection.test.ts, docs/tools/loop-detection.md)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 3e425dde0d62; fix evidence: release v2026.5.12-beta.1, commit 678b2510b22c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling clawsweeper Tracked by ClawSweeper automation docs Improvements or additions to documentation size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: generic_repeat loop detector never escalates to blocking — criticalThreshold has no effect

2 participants