fix: preserve math through streaming HTML repair

Disable only Remend's incomplete-HTML stripping in message/tool content and reasoning rendering. Keep TeX, source data, and sanitization unchanged; unfinished HTML can display literally.

PR #266 identified the less-than comparison trigger. This uses an independently authored renderer configuration fix rather than its TeX-spacing workaround, with streaming, incremental, literal-code, and safety regressions.
This commit is contained in:
amosblomqvist
2026-10-28 23:21:15 +02:00
parent f69fa354cc
commit 3c76930964
3 changed files with 149 additions and 2 deletions
+7
View File
@@ -355,6 +355,12 @@ export const streamdownPlugins = {
math: createMathPlugin({ singleDollarTextMath: true }),
} as unknown as PluginConfig;
// Remend's incomplete-HTML heuristic mistakes `<b` in `$a<b$` for a
// partial tag and deletes the remaining source before math can tokenize.
// Preserve that text (unfinished prose HTML may show literally); Streamdown's
// separate sanitization/hardening and all other Markdown repairs stay enabled.
export const streamdownRemend = { htmlTags: false };
export const MessageResponse = memo(
({ className, children, ...props }: MessageResponseProps) => {
// Legacy backslash delimiters are converted in a single linear scan;
@@ -375,6 +381,7 @@ export const MessageResponse = memo(
)}
components={mdComponents}
plugins={streamdownPlugins}
remend={streamdownRemend}
{...props}
>
{content}
+2 -2
View File
@@ -24,7 +24,7 @@ import {
import { Streamdown } from "streamdown";
import { transformMathDelimiters } from "@/src/core";
import { streamdownPlugins } from "./message";
import { streamdownPlugins, streamdownRemend } from "./message";
import { mdComponents } from "@/components/md-blocks";
import { Shimmer } from "./shimmer";
@@ -209,7 +209,7 @@ export const ReasoningContent = memo(
)}
{...props}
>
<Streamdown components={mdComponents} plugins={streamdownPlugins}>
<Streamdown components={mdComponents} plugins={streamdownPlugins} remend={streamdownRemend}>
{transformMathDelimiters(children)}
</Streamdown>
</CollapsibleContent>