123123213weqw opened a new pull request, #5730:
URL: https://github.com/apache/rocketmq-dashboard/pull/5730

   ## Problem / Evidence
   
   `normalizeAiMarkdown` (`web/src/pages/ai/render/markdown.ts`) repairs model 
markdown before `react-markdown` renders it, and its doc promises "well-formed 
input comes back unchanged". Two of its repairs break that promise:
   
   1. **Every well-formed ATX heading of level ≥ 2 is corrupted.** The heading 
pass is `/^(#{1,6})(?=\S)/gm`: on `## heading` the greedy `#{1,6}` takes both 
hashes, the lookahead sees the space and fails, and the engine **backtracks to 
a single `#`** whose lookahead now sees the second `#` — a match. The 
replacement rewrites the line to `# # heading` (verified: `'## heading'` → `'# 
# heading'`, `'### heading'` → `'## # heading'`). Every assistant answer that 
uses a real level-2+ heading renders it as a deeper heading with a stray `#` in 
the text.
   2. **Thematic breaks and setext underlines are rewritten into bullets.** The 
bullet pass `/^([-+*])(?=\S)/gm` fires on the first dash of `---`: a horizontal 
rule becomes `- --`, and a setext heading underline (`标题\n---`) becomes a 
bullet under the title (verified: `'---'` → `'- --'`, `'***'` → `'* **'`).
   
   ## Root cause / Fix
   
   - Headings: require the marker run to be maximal — `(?=[^\s#])` instead of 
`(?=\S)`, so a marker followed by another `#` never matches and `##结论` still 
gets its space.
   - Bullets: add a negative lookahead `(?!\1\1)` so a run of three or more of 
the same marker (thematic break / setext underline) is left alone while `-第一项` 
is still repaired.
   
   ## Tests
   
   - New `src/pages/ai/render/__tests__/markdown.test.ts`: the repair cases 
(`##结论`, `-第一项`, fence info strings), idempotence over a well-formed document, 
the heading corruption cases (`## heading` / `### heading` / `###### heading`), 
and the thematic-break / setext cases. The heading and break cases fail on the 
pre-fix code.
   - `npx vitest run src/pages/ai` → 198/198 passed; `npx vitest run 
src/pages/ai/components` → 79/79 passed; `npx tsc --noEmit -p 
tsconfig.app.json` clean; eslint on touched files clean.
   
   ## Risk
   
   Low: the function still only inserts whitespace; the two guards exclude 
inputs the repair was never meant to touch.


-- 
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]

Reply via email to