From 5abf8c1f5ed7b2ebe4c1757606067ae1d73e7712 Mon Sep 17 00:00:00 2001 From: vvky Date: Sat, 12 Jul 2025 22:19:30 +0800 Subject: [PATCH] fix: correctly remove outermost code block markers in model responses (fix markdown rendering issue) (#386) * fix: correctly remove outermost code block markers in frontend * fix: correctly remove outermost quote block markers in 'dropMarkdownQuote' * fix: correctly remove outermost quote block markers in 'dropMarkdownQuote' * fix: correctly remove outermost quote block markers in 'dropMarkdownQuote' --------- Co-authored-by: Willem Jiang --- web/src/components/deer-flow/markdown.tsx | 52 +++++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/web/src/components/deer-flow/markdown.tsx b/web/src/components/deer-flow/markdown.tsx index 5f7e253..0a81958 100644 --- a/web/src/components/deer-flow/markdown.tsx +++ b/web/src/components/deer-flow/markdown.tsx @@ -122,11 +122,47 @@ function processKatexInMarkdown(markdown?: string | null) { return markdownWithKatexSyntax; } -function dropMarkdownQuote(markdown?: string | null) { - if (!markdown) return markdown; - return markdown - .replace(/^```markdown\n/gm, "") - .replace(/^```text\n/gm, "") - .replace(/^```\n/gm, "") - .replace(/\n```$/gm, ""); -} +function dropMarkdownQuote(markdown?: string | null): string | null { + if (!markdown) return null; + + const patternsToRemove = [ + { prefix: "```markdown\n", suffix: "\n```", prefixLen: 12 }, + { prefix: "```text\n", suffix: "\n```", prefixLen: 8 }, + { prefix: "```\n", suffix: "\n```", prefixLen: 4 }, + ]; + + let result = markdown; + + for (const { prefix, suffix, prefixLen } of patternsToRemove) { + if (result.startsWith(prefix) && !result.endsWith(suffix)) { + result = result.slice(prefixLen); + break; // remove prefix without suffix only once + } + } + + let changed = true; + + while (changed) { + changed = false; + + for (const { prefix, suffix, prefixLen } of patternsToRemove) { + let startIndex = 0; + while ((startIndex = result.indexOf(prefix, startIndex)) !== -1) { + const endIndex = result.indexOf(suffix, startIndex + prefixLen); + if (endIndex !== -1) { + // only remove fully matched code blocks + const before = result.slice(0, startIndex); + const content = result.slice(startIndex + prefixLen, endIndex); + const after = result.slice(endIndex + suffix.length); + result = before + content + after; + changed = true; + startIndex = before.length + content.length; + } else { + startIndex += prefixLen; + } + } + } + } + + return result; +} \ No newline at end of file