unbridled-41 opened a new issue, #5093:
URL: https://github.com/apache/rocketmq-dashboard/issues/5093
### Before Creating the Bug Report
- [x] I searched the repository's issues and pull requests (`markdown`,
`normalizeAiMarkdown`, `heading`, `emphasis`, `bold`, `code fence`, `渲染`, `标题`)
and found no issue describing this defect. The only results mentioning the
function are this report's pull request.
- [x] This is a defect in RocketMQ Studio (the AI console transcript
rendering), not a usage question and not a defect in another Apache RocketMQ
repository.
- [x] Reproduced on the development trunk `rocketmq-studio` at `a562601d`;
the same file is byte-identical on `master`, so the defect is on both.
### Studio Version
```
branch: rocketmq-studio (development trunk)
git commit id: a562601d0971001c1cd3b888a9f2664b6ef77811
also present on: master (git diff origin/master origin/rocketmq-studio --
web/src/pages/ai/render/markdown.ts is empty)
deployed as: built from source
```
### Runtime Environment
The defect is in a pure frontend function and reproduces without a
deployment, a browser or a live cluster, using the repository's own vitest +
jsdom suites:
```
cd web && npx vitest run src/pages/ai/render/__tests__/markdown.test.ts
cd web && npx vitest run
src/pages/ai/components/__tests__/AssistantBubble.test.tsx
```
### Connected RocketMQ Cluster
None required. The wrong output is produced from the assistant text alone,
before any API call.
### Describe the Bug
`normalizeAiMarkdown` (`web/src/pages/ai/render/markdown.ts`) prepares every
assistant text block for `react-markdown`
(`web/src/pages/ai/components/blocks/TextBlock.tsx:46`, applied to live and
replayed blocks alike). Its own docstring states the contract: *"Purely textual
and idempotent: well-formed input comes back unchanged, so this is safe to
apply to every assistant text block, live or replayed."*
The current implementation breaks that contract in three ways:
1. **Every heading with two or more hashes is demoted and gains a literal
`#`.** `/^(#{1,6})(?=\S)/` is greedy and anchored at the line start, so when
the full marker run is followed by a space the engine backtracks to a shorter
run that does satisfy `(?=\S)`. A single `#` is unaffected.
2. **The bullet repair fires on emphasis, thematic breaks and signed
numbers**, because `/^([-+*])(?=\S)/` cannot tell a list bullet from a `*`/`**`
delimiter, a `---` rule or a sign.
3. **Both passes run over the raw text**, so the same markers inside a
fenced code block are rewritten as well — a `diff` block loses its `-`/`+`
markers.
### Steps to Reproduce
On the unmodified revision above:
```
$ node -e "
const f = (c) => c.replace(/^(#{1,6})(?=\S)/gm,'\$1
').replace(/^([-+*])(?=\S)/gm,'\$1 ');
for (const s of ['## 概述','**bold** start','*italic* start','---','-1
items','\`\`\`diff\n-old line\n+new line\n\`\`\`'])
console.log(JSON.stringify(s), '=>', JSON.stringify(f(s)));
"
"## 概述" => "# # 概述"
"**bold** start" => "* *bold** start"
"*italic* start" => "* italic* start"
"---" => "- --"
"-1 items" => "- 1 items"
"```diff\n-old line\n+new line\n```" => "```diff\n- old line\n+ new
line\n```"
```
Rendered through the component that consumes it (`AssistantBubble` →
`TextBlock`), `## 概述` paints an `h1` whose accessible name is `"# 概述"`, and the
emphasis line paints a `<ul>`:
```
$ npx vitest run src/pages/ai/components/__tests__/AssistantBubble.test.tsx
# fix reverted
FAIL … > rendersWellFormedMarkdownWithoutRewritingItTest
TestingLibraryElementError: Unable to find an accessible element with the
role "heading" and name "概述"
heading:
Name "# 概述":
<h1 />
list:
Name "":
<ul />
```
### What Did You Expect to See?
The repairs the function exists for (`##结论` → `## 结论`, `-第一项` → `- 第一项`, `
```bashls ` → ` ```bash ` + newline) still apply, and anything already well
formed comes back unchanged: headings keep their level and text, emphasis stays
emphasis, `---` stays a thematic break, `-1` stays a number, and fenced code
keeps its lines verbatim.
### What Did You See Instead?
Every `##`/`###`/… heading in an assistant answer is rendered one level
lower with a literal `#` in its text, line-leading emphasis/thematic
breaks/signed numbers are reinterpreted as list items, and fenced blocks are
rewritten in place.
### Additional Context
Call path: `AssistantBubble` → `render/blocks` → `TextBlock.tsx:46` →
`normalizeAiMarkdown(block.text)` → `ReactMarkdown`.
Regression coverage added with the fix (12 unit cases + 1 render-level
case): with the fix reverted the two files report `Tests 10 failed | 22 passed
(32)`.
### Corresponding pull request
#5089 — `fix(ai): stop the transcript markdown repair from corrupting valid
markdown`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]