diff --git a/src/lib/components/chat/Messages/CodeBlock.svelte b/src/lib/components/chat/Messages/CodeBlock.svelte index 13bc7ec2a1..7322773d80 100644 --- a/src/lib/components/chat/Messages/CodeBlock.svelte +++ b/src/lib/components/chat/Messages/CodeBlock.svelte @@ -326,12 +326,26 @@ const render = async () => { onUpdate(token); if (lang === 'mermaid' && (token?.raw ?? '').slice(-4).includes('```')) { - mermaidHtml = await renderMermaidDiagram(code); + try { + mermaidHtml = await renderMermaidDiagram(code); + } catch (error) { + console.error('Failed to render mermaid diagram:', error); + const errorMsg = error instanceof Error ? error.message : String(error); + toast.error($i18n.t('Failed to render diagram') + `: ${errorMsg}`); + mermaidHtml = null; + } } else if ( (lang === 'vega' || lang === 'vega-lite') && (token?.raw ?? '').slice(-4).includes('```') ) { - vegaHtml = await renderVegaVisualization(code); + try { + vegaHtml = await renderVegaVisualization(code); + } catch (error) { + console.error('Failed to render Vega visualization:', error); + const errorMsg = error instanceof Error ? error.message : String(error); + toast.error($i18n.t('Failed to render diagram') + `: ${errorMsg}`); + vegaHtml = null; + } } }; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index fb239e87b3..85000b4448 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -1580,39 +1580,29 @@ export const decodeString = (str: string) => { }; export const renderMermaidDiagram = async (code: string) => { - try { - const { default: mermaid } = await import('mermaid'); - mermaid.initialize({ - startOnLoad: true, - theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default', - securityLevel: 'loose' - }); - if (await mermaid.parse(code)) { - const { svg } = await mermaid.render(`mermaid-${uuidv4()}`, code); - return svg; - } - } catch (error) { - console.log('Failed to render mermaid diagram:', error); - return ''; + const { default: mermaid } = await import('mermaid'); + mermaid.initialize({ + startOnLoad: false, // Should be false when using render API + theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default', + securityLevel: 'loose' + }); + const parseResult = await mermaid.parse(code, { suppressErrors: false }); + if (parseResult) { + const { svg } = await mermaid.render(`mermaid-${uuidv4()}`, code); + return svg; } + return ''; }; -export const renderVegaVisualization = async (spec: string) => { - try { - const vega = await import('vega'); - const parsedSpec = JSON.parse(spec); - let vegaSpec; - if (parsedSpec.$schema && parsedSpec.$schema.includes('vega-lite')) { - const vegaLite = await import('vega-lite'); - vegaSpec = vegaLite.compile(parsedSpec).spec; - } else { - vegaSpec = parsedSpec; - } - const view = new vega.View(vega.parse(vegaSpec), {renderer: 'none'}); - const svg = await view.toSVG(); - return svg; - } catch (error) { - console.log('Failed to render Vega visualization:', error); - return ''; +export const renderVegaVisualization = async (spec: string, i18n?: any) => { + const vega = await import('vega'); + const parsedSpec = JSON.parse(spec); + let vegaSpec = parsedSpec; + if (parsedSpec.$schema && parsedSpec.$schema.includes('vega-lite')) { + const vegaLite = await import('vega-lite'); + vegaSpec = vegaLite.compile(parsedSpec).spec; } + const view = new vega.View(vega.parse(vegaSpec), { renderer: 'none' }); + const svg = await view.toSVG(); + return svg; };