diff --git a/src/lib/components/chat/Messages/ContentRenderer.svelte b/src/lib/components/chat/Messages/ContentRenderer.svelte index ec1454a32d..baca4d6ebc 100644 --- a/src/lib/components/chat/Messages/ContentRenderer.svelte +++ b/src/lib/components/chat/Messages/ContentRenderer.svelte @@ -15,6 +15,57 @@ import FloatingButtons from '../ContentRenderer/FloatingButtons.svelte'; import { createMessagesList } from '$lib/utils'; + /** + * Extracts all top-level
...
blocks from content, + * handling nested
via depth tracking. + * Returns { detailsContent, plainContent }. + */ + const extractDetailsBlocks = (text) => { + const blocks = []; + let remaining = text; + let result = ''; + const openTag = ' 0 && idx < remaining.length) { + if (remaining.startsWith(openTag, idx)) { + depth++; + } else if (remaining.startsWith(closeTag, idx)) { + depth--; + } + if (depth > 0) idx++; + } + + if (depth === 0) { + const end = idx + closeTag.length; + blocks.push(remaining.slice(start, end)); + remaining = remaining.slice(end); + } else { + // Unmatched opening tag, treat as plain text + result += remaining.slice(start); + remaining = ''; + break; + } + } + + return { + detailsContent: blocks.join('\n'), + plainContent: result.trim() + }; + }; + export let id; export let content; @@ -174,43 +225,59 @@
- { - const { lang, text: code } = token; + {#if $settings?.renderMarkdownInAssistantMessages ?? true} + { + const { lang, text: code } = token; - if ( - ($settings?.detectArtifacts ?? true) && - (['html', 'svg'].includes(lang) || (lang === 'xml' && code.includes('svg'))) && - !$mobile && - $chatId - ) { - await tick(); - showArtifacts.set(true); - showControls.set(true); - } - }} - onPreview={async (value) => { - console.log('Preview', value); - await artifactCode.set(value); - await showControls.set(true); - await showArtifacts.set(true); - await showEmbeds.set(false); - }} - /> + if ( + ($settings?.detectArtifacts ?? true) && + (['html', 'svg'].includes(lang) || (lang === 'xml' && code.includes('svg'))) && + !$mobile && + $chatId + ) { + await tick(); + showArtifacts.set(true); + showControls.set(true); + } + }} + onPreview={async (value) => { + console.log('Preview', value); + await artifactCode.set(value); + await showControls.set(true); + await showArtifacts.set(true); + await showEmbeds.set(false); + }} + /> + {:else} + {@const extracted = extractDetailsBlocks(content)} + + {#if extracted.detailsContent} + + + {/if} + {#if extracted.plainContent} +
{extracted.plainContent}
+ {/if} + {/if}
{#if floatingButtons} diff --git a/src/lib/components/chat/Messages/UserMessage.svelte b/src/lib/components/chat/Messages/UserMessage.svelte index acc73c6446..f4f5a94c74 100644 --- a/src/lib/components/chat/Messages/UserMessage.svelte +++ b/src/lib/components/chat/Messages/UserMessage.svelte @@ -376,12 +376,16 @@ : ' w-full'}" > {#if message.content} - + {#if $settings?.renderMarkdownInUserMessages ?? true} + + {:else} +
{message.content}
+ {/if} {/if} diff --git a/src/lib/components/chat/Settings/Interface.svelte b/src/lib/components/chat/Settings/Interface.svelte index ee242fb735..250c75a9ff 100644 --- a/src/lib/components/chat/Settings/Interface.svelte +++ b/src/lib/components/chat/Settings/Interface.svelte @@ -69,6 +69,8 @@ let temporaryChatByDefault = false; let chatFadeStreamingText = true; let collapseCodeBlocks = false; + let renderMarkdownInUserMessages = true; + let renderMarkdownInAssistantMessages = true; let expandDetails = false; let renderMarkdownInPreviews = true; let showChatTitleInTab = true; @@ -232,6 +234,8 @@ copyFormatted = $settings?.copyFormatted ?? false; collapseCodeBlocks = $settings?.collapseCodeBlocks ?? false; + renderMarkdownInUserMessages = $settings?.renderMarkdownInUserMessages ?? true; + renderMarkdownInAssistantMessages = $settings?.renderMarkdownInAssistantMessages ?? true; expandDetails = $settings?.expandDetails ?? false; renderMarkdownInPreviews = $settings?.renderMarkdownInPreviews ?? true; @@ -776,6 +780,44 @@ +
+
+
+ {$i18n.t('Render Markdown in User Messages')} +
+ +
+ { + saveSettings({ renderMarkdownInUserMessages }); + }} + /> +
+
+
+ +
+
+
+ {$i18n.t('Render Markdown in Assistant Messages')} +
+ +
+ { + saveSettings({ renderMarkdownInAssistantMessages }); + }} + /> +
+
+
+
diff --git a/src/lib/i18n/locales/en-US/translation.json b/src/lib/i18n/locales/en-US/translation.json index e3a291a956..49e1c6f56e 100644 --- a/src/lib/i18n/locales/en-US/translation.json +++ b/src/lib/i18n/locales/en-US/translation.json @@ -1697,6 +1697,8 @@ "Remove Model": "", "Rename": "", "Renamed to {{name}}": "", + "Render Markdown in Assistant Messages": "", + "Render Markdown in User Messages": "", "Render Markdown in Previews": "", "Reorder Models": "", "Repeats": "",