"use client"; import React, { useMemo } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import { citationAnchorIdFor, markdownUrlTransform, normalizeMarkdownForDisplay, } from "@/lib/markdown-display"; import { InlineFileCard, makeFileLinkRemarkPlugin, parseAttachmentHref, useInlineFileCardContext, } from "@/components/common/InlineFileCard"; import type { MarkdownRendererProps } from "./MarkdownRenderer"; function extractText(children: React.ReactNode): string { return React.Children.toArray(children) .map((child) => { if (typeof child === "string" || typeof child === "number") { return String(child); } if (React.isValidElement<{ children?: React.ReactNode }>(child)) { return extractText(child.props.children); } return ""; }) .join(""); } function headingId(children: React.ReactNode): string | undefined { const text = extractText(children) .toLowerCase() .replace(/[^\w\s-]/g, "") .replace(/\s+/g, "-"); return text || undefined; } function hasRenderableChildren(children: React.ReactNode): boolean { return ( extractText(children).replace(/[\s\u200B-\u200D\uFEFF]/g, "").length > 0 ); } function hasRenderableDetailsBody(children: React.ReactNode): boolean { return React.Children.toArray(children).some((child) => { if (typeof child === "string" || typeof child === "number") { return String(child).replace(/[\s\u200B-\u200D\uFEFF]/g, "").length > 0; } if (!React.isValidElement(child)) return false; if ( typeof child.type === "string" && child.type.toLowerCase() === "summary" ) { return false; } return true; }); } function stripLeadingHashes(children: React.ReactNode): React.ReactNode { const arr = React.Children.toArray(children); if (arr.length > 0 && typeof arr[0] === "string") { const cleaned = arr[0].replace(/^#{1,6}\s+/, ""); if (cleaned !== arr[0]) return [cleaned, ...arr.slice(1)]; } return children; } export default function SimpleMarkdownRenderer({ content, className = "", variant = "default", }: MarkdownRendererProps) { const normalizedContent = useMemo( () => normalizeMarkdownForDisplay(content), [content], ); const isTrace = variant === "trace"; const gap = isTrace ? "my-1" : variant === "compact" ? "my-2" : "my-4"; const cellPad = isTrace ? "px-1.5 py-1" : variant === "compact" ? "px-2 py-1.5" : "px-3 py-2"; const headingSpacing = variant === "compact" ? "mt-4 mb-2" : "mt-6 mb-3"; const textColor = "text-[var(--foreground)]"; const traceComponents: Record> = { p: ({ node, ...props }: any) => (

), h1: ({ node, children }: any) => (

{children}

), h2: ({ node, children }: any) => (

{children}

), h3: ({ node, children }: any) => (

{children}

), h4: ({ node, children }: any) => (

{children}

), h5: ({ node, children }: any) => (

{children}

), h6: ({ node, children }: any) => (

{children}

), strong: ({ node, children }: any) => ( {children} ), em: ({ node, children }: any) => {children}, a: ({ node, children }: any) => ( {children} ), blockquote: ({ node, children }: any) => (
{children}
), pre: ({ children }: any) => <>{children}, code: ({ node, children }: any) => ( {String(children).replace(/\n$/, "")} ), img: () => null, hr: () =>
, ul: ({ node, ...props }: any) => (