import { useState, useEffect, memo } from 'react';
import { createPortal } from 'react-dom';
import {
CheckCircle,
ChevronRight,
ChevronDown,
Clock,
Loader,
Loader2,
XCircle,
Copy,
Check,
Brain,
Maximize2,
Download,
File,
FileText,
Image,
Music,
Video,
X,
} from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import type { Components } from 'react-markdown';
import remarkGfm from 'remark-gfm';
import type { ChatMessage, Attachment, TaskToolResult } from '../../types/protocol';
import { ToolDetailModal } from './ToolDetailModal';
// 模块级常量:保持引用稳定,避免流式渲染期间每帧重建
// (react-markdown 收到新的 components/plugins 引用会重走内部映射与解析)。
const REMARK_PLUGINS = [remarkGfm];
const MARKDOWN_COMPONENTS: Components = {
// 自定义代码块渲染
code({ className, children, ...props }) {
const isInline = !className;
if (isInline) {
return (
{children}
);
}
return (
{children}
);
},
// 标题样式
h1: ({ children }) => (
{children}
, // 列表 ul: ({ children }) => ({children}), // 分隔线 hr: () =>
{taskPrompt}
{JSON.stringify(message.arguments, null, 2)}
{formatJSON(displayContent)}