Prhub

#2490 dashboard: keep sample status/reward chips visible on the Tokens tab

原始 PR 作者 Shi-Dong 合并时间 2026-08-13 06:57 文件变更 2 提交数 1 评论 0 代码增减 +16 / -7

执行摘要

样本状态 / 奖励 chips 移到标签栏上方,Tokens 页保持可见

PR body 说明 reward 是打开 token 视图时最想解释的东西:用户去看哪些 token 驱动了 0 奖励,或某个高分样本里 importance ratio 在哪里爆掉。此前必须来回切换 Conversation 标签才能确认 reward 和状态,这是该视图核心工作流中的摩擦。status 同理:truncated 样本与 completed 样本的阅读方式完全不同。

值得快速阅读,是小型但完整的 UI 组件拆分案例。关注 renderSampleChips 的拆分方式和 renderTokens 中 DOM 顺序的组织,对理解 dashboard 前端组件组织有帮助。虽然有浏览器验证,但仓库无 JS 测试 harness 是持续存在的技术债,值得后续投入。

讨论亮点

无 review 评论讨论内容,两位 reviewer(yueming-yuan、nblintao)均直接 APPROVED,无争议点。

实现拆解

  1. miles/dashboard/static/conversation.js 中把 chips 渲染逻辑从 renderConversation 抽出,新增导出函数 renderSampleChips(row),返回裸的 .controls 行,不再嵌套在 Conversation panel 内;同时 renderConversation 只渲染标题和消息卡片。
  2. miles/dashboard/static/views_tokens.js 中导入 renderSampleChips,并在 renderTokensview.replaceChildren 调用中,将 renderSampleChips(conversationRow) 放在 panels 之后、tabs 之前,使其位于两个面板之外、标签栏上方。
  3. conversationRow === null 的路径(无对话 sidecar 的样本)维持原样:不渲染标签栏,只渲染 token 面板。
  4. 验证方式:通过真实 dump 管道生成 dummy dump(tests/fast/dashboard/dummy_dump.py),用 python -m miles.dashboard.serve 服务,再通过 Playwright 驱动真实 Chrome 断言 chip 文本与 #view 子元素顺序。仓库无 JS 测试 harness,因此浏览器运行即为验证。
文件 模块 状态 重要度
miles/dashboard/static/conversation.js 前端组件 modified 6.54
miles/dashboard/static/views_tokens.js 样本视图 modified 5.19

关键符号

renderSampleChips renderConversation

关键源码片段

miles/dashboard/static/conversation.js core-logic

核心改动:将 chips 渲染从 renderConversation 中拆出为独立导出 renderSampleChips,返回裸 .controls 行,使 chips 能在标签栏上方独立渲染。

// miles/dashboard/static/conversation.js
import { el, fmtNum } from "./app.js";// sample outcome (status + reward) from the trajectory sidecar。
// 该函数独立于对话面板,因为样本结果描述的是样本本身,
// 而不是某一次渲染,切换 Tokens 标签时它必须保持可见。
export function renderSampleChips(row) {
  const chips = [el("span", { class: "chip" }, [row.status])];
  // 显式判断 null/undefined,避免把真实的 0.0 奖励当成 falsy 吞掉
  if (row.reward !== null && row.reward !== undefined) {
    chips.push(el("span", { class: "chip" }, [`reward ${fmtNum(row.reward)}`]));
  }
  // 返回裸的 controls 行,由调用方决定放置位置(标签栏上方)
  return el("div", { class: "controls" }, chips);
}// 对话面板只负责标题与消息卡片,不再内嵌 chips
export function renderConversation(row) {
  return el("div", { class: "panel" }, [
    el("h3", {}, ["Conversation"]),
    ...row.messages.map(messageCard),
  ]);
}
miles/dashboard/static/views_tokens.js dependency-wiring

变更接入点:将 renderSampleChips 渲染到标签栏上方,使 chips 在两种标签下均可见;同时更新导入。

// miles/dashboard/static/views_tokens.js
import { renderConversation, renderSampleChips } from "./conversation.js";export async function renderTokens(view, meta, route) {
  // ... 前置逻辑:conversationRow 为 null 时直接渲染 token 面板并返回  const conversationPane = renderConversation(conversationRow);
  const tabs = el("div", { class: "tabs" });
  const body = el("div");
  const select = (name) => {
    tabs.replaceChildren(
      ...["conversation", "tokens"].map((tab) =>
        el("button", { class: tab === name ? "active" : "", onclick: () => select(tab) }, [
          tab[0].toUpperCase() + tab.slice(1),
        ]),
      ),
    );
    body.replaceChildren(name === "conversation" ? conversationPane : tokensPane);
    if (name === "tokens") startTokens();
  };
  // chips 位于标签栏上方、两个面板之外,
  // 因此切换标签时不会被替换掉,状态与奖励始终可见
  view.replaceChildren(...panels, renderSampleChips(conversationRow), tabs, body);
  select("conversation");
}

评论区精华

review 审批 other

yueming-yuan 与 nblintao 均 APPROVED,无评论内容。

结论:两位 reviewer 直接批准,无修改意见。 · 已解决

风险与影响

  1. 回归风险:renderTokensview.replaceChildren(...panels, renderSampleChips(conversationRow), tabs, body) 仅在 conversationRow 非 null 时执行,因此该分支不受影响;但若未来有其他调用方直接依赖 renderConversation 的内部 DOM 结构,可能受影响。
  2. 兼容性:纯前端 DOM 结构变化,无 API/schema 变化,Python 测试不受影响。
  3. 样式风险:chips 使用 .controls 类,从面板内移到标签栏上方,视觉位置变化已在 PR 中附前后对比图确认。
  4. 测试缺口:仓库无 JS 测试 harness,本改动没有自动化测试覆盖,只能依赖手动/Playwright 验证。

影响范围:dashboard 前端 Rollouts → sample 视图的显示逻辑。用户影响:在 Tokens 标签下也能看到样本状态和奖励,减少来回切换,提升样本级调试效率。对系统无性能、安全影响,纯展示层改动。对团队影响:为后续 dashboard 前端组件拆分提供一个模式(将跨面板共享信息提升到公共区域)。

缺少 JS 自动化测试覆盖 前端 DOM 结构调整

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论