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

196 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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` 顶部添加:
```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()` 工具函数:
```ts
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()` 统一时间基准:
```ts
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
```
```css
.ant-tabs.nav-only-tabs .ant-tabs-content-holder {
display: none !important;
}
```
三个 Tab 的滚动各自独立,互不干扰。
---
## 四、其他优化
| 项目 | 内容 |
|---|---|
| 代码去重 | 提取 `startRun()` 函数,消除 `handleStart``onRerun` 重复逻辑 |
| 死代码清理 | 删除 `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`),缺失以下配置:
```bash
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` 死代码