refactor: AgentMonitor 改用 MUI Table 布局标签-值对
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
/**
|
||||
* AgentMonitor — Agent 状态指示器
|
||||
*
|
||||
* 完全使用 MUI 组件,Table 布局标签-值对。
|
||||
*/
|
||||
|
||||
import { Box, Typography, Stack } from '@mui/material';
|
||||
import { Activity, Cpu, Clock } from 'lucide-react';
|
||||
import { Box, Typography, Stack, Table, TableBody, TableRow, TableCell, Chip } from '@mui/material';
|
||||
import { Activity, Cpu } from 'lucide-react';
|
||||
import { useEffect } from 'react';
|
||||
import { useAgentStore, type AgentStatus } from '@renderer/stores/agent-store';
|
||||
import { AGENT_STATUS_COLORS, AGENT_STATUS_LABELS, PROVIDER_LABELS } from '@renderer/lib/constants';
|
||||
@@ -20,7 +22,6 @@ export function AgentMonitor(): React.JSX.Element {
|
||||
const traceSteps = useAgentStore((s) => s.traceSteps);
|
||||
const setMaxIterations = useAgentStore((s) => s.setMaxIterations);
|
||||
|
||||
// 启动时从数据库读取 maxIterations
|
||||
useEffect(() => {
|
||||
if (window.metona?.config?.get) {
|
||||
window.metona.config.get('agent.maxIterations').then((v) => {
|
||||
@@ -29,47 +30,68 @@ export function AgentMonitor(): React.JSX.Element {
|
||||
}
|
||||
}, [setMaxIterations]);
|
||||
|
||||
// 监听配置变更
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
if (window.metona?.config?.get) {
|
||||
window.metona.config.get('agent.maxIterations').then((v) => {
|
||||
if (typeof v === 'number' && v > 0) setMaxIterations(v);
|
||||
}).catch(() => {});
|
||||
}
|
||||
}, 3000);
|
||||
return () => clearInterval(interval);
|
||||
}, [setMaxIterations]);
|
||||
const StatusIcon = STATUS_ICONS[agentStatus];
|
||||
const statusColor = AGENT_STATUS_COLORS[agentStatus];
|
||||
const statusLabel = AGENT_STATUS_LABELS[agentStatus];
|
||||
const totalDuration = traceSteps.reduce((sum, s) => sum + (s.completedAt ? s.completedAt - s.startedAt : 0), 0);
|
||||
|
||||
const InfoRow = ({ icon: Icon, label, value }: { icon: typeof Activity; label: string; value: string }) => (
|
||||
<Stack direction="row" alignItems="center" sx={{ gap: 1 }}>
|
||||
<Stack direction="row" spacing={0.75} alignItems="center" sx={{ color: 'text.secondary', flexShrink: 0, minWidth: 60 }}>
|
||||
<Icon size={10} /><Typography variant="caption">{label}</Typography>
|
||||
</Stack>
|
||||
<Typography variant="caption" sx={{ fontFamily: 'monospace', color: 'text.primary', flex: 1, textAlign: 'right', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{value}</Typography>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
return (
|
||||
<Box sx={{ mt: 2, pt: 2, borderTop: 1, borderColor: 'divider', flexShrink: 0 }}>
|
||||
<Stack direction="row" spacing={1} alignItems="center" sx={{ mb: 1.5 }}>
|
||||
<Cpu size={14} style={{ color: '#818cf8' }} />
|
||||
<Typography variant="caption" sx={{ fontWeight: 600, textTransform: 'uppercase', letterSpacing: 1, color: 'text.secondary' }}>Agent 状态</Typography>
|
||||
<Typography variant="caption" sx={{ fontWeight: 600, textTransform: 'uppercase', letterSpacing: 1, color: 'text.secondary' }}>
|
||||
Agent 状态
|
||||
</Typography>
|
||||
</Stack>
|
||||
<Stack direction="row" spacing={1} alignItems="center" sx={{ px: 1.5, py: 1, borderRadius: 1.5, mb: 1, bgcolor: 'background.default' }}>
|
||||
<StatusIcon size={14} style={{ color: statusColor, animation: (agentStatus === 'thinking' || agentStatus === 'executing') ? 'pulse 2s infinite' : 'none' }} />
|
||||
|
||||
{/* 状态指示 */}
|
||||
<Box sx={{ px: 1.5, py: 1, borderRadius: 1.5, mb: 1.5, bgcolor: 'background.default', border: '1px solid', borderColor: 'divider' }}>
|
||||
<Stack direction="row" spacing={1} alignItems="center">
|
||||
<StatusIcon
|
||||
size={14}
|
||||
style={{
|
||||
color: statusColor,
|
||||
animation: (agentStatus === 'thinking' || agentStatus === 'executing') ? 'pulse 2s infinite' : 'none',
|
||||
}}
|
||||
/>
|
||||
<Typography variant="caption" sx={{ fontWeight: 500, color: statusColor }}>{statusLabel}</Typography>
|
||||
{(agentStatus === 'thinking' || agentStatus === 'executing') && (
|
||||
<Box sx={{ width: 6, height: 6, borderRadius: '50%', bgcolor: statusColor, animation: 'pulse 1.5s infinite', ml: 'auto' }} />
|
||||
)}
|
||||
</Stack>
|
||||
<Stack spacing={0.75}>
|
||||
<InfoRow icon={Activity} label="Provider" value={PROVIDER_LABELS[provider] ?? provider} />
|
||||
<InfoRow icon={Cpu} label="模型" value={model} />
|
||||
<InfoRow icon={Activity} label="迭代" value={`${currentIteration} / ${maxIterations}`} />
|
||||
{totalDuration > 0 && <InfoRow icon={Clock} label="总耗时" value={formatDuration(totalDuration)} />}
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
{/* 详情表格 */}
|
||||
<Table size="small" sx={{ '& .MuiTableCell-root': { border: 0, py: 0.5, px: 0.5 } }}>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell sx={{ color: 'text.secondary', fontSize: 11, width: '40%' }}>Provider</TableCell>
|
||||
<TableCell sx={{ fontFamily: 'monospace', fontSize: 11, color: 'text.primary', textAlign: 'right', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 0 }}>
|
||||
{PROVIDER_LABELS[provider] ?? provider}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell sx={{ color: 'text.secondary', fontSize: 11 }}>模型</TableCell>
|
||||
<TableCell sx={{ fontFamily: 'monospace', fontSize: 11, color: 'text.primary', textAlign: 'right', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: 0 }}>
|
||||
{model}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell sx={{ color: 'text.secondary', fontSize: 11 }}>迭代</TableCell>
|
||||
<TableCell sx={{ fontFamily: 'monospace', fontSize: 11, color: 'text.secondary', textAlign: 'right' }}>
|
||||
{currentIteration} / {maxIterations}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{totalDuration > 0 && (
|
||||
<TableRow>
|
||||
<TableCell sx={{ color: 'text.secondary', fontSize: 11 }}>总耗时</TableCell>
|
||||
<TableCell sx={{ fontFamily: 'monospace', fontSize: 11, color: 'text.secondary', textAlign: 'right' }}>
|
||||
{formatDuration(totalDuration)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user