From 29b87d92fc784a7cc127f2840e12cc64905c03f1 Mon Sep 17 00:00:00 2001 From: Haoqing Wang <78337154+hqhq1025@users.noreply.github.com> Date: Sun, 5 Apr 2026 12:37:38 +0800 Subject: [PATCH] fix(web): disable indented code blocks in markdown rendering (#395) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(web): disable indented code blocks in markdown rendering In CommonMark, text indented by 4+ spaces is treated as a code block. LLM responses frequently have indented content inside numbered lists or quoted text, causing large chunks to render as a single code block instead of formatted markdown. Add a remark plugin that disables the codeIndented tokenizer. Fenced code blocks (``` … ```) continue to work normally. via [HAPI](https://hapi.run) Co-Authored-By: HAPI * fix(web): fix typecheck for remark plugin this binding Use `as any` cast for the unified processor `this` context instead of an explicit type annotation that conflicts with the Processor type. via [HAPI](https://hapi.run) Co-Authored-By: HAPI * fix(web): use this:unknown annotation to satisfy noImplicitThis The previous `as any` cast on `this` still triggers noImplicitThis in strict mode. Annotate the parameter as `this: unknown` and cast to the required shape inside the function body. Also use the key-based `data(key, value)` API instead of mutating the returned object. via [HAPI](https://hapi.run) Co-Authored-By: HAPI --------- Co-authored-by: HAPI --- web/src/components/assistant-ui/markdown-text.tsx | 3 ++- web/src/lib/remark-disable-indented-code.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 web/src/lib/remark-disable-indented-code.ts diff --git a/web/src/components/assistant-ui/markdown-text.tsx b/web/src/components/assistant-ui/markdown-text.tsx index 19906789..2f61a17a 100644 --- a/web/src/components/assistant-ui/markdown-text.tsx +++ b/web/src/components/assistant-ui/markdown-text.tsx @@ -6,12 +6,13 @@ import { type CodeHeaderProps, } from '@assistant-ui/react-markdown' import remarkGfm from 'remark-gfm' +import remarkDisableIndentedCode from '@/lib/remark-disable-indented-code' import { cn } from '@/lib/utils' import { SyntaxHighlighter } from '@/components/assistant-ui/shiki-highlighter' import { useCopyToClipboard } from '@/hooks/useCopyToClipboard' import { CopyIcon, CheckIcon } from '@/components/icons' -export const MARKDOWN_PLUGINS = [remarkGfm] +export const MARKDOWN_PLUGINS = [remarkGfm, remarkDisableIndentedCode] function CodeHeader(props: CodeHeaderProps) { const { copied, copy } = useCopyToClipboard() diff --git a/web/src/lib/remark-disable-indented-code.ts b/web/src/lib/remark-disable-indented-code.ts new file mode 100644 index 00000000..833a5cd9 --- /dev/null +++ b/web/src/lib/remark-disable-indented-code.ts @@ -0,0 +1,14 @@ +/** + * Remark plugin that disables indented code blocks (4-space indent). + * + * In CommonMark, text indented by 4+ spaces becomes a code block. This + * frequently misparses LLM output where numbered-list items with nested + * content or quoted text are indented. Fenced code blocks (``` … ```) + * still work normally. + */ +export default function remarkDisableIndentedCode(this: unknown) { + const processor = this as { data(key: string, value?: unknown): unknown } + const micromarkExtensions = (processor.data('micromarkExtensions') ?? []) as unknown[] + micromarkExtensions.push({ disable: { null: ['codeIndented'] } }) + processor.data('micromarkExtensions', micromarkExtensions) +}