AgentEvalTool/docs/dev-log-20260715.md
sinohqb a77cd83e6a v0.2.0-dev: 文件管理 + 页面布局统一 + 6 个 bug 修复
## 新增功能
- 文件管理模块:分类树 + 文件上传/下载/删除
- 文件上传支持拖拽(Dragger)+ 手动上传(customRequest 模式)

## 页面布局统一(参照评测执行页)
- 仪表盘/评测对象/评测场景/评测报告 全部改为全高 flex 布局
- 统一内联页头样式(h2 + 竖线分隔 + 描述)
- 表格撑满高度、overflow 处理
- 每页添加刷新按钮

## Bug 修复
- 分类树操作按钮 hover 不可见(CSS 规则缺失)
- 文件上传失败(multipart boundary 缺失)
- LLM API 响应 content blocks 数组格式支持(_extract_content_from_api_response)
- response_time_max_ms 被静默忽略(隐式规则传空 params)
- 空 messages 导致 IndexError 崩溃
- poll_reply 异常中止整个 run(缺 try/catch)
- engine finally 未关闭 session
- 3 个页面 UTC 时间戳解析偏差 8 小时

## 后端
- EvalEngine: poll_reply 异常保护、空 dialog 保护、session 关闭
- LLM API 响应解析支持 content-block-array 格式
- 隐式 response_time 规则正确传递 max_ms 参数

## 前端
- api.ts: 移除手动 Content-Type(让浏览器自动添加 boundary)
- Files.tsx: customRequest 替代 beforeUpload、布局优化
- index.css: 分类树 hover 规则
- Targets/Scenarios/Home/Reports: 全高布局改造
- 3 个页面时间戳改用 formatDateTime()(修复 UTC 偏差)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-16 15:25:22 +08:00

7.3 KiB
Raw Permalink Blame History

AgentEvalTool 前端开发日志 — 评测执行页改版

日期: 2026-07-15
基线版本: v0.2.0-dev
状态: 已部署至 t480 开发线
作者: AgentEval Team


一、背景

本次开发在 v0.2.0-dev 基础上对评测执行页Runs进行全面 UI 改版,同时修复了若干历史遗留的基础 Bug。


二、关键 Bug 修复

2.1 index.css 从未被引入(历史遗留)

症状: 所有全局 CSS动画、hover、布局覆盖规则完全无效但无报错提示。

根因: main.tsx 缺少 import './index.css'Vite 不会自动包含未被引用的 CSS 文件,导致该文件从项目创建以来就从未生效。

修复: 在 main.tsx 顶部添加:

import './index.css'

影响: 修复后构建产物首次出现独立 .css 文件(dist/assets/index-*.css),全局 CSS 规则一次性全部生效。


2.2 UTC 时间戳显示偏差 8 小时

症状: 评测记录时间比实际时间早 8 小时(如显示 16:40 实为次日 00:40 北京时间)。

根因(三层叠加):

utc_now() → datetime(UTC)
    ↓ SQLite 不保存时区
"2026-07-14T16:40:00"(无 Z 后缀)
    ↓ ECMAScript 规范:无时区字符串按本地时间解析
new Date("2026-07-14T16:40:00") → 北京时间 16:40比 UTC 多 8 小时)

修复: 在 frontend/web/src/utils/date.ts 添加 toDate() 工具函数:

export function toDate(iso: string): Date {
  if (iso.endsWith('Z') || /[+-]\d{2}:\d{2}$/.test(iso)) return new Date(iso)
  return new Date(iso + 'Z')   // 追加 Z强制按 UTC 解析
}

所有解析后端时间戳的地方统一使用 toDate(),不再直接 new Date(str)

注意: 此问题根本解决方式是后端序列化时附带时区(如 datetime.isoformat()+00:00),前端修复为应急兜底。


2.3 时间过滤器与显示时区不一致

症状: 今天发起的记录显示为正确的北京时间,但选择「当天」时过滤器找不到这些记录。

根因: shortDateTime() 已使用 toDate()UTC 解析正确),但 RunList 过滤器仍用 new Date(r.started_at) 按本地时间解析,两者时间基准不一致,差了 8 小时导致过滤失败。

修复: 过滤器改用 toDate() 统一时间基准:

const t = r.started_at ? toDate(r.started_at).getTime() : null

三、评测执行页改版详情

3.1 全局布局修复

问题 修复方案
页面产生外层滚动条 App.tsx tab 容器改为 height: 100%, boxSizing: border-box,消除 minHeight + padding 叠加导致的溢出
页面顶部出现空隙 html, body { margin: 0; padding: 0 } + 覆盖 Ant Design editable-card Tabs 默认 paddingTop
Grid 子元素高度失效 增加 gridTemplateRows: '1fr',显式让单行撑满 Grid 高度
魔法数字 calc(100vh - 152px) PageWrapper fullHeight + flex 链代替,彻底去除硬编码数字
内容区未贴边 Layout.Content 及所有容器 padding 归零,内容贴合浏览器边缘

