From 602ee4054bcd9502f612f881fdd16f4d4c81943d Mon Sep 17 00:00:00 2001 From: zmf Date: Wed, 1 Jul 2026 09:35:13 +0700 Subject: [PATCH] fix(codebuddy-cn): strip empty tool_calls arrays to preserve reasoning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeBuddy CN includes "tool_calls": [] in every SSE streaming delta. @ai-sdk/openai-compatible checks delta.tool_calls != null — an empty array passes ([] != null is true in JS), triggering premature reasoning-end on every reasoning chunk (0/1ms durations in OpenCode). Strip empty tool_calls arrays in passthrough before hasValuableContent. Zero side-effect: real tool_calls always have at least one element. Closes #2176 Co-authored-by: Cursor --- open-sse/utils/stream.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/open-sse/utils/stream.js b/open-sse/utils/stream.js index aea96147..7ce372db 100644 --- a/open-sse/utils/stream.js +++ b/open-sse/utils/stream.js @@ -130,6 +130,20 @@ export function createSSEStream(options = {}) { } } + // Strip empty tool_calls arrays that break AI SDK reasoning tracking. + // Some providers (e.g. CodeBuddy CN) include `"tool_calls": []` in + // every streaming delta. @ai-sdk/openai-compatible checks + // `delta.tool_calls != null` — an empty array passes this check, + // causing premature `reasoning-end` on every chunk. + if (parsed?.choices) { + for (const choice of parsed.choices) { + if (choice.delta?.tool_calls && Array.isArray(choice.delta.tool_calls) && choice.delta.tool_calls.length === 0) { + delete choice.delta.tool_calls; + fieldsInjected = true; + } + } + } + if (!hasValuableContent(parsed, FORMATS.OPENAI)) { continue; }