From b4ad6f15de3ffc8e4cf6ad57f8498f38d2059f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Thu, 9 Apr 2026 20:52:00 +0800 Subject: [PATCH] fix(adapters): ensure placeholder cleanup on message_complete When all buffered text has already been flushed via periodic timer, buf.complete() calls flush(true) which returns early on empty buffer, skipping the onFlush callback that cleans up placeholder state. This causes subsequent messages to keep editing the old completed message instead of creating a new one. Add explicit placeholder cleanup in message_complete handler as a safety net, matching the same pattern used for tool_use finalization. Co-Authored-By: Claude Opus 4.6 (1M context) --- adapters/feishu/index.ts | 10 ++++++++++ adapters/telegram/index.ts | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/adapters/feishu/index.ts b/adapters/feishu/index.ts index 3fac0f9a..a688a8b3 100644 --- a/adapters/feishu/index.ts +++ b/adapters/feishu/index.ts @@ -333,6 +333,16 @@ async function handleServerMessage(chatId: string, msg: ServerMessage): Promise< case 'message_complete': await buf.complete() + // Ensure state is always cleaned up even if buffer was already empty + if (state.replyMessageId) { + const text = accumulatedText.get(chatId) + if (text?.trim()) { + await patchMessage(state.replyMessageId, text) + } + accumulatedText.delete(chatId) + chatStates.delete(chatId) + buffers.get(chatId)?.reset() + } break case 'error': diff --git a/adapters/telegram/index.ts b/adapters/telegram/index.ts index 3fc62385..b6fc8c11 100644 --- a/adapters/telegram/index.ts +++ b/adapters/telegram/index.ts @@ -236,6 +236,22 @@ async function handleServerMessage(chatId: string, msg: ServerMessage): Promise< case 'message_complete': await buf.complete() + // Ensure placeholder is always cleaned up even if buffer was already empty + if (placeholders.has(chatId)) { + const text = accumulatedText.get(chatId) + if (text?.trim()) { + try { + const chunks = splitMessage(text, TELEGRAM_TEXT_LIMIT) + await bot.api.editMessageText(numericChatId, placeholders.get(chatId)!.messageId, chunks[0]!) + for (let i = 1; i < chunks.length; i++) { + await bot.api.sendMessage(numericChatId, chunks[i]!) + } + } catch { /* ignore */ } + } + placeholders.delete(chatId) + accumulatedText.delete(chatId) + buffers.get(chatId)?.reset() + } break case 'error':