feat(app): role-local measured energy axes + per-worker power drilldown | 前端:新增角色级实测能耗坐标轴与每 worker 功耗下钻 - #908
Conversation
…rilldown | 推理图表:新增角色级实测能耗坐标轴与每 worker 功耗下钻 Add y_measuredPrefillJPerInputToken and y_measuredDecodeJPerOutputToken to the Measured Energy group (bilingual labels, lower polarity, explanations), map prefill_joules_per_input_token / decode_joules_per_output_token into chart fields, and render a pinned-only per-worker power table (role, chips, watts, optional temp/util/mem/hosts, 8-row cap, HTML-escaped JSONB strings) in all three tooltip generators. 在“实测能耗”分组新增每输入 token 实测 Prefill 能耗与每输出 token 实测 Decode 能耗两个 Y 轴(双语标签、越低越好、附说明),将角色级能耗字段映射 为图表字段,并在三种工具提示中新增仅固定时显示的每 worker 功耗表 (角色、芯片数、功耗,可选温度/利用率/显存/主机,上限 8 行,HTML 转义)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…worker drilldown | 测试:覆盖 AgentX 实测功耗、角色级能耗坐标轴与 worker 下钻 Agentic-traces transform pass-through and power_valid=0 scrub (including workers), role-energy chart-field emission/absence/zero-preservation, Pareto corners and bilingual labels for the two new axes, input/output token classification and share-link round-trip, and the pinned worker table across all three tooltip generators (cap, ZH, HTML escaping). 覆盖 agentic_traces 变换透传与 power_valid=0 清除(含 workers)、角色级 能耗图表字段的生成/缺省/零值保留、两个新坐标轴的帕累托方向与双语标签、 输入/输出 token 分类与分享链接解析回环,以及三种工具提示中固定状态下 的 worker 表(行数上限、中文、HTML 转义)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…使用合成 worker 数据的 AgentX 实测功耗 Spec-scoped intercepts inject a disagg agentic series (role energy + workers[]) and an aggregate series (whole-run metrics, workers: null): the two role-energy axes render under Measured Energy, the aggregate series coverage-filters off while the legend stays intact, the pinned tooltip shows the worker table, and a workers-less point stays clean. 通过 spec 级拦截注入分离式 agentic 序列(角色级能耗 + workers[])与 聚合序列(全程指标、workers 为 null):两个角色级能耗坐标轴显示在 “实测能耗”分组下,聚合序列因无该指标从图中过滤但图例保持完整, 固定的工具提示显示 worker 表,无 workers 的点保持正常。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @edwingao28's task in 3m 55s —— View job Review: role-local measured energy axes + per-worker power drilldown
🟢 LGTM — no blocking issues found. Clean, well-scoped stacked PR. The implementation is consistent with the surrounding PLAN-02 measured-power machinery, and I verified the changed behavior at runtime. Correctness spot-checks (all pass):
Security: The only untrusted string fields ( Interpolation sync: None of the four TS interpolation functions changed, so no Runtime (localhost, Playwright):
Tests: Comprehensive — transform pass-through + Chinese copy: The new zh strings (axis labels/titles, Note (non-blocking, not new to this PR): the e2e/lint/unit workflows aren't in this PR's check list (likely because the base is a stacked non- |
…n-destructive axis switch | 端到端测试修复:断言覆盖过滤会移出图例,并验证坐标轴切换可无损恢复 The rendered legend is metric-aware (hwTypesWithData), so a series without the selected role-energy metric drops out of the legend too — the previous assertion expected it to stay and failed deterministically. Re-selecting a whole-run measured axis now proves the selection universe survives the switch. Also documents the MiB reading of avg_mem_used_mb in the worker tooltip. 图例渲染依据所选指标(hwTypesWithData),缺少角色级能耗指标的系列会同时从图例中 移除,原断言必然失败。现改为断言其不在图例中,并通过重新选择全局实测坐标轴验证 选择集在切换后无损恢复。同时为 worker 工具提示中 avg_mem_used_mb 的 MiB 语义 补充说明。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Claude finished @edwingao28's task in 2m 47s —— View job Re-review: role-local measured energy axes + per-worker power drilldown
🟢 Re-review: LGTM — no blocking issues found. Only one commit is new since my last review (ffcc972): Everything from the prior pass still stands:
Runtime (localhost, Playwright): Both axes appear under Measured Energy ( Note (non-blocking, unchanged): only the |
|
Superseded by #935 (branch renamed to feat/worker-power-drilldown); identical diff. |
Important
STACKED PR — base branch is
klaud/powerx-02-certified-view(#907). That PR must merge first; this diff contains only the PLAN-10 deltas on top of it. Do not squash-merge this PR intomasterbefore #907 lands.What (PLAN-10 / gap G15)
Three connected gaps left measured-power data invisible or untested in the app frontend:
workers[]was plumbed end-to-end but nothing rendered it. The type, transform (benchmark-transform.ts), and API docs all carry per-worker power, yet no tooltip/dialog/page consumed it.prefill_joules_per_input_token/decode_joules_per_output_tokenare populated wheneverpower_valid !== 0, but users could only plot whole-deployment J/tok and role watts — not the role energy efficiency that separates prefill-bound from decode-bound disagg deployments.single_turn; both power cypress specs were fixed-seq only.Changes
Two new registry axes (Measured Energy group)
y_measuredPrefillJPerInputToken— Measured Prefill Joules per Input Token / 每输入 token 实测 Prefill 能耗y_measuredDecodeJPerOutputToken— Measured Decode Joules per Output Token / 每输出 token 实测 Decode 能耗polarity: 'lower'(Paretolower_righton interactivity /lower_lefton e2e derives automatically), bilingual labels/titles, entries inMETRIC_EXPLANATIONSwith the certification-tier note, and membership inMEASURED_ENERGY_METRIC_CONFIG_KEYS— so the PLAN-02 tier ring / tooltip tier line / footer key apply to them too.buildMeasuredPowerChartFieldsmaps the two role scalars into{y, roof}chart fields;tokenMetricTypeForConfigKeyclassifies theminput/outputby substring (asserted in tests).hwTypesWithData). The switch is non-destructive: the selection universe (selectableHwTypes) never intersects metric coverage, so switching back to an axis both series carry restores the series with no legend re-selection (asserted in the e2e spec).WorkerPower drilldown in the pinned chart tooltip
generateWorkerPowerHTML(d, isPinned, locale)intooltipUtils.ts, rendered by all three generators (official, overlay, GPU-compare) only when pinned andworkersis non-empty.role[worker_idx] · N chips · W, plus temp (avg/peak°C), util %, mem GiB, and hosts when present. Capped at 8 rows with a bilingual+N more workersline.roleandhostsare HTML-escaped (they arrive from artifact JSONB).avg_mem_used_mbis read as MiB (nvidia-smi convention) →/1024GiB; commented in code, to be confirmed against PLAN-09's producer.Tests
benchmark_type='agentic_traces'with the full measured-power payload (pass-through incl.workers) and thepower_valid: 0scrub mirror.chart-utils.test.ts: emission / absence / zero-preservation for the two new chart fields.measured-power-direction.test.ts: Pareto corners + bilingual labels for both new config keys.metric-registry.test.ts: token-type classification + share-link round-trip; the pre-existing registry⇄groups parity test enforces group membership.tooltip-utils.test.ts: worker table across all three generators — pinned/unpinned, empty/absent, 8-row cap, ZH strings, HTML escaping.cypress/e2e/agentic-measured-power.cy.ts(spec-scoped intercepts, synthetic fixtures via newmeasuredPowerMetrics()/syntheticWorkers()helpers inagentic-fixtures.ts): both axes visible under Measured Energy, aggregate series coverage-filtered off chart and legend with a non-destructive switch back, worker table on a pinned agentic point, graceful absence on a workers-less point. Registered intimings.jsonfor cypress-split.Data caveat
Production
workers[]is currently empty for AgentX runs — producer-side emission lands with PLAN-09 (InferenceX repo). The UI renders gracefully withworkersabsent/empty (verified by unit tests and the e2e spec's aggregate series); the synthetic cypress fixtures verify the drilldown ahead of real data. Fixed-seq multinode disagg points already carry realworkerstoday.Backward compatibility
workers, no role energy, nopower_valid) render exactly as before — the untouched pre-existing transform/chart/tooltip tests stay green.resolveMetricConfigKey(fall back to the default axis); old links are unaffected.Review findings & resolutions
An independent two-lens review of the initial push found:
703aaae0): the e2e spec's first test asserted the legend still containsB300after selecting the prefill-energy axis, but the rendered legend is metric-aware (hwTypesWithData,InferenceContext.tsx) and intentionally drops coverage-filtered series — the assertion failed deterministically. Fixed to assertnot.contain.text('B300'), and the test now also proves the switch is non-destructive by re-selecting Measured Joules per Output Token and asserting the b300 dots and legend entry return.E2E_FIXTURES=1dev server): 3/3 passing, plus adjacent regression specsmeasured-power-overlay/yaxis-metrics-render/ttft-x-axis-toggle/certified-power-filter— 69/69 passing.packages/app/AGENTS.md/CLAUDE.md(dev-server byproducts, regenerated on everynext dev) removed from the worktree; never part of this diff.avg_mem_used_mb→ GiB/1024conversion assumes MiB semantics (nvidia-smi convention); noted in code for re-check when PLAN-09's producer lands.have.length, 3) is stricter than sibling specs'at.least. Kept: the fixture injects exactly 3 disagg rows, hidden points are hidden via opacity (not DOM removal), and the assertion passed locally on the first attempt; relax only if CI proves it flaky.Validation
bun run typecheck✅bun run lint✅bun run fmt✅packages/appfull unit suite: 251 files / 4499 tests passed ✅ (targeted power/registry/tooltip suites: 456 tests ✅)packages/db(596 tests) andpackages/constants(47 tests) ✅ (packages/mcpsrc/server.test.tsfails identically on the base branch — pre-existing environment issue, untouched here)E2E_FIXTURES=1): newagentic-measured-power.cy.ts3/3 ✅; adjacentmeasured-power-overlay+yaxis-metrics-render+ttft-x-axis-toggle+certified-power-filter69/69 ✅. CI re-verifies viatests-e2e.yml(specPattern+ cypress-split,timings.jsonentry added).🤖 Generated with Claude Code
Note
Low Risk
Frontend-only visualization and test additions; worker tooltip data is escaped before HTML interpolation and invalid power rows continue to scrub telemetry unchanged.
Overview
Adds two Measured Energy y-axes — Measured Prefill Joules per Input Token and Measured Decode Joules per Output Token — wired through the metric registry, bilingual explanations, chart field mapping from
prefill_joules_per_input_token/decode_joules_per_output_token, and existing coverage filtering so aggregate rows without role energy drop off those axes.Pinned chart tooltips now show a Measured Worker Power section when
workers[]is present: per-worker watts (and optional temp, util, memory, hosts), capped at eight rows with overflow text, HTML-escaped role/host strings, and EN/ZH copy across official, overlay, and GPU-compare tooltip generators; hover and empty/missingworkersstay unchanged.Test coverage expands with transform/chart/registry/tooltip unit tests, Cypress helpers (
measuredPowerMetrics,syntheticWorkers), and a new AgentX e2e spec that intercepts synthetic agentic benchmarks to assert axis visibility, legend filtering, worker drilldown, and graceful absence without workers.Reviewed by Cursor Bugbot for commit 703aaae. Bugbot is set up for automated code reviews on this repo. Configure here.