From 02899ce69f6bc0ef148ef473cf5d877a8b859578 Mon Sep 17 00:00:00 2001 From: Askhz <1361267452@qq.com> Date: Fri, 15 May 2026 17:58:53 +0800 Subject: [PATCH] fix(serve): skip thinking-only message fragments to prevent duplicate response in cs-cloud normalizeMessages() splits a multi-block AssistantMessage (e.g. [thinking, text]) into one message per content block. When serve mode emits both the thinking-only fragment and the text message as separate session.message events, cs-cloud's adaptMessageEvent creates two assistant messages (one via the streaming path, one via the non-streaming path), causing the response to appear twice in the UI. Fix: skip thinking-only normalized messages in normalizeMessage(), since the thinking content is already rendered via the stream_event path. Co-Authored-By: claude-sonnet-4-6 --- src/utils/queryHelpers.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/utils/queryHelpers.ts b/src/utils/queryHelpers.ts index 94dbb7404..ae5f2fabf 100644 --- a/src/utils/queryHelpers.ts +++ b/src/utils/queryHelpers.ts @@ -26,7 +26,7 @@ import { createFileStateCacheWithSizeLimit, type FileStateCache, } from './fileStateCache.js' -import { isNotEmptyMessage, normalizeMessages } from './messages.js' +import { isNotEmptyMessage, isThinkingMessage, normalizeMessages } from './messages.js' import { expandPath } from './path.js' import type { inputSchema as permissionToolInputSchema, @@ -117,6 +117,13 @@ export function* normalizeMessage(message: Message): Generator { if (!isNotEmptyMessage(_)) { continue } + // Skip thinking-only messages: normalizeMessages splits a multi-block + // AssistantMessage (e.g. [thinking, text]) into one message per block. + // Emitting the thinking-only fragment causes serve mode to send a second + // session.message event, which cs-cloud renders as a duplicate response. + if (isThinkingMessage(_)) { + continue + } yield { type: 'assistant', message: _.message,