From da09d54c292f448cb3c3f7604b4f63955fa28f81 Mon Sep 17 00:00:00 2001 From: neorrk <58256328+neorrk@users.noreply.github.com> Date: Mon, 16 Feb 2026 22:24:05 +0100 Subject: [PATCH] fix: prevent pWaitFor hang on reasoning-only responses When a thinking model returns only reasoning_content (no text, no tool calls), assistantMessageContent is empty. Since no content blocks exist, presentAssistantMessage is never called and userMessageContentReady is never set to true, causing pWaitFor to block indefinitely. The fix sets userMessageContentReady = true directly when assistantMessageContent is empty, allowing the flow to proceed to the didToolUse check which will correctly prompt the model to use tools. Addresses second review from @roomote. Co-Authored-By: Claude Opus 4.6 --- src/core/task/Task.ts | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 4d4bb49d55..0e4f921592 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -3565,21 +3565,14 @@ export class Task extends EventEmitter implements TaskLike { } if (hasTextContent || hasToolUses || hasReasoningContent) { - // NOTE: This comment is here for future reference - this was a - // workaround for `userMessageContent` not getting set to true. - // It was due to it not recursively calling for partial blocks - // when `didRejectTool`, so it would get stuck waiting for a - // partial block to complete before it could continue. - // In case the content blocks finished it may be the api stream - // finished after the last parsed content block was executed, so - // we are able to detect out of bounds and set - // `userMessageContentReady` to true (note you should not call - // `presentAssistantMessage` since if the last block i - // completed it will be presented again). - // const completeBlocks = this.assistantMessageContent.filter((block) => !block.partial) // If there are any partial blocks after the stream ended we can consider them invalid. - // if (this.currentStreamingContentIndex >= completeBlocks.length) { - // this.userMessageContentReady = true - // } + // When the model produces only reasoning content (no text blocks, + // no tool uses), assistantMessageContent is empty. In that case, + // presentAssistantMessage is never called, so userMessageContentReady + // would never be set to true. We must set it directly to avoid + // blocking forever on the pWaitFor below. + if (this.assistantMessageContent.length === 0) { + this.userMessageContentReady = true + } await pWaitFor(() => this.userMessageContentReady)