From 5c5a893b50e36646292de1b598d642cd31842c3f Mon Sep 17 00:00:00 2001 From: Daniel <57051444+daniel-lxs@users.noreply.github.com> Date: Thu, 20 Nov 2025 20:31:49 -0500 Subject: [PATCH] Fix preserveReasoning flag to control API reasoning inclusion (#9453) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: store reasoning in conversation history for all providers * refactor: address review feedback - Move comments inside else block - Combine reasoning checks into single if block - Make comments more concise * refactor: make comments more concise * Fix preserveReasoning flag to control API reasoning inclusion Changes: 1. Removed hardcoded tag logic in streaming - Previously hardcoded reasoning into assistant message text - Now passes reasoning to addToApiConversationHistory as parameter 2. Updated buildCleanConversationHistory to respect preserveReasoning flag - When preserveReasoning: true → reasoning block included in API requests - When preserveReasoning: false/undefined → reasoning stripped from API - Reasoning stored in history for all cases 3. Added temporary debug logs to base-openai-compatible-provider.ts - Shows preserveReasoning flag value - Logs reasoning blocks in incoming messages - Logs tags in converted messages sent to API * Fix: Use api.getModel() directly instead of cachedStreamingModel Addresses review comment: cachedStreamingModel is set during streaming but buildCleanConversationHistory is called before streaming starts. Using the cached value could cause stale model info when switching models between requests. Now directly uses this.api.getModel().info.preserveReasoning to ensure we always check the current model's flag, not a potentially stale cached value. * Clean up comments in Task.ts Removed outdated comment regarding model's preserveReasoning flag. * fix: remove unnecessary reasoningBlock variable in task reasoning logic --- src/core/task/Task.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 919d59d125..c0de86aa95 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -2660,21 +2660,14 @@ export class Task extends EventEmitter implements TaskLike { }) } - // Check if we should preserve reasoning in the assistant message - let finalAssistantMessage = assistantMessage - if (reasoningMessage && streamModelInfo.preserveReasoning) { - // Prepend reasoning in XML tags to the assistant message so it's included in API history - finalAssistantMessage = `${reasoningMessage}\n${assistantMessage}` - } - // Build the assistant message content array const assistantContent: Array = [] // Add text content if present - if (finalAssistantMessage) { + if (assistantMessage) { assistantContent.push({ type: "text" as const, - text: finalAssistantMessage, + text: assistantMessage, }) } @@ -3439,15 +3432,24 @@ export class Task extends EventEmitter implements TaskLike { continue } else if (hasPlainTextReasoning) { - // Strip plain text reasoning, send assistant message only + // Check if the model's preserveReasoning flag is set + // If true, include the reasoning block in API requests + // If false/undefined, strip it out (stored for history only, not sent back to API) + const shouldPreserveForApi = this.api.getModel().info.preserveReasoning === true let assistantContent: Anthropic.Messages.MessageParam["content"] - if (rest.length === 0) { - assistantContent = "" - } else if (rest.length === 1 && rest[0].type === "text") { - assistantContent = (rest[0] as Anthropic.Messages.TextBlockParam).text + if (shouldPreserveForApi) { + // Include reasoning block in the content sent to API + assistantContent = contentArray } else { - assistantContent = rest + // Strip reasoning out - stored for history only, not sent back to API + if (rest.length === 0) { + assistantContent = "" + } else if (rest.length === 1 && rest[0].type === "text") { + assistantContent = (rest[0] as Anthropic.Messages.TextBlockParam).text + } else { + assistantContent = rest + } } cleanConversationHistory.push({