diff --git a/frontend/web/src/components/intelligent_eval/EvalOverview.tsx b/frontend/web/src/components/intelligent_eval/EvalOverview.tsx index 902a95b..07c30f5 100644 --- a/frontend/web/src/components/intelligent_eval/EvalOverview.tsx +++ b/frontend/web/src/components/intelligent_eval/EvalOverview.tsx @@ -1,5 +1,5 @@ import { - Alert, Card, Col, Descriptions, Empty, Progress, Row, Space, Spin, Tag, + Alert, Card, Col, Descriptions, Empty, Progress, Row, Space, Spin, Table, Tag, } from 'antd' import type { IntelligentEval } from '../../api' import { colors } from '../../tokens' @@ -14,12 +14,33 @@ function personaLabel(persona: Record): string { return JSON.stringify(persona) } +function FieldBlock({ label, content }: { label: string; content: string }) { + return ( +
+
{label}
+
+ {content || '—'} +
+
+ ) +} + function PlanView({ ev }: { ev: IntelligentEval }) { const plan = ev.plan if (!plan) return return (
- + {plan.estimated_sessions} {plan.budget?.max_turns_per_session ?? '—'} {plan.budget?.total_max_turns ?? '—'} @@ -31,25 +52,38 @@ function PlanView({ ev }: { ev: IntelligentEval }) {
虚拟用户
- + {(plan.virtual_users ?? []).map((u, i) => ( -
- {personaLabel(u.persona)} · 目标:{u.goal} -
+ +
+ {personaLabel(u.persona)} · {u.goal} +
+ ))} -
+
时间分布
- - {(plan.time_distribution ?? []).map((t, i) => ( -
- {t.time_slot} {t.sessions} 个会话 · {t.scenario} -
- ))} -
+ t.time_slot} + dataSource={plan.time_distribution ?? []} + pagination={false} + style={{ marginBottom: 12 }} + columns={[ + { + title: '时段', dataIndex: 'time_slot', width: 100, + render: (v: string) => {v}, + }, + { title: '会话数', dataIndex: 'sessions', width: 70 }, + { title: '场景说明', dataIndex: 'scenario', render: (v: string) => {v} }, + ]} + /> {plan.completion_criteria && ( -
+
完成标准:{plan.completion_criteria}
)} @@ -63,19 +97,22 @@ interface EvalOverviewProps { } /** - * 评估详情"概览"子视图(纯展示):基本信息、用户输入、粗计划、会话进度。 + * 评估详情"概览"子视图(纯展示):核心信息、用户输入、会话进度。 * 审批/取消等动作由评估列表页的详情抽屉头部统一管理。 */ export default function EvalOverview({ ev, targetName }: EvalOverviewProps) { const meta = EVAL_STATUS[ev.status] ?? { label: ev.status, color: 'default' } const showSessions = ev.status === 'executing' || ev.status === 'completed' const sessions = showSessions ? ev.sessions ?? [] : [] + const estimated = ev.plan?.estimated_sessions ?? ev.session_count + const hasSeeds = Object.keys(ev.seeds ?? {}).length > 0 return (
+ {/* 第一行:核心信息(基本信息 + 粗计划) */}
- + {targetName} @@ -85,7 +122,7 @@ export default function EvalOverview({ ev, targetName }: EvalOverviewProps) { {formatDateTime(ev.created_at)} {formatDateTime(ev.started_at)} {formatDateTime(ev.completed_at)} - {ev.completed_sessions}/{ev.plan?.estimated_sessions ?? ev.session_count} + {ev.completed_sessions}/{estimated} @@ -115,103 +152,81 @@ export default function EvalOverview({ ev, targetName }: EvalOverviewProps) { )} - - {showSessions && ( - - )} - > - {sessions.length === 0 && ( -
- 等待 OpenClaw 按粗计划的时间分布创建会话… -
- )} - {sessions.map((s) => { - const sMeta = SESSION_STATUS[s.status] - return ( -
- {personaLabel(s.persona)} - {sMeta.label} - {s.dimension && {s.dimension}} - {s.goal} - {s.turn_count} 轮 - {s.created_at && ( - {shortDateTime(s.created_at)} - )} -
- ) - })} - {ev.status === 'executing' && ( -
- 会话由 OpenClaw 按粗计划的时间分布自唤醒创建,本页每 5 秒自动刷新 -
- )} -
- )} + {/* 第二行:用户输入(种子集独立放大区) */} + + + -
-
评估目标
-
- {ev.goal || '—'} -
-
-
-
考察意图
-
- {ev.intent || '—'} -
-
-
-
角色描述
-
- {ev.role_description || '—'} -
-
- -
种子集
- {Object.keys(ev.seeds ?? {}).length === 0 ? ( -
- ) : ( + {hasSeeds ? (
                 {JSON.stringify(ev.seeds, null, 2)}
               
+ ) : ( +
+ — +
)} + + {/* 第三行:会话进度(全宽) */} + {showSessions && ( + + )} + > + {sessions.length === 0 && ( +
+ 等待 OpenClaw 按粗计划的时间分布创建会话… +
+ )} + {sessions.map((s) => { + const sMeta = SESSION_STATUS[s.status] + return ( +
+ {personaLabel(s.persona)} + {sMeta.label} + {s.dimension && {s.dimension}} + {s.goal} + {s.turn_count} 轮 + {s.created_at && ( + {shortDateTime(s.created_at)} + )} +
+ ) + })} + {ev.status === 'executing' && ( +
+ 会话由 OpenClaw 按粗计划的时间分布自唤醒创建,本页每 5 秒自动刷新 +
+ )} +
+ )} ) }