From a8fb4d893217dd9f180b50a3feb81c9614e99a5c Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Mon, 17 Nov 2025 17:36:45 -0500 Subject: [PATCH 1/2] fix: prevent infinite loop when attempt_completion succeeds When attempt_completion was called and the user clicked 'Yes' to mark the task complete, pushToolResult("") was adding an empty tool_result to userMessageContent. This triggered Task.ts:2609 to create a NEW API request with the empty result, causing the task to continue indefinitely with additional tool calls. Root Cause: - pushToolResult("") adds content to userMessageContent[] via presentAssistantMessage.ts:323-327 - Task.ts:2609 checks 'if (this.userMessageContent.length > 0)' and pushes to stack - This creates a new API request even though the task should end The Fix: Remove pushToolResult("") when task completes successfully. The tool_result is now only sent when the user provides feedback, which is the correct behavior for native protocol. Before (buggy): 1. attempt_completion called 2. User clicks Yes 3. pushToolResult("") -> triggers new API request 4. Model continues -> infinite loop After (fixed): 1. attempt_completion called 2. User clicks Yes 3. NO pushToolResult("") -> task stops (correct) When user provides feedback: 1. attempt_completion called 2. User provides feedback 3. pushToolResult(feedback) -> new API request with feedback (correct) This also fixes a related 400 error where duplicate tool results could occur when users sent messages after task completion. The bug was introduced in commit 5e6e601b0a (native tool support PR) where the empty tool_result was meant as a 'stop signal' but was being treated as real content. --- src/core/tools/AttemptCompletionTool.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/tools/AttemptCompletionTool.ts b/src/core/tools/AttemptCompletionTool.ts index 8a7695748b3..e2e7a95f334 100644 --- a/src/core/tools/AttemptCompletionTool.ts +++ b/src/core/tools/AttemptCompletionTool.ts @@ -83,10 +83,11 @@ export class AttemptCompletionTool extends BaseTool<"attempt_completion"> { const { response, text, images } = await task.ask("completion_result", "", false) if (response === "yesButtonClicked") { - pushToolResult("") + // Task completed successfully - don't push tool result to prevent loop continuation return } + // User provided feedback - push tool result to continue the conversation await task.say("user_feedback", text ?? "", images) const feedbackText = `The user has provided feedback on the results. Consider their input to continue the task, and then attempt completion again.\n\n${text}\n` From 364671def0d7406f48e1e9aaa5db3547df15923e Mon Sep 17 00:00:00 2001 From: daniel-lxs Date: Mon, 17 Nov 2025 17:44:03 -0500 Subject: [PATCH 2/2] fix: remove comment to prevent infinite loop continuation in attempt_completion --- src/core/tools/AttemptCompletionTool.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/tools/AttemptCompletionTool.ts b/src/core/tools/AttemptCompletionTool.ts index e2e7a95f334..b2cac7c4f21 100644 --- a/src/core/tools/AttemptCompletionTool.ts +++ b/src/core/tools/AttemptCompletionTool.ts @@ -83,7 +83,6 @@ export class AttemptCompletionTool extends BaseTool<"attempt_completion"> { const { response, text, images } = await task.ask("completion_result", "", false) if (response === "yesButtonClicked") { - // Task completed successfully - don't push tool result to prevent loop continuation return }