From be0cb021380d4f2f2a16aa67603008fd670c9dc3 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 18 Aug 2026 22:46:15 -0700 Subject: [PATCH] fix(telegram): hide spaced internal reasoning prefixes Co-authored-by: WangYan Punchcard-Session: amber-summit-river-a3 --- ...age-dispatch.reasoning-room-events.test.ts | 25 ++++++++++++++----- .../src/reasoning-lane-coordinator.test.ts | 19 +++++++++++--- .../src/reasoning-lane-coordinator.ts | 5 ++-- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/extensions/telegram/src/bot-message-dispatch.reasoning-room-events.test.ts b/extensions/telegram/src/bot-message-dispatch.reasoning-room-events.test.ts index 0e4273a074ae..27463e28711f 100644 --- a/extensions/telegram/src/bot-message-dispatch.reasoning-room-events.test.ts +++ b/extensions/telegram/src/bot-message-dispatch.reasoning-room-events.test.ts @@ -188,21 +188,34 @@ describeTelegramDispatch("dispatchTelegramMessage reasoning-room-events", () => expect(deliverReplies).not.toHaveBeenCalled(); }); - it("suppresses internal reflection when reasoning streams", async () => { - const { reasoningDraftStream } = setupDraftStreams({ + it("suppresses whitespace-form internal prefixes until one visible final", async () => { + const { answerDraftStream, reasoningDraftStream } = setupDraftStreams({ answerMessageId: 2001, reasoningMessageId: 3001, }); mockTurn(async ({ dispatcherOptions }) => { - await dispatcherOptions.deliver( - { text: "private reflection", isReasoning: true }, - { kind: "final" }, - ); + for (const text of [ + "< internal", + "< internal", + " { }); }); - it("does not emit partial reasoning tag prefixes", () => { - expect(splitTelegramReasoningText(" { + expect(splitTelegramReasoningText(text, true)).toStrictEqual({}); + }); + + it("keeps unrelated partial tags visible", () => { + expect(splitTelegramReasoningText("< interface", true)).toStrictEqual({ + reasoningText: "🧠 _< interface_", + }); }); it("keeps visible Thinking-prefixed answers in the answer lane", () => { diff --git a/extensions/telegram/src/reasoning-lane-coordinator.ts b/extensions/telegram/src/reasoning-lane-coordinator.ts index 2ecc25f8e4e0..e2e1e70aa342 100644 --- a/extensions/telegram/src/reasoning-lane-coordinator.ts +++ b/extensions/telegram/src/reasoning-lane-coordinator.ts @@ -1,7 +1,6 @@ // Telegram plugin module implements reasoning lane coordinator behavior. import { formatReasoningMessage } from "openclaw/plugin-sdk/agent-runtime"; import type { ReplyPayload } from "openclaw/plugin-sdk/reply-payload"; -import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime"; import { findCodeRegions, isInsideCode, @@ -71,14 +70,14 @@ function extractThinkingFromTaggedStreamOutsideCode(text: string): string { } function isPartialReasoningTagPrefix(text: string): boolean { - const trimmed = normalizeLowercaseStringOrEmpty(text.trimStart()); + const trimmed = text.trim().replace(/^<\s*(\/?)\s+/u, "<$1"); if (!trimmed.startsWith("<")) { return false; } if (trimmed.includes(">")) { return false; } - return REASONING_TAG_PREFIXES.some((prefix) => prefix.startsWith(trimmed)); + return REASONING_TAG_PREFIXES.some((prefix) => prefix.startsWith(trimmed.toLowerCase())); } type TelegramReasoningSplit = {