From eb7dd2a8d6fae4ffccb0f08509587f7b3f49b945 Mon Sep 17 00:00:00 2001 From: dingyi Date: Fri, 21 Aug 2026 22:53:05 +0800 Subject: [PATCH] fix(adapters): filter empty text parts in message conversion --- packages/adapter-claude/src/utils.ts | 10 ++++++---- packages/adapter-gemini/src/utils.ts | 6 ++++-- packages/shared-adapter/src/utils.ts | 6 +++++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/adapter-claude/src/utils.ts b/packages/adapter-claude/src/utils.ts index 7769003e8..f281e8c1e 100644 --- a/packages/adapter-claude/src/utils.ts +++ b/packages/adapter-claude/src/utils.ts @@ -320,10 +320,12 @@ async function processMessageContent( await Promise.all( content.map(async (message) => { if (message.type === 'text') { - return { - type: 'text', - text: message.text as string - } as const + return message.text.length > 0 + ? { + type: 'text', + text: message.text as string + } + : null } if (isMessageContentImageUrl(message)) { diff --git a/packages/adapter-gemini/src/utils.ts b/packages/adapter-gemini/src/utils.ts index 37124a6f2..90456c475 100644 --- a/packages/adapter-gemini/src/utils.ts +++ b/packages/adapter-gemini/src/utils.ts @@ -87,7 +87,9 @@ export async function langchainMessageToGeminiMessage( message.additional_kwargs['thought_data'] ?? {} const parts = typeof message.content === 'string' - ? [{ text: message.content }] + ? message.content.length > 0 + ? [{ text: message.content }] + : [] : await processGeminiContentParts(plugin, message.content) item.parts = [...getContextParts(thoughtData), ...parts] @@ -359,7 +361,7 @@ async function processGeminiContentParts( const mappedParts = await Promise.all( content.map(async (part) => { if (isMessageContentText(part)) { - return { text: part.text } + return part.text.length > 0 ? { text: part.text } : null } if (isMessageContentImageUrl(part)) { return await processGeminiImageContent(plugin, part) diff --git a/packages/shared-adapter/src/utils.ts b/packages/shared-adapter/src/utils.ts index 99739905c..fa0825fb3 100644 --- a/packages/shared-adapter/src/utils.ts +++ b/packages/shared-adapter/src/utils.ts @@ -34,7 +34,8 @@ import { logger } from 'koishi-plugin-chatluna' import { getImageMimeType, getMimeTypeFromSource, - isMessageContentImageUrl + isMessageContentImageUrl, + isMessageContentText } from 'koishi-plugin-chatluna/utils/string' import { isChatLunaUserMessage, @@ -447,6 +448,9 @@ export async function langchainMessageToOpenAIMessage( supportImageInputType === true const mappedContent = await Promise.all( msg.content.map(async (content) => { + if (isMessageContentText(content)) { + return content.text.length > 0 ? content : null + } if (isMessageContentImageUrl(content)) { if (!supportsImage) { logger.warn(