From e3f6912d49d14b6e6ffe96bb053644922004ecf3 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 17 Apr 2026 16:59:00 +0200 Subject: [PATCH] fix(ai): preserve qwen chat-template thinking closes #3325 --- packages/ai/CHANGELOG.md | 1 + packages/ai/src/providers/openai-completions.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index cfdf9a3e..77cbb3ca 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixed - Fixed Anthropic and Bedrock adaptive-thinking payload tests to expect the default `display: "summarized"` field when reasoning is enabled. +- Fixed `qwen-chat-template` OpenAI-compatible requests to set `chat_template_kwargs.preserve_thinking: true`, preserving prior Qwen thinking across turns so multi-turn tool calls keep their arguments instead of degrading to empty `{}` payloads ([#3325](https://github.com/badlogic/pi-mono/issues/3325)) ## [0.67.6] - 2026-04-16 diff --git a/packages/ai/src/providers/openai-completions.ts b/packages/ai/src/providers/openai-completions.ts index e2ab39b1..77e76b18 100644 --- a/packages/ai/src/providers/openai-completions.ts +++ b/packages/ai/src/providers/openai-completions.ts @@ -422,7 +422,10 @@ function buildParams(model: Model<"openai-completions">, context: Context, optio } else if (compat.thinkingFormat === "qwen" && model.reasoning) { (params as any).enable_thinking = !!options?.reasoningEffort; } else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) { - (params as any).chat_template_kwargs = { enable_thinking: !!options?.reasoningEffort }; + (params as any).chat_template_kwargs = { + enable_thinking: !!options?.reasoningEffort, + preserve_thinking: true, + }; } else if (compat.thinkingFormat === "openrouter" && model.reasoning) { // OpenRouter normalizes reasoning across providers via a nested reasoning object. const openRouterParams = params as typeof params & { reasoning?: { effort?: string } };