fix(rectification): stop re-parsing settled messages on every stream frame
Independent Staging Quality Gate / validate (push) Failing after 6m18s
Independent Staging Quality Gate / publish (push) Skipped

This commit is contained in:
jesse-ux
2026-09-16 07:13:12 +08:00
parent 53a37ce944
commit 58ccafb67c
25 changed files with 827 additions and 213 deletions
+18 -5
View File
@@ -4,7 +4,7 @@ import test from "node:test";
import { createElement } from "react";
import { renderToString } from "react-dom/server";
import { StreamingMarkdown } from "../src/components/chat-message-content.tsx";
import { StableMarkdownPrefix, StreamingMarkdown } from "../src/components/chat-message-content.tsx";
import { splitStableMarkdown } from "../src/lib/chat-markdown-split.ts";
const contentSource = readFileSync(new URL("../src/components/chat-message-content.tsx", import.meta.url), "utf8");
@@ -68,9 +68,22 @@ test("the streaming renderer parses the prefix and the tail as two separate docu
assert.match(contentSource, /const StableMarkdownPrefix = memo\(function StableMarkdownPrefix/);
assert.match(contentSource, /splitStableMarkdown\(text\)/);
assert.match(contentSource, /streaming\s*\?\s*<StreamingMarkdown/);
// 原值: `: renderMarkdown ? renderMarkdown(spoken)` 只给口语层走 markdown
// 新值: 口语层与报告层都走 `renderProse`
// 原因: 两层可见性后,折叠内外共用同一套解析,避免两套 fallback
assert.match(contentSource, /: renderProse\(spoken, renderMarkdown\)/);
// 原值: `: renderProse(spoken, renderMarkdown)` 结算口语层每次重渲都全量 parse
// 新值: 结算口语层走 `StableMarkdownPrefix`(按文本记忆 + 解析缓存)
// 原因: BUG-725 流式帧不得重跑已结算 Markdown
assert.match(contentSource, /: <StableMarkdownPrefix text=\{spoken\} renderMarkdown=\{renderMarkdown\} \/>/);
assert.match(messageRowSource, /streaming=\{message\.state !== "settled"\}/);
});
test("settled markdown parses the same text only once across consecutive renders", () => {
const calls: string[] = [];
const renderMarkdown = (text: string) => {
calls.push(text);
return createElement("p", null, text);
};
const text = "已结算的一段回答,对照了 D9 和 D10。";
renderToString(createElement(StableMarkdownPrefix, { text, renderMarkdown }));
renderToString(createElement(StableMarkdownPrefix, { text, renderMarkdown }));
assert.equal(calls.length, 1);
assert.deepEqual(calls, [text]);
});