3.2 左侧面板 — 启动区

  • 两行布局: 第一行「评测对象」Select 全宽;第二行「评测场景 + 启动」并排
  • Select 增强: showSearch(输入过滤)+ allowClear(清除按钮)
  • 背景色: 区域改为 colors.bgSubtle#fafafa)浅底色,与列表区视觉分隔

3.3 左侧面板 — 筛选区

三行布局:

Row 1: [搜索框 full-width]
Row 2: [全部 进行中 成功 失败]  [当天][1天][7天][30天]  [N条]

时间快捷标签(替代 DatePicker:

  • 当天:自然日 00:00 23:59本地时间
  • 1天昨天 + 今天
  • 7天最近 7 天含今天
  • 30天最近 30 天含今天
  • 默认选中「当天」;再次点击取消(回到全部时间)

状态分段: 默认「全部」选中态蓝底白字ConfigProvider Segmented token

时间标签颜色: 激活态蓝色实心背景 + 白字;未激活态深灰边框 + 深色文字

3.4 左侧面板 — 列表

项目 改动
行结构 三行固定(名称/元信息/进度条),等高不抖动
进度条 pending/running 显示蓝色动态进度(来自 liveProgresscompleted 显示通过率色阶
分页 每页 10 条,底部固定分页栏(始终占位,布局稳定)
排序 去掉错误的 .reverse()API 已按 started_at DESC 返回
hover 去掉 onMouseEnter/Leave 直接操作 DOM改为 CSS .run-row:hover

3.5 右侧面板 — Tab 滚动

问题: 三个 Tab实时对话、规则总览、用例明细内容区无法独立滚动。

根因: Ant Design v5 使用 CSS-in-JSemotion在运行时注入样式覆盖了静态 CSS 文件中的 flex/height 规则,导致 Tab 内容区高度链断裂。

最终方案(导航与内容分离):

Tabs.nav-only-tabs只渲染导航头内容区 display: none
  ↓
三个内容 div直接 flex 子元素):
  flex: 1, min-height: 0, overflowY: auto
  → 高度由 flex 算法直接确定,不经过 Ant Design 内部 DOM
.ant-tabs.nav-only-tabs .ant-tabs-content-holder {
  display: none !important;
}

三个 Tab 的滚动各自独立,互不干扰。


四、其他优化

项目 内容
代码去重 提取 startRun() 函数,消除 handleStartonRerun 重复逻辑
死代码清理 删除 sessionReducer 中从未被 dispatch 的 SET_RUN action
工具函数复用 RunList 改用 shortDateTime / elapsedStr,删除本地重复的 formatStart / durationStr
类型安全 run.summary as any 改为 Record<string, unknown> 类型收窄
Bundle 瘦身 用时间标签替代 DatePickervendor chunk 缩小约 107KB
CSS 组件化 Segmented 选中态、Run list hover 统一移入 ConfigProvider token / CSS 类,不再散落在组件 inline style

五、t480 部署记录

部署前环境补全(首次排查发现):

.env 只有 1 个键(AGENTEVAL_ALLOWED_ORIGINS),缺失以下配置:

AGENTEVAL_API_KEY=
AGENTEVAL_OPENCLAW_UPSTREAM=http://openclaw-eval:18789
AGENTEVAL_OPENCLAW_WS_UPSTREAM=ws://openclaw-eval:18789
AGENTEVAL_OPENCLAW_PROXY_USER=agenteval
AGENTEVAL_OPENCLAW_AUTH_TOKEN=change-me-in-production

已通过 SSH 补全OpenClaw 代理功能恢复正常。


六、遗留问题

问题 状态 说明
case-001 无发送气泡 待查 只有智能体回复,无用户发送内容;需确认 DB 中 turn.sent_message 字段内容
UTC 时间后缀 待优化 当前前端追加 Z 兜底;根本修复需后端序列化附带时区标记

七、文件变更清单

前端

  • src/main.tsx — 添加 import './index.css'
  • src/index.css — html/body 重置、nav-only-tabs、TabBar padding 覆盖、Segmented 样式
  • src/App.tsx — 布局修复overflow、paddingSegmented token
  • src/components/PageWrapper.tsx — 新增 fullHeight prop
  • src/pages/Runs.tsx — 完整重构布局、启动区、内联头部、Tab 分离
  • src/components/RunList.tsx — 筛选区三行布局、时间标签、toDate 对齐、分页
  • src/utils/date.ts — 新增 toDate()export修复时区
  • src/hooks/sessionReducer.ts — 删除 SET_RUN 死代码