/** * Deep Research V2.0 — Agent Terminal * * 暗色终端风格展示 AI 思考与执行过程: * - 每条日志展示完整思考内容 * - 自动过滤无意义内容(任务 ID 等) * - 条件 auto-scroll */ import { useRef, useEffect, useCallback, useState } from 'react'; import { Spin, Typography, Alert } from 'antd'; import { LoadingOutlined } from '@ant-design/icons'; import type { DeepResearchTask, ExecutionLogEntry } from '../../types/deepResearch'; const { Text } = Typography; interface AgentTerminalProps { task: DeepResearchTask | null; isRunning: boolean; isFailed: boolean; } const LOG_COLORS: Record = { thinking: '#8b949e', searching: '#58a6ff', reading: '#d2a8ff', analyzing: '#7ee787', summary: '#ffa657', info: '#79c0ff', }; const LOG_PREFIXES: Record = { thinking: '🤔 思考', searching: '🔍 搜索', reading: '📖 阅读', analyzing: '🧪 分析', summary: '📊 总结', info: 'ℹ️ 信息', }; const AgentTerminal: React.FC = ({ task, isRunning, isFailed }) => { const containerRef = useRef(null); const [userScrolled, setUserScrolled] = useState(false); const prevLogCountRef = useRef(0); const logs = (task?.executionLogs || []).filter( (log: ExecutionLogEntry) => !log.text.includes('Unifuncs 任务 ID') ); const handleScroll = useCallback(() => { const el = containerRef.current; if (!el) return; const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight; setUserScrolled(distanceFromBottom > 50); }, []); useEffect(() => { if (!userScrolled && containerRef.current && logs.length > prevLogCountRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; } prevLogCountRef.current = logs.length; }, [logs.length, userScrolled]); return (
{isRunning && } size="small" />} {isRunning ? 'Deep Research 执行中...' : isFailed ? '执行失败' : '执行完成'}
{isFailed && task?.errorMessage && ( )}
{/* Header */}
Deep Research Agent
{/* Log entries */} {logs.map((log: ExecutionLogEntry, i: number) => (
{LOG_PREFIXES[log.type] || log.title} {new Date(log.ts).toLocaleTimeString()}
{log.text}
))} {/* Blinking cursor */} {isRunning && ( )} {logs.length === 0 && (
等待任务启动...
)}
{userScrolled && isRunning && (
{ setUserScrolled(false); if (containerRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; } }} > ↓ 回到底部查看最新日志
)}
); }; export default AgentTerminal;