From 81005c39f94435cf8459fbbc119de39c24cb9afc Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 22 Apr 2026 16:24:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(desktop):=20=E4=BF=AE=E5=A4=8D=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E7=BB=93=E6=9E=9C=E6=8E=92=E7=89=88=20=E2=80=94=20str?= =?UTF-8?q?ipToolNarration=20=E4=BF=9D=E7=95=99=20markdown=20=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: stripToolNarration 按句子切分再用空格拼接,破坏了所有 markdown 格式(标题/列表/段落/代码块),导致搜索结果显示为纯文本墙。 修复: 改为按行处理,只过滤匹配叙述模式的行,保留 markdown 结构行 (标题/列表/空行/引用/代码/表格)。关键变化: - 保留空行(markdown 段落分隔符) - 保留以 #/-/*/数字/>/```/| 开头的结构行 - 仅过滤 LLM 内部叙述("让我执行..."、"Let me..."等) --- desktop/src/components/ChatArea.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/desktop/src/components/ChatArea.tsx b/desktop/src/components/ChatArea.tsx index b601a4a..6af5475 100644 --- a/desktop/src/components/ChatArea.tsx +++ b/desktop/src/components/ChatArea.tsx @@ -643,10 +643,14 @@ export function ChatArea({ compact, onOpenDetail }: { compact?: boolean; onOpenD * and Chinese ("让我执行...", "让我尝试..."). These are internal thoughts, not user-facing content. */ function stripToolNarration(content: string): string { - const sentences = content.split(/(?<=[。!?.!?])\s*/); - const filtered = sentences.filter(s => { - const t = s.trim(); - if (!t) return false; + // Process line-by-line to preserve markdown structure (headings, lists, paragraphs) + const lines = content.split('\n'); + const filtered = lines.filter(line => { + const t = line.trim(); + // Keep empty lines (paragraph breaks in markdown) + if (!t) return true; + // Keep markdown structural lines (headings, list items, horizontal rules, blockquotes, code) + if (/^(#{1,6}\s|[-*+]\s|\d+\.\s|>|\s*```|---|\|)/.test(t)) return true; // English narration patterns if (/^(?:Now )?[Ll]et me\s/i.test(t)) return false; if (/^I\s+(?:need to|keep getting|should|will try|have to|can try|must)\s/i.test(t)) return false; @@ -656,8 +660,8 @@ function stripToolNarration(content: string): string { if (/^好的,让我为您/.test(t)) return false; return true; }); - const result = filtered.join(' ').replace(/\s{2,}/g, ' ').trim(); - return result || content; // Fallback: if everything was stripped, show original + const result = filtered.join('\n'); + return result || content; } function MessageBubble({ message, onRetry }: { message: Message; setInput?: (text: string) => void; onRetry?: () => void }) {