From e35095fe3cd0d24ca026b699b409445434fb663d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Wed, 25 Mar 2026 08:03:46 +0100 Subject: [PATCH] Reset tool loop detector after degenerate loop error When a degenerate tool call loop is detected, reset the loop detector so that the user can resume the conversation without immediately hitting the same error on the next tool call. Assisted-By: docker-agent --- pkg/runtime/loop.go | 1 + pkg/runtime/tool_loop_detector.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pkg/runtime/loop.go b/pkg/runtime/loop.go index e6a643d8b..fe5f11283 100644 --- a/pkg/runtime/loop.go +++ b/pkg/runtime/loop.go @@ -352,6 +352,7 @@ func (r *LocalRuntime) RunStream(ctx context.Context, sess *session.Session) <-c loopDetector.consecutive, toolName) events <- Error(errMsg) r.executeNotificationHooks(ctx, a, sess.ID, "error", errMsg) + loopDetector.reset() return } diff --git a/pkg/runtime/tool_loop_detector.go b/pkg/runtime/tool_loop_detector.go index 3eeb3f70b..324a2e881 100644 --- a/pkg/runtime/tool_loop_detector.go +++ b/pkg/runtime/tool_loop_detector.go @@ -24,6 +24,12 @@ func newToolLoopDetector(threshold int) *toolLoopDetector { return &toolLoopDetector{threshold: threshold} } +// reset clears the detector state so it can be reused after recovery. +func (d *toolLoopDetector) reset() { + d.lastSignature = "" + d.consecutive = 0 +} + // record updates the detector with the latest tool call batch and returns // true if the consecutive-duplicate threshold has been reached. func (d *toolLoopDetector) record(calls []tools.ToolCall) bool {