refactor: 移除多余依赖,统一 MUI 为唯一 UI 库
- 移除 radix-ui、clsx、tailwind-merge、class-variance-authority、react-router-dom - 前后端全面适配 MUI 组件,清理残留 Tailwind 工具类引用 - 优化 Agent Loop 引擎、IPC 处理器、Provider Adapter 等后端模块 - 新增 Agent 网络工具通用设计文档 v2
This commit is contained in:
@@ -18,17 +18,18 @@ import type { ChatMessage } from '@renderer/stores/agent-store';
|
||||
import { useAgentStore } from '@renderer/stores/agent-store';
|
||||
import { ThoughtBlock } from './ThoughtBlock';
|
||||
import { ToolCallCard } from './ToolCallCard';
|
||||
import { ToolResultBlock } from './ToolResultBlock';
|
||||
import { formatTime } from '@renderer/lib/formatters';
|
||||
import { ContextMenu, createContextMenuItems } from '@renderer/components/ContextMenu';
|
||||
|
||||
interface AssistantMessageProps {
|
||||
message: ChatMessage;
|
||||
isStreaming?: boolean;
|
||||
streamContent?: string;
|
||||
}
|
||||
|
||||
export function AssistantMessage({ message, isStreaming, streamContent }: AssistantMessageProps): React.JSX.Element {
|
||||
const content = isStreaming ? streamContent ?? '' : message.content;
|
||||
export function AssistantMessage({ message, isStreaming }: AssistantMessageProps): React.JSX.Element {
|
||||
// 直接使用 message.content — updateLastAssistantMessage 已实时更新此字段
|
||||
const content = message.content;
|
||||
const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null);
|
||||
const agentStatus = useAgentStore((s) => s.agentStatus);
|
||||
|
||||
@@ -61,7 +62,7 @@ export function AssistantMessage({ message, isStreaming, streamContent }: Assist
|
||||
{/* ===== 阶段 1: 思考过程 ===== */}
|
||||
{hasThinking && (
|
||||
<>
|
||||
<Stack direction="row" spacing={1} alignItems="center" sx={{ mb: 0.5 }}>
|
||||
<Stack direction="row" spacing={1} sx={{ mb: 0.5, alignItems: 'center' }}>
|
||||
<Typography variant="caption" sx={{ color: '#fbbf24', fontWeight: 600, fontSize: 10, textTransform: 'uppercase', letterSpacing: 0.5 }}>
|
||||
💭 {isThinking ? '正在思考...' : '思考过程'}
|
||||
</Typography>
|
||||
@@ -77,13 +78,18 @@ export function AssistantMessage({ message, isStreaming, streamContent }: Assist
|
||||
{hasTools && (
|
||||
<>
|
||||
{hasThinking && <Box sx={{ height: 8 }} />}
|
||||
<Stack direction="row" spacing={1} alignItems="center" sx={{ mb: 0.5 }}>
|
||||
<Stack direction="row" spacing={1} sx={{ mb: 0.5, alignItems: 'center' }}>
|
||||
<Typography variant="caption" sx={{ color: '#a855f7', fontWeight: 600, fontSize: 10, textTransform: 'uppercase', letterSpacing: 0.5 }}>
|
||||
🔧 工具调用
|
||||
</Typography>
|
||||
</Stack>
|
||||
{message.toolCalls!.map((tc) => (
|
||||
<ToolCallCard key={tc.id} toolCall={tc} />
|
||||
<Box key={tc.id}>
|
||||
<ToolCallCard toolCall={tc} />
|
||||
{tc.status === 'success' && tc.result != null && (
|
||||
<ToolResultBlock toolCall={tc} />
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
@@ -92,7 +98,7 @@ export function AssistantMessage({ message, isStreaming, streamContent }: Assist
|
||||
{(hasContent || isStreaming) && (
|
||||
<>
|
||||
{(hasThinking || hasTools) && (
|
||||
<Stack direction="row" spacing={1} alignItems="center" sx={{ mt: 0.5, mb: 0.5 }}>
|
||||
<Stack direction="row" spacing={1} sx={{ mt: 0.5, mb: 0.5, alignItems: 'center' }}>
|
||||
<Typography variant="caption" sx={{ color: '#34d399', fontWeight: 600, fontSize: 10, textTransform: 'uppercase', letterSpacing: 0.5 }}>
|
||||
✏️ 回复
|
||||
</Typography>
|
||||
@@ -144,7 +150,6 @@ export function AssistantMessage({ message, isStreaming, streamContent }: Assist
|
||||
|
||||
{contextMenu && (
|
||||
<ContextMenu
|
||||
type="message"
|
||||
x={contextMenu.x}
|
||||
y={contextMenu.y}
|
||||
items={contextMenuItems}
|
||||
@@ -164,7 +169,7 @@ function CodeBlock({ language, code }: { language: string; code: string }): Reac
|
||||
|
||||
return (
|
||||
<Box sx={{ position: 'relative', my: 1, '&:hover .copy-btn': { opacity: 1 } }}>
|
||||
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ px: 1.5, py: 0.75, borderTopLeftRadius: 8, borderTopRightRadius: 8, borderBottom: '1px solid', borderColor: 'divider', bgcolor: 'background.default', fontSize: 11, color: 'text.secondary' }}>
|
||||
<Stack direction="row" sx={{ px: 1.5, py: 0.75, borderTopLeftRadius: 8, borderTopRightRadius: 8, borderBottom: '1px solid', borderColor: 'divider', bgcolor: 'background.default', fontSize: 11, color: 'text.secondary', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<span>{language}</span>
|
||||
<Tooltip title={copied ? '已复制' : '复制'}>
|
||||
<IconButton className="copy-btn" size="small" onClick={handleCopy} sx={{ opacity: 0, transition: 'opacity 150ms', color: 'text.secondary' }}>
|
||||
@@ -186,7 +191,7 @@ function extractTextContent(children: React.ReactNode): string {
|
||||
if (!children) return '';
|
||||
if (Array.isArray(children)) return children.map(extractTextContent).join('');
|
||||
if (typeof children === 'object' && 'props' in children) {
|
||||
return extractTextContent((children as React.ReactElement).props.children);
|
||||
return extractTextContent((children as React.ReactElement).props as React.ReactNode);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user