@@ -1,4 +1,7 @@ import DsMarkdown, { ConfigProvider } from 'ds-markdown' +import { katexPlugin } from 'ds-markdown/plugins' + +import 'ds-markdown/katex.css' import { ruRU } from './ds-markdown-locale' @@ -18,6 +21,8 @@ export function DsMarkdownContent({ content, streaming }: DsMarkdownContentProps disableTyping={!streaming} interval={STREAMING_INTERVAL} showCursor={streaming} + plugins={[katexPlugin]} + math={{ splitSymbol: 'bracket' }} > {content} @@ -14,43 +14,38 @@ export function parseThinkBlocks(content: string): ParsedThinkContent { const thinkContents: string[] = [] let remaining = content.replace(COMPLETE_THINK_REGEX, (_, thinkContent: string) => { - const trimmed = thinkContent.trim() - if (trimmed) { - thinkContents.push(trimmed) + if (thinkContent) { + thinkContents.push(thinkContent) } return '' }) const incompleteMatch = remaining.match(INCOMPLETE_THINK_REGEX) if (incompleteMatch) { - const trimmed = incompleteMatch[1].trim() - if (trimmed) { - thinkContents.push(trimmed) + if (incompleteMatch[1]) { + thinkContents.push(incompleteMatch[1]) } remaining = remaining.slice(0, incompleteMatch.index) } return { thinkContents, - mainContent: remaining.trim(), + mainContent: remaining, hasIncompleteThink: Boolean(incompleteMatch), } } /** Removes think text from the answer so it is not rendered twice after `done`. */ export function stripThinkFromMain(main: string, think: string): string { - if (!main || !think.trim()) { + if (!main || !think) { return main } const parsed = parseThinkBlocks(main) - let result = parsed.thinkContents.length > 0 ? parsed.mainContent : main + const result = parsed.thinkContents.length > 0 ? parsed.mainContent : main - const trimmedThink = think.trim() - const trimmedMain = result.trimStart() - - if (trimmedMain.startsWith(trimmedThink)) { - return trimmedMain.slice(trimmedThink.length).trim() + if (result.startsWith(think)) { + return result.slice(think.length) } return result @@ -64,7 +59,7 @@ export function splitFinalStreamContent( const parsed = parseThinkBlocks(content) const thinkFromTags = parsed.thinkContents.join('\n\n') // Prefer already streamed think to keep the block visually stable - const think = streamedThink.trim() ? streamedThink : thinkFromTags + const think = streamedThink || thinkFromTags const mainSource = parsed.thinkContents.length > 0 ? parsed.mainContent : content return {