diff --git a/src/renderer/components/chat-area.ts b/src/renderer/components/chat-area.ts index 58453eb..2f091d1 100644 --- a/src/renderer/components/chat-area.ts +++ b/src/renderer/components/chat-area.ts @@ -338,6 +338,64 @@ function renderToolCallCard(tc: ToolCallRecord): string { `; } +/** + * 流式 Markdown 智能补全:检测并修复流式传输中不完整的 Markdown 语法 + * - 未闭合的代码块(``` / ~~~)→ 追加闭合标记 + * - 未闭合的行内代码(`)→ 追加闭合 ` + * - 未闭合的粗体(**)→ 追加闭合 ** + * 返回补全后的字符串(不修改原始内容,仅用于渲染) + */ +function patchIncompleteMarkdown(md: string): string { + let patched = md; + + // ── 代码块围栏检测(``` 或 ~~~)── + // 统计未闭合的围栏对 + const fenceRegex = /^([`~]{3,})/gm; + const openFences: string[] = []; + let match: RegExpExecArray | null; + while ((match = fenceRegex.exec(patched)) !== null) { + openFences.push(match[1]); + } + // 如果有奇数个围栏,说明最后一个未闭合 + if (openFences.length % 2 === 1) { + const lastFence = openFences[openFences.length - 1]; + patched += '\n' + lastFence; + } + + // ── 行内代码反引号检测(仅当不在代码块内时才有意义)── + // 简化处理:统计不在代码围栏内的奇数个反引号 + // 这里用一个保守的检测:如果末尾有奇数个 `(且不是围栏),补一个 + const inlineBackticks = (patched.match(/(?