From 5e4e4a8fa84649245d5233a00673fd4dd44e1cda Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 2 Feb 2026 18:31:10 +0000 Subject: [PATCH] fix(chat): auto-detect markdown content in read_page tool display RichContentRenderer now intelligently detects whether content is HTML (from TipTap editor) or markdown/plain text and handles each appropriately. Previously, markdown content was rendered as plain text in a
 tag
because isMarkdown prop defaulted to false and content detection only
ran after (skipped) markdown conversion.

https://claude.ai/code/session_01VrkwJzzussmyQ4JNvQeurt
---
 .../chat/tool-calls/RichContentRenderer.tsx   | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/apps/web/src/components/ai/shared/chat/tool-calls/RichContentRenderer.tsx b/apps/web/src/components/ai/shared/chat/tool-calls/RichContentRenderer.tsx
index 14edb295f..af41a6169 100644
--- a/apps/web/src/components/ai/shared/chat/tool-calls/RichContentRenderer.tsx
+++ b/apps/web/src/components/ai/shared/chat/tool-calls/RichContentRenderer.tsx
@@ -68,16 +68,23 @@ export const RichContentRenderer: React.FC = memo(func
     // Strip line numbers if present
     const rawContent = stripLineNumbers(content);
 
-    // Convert markdown to HTML if needed
-    const html = isMarkdown ? markdownToHtml(rawContent) : rawContent;
+    // Check if content already looks like HTML (has actual HTML tags)
+    // This detects content from TipTap editor which outputs HTML
+    const contentIsHtml = /<[a-z][\s\S]*>/i.test(rawContent);
 
-    // Check if content looks like HTML
-    const isHtml = /<[a-z][\s\S]*>/i.test(html);
+    // Convert to HTML:
+    // - If content is already HTML, preserve it (markdownToHtml would escape the tags)
+    // - If content is not HTML (markdown or plain text), convert markdown to HTML
+    // - isMarkdown prop can force markdown conversion for edge cases
+    const html = (contentIsHtml && !isMarkdown) ? rawContent : markdownToHtml(rawContent);
+
+    // After conversion, check if we have HTML to render
+    const hasHtml = /<[a-z][\s\S]*>/i.test(html);
 
     // Sanitize HTML content using allowlist approach
-    const sanitized = isHtml ? sanitizeHtmlAllowlist(html) : html;
+    const sanitized = hasHtml ? sanitizeHtmlAllowlist(html) : html;
 
-    return { processedHtml: sanitized, hasHtmlContent: isHtml };
+    return { processedHtml: sanitized, hasHtmlContent: hasHtml };
   }, [content, isMarkdown]);
 
   const handleNavigate = () => {