render chat output as markdown, cool

This commit is contained in:
perf3ct 2025-03-28 23:46:50 +00:00
parent 8497e77b55
commit a8fc9e9768
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232

View File

@ -7,6 +7,7 @@ import { t } from "../services/i18n.js";
import libraryLoader from "../services/library_loader.js"; import libraryLoader from "../services/library_loader.js";
import { applySyntaxHighlight } from "../services/syntax_highlight.js"; import { applySyntaxHighlight } from "../services/syntax_highlight.js";
import options from "../services/options.js"; import options from "../services/options.js";
import { marked } from "marked";
// Import the LLM Chat CSS // Import the LLM Chat CSS
(async function() { (async function() {
@ -429,13 +430,6 @@ export default class LlmChatPanel extends BasicWidget {
private formatMarkdown(content: string): string { private formatMarkdown(content: string): string {
if (!content) return ''; if (!content) return '';
// Check if content contains HTML sections for thinking visualization
if (content.includes('<div class="thinking-process">') ||
content.includes('<div class=\'thinking-process\'>')) {
console.log('Detected thinking process visualization in response');
// For content with HTML thinking visualizations, we need to protect them
}
// First, extract HTML thinking visualization to protect it from replacements // First, extract HTML thinking visualization to protect it from replacements
const thinkingBlocks: string[] = []; const thinkingBlocks: string[] = [];
let processedContent = content.replace(/<div class=['"](thinking-process|reasoning-process)['"][\s\S]*?<\/div>/g, (match) => { let processedContent = content.replace(/<div class=['"](thinking-process|reasoning-process)['"][\s\S]*?<\/div>/g, (match) => {
@ -444,26 +438,21 @@ export default class LlmChatPanel extends BasicWidget {
return placeholder; return placeholder;
}); });
// Then extract code blocks to protect them from other replacements // Use marked library to parse the markdown
const codeBlocks: string[] = []; const markedContent = marked(processedContent, {
processedContent = processedContent.replace(/```(\w+)?\n([\s\S]+?)\n```/gs, (match, language, code) => { breaks: true, // Convert line breaks to <br>
const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`; gfm: true, // Enable GitHub Flavored Markdown
const languageClass = language ? ` language-${language}` : ''; silent: true // Ignore errors
codeBlocks.push(`<pre class="code${languageClass}"><code>${code}</code></pre>`);
return placeholder;
}); });
// Apply other markdown formatting // Handle potential promise (though it shouldn't be with our options)
processedContent = processedContent if (typeof markedContent === 'string') {
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') processedContent = markedContent;
.replace(/\*(.*?)\*/g, '<em>$1</em>') } else {
.replace(/`([^`]+)`/g, '<code>$1</code>') console.warn('Marked returned a promise unexpectedly');
.replace(/\n/g, '<br>'); // Use the original content as fallback
processedContent = content;
// Restore code blocks }
codeBlocks.forEach((block, index) => {
processedContent = processedContent.replace(`__CODE_BLOCK_${index}__`, block);
});
// Restore thinking visualization blocks // Restore thinking visualization blocks
thinkingBlocks.forEach((block, index) => { thinkingBlocks.forEach((block, index) => {